diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2012-08-27 18:38:01 +0200 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2012-08-27 18:38:01 +0200 |
commit | fb39830546a65c757f3aa473357098f9877dba87 (patch) | |
tree | cb2fe163692ff21da5115d95c055f19ffec3f37b | |
parent | e62907fde541e88ed7badd791629ccaf0353bd46 (diff) | |
download | gnutls-fb39830546a65c757f3aa473357098f9877dba87.tar.gz |
simplified ECDSA/DSA signature generation in tokens.
-rw-r--r-- | lib/gnutls_pk.c | 48 | ||||
-rw-r--r-- | lib/gnutls_pk.h | 4 | ||||
-rw-r--r-- | lib/pkcs11_privkey.c | 55 |
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; } |