}
+static int x509_any_ext_key_usage_oid(struct asn1_oid *oid)
+{
+ return oid->len == 6 &&
+ x509_id_ce_oid(oid) &&
+ oid->oid[3] == 37 /* extKeyUsage */ &&
+ oid->oid[4] == 0 /* anyExtendedKeyUsage */;
+}
+
+
static int x509_parse_ext_key_usage(struct x509_certificate *cert,
const u8 *pos, size_t len)
{
}
+static int x509_id_pkix_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] == 5 /* security */ &&
+ oid->oid[5] == 5 /* mechanisms */ &&
+ oid->oid[6] == 7 /* id-pkix */;
+}
+
+
+static int x509_id_kp_oid(struct asn1_oid *oid)
+{
+ /* id-kp */
+ return oid->len >= 8 &&
+ x509_id_pkix_oid(oid) &&
+ oid->oid[7] == 3 /* id-kp */;
+}
+
+
+static int x509_id_kp_server_auth_oid(struct asn1_oid *oid)
+{
+ /* id-kp */
+ return oid->len == 9 &&
+ x509_id_kp_oid(oid) &&
+ oid->oid[8] == 1 /* id-kp-serverAuth */;
+}
+
+
+static int x509_id_kp_client_auth_oid(struct asn1_oid *oid)
+{
+ /* id-kp */
+ return oid->len == 9 &&
+ x509_id_kp_oid(oid) &&
+ oid->oid[8] == 2 /* id-kp-clientAuth */;
+}
+
+
+static int x509_parse_ext_ext_key_usage(struct x509_certificate *cert,
+ const u8 *pos, size_t len)
+{
+ struct asn1_hdr hdr;
+ const u8 *end;
+ struct asn1_oid oid;
+
+ /*
+ * ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId
+ *
+ * KeyPurposeId ::= 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 "
+ "(ExtKeyUsageSyntax) - 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: ExtKeyUsageSyntax", pos, end - pos);
+
+ while (pos < end) {
+ char buf[80];
+
+ if (asn1_get_oid(pos, end - pos, &oid, &pos))
+ return -1;
+ if (x509_any_ext_key_usage_oid(&oid)) {
+ os_strlcpy(buf, "anyExtendedKeyUsage", sizeof(buf));
+ cert->ext_key_usage |= X509_EXT_KEY_USAGE_ANY;
+ } else if (x509_id_kp_server_auth_oid(&oid)) {
+ os_strlcpy(buf, "id-kp-serverAuth", sizeof(buf));
+ cert->ext_key_usage |= X509_EXT_KEY_USAGE_SERVER_AUTH;
+ } else if (x509_id_kp_client_auth_oid(&oid)) {
+ os_strlcpy(buf, "id-kp-clientAuth", sizeof(buf));
+ cert->ext_key_usage |= X509_EXT_KEY_USAGE_CLIENT_AUTH;
+ } else {
+ asn1_oid_to_str(&oid, buf, sizeof(buf));
+ }
+ wpa_printf(MSG_DEBUG, "ExtKeyUsage KeyPurposeId: %s", buf);
+ }
+
+ cert->extensions_present |= X509_EXT_EXT_KEY_USAGE;
+
+ return 0;
+}
+
+
static int x509_parse_extension_data(struct x509_certificate *cert,
struct asn1_oid *oid,
const u8 *pos, size_t len)
* certificate policies (section 4.2.1.5)
* name constraints (section 4.2.1.11)
* policy constraints (section 4.2.1.12)
- * extended key usage (section 4.2.1.13)
* inhibit any-policy (section 4.2.1.15)
*/
switch (oid->oid[3]) {
return x509_parse_ext_issuer_alt_name(cert, pos, len);
case 19: /* id-ce-basicConstraints */
return x509_parse_ext_basic_constraints(cert, pos, len);
+ case 37: /* id-ce-extKeyUsage */
+ return x509_parse_ext_ext_key_usage(cert, pos, len);
default:
return 1;
}