]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
abstract, x509: add functions to import and export DH keys
authorDaiki Ueno <ueno@gnu.org>
Thu, 31 Aug 2023 04:55:58 +0000 (13:55 +0900)
committerDaiki Ueno <ueno@gnu.org>
Sun, 3 Sep 2023 01:56:44 +0000 (10:56 +0900)
This adds a couple of functions to import and export Diffie-Hellman
private keys.  While it shares the structure as DSA, it differs in q
parameter which is optional in Diffie-Hellman and the algorithm
ID: GNUTLS_PK_DH vs GNUTLS_PK_DSA.

Signed-off-by: Daiki Ueno <ueno@gnu.org>
12 files changed:
devel/libgnutls.abignore
devel/symbols.last
doc/Makefile.am
doc/manpages/Makefile.am
lib/includes/gnutls/abstract.h
lib/includes/gnutls/x509.h
lib/libgnutls.map
lib/nettle/pk.c
lib/pk.c
lib/privkey_raw.c
lib/pubkey.c
lib/x509/privkey.c

index c19dce38e11a1c763a5d7bb7a17888e269dc61bf..9c2c9a960a00b8f4885cd57b3d3fc136a2304075 100644 (file)
@@ -70,3 +70,14 @@ name = drbg_aes_reseed
 
 # The following should be removed in the new release, after updating the
 # abi-dump repository:
+[suppress_function]
+name = gnutls_pubkey_import_dh_raw
+
+[suppress_function]
+name = gnutls_privkey_import_dh_raw
+
+[suppress_function]
+name = gnutls_privkey_export_dh_raw
+
+[suppress_function]
+name = gnutls_x509_privkey_import_dh_raw
index 3500a8292b2387342c097a6aeb557135e5106741..8da47fecde5f6ad6c5b514e4e13ce73d3c32bb58 100644 (file)
@@ -18,6 +18,7 @@ GNUTLS_3_7_4@GNUTLS_3_7_4
 GNUTLS_3_7_5@GNUTLS_3_7_5
 GNUTLS_3_7_7@GNUTLS_3_7_7
 GNUTLS_3_8_1@GNUTLS_3_8_1
+GNUTLS_3_8_2@GNUTLS_3_8_2
 _gnutls_global_init_skip@GNUTLS_3_4
 gnutls_aead_cipher_decrypt@GNUTLS_3_4
 gnutls_aead_cipher_decryptv2@GNUTLS_3_6_10
@@ -630,6 +631,7 @@ gnutls_priority_string_list@GNUTLS_3_4
 gnutls_privkey_decrypt_data2@GNUTLS_3_6_5
 gnutls_privkey_decrypt_data@GNUTLS_3_4
 gnutls_privkey_deinit@GNUTLS_3_4
+gnutls_privkey_export_dh_raw@GNUTLS_3_8_2
 gnutls_privkey_export_dsa_raw2@GNUTLS_3_6_0
 gnutls_privkey_export_dsa_raw@GNUTLS_3_4
 gnutls_privkey_export_ecc_raw2@GNUTLS_3_6_0
@@ -646,6 +648,7 @@ gnutls_privkey_get_pk_algorithm@GNUTLS_3_4
 gnutls_privkey_get_seed@GNUTLS_3_4
 gnutls_privkey_get_spki@GNUTLS_3_6_0
 gnutls_privkey_get_type@GNUTLS_3_4
+gnutls_privkey_import_dh_raw@GNUTLS_3_8_2
 gnutls_privkey_import_dsa_raw@GNUTLS_3_4
 gnutls_privkey_import_ecc_raw@GNUTLS_3_4
 gnutls_privkey_import_ext2@GNUTLS_3_4
@@ -719,6 +722,7 @@ gnutls_pubkey_get_pk_algorithm@GNUTLS_3_4
 gnutls_pubkey_get_preferred_hash_algorithm@GNUTLS_3_4
 gnutls_pubkey_get_spki@GNUTLS_3_6_0
 gnutls_pubkey_import@GNUTLS_3_4
+gnutls_pubkey_import_dh_raw@GNUTLS_3_8_2
 gnutls_pubkey_import_dsa_raw@GNUTLS_3_4
 gnutls_pubkey_import_ecc_raw@GNUTLS_3_4
 gnutls_pubkey_import_ecc_x962@GNUTLS_3_4
@@ -1244,6 +1248,7 @@ gnutls_x509_privkey_get_seed@GNUTLS_3_4
 gnutls_x509_privkey_get_spki@GNUTLS_3_6_0
 gnutls_x509_privkey_import2@GNUTLS_3_4
 gnutls_x509_privkey_import@GNUTLS_3_4
+gnutls_x509_privkey_import_dh_raw@GNUTLS_3_8_2
 gnutls_x509_privkey_import_dsa_raw@GNUTLS_3_4
 gnutls_x509_privkey_import_ecc_raw@GNUTLS_3_4
 gnutls_x509_privkey_import_gost_raw@GNUTLS_3_6_3
index 8a35736621ebb7084390865ea8c6ca819195012f..8cf5a72f2bbe4a9e4fe1ba8a17c750a7af96e3f9 100644 (file)
@@ -1668,6 +1668,8 @@ FUNCS += functions/gnutls_privkey_decrypt_data2
 FUNCS += functions/gnutls_privkey_decrypt_data2.short
 FUNCS += functions/gnutls_privkey_deinit
 FUNCS += functions/gnutls_privkey_deinit.short
+FUNCS += functions/gnutls_privkey_export_dh_raw
+FUNCS += functions/gnutls_privkey_export_dh_raw.short
 FUNCS += functions/gnutls_privkey_export_dsa_raw
 FUNCS += functions/gnutls_privkey_export_dsa_raw.short
 FUNCS += functions/gnutls_privkey_export_dsa_raw2
@@ -1700,6 +1702,8 @@ FUNCS += functions/gnutls_privkey_get_spki
 FUNCS += functions/gnutls_privkey_get_spki.short
 FUNCS += functions/gnutls_privkey_get_type
 FUNCS += functions/gnutls_privkey_get_type.short
+FUNCS += functions/gnutls_privkey_import_dh_raw
+FUNCS += functions/gnutls_privkey_import_dh_raw.short
 FUNCS += functions/gnutls_privkey_import_dsa_raw
 FUNCS += functions/gnutls_privkey_import_dsa_raw.short
 FUNCS += functions/gnutls_privkey_import_ecc_raw
@@ -1848,6 +1852,8 @@ FUNCS += functions/gnutls_pubkey_get_spki
 FUNCS += functions/gnutls_pubkey_get_spki.short
 FUNCS += functions/gnutls_pubkey_import
 FUNCS += functions/gnutls_pubkey_import.short
+FUNCS += functions/gnutls_pubkey_import_dh_raw
+FUNCS += functions/gnutls_pubkey_import_dh_raw.short
 FUNCS += functions/gnutls_pubkey_import_dsa_raw
 FUNCS += functions/gnutls_pubkey_import_dsa_raw.short
 FUNCS += functions/gnutls_pubkey_import_ecc_raw
@@ -2870,6 +2876,8 @@ FUNCS += functions/gnutls_x509_privkey_import
 FUNCS += functions/gnutls_x509_privkey_import.short
 FUNCS += functions/gnutls_x509_privkey_import2
 FUNCS += functions/gnutls_x509_privkey_import2.short
+FUNCS += functions/gnutls_x509_privkey_import_dh_raw
+FUNCS += functions/gnutls_x509_privkey_import_dh_raw.short
 FUNCS += functions/gnutls_x509_privkey_import_dsa_raw
 FUNCS += functions/gnutls_x509_privkey_import_dsa_raw.short
 FUNCS += functions/gnutls_x509_privkey_import_ecc_raw
index e29ff15caa07cd5f9dba610fb44a4fc942f101f1..49cb3942bd48e5b7ae8bbdc252ead4460be55e4f 100644 (file)
@@ -680,6 +680,7 @@ APIMANS += gnutls_priority_string_list.3
 APIMANS += gnutls_privkey_decrypt_data.3
 APIMANS += gnutls_privkey_decrypt_data2.3
 APIMANS += gnutls_privkey_deinit.3
+APIMANS += gnutls_privkey_export_dh_raw.3
 APIMANS += gnutls_privkey_export_dsa_raw.3
 APIMANS += gnutls_privkey_export_dsa_raw2.3
 APIMANS += gnutls_privkey_export_ecc_raw.3
@@ -696,6 +697,7 @@ APIMANS += gnutls_privkey_get_pk_algorithm.3
 APIMANS += gnutls_privkey_get_seed.3
 APIMANS += gnutls_privkey_get_spki.3
 APIMANS += gnutls_privkey_get_type.3
+APIMANS += gnutls_privkey_import_dh_raw.3
 APIMANS += gnutls_privkey_import_dsa_raw.3
 APIMANS += gnutls_privkey_import_ecc_raw.3
 APIMANS += gnutls_privkey_import_ext.3
@@ -770,6 +772,7 @@ APIMANS += gnutls_pubkey_get_pk_algorithm.3
 APIMANS += gnutls_pubkey_get_preferred_hash_algorithm.3
 APIMANS += gnutls_pubkey_get_spki.3
 APIMANS += gnutls_pubkey_import.3
+APIMANS += gnutls_pubkey_import_dh_raw.3
 APIMANS += gnutls_pubkey_import_dsa_raw.3
 APIMANS += gnutls_pubkey_import_ecc_raw.3
 APIMANS += gnutls_pubkey_import_ecc_x962.3
@@ -1281,6 +1284,7 @@ APIMANS += gnutls_x509_privkey_get_seed.3
 APIMANS += gnutls_x509_privkey_get_spki.3
 APIMANS += gnutls_x509_privkey_import.3
 APIMANS += gnutls_x509_privkey_import2.3
+APIMANS += gnutls_x509_privkey_import_dh_raw.3
 APIMANS += gnutls_x509_privkey_import_dsa_raw.3
 APIMANS += gnutls_x509_privkey_import_ecc_raw.3
 APIMANS += gnutls_x509_privkey_import_gost_raw.3
index 641d72012d3de2175cfd4088866c9e61ee742904..579cd02a39d6303aae7b349241fc008c9fc40d29 100644 (file)
@@ -238,6 +238,10 @@ int gnutls_pubkey_import_dsa_raw(gnutls_pubkey_t key, const gnutls_datum_t *p,
                                 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,
+                               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);
 
@@ -437,6 +441,12 @@ int gnutls_privkey_import_dsa_raw(gnutls_privkey_t key, const gnutls_datum_t *p,
                                  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,
+                                const gnutls_datum_t *y,
+                                const gnutls_datum_t *x);
+
 int gnutls_privkey_import_rsa_raw(
        gnutls_privkey_t key, const gnutls_datum_t *m, const gnutls_datum_t *e,
        const gnutls_datum_t *d, const gnutls_datum_t *p,
@@ -511,6 +521,11 @@ int gnutls_privkey_export_dsa_raw2(gnutls_privkey_t key, gnutls_datum_t *p,
                                   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_ecc_raw(gnutls_privkey_t key,
                                  gnutls_ecc_curve_t *curve, gnutls_datum_t *x,
                                  gnutls_datum_t *y, gnutls_datum_t *k);
index af1127a4dcf81110c4733b0e26c7473dc25b9767..61ae85b609ee0dc12f1d413879be5c528d26810c 100644 (file)
@@ -1118,6 +1118,12 @@ int gnutls_x509_privkey_import_dsa_raw(gnutls_x509_privkey_t key,
                                       const gnutls_datum_t *g,
                                       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_datum_t *y,
+                                     const gnutls_datum_t *x);
 
 int gnutls_x509_privkey_get_pk_algorithm(gnutls_x509_privkey_t key);
 int gnutls_x509_privkey_get_pk_algorithm2(gnutls_x509_privkey_t key,
index fae2070dfc392b84e486d17c51c271051e7d4f6c..019914afea297eb9e19ce0069bf46451a6d945ad 100644 (file)
@@ -1419,6 +1419,17 @@ GNUTLS_3_8_1
        *;
 } GNUTLS_3_7_7;
 
+GNUTLS_3_8_2
+{
+ global:
+       gnutls_pubkey_import_dh_raw;
+       gnutls_privkey_import_dh_raw;
+       gnutls_privkey_export_dh_raw;
+       gnutls_x509_privkey_import_dh_raw;
+ local:
+       *;
+} GNUTLS_3_8_1;
+
 GNUTLS_FIPS140_3_4 {
   global:
        gnutls_cipher_self_test;
index 9cf63f7c1269ab0f4244eed791f6894e9115cb74..7995c00d5708fc314783aa77f8ddfd8be8bfba6e 100644 (file)
@@ -3351,6 +3351,7 @@ static int wrap_nettle_pk_verify_priv_params(gnutls_pk_algorithm_t algo,
        }
 
        break;
+       case GNUTLS_PK_DH:
        case GNUTLS_PK_DSA: {
                bigint_t t1 = NULL;
 
index c38c12985b361002e9954fcdf7ddc45b4cf4e26a..cb023e2f23191b95d1ea4f18ca63e3a71aa13e82 100644 (file)
--- a/lib/pk.c
+++ b/lib/pk.c
@@ -922,7 +922,7 @@ int _gnutls_params_get_dsa_raw(const gnutls_pk_params_st *params,
                return GNUTLS_E_INVALID_REQUEST;
        }
 
-       if (params->algo != GNUTLS_PK_DSA) {
+       if (params->algo != GNUTLS_PK_DSA && params->algo != GNUTLS_PK_DH) {
                gnutls_assert();
                return GNUTLS_E_INVALID_REQUEST;
        }
index e9ea8ad88128c7b870946b3a58369aed7fe5440b..3b6b8fd908dc2dbadc595ff11c5515a78e345447 100644 (file)
@@ -179,6 +179,33 @@ int gnutls_privkey_export_dsa_raw2(gnutls_privkey_t key, gnutls_datum_t *p,
        return ret;
 }
 
+/**
+ * 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
+ * @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
+ * appropriate datum.
+ *
+ * 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)
+{
+       return gnutls_privkey_export_dsa_raw2(key, p, q, g, y, x, flags);
+}
+
 /**
  * gnutls_privkey_export_ecc_raw:
  * @key: Holds the public key
@@ -404,6 +431,57 @@ error:
        return ret;
 }
 
+/**
+ * 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
+ * @y: holds the y (optional)
+ * @x: holds the x
+ *
+ * This function will convert the given Diffie-Hellman raw parameters
+ * to the native #gnutls_privkey_t format.  The output will be stored
+ * in @key.
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
+ *   negative error value.
+ *
+ * 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,
+                                const gnutls_datum_t *y,
+                                const gnutls_datum_t *x)
+{
+       int ret;
+       gnutls_x509_privkey_t xkey;
+
+       ret = gnutls_x509_privkey_init(&xkey);
+       if (ret < 0)
+               return gnutls_assert_val(ret);
+
+       ret = gnutls_x509_privkey_import_dh_raw(xkey, p, q, g, y, x);
+       if (ret < 0) {
+               gnutls_assert();
+               goto error;
+       }
+
+       ret = gnutls_privkey_import_x509(key, xkey,
+                                        GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE);
+       if (ret < 0) {
+               gnutls_assert();
+               goto error;
+       }
+
+       return 0;
+
+error:
+       gnutls_x509_privkey_deinit(xkey);
+       return ret;
+}
+
 /**
  * gnutls_privkey_import_ecc_raw:
  * @key: The key
index 2315070fbc5d451de2e69aef4a76850989c30c70..71ba2272dcb1319ad5c77ac89975d2419fcdc049 100644 (file)
@@ -1945,6 +1945,79 @@ cleanup:
        return ret;
 }
 
+/**
+ * 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
+ * @y: holds the y
+ *
+ * This function will convert the given Diffie-Hellman raw parameters
+ * to the native #gnutls_pubkey_t format.  The output will be stored
+ * in @key.
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
+ *   negative error value.
+ *
+ * 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,
+                               const gnutls_datum_t *y)
+{
+       int ret;
+
+       if (unlikely(key == NULL || p == NULL || g == 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;
+       }
+
+       if (_gnutls_mpi_init_scan_nz(&key->params.params[DH_Y], y->data,
+                                    y->size)) {
+               gnutls_assert();
+               ret = GNUTLS_E_MPI_SCAN_FAILED;
+               goto cleanup;
+       }
+
+       key->params.params_nr = DH_PUBLIC_PARAMS;
+       key->params.algo = GNUTLS_PK_DH;
+       key->bits = pubkey_to_bits(&key->params);
+
+       return 0;
+
+cleanup:
+       gnutls_pk_params_clear(&key->params);
+       gnutls_pk_params_release(&key->params);
+       return ret;
+}
+
 /* Updates the gnutls_x509_spki_st parameters based on the signature
  * information, and reports any incompatibilities between the existing
  * parameters (if any) with the signature algorithm */
index 5fb10fa203b8dbc3f9db6c8aca82d8cc2a8fdcc1..3ee15971aa8ef1c5897fafc8db684109995d4339 100644 (file)
@@ -1071,6 +1071,93 @@ cleanup:
        return ret;
 }
 
+/**
+ * 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
+ * @y: holds the y (optional)
+ * @x: holds the x
+ *
+ * This function will convert the given Diffie-Hellman raw parameters
+ * to the native #gnutls_x509_privkey_t format.  The output will be
+ * stored in @key.
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
+ *   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_datum_t *y,
+                                     const gnutls_datum_t *x)
+{
+       int ret;
+
+       if (unlikely(key == NULL || p == NULL || g == 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;
+       }
+
+       if (y) {
+               if (_gnutls_mpi_init_scan_nz(&key->params.params[DH_Y], y->data,
+                                            y->size)) {
+                       gnutls_assert();
+                       ret = GNUTLS_E_MPI_SCAN_FAILED;
+                       goto cleanup;
+               }
+       }
+
+       if (_gnutls_mpi_init_scan_nz(&key->params.params[DH_X], x->data,
+                                    x->size)) {
+               gnutls_assert();
+               ret = GNUTLS_E_MPI_SCAN_FAILED;
+               goto cleanup;
+       }
+
+       ret = _gnutls_pk_fixup(GNUTLS_PK_DH, GNUTLS_IMPORT, &key->params);
+       if (ret < 0) {
+               gnutls_assert();
+               goto cleanup;
+       }
+
+       key->params.algo = GNUTLS_PK_DH;
+       key->params.params_nr = DH_PRIVATE_PARAMS;
+
+       return 0;
+
+cleanup:
+       gnutls_pk_params_clear(&key->params);
+       gnutls_pk_params_release(&key->params);
+       return ret;
+}
+
 /**
  * gnutls_x509_privkey_import_ecc_raw:
  * @key: The data to store the parsed key