diff options
author | Tom Yu <tlyu@mit.edu> | 2000-10-26 22:58:13 +0000 |
---|---|---|
committer | Tom Yu <tlyu@mit.edu> | 2000-10-26 22:58:13 +0000 |
commit | b5e198d5a487d71d92acf3cd2475071fd559554e (patch) | |
tree | a166086adb28a8b2235c0ae8471ed5aa29b03831 /src/lib/krb5/asn.1/asn1_k_decode.c | |
parent | f6ee7cc309306bef489b75f3c70e239b78ddeecc (diff) | |
download | krb5-b5e198d5a487d71d92acf3cd2475071fd559554e.zip krb5-b5e198d5a487d71d92acf3cd2475071fd559554e.tar.gz krb5-b5e198d5a487d71d92acf3cd2475071fd559554e.tar.bz2 |
* asn1buf.c (asn1buf_sync): Add new arguments to include the full
complement of data about a prefetched tag, as well as to indicate
whether the prefetched tag or the surrounding sequence is of an
indefinite length.
(asn1buf_skiptail): Add new arguments to indicate whether the
prefetched tag is indefinite, as well as its length. This
facilitates proper skipping of trailing garbage.
(asn1buf_remains): Add new argument to indicate whether the
surrounding encoding is indefinite. Don't advance buf->next if an
EOC encoding is detected; the caller will do that.
* asn1buf.h: Update prototypes.
* asn1_get.c (asn1_get_tag_indef): Don't treat EOC encoding as
special anymore, since previous behavior was overloading the
tag number in a bad way. Also, report a MISMATCH_INDEF error if
the tag encoding is for the forbidden primitive constructed
encoding.
* asn1_k_decode.c (next_tag): Call get_tag_indef() in order to get
information about whether the length is indefinite. Don't check
the tag class and construction explicitly.
(get_eoc): New macro to get a tag and check if it is an EOC
encoding.
(get_field, opt_field): Move the check for the tag class and
construction to here.
(get_field_body, get_lenfield_body): Call get_eoc() instead of
next_tag() if we are decoding a constructed indefinite encoding.
(begin_structure): Use a different variable to indicate whether
the sequence is indefinite as opposed to whether an individual
field is indefinite.
(end_structure): Update to new calling convention of
asn1buf_sync().
(sequence_of): Rewrite significantly.
(sequence_of_common): Move the bulk of previous sequence_of()
macro to here. Does not declare some variables that sequence_of()
declares.
(sequence_of_no_tagvars): Similar to sequence_of() macro but
declares different variables for the purpose of prefetching the
final tag.
(end_sequence_of_no_tagvars): Similar to end_sequence_of() macro
but uses variables declared by the sequence_of_no_tagvars() macro
to prefetch the final tag.
(asn1_decode_principal_name): Update for new asn1buf_remains()
calling convention. Call sequence_of_no_tagvars(), etc. instead
of sequence_of(), etc. in order to not declare shadowing
block-local variables.
(decode_array_body): Update for new asn1buf_remains() calling
convention.
(asn1_decode_sequence_of_enctype): Update for new
asn1buf_remains() calling convention.
* krb5_decode.c (next_tag): Call get_tag_indef() in order to get
information about whether the length is indefinite. Don't check
the tag class and construction explicitly.
(get_eoc): New macro to get a tag and check if it is an EOC
encoding.
(get_field, opt_field): Move the check for the tag class and
construction to here.
(get_field_body, get_lenfield_body): Call get_eoc() instead of
next_tag() if we are decoding a constructed indefinite encoding.
(begin_structure): Use a different variable to indicate whether
the sequence is indefinite as opposed to whether an individual
field is indefinite.
(end_structure): Update to new calling convention of
asn1buf_sync().
git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@12816 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src/lib/krb5/asn.1/asn1_k_decode.c')
-rw-r--r-- | src/lib/krb5/asn.1/asn1_k_decode.c | 97 |
1 files changed, 72 insertions, 25 deletions
diff --git a/src/lib/krb5/asn.1/asn1_k_decode.c b/src/lib/krb5/asn.1/asn1_k_decode.c index b015063..845f92b 100644 --- a/src/lib/krb5/asn.1/asn1_k_decode.c +++ b/src/lib/krb5/asn.1/asn1_k_decode.c @@ -39,10 +39,16 @@ unsigned int length,taglen #define unused_var(x) if(0) x=0 #define next_tag()\ -retval = asn1_get_tag(&subbuf,&class,&construction,&tagnum,&taglen);\ -if(retval) return retval;\ -if(class != CONTEXT_SPECIFIC || construction != CONSTRUCTED)\ - return ASN1_BAD_ID +retval = asn1_get_tag_indef(&subbuf,&class,&construction,\ + &tagnum,&taglen,&indef);\ +if(retval) return retval; + +#define get_eoc() \ +retval = asn1_get_tag_indef(&subbuf,&class,&construction, \ + &tagnum,&taglen,&indef); \ +if(retval) return retval; \ +if(class != UNIVERSAL || tagnum || indef) \ + return ASN1_MISSING_EOC #define alloc_field(var,type)\ var = (type*)calloc(1,sizeof(type));\ @@ -59,15 +65,21 @@ if(class != APPLICATION || construction != CONSTRUCTED ||\ #define get_field_body(var,decoder)\ retval = decoder(&subbuf,&(var));\ if(retval) return retval;\ -if(!taglen) { next_tag(); }\ +if(!taglen && indef) { get_eoc(); }\ next_tag() #define get_field(var,tagexpect,decoder)\ if(tagnum > (tagexpect)) return ASN1_MISSING_FIELD;\ if(tagnum < (tagexpect)) return ASN1_MISPLACED_FIELD;\ +if((class != CONTEXT_SPECIFIC || construction != CONSTRUCTED) \ + && (tagnum || taglen || class != UNIVERSAL)) \ + return ASN1_BAD_ID;\ get_field_body(var,decoder) #define opt_field(var,tagexpect,decoder,optvalue)\ +if((class != CONTEXT_SPECIFIC || construction != CONSTRUCTED) \ + && (tagnum || taglen || class != UNIVERSAL)) \ + return ASN1_BAD_ID;\ if(tagnum == (tagexpect)){\ get_field_body(var,decoder); }\ else var = optvalue @@ -76,12 +88,15 @@ else var = optvalue #define get_lenfield_body(len,var,decoder)\ retval = decoder(&subbuf,&(len),&(var));\ if(retval) return retval;\ -if(!taglen) { next_tag(); }\ +if(!taglen && indef) { get_eoc(); }\ next_tag() #define get_lenfield(len,var,tagexpect,decoder)\ if(tagnum > (tagexpect)) return ASN1_MISSING_FIELD;\ if(tagnum < (tagexpect)) return ASN1_MISPLACED_FIELD;\ +if((class != CONTEXT_SPECIFIC || construction != CONSTRUCTED) \ + && (tagnum || taglen || class != UNIVERSAL)) \ + return ASN1_BAD_ID;\ get_lenfield_body(len,var,decoder) #define opt_lenfield(len,var,tagexpect,decoder)\ @@ -92,30 +107,58 @@ else { len = 0; var = 0; } #define begin_structure()\ asn1buf subbuf;\ +int seqindef;\ int indef;\ -retval = asn1_get_sequence(buf,&length,&indef);\ +retval = asn1_get_sequence(buf,&length,&seqindef);\ if(retval) return retval;\ -retval = asn1buf_imbed(&subbuf,buf,length,indef);\ +retval = asn1buf_imbed(&subbuf,buf,length,seqindef);\ if(retval) return retval;\ next_tag() #define end_structure()\ -retval = asn1buf_sync(buf,&subbuf,tagnum,length);\ +retval = asn1buf_sync(buf,&subbuf,class,tagnum,length,indef,seqindef);\ if(retval) return retval -#define sequence_of(buf)\ -int size=0;\ -asn1buf seqbuf;\ -unsigned int length;\ -int indef;\ -retval = asn1_get_sequence(buf,&length,&indef);\ -if(retval) return retval;\ -retval = asn1buf_imbed(&seqbuf,buf,length,indef);\ +#define sequence_of(buf) \ +unsigned int length, taglen; \ +asn1_class class; \ +asn1_construction construction; \ +asn1_tagnum tagnum; \ +int indef; \ +sequence_of_common(buf) + +#define sequence_of_common(buf) \ +int size=0; \ +asn1buf seqbuf; \ +int seqofindef; \ +retval = asn1_get_sequence(buf,&length,&seqofindef); \ +if(retval) return retval; \ +retval = asn1buf_imbed(&seqbuf,buf,length,seqofindef); \ if(retval) return retval -#define end_sequence_of(buf)\ -retval = asn1buf_sync(buf,&seqbuf,ASN1_TAGNUM_CEILING,length);\ -if(retval) return retval +#define sequence_of_no_tagvars(buf) \ +asn1_class eseqclass; \ +asn1_construction eseqconstr; \ +asn1_tagnum eseqnum; \ +unsigned int eseqlen; \ +int eseqindef; \ +sequence_of_common(buf) + +#define end_sequence_of_no_tagvars(buf) \ +retval = asn1_get_tag_indef(&seqbuf,&eseqclass,&eseqconstr, \ + &eseqnum,&eseqlen,&eseqindef); \ +if(retval) return retval; \ +retval = asn1buf_sync(buf,&seqbuf,eseqclass,eseqnum, \ + eseqlen,eseqindef,seqofindef); \ +if(retval) return retval; + +#define end_sequence_of(buf) \ +retval = asn1_get_tag_indef(&seqbuf,&class,&construction, \ + &tagnum,&taglen,&indef); \ +if(retval) return retval; \ +retval = asn1buf_sync(buf,&seqbuf,class,tagnum, \ + length,indef,seqofindef); \ +if(retval) return retval; #define cleanup()\ return 0 @@ -206,8 +249,8 @@ asn1_error_code asn1_decode_principal_name(buf, val) { begin_structure(); get_field((*val)->type,0,asn1_decode_int32); - { sequence_of(&subbuf); - while(asn1buf_remains(&seqbuf)){ + { sequence_of_no_tagvars(&subbuf); + while(asn1buf_remains(&seqbuf,seqofindef) > 0){ size++; if ((*val)->data == NULL) (*val)->data = (krb5_data*)malloc(size*sizeof(krb5_data)); @@ -221,8 +264,12 @@ asn1_error_code asn1_decode_principal_name(buf, val) if(retval) return retval; } (*val)->length = size; - end_sequence_of(&subbuf); + end_sequence_of_no_tagvars(&subbuf); + } + if (indef) { + get_eoc(); } + next_tag(); end_structure(); (*val)->magic = KV5M_PRINCIPAL; } @@ -528,7 +575,7 @@ if(*(array) == NULL) return ENOMEM;\ type *elt;\ \ { sequence_of(buf);\ - while(asn1buf_remains(&seqbuf) > 0){\ + while(asn1buf_remains(&seqbuf,seqofindef) > 0){\ alloc_field(elt,type);\ get_element(elt,decoder);\ array_append(val,size,elt,type);\ @@ -665,7 +712,7 @@ asn1_error_code asn1_decode_sequence_of_enctype(buf, num, val) { asn1_error_code retval; { sequence_of(buf); - while(asn1buf_remains(&seqbuf) > 0){ + while(asn1buf_remains(&seqbuf,seqofindef) > 0){ size++; if (*val == NULL) *val = (krb5_enctype*)malloc(size*sizeof(krb5_enctype)); |