diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2012-10-13 23:04:36 +0200 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2012-10-13 23:07:12 +0200 |
commit | dd77bd8f7fe31caa8bee4882e88086b2e643201a (patch) | |
tree | a8480bcccf66c3c7a68fc82b4a21597985502ebb | |
parent | 515a055d1ec7a59e8a6d6de4a349a639e8f11447 (diff) | |
download | gnutls-dd77bd8f7fe31caa8bee4882e88086b2e643201a.tar.gz |
If OCSP revocation data are invalid or too old set appropriate verification flags.
-rw-r--r-- | NEWS | 6 | ||||
-rw-r--r-- | lib/gnutls_x509.c | 41 | ||||
-rw-r--r-- | lib/includes/gnutls/gnutls.h.in | 8 | ||||
-rw-r--r-- | src/common.c | 4 |
4 files changed, 36 insertions, 23 deletions
@@ -4,10 +4,14 @@ See the end for copying conditions. * Version 3.1.4 (unreleased) +** libgnutls: gnutls_certificate_verify_peers2() will set flags depending on +the available revocation data validity. + ** gnutls-cli: Added --local-dns option. ** API and ABI modifications: -No changes since last version. +GNUTLS_CERT_REVOCATION_DATA_TOO_OLD: Added. +GNUTLS_CERT_REVOCATION_DATA_INVALID: Added. * Version 3.1.3 (released 2012-10-12) diff --git a/lib/gnutls_x509.c b/lib/gnutls_x509.c index 309b267b3a..8d52bc4ad0 100644 --- a/lib/gnutls_x509.c +++ b/lib/gnutls_x509.c @@ -88,15 +88,15 @@ check_bits (gnutls_session_t session, gnutls_x509_crt_t crt, unsigned int max_bi /* three days */ #define MAX_OCSP_VALIDITY_SECS (3*60*60*24) -/* Returns: - * -1: certificate is revoked - * 1: certificate is ok - * 0: dunno +/* If the certificate is revoked status will be GNUTLS_CERT_REVOKED. + * + * Returns: + * Zero on success, a negative error code otherwise. */ static int check_ocsp_response (gnutls_session_t session, gnutls_x509_crt_t cert, gnutls_x509_crt_t issuer, - gnutls_datum_t *data) + gnutls_datum_t *data, unsigned int * ostatus) { gnutls_ocsp_resp_t resp; int ret; @@ -107,23 +107,22 @@ check_ocsp_response (gnutls_session_t session, gnutls_x509_crt_t cert, ret = gnutls_ocsp_resp_init (&resp); if (ret < 0) - return gnutls_assert_val(0); + return gnutls_assert_val(ret); ret = gnutls_ocsp_resp_import (resp, data); if (ret < 0) - return gnutls_assert_val(0); + return gnutls_assert_val(ret); ret = gnutls_ocsp_resp_check_crt(resp, 0, cert); if (ret < 0) { - _gnutls_audit_log (session, "Got OCSP response on an unrelated certificate (ignoring)\n"); - ret = 0; + _gnutls_audit_log (session, "Got OCSP response on an unrelated certificate.\n"); goto cleanup; } ret = gnutls_ocsp_resp_verify_direct( resp, issuer, &status, 0); if (ret < 0) - return gnutls_assert_val(0); + return gnutls_assert_val(ret); /* do not consider revocation data if response was not verified */ if (status != 0) @@ -137,13 +136,15 @@ check_ocsp_response (gnutls_session_t session, gnutls_x509_crt_t cert, if (ret < 0) { ret = gnutls_assert_val(0); + *ostatus |= GNUTLS_CERT_REVOCATION_DATA_INVALID; goto cleanup; } if (cert_status == GNUTLS_OCSP_CERT_REVOKED) { _gnutls_audit_log(session, "The certificate was revoked via OCSP\n"); - ret = gnutls_assert_val(-1); + *ostatus |= GNUTLS_CERT_REVOKED; + ret = gnutls_assert_val(0); goto cleanup; } @@ -160,10 +161,12 @@ check_ocsp_response (gnutls_session_t session, gnutls_x509_crt_t cert, if (ntime < now) { _gnutls_audit_log(session, "There is a newer OCSP response but was not provided by the server\n"); + if (now-ntime > MAX_OCSP_VALIDITY_SECS) + *ostatus |= GNUTLS_CERT_REVOCATION_DATA_TOO_OLD; } } - ret = 1; + ret = 0; cleanup: gnutls_ocsp_resp_deinit (resp); @@ -284,9 +287,12 @@ _gnutls_x509_cert_verify_peers (gnutls_session_t session, } } - ret = check_ocsp_response(session, peer_certificate_list[0], issuer, &resp); - if (ret < 0) /* revoked */ - ocsp_status |= GNUTLS_CERT_REVOKED; + ret = check_ocsp_response(session, peer_certificate_list[0], issuer, &resp, &ocsp_status); + if (ret < 0) + { + CLEAR_CERTS; + return gnutls_assert_val(ret); + } skip_ocsp: /* Verify certificate @@ -310,11 +316,6 @@ skip_ocsp: return 0; } -/* - * Read certificates and private keys, from files, memory etc. - */ - - /* Returns the name of the certificate of a null name */ static int get_x509_name(gnutls_x509_crt_t crt, gnutls_str_array_t *names) diff --git a/lib/includes/gnutls/gnutls.h.in b/lib/includes/gnutls/gnutls.h.in index 55928ce268..b6cd8be312 100644 --- a/lib/includes/gnutls/gnutls.h.in +++ b/lib/includes/gnutls/gnutls.h.in @@ -444,9 +444,11 @@ extern "C" * should not be trusted. * @GNUTLS_CERT_NOT_ACTIVATED: The certificate is not yet activated. * @GNUTLS_CERT_EXPIRED: The certificate has expired. + * @GNUTLS_CERT_REVOCATION_DATA_TOO_OLD: The OCSP revocation data are too old. + * @GNUTLS_CERT_REVOCATION_DATA_INVALID: The OCSP revocation data are invalid. * * Enumeration of certificate status codes. Note that the status - * bits have different meanings in OpenPGP keys and X.509 + * bits may have different meanings in OpenPGP keys and X.509 * certificate verification. */ typedef enum @@ -458,7 +460,9 @@ extern "C" GNUTLS_CERT_INSECURE_ALGORITHM = 256, GNUTLS_CERT_NOT_ACTIVATED = 512, GNUTLS_CERT_EXPIRED = 1024, - GNUTLS_CERT_SIGNATURE_FAILURE = 2048 + GNUTLS_CERT_SIGNATURE_FAILURE = 2048, + GNUTLS_CERT_REVOCATION_DATA_TOO_OLD = 4096, + GNUTLS_CERT_REVOCATION_DATA_INVALID = 8192, } gnutls_certificate_status_t; /** diff --git a/src/common.c b/src/common.c index 75048c621c..9ef83b6f81 100644 --- a/src/common.c +++ b/src/common.c @@ -439,6 +439,10 @@ cert_verify (gnutls_session_t session, const char* hostname) if (status & GNUTLS_CERT_REVOKED) printf ("- Peer's certificate chain revoked\n"); + if (status & GNUTLS_CERT_REVOCATION_DATA_TOO_OLD) + printf ("- The revocation data provided by the peer are too old\n"); + if (status & GNUTLS_CERT_REVOCATION_DATA_INVALID) + printf ("- The revocation data provided by the peer are invalid\n"); if (status & GNUTLS_CERT_SIGNER_NOT_FOUND) printf ("- Peer's certificate issuer is unknown\n"); if (status & GNUTLS_CERT_SIGNER_NOT_CA) |