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(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[6] /* x */, session->key.ecdh_params.params[7] /* 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); /* generate pre-shared key */ ret = calc_ecdh_key(session, psk_key); if (ret < 0) return gnutls_assert_val(ret); return data->length; }
/* 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; }
/* * some x509 certificate functions that relate to MPI parameter * setting. This writes an ECPoint. * * Allocates the space used to store the DER data. */ int _gnutls_x509_write_ecc_pubkey(gnutls_pk_params_st * params, gnutls_datum_t * der) { int result; der->data = NULL; der->size = 0; if (params->params_nr < ECC_PUBLIC_PARAMS) return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); result = _gnutls_ecc_ansi_x963_export(params->flags, params->params[ECC_X], params->params[ECC_Y], /*&out */ der); if (result < 0) return gnutls_assert_val(result); return 0; }
/* 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; uint8_t 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[ECC_X], params->params[ECC_Y], &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; } if ((ret = asn1_write_value(*c2, "Version", &one, 1)) != ASN1_SUCCESS) { gnutls_assert(); ret = _gnutls_asn2err(ret); goto cleanup; } ret = _gnutls_x509_write_key_int(*c2, "privateKey", params->params[ECC_K], 1); if (ret < 0) { gnutls_assert(); goto cleanup; } if ((ret = asn1_write_value(*c2, "publicKey", pubkey.data, pubkey.size * 8)) != 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_structure2(c2, ASN1_DELETE_FLAG_ZEROIZE); _gnutls_free_datum(&pubkey); return ret; }