summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2012-08-27 18:38:01 +0200
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2012-08-27 18:38:01 +0200
commitfb39830546a65c757f3aa473357098f9877dba87 (patch)
treecb2fe163692ff21da5115d95c055f19ffec3f37b
parente62907fde541e88ed7badd791629ccaf0353bd46 (diff)
downloadgnutls-fb39830546a65c757f3aa473357098f9877dba87.tar.gz
simplified ECDSA/DSA signature generation in tokens.
-rw-r--r--lib/gnutls_pk.c48
-rw-r--r--lib/gnutls_pk.h4
-rw-r--r--lib/pkcs11_privkey.c55
3 files changed, 69 insertions, 38 deletions
diff --git a/lib/gnutls_pk.c b/lib/gnutls_pk.c
index 8c3b9d3eae..f65b7dad1a 100644
--- a/lib/gnutls_pk.c
+++ b/lib/gnutls_pk.c
@@ -39,6 +39,48 @@
/* 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)
{
ASN1_TYPE sig;
@@ -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;
}
diff --git a/lib/gnutls_pk.h b/lib/gnutls_pk.h
index ee2b80bf7b..29af4c4216 100644
--- a/lib/gnutls_pk.h
+++ b/lib/gnutls_pk.h
@@ -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,
diff --git a/lib/pkcs11_privkey.c b/lib/pkcs11_privkey.c
index 43e3877ad1..3a6ce09652 100644
--- a/lib/pkcs11_privkey.c
+++ b/lib/pkcs11_privkey.c
@@ -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;
}