diff options
author | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2018-09-18 08:35:32 +0200 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2018-09-21 10:19:44 +0200 |
commit | 32929f3d489d0577b7c8e16fe3cee03d7a59fee3 (patch) | |
tree | a23cce567776ad6dea161a32f8c9effd090398d4 | |
parent | cc54c334f8a1f77a03d4e26ed6ac9a3f132a463f (diff) | |
download | gnutls-32929f3d489d0577b7c8e16fe3cee03d7a59fee3.tar.gz |
trust list: added flag to force failure on CRL validation error
This allows an application to be notified of the addition of invalid
CRLs in the trust list.
Signed-off-by: Nikos Mavrogiannopoulos <nmav@redhat.com>
-rw-r--r-- | lib/cert-cred-x509.c | 22 | ||||
-rw-r--r-- | lib/errors.c | 2 | ||||
-rw-r--r-- | lib/includes/gnutls/gnutls.h.in | 6 | ||||
-rw-r--r-- | lib/includes/gnutls/x509.h | 6 | ||||
-rw-r--r-- | lib/x509/verify-high.c | 2 |
5 files changed, 31 insertions, 7 deletions
diff --git a/lib/cert-cred-x509.c b/lib/cert-cred-x509.c index 99a0b366e7..f342a420b5 100644 --- a/lib/cert-cred-x509.c +++ b/lib/cert-cred-x509.c @@ -1493,10 +1493,14 @@ gnutls_certificate_set_x509_crl_mem(gnutls_certificate_credentials_t res, const gnutls_datum_t * CRL, gnutls_x509_crt_fmt_t type) { -int ret; + unsigned flags = GNUTLS_TL_USE_IN_TLS; + int ret; + + if (res->flags & GNUTLS_CERTIFICATE_VERIFY_CRLS) + flags |= GNUTLS_TL_VERIFY_CRL|GNUTLS_TL_FAIL_ON_INVALID_CRL; ret = gnutls_x509_trust_list_add_trust_mem(res->tlist, NULL, CRL, - type, GNUTLS_TL_USE_IN_TLS, 0); + type, flags, 0); if (ret == GNUTLS_E_NO_CERTIFICATE_FOUND) return 0; @@ -1526,6 +1530,10 @@ gnutls_certificate_set_x509_crl(gnutls_certificate_credentials_t res, { int ret, i, j; gnutls_x509_crl_t *new_crl = gnutls_malloc(crl_list_size * sizeof(gnutls_x509_crl_t)); + unsigned flags = GNUTLS_TL_USE_IN_TLS; + + if (res->flags & GNUTLS_CERTIFICATE_VERIFY_CRLS) + flags |= GNUTLS_TL_VERIFY_CRL|GNUTLS_TL_FAIL_ON_INVALID_CRL; if (!new_crl) return GNUTLS_E_MEMORY_ERROR; @@ -1546,7 +1554,7 @@ gnutls_certificate_set_x509_crl(gnutls_certificate_credentials_t res, ret = gnutls_x509_trust_list_add_crls(res->tlist, new_crl, - crl_list_size, GNUTLS_TL_USE_IN_TLS, 0); + crl_list_size, flags, 0); if (ret < 0) { gnutls_assert(); goto cleanup; @@ -1582,10 +1590,14 @@ gnutls_certificate_set_x509_crl_file(gnutls_certificate_credentials_t res, const char *crlfile, gnutls_x509_crt_fmt_t type) { -int ret; + int ret; + unsigned flags = GNUTLS_TL_USE_IN_TLS; + + if (res->flags & GNUTLS_CERTIFICATE_VERIFY_CRLS) + flags |= GNUTLS_TL_VERIFY_CRL|GNUTLS_TL_FAIL_ON_INVALID_CRL; ret = gnutls_x509_trust_list_add_trust_file(res->tlist, NULL, crlfile, - type, GNUTLS_TL_USE_IN_TLS, 0); + type, flags, 0); if (ret == GNUTLS_E_NO_CERTIFICATE_FOUND) return 0; diff --git a/lib/errors.c b/lib/errors.c index c4bc8c72b9..fb6b54b4b0 100644 --- a/lib/errors.c +++ b/lib/errors.c @@ -165,6 +165,8 @@ static const gnutls_error_entry error_entries[] = { GNUTLS_E_CERTIFICATE_TIME_ERROR), ERROR_ENTRY(N_("Error in the certificate verification."), GNUTLS_E_CERTIFICATE_VERIFICATION_ERROR), + ERROR_ENTRY(N_("Error in the CRL verification."), + GNUTLS_E_CRL_VERIFICATION_ERROR), ERROR_ENTRY(N_("Error in the private key verification; seed doesn't match."), GNUTLS_E_PRIVKEY_VERIFICATION_ERROR), ERROR_ENTRY(N_("Could not authenticate peer."), diff --git a/lib/includes/gnutls/gnutls.h.in b/lib/includes/gnutls/gnutls.h.in index 2ee3e4fc83..49990b5f50 100644 --- a/lib/includes/gnutls/gnutls.h.in +++ b/lib/includes/gnutls/gnutls.h.in @@ -1928,13 +1928,16 @@ gnutls_certificate_get_verify_flags(gnutls_certificate_credentials_t res); * @GNUTLS_CERTIFICATE_API_V2: If set the gnutls_certificate_set_*key* functions will return an index of the added key pair instead of zero. * @GNUTLS_CERTIFICATE_SKIP_OCSP_RESPONSE_CHECK: If set, the gnutls_certificate_set_ocsp_status_request_file * function, will not check whether the response set matches any of the certificates. + * @GNUTLS_CERTIFICATE_VERIFY_CRLS: This will enable CRL verification when added in the certificate structure. + * When used, it requires CAs to be added before CRLs. * * Enumeration of different certificate credentials flags. */ typedef enum gnutls_certificate_flags { GNUTLS_CERTIFICATE_SKIP_KEY_CERT_MATCH = 1, GNUTLS_CERTIFICATE_API_V2 = (1<<1), - GNUTLS_CERTIFICATE_SKIP_OCSP_RESPONSE_CHECK = (1<<2) + GNUTLS_CERTIFICATE_SKIP_OCSP_RESPONSE_CHECK = (1<<2), + GNUTLS_CERTIFICATE_VERIFY_CRLS = (1<<3) } gnutls_certificate_flags; void gnutls_certificate_set_flags(gnutls_certificate_credentials_t, @@ -3214,6 +3217,7 @@ void gnutls_fips140_set_mode(gnutls_fips_mode_t mode, unsigned flags); #define GNUTLS_E_NO_COMMON_KEY_SHARE -423 #define GNUTLS_E_REAUTH_REQUEST -424 #define GNUTLS_E_TOO_MANY_MATCHES -425 +#define GNUTLS_E_CRL_VERIFICATION_ERROR -426 #define GNUTLS_E_UNIMPLEMENTED_FEATURE -1250 diff --git a/lib/includes/gnutls/x509.h b/lib/includes/gnutls/x509.h index cd54e8c4ca..1573577d96 100644 --- a/lib/includes/gnutls/x509.h +++ b/lib/includes/gnutls/x509.h @@ -1562,6 +1562,8 @@ int gnutls_x509_trust_list_get_issuer_by_subject_key_id(gnutls_x509_trust_list_t * @GNUTLS_TL_GET_COPY: The semantics of this flag are documented to the functions which * are applicable. In general, on returned value, the function will provide a copy * if this flag is provided, rather than a pointer to internal data. + * @GNUTLS_TL_FAIL_ON_INVALID_CRL: If an CRL is added which cannot be validated return + * an error instead of ignoring (must be used with %GNUTLS_TL_VERIFY_CRL). * * Enumeration of different certificate trust list flags. */ @@ -1574,8 +1576,10 @@ typedef enum gnutls_trust_list_flags_t { #define GNUTLS_TL_NO_DUPLICATES (1<<2) GNUTLS_TL_NO_DUPLICATE_KEY = (1<<3), #define GNUTLS_TL_NO_DUPLICATE_KEY (1<<3) - GNUTLS_TL_GET_COPY = (1<<4) + GNUTLS_TL_GET_COPY = (1<<4), #define GNUTLS_TL_GET_COPY (1<<4) + GNUTLS_TL_FAIL_ON_INVALID_CRL = (1<<5) +#define GNUTLS_TL_FAIL_ON_INVALID_CRL (1<<5) } gnutls_trust_list_flags_t; int diff --git a/lib/x509/verify-high.c b/lib/x509/verify-high.c index 03c63c2687..7f640f1a13 100644 --- a/lib/x509/verify-high.c +++ b/lib/x509/verify-high.c @@ -749,6 +749,8 @@ gnutls_x509_trust_list_add_crls(gnutls_x509_trust_list_t list, _gnutls_debug_log("CRL verification failed, not adding it\n"); if (flags & GNUTLS_TL_NO_DUPLICATES) gnutls_x509_crl_deinit(crl_list[i]); + if (flags & GNUTLS_TL_FAIL_ON_INVALID_CRL) + return gnutls_assert_val(GNUTLS_E_CRL_VERIFICATION_ERROR); continue; } } |