diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2011-05-22 11:55:33 +0200 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2011-05-22 13:37:59 +0200 |
commit | f099342688710138ba8cd94e47846bda5c331faf (patch) | |
tree | 5782228c5fa01060673e3273c583e22b70b25202 | |
parent | 8dcf7e8299fed143c2e61500da55b5e5910eb54c (diff) | |
download | gnutls-f099342688710138ba8cd94e47846bda5c331faf.tar.gz |
gnutls_pk_params_st is used internally to transfer public key parameters. This replaces the raw bigint_t arrays.
46 files changed, 2215 insertions, 1931 deletions
diff --git a/lib/abstract_int.h b/lib/abstract_int.h index 45440fef38..1060679797 100644 --- a/lib/abstract_int.h +++ b/lib/abstract_int.h @@ -4,13 +4,14 @@ #include <gnutls/abstract.h> int _gnutls_privkey_get_public_mpis (gnutls_privkey_t key, - bigint_t * params, int *params_size); + gnutls_pk_params_st*); +int pubkey_to_bits(gnutls_pk_algorithm_t pk, gnutls_pk_params_st* params); int _gnutls_pubkey_compatible_with_sig(gnutls_pubkey_t pubkey, gnutls_protocol_t ver, gnutls_sign_algorithm_t sign); int _gnutls_pubkey_is_over_rsa_512(gnutls_pubkey_t pubkey); int _gnutls_pubkey_get_mpis (gnutls_pubkey_t key, - bigint_t * params, int *params_size); + gnutls_pk_params_st * params); #endif diff --git a/lib/algorithms.h b/lib/algorithms.h index 5d7d7fa248..205a2c19ab 100644 --- a/lib/algorithms.h +++ b/lib/algorithms.h @@ -129,7 +129,8 @@ unsigned int _gnutls_pk_bits_to_subgroup_bits (unsigned int pk_bits); struct gnutls_ecc_curve_entry_st { const char *name; - ecc_curve_t id; + const char* oid; + gnutls_ecc_curve_t id; int tls_id; /* The RFC4492 namedCurve ID */ int size; /* the size in bytes */ @@ -148,11 +149,13 @@ struct gnutls_ecc_curve_entry_st }; typedef struct gnutls_ecc_curve_entry_st gnutls_ecc_curve_entry_st; -const char * _gnutls_ecc_curve_get_name (ecc_curve_t curve); -const gnutls_ecc_curve_entry_st * _gnutls_ecc_curve_get_params (ecc_curve_t curve); -int _gnutls_ecc_curve_get_size (ecc_curve_t curve); -ecc_curve_t _gnutls_ecc_curve_get_id (const char *name); +const gnutls_ecc_curve_entry_st * _gnutls_ecc_curve_get_params (gnutls_ecc_curve_t curve); +gnutls_ecc_curve_t _gnutls_ecc_curve_get_id (const char *name); int _gnutls_tls_id_to_ecc_curve (int num); -int _gnutls_ecc_curve_get_tls_id (ecc_curve_t supported_ecc); +int _gnutls_ecc_curve_get_tls_id (gnutls_ecc_curve_t supported_ecc); +const char * _gnutls_ecc_curve_get_oid (gnutls_ecc_curve_t curve); +gnutls_ecc_curve_t _gnutls_oid_to_ecc_curve (const char* oid); + +#define MAX_ECC_CURVE_SIZE 66 #endif diff --git a/lib/algorithms/ecc.c b/lib/algorithms/ecc.c index 4bd2a130ba..2ba286982e 100644 --- a/lib/algorithms/ecc.c +++ b/lib/algorithms/ecc.c @@ -34,6 +34,7 @@ static const gnutls_ecc_curve_entry_st ecc_curves[] = { { .name = "SECP224R1", + .oid = "1.3.132.0.33", .id = GNUTLS_ECC_CURVE_SECP224R1, .tls_id = 21, .size = 28, @@ -46,6 +47,7 @@ static const gnutls_ecc_curve_entry_st ecc_curves[] = { }, { .name = "SECP256R1", + .oid = "1.2.840.10045.3.1.7", .id = GNUTLS_ECC_CURVE_SECP256R1, .tls_id = 23, .size = 32, @@ -58,6 +60,7 @@ static const gnutls_ecc_curve_entry_st ecc_curves[] = { }, { .name = "SECP384R1", + .oid = "1.3.132.0.34", .id = GNUTLS_ECC_CURVE_SECP384R1, .tls_id = 24, .size = 48, @@ -70,6 +73,7 @@ static const gnutls_ecc_curve_entry_st ecc_curves[] = { }, { .name = "SECP521R1", + .oid = "1.3.132.0.35", .id = GNUTLS_ECC_CURVE_SECP521R1, .tls_id = 25, .size = 66, @@ -93,7 +97,7 @@ static const gnutls_ecc_curve_entry_st ecc_curves[] = { int _gnutls_tls_id_to_ecc_curve (int num) { - ecc_curve_t ret = GNUTLS_ECC_CURVE_INVALID; + gnutls_ecc_curve_t ret = GNUTLS_ECC_CURVE_INVALID; GNUTLS_ECC_CURVE_LOOP ( if (p->tls_id == num) @@ -110,7 +114,7 @@ _gnutls_tls_id_to_ecc_curve (int num) * Returns a negative number on error. */ int -_gnutls_ecc_curve_get_tls_id (ecc_curve_t supported_ecc) +_gnutls_ecc_curve_get_tls_id (gnutls_ecc_curve_t supported_ecc) { int ret = GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER; @@ -125,6 +129,27 @@ _gnutls_ecc_curve_get_tls_id (ecc_curve_t supported_ecc) return ret; } +/*- + * _gnutls_oid_to_ecc_curve: + * @oid: is a curve's OID + * + * Returns: return a #gnutls_ecc_curve_t value corresponding to + * the specified OID, or %GNUTLS_ECC_CURVE_INVALID on error. + -*/ +gnutls_ecc_curve_t _gnutls_oid_to_ecc_curve (const char* oid) +{ + gnutls_ecc_curve_t ret = GNUTLS_ECC_CURVE_INVALID; + + GNUTLS_ECC_CURVE_LOOP ( + if (strcasecmp (p->oid, oid) == 0) + { + ret = p->id; + break; + } + ); + + return ret; +} /*- * _gnutls_ecc_curve_get_id: @@ -132,13 +157,13 @@ _gnutls_ecc_curve_get_tls_id (ecc_curve_t supported_ecc) * * The names are compared in a case insensitive way. * - * Returns: return a #ecc_curve_t value corresponding to - * the specified cipher, or %GNUTLS_ECC_CURVE_INVALID on error. + * Returns: return a #gnutls_ecc_curve_t value corresponding to + * the specified curve, or %GNUTLS_ECC_CURVE_INVALID on error. -*/ -ecc_curve_t +gnutls_ecc_curve_t _gnutls_ecc_curve_get_id (const char *name) { - ecc_curve_t ret = GNUTLS_ECC_CURVE_INVALID; + gnutls_ecc_curve_t ret = GNUTLS_ECC_CURVE_INVALID; GNUTLS_ECC_CURVE_LOOP ( if (strcasecmp (p->name, name) == 0) @@ -151,24 +176,49 @@ _gnutls_ecc_curve_get_id (const char *name) return ret; } +/** + * gnutls_ecc_curve_get_name: + * @curve: is an ECC curve + * + * Convert a #gnutls_ecc_curve_t value to a string. + * + * Returns: a string that contains the name of the specified + * curve or %NULL. + **/ +const char * +gnutls_ecc_curve_get_name (gnutls_ecc_curve_t curve) +{ + const char *ret = NULL; + + GNUTLS_ECC_CURVE_LOOP( + if (p->id == curve) + { + ret = p->name; + break; + } + ); + + return ret; +} + /*- - * _gnutls_ecc_curve_get_name: + * _gnutls_ecc_curve_get_oid: * @curve: is an ECC curve * - * Convert a #ecc_curve_t value to a string. + * Convert a #gnutls_ecc_curve_t value to a string. * * Returns: a string that contains the name of the specified * curve or %NULL. -*/ const char * -_gnutls_ecc_curve_get_name (ecc_curve_t curve) +_gnutls_ecc_curve_get_oid (gnutls_ecc_curve_t curve) { const char *ret = NULL; GNUTLS_ECC_CURVE_LOOP( if (p->id == curve) { - ret = p->name; + ret = p->oid; break; } ); @@ -185,7 +235,7 @@ _gnutls_ecc_curve_get_name (ecc_curve_t curve) * Returns: a pointer to #gnutls_ecc_curve_entry_st or %NULL. -*/ const gnutls_ecc_curve_entry_st * -_gnutls_ecc_curve_get_params (ecc_curve_t curve) +_gnutls_ecc_curve_get_params (gnutls_ecc_curve_t curve) { const gnutls_ecc_curve_entry_st *ret = NULL; @@ -200,15 +250,15 @@ _gnutls_ecc_curve_get_params (ecc_curve_t curve) return ret; } -/*- - * _gnutls_ecc_curve_get_size: +/** + * gnutls_ecc_curve_get_size: * @curve: is an ECC curve * * Returns the size in bytes of the curve. * * Returns: a the size or zero. - -*/ -int _gnutls_ecc_curve_get_size (ecc_curve_t curve) + **/ +int gnutls_ecc_curve_get_size (gnutls_ecc_curve_t curve) { int ret = 0; diff --git a/lib/auth/anon.h b/lib/auth/anon.h index b2616df247..ce51f53376 100644 --- a/lib/auth/anon.h +++ b/lib/auth/anon.h @@ -44,7 +44,7 @@ typedef struct gnutls_anon_client_credentials_st typedef struct anon_auth_info_st { dh_info_st dh; - ecc_curve_t curve; + gnutls_ecc_curve_t curve; } *anon_auth_info_t; typedef struct anon_auth_info_st anon_auth_info_st; diff --git a/lib/auth/ecdh_common.c b/lib/auth/ecdh_common.c index 556f34a253..f04526a5ec 100644 --- a/lib/auth/ecdh_common.c +++ b/lib/auth/ecdh_common.c @@ -75,7 +75,7 @@ int ret; int _gnutls_proc_ecdh_common_client_kx (gnutls_session_t session, opaque * data, size_t _data_size, - ecc_curve_t curve) + gnutls_ecc_curve_t curve) { ssize_t data_size = _data_size; int ret, i = 0; @@ -89,7 +89,7 @@ _gnutls_proc_ecdh_common_client_kx (gnutls_session_t session, i+=1; DECR_LEN (data_size, point_size); - ret = _gnutls_ecc_ansi_x963_import(curve, &data[i], point_size, &session->key->ecdh_x, &session->key->ecdh_y); + ret = _gnutls_ecc_ansi_x963_import(&data[i], point_size, &session->key->ecdh_x, &session->key->ecdh_y); if (ret < 0) return gnutls_assert_val(ret); @@ -139,7 +139,7 @@ _gnutls_proc_ecdh_common_server_kx (gnutls_session_t session, opaque * data, size_t _data_size) { int i, ret, point_size; - ecc_curve_t curve; + gnutls_ecc_curve_t curve; ssize_t data_size = _data_size; i = 0; @@ -162,7 +162,7 @@ _gnutls_proc_ecdh_common_server_kx (gnutls_session_t session, i++; DECR_LEN (data_size, point_size); - ret = _gnutls_ecc_ansi_x963_import(curve, &data[i], point_size, &session->key->ecdh_x, &session->key->ecdh_y); + ret = _gnutls_ecc_ansi_x963_import(&data[i], point_size, &session->key->ecdh_x, &session->key->ecdh_y); if (ret < 0) return gnutls_assert_val(ret); @@ -174,7 +174,7 @@ _gnutls_proc_ecdh_common_server_kx (gnutls_session_t session, /* If the psk flag is set, then an empty psk_identity_hint will * be inserted */ int _gnutls_ecdh_common_print_server_kx (gnutls_session_t session, gnutls_buffer_st* data, - ecc_curve_t curve) + gnutls_ecc_curve_t curve) { opaque p; int ret; diff --git a/lib/auth/ecdh_common.h b/lib/auth/ecdh_common.h index 1fa6eba39a..9b7a92b653 100644 --- a/lib/auth/ecdh_common.h +++ b/lib/auth/ecdh_common.h @@ -30,9 +30,9 @@ int _gnutls_gen_ecdh_common_client_kx (gnutls_session_t, gnutls_buffer_st*); int _gnutls_proc_ecdh_common_client_kx (gnutls_session_t session, opaque * data, size_t _data_size, - ecc_curve_t curve); + gnutls_ecc_curve_t curve); int _gnutls_ecdh_common_print_server_kx (gnutls_session_t, gnutls_buffer_st* data, - ecc_curve_t curve); + gnutls_ecc_curve_t curve); int _gnutls_proc_ecdh_common_server_kx (gnutls_session_t session, opaque * data, size_t _data_size); diff --git a/lib/auth/rsa.c b/lib/auth/rsa.c index 4b162ffde2..52aceaad15 100644 --- a/lib/auth/rsa.c +++ b/lib/auth/rsa.c @@ -68,14 +68,11 @@ const mod_auth_st rsa_auth_struct = { */ static int _gnutls_get_public_rsa_params (gnutls_session_t session, - bigint_t params[MAX_PUBLIC_PARAMS_SIZE], - int *params_len) + gnutls_pk_params_st * params) { int ret; cert_auth_info_t info; gnutls_pcert_st peer_cert; - bigint_t tmp_params[RSA_PUBLIC_PARAMS]; - int tmp_params_size; int i; /* normal non export case */ @@ -99,13 +96,8 @@ _gnutls_get_public_rsa_params (gnutls_session_t session, return ret; } - if (*params_len < RSA_PUBLIC_PARAMS) - { - gnutls_assert (); - ret = GNUTLS_E_INTERNAL_ERROR; - goto cleanup; - } - *params_len = RSA_PUBLIC_PARAMS; + gnutls_pk_params_init(params); + params->params_nr = RSA_PUBLIC_PARAMS; /* EXPORT case: */ if (_gnutls_cipher_suite_get_kx_algo @@ -120,29 +112,22 @@ _gnutls_get_public_rsa_params (gnutls_session_t session, goto cleanup; } - for (i = 0; i < *params_len; i++) + for (i = 0; i < params->params_nr; i++) { - params[i] = _gnutls_mpi_copy (session->key->rsa[i]); + params->params[i] = _gnutls_mpi_copy (session->key->rsa[i]); } ret = 0; goto cleanup; } - tmp_params_size = RSA_PUBLIC_PARAMS; - ret = _gnutls_pubkey_get_mpis(peer_cert.pubkey, tmp_params, &tmp_params_size); + ret = _gnutls_pubkey_get_mpis(peer_cert.pubkey, params); if (ret < 0) { ret = gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR); goto cleanup; } - /* end of export case */ - for (i = 0; i < *params_len; i++) - { - params[i] = _gnutls_mpi_copy (tmp_params[i]); - } - ret = 0; cleanup: @@ -263,9 +248,8 @@ _gnutls_gen_rsa_client_kx (gnutls_session_t session, gnutls_buffer_st* data) { cert_auth_info_t auth = session->key->auth_info; gnutls_datum_t sdata; /* data to send */ - bigint_t params[MAX_PUBLIC_PARAMS_SIZE]; - int params_len = MAX_PUBLIC_PARAMS_SIZE; - int ret, i; + gnutls_pk_params_st params; + int ret; gnutls_protocol_t ver; if (auth == NULL) @@ -310,22 +294,21 @@ _gnutls_gen_rsa_client_kx (gnutls_session_t session, gnutls_buffer_st* data) /* move RSA parameters to key (session). */ if ((ret = - _gnutls_get_public_rsa_params (session, params, ¶ms_len)) < 0) + _gnutls_get_public_rsa_params (session, ¶ms)) < 0) { gnutls_assert (); return ret; } - if ((ret = + ret = _gnutls_pkcs1_rsa_encrypt (&sdata, &session->key->key, - params, params_len, 2)) < 0) - { - gnutls_assert (); - return ret; - } + ¶ms, 2); + + gnutls_pk_params_release(¶ms); + + if (ret < 0) + return gnutls_assert_val(ret); - for (i = 0; i < params_len; i++) - _gnutls_mpi_release (¶ms[i]); if (gnutls_protocol_get_version (session) == GNUTLS_SSL3) { diff --git a/lib/auth/rsa_export.c b/lib/auth/rsa_export.c index 9114863774..baa990ff27 100644 --- a/lib/auth/rsa_export.c +++ b/lib/auth/rsa_export.c @@ -72,7 +72,7 @@ const mod_auth_st rsa_export_auth_struct = { */ static int _gnutls_get_private_rsa_params (gnutls_session_t session, - bigint_t ** params, int *params_size) + gnutls_pk_params_st** params) { int ret; gnutls_certificate_credentials_t cred; @@ -116,8 +116,7 @@ _gnutls_get_private_rsa_params (gnutls_session_t session, * of 512 bits size. The params in the certificate are * used to sign this temporary stuff. */ - *params_size = RSA_PRIVATE_PARAMS; - *params = rsa_params->params; + *params = &rsa_params->params; return 0; } @@ -129,8 +128,7 @@ proc_rsa_export_client_kx (gnutls_session_t session, opaque * data, gnutls_datum_t plaintext; gnutls_datum_t ciphertext; int ret, dsize; - bigint_t *params; - int params_len; + gnutls_pk_params_st *params; int randomize_key = 0; ssize_t data_size = _data_size; @@ -157,14 +155,14 @@ proc_rsa_export_client_kx (gnutls_session_t session, opaque * data, ciphertext.size = dsize; } - ret = _gnutls_get_private_rsa_params (session, ¶ms, ¶ms_len); + ret = _gnutls_get_private_rsa_params (session, ¶ms); if (ret < 0) { gnutls_assert (); return ret; } - ret = _gnutls_pkcs1_rsa_decrypt (&plaintext, &ciphertext, params, params_len, 2); /* btype==2 */ + ret = _gnutls_pkcs1_rsa_decrypt (&plaintext, &ciphertext, params, 2); /* btype==2 */ if (ret < 0 || plaintext.size != GNUTLS_MASTER_SIZE) { @@ -236,7 +234,7 @@ static int gen_rsa_export_server_kx (gnutls_session_t session, gnutls_buffer_st* data) { gnutls_rsa_params_t rsa_params; - const bigint_t *rsa_mpis; + const gnutls_pk_params_st *rsa_mpis; int ret = 0; gnutls_pcert_st *apr_cert_list; gnutls_privkey_t apr_pkey; @@ -290,13 +288,13 @@ gen_rsa_export_server_kx (gnutls_session_t session, gnutls_buffer_st* data) return ret; } - _gnutls_rsa_export_set_pubkey (session, rsa_mpis[1], rsa_mpis[0]); + _gnutls_rsa_export_set_pubkey (session, rsa_mpis->params[1], rsa_mpis->params[0]); - ret = _gnutls_buffer_append_mpi( data, 16, rsa_mpis[0], 0); + ret = _gnutls_buffer_append_mpi( data, 16, rsa_mpis->params[0], 0); if (ret < 0) return gnutls_assert_val(ret); - ret = _gnutls_buffer_append_mpi( data, 16, rsa_mpis[1], 0); + ret = _gnutls_buffer_append_mpi( data, 16, rsa_mpis->params[1], 0); if (ret < 0) return gnutls_assert_val(ret); diff --git a/lib/ext/ecc.c b/lib/ext/ecc.c index b417a2bcfd..7f744cacc1 100644 --- a/lib/ext/ecc.c +++ b/lib/ext/ecc.c @@ -265,5 +265,5 @@ _gnutls_session_supports_ecc_curve (gnutls_session_t session, int ecc_type) } } - return GNUTLS_E_ECC_NO_SUPPORTED_CURVES; + return GNUTLS_E_ECC_UNSUPPORTED_CURVE; } diff --git a/lib/gnutls.asn b/lib/gnutls.asn index f485c27d6d..64e05199b3 100644 --- a/lib/gnutls.asn +++ b/lib/gnutls.asn @@ -89,5 +89,18 @@ DHParameter ::= SEQUENCE { privateValueLength INTEGER OPTIONAL } +-- ECC from RFC5480 +ECPoint ::= OCTET STRING + +ECParameters ::= CHOICE { + namedCurve OBJECT IDENTIFIER +} + +ECPrivateKey ::= SEQUENCE { + Version INTEGER, -- { ecPrivkeyVer1(1) } + privateKey OCTET STRING, + parameters [0] ECParameters OPTIONAL, + publicKey [1] BIT STRING OPTIONAL +} END diff --git a/lib/gnutls_asn1_tab.c b/lib/gnutls_asn1_tab.c index ecac746e5d..74af21df74 100644 --- a/lib/gnutls_asn1_tab.c +++ b/lib/gnutls_asn1_tab.c @@ -55,9 +55,19 @@ const ASN1_ARRAY_TYPE gnutls_asn1_tab[] = { { "g", 1073741827, NULL }, { "Y", 1073741827, NULL }, { "priv", 3, NULL }, - { "DHParameter", 536870917, NULL }, + { "DHParameter", 1610612741, NULL }, { "prime", 1073741827, NULL }, { "base", 1073741827, NULL }, { "privateValueLength", 16387, NULL }, + { "ECPoint", 1073741831, NULL }, + { "ECParameters", 1610612754, NULL }, + { "namedCurve", 12, NULL }, + { "ECPrivateKey", 536870917, NULL }, + { "Version", 1073741827, NULL }, + { "privateKey", 1073741831, NULL }, + { "parameters", 1610637314, "ECParameters"}, + { NULL, 2056, "0"}, + { "publicKey", 536895494, NULL }, + { NULL, 2056, "1"}, { NULL, 0, NULL } }; diff --git a/lib/gnutls_ecc.c b/lib/gnutls_ecc.c index 6eb74eed67..60f1c8eae4 100644 --- a/lib/gnutls_ecc.c +++ b/lib/gnutls_ecc.c @@ -31,71 +31,176 @@ #include <algorithms.h> #include <gnutls_errors.h> -int _gnutls_ecc_ansi_x963_export(ecc_curve_t curve, bigint_t x, bigint_t y, gnutls_datum_t * out) +int +_gnutls_ecc_ansi_x963_export (gnutls_ecc_curve_t curve, bigint_t x, bigint_t y, + gnutls_datum_t * out) { - int numlen = _gnutls_ecc_curve_get_size(curve); - int byte_size, ret; - size_t size; - - if (numlen == 0) - return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); - - out->size = 1 + 2*numlen; - - out->data = gnutls_malloc(out->size); - if (out->data == NULL) - return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); - - memset(out->data, 0, out->size); - - /* store byte 0x04 */ - out->data[0] = 0x04; - - /* pad and store x */ - byte_size = (_gnutls_mpi_get_nbits(x)+7)/8; - size = out->size - (1+(numlen-byte_size)); - ret = _gnutls_mpi_print(x, &out->data[1+(numlen-byte_size)], &size); - if (ret < 0) - return gnutls_assert_val(ret); - - byte_size = (_gnutls_mpi_get_nbits(y)+7)/8; - size = out->size - (1+(numlen+numlen-byte_size)); - ret = _gnutls_mpi_print(y, &out->data[1+numlen+numlen-byte_size], &size); - if (ret < 0) - return gnutls_assert_val(ret); - - /* pad and store y */ - return 0; + int numlen = gnutls_ecc_curve_get_size (curve); + int byte_size, ret; + size_t size; + + if (numlen == 0) + return gnutls_assert_val (GNUTLS_E_INVALID_REQUEST); + + out->size = 1 + 2 * numlen; + + out->data = gnutls_malloc (out->size); + if (out->data == NULL) + return gnutls_assert_val (GNUTLS_E_MEMORY_ERROR); + + memset (out->data, 0, out->size); + + /* store byte 0x04 */ + out->data[0] = 0x04; + + /* pad and store x */ + byte_size = (_gnutls_mpi_get_nbits (x) + 7) / 8; + size = out->size - (1 + (numlen - byte_size)); + ret = _gnutls_mpi_print (x, &out->data[1 + (numlen - byte_size)], &size); + if (ret < 0) + return gnutls_assert_val (ret); + + byte_size = (_gnutls_mpi_get_nbits (y) + 7) / 8; + size = out->size - (1 + (numlen + numlen - byte_size)); + ret = + _gnutls_mpi_print (y, &out->data[1 + numlen + numlen - byte_size], &size); + if (ret < 0) + return gnutls_assert_val (ret); + + /* pad and store y */ + return 0; } -int _gnutls_ecc_ansi_x963_import(ecc_curve_t curve, const opaque *in, unsigned long inlen, bigint_t* x, bigint_t* y) +int +_gnutls_ecc_ansi_x963_import (const opaque * in, + unsigned long inlen, bigint_t * x, bigint_t * y) +{ + int ret; + + /* must be odd */ + if ((inlen & 1) == 0) + { + return GNUTLS_E_INVALID_REQUEST; + } + + /* check for 4 */ + if (in[0] != 4) + { + return gnutls_assert_val (GNUTLS_E_PARSING_ERROR); + } + + /* read data */ + ret = _gnutls_mpi_scan (x, in + 1, (inlen - 1) >> 1); + if (ret < 0) + return gnutls_assert_val (GNUTLS_E_MEMORY_ERROR); + + ret = _gnutls_mpi_scan (y, in + 1 + ((inlen - 1) >> 1), (inlen - 1) >> 1); + if (ret < 0) + { + _gnutls_mpi_release (x); + return gnutls_assert_val (GNUTLS_E_MEMORY_ERROR); + } + + return 0; +} + +int _gnutls_ecc_curve_fill_params(gnutls_ecc_curve_t curve, gnutls_pk_params_st* params) { - int ret; - int numlen = _gnutls_ecc_curve_get_size(curve); - - /* must be odd */ - if ((inlen & 1) == 0 || numlen == 0) - { - return GNUTLS_E_INVALID_REQUEST; - } - - /* check for 4, 6 or 7 */ - if (in[0] != 4 && in[0] != 6 && in[0] != 7) { - return gnutls_assert_val(GNUTLS_E_PARSING_ERROR); - } - - /* read data */ - ret = _gnutls_mpi_scan(x, in+1, (inlen-1)>>1); - if (ret < 0) - return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); - - ret = _gnutls_mpi_scan(y, in+1+((inlen-1)>>1), (inlen-1)>>1); - if (ret < 0) - { - _gnutls_mpi_release(x); - return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); - } - - return 0; +const gnutls_ecc_curve_entry_st *st; +uint8_t val[MAX_ECC_CURVE_SIZE]; +size_t val_size; +int ret; + + st = _gnutls_ecc_curve_get_params(curve); + if (st == NULL) + return gnutls_assert_val(GNUTLS_E_ECC_UNSUPPORTED_CURVE); + + val_size = sizeof(val); + ret = _gnutls_hex2bin(st->prime, strlen(st->prime), val, &val_size); + if (ret < 0) + { + gnutls_assert(); + goto cleanup; + } + + ret = _gnutls_mpi_scan_nz(¶ms->params[0], val, val_size); + if (ret < 0) + { + gnutls_assert(); + goto cleanup; + } + params->params_nr++; + + val_size = sizeof(val); + ret = _gnutls_hex2bin(st->order, strlen(st->order), val, &val_size); + if (ret < 0) + { + gnutls_assert(); + goto cleanup; + } + + ret = _gnutls_mpi_scan_nz(¶ms->params[1], val, val_size); + if (ret < 0) + { + gnutls_assert(); + goto cleanup; + } + params->params_nr++; + + val_size = sizeof(val); + ret = _gnutls_hex2bin(st->A, strlen(st->A), val, &val_size); + if (ret < 0) + { + gnutls_assert(); + goto cleanup; + } + + ret = _gnutls_mpi_scan_nz(¶ms->params[2], val, val_size); + if (ret < 0) + { + gnutls_assert(); + goto cleanup; + } + params->params_nr++; + + val_size = sizeof(val); + ret = _gnutls_hex2bin(st->Gx, strlen(st->Gx), val, &val_size); + if (ret < 0) + { + gnutls_assert(); + goto cleanup; + } + + ret = _gnutls_mpi_scan_nz(¶ms->params[3], val, val_size); + if (ret < 0) + { + gnutls_assert(); + goto cleanup; + } + params->params_nr++; + + val_size = sizeof(val); + ret = _gnutls_hex2bin(st->Gy, strlen(st->Gy), val, &val_size); + if (ret < 0) + { + gnutls_assert(); + goto cleanup; + } + + ret = _gnutls_mpi_scan_nz(¶ms->params[4], val, val_size); + if (ret < 0) + { + gnutls_assert(); + goto cleanup; + } + params->params_nr++; + + + return 0; + +cleanup: + gnutls_pk_params_release(params); + return ret; + } diff --git a/lib/gnutls_ecc.h b/lib/gnutls_ecc.h index 5f91ac5800..2ae454171b 100644 --- a/lib/gnutls_ecc.h +++ b/lib/gnutls_ecc.h @@ -1,2 +1,7 @@ -int _gnutls_ecc_ansi_x963_import(ecc_curve_t curve, const opaque *in, unsigned long inlen, bigint_t* x, bigint_t* y); -int _gnutls_ecc_ansi_x963_export(ecc_curve_t curve, bigint_t x, bigint_t y, gnutls_datum_t * out); +#ifndef GNUTLS_ECC_H +# define GNUTLS_ECC_H + +int _gnutls_ecc_ansi_x963_import(const opaque *in, unsigned long inlen, bigint_t* x, bigint_t* y); +int _gnutls_ecc_ansi_x963_export(gnutls_ecc_curve_t curve, bigint_t x, bigint_t y, gnutls_datum_t * out); +int _gnutls_ecc_curve_fill_params(gnutls_ecc_curve_t curve, gnutls_pk_params_st* params); +#endif diff --git a/lib/gnutls_errors.c b/lib/gnutls_errors.c index 9f700b7e08..39bf11b3a9 100644 --- a/lib/gnutls_errors.c +++ b/lib/gnutls_errors.c @@ -330,6 +330,8 @@ static const gnutls_error_entry error_algorithms[] = { GNUTLS_E_USER_ERROR, 1), ERROR_ENTRY (N_("No supported ECC curves were found"), GNUTLS_E_ECC_NO_SUPPORTED_CURVES, 1), + ERROR_ENTRY (N_("The curve is unsupported"), + GNUTLS_E_ECC_UNSUPPORTED_CURVE, 1), {NULL, NULL, 0, 0} }; diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h index 8dbec24259..0f7609d6c2 100644 --- a/lib/gnutls_int.h +++ b/lib/gnutls_int.h @@ -226,15 +226,6 @@ typedef enum extensions_t } extensions_t; typedef enum -{ - GNUTLS_ECC_CURVE_INVALID=0, - GNUTLS_ECC_CURVE_SECP224R1, - GNUTLS_ECC_CURVE_SECP256R1, - GNUTLS_ECC_CURVE_SECP384R1, - GNUTLS_ECC_CURVE_SECP521R1, -} ecc_curve_t; - -typedef enum { CIPHER_STREAM, CIPHER_BLOCK } cipher_type_t; #define RESUME_TRUE 0 @@ -486,7 +477,7 @@ typedef struct uint16_t max_record_recv_size; /* holds the negotiated certificate type */ gnutls_certificate_type_t cert_type; - ecc_curve_t ecc_curve; /* holds the first supported ECC curve requested by client */ + gnutls_ecc_curve_t ecc_curve; /* holds the first supported ECC curve requested by client */ gnutls_protocol_t version; /* moved here */ /* FIXME: The following are not saved in the session storage diff --git a/lib/gnutls_pk.c b/lib/gnutls_pk.c index 5fc3aa216f..358cef40ec 100644 --- a/lib/gnutls_pk.c +++ b/lib/gnutls_pk.c @@ -45,7 +45,7 @@ int _gnutls_pkcs1_rsa_encrypt (gnutls_datum_t * ciphertext, const gnutls_datum_t * plaintext, - bigint_t * params, unsigned params_len, + gnutls_pk_params_st * params, unsigned btype) { unsigned int i, pad; @@ -53,14 +53,9 @@ _gnutls_pkcs1_rsa_encrypt (gnutls_datum_t * ciphertext, opaque *edata, *ps; size_t k, psize; size_t mod_bits; - gnutls_pk_params_st pk_params; gnutls_datum_t to_encrypt, encrypted; - for (i = 0; i < params_len; i++) - pk_params.params[i] = params[i]; - pk_params.params_nr = params_len; - - mod_bits = _gnutls_mpi_get_nbits (params[0]); + mod_bits = _gnutls_mpi_get_nbits (params->params[0]); k = mod_bits / 8; if (mod_bits % 8 != 0) k++; @@ -91,7 +86,7 @@ _gnutls_pkcs1_rsa_encrypt (gnutls_datum_t * ciphertext, { case 2: /* using public key */ - if (params_len < RSA_PUBLIC_PARAMS) + if (params->params_nr < RSA_PUBLIC_PARAMS) { gnutls_assert (); gnutls_free (edata); @@ -120,7 +115,7 @@ _gnutls_pkcs1_rsa_encrypt (gnutls_datum_t * ciphertext, case 1: /* using private key */ - if (params_len < RSA_PRIVATE_PARAMS) + if (params->params_nr < RSA_PRIVATE_PARAMS) { gnutls_assert (); gnutls_free (edata); @@ -144,10 +139,10 @@ _gnutls_pkcs1_rsa_encrypt (gnutls_datum_t * ciphertext, if (btype == 2) /* encrypt */ ret = - _gnutls_pk_encrypt (GNUTLS_PK_RSA, &encrypted, &to_encrypt, &pk_params); + _gnutls_pk_encrypt (GNUTLS_PK_RSA, &encrypted, &to_encrypt, params); else /* sign */ ret = - _gnutls_pk_sign (GNUTLS_PK_RSA, &encrypted, &to_encrypt, &pk_params); + _gnutls_pk_sign (GNUTLS_PK_RSA, &encrypted, &to_encrypt, params); gnutls_free (edata); @@ -211,19 +206,14 @@ cleanup: int _gnutls_pkcs1_rsa_decrypt (gnutls_datum_t * plaintext, const gnutls_datum_t * ciphertext, - bigint_t * params, unsigned params_len, + gnutls_pk_params_st* params, unsigned btype) { unsigned int k, i; int ret; size_t esize, mod_bits; - gnutls_pk_params_st pk_params; - - for (i = 0; i < params_len; i++) - pk_params.params[i] = params[i]; - pk_params.params_nr = params_len; - mod_bits = _gnutls_mpi_get_nbits (params[0]); + mod_bits = _gnutls_mpi_get_nbits (params->params[0]); k = mod_bits / 8; if (mod_bits % 8 != 0) k++; @@ -242,12 +232,12 @@ _gnutls_pkcs1_rsa_decrypt (gnutls_datum_t * plaintext, if (btype == 2) { ret = - _gnutls_pk_decrypt (GNUTLS_PK_RSA, plaintext, ciphertext, &pk_params); + _gnutls_pk_decrypt (GNUTLS_PK_RSA, plaintext, ciphertext, params); } else { ret = - _gnutls_pk_encrypt (GNUTLS_PK_RSA, plaintext, ciphertext, &pk_params); + _gnutls_pk_encrypt (GNUTLS_PK_RSA, plaintext, ciphertext, params); } if (ret < 0) @@ -324,8 +314,9 @@ _gnutls_pkcs1_rsa_decrypt (gnutls_datum_t * plaintext, int _gnutls_rsa_verify (const gnutls_datum_t * vdata, - const gnutls_datum_t * ciphertext, bigint_t * params, - int params_len, int btype) + const gnutls_datum_t * ciphertext, + gnutls_pk_params_st * params, + int btype) { gnutls_datum_t plain; @@ -333,7 +324,7 @@ _gnutls_rsa_verify (const gnutls_datum_t * vdata, /* decrypt signature */ if ((ret = - _gnutls_pkcs1_rsa_decrypt (&plain, ciphertext, params, params_len, + _gnutls_pkcs1_rsa_decrypt (&plain, ciphertext, params, btype)) < 0) { gnutls_assert (); @@ -410,17 +401,11 @@ _gnutls_encode_ber_rs (gnutls_datum_t * sig_value, bigint_t r, bigint_t s) */ int _gnutls_dsa_sign (gnutls_datum_t * signature, - const gnutls_datum_t * hash, bigint_t * params, - unsigned int params_len) + const gnutls_datum_t * hash, + gnutls_pk_params_st * params) { int ret; - size_t i; size_t k; - gnutls_pk_params_st pk_params; - - for (i = 0; i < params_len; i++) - pk_params.params[i] = params[i]; - pk_params.params_nr = params_len; k = hash->size; if (k < 20) @@ -429,7 +414,7 @@ _gnutls_dsa_sign (gnutls_datum_t * signature, return GNUTLS_E_PK_SIGN_FAILED; } - ret = _gnutls_pk_sign (GNUTLS_PK_DSA, signature, hash, &pk_params); + ret = _gnutls_pk_sign (GNUTLS_PK_DSA, signature, hash, params); /* rs[0], rs[1] now hold r,s */ if (ret < 0) @@ -493,16 +478,11 @@ _gnutls_decode_ber_rs (const gnutls_datum_t * sig_value, bigint_t * r, */ int _gnutls_dsa_verify (const gnutls_datum_t * vdata, - const gnutls_datum_t * sig_value, bigint_t * params, - int params_len) + const gnutls_datum_t * sig_value, + gnutls_pk_params_st* params) { - int ret, i; - gnutls_pk_params_st pk_params; - - for (i = 0; i < params_len; i++) - pk_params.params[i] = params[i]; - pk_params.params_nr = params_len; + int ret; if (vdata->size < 20) { /* SHA1 or better only */ @@ -511,7 +491,7 @@ _gnutls_dsa_verify (const gnutls_datum_t * vdata, } /* decrypt signature */ - ret = _gnutls_pk_verify (GNUTLS_PK_DSA, vdata, sig_value, &pk_params); + ret = _gnutls_pk_verify (GNUTLS_PK_DSA, vdata, sig_value, params); if (ret < 0) { @@ -523,68 +503,21 @@ _gnutls_dsa_verify (const gnutls_datum_t * vdata, } /* some generic pk functions */ -static int -_generate_params (int algo, bigint_t * resarr, unsigned int *resarr_len, - int bits) -{ - gnutls_pk_params_st params; - int ret; - unsigned int i; - - ret = _gnutls_pk_generate (algo, bits, ¶ms); - - if (ret < 0) - { - gnutls_assert (); - return ret; - } - - if (resarr && resarr_len && *resarr_len >= params.params_nr) - { - *resarr_len = params.params_nr; - for (i = 0; i < params.params_nr; i++) - resarr[i] = params.params[i]; - } - else - { - gnutls_assert (); - return GNUTLS_E_INVALID_REQUEST; - } - return 0; -} - - -int -_gnutls_rsa_generate_params (bigint_t * resarr, unsigned int *resarr_len, - int bits) -{ - return _generate_params (GNUTLS_PK_RSA, resarr, resarr_len, bits); -} - -int -_gnutls_dsa_generate_params (bigint_t * resarr, unsigned int *resarr_len, - int bits) -{ - return _generate_params (GNUTLS_PK_DSA, resarr, resarr_len, bits); -} - -int -_gnutls_pk_params_copy (gnutls_pk_params_st * dst, bigint_t * params, - int params_len) +int _gnutls_pk_params_copy (gnutls_pk_params_st * dst, const gnutls_pk_params_st * src) { int i, j; dst->params_nr = 0; - if (params_len == 0 || params == NULL) + if (src == NULL || src->params_nr == 0) { gnutls_assert (); return GNUTLS_E_INVALID_REQUEST; } - for (i = 0; i < params_len; i++) + for (i = 0; i < src->params_nr; i++) { - dst->params[i] = _gnutls_mpi_set (NULL, params[i]); + dst->params[i] = _gnutls_mpi_set (NULL, src->params[i]); if (dst->params[i] == NULL) { for (j = 0; j < i; j++) @@ -611,14 +544,15 @@ gnutls_pk_params_release (gnutls_pk_params_st * p) { _gnutls_mpi_release (&p->params[i]); } + p->params_nr = 0; } int -_gnutls_calc_rsa_exp (bigint_t * params, unsigned int params_size) +_gnutls_calc_rsa_exp (gnutls_pk_params_st* params) { - bigint_t tmp = _gnutls_mpi_alloc_like (params[0]); + bigint_t tmp = _gnutls_mpi_alloc_like (params->params[0]); - if (params_size < RSA_PRIVATE_PARAMS - 2) + if (params->params_nr < RSA_PRIVATE_PARAMS - 2) { gnutls_assert (); return GNUTLS_E_INTERNAL_ERROR; @@ -631,15 +565,15 @@ _gnutls_calc_rsa_exp (bigint_t * params, unsigned int params_size) } /* [6] = d % p-1, [7] = d % q-1 */ - _gnutls_mpi_sub_ui (tmp, params[3], 1); - params[6] = _gnutls_mpi_mod (params[2] /*d */ , tmp); + _gnutls_mpi_sub_ui (tmp, params->params[3], 1); + params->params[6] = _gnutls_mpi_mod (params->params[2] /*d */ , tmp); - _gnutls_mpi_sub_ui (tmp, params[4], 1); - params[7] = _gnutls_mpi_mod (params[2] /*d */ , tmp); + _gnutls_mpi_sub_ui (tmp, params->params[4], 1); + params->params[7] = _gnutls_mpi_mod (params->params[2] /*d */ , tmp); _gnutls_mpi_release (&tmp); - if (params[7] == NULL || params[6] == NULL) + if (params->params[7] == NULL || params->params[6] == NULL) { gnutls_assert (); return GNUTLS_E_MEMORY_ERROR; @@ -649,8 +583,8 @@ _gnutls_calc_rsa_exp (bigint_t * params, unsigned int params_size) } int -_gnutls_pk_get_hash_algorithm (gnutls_pk_algorithm_t pk, bigint_t * params, - int params_size, +_gnutls_pk_get_hash_algorithm (gnutls_pk_algorithm_t pk, + gnutls_pk_params_st* params, gnutls_digest_algorithm_t * dig, unsigned int *mand) { @@ -663,6 +597,6 @@ _gnutls_pk_get_hash_algorithm (gnutls_pk_algorithm_t pk, bigint_t * params, } return _gnutls_x509_verify_algorithm ((gnutls_mac_algorithm_t *) dig, - NULL, pk, params, params_size); + NULL, pk, params); } diff --git a/lib/gnutls_pk.h b/lib/gnutls_pk.h index 07a1acd7e9..1cdcf86227 100644 --- a/lib/gnutls_pk.h +++ b/lib/gnutls_pk.h @@ -45,32 +45,26 @@ _gnutls_pk_fixup (gnutls_pk_algorithm_t algo, gnutls_direction_t direction, return 0; } -int _gnutls_pk_params_copy (gnutls_pk_params_st * dst, bigint_t * params, - int params_len); - -int _gnutls_rsa_generate_params (bigint_t * resarr, unsigned int *resarr_len, - int bits); -int _gnutls_dsa_generate_params (bigint_t * resarr, unsigned int *resarr_len, - int bits); +int _gnutls_pk_params_copy (gnutls_pk_params_st * dst, const gnutls_pk_params_st * src); /* The internal PK interface */ int _gnutls_pkcs1_rsa_encrypt (gnutls_datum_t * ciphertext, const gnutls_datum_t * plaintext, - bigint_t * params, unsigned params_len, + gnutls_pk_params_st * params, unsigned btype); int _gnutls_dsa_sign (gnutls_datum_t * signature, - const gnutls_datum_t * plaintext, bigint_t * params, - unsigned params_len); + const gnutls_datum_t * plaintext, gnutls_pk_params_st*); int _gnutls_pkcs1_rsa_decrypt (gnutls_datum_t * plaintext, const gnutls_datum_t * ciphertext, - bigint_t * params, unsigned params_len, + gnutls_pk_params_st* params, unsigned btype); int _gnutls_rsa_verify (const gnutls_datum_t * vdata, - const gnutls_datum_t * ciphertext, bigint_t * params, - int params_len, int btype); + const gnutls_datum_t * ciphertext, + gnutls_pk_params_st*, + int btype); int _gnutls_dsa_verify (const gnutls_datum_t * vdata, - const gnutls_datum_t * sig_value, bigint_t * params, - int params_len); + const gnutls_datum_t * sig_value, + gnutls_pk_params_st* params); int _gnutls_encode_ber_rs (gnutls_datum_t * sig_value, bigint_t r, bigint_t s); @@ -79,10 +73,10 @@ int _gnutls_decode_ber_rs (const gnutls_datum_t * sig_value, bigint_t * r, bigint_t * s); -int _gnutls_calc_rsa_exp (bigint_t * params, unsigned int params_size); +int _gnutls_calc_rsa_exp (gnutls_pk_params_st*); int _gnutls_pk_get_hash_algorithm (gnutls_pk_algorithm_t pk, - bigint_t * params, int params_size, + gnutls_pk_params_st*, gnutls_digest_algorithm_t * dig, unsigned int *mand); diff --git a/lib/gnutls_privkey.c b/lib/gnutls_privkey.c index 2b92efb0f9..b71e04a224 100644 --- a/lib/gnutls_privkey.c +++ b/lib/gnutls_privkey.c @@ -95,7 +95,7 @@ gnutls_privkey_get_pk_algorithm (gnutls_privkey_t key, unsigned int *bits) return gnutls_pkcs11_privkey_get_pk_algorithm (key->key.pkcs11, bits); case GNUTLS_PRIVKEY_X509: if (bits) - *bits = _gnutls_mpi_get_nbits (key->key.x509->params[0]); + *bits = _gnutls_mpi_get_nbits (key->key.x509->params.params[0]); return gnutls_x509_privkey_get_pk_algorithm (key->key.x509); default: gnutls_assert (); @@ -106,27 +106,20 @@ gnutls_privkey_get_pk_algorithm (gnutls_privkey_t key, unsigned int *bits) static int privkey_to_pubkey (gnutls_pk_algorithm_t pk, - const bigint_t * params, int params_size, - bigint_t * new_params, int *new_params_size) + const gnutls_pk_params_st* priv, + gnutls_pk_params_st* pub) { - int ret, i; + int ret; switch (pk) { case GNUTLS_PK_RSA: - if (*new_params_size < RSA_PUBLIC_PARAMS - || params_size < RSA_PRIVATE_PARAMS) - { - gnutls_assert (); - return GNUTLS_E_INVALID_REQUEST; - } - - new_params[0] = _gnutls_mpi_copy (params[0]); - new_params[1] = _gnutls_mpi_copy (params[1]); + pub->params[0] = _gnutls_mpi_copy (priv->params[0]); + pub->params[1] = _gnutls_mpi_copy (priv->params[1]); - *new_params_size = RSA_PUBLIC_PARAMS; + pub->params_nr = RSA_PUBLIC_PARAMS; - if (new_params[0] == NULL || new_params[1] == NULL) + if (pub->params[0] == NULL || pub->params[1] == NULL) { gnutls_assert (); ret = GNUTLS_E_MEMORY_ERROR; @@ -135,22 +128,15 @@ privkey_to_pubkey (gnutls_pk_algorithm_t pk, break; case GNUTLS_PK_DSA: - if (*new_params_size < DSA_PUBLIC_PARAMS - || params_size < DSA_PRIVATE_PARAMS) - { - gnutls_assert (); - return GNUTLS_E_INVALID_REQUEST; - } + pub->params[0] = _gnutls_mpi_copy (priv->params[0]); + pub->params[1] = _gnutls_mpi_copy (priv->params[1]); + pub->params[2] = _gnutls_mpi_copy (priv->params[2]); + pub->params[3] = _gnutls_mpi_copy (priv->params[3]); - new_params[0] = _gnutls_mpi_copy (params[0]); - new_params[1] = _gnutls_mpi_copy (params[1]); - new_params[2] = _gnutls_mpi_copy (params[2]); - new_params[3] = _gnutls_mpi_copy (params[3]); + pub->params_nr = DSA_PUBLIC_PARAMS; - *new_params_size = DSA_PUBLIC_PARAMS; - - if (new_params[0] == NULL || new_params[1] == NULL || - new_params[2] == NULL || new_params[3] == NULL) + if (pub->params[0] == NULL || pub->params[1] == NULL || + pub->params[2] == NULL || pub->params[3] == NULL) { gnutls_assert (); ret = GNUTLS_E_MEMORY_ERROR; @@ -165,8 +151,7 @@ privkey_to_pubkey (gnutls_pk_algorithm_t pk, return 0; cleanup: - for (i = 0; i < *new_params_size; i++) - _gnutls_mpi_release (new_params[i]); + gnutls_pk_params_release(pub); return ret; } @@ -175,7 +160,7 @@ cleanup: */ int _gnutls_privkey_get_public_mpis (gnutls_privkey_t key, - bigint_t * params, int *params_size) + gnutls_pk_params_st * params) { int ret; gnutls_pk_algorithm_t pk = gnutls_privkey_get_pk_algorithm (key, NULL); @@ -185,9 +170,8 @@ _gnutls_privkey_get_public_mpis (gnutls_privkey_t key, #ifdef ENABLE_OPENPGP case GNUTLS_PRIVKEY_OPENPGP: { - bigint_t tmp_params[MAX_PRIV_PARAMS_SIZE]; - int tmp_params_size = MAX_PRIV_PARAMS_SIZE; - uint32_t kid[2], i; + gnutls_pk_params_st tmp_params; + uint32_t kid[2]; uint8_t keyid[GNUTLS_OPENPGP_KEYID_SIZE]; ret = @@ -197,13 +181,11 @@ _gnutls_privkey_get_public_mpis (gnutls_privkey_t key, { KEYID_IMPORT (kid, keyid); ret = _gnutls_openpgp_privkey_get_mpis (key->key.openpgp, kid, - tmp_params, - &tmp_params_size); + &tmp_params); } else ret = _gnutls_openpgp_privkey_get_mpis (key->key.openpgp, NULL, - tmp_params, - &tmp_params_size); + &tmp_params); if (ret < 0) { @@ -212,21 +194,18 @@ _gnutls_privkey_get_public_mpis (gnutls_privkey_t key, } ret = privkey_to_pubkey (pk, - tmp_params, tmp_params_size, - params, params_size); - - for (i = 0; i < tmp_params_size; i++) - _gnutls_mpi_release (&tmp_params[i]); + &tmp_params, + params); + gnutls_pk_params_release(&tmp_params); } break; #endif case GNUTLS_PRIVKEY_X509: ret = privkey_to_pubkey (pk, - key->key.x509->params, - key->key.x509->params_size, params, - params_size); + &key->key.x509->params, + params); break; default: gnutls_assert (); @@ -574,8 +553,8 @@ _gnutls_privkey_sign_hash (gnutls_privkey_t key, hash, signature); case GNUTLS_PRIVKEY_X509: return _gnutls_soft_sign (key->key.x509->pk_algorithm, - key->key.x509->params, - key->key.x509->params_size, hash, signature); + &key->key.x509->params, + hash, signature); default: gnutls_assert (); return GNUTLS_E_INVALID_REQUEST; @@ -616,8 +595,8 @@ gnutls_privkey_decrypt_data (gnutls_privkey_t key, #endif case GNUTLS_PRIVKEY_X509: return _gnutls_pkcs1_rsa_decrypt (plaintext, ciphertext, - key->key.x509->params, - key->key.x509->params_size, 2); + &key->key.x509->params, + 2); case GNUTLS_PRIVKEY_PKCS11: return _gnutls_pkcs11_privkey_decrypt_data (key->key.pkcs11, flags, diff --git a/lib/gnutls_pubkey.c b/lib/gnutls_pubkey.c index 0c60ea5287..c6ad39abc8 100644 --- a/lib/gnutls_pubkey.c +++ b/lib/gnutls_pubkey.c @@ -1,6 +1,6 @@ /* * GnuTLS PKCS#11 support - * Copyright (C) 2010 Free Software Foundation + * Copyright (C) 2010,2011 Free Software Foundation * * Author: Nikos Mavrogiannopoulos * @@ -58,8 +58,7 @@ struct gnutls_pubkey_st * [2] is g * [3] is public key */ - bigint_t params[MAX_PUBLIC_PARAMS_SIZE]; - int params_size; /* holds the size of MPI params */ + gnutls_pk_params_st params; uint8_t openpgp_key_id[GNUTLS_OPENPGP_KEYID_SIZE]; int openpgp_key_id_set; @@ -67,15 +66,16 @@ struct gnutls_pubkey_st unsigned int key_usage; /* bits from GNUTLS_KEY_* */ }; -static int pubkey_to_bits(gnutls_pk_algorithm_t pk, bigint_t* params, int params_size) +int pubkey_to_bits(gnutls_pk_algorithm_t pk, gnutls_pk_params_st* params) { switch(pk) { case GNUTLS_PK_RSA: - return _gnutls_mpi_get_nbits(params[0]); + return _gnutls_mpi_get_nbits(params->params[0]); case GNUTLS_PK_DSA: - if (params_size < 3) return 0; - return _gnutls_mpi_get_nbits(params[3]); + return _gnutls_mpi_get_nbits(params->params[3]); + case GNUTLS_PK_ECC: + return gnutls_ecc_curve_get_size(params->flags)*8; default: return 0; } @@ -152,13 +152,7 @@ gnutls_pubkey_init (gnutls_pubkey_t * key) void gnutls_pubkey_deinit (gnutls_pubkey_t key) { -int i; - - for (i = 0; i < key->params_size; i++) - { - _gnutls_mpi_release (&key->params[i]); - } - + gnutls_pk_params_release(&key->params); gnutls_free (key); } @@ -186,29 +180,11 @@ gnutls_pubkey_import_x509 (gnutls_pubkey_t key, gnutls_x509_crt_t crt, if (ret < 0) key->key_usage = 0; - key->params_size = sizeof (key->params) / sizeof (key->params[0]); - switch (key->pk_algorithm) + ret = _gnutls_x509_crt_get_mpis (crt, &key->params); + if (ret < 0) { - case GNUTLS_PK_RSA: - ret = _gnutls_x509_crt_get_mpis (crt, key->params, &key->params_size); - if (ret < 0) - { - gnutls_assert (); - return ret; - } - break; - case GNUTLS_PK_DSA: - ret = _gnutls_x509_crt_get_mpis (crt, key->params, &key->params_size); - if (ret < 0) - { - gnutls_assert (); - return ret; - } - - break; - default: gnutls_assert (); - return GNUTLS_E_INVALID_REQUEST; + return ret; } return 0; @@ -237,10 +213,7 @@ gnutls_pubkey_import_privkey (gnutls_pubkey_t key, gnutls_privkey_t pkey, key->key_usage = usage; - key->params_size = sizeof (key->params) / sizeof (key->params[0]); - - return _gnutls_privkey_get_public_mpis (pkey, key->params, - &key->params_size); + return _gnutls_privkey_get_public_mpis (pkey, &key->params); } /** @@ -272,7 +245,7 @@ gnutls_pubkey_get_preferred_hash_algorithm (gnutls_pubkey_t key, } ret = _gnutls_pk_get_hash_algorithm (key->pk_algorithm, - key->params, key->params_size, + &key->params, hash, mand); return ret; @@ -396,34 +369,10 @@ gnutls_pubkey_import_openpgp (gnutls_pubkey_t key, key->pk_algorithm = gnutls_openpgp_crt_get_subkey_pk_algorithm (crt, idx, NULL); } - switch (key->pk_algorithm) - { - case GNUTLS_PK_RSA: - key->params_size = MAX_PUBLIC_PARAMS_SIZE; - ret = - _gnutls_openpgp_crt_get_mpis (crt, k, key->params, - &key->params_size); - if (ret < 0) - { - gnutls_assert (); - return ret; - } - break; - case GNUTLS_PK_DSA: - key->params_size = MAX_PUBLIC_PARAMS_SIZE; - ret = - _gnutls_openpgp_crt_get_mpis (crt, k, key->params, - &key->params_size); - if (ret < 0) - { - gnutls_assert (); - return ret; - } - break; - default: - gnutls_assert (); - return GNUTLS_E_INVALID_REQUEST; - } + ret = + _gnutls_openpgp_crt_get_mpis (crt, k, &key->params); + if (ret < 0) + return gnutls_assert_val(ret); return 0; } @@ -529,7 +478,7 @@ gnutls_pubkey_export (gnutls_pubkey_t key, result = _gnutls_x509_encode_and_copy_PKI_params (spk, "", key->pk_algorithm, - key->params, key->params_size); + &key->params); if (result < 0) { gnutls_assert (); @@ -588,8 +537,8 @@ gnutls_pubkey_get_key_id (gnutls_pubkey_t key, unsigned int flags, } ret = - _gnutls_get_key_id (key->pk_algorithm, key->params, - key->params_size, output_data, output_data_size); + _gnutls_get_key_id (key->pk_algorithm, &key->params, + output_data, output_data_size); if (ret < 0) { gnutls_assert (); @@ -629,14 +578,14 @@ gnutls_pubkey_get_pk_rsa_raw (gnutls_pubkey_t key, return GNUTLS_E_INVALID_REQUEST; } - ret = _gnutls_mpi_dprint (key->params[0], m); + ret = _gnutls_mpi_dprint (key->params.params[0], m); if (ret < 0) { gnutls_assert (); return ret; } - ret = _gnutls_mpi_dprint (key->params[1], e); + ret = _gnutls_mpi_dprint (key->params.params[1], e); if (ret < 0) { gnutls_assert (); @@ -681,7 +630,7 @@ gnutls_pubkey_get_pk_dsa_raw (gnutls_pubkey_t key, } /* P */ - ret = _gnutls_mpi_dprint (key->params[0], p); + ret = _gnutls_mpi_dprint (key->params.params[0], p); if (ret < 0) { gnutls_assert (); @@ -689,7 +638,7 @@ gnutls_pubkey_get_pk_dsa_raw (gnutls_pubkey_t key, } /* Q */ - ret = _gnutls_mpi_dprint (key->params[1], q); + ret = _gnutls_mpi_dprint (key->params.params[1], q); if (ret < 0) { gnutls_assert (); @@ -699,7 +648,7 @@ gnutls_pubkey_get_pk_dsa_raw (gnutls_pubkey_t key, /* G */ - ret = _gnutls_mpi_dprint (key->params[2], g); + ret = _gnutls_mpi_dprint (key->params.params[2], g); if (ret < 0) { gnutls_assert (); @@ -710,7 +659,7 @@ gnutls_pubkey_get_pk_dsa_raw (gnutls_pubkey_t key, /* Y */ - ret = _gnutls_mpi_dprint (key->params[3], y); + ret = _gnutls_mpi_dprint (key->params.params[3], y); if (ret < 0) { gnutls_assert (); @@ -795,8 +744,7 @@ gnutls_pubkey_import (gnutls_pubkey_t key, goto cleanup; } - key->params_size = sizeof (key->params) / sizeof (key->params[0]); - result = _gnutls_get_asn_mpis (spk, "", key->params, &key->params_size); + result = _gnutls_get_asn_mpis (spk, "", &key->params); if (result < 0) { gnutls_assert (); @@ -807,7 +755,7 @@ gnutls_pubkey_import (gnutls_pubkey_t key, * fail. */ key->pk_algorithm = _gnutls_x509_get_pk_algorithm (spk, "", NULL); - key->bits = pubkey_to_bits(key->pk_algorithm, key->params, key->params_size); + key->bits = pubkey_to_bits(key->pk_algorithm, &key->params); result = 0; @@ -844,8 +792,7 @@ gnutls_x509_crt_set_pubkey (gnutls_x509_crt_t crt, gnutls_pubkey_t key) result = _gnutls_x509_encode_and_copy_PKI_params (crt->cert, "tbsCertificate.subjectPublicKeyInfo", key->pk_algorithm, - key->params, - key->params_size); + &key->params); if (result < 0) { @@ -884,7 +831,7 @@ gnutls_x509_crq_set_pubkey (gnutls_x509_crq_t crq, gnutls_pubkey_t key) result = _gnutls_x509_encode_and_copy_PKI_params (crq->crq, "certificationRequestInfo.subjectPKInfo", - key->pk_algorithm, key->params, key->params_size); + key->pk_algorithm, &key->params); if (result < 0) { @@ -992,24 +939,26 @@ gnutls_pubkey_import_rsa_raw (gnutls_pubkey_t key, return GNUTLS_E_INVALID_REQUEST; } + gnutls_pk_params_init(&key->params); + siz = m->size; - if (_gnutls_mpi_scan_nz (&key->params[0], m->data, siz)) + if (_gnutls_mpi_scan_nz (&key->params.params[0], m->data, siz)) { gnutls_assert (); return GNUTLS_E_MPI_SCAN_FAILED; } siz = e->size; - if (_gnutls_mpi_scan_nz (&key->params[1], e->data, siz)) + if (_gnutls_mpi_scan_nz (&key->params.params[1], e->data, siz)) { gnutls_assert (); - _gnutls_mpi_release (&key->params[0]); + _gnutls_mpi_release (&key->params.params[0]); return GNUTLS_E_MPI_SCAN_FAILED; } - key->params_size = RSA_PUBLIC_PARAMS; + key->params.params_nr = RSA_PUBLIC_PARAMS; key->pk_algorithm = GNUTLS_PK_RSA; - key->bits = pubkey_to_bits(GNUTLS_PK_RSA, key->params, key->params_size); + key->bits = pubkey_to_bits(GNUTLS_PK_RSA, &key->params); return 0; } @@ -1038,6 +987,8 @@ gnutls_pubkey_import_dsa_raw (gnutls_pubkey_t key, { size_t siz = 0; + gnutls_pk_params_init(&key->params); + if (key == NULL) { gnutls_assert (); @@ -1045,42 +996,42 @@ gnutls_pubkey_import_dsa_raw (gnutls_pubkey_t key, } siz = p->size; - if (_gnutls_mpi_scan_nz (&key->params[0], p->data, siz)) + if (_gnutls_mpi_scan_nz (&key->params.params[0], p->data, siz)) { gnutls_assert (); return GNUTLS_E_MPI_SCAN_FAILED; } siz = q->size; - if (_gnutls_mpi_scan_nz (&key->params[1], q->data, siz)) + if (_gnutls_mpi_scan_nz (&key->params.params[1], q->data, siz)) { gnutls_assert (); - _gnutls_mpi_release (&key->params[0]); + _gnutls_mpi_release (&key->params.params[0]); return GNUTLS_E_MPI_SCAN_FAILED; } siz = g->size; - if (_gnutls_mpi_scan_nz (&key->params[2], g->data, siz)) + if (_gnutls_mpi_scan_nz (&key->params.params[2], g->data, siz)) { gnutls_assert (); - _gnutls_mpi_release (&key->params[1]); - _gnutls_mpi_release (&key->params[0]); + _gnutls_mpi_release (&key->params.params[1]); + _gnutls_mpi_release (&key->params.params[0]); return GNUTLS_E_MPI_SCAN_FAILED; } siz = y->size; - if (_gnutls_mpi_scan_nz (&key->params[3], y->data, siz)) + if (_gnutls_mpi_scan_nz (&key->params.params[3], y->data, siz)) { gnutls_assert (); - _gnutls_mpi_release (&key->params[2]); - _gnutls_mpi_release (&key->params[1]); - _gnutls_mpi_release (&key->params[0]); + _gnutls_mpi_release (&key->params.params[2]); + _gnutls_mpi_release (&key->params.params[1]); + _gnutls_mpi_release (&key->params.params[0]); return GNUTLS_E_MPI_SCAN_FAILED; } - key->params_size = DSA_PUBLIC_PARAMS; + key->params.params_nr = DSA_PUBLIC_PARAMS; key->pk_algorithm = GNUTLS_PK_DSA; - key->bits = pubkey_to_bits(GNUTLS_PK_DSA, key->params, key->params_size); + key->bits = pubkey_to_bits(GNUTLS_PK_DSA, &key->params); return 0; @@ -1116,7 +1067,7 @@ gnutls_pubkey_verify_data (gnutls_pubkey_t pubkey, unsigned int flags, } ret = pubkey_verify_sig( data, NULL, signature, pubkey->pk_algorithm, - pubkey->params, pubkey->params_size); + &pubkey->params); if (ret < 0) { gnutls_assert(); @@ -1151,12 +1102,11 @@ gnutls_pubkey_verify_hash (gnutls_pubkey_t key, unsigned int flags, } if (flags & GNUTLS_PUBKEY_VERIFY_FLAG_TLS_RSA) - return _gnutls_rsa_verify (hash, signature, key->params, - key->params_size, 1); + return _gnutls_rsa_verify (hash, signature, &key->params, 1); else { return pubkey_verify_sig (NULL, hash, signature, key->pk_algorithm, - key->params, key->params_size); + &key->params); } } @@ -1186,7 +1136,7 @@ gnutls_pubkey_get_verify_algorithm (gnutls_pubkey_t key, return _gnutls_x509_verify_algorithm ((gnutls_mac_algorithm_t *) hash, signature, key->pk_algorithm, - key->params, key->params_size); + &key->params); } @@ -1196,7 +1146,7 @@ int _gnutls_pubkey_compatible_with_sig(gnutls_pubkey_t pubkey, gnutls_protocol_t { if (pubkey->pk_algorithm == GNUTLS_PK_DSA) { /* override */ - int hash_algo = _gnutls_dsa_q_to_hash (pubkey->params[1]); + int hash_algo = _gnutls_dsa_q_to_hash (pubkey->params.params[1]); /* DSA keys over 1024 bits cannot be used with TLS 1.x, x<2 */ if (!_gnutls_version_has_selectable_sighash (ver)) @@ -1218,27 +1168,18 @@ int _gnutls_pubkey_compatible_with_sig(gnutls_pubkey_t pubkey, gnutls_protocol_t /* Returns zero if the public key has more than 512 bits */ int _gnutls_pubkey_is_over_rsa_512(gnutls_pubkey_t pubkey) { - if (pubkey->pk_algorithm == GNUTLS_PK_RSA && _gnutls_mpi_get_nbits (pubkey->params[0]) > 512) + if (pubkey->pk_algorithm == GNUTLS_PK_RSA && _gnutls_mpi_get_nbits (pubkey->params.params[0]) > 512) return 0; else return GNUTLS_E_INVALID_REQUEST; /* doesn't matter */ } -/* Returns the public key. The mpis are the internal copy. Should - * not be deallocated. +/* Returns the public key. */ int _gnutls_pubkey_get_mpis (gnutls_pubkey_t key, - bigint_t * params, int *params_size) + gnutls_pk_params_st * params) { - int i; - - if (*params_size < key->params_size) - return gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER); - - for (i=0;i<key->params_size;i++) - params[i] = key->params[i]; - - return 0; + return _gnutls_pk_params_copy(params, &key->params); } diff --git a/lib/gnutls_rsa_export.c b/lib/gnutls_rsa_export.c index e867927c56..858e5a6d4a 100644 --- a/lib/gnutls_rsa_export.c +++ b/lib/gnutls_rsa_export.c @@ -37,7 +37,7 @@ /* returns e and m, depends on the requested bits. * We only support limited key sizes. */ -const bigint_t * +const gnutls_pk_params_st* _gnutls_rsa_params_to_mpi (gnutls_rsa_params_t rsa_params) { if (rsa_params == NULL) @@ -45,7 +45,7 @@ _gnutls_rsa_params_to_mpi (gnutls_rsa_params_t rsa_params) return NULL; } - return rsa_params->params; + return &rsa_params->params; } /** @@ -201,7 +201,7 @@ gnutls_rsa_params_export_pkcs1 (gnutls_rsa_params_t params, /** * gnutls_rsa_params_export_raw: - * @params: a structure that holds the rsa parameters + * @rsa: a structure that holds the rsa parameters * @m: will hold the modulus * @e: will hold the public exponent * @d: will hold the private exponent @@ -217,7 +217,7 @@ gnutls_rsa_params_export_pkcs1 (gnutls_rsa_params_t params, * Returns: %GNUTLS_E_SUCCESS on success, or an negative error code. **/ int -gnutls_rsa_params_export_raw (gnutls_rsa_params_t params, +gnutls_rsa_params_export_raw (gnutls_rsa_params_t rsa, gnutls_datum_t * m, gnutls_datum_t * e, gnutls_datum_t * d, gnutls_datum_t * p, gnutls_datum_t * q, gnutls_datum_t * u, @@ -225,7 +225,7 @@ gnutls_rsa_params_export_raw (gnutls_rsa_params_t params, { int ret; - ret = gnutls_x509_privkey_export_rsa_raw (params, m, e, d, p, q, u); + ret = gnutls_x509_privkey_export_rsa_raw (rsa, m, e, d, p, q, u); if (ret < 0) { gnutls_assert (); @@ -233,7 +233,7 @@ gnutls_rsa_params_export_raw (gnutls_rsa_params_t params, } if (bits) - *bits = _gnutls_mpi_get_nbits (params->params[3]); + *bits = _gnutls_mpi_get_nbits (rsa->params.params[3]); return 0; } diff --git a/lib/gnutls_rsa_export.h b/lib/gnutls_rsa_export.h index d148a911c4..fa64189868 100644 --- a/lib/gnutls_rsa_export.h +++ b/lib/gnutls_rsa_export.h @@ -23,5 +23,5 @@ * */ -const bigint_t *_gnutls_rsa_params_to_mpi (gnutls_rsa_params_t); +const gnutls_pk_params_st *_gnutls_rsa_params_to_mpi (gnutls_rsa_params_t); int _gnutls_peers_cert_less_512 (gnutls_session_t session); diff --git a/lib/gnutls_sig.c b/lib/gnutls_sig.c index 1e35478f37..1f2ac23ab3 100644 --- a/lib/gnutls_sig.c +++ b/lib/gnutls_sig.c @@ -166,8 +166,8 @@ _gnutls_handshake_sign_data (gnutls_session_t session, gnutls_pcert_st* cert, * given data. The output will be allocated and be put in signature. */ int -_gnutls_soft_sign (gnutls_pk_algorithm_t algo, bigint_t * params, - int params_size, const gnutls_datum_t * data, +_gnutls_soft_sign (gnutls_pk_algorithm_t algo, gnutls_pk_params_st * params, + const gnutls_datum_t * data, gnutls_datum_t * signature) { int ret; @@ -176,8 +176,7 @@ _gnutls_soft_sign (gnutls_pk_algorithm_t algo, bigint_t * params, { case GNUTLS_PK_RSA: /* encrypt */ - if ((ret = _gnutls_pkcs1_rsa_encrypt (signature, data, params, - params_size, 1)) < 0) + if ((ret = _gnutls_pkcs1_rsa_encrypt (signature, data, params, 1)) < 0) { gnutls_assert (); return ret; @@ -186,7 +185,7 @@ _gnutls_soft_sign (gnutls_pk_algorithm_t algo, bigint_t * params, break; case GNUTLS_PK_DSA: /* sign */ - if ((ret = _gnutls_dsa_sign (signature, data, params, params_size)) < 0) + if ((ret = _gnutls_dsa_sign (signature, data, params)) < 0) { gnutls_assert (); return ret; @@ -747,7 +746,7 @@ _gnutls_handshake_sign_cert_vrfy (gnutls_session_t session, int pk_hash_data (gnutls_pk_algorithm_t pk, gnutls_digest_algorithm_t hash, - bigint_t * params, + gnutls_pk_params_st* params, const gnutls_datum_t * data, gnutls_datum_t * digest) { int ret; @@ -757,7 +756,7 @@ pk_hash_data (gnutls_pk_algorithm_t pk, gnutls_digest_algorithm_t hash, case GNUTLS_PK_RSA: break; case GNUTLS_PK_DSA: - if (params && hash != _gnutls_dsa_q_to_hash (params[1])) + if (params && hash != _gnutls_dsa_q_to_hash (params->params[1])) { gnutls_assert (); return GNUTLS_E_INVALID_REQUEST; diff --git a/lib/gnutls_sig.h b/lib/gnutls_sig.h index 44bbce0d14..3b6957ac58 100644 --- a/lib/gnutls_sig.h +++ b/lib/gnutls_sig.h @@ -52,14 +52,14 @@ int _gnutls_handshake_verify_data (gnutls_session_t session, gnutls_sign_algorithm_t algo); int _gnutls_soft_sign (gnutls_pk_algorithm_t algo, - bigint_t * params, int params_size, + gnutls_pk_params_st* params, const gnutls_datum_t * data, gnutls_datum_t * signature); int pk_prepare_hash (gnutls_pk_algorithm_t pk, gnutls_digest_algorithm_t hash, gnutls_datum_t * output); int pk_hash_data (gnutls_pk_algorithm_t pk, gnutls_digest_algorithm_t hash, - bigint_t * params, const gnutls_datum_t * data, + gnutls_pk_params_st * params, const gnutls_datum_t * data, gnutls_datum_t * digest); int diff --git a/lib/gnutls_state.c b/lib/gnutls_state.c index 5cc09b5e49..0a4ee1d17a 100644 --- a/lib/gnutls_state.c +++ b/lib/gnutls_state.c @@ -67,7 +67,7 @@ _gnutls_session_cert_type_set (gnutls_session_t session, void _gnutls_session_ecc_curve_set (gnutls_session_t session, - ecc_curve_t c) + gnutls_ecc_curve_t c) { _gnutls_handshake_log("HSK[%p]: Selected ECC curve (%d)\n", session, c); session->security_parameters.ecc_curve = c; @@ -1188,6 +1188,9 @@ _gnutls_session_is_ecc (gnutls_session_t session) { gnutls_kx_algorithm_t kx; + /* We get the key exchange algorithm through the ciphersuite because + * the negotiated key exchange might not have been set yet. + */ kx = _gnutls_cipher_suite_get_kx_algo (&session-> security_parameters.current_cipher_suite); diff --git a/lib/gnutls_state.h b/lib/gnutls_state.h index 7e51463d8e..3266dd999d 100644 --- a/lib/gnutls_state.h +++ b/lib/gnutls_state.h @@ -31,7 +31,7 @@ void _gnutls_session_cert_type_set (gnutls_session_t session, gnutls_certificate_type_t); -inline static ecc_curve_t _gnutls_session_ecc_curve_get(gnutls_session_t session) +inline static gnutls_ecc_curve_t _gnutls_session_ecc_curve_get(gnutls_session_t session) { return session->security_parameters.ecc_curve; } @@ -40,7 +40,7 @@ int _gnutls_session_is_ecc (gnutls_session_t session); void _gnutls_session_ecc_curve_set (gnutls_session_t session, - ecc_curve_t c); + gnutls_ecc_curve_t c); void _gnutls_record_set_default_version (gnutls_session_t session, diff --git a/lib/includes/gnutls/crypto.h b/lib/includes/gnutls/crypto.h index 4ff4510d9a..80fbf825d9 100644 --- a/lib/includes/gnutls/crypto.h +++ b/lib/includes/gnutls/crypto.h @@ -279,7 +279,7 @@ extern "C" * [3] is y (public key) * [4] is x (private key only) * - * ECDH: + * ECC: * [0] is prime * [1] is order * [2] is A diff --git a/lib/includes/gnutls/gnutls.h.in b/lib/includes/gnutls/gnutls.h.in index 18097cc22f..58e53cd543 100644 --- a/lib/includes/gnutls/gnutls.h.in +++ b/lib/includes/gnutls/gnutls.h.in @@ -622,6 +622,25 @@ extern "C" } gnutls_sign_algorithm_t; /** + * gnutls_ecc_curve_t: + * @GNUTLS_ECC_CURVE_INVALID: Cannot be known + * @GNUTLS_ECC_CURVE_SECP224R1: the SECP224R1 curve + * @GNUTLS_ECC_CURVE_SECP256R1: the SECP256R1 curve + * @GNUTLS_ECC_CURVE_SECP384R1: the SECP384R1 curve + * @GNUTLS_ECC_CURVE_SECP521R1: the SECP521R1 curve + * + * Enumeration of ECC curves. + */ +typedef enum +{ + GNUTLS_ECC_CURVE_INVALID=0, + GNUTLS_ECC_CURVE_SECP224R1, + GNUTLS_ECC_CURVE_SECP256R1, + GNUTLS_ECC_CURVE_SECP384R1, + GNUTLS_ECC_CURVE_SECP521R1, +} gnutls_ecc_curve_t; + + /** * gnutls_sec_param_t: * @GNUTLS_SEC_PARAM_UNKNOWN: Cannot be known * @GNUTLS_SEC_PARAM_WEAK: 50 or less bits of security @@ -721,6 +740,10 @@ extern "C" unsigned int gnutls_sec_param_to_pk_bits (gnutls_pk_algorithm_t algo, gnutls_sec_param_t param); +/* Elliptic curves */ +const char * gnutls_ecc_curve_get_name (gnutls_ecc_curve_t curve); +int gnutls_ecc_curve_get_size (gnutls_ecc_curve_t curve); + /* get information on the current session */ gnutls_cipher_algorithm_t gnutls_cipher_get (gnutls_session_t session); gnutls_kx_algorithm_t gnutls_kx_get (gnutls_session_t session); @@ -1772,6 +1795,7 @@ extern "C" #define GNUTLS_E_TIMEDOUT -319 #define GNUTLS_E_USER_ERROR -320 #define GNUTLS_E_ECC_NO_SUPPORTED_CURVES -321 +#define GNUTLS_E_ECC_UNSUPPORTED_CURVE -322 #define GNUTLS_E_UNIMPLEMENTED_FEATURE -1250 diff --git a/lib/libgnutls.map b/lib/libgnutls.map index ccae4576a0..1fe7dcfd9c 100644 --- a/lib/libgnutls.map +++ b/lib/libgnutls.map @@ -713,6 +713,8 @@ GNUTLS_3_0_0 { gnutls_certificate_set_retrieve_function2; gnutls_x509_trust_list_get_issuer; gnutls_global_set_audit_log_function; + gnutls_ecc_curve_get_name; + gnutls_ecc_curve_get_size; } GNUTLS_2_12; GNUTLS_PRIVATE { diff --git a/lib/nettle/ecc_test.c b/lib/nettle/ecc_test.c index 5dc99b89ab..30250faf3a 100644 --- a/lib/nettle/ecc_test.c +++ b/lib/nettle/ecc_test.c @@ -54,7 +54,7 @@ ecc_test (void) { const gnutls_ecc_curve_entry_st *st = _gnutls_ecc_curve_get_params (i); - printf ("Testing %s (%d)\n", _gnutls_ecc_curve_get_name (i), i); + printf ("Testing %s (%d)\n", gnutls_ecc_curve_get_name (i), i); if (mpz_set_str (A, (char *) st->A, 16) != 0) { diff --git a/lib/nettle/pk.c b/lib/nettle/pk.c index 3af3e20678..971e6f0f0e 100644 --- a/lib/nettle/pk.c +++ b/lib/nettle/pk.c @@ -555,7 +555,7 @@ cleanup: static inline int is_supported_curve(int curve) { - if (_gnutls_ecc_curve_get_name(curve) != NULL) + if (gnutls_ecc_curve_get_name(curve) != NULL) return 1; else return 0; @@ -703,7 +703,7 @@ rsa_fail: return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR); params->params_nr = 0; - for (i = 0; i < ECDH_PRIVATE_PARAMS; i++) + for (i = 0; i < ECC_PRIVATE_PARAMS; i++) { params->params[i] = _gnutls_mpi_alloc_like(&key.prime); if (params->params[i] == NULL) @@ -773,7 +773,7 @@ wrap_nettle_pk_fixup (gnutls_pk_algorithm_t algo, _gnutls_mpi_release (¶ms->params[6]); _gnutls_mpi_release (¶ms->params[7]); - result = _gnutls_calc_rsa_exp (params->params, RSA_PRIVATE_PARAMS - 2); + result = _gnutls_calc_rsa_exp (params); if (result < 0) { gnutls_assert (); diff --git a/lib/openpgp/openpgp_int.h b/lib/openpgp/openpgp_int.h index 7ad6d297ce..9a17b049b3 100644 --- a/lib/openpgp/openpgp_int.h +++ b/lib/openpgp/openpgp_int.h @@ -49,12 +49,11 @@ unsigned int _gnutls_get_pgp_key_usage (unsigned int pgp_usage); int _gnutls_openpgp_crt_get_mpis (gnutls_openpgp_crt_t cert, uint32_t keyid[2], - bigint_t * params, int *params_size); + gnutls_pk_params_st * params); int _gnutls_openpgp_privkey_get_mpis (gnutls_openpgp_privkey_t pkey, - uint32_t keyid[2], bigint_t * params, - int *params_size); + uint32_t keyid[2], gnutls_pk_params_st* params); cdk_packet_t _gnutls_openpgp_find_key (cdk_kbnode_t knode, uint32_t keyid[2], unsigned int priv); diff --git a/lib/openpgp/pgp.c b/lib/openpgp/pgp.c index 9630448bed..45b93ffe77 100644 --- a/lib/openpgp/pgp.c +++ b/lib/openpgp/pgp.c @@ -1187,7 +1187,7 @@ _gnutls_read_pgp_mpi (cdk_packet_t pkt, unsigned int priv, size_t idx, int _gnutls_openpgp_crt_get_mpis (gnutls_openpgp_crt_t cert, uint32_t * keyid /* [2] */ , - bigint_t * params, int *params_size) + gnutls_pk_params_st * params) { int result, i; int pk_algorithm, local_params; @@ -1219,32 +1219,23 @@ _gnutls_openpgp_crt_get_mpis (gnutls_openpgp_crt_t cert, return GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE; } - if (*params_size < local_params) - { - gnutls_assert (); - return GNUTLS_E_INTERNAL_ERROR; - } - - *params_size = local_params; + gnutls_pk_params_init(params); for (i = 0; i < local_params; i++) { - result = _gnutls_read_pgp_mpi (pkt, 0, i, ¶ms[i]); + result = _gnutls_read_pgp_mpi (pkt, 0, i, ¶ms->params[i]); if (result < 0) { gnutls_assert (); goto error; } + params->params_nr++; } return 0; error: - { - int j; - for (j = 0; j < i; j++) - _gnutls_mpi_release (¶ms[j]); - } + gnutls_pk_params_release(params); return result; } @@ -1255,11 +1246,12 @@ static int _get_pk_rsa_raw (gnutls_openpgp_crt_t crt, gnutls_openpgp_keyid_t keyid, gnutls_datum_t * m, gnutls_datum_t * e) { - int pk_algorithm, ret, i; + int pk_algorithm, ret; cdk_packet_t pkt; uint32_t kid32[2]; - bigint_t params[MAX_PUBLIC_PARAMS_SIZE]; - int params_size = MAX_PUBLIC_PARAMS_SIZE; + gnutls_pk_params_st params; + + gnutls_pk_params_init(¶ms); if (crt == NULL) { @@ -1284,21 +1276,21 @@ _get_pk_rsa_raw (gnutls_openpgp_crt_t crt, gnutls_openpgp_keyid_t keyid, return GNUTLS_E_INVALID_REQUEST; } - ret = _gnutls_openpgp_crt_get_mpis (crt, kid32, params, ¶ms_size); + ret = _gnutls_openpgp_crt_get_mpis (crt, kid32, ¶ms); if (ret < 0) { gnutls_assert (); return ret; } - ret = _gnutls_mpi_dprint (params[0], m); + ret = _gnutls_mpi_dprint (params.params[0], m); if (ret < 0) { gnutls_assert (); goto cleanup; } - ret = _gnutls_mpi_dprint (params[1], e); + ret = _gnutls_mpi_dprint (params.params[1], e); if (ret < 0) { gnutls_assert (); @@ -1309,10 +1301,7 @@ _get_pk_rsa_raw (gnutls_openpgp_crt_t crt, gnutls_openpgp_keyid_t keyid, ret = 0; cleanup: - for (i = 0; i < params_size; i++) - { - _gnutls_mpi_release (¶ms[i]); - } + gnutls_pk_params_release(¶ms); return ret; } @@ -1321,11 +1310,12 @@ _get_pk_dsa_raw (gnutls_openpgp_crt_t crt, gnutls_openpgp_keyid_t keyid, gnutls_datum_t * p, gnutls_datum_t * q, gnutls_datum_t * g, gnutls_datum_t * y) { - int pk_algorithm, ret, i; + int pk_algorithm, ret; cdk_packet_t pkt; uint32_t kid32[2]; - bigint_t params[MAX_PUBLIC_PARAMS_SIZE]; - int params_size = MAX_PUBLIC_PARAMS_SIZE; + gnutls_pk_params_st params; + + gnutls_pk_params_init(¶ms); if (crt == NULL) { @@ -1350,7 +1340,7 @@ _get_pk_dsa_raw (gnutls_openpgp_crt_t crt, gnutls_openpgp_keyid_t keyid, return GNUTLS_E_INVALID_REQUEST; } - ret = _gnutls_openpgp_crt_get_mpis (crt, kid32, params, ¶ms_size); + ret = _gnutls_openpgp_crt_get_mpis (crt, kid32, ¶ms); if (ret < 0) { gnutls_assert (); @@ -1358,7 +1348,7 @@ _get_pk_dsa_raw (gnutls_openpgp_crt_t crt, gnutls_openpgp_keyid_t keyid, } /* P */ - ret = _gnutls_mpi_dprint (params[0], p); + ret = _gnutls_mpi_dprint (params.params[0], p); if (ret < 0) { gnutls_assert (); @@ -1366,7 +1356,7 @@ _get_pk_dsa_raw (gnutls_openpgp_crt_t crt, gnutls_openpgp_keyid_t keyid, } /* Q */ - ret = _gnutls_mpi_dprint (params[1], q); + ret = _gnutls_mpi_dprint (params.params[1], q); if (ret < 0) { gnutls_assert (); @@ -1376,7 +1366,7 @@ _get_pk_dsa_raw (gnutls_openpgp_crt_t crt, gnutls_openpgp_keyid_t keyid, /* G */ - ret = _gnutls_mpi_dprint (params[2], g); + ret = _gnutls_mpi_dprint (params.params[2], g); if (ret < 0) { gnutls_assert (); @@ -1387,7 +1377,7 @@ _get_pk_dsa_raw (gnutls_openpgp_crt_t crt, gnutls_openpgp_keyid_t keyid, /* Y */ - ret = _gnutls_mpi_dprint (params[3], y); + ret = _gnutls_mpi_dprint (params.params[3], y); if (ret < 0) { gnutls_assert (); @@ -1400,10 +1390,7 @@ _get_pk_dsa_raw (gnutls_openpgp_crt_t crt, gnutls_openpgp_keyid_t keyid, ret = 0; cleanup: - for (i = 0; i < params_size; i++) - { - _gnutls_mpi_release (¶ms[i]); - } + gnutls_pk_params_release(¶ms); return ret; } diff --git a/lib/openpgp/privkey.c b/lib/openpgp/privkey.c index 2d0a39c45a..d596637496 100644 --- a/lib/openpgp/privkey.c +++ b/lib/openpgp/privkey.c @@ -712,14 +712,13 @@ gnutls_openpgp_privkey_get_subkey_fingerprint (gnutls_openpgp_privkey_t key, int _gnutls_openpgp_privkey_get_mpis (gnutls_openpgp_privkey_t pkey, uint32_t * keyid /*[2] */ , - bigint_t * params, int *params_size) + gnutls_pk_params_st * params) { int result, i; int pk_algorithm; - gnutls_pk_params_st pk_params; cdk_packet_t pkt; - memset (&pk_params, 0, sizeof (pk_params)); + gnutls_pk_params_init(params); if (keyid == NULL) pkt = cdk_kbnode_find_packet (pkey->knode, CDK_PKT_SECRET_KEY); @@ -740,19 +739,19 @@ _gnutls_openpgp_privkey_get_mpis (gnutls_openpgp_privkey_t pkey, case GNUTLS_PK_RSA: /* openpgp does not hold all parameters as in PKCS #1 */ - pk_params.params_nr = RSA_PRIVATE_PARAMS - 2; + params->params_nr = RSA_PRIVATE_PARAMS - 2; break; case GNUTLS_PK_DSA: - pk_params.params_nr = DSA_PRIVATE_PARAMS; + params->params_nr = DSA_PRIVATE_PARAMS; break; default: gnutls_assert (); return GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE; } - for (i = 0; i < pk_params.params_nr; i++) + for (i = 0; i < params->params_nr; i++) { - result = _gnutls_read_pgp_mpi (pkt, 1, i, &pk_params.params[i]); + result = _gnutls_read_pgp_mpi (pkt, 1, i, ¶ms->params[i]); if (result < 0) { gnutls_assert (); @@ -763,31 +762,17 @@ _gnutls_openpgp_privkey_get_mpis (gnutls_openpgp_privkey_t pkey, /* fixup will generate exp1 and exp2 that are not * available here. */ - result = _gnutls_pk_fixup (pk_algorithm, GNUTLS_IMPORT, &pk_params); + result = _gnutls_pk_fixup (pk_algorithm, GNUTLS_IMPORT, params); if (result < 0) { gnutls_assert (); goto error; } - if (*params_size < pk_params.params_nr) - { - gnutls_assert (); - return GNUTLS_E_INTERNAL_ERROR; - } - - *params_size = pk_params.params_nr; - for (i = 0; i < pk_params.params_nr; i++) - params[i] = pk_params.params[i]; - return 0; error: - { - int j; - for (j = 0; j < i; j++) - _gnutls_mpi_release (&pk_params.params[j]); - } + gnutls_pk_params_release(params); return result; } @@ -800,11 +785,10 @@ _get_sk_rsa_raw (gnutls_openpgp_privkey_t pkey, gnutls_openpgp_keyid_t keyid, gnutls_datum_t * d, gnutls_datum_t * p, gnutls_datum_t * q, gnutls_datum_t * u) { - int pk_algorithm, ret, i; + int pk_algorithm, ret; cdk_packet_t pkt; uint32_t kid32[2]; - bigint_t params[MAX_PRIV_PARAMS_SIZE]; - int params_size = MAX_PRIV_PARAMS_SIZE; + gnutls_pk_params_st params; if (pkey == NULL) { @@ -830,21 +814,21 @@ _get_sk_rsa_raw (gnutls_openpgp_privkey_t pkey, gnutls_openpgp_keyid_t keyid, return GNUTLS_E_INVALID_REQUEST; } - ret = _gnutls_openpgp_privkey_get_mpis (pkey, kid32, params, ¶ms_size); + ret = _gnutls_openpgp_privkey_get_mpis (pkey, kid32, ¶ms); if (ret < 0) { gnutls_assert (); return ret; } - ret = _gnutls_mpi_dprint (params[0], m); + ret = _gnutls_mpi_dprint (params.params[0], m); if (ret < 0) { gnutls_assert (); goto cleanup; } - ret = _gnutls_mpi_dprint (params[1], e); + ret = _gnutls_mpi_dprint (params.params[1], e); if (ret < 0) { gnutls_assert (); @@ -852,7 +836,7 @@ _get_sk_rsa_raw (gnutls_openpgp_privkey_t pkey, gnutls_openpgp_keyid_t keyid, goto cleanup; } - ret = _gnutls_mpi_dprint (params[2], d); + ret = _gnutls_mpi_dprint (params.params[2], d); if (ret < 0) { gnutls_assert (); @@ -861,7 +845,7 @@ _get_sk_rsa_raw (gnutls_openpgp_privkey_t pkey, gnutls_openpgp_keyid_t keyid, goto cleanup; } - ret = _gnutls_mpi_dprint (params[3], p); + ret = _gnutls_mpi_dprint (params.params[3], p); if (ret < 0) { gnutls_assert (); @@ -871,7 +855,7 @@ _get_sk_rsa_raw (gnutls_openpgp_privkey_t pkey, gnutls_openpgp_keyid_t keyid, goto cleanup; } - ret = _gnutls_mpi_dprint (params[4], q); + ret = _gnutls_mpi_dprint (params.params[4], q); if (ret < 0) { gnutls_assert (); @@ -882,7 +866,7 @@ _get_sk_rsa_raw (gnutls_openpgp_privkey_t pkey, gnutls_openpgp_keyid_t keyid, goto cleanup; } - ret = _gnutls_mpi_dprint (params[5], u); + ret = _gnutls_mpi_dprint (params.params[5], u); if (ret < 0) { gnutls_assert (); @@ -897,10 +881,7 @@ _get_sk_rsa_raw (gnutls_openpgp_privkey_t pkey, gnutls_openpgp_keyid_t keyid, ret = 0; cleanup: - for (i = 0; i < params_size; i++) - { - _gnutls_mpi_release (¶ms[i]); - } + gnutls_pk_params_release(¶ms); return ret; } @@ -909,11 +890,10 @@ _get_sk_dsa_raw (gnutls_openpgp_privkey_t pkey, gnutls_openpgp_keyid_t keyid, gnutls_datum_t * p, gnutls_datum_t * q, gnutls_datum_t * g, gnutls_datum_t * y, gnutls_datum_t * x) { - int pk_algorithm, ret, i; + int pk_algorithm, ret; cdk_packet_t pkt; uint32_t kid32[2]; - bigint_t params[MAX_PRIV_PARAMS_SIZE]; - int params_size = MAX_PRIV_PARAMS_SIZE; + gnutls_pk_params_st params; if (pkey == NULL) { @@ -939,7 +919,7 @@ _get_sk_dsa_raw (gnutls_openpgp_privkey_t pkey, gnutls_openpgp_keyid_t keyid, return GNUTLS_E_INVALID_REQUEST; } - ret = _gnutls_openpgp_privkey_get_mpis (pkey, kid32, params, ¶ms_size); + ret = _gnutls_openpgp_privkey_get_mpis (pkey, kid32, ¶ms); if (ret < 0) { gnutls_assert (); @@ -947,7 +927,7 @@ _get_sk_dsa_raw (gnutls_openpgp_privkey_t pkey, gnutls_openpgp_keyid_t keyid, } /* P */ - ret = _gnutls_mpi_dprint (params[0], p); + ret = _gnutls_mpi_dprint (params.params[0], p); if (ret < 0) { gnutls_assert (); @@ -955,7 +935,7 @@ _get_sk_dsa_raw (gnutls_openpgp_privkey_t pkey, gnutls_openpgp_keyid_t keyid, } /* Q */ - ret = _gnutls_mpi_dprint (params[1], q); + ret = _gnutls_mpi_dprint (params.params[1], q); if (ret < 0) { gnutls_assert (); @@ -965,7 +945,7 @@ _get_sk_dsa_raw (gnutls_openpgp_privkey_t pkey, gnutls_openpgp_keyid_t keyid, /* G */ - ret = _gnutls_mpi_dprint (params[2], g); + ret = _gnutls_mpi_dprint (params.params[2], g); if (ret < 0) { gnutls_assert (); @@ -976,7 +956,7 @@ _get_sk_dsa_raw (gnutls_openpgp_privkey_t pkey, gnutls_openpgp_keyid_t keyid, /* Y */ - ret = _gnutls_mpi_dprint (params[3], y); + ret = _gnutls_mpi_dprint (params.params[3], y); if (ret < 0) { gnutls_assert (); @@ -986,7 +966,7 @@ _get_sk_dsa_raw (gnutls_openpgp_privkey_t pkey, gnutls_openpgp_keyid_t keyid, goto cleanup; } - ret = _gnutls_mpi_dprint (params[4], x); + ret = _gnutls_mpi_dprint (params.params[4], x); if (ret < 0) { gnutls_assert (); @@ -1000,10 +980,7 @@ _get_sk_dsa_raw (gnutls_openpgp_privkey_t pkey, gnutls_openpgp_keyid_t keyid, ret = 0; cleanup: - for (i = 0; i < params_size; i++) - { - _gnutls_mpi_release (¶ms[i]); - } + gnutls_pk_params_release(¶ms); return ret; } @@ -1249,9 +1226,8 @@ gnutls_openpgp_privkey_sign_hash (gnutls_openpgp_privkey_t key, const gnutls_datum_t * hash, gnutls_datum_t * signature) { - int result, i; - bigint_t params[MAX_PRIV_PARAMS_SIZE]; - int params_size = MAX_PRIV_PARAMS_SIZE; + int result; + gnutls_pk_params_st params; int pk_algorithm; uint8_t keyid[GNUTLS_OPENPGP_KEYID_SIZE]; @@ -1273,13 +1249,12 @@ gnutls_openpgp_privkey_sign_hash (gnutls_openpgp_privkey_t key, pk_algorithm = gnutls_openpgp_privkey_get_subkey_pk_algorithm (key, idx, NULL); result = - _gnutls_openpgp_privkey_get_mpis (key, kid, params, ¶ms_size); + _gnutls_openpgp_privkey_get_mpis (key, kid, ¶ms); } else { pk_algorithm = gnutls_openpgp_privkey_get_pk_algorithm (key, NULL); - result = _gnutls_openpgp_privkey_get_mpis (key, NULL, - params, ¶ms_size); + result = _gnutls_openpgp_privkey_get_mpis (key, NULL, ¶ms); } if (result < 0) @@ -1290,10 +1265,9 @@ gnutls_openpgp_privkey_sign_hash (gnutls_openpgp_privkey_t key, result = - _gnutls_soft_sign (pk_algorithm, params, params_size, hash, signature); + _gnutls_soft_sign (pk_algorithm, ¶ms, hash, signature); - for (i = 0; i < params_size; i++) - _gnutls_mpi_release (¶ms[i]); + gnutls_pk_params_release(¶ms); if (result < 0) { @@ -1325,8 +1299,7 @@ _gnutls_openpgp_privkey_decrypt_data (gnutls_openpgp_privkey_t key, gnutls_datum_t * plaintext) { int result, i; - bigint_t params[MAX_PRIV_PARAMS_SIZE]; - int params_size = MAX_PRIV_PARAMS_SIZE; + gnutls_pk_params_st params; int pk_algorithm; uint8_t keyid[GNUTLS_OPENPGP_KEYID_SIZE]; @@ -1342,8 +1315,7 @@ _gnutls_openpgp_privkey_decrypt_data (gnutls_openpgp_privkey_t key, uint32_t kid[2]; KEYID_IMPORT (kid, keyid); - result = _gnutls_openpgp_privkey_get_mpis (key, kid, - params, ¶ms_size); + result = _gnutls_openpgp_privkey_get_mpis (key, kid, ¶ms); i = gnutls_openpgp_privkey_get_subkey_idx (key, keyid); @@ -1353,8 +1325,7 @@ _gnutls_openpgp_privkey_decrypt_data (gnutls_openpgp_privkey_t key, { pk_algorithm = gnutls_openpgp_privkey_get_pk_algorithm (key, NULL); - result = _gnutls_openpgp_privkey_get_mpis (key, NULL, - params, ¶ms_size); + result = _gnutls_openpgp_privkey_get_mpis (key, NULL, ¶ms); } @@ -1371,10 +1342,9 @@ _gnutls_openpgp_privkey_decrypt_data (gnutls_openpgp_privkey_t key, } result = - _gnutls_pkcs1_rsa_decrypt (plaintext, ciphertext, params, params_size, 2); + _gnutls_pkcs1_rsa_decrypt (plaintext, ciphertext, ¶ms, 2); - for (i = 0; i < params_size; i++) - _gnutls_mpi_release (¶ms[i]); + gnutls_pk_params_release(¶ms); if (result < 0) { diff --git a/lib/x509/Makefile.am b/lib/x509/Makefile.am index 7b022bf765..4af52a1649 100644 --- a/lib/x509/Makefile.am +++ b/lib/x509/Makefile.am @@ -34,8 +34,8 @@ endif noinst_LTLIBRARIES = libgnutls_x509.la libgnutls_x509_la_SOURCES = \ - common.c \ - common.h \ + common.c key_encode.c \ + common.h key_decode.c \ crl.c \ crl_write.c \ crq.c \ diff --git a/lib/x509/common.c b/lib/x509/common.c index 6b76d28b00..9bbfd387bc 100644 --- a/lib/x509/common.c +++ b/lib/x509/common.c @@ -1183,8 +1183,7 @@ int _gnutls_x509_encode_and_copy_PKI_params (ASN1_TYPE dst, const char *dst_name, gnutls_pk_algorithm_t - pk_algorithm, bigint_t * params, - int params_size) + pk_algorithm, gnutls_pk_params_st * params) { const char *pk; gnutls_datum_t der = { NULL, 0 }; @@ -1209,87 +1208,45 @@ _gnutls_x509_encode_and_copy_PKI_params (ASN1_TYPE dst, return _gnutls_asn2err (result); } - if (pk_algorithm == GNUTLS_PK_RSA) + result = _gnutls_x509_write_pubkey_params (pk_algorithm, params, &der); + if (result < 0) { - /* disable parameters, which are not used in RSA. - */ - _asnstr_append_name (name, sizeof (name), dst_name, - ".algorithm.parameters"); - - result = asn1_write_value (dst, name, ASN1_NULL, ASN1_NULL_SIZE); - if (result != ASN1_SUCCESS) - { - gnutls_assert (); - return _gnutls_asn2err (result); - } - - result = _gnutls_x509_write_rsa_params (params, params_size, &der); - if (result < 0) - { - gnutls_assert (); - return result; - } - - /* Write the DER parameters. (in bits) - */ - _asnstr_append_name (name, sizeof (name), dst_name, - ".subjectPublicKey"); - result = asn1_write_value (dst, name, der.data, der.size * 8); - - _gnutls_free_datum (&der); - - if (result != ASN1_SUCCESS) - { - gnutls_assert (); - return _gnutls_asn2err (result); - } + gnutls_assert (); + return result; } - else if (pk_algorithm == GNUTLS_PK_DSA) - { - result = _gnutls_x509_write_dsa_params (params, params_size, &der); - if (result < 0) - { - gnutls_assert (); - return result; - } + _asnstr_append_name (name, sizeof (name), dst_name, + ".algorithm.parameters"); - /* Write the DER parameters. - */ - _asnstr_append_name (name, sizeof (name), dst_name, - ".algorithm.parameters"); - result = asn1_write_value (dst, name, der.data, der.size); + result = asn1_write_value (dst, name, der.data, der.size); - _gnutls_free_datum (&der); - - if (result != ASN1_SUCCESS) - { - gnutls_assert (); - return _gnutls_asn2err (result); - } - - result = _gnutls_x509_write_dsa_public_key (params, params_size, &der); - if (result < 0) - { - gnutls_assert (); - return result; - } + _gnutls_free_datum (&der); - _asnstr_append_name (name, sizeof (name), dst_name, - ".subjectPublicKey"); - result = asn1_write_value (dst, name, der.data, der.size * 8); + if (result != ASN1_SUCCESS) + { + gnutls_assert (); + return _gnutls_asn2err (result); + } - _gnutls_free_datum (&der); + result = _gnutls_x509_write_pubkey (pk_algorithm, params, &der); + if (result < 0) + { + gnutls_assert (); + return result; + } - if (result != ASN1_SUCCESS) - { - gnutls_assert (); - return _gnutls_asn2err (result); - } + /* Write the DER parameters. (in bits) + */ + _asnstr_append_name (name, sizeof (name), dst_name, + ".subjectPublicKey"); + result = asn1_write_value (dst, name, der.data, der.size * 8); + _gnutls_free_datum (&der); + if (result != ASN1_SUCCESS) + { + gnutls_assert (); + return _gnutls_asn2err (result); } - else - return GNUTLS_E_UNIMPLEMENTED_FEATURE; return 0; } @@ -1306,9 +1263,10 @@ _gnutls_x509_get_pk_algorithm (ASN1_TYPE src, const char *src_name, int algo; char oid[64]; int len; - bigint_t params[MAX_PUBLIC_PARAMS_SIZE]; + gnutls_pk_params_st params; char name[128]; + gnutls_pk_params_init(¶ms); _asnstr_append_name (name, sizeof (name), src_name, ".algorithm.algorithm"); len = sizeof (oid); @@ -1372,38 +1330,13 @@ _gnutls_x509_get_pk_algorithm (ASN1_TYPE src, const char *src_name, len /= 8; - switch (algo) - { - case GNUTLS_PK_RSA: - { - if ((result = _gnutls_x509_read_rsa_params (str, len, params)) < 0) - { - gnutls_assert (); - return result; - } - - bits[0] = _gnutls_mpi_get_nbits (params[0]); - - _gnutls_mpi_release (¶ms[0]); - _gnutls_mpi_release (¶ms[1]); - } - break; - case GNUTLS_PK_DSA: - { - - if ((result = _gnutls_x509_read_dsa_pubkey (str, len, params)) < 0) - { - gnutls_assert (); - return result; - } - - bits[0] = _gnutls_mpi_get_nbits (params[3]); - - _gnutls_mpi_release (¶ms[3]); - } - break; - } + result = _gnutls_x509_read_pubkey (algo, str, len, ¶ms); + if (result < 0) + return gnutls_assert_val(result); + + bits[0] = pubkey_to_bits(algo, ¶ms); + gnutls_pk_params_release(¶ms); gnutls_free (str); return algo; } diff --git a/lib/x509/common.h b/lib/x509/common.h index 0368e5acec..86e6b8dfa0 100644 --- a/lib/x509/common.h +++ b/lib/x509/common.h @@ -27,6 +27,7 @@ #define COMMON_H #include <algorithms.h> +#include <abstract_int.h> #include <x509/x509_int.h> #define MAX_STRING_LEN 512 @@ -130,8 +131,7 @@ int _gnutls_x509_get_pk_algorithm (ASN1_TYPE src, const char *src_name, int _gnutls_x509_encode_and_copy_PKI_params (ASN1_TYPE dst, const char *dst_name, gnutls_pk_algorithm_t - pk_algorithm, bigint_t * params, - int params_size); + pk_algorithm, gnutls_pk_params_st * params); int _gnutls_asn1_copy_node (ASN1_TYPE * dst, const char *dst_name, ASN1_TYPE src, const char *src_name); @@ -143,10 +143,10 @@ int _gnutls_x509_get_signature (ASN1_TYPE src, const char *src_name, gnutls_digest_algorithm_t _gnutls_dsa_q_to_hash (bigint_t q); int _gnutls_get_asn_mpis (ASN1_TYPE asn, const char *root, - bigint_t * params, int *params_size); + gnutls_pk_params_st * params); -int _gnutls_get_key_id (gnutls_pk_algorithm_t pk, bigint_t * params, - int params_size, unsigned char *output_data, +int _gnutls_get_key_id (gnutls_pk_algorithm_t pk, gnutls_pk_params_st*, + unsigned char *output_data, size_t * output_data_size); void _asnstr_append_name (char *name, size_t name_size, const char *part1, @@ -155,8 +155,8 @@ void _asnstr_append_name (char *name, size_t name_size, const char *part1, int pubkey_verify_sig (const gnutls_datum_t * tbs, const gnutls_datum_t * hash, const gnutls_datum_t * signature, - gnutls_pk_algorithm_t pk, bigint_t * issuer_params, - int issuer_params_size); + gnutls_pk_algorithm_t pk, + gnutls_pk_params_st * issuer_params); int check_if_same_cert (gnutls_x509_crt_t cert1, gnutls_x509_crt_t cert2); diff --git a/lib/x509/crq.c b/lib/x509/crq.c index 6cd0c96df9..c61b3c4043 100644 --- a/lib/x509/crq.c +++ b/lib/x509/crq.c @@ -792,7 +792,7 @@ gnutls_x509_crq_set_key (gnutls_x509_crq_t crq, gnutls_x509_privkey_t key) result = _gnutls_x509_encode_and_copy_PKI_params (crq->crq, "certificationRequestInfo.subjectPKInfo", - key->pk_algorithm, key->params, key->params_size); + key->pk_algorithm, &key->params); if (result < 0) { @@ -823,9 +823,9 @@ gnutls_x509_crq_get_key_rsa_raw (gnutls_x509_crq_t crq, gnutls_datum_t * m, gnutls_datum_t * e) { int ret; - bigint_t params[MAX_PUBLIC_PARAMS_SIZE]; - int params_size = MAX_PUBLIC_PARAMS_SIZE; - int i; + gnutls_pk_params_st params; + + gnutls_pk_params_init(¶ms); if (crq == NULL) { @@ -840,21 +840,21 @@ gnutls_x509_crq_get_key_rsa_raw (gnutls_x509_crq_t crq, return GNUTLS_E_INVALID_REQUEST; } - ret = _gnutls_x509_crq_get_mpis (crq, params, ¶ms_size); + ret = _gnutls_x509_crq_get_mpis (crq, ¶ms); if (ret < 0) { gnutls_assert (); return ret; } - ret = _gnutls_mpi_dprint (params[0], m); + ret = _gnutls_mpi_dprint (params.params[0], m); if (ret < 0) { gnutls_assert (); goto cleanup; } - ret = _gnutls_mpi_dprint (params[1], e); + ret = _gnutls_mpi_dprint (params.params[1], e); if (ret < 0) { gnutls_assert (); @@ -865,10 +865,7 @@ gnutls_x509_crq_get_key_rsa_raw (gnutls_x509_crq_t crq, ret = 0; cleanup: - for (i = 0; i < params_size; i++) - { - _gnutls_mpi_release (¶ms[i]); - } + gnutls_pk_params_release(¶ms); return ret; } @@ -893,7 +890,9 @@ gnutls_x509_crq_set_key_rsa_raw (gnutls_x509_crq_t crq, { int result, ret; size_t siz = 0; - bigint_t temp_params[RSA_PUBLIC_PARAMS]; + gnutls_pk_params_st temp_params; + + gnutls_pk_params_init(&temp_params); if (crq == NULL) { @@ -901,10 +900,10 @@ gnutls_x509_crq_set_key_rsa_raw (gnutls_x509_crq_t crq, return GNUTLS_E_INVALID_REQUEST; } - memset (temp_params, 0, sizeof (temp_params)); + memset (&temp_params, 0, sizeof (temp_params)); siz = m->size; - if (_gnutls_mpi_scan_nz (&temp_params[0], m->data, siz)) + if (_gnutls_mpi_scan_nz (&temp_params.params[0], m->data, siz)) { gnutls_assert (); ret = GNUTLS_E_MPI_SCAN_FAILED; @@ -912,17 +911,19 @@ gnutls_x509_crq_set_key_rsa_raw (gnutls_x509_crq_t crq, } siz = e->size; - if (_gnutls_mpi_scan_nz (&temp_params[1], e->data, siz)) + if (_gnutls_mpi_scan_nz (&temp_params.params[1], e->data, siz)) { gnutls_assert (); ret = GNUTLS_E_MPI_SCAN_FAILED; goto error; } + temp_params.params_nr = RSA_PUBLIC_PARAMS; + result = _gnutls_x509_encode_and_copy_PKI_params (crq->crq, "certificationRequestInfo.subjectPKInfo", - GNUTLS_PK_RSA, temp_params, RSA_PUBLIC_PARAMS); + GNUTLS_PK_RSA, &temp_params); if (result < 0) { @@ -934,8 +935,7 @@ gnutls_x509_crq_set_key_rsa_raw (gnutls_x509_crq_t crq, ret = 0; error: - _gnutls_mpi_release (&temp_params[0]); - _gnutls_mpi_release (&temp_params[1]); + gnutls_pk_params_release(&temp_params); return ret; } @@ -2271,39 +2271,26 @@ static int rsadsa_crq_get_key_id (gnutls_x509_crq_t crq, int pk, unsigned char *output_data, size_t * output_data_size) { - bigint_t params[MAX_PUBLIC_PARAMS_SIZE]; - int params_size = MAX_PUBLIC_PARAMS_SIZE; - int i, result = 0; + gnutls_pk_params_st params; + int result = 0; gnutls_datum_t der = { NULL, 0 }; digest_hd_st hd; - result = _gnutls_x509_crq_get_mpis (crq, params, ¶ms_size); + gnutls_pk_params_init(¶ms); + + result = _gnutls_x509_crq_get_mpis (crq, ¶ms); if (result < 0) { gnutls_assert (); return result; } - if (pk == GNUTLS_PK_RSA) - { - result = _gnutls_x509_write_rsa_params (params, params_size, &der); - if (result < 0) - { - gnutls_assert (); - goto cleanup; - } - } - else if (pk == GNUTLS_PK_DSA) + result = _gnutls_x509_write_pubkey( pk, ¶ms, &der); + if (result < 0) { - result = _gnutls_x509_write_dsa_public_key (params, params_size, &der); - if (result < 0) - { - gnutls_assert (); - goto cleanup; - } + gnutls_assert (); + goto cleanup; } - else - return GNUTLS_E_INTERNAL_ERROR; result = _gnutls_hash_init (&hd, GNUTLS_MAC_SHA1); if (result < 0) @@ -2325,10 +2312,7 @@ cleanup: /* release all allocated MPIs */ - for (i = 0; i < params_size; i++) - { - _gnutls_mpi_release (¶ms[i]); - } + gnutls_pk_params_release(¶ms); return result; } @@ -2538,8 +2522,10 @@ gnutls_x509_crq_verify (gnutls_x509_crq_t crq, { gnutls_datum data = { NULL, 0 }; gnutls_datum signature = { NULL, 0 }; -bigint_t params[MAX_PUBLIC_PARAMS_SIZE]; -int ret, params_size = 0, i; +gnutls_pk_params_st params; +int ret; + + gnutls_pk_params_init(¶ms); ret = _gnutls_x509_get_signed_data (crq->crq, "certificationRequestInfo", &data); @@ -2556,9 +2542,8 @@ int ret, params_size = 0, i; goto cleanup; } - params_size = MAX_PUBLIC_PARAMS_SIZE; ret = - _gnutls_x509_crq_get_mpis(crq, params, ¶ms_size); + _gnutls_x509_crq_get_mpis(crq, ¶ms); if (ret < 0) { gnutls_assert (); @@ -2567,7 +2552,7 @@ int ret, params_size = 0, i; ret = pubkey_verify_sig(&data, NULL, &signature, gnutls_x509_crq_get_pk_algorithm (crq, NULL), - params, params_size); + ¶ms); if (ret < 0) { gnutls_assert (); @@ -2579,11 +2564,7 @@ int ret, params_size = 0, i; cleanup: _gnutls_free_datum (&data); _gnutls_free_datum (&signature); - - for (i = 0; i < params_size; i++) - { - _gnutls_mpi_release (¶ms[i]); - } + gnutls_pk_params_release(¶ms); return ret; } diff --git a/lib/x509/key_decode.c b/lib/x509/key_decode.c new file mode 100644 index 0000000000..e2b56b538b --- /dev/null +++ b/lib/x509/key_decode.c @@ -0,0 +1,301 @@ +/* + * Copyright (C) 2011 Free Software Foundation, Inc. + * + * Author: Nikos Mavrogiannopoulos + * + * This file is part of GnuTLS. + * + * The GnuTLS is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA + * + */ + +#include <gnutls_int.h> +#include <gnutls_errors.h> +#include <gnutls_global.h> +#include <libtasn1.h> +#include <gnutls_datum.h> +#include "common.h" +#include "x509_int.h" +#include <gnutls_num.h> +#include <gnutls_ecc.h> + +static int _gnutls_x509_read_rsa_pubkey (opaque * der, int dersize, + gnutls_pk_params_st* params); +static int _gnutls_x509_read_dsa_pubkey (opaque * der, int dersize, + gnutls_pk_params_st * params); +static int _gnutls_x509_read_ecc_pubkey (opaque * der, int dersize, + gnutls_pk_params_st * params); + +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. + * Returns 2 parameters (m,e). It does not set params_nr. + */ +int +_gnutls_x509_read_rsa_pubkey (opaque * der, int dersize, gnutls_pk_params_st * params) +{ + int result; + ASN1_TYPE spk = ASN1_TYPE_EMPTY; + + if ((result = asn1_create_element + (_gnutls_get_gnutls_asn (), "GNUTLS.RSAPublicKey", &spk)) + != ASN1_SUCCESS) + { + gnutls_assert (); + return _gnutls_asn2err (result); + } + + result = asn1_der_decoding (&spk, der, dersize, NULL); + + if (result != ASN1_SUCCESS) + { + gnutls_assert (); + asn1_delete_structure (&spk); + return _gnutls_asn2err (result); + } + + + if ((result = _gnutls_x509_read_int (spk, "modulus", ¶ms->params[0])) < 0) + { + gnutls_assert (); + asn1_delete_structure (&spk); + return GNUTLS_E_ASN1_GENERIC_ERROR; + } + + if ((result = _gnutls_x509_read_int (spk, "publicExponent", + ¶ms->params[1])) < 0) + { + gnutls_assert (); + _gnutls_mpi_release (¶ms->params[0]); + asn1_delete_structure (&spk); + return GNUTLS_E_ASN1_GENERIC_ERROR; + } + + asn1_delete_structure (&spk); + + return 0; + +} + +/* + * some x509 certificate parsing functions that relate to MPI parameter + * extraction. This reads the BIT STRING subjectPublicKey. + * Returns 2 parameters (m,e). It does not set params_nr. + */ +int +_gnutls_x509_read_ecc_pubkey (opaque * der, int dersize, gnutls_pk_params_st * params) +{ + uint8_t* octet; + int ret; + size_t octet_size = dersize; + + octet = gnutls_malloc(octet_size); + if (octet == NULL) + return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); + + ret = _gnutls_x509_decode_octet_string (NULL, der, dersize, octet, &octet_size); + if (ret < 0) + return gnutls_assert_val(ret); + + ret = _gnutls_ecc_ansi_x963_import (octet, octet_size, ¶ms->params[5], + ¶ms->params[6]); + gnutls_free(octet); + + return ret; +} + + +/* reads p,q and g + * from the certificate (subjectPublicKey BIT STRING). + * params[0-2]. It does NOT set params_nr. + */ +static int +_gnutls_x509_read_dsa_params (opaque * der, int dersize, gnutls_pk_params_st * params) +{ + int result; + ASN1_TYPE spk = ASN1_TYPE_EMPTY; + + if ((result = asn1_create_element + (_gnutls_get_pkix (), "PKIX1.Dss-Parms", &spk)) != ASN1_SUCCESS) + { + gnutls_assert (); + return _gnutls_asn2err (result); + } + + result = asn1_der_decoding (&spk, der, dersize, NULL); + + if (result != ASN1_SUCCESS) + { + gnutls_assert (); + asn1_delete_structure (&spk); + return _gnutls_asn2err (result); + } + + /* FIXME: If the parameters are not included in the certificate + * then the issuer's parameters should be used. This is not + * done yet. + */ + + /* Read p */ + + if ((result = _gnutls_x509_read_int (spk, "p", ¶ms->params[0])) < 0) + { + gnutls_assert (); + asn1_delete_structure (&spk); + return GNUTLS_E_ASN1_GENERIC_ERROR; + } + + /* Read q */ + + if ((result = _gnutls_x509_read_int (spk, "q", ¶ms->params[1])) < 0) + { + gnutls_assert (); + asn1_delete_structure (&spk); + _gnutls_mpi_release (¶ms->params[0]); + return GNUTLS_E_ASN1_GENERIC_ERROR; + } + + /* Read g */ + + if ((result = _gnutls_x509_read_int (spk, "g", ¶ms->params[2])) < 0) + { + gnutls_assert (); + asn1_delete_structure (&spk); + _gnutls_mpi_release (¶ms->params[0]); + _gnutls_mpi_release (¶ms->params[1]); + return GNUTLS_E_ASN1_GENERIC_ERROR; + } + + asn1_delete_structure (&spk); + + return 0; + +} + +/* reads the curve from the certificate. + * params[0-4]. It does NOT set params_nr. + */ +static int +_gnutls_x509_read_ecc_params (opaque * der, int dersize, gnutls_pk_params_st * params) +{ + int ret; + ASN1_TYPE spk = ASN1_TYPE_EMPTY; + char oid[MAX_OID_SIZE]; + unsigned int oid_size; + + if ((ret = asn1_create_element + (_gnutls_get_gnutls_asn (), "GNUTLS.ECParameters", &spk)) != ASN1_SUCCESS) + { + gnutls_assert (); + return _gnutls_asn2err (ret); + } + + ret = asn1_der_decoding (&spk, der, dersize, NULL); + + if (ret != ASN1_SUCCESS) + { + gnutls_assert (); + ret = _gnutls_asn2err (ret); + goto cleanup; + } + + /* Read curve */ + /* read the curve */ + oid_size = sizeof(oid); + ret = asn1_read_value(spk, "namedCurve", oid, &oid_size); + if (ret != ASN1_SUCCESS) + { + gnutls_assert (); + ret = _gnutls_asn2err (ret); + goto cleanup; + } + + params->flags = _gnutls_oid_to_ecc_curve(oid); + if (params->flags == GNUTLS_ECC_CURVE_INVALID) + { + _gnutls_debug_log("Curve %s is not supported\n", oid); + gnutls_assert(); + ret = GNUTLS_E_ECC_UNSUPPORTED_CURVE; + goto cleanup; + } + + ret = _gnutls_ecc_curve_fill_params(params->flags, params); + if (ret < 0) + { + gnutls_assert(); + goto cleanup; + } + + ret = 0; + +cleanup: + + asn1_delete_structure (&spk); + + return ret; + +} + +int _gnutls_x509_read_pubkey (gnutls_pk_algorithm_t algo, opaque * der, int dersize, + gnutls_pk_params_st * params) +{ + switch(algo) + { + case GNUTLS_PK_RSA: + return _gnutls_x509_read_rsa_pubkey(der, dersize, params); + case GNUTLS_PK_DSA: + return _gnutls_x509_read_dsa_pubkey(der, dersize, params); + case GNUTLS_PK_ECC: + return _gnutls_x509_read_ecc_pubkey(der, dersize, params); + default: + return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE); + } +} + +int _gnutls_x509_read_pubkey_params (gnutls_pk_algorithm_t algo, opaque * der, int dersize, + gnutls_pk_params_st * params) +{ + switch(algo) + { + case GNUTLS_PK_RSA: + return 0; + case GNUTLS_PK_DSA: + return _gnutls_x509_read_dsa_params(der, dersize, params); + case GNUTLS_PK_ECC: + return _gnutls_x509_read_ecc_params(der, dersize, params); + default: + return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE); + } +} + +/* reads DSA's Y + * from the certificate + * only sets params[3] + */ +int +_gnutls_x509_read_dsa_pubkey (opaque * der, int dersize, gnutls_pk_params_st * params) +{ + /* do not set a number */ + params->params_nr = 0; + return _gnutls_x509_read_der_int (der, dersize, ¶ms->params[3]); +} + diff --git a/lib/x509/key_encode.c b/lib/x509/key_encode.c new file mode 100644 index 0000000000..8b44d08001 --- /dev/null +++ b/lib/x509/key_encode.c @@ -0,0 +1,834 @@ +/* + * Copyright (C) 2011 Free Software Foundation, Inc. + * + * Author: Nikos Mavrogiannopoulos + * + * This file is part of GnuTLS. + * + * The GnuTLS is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA + * + */ + +#include <gnutls_int.h> +#include <gnutls_errors.h> +#include <gnutls_global.h> +#include <libtasn1.h> +#include <gnutls_datum.h> +#include "common.h" +#include "x509_int.h" +#include <gnutls_num.h> +#include <gnutls_pk.h> +#include <gnutls_mpi.h> +#include <gnutls_ecc.h> + +static int _gnutls_x509_write_rsa_pubkey (gnutls_pk_params_st * params, + gnutls_datum_t * der); +static int _gnutls_x509_write_dsa_params (gnutls_pk_params_st * params, + gnutls_datum_t * der); +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. + * Needs 2 parameters (m,e). + * + * Allocates the space used to store the DER data. + */ +static int +_gnutls_x509_write_rsa_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 < RSA_PUBLIC_PARAMS) + { + gnutls_assert (); + result = GNUTLS_E_INVALID_REQUEST; + goto cleanup; + } + + if ((result = asn1_create_element + (_gnutls_get_gnutls_asn (), "GNUTLS.RSAPublicKey", &spk)) + != ASN1_SUCCESS) + { + gnutls_assert (); + return _gnutls_asn2err (result); + } + + result = _gnutls_x509_write_int (spk, "modulus", params->params[0], 1); + if (result < 0) + { + gnutls_assert (); + goto cleanup; + } + + result = _gnutls_x509_write_int (spk, "publicExponent", params->params[1], 1); + if (result < 0) + { + gnutls_assert (); + goto cleanup; + } + + result = _gnutls_x509_der_encode (spk, "", der, 0); + if (result < 0) + { + gnutls_assert (); + goto cleanup; + } + + result = 0; + +cleanup: + asn1_delete_structure (&spk); + + return result; +} + +/* + * some x509 certificate functions that relate to MPI parameter + * setting. This writes an ECPoint. + * + * Allocates the space used to store the DER data. + */ +static int +_gnutls_x509_write_ecc_pubkey (gnutls_pk_params_st * params, + gnutls_datum_t * der) +{ + int result; + ASN1_TYPE spk = ASN1_TYPE_EMPTY; + gnutls_datum_t out; + + der->data = NULL; + der->size = 0; + + if (params->params_nr < ECC_PUBLIC_PARAMS) + { + gnutls_assert (); + result = GNUTLS_E_INVALID_REQUEST; + goto cleanup; + } + + result = _gnutls_ecc_ansi_x963_export(params->flags, params->params[5], params->params[6], &out); + if (result < 0) + return gnutls_assert_val(result); + + if ((result = asn1_create_element + (_gnutls_get_gnutls_asn (), "GNUTLS.ECPoint", &spk)) + != ASN1_SUCCESS) + { + gnutls_assert (); + result = _gnutls_asn2err (result); + goto cleanup; + } + + result = asn1_write_value (spk, "", out.data, out.size); + if (result != ASN1_SUCCESS) + { + gnutls_assert (); + result = _gnutls_asn2err (result); + goto cleanup; + } + + result = _gnutls_x509_der_encode (spk, "", der, 0); + if (result < 0) + { + gnutls_assert (); + goto cleanup; + } + + result = 0; + +cleanup: + _gnutls_free_datum(&out); + asn1_delete_structure (&spk); + + return result; +} + +int +_gnutls_x509_write_pubkey_params (gnutls_pk_algorithm_t algo, + gnutls_pk_params_st* params, + gnutls_datum_t * der) +{ + switch(algo) + { + case GNUTLS_PK_DSA: + return _gnutls_x509_write_dsa_params(params, der); + case GNUTLS_PK_RSA: + der->data = gnutls_malloc(ASN1_NULL_SIZE); + if (der->data == NULL) + return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); + + memcpy(der->data, ASN1_NULL, ASN1_NULL_SIZE); + der->size = ASN1_NULL_SIZE; + return 0; + case GNUTLS_PK_ECC: + return _gnutls_x509_write_ecc_params(params, der); + default: + return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE); + } +} + +int +_gnutls_x509_write_pubkey (gnutls_pk_algorithm_t algo, + gnutls_pk_params_st* params, + gnutls_datum_t * der) +{ + switch(algo) + { + case GNUTLS_PK_DSA: + return _gnutls_x509_write_dsa_pubkey(params, der); + case GNUTLS_PK_RSA: + return _gnutls_x509_write_rsa_pubkey(params, der); + case GNUTLS_PK_ECC: + return _gnutls_x509_write_ecc_pubkey(params, der); + default: + return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE); + } +} + +/* + * This function writes the parameters for DSS keys. + * Needs 3 parameters (p,q,g). + * + * Allocates the space used to store the DER data. + */ +static int +_gnutls_x509_write_dsa_params (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 < DSA_PUBLIC_PARAMS-1) + { + gnutls_assert (); + result = GNUTLS_E_INVALID_REQUEST; + goto cleanup; + } + + if ((result = asn1_create_element + (_gnutls_get_gnutls_asn (), "GNUTLS.DSAParameters", &spk)) + != ASN1_SUCCESS) + { + gnutls_assert (); + return _gnutls_asn2err (result); + } + + result = _gnutls_x509_write_int (spk, "p", params->params[0], 1); + if (result < 0) + { + gnutls_assert (); + goto cleanup; + } + + result = _gnutls_x509_write_int (spk, "q", params->params[1], 1); + if (result < 0) + { + gnutls_assert (); + goto cleanup; + } + + result = _gnutls_x509_write_int (spk, "g", params->params[2], 1); + if (result < 0) + { + gnutls_assert (); + goto cleanup; + } + + result = _gnutls_x509_der_encode (spk, "", der, 0); + if (result < 0) + { + gnutls_assert (); + goto cleanup; + } + + result = 0; + +cleanup: + asn1_delete_structure (&spk); + return result; +} + +/* + * This function writes the parameters for ECC keys. + * That is the ECParameters struct. + * + * Allocates the space used to store the DER data. + */ +static int +_gnutls_x509_write_ecc_params (gnutls_pk_params_st* params, + gnutls_datum_t * der) +{ + int result; + ASN1_TYPE spk = ASN1_TYPE_EMPTY; + const char* oid; + + der->data = NULL; + der->size = 0; + + if (params->params_nr < ECC_PUBLIC_PARAMS) + { + gnutls_assert (); + result = GNUTLS_E_INVALID_REQUEST; + goto cleanup; + } + + oid = _gnutls_ecc_curve_get_oid(params->flags); + if (oid == NULL) + return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); + + + if ((result = asn1_create_element + (_gnutls_get_gnutls_asn (), "GNUTLS.ECParameters", &spk)) + != ASN1_SUCCESS) + { + gnutls_assert (); + return _gnutls_asn2err (result); + } + + if ((result = asn1_write_value (spk, "parameters", "namedCurve", 1)) != ASN1_SUCCESS) + { + gnutls_assert (); + result = _gnutls_asn2err (result); + goto cleanup; + } + + if ((result = asn1_write_value (spk, "parameters.namedCurve", oid, 1)) != ASN1_SUCCESS) + { + gnutls_assert (); + result = _gnutls_asn2err (result); + goto cleanup; + } + + result = _gnutls_x509_der_encode (spk, "", der, 0); + if (result < 0) + { + gnutls_assert (); + goto cleanup; + } + + result = 0; + +cleanup: + asn1_delete_structure (&spk); + return result; +} + +/* + * This function writes the public parameters for DSS keys. + * Needs 1 parameter (y). + * + * Allocates the space used to store the DER data. + */ +static int +_gnutls_x509_write_dsa_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 < DSA_PUBLIC_PARAMS) + { + gnutls_assert (); + result = GNUTLS_E_INVALID_REQUEST; + goto cleanup; + } + + if ((result = asn1_create_element + (_gnutls_get_gnutls_asn (), "GNUTLS.DSAPublicKey", &spk)) + != ASN1_SUCCESS) + { + gnutls_assert (); + return _gnutls_asn2err (result); + } + + result = _gnutls_x509_write_int (spk, "", params->params[3], 1); + if (result < 0) + { + gnutls_assert (); + goto cleanup; + } + + result = _gnutls_x509_der_encode (spk, "", der, 0); + if (result < 0) + { + gnutls_assert (); + goto cleanup; + } + + result = 0; + +cleanup: + asn1_delete_structure (&spk); + return result; +} + +/* Encodes the RSA parameters into an ASN.1 RSA private key structure. + */ +static int +_gnutls_asn1_encode_rsa (ASN1_TYPE * c2, gnutls_pk_params_st * params) +{ + int result; + opaque null = '\0'; + gnutls_pk_params_st pk_params; + gnutls_datum_t m, e, d, p, q, u, exp1, exp2; + + gnutls_pk_params_init(&pk_params); + + memset (&m, 0, sizeof (m)); + memset (&p, 0, sizeof (p)); + memset (&q, 0, sizeof (q)); + memset (&p, 0, sizeof (p)); + memset (&u, 0, sizeof (u)); + memset (&e, 0, sizeof (e)); + memset (&d, 0, sizeof (d)); + memset (&exp1, 0, sizeof (exp1)); + memset (&exp2, 0, sizeof (exp2)); + + result = _gnutls_pk_params_copy (&pk_params, params); + if (result < 0) + { + gnutls_assert (); + return result; + } + + result = _gnutls_pk_fixup (GNUTLS_PK_RSA, GNUTLS_EXPORT, &pk_params); + if (result < 0) + { + gnutls_assert (); + goto cleanup; + } + + /* retrieve as data */ + + result = _gnutls_mpi_dprint_lz (pk_params.params[0], &m); + if (result < 0) + { + gnutls_assert (); + goto cleanup; + } + + result = _gnutls_mpi_dprint_lz (pk_params.params[1], &e); + if (result < 0) + { + gnutls_assert (); + goto cleanup; + } + + result = _gnutls_mpi_dprint_lz (pk_params.params[2], &d); + if (result < 0) + { + gnutls_assert (); + goto cleanup; + } + + result = _gnutls_mpi_dprint_lz (pk_params.params[3], &p); + if (result < 0) + { + gnutls_assert (); + goto cleanup; + } + + result = _gnutls_mpi_dprint_lz (pk_params.params[4], &q); + if (result < 0) + { + gnutls_assert (); + goto cleanup; + } + + result = _gnutls_mpi_dprint_lz (pk_params.params[5], &u); + if (result < 0) + { + gnutls_assert (); + goto cleanup; + } + + result = _gnutls_mpi_dprint_lz (pk_params.params[6], &exp1); + if (result < 0) + { + gnutls_assert (); + goto cleanup; + } + + result = _gnutls_mpi_dprint_lz (pk_params.params[7], &exp2); + if (result < 0) + { + gnutls_assert (); + goto cleanup; + } + + /* Ok. Now we have the data. Create the asn1 structures + */ + + /* first make sure that no previously allocated data are leaked */ + if (*c2 != ASN1_TYPE_EMPTY) + { + asn1_delete_structure (c2); + *c2 = ASN1_TYPE_EMPTY; + } + + if ((result = asn1_create_element + (_gnutls_get_gnutls_asn (), "GNUTLS.RSAPrivateKey", c2)) + != ASN1_SUCCESS) + { + gnutls_assert (); + result = _gnutls_asn2err (result); + goto cleanup; + } + + /* Write PRIME + */ + if ((result = asn1_write_value (*c2, "modulus", + m.data, m.size)) != ASN1_SUCCESS) + { + gnutls_assert (); + result = _gnutls_asn2err (result); + goto cleanup; + } + + if ((result = asn1_write_value (*c2, "publicExponent", + e.data, e.size)) != ASN1_SUCCESS) + { + gnutls_assert (); + result = _gnutls_asn2err (result); + goto cleanup; + } + + if ((result = asn1_write_value (*c2, "privateExponent", + d.data, d.size)) != ASN1_SUCCESS) + { + gnutls_assert (); + result = _gnutls_asn2err (result); + goto cleanup; + } + + if ((result = asn1_write_value (*c2, "prime1", + p.data, p.size)) != ASN1_SUCCESS) + { + gnutls_assert (); + result = _gnutls_asn2err (result); + goto cleanup; + } + + if ((result = asn1_write_value (*c2, "prime2", + q.data, q.size)) != ASN1_SUCCESS) + { + gnutls_assert (); + result = _gnutls_asn2err (result); + goto cleanup; + } + + if ((result = asn1_write_value (*c2, "coefficient", + u.data, u.size)) != ASN1_SUCCESS) + { + gnutls_assert (); + result = _gnutls_asn2err (result); + + goto cleanup; + } + + if ((result = asn1_write_value (*c2, "exponent1", + exp1.data, exp1.size)) != ASN1_SUCCESS) + { + gnutls_assert (); + result = _gnutls_asn2err (result); + goto cleanup; + } + + if ((result = asn1_write_value (*c2, "exponent2", + exp2.data, exp2.size)) != ASN1_SUCCESS) + { + gnutls_assert (); + result = _gnutls_asn2err (result); + goto cleanup; + } + + if ((result = asn1_write_value (*c2, "otherPrimeInfos", + NULL, 0)) != ASN1_SUCCESS) + { + gnutls_assert (); + result = _gnutls_asn2err (result); + goto cleanup; + } + + if ((result = asn1_write_value (*c2, "version", &null, 1)) != ASN1_SUCCESS) + { + gnutls_assert (); + result = _gnutls_asn2err (result); + goto cleanup; + } + + result = 0; + +cleanup: + if (result != 0) + asn1_delete_structure (c2); + + gnutls_pk_params_release (&pk_params); + + _gnutls_free_datum (&m); + _gnutls_free_datum (&d); + _gnutls_free_datum (&e); + _gnutls_free_datum (&p); + _gnutls_free_datum (&q); + _gnutls_free_datum (&u); + _gnutls_free_datum (&exp1); + _gnutls_free_datum (&exp2); + + return result; +} + +/* Encodes the ECC parameters into an ASN.1 ECPrivateKey structure. + */ +static int +_gnutls_asn1_encode_ecc (ASN1_TYPE * c2, gnutls_pk_params_st * params) +{ + int ret; + opaque one = '\x01'; + gnutls_datum pubkey = { NULL, 0 }; + const char *oid; + + oid = _gnutls_ecc_curve_get_oid(params->flags); + + if (params->params_nr != ECC_PRIVATE_PARAMS || oid == NULL) + return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); + + ret = _gnutls_ecc_ansi_x963_export(params->flags, params->params[5], params->params[6], &pubkey); + if (ret < 0) + return gnutls_assert_val(ret); + + /* Ok. Now we have the data. Create the asn1 structures + */ + + /* first make sure that no previously allocated data are leaked */ + if (*c2 != ASN1_TYPE_EMPTY) + { + asn1_delete_structure (c2); + *c2 = ASN1_TYPE_EMPTY; + } + + if ((ret = asn1_create_element + (_gnutls_get_gnutls_asn (), "GNUTLS.ECPrivateKey", c2)) + != ASN1_SUCCESS) + { + gnutls_assert (); + ret = _gnutls_asn2err (ret); + goto cleanup; + } + + /* Write PRIME + */ + if ((ret = asn1_write_value (*c2, "version", &one, 1)) != ASN1_SUCCESS) + { + gnutls_assert (); + ret = _gnutls_asn2err (ret); + goto cleanup; + } + + ret = _gnutls_x509_write_int (*c2, "privateKey", params->params[8], 1); + if (ret < 0) + { + gnutls_assert (); + goto cleanup; + } + + if ((ret = asn1_write_value (*c2, "publibKey", pubkey.data, pubkey.size)) != ASN1_SUCCESS) + { + gnutls_assert (); + ret = _gnutls_asn2err (ret); + goto cleanup; + } + + /* write our choice */ + if ((ret = asn1_write_value (*c2, "parameters", "namedCurve", 1)) != ASN1_SUCCESS) + { + gnutls_assert (); + ret = _gnutls_asn2err (ret); + goto cleanup; + } + + if ((ret = asn1_write_value (*c2, "parameters.namedCurve", oid, 1)) != ASN1_SUCCESS) + { + gnutls_assert (); + ret = _gnutls_asn2err (ret); + goto cleanup; + } + + _gnutls_free_datum(&pubkey); + return 0; + +cleanup: + asn1_delete_structure (c2); + _gnutls_free_datum(&pubkey); + + return ret; +} + + +/* Encodes the DSA parameters into an ASN.1 DSAPrivateKey structure. + */ +static int +_gnutls_asn1_encode_dsa (ASN1_TYPE * c2, gnutls_pk_params_st * params) +{ + int result, i; + size_t size[DSA_PRIVATE_PARAMS], total; + opaque *p_data, *q_data, *g_data, *x_data, *y_data; + opaque *all_data = NULL, *p; + opaque null = '\0'; + + /* Read all the sizes */ + total = 0; + for (i = 0; i < DSA_PRIVATE_PARAMS; i++) + { + _gnutls_mpi_print_lz (params->params[i], NULL, &size[i]); + total += size[i]; + } + + /* Encoding phase. + * allocate data enough to hold everything + */ + all_data = gnutls_secure_malloc (total); + if (all_data == NULL) + { + gnutls_assert (); + result = GNUTLS_E_MEMORY_ERROR; + goto cleanup; + } + + p = all_data; + p_data = p; + p += size[0]; + q_data = p; + p += size[1]; + g_data = p; + p += size[2]; + y_data = p; + p += size[3]; + x_data = p; + + _gnutls_mpi_print_lz (params->params[0], p_data, &size[0]); + _gnutls_mpi_print_lz (params->params[1], q_data, &size[1]); + _gnutls_mpi_print_lz (params->params[2], g_data, &size[2]); + _gnutls_mpi_print_lz (params->params[3], y_data, &size[3]); + _gnutls_mpi_print_lz (params->params[4], x_data, &size[4]); + + /* Ok. Now we have the data. Create the asn1 structures + */ + + /* first make sure that no previously allocated data are leaked */ + if (*c2 != ASN1_TYPE_EMPTY) + { + asn1_delete_structure (c2); + *c2 = ASN1_TYPE_EMPTY; + } + + if ((result = asn1_create_element + (_gnutls_get_gnutls_asn (), "GNUTLS.DSAPrivateKey", c2)) + != ASN1_SUCCESS) + { + gnutls_assert (); + result = _gnutls_asn2err (result); + goto cleanup; + } + + /* Write PRIME + */ + if ((result = asn1_write_value (*c2, "p", p_data, size[0])) != ASN1_SUCCESS) + { + gnutls_assert (); + result = _gnutls_asn2err (result); + goto cleanup; + } + + if ((result = asn1_write_value (*c2, "q", q_data, size[1])) != ASN1_SUCCESS) + { + gnutls_assert (); + result = _gnutls_asn2err (result); + goto cleanup; + } + + if ((result = asn1_write_value (*c2, "g", g_data, size[2])) != ASN1_SUCCESS) + { + gnutls_assert (); + result = _gnutls_asn2err (result); + goto cleanup; + } + + if ((result = asn1_write_value (*c2, "Y", y_data, size[3])) != ASN1_SUCCESS) + { + gnutls_assert (); + result = _gnutls_asn2err (result); + goto cleanup; + } + + if ((result = asn1_write_value (*c2, "priv", + x_data, size[4])) != ASN1_SUCCESS) + { + gnutls_assert (); + result = _gnutls_asn2err (result); + goto cleanup; + } + + gnutls_free (all_data); + + if ((result = asn1_write_value (*c2, "version", &null, 1)) != ASN1_SUCCESS) + { + gnutls_assert (); + result = _gnutls_asn2err (result); + goto cleanup; + } + + return 0; + +cleanup: + asn1_delete_structure (c2); + gnutls_free (all_data); + + return result; +} + +int _gnutls_asn1_encode_privkey (gnutls_pk_algorithm_t pk, ASN1_TYPE * c2, gnutls_pk_params_st * params) +{ + switch(pk) + { + case GNUTLS_PK_RSA: + return _gnutls_asn1_encode_rsa(c2, params); + case GNUTLS_PK_DSA: + return _gnutls_asn1_encode_dsa(c2, params); + case GNUTLS_PK_ECC: + return _gnutls_asn1_encode_ecc(c2, params); + default: + return GNUTLS_E_UNIMPLEMENTED_FEATURE; + } +} diff --git a/lib/x509/mpi.c b/lib/x509/mpi.c index 1bd26cbb4a..b57e7988a8 100644 --- a/lib/x509/mpi.c +++ b/lib/x509/mpi.c @@ -31,125 +31,8 @@ #include "common.h" #include "x509_int.h" #include <gnutls_num.h> +#include <gnutls_ecc.h> -/* - * some x509 certificate parsing functions that relate to MPI parameter - * extraction. This reads the BIT STRING subjectPublicKey. - * Returns 2 parameters (m,e). - */ -int -_gnutls_x509_read_rsa_params (opaque * der, int dersize, bigint_t * params) -{ - int result; - ASN1_TYPE spk = ASN1_TYPE_EMPTY; - - if ((result = asn1_create_element - (_gnutls_get_gnutls_asn (), "GNUTLS.RSAPublicKey", &spk)) - != ASN1_SUCCESS) - { - gnutls_assert (); - return _gnutls_asn2err (result); - } - - result = asn1_der_decoding (&spk, der, dersize, NULL); - - if (result != ASN1_SUCCESS) - { - gnutls_assert (); - asn1_delete_structure (&spk); - return _gnutls_asn2err (result); - } - - - if ((result = _gnutls_x509_read_int (spk, "modulus", ¶ms[0])) < 0) - { - gnutls_assert (); - asn1_delete_structure (&spk); - return GNUTLS_E_ASN1_GENERIC_ERROR; - } - - if ((result = _gnutls_x509_read_int (spk, "publicExponent", - ¶ms[1])) < 0) - { - gnutls_assert (); - _gnutls_mpi_release (¶ms[0]); - asn1_delete_structure (&spk); - return GNUTLS_E_ASN1_GENERIC_ERROR; - } - - asn1_delete_structure (&spk); - - return 0; - -} - - -/* reads p,q and g - * from the certificate (subjectPublicKey BIT STRING). - * params[0-2] - */ -int -_gnutls_x509_read_dsa_params (opaque * der, int dersize, bigint_t * params) -{ - int result; - ASN1_TYPE spk = ASN1_TYPE_EMPTY; - - if ((result = asn1_create_element - (_gnutls_get_pkix (), "PKIX1.Dss-Parms", &spk)) != ASN1_SUCCESS) - { - gnutls_assert (); - return _gnutls_asn2err (result); - } - - result = asn1_der_decoding (&spk, der, dersize, NULL); - - if (result != ASN1_SUCCESS) - { - gnutls_assert (); - asn1_delete_structure (&spk); - return _gnutls_asn2err (result); - } - - /* FIXME: If the parameters are not included in the certificate - * then the issuer's parameters should be used. This is not - * done yet. - */ - - /* Read p */ - - if ((result = _gnutls_x509_read_int (spk, "p", ¶ms[0])) < 0) - { - gnutls_assert (); - asn1_delete_structure (&spk); - return GNUTLS_E_ASN1_GENERIC_ERROR; - } - - /* Read q */ - - if ((result = _gnutls_x509_read_int (spk, "q", ¶ms[1])) < 0) - { - gnutls_assert (); - asn1_delete_structure (&spk); - _gnutls_mpi_release (¶ms[0]); - return GNUTLS_E_ASN1_GENERIC_ERROR; - } - - /* Read g */ - - if ((result = _gnutls_x509_read_int (spk, "g", ¶ms[2])) < 0) - { - gnutls_assert (); - asn1_delete_structure (&spk); - _gnutls_mpi_release (¶ms[0]); - _gnutls_mpi_release (¶ms[1]); - return GNUTLS_E_ASN1_GENERIC_ERROR; - } - - asn1_delete_structure (&spk); - - return 0; - -} /* Reads an Integer from the DER encoded data */ @@ -193,28 +76,20 @@ _gnutls_x509_read_der_int (opaque * der, int dersize, bigint_t * out) } -/* reads DSA's Y - * from the certificate - * only sets params[3] - */ -int -_gnutls_x509_read_dsa_pubkey (opaque * der, int dersize, bigint_t * params) -{ - return _gnutls_x509_read_der_int (der, dersize, ¶ms[3]); -} - /* Extracts DSA and RSA parameters from a certificate. */ int _gnutls_get_asn_mpis (ASN1_TYPE asn, const char *root, - bigint_t * params, int *params_size) + gnutls_pk_params_st * params) { int result; char name[256]; gnutls_datum_t tmp = { NULL, 0 }; gnutls_pk_algorithm_t pk_algorithm; + gnutls_pk_params_init(params); + result = _gnutls_x509_get_pk_algorithm (asn, root, NULL); if (result < 0) { @@ -235,86 +110,36 @@ _gnutls_get_asn_mpis (ASN1_TYPE asn, const char *root, return result; } - switch (pk_algorithm) + if ((result = + _gnutls_x509_read_pubkey (pk_algorithm, tmp.data, tmp.size, params)) < 0) { - case GNUTLS_PK_RSA: - /* params[0] is the modulus, - * params[1] is the exponent - */ - if (*params_size < RSA_PUBLIC_PARAMS) - { - gnutls_assert (); - /* internal error. Increase the bigint_ts in params */ - result = GNUTLS_E_INTERNAL_ERROR; - goto error; - } - - if ((result = - _gnutls_x509_read_rsa_params (tmp.data, tmp.size, params)) < 0) - { - gnutls_assert (); - goto error; - } - *params_size = RSA_PUBLIC_PARAMS; - - break; - case GNUTLS_PK_DSA: - /* params[0] is p, - * params[1] is q, - * params[2] is q, - * params[3] is pub. - */ + gnutls_assert (); + goto error; + } - if (*params_size < DSA_PUBLIC_PARAMS) - { - gnutls_assert (); - /* internal error. Increase the bigint_ts in params */ - result = GNUTLS_E_INTERNAL_ERROR; - goto error; - } - - if ((result = - _gnutls_x509_read_dsa_pubkey (tmp.data, tmp.size, params)) < 0) - { - gnutls_assert (); - goto error; - } - - /* Now read the parameters - */ - _gnutls_free_datum (&tmp); + /* Now read the parameters + */ + _gnutls_free_datum (&tmp); + + _asnstr_append_name (name, sizeof (name), root, + ".algorithm.parameters"); + result = _gnutls_x509_read_value (asn, name, &tmp, 0); - _asnstr_append_name (name, sizeof (name), root, - ".algorithm.parameters"); - result = _gnutls_x509_read_value (asn, name, &tmp, 0); + /* FIXME: If the parameters are not included in the certificate + * then the issuer's parameters should be used. This is not + * done yet. + */ - /* FIXME: If the parameters are not included in the certificate - * then the issuer's parameters should be used. This is not - * done yet. - */ + if (result < 0 && pk_algorithm != GNUTLS_PK_RSA) /* RSA doesn't use parameters */ + { + gnutls_assert (); + goto error; + } - if (result < 0) - { - gnutls_assert (); - goto error; - } - - if ((result = - _gnutls_x509_read_dsa_params (tmp.data, tmp.size, params)) < 0) - { - gnutls_assert (); - goto error; - } - *params_size = DSA_PUBLIC_PARAMS; - - break; - - default: - /* other types like DH - * currently not supported - */ + if ((result = + _gnutls_x509_read_pubkey_params (pk_algorithm, tmp.data, tmp.size, params)) < 0) + { gnutls_assert (); - result = GNUTLS_E_X509_CERTIFICATE_ERROR; goto error; } @@ -329,13 +154,12 @@ error: */ int _gnutls_x509_crt_get_mpis (gnutls_x509_crt_t cert, - bigint_t * params, int *params_size) + gnutls_pk_params_st * params) { /* Read the algorithm's OID */ return _gnutls_get_asn_mpis (cert->cert, - "tbsCertificate.subjectPublicKeyInfo", params, - params_size); + "tbsCertificate.subjectPublicKeyInfo", params); } #ifdef ENABLE_PKI @@ -344,78 +168,17 @@ _gnutls_x509_crt_get_mpis (gnutls_x509_crt_t cert, */ int _gnutls_x509_crq_get_mpis (gnutls_x509_crq_t cert, - bigint_t * params, int *params_size) + gnutls_pk_params_st* params) { /* Read the algorithm's OID */ return _gnutls_get_asn_mpis (cert->crq, "certificationRequestInfo.subjectPKInfo", - params, params_size); + params); } #endif -/* - * some x509 certificate functions that relate to MPI parameter - * setting. This writes the BIT STRING subjectPublicKey. - * Needs 2 parameters (m,e). - * - * Allocates the space used to store the DER data. - */ -int -_gnutls_x509_write_rsa_params (bigint_t * params, int params_size, - gnutls_datum_t * der) -{ - int result; - ASN1_TYPE spk = ASN1_TYPE_EMPTY; - - der->data = NULL; - der->size = 0; - - if (params_size < 2) - { - gnutls_assert (); - result = GNUTLS_E_INVALID_REQUEST; - goto cleanup; - } - - if ((result = asn1_create_element - (_gnutls_get_gnutls_asn (), "GNUTLS.RSAPublicKey", &spk)) - != ASN1_SUCCESS) - { - gnutls_assert (); - return _gnutls_asn2err (result); - } - - result = _gnutls_x509_write_int (spk, "modulus", params[0], 1); - if (result < 0) - { - gnutls_assert (); - goto cleanup; - } - - result = _gnutls_x509_write_int (spk, "publicExponent", params[1], 1); - if (result < 0) - { - gnutls_assert (); - goto cleanup; - } - - result = _gnutls_x509_der_encode (spk, "", der, 0); - if (result < 0) - { - gnutls_assert (); - goto cleanup; - } - - asn1_delete_structure (&spk); - return 0; - -cleanup: - asn1_delete_structure (&spk); - - return result; -} /* * This function writes and encodes the parameters for DSS or RSA keys. @@ -473,123 +236,7 @@ _gnutls_x509_write_sig_params (ASN1_TYPE dst, const char *dst_name, return 0; } -/* - * This function writes the parameters for DSS keys. - * Needs 3 parameters (p,q,g). - * - * Allocates the space used to store the DER data. - */ -int -_gnutls_x509_write_dsa_params (bigint_t * params, int params_size, - gnutls_datum_t * der) -{ - int result; - ASN1_TYPE spk = ASN1_TYPE_EMPTY; - - der->data = NULL; - der->size = 0; - - if (params_size < 3) - { - gnutls_assert (); - result = GNUTLS_E_INVALID_REQUEST; - goto cleanup; - } - - if ((result = asn1_create_element - (_gnutls_get_gnutls_asn (), "GNUTLS.DSAParameters", &spk)) - != ASN1_SUCCESS) - { - gnutls_assert (); - return _gnutls_asn2err (result); - } - - result = _gnutls_x509_write_int (spk, "p", params[0], 1); - if (result < 0) - { - gnutls_assert (); - goto cleanup; - } - - result = _gnutls_x509_write_int (spk, "q", params[1], 1); - if (result < 0) - { - gnutls_assert (); - goto cleanup; - } - - result = _gnutls_x509_write_int (spk, "g", params[2], 1); - if (result < 0) - { - gnutls_assert (); - goto cleanup; - } - - result = _gnutls_x509_der_encode (spk, "", der, 0); - if (result < 0) - { - gnutls_assert (); - goto cleanup; - } - - result = 0; - -cleanup: - asn1_delete_structure (&spk); - return result; -} - -/* - * This function writes the public parameters for DSS keys. - * Needs 1 parameter (y). - * - * Allocates the space used to store the DER data. - */ -int -_gnutls_x509_write_dsa_public_key (bigint_t * params, int params_size, - gnutls_datum_t * der) -{ - int result; - ASN1_TYPE spk = ASN1_TYPE_EMPTY; - - der->data = NULL; - der->size = 0; - - if (params_size < 3) - { - gnutls_assert (); - result = GNUTLS_E_INVALID_REQUEST; - goto cleanup; - } - if ((result = asn1_create_element - (_gnutls_get_gnutls_asn (), "GNUTLS.DSAPublicKey", &spk)) - != ASN1_SUCCESS) - { - gnutls_assert (); - return _gnutls_asn2err (result); - } - - result = _gnutls_x509_write_int (spk, "", params[3], 1); - if (result < 0) - { - gnutls_assert (); - goto cleanup; - } - - result = _gnutls_x509_der_encode (spk, "", der, 0); - if (result < 0) - { - gnutls_assert (); - goto cleanup; - } - - result = 0; - -cleanup: - asn1_delete_structure (&spk); - return result; -} /* this function reads a (small) unsigned integer diff --git a/lib/x509/privkey.c b/lib/x509/privkey.c index 66f3290489..925a97032e 100644 --- a/lib/x509/privkey.c +++ b/lib/x509/privkey.c @@ -35,8 +35,7 @@ #include <x509_int.h> #include <gnutls_pk.h> #include <gnutls_mpi.h> - -static int _gnutls_asn1_encode_rsa (ASN1_TYPE * c2, bigint_t * params); +#include <gnutls_ecc.h> /** * gnutls_x509_privkey_init: @@ -71,16 +70,10 @@ gnutls_x509_privkey_init (gnutls_x509_privkey_t * key) void gnutls_x509_privkey_deinit (gnutls_x509_privkey_t key) { - int i; - if (!key) return; - for (i = 0; i < key->params_size; i++) - { - _gnutls_mpi_release (&key->params[i]); - } - + gnutls_pk_params_release(&key->params); asn1_delete_structure (&key->key); gnutls_free (key); } @@ -104,40 +97,26 @@ gnutls_x509_privkey_cpy (gnutls_x509_privkey_t dst, gnutls_x509_privkey_t src) if (!src || !dst) return GNUTLS_E_INVALID_REQUEST; - for (i = 0; i < src->params_size; i++) + for (i = 0; i < src->params.params_nr; i++) { - dst->params[i] = _gnutls_mpi_copy (src->params[i]); - if (dst->params[i] == NULL) + dst->params.params[i] = _gnutls_mpi_copy (src->params.params[i]); + if (dst->params.params[i] == NULL) return GNUTLS_E_MEMORY_ERROR; } - dst->params_size = src->params_size; + dst->params.params_nr = src->params.params_nr; + dst->params.flags = src->params.flags; + dst->pk_algorithm = src->pk_algorithm; dst->crippled = src->crippled; if (!src->crippled) { - switch (dst->pk_algorithm) + ret = _gnutls_asn1_encode_privkey (dst->pk_algorithm, &dst->key, &dst->params); + if (ret < 0) { - case GNUTLS_PK_DSA: - ret = _gnutls_asn1_encode_dsa (&dst->key, dst->params); - if (ret < 0) - { - gnutls_assert (); - return ret; - } - break; - case GNUTLS_PK_RSA: - ret = _gnutls_asn1_encode_rsa (&dst->key, dst->params); - if (ret < 0) - { - gnutls_assert (); - return ret; - } - break; - default: gnutls_assert (); - return GNUTLS_E_INVALID_REQUEST; + return ret; } } @@ -153,10 +132,9 @@ _gnutls_privkey_decode_pkcs1_rsa_key (const gnutls_datum_t * raw_key, { int result; ASN1_TYPE pkey_asn; - gnutls_pk_params_st pk_params; - memset (&pk_params, 0, sizeof (pk_params)); - pk_params.params_nr = RSA_PRIVATE_PARAMS; + gnutls_pk_params_init(&pkey->params); + if ((result = asn1_create_element (_gnutls_get_gnutls_asn (), @@ -175,7 +153,7 @@ _gnutls_privkey_decode_pkcs1_rsa_key (const gnutls_datum_t * raw_key, } if ((result = _gnutls_x509_read_int (pkey_asn, "modulus", - &pk_params.params[0])) < 0) + &pkey->params.params[0])) < 0) { gnutls_assert (); goto error; @@ -183,7 +161,7 @@ _gnutls_privkey_decode_pkcs1_rsa_key (const gnutls_datum_t * raw_key, if ((result = _gnutls_x509_read_int (pkey_asn, "publicExponent", - &pk_params.params[1])) < 0) + &pkey->params.params[1])) < 0) { gnutls_assert (); goto error; @@ -191,74 +169,174 @@ _gnutls_privkey_decode_pkcs1_rsa_key (const gnutls_datum_t * raw_key, if ((result = _gnutls_x509_read_int (pkey_asn, "privateExponent", - &pk_params.params[2])) < 0) + &pkey->params.params[2])) < 0) { gnutls_assert (); goto error; } if ((result = _gnutls_x509_read_int (pkey_asn, "prime1", - &pk_params.params[3])) < 0) + &pkey->params.params[3])) < 0) { gnutls_assert (); goto error; } if ((result = _gnutls_x509_read_int (pkey_asn, "prime2", - &pk_params.params[4])) < 0) + &pkey->params.params[4])) < 0) { gnutls_assert (); goto error; } if ((result = _gnutls_x509_read_int (pkey_asn, "coefficient", - &pk_params.params[5])) < 0) + &pkey->params.params[5])) < 0) { gnutls_assert (); goto error; } if ((result = _gnutls_x509_read_int (pkey_asn, "exponent1", - &pk_params.params[6])) < 0) + &pkey->params.params[6])) < 0) { gnutls_assert (); goto error; } if ((result = _gnutls_x509_read_int (pkey_asn, "exponent2", - &pk_params.params[7])) < 0) + &pkey->params.params[7])) < 0) { gnutls_assert (); goto error; } - result = _gnutls_pk_fixup (GNUTLS_PK_RSA, GNUTLS_IMPORT, &pk_params); + result = _gnutls_pk_fixup (GNUTLS_PK_RSA, GNUTLS_IMPORT, &pkey->params); if (result < 0) { gnutls_assert (); goto error; } - pkey->params[0] = pk_params.params[0]; - pkey->params[1] = pk_params.params[1]; - pkey->params[2] = pk_params.params[2]; - pkey->params[3] = pk_params.params[3]; - pkey->params[4] = pk_params.params[4]; - pkey->params[5] = pk_params.params[5]; - pkey->params[6] = pk_params.params[6]; - pkey->params[7] = pk_params.params[7]; - pkey->params_size = pk_params.params_nr; + pkey->params.params_nr = RSA_PRIVATE_PARAMS; return pkey_asn; error: asn1_delete_structure (&pkey_asn); - gnutls_pk_params_release (&pk_params); + gnutls_pk_params_release (&pkey->params); + return NULL; + +} + +/* Converts an ECC key to + * an internal structure (gnutls_private_key) + */ +ASN1_TYPE +_gnutls_privkey_decode_ecc_key (const gnutls_datum_t * raw_key, + gnutls_x509_privkey_t pkey) +{ + int ret; + ASN1_TYPE pkey_asn; + unsigned int version; + char oid[MAX_OID_SIZE]; + unsigned int oid_size; + gnutls_datum out; + + gnutls_pk_params_init(&pkey->params); + + if ((ret = + asn1_create_element (_gnutls_get_gnutls_asn (), + "GNUTLS.ECPrivateKey", + &pkey_asn)) != ASN1_SUCCESS) + { + gnutls_assert (); + return NULL; + } + + ret = asn1_der_decoding (&pkey_asn, raw_key->data, raw_key->size, NULL); + if (ret != ASN1_SUCCESS) + { + gnutls_assert (); + goto error; + } + + ret = _gnutls_x509_read_uint (pkey_asn, "Version", &version); + if (ret < 0) + { + gnutls_assert(); + goto error; + } + + if (version != 1) + { + _gnutls_debug_log("ECC private key version %u is not supported\n", version); + gnutls_assert(); + goto error; + } + + /* read the curve */ + oid_size = sizeof(oid); + ret = asn1_read_value(pkey_asn, "parameters.namedCurve", oid, &oid_size); + if (ret != ASN1_SUCCESS) + { + gnutls_assert (); + goto error; + } + + pkey->params.flags = _gnutls_oid_to_ecc_curve(oid); + if (pkey->params.flags == GNUTLS_ECC_CURVE_INVALID) + { + _gnutls_debug_log("Curve %s is not supported\n", oid); + gnutls_assert(); + goto error; + } + + ret = _gnutls_ecc_curve_fill_params(pkey->params.flags, &pkey->params); + if (ret < 0) + { + gnutls_assert(); + goto error; + } + + /* read the public key */ + ret = _gnutls_x509_read_value(pkey_asn, "publicKey", &out, 2); + if (ret < 0) + { + gnutls_assert(); + goto error; + } + + ret = _gnutls_ecc_ansi_x963_import (out.data, out.size, &pkey->params.params[5], + &pkey->params.params[6]); + + _gnutls_free_datum(&out); + if (ret < 0) + { + gnutls_assert(); + goto error; + } + pkey->params.params_nr += 2; + + /* read the private key */ + ret = _gnutls_x509_read_int (pkey_asn, "privateKey", &pkey->params.params[7]); + if (ret < 0) + { + gnutls_assert(); + goto error; + } + pkey->params.params_nr ++; + + return pkey_asn; + +error: + asn1_delete_structure (&pkey_asn); + gnutls_pk_params_release (&pkey->params); return NULL; } + static ASN1_TYPE decode_dsa_key (const gnutls_datum_t * raw_key, gnutls_x509_privkey_t pkey) { @@ -274,54 +352,57 @@ decode_dsa_key (const gnutls_datum_t * raw_key, gnutls_x509_privkey_t pkey) return NULL; } + pkey->params.params_nr = 0; + result = asn1_der_decoding (&dsa_asn, raw_key->data, raw_key->size, NULL); if (result != ASN1_SUCCESS) { gnutls_assert (); goto error; } + pkey->params.params_nr++; - if ((result = _gnutls_x509_read_int (dsa_asn, "p", &pkey->params[0])) < 0) + if ((result = _gnutls_x509_read_int (dsa_asn, "p", &pkey->params.params[0])) < 0) { gnutls_assert (); goto error; } + pkey->params.params_nr++; - if ((result = _gnutls_x509_read_int (dsa_asn, "q", &pkey->params[1])) < 0) + if ((result = _gnutls_x509_read_int (dsa_asn, "q", &pkey->params.params[1])) < 0) { gnutls_assert (); goto error; } + pkey->params.params_nr++; - if ((result = _gnutls_x509_read_int (dsa_asn, "g", &pkey->params[2])) < 0) + if ((result = _gnutls_x509_read_int (dsa_asn, "g", &pkey->params.params[2])) < 0) { gnutls_assert (); goto error; } + pkey->params.params_nr++; - if ((result = _gnutls_x509_read_int (dsa_asn, "Y", &pkey->params[3])) < 0) + if ((result = _gnutls_x509_read_int (dsa_asn, "Y", &pkey->params.params[3])) < 0) { gnutls_assert (); goto error; } + pkey->params.params_nr++; if ((result = _gnutls_x509_read_int (dsa_asn, "priv", - &pkey->params[4])) < 0) + &pkey->params.params[4])) < 0) { gnutls_assert (); goto error; } - pkey->params_size = 5; + pkey->params.params_nr++; return dsa_asn; error: asn1_delete_structure (&dsa_asn); - _gnutls_mpi_release (&pkey->params[0]); - _gnutls_mpi_release (&pkey->params[1]); - _gnutls_mpi_release (&pkey->params[2]); - _gnutls_mpi_release (&pkey->params[3]); - _gnutls_mpi_release (&pkey->params[4]); + gnutls_pk_params_release(&pkey->params); return NULL; } @@ -414,6 +495,12 @@ gnutls_x509_privkey_import (gnutls_x509_privkey_t key, if (key->key == NULL) gnutls_assert (); } + else if (key->pk_algorithm == GNUTLS_PK_ECC) + { + key->key = _gnutls_privkey_decode_ecc_key (&_data, key); + if (key->key == NULL) + gnutls_assert (); + } else { /* Try decoding with both, and accept the one that @@ -463,11 +550,6 @@ failover: return result; } -#define FREE_RSA_PRIVATE_PARAMS for (i=0;i<RSA_PRIVATE_PARAMS;i++) \ - _gnutls_mpi_release(&key->params[i]) -#define FREE_DSA_PRIVATE_PARAMS for (i=0;i<DSA_PRIVATE_PARAMS;i++) \ - _gnutls_mpi_release(&key->params[i]) - /** * gnutls_x509_privkey_import_rsa_raw: * @key: The structure to store the parsed key @@ -528,11 +610,10 @@ gnutls_x509_privkey_import_rsa_raw2 (gnutls_x509_privkey_t key, const gnutls_datum_t * e1, const gnutls_datum_t * e2) { - int i = 0, ret; + int ret; size_t siz = 0; - gnutls_pk_params_st pk_params; - memset (&pk_params, 0, sizeof (pk_params)); + gnutls_pk_params_init(&key->params); if (key == NULL) { @@ -540,120 +621,109 @@ gnutls_x509_privkey_import_rsa_raw2 (gnutls_x509_privkey_t key, return GNUTLS_E_INVALID_REQUEST; } - key->params_size = 0; + key->params.params_nr = 0; siz = m->size; - if (_gnutls_mpi_scan_nz (&key->params[0], m->data, siz)) + if (_gnutls_mpi_scan_nz (&key->params.params[0], m->data, siz)) { gnutls_assert (); - FREE_RSA_PRIVATE_PARAMS; - return GNUTLS_E_MPI_SCAN_FAILED; + ret = GNUTLS_E_MPI_SCAN_FAILED; + goto cleanup; } - key->params_size++; + key->params.params_nr++; siz = e->size; - if (_gnutls_mpi_scan_nz (&key->params[1], e->data, siz)) + if (_gnutls_mpi_scan_nz (&key->params.params[1], e->data, siz)) { gnutls_assert (); - FREE_RSA_PRIVATE_PARAMS; - return GNUTLS_E_MPI_SCAN_FAILED; + ret = GNUTLS_E_MPI_SCAN_FAILED; + goto cleanup; } - key->params_size++; + key->params.params_nr++; siz = d->size; - if (_gnutls_mpi_scan_nz (&key->params[2], d->data, siz)) + if (_gnutls_mpi_scan_nz (&key->params.params[2], d->data, siz)) { gnutls_assert (); - FREE_RSA_PRIVATE_PARAMS; - return GNUTLS_E_MPI_SCAN_FAILED; + ret = GNUTLS_E_MPI_SCAN_FAILED; + goto cleanup; } - key->params_size++; + key->params.params_nr++; siz = p->size; - if (_gnutls_mpi_scan_nz (&key->params[3], p->data, siz)) + if (_gnutls_mpi_scan_nz (&key->params.params[3], p->data, siz)) { gnutls_assert (); - FREE_RSA_PRIVATE_PARAMS; - return GNUTLS_E_MPI_SCAN_FAILED; + ret = GNUTLS_E_MPI_SCAN_FAILED; + goto cleanup; } - key->params_size++; + key->params.params_nr++; siz = q->size; - if (_gnutls_mpi_scan_nz (&key->params[4], q->data, siz)) + if (_gnutls_mpi_scan_nz (&key->params.params[4], q->data, siz)) { gnutls_assert (); - FREE_RSA_PRIVATE_PARAMS; - return GNUTLS_E_MPI_SCAN_FAILED; + ret = GNUTLS_E_MPI_SCAN_FAILED; + goto cleanup; } - key->params_size++; + key->params.params_nr++; siz = u->size; - if (_gnutls_mpi_scan_nz (&key->params[5], u->data, siz)) + if (_gnutls_mpi_scan_nz (&key->params.params[5], u->data, siz)) { gnutls_assert (); - FREE_RSA_PRIVATE_PARAMS; - return GNUTLS_E_MPI_SCAN_FAILED; + ret = GNUTLS_E_MPI_SCAN_FAILED; + goto cleanup; } - key->params_size++; + key->params.params_nr++; if (e1 && e2) { siz = e1->size; - if (_gnutls_mpi_scan_nz (&key->params[6], e1->data, siz)) + if (_gnutls_mpi_scan_nz (&key->params.params[6], e1->data, siz)) { gnutls_assert (); - FREE_RSA_PRIVATE_PARAMS; - return GNUTLS_E_MPI_SCAN_FAILED; + ret = GNUTLS_E_MPI_SCAN_FAILED; + goto cleanup; } - key->params_size++; + key->params.params_nr++; siz = e2->size; - if (_gnutls_mpi_scan_nz (&key->params[7], e2->data, siz)) + if (_gnutls_mpi_scan_nz (&key->params.params[7], e2->data, siz)) { gnutls_assert (); - FREE_RSA_PRIVATE_PARAMS; - return GNUTLS_E_MPI_SCAN_FAILED; + ret = GNUTLS_E_MPI_SCAN_FAILED; + goto cleanup; } - key->params_size++; - } - - for (i = 0; i < key->params_size; i++) - { - pk_params.params[i] = key->params[i]; + key->params.params_nr++; } - pk_params.params_nr = key->params_size; - - ret = _gnutls_pk_fixup (GNUTLS_PK_RSA, GNUTLS_IMPORT, &pk_params); + ret = _gnutls_pk_fixup (GNUTLS_PK_RSA, GNUTLS_IMPORT, &key->params); if (ret < 0) { gnutls_assert (); - FREE_RSA_PRIVATE_PARAMS; - return ret; - } - - for (i = 0; i < pk_params.params_nr; i++) - { - key->params[i] = pk_params.params[i]; + goto cleanup; } - key->params_size = pk_params.params_nr; if (!key->crippled) { - ret = _gnutls_asn1_encode_rsa (&key->key, key->params); + ret = _gnutls_asn1_encode_privkey (GNUTLS_PK_RSA, &key->key, &key->params); if (ret < 0) { gnutls_assert (); - FREE_RSA_PRIVATE_PARAMS; - return ret; + goto cleanup; } } - key->params_size = RSA_PRIVATE_PARAMS; + key->params.params_nr = RSA_PRIVATE_PARAMS; key->pk_algorithm = GNUTLS_PK_RSA; return 0; +cleanup: + gnutls_pk_params_release(&key->params); + return ret; + } /** @@ -680,7 +750,7 @@ gnutls_x509_privkey_import_dsa_raw (gnutls_x509_privkey_t key, const gnutls_datum_t * y, const gnutls_datum_t * x) { - int i = 0, ret; + int ret; size_t siz = 0; if (key == NULL) @@ -690,61 +760,64 @@ gnutls_x509_privkey_import_dsa_raw (gnutls_x509_privkey_t key, } siz = p->size; - if (_gnutls_mpi_scan_nz (&key->params[0], p->data, siz)) + if (_gnutls_mpi_scan_nz (&key->params.params[0], p->data, siz)) { gnutls_assert (); - FREE_DSA_PRIVATE_PARAMS; - return GNUTLS_E_MPI_SCAN_FAILED; + ret = GNUTLS_E_MPI_SCAN_FAILED; + goto cleanup; } siz = q->size; - if (_gnutls_mpi_scan_nz (&key->params[1], q->data, siz)) + if (_gnutls_mpi_scan_nz (&key->params.params[1], q->data, siz)) { gnutls_assert (); - FREE_DSA_PRIVATE_PARAMS; - return GNUTLS_E_MPI_SCAN_FAILED; + ret = GNUTLS_E_MPI_SCAN_FAILED; + goto cleanup; } siz = g->size; - if (_gnutls_mpi_scan_nz (&key->params[2], g->data, siz)) + if (_gnutls_mpi_scan_nz (&key->params.params[2], g->data, siz)) { gnutls_assert (); - FREE_DSA_PRIVATE_PARAMS; - return GNUTLS_E_MPI_SCAN_FAILED; + ret = GNUTLS_E_MPI_SCAN_FAILED; + goto cleanup; } siz = y->size; - if (_gnutls_mpi_scan_nz (&key->params[3], y->data, siz)) + if (_gnutls_mpi_scan_nz (&key->params.params[3], y->data, siz)) { gnutls_assert (); - FREE_DSA_PRIVATE_PARAMS; - return GNUTLS_E_MPI_SCAN_FAILED; + ret = GNUTLS_E_MPI_SCAN_FAILED; + goto cleanup; } siz = x->size; - if (_gnutls_mpi_scan_nz (&key->params[4], x->data, siz)) + if (_gnutls_mpi_scan_nz (&key->params.params[4], x->data, siz)) { gnutls_assert (); - FREE_DSA_PRIVATE_PARAMS; - return GNUTLS_E_MPI_SCAN_FAILED; + ret = GNUTLS_E_MPI_SCAN_FAILED; + goto cleanup; } if (!key->crippled) { - ret = _gnutls_asn1_encode_dsa (&key->key, key->params); + ret = _gnutls_asn1_encode_privkey (GNUTLS_PK_DSA, &key->key, &key->params); if (ret < 0) { gnutls_assert (); - FREE_DSA_PRIVATE_PARAMS; - return ret; + goto cleanup; } } - key->params_size = DSA_PRIVATE_PARAMS; + key->params.params_nr = DSA_PRIVATE_PARAMS; key->pk_algorithm = GNUTLS_PK_DSA; return 0; +cleanup: + gnutls_pk_params_release(&key->params); + return ret; + } @@ -814,29 +887,12 @@ gnutls_x509_privkey_export (gnutls_x509_privkey_t key, msg = NULL; if (key->crippled) - { /* encode the parameters on the fly. - */ - switch (key->pk_algorithm) + { /* encode the parameters on the fly. */ + ret = _gnutls_asn1_encode_privkey (key->pk_algorithm, &key->key, &key->params); + if (ret < 0) { - case GNUTLS_PK_DSA: - ret = _gnutls_asn1_encode_dsa (&key->key, key->params); - if (ret < 0) - { - gnutls_assert (); - return ret; - } - break; - case GNUTLS_PK_RSA: - ret = _gnutls_asn1_encode_rsa (&key->key, key->params); - if (ret < 0) - { - gnutls_assert (); - return ret; - } - break; - default: gnutls_assert (); - return GNUTLS_E_INVALID_REQUEST; + return ret; } } @@ -857,23 +913,13 @@ gnutls_x509_privkey_export (gnutls_x509_privkey_t key, gnutls_sec_param_t gnutls_x509_privkey_sec_param (gnutls_x509_privkey_t key) { - int ret; + int bits; - switch (key->pk_algorithm) - { - case GNUTLS_PK_RSA: - ret = gnutls_pk_bits_to_sec_param (GNUTLS_PK_RSA, _gnutls_mpi_get_nbits (key->params[0] /*m */ - )); - break; - case GNUTLS_PK_DSA: - ret = gnutls_pk_bits_to_sec_param (GNUTLS_PK_DSA, _gnutls_mpi_get_nbits (key->params[0] /*p */ - )); - break; - default: - ret = GNUTLS_SEC_PARAM_UNKNOWN; - } - - return ret; + bits = pubkey_to_bits(key->pk_algorithm, &key->params); + if (bits <= 0) + return GNUTLS_SEC_PARAM_UNKNOWN; + + return gnutls_pk_bits_to_sec_param(key->pk_algorithm, bits); } /** @@ -932,8 +978,8 @@ gnutls_x509_privkey_export_rsa_raw2 (gnutls_x509_privkey_t key, { int ret; gnutls_pk_params_st pk_params; - - memset (&pk_params, 0, sizeof (pk_params)); + + gnutls_pk_params_init(&pk_params); if (key == NULL) { @@ -944,7 +990,7 @@ gnutls_x509_privkey_export_rsa_raw2 (gnutls_x509_privkey_t key, m->data = e->data = d->data = p->data = q->data = u->data = NULL; m->size = e->size = d->size = p->size = q->size = u->size = 0; - ret = _gnutls_pk_params_copy (&pk_params, key->params, RSA_PRIVATE_PARAMS); + ret = _gnutls_pk_params_copy (&pk_params, &key->params); if (ret < 0) { gnutls_assert (); @@ -998,7 +1044,7 @@ gnutls_x509_privkey_export_rsa_raw2 (gnutls_x509_privkey_t key, } /* U */ - ret = _gnutls_mpi_dprint_lz (key->params[5], u); + ret = _gnutls_mpi_dprint_lz (key->params.params[5], u); if (ret < 0) { gnutls_assert (); @@ -1008,7 +1054,7 @@ gnutls_x509_privkey_export_rsa_raw2 (gnutls_x509_privkey_t key, /* E1 */ if (e1) { - ret = _gnutls_mpi_dprint_lz (key->params[6], e1); + ret = _gnutls_mpi_dprint_lz (key->params.params[6], e1); if (ret < 0) { gnutls_assert (); @@ -1019,7 +1065,7 @@ gnutls_x509_privkey_export_rsa_raw2 (gnutls_x509_privkey_t key, /* E2 */ if (e2) { - ret = _gnutls_mpi_dprint_lz (key->params[7], e2); + ret = _gnutls_mpi_dprint_lz (key->params.params[7], e2); if (ret < 0) { gnutls_assert (); @@ -1073,7 +1119,7 @@ gnutls_x509_privkey_export_dsa_raw (gnutls_x509_privkey_t key, } /* P */ - ret = _gnutls_mpi_dprint_lz (key->params[0], p); + ret = _gnutls_mpi_dprint_lz (key->params.params[0], p); if (ret < 0) { gnutls_assert (); @@ -1081,7 +1127,7 @@ gnutls_x509_privkey_export_dsa_raw (gnutls_x509_privkey_t key, } /* Q */ - ret = _gnutls_mpi_dprint_lz (key->params[1], q); + ret = _gnutls_mpi_dprint_lz (key->params.params[1], q); if (ret < 0) { gnutls_assert (); @@ -1091,7 +1137,7 @@ gnutls_x509_privkey_export_dsa_raw (gnutls_x509_privkey_t key, /* G */ - ret = _gnutls_mpi_dprint_lz (key->params[2], g); + ret = _gnutls_mpi_dprint_lz (key->params.params[2], g); if (ret < 0) { gnutls_assert (); @@ -1102,7 +1148,7 @@ gnutls_x509_privkey_export_dsa_raw (gnutls_x509_privkey_t key, /* Y */ - ret = _gnutls_mpi_dprint_lz (key->params[3], y); + ret = _gnutls_mpi_dprint_lz (key->params.params[3], y); if (ret < 0) { gnutls_assert (); @@ -1113,7 +1159,7 @@ gnutls_x509_privkey_export_dsa_raw (gnutls_x509_privkey_t key, } /* X */ - ret = _gnutls_mpi_dprint_lz (key->params[4], x); + ret = _gnutls_mpi_dprint_lz (key->params.params[4], x); if (ret < 0) { gnutls_assert (); @@ -1128,343 +1174,6 @@ gnutls_x509_privkey_export_dsa_raw (gnutls_x509_privkey_t key, } -/* Encodes the RSA parameters into an ASN.1 RSA private key structure. - */ -static int -_gnutls_asn1_encode_rsa (ASN1_TYPE * c2, bigint_t * params) -{ - int result; - opaque null = '\0'; - gnutls_pk_params_st pk_params; - gnutls_datum_t m, e, d, p, q, u, exp1, exp2; - - memset (&pk_params, 0, sizeof (pk_params)); - - memset (&m, 0, sizeof (m)); - memset (&p, 0, sizeof (p)); - memset (&q, 0, sizeof (q)); - memset (&p, 0, sizeof (p)); - memset (&u, 0, sizeof (u)); - memset (&e, 0, sizeof (e)); - memset (&d, 0, sizeof (d)); - memset (&exp1, 0, sizeof (exp1)); - memset (&exp2, 0, sizeof (exp2)); - - result = _gnutls_pk_params_copy (&pk_params, params, RSA_PRIVATE_PARAMS); - if (result < 0) - { - gnutls_assert (); - return result; - } - - result = _gnutls_pk_fixup (GNUTLS_PK_RSA, GNUTLS_EXPORT, &pk_params); - if (result < 0) - { - gnutls_assert (); - goto cleanup; - } - - /* retrieve as data */ - - result = _gnutls_mpi_dprint_lz (pk_params.params[0], &m); - if (result < 0) - { - gnutls_assert (); - goto cleanup; - } - - result = _gnutls_mpi_dprint_lz (pk_params.params[1], &e); - if (result < 0) - { - gnutls_assert (); - goto cleanup; - } - - result = _gnutls_mpi_dprint_lz (pk_params.params[2], &d); - if (result < 0) - { - gnutls_assert (); - goto cleanup; - } - - result = _gnutls_mpi_dprint_lz (pk_params.params[3], &p); - if (result < 0) - { - gnutls_assert (); - goto cleanup; - } - - result = _gnutls_mpi_dprint_lz (pk_params.params[4], &q); - if (result < 0) - { - gnutls_assert (); - goto cleanup; - } - - result = _gnutls_mpi_dprint_lz (pk_params.params[5], &u); - if (result < 0) - { - gnutls_assert (); - goto cleanup; - } - - result = _gnutls_mpi_dprint_lz (pk_params.params[6], &exp1); - if (result < 0) - { - gnutls_assert (); - goto cleanup; - } - - result = _gnutls_mpi_dprint_lz (pk_params.params[7], &exp2); - if (result < 0) - { - gnutls_assert (); - goto cleanup; - } - - /* Ok. Now we have the data. Create the asn1 structures - */ - - /* first make sure that no previously allocated data are leaked */ - if (*c2 != ASN1_TYPE_EMPTY) - { - asn1_delete_structure (c2); - *c2 = ASN1_TYPE_EMPTY; - } - - if ((result = asn1_create_element - (_gnutls_get_gnutls_asn (), "GNUTLS.RSAPrivateKey", c2)) - != ASN1_SUCCESS) - { - gnutls_assert (); - result = _gnutls_asn2err (result); - goto cleanup; - } - - /* Write PRIME - */ - if ((result = asn1_write_value (*c2, "modulus", - m.data, m.size)) != ASN1_SUCCESS) - { - gnutls_assert (); - result = _gnutls_asn2err (result); - goto cleanup; - } - - if ((result = asn1_write_value (*c2, "publicExponent", - e.data, e.size)) != ASN1_SUCCESS) - { - gnutls_assert (); - result = _gnutls_asn2err (result); - goto cleanup; - } - - if ((result = asn1_write_value (*c2, "privateExponent", - d.data, d.size)) != ASN1_SUCCESS) - { - gnutls_assert (); - result = _gnutls_asn2err (result); - goto cleanup; - } - - if ((result = asn1_write_value (*c2, "prime1", - p.data, p.size)) != ASN1_SUCCESS) - { - gnutls_assert (); - result = _gnutls_asn2err (result); - goto cleanup; - } - - if ((result = asn1_write_value (*c2, "prime2", - q.data, q.size)) != ASN1_SUCCESS) - { - gnutls_assert (); - result = _gnutls_asn2err (result); - goto cleanup; - } - - if ((result = asn1_write_value (*c2, "coefficient", - u.data, u.size)) != ASN1_SUCCESS) - { - gnutls_assert (); - result = _gnutls_asn2err (result); - - goto cleanup; - } - - if ((result = asn1_write_value (*c2, "exponent1", - exp1.data, exp1.size)) != ASN1_SUCCESS) - { - gnutls_assert (); - result = _gnutls_asn2err (result); - goto cleanup; - } - - if ((result = asn1_write_value (*c2, "exponent2", - exp2.data, exp2.size)) != ASN1_SUCCESS) - { - gnutls_assert (); - result = _gnutls_asn2err (result); - goto cleanup; - } - - if ((result = asn1_write_value (*c2, "otherPrimeInfos", - NULL, 0)) != ASN1_SUCCESS) - { - gnutls_assert (); - result = _gnutls_asn2err (result); - goto cleanup; - } - - if ((result = asn1_write_value (*c2, "version", &null, 1)) != ASN1_SUCCESS) - { - gnutls_assert (); - result = _gnutls_asn2err (result); - goto cleanup; - } - - result = 0; - -cleanup: - if (result != 0) - asn1_delete_structure (c2); - - gnutls_pk_params_release (&pk_params); - - _gnutls_free_datum (&m); - _gnutls_free_datum (&d); - _gnutls_free_datum (&e); - _gnutls_free_datum (&p); - _gnutls_free_datum (&q); - _gnutls_free_datum (&u); - _gnutls_free_datum (&exp1); - _gnutls_free_datum (&exp2); - - return result; -} - -/* Encodes the DSA parameters into an ASN.1 DSAPrivateKey structure. - */ -int -_gnutls_asn1_encode_dsa (ASN1_TYPE * c2, bigint_t * params) -{ - int result, i; - size_t size[DSA_PRIVATE_PARAMS], total; - opaque *p_data, *q_data, *g_data, *x_data, *y_data; - opaque *all_data = NULL, *p; - opaque null = '\0'; - - /* Read all the sizes */ - total = 0; - for (i = 0; i < DSA_PRIVATE_PARAMS; i++) - { - _gnutls_mpi_print_lz (params[i], NULL, &size[i]); - total += size[i]; - } - - /* Encoding phase. - * allocate data enough to hold everything - */ - all_data = gnutls_secure_malloc (total); - if (all_data == NULL) - { - gnutls_assert (); - result = GNUTLS_E_MEMORY_ERROR; - goto cleanup; - } - - p = all_data; - p_data = p; - p += size[0]; - q_data = p; - p += size[1]; - g_data = p; - p += size[2]; - y_data = p; - p += size[3]; - x_data = p; - - _gnutls_mpi_print_lz (params[0], p_data, &size[0]); - _gnutls_mpi_print_lz (params[1], q_data, &size[1]); - _gnutls_mpi_print_lz (params[2], g_data, &size[2]); - _gnutls_mpi_print_lz (params[3], y_data, &size[3]); - _gnutls_mpi_print_lz (params[4], x_data, &size[4]); - - /* Ok. Now we have the data. Create the asn1 structures - */ - - /* first make sure that no previously allocated data are leaked */ - if (*c2 != ASN1_TYPE_EMPTY) - { - asn1_delete_structure (c2); - *c2 = ASN1_TYPE_EMPTY; - } - - if ((result = asn1_create_element - (_gnutls_get_gnutls_asn (), "GNUTLS.DSAPrivateKey", c2)) - != ASN1_SUCCESS) - { - gnutls_assert (); - result = _gnutls_asn2err (result); - goto cleanup; - } - - /* Write PRIME - */ - if ((result = asn1_write_value (*c2, "p", p_data, size[0])) != ASN1_SUCCESS) - { - gnutls_assert (); - result = _gnutls_asn2err (result); - goto cleanup; - } - - if ((result = asn1_write_value (*c2, "q", q_data, size[1])) != ASN1_SUCCESS) - { - gnutls_assert (); - result = _gnutls_asn2err (result); - goto cleanup; - } - - if ((result = asn1_write_value (*c2, "g", g_data, size[2])) != ASN1_SUCCESS) - { - gnutls_assert (); - result = _gnutls_asn2err (result); - goto cleanup; - } - - if ((result = asn1_write_value (*c2, "Y", y_data, size[3])) != ASN1_SUCCESS) - { - gnutls_assert (); - result = _gnutls_asn2err (result); - goto cleanup; - } - - if ((result = asn1_write_value (*c2, "priv", - x_data, size[4])) != ASN1_SUCCESS) - { - gnutls_assert (); - result = _gnutls_asn2err (result); - goto cleanup; - } - - gnutls_free (all_data); - - if ((result = asn1_write_value (*c2, "version", &null, 1)) != ASN1_SUCCESS) - { - gnutls_assert (); - result = _gnutls_asn2err (result); - goto cleanup; - } - - return 0; - -cleanup: - asn1_delete_structure (c2); - gnutls_free (all_data); - - return result; -} - /** * gnutls_x509_privkey_generate: @@ -1487,8 +1196,6 @@ gnutls_x509_privkey_generate (gnutls_x509_privkey_t key, unsigned int flags) { int ret; - unsigned int params_len = MAX_PRIV_PARAMS_SIZE; - unsigned int i; if (key == NULL) { @@ -1496,74 +1203,31 @@ gnutls_x509_privkey_generate (gnutls_x509_privkey_t key, return GNUTLS_E_INVALID_REQUEST; } - switch (algo) - { - case GNUTLS_PK_DSA: - ret = _gnutls_dsa_generate_params (key->params, ¶ms_len, bits); - if (params_len != DSA_PRIVATE_PARAMS) - { - gnutls_assert (); - ret = GNUTLS_E_INTERNAL_ERROR; - } - - if (ret < 0) - { - gnutls_assert (); - return ret; - } + gnutls_pk_params_init(&key->params); - if (!key->crippled) - { - ret = _gnutls_asn1_encode_dsa (&key->key, key->params); - if (ret < 0) - { - gnutls_assert (); - goto cleanup; - } - } - key->params_size = params_len; - key->pk_algorithm = GNUTLS_PK_DSA; + ret = _gnutls_pk_generate (algo, bits, &key->params); + if (ret < 0) + { + gnutls_assert (); + return ret; + } - break; - case GNUTLS_PK_RSA: - ret = _gnutls_rsa_generate_params (key->params, ¶ms_len, bits); - if (params_len != RSA_PRIVATE_PARAMS) - { - gnutls_assert (); - ret = GNUTLS_E_INTERNAL_ERROR; - } + if (!key->crippled) + { + ret = _gnutls_asn1_encode_privkey (algo, &key->key, &key->params); if (ret < 0) { gnutls_assert (); - return ret; - } - - if (!key->crippled) - { - ret = _gnutls_asn1_encode_rsa (&key->key, key->params); - if (ret < 0) - { - gnutls_assert (); - goto cleanup; - } + goto cleanup; } - - key->params_size = params_len; - key->pk_algorithm = GNUTLS_PK_RSA; - - break; - default: - gnutls_assert (); - return GNUTLS_E_INVALID_REQUEST; } + key->pk_algorithm = algo; return 0; cleanup: key->pk_algorithm = GNUTLS_PK_UNKNOWN; - key->params_size = 0; - for (i = 0; i < params_len; i++) - _gnutls_mpi_release (&key->params[i]); + gnutls_pk_params_release(&key->params); return ret; } @@ -1611,29 +1275,12 @@ gnutls_x509_privkey_get_key_id (gnutls_x509_privkey_t key, return GNUTLS_E_SHORT_MEMORY_BUFFER; } - if (key->pk_algorithm == GNUTLS_PK_RSA) - { - result = - _gnutls_x509_write_rsa_params (key->params, key->params_size, &der); - if (result < 0) - { - gnutls_assert (); - goto cleanup; - } - } - else if (key->pk_algorithm == GNUTLS_PK_DSA) + result = _gnutls_x509_write_pubkey(key->pk_algorithm, &key->params, &der); + if (result < 0) { - result = - _gnutls_x509_write_dsa_public_key (key->params, - key->params_size, &der); - if (result < 0) - { - gnutls_assert (); - goto cleanup; - } + gnutls_assert (); + goto cleanup; } - else - return GNUTLS_E_INTERNAL_ERROR; result = _gnutls_hash_init (&hd, GNUTLS_MAC_SHA1); if (result < 0) @@ -1705,8 +1352,8 @@ _gnutls_x509_privkey_sign_hash2 (gnutls_x509_privkey_t signer, goto cleanup; } - ret = _gnutls_soft_sign (signer->pk_algorithm, signer->params, - signer->params_size, &digest, signature); + ret = _gnutls_soft_sign (signer->pk_algorithm, &signer->params, + &digest, signature); if (ret < 0) { @@ -1750,8 +1397,8 @@ gnutls_x509_privkey_sign_hash (gnutls_x509_privkey_t key, return GNUTLS_E_INVALID_REQUEST; } - result = _gnutls_soft_sign (key->pk_algorithm, key->params, - key->params_size, hash, signature); + result = _gnutls_soft_sign (key->pk_algorithm, &key->params, + hash, signature); if (result < 0) { gnutls_assert (); @@ -1806,7 +1453,7 @@ gnutls_x509_privkey_sign_data (gnutls_x509_privkey_t key, } result = - pk_hash_data (key->pk_algorithm, digest, key->params, data, &hash); + pk_hash_data (key->pk_algorithm, digest, &key->params, data, &hash); if (result < 0) { gnutls_assert (); @@ -1902,27 +1549,12 @@ gnutls_x509_privkey_fix (gnutls_x509_privkey_t key) if (!key->crippled) asn1_delete_structure (&key->key); - switch (key->pk_algorithm) + + ret = _gnutls_asn1_encode_privkey (key->pk_algorithm, &key->key, &key->params); + if (ret < 0) { - case GNUTLS_PK_DSA: - ret = _gnutls_asn1_encode_dsa (&key->key, key->params); - if (ret < 0) - { - gnutls_assert (); - return ret; - } - break; - case GNUTLS_PK_RSA: - ret = _gnutls_asn1_encode_rsa (&key->key, key->params); - if (ret < 0) - { - gnutls_assert (); - return ret; - } - break; - default: gnutls_assert (); - return GNUTLS_E_INVALID_REQUEST; + return ret; } return 0; diff --git a/lib/x509/privkey_pkcs8.c b/lib/x509/privkey_pkcs8.c index 47059d5679..5ef565deb4 100644 --- a/lib/x509/privkey_pkcs8.c +++ b/lib/x509/privkey_pkcs8.c @@ -40,6 +40,8 @@ #include <random.h> #include <pbkdf2-sha1.h> +static int _decode_pkcs8_ecc_key (ASN1_TYPE pkcs8_asn, gnutls_x509_privkey_t pkey); + #define PBES2_OID "1.2.840.113549.1.5.13" #define PBKDF2_OID "1.2.840.113549.1.5.12" #define DES_EDE3_CBC_OID "1.2.840.113549.3.7" @@ -140,6 +142,7 @@ _encode_privkey (gnutls_x509_privkey_t pkey, gnutls_datum_t * raw) switch (pkey->pk_algorithm) { case GNUTLS_PK_RSA: + case GNUTLS_PK_ECC: ret = gnutls_x509_privkey_export (pkey, GNUTLS_X509_FMT_DER, NULL, &size); if (ret != GNUTLS_E_SHORT_MEMORY_BUFFER) @@ -178,7 +181,7 @@ _encode_privkey (gnutls_x509_privkey_t pkey, gnutls_datum_t * raw) return _gnutls_asn2err (ret); } - ret = _gnutls_x509_write_int (spk, "", pkey->params[4], 1); + ret = _gnutls_x509_write_int (spk, "", pkey->params.params[4], 1); if (ret < 0) { gnutls_assert (); @@ -223,30 +226,19 @@ encode_to_private_key_info (gnutls_x509_privkey_t pkey, gnutls_datum_t algo_params = { NULL, 0 }; gnutls_datum_t algo_privkey = { NULL, 0 }; - if (pkey->pk_algorithm != GNUTLS_PK_RSA - && pkey->pk_algorithm != GNUTLS_PK_DSA) + oid = _gnutls_x509_pk_to_oid(pkey->pk_algorithm); + if (oid == NULL) { gnutls_assert (); return GNUTLS_E_UNIMPLEMENTED_FEATURE; } - if (pkey->pk_algorithm == GNUTLS_PK_RSA) - { - oid = PK_PKIX1_RSA_OID; - /* parameters are null - */ - } - else + result = + _gnutls_x509_write_pubkey_params (pkey->pk_algorithm, &pkey->params, &algo_params); + if (result < 0) { - oid = PK_DSA_OID; - result = - _gnutls_x509_write_dsa_params (pkey->params, pkey->params_size, - &algo_params); - if (result < 0) - { - gnutls_assert (); - return result; - } + gnutls_assert (); + return result; } if ((result = @@ -986,6 +978,36 @@ error: return ret; } +/* Decodes an ECC privateKey from a PKCS8 structure. + */ +static int +_decode_pkcs8_ecc_key (ASN1_TYPE pkcs8_asn, gnutls_x509_privkey_t pkey) +{ + int ret; + gnutls_datum_t tmp; + + ret = _gnutls_x509_read_value (pkcs8_asn, "privateKey", &tmp, 0); + if (ret < 0) + { + gnutls_assert (); + goto error; + } + + pkey->key = _gnutls_privkey_decode_ecc_key (&tmp, pkey); + _gnutls_free_datum (&tmp); + if (pkey->key == NULL) + { + gnutls_assert (); + goto error; + } + + return 0; + +error: + gnutls_x509_privkey_deinit (pkey); + return ret; +} + /* Decodes an DSA privateKey and params from a PKCS8 structure. */ static int @@ -1001,7 +1023,7 @@ _decode_pkcs8_dsa_key (ASN1_TYPE pkcs8_asn, gnutls_x509_privkey_t pkey) goto error; } - ret = _gnutls_x509_read_der_int (tmp.data, tmp.size, &pkey->params[4]); + ret = _gnutls_x509_read_der_int (tmp.data, tmp.size, &pkey->params.params[4]); _gnutls_free_datum (&tmp); if (ret < 0) @@ -1019,7 +1041,7 @@ _decode_pkcs8_dsa_key (ASN1_TYPE pkcs8_asn, gnutls_x509_privkey_t pkey) goto error; } - ret = _gnutls_x509_read_dsa_params (tmp.data, tmp.size, pkey->params); + ret = _gnutls_x509_read_pubkey_params (GNUTLS_PK_DSA, tmp.data, tmp.size, &pkey->params); _gnutls_free_datum (&tmp); if (ret < 0) { @@ -1028,19 +1050,19 @@ _decode_pkcs8_dsa_key (ASN1_TYPE pkcs8_asn, gnutls_x509_privkey_t pkey) } /* the public key can be generated as g^x mod p */ - pkey->params[3] = _gnutls_mpi_alloc_like (pkey->params[0]); - if (pkey->params[3] == NULL) + pkey->params.params[3] = _gnutls_mpi_alloc_like (pkey->params.params[0]); + if (pkey->params.params[3] == NULL) { gnutls_assert (); goto error; } - _gnutls_mpi_powm (pkey->params[3], pkey->params[2], pkey->params[4], - pkey->params[0]); + _gnutls_mpi_powm (pkey->params.params[3], pkey->params.params[2], pkey->params.params[4], + pkey->params.params[0]); if (!pkey->crippled) { - ret = _gnutls_asn1_encode_dsa (&pkey->key, pkey->params); + ret = _gnutls_asn1_encode_privkey (GNUTLS_PK_DSA, &pkey->key, &pkey->params); if (ret < 0) { gnutls_assert (); @@ -1048,7 +1070,7 @@ _decode_pkcs8_dsa_key (ASN1_TYPE pkcs8_asn, gnutls_x509_privkey_t pkey) } } - pkey->params_size = DSA_PRIVATE_PARAMS; + pkey->params.params_nr = DSA_PRIVATE_PARAMS; return 0; @@ -1099,11 +1121,9 @@ decode_private_key_info (const gnutls_datum_t * der, /* we only support RSA and DSA private keys. */ - if (strcmp (oid, PK_PKIX1_RSA_OID) == 0) - pkey->pk_algorithm = GNUTLS_PK_RSA; - else if (strcmp (oid, PK_DSA_OID) == 0) - pkey->pk_algorithm = GNUTLS_PK_DSA; - else + + pkey->pk_algorithm = _gnutls_x509_oid2pk_algorithm(oid); + if (pkey->pk_algorithm == GNUTLS_PK_UNKNOWN) { gnutls_assert (); _gnutls_debug_log @@ -1119,6 +1139,9 @@ decode_private_key_info (const gnutls_datum_t * der, result = _decode_pkcs8_rsa_key (pkcs8_asn, pkey); else if (pkey->pk_algorithm == GNUTLS_PK_DSA) result = _decode_pkcs8_dsa_key (pkcs8_asn, pkey); + else if (pkey->pk_algorithm == GNUTLS_PK_ECC) + result = _decode_pkcs8_ecc_key (pkcs8_asn, pkey); + else return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE); if (result < 0) { diff --git a/lib/x509/verify.c b/lib/x509/verify.c index 5a9db51cda..747405ff41 100644 --- a/lib/x509/verify.c +++ b/lib/x509/verify.c @@ -752,8 +752,8 @@ decode_ber_digest_info (const gnutls_datum_t * info, static int _pkcs1_rsa_verify_sig (const gnutls_datum_t * text, const gnutls_datum_t * prehash, - const gnutls_datum_t * signature, bigint_t * params, - int params_len) + const gnutls_datum_t * signature, + gnutls_pk_params_st * params) { gnutls_mac_algorithm_t hash = GNUTLS_MAC_UNKNOWN; int ret; @@ -763,7 +763,7 @@ _pkcs1_rsa_verify_sig (const gnutls_datum_t * text, gnutls_datum_t decrypted; ret = - _gnutls_pkcs1_rsa_decrypt (&decrypted, signature, params, params_len, 1); + _gnutls_pkcs1_rsa_decrypt (&decrypted, signature, params, 1); if (ret < 0) { gnutls_assert (); @@ -829,8 +829,8 @@ _pkcs1_rsa_verify_sig (const gnutls_datum_t * text, static int dsa_verify_sig (const gnutls_datum_t * text, const gnutls_datum_t * hash, - const gnutls_datum_t * signature, bigint_t * params, - int params_len) + const gnutls_datum_t * signature, + gnutls_pk_params_st* params) { int ret; opaque _digest[MAX_HASH_SIZE]; @@ -838,7 +838,7 @@ dsa_verify_sig (const gnutls_datum_t * text, digest_hd_st hd; gnutls_digest_algorithm_t algo; - algo = _gnutls_dsa_q_to_hash (params[1]); + algo = _gnutls_dsa_q_to_hash (params->params[1]); if (hash) { /* SHA1 or better allowed */ @@ -867,7 +867,7 @@ dsa_verify_sig (const gnutls_datum_t * text, digest.size = _gnutls_hash_get_algo_len(algo); } - ret = _gnutls_dsa_verify (&digest, signature, params, params_len); + ret = _gnutls_dsa_verify (&digest, signature, params); return ret; } @@ -879,8 +879,8 @@ int pubkey_verify_sig (const gnutls_datum_t * tbs, const gnutls_datum_t * hash, const gnutls_datum_t * signature, - gnutls_pk_algorithm_t pk, bigint_t * issuer_params, - int issuer_params_size) + gnutls_pk_algorithm_t pk, + gnutls_pk_params_st * issuer_params) { switch (pk) @@ -888,7 +888,7 @@ pubkey_verify_sig (const gnutls_datum_t * tbs, case GNUTLS_PK_RSA: if (_pkcs1_rsa_verify_sig - (tbs, hash, signature, issuer_params, issuer_params_size) != 0) + (tbs, hash, signature, issuer_params) != 0) { gnutls_assert (); return GNUTLS_E_PK_SIG_VERIFY_FAILED; @@ -899,7 +899,7 @@ pubkey_verify_sig (const gnutls_datum_t * tbs, case GNUTLS_PK_DSA: if (dsa_verify_sig - (tbs, hash, signature, issuer_params, issuer_params_size) != 0) + (tbs, hash, signature, issuer_params) != 0) { gnutls_assert (); return GNUTLS_E_PK_SIG_VERIFY_FAILED; @@ -941,8 +941,7 @@ int _gnutls_x509_verify_algorithm (gnutls_mac_algorithm_t * hash, const gnutls_datum_t * signature, gnutls_pk_algorithm_t pk, - bigint_t * issuer_params, - unsigned int issuer_params_size) + gnutls_pk_params_st * issuer_params) { opaque digest[MAX_HASH_SIZE]; gnutls_datum_t decrypted; @@ -954,7 +953,7 @@ _gnutls_x509_verify_algorithm (gnutls_mac_algorithm_t * hash, case GNUTLS_PK_DSA: if (hash) - *hash = _gnutls_dsa_q_to_hash (issuer_params[1]); + *hash = _gnutls_dsa_q_to_hash (issuer_params->params[1]); ret = 0; break; @@ -968,7 +967,7 @@ _gnutls_x509_verify_algorithm (gnutls_mac_algorithm_t * hash, ret = _gnutls_pkcs1_rsa_decrypt (&decrypted, signature, - issuer_params, issuer_params_size, 1); + issuer_params, 1); if (ret < 0) @@ -1021,14 +1020,13 @@ _gnutls_x509_verify_signature (const gnutls_datum_t * tbs, const gnutls_datum_t * signature, gnutls_x509_crt_t issuer) { - bigint_t issuer_params[MAX_PUBLIC_PARAMS_SIZE]; - int ret, issuer_params_size, i; + gnutls_pk_params_st issuer_params; + int ret; /* Read the MPI parameters from the issuer's certificate. */ - issuer_params_size = MAX_PUBLIC_PARAMS_SIZE; ret = - _gnutls_x509_crt_get_mpis (issuer, issuer_params, &issuer_params_size); + _gnutls_x509_crt_get_mpis (issuer, &issuer_params); if (ret < 0) { gnutls_assert (); @@ -1038,7 +1036,7 @@ _gnutls_x509_verify_signature (const gnutls_datum_t * tbs, ret = pubkey_verify_sig (tbs, hash, signature, gnutls_x509_crt_get_pk_algorithm (issuer, NULL), - issuer_params, issuer_params_size); + &issuer_params); if (ret < 0) { gnutls_assert (); @@ -1046,10 +1044,7 @@ _gnutls_x509_verify_signature (const gnutls_datum_t * tbs, /* release all allocated MPIs */ - for (i = 0; i < issuer_params_size; i++) - { - _gnutls_mpi_release (&issuer_params[i]); - } + gnutls_pk_params_release(&issuer_params); return ret; } @@ -1068,7 +1063,7 @@ _gnutls_x509_privkey_verify_signature (const gnutls_datum_t * tbs, int ret; ret = pubkey_verify_sig (tbs, NULL, signature, issuer->pk_algorithm, - issuer->params, issuer->params_size); + &issuer->params); if (ret < 0) { gnutls_assert (); diff --git a/lib/x509/x509.c b/lib/x509/x509.c index ee97a5cebd..810057a049 100644 --- a/lib/x509/x509.c +++ b/lib/x509/x509.c @@ -2190,8 +2190,8 @@ gnutls_x509_crt_export (gnutls_x509_crt_t cert, } int -_gnutls_get_key_id (gnutls_pk_algorithm_t pk, bigint_t * params, - int params_size, unsigned char *output_data, +_gnutls_get_key_id (gnutls_pk_algorithm_t pk, gnutls_pk_params_st * params, + unsigned char *output_data, size_t * output_data_size) { int result = 0; @@ -2205,26 +2205,12 @@ _gnutls_get_key_id (gnutls_pk_algorithm_t pk, bigint_t * params, return GNUTLS_E_SHORT_MEMORY_BUFFER; } - if (pk == GNUTLS_PK_RSA) - { - result = _gnutls_x509_write_rsa_params (params, params_size, &der); - if (result < 0) - { - gnutls_assert (); - goto cleanup; - } - } - else if (pk == GNUTLS_PK_DSA) + result = _gnutls_x509_write_pubkey(pk, params, &der); + if (result < 0) { - result = _gnutls_x509_write_dsa_public_key (params, params_size, &der); - if (result < 0) - { - gnutls_assert (); - goto cleanup; - } + gnutls_assert (); + goto cleanup; } - else - return GNUTLS_E_INTERNAL_ERROR; result = _gnutls_hash_init (&hd, GNUTLS_MAC_SHA1); if (result < 0) @@ -2251,11 +2237,10 @@ static int rsadsa_get_key_id (gnutls_x509_crt_t crt, int pk, unsigned char *output_data, size_t * output_data_size) { - bigint_t params[MAX_PUBLIC_PARAMS_SIZE]; - int params_size = MAX_PUBLIC_PARAMS_SIZE; - int i, result = 0; + gnutls_pk_params_st params; + int result = 0; - result = _gnutls_x509_crt_get_mpis (crt, params, ¶ms_size); + result = _gnutls_x509_crt_get_mpis (crt, ¶ms); if (result < 0) { gnutls_assert (); @@ -2263,7 +2248,7 @@ rsadsa_get_key_id (gnutls_x509_crt_t crt, int pk, } result = - _gnutls_get_key_id (pk, params, params_size, output_data, + _gnutls_get_key_id (pk, ¶ms, output_data, output_data_size); if (result < 0) { @@ -2277,10 +2262,7 @@ cleanup: /* release all allocated MPIs */ - for (i = 0; i < params_size; i++) - { - _gnutls_mpi_release (¶ms[i]); - } + gnutls_pk_params_release(¶ms); return result; } @@ -2524,9 +2506,8 @@ gnutls_x509_crt_get_verify_algorithm (gnutls_x509_crt_t crt, const gnutls_datum_t * signature, gnutls_digest_algorithm_t * hash) { - bigint_t issuer_params[MAX_PUBLIC_PARAMS_SIZE]; - int issuer_params_size; - int ret, i; + gnutls_pk_params_st issuer_params; + int ret; if (crt == NULL) { @@ -2534,8 +2515,7 @@ gnutls_x509_crt_get_verify_algorithm (gnutls_x509_crt_t crt, return GNUTLS_E_INVALID_REQUEST; } - issuer_params_size = MAX_PUBLIC_PARAMS_SIZE; - ret = _gnutls_x509_crt_get_mpis (crt, issuer_params, &issuer_params_size); + ret = _gnutls_x509_crt_get_mpis (crt, &issuer_params); if (ret < 0) { gnutls_assert (); @@ -2546,13 +2526,10 @@ gnutls_x509_crt_get_verify_algorithm (gnutls_x509_crt_t crt, signature, gnutls_x509_crt_get_pk_algorithm (crt, NULL), - issuer_params, issuer_params_size); + &issuer_params); /* release allocated mpis */ - for (i = 0; i < issuer_params_size; i++) - { - _gnutls_mpi_release (&issuer_params[i]); - } + gnutls_pk_params_release(&issuer_params); return ret; } @@ -2581,9 +2558,8 @@ gnutls_x509_crt_get_preferred_hash_algorithm (gnutls_x509_crt_t crt, gnutls_digest_algorithm_t * hash, unsigned int *mand) { - bigint_t issuer_params[MAX_PUBLIC_PARAMS_SIZE]; - int issuer_params_size; - int ret, i; + gnutls_pk_params_st issuer_params; + int ret; if (crt == NULL) { @@ -2591,8 +2567,7 @@ gnutls_x509_crt_get_preferred_hash_algorithm (gnutls_x509_crt_t crt, return GNUTLS_E_INVALID_REQUEST; } - issuer_params_size = MAX_PUBLIC_PARAMS_SIZE; - ret = _gnutls_x509_crt_get_mpis (crt, issuer_params, &issuer_params_size); + ret = _gnutls_x509_crt_get_mpis (crt, &issuer_params); if (ret < 0) { gnutls_assert (); @@ -2601,14 +2576,11 @@ gnutls_x509_crt_get_preferred_hash_algorithm (gnutls_x509_crt_t crt, ret = _gnutls_pk_get_hash_algorithm (gnutls_x509_crt_get_pk_algorithm - (crt, NULL), issuer_params, - issuer_params_size, hash, mand); + (crt, NULL), &issuer_params, + hash, mand); /* release allocated mpis */ - for (i = 0; i < issuer_params_size; i++) - { - _gnutls_mpi_release (&issuer_params[i]); - } + gnutls_pk_params_release(&issuer_params); return ret; } @@ -2936,9 +2908,7 @@ gnutls_x509_crt_get_pk_rsa_raw (gnutls_x509_crt_t crt, gnutls_datum_t * m, gnutls_datum_t * e) { int ret; - bigint_t params[MAX_PUBLIC_PARAMS_SIZE]; - int params_size = MAX_PUBLIC_PARAMS_SIZE; - int i; + gnutls_pk_params_st params; if (crt == NULL) { @@ -2953,21 +2923,21 @@ gnutls_x509_crt_get_pk_rsa_raw (gnutls_x509_crt_t crt, return GNUTLS_E_INVALID_REQUEST; } - ret = _gnutls_x509_crt_get_mpis (crt, params, ¶ms_size); + ret = _gnutls_x509_crt_get_mpis (crt, ¶ms); if (ret < 0) { gnutls_assert (); return ret; } - ret = _gnutls_mpi_dprint_lz (params[0], m); + ret = _gnutls_mpi_dprint_lz (params.params[0], m); if (ret < 0) { gnutls_assert (); goto cleanup; } - ret = _gnutls_mpi_dprint_lz (params[1], e); + ret = _gnutls_mpi_dprint_lz (params.params[1], e); if (ret < 0) { gnutls_assert (); @@ -2978,10 +2948,7 @@ gnutls_x509_crt_get_pk_rsa_raw (gnutls_x509_crt_t crt, ret = 0; cleanup: - for (i = 0; i < params_size; i++) - { - _gnutls_mpi_release (¶ms[i]); - } + gnutls_pk_params_release(¶ms); return ret; } @@ -3005,9 +2972,7 @@ gnutls_x509_crt_get_pk_dsa_raw (gnutls_x509_crt_t crt, gnutls_datum_t * g, gnutls_datum_t * y) { int ret; - bigint_t params[MAX_PUBLIC_PARAMS_SIZE]; - int params_size = MAX_PUBLIC_PARAMS_SIZE; - int i; + gnutls_pk_params_st params; if (crt == NULL) { @@ -3022,7 +2987,7 @@ gnutls_x509_crt_get_pk_dsa_raw (gnutls_x509_crt_t crt, return GNUTLS_E_INVALID_REQUEST; } - ret = _gnutls_x509_crt_get_mpis (crt, params, ¶ms_size); + ret = _gnutls_x509_crt_get_mpis (crt, ¶ms); if (ret < 0) { gnutls_assert (); @@ -3031,7 +2996,7 @@ gnutls_x509_crt_get_pk_dsa_raw (gnutls_x509_crt_t crt, /* P */ - ret = _gnutls_mpi_dprint_lz (params[0], p); + ret = _gnutls_mpi_dprint_lz (params.params[0], p); if (ret < 0) { gnutls_assert (); @@ -3039,7 +3004,7 @@ gnutls_x509_crt_get_pk_dsa_raw (gnutls_x509_crt_t crt, } /* Q */ - ret = _gnutls_mpi_dprint_lz (params[1], q); + ret = _gnutls_mpi_dprint_lz (params.params[1], q); if (ret < 0) { gnutls_assert (); @@ -3049,7 +3014,7 @@ gnutls_x509_crt_get_pk_dsa_raw (gnutls_x509_crt_t crt, /* G */ - ret = _gnutls_mpi_dprint_lz (params[2], g); + ret = _gnutls_mpi_dprint_lz (params.params[2], g); if (ret < 0) { gnutls_assert (); @@ -3060,7 +3025,7 @@ gnutls_x509_crt_get_pk_dsa_raw (gnutls_x509_crt_t crt, /* Y */ - ret = _gnutls_mpi_dprint_lz (params[3], y); + ret = _gnutls_mpi_dprint_lz (params.params[3], y); if (ret < 0) { gnutls_assert (); @@ -3073,10 +3038,7 @@ gnutls_x509_crt_get_pk_dsa_raw (gnutls_x509_crt_t crt, ret = 0; cleanup: - for (i = 0; i < params_size; i++) - { - _gnutls_mpi_release (¶ms[i]); - } + gnutls_pk_params_release(¶ms); return ret; } diff --git a/lib/x509/x509_int.h b/lib/x509/x509_int.h index ce9faae58d..95132ff67c 100644 --- a/lib/x509/x509_int.h +++ b/lib/x509/x509_int.h @@ -78,7 +78,7 @@ typedef struct gnutls_pkcs7_int /* parameters should not be larger than this limit */ #define DSA_PUBLIC_PARAMS 4 #define RSA_PUBLIC_PARAMS 2 -#define ECDH_PUBLIC_PARAMS 8 +#define ECC_PUBLIC_PARAMS 8 #define MAX_PRIV_PARAMS_SIZE GNUTLS_MAX_PK_PARAMS /* ok for RSA and DSA */ @@ -86,12 +86,16 @@ typedef struct gnutls_pkcs7_int /* parameters should not be larger than this limit */ #define DSA_PRIVATE_PARAMS 5 #define RSA_PRIVATE_PARAMS 8 -#define ECDH_PRIVATE_PARAMS 9 +#define ECC_PRIVATE_PARAMS 9 #if MAX_PRIV_PARAMS_SIZE - RSA_PRIVATE_PARAMS < 0 #error INCREASE MAX_PRIV_PARAMS #endif +#if MAX_PRIV_PARAMS_SIZE - ECC_PRIVATE_PARAMS < 0 +#error INCREASE MAX_PRIV_PARAMS +#endif + #if MAX_PRIV_PARAMS_SIZE - DSA_PRIVATE_PARAMS < 0 #error INCREASE MAX_PRIV_PARAMS #endif @@ -101,29 +105,7 @@ typedef struct gnutls_x509_privkey_int /* the size of params depends on the public * key algorithm */ - bigint_t params[MAX_PRIV_PARAMS_SIZE]; - - /* - * RSA: [0] is modulus - * [1] is public exponent - * [2] is private exponent - * [3] is prime1 (p) - * [4] is prime2 (q) - * [5] is coefficient (u == inverse of p mod q) - * note that other packages used inverse of q mod p, - * so we need to perform conversions on import/export - * using fixup. - * The following two are also not always available thus fixup - * will generate them. - * [6] e1 == d mod (p-1) - * [7] e2 == d mod (q-1) - * DSA: [0] is p - * [1] is q - * [2] is g - * [3] is y (public key) - * [4] is x (private key) - */ - int params_size; /* holds the number of params */ + gnutls_pk_params_st params; gnutls_pk_algorithm_t pk_algorithm; @@ -198,8 +180,7 @@ int _gnutls_x509_verify_algorithm (gnutls_mac_algorithm_t * hash, const gnutls_datum_t * signature, gnutls_pk_algorithm_t pk, - bigint_t * issuer_params, - unsigned int issuer_params_size); + gnutls_pk_params_st * issuer_params); int _gnutls_x509_verify_signature (const gnutls_datum_t * tbs, const gnutls_datum_t * hash, @@ -213,7 +194,10 @@ int _gnutls_x509_privkey_verify_signature (const gnutls_datum_t * tbs, ASN1_TYPE _gnutls_privkey_decode_pkcs1_rsa_key (const gnutls_datum_t * raw_key, gnutls_x509_privkey_t pkey); -int _gnutls_asn1_encode_dsa (ASN1_TYPE * c2, bigint_t * params); +ASN1_TYPE _gnutls_privkey_decode_ecc_key (const gnutls_datum_t * + raw_key, + gnutls_x509_privkey_t pkey); +int _gnutls_asn1_encode_privkey (gnutls_pk_algorithm_t pk, ASN1_TYPE * c2, gnutls_pk_params_st * params); /* extensions.c */ int _gnutls_x509_crl_get_extension (gnutls_x509_crl_t crl, @@ -288,22 +272,22 @@ int _gnutls_x509_ext_gen_proxyCertInfo (int pathLenConstraint, /* mpi.c */ int _gnutls_x509_crq_get_mpis (gnutls_x509_crq_t cert, - bigint_t * params, int *params_size); + gnutls_pk_params_st*); int _gnutls_x509_crt_get_mpis (gnutls_x509_crt_t cert, - bigint_t * params, int *params_size); -int _gnutls_x509_read_rsa_params (opaque * der, int dersize, - bigint_t * params); -int _gnutls_x509_read_dsa_pubkey (opaque * der, int dersize, - bigint_t * params); -int _gnutls_x509_read_dsa_params (opaque * der, int dersize, - bigint_t * params); - -int _gnutls_x509_write_rsa_params (bigint_t * params, int params_size, - gnutls_datum_t * der); -int _gnutls_x509_write_dsa_params (bigint_t * params, int params_size, + gnutls_pk_params_st * params); + +int _gnutls_x509_read_pubkey_params (gnutls_pk_algorithm_t, opaque * der, int dersize, + gnutls_pk_params_st * params); + +int _gnutls_x509_read_pubkey (gnutls_pk_algorithm_t, opaque * der, int dersize, + gnutls_pk_params_st * params); + +int +_gnutls_x509_write_pubkey_params (gnutls_pk_algorithm_t algo, + gnutls_pk_params_st* params, gnutls_datum_t * der); -int _gnutls_x509_write_dsa_public_key (bigint_t * params, int params_size, +int _gnutls_x509_write_pubkey (gnutls_pk_algorithm_t, gnutls_pk_params_st * params, gnutls_datum_t * der); int _gnutls_x509_read_uint (ASN1_TYPE node, const char *value, diff --git a/lib/x509/x509_write.c b/lib/x509/x509_write.c index 68f0103670..45c3e74864 100644 --- a/lib/x509/x509_write.c +++ b/lib/x509/x509_write.c @@ -233,8 +233,7 @@ gnutls_x509_crt_set_key (gnutls_x509_crt_t crt, gnutls_x509_privkey_t key) result = _gnutls_x509_encode_and_copy_PKI_params (crt->cert, "tbsCertificate.subjectPublicKeyInfo", key->pk_algorithm, - key->params, - key->params_size); + &key->params); if (result < 0) { |