]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
Use the server's OCSP provided data when verifying a certificate's validity.
authorNikos Mavrogiannopoulos <nmav@gnutls.org>
Fri, 28 Sep 2012 17:00:19 +0000 (19:00 +0200)
committerNikos Mavrogiannopoulos <nmav@gnutls.org>
Fri, 28 Sep 2012 17:00:19 +0000 (19:00 +0200)
src/cli.c
src/ocsptool-common.c

index aaf66c1c631e957f387fa3929c0f8baa12e79094..95a6da92ab5e7e0d8e81c1ed5d67a7828d4dfb60 100644 (file)
--- a/src/cli.c
+++ b/src/cli.c
@@ -403,7 +403,7 @@ cert_verify_callback (gnutls_session_t session)
       if (!insecure && !ssh)
         return -1;
     }
-  else if (ENABLED_OPT(OCSP))
+  else if (ENABLED_OPT(OCSP) || status_request_ocsp)
     { /* off-line verification succeeded. Try OCSP */
       rc = cert_verify_ocsp(session);
       if (rc == 0)
@@ -1104,6 +1104,9 @@ const char* rest = NULL;
 
   record_max_size = OPT_VALUE_RECORDSIZE;
   status_request_ocsp = HAVE_OPT(STATUS_REQUEST_OCSP);
+  if (ENABLED_OPT(OCSP))
+    status_request_ocsp = 1;
+  
   fingerprint = HAVE_OPT(FINGERPRINT);
 
   if (HAVE_OPT(X509FMTDER))
@@ -1482,6 +1485,26 @@ cert_verify_ocsp (gnutls_session_t session)
       ret = -1;
       goto cleanup;
     }
+
+  if (status_request_ocsp)
+    { /* try the server's OCSP response */
+      ret = gnutls_status_request_get_ocsp(session, &resp);
+      if (ret < 0 && !ENABLED_OPT(OCSP))
+        {
+          if (ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
+            fprintf(stderr, "gnutls_status_request_get_ocsp: %s\n", gnutls_strerror(ret));
+          ret = -1;
+          goto cleanup;
+        }
+      
+      if (ret >= 0)
+        {
+          ret = check_ocsp_response(issuer, &resp);
+          if (ret >= 0 || !ENABLED_OPT(OCSP))
+            goto cleanup;
+        }
+    }
+    
     
   ret = send_ocsp_request(NULL, crt, issuer, &resp, 1);
   if (ret < 0)
index 4436fd765710f69876e23e1a13bbf2fcf877f837..1c441b3824da25437a26db0edb5b06b60672bb1f 100644 (file)
@@ -302,6 +302,9 @@ print_ocsp_verify_res (unsigned int output)
     }
 }
 
+/* three days */
+#define OCSP_VALIDITY_SECS (3*60*60*24)
+
 /* Returns:
  *  0: certificate is revoked
  *  1: certificate is ok
@@ -314,7 +317,9 @@ check_ocsp_response (gnutls_x509_crt_t issuer,
   gnutls_ocsp_resp_t resp;
   int ret;
   unsigned int status, cert_status;
-  time_t rtime, ttime;
+  time_t rtime, vtime, ntime, now;
+  
+  now = time(0);
 
   ret = gnutls_ocsp_resp_init (&resp);
   if (ret < 0)
@@ -344,7 +349,7 @@ check_ocsp_response (gnutls_x509_crt_t issuer,
     }
 
   ret = gnutls_ocsp_resp_get_single(resp, 0, NULL, NULL, NULL, NULL,
-        &cert_status, &ttime, NULL, &rtime, NULL);
+        &cert_status, &vtime, &ntime, &rtime, NULL);
   if (ret < 0)
     error (EXIT_FAILURE, 0, "reading response: %s", gnutls_strerror (ret));
   
@@ -355,7 +360,27 @@ check_ocsp_response (gnutls_x509_crt_t issuer,
       goto cleanup;
     }
   
-  printf("- OCSP server flags certificate not revoked as of %s", ctime(&ttime));
+  if (ntime == -1)
+    {
+      if (now - vtime > OCSP_VALIDITY_SECS)
+        {
+          printf("*** The OCSP response is old (was issued at: %s) ignoring", ctime(&vtime));
+          ret = -1;
+          goto cleanup;
+        }
+    }
+  else
+    {
+      /* there is a newer OCSP answer, don't trust this one */
+      if (ntime < now)
+        {
+          printf("*** The OCSP response was issued at: %s, but there is a newer issue at %s", ctime(&vtime), ctime(&ntime));
+          ret = -1;
+          goto cleanup;
+        }
+    }
+  
+  printf("- OCSP server flags certificate not revoked as of %s", ctime(&vtime));
   ret = 1;
 cleanup:
   gnutls_ocsp_resp_deinit (resp);