summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Vcelak <jan.vcelak@nic.cz>2016-03-08 15:11:54 +0100
committerNikos Mavrogiannopoulos <nmav@redhat.com>2016-03-08 15:13:30 +0100
commit1bb18e7cf56c577a771f41b0a27bf95f8b2f9e10 (patch)
treea08b114d1730781fd2fea4faebba266022d5ce9a
parentc810c06918d1ac4cfa651bc4420a1a93734a5869 (diff)
downloadgnutls-1bb18e7cf56c577a771f41b0a27bf95f8b2f9e10.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 cc09a66002..9df4594aee 100644
--- a/lib/pkcs11_privkey.c
+++ b/lib/pkcs11_privkey.c
@@ -655,6 +655,58 @@ gnutls_pkcs11_privkey_generate2(const char *url, gnutls_pk_algorithm_t pk,
}
#endif
+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
@@ -708,6 +760,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;
FIX_KEY_USAGE(pk, key_usage);
@@ -830,10 +883,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;