}
/*
- * Verifies the given certificate again a certificate list of
+ * Verifies the given certificate against a certificate list of
* trusted CAs.
*
* Returns only 0 or 1. If 1 it means that the certificate
gnutls_x509_crt_t * _issuer,
time_t now,
unsigned int *max_path,
+ gnutls_x509_name_constraints_t nc,
gnutls_verify_output_function func)
{
gnutls_datum_t cert_signed_data = { NULL, 0 };
if (_issuer != NULL)
*_issuer = issuer;
+ if (nc != NULL) {
+ /* append the issuer's constraints */
+ result = gnutls_x509_crt_get_name_constraints(issuer, nc,
+ GNUTLS_NAME_CONSTRAINTS_FLAG_APPEND, NULL);
+ if (result < 0 && result != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
+ nc_fail:
+ out =
+ GNUTLS_CERT_SIGNER_CONSTRAINTS_FAILURE |
+ GNUTLS_CERT_INVALID;
+ if (output)
+ *output |= out;
+ gnutls_assert();
+ result = 0;
+ goto cleanup;
+ }
+
+ result = gnutls_x509_name_constraints_check_crt(nc, GNUTLS_SAN_DNSNAME, cert);
+ if (result == 0) {
+ gnutls_assert();
+ goto nc_fail;
+ }
+
+ result = gnutls_x509_name_constraints_check_crt(nc, GNUTLS_SAN_RFC822NAME, cert);
+ if (result == 0) {
+ gnutls_assert();
+ goto nc_fail;
+ }
+
+ result = gnutls_x509_name_constraints_check_crt(nc, GNUTLS_SAN_DN, cert);
+ if (result == 0) {
+ gnutls_assert();
+ goto nc_fail;
+ }
+
+ result = gnutls_x509_name_constraints_check_crt(nc, GNUTLS_SAN_URI, cert);
+ if (result == 0) {
+ gnutls_assert();
+ goto nc_fail;
+ }
+ }
+
issuer_version = gnutls_x509_crt_get_version(issuer);
if (issuer_version < 0) {
gnutls_assert();
- return issuer_version;
+ result = 0;
+ goto cleanup;
}
if (!(flags & GNUTLS_VERIFY_DISABLE_CA_SIGN) &&
_gnutls_x509_get_signed_data(cert->cert, "tbsCertificate",
&cert_signed_data);
if (result < 0) {
+ result = 0;
gnutls_assert();
goto cleanup;
}
_gnutls_x509_get_signature(cert->cert, "signature",
&cert_signature);
if (result < 0) {
+ result = 0;
gnutls_assert();
goto cleanup;
}
_gnutls_x509_get_signature_algorithm(cert->cert,
"signatureAlgorithm.algorithm");
if (result < 0) {
+ result = 0;
gnutls_assert();
goto cleanup;
}
*output |= out;
result = 0;
} else if (result < 0) {
+ result = 0;
gnutls_assert();
goto cleanup;
}
time_t now = gnutls_time(0);
gnutls_x509_crt_t issuer = NULL;
unsigned int max_path;
+ gnutls_x509_name_constraints_t nc;
if (clist_size > 1) {
/* Check if the last certificate in the path is self signed.
return status;
}
+ ret = gnutls_x509_name_constraints_init(&nc);
+ if (ret < 0) {
+ gnutls_assert();
+ status |= GNUTLS_CERT_INVALID;
+ return status;
+ }
+
/* Verify the last certificate in the certificate path
* against the trusted CA certificate list.
*
ret = _gnutls_verify_certificate2(certificate_list[clist_size - 1],
trusted_cas, tcas_size, flags,
&output, &issuer, now, &max_path,
- func);
+ nc, func);
if (ret == 0) {
/* if the last certificate in the certificate
* list is invalid, then the certificate is not
gnutls_assert();
status |= output;
status |= GNUTLS_CERT_INVALID;
- return status;
+ goto cleanup;
}
/* Verify the certificate path (chain)
_gnutls_verify_certificate2(certificate_list[i - 1],
&certificate_list[i], 1,
flags, &output, NULL, now,
- &max_path, func)) == 0) {
+ &max_path, nc, func)) == 0) {
status |= output;
status |= GNUTLS_CERT_INVALID;
- return status;
+ goto cleanup;
}
}
- return 0;
+ status = 0;
+cleanup:
+ gnutls_x509_name_constraints_deinit(nc);
+ return status;
}
#ifdef ENABLE_PKCS11
status |= GNUTLS_CERT_SIGNER_NOT_FOUND;
goto cleanup;
}
-
+
status = _gnutls_x509_verify_certificate(certificate_list, clist_size,
&issuer, 1, flags, func);
gnutls_free(raw_issuer.data);
if (issuer != NULL)
gnutls_x509_crt_deinit(issuer);
-
+
return status;
}
#endif