mirror of
git://git.gnupg.org/gnupg.git
synced 2025-07-03 22:56:33 +02:00
gpgsm: Allow parsing of PKCS#12 files with two private keys.
* sm/minip12.c (struct p12_parse_ctx_s): Add privatekey2. (parse_shrouded_key_bag): Handle a second private key. (p12_parse_free_kparms): New. * sm/import.c (parse_p12): Factor some code out to ... (p12_to_skey): this. (parse_p12): Use p12_parse_free_kparms. -- Take care: We allow parsing of a second private key but we are not yet able to import the second private key. The whole things is required to at least import the certificates of current pkcs#12 files as created by the German Elster tax system. No test data, sorry.
This commit is contained in:
parent
092154e17e
commit
0cb622d632
4 changed files with 133 additions and 91 deletions
157
sm/import.c
157
sm/import.c
|
@ -692,6 +692,85 @@ store_cert_cb (void *opaque,
|
|||
}
|
||||
|
||||
|
||||
/* Helper for parse_p12. */
|
||||
static gpg_error_t
|
||||
p12_to_skey (gcry_mpi_t *kparms, const char *curve, gcry_sexp_t *r_skey)
|
||||
{
|
||||
gpg_error_t err = 0;
|
||||
struct rsa_secret_key_s sk;
|
||||
gcry_ctx_t ecctx = NULL;
|
||||
|
||||
if (curve)
|
||||
{
|
||||
/* log_debug ("curve: %s\n", curve); */
|
||||
/* gcry_log_debugmpi ("MPI[0]", kparms[0]); */
|
||||
|
||||
/* 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));
|
||||
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);
|
||||
goto leave;
|
||||
}
|
||||
|
||||
err = gcry_sexp_build (r_skey, 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 (r_skey, 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);
|
||||
}
|
||||
|
||||
leave:
|
||||
gcry_ctx_release (ecctx);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
/* Assume that the reader is at a pkcs#12 message and try to import
|
||||
certificates from that stupid format. We will transfer secret
|
||||
keys to the agent. */
|
||||
|
@ -706,7 +785,6 @@ parse_p12 (ctrl_t ctrl, ksba_reader_t reader, struct stats_s *stats)
|
|||
size_t p12buflen;
|
||||
size_t p12bufoff;
|
||||
gcry_mpi_t *kparms = NULL;
|
||||
struct rsa_secret_key_s sk;
|
||||
char *passphrase = NULL;
|
||||
unsigned char *key = NULL;
|
||||
size_t keylen;
|
||||
|
@ -792,82 +870,9 @@ parse_p12 (ctrl_t ctrl, ksba_reader_t reader, struct stats_s *stats)
|
|||
goto leave;
|
||||
}
|
||||
|
||||
if (curve)
|
||||
{
|
||||
gcry_ctx_t ecctx = NULL;
|
||||
|
||||
/* log_debug ("curve: %s\n", curve); */
|
||||
/* gcry_log_debugmpi ("MPI[0]", kparms[0]); */
|
||||
|
||||
/* 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);
|
||||
err = p12_to_skey (kparms, curve, &s_key);
|
||||
p12_parse_free_kparms (kparms);
|
||||
kparms = NULL;
|
||||
if (err)
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue