** API and ABI modifications:
gnutls_pubkey_import_dh_raw: New function
gnutls_privkey_import_dh_raw: New function
+gnutls_pubkey_export_dh_raw: New function
gnutls_privkey_export_dh_raw: New function
gnutls_x509_privkey_import_dh_raw: New function
gnutls_privkey_derive_secret: New function
[suppress_function]
name = gnutls_privkey_import_dh_raw
+[suppress_function]
+name = gnutls_pubkey_export_dh_raw
+
[suppress_function]
name = gnutls_privkey_export_dh_raw
gnutls_pubkey_encrypt_data@GNUTLS_3_4
gnutls_pubkey_export2@GNUTLS_3_4
gnutls_pubkey_export@GNUTLS_3_4
+gnutls_pubkey_export_dh_raw@GNUTLS_3_8_2
gnutls_pubkey_export_dsa_raw2@GNUTLS_3_6_0
gnutls_pubkey_export_dsa_raw@GNUTLS_3_4
gnutls_pubkey_export_ecc_raw2@GNUTLS_3_6_0
FUNCS += functions/gnutls_pubkey_export.short
FUNCS += functions/gnutls_pubkey_export2
FUNCS += functions/gnutls_pubkey_export2.short
+FUNCS += functions/gnutls_pubkey_export_dh_raw
+FUNCS += functions/gnutls_pubkey_export_dh_raw.short
FUNCS += functions/gnutls_pubkey_export_dsa_raw
FUNCS += functions/gnutls_pubkey_export_dsa_raw.short
FUNCS += functions/gnutls_pubkey_export_dsa_raw2
APIMANS += gnutls_pubkey_encrypt_data.3
APIMANS += gnutls_pubkey_export.3
APIMANS += gnutls_pubkey_export2.3
+APIMANS += gnutls_pubkey_export_dh_raw.3
APIMANS += gnutls_pubkey_export_dsa_raw.3
APIMANS += gnutls_pubkey_export_dsa_raw2.3
APIMANS += gnutls_pubkey_export_ecc_raw.3
gnutls_datum_t *q, gnutls_datum_t *g,
gnutls_datum_t *y, unsigned flags);
+int gnutls_pubkey_export_dh_raw(gnutls_pubkey_t key, gnutls_dh_params_t params,
+ gnutls_datum_t *y, unsigned flags);
+
int gnutls_pubkey_export_ecc_raw2(gnutls_pubkey_t key,
gnutls_ecc_curve_t *curve, gnutls_datum_t *x,
gnutls_datum_t *y, unsigned flags);
const gnutls_datum_t *q,
const gnutls_datum_t *g,
const gnutls_datum_t *y);
-int gnutls_pubkey_import_dh_raw(gnutls_pubkey_t key, const gnutls_datum_t *p,
- const gnutls_datum_t *q,
- const gnutls_datum_t *g,
+int gnutls_pubkey_import_dh_raw(gnutls_pubkey_t key,
+ const gnutls_dh_params_t params,
const gnutls_datum_t *y);
int gnutls_pubkey_import_rsa_raw(gnutls_pubkey_t key, const gnutls_datum_t *m,
const gnutls_datum_t *e);
const gnutls_datum_t *y,
const gnutls_datum_t *x);
-int gnutls_privkey_import_dh_raw(gnutls_privkey_t key, const gnutls_datum_t *p,
- const gnutls_datum_t *q,
- const gnutls_datum_t *g,
+int gnutls_privkey_import_dh_raw(gnutls_privkey_t key,
+ const gnutls_dh_params_t params,
const gnutls_datum_t *y,
const gnutls_datum_t *x);
gnutls_datum_t *y, gnutls_datum_t *x,
unsigned flags);
-int gnutls_privkey_export_dh_raw(gnutls_privkey_t key, gnutls_datum_t *p,
- gnutls_datum_t *q, gnutls_datum_t *g,
- gnutls_datum_t *y, gnutls_datum_t *x,
- unsigned int flags);
+int gnutls_privkey_export_dh_raw(gnutls_privkey_t key,
+ gnutls_dh_params_t params, gnutls_datum_t *y,
+ gnutls_datum_t *x, unsigned int flags);
int gnutls_privkey_export_ecc_raw(gnutls_privkey_t key,
gnutls_ecc_curve_t *curve, gnutls_datum_t *x,
const gnutls_datum_t *y,
const gnutls_datum_t *x);
int gnutls_x509_privkey_import_dh_raw(gnutls_x509_privkey_t key,
- const gnutls_datum_t *p,
- const gnutls_datum_t *q,
- const gnutls_datum_t *g,
+ const gnutls_dh_params_t params,
const gnutls_datum_t *y,
const gnutls_datum_t *x);
global:
gnutls_pubkey_import_dh_raw;
gnutls_privkey_import_dh_raw;
+ gnutls_pubkey_export_dh_raw;
gnutls_privkey_export_dh_raw;
gnutls_x509_privkey_import_dh_raw;
gnutls_privkey_derive_secret;
* @key: A key of type #gnutls_pubkey_t
* @url: A PKCS 11 url
*
- * This function will import a PKCS 11 private key to a #gnutls_private_key_t
+ * This function will import a PKCS 11 private key to a #gnutls_privkey_t
* type.
*
* Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
/**
* gnutls_privkey_export_dh_raw:
- * @key: Holds the public key
- * @p: will hold the p
- * @q: will hold the q
- * @g: will hold the g
- * @y: will hold the y
+ * @key: Holds the private key
+ * @params: will hold the Diffie-Hellman parameters (optional), must be initialized
+ * @y: will hold the y (optional)
* @x: will hold the x
* @flags: flags from %gnutls_abstract_export_flags_t
*
- * This function will export the Diffie-Hellman private key's
- * parameters found in the given structure. The new parameters will be
- * allocated using gnutls_malloc() and will be stored in the
+ * This function will export the Diffie-Hellman private key parameter
+ * found in the given %gnutls_privkey_t structure. The new parameter
+ * will be allocated using gnutls_malloc() and will be stored in the
* appropriate datum.
*
+ * To retrieve other parameters common in both public key and private
+ * key, use gnutls_dh_params_export_raw().
+ *
* Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
*
* Since: 3.8.2
**/
-int gnutls_privkey_export_dh_raw(gnutls_privkey_t key, gnutls_datum_t *p,
- gnutls_datum_t *q, gnutls_datum_t *g,
- gnutls_datum_t *y, gnutls_datum_t *x,
- unsigned int flags)
+int gnutls_privkey_export_dh_raw(gnutls_privkey_t key,
+ gnutls_dh_params_t params, gnutls_datum_t *y,
+ gnutls_datum_t *x, unsigned int flags)
{
- return gnutls_privkey_export_dsa_raw2(key, p, q, g, y, x, flags);
+ if (params) {
+ gnutls_pk_params_st pk_params;
+ int ret;
+
+ gnutls_pk_params_init(&pk_params);
+
+ ret = _gnutls_privkey_get_mpis(key, &pk_params);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+
+ params->params[0] = _gnutls_mpi_copy(pk_params.params[DH_P]);
+ params->params[1] = _gnutls_mpi_copy(pk_params.params[DH_G]);
+ if (pk_params.params[DH_Q]) {
+ params->params[2] =
+ _gnutls_mpi_copy(pk_params.params[DH_Q]);
+ }
+ params->q_bits = pk_params.qbits;
+
+ gnutls_pk_params_release(&pk_params);
+ }
+
+ return gnutls_privkey_export_dsa_raw2(key, NULL, NULL, NULL, y, x,
+ flags);
}
/**
/**
* gnutls_privkey_import_dh_raw:
* @key: The structure to store the parsed key
- * @p: holds the p
- * @q: holds the q (optional)
- * @g: holds the g
+ * @params: holds the %gnutls_dh_params_t
* @y: holds the y (optional)
* @x: holds the x
*
*
* Since: 3.8.2
**/
-int gnutls_privkey_import_dh_raw(gnutls_privkey_t key, const gnutls_datum_t *p,
- const gnutls_datum_t *q,
- const gnutls_datum_t *g,
+int gnutls_privkey_import_dh_raw(gnutls_privkey_t key,
+ const gnutls_dh_params_t params,
const gnutls_datum_t *y,
const gnutls_datum_t *x)
{
if (ret < 0)
return gnutls_assert_val(ret);
- ret = gnutls_x509_privkey_import_dh_raw(xkey, p, q, g, y, x);
+ ret = gnutls_x509_privkey_import_dh_raw(xkey, params, y, x);
if (ret < 0) {
gnutls_assert();
goto error;
return 0;
}
+/**
+ * gnutls_pubkey_export_dh_raw:
+ * @key: Holds the public key
+ * @params: will hold the Diffie-Hellman parameter (optional), must be initialized
+ * @y: will hold the y
+ * @flags: flags from %gnutls_abstract_export_flags_t
+ *
+ * This function will export the Diffie-Hellman public key parameter
+ * found in the given public key. The new parameter will be allocated
+ * using gnutls_malloc() and will be stored in the appropriate datum.
+ *
+ * To retrieve other parameters common in both public key and private
+ * key, use gnutls_dh_params_export_raw().
+ *
+ * This function allows for %NULL parameters since 3.4.1.
+ *
+ * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
+ *
+ * Since: 3.8.2
+ **/
+int gnutls_pubkey_export_dh_raw(gnutls_pubkey_t key, gnutls_dh_params_t params,
+ gnutls_datum_t *y, unsigned flags)
+{
+ int ret;
+ mpi_dprint_func dprint = _gnutls_mpi_dprint_lz;
+
+ if (flags & GNUTLS_EXPORT_FLAG_NO_LZ) {
+ dprint = _gnutls_mpi_dprint;
+ }
+
+ if (key == NULL) {
+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+ }
+
+ if (key->params.algo != GNUTLS_PK_DH) {
+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+ }
+
+ if (params) {
+ params->params[0] = _gnutls_mpi_copy(key->params.params[DH_P]);
+ params->params[1] = _gnutls_mpi_copy(key->params.params[DH_G]);
+ if (key->params.params[DH_Q]) {
+ params->params[2] =
+ _gnutls_mpi_copy(key->params.params[DH_Q]);
+ }
+ params->q_bits = key->params.qbits;
+ }
+
+ /* Y */
+ if (y) {
+ ret = dprint(key->params.params[DH_Y], y);
+ if (ret < 0) {
+ return gnutls_assert_val(ret);
+ }
+ }
+
+ return 0;
+}
+
/**
* gnutls_pubkey_export_ecc_raw:
* @key: Holds the public key
/**
* gnutls_pubkey_import_dh_raw:
* @key: The structure to store the parsed key
- * @p: holds the p
- * @q: holds the q (optional)
- * @g: holds the g
+ * @params: holds the %gnutls_dh_params_t
* @y: holds the y
*
* This function will convert the given Diffie-Hellman raw parameters
*
* Since: 3.8.2
**/
-int gnutls_pubkey_import_dh_raw(gnutls_pubkey_t key, const gnutls_datum_t *p,
- const gnutls_datum_t *q,
- const gnutls_datum_t *g,
+int gnutls_pubkey_import_dh_raw(gnutls_pubkey_t key,
+ const gnutls_dh_params_t params,
const gnutls_datum_t *y)
{
int ret;
- if (unlikely(key == NULL || p == NULL || g == NULL || y == NULL)) {
+ if (unlikely(key == NULL || params == NULL || y == NULL)) {
return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
}
gnutls_pk_params_release(&key->params);
gnutls_pk_params_init(&key->params);
- if (_gnutls_mpi_init_scan_nz(&key->params.params[DH_P], p->data,
- p->size)) {
- gnutls_assert();
- ret = GNUTLS_E_MPI_SCAN_FAILED;
- goto cleanup;
- }
-
- if (q) {
- if (_gnutls_mpi_init_scan_nz(&key->params.params[DH_Q], q->data,
- q->size)) {
- gnutls_assert();
- ret = GNUTLS_E_MPI_SCAN_FAILED;
- goto cleanup;
- }
- }
-
- if (_gnutls_mpi_init_scan_nz(&key->params.params[DH_G], g->data,
- g->size)) {
- gnutls_assert();
- ret = GNUTLS_E_MPI_SCAN_FAILED;
- goto cleanup;
+ key->params.params[DH_P] = _gnutls_mpi_copy(params->params[0]);
+ key->params.params[DH_G] = _gnutls_mpi_copy(params->params[1]);
+ if (params->params[2]) {
+ key->params.params[DH_Q] = _gnutls_mpi_copy(params->params[2]);
}
+ key->params.qbits = params->q_bits;
if (_gnutls_mpi_init_scan_nz(&key->params.params[DH_Y], y->data,
y->size)) {
/**
* gnutls_x509_privkey_import_dh_raw:
* @key: The data to store the parsed key
- * @p: holds the p
- * @q: holds the q (optional)
- * @g: holds the g
+ * @params: holds the %gnutls_dh_params_t
* @y: holds the y (optional)
* @x: holds the x
*
* negative error value.
**/
int gnutls_x509_privkey_import_dh_raw(gnutls_x509_privkey_t key,
- const gnutls_datum_t *p,
- const gnutls_datum_t *q,
- const gnutls_datum_t *g,
+ const gnutls_dh_params_t params,
const gnutls_datum_t *y,
const gnutls_datum_t *x)
{
int ret;
- if (unlikely(key == NULL || p == NULL || g == NULL || x == NULL)) {
+ if (unlikely(key == NULL || params == NULL || x == NULL)) {
return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
}
gnutls_pk_params_init(&key->params);
- if (_gnutls_mpi_init_scan_nz(&key->params.params[DH_P], p->data,
- p->size)) {
- gnutls_assert();
- ret = GNUTLS_E_MPI_SCAN_FAILED;
- goto cleanup;
- }
-
- if (q) {
- if (_gnutls_mpi_init_scan_nz(&key->params.params[DH_Q], q->data,
- q->size)) {
- gnutls_assert();
- ret = GNUTLS_E_MPI_SCAN_FAILED;
- goto cleanup;
- }
- }
-
- if (_gnutls_mpi_init_scan_nz(&key->params.params[DH_G], g->data,
- g->size)) {
- gnutls_assert();
- ret = GNUTLS_E_MPI_SCAN_FAILED;
- goto cleanup;
+ key->params.params[DH_P] = _gnutls_mpi_copy(params->params[0]);
+ key->params.params[DH_G] = _gnutls_mpi_copy(params->params[1]);
+ if (params->params[2]) {
+ key->params.params[DH_Q] = _gnutls_mpi_copy(params->params[2]);
}
+ key->params.qbits = params->q_bits;
if (y) {
if (_gnutls_mpi_init_scan_nz(&key->params.params[DH_Y], y->data,
_gnutls_mpi_copy(dh_params->params[1]);
/* X and Y will be added by _gnutls_pk_generate_keys */
key->params.params_nr = 3;
+ key->params.qbits = dh_params->q_bits;
} else {
ret = _gnutls_pk_generate_params(algo, bits, &key->params);
if (ret < 0) {
fail("error\n");
}
+static bool dh_params_equal(const gnutls_dh_params_t a,
+ const gnutls_dh_params_t b)
+{
+ gnutls_datum_t prime1, generator1;
+ unsigned int bits1;
+ gnutls_datum_t prime2, generator2;
+ unsigned int bits2;
+ int ret;
+ bool ok;
+
+ ret = gnutls_dh_params_export_raw(a, &prime1, &generator1, &bits1);
+ assert(ret >= 0);
+ ret = gnutls_dh_params_export_raw(b, &prime2, &generator2, &bits2);
+ assert(ret >= 0);
+
+ ok = prime1.size == prime2.size &&
+ !memcmp(prime1.data, prime2.data, prime1.size) &&
+ generator1.size == generator2.size &&
+ !memcmp(generator1.data, generator2.data, generator1.size) &&
+ bits1 == bits2;
+
+ gnutls_free(prime1.data);
+ gnutls_free(prime2.data);
+ gnutls_free(generator1.data);
+ gnutls_free(generator2.data);
+
+ return ok;
+}
+
static void genkey(const gnutls_dh_params_t dh_params, gnutls_datum_t *priv_key,
gnutls_datum_t *pub_key)
{
int ret;
gnutls_privkey_t privkey;
+ gnutls_pubkey_t pubkey;
gnutls_keygen_data_st data;
+ gnutls_dh_params_t dh_params_exported;
+ gnutls_datum_t tmp;
ret = gnutls_privkey_init(&privkey);
- if (ret != 0)
- fail("error\n");
+ assert(ret >= 0);
+
+ ret = gnutls_pubkey_init(&pubkey);
+ assert(ret >= 0);
data.type = GNUTLS_KEYGEN_DH;
data.data = (unsigned char *)dh_params;
if (ret != 0)
fail("error\n");
- ret = gnutls_privkey_export_dh_raw(privkey, NULL, NULL, NULL, pub_key,
- priv_key, 0);
- if (ret != 0)
- fail("error: %s\n", gnutls_strerror(ret));
+ ret = gnutls_pubkey_import_privkey(pubkey, privkey, 0, 0);
+ assert(ret >= 0);
+
+ /* Retrieve only private key */
+ ret = gnutls_privkey_export_dh_raw(privkey, NULL, NULL, &tmp, 0);
+ if (ret != 0) {
+ fail("unable to export private key: %s\n",
+ gnutls_strerror(ret));
+ }
+ gnutls_free(tmp.data);
+
+ /* Retrieve DH params and private key */
+ ret = gnutls_dh_params_init(&dh_params_exported);
+ assert(ret >= 0);
+
+ ret = gnutls_privkey_export_dh_raw(privkey, dh_params_exported, NULL,
+ &tmp, 0);
+ if (ret != 0) {
+ fail("unable to export private key: %s\n",
+ gnutls_strerror(ret));
+ }
+ *priv_key = tmp;
+
+ if (!dh_params_equal(dh_params_exported, dh_params)) {
+ fail("error\n");
+ }
+
+ gnutls_dh_params_deinit(dh_params_exported);
+ /* Retrieve only public key */
+ ret = gnutls_pubkey_export_dh_raw(pubkey, NULL, &tmp, 0);
+ if (ret != 0) {
+ fail("unable to export public key: %s\n", gnutls_strerror(ret));
+ }
+ gnutls_free(tmp.data);
+
+ /* Retrieve DH params and public key */
+ ret = gnutls_dh_params_init(&dh_params_exported);
+ assert(ret >= 0);
+
+ ret = gnutls_pubkey_export_dh_raw(pubkey, dh_params_exported, &tmp, 0);
+ if (ret != 0) {
+ fail("unable to export public key: %s\n", gnutls_strerror(ret));
+ }
+ *pub_key = tmp;
+
+ if (!dh_params_equal(dh_params_exported, dh_params)) {
+ fail("error\n");
+ }
+
+ gnutls_dh_params_deinit(dh_params_exported);
gnutls_privkey_deinit(privkey);
+ gnutls_pubkey_deinit(pubkey);
}
static void compute_key(const char *name, const gnutls_dh_params_t dh_params,
int ret;
gnutls_privkey_t privkey;
gnutls_pubkey_t pubkey;
- gnutls_datum_t prime, generator;
- unsigned int bits;
ret = gnutls_privkey_init(&privkey);
- if (ret != 0)
- fail("error\n");
+ assert(ret >= 0);
- ret = gnutls_dh_params_export_raw(dh_params, &prime, &generator, &bits);
- if (ret != 0)
- fail("error\n");
-
- ret = gnutls_privkey_import_dh_raw(privkey, &prime, NULL, &generator,
- NULL, priv_key);
- if (ret != 0)
- fail("error\n");
+ ret = gnutls_privkey_import_dh_raw(privkey, dh_params, NULL, priv_key);
+ assert(ret >= 0);
ret = gnutls_pubkey_init(&pubkey);
- if (ret != 0)
- fail("error\n");
+ assert(ret >= 0);
- ret = gnutls_pubkey_import_dh_raw(pubkey, &prime, NULL, &generator,
- pub_key);
- if (ret != 0)
- fail("error\n");
+ ret = gnutls_pubkey_import_dh_raw(pubkey, dh_params, pub_key);
+ assert(ret >= 0);
ret = gnutls_privkey_derive_secret(privkey, pubkey, NULL, &Z, 0);
- if (ret != 0)
- fail("error\n");
+ if (ret != 0) {
+ fail("unable to derive secret: %s\n", gnutls_strerror(ret));
+ }
if (result) {
success = (Z.size != result->size &&
fail("%s: failed to match result\n", name);
}
gnutls_free(Z.data);
- gnutls_free(prime.data);
- gnutls_free(generator.data);
gnutls_privkey_deinit(privkey);
gnutls_pubkey_deinit(pubkey);
}