aboutsummaryrefslogtreecommitdiffstats
path: root/sm/import.c
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2024-01-15 08:55:55 +0000
committerWerner Koch <[email protected]>2024-01-15 08:56:07 +0000
commit0cb622d632f732c24a5d312baf2c6e453775eb10 (patch)
treea14ab9a8f804a37eb3875f13f8c432717a271b28 /sm/import.c
parentgpgsm: Improve the status line for --verify errors. (diff)
downloadgnupg-0cb622d632f732c24a5d312baf2c6e453775eb10.tar.gz
gnupg-0cb622d632f732c24a5d312baf2c6e453775eb10.zip
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.
Diffstat (limited to 'sm/import.c')
-rw-r--r--sm/import.c157
1 files changed, 81 insertions, 76 deletions
diff --git a/sm/import.c b/sm/import.c
index 5a193ef52..cbf8fa627 100644
--- a/sm/import.c
+++ b/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)
{