TLS: Move ASN.1 DER BOOLEAN validation into generic ASN.1 parsing
This does not need to be specific to X.509, so move the BOOLEAN DER encoding validation into asn1_get_next() to make it apply for all cases instead of having to have the caller handle this separately. Signed-off-by: Jouni Malinen <j@w1.fi>
This commit is contained in:
parent
34c1b75c82
commit
702cc6da1a
2 changed files with 32 additions and 24 deletions
|
@ -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)
|
int asn1_get_next(const u8 *buf, size_t len, struct asn1_hdr *hdr)
|
||||||
{
|
{
|
||||||
const u8 *pos, *end;
|
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;
|
hdr->payload = pos;
|
||||||
return 0;
|
|
||||||
|
return asn1_valid_der(hdr) ? 0 : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -846,18 +846,6 @@ static int x509_parse_ext_basic_constraints(struct x509_certificate *cert,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hdr.tag == ASN1_TAG_BOOLEAN) {
|
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];
|
cert->ca = hdr.payload[0];
|
||||||
|
|
||||||
pos = hdr.payload + hdr.length;
|
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.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];
|
critical_ext = hdr.payload[0];
|
||||||
pos = hdr.payload;
|
pos = hdr.payload;
|
||||||
if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
|
if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
|
||||||
|
|
Loading…
Reference in a new issue