]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
If OCSP revocation data are invalid or too old set appropriate verification flags.
authorNikos Mavrogiannopoulos <nmav@gnutls.org>
Sat, 13 Oct 2012 21:04:36 +0000 (23:04 +0200)
committerNikos Mavrogiannopoulos <nmav@gnutls.org>
Sat, 13 Oct 2012 21:07:12 +0000 (23:07 +0200)
NEWS
lib/gnutls_x509.c
lib/includes/gnutls/gnutls.h.in
src/common.c

diff --git a/NEWS b/NEWS
index ce32bf7c93ba10b0fa802e99e905488ad1c7d289..66f0b72a5986bd6bcaf5e70187f145d2e2559e17 100644 (file)
--- 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)
index 309b267b3ab8474e852544516def1a035bcd0255..8d52bc4ad05aea072e726679ceccae9db922b161 100644 (file)
@@ -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)
index 55928ce268a516925b1d1988014aebaf4a268b43..b6cd8be3128f1a0d11f606902ded6e967093f9e8 100644 (file)
@@ -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;
 
 /**
index 75048c621c6464c0d3df9551f3f2184763c0a1c0..9ef83b6f8116500ed967952a2c1d1b572247e7c0 100644 (file)
@@ -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)