krb5 commit: Simplify ASN.1 encoding

Greg Hudson <[email protected]>
Newsgroups gmane.comp.encryption.kerberos.cvs
Message-ID <[email protected]>
https://github.com/krb5/krb5/commit/5dd2f6877bb88aa57e6650b26daf0864ae732ae8
commit 5dd2f6877bb88aa57e6650b26daf0864ae732ae8
Author: Greg Hudson <[email protected]>
Date:   Wed Mar 21 18:17:08 2018 -0400

    Simplify ASN.1 encoding
    
    Like most ASN.1 DER implementations, we encode backwards.  The
    existing asn1buf implementation inserts bytes forward into a
    resizeable buffer, then reallocates the number of bytes inserted and
    reverses them.
    
    Throw out this implementation and replace it with two simple inline
    functions in asn1_encode.c, which conditionally insert bytes in
    reverse order and unconditionally increment a count.  Make two passes
    over the input representation, once to count the encoding size and
    once to actually encode it into a precisely allocated buffer.  Remove
    all of the explicit length counting from encoding functions; in the
    places where we need intermediate lengths, compute them from the
    difference in buffer byte count.  Make a few encoding functions return
    void as they no longer have error cases.

 src/lib/krb5/asn.1/Makefile.in     |    3 -
 src/lib/krb5/asn.1/asn1_encode.c   |  323 ++++++++++++++++--------------------
 src/lib/krb5/asn.1/asn1_encode.h   |   25 ++--
 src/lib/krb5/asn.1/asn1_k_encode.c |   26 ++--
 src/lib/krb5/asn.1/asn1buf.c       |  208 -----------------------
 src/lib/krb5/asn.1/asn1buf.h       |  147 ----------------
 src/lib/krb5/asn.1/deps            |   26 +--
 7 files changed, 173 insertions(+), 585 deletions(-)

diff --git a/src/lib/krb5/asn.1/Makefile.in b/src/lib/krb5/asn.1/Makefile.in
index e2e6a35..fe29523 100644
--- a/src/lib/krb5/asn.1/Makefile.in
+++ b/src/lib/krb5/asn.1/Makefile.in
@@ -9,19 +9,16 @@ EHDRDIR=$(BUILDTOP)/include/krb5/asn.1
 
 STLIBOBJS= \
 	asn1_encode.o\
-	asn1buf.o\
 	asn1_k_encode.o\
 	ldap_key_seq.o
 
 SRCS= \
 	$(srcdir)/asn1_encode.c\
-	$(srcdir)/asn1buf.c\
 	$(srcdir)/asn1_k_encode.c\
 	$(srcdir)/ldap_key_seq.c
 
 OBJS= \
 	$(OUTPRE)asn1_encode.$(OBJEXT)\
-	$(OUTPRE)asn1buf.$(OBJEXT)\
 	$(OUTPRE)asn1_k_encode.$(OBJEXT)\
 	$(OUTPRE)ldap_key_seq.$(OBJEXT)
 
diff --git a/src/lib/krb5/asn.1/asn1_encode.c b/src/lib/krb5/asn.1/asn1_encode.c
index a7a5a2f..a160cf4 100644
--- a/src/lib/krb5/asn.1/asn1_encode.c
+++ b/src/lib/krb5/asn.1/asn1_encode.c
@@ -26,97 +26,94 @@
 
 #include "asn1_encode.h"
 
+struct asn1buf_st {
+    uint8_t *ptr;               /* Position, moving backwards; may be NULL */
+    size_t count;               /* Count of bytes written so far */
+};
+
 /**** Functions for encoding primitive types ****/
 
-krb5_error_code
-k5_asn1_encode_bool(asn1buf *buf, intmax_t val, size_t *len_out)
+/* Insert one byte into buf going backwards. */
+static inline void
+insert_byte(asn1buf *buf, uint8_t o)
 {
-    uint8_t bval = val ? 0xFF : 0x00;
+    if (buf->ptr != NULL) {
+        buf->ptr--;
+        *buf->ptr = o;
+    }
+    buf->count++;
+}
 
-    *len_out = 1;
-    return asn1buf_insert_octet(buf, bval);
+/* Insert a block of bytes into buf going backwards (but without reversing
+ * bytes). */
+static inline void
+insert_bytes(asn1buf *buf, const void *bytes, size_t len)
+{
+    if (buf->ptr != NULL) {
+        memcpy(buf->ptr - len, bytes, len);
+        buf->ptr -= len;
+    }
+    buf->count += len;
 }
 
-krb5_error_code
-k5_asn1_encode_int(asn1buf *buf, intmax_t val, size_t *len_out)
+void
+k5_asn1_encode_bool(asn1buf *buf, intmax_t val)
+{
+    insert_byte(buf, val ? 0xFF : 0x00);
+}
+
+void
+k5_asn1_encode_int(asn1buf *buf, intmax_t val)
 {
-    krb5_error_code ret;
-    size_t len = 0;
     long valcopy;
     int digit;
 
     valcopy = val;
     do {
         digit = valcopy & 0xFF;
-        ret = asn1buf_insert_octet(buf, digit);
-        if (ret)
-            return ret;
-        len++;
+        insert_byte(buf, digit);
         valcopy = valcopy >> 8;
     } while (valcopy != 0 && valcopy != ~0);
 
-    if (val > 0 && (digit & 0x80) == 0x80) { /* make sure the high bit is */
-        ret = asn1buf_insert_octet(buf, 0);  /* of the proper signed-ness */
-        if (ret)
-            return ret;
-        len++;
-    } else if (val < 0 && (digit & 0x80) != 0x80) {
-        ret = asn1buf_insert_octet(buf, 0xFF);
-        if (ret)
-            return ret;
-        len++;
-    }
-
-
-    *len_out = len;
-    return 0;
+    /* Make sure the high bit is of the proper signed-ness. */
+    if (val > 0 && (digit & 0x80) == 0x80)
+        insert_byte(buf, 0);
+    else if (val < 0 && (digit & 0x80) != 0x80)
+        insert_byte(buf, 0xFF);
 }
 
-krb5_error_code
-k5_asn1_encode_uint(asn1buf *buf, uintmax_t val, size_t *len_out)
+void
+k5_asn1_encode_uint(asn1buf *buf, uintmax_t val)
 {
-    krb5_error_code ret;
-    size_t len = 0;
     uintmax_t valcopy;
     int digit;
 
     valcopy = val;
     do {
         digit = valcopy & 0xFF;
-        ret = asn1buf_insert_octet(buf, digit);
-        if (ret)
-            return ret;
-        len++;
+        insert_byte(buf, digit);
         valcopy = valcopy >> 8;
     } while (valcopy != 0);
 
-    if (digit & 0x80) {                     /* make sure the high bit is */
-        ret = asn1buf_insert_octet(buf, 0); /* of the proper signed-ness */
-        if (ret)
-            return ret;
-        len++;
-    }
-
-    *len_out = len;
-    return 0;
+    /* Make sure the high bit is of the proper signed-ness. */
+    if (digit & 0x80)
+        insert_byte(buf, 0);
 }
 
 krb5_error_code
-k5_asn1_encode_bytestring(asn1buf *buf, uint8_t *const *val, size_t len,
-                          size_t *len_out)
+k5_asn1_encode_bytestring(asn1buf *buf, uint8_t *const *val, size_t len)
 {
     if (len > 0 && val == NULL)
         return ASN1_MISSING_FIELD;
-    *len_out = len;
-    return asn1buf_insert_octetstring(buf, len, *val);
+    insert_bytes(buf, *val, len);
+    return 0;
 }
 
 krb5_error_code
-k5_asn1_encode_generaltime(asn1buf *buf, time_t val, size_t *len_out)
+k5_asn1_encode_generaltime(asn1buf *buf, time_t val)
 {
     struct tm *gtime, gtimebuf;
-    char s[16];
-    uint8_t *sp;
+    char s[16], *sp;
     time_t gmt_time = val;
     int len;
 
@@ -124,7 +121,7 @@ k5_asn1_encode_generaltime(asn1buf *buf, time_t val, size_t *len_out)
      * Time encoding: YYYYMMDDhhmmssZ
      */
     if (gmt_time == 0) {
-        sp = (uint8_t *)"19700101000000Z";
+        sp = "19700101000000Z";
     } else {
         /*
          * Sanity check this just to be paranoid, as gmtime can return NULL,
@@ -157,23 +154,19 @@ k5_asn1_encode_generaltime(asn1buf *buf, time_t val, size_t *len_out)
         if (SNPRINTF_OVERFLOW(len, sizeof(s)))
             /* Shouldn't be possible given above tests.  */
             return ASN1_BAD_GMTIME;
-        sp = (uint8_t *)s;
+        sp = s;
     }
 
-    return k5_asn1_encode_bytestring(buf, &sp, 15, len_out);
+    insert_bytes(buf, sp, 15);
+    return 0;
 }
 
 krb5_error_code
-k5_asn1_encode_bitstring(asn1buf *buf, uint8_t *const *val, size_t len,
-                         size_t *len_out)
+k5_asn1_encode_bitstring(asn1buf *buf, uint8_t *const *val, size_t len)
 {
-    krb5_error_code ret;
-
-    ret = asn1buf_insert_octetstring(buf, len, *val);
-    if (ret)
-        return ret;
-    *len_out = len + 1;
-    return asn1buf_insert_octet(buf, '\0');
+    insert_bytes(buf, *val, len);
+    insert_byte(buf, 0);
+    return 0;
 }
 
 /**** Functions for decoding primitive types ****/
@@ -315,67 +308,38 @@ k5_asn1_decode_bitstring(const uint8_t *asn1, size_t len,
 /* 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 krb5_error_code
-make_tag(asn1buf *buf, const taginfo *t, size_t len, size_t *retlen)
+make_tag(asn1buf *buf, const taginfo *t, size_t len)
 {
-    krb5_error_code ret;
     asn1_tagnum tag_copy;
-    size_t sum = 0, length, len_copy;
+    size_t len_copy, oldcount;
 
     if (t->tagnum > ASN1_TAGNUM_MAX)
         return ASN1_OVERFLOW;
 
     /* Encode the length of the content within the tag. */
     if (len < 128) {
-        ret = asn1buf_insert_octet(buf, len & 0x7F);
-        if (ret)
-            return ret;
-        length = 1;
+        insert_byte(buf, len & 0x7F);
     } else {
-        length = 0;
-        for (len_copy = len; len_copy != 0; len_copy >>= 8) {
-            ret = asn1buf_insert_octet(buf, len_copy & 0xFF);
-            if (ret)
-                return ret;
-            length++;
-        }
-        ret = asn1buf_insert_octet(buf, 0x80 | (length & 0x7F));
-        if (ret)
-            return ret;
-        length++;
+        oldcount = buf->count;
+        for (len_copy = len; len_copy != 0; len_copy >>= 8)
+            insert_byte(buf, len_copy & 0xFF);
+        insert_byte(buf, 0x80 | ((buf->count - oldcount) & 0x7F));
     }
-    sum += length;
 
     /* Encode the tag and construction bit. */
     if (t->tagnum < 31) {
-        ret = asn1buf_insert_octet(buf,
-                                   t->asn1class | t->construction | t->tagnum);
-        if (ret)
-            return ret;
-        length = 1;
+        insert_byte(buf, t->asn1class | t->construction | t->tagnum);
     } else {
         tag_copy = t->tagnum;
-        length = 0;
-        ret = asn1buf_insert_octet(buf, tag_copy & 0x7F);
-        if (ret)
-            return ret;
+        insert_byte(buf, tag_copy & 0x7F);
         tag_copy >>= 7;
-        length++;
 
-        for (; tag_copy != 0; tag_copy >>= 7) {
-            ret = asn1buf_insert_octet(buf, 0x80 | (tag_copy & 0x7F));
-            if (ret)
-                return ret;
-            length++;
-        }
+        for (; tag_copy != 0; tag_copy >>= 7)
+            insert_byte(buf, 0x80 | (tag_copy & 0x7F));
 
-        ret = asn1buf_insert_octet(buf, t->asn1class | t->construction | 0x1F);
-        if (ret)
-            return ret;
-        length++;
+        insert_byte(buf, t->asn1class | t->construction | 0x1F);
     }
-    sum += length;
 
-    *retlen = sum;
     return 0;
 }
 
@@ -506,18 +470,17 @@ get_nullterm_sequence_len(const void *valp, const struct atype_info *seq)
 }
 static krb5_error_code
 encode_sequence_of(asn1buf *buf, size_t seqlen, const void *val,
-                   const struct atype_info *eltinfo, size_t *len_out);
+                   const struct atype_info *eltinfo);
 
 static krb5_error_code
 encode_nullterm_sequence_of(asn1buf *buf, const void *val,
-                            const struct atype_info *type,
-                            int can_be_empty, size_t *len_out)
+                            const struct atype_info *type, int can_be_empty)
 {
     size_t len = get_nullterm_sequence_len(val, type);
 
     if (!can_be_empty && len == 0)
         return ASN1_MISSING_FIELD;
-    return encode_sequence_of(buf, len, val, type, len_out);
+    return encode_sequence_of(buf, len, val, type);
 }
 
 static intmax_t
@@ -644,8 +607,7 @@ store_count(size_t count, const struct counted_info *counted, void *val)
 /* Split a DER encoding into tag and contents.  Insert the contents into buf,
  * then return the length of the contents and the tag. */
 static krb5_error_code
-split_der(asn1buf *buf, uint8_t *const *der, size_t len,
-          taginfo *tag_out, size_t *len_out)
+split_der(asn1buf *buf, uint8_t *const *der, size_t len, taginfo *tag_out)
 {
     krb5_error_code ret;
     const uint8_t *contents, *remainder;
@@ -656,8 +618,8 @@ split_der(asn1buf *buf, uint8_t *const *der, size_t len,
         return ret;
     if (rlen != 0)
         return ASN1_BAD_LENGTH;
-    *len_out = clen;
-    return asn1buf_insert_bytestring(buf, clen, contents);
+    insert_bytes(buf, contents, clen);
+    return 0;
 }
 
 /*
@@ -684,17 +646,16 @@ store_der(const taginfo *t, const uint8_t *asn1, size_t len, void *val,
 }
 
 static krb5_error_code
-encode_sequence(asn1buf *buf, const void *val, const struct seq_info *seq,
-                size_t *len_out);
+encode_sequence(asn1buf *buf, const void *val, const struct seq_info *seq);
 static krb5_error_code
 encode_cntype(asn1buf *buf, const void *val, size_t len,
-              const struct cntype_info *c, taginfo *tag_out, size_t *len_out);
+              const struct cntype_info *c, taginfo *tag_out);
 
 /* Encode a value (contents only, no outer tag) according to a type, and return
  * its encoded tag information. */
 static krb5_error_code
 encode_atype(asn1buf *buf, const void *val, const struct atype_info *a,
-             taginfo *tag_out, size_t *len_out)
+             taginfo *tag_out)
 {
     krb5_error_code ret;
 
@@ -705,11 +666,11 @@ encode_atype(asn1buf *buf, const void *val, const struct atype_info *a,
     case atype_fn: {
         const struct fn_info *fn = a->tinfo;
         assert(fn->enc != NULL);
-        return fn->enc(buf, val, tag_out, len_out);
+        return fn->enc(buf, val, tag_out);
     }
     case atype_sequence:
         assert(a->tinfo != NULL);
-        ret = encode_sequence(buf, val, a->tinfo, len_out);
+        ret = encode_sequence(buf, val, a->tinfo);
         if (ret)
             return ret;
         tag_out->asn1class = UNIVERSAL;
@@ -719,20 +680,19 @@ encode_atype(asn1buf *buf, const void *val, const struct atype_info *a,
     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,
-                            len_out);
+        return encode_atype(buf, LOADPTR(val, ptr), ptr->basetype, tag_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, len_out);
+                            off->basetype, tag_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, len_out);
+            return encode_atype(buf, val, opt->basetype, tag_out);
         else
             return ASN1_OMITTED;
     }
@@ -744,16 +704,14 @@ encode_atype(asn1buf *buf, const void *val, const struct atype_info *a,
         ret = load_count(val, counted, &count);
         if (ret)
             return ret;
-        return encode_cntype(buf, dataptr, count, counted->basetype, tag_out,
-                             len_out);
+        return encode_cntype(buf, dataptr, count, counted->basetype, tag_out);
     }
     case atype_nullterm_sequence_of:
     case atype_nonempty_nullterm_sequence_of:
         assert(a->tinfo != NULL);
         ret = encode_nullterm_sequence_of(buf, val, a->tinfo,
                                           a->type ==
-                                          atype_nullterm_sequence_of,
-                                          len_out);
+                                          atype_nullterm_sequence_of);
         if (ret)
             return ret;
         tag_out->asn1class = UNIVERSAL;
@@ -762,15 +720,14 @@ encode_atype(asn1buf *buf, const void *val, const struct atype_info *a,
         break;
     case atype_tagged_thing: {
         const struct tagged_info *tag = a->tinfo;
-        ret = encode_atype(buf, val, tag->basetype, tag_out, len_out);
+        size_t oldcount = buf->count;
+        ret = encode_atype(buf, val, tag->basetype, tag_out);
         if (ret)
             return ret;
         if (!tag->implicit) {
-            size_t tlen;
-            ret = make_tag(buf, tag_out, *len_out, &tlen);
+            ret = make_tag(buf, tag_out, buf->count - oldcount);
             if (ret)
                 return ret;
-            *len_out += tlen;
             tag_out->construction = tag->construction;
         }
         tag_out->asn1class = tag->tagtype;
@@ -778,34 +735,26 @@ encode_atype(asn1buf *buf, const void *val, const struct atype_info *a,
         break;
     }
     case atype_bool:
-        ret = k5_asn1_encode_bool(buf, load_int(val, a->size), len_out);
-        if (ret)
-            return ret;
+        k5_asn1_encode_bool(buf, load_int(val, a->size));
         tag_out->asn1class = UNIVERSAL;
         tag_out->construction = PRIMITIVE;
         tag_out->tagnum = ASN1_BOOLEAN;
         break;
     case atype_int:
-        ret = k5_asn1_encode_int(buf, load_int(val, a->size), len_out);
-        if (ret)
-            return ret;
+        k5_asn1_encode_int(buf, load_int(val, a->size));
         tag_out->asn1class = UNIVERSAL;
         tag_out->construction = PRIMITIVE;
         tag_out->tagnum = ASN1_INTEGER;
         break;
     case atype_uint:
-        ret = k5_asn1_encode_uint(buf, load_uint(val, a->size), len_out);
-        if (ret)
-            return ret;
+        k5_asn1_encode_uint(buf, load_uint(val, a->size));
         tag_out->asn1class = UNIVERSAL;
         tag_out->construction = PRIMITIVE;
         tag_out->tagnum = ASN1_INTEGER;
         break;
     case atype_int_immediate: {
         const struct immediate_info *imm = a->tinfo;
-        ret = k5_asn1_encode_int(buf, imm->val, len_out);
-        if (ret)
-            return ret;
+        k5_asn1_encode_int(buf, imm->val);
         tag_out->asn1class = UNIVERSAL;
         tag_out->construction = PRIMITIVE;
         tag_out->tagnum = ASN1_INTEGER;
@@ -821,20 +770,18 @@ encode_atype(asn1buf *buf, const void *val, const struct atype_info *a,
 }
 
 static krb5_error_code
-encode_atype_and_tag(asn1buf *buf, const void *val, const struct atype_info *a,
-                     size_t *len_out)
+encode_atype_and_tag(asn1buf *buf, const void *val, const struct atype_info *a)
 {
     taginfo t;
     krb5_error_code ret;
-    size_t clen, tlen;
+    size_t oldcount = buf->count;
 
-    ret = encode_atype(buf, val, a, &t, &clen);
+    ret = encode_atype(buf, val, a, &t);
     if (ret)
         return ret;
-    ret = make_tag(buf, &t, clen, &tlen);
+    ret = make_tag(buf, &t, buf->count - oldcount);
     if (ret)
         return ret;
-    *len_out = clen + tlen;
     return 0;
 }
 
@@ -845,7 +792,7 @@ encode_atype_and_tag(asn1buf *buf, const void *val, const struct atype_info *a,
  */
 static krb5_error_code
 encode_cntype(asn1buf *buf, const void *val, size_t count,
-              const struct cntype_info *c, taginfo *tag_out, size_t *len_out)
+              const struct cntype_info *c, taginfo *tag_out)
 {
     krb5_error_code ret;
 
@@ -853,7 +800,7 @@ encode_cntype(asn1buf *buf, const void *val, size_t count,
     case cntype_string: {
         const struct string_info *string = c->tinfo;
         assert(string->enc != NULL);
-        ret = string->enc(buf, val, count, len_out);
+        ret = string->enc(buf, val, count);
         if (ret)
             return ret;
         tag_out->asn1class = UNIVERSAL;
@@ -862,13 +809,13 @@ encode_cntype(asn1buf *buf, const void *val, size_t count,
         break;
     }
     case cntype_der:
-        return split_der(buf, val, count, tag_out, len_out);
+        return split_der(buf, val, count, tag_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, len_out);
+        ret = encode_sequence_of(buf, count, val, ptr->basetype);
         if (ret)
             return ret;
         tag_out->asn1class = UNIVERSAL;
@@ -880,8 +827,7 @@ encode_cntype(asn1buf *buf, const void *val, size_t count,
         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,
-                            len_out);
+        return encode_atype(buf, val, choice->options[count], tag_out);
     }
 
     default:
@@ -894,41 +840,36 @@ encode_cntype(asn1buf *buf, const void *val, size_t count,
 }
 
 static krb5_error_code
-encode_sequence(asn1buf *buf, const void *val, const struct seq_info *seq,
-                size_t *len_out)
+encode_sequence(asn1buf *buf, const void *val, const struct seq_info *seq)
 {
     krb5_error_code ret;
-    size_t i, len, sum = 0;
+    size_t i;
 
     for (i = seq->n_fields; i > 0; i--) {
-        ret = encode_atype_and_tag(buf, val, seq->fields[i - 1], &len);
+        ret = encode_atype_and_tag(buf, val, seq->fields[i - 1]);
         if (ret == ASN1_OMITTED)
             continue;
         else if (ret != 0)
             return ret;
-        sum += len;
     }
-    *len_out = sum;
     return 0;
 }
 
 static krb5_error_code
 encode_sequence_of(asn1buf *buf, size_t seqlen, const void *val,
-                   const struct atype_info *eltinfo, size_t *len_out)
+                   const struct atype_info *eltinfo)
 {
     krb5_error_code ret;
-    size_t sum = 0, i, len;
+    size_t i;
     const void *eltptr;
 
     assert(eltinfo->size != 0);
     for (i = seqlen; i > 0; i--) {
         eltptr = (const char *)val + (i - 1) * eltinfo->size;
-        ret = encode_atype_and_tag(buf, eltptr, eltinfo, &len);
+        ret = encode_atype_and_tag(buf, eltptr, eltinfo);
         if (ret)
             return ret;
-        sum += len;
     }
-    *len_out = sum;
     return 0;
 }
 
@@ -1572,9 +1513,9 @@ error:
 
 krb5_error_code
 k5_asn1_encode_atype(asn1buf *buf, const void *val, const struct atype_info *a,
-                     taginfo *tag_out, size_t *len_out)
+                     taginfo *tag_out)
 {
-    return encode_atype(buf, val, a, tag_out, len_out);
+    return encode_atype(buf, val, a, tag_out);
 }
 
 krb5_error_code
@@ -1588,28 +1529,48 @@ krb5_error_code
 k5_asn1_full_encode(const void *rep, const struct atype_info *a,
                     krb5_data **code_out)
 {
-    size_t len;
     krb5_error_code ret;
-    asn1buf *buf = NULL;
+    asn1buf buf;
     krb5_data *d;
+    uint8_t *bytes;
 
     *code_out = NULL;
 
     if (rep == NULL)
         return ASN1_MISSING_FIELD;
-    ret = asn1buf_create(&buf);
+
+    /* Make a first pass over rep to count the encoding size. */
+    buf.ptr = NULL;
+    buf.count = 0;
+    ret = encode_atype_and_tag(&buf, rep, a);
     if (ret)
         return ret;
-    ret = encode_atype_and_tag(buf, rep, a, &len);
-    if (ret)
-        goto cleanup;
-    ret = asn12krb5_buf(buf, &d);
-    if (ret)
-        goto cleanup;
-    *code_out = d;
-cleanup:
-    asn1buf_destroy(&buf);
-    return ret;
+
+    /* Allocate space for the encoding. */
+    bytes = malloc(buf.count + 1);
+    if (bytes == NULL)
+        return ENOMEM;
+    bytes[buf.count] = 0;
+
+    /* Make a second pass over rep to encode it.  buf.ptr moves backwards as we
+     * encode, and will always exactly return to the base. */
+    buf.ptr = bytes + buf.count;
+    buf.count = 0;
+    ret = encode_atype_and_tag(&buf, rep, a);
+    if (ret) {
+        free(bytes);
+        return ret;
+    }
+    assert(buf.ptr == bytes);
+
+    /* Create the output data object. */
+    *code_out = malloc(sizeof(*d));
+    if (*code_out == NULL) {
+        free(bytes);
+        return ENOMEM;
+    }
+    **code_out = make_data(bytes, buf.count);
+    return 0;
 }
 
 krb5_error_code
diff --git a/src/lib/krb5/asn.1/asn1_encode.h b/src/lib/krb5/asn.1/asn1_encode.h
index 1e17075..fde875b 100644
--- a/src/lib/krb5/asn.1/asn1_encode.h
+++ b/src/lib/krb5/asn.1/asn1_encode.h
@@ -29,9 +29,10 @@
 
 #include "k5-int.h"
 #include "krbasn1.h"
-#include "asn1buf.h"
 #include <time.h>
 
+typedef struct asn1buf_st asn1buf;
+
 typedef struct {
     asn1_class asn1class;
     asn1_construction construction;
@@ -45,18 +46,14 @@ typedef struct {
 
 /* These functions are referenced by encoder structures.  They handle the
  * encoding of primitive ASN.1 types. */
-krb5_error_code k5_asn1_encode_bool(asn1buf *buf, intmax_t val,
-                                    size_t *len_out);
-krb5_error_code k5_asn1_encode_int(asn1buf *buf, intmax_t val,
-                                   size_t *len_out);
-krb5_error_code k5_asn1_encode_uint(asn1buf *buf, uintmax_t val,
-                                    size_t *len_out);
+void k5_asn1_encode_bool(asn1buf *buf, intmax_t val);
+void k5_asn1_encode_int(asn1buf *buf, intmax_t val);
+void k5_asn1_encode_uint(asn1buf *buf, uintmax_t val);
 krb5_error_code k5_asn1_encode_bytestring(asn1buf *buf, uint8_t *const *val,
-                                          size_t len, size_t *len_out);
+                                          size_t len);
 krb5_error_code k5_asn1_encode_bitstring(asn1buf *buf, uint8_t *const *val,
-                                         size_t len, size_t *len_out);
-krb5_error_code k5_asn1_encode_generaltime(asn1buf *buf, time_t val,
-                                           size_t *len_out);
+                                         size_t len);
+krb5_error_code k5_asn1_encode_generaltime(asn1buf *buf, time_t val);
 
 /* These functions are referenced by encoder structures.  They handle the
  * decoding of primitive ASN.1 types. */
@@ -148,7 +145,7 @@ struct atype_info {
 };
 
 struct fn_info {
-    krb5_error_code (*enc)(asn1buf *, const void *, taginfo *, size_t *);
+    krb5_error_code (*enc)(asn1buf *, const void *, taginfo *);
     krb5_error_code (*dec)(const taginfo *, const uint8_t *, size_t, void *);
     int (*check_tag)(const taginfo *);
     void (*free_func)(void *);
@@ -226,7 +223,7 @@ struct cntype_info {
 };
 
 struct string_info {
-    krb5_error_code (*enc)(asn1buf *, uint8_t *const *, size_t, size_t *);
+    krb5_error_code (*enc)(asn1buf *, uint8_t *const *, size_t);
     krb5_error_code (*dec)(const uint8_t *, size_t, uint8_t **, size_t *);
     unsigned int tagval : 5;
 };
@@ -527,7 +524,7 @@ struct seq_info {
  * Used only by kdc_req_body. */
 krb5_error_code
 k5_asn1_encode_atype(asn1buf *buf, const void *val, const struct atype_info *a,
-                     taginfo *tag_out, size_t *len_out);
+                     taginfo *tag_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. */
diff --git a/src/lib/krb5/asn.1/asn1_k_encode.c b/src/lib/krb5/asn.1/asn1_k_encode.c
index 0b6003b..65c84be 100644
--- a/src/lib/krb5/asn.1/asn1_k_encode.c
+++ b/src/lib/krb5/asn.1/asn1_k_encode.c
@@ -121,13 +121,14 @@ DEFOPTIONALZEROTYPE(opt_principal, principal);
  * with old implementations.
  */
 static krb5_error_code
-encode_seqno(asn1buf *buf, const void *p, taginfo *rettag, size_t *len_out)
+encode_seqno(asn1buf *buf, const void *p, taginfo *rettag)
 {
     uint32_t val = *(uint32_t *)p;
     rettag->asn1class = UNIVERSAL;
     rettag->construction = PRIMITIVE;
     rettag->tagnum = ASN1_INTEGER;
-    return k5_asn1_encode_uint(buf, val, len_out);
+    k5_asn1_encode_uint(buf, val);
+    return 0;
 }
 static krb5_error_code
 decode_seqno(const taginfo *t, const uint8_t *asn1, size_t len, void *p)
@@ -155,14 +156,13 @@ DEFOPTIONALZEROTYPE(opt_seqno, seqno);
 /* Define the kerberos_time type, which is an ASN.1 generaltime represented in
  * a krb5_timestamp. */
 static krb5_error_code
-encode_kerberos_time(asn1buf *buf, const void *p, taginfo *rettag,
-                     size_t *len_out)
+encode_kerberos_time(asn1buf *buf, const void *p, taginfo *rettag)
 {
     time_t val = ts2tt(*(krb5_timestamp *)p);
     rettag->asn1class = UNIVERSAL;
     rettag->construction = PRIMITIVE;
     rettag->tagnum = ASN1_GENERALTIME;
-    return k5_asn1_encode_generaltime(buf, val, len_out);
+    return k5_asn1_encode_generaltime(buf, val);
 }
 static krb5_error_code
 decode_kerberos_time(const taginfo *t, const uint8_t *asn1, size_t len,
@@ -229,15 +229,14 @@ DEFOPTIONALTYPE(opt_encrypted_data, nonempty_enc_data, NULL, encrypted_data);
 /* Define the krb5_flags type, which is an ASN.1 bit string represented in a
  * 32-bit integer. */
 static krb5_error_code
-encode_krb5_flags(asn1buf *buf, const void *p, taginfo *rettag,
-                  size_t *len_out)
+encode_krb5_flags(asn1buf *buf, const void *p, taginfo *rettag)
 {
     uint8_t cbuf[4], *cptr = cbuf;
     store_32_be((uint32_t)*(const krb5_flags *)p, cbuf);
     rettag->asn1class = UNIVERSAL;
     rettag->construction = PRIMITIVE;
     rettag->tagnum = ASN1_BITSTRING;
-    return k5_asn1_encode_bitstring(buf, &cptr, 4, len_out);
+    return k5_asn1_encode_bitstring(buf, &cptr, 4);
 }
 static krb5_error_code
 decode_krb5_flags(const taginfo *t, const uint8_t *asn1, size_t len, void *val)
@@ -316,13 +315,14 @@ DEFOPTIONALZEROTYPE(opt_checksum_ptr, checksum_ptr);
 /* Define the last_req_type type, which is an int32_t with some massaging on
  * decode for backward compatibility. */
 static krb5_error_code
-encode_lr_type(asn1buf *buf, const void *p, taginfo *rettag, size_t *len_out)
+encode_lr_type(asn1buf *buf, const void *p, taginfo *rettag)
 {
     int32_t val = *(int32_t *)p;
     rettag->asn1class = UNIVERSAL;
     rettag->construction = PRIMITIVE;
     rettag->tagnum = ASN1_INTEGER;
-    return k5_asn1_encode_int(buf, val, len_out);
+    k5_asn1_encode_int(buf, val);
+    return 0;
 }
 static krb5_error_code
 decode_lr_type(const taginfo *t, const uint8_t *asn1, size_t len, void *p)
@@ -472,8 +472,7 @@ static const struct atype_info *kdc_req_hack_fields[] = {
 };
 DEFSEQTYPE(kdc_req_body_hack, kdc_req_hack, kdc_req_hack_fields);
 static krb5_error_code
-encode_kdc_req_body(asn1buf *buf, const void *p, taginfo *tag_out,
-                    size_t *len_out)
+encode_kdc_req_body(asn1buf *buf, const void *p, taginfo *tag_out)
 {
     const krb5_kdc_req *val = p;
     kdc_req_hack h;
@@ -487,8 +486,7 @@ encode_kdc_req_body(asn1buf *buf, const void *p, taginfo *tag_out,
         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,
-                                len_out);
+    return k5_asn1_encode_atype(buf, &h, &k5_atype_kdc_req_body_hack, tag_out);
 }
 static void
 free_kdc_req_body(void *val)
diff --git a/src/lib/krb5/asn.1/asn1buf.c b/src/lib/krb5/asn.1/asn1buf.c
deleted file mode 100644
index c27bfb9..0000000
--- a/src/lib/krb5/asn.1/asn1buf.c
+++ /dev/null
@@ -1,208 +0,0 @@
-/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
-/* Coding Buffer Implementation */
-
-/*
- *  Implementation
- *
- *    Encoding mode
- *
- *    The encoding buffer is filled from bottom (lowest address) to top
- *    (highest address).  This makes it easier to expand the buffer,
- *    since realloc preserves the existing portion of the buffer.
- *
- *    Note: Since ASN.1 encoding must be done in reverse, this means
- *    that you can't simply memcpy out the buffer data, since it will be
- *    backwards.  You need to reverse-iterate through it, instead.
- *
- *    ***This decision may have been a mistake.  In practice, the
- *    implementation will probably be tuned such that reallocation is
- *    rarely necessary.  Also, the realloc probably has recopy the
- *    buffer itself, so we don't really gain that much by avoiding an
- *    explicit copy of the buffer.  --Keep this in mind for future reference.
- *
- *
- *    Decoding mode
- *
- *    The decoding buffer is in normal order and is created by wrapping
- *    an asn1buf around a krb5_data structure.
- */
-
-/*
- * Abstraction Function
- *
- *   Programs should use just pointers to asn1buf's (e.g. asn1buf *mybuf).
- *   These pointers must always point to a valid, allocated asn1buf
- *   structure or be NULL.
- *
- *   The contents of the asn1buf represent an octet string.  This string
- *   begins at base and continues to the octet immediately preceding next.
- *   If next == base or mybuf == NULL, then the asn1buf represents an empty
- *   octet string.
- */
-
-/*
- * Representation Invariant
- *
- *   Pointers to asn1buf's must always point to a valid, allocated
- *   asn1buf structure or be NULL.
- *
- *   base points to a valid, allocated octet array or is NULL
- *   bound, if non-NULL, points to the last valid octet
- *   next >= base
- *   next <= bound+2  (i.e. next should be able to step just past the bound,
- *                     but no further.  (The bound should move out in response
- *                     to being crossed by next.))
- */
-
-#define ASN1BUF_OMIT_INLINE_FUNCS
-#include "asn1buf.h"
-#include <stdio.h>
-
-#ifdef USE_VALGRIND
-#include <valgrind/memcheck.h>
-#else
-#define VALGRIND_CHECK_READABLE(PTR,SIZE) ((void)0)
-#endif
-
-#if !defined(__GNUC__) || defined(CONFIG_SMALL)
-/*
- * Declare private procedures as static if they're not used for inline
- * expansion of other stuff elsewhere.
- */
-static unsigned int asn1buf_free(const asn1buf *);
-static krb5_error_code asn1buf_ensure_space(asn1buf *, unsigned int);
-static krb5_error_code asn1buf_expand(asn1buf *, unsigned int);
-#endif
-
-#define asn1_is_eoc(class, num, indef)                  \
-    ((class) == UNIVERSAL && !(num) && !(indef))
-
-krb5_error_code
-asn1buf_create(asn1buf **buf)
-{
-    *buf = (asn1buf*)malloc(sizeof(asn1buf));
-    if (*buf == NULL) return ENOMEM;
-    (*buf)->base = NULL;
-    (*buf)->bound = NULL;
-    (*buf)->next = NULL;
-    return 0;
-}
-
-void
-asn1buf_destroy(asn1buf **buf)
-{
-    if (*buf != NULL) {
-        free((*buf)->base);
-        free(*buf);
-        *buf = NULL;
-    }
-}
-
-#ifdef asn1buf_insert_octet
-#undef asn1buf_insert_octet
-#endif
-krb5_error_code
-asn1buf_insert_octet(asn1buf *buf, const int o)
-{
-    krb5_error_code retval;
-
-    retval = asn1buf_ensure_space(buf,1U);
-    if (retval) return retval;
-    *(buf->next) = (char)o;
-    (buf->next)++;
-    return 0;
-}
-
-krb5_error_code
-asn1buf_insert_bytestring(asn1buf *buf, const unsigned int len, const void *sv)
-{
-    krb5_error_code retval;
-    unsigned int length;
-    const char *s = sv;
-
-    retval = asn1buf_ensure_space(buf,len);
-    if (retval) return retval;
-    VALGRIND_CHECK_READABLE(sv, len);
-    for (length=1; length<=len; length++,(buf->next)++)
-        *(buf->next) = (s[len-length]);
-    return 0;
-}
-
-krb5_error_code
-asn12krb5_buf(const asn1buf *buf, krb5_data **code)
-{
-    unsigned int i;
-    krb5_data *d;
-
-    *code = NULL;
-
-    d = calloc(1, sizeof(krb5_data));
-    if (d == NULL)
-        return ENOMEM;
-    d->length = asn1buf_len(buf);
-    d->data = malloc(d->length + 1);
-    if (d->data == NULL) {
-        free(d);
-        return ENOMEM;
-    }
-    for (i=0; i < d->length; i++)
-        d->data[i] = buf->base[d->length - i - 1];
-    d->data[d->length] = '\0';
-    d->magic = KV5M_DATA;
-    *code = d;
-    return 0;
-}
-
-/****************************************************************/
-/* Private Procedures */
-
-static int
-asn1buf_size(const asn1buf *buf)
-{
-    if (buf == NULL || buf->base == NULL) return 0;
-    return buf->bound - buf->base + 1;
-}
-
-#undef asn1buf_free
-unsigned int
-asn1buf_free(const asn1buf *buf)
-{
-    if (buf == NULL || buf->base == NULL) return 0;
-    else return buf->bound - buf->next + 1;
-}
-
-#undef asn1buf_ensure_space
-krb5_error_code
-asn1buf_ensure_space(asn1buf *buf, const unsigned int amount)
-{
-    unsigned int avail = asn1buf_free(buf);
-    if (avail >= amount)
-        return 0;
-    return asn1buf_expand(buf, amount-avail);
-}
-
-krb5_error_code
-asn1buf_expand(asn1buf *buf, unsigned int inc)
-{
-#define STANDARD_INCREMENT 200
-    int next_offset = buf->next - buf->base;
-    int bound_offset;
-    if (buf->base == NULL) bound_offset = -1;
-    else bound_offset = buf->bound - buf->base;
-
-    if (inc < STANDARD_INCREMENT)
-        inc = STANDARD_INCREMENT;
-
-    buf->base = realloc(buf->base, asn1buf_size(buf) + inc);
-    if (buf->base == NULL) return ENOMEM; /* XXX leak */
-    buf->bound = (buf->base) + bound_offset + inc;
-    buf->next = (buf->base) + next_offset;
-    return 0;
-}
-
-#undef asn1buf_len
-int
-asn1buf_len(const asn1buf *buf)
-{
-    return buf->next - buf->base;
-}
diff --git a/src/lib/krb5/asn.1/asn1buf.h b/src/lib/krb5/asn.1/asn1buf.h
deleted file mode 100644
index 494417f..0000000
--- a/src/lib/krb5/asn.1/asn1buf.h
+++ /dev/null
@@ -1,147 +0,0 @@
-/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
-/* Coding Buffer Specifications */
-#ifndef __ASN1BUF_H__
-#define __ASN1BUF_H__
-
-#include "k5-int.h"
-#include "krbasn1.h"
-
-typedef struct code_buffer_rep {
-    char *base, *bound, *next;
-} asn1buf;
-
-
-/**************** Private Procedures ****************/
-
-#if (__GNUC__ >= 2) && !defined(CONFIG_SMALL)
-unsigned int asn1buf_free(const asn1buf *buf);
-/*
- * requires  *buf is allocated
- * effects   Returns the number of unused, allocated octets in *buf.
- */
-#define asn1buf_free(buf)                               \
-    (((buf) == NULL || (buf)->base == NULL)             \
-     ? 0U                                               \
-     : (unsigned int)((buf)->bound - (buf)->next + 1))
-
-
-krb5_error_code asn1buf_ensure_space(asn1buf *buf, const unsigned int amount);
-/*
- * requires  *buf is allocated
- * modifies  *buf
- * effects  If buf has less than amount octets of free space, then it is
- *          expanded to have at least amount octets of free space.
- *          Returns ENOMEM memory is exhausted.
- */
-#define asn1buf_ensure_space(buf,amount)                        \
-    ((asn1buf_free(buf) < (amount))                             \
-     ? (asn1buf_expand((buf), (amount)-asn1buf_free(buf)))      \
-     : 0)
-
-krb5_error_code asn1buf_expand(asn1buf *buf, unsigned int inc);
-/*
- * requires  *buf is allocated
- * modifies  *buf
- * effects   Expands *buf by allocating space for inc more octets.
- *            Returns ENOMEM if memory is exhausted.
- */
-#endif
-
-int asn1buf_len(const asn1buf *buf);
-/*
- * requires  *buf is allocated
- * effects   Returns the length of the encoding in *buf.
- */
-#define asn1buf_len(buf)        ((buf)->next - (buf)->base)
-
-/****** End of private procedures *****/
-
-/*
- * Overview
- *
- *  The coding buffer is an array of char (to match a krb5_data structure)
- *   with 3 reference pointers:
- *   1) base - The bottom of the octet array.  Used for memory management
- *             operations on the array (e.g. alloc, realloc, free).
- *   2) next - Points to the next available octet position in the array.
- *             During encoding, this is the next free position, and it
- *               advances as octets are added to the array.
- *             During decoding, this is the next unread position, and it
- *               advances as octets are read from the array.
- *   3) bound - Points to the top of the array. Used for bounds-checking.
- *
- *  All pointers to encoding buffers should be initalized to NULL.
- *
- * Operations
- *
- *  asn1buf_create
- *  asn1buf_wrap_data
- *  asn1buf_destroy
- *  asn1buf_insert_octet
- *  asn1buf_insert_charstring
- *  asn1buf_remove_octet
- *  asn1buf_remove_charstring
- *  asn1buf_unparse
- *  asn1buf_hex_unparse
- *  asn12krb5_buf
- *  asn1buf_remains
- *
- *  (asn1buf_size)
- *  (asn1buf_free)
- *  (asn1buf_ensure_space)
- *  (asn1buf_expand)
- *  (asn1buf_len)
- */
-
-krb5_error_code asn1buf_create(asn1buf **buf);
-/*
- * effects   Creates a new encoding buffer pointed to by *buf.
- *           Returns ENOMEM if the buffer can't be created.
- */
-
-void asn1buf_destroy(asn1buf **buf);
-/* effects   Deallocates **buf, sets *buf to NULL. */
-
-/*
- * requires  *buf is allocated
- * effects   Inserts o into the buffer *buf, expanding the buffer if
- *           necessary.  Returns ENOMEM memory is exhausted.
- */
-#if ((__GNUC__ >= 2) && !defined(ASN1BUF_OMIT_INLINE_FUNCS)) && !defined(CONFIG_SMALL)
-static inline krb5_error_code
-asn1buf_insert_octet(asn1buf *buf, const int o)
-{
-    krb5_error_code retval;
-
-    retval = asn1buf_ensure_space(buf,1U);
-    if (retval) return retval;
-    *(buf->next) = (char)o;
-    (buf->next)++;
-    return 0;
-}
-#else
-krb5_error_code asn1buf_insert_octet(asn1buf *buf, const int o);
-#endif
-
-krb5_error_code
-asn1buf_insert_bytestring(
-    asn1buf *buf,
-    const unsigned int len,
-    const void *s);
-/*
- * requires  *buf is allocated
- * modifies  *buf
- * effects   Inserts the contents of s (an array of length len)
- *            into the buffer *buf, expanding the buffer if necessary.
- *           Returns ENOMEM if memory is exhausted.
- */
-
-#define asn1buf_insert_octetstring asn1buf_insert_bytestring
-
-krb5_error_code asn12krb5_buf(const asn1buf *buf, krb5_data **code);
-/*
- * modifies  *code
- * effects   Instantiates **code with the krb5_data representation of **buf.
- */
-
-#endif
diff --git a/src/lib/krb5/asn.1/deps b/src/lib/krb5/asn.1/deps
index 47050d6..01d2d23 100644
--- a/src/lib/krb5/asn.1/deps
+++ b/src/lib/krb5/asn.1/deps
@@ -11,29 +11,19 @@ asn1_encode.so asn1_encode.po $(OUTPRE)asn1_encode.$(OBJEXT): \
   $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \
   $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \
   $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \
-  asn1_encode.c asn1_encode.h asn1buf.h krbasn1.h
-asn1buf.so asn1buf.po $(OUTPRE)asn1buf.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
-  $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
-  $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \
-  $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \
-  $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \
-  $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \
-  $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \
-  $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \
-  $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \
-  $(top_srcdir)/include/socket-utils.h asn1buf.c asn1buf.h \
-  krbasn1.h
+  asn1_encode.c asn1_encode.h krbasn1.h
 asn1_k_encode.so asn1_k_encode.po $(OUTPRE)asn1_k_encode.$(OBJEXT): \
   $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \
   $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \
   $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \
   $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \
   $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \
-  $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \
-  $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \
-  $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \
-  $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \
-  asn1_encode.h asn1_k_encode.c asn1buf.h krbasn1.h
+  $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-spake.h \
+  $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \
+  $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \
+  $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \
+  $(top_srcdir)/include/socket-utils.h asn1_encode.h \
+  asn1_k_encode.c krbasn1.h
 ldap_key_seq.so ldap_key_seq.po $(OUTPRE)ldap_key_seq.$(OBJEXT): \
   $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \
   $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \
@@ -45,4 +35,4 @@ ldap_key_seq.so ldap_key_seq.po $(OUTPRE)ldap_key_seq.$(OBJEXT): \
   $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \
   $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \
   $(top_srcdir)/include/socket-utils.h asn1_encode.h \
-  asn1buf.h krbasn1.h ldap_key_seq.c
+  krbasn1.h ldap_key_seq.c
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.