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 <j@w1.fi>
This commit is contained in:
parent
d6831a0e93
commit
3af75f23b0
1 changed files with 17 additions and 0 deletions
|
@ -186,18 +186,35 @@ int asn1_get_next(const u8 *buf, size_t len, struct asn1_hdr *hdr)
|
||||||
hdr->constructed = !!(hdr->identifier & (1 << 5));
|
hdr->constructed = !!(hdr->identifier & (1 << 5));
|
||||||
|
|
||||||
if ((hdr->identifier & 0x1f) == 0x1f) {
|
if ((hdr->identifier & 0x1f) == 0x1f) {
|
||||||
|
size_t ext_len = 0;
|
||||||
|
|
||||||
hdr->tag = 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 {
|
do {
|
||||||
if (pos >= end) {
|
if (pos >= end) {
|
||||||
wpa_printf(MSG_DEBUG, "ASN.1: Identifier "
|
wpa_printf(MSG_DEBUG, "ASN.1: Identifier "
|
||||||
"underflow");
|
"underflow");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
ext_len++;
|
||||||
tmp = *pos++;
|
tmp = *pos++;
|
||||||
wpa_printf(MSG_MSGDUMP, "ASN.1: Extended tag data: "
|
wpa_printf(MSG_MSGDUMP, "ASN.1: Extended tag data: "
|
||||||
"0x%02x", tmp);
|
"0x%02x", tmp);
|
||||||
hdr->tag = (hdr->tag << 7) | (tmp & 0x7f);
|
hdr->tag = (hdr->tag << 7) | (tmp & 0x7f);
|
||||||
} while (tmp & 0x80);
|
} 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
|
} else
|
||||||
hdr->tag = hdr->identifier & 0x1f;
|
hdr->tag = hdr->identifier & 0x1f;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue