2 * src/lib/krb5/asn.1/asn1_k_decode.c
4 * Copyright 1994 by the Massachusetts Institute of Technology.
7 * Export of this software from the United States of America may
8 * require a specific license from the United States Government.
9 * It is the responsibility of any person or organization contemplating
10 * export to obtain such a license before exporting.
12 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
13 * distribute this software and its documentation for any purpose and
14 * without fee is hereby granted, provided that the above copyright
15 * notice appear in all copies and that both that copyright notice and
16 * this permission notice appear in supporting documentation, and that
17 * the name of M.I.T. not be used in advertising or publicity pertaining
18 * to distribution of the software without specific, written prior
19 * permission. M.I.T. makes no representations about the suitability of
20 * this software for any purpose. It is provided "as is" without express
21 * or implied warranty.
24 #include "asn1_k_decode.h"
25 #include "asn1_decode.h"
27 #include "asn1_misc.h"
30 asn1_error_code retval;\
32 asn1_construction construction;\
37 retval = asn1_get_tag(&subbuf,&class,&construction,&tagnum,NULL);\
38 if(retval) return retval;\
39 if(class != CONTEXT_SPECIFIC || construction != CONSTRUCTED)\
42 #define alloc_field(var,type)\
43 var = (type*)calloc(1,sizeof(type));\
44 if((var) == NULL) return ENOMEM
47 #define apptag(tagexpect)\
48 retval = asn1_get_tag(buf,&class,&construction,&tagnum,NULL);\
49 if(retval) return retval;\
50 if(class != APPLICATION || construction != CONSTRUCTED ||\
51 tagnum != (tagexpect)) return ASN1_BAD_ID
53 /**** normal fields ****/
54 #define get_field_body(var,decoder)\
55 retval = decoder(&subbuf,&(var));\
56 if(retval) return retval;\
59 #define get_field(var,tagexpect,decoder)\
60 if(tagnum > (tagexpect)) return ASN1_MISSING_FIELD;\
61 if(tagnum < (tagexpect)) return ASN1_MISPLACED_FIELD;\
62 get_field_body(var,decoder)
64 #define opt_field(var,tagexpect,decoder,optvalue)\
65 if(tagnum == (tagexpect)){\
66 get_field_body(var,decoder); }\
69 /**** fields w/ length ****/
70 #define get_lenfield_body(len,var,decoder)\
71 retval = decoder(&subbuf,&(len),&(var));\
72 if(retval) return retval;\
75 #define get_lenfield(len,var,tagexpect,decoder)\
76 if(tagnum > (tagexpect)) return ASN1_MISSING_FIELD;\
77 if(tagnum < (tagexpect)) return ASN1_MISPLACED_FIELD;\
78 get_lenfield_body(len,var,decoder)
82 #define begin_structure()\
84 retval = asn1_get_tag(buf,&class,&construction,&tagnum,&length);\
85 if(retval) return retval;\
86 if(class != UNIVERSAL || construction != CONSTRUCTED ||\
87 tagnum != ASN1_SEQUENCE) return ASN1_BAD_ID;\
88 retval = asn1buf_imbed(&subbuf,buf,length);\
89 if(retval) return retval;\
92 #define end_structure()\
93 asn1buf_sync(buf,&subbuf)
95 #define sequence_of(buf)\
99 retval = asn1_get_sequence(buf,&length);\
100 if(retval) return retval;\
101 retval = asn1buf_imbed(&seqbuf,buf,length);\
102 if(retval) return retval
104 #define end_sequence_of(buf)\
105 asn1buf_sync(buf,&seqbuf)
113 asn1_error_code INTERFACE asn1_decode_kerberos_time(buf, val)
115 krb5_timestamp * val;
118 asn1_error_code retval;
120 retval = asn1_decode_generaltime(buf,&t);
128 #define integer_convert(fname,ktype)\
129 asn1_error_code INTERFACE fname(buf, val)\
133 asn1_error_code retval;\
135 retval = asn1_decode_integer(buf,&n);\
136 if(retval) return retval;\
140 #define unsigned_integer_convert(fname,ktype)\
141 asn1_error_code INTERFACE fname(buf, val)\
145 asn1_error_code retval;\
147 retval = asn1_decode_unsigned_integer(buf,&n);\
148 if(retval) return retval;\
152 integer_convert(asn1_decode_int,int)
153 integer_convert(asn1_decode_int32,krb5_int32)
154 integer_convert(asn1_decode_kvno,krb5_kvno)
155 integer_convert(asn1_decode_keytype,krb5_keytype)
156 integer_convert(asn1_decode_cksumtype,krb5_cksumtype)
157 integer_convert(asn1_decode_enctype,krb5_enctype)
158 integer_convert(asn1_decode_octet,krb5_octet)
159 integer_convert(asn1_decode_addrtype,krb5_addrtype)
160 integer_convert(asn1_decode_authdatatype,krb5_authdatatype)
161 unsigned_integer_convert(asn1_decode_ui_2,krb5_ui_2)
162 unsigned_integer_convert(asn1_decode_ui_4,krb5_ui_4)
164 asn1_error_code INTERFACE asn1_decode_msgtype(buf, val)
168 asn1_error_code retval;
171 retval = asn1_decode_unsigned_integer(buf,&n);
172 if(retval) return retval;
174 *val = (krb5_msgtype) n;
180 asn1_error_code INTERFACE asn1_decode_realm(buf, val)
182 krb5_principal * val;
184 return asn1_decode_generalstring(buf,
185 &((*val)->realm.length),
186 &((*val)->realm.data));
189 asn1_error_code INTERFACE asn1_decode_principal_name(buf, val)
191 krb5_principal * val;
195 get_field((*val)->type,0,asn1_decode_int32);
197 { sequence_of(&subbuf);
198 while(asn1buf_remains(&seqbuf)){
200 if ((*val)->data == NULL)
201 (*val)->data = (krb5_data*)malloc(size*sizeof(krb5_data));
203 (*val)->data = (krb5_data*)realloc((*val)->data,
204 size*sizeof(krb5_data));
205 if((*val)->data == NULL) return ENOMEM;
206 retval = asn1_decode_generalstring(&seqbuf,
207 &((*val)->data[size-1].length),
208 &((*val)->data[size-1].data));
209 if(retval) return retval;
211 (*val)->length = size;
212 end_sequence_of(&subbuf);
215 (*val)->magic = KV5M_PRINCIPAL;
220 asn1_error_code INTERFACE asn1_decode_checksum(buf, val)
226 get_field(val->checksum_type,0,asn1_decode_cksumtype);
227 get_lenfield(val->length,val->contents,1,asn1_decode_octetstring);
229 val->magic = KV5M_CHECKSUM;
234 asn1_error_code INTERFACE asn1_decode_encryption_key(buf, val)
240 get_field(val->keytype,0,asn1_decode_keytype);
241 get_lenfield(val->length,val->contents,1,asn1_decode_octetstring);
243 val->magic = KV5M_KEYBLOCK;
244 val->etype = ETYPE_UNKNOWN;
249 asn1_error_code INTERFACE asn1_decode_encrypted_data(buf, val)
255 get_field(val->etype,0,asn1_decode_enctype);
256 opt_field(val->kvno,1,asn1_decode_kvno,0);
257 get_lenfield(val->ciphertext.length,val->ciphertext.data,2,asn1_decode_charstring);
259 val->magic = KV5M_ENC_DATA;
264 asn1_error_code INTERFACE asn1_decode_krb5_flags(buf, val)
273 retval = asn1_get_tag(buf,&class,&construction,&tagnum,&length);
274 if(retval) return retval;
275 if(class != UNIVERSAL || construction != PRIMITIVE ||
276 tagnum != ASN1_BITSTRING) return ASN1_BAD_ID;
277 if(length != 5) return ASN1_BAD_LENGTH;
279 retval = asn1buf_remove_octet(buf,&o); /* # of padding bits */
280 if(retval) return retval; /* should be 0 */
281 if(o != 0) return ASN1_BAD_FORMAT;
284 retval = asn1buf_remove_octet(buf,&o);
285 if(retval) return retval;
286 f = (f<<8) | ((krb5_flags)o&0xFF);
292 asn1_error_code INTERFACE asn1_decode_ticket_flags(buf, val)
295 { return asn1_decode_krb5_flags(buf,val); }
297 asn1_error_code INTERFACE asn1_decode_ap_options(buf, val)
300 { return asn1_decode_krb5_flags(buf,val); }
302 asn1_error_code INTERFACE asn1_decode_kdc_options(buf, val)
305 { return asn1_decode_krb5_flags(buf,val); }
307 asn1_error_code INTERFACE asn1_decode_transited_encoding(buf, val)
309 krb5_transited * val;
313 get_field(val->tr_type,0,asn1_decode_octet);
314 get_lenfield(val->tr_contents.length,val->tr_contents.data,1,asn1_decode_charstring);
316 val->magic = KV5M_TRANSITED;
321 asn1_error_code INTERFACE asn1_decode_enc_kdc_rep_part(buf, val)
323 krb5_enc_kdc_rep_part * val;
327 alloc_field(val->session,krb5_keyblock);
328 get_field(*(val->session),0,asn1_decode_encryption_key);
329 get_field(val->last_req,1,asn1_decode_last_req);
330 get_field(val->nonce,2,asn1_decode_int32);
331 opt_field(val->key_exp,3,asn1_decode_kerberos_time,0);
332 get_field(val->flags,4,asn1_decode_ticket_flags);
333 get_field(val->times.authtime,5,asn1_decode_kerberos_time);
334 opt_field(val->times.starttime,6,asn1_decode_kerberos_time,0);
335 get_field(val->times.endtime,7,asn1_decode_kerberos_time);
336 opt_field(val->times.renew_till,8,asn1_decode_kerberos_time,0);
337 alloc_field(val->server,krb5_principal_data);
338 get_field(val->server,9,asn1_decode_realm);
339 get_field(val->server,10,asn1_decode_principal_name);
340 opt_field(val->caddrs,11,asn1_decode_host_addresses,NULL);
342 val->magic = KV5M_ENC_KDC_REP_PART;
347 asn1_error_code INTERFACE asn1_decode_ticket(buf, val)
355 get_field(vno,0,asn1_decode_kvno);
356 if(vno != KVNO) return KRB5KDC_ERR_BAD_PVNO; }
357 alloc_field(val->server,krb5_principal_data);
358 get_field(val->server,1,asn1_decode_realm);
359 get_field(val->server,2,asn1_decode_principal_name);
360 get_field(val->enc_part,3,asn1_decode_encrypted_data);
362 val->magic = KV5M_TICKET;
367 asn1_error_code INTERFACE asn1_decode_kdc_req(buf, val)
374 get_field(kvno,1,asn1_decode_kvno);
375 if(kvno != KVNO) return KRB5KDC_ERR_BAD_PVNO; }
376 get_field(val->msg_type,2,asn1_decode_msgtype);
377 opt_field(val->padata,3,asn1_decode_sequence_of_pa_data,NULL);
378 get_field(*val,4,asn1_decode_kdc_req_body);
380 val->magic = KV5M_KDC_REQ;
385 asn1_error_code INTERFACE asn1_decode_kdc_req_body(buf, val)
391 get_field(val->kdc_options,0,asn1_decode_kdc_options);
392 if(tagnum == 1){ alloc_field(val->client,krb5_principal_data); }
393 opt_field(val->client,1,asn1_decode_principal_name,NULL);
394 alloc_field(val->server,krb5_principal_data);
395 get_field(val->server,2,asn1_decode_realm);
396 if(val->client != NULL){
397 retval = asn1_krb5_realm_copy(val->client,val->server);
398 if(retval) return retval; }
399 opt_field(val->server,3,asn1_decode_principal_name,NULL);
400 opt_field(val->from,4,asn1_decode_kerberos_time,0);
401 get_field(val->till,5,asn1_decode_kerberos_time);
402 opt_field(val->rtime,6,asn1_decode_kerberos_time,0);
403 get_field(val->nonce,7,asn1_decode_int32);
404 get_lenfield(val->netypes,val->etype,8,asn1_decode_sequence_of_enctype);
405 opt_field(val->addresses,9,asn1_decode_host_addresses,0);
407 get_field(val->authorization_data,10,asn1_decode_encrypted_data); }
409 val->authorization_data.magic = 0;
410 val->authorization_data.etype = 0;
411 val->authorization_data.kvno = 0;
412 val->authorization_data.ciphertext.data = NULL;
413 val->authorization_data.ciphertext.length = 0;
415 opt_field(val->second_ticket,11,asn1_decode_sequence_of_ticket,NULL);
417 val->magic = KV5M_KDC_REQ;
422 asn1_error_code INTERFACE asn1_decode_krb_safe_body(buf, val)
428 get_lenfield(val->user_data.length,val->user_data.data,0,asn1_decode_charstring);
429 opt_field(val->timestamp,1,asn1_decode_kerberos_time,0);
430 opt_field(val->usec,2,asn1_decode_int32,0);
431 opt_field(val->seq_number,3,asn1_decode_int32,0);
432 alloc_field(val->s_address,krb5_address);
433 get_field(*(val->s_address),4,asn1_decode_host_address);
435 alloc_field(val->r_address,krb5_address);
436 get_field(*(val->r_address),5,asn1_decode_host_address);
437 } else val->r_address = NULL;
439 val->magic = KV5M_SAFE;
444 asn1_error_code INTERFACE asn1_decode_host_address(buf, val)
450 get_field(val->addrtype,0,asn1_decode_addrtype);
451 get_lenfield(val->length,val->contents,1,asn1_decode_octetstring);
453 val->magic = KV5M_ADDRESS;
458 asn1_error_code INTERFACE asn1_decode_kdc_rep(buf, val)
465 get_field(pvno,0,asn1_decode_kvno);
466 if(pvno != KVNO) return KRB5KDC_ERR_BAD_PVNO; }
467 get_field(val->msg_type,1,asn1_decode_msgtype);
468 opt_field(val->padata,2,asn1_decode_sequence_of_pa_data,NULL);
469 alloc_field(val->client,krb5_principal_data);
470 get_field(val->client,3,asn1_decode_realm);
471 get_field(val->client,4,asn1_decode_principal_name);
472 alloc_field(val->ticket,krb5_ticket);
473 get_field(*(val->ticket),5,asn1_decode_ticket);
474 get_field(val->enc_part,6,asn1_decode_encrypted_data);
476 val->magic = KV5M_KDC_REP;
483 #define get_element(element,decoder)\
484 retval = decoder(&seqbuf,element);\
485 if(retval) return retval
487 #define array_append(array,size,element,type)\
489 if (*(array) == NULL)\
490 *(array) = (type**)malloc((size+1)*sizeof(type*));\
492 *(array) = (type**)realloc(*(array),\
493 (size+1)*sizeof(type*));\
494 if(*(array) == NULL) return ENOMEM;\
495 (*(array))[(size)-1] = elt
497 #define decode_array_body(type,decoder)\
498 asn1_error_code retval;\
502 while(asn1buf_remains(&seqbuf) > 0){\
503 alloc_field(elt,type);\
504 get_element(elt,decoder);\
505 array_append(val,size,elt,type);\
507 (*val)[size] = NULL;\
508 end_sequence_of(buf);\
513 asn1_error_code INTERFACE asn1_decode_authorization_data(buf, val)
515 krb5_authdata *** val;
517 decode_array_body(krb5_authdata,asn1_decode_authdata_elt);
520 asn1_error_code INTERFACE asn1_decode_authdata_elt(buf, val)
526 get_field(val->ad_type,0,asn1_decode_authdatatype);
527 get_lenfield(val->length,val->contents,1,asn1_decode_octetstring);
529 val->magic = KV5M_AUTHDATA;
534 asn1_error_code INTERFACE asn1_decode_host_addresses(buf, val)
536 krb5_address *** val;
538 decode_array_body(krb5_address,asn1_decode_host_address);
541 asn1_error_code INTERFACE asn1_decode_sequence_of_ticket(buf, val)
545 decode_array_body(krb5_ticket,asn1_decode_ticket);
548 asn1_error_code INTERFACE asn1_decode_sequence_of_krb_cred_info(buf, val)
550 krb5_cred_info *** val;
552 decode_array_body(krb5_cred_info,asn1_decode_krb_cred_info);
555 asn1_error_code INTERFACE asn1_decode_krb_cred_info(buf, val)
557 krb5_cred_info * val;
561 alloc_field(val->session,krb5_keyblock);
562 get_field(*(val->session),0,asn1_decode_encryption_key);
564 alloc_field(val->client,krb5_principal_data);
565 opt_field(val->client,1,asn1_decode_realm,NULL);
566 opt_field(val->client,2,asn1_decode_principal_name,NULL); }
567 opt_field(val->flags,3,asn1_decode_ticket_flags,0);
568 opt_field(val->times.authtime,4,asn1_decode_kerberos_time,0);
569 opt_field(val->times.starttime,5,asn1_decode_kerberos_time,0);
570 opt_field(val->times.endtime,6,asn1_decode_kerberos_time,0);
571 opt_field(val->times.renew_till,7,asn1_decode_kerberos_time,0);
573 alloc_field(val->server,krb5_principal_data);
574 opt_field(val->server,8,asn1_decode_realm,NULL);
575 opt_field(val->server,9,asn1_decode_principal_name,NULL); }
576 opt_field(val->caddrs,10,asn1_decode_host_addresses,NULL);
578 val->magic = KV5M_CRED_INFO;
583 asn1_error_code INTERFACE asn1_decode_sequence_of_pa_data(buf, val)
585 krb5_pa_data *** val;
587 decode_array_body(krb5_pa_data,asn1_decode_pa_data);
590 asn1_error_code INTERFACE asn1_decode_pa_data(buf, val)
596 get_field(val->pa_type,1,asn1_decode_ui_2);
597 get_lenfield(val->length,val->contents,2,asn1_decode_octetstring);
599 val->magic = KV5M_PA_DATA;
604 asn1_error_code INTERFACE asn1_decode_last_req(buf, val)
606 krb5_last_req_entry *** val;
608 decode_array_body(krb5_last_req_entry,asn1_decode_last_req_entry);
611 asn1_error_code INTERFACE asn1_decode_last_req_entry(buf, val)
613 krb5_last_req_entry * val;
617 get_field(val->lr_type,0,asn1_decode_octet);
618 get_field(val->value,1,asn1_decode_kerberos_time);
620 val->magic = KV5M_LAST_REQ_ENTRY;
625 asn1_error_code INTERFACE asn1_decode_sequence_of_enctype(buf, num, val)
630 asn1_error_code retval;
632 while(asn1buf_remains(&seqbuf) > 0){
635 *val = (krb5_enctype*)malloc(size*sizeof(krb5_enctype));
637 *val = (krb5_enctype*)realloc(*val,size*sizeof(krb5_enctype));
638 if(*val == NULL) return ENOMEM;
639 retval = asn1_decode_enctype(&seqbuf,&((*val)[size-1]));
640 if(retval) return retval;
643 end_sequence_of(buf);
648 asn1_error_code INTERFACE asn1_decode_passwdsequence(buf, val)
650 passwd_phrase_element * val;
654 alloc_field(val->passwd,krb5_data);
655 get_lenfield(val->passwd->length,val->passwd->data,
656 0,asn1_decode_charstring);
657 alloc_field(val->phrase,krb5_data);
658 get_lenfield(val->phrase->length,val->phrase->data,
659 1,asn1_decode_charstring);
665 asn1_error_code INTERFACE asn1_decode_sequence_of_passwdsequence(buf, val)
667 passwd_phrase_element *** val;
669 decode_array_body(passwd_phrase_element,asn1_decode_passwdsequence);