diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2010-03-14 22:57:55 +0100 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2010-03-14 22:57:55 +0100 |
commit | 897cbce62c0263a498088ac3e465aa5f05f8719c (patch) | |
tree | a4ef11e2a99a1a18f8a700ffded7528bc28b5d08 | |
parent | e9724276a47562bac049b1c98d3c9e31f639dd41 (diff) | |
download | gnutls-897cbce62c0263a498088ac3e465aa5f05f8719c.tar.gz |
Extended time verification to trusted certificate list as well. Introduced
the flag GNUTLS_VERIFY_DISABLE_TRUSTED_TIME_CHECKS that will prevent the
trusted certificate list verification.
-rw-r--r-- | NEWS | 3 | ||||
-rw-r--r-- | lib/includes/gnutls/x509.h | 5 | ||||
-rw-r--r-- | lib/x509/verify.c | 83 |
3 files changed, 70 insertions, 21 deletions
@@ -5,6 +5,9 @@ See the end for copying conditions. * Version 2.9.10 (unreleased) +** libgnutls: Time verification extended to trusted certificate list, +unless GNUTLS_VERIFY_DISABLE_TRUSTED_TIME_CHECKS flag is specified. + ** libgnutls: Added Steve Dispensa's patch for safe renegotiation (RFC 5746) Solves the issue discussed in: <http://www.ietf.org/mail-archive/web/tls/current/msg03928.html> and diff --git a/lib/includes/gnutls/x509.h b/lib/includes/gnutls/x509.h index 0645e9b1d7..6ea5f5d6ab 100644 --- a/lib/includes/gnutls/x509.h +++ b/lib/includes/gnutls/x509.h @@ -500,6 +500,8 @@ extern "C" * @GNUTLS_VERIFY_DISABLE_CA_SIGN: If set a signer does not have to be * a certificate authority. This flag should normaly be disabled, * unless you know what this means. + * @GNUTLS_VERIFY_DISABLE_TRUSTED_TIME_CHECKS: If set a signer in the trusted + * list is never checked for expiration or activation. * @GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT: Allow only trusted CA * certificates that have version 1. This is safer than * %GNUTLS_VERIFY_ALLOW_ANY_X509_V1_CA_CRT, and should be used @@ -531,7 +533,8 @@ extern "C" GNUTLS_VERIFY_ALLOW_ANY_X509_V1_CA_CRT = 8, GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD2 = 16, GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD5 = 32, - GNUTLS_VERIFY_DISABLE_TIME_CHECKS = 64 + GNUTLS_VERIFY_DISABLE_TIME_CHECKS = 64, + GNUTLS_VERIFY_DISABLE_TRUSTED_TIME_CHECKS = 128, } gnutls_certificate_verify_flags; int gnutls_x509_crt_check_issuer (gnutls_x509_crt_t cert, diff --git a/lib/x509/verify.c b/lib/x509/verify.c index a464596ac6..5bb20bc95c 100644 --- a/lib/x509/verify.c +++ b/lib/x509/verify.c @@ -42,7 +42,7 @@ static int _gnutls_verify_certificate2 (gnutls_x509_crt_t cert, const gnutls_x509_crt_t * trusted_cas, int tcas_size, unsigned int flags, - unsigned int *output); + unsigned int *output, gnutls_x509_crt_t* issuer); static int is_crl_issuer (gnutls_x509_crl_t crl, gnutls_x509_crt_t issuer_cert); @@ -261,17 +261,17 @@ find_issuer (gnutls_x509_crt_t cert, * 'flags': an OR of the gnutls_certificate_verify_flags enumeration. * * Output will hold some extra information about the verification - * procedure. + * procedure. Issuer will hold the actual issuer from the trusted list. */ static int _gnutls_verify_certificate2 (gnutls_x509_crt_t cert, const gnutls_x509_crt_t * trusted_cas, int tcas_size, unsigned int flags, - unsigned int *output) + unsigned int *output, gnutls_x509_crt_t *_issuer) { gnutls_datum_t cert_signed_data = { NULL, 0 }; gnutls_datum_t cert_signature = { NULL, 0 }; - gnutls_x509_crt_t issuer; + gnutls_x509_crt_t issuer = NULL; int ret, issuer_version, result; if (output) @@ -298,6 +298,8 @@ _gnutls_verify_certificate2 (gnutls_x509_crt_t cert, return 0; } + if (_issuer != NULL) *_issuer = issuer; + issuer_version = gnutls_x509_crt_get_version (issuer); if (issuer_version < 0) { @@ -399,6 +401,29 @@ gnutls_x509_crt_check_issuer (gnutls_x509_crt_t cert, return is_issuer (cert, issuer); } +static unsigned int check_time(gnutls_x509_crt_t crt, time_t now) +{ +int status = 0; +time_t t; + + t = gnutls_x509_crt_get_activation_time (crt); + if (t == (time_t) - 1 || now < t) + { + status |= GNUTLS_CERT_NOT_ACTIVATED; + status |= GNUTLS_CERT_INVALID; + return status; + } + + t = gnutls_x509_crt_get_expiration_time (crt); + if (t == (time_t) - 1 || now > t) + { + status |= GNUTLS_CERT_EXPIRED; + status |= GNUTLS_CERT_INVALID; + return status; + } + + return 0; +} /* Verify X.509 certificate chain. * @@ -417,6 +442,8 @@ _gnutls_x509_verify_certificate (const gnutls_x509_crt_t * certificate_list, { int i = 0, ret; unsigned int status = 0, output; + time_t now = time (0); + gnutls_x509_crt_t issuer = NULL; if (clist_size > 1) { @@ -452,6 +479,17 @@ _gnutls_x509_verify_certificate (const gnutls_x509_crt_t * certificate_list, if (check_if_same_cert (certificate_list[i], trusted_cas[j]) == 0) { + /* explicity time check for trusted CA that we remove from + * list. GNUTLS_VERIFY_DISABLE_TRUSTED_TIME_CHECKS + */ + if (!(flags&GNUTLS_VERIFY_DISABLE_TRUSTED_TIME_CHECKS) && !(flags&GNUTLS_VERIFY_DISABLE_TIME_CHECKS)) + { + status |= check_time(trusted_cas[j], now); + if (status != 0) + { + return status; + } + } clist_size = i; break; } @@ -472,7 +510,7 @@ _gnutls_x509_verify_certificate (const gnutls_x509_crt_t * certificate_list, * in self signed etc certificates. */ ret = _gnutls_verify_certificate2 (certificate_list[clist_size - 1], - trusted_cas, tcas_size, flags, &output); + trusted_cas, tcas_size, flags, &output, &issuer); if (ret == 0) { /* if the last certificate in the certificate @@ -501,27 +539,32 @@ _gnutls_x509_verify_certificate (const gnutls_x509_crt_t * certificate_list, } #endif + /* Check activation/expiration times */ if (!(flags & GNUTLS_VERIFY_DISABLE_TIME_CHECKS)) { - time_t t, now = time (0); + /* check the time of the issuer first */ + if (!(flags&GNUTLS_VERIFY_DISABLE_TRUSTED_TIME_CHECKS)) + { + if (issuer == NULL) + { + gnutls_assert(); + return GNUTLS_E_INTERNAL_ERROR; + } + + status |= check_time(issuer, now); + if (status != 0) + { + return status; + } + } for (i = 0; i < clist_size; i++) { - t = gnutls_x509_crt_get_activation_time (certificate_list[i]); - if (t == (time_t) - 1 || now < t) - { - status |= GNUTLS_CERT_NOT_ACTIVATED; - status |= GNUTLS_CERT_INVALID; - return status; - } - - t = gnutls_x509_crt_get_expiration_time (certificate_list[i]); - if (t == (time_t) - 1 || now > t) + status |= check_time(certificate_list[i], now); + if (status != 0) { - status |= GNUTLS_CERT_EXPIRED; - status |= GNUTLS_CERT_INVALID; return status; } } @@ -542,7 +585,7 @@ _gnutls_x509_verify_certificate (const gnutls_x509_crt_t * certificate_list, if ((ret = _gnutls_verify_certificate2 (certificate_list[i - 1], &certificate_list[i], 1, flags, - NULL)) == 0) + NULL, NULL)) == 0) { status |= GNUTLS_CERT_INVALID; return status; @@ -1009,7 +1052,7 @@ gnutls_x509_crt_verify (gnutls_x509_crt_t cert, */ ret = _gnutls_verify_certificate2 (cert, CA_list, CA_list_length, flags, - verify); + verify, NULL); if (ret < 0) { gnutls_assert (); |