/** * gnutls_x509_privkey_generate: * @key: should contain a #gnutls_x509_privkey_t structure * @algo: is one of the algorithms in #gnutls_pk_algorithm_t. * @bits: the size of the modulus * @flags: unused for now. Must be 0. * * This function will generate a random private key. Note that this * function must be called on an empty private key. * * Note that when generating an elliptic curve key, the curve * can be substituted in the place of the bits parameter using the * GNUTLS_CURVE_TO_BITS() macro. * * For DSA keys, if the subgroup size needs to be specified check * the GNUTLS_SUBGROUP_TO_BITS() macro. * * Do not set the number of bits directly, use gnutls_sec_param_to_pk_bits(). * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a * negative error value. **/ int gnutls_x509_privkey_generate(gnutls_x509_privkey_t key, gnutls_pk_algorithm_t algo, unsigned int bits, unsigned int flags) { int ret; if (key == NULL) { gnutls_assert(); return GNUTLS_E_INVALID_REQUEST; } gnutls_pk_params_init(&key->params); if (algo == GNUTLS_PK_EC) { if (GNUTLS_BITS_ARE_CURVE(bits)) bits = GNUTLS_BITS_TO_CURVE(bits); else bits = _gnutls_ecc_bits_to_curve(bits); } ret = _gnutls_pk_generate_params(algo, bits, &key->params); if (ret < 0) { gnutls_assert(); return ret; } ret = _gnutls_pk_generate_keys(algo, bits, &key->params); if (ret < 0) { gnutls_assert(); return ret; } #ifndef ENABLE_FIPS140 ret = _gnutls_pk_verify_priv_params(algo, &key->params); #else ret = pct_test(algo, &key->params); #endif if (ret < 0) { gnutls_assert(); return ret; } ret = _gnutls_asn1_encode_privkey(algo, &key->key, &key->params); if (ret < 0) { gnutls_assert(); goto cleanup; } key->pk_algorithm = algo; return 0; cleanup: key->pk_algorithm = GNUTLS_PK_UNKNOWN; gnutls_pk_params_clear(&key->params); gnutls_pk_params_release(&key->params); return ret; }
int _gnutls_gen_dh_common_client_kx_int(gnutls_session_t session, gnutls_buffer_st * data, gnutls_datum_t * pskkey) { int ret; gnutls_pk_params_st peer_pub; gnutls_datum_t tmp_dh_key = {NULL, 0}; gnutls_pk_params_init(&peer_pub); ret = _gnutls_pk_generate_keys(GNUTLS_PK_DH, 0, &session->key.dh_params, 1); if (ret < 0) return gnutls_assert_val(ret); _gnutls_dh_set_secret_bits(session, _gnutls_mpi_get_nbits(session->key.dh_params.params[DH_X])); ret = _gnutls_buffer_append_mpi(data, 16, session->key.dh_params.params[DH_Y], 0); if (ret < 0) { gnutls_assert(); goto error; } peer_pub.params[DH_Y] = session->key.client_Y; /* calculate the key after calculating the message */ ret = _gnutls_pk_derive(GNUTLS_PK_DH, &tmp_dh_key, &session->key.dh_params, &peer_pub); if (ret < 0) { gnutls_assert(); goto error; } if (_gnutls_cipher_suite_get_kx_algo (session->security_parameters.cipher_suite) != GNUTLS_KX_DHE_PSK) { session->key.key.data = tmp_dh_key.data; session->key.key.size = tmp_dh_key.size; } else { /* In DHE_PSK the key is set differently */ ret = _gnutls_set_psk_session_key(session, pskkey, &tmp_dh_key); _gnutls_free_temp_key_datum(&tmp_dh_key); } if (ret < 0) { gnutls_assert(); goto error; } ret = data->length; error: gnutls_pk_params_clear(&session->key.dh_params); return ret; }
/* 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, gnutls_ecc_curve_t curve) { uint8_t p; int ret; gnutls_datum_t out; if (curve == GNUTLS_ECC_CURVE_INVALID) return gnutls_assert_val(GNUTLS_E_ECC_NO_SUPPORTED_CURVES); /* just in case we are resuming a session */ gnutls_pk_params_release(&session->key.ecdh_params); gnutls_pk_params_init(&session->key.ecdh_params); /* curve type */ p = 3; ret = _gnutls_buffer_append_data(data, &p, 1); if (ret < 0) return gnutls_assert_val(ret); ret = _gnutls_buffer_append_prefix(data, 16, _gnutls_ecc_curve_get_tls_id (curve)); if (ret < 0) return gnutls_assert_val(ret); /* generate temporal key */ ret = _gnutls_pk_generate_keys(GNUTLS_PK_EC, curve, &session->key.ecdh_params); if (ret < 0) return gnutls_assert_val(ret); ret = _gnutls_ecc_ansi_x963_export(curve, session->key.ecdh_params. params[ECC_X] /* x */ , session->key.ecdh_params. params[ECC_Y] /* y */ , &out); if (ret < 0) return gnutls_assert_val(ret); ret = _gnutls_buffer_append_data_prefix(data, 8, out.data, out.size); _gnutls_free_datum(&out); if (ret < 0) return gnutls_assert_val(ret); return data->length; }
int _gnutls_ecdh_generate_key(gnutls_ecc_curve_t curve, gnutls_datum_t *x, gnutls_datum_t *y, gnutls_datum_t *k) { gnutls_pk_params_st params; int ret; gnutls_pk_params_init(¶ms); params.flags = curve; params.algo = GNUTLS_PK_EC; x->data = NULL; y->data = NULL; k->data = NULL; ret = _gnutls_pk_generate_keys(GNUTLS_PK_EC, curve, ¶ms); if (ret < 0) { return gnutls_assert_val(ret); } ret = _gnutls_mpi_dprint_lz(params.params[ECC_X], x); if (ret < 0) { gnutls_assert(); goto fail; } ret = _gnutls_mpi_dprint_lz(params.params[ECC_Y], y); if (ret < 0) { gnutls_assert(); goto fail; } ret = _gnutls_mpi_dprint_lz(params.params[ECC_K], k); if (ret < 0) { gnutls_assert(); goto fail; } ret = 0; goto cleanup; fail: gnutls_free(y->data); gnutls_free(x->data); gnutls_free(k->data); cleanup: gnutls_pk_params_clear(¶ms); return ret; }
int _gnutls_gen_ecdh_common_client_kx_int(gnutls_session_t session, gnutls_buffer_st * data, gnutls_datum_t * psk_key) { int ret; gnutls_datum_t out; int curve = _gnutls_session_ecc_curve_get(session); /* generate temporal key */ ret = _gnutls_pk_generate_keys(GNUTLS_PK_EC, curve, &session->key.ecdh_params); if (ret < 0) return gnutls_assert_val(ret); ret = _gnutls_ecc_ansi_x963_export(curve, session->key.ecdh_params. params[ECC_X] /* x */ , session->key.ecdh_params. params[ECC_Y] /* y */ , &out); if (ret < 0) { gnutls_assert(); goto cleanup; } ret = _gnutls_buffer_append_data_prefix(data, 8, out.data, out.size); _gnutls_free_datum(&out); if (ret < 0) { gnutls_assert(); goto cleanup; } /* generate pre-shared key */ ret = calc_ecdh_key(session, psk_key, curve); if (ret < 0) { gnutls_assert(); goto cleanup; } ret = data->length; cleanup: gnutls_pk_params_clear(&session->key.ecdh_params); return ret; }
int _gnutls_dh_common_print_server_kx(gnutls_session_t session, gnutls_buffer_st * data) { int ret; unsigned q_bits = session->key.dh_params.flags; if (q_bits < 192 && q_bits != 0) { gnutls_assert(); _gnutls_debug_log("too small q_bits value for DH: %u\n", q_bits); q_bits = 0; /* auto-detect */ } /* Y=g^x mod p */ ret = _gnutls_pk_generate_keys(GNUTLS_PK_DH, q_bits, &session->key.dh_params, 1); if (ret < 0) return gnutls_assert_val(ret); _gnutls_dh_set_secret_bits(session, _gnutls_mpi_get_nbits(session->key.dh_params.params[DH_X])); ret = _gnutls_buffer_append_mpi(data, 16, session->key.dh_params.params[DH_P], 0); if (ret < 0) { gnutls_assert(); goto cleanup; } ret = _gnutls_buffer_append_mpi(data, 16, session->key.dh_params.params[DH_G], 0); if (ret < 0) { gnutls_assert(); goto cleanup; } ret = _gnutls_buffer_append_mpi(data, 16, session->key.dh_params.params[DH_Y], 0); if (ret < 0) { gnutls_assert(); goto cleanup; } ret = data->length; cleanup: return ret; }
int _gnutls_dh_generate_key(gnutls_dh_params_t dh_params, gnutls_datum_t *priv_key, gnutls_datum_t *pub_key) { gnutls_pk_params_st params; int ret; gnutls_pk_params_init(¶ms); params.params[DH_P] = _gnutls_mpi_copy(dh_params->params[0]); params.params[DH_G] = _gnutls_mpi_copy(dh_params->params[1]); params.params_nr = 3; /* include empty q */ params.algo = GNUTLS_PK_DH; priv_key->data = NULL; pub_key->data = NULL; ret = _gnutls_pk_generate_keys(GNUTLS_PK_DH, 0, ¶ms); if (ret < 0) { return gnutls_assert_val(ret); } ret = _gnutls_mpi_dprint_lz(params.params[DH_X], priv_key); if (ret < 0) { gnutls_assert(); goto fail; } ret = _gnutls_mpi_dprint_lz(params.params[DH_Y], pub_key); if (ret < 0) { gnutls_assert(); goto fail; } ret = 0; goto cleanup; fail: gnutls_free(pub_key->data); gnutls_free(priv_key->data); cleanup: gnutls_pk_params_clear(¶ms); return ret; }