From 3af75f23b0899e095f3c593565009b121f7f0d1a Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Sat, 13 Mar 2021 16:49:07 +0200 Subject: [PATCH] ASN.1: Reject invalid extended tags in DER encoding The extended tag case is allowed only for tag values that are 31 or larger (i.e., the ones that would not fit in the single octet identifier case with five bits). Extended tag format was previously accepted even for the values 0..31 and this would enable multiple different encodings for the same tag value. That is not allowed for DER. Perform more strict checks to reject invalid extended tag values. This is needed for a compliant implementation and this is especially important for the case of verifying DER encoded signatures to prevent potential forging attacks. Signed-off-by: Jouni Malinen --- src/tls/asn1.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/tls/asn1.c b/src/tls/asn1.c index f4d06e556..57e2d5387 100644 --- a/src/tls/asn1.c +++ b/src/tls/asn1.c @@ -186,18 +186,35 @@ int asn1_get_next(const u8 *buf, size_t len, struct asn1_hdr *hdr) hdr->constructed = !!(hdr->identifier & (1 << 5)); if ((hdr->identifier & 0x1f) == 0x1f) { + size_t ext_len = 0; + hdr->tag = 0; + if (pos == end || (*pos & 0x7f) == 0) { + wpa_printf(MSG_DEBUG, + "ASN.1: Invalid extended tag (first octet has to be included with at least one nonzero bit for the tag value)"); + return -1; + } do { if (pos >= end) { wpa_printf(MSG_DEBUG, "ASN.1: Identifier " "underflow"); return -1; } + ext_len++; tmp = *pos++; wpa_printf(MSG_MSGDUMP, "ASN.1: Extended tag data: " "0x%02x", tmp); hdr->tag = (hdr->tag << 7) | (tmp & 0x7f); } while (tmp & 0x80); + wpa_printf(MSG_MSGDUMP, "ASN.1: Extended Tag: 0x%x (len=%zu)", + hdr->tag, ext_len); + if ((hdr->class != ASN1_CLASS_PRIVATE && hdr->tag < 31) || + ext_len * 7 > sizeof(hdr->tag) * 8) { + wpa_printf(MSG_DEBUG, + "ASN.1: Invalid or unsupported (too large) extended Tag: 0x%x (len=%zu)", + hdr->tag, ext_len); + return -1; + } } else hdr->tag = hdr->identifier & 0x1f;