]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
Added gnutls_x509_crq_verify().
authorNikos Mavrogiannopoulos <nmav@gnutls.org>
Sat, 7 May 2011 16:44:21 +0000 (18:44 +0200)
committerNikos Mavrogiannopoulos <nmav@gnutls.org>
Sat, 7 May 2011 16:46:23 +0000 (18:46 +0200)
NEWS
lib/includes/gnutls/x509.h
lib/libgnutls.map
lib/x509/crq.c
lib/x509/x509_write.c
tests/crq_key_id.c

diff --git a/NEWS b/NEWS
index eea62cac8ea8dc67d5c41130a103e59a73687419..ca94162626f52c68451c4248ad555c9529f660ba 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -9,9 +9,19 @@ See the end for copying conditions.
 gnutls_x509_trust_list_get_issuer() to compensate for the
 missing gnutls_certificate_get_x509_cas().
 
+** libgnutls: Added gnutls_x509_crq_verify() to allow
+verification of the self signature in a certificate request.
+This allows verifying whether the owner of the private key
+is the generator of the request.
+
+** libgnutls: gnutls_x509_crt_set_crq() implicitly verifies
+the self signature of the request.
+
 ** API and ABI modifications:
 gnutls_certificate_get_issuer: ADDED
 gnutls_x509_trust_list_get_issuer: ADDED
+gnutls_x509_crq_verify: ADDED
+
 
 * Version 2.99.1 (released 2011-04-23)
 
index f220844d77e2520bac4fcd527b3330b599b3f62a..6ddd85c836b92cdb4a925ef6d8b3432c70c53c42 100644 (file)
@@ -721,6 +721,8 @@ extern "C"
                              gnutls_certificate_print_formats_t format,
                              gnutls_datum_t * out);
 
+  int gnutls_x509_crq_verify (gnutls_x509_crq_t crq, unsigned int flags);
+
   int gnutls_x509_crq_init (gnutls_x509_crq_t * crq);
   void gnutls_x509_crq_deinit (gnutls_x509_crq_t crq);
   int gnutls_x509_crq_import (gnutls_x509_crq_t crq,
index 229792e955bf37a537e862590848d83345e4bd24..63bacd21043fc1f82c47226b19e66eb7e0cfdca8 100644 (file)
@@ -677,6 +677,8 @@ GNUTLS_2_12
        gnutls_openpgp_crt_verify_hash;
        gnutls_pubkey_import_privkey;
        gnutls_pubkey_verify_data;
+       gnutls_certificate_get_issuer;
+       gnutls_x509_crq_verify;
 } GNUTLS_2_10;
 
 GNUTLS_3_0_0 {
@@ -710,7 +712,6 @@ GNUTLS_3_0_0 {
        gnutls_pubkey_get_openpgp_key_id;
        gnutls_certificate_set_retrieve_function2;
        gnutls_x509_trust_list_get_issuer;
-       gnutls_certificate_get_issuer;
 } GNUTLS_2_12;
 
 GNUTLS_PRIVATE {
index 02dc2c4a80d98dd76e0867018767f3b520ba7482..ed0f844a564d2f69c967be8a215a251ea62c448f 100644 (file)
@@ -2521,5 +2521,72 @@ gnutls_x509_crq_privkey_sign (gnutls_x509_crq_t crq, gnutls_privkey_t key,
 }
 
 
+/**
+ * gnutls_x509_crq_verify:
+ * @crq: is the crq to be verified
+ * @flags: Flags that may be used to change the verification algorithm. Use OR of the gnutls_certificate_verify_flags enumerations.
+ *
+ * This function will verify self signature in the certificate
+ * request and return its status.
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS is returned, %GNUTLS_E_PK_SIG_VERIFY_FAILED
+ * if verification failed, otherwise a negative error value.
+ **/
+int
+gnutls_x509_crq_verify (gnutls_x509_crq_t crq,
+                        unsigned int flags)
+{
+gnutls_datum data = { NULL, 0 };
+gnutls_datum signature = { NULL, 0 };
+bigint_t params[MAX_PUBLIC_PARAMS_SIZE];
+int ret, params_size = 0, i;
+
+  ret =
+    _gnutls_x509_get_signed_data (crq->crq, "certificationRequestInfo", &data);
+  if (ret < 0)
+    {
+      gnutls_assert ();
+      return ret;
+    }
+
+  ret = _gnutls_x509_get_signature (crq->crq, "signature", &signature);
+  if (ret < 0)
+    {
+      gnutls_assert ();
+      goto cleanup;
+    }
+
+  params_size = MAX_PUBLIC_PARAMS_SIZE;
+  ret =
+    _gnutls_x509_crq_get_mpis(crq, params, &params_size);
+  if (ret < 0)
+    {
+      gnutls_assert ();
+      goto cleanup;
+    }
+
+  ret = pubkey_verify_sig(&data, NULL, &signature,
+                          gnutls_x509_crq_get_pk_algorithm (crq, NULL),
+    params, params_size);
+  if (ret < 0)
+    {
+      gnutls_assert ();
+      goto cleanup;
+    }
+
+  ret = 0;
+
+cleanup:
+  _gnutls_free_datum (&data);
+  _gnutls_free_datum (&signature);
+
+  for (i = 0; i < params_size; i++)
+      {
+            _gnutls_mpi_release (&params[i]);
+      }
+
+  return ret;
+}
 
 #endif /* ENABLE_PKI */
+
index 5d31a830dabca79304efdb9160664b2d587299ed..68f010367066313af6a906aa820b59d1c4b62a3b 100644 (file)
@@ -268,6 +268,10 @@ gnutls_x509_crt_set_crq (gnutls_x509_crt_t crt, gnutls_x509_crq_t crq)
       return GNUTLS_E_INVALID_REQUEST;
     }
 
+  result = gnutls_x509_crq_verify(crq, 0);
+  if (result < 0)
+    return gnutls_assert_val(result);
+
   result = asn1_copy_node (crt->cert, "tbsCertificate.subject",
                            crq->crq, "certificationRequestInfo.subject");
   if (result != ASN1_SUCCESS)
index fff9f8f4adf83482e918fc0c52bcbdf2cf964cad..74d5dc6b60c9362f56dff26b95cfc08d9be9f34f 100644 (file)
@@ -137,11 +137,17 @@ doit (void)
         }
 
       ret = gnutls_x509_crq_privkey_sign (crq, abs_pkey, GNUTLS_DIG_SHA1, 0);
-      if (ret)
+      if (ret < 0)
         {
           fail ("gnutls_x509_crq_sign: %d\n", ret);
         }
 
+      ret = gnutls_x509_crq_verify (crq, 0);
+      if (ret < 0)
+        {
+          fail ("gnutls_x509_crq_verify: %d\n", ret);
+        }
+
       crq_key_id_len = 0;
       ret = gnutls_x509_crq_get_key_id (crq, 0, crq_key_id, &crq_key_id_len);
       if (ret != GNUTLS_E_SHORT_MEMORY_BUFFER)