diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2011-09-06 13:25:00 +0200 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2011-09-06 13:25:00 +0200 |
commit | 0f4a6959907369eb7f4c067a6dc50d37d1f91cc7 (patch) | |
tree | 4b59a9b3f2d1470266e5edf7ee594cd724f07076 | |
parent | ceb4f32c9417ab44a2df831c306d7329eb5a1fce (diff) | |
parent | b40785d940c460680347a886aabe6adace6b0861 (diff) | |
download | gnutls-0f4a6959907369eb7f4c067a6dc50d37d1f91cc7.tar.gz |
Merge branch 'master' into gnutls_3_0_x
Conflicts:
NEWS
lib/x509/x509.c
-rw-r--r-- | NEWS | 18 | ||||
-rw-r--r-- | lib/gnutls_pubkey.c | 154 | ||||
-rw-r--r-- | lib/gnutls_x509.c | 3 | ||||
-rw-r--r-- | lib/includes/gnutls/abstract.h | 13 | ||||
-rw-r--r-- | lib/includes/gnutls/pkcs11.h | 5 | ||||
-rw-r--r-- | lib/libgnutls.map | 3 | ||||
-rw-r--r-- | lib/pkcs11.c | 133 | ||||
-rw-r--r-- | lib/pkcs11_int.h | 42 | ||||
-rw-r--r-- | lib/pkcs11_privkey.c | 213 | ||||
-rw-r--r-- | lib/pkcs11_write.c | 55 | ||||
-rw-r--r-- | lib/x509/key_decode.c | 5 | ||||
-rw-r--r-- | lib/x509/key_encode.c | 24 | ||||
-rw-r--r-- | lib/x509/privkey.c | 2 | ||||
-rw-r--r-- | lib/x509/x509.c | 7 | ||||
-rw-r--r-- | lib/x509/x509_int.h | 9 | ||||
-rw-r--r-- | src/certtool-common.c | 58 | ||||
-rw-r--r-- | src/certtool-common.h | 9 | ||||
-rw-r--r-- | src/certtool-gaa.c | 5 | ||||
-rw-r--r-- | src/certtool.c | 69 | ||||
-rw-r--r-- | src/certtool.gaa | 3 | ||||
-rw-r--r-- | src/p11common.c | 1 | ||||
-rw-r--r-- | src/p11tool-gaa.c | 232 | ||||
-rw-r--r-- | src/p11tool-gaa.h | 34 | ||||
-rw-r--r-- | src/p11tool.c | 5 | ||||
-rw-r--r-- | src/p11tool.gaa | 15 | ||||
-rw-r--r-- | src/p11tool.h | 6 | ||||
-rw-r--r-- | src/pkcs11.c | 40 | ||||
-rw-r--r-- | src/prime.c | 24 |
28 files changed, 949 insertions, 238 deletions
@@ -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, ":"); |