]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
Separated the sign_data functions to a hashing phase, a preparing phase, and the...
authorNikos Mavrogiannopoulos <nmav@gnutls.org>
Sat, 11 Dec 2010 17:22:13 +0000 (18:22 +0100)
committerNikos Mavrogiannopoulos <nmav@gnutls.org>
Sat, 11 Dec 2010 17:22:13 +0000 (18:22 +0100)
lib/gnutls_privkey.c
lib/pkcs11_privkey.c
lib/x509/privkey.c
lib/x509/sign.c
lib/x509/sign.h

index 99f47e8f5f208675307fef4b4065daff60e49966..a10d1a59472698fc7e9931526be9703760971fbf 100644 (file)
@@ -249,10 +249,17 @@ gnutls_privkey_sign_data (gnutls_privkey_t signer,
   int ret;
   gnutls_datum_t digest;
 
+  ret = pk_hash_data(signer->pk_algorithm, hash, NULL, data, signature);
+  if (ret < 0)
+    {
+      gnutls_assert();
+      return ret;
+    }
+
   switch (signer->pk_algorithm)
     {
     case GNUTLS_PK_RSA:
-      ret = pk_pkcs1_rsa_hash (hash, data, &digest);
+      ret = pk_prepare_pkcs1_rsa_hash (hash, &digest);
       if (ret < 0)
        {
          gnutls_assert ();
@@ -260,20 +267,14 @@ gnutls_privkey_sign_data (gnutls_privkey_t signer,
        }
       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;
+      ret = GNUTLS_E_UNIMPLEMENTED_FEATURE;
+      goto cleanup;
     }
 
-  ret = gnutls_privkey_sign_hash (signer, &digest, signature);
+  ret = _gnutls_privkey_sign_hash (signer, &digest, signature);
   _gnutls_free_datum (&digest);
 
   if (ret < 0)
@@ -283,10 +284,14 @@ gnutls_privkey_sign_data (gnutls_privkey_t signer,
     }
 
   return 0;
+
+cleanup:
+  _gnutls_free_datum (&digest);
+  return ret;
 }
 
-/**
- * gnutls_privkey_sign_hash:
+/*-
+ * _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 +301,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)
 {
index 5d5cf48250bebf66ba9d77fbe2df238f2921dedc..efc5e6de2e8fd111142d8ac93ed659eaa86e52ed 100644 (file)
@@ -140,10 +140,17 @@ gnutls_pkcs11_privkey_sign_data (gnutls_pkcs11_privkey_t signer,
   int ret;
   gnutls_datum_t digest;
 
+  ret = pk_hash_data(signer->pk_algorithm, hash, NULL, data, signature);
+  if (ret < 0)
+    {
+      gnutls_assert();
+      return ret;
+    }
+
   switch (signer->pk_algorithm)
     {
     case GNUTLS_PK_RSA:
-      ret = pk_pkcs1_rsa_hash (hash, data, &digest);
+      ret = pk_prepare_pkcs1_rsa_hash (hash, &digest);
       if (ret < 0)
        {
          gnutls_assert ();
@@ -151,17 +158,11 @@ gnutls_pkcs11_privkey_sign_data (gnutls_pkcs11_privkey_t signer,
        }
       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;
+      ret = GNUTLS_E_UNIMPLEMENTED_FEATURE;
+      goto cleanup;
     }
 
   ret = gnutls_pkcs11_privkey_sign_hash (signer, &digest, signature);
@@ -175,6 +176,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) \
index baa39db8f7b84ab8b8cf49eb82e8fe26cb684dc2..e023d7b33ecb2295dc3b2ab860d337247100e3d1 100644 (file)
@@ -1687,10 +1687,17 @@ 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);
+  if (ret < 0)
+    {
+      gnutls_assert();
+      return ret;
+    }
+
   switch (signer->pk_algorithm)
     {
     case GNUTLS_PK_RSA:
-      ret = pk_pkcs1_rsa_hash (hash, data, &digest);
+      ret = pk_prepare_pkcs1_rsa_hash (hash, &digest);
       if (ret < 0)
        {
          gnutls_assert ();
@@ -1698,23 +1705,15 @@ gnutls_x509_privkey_sign_data2 (gnutls_x509_privkey_t signer,
        }
       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;
+      ret = GNUTLS_E_UNIMPLEMENTED_FEATURE;
+      goto cleanup;
     }
 
-  ret = gnutls_x509_privkey_sign_hash (signer, &digest, signature);
+  ret = _gnutls_soft_sign (signer->pk_algorithm, signer->params,
+                             signer->params_size, &digest, signature);
   _gnutls_free_datum (&digest);
 
   if (ret < 0)
@@ -1725,6 +1724,9 @@ gnutls_x509_privkey_sign_data2 (gnutls_x509_privkey_t signer,
 
   return 0;
 
+cleanup:
+  _gnutls_free_datum (&digest);
+  return ret;
 }
 
 /**
index 1151300c6c1fac2a10f324ee8deee992b7748dc9..3da98ed778ff25b422d9a33cf93cc9db252fc292 100644 (file)
@@ -55,6 +55,8 @@ encode_ber_digest_info (gnutls_digest_algorithm_t hash,
   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)
@@ -102,10 +104,10 @@ encode_ber_digest_info (gnutls_digest_algorithm_t hash,
       return _gnutls_asn2err (result);
     }
 
-  output->size = 0;
-  asn1_der_coding (dinfo, "", NULL, &output->size, NULL);
+  tmp_output_size = 0;
+  asn1_der_coding (dinfo, "", NULL, &tmp_output_size, NULL);
 
-  output->data = gnutls_malloc (output->size);
+  tmp_output = gnutls_malloc (tmp_output_size);
   if (output->data == NULL)
     {
       gnutls_assert ();
@@ -113,7 +115,7 @@ encode_ber_digest_info (gnutls_digest_algorithm_t hash,
       return GNUTLS_E_MEMORY_ERROR;
     }
 
-  result = asn1_der_coding (dinfo, "", output->data, &output->size, NULL);
+  result = asn1_der_coding (dinfo, "", tmp_output, &tmp_output_size, NULL);
   if (result != ASN1_SUCCESS)
     {
       gnutls_assert ();
@@ -122,87 +124,83 @@ encode_ber_digest_info (gnutls_digest_algorithm_t hash,
     }
 
   asn1_delete_structure (&dinfo);
+  
+  output->size = tmp_output_size;
+  output->data = tmp_output;
 
   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 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;
-  opaque _digest[MAX_HASH_SIZE];
-  digest_hd_st hd;
-  gnutls_datum_t digest;
 
-  ret = _gnutls_hash_init (&hd, HASH2MAC (hash));
-  if (ret < 0)
+  switch (pk)
     {
-      gnutls_assert ();
-      return ret;
+    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;
     }
 
-  _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)
+  digest->size = _gnutls_hash_get_algo_len (hash);
+  digest->data = gnutls_malloc (digest->size);
+  if (digest->data == NULL)
     {
       gnutls_assert ();
-      return ret;
+      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;
 }
 
+/* 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_dsa_hash (gnutls_digest_algorithm_t hash, const gnutls_datum_t * text,
-            gnutls_datum_t * digest)
+pk_prepare_pkcs1_rsa_hash (gnutls_digest_algorithm_t hash,
+                  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;
-    }
+  gnutls_datum old_digest = { digest->data, digest->size };
 
-  ret = _gnutls_hash_init (&hd, hash);
-  if (ret < 0)
+  /* Encode the digest as a DigestInfo
+   */
+  if ((ret = encode_ber_digest_info (hash, digest, digest)) != 0)
     {
       gnutls_assert ();
-      goto fail;
+      return ret;
     }
 
-  _gnutls_hash (&hd, text->data, text->size);
-
-  _gnutls_hash_deinit (&hd, digest->data);
+  _gnutls_free_datum(&old_digest);
 
   return 0;
-
-fail:
-  gnutls_free (digest->data);
-
-  return ret;
 }
 
 /* This is the same as the _gnutls_x509_sign, but this one will decode
index 190e4c363beca6c1dbfd96defa89fb621275ee89..5992bbd3bfea11f17a9bd22f6f702489c741c49b 100644 (file)
@@ -1,9 +1,9 @@
 #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);
+int pk_prepare_pkcs1_rsa_hash (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);
 
 #endif