summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2012-10-13 23:04:36 +0200
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2012-10-13 23:07:12 +0200
commitdd77bd8f7fe31caa8bee4882e88086b2e643201a (patch)
treea8480bcccf66c3c7a68fc82b4a21597985502ebb
parent515a055d1ec7a59e8a6d6de4a349a639e8f11447 (diff)
downloadgnutls-dd77bd8f7fe31caa8bee4882e88086b2e643201a.tar.gz
If OCSP revocation data are invalid or too old set appropriate verification flags.
-rw-r--r--NEWS6
-rw-r--r--lib/gnutls_x509.c41
-rw-r--r--lib/includes/gnutls/gnutls.h.in8
-rw-r--r--src/common.c4
4 files changed, 36 insertions, 23 deletions
diff --git a/NEWS b/NEWS
index ce32bf7c93..66f0b72a59 100644
--- a/NEWS
+++ b/NEWS
@@ -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)