aboutsummaryrefslogtreecommitdiffstats
path: root/sm/import.c
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2020-04-21 18:59:52 +0000
committerWerner Koch <[email protected]>2020-04-21 19:05:39 +0000
commit8dfef5197af9f655697e0095c6613137d51c91e7 (patch)
tree98ed5145b344708b300b5774bc78f50b05125b69 /sm/import.c
parentsm: Replace some debug message by log_error or log_info (diff)
downloadgnupg-8dfef5197af9f655697e0095c6613137d51c91e7.tar.gz
gnupg-8dfef5197af9f655697e0095c6613137d51c91e7.zip
sm: Support import of PKCS#12 encoded ECC private keys.
* sm/minip12.c: Include ksba.h. (oid_pcPublicKey): New const. (parse_bag_data): Add arg 'r-curve'. Support parsing of ECC private keys. (p12_parse): Add arg 'r_curve'. * sm/import.c (parse_p12): Support ECC import. -- GnuPG-bug-id: 4921 Signed-off-by: Werner Koch <[email protected]>
Diffstat (limited to 'sm/import.c')
-rw-r--r--sm/import.c107
1 files changed, 77 insertions, 30 deletions
diff --git a/sm/import.c b/sm/import.c
index ca693824a..4c699c2dd 100644
--- a/sm/import.c
+++ b/sm/import.c
@@ -717,6 +717,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;
@@ -777,7 +778,8 @@ parse_p12 (ctrl_t ctrl, ksba_reader_t reader, struct stats_s *stats)
goto leave;
kparms = p12_parse (p12buffer + p12bufoff, p12buflen - p12bufoff,
- passphrase, store_cert_cb, &store_cert_parm, &bad_pass);
+ passphrase, store_cert_cb,
+ &store_cert_parm, &bad_pass, &curve);
xfree (passphrase);
passphrase = NULL;
@@ -789,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]); */
-
- 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);
+ 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);
@@ -923,6 +969,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)
{