]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
ASN.1: Explicitly validate constructed bit while parsing DER
authorJouni Malinen <j@w1.fi>
Sat, 13 Mar 2021 21:11:41 +0000 (23:11 +0200)
committerJouni Malinen <j@w1.fi>
Sun, 14 Mar 2021 09:37:58 +0000 (11:37 +0200)
The identifier octet in DER encoding includes three components. Only two
of these (Class and Tag) were checked in most cases when looking for a
specific data type. Also check the Primitive/Constructed bit to avoid
accepting invalid encoding.

This is needed for correct behavior in DER parsing and especially
important for the case of verifying DER encoded signatures to prevent
potential forging attacks.

Signed-off-by: Jouni Malinen <j@w1.fi>
src/tls/asn1.c

index d4611edaf5a0aedb87cac9bc755fa083e5c6595a..f4d06e5569e68edc9f4e72bd41816a0191feeec1 100644 (file)
@@ -131,6 +131,39 @@ static int asn1_valid_der(struct asn1_hdr *hdr)
                return 0;
        if (hdr->tag == ASN1_TAG_NULL && hdr->length != 0)
                return 0;
+
+       /* Check for allowed primitive/constructed values */
+       if (hdr->constructed &&
+           (hdr->tag == ASN1_TAG_BOOLEAN ||
+            hdr->tag == ASN1_TAG_INTEGER ||
+            hdr->tag == ASN1_TAG_NULL ||
+            hdr->tag == ASN1_TAG_OID ||
+            hdr->tag == ANS1_TAG_RELATIVE_OID ||
+            hdr->tag == ASN1_TAG_REAL ||
+            hdr->tag == ASN1_TAG_ENUMERATED ||
+            hdr->tag == ASN1_TAG_BITSTRING ||
+            hdr->tag == ASN1_TAG_OCTETSTRING ||
+            hdr->tag == ASN1_TAG_NUMERICSTRING ||
+            hdr->tag == ASN1_TAG_PRINTABLESTRING ||
+            hdr->tag == ASN1_TAG_T61STRING ||
+            hdr->tag == ASN1_TAG_VIDEOTEXSTRING ||
+            hdr->tag == ASN1_TAG_VISIBLESTRING ||
+            hdr->tag == ASN1_TAG_IA5STRING ||
+            hdr->tag == ASN1_TAG_GRAPHICSTRING ||
+            hdr->tag == ASN1_TAG_GENERALSTRING ||
+            hdr->tag == ASN1_TAG_UNIVERSALSTRING ||
+            hdr->tag == ASN1_TAG_UTF8STRING ||
+            hdr->tag == ASN1_TAG_BMPSTRING ||
+            hdr->tag == ASN1_TAG_CHARACTERSTRING ||
+            hdr->tag == ASN1_TAG_UTCTIME ||
+            hdr->tag == ASN1_TAG_GENERALIZEDTIME ||
+            hdr->tag == ASN1_TAG_TIME))
+               return 0;
+       if (!hdr->constructed &&
+           (hdr->tag == ASN1_TAG_SEQUENCE ||
+            hdr->tag == ASN1_TAG_SET))
+               return 0;
+
        return 1;
 }