TLS: Use ASN.1 helper functions

Simplify ASN.1 parser operations by using the shared helper functions.

Signed-off-by: Jouni Malinen <j@w1.fi>
This commit is contained in:
Jouni Malinen 2021-03-12 23:24:54 +02:00
parent d4e1d76dbf
commit 626035bec7
2 changed files with 154 additions and 265 deletions

View file

@ -138,12 +138,8 @@ static int tls_process_ocsp_single_response(struct tlsv1_client *conn,
*/ */
/* CertID ::= SEQUENCE */ /* CertID ::= SEQUENCE */
if (asn1_get_next(resp, len, &hdr) < 0 || if (asn1_get_next(resp, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
hdr.class != ASN1_CLASS_UNIVERSAL || asn1_unexpected(&hdr, "OCSP: Expected SEQUENCE (CertID)");
hdr.tag != ASN1_TAG_SEQUENCE) {
wpa_printf(MSG_DEBUG,
"OCSP: Expected SEQUENCE (CertID) - found class %d tag 0x%x",
hdr.class, hdr.tag);
return -1; return -1;
} }
pos = hdr.payload; pos = hdr.payload;
@ -163,11 +159,9 @@ static int tls_process_ocsp_single_response(struct tlsv1_client *conn,
/* issuerNameHash OCTET STRING */ /* issuerNameHash OCTET STRING */
if (asn1_get_next(pos, end - pos, &hdr) < 0 || if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
hdr.class != ASN1_CLASS_UNIVERSAL || !asn1_is_octetstring(&hdr)) {
hdr.tag != ASN1_TAG_OCTETSTRING) { asn1_unexpected(&hdr,
wpa_printf(MSG_DEBUG, "OCSP: Expected OCTET STRING (issuerNameHash)");
"OCSP: Expected OCTET STRING (issuerNameHash) - found class %d tag 0x%x",
hdr.class, hdr.tag);
return -1; return -1;
} }
name_hash = hdr.payload; name_hash = hdr.payload;
@ -190,11 +184,9 @@ static int tls_process_ocsp_single_response(struct tlsv1_client *conn,
/* issuerKeyHash OCTET STRING */ /* issuerKeyHash OCTET STRING */
if (asn1_get_next(pos, end - pos, &hdr) < 0 || if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
hdr.class != ASN1_CLASS_UNIVERSAL || !asn1_is_octetstring(&hdr)) {
hdr.tag != ASN1_TAG_OCTETSTRING) { asn1_unexpected(&hdr,
wpa_printf(MSG_DEBUG, "OCSP: Expected OCTET STRING (issuerKeyHash)");
"OCSP: Expected OCTET STRING (issuerKeyHash) - found class %d tag 0x%x",
hdr.class, hdr.tag);
return -1; return -1;
} }
key_hash = hdr.payload; key_hash = hdr.payload;
@ -214,11 +206,10 @@ static int tls_process_ocsp_single_response(struct tlsv1_client *conn,
/* serialNumber CertificateSerialNumber ::= INTEGER */ /* serialNumber CertificateSerialNumber ::= INTEGER */
if (asn1_get_next(pos, end - pos, &hdr) < 0 || if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
hdr.class != ASN1_CLASS_UNIVERSAL || !asn1_is_integer(&hdr) ||
hdr.tag != ASN1_TAG_INTEGER ||
hdr.length < 1 || hdr.length > X509_MAX_SERIAL_NUM_LEN) { hdr.length < 1 || hdr.length > X509_MAX_SERIAL_NUM_LEN) {
wpa_printf(MSG_DEBUG, "OCSP: No INTEGER tag found for serialNumber; class=%d tag=0x%x length=%u", asn1_unexpected(&hdr,
hdr.class, hdr.tag, hdr.length); "OCSP: No INTEGER tag found for serialNumber");
return -1; return -1;
} }
serial_number = hdr.payload; serial_number = hdr.payload;
@ -240,12 +231,16 @@ static int tls_process_ocsp_single_response(struct tlsv1_client *conn,
pos = end; pos = end;
end = resp + len; end = resp + len;
/* certStatus CertStatus ::= CHOICE */ /* certStatus CertStatus ::= CHOICE
*
* CertStatus ::= CHOICE {
* good [0] IMPLICIT NULL,
* revoked [1] IMPLICIT RevokedInfo,
* unknown [2] IMPLICIT UnknownInfo }
*/
if (asn1_get_next(pos, end - pos, &hdr) < 0 || if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
hdr.class != ASN1_CLASS_CONTEXT_SPECIFIC) { hdr.class != ASN1_CLASS_CONTEXT_SPECIFIC) {
wpa_printf(MSG_DEBUG, asn1_unexpected(&hdr, "OCSP: Expected CHOICE (CertStatus)");
"OCSP: Expected CHOICE (CertStatus) - found class %d tag 0x%x",
hdr.class, hdr.tag);
return -1; return -1;
} }
cert_status = hdr.tag; cert_status = hdr.tag;
@ -257,8 +252,7 @@ static int tls_process_ocsp_single_response(struct tlsv1_client *conn,
os_get_time(&now); os_get_time(&now);
/* thisUpdate GeneralizedTime */ /* thisUpdate GeneralizedTime */
if (asn1_get_next(pos, end - pos, &hdr) < 0 || if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
hdr.class != ASN1_CLASS_UNIVERSAL || !asn1_is_generalizedtime(&hdr) ||
hdr.tag != ASN1_TAG_GENERALIZEDTIME ||
x509_parse_time(hdr.payload, hdr.length, hdr.tag, &update) < 0) { x509_parse_time(hdr.payload, hdr.length, hdr.tag, &update) < 0) {
wpa_printf(MSG_DEBUG, "OCSP: Failed to parse thisUpdate"); wpa_printf(MSG_DEBUG, "OCSP: Failed to parse thisUpdate");
return -1; return -1;
@ -275,12 +269,11 @@ static int tls_process_ocsp_single_response(struct tlsv1_client *conn,
if (pos < end) { if (pos < end) {
if (asn1_get_next(pos, end - pos, &hdr) < 0) if (asn1_get_next(pos, end - pos, &hdr) < 0)
return -1; return -1;
if (hdr.class == ASN1_CLASS_CONTEXT_SPECIFIC && hdr.tag == 0) { if (asn1_is_cs_tag(&hdr, 0) && hdr.constructed) {
const u8 *next = hdr.payload + hdr.length; const u8 *next = hdr.payload + hdr.length;
if (asn1_get_next(hdr.payload, hdr.length, &hdr) < 0 || if (asn1_get_next(hdr.payload, hdr.length, &hdr) < 0 ||
hdr.class != ASN1_CLASS_UNIVERSAL || !asn1_is_generalizedtime(&hdr) ||
hdr.tag != ASN1_TAG_GENERALIZEDTIME ||
x509_parse_time(hdr.payload, hdr.length, hdr.tag, x509_parse_time(hdr.payload, hdr.length, hdr.tag,
&update) < 0) { &update) < 0) {
wpa_printf(MSG_DEBUG, wpa_printf(MSG_DEBUG,
@ -329,11 +322,9 @@ tls_process_ocsp_responses(struct tlsv1_client *conn,
while (pos < end) { while (pos < end) {
/* SingleResponse ::= SEQUENCE */ /* SingleResponse ::= SEQUENCE */
if (asn1_get_next(pos, end - pos, &hdr) < 0 || if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
hdr.class != ASN1_CLASS_UNIVERSAL || !asn1_is_sequence(&hdr)) {
hdr.tag != ASN1_TAG_SEQUENCE) { asn1_unexpected(&hdr,
wpa_printf(MSG_DEBUG, "OCSP: Expected SEQUENCE (SingleResponse)");
"OCSP: Expected SEQUENCE (SingleResponse) - found class %d tag 0x%x",
hdr.class, hdr.tag);
return TLS_OCSP_INVALID; return TLS_OCSP_INVALID;
} }
if (tls_process_ocsp_single_response(conn, cert, issuer, if (tls_process_ocsp_single_response(conn, cert, issuer,
@ -381,12 +372,9 @@ tls_process_basic_ocsp_response(struct tlsv1_client *conn,
* certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL } * certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL }
*/ */
if (asn1_get_next(resp, len, &hdr) < 0 || if (asn1_get_next(resp, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
hdr.class != ASN1_CLASS_UNIVERSAL || asn1_unexpected(&hdr,
hdr.tag != ASN1_TAG_SEQUENCE) { "OCSP: Expected SEQUENCE (BasicOCSPResponse)");
wpa_printf(MSG_DEBUG,
"OCSP: Expected SEQUENCE (BasicOCSPResponse) - found class %d tag 0x%x",
hdr.class, hdr.tag);
return TLS_OCSP_INVALID; return TLS_OCSP_INVALID;
} }
pos = hdr.payload; pos = hdr.payload;
@ -394,11 +382,9 @@ tls_process_basic_ocsp_response(struct tlsv1_client *conn,
/* ResponseData ::= SEQUENCE */ /* ResponseData ::= SEQUENCE */
if (asn1_get_next(pos, end - pos, &hdr) < 0 || if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
hdr.class != ASN1_CLASS_UNIVERSAL || !asn1_is_sequence(&hdr)) {
hdr.tag != ASN1_TAG_SEQUENCE) { asn1_unexpected(&hdr,
wpa_printf(MSG_DEBUG, "OCSP: Expected SEQUENCE (ResponseData)");
"OCSP: Expected SEQUENCE (ResponseData) - found class %d tag 0x%x",
hdr.class, hdr.tag);
return TLS_OCSP_INVALID; return TLS_OCSP_INVALID;
} }
resp_data = hdr.payload; resp_data = hdr.payload;
@ -413,11 +399,9 @@ tls_process_basic_ocsp_response(struct tlsv1_client *conn,
/* signature BIT STRING */ /* signature BIT STRING */
if (asn1_get_next(pos, end - pos, &hdr) < 0 || if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
hdr.class != ASN1_CLASS_UNIVERSAL || !asn1_is_bitstring(&hdr)) {
hdr.tag != ASN1_TAG_BITSTRING) { asn1_unexpected(&hdr,
wpa_printf(MSG_DEBUG, "OCSP: Expected BITSTRING (signature)");
"OCSP: Expected BITSTRING (signature) - found class %d tag 0x%x",
hdr.class, hdr.tag);
return TLS_OCSP_INVALID; return TLS_OCSP_INVALID;
} }
if (hdr.length < 1) if (hdr.length < 1)
@ -439,11 +423,9 @@ tls_process_basic_ocsp_response(struct tlsv1_client *conn,
/* certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL */ /* certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL */
if (pos < end) { if (pos < end) {
if (asn1_get_next(pos, end - pos, &hdr) < 0 || if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
hdr.class != ASN1_CLASS_CONTEXT_SPECIFIC || !hdr.constructed || !asn1_is_cs_tag(&hdr, 0)) {
hdr.tag != 0) { asn1_unexpected(&hdr,
wpa_printf(MSG_DEBUG, "OCSP: Expected [0] EXPLICIT (certs)");
"OCSP: Expected [0] EXPLICIT (certs) - found class %d tag 0x%x",
hdr.class, hdr.tag);
return TLS_OCSP_INVALID; return TLS_OCSP_INVALID;
} }
wpa_hexdump(MSG_MSGDUMP, "OCSP: certs", wpa_hexdump(MSG_MSGDUMP, "OCSP: certs",
@ -454,11 +436,9 @@ tls_process_basic_ocsp_response(struct tlsv1_client *conn,
struct x509_certificate *cert; struct x509_certificate *cert;
if (asn1_get_next(pos, end - pos, &hdr) < 0 || if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
hdr.class != ASN1_CLASS_UNIVERSAL || !asn1_is_sequence(&hdr)) {
hdr.tag != ASN1_TAG_SEQUENCE) { asn1_unexpected(&hdr,
wpa_printf(MSG_DEBUG, "OCSP: Expected SEQUENCE (Certificate)");
"OCSP: Expected SEQUENCE (Certificate) - found class %d tag 0x%x",
hdr.class, hdr.tag);
goto fail; goto fail;
} }
@ -491,16 +471,12 @@ tls_process_basic_ocsp_response(struct tlsv1_client *conn,
* version [0] EXPLICIT Version DEFAULT v1 * version [0] EXPLICIT Version DEFAULT v1
* Version ::= INTEGER { v1(0) } * Version ::= INTEGER { v1(0) }
*/ */
if (asn1_get_next(pos, end - pos, &hdr) < 0 && if (asn1_get_next(pos, end - pos, &hdr) == 0 && hdr.constructed &&
hdr.class == ASN1_CLASS_CONTEXT_SPECIFIC && asn1_is_cs_tag(&hdr, 0)) {
hdr.tag == 0) {
if (asn1_get_next(pos, end - pos, &hdr) < 0 || if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
hdr.class != ASN1_CLASS_UNIVERSAL || !asn1_is_integer(&hdr) || hdr.length != 1) {
hdr.tag != ASN1_TAG_INTEGER || asn1_unexpected(&hdr,
hdr.length != 1) { "OCSP: No INTEGER (len=1) tag found for version field");
wpa_printf(MSG_DEBUG,
"OCSP: No INTEGER (len=1) tag found for version field - found class %d tag 0x%x length %d",
hdr.class, hdr.tag, hdr.length);
goto fail; goto fail;
} }
wpa_printf(MSG_DEBUG, "OCSP: ResponseData version %u", wpa_printf(MSG_DEBUG, "OCSP: ResponseData version %u",
@ -524,9 +500,7 @@ tls_process_basic_ocsp_response(struct tlsv1_client *conn,
*/ */
if (asn1_get_next(pos, end - pos, &hdr) < 0 || if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
hdr.class != ASN1_CLASS_CONTEXT_SPECIFIC) { hdr.class != ASN1_CLASS_CONTEXT_SPECIFIC) {
wpa_printf(MSG_DEBUG, asn1_unexpected(&hdr, "OCSP: Expected CHOICE (ResponderID)");
"OCSP: Expected CHOICE (ResponderID) - found class %d tag 0x%x",
hdr.class, hdr.tag);
goto fail; goto fail;
} }
@ -539,11 +513,9 @@ tls_process_basic_ocsp_response(struct tlsv1_client *conn,
} else if (hdr.tag == 2) { } else if (hdr.tag == 2) {
/* KeyHash ::= OCTET STRING */ /* KeyHash ::= OCTET STRING */
if (asn1_get_next(hdr.payload, hdr.length, &hdr) < 0 || if (asn1_get_next(hdr.payload, hdr.length, &hdr) < 0 ||
hdr.class != ASN1_CLASS_UNIVERSAL || !asn1_is_octetstring(&hdr)) {
hdr.tag != ASN1_TAG_OCTETSTRING) { asn1_unexpected(&hdr,
wpa_printf(MSG_DEBUG, "OCSP: Expected OCTET STRING (KeyHash)");
"OCSP: Expected OCTET STRING (KeyHash) - found class %d tag 0x%x",
hdr.class, hdr.tag);
goto fail; goto fail;
} }
key_hash = hdr.payload; key_hash = hdr.payload;
@ -564,8 +536,7 @@ tls_process_basic_ocsp_response(struct tlsv1_client *conn,
/* producedAt GeneralizedTime */ /* producedAt GeneralizedTime */
if (asn1_get_next(pos, end - pos, &hdr) < 0 || if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
hdr.class != ASN1_CLASS_UNIVERSAL || !asn1_is_generalizedtime(&hdr) ||
hdr.tag != ASN1_TAG_GENERALIZEDTIME ||
x509_parse_time(hdr.payload, hdr.length, hdr.tag, x509_parse_time(hdr.payload, hdr.length, hdr.tag,
&produced_at) < 0) { &produced_at) < 0) {
wpa_printf(MSG_DEBUG, "OCSP: Failed to parse producedAt"); wpa_printf(MSG_DEBUG, "OCSP: Failed to parse producedAt");
@ -577,11 +548,9 @@ tls_process_basic_ocsp_response(struct tlsv1_client *conn,
/* responses SEQUENCE OF SingleResponse */ /* responses SEQUENCE OF SingleResponse */
if (asn1_get_next(pos, end - pos, &hdr) < 0 || if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
hdr.class != ASN1_CLASS_UNIVERSAL || !asn1_is_sequence(&hdr)) {
hdr.tag != ASN1_TAG_SEQUENCE) { asn1_unexpected(&hdr,
wpa_printf(MSG_DEBUG, "OCSP: Expected SEQUENCE (responses)");
"OCSP: Expected SEQUENCE (responses) - found class %d tag 0x%x",
hdr.class, hdr.tag);
goto fail; goto fail;
} }
responses = hdr.payload; responses = hdr.payload;
@ -697,12 +666,9 @@ enum tls_ocsp_result tls_process_ocsp_response(struct tlsv1_client *conn,
* responseBytes [0] EXPLICIT ResponseBytes OPTIONAL } * responseBytes [0] EXPLICIT ResponseBytes OPTIONAL }
*/ */
if (asn1_get_next(resp, len, &hdr) < 0 || if (asn1_get_next(resp, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
hdr.class != ASN1_CLASS_UNIVERSAL || asn1_unexpected(&hdr,
hdr.tag != ASN1_TAG_SEQUENCE) { "OCSP: Expected SEQUENCE (OCSPResponse)");
wpa_printf(MSG_DEBUG,
"OCSP: Expected SEQUENCE (OCSPResponse) - found class %d tag 0x%x",
hdr.class, hdr.tag);
return TLS_OCSP_INVALID; return TLS_OCSP_INVALID;
} }
pos = hdr.payload; pos = hdr.payload;
@ -710,12 +676,9 @@ enum tls_ocsp_result tls_process_ocsp_response(struct tlsv1_client *conn,
/* OCSPResponseStatus ::= ENUMERATED */ /* OCSPResponseStatus ::= ENUMERATED */
if (asn1_get_next(pos, end - pos, &hdr) < 0 || if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
hdr.class != ASN1_CLASS_UNIVERSAL || !asn1_is_enumerated(&hdr) || hdr.length != 1) {
hdr.tag != ASN1_TAG_ENUMERATED || asn1_unexpected(&hdr,
hdr.length != 1) { "OCSP: Expected ENUMERATED (responseStatus)");
wpa_printf(MSG_DEBUG,
"OCSP: Expected ENUMERATED (responseStatus) - found class %d tag 0x%x length %u",
hdr.class, hdr.tag, hdr.length);
return TLS_OCSP_INVALID; return TLS_OCSP_INVALID;
} }
resp_status = hdr.payload[0]; resp_status = hdr.payload[0];
@ -730,12 +693,10 @@ enum tls_ocsp_result tls_process_ocsp_response(struct tlsv1_client *conn,
if (pos == end) if (pos == end)
return TLS_OCSP_NO_RESPONSE; return TLS_OCSP_NO_RESPONSE;
if (asn1_get_next(pos, end - pos, &hdr) < 0 || if (asn1_get_next(pos, end - pos, &hdr) < 0 || !hdr.constructed ||
hdr.class != ASN1_CLASS_CONTEXT_SPECIFIC || !asn1_is_cs_tag(&hdr, 0)) {
hdr.tag != 0) { asn1_unexpected(&hdr,
wpa_printf(MSG_DEBUG, "OCSP: Expected [0] EXPLICIT (responseBytes)");
"OCSP: Expected [0] EXPLICIT (responseBytes) - found class %d tag 0x%x",
hdr.class, hdr.tag);
return TLS_OCSP_INVALID; return TLS_OCSP_INVALID;
} }
@ -746,11 +707,9 @@ enum tls_ocsp_result tls_process_ocsp_response(struct tlsv1_client *conn,
*/ */
if (asn1_get_next(hdr.payload, hdr.length, &hdr) < 0 || if (asn1_get_next(hdr.payload, hdr.length, &hdr) < 0 ||
hdr.class != ASN1_CLASS_UNIVERSAL || !asn1_is_sequence(&hdr)) {
hdr.tag != ASN1_TAG_SEQUENCE) { asn1_unexpected(&hdr,
wpa_printf(MSG_DEBUG, "OCSP: Expected SEQUENCE (ResponseBytes)");
"OCSP: Expected SEQUENCE (ResponseBytes) - found class %d tag 0x%x",
hdr.class, hdr.tag);
return TLS_OCSP_INVALID; return TLS_OCSP_INVALID;
} }
pos = hdr.payload; pos = hdr.payload;
@ -771,11 +730,8 @@ enum tls_ocsp_result tls_process_ocsp_response(struct tlsv1_client *conn,
/* response OCTET STRING */ /* response OCTET STRING */
if (asn1_get_next(pos, end - pos, &hdr) < 0 || if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
hdr.class != ASN1_CLASS_UNIVERSAL || !asn1_is_octetstring(&hdr)) {
hdr.tag != ASN1_TAG_OCTETSTRING) { asn1_unexpected(&hdr, "OCSP: Expected OCTET STRING (response)");
wpa_printf(MSG_DEBUG,
"OCSP: Expected OCTET STRING (response) - found class %d tag 0x%x",
hdr.class, hdr.tag);
return TLS_OCSP_INVALID; return TLS_OCSP_INVALID;
} }

View file

@ -455,12 +455,8 @@ static int pkcs12_certbag(struct tlsv1_credentials *cred,
* } * }
*/ */
if (asn1_get_next(buf, len, &hdr) < 0 || if (asn1_get_next(buf, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
hdr.class != ASN1_CLASS_UNIVERSAL || asn1_unexpected(&hdr, "PKCS #12: Expected SEQUENCE (CertBag)");
hdr.tag != ASN1_TAG_SEQUENCE) {
wpa_printf(MSG_DEBUG,
"PKCS #12: Expected SEQUENCE (CertBag) - found class %d tag 0x%x",
hdr.class, hdr.tag);
return -1; return -1;
} }
@ -482,21 +478,17 @@ static int pkcs12_certbag(struct tlsv1_credentials *cred,
obuf); obuf);
} }
if (asn1_get_next(pos, end - pos, &hdr) < 0 || if (asn1_get_next(pos, end - pos, &hdr) < 0 || !hdr.constructed ||
hdr.class != ASN1_CLASS_CONTEXT_SPECIFIC || !asn1_is_cs_tag(&hdr, 0)) {
hdr.tag != 0) { asn1_unexpected(&hdr,
wpa_printf(MSG_DEBUG, "PKCS #12: Expected [0] EXPLICIT (certValue)");
"PKCS #12: Expected [0] EXPLICIT (certValue) - found class %d tag 0x%x",
hdr.class, hdr.tag);
return -1; return -1;
} }
if (asn1_get_next(hdr.payload, hdr.length, &hdr) < 0 || if (asn1_get_next(hdr.payload, hdr.length, &hdr) < 0 ||
hdr.class != ASN1_CLASS_UNIVERSAL || !asn1_is_octetstring(&hdr)) {
hdr.tag != ASN1_TAG_OCTETSTRING) { asn1_unexpected(&hdr,
wpa_printf(MSG_DEBUG, "PKCS #12: Expected OCTET STRING (x509Certificate)");
"PKCS #12: Expected OCTET STRING (x509Certificate) - found class %d tag 0x%x",
hdr.class, hdr.tag);
return -1; return -1;
} }
@ -534,11 +526,9 @@ static int pkcs12_parse_attr_friendly_name(const u8 *pos, const u8 *end)
* } * }
*/ */
if (asn1_get_next(pos, end - pos, &hdr) < 0 || if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
hdr.class != ASN1_CLASS_UNIVERSAL || !asn1_is_bmpstring(&hdr)) {
hdr.tag != ASN1_TAG_BMPSTRING) { asn1_unexpected(&hdr,
wpa_printf(MSG_DEBUG, "PKCS #12: Expected BMPSTRING (friendlyName)");
"PKCS #12: Expected BMPSTRING (friendlyName) - found class %d tag 0x%x",
hdr.class, hdr.tag);
return 0; return 0;
} }
wpa_hexdump_ascii(MSG_DEBUG, "PKCS #12: friendlyName", wpa_hexdump_ascii(MSG_DEBUG, "PKCS #12: friendlyName",
@ -561,11 +551,9 @@ static int pkcs12_parse_attr_local_key_id(const u8 *pos, const u8 *end)
* } * }
*/ */
if (asn1_get_next(pos, end - pos, &hdr) < 0 || if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
hdr.class != ASN1_CLASS_UNIVERSAL || !asn1_is_octetstring(&hdr)) {
hdr.tag != ASN1_TAG_OCTETSTRING) { asn1_unexpected(&hdr,
wpa_printf(MSG_DEBUG, "PKCS #12: Expected OCTET STRING (localKeyID)");
"PKCS #12: Expected OCTET STRING (localKeyID) - found class %d tag 0x%x",
hdr.class, hdr.tag);
return -1; return -1;
} }
wpa_hexdump_key(MSG_DEBUG, "PKCS #12: localKeyID", wpa_hexdump_key(MSG_DEBUG, "PKCS #12: localKeyID",
@ -596,12 +584,8 @@ static int pkcs12_parse_attr(const u8 *pos, size_t len)
asn1_oid_to_str(&a_oid, obuf, sizeof(obuf)); asn1_oid_to_str(&a_oid, obuf, sizeof(obuf));
wpa_printf(MSG_DEBUG, "PKCS #12: attrId %s", obuf); wpa_printf(MSG_DEBUG, "PKCS #12: attrId %s", obuf);
if (asn1_get_next(pos, end - pos, &hdr) < 0 || if (asn1_get_next(pos, end - pos, &hdr) < 0 || !asn1_is_set(&hdr)) {
hdr.class != ASN1_CLASS_UNIVERSAL || asn1_unexpected(&hdr, "PKCS #12: Expected SET (attrValues)");
hdr.tag != ASN1_TAG_SET) {
wpa_printf(MSG_DEBUG,
"PKCS #12: Expected SET (attrValues) - found class %d tag 0x%x",
hdr.class, hdr.tag);
return -1; return -1;
} }
wpa_hexdump_key(MSG_MSGDUMP, "PKCS #12: attrValues", wpa_hexdump_key(MSG_MSGDUMP, "PKCS #12: attrValues",
@ -641,12 +625,10 @@ static int pkcs12_safebag(struct tlsv1_credentials *cred,
asn1_oid_to_str(&oid, obuf, sizeof(obuf)); asn1_oid_to_str(&oid, obuf, sizeof(obuf));
wpa_printf(MSG_DEBUG, "PKCS #12: BAG-TYPE %s", obuf); wpa_printf(MSG_DEBUG, "PKCS #12: BAG-TYPE %s", obuf);
if (asn1_get_next(pos, end - pos, &hdr) < 0 || if (asn1_get_next(pos, end - pos, &hdr) < 0 || !hdr.constructed ||
hdr.class != ASN1_CLASS_CONTEXT_SPECIFIC || !asn1_is_cs_tag(&hdr, 0)) {
hdr.tag != 0) { asn1_unexpected(&hdr,
wpa_printf(MSG_DEBUG, "PKCS #12: Expected [0] EXPLICIT (bagValue)");
"PKCS #12: Expected [0] EXPLICIT (bagValue) - found class %d tag 0x%x",
hdr.class, hdr.tag);
return 0; return 0;
} }
value = hdr.payload; value = hdr.payload;
@ -657,11 +639,9 @@ static int pkcs12_safebag(struct tlsv1_credentials *cred,
if (pos < end) { if (pos < end) {
/* bagAttributes SET OF PKCS12Attribute OPTIONAL */ /* bagAttributes SET OF PKCS12Attribute OPTIONAL */
if (asn1_get_next(pos, end - pos, &hdr) < 0 || if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
hdr.class != ASN1_CLASS_UNIVERSAL || !asn1_is_set(&hdr)) {
hdr.tag != ASN1_TAG_SET) { asn1_unexpected(&hdr,
wpa_printf(MSG_DEBUG, "PKCS #12: Expected SET (bagAttributes)");
"PKCS #12: Expected SET (bagAttributes) - found class %d tag 0x%x",
hdr.class, hdr.tag);
return -1; return -1;
} }
wpa_hexdump_key(MSG_MSGDUMP, "PKCS #12: bagAttributes", wpa_hexdump_key(MSG_MSGDUMP, "PKCS #12: bagAttributes",
@ -672,11 +652,9 @@ static int pkcs12_safebag(struct tlsv1_credentials *cred,
while (pos < end) { while (pos < end) {
/* PKCS12Attribute ::= SEQUENCE */ /* PKCS12Attribute ::= SEQUENCE */
if (asn1_get_next(pos, end - pos, &hdr) < 0 || if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
hdr.class != ASN1_CLASS_UNIVERSAL || !asn1_is_sequence(&hdr)) {
hdr.tag != ASN1_TAG_SEQUENCE) { asn1_unexpected(&hdr,
wpa_printf(MSG_DEBUG, "PKCS #12: Expected SEQUENCE (PKCS12Attribute)");
"PKCS #12: Expected SEQUENCE (PKCS12Attribute) - found class %d tag 0x%x",
hdr.class, hdr.tag);
return -1; return -1;
} }
if (pkcs12_parse_attr(hdr.payload, hdr.length) < 0) if (pkcs12_parse_attr(hdr.payload, hdr.length) < 0)
@ -705,12 +683,9 @@ static int pkcs12_safecontents(struct tlsv1_credentials *cred,
const u8 *pos, *end; const u8 *pos, *end;
/* SafeContents ::= SEQUENCE OF SafeBag */ /* SafeContents ::= SEQUENCE OF SafeBag */
if (asn1_get_next(buf, len, &hdr) < 0 || if (asn1_get_next(buf, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
hdr.class != ASN1_CLASS_UNIVERSAL || asn1_unexpected(&hdr,
hdr.tag != ASN1_TAG_SEQUENCE) { "PKCS #12: Expected SEQUENCE (SafeContents)");
wpa_printf(MSG_DEBUG,
"PKCS #12: Expected SEQUENCE (SafeContents) - found class %d tag 0x%x",
hdr.class, hdr.tag);
return -1; return -1;
} }
pos = hdr.payload; pos = hdr.payload;
@ -726,11 +701,9 @@ static int pkcs12_safecontents(struct tlsv1_credentials *cred,
while (pos < end) { while (pos < end) {
if (asn1_get_next(pos, end - pos, &hdr) < 0 || if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
hdr.class != ASN1_CLASS_UNIVERSAL || !asn1_is_sequence(&hdr)) {
hdr.tag != ASN1_TAG_SEQUENCE) { asn1_unexpected(&hdr,
wpa_printf(MSG_DEBUG, "PKCS #12: Expected SEQUENCE (SafeBag)");
"PKCS #12: Expected SEQUENCE (SafeBag) - found class %d tag 0x%x",
hdr.class, hdr.tag);
return -1; return -1;
} }
if (pkcs12_safebag(cred, hdr.payload, hdr.length, passwd) < 0) if (pkcs12_safebag(cred, hdr.payload, hdr.length, passwd) < 0)
@ -750,11 +723,8 @@ static int pkcs12_parse_content_data(struct tlsv1_credentials *cred,
/* Data ::= OCTET STRING */ /* Data ::= OCTET STRING */
if (asn1_get_next(pos, end - pos, &hdr) < 0 || if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
hdr.class != ASN1_CLASS_UNIVERSAL || !asn1_is_octetstring(&hdr)) {
hdr.tag != ASN1_TAG_OCTETSTRING) { asn1_unexpected(&hdr, "PKCS #12: Expected OCTET STRING (Data)");
wpa_printf(MSG_DEBUG,
"PKCS #12: Expected OCTET STRING (Data) - found class %d tag 0x%x",
hdr.class, hdr.tag);
return -1; return -1;
} }
@ -782,21 +752,17 @@ static int pkcs12_parse_content_enc_data(struct tlsv1_credentials *cred,
* encryptedContentInfo EncryptedContentInfo } * encryptedContentInfo EncryptedContentInfo }
*/ */
if (asn1_get_next(pos, end - pos, &hdr) < 0 || if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
hdr.class != ASN1_CLASS_UNIVERSAL || !asn1_is_sequence(&hdr)) {
hdr.tag != ASN1_TAG_SEQUENCE) { asn1_unexpected(&hdr,
wpa_printf(MSG_DEBUG, "PKCS #12: Expected SEQUENCE (EncryptedData)");
"PKCS #12: Expected SEQUENCE (EncryptedData) - found class %d tag 0x%x",
hdr.class, hdr.tag);
return 0; return 0;
} }
pos = hdr.payload; pos = hdr.payload;
/* Version ::= INTEGER */ /* Version ::= INTEGER */
if (asn1_get_next(pos, end - pos, &hdr) < 0 || if (asn1_get_next(pos, end - pos, &hdr) < 0 || !asn1_is_integer(&hdr)) {
hdr.class != ASN1_CLASS_UNIVERSAL || hdr.tag != ASN1_TAG_INTEGER) { asn1_unexpected(&hdr,
wpa_printf(MSG_DEBUG, "PKCS #12: No INTEGER tag found for version");
"PKCS #12: No INTEGER tag found for version; class=%d tag=0x%x",
hdr.class, hdr.tag);
return -1; return -1;
} }
if (hdr.length != 1 || hdr.payload[0] != 0) { if (hdr.length != 1 || hdr.payload[0] != 0) {
@ -815,11 +781,9 @@ static int pkcs12_parse_content_enc_data(struct tlsv1_credentials *cred,
* encryptedContent [0] IMPLICIT EncryptedContent OPTIONAL } * encryptedContent [0] IMPLICIT EncryptedContent OPTIONAL }
*/ */
if (asn1_get_next(pos, end - pos, &hdr) < 0 || if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
hdr.class != ASN1_CLASS_UNIVERSAL || !asn1_is_sequence(&hdr)) {
hdr.tag != ASN1_TAG_SEQUENCE) { asn1_unexpected(&hdr,
wpa_printf(MSG_DEBUG, "PKCS #12: Expected SEQUENCE (EncryptedContentInfo)");
"PKCS #12: Expected SEQUENCE (EncryptedContentInfo) - found class %d tag 0x%x",
hdr.class, hdr.tag);
return -1; return -1;
} }
@ -845,22 +809,19 @@ static int pkcs12_parse_content_enc_data(struct tlsv1_credentials *cred,
/* ContentEncryptionAlgorithmIdentifier ::= AlgorithmIdentifier */ /* ContentEncryptionAlgorithmIdentifier ::= AlgorithmIdentifier */
if (asn1_get_next(pos, end - pos, &hdr) < 0 || if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
hdr.class != ASN1_CLASS_UNIVERSAL || !asn1_is_sequence(&hdr)) {
hdr.tag != ASN1_TAG_SEQUENCE) { asn1_unexpected(&hdr,
wpa_printf(MSG_DEBUG, "PKCS #12: Expected SEQUENCE (ContentEncryptionAlgorithmIdentifier) - found class %d tag 0x%x", "PKCS #12: Expected SEQUENCE (ContentEncryptionAlgorithmIdentifier)");
hdr.class, hdr.tag);
return -1; return -1;
} }
enc_alg = hdr.payload; enc_alg = hdr.payload;
enc_alg_len = hdr.length; enc_alg_len = hdr.length;
pos = hdr.payload + hdr.length; pos = hdr.payload + hdr.length;
if (asn1_get_next(pos, end - pos, &hdr) < 0 || if (asn1_get_next(pos, end - pos, &hdr) < 0 || hdr.constructed ||
hdr.class != ASN1_CLASS_CONTEXT_SPECIFIC || !asn1_is_cs_tag(&hdr, 0)) {
hdr.tag != 0) { asn1_unexpected(&hdr,
wpa_printf(MSG_DEBUG, "PKCS #12: Expected [0] IMPLICIT (encryptedContent)");
"PKCS #12: Expected [0] IMPLICIT (encryptedContent) - found class %d tag 0x%x",
hdr.class, hdr.tag);
return -1; return -1;
} }
@ -900,12 +861,10 @@ static int pkcs12_parse_content(struct tlsv1_credentials *cred,
asn1_oid_to_str(&oid, txt, sizeof(txt)); asn1_oid_to_str(&oid, txt, sizeof(txt));
wpa_printf(MSG_DEBUG, "PKCS #12: contentType %s", txt); wpa_printf(MSG_DEBUG, "PKCS #12: contentType %s", txt);
if (asn1_get_next(pos, end - pos, &hdr) < 0 || if (asn1_get_next(pos, end - pos, &hdr) < 0 || !hdr.constructed ||
hdr.class != ASN1_CLASS_CONTEXT_SPECIFIC || !asn1_is_cs_tag(&hdr, 0)) {
hdr.tag != 0) { asn1_unexpected(&hdr,
wpa_printf(MSG_DEBUG, "PKCS #12: Expected [0] EXPLICIT (content)");
"PKCS #12: Expected [0] EXPLICIT (content) - found class %d tag 0x%x",
hdr.class, hdr.tag);
return 0; return 0;
} }
pos = hdr.payload; pos = hdr.payload;
@ -938,23 +897,18 @@ static int pkcs12_parse(struct tlsv1_credentials *cred,
* } * }
*/ */
if (asn1_get_next(key, len, &hdr) < 0 || if (asn1_get_next(key, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
hdr.class != ASN1_CLASS_UNIVERSAL || asn1_unexpected(&hdr,
hdr.tag != ASN1_TAG_SEQUENCE) { "PKCS #12: Expected SEQUENCE (PFX); assume PKCS #12 not used");
wpa_printf(MSG_DEBUG,
"PKCS #12: Expected SEQUENCE (PFX) - found class %d tag 0x%x; assume PKCS #12 not used",
hdr.class, hdr.tag);
return -1; return -1;
} }
pos = hdr.payload; pos = hdr.payload;
end = pos + hdr.length; end = pos + hdr.length;
if (asn1_get_next(pos, end - pos, &hdr) < 0 || if (asn1_get_next(pos, end - pos, &hdr) < 0 || !asn1_is_integer(&hdr)) {
hdr.class != ASN1_CLASS_UNIVERSAL || hdr.tag != ASN1_TAG_INTEGER) { asn1_unexpected(&hdr,
wpa_printf(MSG_DEBUG, "PKCS #12: No INTEGER tag found for version");
"PKCS #12: No INTEGER tag found for version; class=%d tag=0x%x",
hdr.class, hdr.tag);
return -1; return -1;
} }
if (hdr.length != 1 || hdr.payload[0] != 3) { if (hdr.length != 1 || hdr.payload[0] != 3) {
@ -970,11 +924,9 @@ static int pkcs12_parse(struct tlsv1_credentials *cred,
*/ */
if (asn1_get_next(pos, end - pos, &hdr) < 0 || if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
hdr.class != ASN1_CLASS_UNIVERSAL || !asn1_is_sequence(&hdr)) {
hdr.tag != ASN1_TAG_SEQUENCE) { asn1_unexpected(&hdr,
wpa_printf(MSG_DEBUG, "PKCS #12: Expected SEQUENCE (authSafe); assume PKCS #12 not used");
"PKCS #12: Expected SEQUENCE (authSafe) - found class %d tag 0x%x; assume PKCS #12 not used",
hdr.class, hdr.tag);
return -1; return -1;
} }
@ -995,12 +947,10 @@ static int pkcs12_parse(struct tlsv1_credentials *cred,
return -1; return -1;
} }
if (asn1_get_next(pos, end - pos, &hdr) < 0 || if (asn1_get_next(pos, end - pos, &hdr) < 0 || !hdr.constructed ||
hdr.class != ASN1_CLASS_CONTEXT_SPECIFIC || !asn1_is_cs_tag(&hdr, 0)) {
hdr.tag != 0) { asn1_unexpected(&hdr,
wpa_printf(MSG_DEBUG, "PKCS #12: Expected [0] EXPLICIT (content); assume PKCS #12 not used");
"PKCS #12: Expected [0] EXPLICIT (content) - found class %d tag 0x%x; assume PKCS #12 not used",
hdr.class, hdr.tag);
return -1; return -1;
} }
@ -1008,11 +958,9 @@ static int pkcs12_parse(struct tlsv1_credentials *cred,
/* Data ::= OCTET STRING */ /* Data ::= OCTET STRING */
if (asn1_get_next(pos, end - pos, &hdr) < 0 || if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
hdr.class != ASN1_CLASS_UNIVERSAL || !asn1_is_octetstring(&hdr)) {
hdr.tag != ASN1_TAG_OCTETSTRING) { asn1_unexpected(&hdr,
wpa_printf(MSG_DEBUG, "PKCS #12: Expected OCTET STRING (Data); assume PKCS #12 not used");
"PKCS #12: Expected OCTET STRING (Data) - found class %d tag 0x%x; assume PKCS #12 not used",
hdr.class, hdr.tag);
return -1; return -1;
} }
@ -1026,11 +974,9 @@ static int pkcs12_parse(struct tlsv1_credentials *cred,
hdr.payload, hdr.length); hdr.payload, hdr.length);
if (asn1_get_next(hdr.payload, hdr.length, &hdr) < 0 || if (asn1_get_next(hdr.payload, hdr.length, &hdr) < 0 ||
hdr.class != ASN1_CLASS_UNIVERSAL || !asn1_is_sequence(&hdr)) {
hdr.tag != ASN1_TAG_SEQUENCE) { asn1_unexpected(&hdr,
wpa_printf(MSG_DEBUG, "PKCS #12: Expected SEQUENCE within Data content; assume PKCS #12 not used");
"PKCS #12: Expected SEQUENCE within Data content - found class %d tag 0x%x; assume PKCS #12 not used",
hdr.class, hdr.tag);
return -1; return -1;
} }
@ -1039,11 +985,9 @@ static int pkcs12_parse(struct tlsv1_credentials *cred,
while (end > pos) { while (end > pos) {
if (asn1_get_next(pos, end - pos, &hdr) < 0 || if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
hdr.class != ASN1_CLASS_UNIVERSAL || !asn1_is_sequence(&hdr)) {
hdr.tag != ASN1_TAG_SEQUENCE) { asn1_unexpected(&hdr,
wpa_printf(MSG_DEBUG, "PKCS #12: Expected SEQUENCE (ContentInfo); assume PKCS #12 not used");
"PKCS #12: Expected SEQUENCE (ContentInfo) - found class %d tag 0x%x; assume PKCS #12 not used",
hdr.class, hdr.tag);
return -1; return -1;
} }
if (pkcs12_parse_content(cred, hdr.payload, hdr.length, if (pkcs12_parse_content(cred, hdr.payload, hdr.length,
@ -1141,24 +1085,17 @@ static int tlsv1_set_dhparams_der(struct tlsv1_credentials *cred,
*/ */
/* DHParamer ::= SEQUENCE */ /* DHParamer ::= SEQUENCE */
if (asn1_get_next(pos, len, &hdr) < 0 || if (asn1_get_next(pos, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
hdr.class != ASN1_CLASS_UNIVERSAL || asn1_unexpected(&hdr,
hdr.tag != ASN1_TAG_SEQUENCE) { "DH: DH parameters did not start with a valid SEQUENCE");
wpa_printf(MSG_DEBUG, "DH: DH parameters did not start with a "
"valid SEQUENCE - found class %d tag 0x%x",
hdr.class, hdr.tag);
return -1; return -1;
} }
pos = hdr.payload; pos = hdr.payload;
/* prime INTEGER */ /* prime INTEGER */
if (asn1_get_next(pos, end - pos, &hdr) < 0) if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
return -1; !asn1_is_integer(&hdr)) {
asn1_unexpected(&hdr, "DH: No INTEGER tag found for p");
if (hdr.class != ASN1_CLASS_UNIVERSAL ||
hdr.tag != ASN1_TAG_INTEGER) {
wpa_printf(MSG_DEBUG, "DH: No INTEGER tag found for p; "
"class=%d tag=0x%x", hdr.class, hdr.tag);
return -1; return -1;
} }
@ -1173,13 +1110,9 @@ static int tlsv1_set_dhparams_der(struct tlsv1_credentials *cred,
pos = hdr.payload + hdr.length; pos = hdr.payload + hdr.length;
/* base INTEGER */ /* base INTEGER */
if (asn1_get_next(pos, end - pos, &hdr) < 0) if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
return -1; !asn1_is_integer(&hdr)) {
asn1_unexpected(&hdr, "DH: No INTEGER tag found for g");
if (hdr.class != ASN1_CLASS_UNIVERSAL ||
hdr.tag != ASN1_TAG_INTEGER) {
wpa_printf(MSG_DEBUG, "DH: No INTEGER tag found for g; "
"class=%d tag=0x%x", hdr.class, hdr.tag);
return -1; return -1;
} }