aboutsummaryrefslogtreecommitdiff
path: root/src/lib/krb5/asn.1/asn1_k_decode.c
diff options
context:
space:
mode:
authorTom Yu <tlyu@mit.edu>2000-10-26 22:58:13 +0000
committerTom Yu <tlyu@mit.edu>2000-10-26 22:58:13 +0000
commitb5e198d5a487d71d92acf3cd2475071fd559554e (patch)
treea166086adb28a8b2235c0ae8471ed5aa29b03831 /src/lib/krb5/asn.1/asn1_k_decode.c
parentf6ee7cc309306bef489b75f3c70e239b78ddeecc (diff)
downloadkrb5-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.c97
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));