From afbe61d54a669d7115f2ed953243f04726d05ae0 Mon Sep 17 00:00:00 2001 From: Nikolay Sivov Date: Sun, 6 Sep 2020 21:18:57 +0300 Subject: Use symbols defined for RSA key parameter indices in some more places. Signed-off-by: Nikolay Sivov --- lib/nettle/pk.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/lib/nettle/pk.c b/lib/nettle/pk.c index e9a380857c..1a30607a67 100644 --- a/lib/nettle/pk.c +++ b/lib/nettle/pk.c @@ -146,12 +146,12 @@ static void _rsa_params_to_privkey(const gnutls_pk_params_st * pk_params, struct rsa_private_key *priv) { - memcpy(priv->d, pk_params->params[2], SIZEOF_MPZT); - memcpy(priv->p, pk_params->params[3], SIZEOF_MPZT); - memcpy(priv->q, pk_params->params[4], SIZEOF_MPZT); - memcpy(priv->c, pk_params->params[5], SIZEOF_MPZT); - memcpy(priv->a, pk_params->params[6], SIZEOF_MPZT); - memcpy(priv->b, pk_params->params[7], SIZEOF_MPZT); + memcpy(priv->d, pk_params->params[RSA_PRIV], SIZEOF_MPZT); + memcpy(priv->p, pk_params->params[RSA_PRIME1], SIZEOF_MPZT); + memcpy(priv->q, pk_params->params[RSA_PRIME2], SIZEOF_MPZT); + memcpy(priv->c, pk_params->params[RSA_COEF], SIZEOF_MPZT); + memcpy(priv->a, pk_params->params[RSA_E1], SIZEOF_MPZT); + memcpy(priv->b, pk_params->params[RSA_E2], SIZEOF_MPZT); /* we do not rsa_private_key_prepare() because it involves a multiplication. * we call it once when we import the parameters */ priv->size = @@ -2511,14 +2511,14 @@ wrap_nettle_pk_generate_keys(gnutls_pk_algorithm_t algo, params->params_nr++; } - mpz_set(TOMPZ(params->params[0]), pub.n); - mpz_set(TOMPZ(params->params[1]), pub.e); - mpz_set(TOMPZ(params->params[2]), priv.d); - mpz_set(TOMPZ(params->params[3]), priv.p); - mpz_set(TOMPZ(params->params[4]), priv.q); - mpz_set(TOMPZ(params->params[5]), priv.c); - mpz_set(TOMPZ(params->params[6]), priv.a); - mpz_set(TOMPZ(params->params[7]), priv.b); + mpz_set(TOMPZ(params->params[RSA_MODULUS]), pub.n); + mpz_set(TOMPZ(params->params[RSA_PUB]), pub.e); + mpz_set(TOMPZ(params->params[RSA_PRIV]), priv.d); + mpz_set(TOMPZ(params->params[RSA_PRIME1]), priv.p); + mpz_set(TOMPZ(params->params[RSA_PRIME2]), priv.q); + mpz_set(TOMPZ(params->params[RSA_COEF]), priv.c); + mpz_set(TOMPZ(params->params[RSA_E1]), priv.a); + mpz_set(TOMPZ(params->params[RSA_E2]), priv.b); ret = 0; -- cgit v1.2.1 From 81b0a397a3382bb7257a39cc886b1a1f7607c072 Mon Sep 17 00:00:00 2001 From: Nikolay Sivov Date: Sun, 6 Sep 2020 23:42:33 +0300 Subject: Make private exponent optional in gnutls_privkey_import_rsa_raw(). Signed-off-by: Nikolay Sivov --- lib/nettle/pk.c | 38 ++++++++++++++++++++++++++++++++++++++ lib/privkey_raw.c | 2 +- lib/x509/privkey.c | 14 ++++++++------ tests/key-import-export.c | 32 ++++++++++++++++++++++++++++++++ 4 files changed, 79 insertions(+), 7 deletions(-) diff --git a/lib/nettle/pk.c b/lib/nettle/pk.c index 1a30607a67..0c91aac493 100644 --- a/lib/nettle/pk.c +++ b/lib/nettle/pk.c @@ -3306,6 +3306,37 @@ fail: return ret; } +static int calc_rsa_priv(gnutls_pk_params_st * params) +{ + bigint_t lcm, p1, q1; + int ret; + + params->params[RSA_PRIV] = NULL; + + ret = _gnutls_mpi_init_multi(¶ms->params[RSA_PRIV], &lcm, &p1, &q1, NULL); + if (ret < 0) + return gnutls_assert_val(ret); + + /* lcm(p - 1, q - 1) */ + mpz_sub_ui(p1, params->params[RSA_PRIME1], 1); + mpz_sub_ui(q1, params->params[RSA_PRIME2], 1); + mpz_lcm(lcm, p1, q1); + + zrelease_mpi_key(&p1); + zrelease_mpi_key(&q1); + + /* d = e^{-1} (mod lcm) */ + ret = mpz_invert(params->params[RSA_PRIV], params->params[RSA_PUB], lcm); + + zrelease_mpi_key(&lcm); + + if (ret == 0) { + zrelease_mpi_key(¶ms->params[RSA_PRIV]); + return GNUTLS_E_INVALID_REQUEST; + } + + return 0; +} static int wrap_nettle_pk_fixup(gnutls_pk_algorithm_t algo, @@ -3320,6 +3351,13 @@ wrap_nettle_pk_fixup(gnutls_pk_algorithm_t algo, if (algo == GNUTLS_PK_RSA) { struct rsa_private_key priv; + if (params->params[RSA_PRIV] == NULL) { + ret = calc_rsa_priv(params); + if (ret < 0) + return gnutls_assert_val(ret); + params->params_nr++; + } + /* do not trust the generated values. Some old private keys * generated by us have mess on the values. Those were very * old but it seemed some of the shipped example private diff --git a/lib/privkey_raw.c b/lib/privkey_raw.c index 5f1dc8c26c..27327fc6d1 100644 --- a/lib/privkey_raw.c +++ b/lib/privkey_raw.c @@ -324,7 +324,7 @@ gnutls_privkey_export_gost_raw2(gnutls_privkey_t key, * @key: The structure to store the parsed key * @m: holds the modulus * @e: holds the public exponent - * @d: holds the private exponent + * @d: holds the private exponent (optional) * @p: holds the first prime (p) * @q: holds the second prime (q) * @u: holds the coefficient (optional) diff --git a/lib/x509/privkey.c b/lib/x509/privkey.c index 3852064648..020453cc17 100644 --- a/lib/x509/privkey.c +++ b/lib/x509/privkey.c @@ -900,13 +900,15 @@ gnutls_x509_privkey_import_rsa_raw2(gnutls_x509_privkey_t key, } key->params.params_nr++; - siz = d->size; - if (_gnutls_mpi_init_scan_nz(&key->params.params[RSA_PRIV], d->data, siz)) { - gnutls_assert(); - ret = GNUTLS_E_MPI_SCAN_FAILED; - goto cleanup; + if (d) { + siz = d->size; + if (_gnutls_mpi_init_scan_nz(&key->params.params[RSA_PRIV], d->data, siz)) { + gnutls_assert(); + ret = GNUTLS_E_MPI_SCAN_FAILED; + goto cleanup; + } + key->params.params_nr++; } - key->params.params_nr++; siz = p->size; if (_gnutls_mpi_init_scan_nz(&key->params.params[RSA_PRIME1], p->data, siz)) { diff --git a/tests/key-import-export.c b/tests/key-import-export.c index e28b21a4f2..fc6c25e6a7 100644 --- a/tests/key-import-export.c +++ b/tests/key-import-export.c @@ -367,6 +367,38 @@ int check_privkey_import_export(void) gnutls_privkey_deinit(key); } + /* Optional private exponent */ + ret = gnutls_privkey_init(&key); + if (ret < 0) + fail("error\n"); + + ret = gnutls_privkey_import_rsa_raw(key, &_rsa_m, &_rsa_e, NULL, &_rsa_p, &_rsa_q, NULL, NULL, NULL); + if (ret < 0) + fail("error\n"); + + ret = gnutls_privkey_export_rsa_raw2(key, &m, &e, &d, &p, &q, &u, &e1, &e2, 0); + if (ret < 0) + fail("error\n"); + + CMP("m", &m, rsa_m); + CMP("e", &e, rsa_e); + CMP("d", &d, rsa_d); + CMP("p", &p, rsa_p); + CMP("q", &q, rsa_q); + CMP("u", &u, rsa_u); + CMP("e1", &e1, rsa_e1); + CMP("e2", &e2, rsa_e2); + gnutls_free(m.data); + gnutls_free(e.data); + gnutls_free(d.data); + gnutls_free(p.data); + gnutls_free(q.data); + gnutls_free(u.data); + gnutls_free(e1.data); + gnutls_free(e2.data); + + gnutls_privkey_deinit(key); + ret = gnutls_privkey_init(&key); if (ret < 0) fail("error\n"); -- cgit v1.2.1