result_t x509_verify_cert_eku (x509_crt *cert, const char * const expected_oid) { result_t fFound = FAILURE; if (!(cert->ext_types & EXT_EXTENDED_KEY_USAGE)) { msg (D_HANDSHAKE, "Certificate does not have extended key usage extension"); } else { x509_sequence *oid_seq = &(cert->ext_key_usage); msg (D_HANDSHAKE, "Validating certificate extended key usage"); while (oid_seq != NULL) { x509_buf *oid = &oid_seq->buf; char oid_num_str[1024]; const char *oid_str; if (0 == oid_get_extended_key_usage( oid, &oid_str )) { msg (D_HANDSHAKE, "++ Certificate has EKU (str) %s, expects %s", oid_str, expected_oid); if (!strcmp (expected_oid, oid_str)) { fFound = SUCCESS; break; } } if (0 < oid_get_numeric_string( oid_num_str, sizeof (oid_num_str), oid)) { msg (D_HANDSHAKE, "++ Certificate has EKU (oid) %s, expects %s", oid_num_str, expected_oid); if (!strcmp (expected_oid, oid_num_str)) { fFound = SUCCESS; break; } } oid_seq = oid_seq->next; } } return fFound; }
int x509_oid_get_numeric_string( char *buf, size_t size, x509_buf *oid ) { return oid_get_numeric_string( buf, size, oid ); }
static int x509_get_crt_ext_data(const unsigned char **ext_data, size_t *ext_len, x509_crt *crt, const char *oid) { int ret; size_t len; unsigned char *end_ext_data, *end_ext_octet; unsigned char *p; const unsigned char *end; char oid_str[64]; p = crt->v3_ext.p; end = crt->v3_ext.p + crt->v3_ext.len; ret = asn1_get_tag(&p, end, &len, ASN1_CONSTRUCTED | ASN1_SEQUENCE); if (ret != 0) return POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret; if (end != p + len) return POLARSSL_ERR_X509_INVALID_EXTENSIONS + POLARSSL_ERR_ASN1_LENGTH_MISMATCH; while (p < end) { /* * Extension ::= SEQUENCE { * extnID OBJECT IDENTIFIER, * critical BOOLEAN DEFAULT FALSE, * extnValue OCTET STRING } */ x509_buf extn_oid = {0, 0, NULL}; int is_critical = 0; /* DEFAULT FALSE */ ret = asn1_get_tag(&p, end, &len, ASN1_CONSTRUCTED | ASN1_SEQUENCE); if (ret != 0) return POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret; end_ext_data = p + len; /* Get extension ID */ extn_oid.tag = *p; ret = asn1_get_tag(&p, end, &extn_oid.len, ASN1_OID); if (ret != 0) return POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret; extn_oid.p = p; p += extn_oid.len; if ((end - p) < 1) return POLARSSL_ERR_X509_INVALID_EXTENSIONS + POLARSSL_ERR_ASN1_OUT_OF_DATA; /* Get optional critical */ ret = asn1_get_bool(&p, end_ext_data, &is_critical); if (ret != 0 && (ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG)) return POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret; /* Data should be octet string type */ ret = asn1_get_tag(&p, end_ext_data, &len, ASN1_OCTET_STRING); if (ret != 0) return POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret; end_ext_octet = p + len; if (end_ext_octet != end_ext_data) return POLARSSL_ERR_X509_INVALID_EXTENSIONS + POLARSSL_ERR_ASN1_LENGTH_MISMATCH; /* Detect requested extension */ oid_get_numeric_string(oid_str, 64, &extn_oid); if (memcmp(oid, oid_str, sizeof(oid)) == 0) { *ext_data = p; *ext_len = len; return 0; } /* Next */ p = end_ext_octet; } if (p != end) return POLARSSL_ERR_X509_INVALID_EXTENSIONS + POLARSSL_ERR_ASN1_LENGTH_MISMATCH; return POLARSSL_ERR_X509_UNKNOWN_OID; }