diff options
Diffstat (limited to 'src/lib/krb5/asn.1/krb5_decode.c')
-rw-r--r-- | src/lib/krb5/asn.1/krb5_decode.c | 336 |
1 files changed, 170 insertions, 166 deletions
diff --git a/src/lib/krb5/asn.1/krb5_decode.c b/src/lib/krb5/asn.1/krb5_decode.c index 0daa32e..e255551 100644 --- a/src/lib/krb5/asn.1/krb5_decode.c +++ b/src/lib/krb5/asn.1/krb5_decode.c @@ -1,4 +1,4 @@ -/* -*- mode: c; indent-tabs-mode: nil -*- */ +/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * src/lib/krb5/asn.1/krb5_decode.c * @@ -33,77 +33,79 @@ /* setup *********************************************************/ /* set up variables */ -/* the setup* macros can return, but are always used at function start - and thus need no malloc cleanup */ -#define setup_buf_only(type)\ -asn1_error_code retval;\ -asn1buf buf;\ -type rep = NULL;\ -\ -*repptr = NULL;\ -retval = asn1buf_wrap_data(&buf,code);\ -if (retval) return retval - -#define setup_no_tagnum(type)\ -asn1_class asn1class;\ -asn1_construction construction;\ -setup_buf_only(type) - -#define setup_no_length(type)\ -asn1_tagnum tagnum;\ -setup_no_tagnum(type) - -#define setup(type)\ -unsigned int length;\ -setup_no_length(type) +/* + * the setup* macros can return, but are always used at function start + * and thus need no malloc cleanup + */ +#define setup_buf_only(type) \ + asn1_error_code retval; \ + asn1buf buf; \ + type rep = NULL; \ + \ + *repptr = NULL; \ + retval = asn1buf_wrap_data(&buf,code); \ + if (retval) return retval + +#define setup_no_tagnum(type) \ + asn1_class asn1class; \ + asn1_construction construction; \ + setup_buf_only(type) + +#define setup_no_length(type) \ + asn1_tagnum tagnum; \ + setup_no_tagnum(type) + +#define setup(type) \ + unsigned int length; \ + setup_no_length(type) /* helper macros for cleanup */ #define clean_return(val) { retval = val; goto error_out; } /* alloc_field is the first thing to allocate storage that may need cleanup */ -#define alloc_field(var)\ -var = calloc(1,sizeof(*var));\ -if ((var) == NULL) clean_return(ENOMEM) +#define alloc_field(var) \ + var = calloc(1,sizeof(*var)); \ + if ((var) == NULL) clean_return(ENOMEM) /* * Allocate a principal and initialize enough fields for * krb5_free_principal to have defined behavior. */ #define alloc_principal(var) \ - alloc_field(var); \ - var->realm.data = NULL; \ - var->data = NULL + alloc_field(var); \ + var->realm.data = NULL; \ + var->data = NULL /* process encoding header ***************************************/ /* decode tag and check that it == [APPLICATION tagnum] */ #define check_apptag(tagexpect) \ -{ \ - taginfo t1; \ - retval = asn1_get_tag_2(&buf, &t1); \ - if (retval) clean_return (retval); \ - if (t1.asn1class != APPLICATION || t1.construction != CONSTRUCTED) \ - clean_return(ASN1_BAD_ID); \ - if (t1.tagnum != (tagexpect)) clean_return(KRB5_BADMSGTYPE); \ - asn1class = t1.asn1class; \ - construction = t1.construction; \ - tagnum = t1.tagnum; \ -} + { \ + taginfo t1; \ + retval = asn1_get_tag_2(&buf, &t1); \ + if (retval) clean_return (retval); \ + if (t1.asn1class != APPLICATION || t1.construction != CONSTRUCTED) \ + clean_return(ASN1_BAD_ID); \ + if (t1.tagnum != (tagexpect)) clean_return(KRB5_BADMSGTYPE); \ + asn1class = t1.asn1class; \ + construction = t1.construction; \ + tagnum = t1.tagnum; \ + } /* process a structure *******************************************/ /* decode an explicit tag and place the number in tagnum */ -#define next_tag_from_buf(buf) \ -{ taginfo t2; \ - retval = asn1_get_tag_2(&(buf), &t2); \ - if (retval) clean_return(retval); \ - asn1class = t2.asn1class; \ - construction = t2.construction; \ - tagnum = t2.tagnum; \ - indef = t2.indef; \ - taglen = t2.length; \ -} +#define next_tag_from_buf(buf) \ + { taginfo t2; \ + retval = asn1_get_tag_2(&(buf), &t2); \ + if (retval) clean_return(retval); \ + asn1class = t2.asn1class; \ + construction = t2.construction; \ + tagnum = t2.tagnum; \ + indef = t2.indef; \ + taglen = t2.length; \ + } #define next_tag() next_tag_from_buf(subbuf) @@ -121,35 +123,36 @@ asn1_get_eoc_tag (asn1buf *buf) return 0; } -#define get_eoc() \ -{ \ - retval = asn1_get_eoc_tag(&subbuf); \ - if (retval) clean_return(retval); \ -} +#define get_eoc() \ + { \ + retval = asn1_get_eoc_tag(&subbuf); \ + if (retval) clean_return(retval); \ + } /* decode sequence header and initialize tagnum with the first field */ -#define begin_structure()\ -unsigned int taglen;\ -asn1buf subbuf;\ -int seqindef;\ -int indef;\ -retval = asn1_get_sequence(&buf,&length,&seqindef);\ -if (retval) clean_return(retval);\ -retval = asn1buf_imbed(&subbuf,&buf,length,seqindef);\ -if (retval) clean_return(retval);\ -next_tag() - -#define end_structure()\ -retval = asn1buf_sync(&buf,&subbuf,asn1class,tagnum,length,indef,seqindef);\ -if (retval) clean_return(retval) +#define begin_structure() \ + unsigned int taglen; \ + asn1buf subbuf; \ + int seqindef; \ + int indef; \ + retval = asn1_get_sequence(&buf,&length,&seqindef); \ + if (retval) clean_return(retval); \ + retval = asn1buf_imbed(&subbuf,&buf,length,seqindef); \ + if (retval) clean_return(retval); \ + next_tag() + +#define end_structure() \ + retval = asn1buf_sync(&buf,&subbuf,asn1class, \ + tagnum,length,indef,seqindef); \ + if (retval) clean_return(retval) /* process fields *******************************************/ /* normal fields ************************/ -#define get_field_body(var,decoder)\ -retval = decoder(&subbuf,&(var));\ -if (retval) clean_return(retval);\ -if (indef) { get_eoc(); }\ -next_tag() +#define get_field_body(var,decoder) \ + retval = decoder(&subbuf,&(var)); \ + if (retval) clean_return(retval); \ + if (indef) { get_eoc(); } \ + next_tag() /* * error_if_bad_tag @@ -157,74 +160,76 @@ next_tag() * Checks that the next tag is the expected one; returns with an error * if not. */ -#define error_if_bad_tag(tagexpect) \ - if (tagnum != (tagexpect)) { clean_return ((tagnum < (tagexpect)) ? ASN1_MISPLACED_FIELD : ASN1_MISSING_FIELD); } - -/* decode a field (<[UNIVERSAL id]> <length> <contents>) - check that the id number == tagexpect then - decode into var - get the next tag */ -#define get_field(var,tagexpect,decoder)\ -error_if_bad_tag(tagexpect);\ -if (asn1class != CONTEXT_SPECIFIC || construction != CONSTRUCTED)\ - clean_return(ASN1_BAD_ID);\ -get_field_body(var,decoder) +#define error_if_bad_tag(tagexpect) \ + if (tagnum != (tagexpect)) { clean_return ((tagnum < (tagexpect)) ? ASN1_MISPLACED_FIELD : ASN1_MISSING_FIELD); } + +/* + * decode a field (<[UNIVERSAL id]> <length> <contents>) + * check that the id number == tagexpect then + * decode into var + * get the next tag + */ +#define get_field(var,tagexpect,decoder) \ + error_if_bad_tag(tagexpect); \ + if (asn1class != CONTEXT_SPECIFIC || construction != CONSTRUCTED) \ + clean_return(ASN1_BAD_ID); \ + get_field_body(var,decoder) /* decode (or skip, if not present) an optional field */ #define opt_field(var,tagexpect,decoder) \ - if (asn1buf_remains(&subbuf, seqindef)) { \ - if (asn1class != CONTEXT_SPECIFIC || construction != CONSTRUCTED) \ - clean_return(ASN1_BAD_ID); \ - if (tagnum == (tagexpect)) { \ - get_field_body(var,decoder); \ - } \ - } + if (asn1buf_remains(&subbuf, seqindef)) { \ + if (asn1class != CONTEXT_SPECIFIC || construction != CONSTRUCTED) \ + clean_return(ASN1_BAD_ID); \ + if (tagnum == (tagexpect)) { \ + get_field_body(var,decoder); \ + } \ + } /* field w/ accompanying length *********/ -#define get_lenfield_body(len,var,decoder)\ -retval = decoder(&subbuf,&(len),&(var));\ -if (retval) clean_return(retval);\ -if (indef) { get_eoc(); }\ -next_tag() +#define get_lenfield_body(len,var,decoder) \ + retval = decoder(&subbuf,&(len),&(var)); \ + if (retval) clean_return(retval); \ + if (indef) { get_eoc(); } \ + next_tag() /* decode a field w/ its length (for string types) */ -#define get_lenfield(len,var,tagexpect,decoder)\ -error_if_bad_tag(tagexpect);\ -if (asn1class != CONTEXT_SPECIFIC || construction != CONSTRUCTED)\ - clean_return(ASN1_BAD_ID);\ -get_lenfield_body(len,var,decoder) +#define get_lenfield(len,var,tagexpect,decoder) \ + error_if_bad_tag(tagexpect); \ + if (asn1class != CONTEXT_SPECIFIC || construction != CONSTRUCTED) \ + clean_return(ASN1_BAD_ID); \ + get_lenfield_body(len,var,decoder) /* decode an optional field w/ length */ #define opt_lenfield(len,var,tagexpect,decoder) \ - if (asn1buf_remains(&subbuf, seqindef)) { \ - if (asn1class != CONTEXT_SPECIFIC || construction != CONSTRUCTED) \ - clean_return(ASN1_BAD_ID); \ - if (tagnum == (tagexpect)) { \ - get_lenfield_body(len,var,decoder); \ - } \ - } + if (asn1buf_remains(&subbuf, seqindef)) { \ + if (asn1class != CONTEXT_SPECIFIC || construction != CONSTRUCTED) \ + clean_return(ASN1_BAD_ID); \ + if (tagnum == (tagexpect)) { \ + get_lenfield_body(len,var,decoder); \ + } \ + } /* clean up ******************************************************/ /* finish up */ /* to make things less painful, assume the cleanup is passed rep */ -#define cleanup(cleanup_routine)\ - *repptr = rep; \ - return 0; \ -error_out: \ - if (rep) \ - cleanup_routine(rep); \ - return retval; - -#define cleanup_none()\ - *repptr = rep; \ - return 0; \ -error_out: \ - return retval; - -#define cleanup_manual()\ - *repptr = rep; \ - return 0; +#define cleanup(cleanup_routine) \ + *repptr = rep; \ + return 0; \ +error_out: \ +if (rep) \ + cleanup_routine(rep); \ +return retval; + +#define cleanup_none() \ + *repptr = rep; \ + return 0; \ +error_out: \ +return retval; + +#define cleanup_manual() \ + *repptr = rep; \ + return 0; #define free_field(rep,f) free((rep)->f) #define clear_field(rep,f) (rep)->f = 0 @@ -264,8 +269,7 @@ error_out: } #endif -krb5_error_code -KRB5_CALLCONV +krb5_error_code KRB5_CALLCONV krb5_decode_ticket(const krb5_data *code, krb5_ticket **repptr) { return decode_krb5_ticket(code, repptr); @@ -1099,23 +1103,23 @@ decode_krb5_etype_list(const krb5_data *code, krb5_etype_list **repptr) krb5_error_code decode_krb5_pa_fx_fast_request (const krb5_data *code, krb5_fast_armored_req **repptr) { - setup(krb5_fast_armored_req *); - alloc_field(rep); - clear_field(rep, armor); - { - int indef; - unsigned int taglen; - next_tag_from_buf(buf); - if (tagnum != 0) - clean_return(ASN1_BAD_ID); - } - {begin_structure(); - opt_field(rep->armor, 0, asn1_decode_fast_armor_ptr); - get_field(rep->req_checksum, 1, asn1_decode_checksum); - get_field(rep->enc_part, 2, asn1_decode_encrypted_data); - end_structure();} - rep->magic = KV5M_FAST_ARMORED_REQ; - cleanup(free); + setup(krb5_fast_armored_req *); + alloc_field(rep); + clear_field(rep, armor); + { + int indef; + unsigned int taglen; + next_tag_from_buf(buf); + if (tagnum != 0) + clean_return(ASN1_BAD_ID); + } + {begin_structure(); + opt_field(rep->armor, 0, asn1_decode_fast_armor_ptr); + get_field(rep->req_checksum, 1, asn1_decode_checksum); + get_field(rep->enc_part, 2, asn1_decode_encrypted_data); + end_structure();} + rep->magic = KV5M_FAST_ARMORED_REQ; + cleanup(free); } krb5_error_code decode_krb5_fast_req @@ -1126,13 +1130,13 @@ krb5_error_code decode_krb5_fast_req alloc_field(rep->req_body); clear_field(rep, req_body->padata); {begin_structure(); - get_field(rep->fast_options, 0, asn1_decode_krb5_flags); - opt_field(rep->req_body->padata, 1, asn1_decode_sequence_of_pa_data); - get_field(*(rep->req_body), 2, asn1_decode_kdc_req_body); - end_structure(); } + get_field(rep->fast_options, 0, asn1_decode_krb5_flags); + opt_field(rep->req_body->padata, 1, asn1_decode_sequence_of_pa_data); + get_field(*(rep->req_body), 2, asn1_decode_kdc_req_body); + end_structure(); } rep->magic = KV5M_FAST_REQ; cleanup_manual(); - error_out: +error_out: if (rep) { if (rep->req_body) krb5_free_kdc_req(0, rep->req_body); @@ -1151,10 +1155,10 @@ krb5_error_code decode_krb5_fast_response clear_field(rep, padata); clear_field(rep,strengthen_key); {begin_structure(); - get_field(rep->padata, 0, asn1_decode_sequence_of_pa_data); - opt_field(rep->strengthen_key, 1, asn1_decode_encryption_key_ptr); - opt_field(rep->finished, 2, asn1_decode_fast_finished_ptr); - get_field(rep->nonce, 3, asn1_decode_int32); + get_field(rep->padata, 0, asn1_decode_sequence_of_pa_data); + opt_field(rep->strengthen_key, 1, asn1_decode_encryption_key_ptr); + opt_field(rep->finished, 2, asn1_decode_fast_finished_ptr); + get_field(rep->nonce, 3, asn1_decode_int32); end_structure(); } rep->magic = KV5M_FAST_RESPONSE; cleanup(free); @@ -1173,15 +1177,15 @@ krb5_error_code decode_krb5_pa_fx_fast_reply clean_return(ASN1_BAD_ID); } {begin_structure(); - get_field(*rep, 0, asn1_decode_encrypted_data); - end_structure(); + get_field(*rep, 0, asn1_decode_encrypted_data); + end_structure(); } cleanup(free); } -krb5_error_code decode_krb5_ad_kdcissued -(const krb5_data *code, krb5_ad_kdcissued **repptr) +krb5_error_code +decode_krb5_ad_kdcissued(const krb5_data *code, krb5_ad_kdcissued **repptr) { setup_buf_only(krb5_ad_kdcissued *); alloc_field(rep); @@ -1192,8 +1196,8 @@ krb5_error_code decode_krb5_ad_kdcissued cleanup(free); } -krb5_error_code decode_krb5_ad_signedpath -(const krb5_data *code, krb5_ad_signedpath **repptr) +krb5_error_code +decode_krb5_ad_signedpath(const krb5_data *code, krb5_ad_signedpath **repptr) { setup_buf_only(krb5_ad_signedpath *); alloc_field(rep); @@ -1218,12 +1222,12 @@ krb5int_get_authdata_containee_types(krb5_context context, *num = 0; { - setup_buf_only(krb5_authdatatype *); + setup_buf_only(krb5_authdatatype *); - retval = asn1_peek_authorization_data(&buf, num, &rep); - if (retval) clean_return(retval); + retval = asn1_peek_authorization_data(&buf, num, &rep); + if (retval) clean_return(retval); - cleanup_none(); + cleanup_none(); } assert(0); /* NOTREACHED */ } |