svn rev #25698: trunk/src/lib/krb5/asn.1/

ghudson@MIT.EDU ghudson at MIT.EDU
Sun Feb 12 12:13:25 EST 2012


http://src.mit.edu/fisheye/changelog/krb5/?cs=25698
Commit By: ghudson
Log Message:
Separate tag info and length in ASN.1 encoder

Remove the length field of taginfo, and change the internal ASN.1
encoder interfaces to return length separately from tag info.


Changed Files:
U   trunk/src/lib/krb5/asn.1/asn1_encode.c
U   trunk/src/lib/krb5/asn.1/asn1_encode.h
U   trunk/src/lib/krb5/asn.1/asn1_k_encode.c
Modified: trunk/src/lib/krb5/asn.1/asn1_encode.c
===================================================================
--- trunk/src/lib/krb5/asn.1/asn1_encode.c	2012-02-12 16:43:01 UTC (rev 25697)
+++ trunk/src/lib/krb5/asn.1/asn1_encode.c	2012-02-12 17:13:24 UTC (rev 25698)
@@ -311,10 +311,10 @@
 
 /**** Functions for encoding and decoding tags ****/
 
-/* Encode a DER tag into buf with the tag and length parameters in t.  Place
- * the length of the encoded tag in *retlen. */
+/* Encode a DER tag into buf with the tag parameters in t and the content
+ * length len.  Place the length of the encoded tag in *retlen. */
 static asn1_error_code
-make_tag(asn1buf *buf, const taginfo *t, size_t *retlen)
+make_tag(asn1buf *buf, const taginfo *t, size_t len, size_t *retlen)
 {
     asn1_error_code ret;
     asn1_tagnum tag_copy;
@@ -324,14 +324,14 @@
         return ASN1_OVERFLOW;
 
     /* Encode the length of the content within the tag. */
-    if (t->length < 128) {
-        ret = asn1buf_insert_octet(buf, t->length & 0x7F);
+    if (len < 128) {
+        ret = asn1buf_insert_octet(buf, len & 0x7F);
         if (ret)
             return ret;
         length = 1;
     } else {
         length = 0;
-        for (len_copy = t->length; len_copy != 0; len_copy >>= 8) {
+        for (len_copy = len; len_copy != 0; len_copy >>= 8) {
             ret = asn1buf_insert_octet(buf, len_copy & 0xFF);
             if (ret)
                 return ret;
@@ -644,7 +644,7 @@
  * then return the length of the contents and the tag. */
 static asn1_error_code
 split_der(asn1buf *buf, unsigned char *const *der, size_t len,
-          taginfo *tag_out)
+          taginfo *tag_out, size_t *len_out)
 {
     asn1_error_code ret;
     const unsigned char *contents, *remainder;
@@ -655,7 +655,7 @@
         return ret;
     if (rlen != 0)
         return ASN1_BAD_LENGTH;
-    tag_out->length = clen;
+    *len_out = clen;
     return asn1buf_insert_bytestring(buf, clen, contents);
 }
 
@@ -687,13 +687,13 @@
                 size_t *len_out);
 static asn1_error_code
 encode_cntype(asn1buf *buf, const void *val, size_t len,
-              const struct cntype_info *c, taginfo *tag_out);
+              const struct cntype_info *c, taginfo *tag_out, size_t *len_out);
 
 /* Encode a value (contents only, no outer tag) according to a type, and return
  * its encoded tag information. */
 static asn1_error_code
 encode_atype(asn1buf *buf, const void *val, const struct atype_info *a,
-             taginfo *tag_out)
+             taginfo *tag_out, size_t *len_out)
 {
     asn1_error_code ret;
 
@@ -704,11 +704,11 @@
     case atype_fn: {
         const struct fn_info *fn = a->tinfo;
         assert(fn->enc != NULL);
-        return fn->enc(buf, val, tag_out);
+        return fn->enc(buf, val, tag_out, len_out);
     }
     case atype_sequence:
         assert(a->tinfo != NULL);
-        ret = encode_sequence(buf, val, a->tinfo, &tag_out->length);
+        ret = encode_sequence(buf, val, a->tinfo, len_out);
         if (ret)
             return ret;
         tag_out->asn1class = UNIVERSAL;
@@ -718,19 +718,20 @@
     case atype_ptr: {
         const struct ptr_info *ptr = a->tinfo;
         assert(ptr->basetype != NULL);
-        return encode_atype(buf, LOADPTR(val, ptr), ptr->basetype, tag_out);
+        return encode_atype(buf, LOADPTR(val, ptr), ptr->basetype, tag_out,
+                            len_out);
     }
     case atype_offset: {
         const struct offset_info *off = a->tinfo;
         assert(off->basetype != NULL);
         return encode_atype(buf, (const char *)val + off->dataoff,
-                            off->basetype, tag_out);
+                            off->basetype, tag_out, len_out);
     }
     case atype_optional: {
         const struct optional_info *opt = a->tinfo;
         assert(opt->is_present != NULL);
         if (opt->is_present(val))
-            return encode_atype(buf, val, opt->basetype, tag_out);
+            return encode_atype(buf, val, opt->basetype, tag_out, len_out);
         else
             return ASN1_OMITTED;
     }
@@ -742,7 +743,8 @@
         ret = load_count(val, counted, &count);
         if (ret)
             return ret;
-        return encode_cntype(buf, dataptr, count, counted->basetype, tag_out);
+        return encode_cntype(buf, dataptr, count, counted->basetype, tag_out,
+                             len_out);
     }
     case atype_nullterm_sequence_of:
     case atype_nonempty_nullterm_sequence_of:
@@ -750,7 +752,7 @@
         ret = encode_nullterm_sequence_of(buf, val, a->tinfo,
                                           a->type ==
                                           atype_nullterm_sequence_of,
-                                          &tag_out->length);
+                                          len_out);
         if (ret)
             return ret;
         tag_out->asn1class = UNIVERSAL;
@@ -759,15 +761,15 @@
         break;
     case atype_tagged_thing: {
         const struct tagged_info *tag = a->tinfo;
-        ret = encode_atype(buf, val, tag->basetype, tag_out);
+        ret = encode_atype(buf, val, tag->basetype, tag_out, len_out);
         if (ret)
             return ret;
         if (!tag->implicit) {
             size_t tlen;
-            ret = make_tag(buf, tag_out, &tlen);
+            ret = make_tag(buf, tag_out, *len_out, &tlen);
             if (ret)
                 return ret;
-            tag_out->length += tlen;
+            *len_out += tlen;
             tag_out->construction = tag->construction;
         }
         tag_out->asn1class = tag->tagtype;
@@ -775,8 +777,7 @@
         break;
     }
     case atype_bool:
-        ret = k5_asn1_encode_bool(buf, load_int(val, a->size)
-                                  , &tag_out->length);
+        ret = k5_asn1_encode_bool(buf, load_int(val, a->size), len_out);
         if (ret)
             return ret;
         tag_out->asn1class = UNIVERSAL;
@@ -784,8 +785,7 @@
         tag_out->tagnum = ASN1_BOOLEAN;
         break;
     case atype_int:
-        ret = k5_asn1_encode_int(buf, load_int(val, a->size),
-                                 &tag_out->length);
+        ret = k5_asn1_encode_int(buf, load_int(val, a->size), len_out);
         if (ret)
             return ret;
         tag_out->asn1class = UNIVERSAL;
@@ -793,8 +793,7 @@
         tag_out->tagnum = ASN1_INTEGER;
         break;
     case atype_uint:
-        ret = k5_asn1_encode_uint(buf, load_uint(val, a->size),
-                                  &tag_out->length);
+        ret = k5_asn1_encode_uint(buf, load_uint(val, a->size), len_out);
         if (ret)
             return ret;
         tag_out->asn1class = UNIVERSAL;
@@ -803,7 +802,7 @@
         break;
     case atype_int_immediate: {
         const struct immediate_info *imm = a->tinfo;
-        ret = k5_asn1_encode_int(buf, imm->val, &tag_out->length);
+        ret = k5_asn1_encode_int(buf, imm->val, len_out);
         if (ret)
             return ret;
         tag_out->asn1class = UNIVERSAL;
@@ -826,15 +825,15 @@
 {
     taginfo t;
     asn1_error_code ret;
-    size_t tlen;
+    size_t clen, tlen;
 
-    ret = encode_atype(buf, val, a, &t);
+    ret = encode_atype(buf, val, a, &t, &clen);
     if (ret)
         return ret;
-    ret = make_tag(buf, &t, &tlen);
+    ret = make_tag(buf, &t, clen, &tlen);
     if (ret)
         return ret;
-    *len_out = t.length + tlen;
+    *len_out = clen + tlen;
     return 0;
 }
 
@@ -845,7 +844,7 @@
  */
 static asn1_error_code
 encode_cntype(asn1buf *buf, const void *val, size_t count,
-              const struct cntype_info *c, taginfo *tag_out)
+              const struct cntype_info *c, taginfo *tag_out, size_t *len_out)
 {
     asn1_error_code ret;
 
@@ -853,7 +852,7 @@
     case cntype_string: {
         const struct string_info *string = c->tinfo;
         assert(string->enc != NULL);
-        ret = string->enc(buf, val, count, &tag_out->length);
+        ret = string->enc(buf, val, count, len_out);
         if (ret)
             return ret;
         tag_out->asn1class = UNIVERSAL;
@@ -862,14 +861,13 @@
         break;
     }
     case cntype_der:
-        return split_der(buf, val, count, tag_out);
+        return split_der(buf, val, count, tag_out, len_out);
     case cntype_seqof: {
         const struct atype_info *a = c->tinfo;
         const struct ptr_info *ptr = a->tinfo;
         assert(a->type == atype_ptr);
         val = LOADPTR(val, ptr);
-        ret = encode_sequence_of(buf, count, val, ptr->basetype,
-                                 &tag_out->length);
+        ret = encode_sequence_of(buf, count, val, ptr->basetype, len_out);
         if (ret)
             return ret;
         tag_out->asn1class = UNIVERSAL;
@@ -881,7 +879,8 @@
         const struct choice_info *choice = c->tinfo;
         if (count >= choice->n_options)
             return ASN1_MISSING_FIELD;
-        return encode_atype(buf, val, choice->options[count], tag_out);
+        return encode_atype(buf, val, choice->options[count], tag_out,
+                            len_out);
     }
 
     default:
@@ -1573,9 +1572,9 @@
 
 asn1_error_code
 k5_asn1_encode_atype(asn1buf *buf, const void *val, const struct atype_info *a,
-                     taginfo *tag_out)
+                     taginfo *tag_out, size_t *len_out)
 {
-    return encode_atype(buf, val, a, tag_out);
+    return encode_atype(buf, val, a, tag_out, len_out);
 }
 
 asn1_error_code

Modified: trunk/src/lib/krb5/asn.1/asn1_encode.h
===================================================================
--- trunk/src/lib/krb5/asn.1/asn1_encode.h	2012-02-12 16:43:01 UTC (rev 25697)
+++ trunk/src/lib/krb5/asn.1/asn1_encode.h	2012-02-12 17:13:24 UTC (rev 25698)
@@ -36,7 +36,6 @@
     asn1_class asn1class;
     asn1_construction construction;
     asn1_tagnum tagnum;
-    size_t length;
 
     /* When decoding, stores the leading and trailing lengths of a tag.  Used
      * by store_der(). */
@@ -153,7 +152,7 @@
 };
 
 struct fn_info {
-    asn1_error_code (*enc)(asn1buf *, const void *, taginfo *);
+    asn1_error_code (*enc)(asn1buf *, const void *, taginfo *, size_t *);
     asn1_error_code (*dec)(const taginfo *, const unsigned char *, size_t,
                            void *);
     int (*check_tag)(const taginfo *);
@@ -535,7 +534,7 @@
  * Used only by kdc_req_body. */
 asn1_error_code
 k5_asn1_encode_atype(asn1buf *buf, const void *val, const struct atype_info *a,
-                     taginfo *tag_out);
+                     taginfo *tag_out, size_t *len_out);
 
 /* Decode the tag and contents of a type, storing the result in the
  * caller-allocated C object val.  Used only by kdc_req_body. */

Modified: trunk/src/lib/krb5/asn.1/asn1_k_encode.c
===================================================================
--- trunk/src/lib/krb5/asn.1/asn1_k_encode.c	2012-02-12 16:43:01 UTC (rev 25697)
+++ trunk/src/lib/krb5/asn.1/asn1_k_encode.c	2012-02-12 17:13:24 UTC (rev 25698)
@@ -94,13 +94,13 @@
  * with old implementations.
  */
 static asn1_error_code
-encode_seqno(asn1buf *buf, const void *p, taginfo *rettag)
+encode_seqno(asn1buf *buf, const void *p, taginfo *rettag, size_t *len_out)
 {
     krb5_ui_4 val = *(krb5_ui_4 *)p;
     rettag->asn1class = UNIVERSAL;
     rettag->construction = PRIMITIVE;
     rettag->tagnum = ASN1_INTEGER;
-    return k5_asn1_encode_uint(buf, val, &rettag->length);
+    return k5_asn1_encode_uint(buf, val, len_out);
 }
 static asn1_error_code
 decode_seqno(const taginfo *t, const unsigned char *asn1, size_t len, void *p)
@@ -128,14 +128,15 @@
 /* Define the kerberos_time type, which is an ASN.1 generaltime represented in
  * a krb5_timestamp. */
 static asn1_error_code
-encode_kerberos_time(asn1buf *buf, const void *p, taginfo *rettag)
+encode_kerberos_time(asn1buf *buf, const void *p, taginfo *rettag,
+                     size_t *len_out)
 {
     /* Range checking for time_t vs krb5_timestamp?  */
     time_t val = *(krb5_timestamp *)p;
     rettag->asn1class = UNIVERSAL;
     rettag->construction = PRIMITIVE;
     rettag->tagnum = ASN1_GENERALTIME;
-    return k5_asn1_encode_generaltime(buf, val, &rettag->length);
+    return k5_asn1_encode_generaltime(buf, val, len_out);
 }
 static asn1_error_code
 decode_kerberos_time(const taginfo *t, const unsigned char *asn1, size_t len,
@@ -190,14 +191,15 @@
 /* Define the krb5_flags type, which is an ASN.1 bit string represented in a
  * 32-bit integer. */
 static asn1_error_code
-encode_krb5_flags(asn1buf *buf, const void *p, taginfo *rettag)
+encode_krb5_flags(asn1buf *buf, const void *p, taginfo *rettag,
+                  size_t *len_out)
 {
     unsigned char cbuf[4], *cptr = cbuf;
     store_32_be((krb5_ui_4)*(const krb5_flags *)p, cbuf);
     rettag->asn1class = UNIVERSAL;
     rettag->construction = PRIMITIVE;
     rettag->tagnum = ASN1_BITSTRING;
-    return k5_asn1_encode_bitstring(buf, &cptr, 4, &rettag->length);
+    return k5_asn1_encode_bitstring(buf, &cptr, 4, len_out);
 }
 static asn1_error_code
 decode_krb5_flags(const taginfo *t, const unsigned char *asn1, size_t len,
@@ -277,13 +279,13 @@
 /* Define the last_req_type type, which is a krb5_int32 with some massaging
  * on decode for backward compatibility. */
 static asn1_error_code
-encode_lr_type(asn1buf *buf, const void *p, taginfo *rettag)
+encode_lr_type(asn1buf *buf, const void *p, taginfo *rettag, size_t *len_out)
 {
     krb5_int32 val = *(krb5_int32 *)p;
     rettag->asn1class = UNIVERSAL;
     rettag->construction = PRIMITIVE;
     rettag->tagnum = ASN1_INTEGER;
-    return k5_asn1_encode_int(buf, val, &rettag->length);
+    return k5_asn1_encode_int(buf, val, len_out);
 }
 static asn1_error_code
 decode_lr_type(const taginfo *t, const unsigned char *asn1, size_t len,
@@ -434,7 +436,8 @@
 };
 DEFSEQTYPE(kdc_req_body_hack, kdc_req_hack, kdc_req_hack_fields);
 static asn1_error_code
-encode_kdc_req_body(asn1buf *buf, const void *p, taginfo *tag_out)
+encode_kdc_req_body(asn1buf *buf, const void *p, taginfo *tag_out,
+                    size_t *len_out)
 {
     const krb5_kdc_req *val = p;
     kdc_req_hack h;
@@ -448,7 +451,8 @@
         h.server_realm = val->server->realm;
     else
         return ASN1_MISSING_FIELD;
-    return k5_asn1_encode_atype(buf, &h, &k5_atype_kdc_req_body_hack, tag_out);
+    return k5_asn1_encode_atype(buf, &h, &k5_atype_kdc_req_body_hack, tag_out,
+                                len_out);
 }
 static void
 free_kdc_req_body(void *val)



More information about the cvs-krb5 mailing list