TLS: TOD-STRICT and TOD-TOFU certificate policies
Add parsing of certificate policies for TOD-STRICT and TOD-TOFU when using CONFIG_TLS=internal. Signed-off-by: Jouni Malinen <j@w1.fi>
This commit is contained in:
parent
31a3d4c234
commit
d165b32f38
3 changed files with 144 additions and 1 deletions
|
@ -312,6 +312,14 @@ static void tls_peer_cert_event(struct tlsv1_client *conn, int depth,
|
||||||
x509_name_string(&cert->subject, subject, sizeof(subject));
|
x509_name_string(&cert->subject, subject, sizeof(subject));
|
||||||
ev.peer_cert.subject = subject;
|
ev.peer_cert.subject = subject;
|
||||||
|
|
||||||
|
if (cert->extensions_present & X509_EXT_CERTIFICATE_POLICY) {
|
||||||
|
if (cert->certificate_policy & X509_EXT_CERT_POLICY_TOD_STRICT)
|
||||||
|
ev.peer_cert.tod = 1;
|
||||||
|
else if (cert->certificate_policy &
|
||||||
|
X509_EXT_CERT_POLICY_TOD_TOFU)
|
||||||
|
ev.peer_cert.tod = 2;
|
||||||
|
}
|
||||||
|
|
||||||
conn->event_cb(conn->cb_ctx, TLS_PEER_CERTIFICATE, &ev);
|
conn->event_cb(conn->cb_ctx, TLS_PEER_CERTIFICATE, &ev);
|
||||||
wpabuf_free(cert_buf);
|
wpabuf_free(cert_buf);
|
||||||
}
|
}
|
||||||
|
|
130
src/tls/x509v3.c
130
src/tls/x509v3.c
|
@ -1120,6 +1120,133 @@ static int x509_parse_ext_issuer_alt_name(struct x509_certificate *cert,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int x509_id_cert_policy_any_oid(struct asn1_oid *oid)
|
||||||
|
{
|
||||||
|
return oid->len == 5 &&
|
||||||
|
oid->oid[0] == 2 /* iso/itu-t */ &&
|
||||||
|
oid->oid[1] == 5 /* X.500 Directory Services */ &&
|
||||||
|
oid->oid[2] == 29 /* id-ce */ &&
|
||||||
|
oid->oid[3] == 32 /* id-ce-certificate-policies */ &&
|
||||||
|
oid->oid[4] == 0 /* anyPolicy */;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int x509_id_wfa_oid(struct asn1_oid *oid)
|
||||||
|
{
|
||||||
|
return oid->len >= 7 &&
|
||||||
|
oid->oid[0] == 1 /* iso */ &&
|
||||||
|
oid->oid[1] == 3 /* identified-organization */ &&
|
||||||
|
oid->oid[2] == 6 /* dod */ &&
|
||||||
|
oid->oid[3] == 1 /* internet */ &&
|
||||||
|
oid->oid[4] == 4 /* private */ &&
|
||||||
|
oid->oid[5] == 1 /* enterprise */ &&
|
||||||
|
oid->oid[6] == 40808 /* WFA */;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int x509_id_wfa_tod_oid(struct asn1_oid *oid)
|
||||||
|
{
|
||||||
|
return oid->len >= 9 &&
|
||||||
|
x509_id_wfa_oid(oid) &&
|
||||||
|
oid->oid[7] == 1 &&
|
||||||
|
oid->oid[8] == 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int x509_id_wfa_tod_strict_oid(struct asn1_oid *oid)
|
||||||
|
{
|
||||||
|
return oid->len == 10 &&
|
||||||
|
x509_id_wfa_tod_oid(oid) &&
|
||||||
|
oid->oid[9] == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int x509_id_wfa_tod_tofu_oid(struct asn1_oid *oid)
|
||||||
|
{
|
||||||
|
return oid->len == 10 &&
|
||||||
|
x509_id_wfa_tod_oid(oid) &&
|
||||||
|
oid->oid[9] == 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int x509_parse_ext_certificate_policies(struct x509_certificate *cert,
|
||||||
|
const u8 *pos, size_t len)
|
||||||
|
{
|
||||||
|
struct asn1_hdr hdr;
|
||||||
|
const u8 *end;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* certificatePolicies ::= SEQUENCE SIZE (1..MAX) OF PolicyInformation
|
||||||
|
*
|
||||||
|
* PolicyInformation ::= SEQUENCE {
|
||||||
|
* policyIdentifier CertPolicyId,
|
||||||
|
* policyQualifiers SEQUENCE SIZE (1..MAX) OF
|
||||||
|
* PolicyQualifierInfo OPTIONAL }
|
||||||
|
*
|
||||||
|
* CertPolicyId ::= OBJECT IDENTIFIER
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (asn1_get_next(pos, len, &hdr) < 0 ||
|
||||||
|
hdr.class != ASN1_CLASS_UNIVERSAL ||
|
||||||
|
hdr.tag != ASN1_TAG_SEQUENCE) {
|
||||||
|
wpa_printf(MSG_DEBUG, "X509: Expected SEQUENCE (certificatePolicies) - found class %d tag 0x%x",
|
||||||
|
hdr.class, hdr.tag);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (hdr.length > pos + len - hdr.payload)
|
||||||
|
return -1;
|
||||||
|
pos = hdr.payload;
|
||||||
|
end = pos + hdr.length;
|
||||||
|
|
||||||
|
wpa_hexdump(MSG_MSGDUMP, "X509: certificatePolicies", pos, end - pos);
|
||||||
|
|
||||||
|
while (pos < end) {
|
||||||
|
const u8 *pol_end;
|
||||||
|
struct asn1_oid oid;
|
||||||
|
char buf[80];
|
||||||
|
|
||||||
|
if (asn1_get_next(pos, len, &hdr) < 0 ||
|
||||||
|
hdr.class != ASN1_CLASS_UNIVERSAL ||
|
||||||
|
hdr.tag != ASN1_TAG_SEQUENCE) {
|
||||||
|
wpa_printf(MSG_DEBUG, "X509: Expected SEQUENCE (PolicyInformation) - found class %d tag 0x%x",
|
||||||
|
hdr.class, hdr.tag);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (hdr.length > pos + len - hdr.payload)
|
||||||
|
return -1;
|
||||||
|
pos = hdr.payload;
|
||||||
|
pol_end = pos + hdr.length;
|
||||||
|
wpa_hexdump(MSG_MSGDUMP, "X509: PolicyInformation",
|
||||||
|
pos, pol_end - pos);
|
||||||
|
|
||||||
|
if (asn1_get_oid(pos, pol_end - pos, &oid, &pos))
|
||||||
|
return -1;
|
||||||
|
if (x509_id_cert_policy_any_oid(&oid)) {
|
||||||
|
os_strlcpy(buf, "anyPolicy-STRICT", sizeof(buf));
|
||||||
|
cert->certificate_policy |=
|
||||||
|
X509_EXT_CERT_POLICY_ANY;
|
||||||
|
} else if (x509_id_wfa_tod_strict_oid(&oid)) {
|
||||||
|
os_strlcpy(buf, "TOD-STRICT", sizeof(buf));
|
||||||
|
cert->certificate_policy |=
|
||||||
|
X509_EXT_CERT_POLICY_TOD_STRICT;
|
||||||
|
} else if (x509_id_wfa_tod_tofu_oid(&oid)) {
|
||||||
|
os_strlcpy(buf, "TOD-TOFU", sizeof(buf));
|
||||||
|
cert->certificate_policy |=
|
||||||
|
X509_EXT_CERT_POLICY_TOD_TOFU;
|
||||||
|
} else {
|
||||||
|
asn1_oid_to_str(&oid, buf, sizeof(buf));
|
||||||
|
}
|
||||||
|
wpa_printf(MSG_DEBUG, "policyIdentifier: %s", buf);
|
||||||
|
|
||||||
|
pos = pol_end;
|
||||||
|
}
|
||||||
|
|
||||||
|
cert->extensions_present |= X509_EXT_CERTIFICATE_POLICY;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int x509_id_pkix_oid(struct asn1_oid *oid)
|
static int x509_id_pkix_oid(struct asn1_oid *oid)
|
||||||
{
|
{
|
||||||
return oid->len >= 7 &&
|
return oid->len >= 7 &&
|
||||||
|
@ -1234,7 +1361,6 @@ static int x509_parse_extension_data(struct x509_certificate *cert,
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
/* TODO: add other extensions required by RFC 3280, Ch 4.2:
|
/* TODO: add other extensions required by RFC 3280, Ch 4.2:
|
||||||
* certificate policies (section 4.2.1.5)
|
|
||||||
* name constraints (section 4.2.1.11)
|
* name constraints (section 4.2.1.11)
|
||||||
* policy constraints (section 4.2.1.12)
|
* policy constraints (section 4.2.1.12)
|
||||||
* inhibit any-policy (section 4.2.1.15)
|
* inhibit any-policy (section 4.2.1.15)
|
||||||
|
@ -1248,6 +1374,8 @@ static int x509_parse_extension_data(struct x509_certificate *cert,
|
||||||
return x509_parse_ext_issuer_alt_name(cert, pos, len);
|
return x509_parse_ext_issuer_alt_name(cert, pos, len);
|
||||||
case 19: /* id-ce-basicConstraints */
|
case 19: /* id-ce-basicConstraints */
|
||||||
return x509_parse_ext_basic_constraints(cert, pos, len);
|
return x509_parse_ext_basic_constraints(cert, pos, len);
|
||||||
|
case 32: /* id-ce-certificatePolicies */
|
||||||
|
return x509_parse_ext_certificate_policies(cert, pos, len);
|
||||||
case 37: /* id-ce-extKeyUsage */
|
case 37: /* id-ce-extKeyUsage */
|
||||||
return x509_parse_ext_ext_key_usage(cert, pos, len);
|
return x509_parse_ext_ext_key_usage(cert, pos, len);
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -74,6 +74,7 @@ struct x509_certificate {
|
||||||
#define X509_EXT_SUBJECT_ALT_NAME (1 << 3)
|
#define X509_EXT_SUBJECT_ALT_NAME (1 << 3)
|
||||||
#define X509_EXT_ISSUER_ALT_NAME (1 << 4)
|
#define X509_EXT_ISSUER_ALT_NAME (1 << 4)
|
||||||
#define X509_EXT_EXT_KEY_USAGE (1 << 5)
|
#define X509_EXT_EXT_KEY_USAGE (1 << 5)
|
||||||
|
#define X509_EXT_CERTIFICATE_POLICY (1 << 6)
|
||||||
|
|
||||||
/* BasicConstraints */
|
/* BasicConstraints */
|
||||||
int ca; /* cA */
|
int ca; /* cA */
|
||||||
|
@ -98,6 +99,12 @@ struct x509_certificate {
|
||||||
#define X509_EXT_KEY_USAGE_CLIENT_AUTH (1 << 2)
|
#define X509_EXT_KEY_USAGE_CLIENT_AUTH (1 << 2)
|
||||||
#define X509_EXT_KEY_USAGE_OCSP (1 << 3)
|
#define X509_EXT_KEY_USAGE_OCSP (1 << 3)
|
||||||
|
|
||||||
|
/* CertificatePolicy */
|
||||||
|
unsigned long certificate_policy;
|
||||||
|
#define X509_EXT_CERT_POLICY_ANY (1 << 0)
|
||||||
|
#define X509_EXT_CERT_POLICY_TOD_STRICT (1 << 1)
|
||||||
|
#define X509_EXT_CERT_POLICY_TOD_TOFU (1 << 2)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The DER format certificate follows struct x509_certificate. These
|
* The DER format certificate follows struct x509_certificate. These
|
||||||
* pointers point to that buffer.
|
* pointers point to that buffer.
|
||||||
|
|
Loading…
Reference in a new issue