diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/krb5/asn.1/ChangeLog | 25 | ||||
-rw-r--r-- | src/lib/krb5/asn.1/asn1_decode.c | 12 | ||||
-rw-r--r-- | src/lib/krb5/asn.1/asn1_get.c | 183 | ||||
-rw-r--r-- | src/lib/krb5/asn.1/asn1_get.h | 36 | ||||
-rw-r--r-- | src/lib/krb5/asn.1/asn1_k_decode.c | 115 | ||||
-rw-r--r-- | src/lib/krb5/asn.1/asn1buf.c | 19 | ||||
-rw-r--r-- | src/lib/krb5/asn.1/krb5_decode.c | 59 |
7 files changed, 246 insertions, 203 deletions
diff --git a/src/lib/krb5/asn.1/ChangeLog b/src/lib/krb5/asn.1/ChangeLog index 5052405..b1ff161 100644 --- a/src/lib/krb5/asn.1/ChangeLog +++ b/src/lib/krb5/asn.1/ChangeLog @@ -1,3 +1,28 @@ +2003-03-11 Ken Raeburn <raeburn@mit.edu> + + * asn1_get.c (asn1_get_tag): Deleted. + (asn1_get_tag_2): Renamed from asn1_get_tag_indef, now uses a + pointer to taginfo rather than a bunch of pointer args. + (asn1_get_id, asn1_get_length): Folded into asn1_get_tag_2. + (asn1_get_sequence): Call asn1_get_tag_2. + * asn1_get.h (taginfo): New structure. + (asn1_get_tag_indef, asn1_get_tag, asn1_get_id, asn1_get_length): + Declarations deleted. + (asn1_get_tag_2): Declare. + * asn1_decode.c (setup): Declare only a taginfo variable. + (asn1class, construction, tagnum, length): New macros. + (tag): Call asn1_get_tag_2. + * asn1_k_decode.c (next_tag, get_eoc, apptag, end_sequence_of, + end_sequence_of_no_tagvars, asn1_decode_krb5_flags): Call + asn1_get_tag_2; if no error, copy out values into scalar + variables. + (asn1_decode_ticket): Call asn1_get_tag_2. + * asn1buf.c (asn1buf_skiptail): Call asn1_get_tag_2. + * krb5_decode.c (check_apptag, next_tag, get_eoc): Call + asn1_get_tag_2; if no error, copy out values into scalar + variables. + (decode_krb5_enc_kdc_rep_part): Call asn1_get_tag_2. + 2003-01-10 Ken Raeburn <raeburn@mit.edu> * Makefile.in: Add AC_SUBST_FILE marker for libobj_frag. diff --git a/src/lib/krb5/asn.1/asn1_decode.c b/src/lib/krb5/asn.1/asn1_decode.c index f817083..56904c5 100644 --- a/src/lib/krb5/asn.1/asn1_decode.c +++ b/src/lib/krb5/asn.1/asn1_decode.c @@ -39,13 +39,15 @@ #define setup()\ asn1_error_code retval;\ -asn1_class asn1class;\ -asn1_construction construction;\ -asn1_tagnum tagnum;\ -unsigned int length +taginfo tinfo + +#define asn1class (tinfo.asn1class) +#define construction (tinfo.construction) +#define tagnum (tinfo.tagnum) +#define length (tinfo.length) #define tag(type)\ -retval = asn1_get_tag(buf,&asn1class,&construction,&tagnum,&length);\ +retval = asn1_get_tag_2(buf,&tinfo);\ if(retval) return retval;\ if(asn1class != UNIVERSAL || construction != PRIMITIVE || tagnum != type)\ return ASN1_BAD_ID diff --git a/src/lib/krb5/asn.1/asn1_get.c b/src/lib/krb5/asn.1/asn1_get.c index e90ac6b..d5a7ca4 100644 --- a/src/lib/krb5/asn.1/asn1_get.c +++ b/src/lib/krb5/asn.1/asn1_get.c @@ -27,123 +27,92 @@ #include "asn1_get.h" asn1_error_code -asn1_get_tag_indef(asn1buf *buf, asn1_class *asn1class, - asn1_construction *construction, asn1_tagnum *tagnum, - unsigned int *retlen, int *indef) +asn1_get_tag_2(asn1buf *buf, taginfo *t) { - asn1_error_code retval; - - if (buf == NULL || buf->base == NULL || - buf->bound - buf->next + 1 <= 0) { - *tagnum = ASN1_TAGNUM_CEILING; /* emphatically not an EOC tag */ - if (asn1class != NULL) - *asn1class = UNIVERSAL; - if (construction != NULL) - *construction = PRIMITIVE; - if (retlen != NULL) - *retlen = 0; - if (indef != NULL) - *indef = 0; - return 0; - } - retval = asn1_get_id(buf,asn1class,construction,tagnum); - if(retval) return retval; - retval = asn1_get_length(buf,retlen,indef); - if(retval) return retval; - if (indef != NULL && *indef && - construction != NULL && *construction != CONSTRUCTED) - return ASN1_MISMATCH_INDEF; - return 0; -} - -asn1_error_code -asn1_get_tag(asn1buf *buf, asn1_class *asn1class, - asn1_construction *construction, asn1_tagnum *tagnum, - unsigned int *retlen) -{ - int indef; - - return asn1_get_tag_indef(buf, asn1class, construction, tagnum, retlen, - &indef); -} - -asn1_error_code asn1_get_sequence(asn1buf *buf, unsigned int *retlen, int *indef) -{ - asn1_error_code retval; - asn1_class asn1class; - asn1_construction construction; - asn1_tagnum tagnum; - - retval = asn1_get_tag_indef(buf,&asn1class,&construction,&tagnum,retlen,indef); - if(retval) return retval; - if(retval) return (krb5_error_code)retval; - if(asn1class != UNIVERSAL || construction != CONSTRUCTED || - tagnum != ASN1_SEQUENCE) return ASN1_BAD_ID; - return 0; -} - -/****************************************************************/ -/* Private Procedures */ + asn1_error_code retval; -asn1_error_code asn1_get_id(asn1buf *buf, asn1_class *asn1class, - asn1_construction *construction, - asn1_tagnum *tagnum) -{ - asn1_error_code retval; - asn1_tagnum tn=0; - asn1_octet o; + if (buf == NULL || buf->base == NULL || + buf->bound - buf->next + 1 <= 0) { + t->tagnum = ASN1_TAGNUM_CEILING; /* emphatically not an EOC tag */ + t->asn1class = UNIVERSAL; + t->construction = PRIMITIVE; + t->length = 0; + t->indef = 0; + return 0; + } + { + /* asn1_get_id(buf, t) */ + asn1_tagnum tn=0; + asn1_octet o; #define ASN1_CLASS_MASK 0xC0 #define ASN1_CONSTRUCTION_MASK 0x20 #define ASN1_TAG_NUMBER_MASK 0x1F - retval = asn1buf_remove_octet(buf,&o); - if(retval) return retval; + retval = asn1buf_remove_octet(buf,&o); + if (retval) + return retval; - if(asn1class != NULL) - *asn1class = (asn1_class)(o&ASN1_CLASS_MASK); - if(construction != NULL) - *construction = (asn1_construction)(o&ASN1_CONSTRUCTION_MASK); - if((o&ASN1_TAG_NUMBER_MASK) != ASN1_TAG_NUMBER_MASK){ - /* low-tag-number form */ - if(tagnum != NULL) *tagnum = (asn1_tagnum)(o&ASN1_TAG_NUMBER_MASK); - }else{ - /* high-tag-number form */ - do{ - retval = asn1buf_remove_octet(buf,&o); - if(retval) return retval; - tn = (tn<<7) + (asn1_tagnum)(o&0x7F); - }while(tn&0x80); - if(tagnum != NULL) *tagnum = tn; - } - return 0; -} + t->asn1class = (asn1_class)(o&ASN1_CLASS_MASK); + t->construction = (asn1_construction)(o&ASN1_CONSTRUCTION_MASK); + if ((o&ASN1_TAG_NUMBER_MASK) != ASN1_TAG_NUMBER_MASK){ + /* low-tag-number form */ + t->tagnum = (asn1_tagnum)(o&ASN1_TAG_NUMBER_MASK); + } else { + /* high-tag-number form */ + do { + retval = asn1buf_remove_octet(buf,&o); + if (retval) return retval; + tn = (tn<<7) + (asn1_tagnum)(o&0x7F); + }while(tn&0x80); + t->tagnum = tn; + } + } -asn1_error_code asn1_get_length(asn1buf *buf, unsigned int *retlen, int *indef) -{ - asn1_error_code retval; - asn1_octet o; + { + /* asn1_get_length(buf, t) */ + asn1_octet o; - if (indef != NULL) - *indef = 0; - retval = asn1buf_remove_octet(buf,&o); - if(retval) return retval; - if((o&0x80) == 0){ - if(retlen != NULL) *retlen = (int)(o&0x7F); - }else{ - int num; - int len=0; + t->indef = 0; + retval = asn1buf_remove_octet(buf,&o); + if (retval) return retval; + if ((o&0x80) == 0) { + t->length = (int)(o&0x7F); + } else { + int num; + int len=0; - for(num = (int)(o&0x7F); num>0; num--){ - retval = asn1buf_remove_octet(buf,&o); - if(retval) return retval; - len = (len<<8) + (int)o; + for (num = (int)(o&0x7F); num>0; num--) { + retval = asn1buf_remove_octet(buf,&o); + if(retval) return retval; + len = (len<<8) + (int)o; + } + if (len < 0) + return ASN1_OVERRUN; + if (!len) + t->indef = 1; + t->length = len; + } } - if (len < 0) - return ASN1_OVERRUN; - if (indef != NULL && !len) - *indef = 1; - if(retlen != NULL) *retlen = len; - } - return 0; + if (t->indef && t->construction != CONSTRUCTED) + return ASN1_MISMATCH_INDEF; + return 0; +} + +asn1_error_code asn1_get_sequence(asn1buf *buf, unsigned int *retlen, int *indef) +{ + taginfo t; + asn1_error_code retval; + + retval = asn1_get_tag_2(buf, &t); + if (retval) + return retval; + if (t.asn1class != UNIVERSAL || t.construction != CONSTRUCTED || + t.tagnum != ASN1_SEQUENCE) + return ASN1_BAD_ID; + if (retlen) + *retlen = t.length; + if (indef) + *indef = t.indef; + return 0; } diff --git a/src/lib/krb5/asn.1/asn1_get.h b/src/lib/krb5/asn.1/asn1_get.h index 169490a..50a1b75 100644 --- a/src/lib/krb5/asn.1/asn1_get.h +++ b/src/lib/krb5/asn.1/asn1_get.h @@ -33,12 +33,24 @@ #include "krbasn1.h" #include "asn1buf.h" +typedef struct { + asn1_class asn1class; + asn1_construction construction; + asn1_tagnum tagnum; + unsigned int length; + int indef; +} taginfo; + +asn1_error_code asn1_get_tag_2 (asn1buf *buf, taginfo *tinfo); + +#if 0 asn1_error_code asn1_get_tag_indef (asn1buf *buf, asn1_class *Class, asn1_construction *construction, asn1_tagnum *tagnum, unsigned int *retlen, int *indef); + asn1_error_code asn1_get_tag (asn1buf *buf, asn1_class *Class, @@ -53,6 +65,7 @@ asn1_error_code asn1_get_tag If *buf is empty to begin with, *tagnum is set to ASN1_TAGNUM_CEILING. Returns ASN1_OVERRUN if *buf is exhausted during the parse. */ +#endif asn1_error_code asn1_get_sequence (asn1buf *buf, unsigned int *retlen, int *indef); @@ -61,27 +74,4 @@ asn1_error_code asn1_get_sequence doesn't have a sequence ID. If retlen != NULL, the associated length is returned in *retlen. */ -/****************************************************************/ -/* Private Procedures */ - -asn1_error_code asn1_get_id - (asn1buf *buf, - asn1_class *Class, - asn1_construction *construction, - asn1_tagnum *tagnum); -/* requires *buf is allocated - effects Decodes the group of identifier octets at *buf's - current position. If class != NULL, returns the class - in *Class. Similarly, the construction and tag number - are returned in *construction and *tagnum, respectively. - Returns ASN1_OVERRUN if *buf is exhausted. */ - -asn1_error_code asn1_get_length - (asn1buf *buf, unsigned int *retlen, int *indef); -/* requires *buf is allocated - effects Decodes the group of length octets at *buf's - current position. If retlen != NULL, the - length is returned in *retlen. - Returns ASN1_OVERRUN if *buf is exhausted. */ - #endif diff --git a/src/lib/krb5/asn.1/asn1_k_decode.c b/src/lib/krb5/asn.1/asn1_k_decode.c index 0917d71..c64ebb8 100644 --- a/src/lib/krb5/asn.1/asn1_k_decode.c +++ b/src/lib/krb5/asn.1/asn1_k_decode.c @@ -40,29 +40,52 @@ #define unused_var(x) if (0) { x = 0; x = x - x; } /* This is used for prefetch of next tag in sequence. */ -#define next_tag() \ - retval = asn1_get_tag_indef(&subbuf, &asn1class, &construction, \ - &tagnum, &taglen, &indef); \ - if (retval) return retval; +#define next_tag() \ +{ taginfo t2; \ + retval = asn1_get_tag_2(&subbuf, &t2); \ + if (retval) return retval; \ + /* Copy out to match previous functionality, until better integrated. */ \ + asn1class = t2.asn1class; \ + construction = t2.construction; \ + tagnum = t2.tagnum; \ + taglen = t2.length; \ + indef = t2.indef; \ +} /* Force check for EOC tag. */ -#define get_eoc() \ - retval = asn1_get_tag_indef(&subbuf, &asn1class, &construction, \ - &tagnum, &taglen, &indef); \ - if (retval) return retval; \ - if (asn1class != UNIVERSAL || tagnum || indef) \ - return ASN1_MISSING_EOC +#define get_eoc() \ + { \ + taginfo t3; \ + retval = asn1_get_tag_2(&subbuf, &t3); \ + if(retval) return retval; \ + if (t3.asn1class != UNIVERSAL || t3.tagnum || t3.indef) \ + return ASN1_MISSING_EOC; \ + /* Copy out to match previous functionality, until better integrated. */ \ + asn1class = t3.asn1class; \ + construction = t3.construction; \ + tagnum = t3.tagnum; \ + taglen = t3.length; \ + indef = t3.indef; \ + } #define alloc_field(var, type) \ var = (type*)calloc(1, sizeof(type)); \ if ((var) == NULL) return ENOMEM /* Fetch an expected APPLICATION class tag and verify. */ -#define apptag(tagexpect) \ - retval = asn1_get_tag(buf, &asn1class, &construction, &tagnum, &applen); \ - if (retval) return retval; \ - if (asn1class != APPLICATION || construction != CONSTRUCTED || \ - tagnum != (tagexpect)) return ASN1_BAD_ID +#define apptag(tagexpect) \ + { \ + taginfo t1; \ + retval = asn1_get_tag_2(buf, &t1); \ + if (retval) return retval; \ + if (t1.asn1class != APPLICATION || t1.construction != CONSTRUCTED || \ + t1.tagnum != (tagexpect)) return ASN1_BAD_ID; \ + /* Copy out to match previous functionality, until better integrated. */ \ + asn1class = t1.asn1class; \ + construction = t1.construction; \ + tagnum = t1.tagnum; \ + applen = t1.length; \ + } /**** normal fields ****/ @@ -211,12 +234,20 @@ * Attempts to fetch an EOC tag, if any, and to sync over trailing * garbage, if any. */ -#define end_sequence_of(buf) \ - retval = asn1_get_tag_indef(&seqbuf, &asn1class, &construction, \ - &tagnum, &taglen, &indef); \ - if (retval) return retval; \ - retval = asn1buf_sync(buf, &seqbuf, asn1class, tagnum, \ - length, indef, seqofindef); \ +#define end_sequence_of(buf) \ + { \ + taginfo t4; \ + retval = asn1_get_tag_2(&seqbuf, &t4); \ + if (retval) return retval; \ + /* Copy out to match previous functionality, until better integrated. */ \ + asn1class = t4.asn1class; \ + construction = t4.construction; \ + tagnum = t4.tagnum; \ + taglen = t4.length; \ + indef = t4.indef; \ + } \ + retval = asn1buf_sync(buf, &seqbuf, asn1class, tagnum, \ + length, indef, seqofindef); \ if (retval) return retval; /* @@ -225,12 +256,20 @@ * Like end_sequence_of(), but uses the different (non-shadowing) * variable names. */ -#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); \ +#define end_sequence_of_no_tagvars(buf) \ + { \ + taginfo t5; \ + retval = asn1_get_tag_2(&seqbuf, &t5); \ + if (retval) return retval; \ + /* Copy out to match previous functionality, until better integrated. */ \ + eseqclass = t5.asn1class; \ + eseqconstr = t5.construction; \ + eseqnum = t5.tagnum; \ + eseqlen = t5.length; \ + eseqindef = t5.indef; \ + } \ + retval = asn1buf_sync(buf, &seqbuf, eseqclass, eseqnum, \ + eseqlen, eseqindef, seqofindef); \ if (retval) return retval; #define cleanup() \ @@ -374,16 +413,19 @@ asn1_error_code asn1_decode_encrypted_data(asn1buf *buf, krb5_enc_data *val) asn1_error_code asn1_decode_krb5_flags(asn1buf *buf, krb5_flags *val) { - setup(); + asn1_error_code retval; asn1_octet unused, o; + taginfo t; int i; krb5_flags f=0; - unused_var(taglen); + unsigned int length; - retval = asn1_get_tag(buf,&asn1class,&construction,&tagnum,&length); - if(retval) return retval; - if(asn1class != UNIVERSAL || construction != PRIMITIVE || - tagnum != ASN1_BITSTRING) return ASN1_BAD_ID; + retval = asn1_get_tag_2(buf, &t); + if (retval) return retval; + if (t.asn1class != UNIVERSAL || t.construction != PRIMITIVE || + t.tagnum != ASN1_BITSTRING) + return ASN1_BAD_ID; + length = t.length; retval = asn1buf_remove_octet(buf,&unused); /* # of padding bits */ if(retval) return retval; @@ -472,9 +514,10 @@ asn1_error_code asn1_decode_ticket(asn1buf *buf, krb5_ticket *val) end_structure(); val->magic = KV5M_TICKET; } - if(!applen) { - retval = asn1_get_tag(buf,&asn1class,&construction,&tagnum,NULL); - if (retval) return retval; + if (!applen) { + taginfo t; + retval = asn1_get_tag_2(buf, &t); + if (retval) return retval; } cleanup(); } diff --git a/src/lib/krb5/asn.1/asn1buf.c b/src/lib/krb5/asn.1/asn1buf.c index d28e310..47e1902 100644 --- a/src/lib/krb5/asn.1/asn1buf.c +++ b/src/lib/krb5/asn.1/asn1buf.c @@ -111,12 +111,8 @@ asn1_error_code asn1buf_sync(asn1buf *buf, asn1buf *subbuf, asn1_error_code asn1buf_skiptail(asn1buf *buf, const unsigned int length, const int indef) { asn1_error_code retval; - asn1_class asn1class; - asn1_construction construction; - asn1_tagnum tagnum; - unsigned int taglen; + taginfo t; int nestlevel; - int tagindef; nestlevel = 1 + indef; if (!indef) { @@ -126,18 +122,17 @@ asn1_error_code asn1buf_skiptail(asn1buf *buf, const unsigned int length, const return ASN1_OVERRUN; } while (nestlevel > 0) { - retval = asn1_get_tag_indef(buf, &asn1class, &construction, &tagnum, - &taglen, &tagindef); + retval = asn1_get_tag_2(buf, &t); if (retval) return retval; - if (!tagindef) { - if (taglen <= buf->bound - buf->next + 1) - buf->next += taglen; + if (!t.indef) { + if (t.length <= buf->bound - buf->next + 1) + buf->next += t.length; else return ASN1_OVERRUN; } - if (tagindef) + if (t.indef) nestlevel++; - if (asn1_is_eoc(asn1class, tagnum, tagindef)) + if (asn1_is_eoc(t.asn1class, t.tagnum, t.indef)) nestlevel--; /* got an EOC encoding */ } return 0; diff --git a/src/lib/krb5/asn.1/krb5_decode.c b/src/lib/krb5/asn.1/krb5_decode.c index f2d9165..03a3029 100644 --- a/src/lib/krb5/asn.1/krb5_decode.c +++ b/src/lib/krb5/asn.1/krb5_decode.c @@ -64,28 +64,46 @@ if((var) == NULL) clean_return(ENOMEM) /* process encoding header ***************************************/ /* decode tag and check that it == [APPLICATION tagnum] */ -#define check_apptag(tagexpect)\ -retval = asn1_get_tag(&buf,&asn1class,&construction,&tagnum,NULL);\ -if(retval) clean_return(retval);\ -if(asn1class != APPLICATION || construction != CONSTRUCTED) \ - clean_return(ASN1_BAD_ID);\ -if(tagnum != (tagexpect)) clean_return(KRB5_BADMSGTYPE) +#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; \ +} /* process a structure *******************************************/ /* decode an explicit tag and place the number in tagnum */ -#define next_tag()\ -retval = asn1_get_tag_indef(&subbuf,&asn1class,&construction,&tagnum,NULL,&indef);\ -if(retval) clean_return(retval) +#define next_tag() \ +{ taginfo t2; \ + retval = asn1_get_tag_2(&subbuf, &t2); \ + if(retval) clean_return(retval); \ + asn1class = t2.asn1class; \ + construction = t2.construction; \ + tagnum = t2.tagnum; \ + indef = t2.indef; \ +} #define get_eoc() \ -retval = asn1_get_tag_indef(&subbuf,&asn1class,&construction, \ - &tagnum,NULL,&indef); \ -if(retval) return retval; \ -if(asn1class != UNIVERSAL || tagnum || indef) \ - return ASN1_MISSING_EOC +{ \ + taginfo t3; \ + retval = asn1_get_tag_2(&subbuf, &t3); \ + if (retval) return retval; \ + if (t3.asn1class != UNIVERSAL || t3.tagnum || t3.indef) \ + return ASN1_MISSING_EOC; \ + asn1class = t3.asn1class; \ + construction = t3.construction; \ + tagnum = t3.tagnum; \ + indef = t3.indef; \ +} /* decode sequence header and initialize tagnum with the first field */ #define begin_structure()\ @@ -306,14 +324,15 @@ error_out: krb5_error_code decode_krb5_enc_kdc_rep_part(const krb5_data *code, krb5_enc_kdc_rep_part **rep) { - setup_no_length(); + taginfo t4; + setup_buf_only(); alloc_field(*rep,krb5_enc_kdc_rep_part); - retval = asn1_get_tag(&buf,&asn1class,&construction,&tagnum,NULL); - if(retval) clean_return(retval); - if(asn1class != APPLICATION || construction != CONSTRUCTED) clean_return(ASN1_BAD_ID); - if(tagnum == 25) (*rep)->msg_type = KRB5_AS_REP; - else if(tagnum == 26) (*rep)->msg_type = KRB5_TGS_REP; + retval = asn1_get_tag_2(&buf, &t4); + if (retval) clean_return(retval); + if (t4.asn1class != APPLICATION || t4.construction != CONSTRUCTED) clean_return(ASN1_BAD_ID); + if (t4.tagnum == 25) (*rep)->msg_type = KRB5_AS_REP; + else if(t4.tagnum == 26) (*rep)->msg_type = KRB5_TGS_REP; else clean_return(KRB5_BADMSGTYPE); retval = asn1_decode_enc_kdc_rep_part(&buf,*rep); |