summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS12
-rw-r--r--lib/includes/gnutls/pkcs11.h5
-rw-r--r--lib/libgnutls.map1
-rw-r--r--lib/pkcs11.c15
-rw-r--r--lib/pkcs11_int.h31
-rw-r--r--lib/pkcs11_privkey.c203
-rw-r--r--lib/pkcs11_write.c1
-rw-r--r--src/certtool-common.c58
-rw-r--r--src/certtool-common.h5
-rw-r--r--src/certtool-gaa.c5
-rw-r--r--src/certtool.c63
-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.c33
19 files changed, 580 insertions, 148 deletions
diff --git a/NEWS b/NEWS
index 419bb8566e..1f155c49ae 100644
--- a/NEWS
+++ b/NEWS
@@ -2,10 +2,22 @@ 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 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
+
+
* Version 3.0.2 (released 2011-09-01)
** libgnutls: OpenPGP certificate type is not enabled
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..f2d57aa83b 100644
--- a/lib/libgnutls.map
+++ b/lib/libgnutls.map
@@ -713,6 +713,7 @@ 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_2_12;
GNUTLS_PRIVATE {
diff --git a/lib/pkcs11.c b/lib/pkcs11.c
index 91db86c7d7..e08d6937ae 100644
--- a/lib/pkcs11.c
+++ b/lib/pkcs11.c
@@ -2849,6 +2849,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..2a8fc8bf80 100644
--- a/lib/pkcs11_int.h
+++ b/lib/pkcs11_int.h
@@ -96,6 +96,37 @@ _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 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..193fddf460 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;
@@ -324,8 +323,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 +400,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..834194da7a 100644
--- a/lib/pkcs11_write.c
+++ b/lib/pkcs11_write.c
@@ -786,3 +786,4 @@ finish:
return ret;
}
+
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..add8a69bbb 100644
--- a/src/certtool-common.h
+++ b/src/certtool-common.h
@@ -67,9 +67,8 @@ 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);
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..e8fc37d05e 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));
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..b0693da214 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)
{