sm: Support import of PKCS#12 encoded ECC private keys.

* sm/import.c (parse_p12): Support ECC import.
--

Although I extended the parser and its test the actual import
missed the required code.

GnuPG-bug-id: 6253
Backported-from-master: 8dfef5197a
This commit is contained in:
Werner Koch 2020-04-21 20:59:52 +02:00
parent 2e99d27bd2
commit 2e7a08a829
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
1 changed files with 74 additions and 29 deletions

View File

@ -718,6 +718,7 @@ parse_p12 (ctrl_t ctrl, ksba_reader_t reader, struct stats_s *stats)
gcry_sexp_t s_key = NULL;
unsigned char grip[20];
int bad_pass = 0;
char *curve = NULL;
int i;
struct store_cert_parm_s store_cert_parm;
@ -779,8 +780,7 @@ parse_p12 (ctrl_t ctrl, ksba_reader_t reader, struct stats_s *stats)
kparms = p12_parse (p12buffer + p12bufoff, p12buflen - p12bufoff,
passphrase, store_cert_cb, &store_cert_parm,
&bad_pass, NULL);
&bad_pass, &curve);
xfree (passphrase);
passphrase = NULL;
@ -791,35 +791,79 @@ parse_p12 (ctrl_t ctrl, ksba_reader_t reader, struct stats_s *stats)
goto leave;
}
/* print_mpi (" n", kparms[0]); */
/* print_mpi (" e", kparms[1]); */
/* print_mpi (" d", kparms[2]); */
/* print_mpi (" p", kparms[3]); */
/* print_mpi (" q", kparms[4]); */
/* print_mpi ("dmp1", kparms[5]); */
/* print_mpi ("dmq1", kparms[6]); */
/* print_mpi (" u", kparms[7]); */
if (curve)
{
gcry_ctx_t ecctx = NULL;
sk.n = kparms[0];
sk.e = kparms[1];
sk.d = kparms[2];
sk.q = kparms[3];
sk.p = kparms[4];
sk.u = kparms[7];
err = rsa_key_check (&sk);
if (err)
goto leave;
/* print_mpi (" n", sk.n); */
/* print_mpi (" e", sk.e); */
/* print_mpi (" d", sk.d); */
/* print_mpi (" p", sk.p); */
/* print_mpi (" q", sk.q); */
/* print_mpi (" u", sk.u); */
/* log_debug ("curve: %s\n", curve); */
/* gcry_log_debugmpi ("MPI[0]", kparms[0]); */
/* Create an S-expression from the parameters. */
err = gcry_sexp_build (&s_key, NULL,
"(private-key(rsa(n%m)(e%m)(d%m)(p%m)(q%m)(u%m)))",
sk.n, sk.e, sk.d, sk.p, sk.q, sk.u, NULL);
/* We need to get the public key. */
err = gcry_mpi_ec_new (&ecctx, NULL, curve);
if (err)
{
log_error ("error creating context for curve '%s': %s\n",
curve, gpg_strerror (err));
goto leave;
}
err = gcry_mpi_ec_set_mpi ("d", kparms[0], ecctx);
if (err)
{
log_error ("error setting 'd' into context of curve '%s': %s\n",
curve, gpg_strerror (err));
gcry_ctx_release (ecctx);
goto leave;
}
kparms[1] = gcry_mpi_ec_get_mpi ("q", ecctx, 1);
if (!kparms[1])
{
log_error ("error computing 'q' from 'd' for curve '%s'\n", curve);
gcry_ctx_release (ecctx);
goto leave;
}
gcry_ctx_release (ecctx);
err = gcry_sexp_build (&s_key, NULL,
"(private-key(ecc(curve %s)(q%m)(d%m)))",
curve, kparms[1], kparms[0], NULL);
}
else /* RSA */
{
/* print_mpi (" n", kparms[0]); */
/* print_mpi (" e", kparms[1]); */
/* print_mpi (" d", kparms[2]); */
/* print_mpi (" p", kparms[3]); */
/* print_mpi (" q", kparms[4]); */
/* print_mpi ("dmp1", kparms[5]); */
/* print_mpi ("dmq1", kparms[6]); */
/* print_mpi (" u", kparms[7]); */
sk.n = kparms[0];
sk.e = kparms[1];
sk.d = kparms[2];
sk.q = kparms[3];
sk.p = kparms[4];
sk.u = kparms[7];
err = rsa_key_check (&sk);
if (err)
goto leave;
/* print_mpi (" n", sk.n); */
/* print_mpi (" e", sk.e); */
/* print_mpi (" d", sk.d); */
/* print_mpi (" p", sk.p); */
/* print_mpi (" q", sk.q); */
/* print_mpi (" u", sk.u); */
/* Create an S-expression from the parameters. */
err = gcry_sexp_build (&s_key, NULL,
"(private-key(rsa(n%m)(e%m)(d%m)(p%m)(q%m)(u%m)))",
sk.n, sk.e, sk.d, sk.p, sk.q, sk.u, NULL);
}
/* The next is very ugly - we really should not rely on our
* knowledge of p12_parse internals. */
for (i=0; i < 8; i++)
gcry_mpi_release (kparms[i]);
gcry_free (kparms);
@ -926,6 +970,7 @@ parse_p12 (ctrl_t ctrl, ksba_reader_t reader, struct stats_s *stats)
xfree (kek);
xfree (get_membuf (&p12mbuf, NULL));
xfree (p12buffer);
xfree (curve);
if (bad_pass)
{