_gnutls_check_if_same_cert2(gnutls_x509_crt_t cert1,
gnutls_datum_t * cert2bin);
+bool _gnutls_check_key_purpose(gnutls_x509_crt_t cert, const char *purpose);
+
time_t _gnutls_x509_generalTime2gtime(const char *ttime);
int _gnutls_get_extension(ASN1_TYPE asn, const char *root,
NULL, 0, flags, voutput, func);
}
-static
-int check_key_purpose(gnutls_x509_crt_t crt, const gnutls_datum_t *ext_data, unsigned *voutput,
- const char *purpose)
-{
- gnutls_datum_t coid = {NULL, 0};
- gnutls_x509_key_purposes_t p = NULL;
- unsigned i;
- int ret;
-
- ret = gnutls_x509_key_purpose_init(&p);
- if (ret < 0) {
- gnutls_assert();
- goto fail;
- }
-
- ret = gnutls_x509_ext_import_key_purposes(ext_data, p, 0);
- if (ret < 0) {
- gnutls_assert();
- goto fail;
- }
-
- for (i=0;;i++) {
- ret = gnutls_x509_key_purpose_get(p, i, &coid);
- if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
- if (i==0) {
- break;
- } else { /* no acceptable purpose was found */
- gnutls_assert();
- goto fail;
- }
- } else if (ret < 0) {
- gnutls_assert();
- goto fail;
- }
-
- if (strcmp((char*)coid.data, purpose) == 0 || strcmp((char*)coid.data, GNUTLS_KP_ANY) == 0)
- break;
- }
-
- gnutls_x509_key_purpose_deinit(p);
- return 0;
- fail:
- *voutput |= GNUTLS_CERT_SIGNER_CONSTRAINTS_FAILURE|GNUTLS_CERT_INVALID;
- if (p != NULL)
- gnutls_x509_key_purpose_deinit(p);
- return ret;
-}
-
/**
* gnutls_x509_trust_list_verify_crt2:
* @list: The structure of the list
}
/* End-certificate, key purpose and hostname checks. */
- if (purpose) do {
- gnutls_datum_t ext_data = {NULL, 0};
-
- ret = gnutls_x509_crt_get_extension_by_oid2(cert_list[0], "2.5.29.37", 0, &ext_data, NULL);
- if (ret < 0) {
- /* it's not a fatal error if the extended key usage extension isn't there */
- gnutls_assert();
- break;
- }
-
- ret = check_key_purpose(cert_list[0], &ext_data, voutput, purpose);
- gnutls_free(ext_data.data);
-
- if (ret < 0) {
+ if (purpose) {
+ ret = _gnutls_check_key_purpose(cert_list[0], purpose);
+ if (ret != 1) {
gnutls_assert();
+ *voutput |= GNUTLS_CERT_SIGNER_CONSTRAINTS_FAILURE|GNUTLS_CERT_INVALID;
}
- } while(0);
+ }
if (hostname) {
ret =
return status;
}
-#ifdef ENABLE_PKCS11
-static bool check_key_purpose(gnutls_x509_crt_t issuer, const char *purpose)
+/* Returns true if the provided purpose is in accordance with the certificate.
+ */
+bool _gnutls_check_key_purpose(gnutls_x509_crt_t cert, const char *purpose)
{
char oid[MAX_OID_SIZE];
size_t oid_size;
for (i=0;;i++) {
oid_size = sizeof(oid);
- ret = gnutls_x509_crt_get_key_purpose_oid(issuer, i, oid, &oid_size, NULL);
+ ret = gnutls_x509_crt_get_key_purpose_oid(cert, i, oid, &oid_size, NULL);
if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
if (i==0) {
/* no key purpose in certificate, assume ANY */
return 0;
}
+#ifdef ENABLE_PKCS11
/* Verify X.509 certificate chain using a PKCS #11 token.
*
* Note that the return value is an OR of GNUTLS_CERT_* elements.
}
if (purpose != NULL) {
- ret = check_key_purpose(issuer, purpose);
+ ret = _gnutls_check_key_purpose(issuer, purpose);
if (ret != 1) {
gnutls_assert();
status |= GNUTLS_CERT_INVALID;