summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2011-09-06 13:25:00 +0200
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2011-09-06 13:25:00 +0200
commit0f4a6959907369eb7f4c067a6dc50d37d1f91cc7 (patch)
tree4b59a9b3f2d1470266e5edf7ee594cd724f07076
parentceb4f32c9417ab44a2df831c306d7329eb5a1fce (diff)
parentb40785d940c460680347a886aabe6adace6b0861 (diff)
downloadgnutls-0f4a6959907369eb7f4c067a6dc50d37d1f91cc7.tar.gz
Merge branch 'master' into gnutls_3_0_x
Conflicts: NEWS lib/x509/x509.c
-rw-r--r--NEWS18
-rw-r--r--lib/gnutls_pubkey.c154
-rw-r--r--lib/gnutls_x509.c3
-rw-r--r--lib/includes/gnutls/abstract.h13
-rw-r--r--lib/includes/gnutls/pkcs11.h5
-rw-r--r--lib/libgnutls.map3
-rw-r--r--lib/pkcs11.c133
-rw-r--r--lib/pkcs11_int.h42
-rw-r--r--lib/pkcs11_privkey.c213
-rw-r--r--lib/pkcs11_write.c55
-rw-r--r--lib/x509/key_decode.c5
-rw-r--r--lib/x509/key_encode.c24
-rw-r--r--lib/x509/privkey.c2
-rw-r--r--lib/x509/x509.c7
-rw-r--r--lib/x509/x509_int.h9
-rw-r--r--src/certtool-common.c58
-rw-r--r--src/certtool-common.h9
-rw-r--r--src/certtool-gaa.c5
-rw-r--r--src/certtool.c69
-rw-r--r--src/certtool.gaa3
-rw-r--r--src/p11common.c1
-rw-r--r--src/p11tool-gaa.c232
-rw-r--r--src/p11tool-gaa.h34
-rw-r--r--src/p11tool.c5
-rw-r--r--src/p11tool.gaa15
-rw-r--r--src/p11tool.h6
-rw-r--r--src/pkcs11.c40
-rw-r--r--src/prime.c24
28 files changed, 949 insertions, 238 deletions
diff --git a/NEWS b/NEWS
index 419bb8566e..406abafb1f 100644
--- a/NEWS
+++ b/NEWS
@@ -2,10 +2,28 @@ GnuTLS NEWS -- History of user-visible changes. -*- outline -*-
Copyright (C) 2000-2011 Free Software Foundation, Inc.
See the end for copying conditions.
+* Version 3.0.3 (unreleased)
+
** libgnutls: Allow CA importing of 0 certificates to succeed.
Reported by Jonathan Nieder <jrnieder@gmail.com> in
<http://bugs.debian.org/640639>.
+** libgnutls: Added support for elliptic curves in
+PKCS #11.
+
+** libgnutls: Added gnutls_pkcs11_privkey_generate()
+to allow generating a key in a token.
+
+** p11tool: Added generate-rsa, generate-dsa and
+generate-ecc options.
+
+** API and ABI modifications:
+gnutls_pkcs11_privkey_generate: Added
+gnutls_pubkey_import_ecc_raw: Added
+gnutls_pubkey_import_ecc_x962: Added
+gnutls_pubkey_get_pk_ecc_x962: Added
+
+
* Version 3.0.2 (released 2011-09-01)
** libgnutls: OpenPGP certificate type is not enabled
diff --git a/lib/gnutls_pubkey.c b/lib/gnutls_pubkey.c
index baea500fa3..52a0720562 100644
--- a/lib/gnutls_pubkey.c
+++ b/lib/gnutls_pubkey.c
@@ -34,6 +34,7 @@
#include <x509/common.h>
#include <x509_b64.h>
#include <abstract_int.h>
+#include <gnutls_ecc.h>
#define PK_PEM_HEADER "PUBLIC KEY"
@@ -299,6 +300,10 @@ gnutls_pubkey_import_pkcs11 (gnutls_pubkey_t key,
&obj->pubkey[1],
&obj->pubkey[2], &obj->pubkey[3]);
break;
+ case GNUTLS_PK_ECC:
+ ret = gnutls_pubkey_import_ecc_x962 (key, &obj->pubkey[0],
+ &obj->pubkey[1]);
+ break;
default:
gnutls_assert ();
return GNUTLS_E_UNIMPLEMENTED_FEATURE;
@@ -753,6 +758,42 @@ gnutls_pubkey_get_pk_ecc_raw (gnutls_pubkey_t key, gnutls_ecc_curve_t *curve,
}
/**
+ * gnutls_pubkey_get_pk_ecc_x962:
+ * @key: Holds the public key
+ * @parameters: DER encoding of an ANSI X9.62 parameters
+ * @ecpoint: DER encoding of ANSI X9.62 ECPoint
+ *
+ * This function will export the ECC public key's parameters found in
+ * the given certificate. The new parameters will be allocated using
+ * gnutls_malloc() and will be stored in the appropriate datum.
+ *
+ * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
+ *
+ * Since: 3.0.0
+ **/
+int gnutls_pubkey_get_pk_ecc_x962 (gnutls_pubkey_t key, gnutls_datum_t* parameters,
+ gnutls_datum_t * ecpoint)
+{
+ int ret;
+
+ if (key == NULL || key->pk_algorithm != GNUTLS_PK_ECC)
+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+
+ ret = _gnutls_x509_write_ecc_pubkey(&key->params, ecpoint);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+
+ ret = _gnutls_x509_write_ecc_params(&key->params, parameters);
+ if (ret < 0)
+ {
+ _gnutls_free_datum(ecpoint);
+ return gnutls_assert_val(ret);
+ }
+
+ return 0;
+}
+
+/**
* gnutls_pubkey_import:
* @key: The structure to store the parsed public key.
* @data: The DER or PEM encoded certificate.
@@ -1060,6 +1101,119 @@ gnutls_pubkey_import_rsa_raw (gnutls_pubkey_t key,
}
/**
+ * gnutls_pubkey_import_ecc_raw:
+ * @key: The structure to store the parsed key
+ * @curve: holds the curve
+ * @x: holds the x
+ * @y: holds the y
+ *
+ * This function will convert the given elliptic curve parameters to a
+ * #gnutls_pubkey_t. The output will be stored in @key.
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
+ * negative error value.
+ *
+ * Since: 3.0.0
+ **/
+int
+gnutls_pubkey_import_ecc_raw (gnutls_pubkey_t key,
+ gnutls_ecc_curve_t curve,
+ const gnutls_datum_t * x,
+ const gnutls_datum_t * y)
+{
+ int ret;
+
+ if (key == NULL)
+ {
+ gnutls_assert ();
+ return GNUTLS_E_INVALID_REQUEST;
+ }
+
+ key->params.flags = curve;
+
+ ret = _gnutls_ecc_curve_fill_params(curve, &key->params);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+
+ if (_gnutls_mpi_scan_nz (&key->params.params[5], x->data, x->size))
+ {
+ gnutls_assert ();
+ ret = GNUTLS_E_MPI_SCAN_FAILED;
+ goto cleanup;
+ }
+ key->params.params_nr++;
+
+ if (_gnutls_mpi_scan_nz (&key->params.params[6], y->data, y->size))
+ {
+ gnutls_assert ();
+ ret = GNUTLS_E_MPI_SCAN_FAILED;
+ goto cleanup;
+ }
+ key->params.params_nr++;
+ key->pk_algorithm = GNUTLS_PK_ECC;
+
+ return 0;
+
+cleanup:
+ gnutls_pk_params_release(&key->params);
+ return ret;
+}
+
+/**
+ * gnutls_pubkey_import_ecc_x962:
+ * @key: The structure to store the parsed key
+ * @parameters: DER encoding of an ANSI X9.62 parameters
+ * @ecpoint: DER encoding of ANSI X9.62 ECPoint
+ *
+ * This function will convert the given elliptic curve parameters to a
+ * #gnutls_pubkey_t. The output will be stored in @key.
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
+ * negative error value.
+ *
+ * Since: 3.0.0
+ **/
+int
+gnutls_pubkey_import_ecc_x962 (gnutls_pubkey_t key,
+ const gnutls_datum_t * parameters,
+ const gnutls_datum_t * ecpoint)
+{
+ int ret;
+
+ if (key == NULL)
+ {
+ gnutls_assert ();
+ return GNUTLS_E_INVALID_REQUEST;
+ }
+
+ key->params.params_nr = 0;
+
+ ret = _gnutls_x509_read_ecc_params(parameters->data, parameters->size,
+ &key->params);
+ if (ret < 0)
+ {
+ gnutls_assert ();
+ goto cleanup;
+ }
+
+ ret = _gnutls_ecc_ansi_x963_import(ecpoint->data, ecpoint->size,
+ &key->params.params[5], &key->params.params[6]);
+ if (ret < 0)
+ {
+ gnutls_assert ();
+ goto cleanup;
+ }
+ key->params.params_nr+=2;
+ key->pk_algorithm = GNUTLS_PK_ECC;
+
+ return 0;
+
+cleanup:
+ gnutls_pk_params_release(&key->params);
+ return ret;
+}
+
+/**
* gnutls_pubkey_import_dsa_raw:
* @key: The structure to store the parsed key
* @p: holds the p
diff --git a/lib/gnutls_x509.c b/lib/gnutls_x509.c
index a2b8838544..16c0cf86eb 100644
--- a/lib/gnutls_x509.c
+++ b/lib/gnutls_x509.c
@@ -1378,6 +1378,9 @@ gnutls_certificate_set_x509_trust_mem (gnutls_certificate_credentials_t res,
ret = parse_pem_ca_mem (res,
ca->data, ca->size);
+ if (ret == GNUTLS_E_NO_CERTIFICATE_FOUND)
+ return 0;
+
return ret;
}
diff --git a/lib/includes/gnutls/abstract.h b/lib/includes/gnutls/abstract.h
index 429b06fe48..2d570798a6 100644
--- a/lib/includes/gnutls/abstract.h
+++ b/lib/includes/gnutls/abstract.h
@@ -64,6 +64,8 @@ int gnutls_pubkey_get_pk_dsa_raw (gnutls_pubkey_t key,
gnutls_datum_t * g, gnutls_datum_t * y);
int gnutls_pubkey_get_pk_ecc_raw (gnutls_pubkey_t key, gnutls_ecc_curve_t *curve,
gnutls_datum_t * x, gnutls_datum_t * y);
+int gnutls_pubkey_get_pk_ecc_x962 (gnutls_pubkey_t key, gnutls_datum_t* parameters,
+ gnutls_datum_t * ecpoint);
int gnutls_pubkey_export (gnutls_pubkey_t key,
gnutls_x509_crt_fmt_t format,
@@ -99,6 +101,17 @@ int gnutls_pubkey_import_rsa_raw (gnutls_pubkey_t key,
const gnutls_datum_t * m,
const gnutls_datum_t * e);
+int
+gnutls_pubkey_import_ecc_x962 (gnutls_pubkey_t key,
+ const gnutls_datum_t * parameters,
+ const gnutls_datum_t * ecpoint);
+
+int
+gnutls_pubkey_import_ecc_raw (gnutls_pubkey_t key,
+ gnutls_ecc_curve_t curve,
+ const gnutls_datum_t * x,
+ const gnutls_datum_t * y);
+
int gnutls_x509_crt_set_pubkey (gnutls_x509_crt_t crt, gnutls_pubkey_t key);
int gnutls_x509_crq_set_pubkey (gnutls_x509_crq_t crq, gnutls_pubkey_t key);
diff --git a/lib/includes/gnutls/pkcs11.h b/lib/includes/gnutls/pkcs11.h
index 6dca20f4e0..7db5d9e575 100644
--- a/lib/includes/gnutls/pkcs11.h
+++ b/lib/includes/gnutls/pkcs11.h
@@ -338,4 +338,9 @@ int gnutls_pkcs11_privkey_export_url (gnutls_pkcs11_privkey_t key,
gnutls_pkcs11_url_type_t detailed,
char **url);
+int
+gnutls_pkcs11_privkey_generate (const char* url,
+ gnutls_pk_algorithm_t pk, unsigned int bits,
+ const char* label, unsigned int flags);
+
#endif
diff --git a/lib/libgnutls.map b/lib/libgnutls.map
index 33305330fd..97ff01cc50 100644
--- a/lib/libgnutls.map
+++ b/lib/libgnutls.map
@@ -713,6 +713,9 @@ GNUTLS_3_0_0 {
gnutls_x509_trust_list_add_named_crt;
gnutls_alert_get_strname;
gnutls_pcert_list_import_x509_raw;
+ gnutls_pkcs11_privkey_generate;
+ gnutls_pubkey_import_ecc_raw;
+ gnutls_pubkey_import_ecc_raw2;
} GNUTLS_2_12;
GNUTLS_PRIVATE {
diff --git a/lib/pkcs11.c b/lib/pkcs11.c
index 91db86c7d7..89bda0c1ac 100644
--- a/lib/pkcs11.c
+++ b/lib/pkcs11.c
@@ -1109,30 +1109,15 @@ pkcs11_obj_import (ck_object_class_t class, gnutls_pkcs11_obj_t obj,
return 0;
}
-static int
-pkcs11_obj_import_pubkey (struct ck_function_list *module,
- ck_session_handle_t pks,
- ck_object_handle_t obj,
- gnutls_pkcs11_obj_t crt,
- const gnutls_datum_t * id,
- const gnutls_datum_t * label,
- struct ck_token_info *tinfo,
- struct ck_info *lib_info)
+static int read_pkcs11_pubkey(struct ck_function_list *module,
+ ck_session_handle_t pks, ck_object_handle_t obj,
+ ck_key_type_t key_type, gnutls_datum_t * pubkey)
{
-
struct ck_attribute a[4];
- ck_key_type_t key_type;
opaque tmp1[2048];
opaque tmp2[2048];
int ret;
- ck_bool_t tval;
-
- a[0].type = CKA_KEY_TYPE;
- a[0].value = &key_type;
- a[0].value_len = sizeof (key_type);
- if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK)
- {
switch (key_type)
{
case CKK_RSA:
@@ -1147,19 +1132,19 @@ pkcs11_obj_import_pubkey (struct ck_function_list *module,
{
ret =
- _gnutls_set_datum (&crt->pubkey[0],
+ _gnutls_set_datum (&pubkey[0],
a[0].value, a[0].value_len);
if (ret >= 0)
ret =
- _gnutls_set_datum (&crt->pubkey
+ _gnutls_set_datum (&pubkey
[1], a[1].value, a[1].value_len);
if (ret < 0)
{
gnutls_assert ();
- _gnutls_free_datum (&crt->pubkey[1]);
- _gnutls_free_datum (&crt->pubkey[0]);
+ _gnutls_free_datum (&pubkey[1]);
+ _gnutls_free_datum (&pubkey[0]);
return GNUTLS_E_MEMORY_ERROR;
}
}
@@ -1168,7 +1153,6 @@ pkcs11_obj_import_pubkey (struct ck_function_list *module,
gnutls_assert ();
return GNUTLS_E_PKCS11_ERROR;
}
- crt->pk_algorithm = GNUTLS_PK_RSA;
break;
case CKK_DSA:
a[0].type = CKA_PRIME;
@@ -1181,19 +1165,19 @@ pkcs11_obj_import_pubkey (struct ck_function_list *module,
if (pkcs11_get_attribute_value (module, pks, obj, a, 2) == CKR_OK)
{
ret =
- _gnutls_set_datum (&crt->pubkey[0],
+ _gnutls_set_datum (&pubkey[0],
a[0].value, a[0].value_len);
if (ret >= 0)
ret =
- _gnutls_set_datum (&crt->pubkey
+ _gnutls_set_datum (&pubkey
[1], a[1].value, a[1].value_len);
if (ret < 0)
{
gnutls_assert ();
- _gnutls_free_datum (&crt->pubkey[1]);
- _gnutls_free_datum (&crt->pubkey[0]);
+ _gnutls_free_datum (&pubkey[1]);
+ _gnutls_free_datum (&pubkey[0]);
return GNUTLS_E_MEMORY_ERROR;
}
}
@@ -1213,21 +1197,21 @@ pkcs11_obj_import_pubkey (struct ck_function_list *module,
if (pkcs11_get_attribute_value (module, pks, obj, a, 2) == CKR_OK)
{
ret =
- _gnutls_set_datum (&crt->pubkey[2],
+ _gnutls_set_datum (&pubkey[2],
a[0].value, a[0].value_len);
if (ret >= 0)
ret =
- _gnutls_set_datum (&crt->pubkey
+ _gnutls_set_datum (&pubkey
[3], a[1].value, a[1].value_len);
if (ret < 0)
{
gnutls_assert ();
- _gnutls_free_datum (&crt->pubkey[0]);
- _gnutls_free_datum (&crt->pubkey[1]);
- _gnutls_free_datum (&crt->pubkey[2]);
- _gnutls_free_datum (&crt->pubkey[3]);
+ _gnutls_free_datum (&pubkey[0]);
+ _gnutls_free_datum (&pubkey[1]);
+ _gnutls_free_datum (&pubkey[2]);
+ _gnutls_free_datum (&pubkey[3]);
return GNUTLS_E_MEMORY_ERROR;
}
}
@@ -1236,12 +1220,74 @@ pkcs11_obj_import_pubkey (struct ck_function_list *module,
gnutls_assert ();
return GNUTLS_E_PKCS11_ERROR;
}
- crt->pk_algorithm = GNUTLS_PK_RSA;
+ break;
+ case CKK_ECDSA:
+ a[0].type = CKA_EC_PARAMS;
+ a[0].value = tmp1;
+ a[0].value_len = sizeof (tmp1);
+ a[1].type = CKA_EC_POINT;
+ a[1].value = tmp2;
+ a[1].value_len = sizeof (tmp2);
+
+ if (pkcs11_get_attribute_value (module, pks, obj, a, 2) == CKR_OK)
+ {
+ ret =
+ _gnutls_set_datum (&pubkey[0],
+ a[0].value, a[0].value_len);
+
+ if (ret >= 0)
+ ret =
+ _gnutls_set_datum (&pubkey
+ [1], a[1].value, a[1].value_len);
+
+ if (ret < 0)
+ {
+ gnutls_assert ();
+ _gnutls_free_datum (&pubkey[1]);
+ _gnutls_free_datum (&pubkey[0]);
+ return GNUTLS_E_MEMORY_ERROR;
+ }
+ }
+ else
+ {
+ gnutls_assert ();
+ return GNUTLS_E_PKCS11_ERROR;
+ }
+
break;
default:
- gnutls_assert ();
- return GNUTLS_E_UNIMPLEMENTED_FEATURE;
+ return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
}
+
+ return 0;
+}
+
+static int
+pkcs11_obj_import_pubkey (struct ck_function_list *module,
+ ck_session_handle_t pks,
+ ck_object_handle_t obj,
+ gnutls_pkcs11_obj_t crt,
+ const gnutls_datum_t * id,
+ const gnutls_datum_t * label,
+ struct ck_token_info *tinfo,
+ struct ck_info *lib_info)
+{
+ struct ck_attribute a[4];
+ ck_key_type_t key_type;
+ int ret;
+ ck_bool_t tval;
+
+ a[0].type = CKA_KEY_TYPE;
+ a[0].value = &key_type;
+ a[0].value_len = sizeof (key_type);
+
+ if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK)
+ {
+ crt->pk_algorithm = mech_to_pk(key_type);
+
+ ret = read_pkcs11_pubkey(module, pks, obj, key_type, crt->pubkey);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
}
/* read key usage flags */
@@ -2849,6 +2895,21 @@ pkcs11_sign (struct ck_function_list *module,
}
ck_rv_t
+pkcs11_generate_key_pair (struct ck_function_list *module,
+ ck_session_handle_t sess,
+ struct ck_mechanism *mechanism,
+ struct ck_attribute *pub_templ,
+ unsigned long pub_templ_count,
+ struct ck_attribute *priv_templ,
+ unsigned long priv_templ_count,
+ ck_object_handle_t *pub,
+ ck_object_handle_t *priv)
+{
+ return (module)->C_GenerateKeyPair (sess, mechanism, pub_templ, pub_templ_count,
+ priv_templ, priv_templ_count, pub, priv);
+}
+
+ck_rv_t
pkcs11_decrypt_init (struct ck_function_list *module,
ck_session_handle_t sess,
struct ck_mechanism *mechanism,
diff --git a/lib/pkcs11_int.h b/lib/pkcs11_int.h
index cd62904889..2480da7769 100644
--- a/lib/pkcs11_int.h
+++ b/lib/pkcs11_int.h
@@ -96,6 +96,48 @@ _gnutls_pkcs11_privkey_decrypt_data (gnutls_pkcs11_privkey_t key,
const gnutls_datum_t * ciphertext,
gnutls_datum_t * plaintext);
+static inline int pk_to_mech(gnutls_pk_algorithm_t pk)
+{
+ if (pk == GNUTLS_PK_DSA)
+ return CKM_DSA;
+ else if (pk == GNUTLS_PK_ECC)
+ return CKM_ECDSA;
+ else
+ return CKM_RSA_PKCS;
+}
+
+static inline gnutls_pk_algorithm_t mech_to_pk(ck_key_type_t m)
+{
+ if (m == CKK_RSA)
+ return GNUTLS_PK_RSA;
+ else if (m == CKK_DSA)
+ return GNUTLS_PK_DSA;
+ else if (m == CKK_ECDSA)
+ return GNUTLS_PK_ECC;
+ else return GNUTLS_PK_UNKNOWN;
+}
+
+static inline int pk_to_genmech(gnutls_pk_algorithm_t pk)
+{
+ if (pk == GNUTLS_PK_DSA)
+ return CKM_DSA_KEY_PAIR_GEN;
+ else if (pk == GNUTLS_PK_ECC)
+ return CKM_ECDSA_KEY_PAIR_GEN;
+ else
+ return CKM_RSA_PKCS_KEY_PAIR_GEN;
+}
+
+ck_rv_t
+pkcs11_generate_key_pair (struct ck_function_list *module,
+ ck_session_handle_t sess,
+ struct ck_mechanism *mechanism,
+ struct ck_attribute *pub_templ,
+ unsigned long pub_templ_count,
+ struct ck_attribute *priv_templ,
+ unsigned long priv_templ_count,
+ ck_object_handle_t *pub,
+ ck_object_handle_t *priv);
+
ck_rv_t
pkcs11_get_slot_list (struct ck_function_list * module,
unsigned char token_present,
diff --git a/lib/pkcs11_privkey.c b/lib/pkcs11_privkey.c
index c1ba8fbc95..ffc5ac6ed3 100644
--- a/lib/pkcs11_privkey.c
+++ b/lib/pkcs11_privkey.c
@@ -169,8 +169,7 @@ _gnutls_pkcs11_privkey_sign_hash (gnutls_pkcs11_privkey_t key,
FIND_OBJECT (module, pks, obj, key);
- mech.mechanism =
- key->pk_algorithm == GNUTLS_PK_DSA ? CKM_DSA : CKM_RSA_PKCS;
+ mech.mechanism = pk_to_mech(key->pk_algorithm);
mech.parameter = NULL;
mech.parameter_len = 0;
@@ -272,15 +271,9 @@ gnutls_pkcs11_privkey_import_url (gnutls_pkcs11_privkey_t pkey,
if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK)
{
- switch (key_type)
+ pkey->pk_algorithm = mech_to_pk(key_type);
+ if (pkey->pk_algorithm == GNUTLS_PK_UNKNOWN)
{
- case CKK_RSA:
- pkey->pk_algorithm = GNUTLS_PK_RSA;
- break;
- case CKK_DSA:
- pkey->pk_algorithm = GNUTLS_PK_DSA;
- break;
- default:
_gnutls_debug_log("Cannot determine PKCS #11 key algorithm\n");
ret = GNUTLS_E_UNKNOWN_ALGORITHM;
goto cleanup;
@@ -324,8 +317,10 @@ _gnutls_pkcs11_privkey_decrypt_data (gnutls_pkcs11_privkey_t key,
FIND_OBJECT (module, pks, obj, key);
- mech.mechanism =
- key->pk_algorithm == GNUTLS_PK_DSA ? CKM_DSA : CKM_RSA_PKCS;
+ if (key->pk_algorithm != GNUTLS_PK_RSA)
+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+
+ mech.mechanism = CKM_RSA_PKCS;
mech.parameter = NULL;
mech.parameter_len = 0;
@@ -399,3 +394,197 @@ gnutls_pkcs11_privkey_export_url (gnutls_pkcs11_privkey_t key,
return 0;
}
+
+
+/**
+ * gnutls_pkcs11_privkey_generate:
+ * @url: a token URL
+ * @pk: the public key algorithm
+ * @bits: the security bits
+ * @label: a label
+ * @flags: should be zero
+ *
+ * This function will generate a private key in the specified
+ * by the @url token. The pivate key will be generate within
+ * the token and will not be exportable.
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
+ * negative error value.
+ **/
+int
+gnutls_pkcs11_privkey_generate (const char* url,
+ gnutls_pk_algorithm_t pk, unsigned int bits,
+ const char* label, unsigned int flags)
+{
+ int ret;
+ const ck_bool_t tval = 1;
+ const ck_bool_t fval = 0;
+ struct ck_function_list *module;
+ ck_session_handle_t pks = 0;
+ struct p11_kit_uri *info = NULL;
+ ck_rv_t rv;
+ size_t id_size;
+ opaque id[20];
+ struct ck_attribute a[10], p[10];
+ ck_object_handle_t pub, priv;
+ unsigned long _bits = bits;
+ int a_val, p_val;
+ struct ck_mechanism mech;
+
+ ret = pkcs11_url_to_info (url, &info);
+ if (ret < 0)
+ {
+ gnutls_assert ();
+ return ret;
+ }
+
+ ret =
+ pkcs11_open_session (&module, &pks, info,
+ SESSION_WRITE | pkcs11_obj_flags_to_int (flags));
+ p11_kit_uri_free (info);
+
+ if (ret < 0)
+ {
+ gnutls_assert ();
+ goto cleanup;
+ }
+
+ /* a holds the public key template
+ * and p the private key */
+ a_val = p_val = 0;
+ mech.parameter = NULL;
+ mech.parameter_len = 0;
+ mech.mechanism = pk_to_genmech(pk);
+
+ switch(pk)
+ {
+ case GNUTLS_PK_RSA:
+ p[p_val].type = CKA_DECRYPT;
+ p[p_val].value = (void*)&tval;
+ p[p_val].value_len = sizeof (tval);
+ p_val++;
+
+ p[p_val].type = CKA_SIGN;
+ p[p_val].value = (void*)&tval;
+ p[p_val].value_len = sizeof (tval);
+ p_val++;
+
+ a[a_val].type = CKA_ENCRYPT;
+ a[a_val].value = (void*)&tval;
+ a[a_val].value_len = sizeof (tval);
+ a_val++;
+
+ a[a_val].type = CKA_VERIFY;
+ a[a_val].value = (void*)&tval;
+ 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++;
+ break;
+ case GNUTLS_PK_DSA:
+ p[p_val].type = CKA_SIGN;
+ p[p_val].value = (void*)&tval;
+ p[p_val].value_len = sizeof (tval);
+ p_val++;
+
+ a[a_val].type = CKA_VERIFY;
+ a[a_val].value = (void*)&tval;
+ 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++;
+ break;
+ case GNUTLS_PK_ECC:
+ p[p_val].type = CKA_SIGN;
+ p[p_val].value = (void*)&tval;
+ p[p_val].value_len = sizeof (tval);
+ p_val++;
+
+ a[a_val].type = CKA_VERIFY;
+ a[a_val].value = (void*)&tval;
+ 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++;
+ break;
+ default:
+ ret = gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+ goto cleanup;
+ }
+
+ /* a private key is set always as private unless
+ * requested otherwise
+ */
+ if (flags & GNUTLS_PKCS11_OBJ_FLAG_MARK_NOT_PRIVATE)
+ {
+ p[p_val].type = CKA_PRIVATE;
+ p[p_val].value = (void*)&fval;
+ p[p_val].value_len = sizeof(fval);
+ p_val++;
+ }
+ else
+ {
+ p[p_val].type = CKA_PRIVATE;
+ p[p_val].value = (void*)&tval;
+ p[p_val].value_len = sizeof (tval);
+ p_val++;
+ }
+
+ p[p_val].type = CKA_TOKEN;
+ p[p_val].value = (void *)&tval;
+ p[p_val].value_len = sizeof (tval);
+ p_val++;
+
+ if (label)
+ {
+ p[p_val].type = CKA_LABEL;
+ p[p_val].value = (void*)label;
+ p[p_val].value_len = strlen (label);
+ p_val++;
+
+ a[a_val].type = CKA_LABEL;
+ a[a_val].value = (void*)label;
+ a[a_val].value_len = strlen (label);
+ a_val++;
+ }
+
+ if (flags & GNUTLS_PKCS11_OBJ_FLAG_MARK_SENSITIVE)
+ {
+ p[p_val].type = CKA_SENSITIVE;
+ p[p_val].value = (void*)&tval;
+ p[p_val].value_len = sizeof (tval);
+ p_val++;
+ }
+ else
+ {
+ p[p_val].type = CKA_SENSITIVE;
+ p[p_val].value = (void*)&fval;
+ p[p_val].value_len = sizeof (fval);
+ p_val++;
+ }
+
+ rv = pkcs11_generate_key_pair( module, pks, &mech, a, a_val, p, p_val, &pub, &priv);
+ if (rv != CKR_OK)
+ {
+ gnutls_assert ();
+ _gnutls_debug_log ("pkcs11: %s\n", pkcs11_strerror (rv));
+ ret = pkcs11_rv_to_err (rv);
+ goto cleanup;
+ }
+
+
+cleanup:
+ if (pks != 0)
+ pkcs11_close_session (module, pks);
+
+ return ret;
+}
diff --git a/lib/pkcs11_write.c b/lib/pkcs11_write.c
index e5226a4e09..5b2fd7bee1 100644
--- a/lib/pkcs11_write.c
+++ b/lib/pkcs11_write.c
@@ -243,6 +243,17 @@ gnutls_pkcs11_copy_x509_privkey (const char *token_url,
gnutls_datum_t p, q, g, y, x;
gnutls_datum_t m, e, d, u, exp1, exp2;
+ memset(&p, 0, sizeof(p));
+ memset(&q, 0, sizeof(q));
+ memset(&g, 0, sizeof(g));
+ memset(&y, 0, sizeof(y));
+ memset(&x, 0, sizeof(x));
+ memset(&m, 0, sizeof(m));
+ memset(&e, 0, sizeof(e));
+ memset(&d, 0, sizeof(d));
+ memset(&u, 0, sizeof(u));
+ memset(&exp1, 0, sizeof(exp1));
+ memset(&exp2, 0, sizeof(exp2));
ret = pkcs11_url_to_info (token_url, &info);
if (ret < 0)
@@ -427,6 +438,36 @@ gnutls_pkcs11_copy_x509_privkey (const char *token_url,
break;
}
+ case GNUTLS_PK_ECC:
+ {
+ ret = _gnutls_x509_write_ecc_params(&key->params, &p);
+ if (ret < 0)
+ {
+ gnutls_assert ();
+ goto cleanup;
+ }
+
+ ret = _gnutls_mpi_dprint_lz(&key->params.params[7], &x);
+ if (ret < 0)
+ {
+ gnutls_assert ();
+ goto cleanup;
+ }
+
+ type = CKK_ECDSA;
+
+ a[a_val].type = CKA_EC_PARAMS;
+ a[a_val].value = p.data;
+ a[a_val].value_len = p.size;
+ a_val++;
+
+ a[a_val].type = CKA_VALUE;
+ a[a_val].value = x.data;
+ a[a_val].value_len = x.size;
+ a_val++;
+
+ break;
+ }
default:
gnutls_assert ();
ret = GNUTLS_E_INVALID_REQUEST;
@@ -442,9 +483,9 @@ gnutls_pkcs11_copy_x509_privkey (const char *token_url,
goto cleanup;
}
- /* generated!
- */
+ ret = 0;
+cleanup:
switch (pk)
{
case GNUTLS_PK_RSA:
@@ -468,15 +509,18 @@ gnutls_pkcs11_copy_x509_privkey (const char *token_url,
gnutls_free (x.data);
break;
}
+ case GNUTLS_PK_ECC:
+ {
+ gnutls_free (p.data);
+ gnutls_free (x.data);
+ break;
+ }
default:
gnutls_assert ();
ret = GNUTLS_E_INVALID_REQUEST;
goto cleanup;
}
- ret = 0;
-
-cleanup:
if (pks != 0)
pkcs11_close_session (module, pks);
@@ -786,3 +830,4 @@ finish:
return ret;
}
+
diff --git a/lib/x509/key_decode.c b/lib/x509/key_decode.c
index 0690a49bcc..a13a72529e 100644
--- a/lib/x509/key_decode.c
+++ b/lib/x509/key_decode.c
@@ -40,9 +40,6 @@ static int _gnutls_x509_read_ecc_pubkey (opaque * der, int dersize,
static int
_gnutls_x509_read_dsa_params (opaque * der, int dersize, gnutls_pk_params_st * params);
-static int
-_gnutls_x509_read_ecc_params (opaque * der, int dersize, gnutls_pk_params_st * params);
-
/*
* some x509 certificate parsing functions that relate to MPI parameter
* extraction. This reads the BIT STRING subjectPublicKey.
@@ -180,7 +177,7 @@ _gnutls_x509_read_dsa_params (opaque * der, int dersize, gnutls_pk_params_st * p
/* reads the curve from the certificate.
* params[0-4]. It does NOT set params_nr.
*/
-static int
+int
_gnutls_x509_read_ecc_params (opaque * der, int dersize, gnutls_pk_params_st * params)
{
int ret;
diff --git a/lib/x509/key_encode.c b/lib/x509/key_encode.c
index 7c442f3364..42df697989 100644
--- a/lib/x509/key_encode.c
+++ b/lib/x509/key_encode.c
@@ -39,12 +39,6 @@ static int _gnutls_x509_write_dsa_params (gnutls_pk_params_st * params,
static int _gnutls_x509_write_dsa_pubkey (gnutls_pk_params_st * params,
gnutls_datum_t * der);
-static int _gnutls_x509_write_ecc_params (gnutls_pk_params_st * params,
- gnutls_datum_t * der);
-static int _gnutls_x509_write_ecc_pubkey (gnutls_pk_params_st * params,
- gnutls_datum_t * der);
-
-
/*
* some x509 certificate functions that relate to MPI parameter
* setting. This writes the BIT STRING subjectPublicKey.
@@ -112,33 +106,23 @@ cleanup:
*
* Allocates the space used to store the DER data.
*/
-static int
+int
_gnutls_x509_write_ecc_pubkey (gnutls_pk_params_st * params,
gnutls_datum_t * der)
{
int result;
- ASN1_TYPE spk = ASN1_TYPE_EMPTY;
der->data = NULL;
der->size = 0;
if (params->params_nr < ECC_PUBLIC_PARAMS)
- {
- gnutls_assert ();
- result = GNUTLS_E_INVALID_REQUEST;
- goto cleanup;
- }
+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
result = _gnutls_ecc_ansi_x963_export(params->flags, params->params[5], params->params[6], /*&out*/der);
if (result < 0)
return gnutls_assert_val(result);
- result = 0;
-
-cleanup:
- asn1_delete_structure (&spk);
-
- return result;
+ return 0;
}
int
@@ -255,7 +239,7 @@ cleanup:
*
* Allocates the space used to store the DER data.
*/
-static int
+int
_gnutls_x509_write_ecc_params (gnutls_pk_params_st* params,
gnutls_datum_t * der)
{
diff --git a/lib/x509/privkey.c b/lib/x509/privkey.c
index 31762dae3d..9327bdf4bc 100644
--- a/lib/x509/privkey.c
+++ b/lib/x509/privkey.c
@@ -830,7 +830,7 @@ cleanup:
* @y: holds the y
* @k: holds the k
*
- * This function will convert the given DSA raw parameters to the
+ * This function will convert the given elliptic curve parameters to the
* native #gnutls_x509_privkey_t format. The output will be stored
* in @key.
*
diff --git a/lib/x509/x509.c b/lib/x509/x509.c
index 9d85384777..34310721bb 100644
--- a/lib/x509/x509.c
+++ b/lib/x509/x509.c
@@ -3217,12 +3217,7 @@ gnutls_x509_crt_list_import (gnutls_x509_crt_t * certs,
PEM_CERT_SEP2, sizeof (PEM_CERT_SEP2) - 1);
if (ptr == NULL)
- {
- gnutls_assert ();
- *cert_max = 0;
- /* no certificate found, likely empty file or garbage input */
- return 0;
- }
+ return gnutls_assert_val(GNUTLS_E_NO_CERTIFICATE_FOUND);
count = 0;
diff --git a/lib/x509/x509_int.h b/lib/x509/x509_int.h
index c5d466a699..6976b07624 100644
--- a/lib/x509/x509_int.h
+++ b/lib/x509/x509_int.h
@@ -189,6 +189,10 @@ ASN1_TYPE _gnutls_privkey_decode_pkcs1_rsa_key (const gnutls_datum_t *
ASN1_TYPE _gnutls_privkey_decode_ecc_key (const gnutls_datum_t *
raw_key,
gnutls_x509_privkey_t pkey);
+
+int
+_gnutls_x509_read_ecc_params (opaque * der, int dersize, gnutls_pk_params_st * params);
+
int _gnutls_asn1_encode_privkey (gnutls_pk_algorithm_t pk, ASN1_TYPE * c2, gnutls_pk_params_st * params);
/* extensions.c */
@@ -275,6 +279,11 @@ int _gnutls_x509_read_pubkey_params (gnutls_pk_algorithm_t, opaque * der, int de
int _gnutls_x509_read_pubkey (gnutls_pk_algorithm_t, opaque * der, int dersize,
gnutls_pk_params_st * params);
+int _gnutls_x509_write_ecc_params (gnutls_pk_params_st * params,
+ gnutls_datum_t * der);
+int _gnutls_x509_write_ecc_pubkey (gnutls_pk_params_st * params,
+ gnutls_datum_t * der);
+
int
_gnutls_x509_write_pubkey_params (gnutls_pk_algorithm_t algo,
gnutls_pk_params_st* params,
diff --git a/src/certtool-common.c b/src/certtool-common.c
index 1482d34b68..5ad9934ed3 100644
--- a/src/certtool-common.c
+++ b/src/certtool-common.c
@@ -607,3 +607,61 @@ int ret;
return pubkey;
}
+int
+get_bits (gnutls_pk_algorithm_t key_type, int info_bits, const char* info_sec_param)
+{
+ int bits;
+
+ if (info_bits != 0)
+ {
+ static int warned = 0;
+
+ if (warned == 0)
+ {
+ warned = 1;
+ fprintf (stderr,
+ "** Note: Please use the --sec-param instead of --bits\n");
+ }
+ bits = info_bits;
+ }
+ else
+ {
+ if (info_sec_param)
+ {
+ bits =
+ gnutls_sec_param_to_pk_bits (key_type,
+ str_to_sec_param (info_sec_param));
+ }
+ else
+ bits =
+ gnutls_sec_param_to_pk_bits (key_type, GNUTLS_SEC_PARAM_NORMAL);
+ }
+
+ return bits;
+}
+
+gnutls_sec_param_t str_to_sec_param (const char *str)
+{
+ if (strcasecmp (str, "low") == 0)
+ {
+ return GNUTLS_SEC_PARAM_LOW;
+ }
+ else if (strcasecmp (str, "normal") == 0)
+ {
+ return GNUTLS_SEC_PARAM_NORMAL;
+ }
+ else if (strcasecmp (str, "high") == 0)
+ {
+ return GNUTLS_SEC_PARAM_HIGH;
+ }
+ else if (strcasecmp (str, "ultra") == 0)
+ {
+ return GNUTLS_SEC_PARAM_ULTRA;
+ }
+ else
+ {
+ fprintf (stderr, "Unknown security parameter string: %s\n", str);
+ exit (1);
+ }
+
+}
diff --git a/src/certtool-common.h b/src/certtool-common.h
index e8ed9c7bac..a67ee698d5 100644
--- a/src/certtool-common.h
+++ b/src/certtool-common.h
@@ -54,6 +54,8 @@ typedef struct common_info
const char *request;
const char *ca;
const char *ca_privkey;
+ int bits;
+ const char* sec_param;
} common_info_st;
gnutls_pubkey_t load_public_key_or_import(int mand, gnutls_privkey_t privkey, common_info_st * info);
@@ -67,12 +69,11 @@ gnutls_datum_t *load_secret_key (int mand, common_info_st * info);
gnutls_pubkey_t load_pubkey (int mand, common_info_st * info);
gnutls_x509_crt_t *load_cert_list (int mand, size_t * size,
common_info_st * info);
-
-/* returns the bits specified in cmd */
-int get_bits (gnutls_pk_algorithm_t);
+int get_bits (gnutls_pk_algorithm_t key_type, int info_bits, const char* info_sec_param);
+gnutls_sec_param_t str_to_sec_param (const char *str);
/* prime.c */
-int generate_prime (int how);
+int generate_prime (int how, common_info_st * info);
FILE *safe_open_rw (const char *file, int privkey_op);
diff --git a/src/certtool-gaa.c b/src/certtool-gaa.c
index 67ba16bf4c..01aebc4c6e 100644
--- a/src/certtool-gaa.c
+++ b/src/certtool-gaa.c
@@ -1289,7 +1289,8 @@ int gaa(int argc, char **argv, gaainfo *gaaval)
gaaval->debug=1; gaaval->request = NULL; gaaval->infile = NULL; gaaval->outfile = NULL; gaaval->cert = NULL;
gaaval->incert_format = 0; gaaval->outcert_format = 0; gaaval->action=-1; gaaval->pass = NULL; gaaval->v1_cert = 0;
gaaval->export = 0; gaaval->template = NULL; gaaval->hash=NULL; gaaval->fix_key = 0; gaaval->quick_random=1;
- gaaval->privkey_op = 0; gaaval->pkcs_cipher = "aes-128"; gaaval->crq_extensions=1; gaaval->ecc=0; ;};
+ gaaval->privkey_op = 0; gaaval->pkcs_cipher = "aes-128"; gaaval->crq_extensions=1; gaaval->ecc=0;
+ gaaval->sec_param = NULL; ;};
}
inited = 1;
@@ -1437,7 +1438,7 @@ static int gaa_internal_get_next_str(FILE *file, gaa_str_node *tmp_str, int argc
len++;
a = fgetc( file);
- if(a==EOF) return 0; //a = ' ';
+ if(a==EOF) return 0;
}
len += 1;
diff --git a/src/certtool.c b/src/certtool.c
index acdc8d74ec..5362871f4a 100644
--- a/src/certtool.c
+++ b/src/certtool.c
@@ -188,67 +188,6 @@ print_rsa_pkey (gnutls_datum_t * m, gnutls_datum_t * e, gnutls_datum_t * d,
}
}
-static gnutls_sec_param_t
-str_to_sec_param (const char *str)
-{
- if (strcasecmp (str, "low") == 0)
- {
- return GNUTLS_SEC_PARAM_LOW;
- }
- else if (strcasecmp (str, "normal") == 0)
- {
- return GNUTLS_SEC_PARAM_NORMAL;
- }
- else if (strcasecmp (str, "high") == 0)
- {
- return GNUTLS_SEC_PARAM_HIGH;
- }
- else if (strcasecmp (str, "ultra") == 0)
- {
- return GNUTLS_SEC_PARAM_ULTRA;
- }
- else
- {
- fprintf (stderr, "Unknown security parameter string: %s\n", str);
- exit (1);
- }
-
-}
-
-int
-get_bits (gnutls_pk_algorithm_t key_type)
-{
- int bits;
-
- if (info.bits != 0)
- {
- static int warned = 0;
-
- if (warned == 0)
- {
- warned = 1;
- fprintf (stderr,
- "** Note: Please use the --sec-param instead of --bits\n");
- }
- bits = info.bits;
- }
- else
- {
- if (info.sec_param)
- {
- bits =
- gnutls_sec_param_to_pk_bits (key_type,
- str_to_sec_param (info.sec_param));
- }
- else
- bits =
- gnutls_sec_param_to_pk_bits (key_type, GNUTLS_SEC_PARAM_NORMAL);
- }
-
- return bits;
-}
-
-
static gnutls_x509_privkey_t
generate_private_key_int (void)
{
@@ -266,7 +205,7 @@ generate_private_key_int (void)
if (ret < 0)
error (EXIT_FAILURE, 0, "privkey_init: %s", gnutls_strerror (ret));
- bits = get_bits (key_type);
+ bits = get_bits (key_type, info.bits, info.sec_param);
fprintf (stderr, "Generating a %d bit %s private key...\n",
bits, gnutls_pk_algorithm_get_name (key_type));
@@ -1109,6 +1048,8 @@ gaa_parser (int argc, char **argv)
cinfo.request = info.request;
cinfo.ca = info.ca;
cinfo.ca_privkey = info.ca_privkey;
+ cinfo.bits = info.bits;
+ cinfo.sec_param = info.sec_param;
switch (info.action)
{
@@ -1152,10 +1093,10 @@ gaa_parser (int argc, char **argv)
pkcs12_info ();
break;
case ACTION_GENERATE_DH:
- generate_prime (1);
+ generate_prime (1, &cinfo);
break;
case ACTION_GET_DH:
- generate_prime (0);
+ generate_prime (0, &cinfo);
break;
case ACTION_CRL_INFO:
crl_info ();
diff --git a/src/certtool.gaa b/src/certtool.gaa
index 078a5e8d86..4834d60a24 100644
--- a/src/certtool.gaa
+++ b/src/certtool.gaa
@@ -153,4 +153,5 @@ init { $bits = 0; $pkcs8 = 0; $privkey = NULL; $ca=NULL; $ca_privkey = NULL;
$debug=1; $request = NULL; $infile = NULL; $outfile = NULL; $cert = NULL;
$incert_format = 0; $outcert_format = 0; $action=-1; $pass = NULL; $v1_cert = 0;
$export = 0; $template = NULL; $hash=NULL; $fix_key = 0; $quick_random=1;
- $privkey_op = 0; $pkcs_cipher = "aes-128"; $crq_extensions=1; $ecc=0; }
+ $privkey_op = 0; $pkcs_cipher = "aes-128"; $crq_extensions=1; $ecc=0;
+ $sec_param = NULL; }
diff --git a/src/p11common.c b/src/p11common.c
index 4c7df1e1b7..0a8cf85299 100644
--- a/src/p11common.c
+++ b/src/p11common.c
@@ -129,3 +129,4 @@ pkcs11_common (void)
gnutls_pkcs11_set_token_function (token_callback, NULL);
}
+
diff --git a/src/p11tool-gaa.c b/src/p11tool-gaa.c
index 18162402e8..8938e33d1b 100644
--- a/src/p11tool-gaa.c
+++ b/src/p11tool-gaa.c
@@ -145,6 +145,9 @@ void gaa_help(void)
__gaa_helpsingle(0, "initialize", "URL ", "Initializes a PKCS11 token.");
__gaa_helpsingle(0, "write", "URL ", "Writes loaded certificates, private or secret keys to a PKCS11 token.");
__gaa_helpsingle(0, "delete", "URL ", "Deletes objects matching the URL.");
+ __gaa_helpsingle(0, "generate-rsa", "URL ", "Generates an RSA private key on the specified token.");
+ __gaa_helpsingle(0, "generate-dsa", "URL ", "Generates a DSA private key on the specified token.");
+ __gaa_helpsingle(0, "generate-ecc", "URL ", "Generates an ECDSA private key on the specified token.");
__gaa_helpsingle(0, "label", "label ", "Sets a label for the write operation.");
__gaa_helpsingle(0, "trusted", "", "Marks the certificate to be written as trusted.");
__gaa_helpsingle(0, "private", "", "Marks the object to be written as private (requires PIN).");
@@ -157,6 +160,8 @@ void gaa_help(void)
__gaa_helpsingle(0, "load-pubkey", "FILE ", "Private key file to use.");
__gaa_helpsingle(0, "load-certificate", "FILE ", "Certificate file to use.");
__gaa_helpsingle('8', "pkcs8", "", "Use PKCS #8 format for private keys.");
+ __gaa_helpsingle(0, "bits", "BITS ", "specify the number of bits for key generation.");
+ __gaa_helpsingle(0, "sec-param", "PARAM ", "specify the security level [low|normal|high|ultra].");
__gaa_helpsingle(0, "inder", "", "Use DER format for input certificates and private keys.");
__gaa_helpsingle(0, "inraw", "", "Use RAW/DER format for input certificates and private keys.");
__gaa_helpsingle(0, "provider", "Library ", "Specify the pkcs11 provider library");
@@ -177,34 +182,40 @@ typedef struct _gaainfo gaainfo;
struct _gaainfo
{
-#line 84 "p11tool.gaa"
+#line 94 "p11tool.gaa"
int debug;
-#line 79 "p11tool.gaa"
+#line 89 "p11tool.gaa"
char *outfile;
-#line 76 "p11tool.gaa"
+#line 86 "p11tool.gaa"
int action;
-#line 75 "p11tool.gaa"
+#line 85 "p11tool.gaa"
char* pkcs11_provider;
-#line 71 "p11tool.gaa"
+#line 81 "p11tool.gaa"
int incert_format;
-#line 68 "p11tool.gaa"
+#line 78 "p11tool.gaa"
+ char* sec_param;
+#line 75 "p11tool.gaa"
+ int bits;
+#line 72 "p11tool.gaa"
int pkcs8;
-#line 65 "p11tool.gaa"
+#line 69 "p11tool.gaa"
char *cert;
-#line 62 "p11tool.gaa"
+#line 66 "p11tool.gaa"
char *pubkey;
-#line 59 "p11tool.gaa"
+#line 63 "p11tool.gaa"
char *privkey;
-#line 56 "p11tool.gaa"
+#line 60 "p11tool.gaa"
char* secret_key;
-#line 52 "p11tool.gaa"
+#line 56 "p11tool.gaa"
int pkcs11_detailed_url;
-#line 49 "p11tool.gaa"
+#line 53 "p11tool.gaa"
int pkcs11_login;
-#line 45 "p11tool.gaa"
+#line 49 "p11tool.gaa"
int pkcs11_private;
-#line 42 "p11tool.gaa"
+#line 46 "p11tool.gaa"
int pkcs11_trusted;
+#line 40 "p11tool.gaa"
+ int key_type;
#line 35 "p11tool.gaa"
char* pkcs11_label;
#line 24 "p11tool.gaa"
@@ -265,36 +276,41 @@ static int gaa_error = 0;
#define GAA_MULTIPLE_OPTION 3
#define GAA_REST 0
-#define GAA_NB_OPTION 29
+#define GAA_NB_OPTION 34
#define GAAOPTID_help 1
#define GAAOPTID_debug 2
#define GAAOPTID_outfile 3
#define GAAOPTID_provider 4
#define GAAOPTID_inraw 5
#define GAAOPTID_inder 6
-#define GAAOPTID_pkcs8 7
-#define GAAOPTID_load_certificate 8
-#define GAAOPTID_load_pubkey 9
-#define GAAOPTID_load_privkey 10
-#define GAAOPTID_secret_key 11
-#define GAAOPTID_no_detailed_url 12
-#define GAAOPTID_detailed_url 13
-#define GAAOPTID_login 14
-#define GAAOPTID_no_private 15
-#define GAAOPTID_private 16
-#define GAAOPTID_trusted 17
-#define GAAOPTID_label 18
-#define GAAOPTID_delete 19
-#define GAAOPTID_write 20
-#define GAAOPTID_initialize 21
-#define GAAOPTID_list_trusted 22
-#define GAAOPTID_list_privkeys 23
-#define GAAOPTID_list_certs 24
-#define GAAOPTID_list_all_certs 25
-#define GAAOPTID_list_all 26
-#define GAAOPTID_list_mechanisms 27
-#define GAAOPTID_list_tokens 28
-#define GAAOPTID_export 29
+#define GAAOPTID_sec_param 7
+#define GAAOPTID_bits 8
+#define GAAOPTID_pkcs8 9
+#define GAAOPTID_load_certificate 10
+#define GAAOPTID_load_pubkey 11
+#define GAAOPTID_load_privkey 12
+#define GAAOPTID_secret_key 13
+#define GAAOPTID_no_detailed_url 14
+#define GAAOPTID_detailed_url 15
+#define GAAOPTID_login 16
+#define GAAOPTID_no_private 17
+#define GAAOPTID_private 18
+#define GAAOPTID_trusted 19
+#define GAAOPTID_label 20
+#define GAAOPTID_generate_ecc 21
+#define GAAOPTID_generate_dsa 22
+#define GAAOPTID_generate_rsa 23
+#define GAAOPTID_delete 24
+#define GAAOPTID_write 25
+#define GAAOPTID_initialize 26
+#define GAAOPTID_list_trusted 27
+#define GAAOPTID_list_privkeys 28
+#define GAAOPTID_list_certs 29
+#define GAAOPTID_list_all_certs 30
+#define GAAOPTID_list_all 31
+#define GAAOPTID_list_mechanisms 32
+#define GAAOPTID_list_tokens 33
+#define GAAOPTID_export 34
#line 168 "gaa.skel"
@@ -499,6 +515,18 @@ struct GAAOPTION_provider
int size1;
};
+struct GAAOPTION_sec_param
+{
+ char* arg1;
+ int size1;
+};
+
+struct GAAOPTION_bits
+{
+ int arg1;
+ int size1;
+};
+
struct GAAOPTION_load_certificate
{
char* arg1;
@@ -529,6 +557,24 @@ struct GAAOPTION_label
int size1;
};
+struct GAAOPTION_generate_ecc
+{
+ char* arg1;
+ int size1;
+};
+
+struct GAAOPTION_generate_dsa
+{
+ char* arg1;
+ int size1;
+};
+
+struct GAAOPTION_generate_rsa
+{
+ char* arg1;
+ int size1;
+};
+
struct GAAOPTION_delete
{
char* arg1;
@@ -591,11 +637,16 @@ static int gaa_get_option_num(char *str, int status)
GAA_CHECK1STR("d", GAAOPTID_debug);
GAA_CHECK1STR("", GAAOPTID_outfile);
GAA_CHECK1STR("", GAAOPTID_provider);
+ GAA_CHECK1STR("", GAAOPTID_sec_param);
+ GAA_CHECK1STR("", GAAOPTID_bits);
GAA_CHECK1STR("", GAAOPTID_load_certificate);
GAA_CHECK1STR("", GAAOPTID_load_pubkey);
GAA_CHECK1STR("", GAAOPTID_load_privkey);
GAA_CHECK1STR("", GAAOPTID_secret_key);
GAA_CHECK1STR("", GAAOPTID_label);
+ GAA_CHECK1STR("", GAAOPTID_generate_ecc);
+ GAA_CHECK1STR("", GAAOPTID_generate_dsa);
+ GAA_CHECK1STR("", GAAOPTID_generate_rsa);
GAA_CHECK1STR("", GAAOPTID_delete);
GAA_CHECK1STR("", GAAOPTID_write);
GAA_CHECK1STR("", GAAOPTID_initialize);
@@ -629,6 +680,8 @@ static int gaa_get_option_num(char *str, int status)
GAA_CHECKSTR("provider", GAAOPTID_provider);
GAA_CHECKSTR("inraw", GAAOPTID_inraw);
GAA_CHECKSTR("inder", GAAOPTID_inder);
+ GAA_CHECKSTR("sec-param", GAAOPTID_sec_param);
+ GAA_CHECKSTR("bits", GAAOPTID_bits);
GAA_CHECKSTR("pkcs8", GAAOPTID_pkcs8);
GAA_CHECKSTR("load-certificate", GAAOPTID_load_certificate);
GAA_CHECKSTR("load-pubkey", GAAOPTID_load_pubkey);
@@ -641,6 +694,9 @@ static int gaa_get_option_num(char *str, int status)
GAA_CHECKSTR("private", GAAOPTID_private);
GAA_CHECKSTR("trusted", GAAOPTID_trusted);
GAA_CHECKSTR("label", GAAOPTID_label);
+ GAA_CHECKSTR("generate-ecc", GAAOPTID_generate_ecc);
+ GAA_CHECKSTR("generate-dsa", GAAOPTID_generate_dsa);
+ GAA_CHECKSTR("generate-rsa", GAAOPTID_generate_rsa);
GAA_CHECKSTR("delete", GAAOPTID_delete);
GAA_CHECKSTR("write", GAAOPTID_write);
GAA_CHECKSTR("initialize", GAAOPTID_initialize);
@@ -667,11 +723,16 @@ static int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list)
struct GAAOPTION_debug GAATMP_debug;
struct GAAOPTION_outfile GAATMP_outfile;
struct GAAOPTION_provider GAATMP_provider;
+ struct GAAOPTION_sec_param GAATMP_sec_param;
+ struct GAAOPTION_bits GAATMP_bits;
struct GAAOPTION_load_certificate GAATMP_load_certificate;
struct GAAOPTION_load_pubkey GAATMP_load_pubkey;
struct GAAOPTION_load_privkey GAATMP_load_privkey;
struct GAAOPTION_secret_key GAATMP_secret_key;
struct GAAOPTION_label GAATMP_label;
+ struct GAAOPTION_generate_ecc GAATMP_generate_ecc;
+ struct GAAOPTION_generate_dsa GAATMP_generate_dsa;
+ struct GAAOPTION_generate_rsa GAATMP_generate_rsa;
struct GAAOPTION_delete GAATMP_delete;
struct GAAOPTION_write GAATMP_write;
struct GAAOPTION_initialize GAATMP_initialize;
@@ -699,7 +760,7 @@ static int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list)
{
case GAAOPTID_help:
OK = 0;
-#line 87 "p11tool.gaa"
+#line 97 "p11tool.gaa"
{ gaa_help(); exit(0); ;};
return GAA_OK;
@@ -709,7 +770,7 @@ static int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list)
GAA_TESTMOREARGS;
GAA_FILL(GAATMP_debug.arg1, gaa_getint, GAATMP_debug.size1);
gaa_index++;
-#line 85 "p11tool.gaa"
+#line 95 "p11tool.gaa"
{ gaaval->debug = GAATMP_debug.arg1 ;};
return GAA_OK;
@@ -719,7 +780,7 @@ static int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list)
GAA_TESTMOREARGS;
GAA_FILL(GAATMP_outfile.arg1, gaa_getstr, GAATMP_outfile.size1);
gaa_index++;
-#line 80 "p11tool.gaa"
+#line 90 "p11tool.gaa"
{ gaaval->outfile = GAATMP_outfile.arg1 ;};
return GAA_OK;
@@ -729,28 +790,48 @@ static int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list)
GAA_TESTMOREARGS;
GAA_FILL(GAATMP_provider.arg1, gaa_getstr, GAATMP_provider.size1);
gaa_index++;
-#line 77 "p11tool.gaa"
+#line 87 "p11tool.gaa"
{ gaaval->pkcs11_provider = GAATMP_provider.arg1 ;};
return GAA_OK;
break;
case GAAOPTID_inraw:
OK = 0;
-#line 73 "p11tool.gaa"
+#line 83 "p11tool.gaa"
{ gaaval->incert_format=GNUTLS_X509_FMT_DER ;};
return GAA_OK;
break;
case GAAOPTID_inder:
OK = 0;
-#line 72 "p11tool.gaa"
+#line 82 "p11tool.gaa"
{ gaaval->incert_format=GNUTLS_X509_FMT_DER ;};
return GAA_OK;
break;
+ case GAAOPTID_sec_param:
+ OK = 0;
+ GAA_TESTMOREARGS;
+ GAA_FILL(GAATMP_sec_param.arg1, gaa_getstr, GAATMP_sec_param.size1);
+ gaa_index++;
+#line 79 "p11tool.gaa"
+{ gaaval->sec_param = GAATMP_sec_param.arg1 ;};
+
+ return GAA_OK;
+ break;
+ case GAAOPTID_bits:
+ OK = 0;
+ GAA_TESTMOREARGS;
+ GAA_FILL(GAATMP_bits.arg1, gaa_getint, GAATMP_bits.size1);
+ gaa_index++;
+#line 76 "p11tool.gaa"
+{ gaaval->bits = GAATMP_bits.arg1 ;};
+
+ return GAA_OK;
+ break;
case GAAOPTID_pkcs8:
OK = 0;
-#line 69 "p11tool.gaa"
+#line 73 "p11tool.gaa"
{ gaaval->pkcs8=1 ;};
return GAA_OK;
@@ -760,7 +841,7 @@ static int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list)
GAA_TESTMOREARGS;
GAA_FILL(GAATMP_load_certificate.arg1, gaa_getstr, GAATMP_load_certificate.size1);
gaa_index++;
-#line 66 "p11tool.gaa"
+#line 70 "p11tool.gaa"
{ gaaval->cert = GAATMP_load_certificate.arg1 ;};
return GAA_OK;
@@ -770,7 +851,7 @@ static int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list)
GAA_TESTMOREARGS;
GAA_FILL(GAATMP_load_pubkey.arg1, gaa_getstr, GAATMP_load_pubkey.size1);
gaa_index++;
-#line 63 "p11tool.gaa"
+#line 67 "p11tool.gaa"
{ gaaval->pubkey = GAATMP_load_pubkey.arg1 ;};
return GAA_OK;
@@ -780,7 +861,7 @@ static int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list)
GAA_TESTMOREARGS;
GAA_FILL(GAATMP_load_privkey.arg1, gaa_getstr, GAATMP_load_privkey.size1);
gaa_index++;
-#line 60 "p11tool.gaa"
+#line 64 "p11tool.gaa"
{ gaaval->privkey = GAATMP_load_privkey.arg1 ;};
return GAA_OK;
@@ -790,49 +871,49 @@ static int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list)
GAA_TESTMOREARGS;
GAA_FILL(GAATMP_secret_key.arg1, gaa_getstr, GAATMP_secret_key.size1);
gaa_index++;
-#line 57 "p11tool.gaa"
+#line 61 "p11tool.gaa"
{ gaaval->secret_key = GAATMP_secret_key.arg1; ;};
return GAA_OK;
break;
case GAAOPTID_no_detailed_url:
OK = 0;
-#line 54 "p11tool.gaa"
+#line 58 "p11tool.gaa"
{ gaaval->pkcs11_detailed_url = 0; ;};
return GAA_OK;
break;
case GAAOPTID_detailed_url:
OK = 0;
-#line 53 "p11tool.gaa"
+#line 57 "p11tool.gaa"
{ gaaval->pkcs11_detailed_url = GNUTLS_PKCS11_URL_LIB; ;};
return GAA_OK;
break;
case GAAOPTID_login:
OK = 0;
-#line 50 "p11tool.gaa"
+#line 54 "p11tool.gaa"
{ gaaval->pkcs11_login = 1; ;};
return GAA_OK;
break;
case GAAOPTID_no_private:
OK = 0;
-#line 47 "p11tool.gaa"
+#line 51 "p11tool.gaa"
{ gaaval->pkcs11_private = 0; ;};
return GAA_OK;
break;
case GAAOPTID_private:
OK = 0;
-#line 46 "p11tool.gaa"
+#line 50 "p11tool.gaa"
{ gaaval->pkcs11_private = 1; ;};
return GAA_OK;
break;
case GAAOPTID_trusted:
OK = 0;
-#line 43 "p11tool.gaa"
+#line 47 "p11tool.gaa"
{ gaaval->pkcs11_trusted = 1; ;};
return GAA_OK;
@@ -842,11 +923,41 @@ static int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list)
GAA_TESTMOREARGS;
GAA_FILL(GAATMP_label.arg1, gaa_getstr, GAATMP_label.size1);
gaa_index++;
-#line 41 "p11tool.gaa"
+#line 45 "p11tool.gaa"
{ gaaval->pkcs11_label = GAATMP_label.arg1; ;};
return GAA_OK;
break;
+ case GAAOPTID_generate_ecc:
+ OK = 0;
+ GAA_TESTMOREARGS;
+ GAA_FILL(GAATMP_generate_ecc.arg1, gaa_getstr, GAATMP_generate_ecc.size1);
+ gaa_index++;
+#line 43 "p11tool.gaa"
+{ gaaval->action = ACTION_PKCS11_GENERATE; gaaval->key_type = GNUTLS_PK_ECC; gaaval->pkcs11_url = GAATMP_generate_ecc.arg1; ;};
+
+ return GAA_OK;
+ break;
+ case GAAOPTID_generate_dsa:
+ OK = 0;
+ GAA_TESTMOREARGS;
+ GAA_FILL(GAATMP_generate_dsa.arg1, gaa_getstr, GAATMP_generate_dsa.size1);
+ gaa_index++;
+#line 42 "p11tool.gaa"
+{ gaaval->action = ACTION_PKCS11_GENERATE; gaaval->key_type = GNUTLS_PK_DSA; gaaval->pkcs11_url = GAATMP_generate_dsa.arg1; ;};
+
+ return GAA_OK;
+ break;
+ case GAAOPTID_generate_rsa:
+ OK = 0;
+ GAA_TESTMOREARGS;
+ GAA_FILL(GAATMP_generate_rsa.arg1, gaa_getstr, GAATMP_generate_rsa.size1);
+ gaa_index++;
+#line 41 "p11tool.gaa"
+{ gaaval->action = ACTION_PKCS11_GENERATE; gaaval->key_type = GNUTLS_PK_RSA; gaaval->pkcs11_url = GAATMP_generate_rsa.arg1; ;};
+
+ return GAA_OK;
+ break;
case GAAOPTID_delete:
OK = 0;
GAA_TESTMOREARGS;
@@ -963,12 +1074,13 @@ int gaa(int argc, char **argv, gaainfo *gaaval)
if(inited == 0)
{
-#line 89 "p11tool.gaa"
+#line 99 "p11tool.gaa"
{
gaaval->action = -1; gaaval->pkcs11_provider= NULL; gaaval->outfile = NULL; gaaval->pubkey = NULL; gaaval->privkey = NULL;
gaaval->pkcs11_url = NULL; gaaval->pkcs11_type = PKCS11_TYPE_PK; gaaval->pubkey=NULL; gaaval->pkcs11_label = NULL;
- gaaval->pkcs11_trusted=0; gaaval->pkcs11_login = 0; gaaval->pkcs11_detailed_url = GNUTLS_PKCS11_URL_LIB;
- gaaval->secret_key = NULL; gaaval->cert = NULL; gaaval->incert_format = GNUTLS_X509_FMT_PEM; gaaval->pkcs11_private = -1; ;};
+ gaaval->pkcs11_trusted=0; gaaval->pkcs11_login = 0; gaaval->pkcs11_detailed_url = 0;
+ gaaval->secret_key = NULL; gaaval->cert = NULL; gaaval->incert_format = GNUTLS_X509_FMT_PEM; gaaval->pkcs11_private = -1;
+ gaaval->key_type = 0; gaaval->bits = 0; gaaval->sec_param = NULL; ;};
}
inited = 1;
@@ -1116,7 +1228,7 @@ static int gaa_internal_get_next_str(FILE *file, gaa_str_node *tmp_str, int argc
len++;
a = fgetc( file);
- if(a==EOF) return 0; //a = ' ';
+ if(a==EOF) return 0;
}
len += 1;
diff --git a/src/p11tool-gaa.h b/src/p11tool-gaa.h
index bc5871f5e6..7fec01a0ae 100644
--- a/src/p11tool-gaa.h
+++ b/src/p11tool-gaa.h
@@ -8,34 +8,40 @@ typedef struct _gaainfo gaainfo;
struct _gaainfo
{
-#line 84 "p11tool.gaa"
+#line 94 "p11tool.gaa"
int debug;
-#line 79 "p11tool.gaa"
+#line 89 "p11tool.gaa"
char *outfile;
-#line 76 "p11tool.gaa"
+#line 86 "p11tool.gaa"
int action;
-#line 75 "p11tool.gaa"
+#line 85 "p11tool.gaa"
char* pkcs11_provider;
-#line 71 "p11tool.gaa"
+#line 81 "p11tool.gaa"
int incert_format;
-#line 68 "p11tool.gaa"
+#line 78 "p11tool.gaa"
+ char* sec_param;
+#line 75 "p11tool.gaa"
+ int bits;
+#line 72 "p11tool.gaa"
int pkcs8;
-#line 65 "p11tool.gaa"
+#line 69 "p11tool.gaa"
char *cert;
-#line 62 "p11tool.gaa"
+#line 66 "p11tool.gaa"
char *pubkey;
-#line 59 "p11tool.gaa"
+#line 63 "p11tool.gaa"
char *privkey;
-#line 56 "p11tool.gaa"
+#line 60 "p11tool.gaa"
char* secret_key;
-#line 52 "p11tool.gaa"
+#line 56 "p11tool.gaa"
int pkcs11_detailed_url;
-#line 49 "p11tool.gaa"
+#line 53 "p11tool.gaa"
int pkcs11_login;
-#line 45 "p11tool.gaa"
+#line 49 "p11tool.gaa"
int pkcs11_private;
-#line 42 "p11tool.gaa"
+#line 46 "p11tool.gaa"
int pkcs11_trusted;
+#line 40 "p11tool.gaa"
+ int key_type;
#line 35 "p11tool.gaa"
char* pkcs11_label;
#line 24 "p11tool.gaa"
diff --git a/src/p11tool.c b/src/p11tool.c
index ebaa6fd4b0..2df036b55c 100644
--- a/src/p11tool.c
+++ b/src/p11tool.c
@@ -155,6 +155,11 @@ gaa_parser (int argc, char **argv)
case ACTION_PKCS11_DELETE_URL:
pkcs11_delete (outfile, info.pkcs11_url, 0, info.pkcs11_login, &cinfo);
break;
+ case ACTION_PKCS11_GENERATE:
+ pkcs11_generate (outfile, info.pkcs11_url, info.key_type, get_bits(info.key_type, info.bits, info.sec_param),
+ info.pkcs11_label, info.pkcs11_private, info.pkcs11_detailed_url, info.pkcs11_login,
+ &cinfo);
+ break;
default:
gaa_help ();
exit (0);
diff --git a/src/p11tool.gaa b/src/p11tool.gaa
index 9c2e4ae174..3c3cdfc411 100644
--- a/src/p11tool.gaa
+++ b/src/p11tool.gaa
@@ -37,6 +37,10 @@ option (initialize) STR "URL" { $action = ACTION_PKCS11_TOKEN_INIT; $pkcs11_url
option (write) STR "URL" { $action = ACTION_PKCS11_WRITE_URL; $pkcs11_url = $1; } "Writes loaded certificates, private or secret keys to a PKCS11 token."
option (delete) STR "URL" { $action = ACTION_PKCS11_DELETE_URL; $pkcs11_url = $1; } "Deletes objects matching the URL."
+#int key_type;
+option (generate-rsa) STR "URL" { $action = ACTION_PKCS11_GENERATE; $key_type = GNUTLS_PK_RSA; $pkcs11_url = $1; } "Generates an RSA private key on the specified token."
+option (generate-dsa) STR "URL" { $action = ACTION_PKCS11_GENERATE; $key_type = GNUTLS_PK_DSA; $pkcs11_url = $1; } "Generates a DSA private key on the specified token."
+option (generate-ecc) STR "URL" { $action = ACTION_PKCS11_GENERATE; $key_type = GNUTLS_PK_ECC; $pkcs11_url = $1; } "Generates an ECDSA private key on the specified token."
option (label) STR "label" { $pkcs11_label = $1; } "Sets a label for the write operation."
#int pkcs11_trusted;
@@ -68,6 +72,12 @@ option (load-certificate) STR "FILE" { $cert = $1 } "Certificate file to use."
#int pkcs8;
option (8, pkcs8) { $pkcs8=1 } "Use PKCS #8 format for private keys."
+#int bits;
+option (bits) INT "BITS" { $bits = $1 } "specify the number of bits for key generation."
+
+#char* sec_param;
+option (sec-param) STR "PARAM" { $sec_param = $1 } "specify the security level [low|normal|high|ultra]."
+
#int incert_format;
option (inder) { $incert_format=GNUTLS_X509_FMT_DER } "Use DER format for input certificates and private keys."
option (inraw) { $incert_format=GNUTLS_X509_FMT_DER } "Use RAW/DER format for input certificates and private keys."
@@ -89,5 +99,6 @@ option (h, help) { gaa_help(); exit(0); } "shows this help text"
init {
$action = -1; $pkcs11_provider= NULL; $outfile = NULL; $pubkey = NULL; $privkey = NULL;
$pkcs11_url = NULL; $pkcs11_type = PKCS11_TYPE_PK; $pubkey=NULL; $pkcs11_label = NULL;
- $pkcs11_trusted=0; $pkcs11_login = 0; $pkcs11_detailed_url = GNUTLS_PKCS11_URL_LIB;
- $secret_key = NULL; $cert = NULL; $incert_format = GNUTLS_X509_FMT_PEM; $pkcs11_private = -1; }
+ $pkcs11_trusted=0; $pkcs11_login = 0; $pkcs11_detailed_url = 0;
+ $secret_key = NULL; $cert = NULL; $incert_format = GNUTLS_X509_FMT_PEM; $pkcs11_private = -1;
+ $key_type = 0; $bits = 0; $sec_param = NULL; }
diff --git a/src/p11tool.h b/src/p11tool.h
index 3682fb15ad..7506751adc 100644
--- a/src/p11tool.h
+++ b/src/p11tool.h
@@ -18,6 +18,11 @@ void pkcs11_delete (FILE * outfile, const char *pkcs11_url, int batch,
unsigned int login, common_info_st *);
void pkcs11_init (FILE * outfile, const char *pkcs11_url, const char *label,
common_info_st *);
+void
+pkcs11_generate (FILE * outfile, const char *url, gnutls_pk_algorithm_t type,
+ unsigned int bits,
+ const char *label, int private, int detailed,
+ unsigned int login, common_info_st * info);
#define PKCS11_TYPE_CRT_ALL 1
#define PKCS11_TYPE_TRUSTED 2
@@ -35,6 +40,7 @@ enum
ACTION_PKCS11_DELETE_URL,
ACTION_PKCS11_TOKEN_INIT,
ACTION_PKCS11_MECHANISMS,
+ ACTION_PKCS11_GENERATE,
};
#endif
diff --git a/src/pkcs11.c b/src/pkcs11.c
index 8a7420440b..251f79fed2 100644
--- a/src/pkcs11.c
+++ b/src/pkcs11.c
@@ -546,6 +546,39 @@ pkcs11_write (FILE * outfile, const char *url, const char *label,
}
void
+pkcs11_generate (FILE * outfile, const char *url, gnutls_pk_algorithm_t pk,
+ unsigned int bits,
+ const char *label, int private, int detailed,
+ unsigned int login, common_info_st * info)
+{
+ int ret;
+ unsigned int flags = 0;
+
+ if (login)
+ flags = GNUTLS_PKCS11_OBJ_FLAG_LOGIN;
+
+ pkcs11_common ();
+
+ if (url == NULL)
+ url = "pkcs11:";
+
+ if (private == 1)
+ flags |= GNUTLS_PKCS11_OBJ_FLAG_MARK_PRIVATE;
+ else if (private == 0)
+ flags |= GNUTLS_PKCS11_OBJ_FLAG_MARK_NOT_PRIVATE;
+
+ ret = gnutls_pkcs11_privkey_generate(url, pk, bits, label, flags);
+ if (ret < 0)
+ {
+ fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
+ gnutls_strerror (ret));
+ exit(1);
+ }
+
+ return;
+}
+
+void
pkcs11_init (FILE * outfile, const char *url, const char *label,
common_info_st * info)
{
@@ -783,6 +816,13 @@ const char *mech_list[] = {
[0x2000] = "CKM_DSA_PARAMETER_GEN",
[0x2001] = "CKM_DH_PKCS_PARAMETER_GEN",
[0x2002] = "CKM_X9_42_DH_PARAMETER_GEN",
+ [0x1200] = "CKM_GOSTR3410_KEY_PAIR_GEN",
+ [0x1201] = "CKM_GOSTR3410",
+ [0x1202] = "CKM_GOSTR3410_WITH_GOSTR3411",
+ [0x1203] = "CKM_GOSTR3410_KEY_WRAP",
+ [0x1204] = "CKM_GOSTR3410_DERIVE",
+ [0x1210] = "CKM_GOSTR3411",
+ [0x1211] = "CKM_GOSTR3411_HMAC",
[0x255] = "CKM_SHA224",
[0x256] = "CKM_SHA224_HMAC",
[0x257] = "CKM_SHA224_HMAC_GENERAL",
diff --git a/src/prime.c b/src/prime.c
index 4c4efd3440..d3241e143d 100644
--- a/src/prime.c
+++ b/src/prime.c
@@ -37,22 +37,28 @@
extern FILE *outfile;
extern FILE *infile;
-static int cparams = 0;
+const static int cparams = 0;
/* If how is zero then the included parameters are used.
*/
int
-generate_prime (int how)
+generate_prime (int how, common_info_st * info)
{
unsigned int i;
int ret;
gnutls_dh_params_t dh_params;
gnutls_datum_t p, g;
- int bits = get_bits (GNUTLS_PK_DH);
+ int bits = get_bits (GNUTLS_PK_DH, info->bits, info->sec_param);
gnutls_dh_params_init (&dh_params);
- fprintf (stderr, "Generating DH parameters...");
+ if (how != 0)
+ {
+ fprintf (stderr, "Generating DH parameters (%d bits)...\n", bits);
+ fprintf (stderr, "(might take long time)\n");
+ }
+ else
+ fprintf (stderr, "Retrieving DH parameters...\n", bits);
if (how != 0)
{
@@ -79,16 +85,19 @@ generate_prime (int how)
{
p = gnutls_srp_1024_group_prime;
g = gnutls_srp_1024_group_generator;
+ bits = 1024;
}
else if (bits <= 1536)
{
p = gnutls_srp_1536_group_prime;
g = gnutls_srp_1536_group_generator;
+ bits = 1536;
}
else
{
p = gnutls_srp_2048_group_prime;
g = gnutls_srp_2048_group_generator;
+ bits = 2048;
}
ret = gnutls_dh_params_import_raw (dh_params, &p, &g);
@@ -99,7 +108,8 @@ generate_prime (int how)
exit (1);
}
#else
- fprintf (stderr, "Parameters unavailable as SRP disabled.\n");
+ fprintf (stderr, "Parameters unavailable as SRP is disabled.\n");
+ exit(1);
#endif
}
@@ -157,11 +167,11 @@ generate_prime (int how)
}
else
{
- fprintf (outfile, "Prime: ");
+ fprintf (outfile, "Prime (%d bits):", bits);
for (i = 0; i < p.size; i++)
{
- if (i != 0 && i % 12 == 0)
+ if (i % 12 == 0)
fprintf (outfile, "\n\t");
else if (i != 0 && i != p.size)
fprintf (outfile, ":");