From: Nikos Mavrogiannopoulos Date: Tue, 6 Sep 2011 09:59:11 +0000 (+0200) Subject: Added support to read elliptic curve public keys from PKCS #11 tokens (untested). X-Git-Tag: gnutls_3_0_3~51 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2a693e1d3d7a7c6e4a14ecea664d0cc86f12216b;p=thirdparty%2Fgnutls.git Added support to read elliptic curve public keys from PKCS #11 tokens (untested). --- diff --git a/NEWS b/NEWS index 1f155c49ae..406abafb1f 100644 --- a/NEWS +++ b/NEWS @@ -8,6 +8,9 @@ See the end for copying conditions. Reported by Jonathan Nieder in . +** libgnutls: Added support for elliptic curves in +PKCS #11. + ** libgnutls: Added gnutls_pkcs11_privkey_generate() to allow generating a key in a token. @@ -16,6 +19,9 @@ 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) 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 #include #include +#include #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; @@ -752,6 +757,42 @@ gnutls_pubkey_get_pk_ecc_raw (gnutls_pubkey_t key, gnutls_ecc_curve_t *curve, return 0; } +/** + * 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. @@ -1059,6 +1100,119 @@ gnutls_pubkey_import_rsa_raw (gnutls_pubkey_t key, return 0; } +/** + * 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 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/libgnutls.map b/lib/libgnutls.map index f2d57aa83b..97ff01cc50 100644 --- a/lib/libgnutls.map +++ b/lib/libgnutls.map @@ -714,6 +714,8 @@ GNUTLS_3_0_0 { 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 e08d6937ae..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 */ diff --git a/lib/pkcs11_int.h b/lib/pkcs11_int.h index 2a8fc8bf80..2480da7769 100644 --- a/lib/pkcs11_int.h +++ b/lib/pkcs11_int.h @@ -106,6 +106,17 @@ static inline int pk_to_mech(gnutls_pk_algorithm_t pk) 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) diff --git a/lib/pkcs11_privkey.c b/lib/pkcs11_privkey.c index 193fddf460..ffc5ac6ed3 100644 --- a/lib/pkcs11_privkey.c +++ b/lib/pkcs11_privkey.c @@ -271,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; diff --git a/lib/pkcs11_write.c b/lib/pkcs11_write.c index 834194da7a..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) @@ -425,6 +436,36 @@ gnutls_pkcs11_copy_x509_privkey (const char *token_url, a[a_val].value_len = x.size; a_val++; + 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: @@ -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); 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_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.h b/src/certtool-common.h index add8a69bbb..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); @@ -71,7 +73,7 @@ int get_bits (gnutls_pk_algorithm_t key_type, int info_bits, const char* info_se 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.c b/src/certtool.c index e8fc37d05e..5362871f4a 100644 --- a/src/certtool.c +++ b/src/certtool.c @@ -1048,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) { @@ -1091,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/pkcs11.c b/src/pkcs11.c index b0693da214..251f79fed2 100644 --- a/src/pkcs11.c +++ b/src/pkcs11.c @@ -816,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, ":");