gnutls-commit
[Top][All Lists]
Advanced

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

[SCM] GNU gnutls branch, master, updated. gnutls_2_11_6-21-gc9c9dc0


From: Nikos Mavrogiannopoulos
Subject: [SCM] GNU gnutls branch, master, updated. gnutls_2_11_6-21-gc9c9dc0
Date: Mon, 13 Dec 2010 21:40:19 +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=c9c9dc047f2ce9661f7cd33a15e824f2978c2a7a

The branch, master has been updated
       via  c9c9dc047f2ce9661f7cd33a15e824f2978c2a7a (commit)
       via  31be538386600d74db366158e9ee4f0eaede6048 (commit)
       via  b121dd59010ba4acdff8e3265952a23000ca5d33 (commit)
       via  69ede077cc14046c26e88d6bef5a3b297f73161f (commit)
       via  fd07bbadb2fac571d273d0ec64c6b94d2be5c1f8 (commit)
       via  82422a562a62856607894f07f3deadde9a340755 (commit)
       via  1c297951ba962c0922f7e8b60f91d32b0d2e901f (commit)
       via  535596a4e2f857e6373b28142295bf8d6d1b6654 (commit)
       via  b008a11f78688eb769192349aa7f53f30a8f7139 (commit)
       via  e4781f1e4b0a2640926dc56e28997624b133171a (commit)
       via  b4566f433f23d82ed36461cf7eb45cde839d8296 (commit)
       via  40a545318bced43171e062949b01988b6cda8e18 (commit)
       via  fa6c67f202e7ab66bbdbb02fc3f1195cb12f2c4b (commit)
       via  e794b42b5fc57a8fff4382e503a78683658f83ef (commit)
      from  e1dba2adfeeeffd9e5fb3b50221d971afe49187a (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 c9c9dc047f2ce9661f7cd33a15e824f2978c2a7a
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Mon Dec 13 22:39:33 2010 +0100

    Added new functions.

commit 31be538386600d74db366158e9ee4f0eaede6048
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Mon Dec 13 22:39:18 2010 +0100

    Added new functions.

commit b121dd59010ba4acdff8e3265952a23000ca5d33
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Mon Dec 13 22:29:40 2010 +0100

    de-deprecated gnutls_x509_crt_verify_hash()

commit 69ede077cc14046c26e88d6bef5a3b297f73161f
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Mon Dec 13 22:27:43 2010 +0100

    Added gnutls_openpgp_crt_verify_hash().

commit fd07bbadb2fac571d273d0ec64c6b94d2be5c1f8
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Mon Dec 13 22:01:51 2010 +0100

    added gnutls_privkey_sign_hash2()

commit 82422a562a62856607894f07f3deadde9a340755
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Mon Dec 13 21:53:08 2010 +0100

    Simplified preparation of signing code.

commit 1c297951ba962c0922f7e8b60f91d32b0d2e901f
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Sun Dec 12 09:40:29 2010 +0100

    deprecated x509/sign.h and moved functionality of it in gnutls_sig.h.

commit 535596a4e2f857e6373b28142295bf8d6d1b6654
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Sun Dec 12 09:26:34 2010 +0100

    pk_hash_data() will fail unless DSA or RSA are specified.

commit b008a11f78688eb769192349aa7f53f30a8f7139
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Sun Dec 12 09:25:27 2010 +0100

    better comments

commit e4781f1e4b0a2640926dc56e28997624b133171a
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Sun Dec 12 09:25:13 2010 +0100

    reorganization of the privkey_ functions().

commit b4566f433f23d82ed36461cf7eb45cde839d8296
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Sat Dec 11 18:58:27 2010 +0100

    Introduced gnutls_*_privkey_sign_hash2() that is a high level function to 
produce signatures.

commit 40a545318bced43171e062949b01988b6cda8e18
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Sat Dec 11 18:22:13 2010 +0100

    Separated the sign_data functions to a hashing phase, a preparing phase, 
and the actual signing.

commit fa6c67f202e7ab66bbdbb02fc3f1195cb12f2c4b
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Sat Dec 11 17:35:46 2010 +0100

    documented deprecated functions.

commit e794b42b5fc57a8fff4382e503a78683658f83ef
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Thu Dec 9 09:15:16 2010 +0100

    All the sign hash functions were deprecated.

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

Summary of changes:
 NEWS                           |   13 ++-
 lib/gnutls_privkey.c           |  111 +++++++++++++-----
 lib/gnutls_pubkey.c            |    1 -
 lib/gnutls_sig.c               |  174 +++++++++++++++++++++++++++-
 lib/gnutls_sig.h               |   10 ++
 lib/includes/gnutls/abstract.h |   10 +-
 lib/includes/gnutls/openpgp.h  |   20 +++-
 lib/includes/gnutls/pkcs11.h   |   10 +-
 lib/includes/gnutls/x509.h     |    7 +
 lib/libgnutls.map              |    8 +-
 lib/openpgp/gnutls_openpgp.c   |  148 -----------------------
 lib/openpgp/gnutls_openpgp.h   |    5 +
 lib/openpgp/pgp.c              |   57 +++++++++
 lib/openpgp/privkey.c          |  259 ++++++++++++++++++++++++++++++++++++++++
 lib/pkcs11_int.h               |    5 +
 lib/pkcs11_privkey.c           |  103 ++++++++++++----
 lib/x509/Makefile.am           |    1 -
 lib/x509/privkey.c             |  119 +++++++++++++------
 lib/x509/sign.c                |  162 -------------------------
 lib/x509/sign.h                |    9 --
 tests/x509sign-verify.c        |   44 ++++---
 21 files changed, 836 insertions(+), 440 deletions(-)
 delete mode 100644 lib/x509/sign.h

diff --git a/NEWS b/NEWS
index 2e4b57b..585ce89 100644
--- a/NEWS
+++ b/NEWS
@@ -12,7 +12,18 @@ integers.
 Reported by "Brendan Doherty" <address@hidden>.
 
 ** API and ABI modifications:
-No changes since last version.
+gnutls_pkcs11_privkey_sign_hash2: ADDED
+gnutls_openpgp_privkey_sign_hash2: ADDED
+gnutls_x509_privkey_sign_hash2: ADDED
+gnutls_privkey_sign_hash2: ADDED
+gnutls_openpgp_privkey_sign_data2: ADDED
+gnutls_x509_privkey_sign_data2: ADDED
+gnutls_openpgp_crt_verify_hash: ADDED
+gnutls_openpgp_privkey_sign_hash: DEPRECATED
+gnutls_x509_privkey_sign_hash: DEPRECATED
+gnutls_psk_netconf_derive_key: DEPRECATED
+gnutls_session_set_finished_function: DEPRECATED
+gnutls_ext_register: DEPRECATED
 
 * Version 2.11.6 (released 2010-12-06)
 
diff --git a/lib/gnutls_privkey.c b/lib/gnutls_privkey.c
index 99f47e8..86e45ed 100644
--- a/lib/gnutls_privkey.c
+++ b/lib/gnutls_privkey.c
@@ -30,10 +30,11 @@
 #include <gnutls_datum.h>
 #include <pkcs11_int.h>
 #include <gnutls/abstract.h>
-#include <sign.h>
 #include <gnutls_pk.h>
 #include <x509_int.h>
 #include <openpgp/openpgp_int.h>
+#include <openpgp/gnutls_openpgp.h>
+#include <gnutls_sig.h>
 
 struct gnutls_privkey_st
 {
@@ -249,31 +250,21 @@ gnutls_privkey_sign_data (gnutls_privkey_t signer,
   int ret;
   gnutls_datum_t digest;
 
-  switch (signer->pk_algorithm)
+  ret = pk_hash_data(signer->pk_algorithm, hash, NULL, data, signature);
+  if (ret < 0)
     {
-    case GNUTLS_PK_RSA:
-      ret = pk_pkcs1_rsa_hash (hash, data, &digest);
-      if (ret < 0)
-       {
-         gnutls_assert ();
-         return ret;
-       }
-      break;
-    case GNUTLS_PK_DSA:
-      ret = pk_dsa_hash (hash, data, &digest);
-      if (ret < 0)
-       {
-         gnutls_assert ();
-         return ret;
-       }
-
-      break;
-    default:
-      gnutls_assert ();
-      return GNUTLS_E_INTERNAL_ERROR;
+      gnutls_assert();
+      return ret;
     }
 
-  ret = gnutls_privkey_sign_hash (signer, &digest, signature);
+  ret = pk_prepare_hash (signer->pk_algorithm, hash, &digest);
+  if (ret < 0)
+    {
+      gnutls_assert();
+      goto cleanup;
+    }
+
+  ret = _gnutls_privkey_sign_hash (signer, &digest, signature);
   _gnutls_free_datum (&digest);
 
   if (ret < 0)
@@ -283,10 +274,73 @@ gnutls_privkey_sign_data (gnutls_privkey_t signer,
     }
 
   return 0;
+
+cleanup:
+  _gnutls_free_datum (&digest);
+  return ret;
 }
 
 /**
- * gnutls_privkey_sign_hash:
+ * 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);
+
+  ret = pk_prepare_hash (signer->pk_algorithm, hash_algo, &digest);
+  if (ret < 0)
+    {
+      gnutls_assert ();
+      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
  * @data: holds the data to be signed
  * @signature: will contain the signature allocate with gnutls_malloc()
@@ -296,9 +350,9 @@ gnutls_privkey_sign_data (gnutls_privkey_t signer,
  *
  * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
  * negative error value.
- **/
+ -*/
 int
-gnutls_privkey_sign_hash (gnutls_privkey_t key,
+_gnutls_privkey_sign_hash (gnutls_privkey_t key,
                          const gnutls_datum_t * hash,
                          gnutls_datum_t * signature)
 {
@@ -306,14 +360,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,
+      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;
diff --git a/lib/gnutls_pubkey.c b/lib/gnutls_pubkey.c
index bce1334..7169aec 100644
--- a/lib/gnutls_pubkey.c
+++ b/lib/gnutls_pubkey.c
@@ -30,7 +30,6 @@
 #include <gnutls_datum.h>
 #include <pkcs11_int.h>
 #include <gnutls/abstract.h>
-#include <sign.h>
 #include <gnutls_pk.h>
 #include <x509_int.h>
 #include <openpgp/openpgp_int.h>
diff --git a/lib/gnutls_sig.c b/lib/gnutls_sig.c
index 165a6dc..1c60ef4 100644
--- a/lib/gnutls_sig.c
+++ b/lib/gnutls_sig.c
@@ -304,7 +304,7 @@ _gnutls_tls_sign (gnutls_session_t session,
        }
     }
 
-  return gnutls_privkey_sign_hash (pkey, hash_concat, signature);
+  return _gnutls_privkey_sign_hash (pkey, hash_concat, signature);
 }
 
 static int
@@ -796,3 +796,175 @@ _gnutls_handshake_sign_cert_vrfy (gnutls_session_t 
session,
 
   return ret;
 }
+
+int pk_hash_data(gnutls_pk_algorithm_t pk, gnutls_digest_algorithm_t hash,
+  bigint_t * params,
+  const gnutls_datum_t * data, gnutls_datum_t * digest)
+{
+  int ret;
+
+  switch (pk)
+    {
+    case GNUTLS_PK_RSA:
+      if (hash != GNUTLS_DIG_SHA1 && hash != GNUTLS_DIG_SHA224 &&
+        hash != GNUTLS_DIG_SHA256)
+        {
+          gnutls_assert ();
+          return GNUTLS_E_INVALID_REQUEST;
+        }
+      break;
+    case GNUTLS_PK_DSA:
+      if (params && hash != _gnutls_dsa_q_to_hash (params[1]))
+        {
+          gnutls_assert ();
+          return GNUTLS_E_INVALID_REQUEST;
+        }
+      break;
+    default:
+      gnutls_assert();
+      return GNUTLS_E_INVALID_REQUEST;
+    }
+
+  digest->size = _gnutls_hash_get_algo_len (hash);
+  digest->data = gnutls_malloc (digest->size);
+  if (digest->data == NULL)
+    {
+      gnutls_assert ();
+      return GNUTLS_E_MEMORY_ERROR;
+    }
+
+  ret = _gnutls_hash_fast(hash, data->data, data->size, digest->data);
+  if (ret < 0)
+    {
+      gnutls_assert();
+      goto cleanup;
+    }
+
+  return 0;
+
+cleanup:
+  gnutls_free(digest->data);
+  return ret;
+}
+
+/* Writes the digest information and the digest in a DER encoded
+ * structure. The digest info is allocated and stored into the info structure.
+ */
+static int
+encode_ber_digest_info (gnutls_digest_algorithm_t hash,
+                       const gnutls_datum_t * digest,
+                       gnutls_datum_t * output)
+{
+  ASN1_TYPE dinfo = ASN1_TYPE_EMPTY;
+  int result;
+  const char *algo;
+  opaque* tmp_output;
+  int tmp_output_size;
+
+  algo = _gnutls_x509_mac_to_oid ((gnutls_mac_algorithm_t) hash);
+  if (algo == NULL)
+    {
+      gnutls_assert ();
+      _gnutls_x509_log ("Hash algorithm: %d\n", hash);
+      return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
+    }
+
+  if ((result = asn1_create_element (_gnutls_get_gnutls_asn (),
+                                    "GNUTLS.DigestInfo",
+                                    &dinfo)) != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      return _gnutls_asn2err (result);
+    }
+
+  result = asn1_write_value (dinfo, "digestAlgorithm.algorithm", algo, 1);
+  if (result != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      asn1_delete_structure (&dinfo);
+      return _gnutls_asn2err (result);
+    }
+
+  /* Write an ASN.1 NULL in the parameters field.  This matches RFC
+     3279 and RFC 4055, although is arguable incorrect from a historic
+     perspective (see those documents for more information).
+     Regardless of what is correct, this appears to be what most
+     implementations do.  */
+  result = asn1_write_value (dinfo, "digestAlgorithm.parameters",
+                            ASN1_NULL, ASN1_NULL_SIZE);
+  if (result != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      asn1_delete_structure (&dinfo);
+      return _gnutls_asn2err (result);
+    }
+
+  result = asn1_write_value (dinfo, "digest", digest->data, digest->size);
+  if (result != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      asn1_delete_structure (&dinfo);
+      return _gnutls_asn2err (result);
+    }
+
+  tmp_output_size = 0;
+  asn1_der_coding (dinfo, "", NULL, &tmp_output_size, NULL);
+
+  tmp_output = gnutls_malloc (tmp_output_size);
+  if (output->data == NULL)
+    {
+      gnutls_assert ();
+      asn1_delete_structure (&dinfo);
+      return GNUTLS_E_MEMORY_ERROR;
+    }
+
+  result = asn1_der_coding (dinfo, "", tmp_output, &tmp_output_size, NULL);
+  if (result != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      asn1_delete_structure (&dinfo);
+      return _gnutls_asn2err (result);
+    }
+
+  asn1_delete_structure (&dinfo);
+  
+  output->size = tmp_output_size;
+  output->data = tmp_output;
+
+  return 0;
+}
+
+/* 
+ * This function will do RSA PKCS #1 1.5 encoding
+ * on the given digest. The given digest must be allocated
+ * and will be freed if replacement is required.
+ */
+int
+pk_prepare_hash (gnutls_pk_algorithm_t pk,
+  gnutls_digest_algorithm_t hash,
+  gnutls_datum_t * digest)
+{
+  int ret;
+  gnutls_datum old_digest = { digest->data, digest->size };
+
+  switch(pk)
+    {
+      case GNUTLS_PK_RSA:
+        /* Encode the digest as a DigestInfo
+         */
+        if ((ret = encode_ber_digest_info (hash, digest, digest)) != 0)
+          {
+            gnutls_assert ();
+            return ret;
+          }
+
+        _gnutls_free_datum(&old_digest);
+      case GNUTLS_PK_DSA:
+        break;
+      default:
+        gnutls_assert ();
+        return GNUTLS_E_UNIMPLEMENTED_FEATURE;
+    }
+
+  return 0;
+}
diff --git a/lib/gnutls_sig.h b/lib/gnutls_sig.h
index 77a97af..6b59d93 100644
--- a/lib/gnutls_sig.h
+++ b/lib/gnutls_sig.h
@@ -56,4 +56,14 @@ int _gnutls_soft_sign (gnutls_pk_algorithm_t algo,
                       const gnutls_datum_t * data,
                       gnutls_datum_t * signature);
 
+int pk_prepare_hash (gnutls_pk_algorithm_t pk, gnutls_digest_algorithm_t hash,
+                      gnutls_datum_t * output);
+int pk_hash_data(gnutls_pk_algorithm_t pk, gnutls_digest_algorithm_t hash,
+  bigint_t * params, const gnutls_datum_t * data, gnutls_datum_t * digest);
+
+int
+_gnutls_privkey_sign_hash (gnutls_privkey_t key,
+                         const gnutls_datum_t * hash,
+                         gnutls_datum_t * signature);
+
 #endif
diff --git a/lib/includes/gnutls/abstract.h b/lib/includes/gnutls/abstract.h
index f80d136..2e68632 100644
--- a/lib/includes/gnutls/abstract.h
+++ b/lib/includes/gnutls/abstract.h
@@ -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,
diff --git a/lib/includes/gnutls/openpgp.h b/lib/includes/gnutls/openpgp.h
index cad2235..5f15e91 100644
--- a/lib/includes/gnutls/openpgp.h
+++ b/lib/includes/gnutls/openpgp.h
@@ -169,13 +169,27 @@ 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_crt_verify_hash (gnutls_openpgp_crt_t crt, 
+           unsigned int flags,
+           const gnutls_datum_t * hash,
+           const 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,
                                           gnutls_datum_t * plaintext);
-  int gnutls_openpgp_privkey_sign_hash (gnutls_openpgp_privkey_t key,
-                                       const gnutls_datum_t * hash,
-                                       gnutls_datum_t * signature);
   int gnutls_openpgp_privkey_get_fingerprint (gnutls_openpgp_privkey_t key,
                                              void *fpr, size_t * fprlen);
   int gnutls_openpgp_privkey_get_subkey_fingerprint (gnutls_openpgp_privkey_t
diff --git a/lib/includes/gnutls/pkcs11.h b/lib/includes/gnutls/pkcs11.h
index 9ea9a6e..937193f 100644
--- a/lib/includes/gnutls/pkcs11.h
+++ b/lib/includes/gnutls/pkcs11.h
@@ -200,9 +200,13 @@ int gnutls_pkcs11_privkey_sign_data 
(gnutls_pkcs11_privkey_t signer,
                                     unsigned int flags,
                                     const gnutls_datum_t * data,
                                     gnutls_datum_t * signature);
-int gnutls_pkcs11_privkey_sign_hash (gnutls_pkcs11_privkey_t key,
-                                    const gnutls_datum_t * hash,
-                                    gnutls_datum_t * signature);
+int
+gnutls_pkcs11_privkey_sign_hash2 (gnutls_pkcs11_privkey_t signer,
+                               gnutls_digest_algorithm_t hash_algo,
+                               unsigned int flags,
+                               const gnutls_datum_t * hash_data,
+                               gnutls_datum_t * signature);
+
 int
 gnutls_pkcs11_privkey_decrypt_data (gnutls_pkcs11_privkey_t key,
                                    unsigned int flags,
diff --git a/lib/includes/gnutls/x509.h b/lib/includes/gnutls/x509.h
index 80bb435..8c9570b 100644
--- a/lib/includes/gnutls/x509.h
+++ b/lib/includes/gnutls/x509.h
@@ -729,6 +729,13 @@ extern "C"
                                   unsigned int flags,
                                   const gnutls_datum_t * data,
                                   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_verify_hash (gnutls_x509_crt_t crt,
                                   unsigned int flags,
                                   const gnutls_datum_t * hash,
diff --git a/lib/libgnutls.map b/lib/libgnutls.map
index f719563..2a1b869 100644
--- a/lib/libgnutls.map
+++ b/lib/libgnutls.map
@@ -232,7 +232,6 @@ GNUTLS_1_4
     gnutls_openpgp_privkey_import;
     gnutls_openpgp_privkey_init;
     gnutls_openpgp_privkey_set_preferred_key_id;
-    gnutls_openpgp_privkey_sign_hash;
     gnutls_openpgp_send_cert;
     gnutls_openpgp_set_recv_key_function;
     gnutls_oprfi_enable_client;
@@ -694,6 +693,13 @@ 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_openpgp_crt_verify_hash;
+       gnutls_x509_privkey_sign_data2;
+       gnutls_pkcs11_privkey_sign_hash2;
 } GNUTLS_2_10;
 
 GNUTLS_PRIVATE {
diff --git a/lib/openpgp/gnutls_openpgp.c b/lib/openpgp/gnutls_openpgp.c
index 2223c98..0bf640d 100644
--- a/lib/openpgp/gnutls_openpgp.c
+++ b/lib/openpgp/gnutls_openpgp.c
@@ -840,151 +840,3 @@ _gnutls_openpgp_crt_to_gcert (gnutls_cert * gcert, 
gnutls_openpgp_crt_t cert)
 
 }
 
-/**
- * gnutls_openpgp_privkey_sign_hash:
- * @key: Holds the key
- * @hash: holds the data to be signed
- * @signature: will contain newly allocated signature
- *
- * 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_hash (gnutls_openpgp_privkey_t key,
-                                 const gnutls_datum_t * hash,
-                                 gnutls_datum_t * signature)
-{
-  int result, i;
-  bigint_t params[MAX_PRIV_PARAMS_SIZE];
-  int params_size = MAX_PRIV_PARAMS_SIZE;
-  int pk_algorithm;
-  gnutls_openpgp_keyid_t keyid;
-
-  if (key == NULL)
-    {
-      gnutls_assert ();
-      return GNUTLS_E_INVALID_REQUEST;
-    }
-
-  result = gnutls_openpgp_privkey_get_preferred_key_id (key, keyid);
-  if (result == 0)
-    {
-      uint32_t kid[2];
-      int idx;
-
-      KEYID_IMPORT (kid, keyid);
-
-      idx = gnutls_openpgp_privkey_get_subkey_idx (key, keyid);
-      pk_algorithm =
-       gnutls_openpgp_privkey_get_subkey_pk_algorithm (key, idx, NULL);
-      result =
-       _gnutls_openpgp_privkey_get_mpis (key, kid, params, &params_size);
-    }
-  else
-    {
-      pk_algorithm = gnutls_openpgp_privkey_get_pk_algorithm (key, NULL);
-      result = _gnutls_openpgp_privkey_get_mpis (key, NULL,
-                                                params, &params_size);
-    }
-
-  if (result < 0)
-    {
-      gnutls_assert ();
-      return result;
-    }
-
-
-  result =
-    _gnutls_soft_sign (pk_algorithm, params, params_size, hash, signature);
-
-  for (i = 0; i < params_size; i++)
-    _gnutls_mpi_release (&params[i]);
-
-  if (result < 0)
-    {
-      gnutls_assert ();
-      return result;
-    }
-
-  return 0;
-}
-
-/**
- * gnutls_openpgp_privkey_decrypt_data:
- * @key: Holds the key
- * @flags: zero for now
- * @ciphertext: holds the data to be decrypted
- * @plaintext: will contain newly allocated plaintext
- *
- * 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_decrypt_data (gnutls_openpgp_privkey_t key,
-                                    unsigned int flags,
-                                    const gnutls_datum_t * ciphertext,
-                                    gnutls_datum_t * plaintext)
-{
-  int result, i;
-  bigint_t params[MAX_PUBLIC_PARAMS_SIZE];
-  int params_size = MAX_PUBLIC_PARAMS_SIZE;
-  int pk_algorithm;
-  gnutls_openpgp_keyid_t keyid;
-
-  if (key == NULL)
-    {
-      gnutls_assert ();
-      return GNUTLS_E_INVALID_REQUEST;
-    }
-
-  result = gnutls_openpgp_privkey_get_preferred_key_id (key, keyid);
-  if (result == 0)
-    {
-      uint32_t kid[2];
-
-      KEYID_IMPORT (kid, keyid);
-      result = _gnutls_openpgp_privkey_get_mpis (key, kid,
-                                                params, &params_size);
-    }
-  else
-    {
-      result = _gnutls_openpgp_privkey_get_mpis (key, NULL,
-                                                params, &params_size);
-    }
-
-  if (result < 0)
-    {
-      gnutls_assert ();
-      return result;
-    }
-
-  pk_algorithm = gnutls_openpgp_privkey_get_pk_algorithm (key, NULL);
-
-  if (pk_algorithm != GNUTLS_PK_RSA)
-    {
-      gnutls_assert ();
-      return GNUTLS_E_INVALID_REQUEST;
-    }
-
-  result =
-    _gnutls_pkcs1_rsa_decrypt (plaintext, ciphertext, params, params_size, 2);
-
-  for (i = 0; i < params_size; i++)
-    _gnutls_mpi_release (&params[i]);
-
-  if (result < 0)
-    {
-      gnutls_assert ();
-      return result;
-    }
-
-  return 0;
-}
diff --git a/lib/openpgp/gnutls_openpgp.h b/lib/openpgp/gnutls_openpgp.h
index b5f67d4..c89b867 100644
--- a/lib/openpgp/gnutls_openpgp.h
+++ b/lib/openpgp/gnutls_openpgp.h
@@ -49,6 +49,11 @@ time_t _gnutls_openpgp_get_raw_key_creation_time (const 
gnutls_datum_t *
 time_t _gnutls_openpgp_get_raw_key_expiration_time (const gnutls_datum_t *
                                                    cert);
 
+int
+_gnutls_openpgp_privkey_sign_hash (gnutls_openpgp_privkey_t key,
+                                 const gnutls_datum_t * hash,
+                                 gnutls_datum_t * signature);
+
 
 #endif /*GNUTLS_OPENPGP_LOCAL_H */
 
diff --git a/lib/openpgp/pgp.c b/lib/openpgp/pgp.c
index e2a5230..fb6953b 100644
--- a/lib/openpgp/pgp.c
+++ b/lib/openpgp/pgp.c
@@ -33,6 +33,7 @@
 #include <openpgp_int.h>
 #include <gnutls_str.h>
 #include <gnutls_num.h>
+#include <x509/common.h>
 
 /**
  * gnutls_openpgp_crt_init:
@@ -1686,3 +1687,59 @@ gnutls_openpgp_crt_get_auth_subkey (gnutls_openpgp_crt_t 
crt,
   else
     return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
 }
+
+/**
+ * gnutls_openpgp_crt_verify_hash:
+ * @crt: Holds the certificate
+ * @flags: should be 0 for now
+ * @hash: holds the hash digest to be verified
+ * @signature: contains the signature
+ *
+ * This function will verify the given signed digest, using the
+ * parameters from the certificate.
+ *
+ * Returns: In case of a verification failure 0 is returned, and 1 on
+ * success.
+ **/
+int
+gnutls_openpgp_crt_verify_hash (gnutls_openpgp_crt_t crt, unsigned int flags,
+                            const gnutls_datum_t * hash,
+                            const gnutls_datum_t * signature)
+{
+  int ret;
+  bigint_t params[MAX_PUBLIC_PARAMS_SIZE];
+  int params_size = MAX_PUBLIC_PARAMS_SIZE;
+  gnutls_pk_algorithm_t pk;
+  uint32_t kid[2];
+  
+  if (crt == NULL || !crt->preferred_set)
+    {
+      gnutls_assert ();
+      return GNUTLS_E_INVALID_REQUEST;
+    }
+
+  ret = gnutls_openpgp_crt_get_pk_algorithm (crt, NULL);
+  if (ret < 0)
+    {
+      gnutls_assert ();
+      return ret;
+    }
+  pk = ret;
+  
+  KEYID_IMPORT (kid, crt->preferred_keyid);
+  ret = _gnutls_openpgp_crt_get_mpis (crt, kid, params, &params_size);
+  if (ret < 0)
+    {
+      gnutls_assert ();
+      return ret;
+    }
+
+  ret = pubkey_verify_sig( NULL, hash, signature, pk, params, params_size);
+  if (ret < 0)
+    {
+      gnutls_assert ();
+      return 0;
+    }
+
+  return ret;
+}
diff --git a/lib/openpgp/privkey.c b/lib/openpgp/privkey.c
index a3cdf12..29dfe51 100644
--- a/lib/openpgp/privkey.c
+++ b/lib/openpgp/privkey.c
@@ -34,6 +34,7 @@
 #include <openpgp_int.h>
 #include <gnutls_openpgp.h>
 #include <gnutls_cert.h>
+#include <gnutls_sig.h>
 
 /**
  * gnutls_openpgp_privkey_init:
@@ -1223,3 +1224,261 @@ gnutls_openpgp_privkey_set_preferred_key_id 
(gnutls_openpgp_privkey_t key,
 
   return 0;
 }
+
+/*-
+ * _gnutls_openpgp_privkey_sign_hash:
+ * @key: Holds the key
+ * @hash: holds the data to be signed
+ * @signature: will contain newly allocated signature
+ *
+ * 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_hash (gnutls_openpgp_privkey_t key,
+                                 const gnutls_datum_t * hash,
+                                 gnutls_datum_t * signature)
+{
+  int result, i;
+  bigint_t params[MAX_PRIV_PARAMS_SIZE];
+  int params_size = MAX_PRIV_PARAMS_SIZE;
+  int pk_algorithm;
+  gnutls_openpgp_keyid_t keyid;
+
+  if (key == NULL)
+    {
+      gnutls_assert ();
+      return GNUTLS_E_INVALID_REQUEST;
+    }
+
+  result = gnutls_openpgp_privkey_get_preferred_key_id (key, keyid);
+  if (result == 0)
+    {
+      uint32_t kid[2];
+      int idx;
+
+      KEYID_IMPORT (kid, keyid);
+
+      idx = gnutls_openpgp_privkey_get_subkey_idx (key, keyid);
+      pk_algorithm =
+       gnutls_openpgp_privkey_get_subkey_pk_algorithm (key, idx, NULL);
+      result =
+       _gnutls_openpgp_privkey_get_mpis (key, kid, params, &params_size);
+    }
+  else
+    {
+      pk_algorithm = gnutls_openpgp_privkey_get_pk_algorithm (key, NULL);
+      result = _gnutls_openpgp_privkey_get_mpis (key, NULL,
+                                                params, &params_size);
+    }
+
+  if (result < 0)
+    {
+      gnutls_assert ();
+      return result;
+    }
+
+
+  result =
+    _gnutls_soft_sign (pk_algorithm, params, params_size, hash, signature);
+
+  for (i = 0; i < params_size; i++)
+    _gnutls_mpi_release (&params[i]);
+
+  if (result < 0)
+    {
+      gnutls_assert ();
+      return result;
+    }
+
+  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);
+
+  ret = pk_prepare_hash (gnutls_openpgp_privkey_get_pk_algorithm (signer, 
NULL),
+      hash_algo, &digest);
+  if (ret < 0)
+    {
+      gnutls_assert ();
+      goto cleanup;
+    }
+
+  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
+ * address@hidden 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
+ * @flags: zero for now
+ * @ciphertext: holds the data to be decrypted
+ * @plaintext: will contain newly allocated plaintext
+ *
+ * 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_decrypt_data (gnutls_openpgp_privkey_t key,
+                                    unsigned int flags,
+                                    const gnutls_datum_t * ciphertext,
+                                    gnutls_datum_t * plaintext)
+{
+  int result, i;
+  bigint_t params[MAX_PUBLIC_PARAMS_SIZE];
+  int params_size = MAX_PUBLIC_PARAMS_SIZE;
+  int pk_algorithm;
+  gnutls_openpgp_keyid_t keyid;
+
+  if (key == NULL)
+    {
+      gnutls_assert ();
+      return GNUTLS_E_INVALID_REQUEST;
+    }
+
+  result = gnutls_openpgp_privkey_get_preferred_key_id (key, keyid);
+  if (result == 0)
+    {
+      uint32_t kid[2];
+
+      KEYID_IMPORT (kid, keyid);
+      result = _gnutls_openpgp_privkey_get_mpis (key, kid,
+                                                params, &params_size);
+    }
+  else
+    {
+      result = _gnutls_openpgp_privkey_get_mpis (key, NULL,
+                                                params, &params_size);
+    }
+
+  if (result < 0)
+    {
+      gnutls_assert ();
+      return result;
+    }
+
+  pk_algorithm = gnutls_openpgp_privkey_get_pk_algorithm (key, NULL);
+
+  if (pk_algorithm != GNUTLS_PK_RSA)
+    {
+      gnutls_assert ();
+      return GNUTLS_E_INVALID_REQUEST;
+    }
+
+  result =
+    _gnutls_pkcs1_rsa_decrypt (plaintext, ciphertext, params, params_size, 2);
+
+  for (i = 0; i < params_size; i++)
+    _gnutls_mpi_release (&params[i]);
+
+  if (result < 0)
+    {
+      gnutls_assert ();
+      return result;
+    }
+
+  return 0;
+}
diff --git a/lib/pkcs11_int.h b/lib/pkcs11_int.h
index 23aeb1b..4725d1e 100644
--- a/lib/pkcs11_int.h
+++ b/lib/pkcs11_int.h
@@ -97,4 +97,9 @@ int pkcs11_find_object (pakchois_session_t ** _pks,
 
 unsigned int pkcs11_obj_flags_to_int (unsigned int flags);
 
+int
+_gnutls_pkcs11_privkey_sign_hash (gnutls_pkcs11_privkey_t key,
+                                const gnutls_datum_t * hash,
+                                gnutls_datum_t * signature);
+
 #endif
diff --git a/lib/pkcs11_privkey.c b/lib/pkcs11_privkey.c
index 5d5cf48..208e6e7 100644
--- a/lib/pkcs11_privkey.c
+++ b/lib/pkcs11_privkey.c
@@ -29,7 +29,7 @@
 #include <gnutls_errors.h>
 #include <gnutls_datum.h>
 #include <pkcs11_int.h>
-#include <sign.h>
+#include <gnutls_sig.h>
 
 struct gnutls_pkcs11_privkey_st
 {
@@ -140,31 +140,21 @@ gnutls_pkcs11_privkey_sign_data (gnutls_pkcs11_privkey_t 
signer,
   int ret;
   gnutls_datum_t digest;
 
-  switch (signer->pk_algorithm)
+  ret = pk_hash_data(signer->pk_algorithm, hash, NULL, data, &digest);
+  if (ret < 0)
+    {
+      gnutls_assert();
+      return ret;
+    }
+
+  ret = pk_prepare_hash (signer->pk_algorithm, hash, &digest);
+  if (ret < 0)
     {
-    case GNUTLS_PK_RSA:
-      ret = pk_pkcs1_rsa_hash (hash, data, &digest);
-      if (ret < 0)
-       {
-         gnutls_assert ();
-         return ret;
-       }
-      break;
-    case GNUTLS_PK_DSA:
-      ret = pk_dsa_hash (hash, data, &digest);
-      if (ret < 0)
-       {
-         gnutls_assert ();
-         return ret;
-       }
-
-      break;
-    default:
       gnutls_assert ();
-      return GNUTLS_E_INTERNAL_ERROR;
+      goto cleanup;
     }
 
-  ret = gnutls_pkcs11_privkey_sign_hash (signer, &digest, signature);
+  ret = _gnutls_pkcs11_privkey_sign_hash (signer, &digest, signature);
   _gnutls_free_datum (&digest);
 
   if (ret < 0)
@@ -175,6 +165,9 @@ gnutls_pkcs11_privkey_sign_data (gnutls_pkcs11_privkey_t 
signer,
 
   return 0;
 
+cleanup:
+  _gnutls_free_datum (&digest);
+  return ret;
 }
 
 #define FIND_OBJECT(pks, obj, key) \
@@ -191,8 +184,8 @@ gnutls_pkcs11_privkey_sign_data (gnutls_pkcs11_privkey_t 
signer,
                } \
        } while (ret < 0);
 
-/**
- * gnutls_pkcs11_privkey_sign_hash:
+/*-
+ * _gnutls_pkcs11_privkey_sign_hash:
  * @key: Holds the key
  * @hash: holds the data to be signed (should be output of a hash)
  * @signature: will contain the signature allocated with gnutls_malloc()
@@ -203,9 +196,9 @@ gnutls_pkcs11_privkey_sign_data (gnutls_pkcs11_privkey_t 
signer,
  *
  * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
  *   negative error value.
- **/
+ -*/
 int
-gnutls_pkcs11_privkey_sign_hash (gnutls_pkcs11_privkey_t key,
+_gnutls_pkcs11_privkey_sign_hash (gnutls_pkcs11_privkey_t key,
                                 const gnutls_datum_t * hash,
                                 gnutls_datum_t * signature)
 {
@@ -264,6 +257,64 @@ cleanup:
   return ret;
 }
 
+/**
+ * gnutls_pkcs11_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_pkcs11_privkey_sign_hash2 (gnutls_pkcs11_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);
+
+  ret = pk_prepare_hash (signer->pk_algorithm, hash_algo, &digest);
+  if (ret < 0)
+    {
+      gnutls_assert ();
+      goto cleanup;
+    }
+
+  ret = _gnutls_pkcs11_privkey_sign_hash (signer, &digest, signature);
+  if (ret < 0)
+    {
+      gnutls_assert ();
+      goto cleanup;
+    }
+
+  ret = 0;
+
+cleanup:
+  _gnutls_free_datum(&digest);
+  return ret;
+}
 
 /**
  * gnutls_pkcs11_privkey_import_url:
diff --git a/lib/x509/Makefile.am b/lib/x509/Makefile.am
index 042f7eb..0081521 100644
--- a/lib/x509/Makefile.am
+++ b/lib/x509/Makefile.am
@@ -37,7 +37,6 @@ noinst_LTLIBRARIES = libgnutls_x509.la
 libgnutls_x509_la_SOURCES =    \
        common.c                \
        common.h                \
-       sign.h                  \
        crl.c                   \
        crl_write.c             \
        crq.c                   \
diff --git a/lib/x509/privkey.c b/lib/x509/privkey.c
index baa39db..9636883 100644
--- a/lib/x509/privkey.c
+++ b/lib/x509/privkey.c
@@ -34,7 +34,6 @@
 #include <x509_b64.h>
 #include <x509_int.h>
 #include <gnutls_pk.h>
-#include <sign.h>
 #include <gnutls_mpi.h>
 
 static int _gnutls_asn1_encode_rsa (ASN1_TYPE * c2, bigint_t * params);
@@ -1665,15 +1664,18 @@ 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-1,SHA-224 and SHA-256 
+ * for the DSA keys, depending on their bit size.
+ *
+ * Use gnutls_x509_crt_get_preferred_hash_algorithm() to determine
+ * the hash algorithm.
+ *
+ * The RSA algorithm is used in PKCS #1 v1.5 mode.
  *
  * If the buffer provided is not long enough to hold the output, then
  * address@hidden is updated and %GNUTLS_E_SHORT_MEMORY_BUFFER will
  * be returned.
  *
- * 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.
  **/
@@ -1687,47 +1689,28 @@ gnutls_x509_privkey_sign_data2 (gnutls_x509_privkey_t 
signer,
   int ret;
   gnutls_datum_t digest;
 
-  switch (signer->pk_algorithm)
+  ret = pk_hash_data(signer->pk_algorithm, hash, signer->params, data, 
&digest);
+  if (ret < 0)
     {
-    case GNUTLS_PK_RSA:
-      ret = pk_pkcs1_rsa_hash (hash, data, &digest);
-      if (ret < 0)
-       {
-         gnutls_assert ();
-         return ret;
-       }
-      break;
-    case GNUTLS_PK_DSA:
-      /* override hash for DSA */
-      ret =
-       pk_dsa_hash (_gnutls_dsa_q_to_hash (signer->params[1]), data,
-                    &digest);
-      if (ret < 0)
-       {
-         gnutls_assert ();
-         return ret;
-       }
-
-      break;
-    default:
-      gnutls_assert ();
-      return GNUTLS_E_INTERNAL_ERROR;
+      gnutls_assert();
+      return ret;
     }
 
-  ret = gnutls_x509_privkey_sign_hash (signer, &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
@@ -1740,7 +1723,7 @@ gnutls_x509_privkey_sign_data2 (gnutls_x509_privkey_t 
signer,
  *
  * 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,
@@ -1765,6 +1748,70 @@ 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-1,SHA-224 and SHA-256 
+ * for the DSA keys, depending on their bit size.
+ *
+ * Use gnutls_x509_crt_get_preferred_hash_algorithm() to determine
+ * the hash algorithm.
+ *
+ * The RSA algorithm is used in PKCS #1 v1.5 mode.
+ *
+ * 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);
+
+  ret = pk_prepare_hash (signer->pk_algorithm, hash_algo, &digest);
+  if (ret < 0)
+    {
+      gnutls_assert ();
+      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:
diff --git a/lib/x509/sign.c b/lib/x509/sign.c
index 1151300..07f7ef6 100644
--- a/lib/x509/sign.c
+++ b/lib/x509/sign.c
@@ -41,170 +41,8 @@
 #include <gnutls_datum.h>
 #include <x509_int.h>
 #include <common.h>
-#include <sign.h>
 #include <gnutls/abstract.h>
 
-/* Writes the digest information and the digest in a DER encoded
- * structure. The digest info is allocated and stored into the info structure.
- */
-static int
-encode_ber_digest_info (gnutls_digest_algorithm_t hash,
-                       const gnutls_datum_t * digest,
-                       gnutls_datum_t * output)
-{
-  ASN1_TYPE dinfo = ASN1_TYPE_EMPTY;
-  int result;
-  const char *algo;
-
-  algo = _gnutls_x509_mac_to_oid ((gnutls_mac_algorithm_t) hash);
-  if (algo == NULL)
-    {
-      gnutls_assert ();
-      _gnutls_x509_log ("Hash algorithm: %d\n", hash);
-      return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
-    }
-
-  if ((result = asn1_create_element (_gnutls_get_gnutls_asn (),
-                                    "GNUTLS.DigestInfo",
-                                    &dinfo)) != ASN1_SUCCESS)
-    {
-      gnutls_assert ();
-      return _gnutls_asn2err (result);
-    }
-
-  result = asn1_write_value (dinfo, "digestAlgorithm.algorithm", algo, 1);
-  if (result != ASN1_SUCCESS)
-    {
-      gnutls_assert ();
-      asn1_delete_structure (&dinfo);
-      return _gnutls_asn2err (result);
-    }
-
-  /* Write an ASN.1 NULL in the parameters field.  This matches RFC
-     3279 and RFC 4055, although is arguable incorrect from a historic
-     perspective (see those documents for more information).
-     Regardless of what is correct, this appears to be what most
-     implementations do.  */
-  result = asn1_write_value (dinfo, "digestAlgorithm.parameters",
-                            ASN1_NULL, ASN1_NULL_SIZE);
-  if (result != ASN1_SUCCESS)
-    {
-      gnutls_assert ();
-      asn1_delete_structure (&dinfo);
-      return _gnutls_asn2err (result);
-    }
-
-  result = asn1_write_value (dinfo, "digest", digest->data, digest->size);
-  if (result != ASN1_SUCCESS)
-    {
-      gnutls_assert ();
-      asn1_delete_structure (&dinfo);
-      return _gnutls_asn2err (result);
-    }
-
-  output->size = 0;
-  asn1_der_coding (dinfo, "", NULL, &output->size, NULL);
-
-  output->data = gnutls_malloc (output->size);
-  if (output->data == NULL)
-    {
-      gnutls_assert ();
-      asn1_delete_structure (&dinfo);
-      return GNUTLS_E_MEMORY_ERROR;
-    }
-
-  result = asn1_der_coding (dinfo, "", output->data, &output->size, NULL);
-  if (result != ASN1_SUCCESS)
-    {
-      gnutls_assert ();
-      asn1_delete_structure (&dinfo);
-      return _gnutls_asn2err (result);
-    }
-
-  asn1_delete_structure (&dinfo);
-
-  return 0;
-}
-
-/* if hash==MD5 then we do RSA-MD5
- * if hash==SHA then we do RSA-SHA
- * params[0] is modulus
- * params[1] is public key
- */
-int
-pk_pkcs1_rsa_hash (gnutls_digest_algorithm_t hash,
-                  const gnutls_datum_t * text, gnutls_datum_t * output)
-{
-  int ret;
-  opaque _digest[MAX_HASH_SIZE];
-  digest_hd_st hd;
-  gnutls_datum_t digest;
-
-  ret = _gnutls_hash_init (&hd, HASH2MAC (hash));
-  if (ret < 0)
-    {
-      gnutls_assert ();
-      return ret;
-    }
-
-  _gnutls_hash (&hd, text->data, text->size);
-  _gnutls_hash_deinit (&hd, _digest);
-
-  digest.data = _digest;
-  digest.size = _gnutls_hash_get_algo_len (HASH2MAC (hash));
-
-  /* Encode the digest as a DigestInfo
-   */
-  if ((ret = encode_ber_digest_info (hash, &digest, output)) != 0)
-    {
-      gnutls_assert ();
-      return ret;
-    }
-
-  return 0;
-}
-
-int
-pk_dsa_hash (gnutls_digest_algorithm_t hash, const gnutls_datum_t * text,
-            gnutls_datum_t * digest)
-{
-  int ret;
-  digest_hd_st hd;
-
-  if (hash != GNUTLS_DIG_SHA1 && hash != GNUTLS_DIG_SHA224 &&
-      hash != GNUTLS_DIG_SHA256)
-    {
-      gnutls_assert ();
-      return GNUTLS_E_INVALID_REQUEST;
-    }
-
-  digest->size = _gnutls_hash_get_algo_len (hash);
-  digest->data = gnutls_malloc (digest->size);
-  if (digest->data == NULL)
-    {
-      gnutls_assert ();
-      return GNUTLS_E_MEMORY_ERROR;
-    }
-
-  ret = _gnutls_hash_init (&hd, hash);
-  if (ret < 0)
-    {
-      gnutls_assert ();
-      goto fail;
-    }
-
-  _gnutls_hash (&hd, text->data, text->size);
-
-  _gnutls_hash_deinit (&hd, digest->data);
-
-  return 0;
-
-fail:
-  gnutls_free (digest->data);
-
-  return ret;
-}
-
 /* This is the same as the _gnutls_x509_sign, but this one will decode
  * the ASN1_TYPE given, and sign the DER data. Actually used to get the DER
  * of the TBS and sign it on the fly.
diff --git a/lib/x509/sign.h b/lib/x509/sign.h
deleted file mode 100644
index 190e4c3..0000000
--- a/lib/x509/sign.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#ifndef GNUTLS_SIGN_H
-#define GNUTLS_SIGN_H
-
-int pk_pkcs1_rsa_hash (gnutls_digest_algorithm_t hash,
-                      const gnutls_datum_t * text, gnutls_datum_t * output);
-int pk_dsa_hash (gnutls_digest_algorithm_t hash, const gnutls_datum_t * text,
-                gnutls_datum_t * output);
-
-#endif
diff --git a/tests/x509sign-verify.c b/tests/x509sign-verify.c
index 1eb86f5..8bde011 100644
--- a/tests/x509sign-verify.c
+++ b/tests/x509sign-verify.c
@@ -138,9 +138,8 @@ doit (void)
   gnutls_x509_privkey_t key;
   gnutls_x509_crt_t crt;
   gnutls_digest_algorithm_t hash_algo;
-  unsigned char _signature[128];
-  size_t _signature_size = sizeof (_signature);
   gnutls_datum_t signature;
+  gnutls_datum_t signature2;
   int ret;
   size_t i;
 
@@ -149,41 +148,52 @@ doit (void)
   for (i = 0; i < sizeof (key_dat) / sizeof (key_dat[0]); i++)
     {
       if (debug)
-       success ("loop %d\n", (int) i);
+        success ("loop %d\n", (int) i);
 
       ret = gnutls_x509_privkey_init (&key);
       if (ret < 0)
-       fail ("gnutls_x509_privkey_init\n");
+        fail ("gnutls_x509_privkey_init\n");
 
       ret =
-       gnutls_x509_privkey_import (key, &key_dat[i], GNUTLS_X509_FMT_PEM);
+        gnutls_x509_privkey_import (key, &key_dat[i], GNUTLS_X509_FMT_PEM);
       if (ret < 0)
-       fail ("gnutls_x509_privkey_import\n");
+        fail ("gnutls_x509_privkey_import\n");
 
-      ret = gnutls_x509_privkey_sign_data (key, GNUTLS_DIG_SHA1, 0, &raw_data,
-                                          _signature, &_signature_size);
+      ret = gnutls_x509_privkey_sign_hash2 (key, GNUTLS_DIG_SHA1, 0, 
&hash_data,
+                                          &signature2);
       if (ret < 0)
-       fail ("gnutls_x509_privkey_sign_hash\n");
+        fail ("gnutls_x509_privkey_sign_hash\n");
+
+      ret = gnutls_x509_privkey_sign_data2 (key, GNUTLS_DIG_SHA1, 0, &raw_data,
+                                          &signature);
+      if (ret < 0)
+        fail ("gnutls_x509_privkey_sign_hash\n");
 
       ret = gnutls_x509_crt_init (&crt);
       if (ret < 0)
-       fail ("gnutls_x509_crt_init\n");
+        fail ("gnutls_x509_crt_init\n");
 
       ret = gnutls_x509_crt_import (crt, &cert_dat[i], GNUTLS_X509_FMT_PEM);
       if (ret < 0)
-       fail ("gnutls_x509_crt_import\n");
-
-      signature.data = _signature;
-      signature.size = _signature_size;
+        fail ("gnutls_x509_crt_import\n");
 
       ret =
-       gnutls_x509_crt_get_verify_algorithm (crt, &signature, &hash_algo);
+        gnutls_x509_crt_get_verify_algorithm (crt, &signature, &hash_algo);
       if (ret < 0 || hash_algo != GNUTLS_DIG_SHA1)
-       fail ("gnutls_x509_crt_get_verify_algorithm\n");
+        fail ("gnutls_x509_crt_get_verify_algorithm\n");
 
       ret = gnutls_x509_crt_verify_hash (crt, 0, &hash_data, &signature);
       if (ret < 0)
-       fail ("gnutls_x509_privkey_verify_hash\n");
+        fail ("gnutls_x509_privkey_verify_hash\n");
+
+      ret =
+        gnutls_x509_crt_get_verify_algorithm (crt, &signature2, &hash_algo);
+      if (ret < 0 || hash_algo != GNUTLS_DIG_SHA1)
+        fail ("gnutls_x509_crt_get_verify_algorithm (hashed data)\n");
+
+      ret = gnutls_x509_crt_verify_hash (crt, 0, &hash_data, &signature2);
+      if (ret < 0)
+        fail ("gnutls_x509_privkey_verify_hash (hashed data)\n");
 
       gnutls_x509_privkey_deinit (key);
       gnutls_x509_crt_deinit (crt);


hooks/post-receive
-- 
GNU gnutls



reply via email to

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