gnutls-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[SCM] GNU gnutls branch, ocsp, updated. gnutls_3_0_8-50-g5269104


From: Simon Josefsson
Subject: [SCM] GNU gnutls branch, ocsp, updated. gnutls_3_0_8-50-g5269104
Date: Thu, 15 Dec 2011 12:40:59 +0000

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU gnutls".

http://git.savannah.gnu.org/cgit/gnutls.git/commit/?id=5269104c4ef577c4957b0bff762100233795765e

The branch, ocsp has been updated
       via  5269104c4ef577c4957b0bff762100233795765e (commit)
       via  0603301e92f444daccbcc301d1dfd043e9190e71 (commit)
      from  f4f9ab89dad07c87ab32173fc2a72ec31ff11ad9 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 5269104c4ef577c4957b0bff762100233795765e
Author: Simon Josefsson <address@hidden>
Date:   Thu Dec 15 12:05:35 2011 +0100

    Split up OCSP response verify functions.

commit 0603301e92f444daccbcc301d1dfd043e9190e71
Author: Simon Josefsson <address@hidden>
Date:   Thu Dec 15 11:46:57 2011 +0100

    Doc fix.

-----------------------------------------------------------------------

Summary of changes:
 NEWS                       |    3 +-
 doc/cha-cert-auth2.texi    |    5 +
 doc/manpages/Makefile.am   |    1 +
 lib/includes/gnutls/ocsp.h |    5 +-
 lib/libgnutls.map          |   11 +-
 lib/x509/ocsp.c            |  300 +++++++++++++++++++++++++-------------------
 src/ocsptool.c             |    2 +-
 7 files changed, 191 insertions(+), 136 deletions(-)

diff --git a/NEWS b/NEWS
index 36885b7..80009d2 100644
--- a/NEWS
+++ b/NEWS
@@ -9,7 +9,8 @@ There is a new header file gnutls/ocsp.h and a set of new 
functions
 under the gnutls_ocsp namespace.  Currently the functionality provided
 is to parse and extract information from OCSP requests/responses, to
 generate OCSP requests and to verify OCSP responses.  See the manual
-for more information.
+for more information.  Run ./configure with --disable-ocsp to build
+GnuTLS without OCSP support.
 
 ** ocsptool: Added new command line tool.
 The tool can parse OCSP request/responses, generate OCSP requests and
diff --git a/doc/cha-cert-auth2.texi b/doc/cha-cert-auth2.texi
index 5e22b02..f5d2f4d 100644
--- a/doc/cha-cert-auth2.texi
+++ b/doc/cha-cert-auth2.texi
@@ -277,6 +277,11 @@ automatically parsed when an OCSP Response is imported.
 
 
@showfuncE{gnutls_ocsp_resp_init,gnutls_ocsp_resp_deinit,gnutls_ocsp_resp_import,gnutls_ocsp_resp_export,gnutls_ocsp_resp_print}
 
+The OCSP response needs to be verified against some set of trust
+anchors before it can be relied upon.
+
address@hidden,gnutls_ocsp_resp_verify_direct}
+
 @node Managing encrypted keys
 @section Managing encrypted keys
 @cindex Encrypted keys
diff --git a/doc/manpages/Makefile.am b/doc/manpages/Makefile.am
index bb14f48..a804745 100644
--- a/doc/manpages/Makefile.am
+++ b/doc/manpages/Makefile.am
@@ -384,6 +384,7 @@ APIMANS += gnutls_ocsp_resp_get_nonce.3
 APIMANS += gnutls_ocsp_resp_get_signature_algorithm.3
 APIMANS += gnutls_ocsp_resp_get_signature.3
 APIMANS += gnutls_ocsp_resp_get_certs.3
+APIMANS += gnutls_ocsp_resp_verify_direct.3
 APIMANS += gnutls_ocsp_resp_verify.3
 APIMANS += gnutls_openpgp_crt_init.3
 APIMANS += gnutls_openpgp_crt_deinit.3
diff --git a/lib/includes/gnutls/ocsp.h b/lib/includes/gnutls/ocsp.h
index ab98743..1044d21 100644
--- a/lib/includes/gnutls/ocsp.h
+++ b/lib/includes/gnutls/ocsp.h
@@ -223,9 +223,12 @@ extern "C"
                                  gnutls_x509_crt_t ** certs,
                                  size_t *ncerts);
 
+  int gnutls_ocsp_resp_verify_direct (gnutls_ocsp_resp_t resp,
+                                     gnutls_x509_crt_t signercert,
+                                     unsigned *verify,
+                                     int flags);
   int gnutls_ocsp_resp_verify (gnutls_ocsp_resp_t resp,
                               gnutls_x509_trust_list_t trustlist,
-                              gnutls_x509_crt_t signercert,
                               unsigned *verify,
                               int flags);
 
diff --git a/lib/libgnutls.map b/lib/libgnutls.map
index aaf2dea..b7be867 100644
--- a/lib/libgnutls.map
+++ b/lib/libgnutls.map
@@ -718,22 +718,25 @@ GNUTLS_3_0_0 {
        gnutls_pubkey_import_ecc_raw2;
        gnutls_record_get_discarded;
        gnutls_x509_crt_get_authority_info_access;
+       gnutls_ocsp_req_add_cert;
        gnutls_ocsp_req_add_cert_id;
        gnutls_ocsp_req_deinit;
        gnutls_ocsp_req_export;
        gnutls_ocsp_req_get_cert_id;
-       gnutls_ocsp_req_add_cert;
-       gnutls_ocsp_req_get_nonce;
        gnutls_ocsp_req_get_extension;
+       gnutls_ocsp_req_get_nonce;
        gnutls_ocsp_req_get_version;
        gnutls_ocsp_req_import;
        gnutls_ocsp_req_init;
        gnutls_ocsp_req_print;
+       gnutls_ocsp_req_randomize_nonce;
        gnutls_ocsp_req_set_extension;
+       gnutls_ocsp_req_set_nonce;
        gnutls_ocsp_resp_deinit;
        gnutls_ocsp_resp_export;
        gnutls_ocsp_resp_get_certs;
        gnutls_ocsp_resp_get_extension;
+       gnutls_ocsp_resp_get_nonce;
        gnutls_ocsp_resp_get_produced;
        gnutls_ocsp_resp_get_responder;
        gnutls_ocsp_resp_get_response;
@@ -745,10 +748,8 @@ GNUTLS_3_0_0 {
        gnutls_ocsp_resp_import;
        gnutls_ocsp_resp_init;
        gnutls_ocsp_resp_print;
-       gnutls_ocsp_resp_get_nonce;
-       gnutls_ocsp_req_set_nonce;
        gnutls_ocsp_resp_verify;
-       gnutls_ocsp_req_randomize_nonce;
+       gnutls_ocsp_resp_verify_direct;
        gnutls_privkey_import_ext;
        gnutls_certificate_set_key;
        gnutls_srp_3072_group_generator;
diff --git a/lib/x509/ocsp.c b/lib/x509/ocsp.c
index cc70c11..fda1f5f 100644
--- a/lib/x509/ocsp.c
+++ b/lib/x509/ocsp.c
@@ -453,6 +453,9 @@ gnutls_ocsp_req_get_version (gnutls_ocsp_req_t req)
  *        serialNumber        CertificateSerialNumber }
  * </programlisting></informalexample>
  *
+ * Each of the pointers to output variables may be NULL to indicate
+ * that the caller is not interested in that value.
+ *
  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
  *   negative error code is returned.  If you have reached the last
  *   CertID available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be
@@ -1247,8 +1250,7 @@ gnutls_ocsp_resp_get_produced (gnutls_ocsp_resp_t resp)
  * This function will return the certificate information of the
  * @indx'ed response in the Basic OCSP Response @resp.  The
  * information returned corresponds to the SingleResponse structure
- * except the final singleExtensions (use
- * gnutls_ocsp_get_singleextensions() for that).
+ * except the final singleExtensions, reproduced here for illustration:
  *
  * <informalexample><programlisting>
  * SingleResponse ::= SEQUENCE {
@@ -1274,6 +1276,9 @@ gnutls_ocsp_resp_get_produced (gnutls_ocsp_resp_t resp)
  *     revocationReason    [0]     EXPLICIT CRLReason OPTIONAL }
  * </programlisting></informalexample>
  *
+ * Each of the pointers to output variables may be NULL to indicate
+ * that the caller is not interested in that value.
+ *
  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
  *   negative error code is returned.  If you have reached the last
  *   CertID available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be
@@ -1481,10 +1486,10 @@ gnutls_ocsp_resp_get_single (gnutls_ocsp_resp_t resp,
  **/
 int
 gnutls_ocsp_resp_get_extension (gnutls_ocsp_resp_t resp,
-                              unsigned indx,
-                              gnutls_datum_t *oid,
-                              unsigned int *critical,
-                              gnutls_datum_t *data)
+                               unsigned indx,
+                               gnutls_datum_t *oid,
+                               unsigned int *critical,
+                               gnutls_datum_t *data)
 {
   int ret;
   char str_critical[10];
@@ -1859,22 +1864,14 @@ find_signercert (gnutls_ocsp_resp_t resp)
 }
 
 /**
- * gnutls_ocsp_resp_verify:
+ * gnutls_ocsp_resp_verify_direct:
  * @resp: should contain a #gnutls_ocsp_resp_t structure
- * @trustlist: trust anchors as a #gnutls_x509_trust_list_t structure, or NULL
- * @signercert: give explicit signer cert, or NULL
+ * @signercert: certificate believed to have signed the response
  * @verify: output variable with verification status codes
  * @flags: verification flags, 0 for now.
  *
  * Verify signature of the Basic OCSP Response against the public key
- * in the certificate of a trusted signer.
- *
- * Normally the @trustlist is populated with trusted CAs and
- * @signercert is NULL.  In this mode, the function will find the
- * signer certificate in the Basic OCSP Response and will verify it
- * against the @trustlist.  If for some reason you may want to attempt
- * to verify the signature against a particular certificate, specify
- * it in @signercert and leave @trustlist as NULL.
+ * in the @signercert certificate.
  *
  * The output @verify variable will hold verification status codes
  * (e.g., %GNUTLS_OCSP_VERIFY_SIGNER_NOT_FOUND,
@@ -1891,123 +1888,25 @@ find_signercert (gnutls_ocsp_resp_t resp)
  *   negative error value.
  **/
 int
-gnutls_ocsp_resp_verify (gnutls_ocsp_resp_t resp,
-                        gnutls_x509_trust_list_t trustlist,
-                        gnutls_x509_crt_t signercert,
-                        unsigned *verify,
-                        int flags)
+gnutls_ocsp_resp_verify_direct (gnutls_ocsp_resp_t resp,
+                               gnutls_x509_crt_t signercert,
+                               unsigned *verify,
+                               int flags)
 {
-  gnutls_x509_crt_t free_signercert = NULL;
-  gnutls_pubkey_t pubkey = NULL;
-  int rc;
-  int sigalg = gnutls_ocsp_resp_get_signature_algorithm (resp);
   gnutls_datum_t sig = { NULL };
   gnutls_datum_t data = { NULL };
+  gnutls_pubkey_t pubkey = NULL;
+  int sigalg;
+  int rc;
 
-  /* Algorithm:
-     1. Unless given as input, find signer cert.
-        1a. Search in OCSP response Certificate field for responderID.
-        1b. Verify that signer cert is trusted.
-            2a. It is in trustlist?
-           2b. It has OCSP key usage and directly signed by a CA in trustlist?
-     3. Verify signature of Basic Response using public key from signer cert.
-  */
-
-  if (signercert == NULL)
+  if (resp == NULL || signercert == NULL)
     {
-      free_signercert = signercert = find_signercert (resp);
-      if (!signercert)
-       {
-         /* XXX Search in trustlist for certificate matching
-            responderId as well? */
-         gnutls_assert ();
-         *verify = GNUTLS_OCSP_VERIFY_SIGNER_NOT_FOUND;
-         rc = GNUTLS_E_SUCCESS;
-         goto done;
-       }
-
-      /* Either it is directly trusted (i.e., in the list) or it is
-        directly signed by something we trust, and has proper OCSP
-        extkeyusage. */
-
-      rc = _gnutls_trustlist_inlist_p (trustlist, signercert);
-      if (rc < 0)
-       {
-         gnutls_assert ();
-         goto done;
-       }
-
-      if (rc == 0)
-       {
-         gnutls_x509_crt_t issuer;
-         unsigned vtmp;
-         char oidtmp[sizeof (GNUTLS_KP_OCSP_SIGNING)];
-         size_t oidsize;
-         int indx;
-
-         rc = gnutls_x509_trust_list_get_issuer (trustlist, signercert,
-                                                 &issuer, 0);
-         if (rc != GNUTLS_E_SUCCESS)
-           {
-             gnutls_assert ();
-             *verify = GNUTLS_OCSP_VERIFY_UNTRUSTED_SIGNER;
-             rc = GNUTLS_E_SUCCESS;
-             goto done;
-           }
-
-         rc = gnutls_x509_crt_verify (signercert, &issuer, 1, 0, &vtmp);
-         if (rc != GNUTLS_E_SUCCESS)
-           {
-             gnutls_assert ();
-             goto done;
-           }
-
-         if (vtmp != 0)
-           {
-             if (vtmp & GNUTLS_CERT_INSECURE_ALGORITHM)
-               *verify = GNUTLS_OCSP_VERIFY_INSECURE_ALGORITHM;
-             else if (vtmp & GNUTLS_CERT_NOT_ACTIVATED)
-               *verify = GNUTLS_OCSP_VERIFY_CERT_NOT_ACTIVATED;
-             else if (vtmp & GNUTLS_CERT_EXPIRED)
-               *verify = GNUTLS_OCSP_VERIFY_CERT_EXPIRED;
-             else
-               *verify = GNUTLS_OCSP_VERIFY_UNTRUSTED_SIGNER;
-             rc = GNUTLS_E_SUCCESS;
-             goto done;
-           }
-
-         for (indx = 0; ; indx++)
-           {
-             oidsize = sizeof (oidtmp);
-             rc = gnutls_x509_crt_get_key_purpose_oid (signercert, indx,
-                                                       oidtmp, &oidsize,
-                                                       NULL);
-             if (rc == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
-               {
-                 *verify = GNUTLS_OCSP_VERIFY_SIGNER_KEYUSAGE_ERROR;
-                 rc = GNUTLS_E_SUCCESS;
-                 goto done;
-               }
-             else if (rc == GNUTLS_E_SHORT_MEMORY_BUFFER)
-               continue;
-             else if (rc != GNUTLS_E_SUCCESS)
-               {
-                 gnutls_assert ();
-                 goto done;
-               }
-
-             if (memcmp (oidtmp, GNUTLS_KP_OCSP_SIGNING, oidsize) != 0)
-               {
-                 *verify = GNUTLS_OCSP_VERIFY_SIGNER_KEYUSAGE_ERROR;
-                 rc = GNUTLS_E_SUCCESS;
-                 goto done;
-               }
-
-             break;
-           }
-       }
+      gnutls_assert ();
+      return GNUTLS_E_INVALID_REQUEST;
     }
 
+  sigalg = gnutls_ocsp_resp_get_signature_algorithm (resp);
+
   rc = export (resp->basicresp, "tbsResponseData", &data);
   if (rc != GNUTLS_E_SUCCESS)
     {
@@ -2051,10 +1950,155 @@ gnutls_ocsp_resp_verify (gnutls_ocsp_resp_t resp,
   rc = GNUTLS_E_SUCCESS;
 
  done:
-  gnutls_x509_crt_deinit (free_signercert);
   gnutls_free (data.data);
   gnutls_free (sig.data);
   gnutls_pubkey_deinit (pubkey);
 
   return rc;
 }
+
+/**
+ * gnutls_ocsp_resp_verify:
+ * @resp: should contain a #gnutls_ocsp_resp_t structure
+ * @trustlist: trust anchors as a #gnutls_x509_trust_list_t structure
+ * @verify: output variable with verification status codes
+ * @flags: verification flags, 0 for now.
+ *
+ * Verify signature of the Basic OCSP Response against the public key
+ * in the certificate of a trusted signer.  The @trustlist should be
+ * populated with trusted CAs.  The function will extract the signer
+ * certificate from the Basic OCSP Response and will verify it against
+ * the @trustlist.
+ *
+ * The output @verify variable will hold verification status codes
+ * (e.g., %GNUTLS_OCSP_VERIFY_SIGNER_NOT_FOUND,
+ * %GNUTLS_OCSP_VERIFY_INSECURE_ALGORITHM) which are only valid if the
+ * function returned %GNUTLS_E_SUCCESS.
+ *
+ * Note that the function returns %GNUTLS_E_SUCCESS even when
+ * verification failed.  The caller must always inspect the @verify
+ * variable to find out the verification status.
+ *
+ * The @flags variable should be 0 for now.
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
+ *   negative error value.
+ **/
+int
+gnutls_ocsp_resp_verify (gnutls_ocsp_resp_t resp,
+                        gnutls_x509_trust_list_t trustlist,
+                        unsigned *verify,
+                        int flags)
+{
+  gnutls_x509_crt_t signercert = NULL;
+  int rc;
+
+  /* Algorithm:
+     1. Find signer cert.
+        1a. Search in OCSP response Certificate field for responderID.
+        1b. Verify that signer cert is trusted.
+        2a. It is in trustlist?
+        2b. It has OCSP key usage and directly signed by a CA in trustlist?
+     3. Verify signature of Basic Response using public key from signer cert.
+  */
+
+  signercert = find_signercert (resp);
+  if (!signercert)
+    {
+      /* XXX Search in trustlist for certificate matching
+        responderId as well? */
+      gnutls_assert ();
+      *verify = GNUTLS_OCSP_VERIFY_SIGNER_NOT_FOUND;
+      rc = GNUTLS_E_SUCCESS;
+      goto done;
+    }
+
+  /* Either it is directly trusted (i.e., in the list) or it is
+     directly signed by something we trust, and has proper OCSP
+     extkeyusage. */
+
+  rc = _gnutls_trustlist_inlist_p (trustlist, signercert);
+  if (rc < 0)
+    {
+      gnutls_assert ();
+      goto done;
+    }
+
+  /* indirect trust, need to verify signature and bits */
+  if (rc == 0)
+    {
+      gnutls_x509_crt_t issuer;
+      unsigned vtmp;
+      char oidtmp[sizeof (GNUTLS_KP_OCSP_SIGNING)];
+      size_t oidsize;
+      int indx;
+
+      rc = gnutls_x509_trust_list_get_issuer (trustlist, signercert,
+                                             &issuer, 0);
+      if (rc != GNUTLS_E_SUCCESS)
+       {
+         gnutls_assert ();
+         *verify = GNUTLS_OCSP_VERIFY_UNTRUSTED_SIGNER;
+         rc = GNUTLS_E_SUCCESS;
+         goto done;
+       }
+
+      rc = gnutls_x509_crt_verify (signercert, &issuer, 1, 0, &vtmp);
+      if (rc != GNUTLS_E_SUCCESS)
+       {
+         gnutls_assert ();
+         goto done;
+       }
+
+      if (vtmp != 0)
+       {
+         if (vtmp & GNUTLS_CERT_INSECURE_ALGORITHM)
+           *verify = GNUTLS_OCSP_VERIFY_INSECURE_ALGORITHM;
+         else if (vtmp & GNUTLS_CERT_NOT_ACTIVATED)
+           *verify = GNUTLS_OCSP_VERIFY_CERT_NOT_ACTIVATED;
+         else if (vtmp & GNUTLS_CERT_EXPIRED)
+           *verify = GNUTLS_OCSP_VERIFY_CERT_EXPIRED;
+         else
+           *verify = GNUTLS_OCSP_VERIFY_UNTRUSTED_SIGNER;
+         rc = GNUTLS_E_SUCCESS;
+         goto done;
+       }
+
+      for (indx = 0; ; indx++)
+       {
+         oidsize = sizeof (oidtmp);
+         rc = gnutls_x509_crt_get_key_purpose_oid (signercert, indx,
+                                                   oidtmp, &oidsize,
+                                                   NULL);
+         if (rc == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
+           {
+             *verify = GNUTLS_OCSP_VERIFY_SIGNER_KEYUSAGE_ERROR;
+             rc = GNUTLS_E_SUCCESS;
+             goto done;
+           }
+         else if (rc == GNUTLS_E_SHORT_MEMORY_BUFFER)
+           continue;
+         else if (rc != GNUTLS_E_SUCCESS)
+           {
+             gnutls_assert ();
+             goto done;
+           }
+
+         if (memcmp (oidtmp, GNUTLS_KP_OCSP_SIGNING, oidsize) != 0)
+           {
+             *verify = GNUTLS_OCSP_VERIFY_SIGNER_KEYUSAGE_ERROR;
+             rc = GNUTLS_E_SUCCESS;
+             goto done;
+           }
+
+         break;
+       }
+    }
+
+  rc = gnutls_ocsp_resp_verify_direct (resp, signercert, verify, flags);
+
+ done:
+  gnutls_x509_crt_deinit (signercert);
+
+  return rc;
+}
diff --git a/src/ocsptool.c b/src/ocsptool.c
index ac8e9bf..963ccb7 100644
--- a/src/ocsptool.c
+++ b/src/ocsptool.c
@@ -302,7 +302,7 @@ verify_response (void)
   if (ret < 0)
     error (EXIT_FAILURE, 0, "importing response: %s", gnutls_strerror (ret));
 
-  ret = gnutls_ocsp_resp_verify (resp, list, NULL, &verify, 0);
+  ret = gnutls_ocsp_resp_verify (resp, list, &verify, 0);
   if (ret < 0)
     error (EXIT_FAILURE, 0, "gnutls_ocsp_resp_verify: %s",
           gnutls_strerror (ret));


hooks/post-receive
-- 
GNU gnutls



reply via email to

[Prev in Thread] Current Thread [Next in Thread]