]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
simplified ECDSA/DSA signature generation in tokens.
authorNikos Mavrogiannopoulos <nmav@gnutls.org>
Mon, 27 Aug 2012 16:38:01 +0000 (18:38 +0200)
committerNikos Mavrogiannopoulos <nmav@gnutls.org>
Mon, 27 Aug 2012 16:38:01 +0000 (18:38 +0200)
lib/gnutls_pk.c
lib/gnutls_pk.h
lib/pkcs11_privkey.c

index 8c3b9d3eaee7b4b408af1d591554471a3337c65c..f65b7dad1a99e099cba9212266043f09acb08b78 100644 (file)
 
 /* encodes the Dss-Sig-Value structure
  */
+int
+_gnutls_encode_ber_rs_raw (gnutls_datum_t * sig_value, 
+                           const gnutls_datum_t *r, 
+                           const gnutls_datum_t *s)
+{
+  ASN1_TYPE sig;
+  int result;
+
+  if ((result =
+       asn1_create_element (_gnutls_get_gnutls_asn (),
+                            "GNUTLS.DSASignatureValue",
+                            &sig)) != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      return _gnutls_asn2err (result);
+    }
+
+  result = asn1_write_value( sig, "r", r->data, r->size);
+  if (result != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      asn1_delete_structure (&sig);
+      return _gnutls_asn2err(result);
+    }
+
+  result = asn1_write_value( sig, "s", s->data, s->size);
+  if (result != ASN1_SUCCESS)
+    {
+      gnutls_assert ();
+      asn1_delete_structure (&sig);
+      return _gnutls_asn2err(result);
+    }
+
+  result = _gnutls_x509_der_encode (sig, "", sig_value, 0);
+  asn1_delete_structure (&sig);
+
+  if (result < 0)
+    return gnutls_assert_val(result);
+
+  return 0;
+}
+
 int
 _gnutls_encode_ber_rs (gnutls_datum_t * sig_value, bigint_t r, bigint_t s)
 {
@@ -70,14 +112,10 @@ _gnutls_encode_ber_rs (gnutls_datum_t * sig_value, bigint_t r, bigint_t s)
     }
 
   result = _gnutls_x509_der_encode (sig, "", sig_value, 0);
-
   asn1_delete_structure (&sig);
 
   if (result < 0)
-    {
-      gnutls_assert ();
-      return result;
-    }
+    return gnutls_assert_val(result);
 
   return 0;
 }
index ee2b80bf7b94890b6b519ec3527ea0f7b4b388ea..29af4c421669989a2ef24be25a2ea72f43eecd8c 100644 (file)
@@ -49,6 +49,10 @@ int _gnutls_pk_params_copy (gnutls_pk_params_st * dst, const gnutls_pk_params_st
 /* The internal PK interface */
 int
 _gnutls_encode_ber_rs (gnutls_datum_t * sig_value, bigint_t r, bigint_t s);
+int
+_gnutls_encode_ber_rs_raw (gnutls_datum_t * sig_value, 
+                           const gnutls_datum_t *r, 
+                           const gnutls_datum_t *s);
 
 int
 _gnutls_decode_ber_rs (const gnutls_datum_t * sig_value, bigint_t * r,
index 43e3877ad1a45110e269d9c6ae18ca4950303663..3a6ce09652834ca9c5ba1600528a9906fe1b456b 100644 (file)
@@ -148,22 +148,6 @@ gnutls_pkcs11_privkey_get_info (gnutls_pkcs11_privkey_t pkey,
        } while (0);
 
 
-static int read_rs(bigint_t *r, bigint_t *s, uint8_t *data, size_t data_size)
-{
-unsigned int dhalf = data_size/2;
-
-  if (_gnutls_mpi_scan_nz (r, data, dhalf) != 0)
-    return gnutls_assert_val(GNUTLS_E_MPI_SCAN_FAILED);
-
-  if (_gnutls_mpi_scan_nz (s, &data[dhalf], dhalf) != 0)
-    {
-      _gnutls_mpi_release(r);
-      return gnutls_assert_val(GNUTLS_E_MPI_SCAN_FAILED);
-    }
-
-  return 0;
-}
-
 /*-
  * _gnutls_pkcs11_privkey_sign_hash:
  * @key: Holds the key
@@ -185,6 +169,7 @@ _gnutls_pkcs11_privkey_sign_hash (gnutls_pkcs11_privkey_t key,
   ck_rv_t rv;
   int ret;
   struct ck_mechanism mech;
+  gnutls_datum_t tmp = {NULL, 0};
   unsigned long siglen;
   struct pkcs11_session_info _sinfo;
   struct pkcs11_session_info *sinfo;
@@ -225,23 +210,22 @@ _gnutls_pkcs11_privkey_sign_hash (gnutls_pkcs11_privkey_t key,
       goto cleanup;
     }
 
-  signature->data = gnutls_malloc (siglen);
-  signature->size = siglen;
+  tmp.data = gnutls_malloc (siglen);
+  tmp.size = siglen;
 
-  rv = pkcs11_sign (sinfo->module, sinfo->pks, hash->data, hash->size, signature->data, &siglen);
+  rv = pkcs11_sign (sinfo->module, sinfo->pks, hash->data, hash->size, tmp.data, &siglen);
   if (rv != CKR_OK)
     {
-      gnutls_free (signature->data);
       gnutls_assert ();
       ret = pkcs11_rv_to_err (rv);
       goto cleanup;
     }
 
-  signature->size = siglen;
   
   if (key->pk_algorithm == GNUTLS_PK_EC || key->pk_algorithm == GNUTLS_PK_DSA)
     {
-      bigint_t r,s;
+      unsigned int hlen = siglen / 2;
+      gnutls_datum_t r, s;
 
       if (siglen % 2 != 0)
         {
@@ -250,23 +234,26 @@ _gnutls_pkcs11_privkey_sign_hash (gnutls_pkcs11_privkey_t key,
           goto cleanup;
         }
 
-      ret = read_rs(&r, &s, signature->data, signature->size);
-      if (ret < 0)
-        {
-          gnutls_assert();
-          goto cleanup;
-        }
-      
-      gnutls_free(signature->data);
-      ret = _gnutls_encode_ber_rs (signature, r, s);
-      _gnutls_mpi_release(&r);
-      _gnutls_mpi_release(&s);
+      r.data = tmp.data;
+      r.size = hlen;
+
+      s.data = &tmp.data[hlen];
+      s.size = hlen;
       
+      ret = _gnutls_encode_ber_rs_raw (signature, &r, &s);
       if (ret < 0)
         {
           gnutls_assert();
           goto cleanup;
         }
+
+      gnutls_free(tmp.data);
+      tmp.data = NULL;
+    }
+  else
+    {
+      signature->size = siglen;
+      signature->data = tmp.data;
     }
 
   ret = 0;
@@ -274,6 +261,8 @@ _gnutls_pkcs11_privkey_sign_hash (gnutls_pkcs11_privkey_t key,
 cleanup:
   if (sinfo != &key->sinfo)
     pkcs11_close_session (sinfo);
+  if (ret < 0)
+    gnutls_free(tmp.data);
 
   return ret;
 }