]> git.ipfire.org Git - thirdparty/krb5.git/commitdiff
Be stricter about ASN.1 decoding 1129/head
authorDemi M. Obenour <demiobenour@gmail.com>
Sun, 25 Oct 2020 15:05:23 +0000 (11:05 -0400)
committerGreg Hudson <ghudson@mit.edu>
Mon, 9 Nov 2020 02:18:30 +0000 (21:18 -0500)
Remove support for BER indefinite-length encodings, which are not
valid in DER.  Enforce validity of digits in GeneralizedTime values.
Reject signed integer encodings large enough to possibly overflow
intmax_t, and use regular arithmetic to avoid the undefined behavior
of left-shifting a negative integer.  Reject trailing garbage in
explicitly-tagged single values.  Remove the unnecessary
KRB5_GENEROUS_LR_TYPE workaround; our KDC doesn't generate last-req
information, so the broken pre-2000 encoding behavior had no impact.

[ghudson@mit.edu: edited commit message]

src/lib/krb5/asn.1/README.asn1
src/lib/krb5/asn.1/asn1_encode.c
src/lib/krb5/asn.1/asn1_encode.h
src/lib/krb5/asn.1/asn1_k_encode.c
src/lib/krb5/asn.1/krbasn1.h
src/lib/krb5/error_tables/asn1_err.et
src/tests/asn.1/krb5_decode_test.c

index dcc48c41009f19c328bb134a1f4c657d6af37c49..4990eec4fd5e4cd4497176206e24e4dd807d98bf 100644 (file)
@@ -527,11 +527,6 @@ behavior is to skip that field and assign the value to a subsequent
 field.  It should be very rare for ASN.1 modules to use choice or open
 types this way.
 
-For historical interoperability reasons, our decoder accepts the
-indefinite length form for constructed tags, which is allowed by BER
-but not DER.  We still require the primitive forms of basic scalar
-types, however, so we do not accept all BER encodings of ASN.1 values.
-
 
 Debugging
 ---------
index cd6b879f776a414d1a9de3bfdd5349c5d2c08148..c4140021e5e041d01d9328fc2960f30fffb457da 100644 (file)
@@ -191,11 +191,11 @@ k5_asn1_decode_int(const uint8_t *asn1, size_t len, intmax_t *val)
     if (len == 0)
         return ASN1_BAD_LENGTH;
     n = (asn1[0] & 0x80) ? -1 : 0;
-    /* Check length; allow extra octet if first octet is 0. */
-    if (len > sizeof(intmax_t) + (asn1[0] == 0))
+    /* Check length. */
+    if (len > sizeof(intmax_t))
         return ASN1_OVERFLOW;
     for (i = 0; i < len; i++)
-        n = (n << 8) | asn1[i];
+        n = n * 256 + asn1[i];
     *val = n;
     return 0;
 }
@@ -244,6 +244,7 @@ k5_asn1_decode_generaltime(const uint8_t *asn1, size_t len, time_t *time_out)
     const char *s = (char *)asn1;
     struct tm ts;
     time_t t;
+    size_t i;
 
     *time_out = 0;
     if (len != 15)
@@ -256,6 +257,10 @@ k5_asn1_decode_generaltime(const uint8_t *asn1, size_t len, time_t *time_out)
         return 0;
     }
 #define c2i(c) ((c) - '0')
+    for (i = 0; i < 14; ++i) {
+        if ((uint8_t)c2i(s[i]) > 9)
+            return ASN1_BAD_TIMEFORMAT;
+    }
     ts.tm_year = 1000 * c2i(s[0]) + 100 * c2i(s[1]) + 10 * c2i(s[2]) +
         c2i(s[3]) - 1900;
     ts.tm_mon = 10 * c2i(s[4]) + c2i(s[5]) - 1;
@@ -344,25 +349,19 @@ make_tag(asn1buf *buf, const taginfo *t, size_t len)
 }
 
 /*
- * Read a BER tag and length from asn1/len.  Place the tag parameters in
+ * Read a DER tag and length from asn1/len.  Place the tag parameters in
  * tag_out.  Set contents_out/clen_out to the octet range of the tag's
  * contents, and remainder_out/rlen_out to the octet range after the end of the
- * BER encoding.
- *
- * (krb5 ASN.1 encodings should be in DER, but for compatibility with some
- * really ancient implementations we handle the indefinite length form in tags.
- * However, we still insist on the primitive form of string types.)
+ * DER encoding.
  */
 static krb5_error_code
 get_tag(const uint8_t *asn1, size_t len, taginfo *tag_out,
         const uint8_t **contents_out, size_t *clen_out,
-        const uint8_t **remainder_out, size_t *rlen_out, int recursion)
+        const uint8_t **remainder_out, size_t *rlen_out)
 {
-    krb5_error_code ret;
     uint8_t o;
-    const uint8_t *c, *p, *tag_start = asn1;
+    const uint8_t *tag_start = asn1;
     size_t clen, llen, i;
-    taginfo t;
 
     *contents_out = *remainder_out = NULL;
     *clen_out = *rlen_out = 0;
@@ -379,10 +378,15 @@ get_tag(const uint8_t *asn1, size_t len, taginfo *tag_out,
         do {
             if (len == 0)
                 return ASN1_OVERRUN;
+            if (tag_out->tagnum > (ASN1_TAGNUM_MAX >> 7))
+                return ASN1_OVERFLOW;
             o = *asn1++;
             len--;
             tag_out->tagnum = (tag_out->tagnum << 7) | (o & 0x7F);
         } while (o & 0x80);
+        /* Check for overly large tag values */
+        if (tag_out->tagnum > ASN1_TAGNUM_MAX)
+            return ASN1_OVERFLOW;
     }
 
     if (len == 0)
@@ -390,28 +394,10 @@ get_tag(const uint8_t *asn1, size_t len, taginfo *tag_out,
     o = *asn1++;
     len--;
 
-    if (o == 0x80) {
-        /* Indefinite form (should not be present in DER, but we accept it). */
-        if (tag_out->construction != CONSTRUCTED)
-            return ASN1_MISMATCH_INDEF;
-        if (recursion >= 32)
-            return ASN1_OVERFLOW;
-        p = asn1;
-        while (!(len >= 2 && p[0] == 0 && p[1] == 0)) {
-            ret = get_tag(p, len, &t, &c, &clen, &p, &len, recursion + 1);
-            if (ret)
-                return ret;
-        }
-        tag_out->tag_end_len = 2;
-        *contents_out = asn1;
-        *clen_out = p - asn1;
-        *remainder_out = p + 2;
-        *rlen_out = len - 2;
-    } else if ((o & 0x80) == 0) {
+    if ((o & 0x80) == 0) {
         /* Short form (first octet gives content length). */
         if (o > len)
             return ASN1_OVERRUN;
-        tag_out->tag_end_len = 0;
         *contents_out = asn1;
         *clen_out = o;
         *remainder_out = asn1 + *clen_out;
@@ -423,11 +409,12 @@ get_tag(const uint8_t *asn1, size_t len, taginfo *tag_out,
             return ASN1_OVERRUN;
         if (llen > sizeof(*clen_out))
             return ASN1_OVERFLOW;
+        if (llen == 0)
+            return ASN1_INDEF;
         for (i = 0, clen = 0; i < llen; i++)
             clen = (clen << 8) | asn1[i];
         if (clen > len - llen)
             return ASN1_OVERRUN;
-        tag_out->tag_end_len = 0;
         *contents_out = asn1 + llen;
         *clen_out = clen;
         *remainder_out = *contents_out + clen;
@@ -615,7 +602,7 @@ split_der(asn1buf *buf, uint8_t *const *der, size_t len, taginfo *tag_out)
     const uint8_t *contents, *remainder;
     size_t clen, rlen;
 
-    ret = get_tag(*der, len, tag_out, &contents, &clen, &remainder, &rlen, 0);
+    ret = get_tag(*der, len, tag_out, &contents, &clen, &remainder, &rlen);
     if (ret)
         return ret;
     if (rlen != 0)
@@ -637,7 +624,7 @@ store_der(const taginfo *t, const uint8_t *asn1, size_t len, void *val,
     size_t der_len;
 
     *count_out = 0;
-    der_len = t->tag_len + len + t->tag_end_len;
+    der_len = t->tag_len + len;
     der = malloc(der_len);
     if (der == NULL)
         return ENOMEM;
@@ -1201,10 +1188,11 @@ decode_atype(const taginfo *t, const uint8_t *asn1, size_t len,
         const uint8_t *rem;
         size_t rlen;
         if (!tag->implicit) {
-            ret = get_tag(asn1, len, &inner_tag, &asn1, &len, &rem, &rlen, 0);
+            ret = get_tag(asn1, len, &inner_tag, &asn1, &len, &rem, &rlen);
             if (ret)
                 return ret;
-            /* Note: we don't check rlen (it should be 0). */
+            if (rlen)
+                return ASN1_BAD_LENGTH;
             tp = &inner_tag;
             if (!check_atype_tag(tag->basetype, tp))
                 return ASN1_BAD_ID;
@@ -1422,7 +1410,7 @@ decode_sequence(const uint8_t *asn1, size_t len, const struct seq_info *seq,
     for (i = 0; i < seq->n_fields; i++) {
         if (len == 0)
             break;
-        ret = get_tag(asn1, len, &t, &contents, &clen, &asn1, &len, 0);
+        ret = get_tag(asn1, len, &t, &contents, &clen, &asn1, &len);
         if (ret)
             goto error;
         /*
@@ -1480,7 +1468,7 @@ decode_sequence_of(const uint8_t *asn1, size_t len,
     *seq_out = NULL;
     *count_out = 0;
     while (len > 0) {
-        ret = get_tag(asn1, len, &t, &contents, &clen, &asn1, &len, 0);
+        ret = get_tag(asn1, len, &t, &contents, &clen, &asn1, &len);
         if (ret)
             goto error;
         if (!check_atype_tag(elemtype, &t)) {
@@ -1586,7 +1574,7 @@ k5_asn1_full_decode(const krb5_data *code, const struct atype_info *a,
 
     *retrep = NULL;
     ret = get_tag((uint8_t *)code->data, code->length, &t, &contents,
-                  &clen, &remainder, &rlen, 0);
+                  &clen, &remainder, &rlen);
     if (ret)
         return ret;
     /* rlen should be 0, but we don't check it (and due to padding in
index fde875b5736f84dcfdc108c1f8070431b655c582..118f5cadb130fc2089a91ddf1e286c29e228c8cc 100644 (file)
@@ -38,10 +38,9 @@ typedef struct {
     asn1_construction construction;
     asn1_tagnum tagnum;
 
-    /* When decoding, stores the leading and trailing lengths of a tag.  Used
-     * by store_der(). */
+    /* When decoding, stores the leading length of a tag.  Used by
+     * store_der(). */
     size_t tag_len;
-    size_t tag_end_len;
 } taginfo;
 
 /* These functions are referenced by encoder structures.  They handle the
index 39fa8e3bbb2301466493b7bf0bd494c2a4863924..3ce4bd59e0eed55305b985725128adfefa632454 100644 (file)
@@ -334,11 +334,6 @@ decode_lr_type(const taginfo *t, const uint8_t *asn1, size_t len, void *p)
         return ret;
     if (val > INT32_MAX || val < INT32_MIN)
         return ASN1_OVERFLOW;
-#ifdef KRB5_GENEROUS_LR_TYPE
-    /* If type is in the 128-255 range, treat it as a negative 8-bit value. */
-    if (val >= 128 && val <= 255)
-        val -= 256;
-#endif
     *(int32_t *)p = val;
     return 0;
 }
index c580335396fa4c7829168558283389090503ca43..59d7fd98eece37f3f0d0bba985291bbb5a71f7af 100644 (file)
 #include <stdlib.h>
 #endif
 
-/*
- * If KRB5_MSGTYPE_STRICT is defined, then be strict about checking
- * the msgtype fields.  Unfortunately, there old versions of Kerberos
- * don't set these fields correctly, so we have to make allowances for
- * them.
- */
-/* #define KRB5_MSGTYPE_STRICT */
-
-/*
- * If KRB5_GENEROUS_LR_TYPE is defined, then we are generous about
- * accepting a one byte negative lr_type - which is not sign
- * extended. Prior to July 2000, we were sending a negative lr_type as
- * a positive single byte value - instead of a signed integer. This
- * allows us to receive the old value and deal
- */
-#define KRB5_GENEROUS_LR_TYPE
-
 typedef krb5_error_code asn1_error_code;
 
 typedef enum { PRIMITIVE = 0x00, CONSTRUCTED = 0x20 } asn1_construction;
index 30c43564124eba0d6b16c4826668d1fd03f4c7d2..a448bb59798dd3cc0dc0514951d6ecc1f134e80c 100644 (file)
@@ -10,7 +10,7 @@ error_code ASN1_BAD_LENGTH, "ASN.1 length doesn't match expected value"
 error_code ASN1_BAD_FORMAT, "ASN.1 badly-formatted encoding"
 error_code ASN1_PARSE_ERROR, "ASN.1 parse error"
 error_code ASN1_BAD_GMTIME, "ASN.1 bad return from gmtime"
-error_code ASN1_MISMATCH_INDEF, "ASN.1 non-constructed indefinite encoding"
+error_code ASN1_INDEF, "ASN.1 indefinite encoding"
 error_code ASN1_MISSING_EOC, "ASN.1 missing expected EOC"
 error_code ASN1_OMITTED, "ASN.1 object omitted in sequence"
 end
index 7a116b40d9ea6ae11ff6718541b639f0f922d53b..c1484715455f2c039f6b858bace8912552cb5e8e 100644 (file)
@@ -72,8 +72,9 @@ int main(argc, argv)
 #define setup(type,constructor)                                         \
     type ref, *var;                                                     \
     constructor(&ref);                                                  \
+    do {} while (0)
 
-#define decode_run(typestring,description,encoding,decoder,comparator,cleanup) \
+#define decode_run(typestring,description,encoding,decoder,comparator,cleanup) do { \
     retval = krb5_data_hex_parse(&code,encoding);                       \
     if (retval) {                                                       \
         com_err("krb5_decode_test", retval, "while parsing %s", typestring); \
@@ -87,7 +88,23 @@ int main(argc, argv)
     test(comparator(&ref,var),typestring);                              \
     printf("%s\n",description);                                         \
     krb5_free_data_contents(test_context, &code);                       \
-    cleanup(test_context, var);
+    cleanup(test_context, var);                                         \
+} while (0)
+
+#define decode_fail(err,typestring,description,encoding,decoder) do {   \
+    retval = krb5_data_hex_parse(&code,encoding);                       \
+    if (retval) {                                                       \
+        com_err("krb5_decode_test", retval, "while parsing %s", typestring); \
+        exit(1);                                                        \
+    }                                                                   \
+    retval = decoder(&code,&var);                                       \
+    if (retval != (err)) {                                              \
+        com_err("krb5_decode_test", retval, "while decoding %s", typestring); \
+        error_count++;                                                  \
+    }                                                                   \
+    test(1,typestring);                                                 \
+    printf("%s\n",description);                                         \
+} while (0)
 
     /****************************************************************/
     /* decode_krb5_authenticator */
@@ -303,7 +320,7 @@ int main(argc, argv)
   "  00 00 00 00"
   "00 00 00 00"
 */
-        decode_run("ticket","(indefinite lengths)", "61 80 30 80 A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 80 30 80 A0 03 02 01 01 A1 80 30 80 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 00 00 00 00 00 00 00 00 A3 80 30 80 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 00 00 00 00 00 00 00 00" ,decode_krb5_ticket,ktest_equal_ticket,krb5_free_ticket);
+        decode_fail(ASN1_INDEF,"ticket","(indefinite lengths)", "61 80 30 80 A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 80 30 80 A0 03 02 01 01 A1 80 30 80 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 00 00 00 00 00 00 00 00 A3 80 30 80 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 00 00 00 00 00 00 00 00" ,decode_krb5_ticket);
 /*
   "61 80 30 80 "
   "  A0 03 02 01 05 "
@@ -324,7 +341,7 @@ int main(argc, argv)
   "  A4 03 02 01 01 "
   "00 00 00 00"
 */
-        decode_run("ticket","(indefinite lengths + trailing [4] INTEGER)", "61 80 30 80 A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 80 30 80 A0 03 02 01 01 A1 80 30 80 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 00 00 00 00 00 00 00 00 A3 80 30 80 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 00 00 00 00 A4 03 02 01 01 00 00 00 00",decode_krb5_ticket,ktest_equal_ticket,krb5_free_ticket);
+        decode_fail(ASN1_INDEF,"ticket","(indefinite lengths + trailing [4] INTEGER)", "61 80 30 80 A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 80 30 80 A0 03 02 01 01 A1 80 30 80 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 00 00 00 00 00 00 00 00 A3 80 30 80 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 00 00 00 00 A4 03 02 01 01 00 00 00 00",decode_krb5_ticket);
 
         ktest_empty_ticket(&ref);
 
@@ -339,10 +356,10 @@ int main(argc, argv)
 
         decode_run("encryption_key","(+ trailing [2] INTEGER)","30 16 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A2 03 02 01 01",decode_krb5_encryption_key,ktest_equal_encryption_key,krb5_free_keyblock);
         decode_run("encryption_key","(+ trailing [2] SEQUENCE {[0] INTEGER})","30 1A A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A2 07 30 05 A0 03 02 01 01",decode_krb5_encryption_key,ktest_equal_encryption_key,krb5_free_keyblock);
-        decode_run("encryption_key","(indefinite lengths)","30 80 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 00 00",decode_krb5_encryption_key,ktest_equal_encryption_key,krb5_free_keyblock);
-        decode_run("encryption_key","(indefinite lengths + trailing [2] INTEGER)","30 80 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A2 03 02 01 01 00 00",decode_krb5_encryption_key,ktest_equal_encryption_key,krb5_free_keyblock);
-        decode_run("encryption_key","(indefinite lengths + trailing [2] SEQUENCE {[0] INTEGER})","30 80 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A2 80 30 80 A0 03 02 01 01 00 00 00 00 00 00",decode_krb5_encryption_key,ktest_equal_encryption_key,krb5_free_keyblock);
-        decode_run("encryption_key","(indefinite lengths + trailing SEQUENCE {[0] INTEGER})","30 80 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 30 80 A0 03 02 01 01 00 00 00 00",decode_krb5_encryption_key,ktest_equal_encryption_key,krb5_free_keyblock);
+        decode_fail(ASN1_INDEF,"encryption_key","(indefinite lengths)","30 80 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 00 00",decode_krb5_encryption_key);
+        decode_fail(ASN1_INDEF,"encryption_key","(indefinite lengths + trailing [2] INTEGER)","30 80 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A2 03 02 01 01 00 00",decode_krb5_encryption_key);
+        decode_fail(ASN1_INDEF,"encryption_key","(indefinite lengths + trailing [2] SEQUENCE {[0] INTEGER})","30 80 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A2 80 30 80 A0 03 02 01 01 00 00 00 00 00 00",decode_krb5_encryption_key);
+        decode_fail(ASN1_INDEF,"encryption_key","(indefinite lengths + trailing SEQUENCE {[0] INTEGER})","30 80 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 30 80 A0 03 02 01 01 00 00 00 00",decode_krb5_encryption_key);
         ref.enctype = -1;
         decode_run("encryption_key","(enctype = -1)","30 11 A0 03 02 01 FF A1 0A 04 08 31 32 33 34 35 36 37 38",decode_krb5_encryption_key,ktest_equal_encryption_key,krb5_free_keyblock);
         ref.enctype = -255;
@@ -393,10 +410,6 @@ int main(argc, argv)
     {
         setup(krb5_enc_kdc_rep_part,ktest_make_sample_enc_kdc_rep_part);
 
-#ifdef KRB5_GENEROUS_LR_TYPE
-        decode_run("enc_kdc_rep_part","(compat_lr_type)","7A 82 01 10 30 82 01 0C A0 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A1 38 30 36 30 19 A0 04 02 02 00 FB A1 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A 30 19 A0 04 02 02 00 FB A1 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A2 03 02 01 2A A3 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A4 07 03 05 00 FE DC BA 98 A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A6 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A8 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A9 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 AA 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 AB 20 30 1E 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23",decode_krb5_enc_kdc_rep_part,ktest_equal_enc_kdc_rep_part,krb5_free_enc_kdc_rep_part);
-#endif
-
         decode_run("enc_kdc_rep_part","","7A 82 01 0E 30 82 01 0A A0 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A1 36 30 34 30 18 A0 03 02 01 FB A1 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A 30 18 A0 03 02 01 FB A1 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A2 03 02 01 2A A3 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A4 07 03 05 00 FE DC BA 98 A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A6 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A8 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A9 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 AA 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 AB 20 30 1E 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23",decode_krb5_enc_kdc_rep_part,ktest_equal_enc_kdc_rep_part,krb5_free_enc_kdc_rep_part);
 
         ref.key_exp = 0;
@@ -406,10 +419,6 @@ int main(argc, argv)
         ref.flags &= ~TKT_FLG_RENEWABLE;
         ktest_destroy_addresses(&(ref.caddrs));
 
-#ifdef KRB5_GENEROUS_LR_TYPE
-        decode_run("enc_kdc_rep_part","(optionals NULL)(compat lr_type)","7A 81 B4 30 81 B1 A0 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A1 38 30 36 30 19 A0 04 02 02 00 FB A1 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A 30 19 A0 04 02 02 00 FB A1 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A2 03 02 01 2A A4 07 03 05 00 FE 5C BA 98 A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A9 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 AA 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61",decode_krb5_enc_kdc_rep_part,ktest_equal_enc_kdc_rep_part,krb5_free_enc_kdc_rep_part);
-#endif
-
         decode_run("enc_kdc_rep_part","(optionals NULL)","7A 81 B2 30 81 AF A0 13 30 11 A0 03 02 01 01 A1 0A 04 08 31 32 33 34 35 36 37 38 A1 36 30 34 30 18 A0 03 02 01 FB A1 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A 30 18 A0 03 02 01 FB A1 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A2 03 02 01 2A A4 07 03 05 00 FE 5C BA 98 A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A9 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 AA 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61",decode_krb5_enc_kdc_rep_part,ktest_equal_enc_kdc_rep_part,krb5_free_enc_kdc_rep_part);
 
         ktest_empty_enc_kdc_rep_part(&ref);
@@ -472,7 +481,7 @@ int main(argc, argv)
   00 00 00 00
   00 00 00 00
 */
-        decode_run("as_rep","(indefinite lengths)","6B 80 30 80 A0 03 02 01 05 A1 03 02 01 0B A2 80 30 80 30 80 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 00 00 30 80 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 00 00 00 00 00 00 A3 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A4 80 30 80 A0 03 02 01 01 A1 80 30 80 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 00 00 00 00 00 00 00 00 A5 80 61 80 30 80 A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 80 30 80 A0 03 02 01 01 A1 80 30 80 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 00 00 00 00 00 00 00 00 A3 80 30 80 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 00 00 00 00 00 00 00 00 00 00 A6 80 30 80 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 00 00 00 00 00 00 00 00",decode_krb5_as_rep,ktest_equal_as_rep,krb5_free_kdc_rep);
+        decode_fail(ASN1_INDEF,"as_rep","(indefinite lengths)","6B 80 30 80 A0 03 02 01 05 A1 03 02 01 0B A2 80 30 80 30 80 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 00 00 30 80 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 00 00 00 00 00 00 A3 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A4 80 30 80 A0 03 02 01 01 A1 80 30 80 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 00 00 00 00 00 00 00 00 A5 80 61 80 30 80 A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 80 30 80 A0 03 02 01 01 A1 80 30 80 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 00 00 00 00 00 00 00 00 A3 80 30 80 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 00 00 00 00 00 00 00 00 00 00 A6 80 30 80 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 00 00 00 00 00 00 00 00",decode_krb5_as_rep);
         ktest_destroy_pa_data_array(&(ref.padata));
         decode_run("as_rep","(optionals NULL)","6B 81 C2 30 81 BF A0 03 02 01 05 A1 03 02 01 0B A3 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A4 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A5 5E 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 A6 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65",decode_krb5_as_rep,ktest_equal_as_rep,krb5_free_kdc_rep);