From: Jouni Malinen Date: Sat, 13 Mar 2021 21:11:41 +0000 (+0200) Subject: ASN.1: Explicitly validate constructed bit while parsing DER X-Git-Tag: hostap_2_10~420 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d6831a0e93bb13830793abb731499da9434619d8;p=thirdparty%2Fhostap.git ASN.1: Explicitly validate constructed bit while parsing DER 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 --- diff --git a/src/tls/asn1.c b/src/tls/asn1.c index d4611edaf..f4d06e556 100644 --- a/src/tls/asn1.c +++ b/src/tls/asn1.c @@ -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; }