diff --git a/src/tls/asn1.c b/src/tls/asn1.c index 822f87c18..a08c2e1e3 100644 --- a/src/tls/asn1.c +++ b/src/tls/asn1.c @@ -22,6 +22,36 @@ struct asn1_oid asn1_sha256_oid = { }; +static int asn1_valid_der_boolean(struct asn1_hdr *hdr) +{ + /* Enforce DER requirements for a single way of encoding a BOOLEAN */ + if (hdr->length != 1) { + wpa_printf(MSG_DEBUG, "ASN.1: Unexpected BOOLEAN length (%u)", + hdr->length); + return 0; + } + + if (hdr->payload[0] != 0 && hdr->payload[0] != 0xff) { + wpa_printf(MSG_DEBUG, + "ASN.1: Invalid BOOLEAN value 0x%x (DER requires 0 or 0xff)", + hdr->payload[0]); + return 0; + } + + return 1; +} + + +static int asn1_valid_der(struct asn1_hdr *hdr) +{ + if (hdr->class != ASN1_CLASS_UNIVERSAL) + return 1; + if (hdr->tag == ASN1_TAG_BOOLEAN && !asn1_valid_der_boolean(hdr)) + return 0; + return 1; +} + + int asn1_get_next(const u8 *buf, size_t len, struct asn1_hdr *hdr) { const u8 *pos, *end; @@ -91,7 +121,8 @@ int asn1_get_next(const u8 *buf, size_t len, struct asn1_hdr *hdr) } hdr->payload = pos; - return 0; + + return asn1_valid_der(hdr) ? 0 : -1; } diff --git a/src/tls/x509v3.c b/src/tls/x509v3.c index 76b6ba159..1bd5aa009 100644 --- a/src/tls/x509v3.c +++ b/src/tls/x509v3.c @@ -846,18 +846,6 @@ static int x509_parse_ext_basic_constraints(struct x509_certificate *cert, } if (hdr.tag == ASN1_TAG_BOOLEAN) { - if (hdr.length != 1) { - wpa_printf(MSG_DEBUG, "X509: Unexpected " - "Boolean length (%u) in BasicConstraints", - hdr.length); - return -1; - } - if (hdr.payload[0] != 0 && hdr.payload[0] != 0xff) { - wpa_printf(MSG_DEBUG, - "X509: Invalid cA BOOLEAN value 0x%x in BasicConstraints (DER requires 0 or 0xff)", - hdr.payload[0]); - return -1; - } cert->ca = hdr.payload[0]; pos = hdr.payload + hdr.length; @@ -1313,17 +1301,6 @@ static int x509_parse_extension(struct x509_certificate *cert, } if (hdr.tag == ASN1_TAG_BOOLEAN) { - if (hdr.length != 1) { - wpa_printf(MSG_DEBUG, "X509: Unexpected " - "Boolean length (%u)", hdr.length); - return -1; - } - if (hdr.payload[0] != 0 && hdr.payload[0] != 0xff) { - wpa_printf(MSG_DEBUG, - "X509: Invalid critical BOOLEAN value 0x%x in Extension (DER requires 0 or 0xff)", - hdr.payload[0]); - return -1; - } critical_ext = hdr.payload[0]; pos = hdr.payload; if (asn1_get_next(pos, end - pos, &hdr) < 0 ||