]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
Separated pk_generate to pk_generate_params() and pk_generate_keys().
authorNikos Mavrogiannopoulos <nmav@redhat.com>
Wed, 20 Nov 2013 18:04:43 +0000 (19:04 +0100)
committerNikos Mavrogiannopoulos <nmav@redhat.com>
Wed, 27 Nov 2013 10:41:43 +0000 (11:41 +0100)
This allows using the pk_generate interface to get DH parameters
and DH keys.

lib/auth/ecdhe.c
lib/crypto-backend.h
lib/gnutls_pk.h
lib/nettle/pk.c
lib/x509/privkey.c

index 94988fe81448e85e991de0a00d237ebfd4ec23d8..4074002307dc1ba4fea3911a2dda91bd17234ef7 100644 (file)
@@ -202,8 +202,8 @@ _gnutls_gen_ecdh_common_client_kx_int(gnutls_session_t session,
 
        /* generate temporal key */
        ret =
-           _gnutls_pk_generate(GNUTLS_PK_EC, curve,
-                               &session->key.ecdh_params);
+           _gnutls_pk_generate_keys(GNUTLS_PK_EC, curve,
+                                    &session->key.ecdh_params);
        if (ret < 0)
                return gnutls_assert_val(ret);
 
@@ -320,8 +320,8 @@ int _gnutls_ecdh_common_print_server_kx(gnutls_session_t session,
 
        /* generate temporal key */
        ret =
-           _gnutls_pk_generate(GNUTLS_PK_EC, curve,
-                               &session->key.ecdh_params);
+           _gnutls_pk_generate_keys(GNUTLS_PK_EC, curve,
+                                    &session->key.ecdh_params);
        if (ret < 0)
                return gnutls_assert_val(ret);
 
index f7bcd53fa5910fe8b5b93ed26e850926fc893da0..6472d2ef370bfa90cc33b4e8bf98e85d3e7d3c84 100644 (file)
@@ -181,6 +181,7 @@ typedef struct {
        bigint_t params[GNUTLS_MAX_PK_PARAMS];
        unsigned int params_nr; /* the number of parameters */
        unsigned int flags;
+       gnutls_pk_algorithm_t algo;
 } gnutls_pk_params_st;
 
 /**
@@ -317,7 +318,9 @@ typedef struct gnutls_crypto_pk {
        /* sanity checks the public key parameters */
        int (*verify_params) (gnutls_pk_algorithm_t,
                              const gnutls_pk_params_st * pub);
-       int (*generate) (gnutls_pk_algorithm_t, unsigned int nbits,
+       int (*generate_keys) (gnutls_pk_algorithm_t, unsigned int nbits,
+                        gnutls_pk_params_st *);
+       int (*generate_params) (gnutls_pk_algorithm_t, unsigned int nbits,
                         gnutls_pk_params_st *);
        /* this function should convert params to ones suitable
         * for the above functions
index 22ff54a08d580d8a46bbbd82d5cef0bda1995304..46eb3d4f7a572f172bcfe81e4cbddebc870ec77d 100644 (file)
@@ -32,7 +32,8 @@ extern gnutls_crypto_pk_st _gnutls_pk_ops;
 #define _gnutls_pk_verify( algo, data, sig, params) _gnutls_pk_ops.verify( algo, data, sig, params)
 #define _gnutls_pk_verify_params( algo, params) _gnutls_pk_ops.verify_params( algo, params)
 #define _gnutls_pk_derive( algo, out, pub, priv) _gnutls_pk_ops.derive( algo, out, pub, priv)
-#define _gnutls_pk_generate( algo, bits, priv) _gnutls_pk_ops.generate( algo, bits, priv)
+#define _gnutls_pk_generate_keys( algo, bits, priv) _gnutls_pk_ops.generate_keys( algo, bits, priv)
+#define _gnutls_pk_generate_params( algo, bits, priv) _gnutls_pk_ops.generate_params( algo, bits, priv)
 #define _gnutls_pk_hash_algorithm( pk, sig, params, hash) _gnutls_pk_ops.hash_algorithm(pk, sig, params, hash)
 
 inline static int
index ae16f5aca01d4e922dbc43fc5a1481906ccd260c..765b2a60bd77792626dadfc168f182b837ad15e4 100644 (file)
@@ -51,7 +51,8 @@ static inline const struct ecc_curve *get_supported_curve(int curve);
 
 static void rnd_func(void *_ctx, unsigned length, uint8_t * data)
 {
-       _gnutls_rnd(GNUTLS_RND_RANDOM, data, length);
+       if (_gnutls_rnd(GNUTLS_RND_RANDOM, data, length) < 0)
+               abort();
 }
 
 static void
@@ -76,7 +77,9 @@ _dsa_params_to_pubkey(const gnutls_pk_params_st * pk_params,
        memcpy(&pub->p, pk_params->params[0], sizeof(mpz_t));
        memcpy(&pub->q, pk_params->params[1], sizeof(mpz_t));
        memcpy(&pub->g, pk_params->params[2], sizeof(mpz_t));
-       memcpy(&pub->y, pk_params->params[3], sizeof(mpz_t));
+       
+       if (pk_params->params[3] != NULL)
+               memcpy(&pub->y, pk_params->params[3], sizeof(mpz_t));
 }
 
 static void
@@ -655,20 +658,25 @@ static inline const struct ecc_curve *get_supported_curve(int curve)
        }
 }
 
-
+/* Generates algorithm's parameters. That is:
+ *  For DSA: p, q, and g are generated.
+ *  For RSA: nothing
+ *  For ECDSA: just checks the curve is ok
+ */
 static int
 wrap_nettle_pk_generate_params(gnutls_pk_algorithm_t algo,
-                              unsigned int level /*bits */ ,
+                              unsigned int level /*bits or curve*/ ,
                               gnutls_pk_params_st * params)
 {
        int ret;
        unsigned int i, q_bits;
 
        memset(params, 0, sizeof(*params));
+       params->algo = algo;
 
        switch (algo) {
-
        case GNUTLS_PK_DSA:
+       case GNUTLS_PK_DH:
                {
                        struct dsa_public_key pub;
                        struct dsa_private_key priv;
@@ -694,7 +702,7 @@ wrap_nettle_pk_generate_params(gnutls_pk_algorithm_t algo,
                        }
 
                        params->params_nr = 0;
-                       for (i = 0; i < DSA_PRIVATE_PARAMS; i++) {
+                       for (i = 0; i < DSA_PRIVATE_PARAMS-2; i++) {
                                params->params[i] =
                                    _gnutls_mpi_alloc_like(&pub.p);
                                if (params->params[i] == NULL) {
@@ -708,8 +716,6 @@ wrap_nettle_pk_generate_params(gnutls_pk_algorithm_t algo,
                        _gnutls_mpi_set(params->params[0], pub.p);
                        _gnutls_mpi_set(params->params[1], pub.q);
                        _gnutls_mpi_set(params->params[2], pub.g);
-                       _gnutls_mpi_set(params->params[3], pub.y);
-                       _gnutls_mpi_set(params->params[4], priv.x);
 
                      dsa_fail:
                        dsa_private_key_clear(&priv);
@@ -721,6 +727,86 @@ wrap_nettle_pk_generate_params(gnutls_pk_algorithm_t algo,
                        break;
                }
        case GNUTLS_PK_RSA:
+       case GNUTLS_PK_EC:
+               ret = 0;
+               break;
+       default:
+               gnutls_assert();
+               return GNUTLS_E_INVALID_REQUEST;
+       }
+
+       return 0;
+
+      fail:
+
+       for (i = 0; i < params->params_nr; i++) {
+               _gnutls_mpi_release(&params->params[i]);
+       }
+       params->params_nr = 0;
+
+       return ret;
+}
+
+static int
+wrap_nettle_pk_generate_keys(gnutls_pk_algorithm_t algo,
+                              unsigned int level /*bits */ ,
+                              gnutls_pk_params_st * params)
+{
+       int ret;
+       unsigned int i;
+
+       switch (algo) {
+       case GNUTLS_PK_DSA:
+       case GNUTLS_PK_DH:
+               {
+                       struct dsa_public_key pub;
+                       mpz_t r;
+                       mpz_t x, y;
+                       
+                       if (algo != params->algo)
+                               return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+
+                       _dsa_params_to_pubkey(params, &pub);
+
+                       mpz_init(r);
+                       mpz_init(x);
+                       mpz_init(y);
+                       mpz_set(r, pub.q);
+                       mpz_sub_ui(r, r, 2);
+                       nettle_mpz_random(x, NULL, rnd_func, r);
+                       mpz_add_ui(x, x, 1);
+
+                       mpz_powm(y, pub.g, x, pub.p);
+                       
+                       params->params[DSA_Y] = _gnutls_mpi_alloc_like(&pub.p);
+                       if (params->params[DSA_Y] == NULL) {
+                               ret = GNUTLS_E_MEMORY_ERROR;
+                               goto dsa_fail;
+                       }
+
+                       params->params[DSA_X] = _gnutls_mpi_alloc_like(&pub.p);
+                       if (params->params[DSA_X] == NULL) {
+                               ret = GNUTLS_E_MEMORY_ERROR;
+                               goto dsa_fail;
+                       }
+
+                       _gnutls_mpi_set(params->params[DSA_Y], y);
+                       _gnutls_mpi_set(params->params[DSA_X], x);
+                       params->params_nr += 2;
+
+                       ret = 0;
+
+                     dsa_fail:
+                       mpz_clear(r);
+                       mpz_clear(x);
+                       mpz_clear(y);
+
+                       if (ret < 0)
+                               goto fail;
+
+                       break;
+               }
+       case GNUTLS_PK_RSA:
                {
                        struct rsa_public_key pub;
                        struct rsa_private_key priv;
@@ -802,7 +888,8 @@ wrap_nettle_pk_generate_params(gnutls_pk_algorithm_t algo,
                                                    params[ECC_Y]);
                                _gnutls_mpi_release(&params->
                                                    params[ECC_K]);
-                               goto ecc_cleanup;
+                               ret = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
+                               goto ecc_fail;
                        }
 
                        params->flags = level;
@@ -812,9 +899,14 @@ wrap_nettle_pk_generate_params(gnutls_pk_algorithm_t algo,
                                      TOMPZ(params->params[ECC_Y]));
                        ecc_scalar_get(&key, TOMPZ(params->params[ECC_K]));
 
-                     ecc_cleanup:
+                       ret = 0;
+
+                     ecc_fail:
                        ecc_point_clear(&pub);
                        ecc_scalar_clear(&key);
+                       
+                       if (ret < 0)
+                               goto fail;
 
                        break;
                }
@@ -1247,7 +1339,8 @@ gnutls_crypto_pk_st _gnutls_pk_ops = {
        .sign = _wrap_nettle_pk_sign,
        .verify = _wrap_nettle_pk_verify,
        .verify_params = wrap_nettle_pk_verify_params,
-       .generate = wrap_nettle_pk_generate_params,
+       .generate_params = wrap_nettle_pk_generate_params,
+       .generate_keys = wrap_nettle_pk_generate_keys,
        .pk_fixup_private_params = wrap_nettle_pk_fixup,
        .derive = _wrap_nettle_pk_derive,
 };
index bf4b77637db99edd5657654e0858f1ecc3e360a9..1cc71768817b848395d98d63f095e160a49ebec9 100644 (file)
@@ -1490,7 +1490,13 @@ gnutls_x509_privkey_generate(gnutls_x509_privkey_t key,
                        bits = _gnutls_ecc_bits_to_curve(bits);
        }
 
-       ret = _gnutls_pk_generate(algo, bits, &key->params);
+       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;