]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
Introduced gnutls_*_privkey_sign_hash2() that is a high level function to produce...
authorNikos Mavrogiannopoulos <nmav@gnutls.org>
Sat, 11 Dec 2010 17:58:27 +0000 (18:58 +0100)
committerNikos Mavrogiannopoulos <nmav@gnutls.org>
Sat, 11 Dec 2010 17:58:27 +0000 (18:58 +0100)
lib/gnutls_privkey.c
lib/includes/gnutls/abstract.h
lib/includes/gnutls/compat.h
lib/includes/gnutls/openpgp.h
lib/includes/gnutls/x509.h
lib/libgnutls.map
lib/openpgp/gnutls_openpgp.c
lib/x509/privkey.c

index a10d1a59472698fc7e9931526be9703760971fbf..4ba21d4e8d907f36cb01c2de85d0fe31d1232a7c 100644 (file)
@@ -290,6 +290,76 @@ cleanup:
   return ret;
 }
 
+/**
+ * gnutls_privkey_sign_hash2:
+ * @signer: Holds the signer's key
+ * @hash_algo: The hash algorithm used
+ * @flags: zero for now
+ * @hash_data: holds the data to be signed
+ * @signature: will contain newly allocated signature
+ *
+ * This function will sign the given hashed data using a signature algorithm
+ * supported by the private key. Signature algorithms are always used
+ * together with a hash functions.  Different hash functions may be
+ * used for the RSA algorithm, but only SHA-XXX for the DSA keys.
+ *
+ * Use gnutls_x509_crt_get_preferred_hash_algorithm() to determine
+ * the hash algorithm.
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
+ *   negative error value.
+ **/
+int
+gnutls_privkey_sign_hash2 (gnutls_privkey_t signer,
+                               gnutls_digest_algorithm_t hash_algo,
+                               unsigned int flags,
+                               const gnutls_datum_t * hash_data,
+                               gnutls_datum_t * signature)
+{
+  int ret;
+  gnutls_datum_t digest;
+
+  digest.data = gnutls_malloc(hash_data->size);
+  if (digest.data == NULL)
+    {
+      gnutls_assert();
+      return GNUTLS_E_MEMORY_ERROR;
+    }
+  digest.size = hash_data->size;
+  memcpy(digest.data, hash_data->data, digest.size);
+
+  switch (signer->pk_algorithm)
+    {
+    case GNUTLS_PK_RSA:
+      ret = pk_prepare_pkcs1_rsa_hash (hash_algo, &digest);
+      if (ret < 0)
+       {
+         gnutls_assert ();
+         return ret;
+       }
+      break;
+    case GNUTLS_PK_DSA:
+      break;
+    default:
+      gnutls_assert ();
+      ret = GNUTLS_E_UNIMPLEMENTED_FEATURE;
+      goto cleanup;
+    }
+
+  ret = _gnutls_privkey_sign_hash (signer, &digest, signature);
+  if (ret < 0)
+    {
+      gnutls_assert ();
+      goto cleanup;
+    }
+
+  ret = 0;
+
+cleanup:
+  _gnutls_free_datum(&digest);
+  return ret;
+}
+
 /*-
  * _gnutls_privkey_sign_hash:
  * @key: Holds the key
@@ -311,14 +381,15 @@ _gnutls_privkey_sign_hash (gnutls_privkey_t key,
     {
 #ifdef ENABLE_OPENPGP
     case GNUTLS_PRIVKEY_OPENPGP:
-      return gnutls_openpgp_privkey_sign_hash (key->key.openpgp,
+      return _gnutls_openpgp_privkey_sign_hash (key->key.openpgp,
                                               hash, signature);
 #endif
     case GNUTLS_PRIVKEY_PKCS11:
       return gnutls_pkcs11_privkey_sign_hash (key->key.pkcs11,
                                              hash, signature);
     case GNUTLS_PRIVKEY_X509:
-      return gnutls_x509_privkey_sign_hash (key->key.x509, hash, signature);
+      return _gnutls_soft_sign (key->key.x509->pk_algorithm, key->key.x509->params,
+        key->key.x509->params_size, hash, signature);
     default:
       gnutls_assert ();
       return GNUTLS_E_INVALID_REQUEST;
index f80d1363596210b8c2c06870f15218fb04639b1c..2e68632b23ea235939b95449e280d3e30a5c92d8 100644 (file)
@@ -104,9 +104,13 @@ int gnutls_privkey_sign_data (gnutls_privkey_t signer,
                              unsigned int flags,
                              const gnutls_datum_t * data,
                              gnutls_datum_t * signature);
-int gnutls_privkey_sign_hash (gnutls_privkey_t key,
-                             const gnutls_datum_t * hash,
-                             gnutls_datum_t * signature);
+
+int
+gnutls_privkey_sign_hash2 (gnutls_privkey_t signer,
+                               gnutls_digest_algorithm_t hash_algo,
+                               unsigned int flags,
+                               const gnutls_datum_t * hash_data,
+                               gnutls_datum_t * signature);
 
 int gnutls_privkey_decrypt_data (gnutls_privkey_t signer,
                                 unsigned int flags,
index a31f067485634e6c68e349cbe70063b1e888b0f2..aaee9d8f4e0f3bdcf9e7faaa59498e7e0912ed5b 100644 (file)
@@ -223,9 +223,10 @@ gnutls_sign_callback_get (gnutls_session_t session, void **userdata);
                                     gnutls_datum_t * signature)
                                     _GNUTLS_GCC_ATTR_DEPRECATED;
 
-  int gnutls_openpgp_privkey_sign_hash (gnutls_openpgp_privkey_t key,
-                                       const gnutls_datum_t * hash,
-                                       gnutls_datum_t * signature)
-                                       _GNUTLS_GCC_ATTR_DEPRECATED;
+  int gnutls_x509_crt_verify_hash (gnutls_x509_crt_t crt,
+                                  unsigned int flags,
+                                  const gnutls_datum_t * hash,
+                                  const gnutls_datum_t * signature)
+                                  _GNUTLS_GCC_ATTR_DEPRECATED;
 
 #endif /* _GNUTLS_COMPAT_H */
index 4babbcc652548717fe4868cd687ec7350fe528d7..d6961458c101f8eae1f995906a5819e71137adfe 100644 (file)
@@ -169,6 +169,18 @@ extern "C"
                                     const char *password,
                                     unsigned int flags);
 
+  int gnutls_openpgp_privkey_sign_hash2 (gnutls_openpgp_privkey_t signer,
+                               gnutls_digest_algorithm_t hash_algo,
+                               unsigned int flags,
+                               const gnutls_datum_t * hash_data,
+                               gnutls_datum_t * signature);
+
+  int gnutls_openpgp_privkey_sign_data2 (gnutls_openpgp_privkey_t signer,
+                               gnutls_digest_algorithm_t hash,
+                               unsigned int flags,
+                               const gnutls_datum_t * data,
+                               gnutls_datum_t * signature);
+
   int gnutls_openpgp_privkey_decrypt_data (gnutls_openpgp_privkey_t key,
                                           unsigned int flags,
                                           const gnutls_datum_t * ciphertext,
index 80bb435999fa6be183a0246ab5a0ae2e660169ff..21923a3ba440790c39569acd2c1774ee9f5f8e9f 100644 (file)
@@ -729,10 +729,12 @@ extern "C"
                                   unsigned int flags,
                                   const gnutls_datum_t * data,
                                   const gnutls_datum_t * signature);
-  int gnutls_x509_crt_verify_hash (gnutls_x509_crt_t crt,
-                                  unsigned int flags,
-                                  const gnutls_datum_t * hash,
-                                  const gnutls_datum_t * signature);
+
+  int gnutls_x509_privkey_sign_hash2 (gnutls_x509_privkey_t signer,
+                               gnutls_digest_algorithm_t hash_algo,
+                               unsigned int flags,
+                               const gnutls_datum_t * hash_data,
+                               gnutls_datum_t * signature);
 
   int gnutls_x509_crt_get_verify_algorithm (gnutls_x509_crt_t crt,
                                            const gnutls_datum_t * signature,
index f719563fe989d143fabb02a3c730cc815c348dc4..971931f3f181f60b719b80a76e3047136a4fbcb0 100644 (file)
@@ -694,6 +694,10 @@ GNUTLS_2_12
        gnutls_pkcs11_token_init;
        gnutls_pkcs11_token_set_pin;
        gnutls_pkcs11_token_get_mechanism;
+       gnutls_privkey_sign_hash2;
+       gnutls_openpgp_privkey_sign_data2;
+       gnutls_openpgp_privkey_sign_hash2;
+       gnutls_x509_privkey_sign_hash2;
 } GNUTLS_2_10;
 
 GNUTLS_PRIVATE {
index 2223c98068006bce56fdc29a4b382bd506d444c0..1cd0528e524643f3af00805c6d0c49f93726401b 100644 (file)
@@ -840,8 +840,8 @@ _gnutls_openpgp_crt_to_gcert (gnutls_cert * gcert, gnutls_openpgp_crt_t cert)
 
 }
 
-/**
- * gnutls_openpgp_privkey_sign_hash:
+/*-
+ * _gnutls_openpgp_privkey_sign_hash:
  * @key: Holds the key
  * @hash: holds the data to be signed
  * @signature: will contain newly allocated signature
@@ -852,9 +852,9 @@ _gnutls_openpgp_crt_to_gcert (gnutls_cert * gcert, gnutls_openpgp_crt_t cert)
  *
  * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
  *   negative error value.
**/
-*/
 int
-gnutls_openpgp_privkey_sign_hash (gnutls_openpgp_privkey_t key,
+_gnutls_openpgp_privkey_sign_hash (gnutls_openpgp_privkey_t key,
                                  const gnutls_datum_t * hash,
                                  gnutls_datum_t * signature)
 {
@@ -913,6 +913,126 @@ gnutls_openpgp_privkey_sign_hash (gnutls_openpgp_privkey_t key,
   return 0;
 }
 
+/**
+ * gnutls_openpgp_privkey_sign_hash2:
+ * @signer: Holds the signer's key
+ * @hash_algo: The hash algorithm used
+ * @hash_data: holds the data to be signed
+ * @signature: will contain newly allocated signature
+ * @flags: zero for now
+ *
+ * This function will sign the given hash using the private key.  You
+ * should use gnutls_openpgp_privkey_set_preferred_key_id() before
+ * calling this function to set the subkey to use.
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
+ *   negative error value.
+ **/
+int
+gnutls_openpgp_privkey_sign_hash2 (gnutls_openpgp_privkey_t signer,
+                               gnutls_digest_algorithm_t hash_algo,
+                               unsigned int flags,
+                               const gnutls_datum_t * hash_data,
+                               gnutls_datum_t * signature)
+{
+  int ret;
+  gnutls_datum_t digest;
+
+  digest.data = gnutls_malloc(hash_data->size);
+  if (digest.data == NULL)
+    {
+      gnutls_assert();
+      return GNUTLS_E_MEMORY_ERROR;
+    }
+  digest.size = hash_data->size;
+  memcpy(digest.data, hash_data->data, digest.size);
+
+  switch (gnutls_openpgp_privkey_get_pk_algorithm (signer, NULL))
+    {
+    case GNUTLS_PK_RSA:
+      ret = pk_prepare_pkcs1_rsa_hash (hash_algo, &digest);
+      if (ret < 0)
+       {
+         gnutls_assert ();
+         return ret;
+       }
+      break;
+    case GNUTLS_PK_DSA:
+      break;
+    default:
+      gnutls_assert ();
+      ret = GNUTLS_E_UNIMPLEMENTED_FEATURE;
+      goto cleanup;
+    }
+  return 0;
+
+  ret = _gnutls_openpgp_privkey_sign_hash (signer, &digest, signature);
+  if (ret < 0)
+    {
+      gnutls_assert ();
+      goto cleanup;
+    }
+
+  ret = 0;
+
+cleanup:
+  _gnutls_free_datum(&digest);
+  return ret;
+}
+
+/**
+ * gnutls_openpgp_privkey_sign_data2:
+ * @signer: Holds the key
+ * @digest: should be MD5 or SHA1
+ * @flags: should be 0 for now
+ * @data: holds the data to be signed
+ * @signature: will contain the signature allocate with gnutls_malloc()
+ *
+ * This function will sign the given data using a signature algorithm
+ * supported by the private key. Signature algorithms are always used
+ * together with a hash functions.  Different hash functions may be
+ * used for the RSA algorithm, but only SHA-XXX for the DSA keys.
+ *
+ * The RSA algorithm is used in PKCS #1 v1.5 mode.
+ *
+ * If the buffer provided is not long enough to hold the output, then
+ * *@signature_size is updated and %GNUTLS_E_SHORT_MEMORY_BUFFER will
+ * be returned.
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
+ *   negative error value.
+ **/
+int
+gnutls_openpgp_privkey_sign_data2 (gnutls_openpgp_privkey_t signer,
+                               gnutls_digest_algorithm_t hash,
+                               unsigned int flags,
+                               const gnutls_datum_t * data,
+                               gnutls_datum_t * signature)
+{
+  int ret;
+  gnutls_datum_t digest;
+
+  ret = pk_hash_data(gnutls_openpgp_privkey_get_pk_algorithm(signer,NULL), hash, NULL, data, &digest);
+  if (ret < 0)
+    {
+      gnutls_assert();
+      return ret;
+    }
+
+  ret = gnutls_openpgp_privkey_sign_hash2(signer, hash, flags, &digest, signature);
+  if (ret < 0)
+    {
+      gnutls_assert ();
+      goto cleanup;
+    }
+
+  ret = 0;
+
+cleanup:
+  _gnutls_free_datum (&digest);
+  return ret;
+}
+
 /**
  * gnutls_openpgp_privkey_decrypt_data:
  * @key: Holds the key
index e023d7b33ecb2295dc3b2ab860d337247100e3d1..456427e19393a24975745a09320ca75c7f5db07a 100644 (file)
@@ -1665,7 +1665,9 @@ cleanup:
  * This function will sign the given data using a signature algorithm
  * supported by the private key. Signature algorithms are always used
  * together with a hash functions.  Different hash functions may be
- * used for the RSA algorithm, but only SHA-1 for the DSA keys.
+ * used for the RSA algorithm, but only SHA-XXX for the DSA keys.
+ *
+ * The RSA algorithm is used in PKCS #1 v1.5 mode.
  *
  * If the buffer provided is not long enough to hold the output, then
  * *@signature_size is updated and %GNUTLS_E_SHORT_MEMORY_BUFFER will
@@ -1687,49 +1689,28 @@ gnutls_x509_privkey_sign_data2 (gnutls_x509_privkey_t signer,
   int ret;
   gnutls_datum_t digest;
 
-  ret = pk_hash_data(signer->pk_algorithm, hash, signer->params, data, signature);
+  ret = pk_hash_data(signer->pk_algorithm, hash, signer->params, data, &digest);
   if (ret < 0)
     {
       gnutls_assert();
       return ret;
     }
 
-  switch (signer->pk_algorithm)
-    {
-    case GNUTLS_PK_RSA:
-      ret = pk_prepare_pkcs1_rsa_hash (hash, &digest);
-      if (ret < 0)
-       {
-         gnutls_assert ();
-         return ret;
-       }
-      break;
-    case GNUTLS_PK_DSA:
-      break;
-    default:
-      gnutls_assert ();
-      ret = GNUTLS_E_UNIMPLEMENTED_FEATURE;
-      goto cleanup;
-    }
-
-  ret = _gnutls_soft_sign (signer->pk_algorithm, signer->params,
-                             signer->params_size, &digest, signature);
-  _gnutls_free_datum (&digest);
-
+  ret = gnutls_x509_privkey_sign_hash2(signer, hash, flags, &digest, signature);
   if (ret < 0)
     {
       gnutls_assert ();
-      return ret;
+      goto cleanup;
     }
 
-  return 0;
+  ret = 0;
 
 cleanup:
   _gnutls_free_datum (&digest);
   return ret;
 }
 
-/**
+/*-
  * gnutls_x509_privkey_sign_hash:
  * @key: Holds the key
  * @hash: holds the data to be signed
@@ -1742,7 +1723,7 @@ cleanup:
  *
  * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
  *   negative error value.
**/
-*/
 int
 gnutls_x509_privkey_sign_hash (gnutls_x509_privkey_t key,
                               const gnutls_datum_t * hash,
@@ -1767,6 +1748,78 @@ gnutls_x509_privkey_sign_hash (gnutls_x509_privkey_t key,
   return 0;
 }
 
+/**
+ * gnutls_x509_privkey_sign_hash2:
+ * @signer: Holds the signer's key
+ * @hash_algo: The hash algorithm used
+ * @hash_data: holds the data to be signed
+ * @signature: will contain newly allocated signature
+ * @flags: zero for now
+ *
+ * This function will sign the given hashed data using a signature algorithm
+ * supported by the private key. Signature algorithms are always used
+ * together with a hash functions.  Different hash functions may be
+ * used for the RSA algorithm, but only SHA-XXX for the DSA keys.
+ *
+ * Use gnutls_x509_crt_get_preferred_hash_algorithm() to determine
+ * the hash algorithm.
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
+ *   negative error value.
+ **/
+int
+gnutls_x509_privkey_sign_hash2 (gnutls_x509_privkey_t signer,
+                               gnutls_digest_algorithm_t hash_algo,
+                               unsigned int flags,
+                               const gnutls_datum_t * hash_data,
+                               gnutls_datum_t * signature)
+{
+  int ret;
+  gnutls_datum_t digest;
+
+  digest.data = gnutls_malloc(hash_data->size);
+  if (digest.data == NULL)
+    {
+      gnutls_assert();
+      return GNUTLS_E_MEMORY_ERROR;
+    }
+  digest.size = hash_data->size;
+  memcpy(digest.data, hash_data->data, digest.size);
+
+  switch (signer->pk_algorithm)
+    {
+    case GNUTLS_PK_RSA:
+      ret = pk_prepare_pkcs1_rsa_hash (hash_algo, &digest);
+      if (ret < 0)
+       {
+         gnutls_assert ();
+         return ret;
+       }
+      break;
+    case GNUTLS_PK_DSA:
+      break;
+    default:
+      gnutls_assert ();
+      ret = GNUTLS_E_UNIMPLEMENTED_FEATURE;
+      goto cleanup;
+    }
+
+  ret = _gnutls_soft_sign (signer->pk_algorithm, signer->params,
+                             signer->params_size, &digest, signature);
+
+  if (ret < 0)
+    {
+      gnutls_assert ();
+      goto cleanup;
+    }
+
+  ret = 0;
+
+cleanup:
+  _gnutls_free_datum(&digest);
+  return ret;
+}
+
 #ifdef ENABLE_PKI
 /**
  * gnutls_x509_privkey_sign_data: