summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@redhat.com>2018-09-18 08:35:32 +0200
committerNikos Mavrogiannopoulos <nmav@redhat.com>2018-09-20 10:17:38 +0200
commit86ffc1de074dfa6d96d0342bf14e2f6b74599509 (patch)
tree21ef629196d03abe9191034274e7fd3a53a499cb
parent8ee1fb73c8284bfd2105d7258d217d1f6fbb3696 (diff)
downloadgnutls-86ffc1de074dfa6d96d0342bf14e2f6b74599509.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.c22
-rw-r--r--lib/errors.c2
-rw-r--r--lib/includes/gnutls/gnutls.h.in6
-rw-r--r--lib/includes/gnutls/x509.h6
-rw-r--r--lib/x509/verify-high.c2
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;
}
}