summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Vcelak <jan.vcelak@nic.cz>2016-02-25 15:21:30 +0100
committerNikos Mavrogiannopoulos <nmav@redhat.com>2017-06-23 16:57:42 +0200
commit84373c719aca7e0ed7d60eb106224246add3dd76 (patch)
tree10fabd8d26a2a5d2568445f19a2e588c7869e698
parente202634dcfdbf277a6b17d4c5650091e5a3868a8 (diff)
downloadgnutls-84373c719aca7e0ed7d60eb106224246add3dd76.tar.gz
pkcs11: implement correct DSA key pair generating
Signed-off-by: Jan Vcelak <jan.vcelak@nic.cz>
-rw-r--r--lib/pkcs11_privkey.c63
1 files changed, 59 insertions, 4 deletions
diff --git a/lib/pkcs11_privkey.c b/lib/pkcs11_privkey.c
index 86c6e9c1ad..b436134f59 100644
--- a/lib/pkcs11_privkey.c
+++ b/lib/pkcs11_privkey.c
@@ -642,6 +642,58 @@ gnutls_pkcs11_privkey_generate2(const char *url, gnutls_pk_algorithm_t pk,
return gnutls_pkcs11_privkey_generate3(url, pk, bits, label, NULL, fmt, pubkey, flags);
}
+struct dsa_params {
+ /* FIPS 186-3 maximal size for L and N length pair is (3072,256). */
+ uint8_t prime[384];
+ uint8_t subprime[32];
+ uint8_t generator[384];
+};
+
+static int
+_dsa_params_generate(struct ck_function_list *module, ck_session_handle_t session,
+ unsigned long bits, struct dsa_params *params,
+ struct ck_attribute *a, int *a_val)
+{
+ struct ck_mechanism mech = { CKM_DSA_PARAMETER_GEN };
+ struct ck_attribute attr = { CKA_PRIME_BITS, &bits, sizeof(bits) };
+ ck_object_handle_t key;
+ ck_rv_t rv;
+
+ /* Generate DSA parameters from prime length. */
+
+ rv = pkcs11_generate_key(module, session, &mech, &attr, 1, &key);
+ if (rv != CKR_OK) {
+ gnutls_assert();
+ _gnutls_debug_log("p11: %s\n", pkcs11_strerror(rv));
+ return pkcs11_rv_to_err(rv);
+ }
+
+ /* Retrieve generated parameters to be used with the new key pair. */
+
+ a[*a_val + 0].type = CKA_PRIME;
+ a[*a_val + 0].value = params->prime;
+ a[*a_val + 0].value_len = sizeof(params->prime);
+
+ a[*a_val + 1].type = CKA_SUBPRIME;
+ a[*a_val + 1].value = params->subprime;
+ a[*a_val + 1].value_len = sizeof(params->subprime);
+
+ a[*a_val + 2].type = CKA_BASE;
+ a[*a_val + 2].value = params->generator;
+ a[*a_val + 2].value_len = sizeof(params->generator);
+
+ rv = pkcs11_get_attribute_value(module, session, key, &a[*a_val], 3);
+ if (rv != CKR_OK) {
+ gnutls_assert();
+ _gnutls_debug_log("p11: %s\n", pkcs11_strerror(rv));
+ return pkcs11_rv_to_err(rv);
+ }
+
+ *a_val += 3;
+
+ return 0;
+}
+
/**
* gnutls_pkcs11_privkey_generate3:
* @url: a token URL
@@ -693,6 +745,7 @@ gnutls_pkcs11_privkey_generate3(const char *url, gnutls_pk_algorithm_t pk,
ck_key_type_t key_type;
char pubEx[3] = { 1,0,1 }; // 65537 = 0x10001
uint8_t id[20];
+ struct dsa_params dsa_params;
PKCS11_CHECK_INIT;
@@ -799,10 +852,12 @@ gnutls_pkcs11_privkey_generate3(const char *url, gnutls_pk_algorithm_t pk,
a[a_val].value_len = sizeof(tval);
a_val++;
- a[a_val].type = CKA_MODULUS_BITS;
- a[a_val].value = &_bits;
- a[a_val].value_len = sizeof(_bits);
- a_val++;
+ ret = _dsa_params_generate(sinfo.module, sinfo.pks, _bits,
+ &dsa_params, a, &a_val);
+ if (ret < 0) {
+ goto cleanup;
+ }
+
break;
case GNUTLS_PK_EC:
p[p_val].type = CKA_SIGN;