summaryrefslogtreecommitdiffstats
path: root/sm
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2024-01-26 09:41:00 +0100
committerWerner Koch <wk@gnupg.org>2024-01-26 09:41:00 +0100
commitdfa60c09f5cd992515df5fdb275dbee7f8f23b71 (patch)
treee68215d4b947727fa98eb8c95244b8819b058b1e /sm
parentgpg: Clean up pk_ecdh_decrypt function. (diff)
parentPost release updates (diff)
downloadgnupg2-dfa60c09f5cd992515df5fdb275dbee7f8f23b71.tar.xz
gnupg2-dfa60c09f5cd992515df5fdb275dbee7f8f23b71.zip
Merge branch 'STABLE-BRANCH-2-4'
-- Fixed conflicts: NEWS configure.ac doc/gpg.texi
Diffstat (limited to 'sm')
-rw-r--r--sm/encrypt.c2
-rw-r--r--sm/import.c157
-rw-r--r--sm/minip12.c58
-rw-r--r--sm/minip12.h1
-rw-r--r--sm/t-minip12.c8
-rw-r--r--sm/verify.c7
6 files changed, 140 insertions, 93 deletions
diff --git a/sm/encrypt.c b/sm/encrypt.c
index 16c48c8d5..202bbb92f 100644
--- a/sm/encrypt.c
+++ b/sm/encrypt.c
@@ -260,7 +260,7 @@ ecdh_encrypt (DEK dek, gcry_sexp_t s_pkey, gcry_sexp_t *r_encval)
encr_algo_str = "1.3.132.1.11.2";
wrap_algo_str = "2.16.840.1.101.3.4.1.25";
hash_algo = GCRY_MD_SHA384;
- cipher_algo = GCRY_CIPHER_AES256;
+ cipher_algo = GCRY_CIPHER_AES192;
keylen = 24;
}
else
diff --git a/sm/import.c b/sm/import.c
index cd28cfbff..4f993ef30 100644
--- a/sm/import.c
+++ b/sm/import.c
@@ -681,6 +681,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. */
@@ -695,7 +774,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;
@@ -781,82 +859,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)
{
diff --git a/sm/minip12.c b/sm/minip12.c
index 1bbe126ae..2e7b50e1c 100644
--- a/sm/minip12.c
+++ b/sm/minip12.c
@@ -168,6 +168,9 @@ struct p12_parse_ctx_s
/* The private key as an MPI array. */
gcry_mpi_t *privatekey;
+
+ /* A second private key as an MPI array. */
+ gcry_mpi_t *privatekey2;
};
@@ -1248,6 +1251,7 @@ parse_shrouded_key_bag (struct p12_parse_ctx_s *ctx, tlv_parser_t tlv)
int is_pbes2 = 0;
int is_aes256 = 0;
int digest_algo = GCRY_MD_SHA1;
+ gcry_mpi_t *privatekey;
where = "shrouded_key_bag";
if (opt_verbose)
@@ -1565,19 +1569,26 @@ parse_shrouded_key_bag (struct p12_parse_ctx_s *ctx, tlv_parser_t tlv)
if (tlv_expect_sequence (tlv))
goto bailout;
- if (ctx->privatekey)
+ if (ctx->privatekey2)
{
err = gpg_error (GPG_ERR_DUP_VALUE);
- log_error ("a private key has already been received\n");
+ log_error ("two private kesy have already been received\n");
goto bailout;
}
- ctx->privatekey = gcry_calloc (10, sizeof *ctx->privatekey);
- if (!ctx->privatekey)
+ privatekey = gcry_calloc (10, sizeof *privatekey);
+ if (!privatekey)
{
err = gpg_error_from_syserror ();
log_error ("error allocating privatekey element array\n");
goto bailout;
}
+ if (ctx->privatekey)
+ {
+ log_info ("a private key has already been received - reading second\n");
+ ctx->privatekey2 = privatekey;
+ }
+ else
+ ctx->privatekey = privatekey;
where = "shrouded_key_bag.reading.key-parameters";
if (ctx->curve) /* ECC case. */
@@ -1600,7 +1611,7 @@ parse_shrouded_key_bag (struct p12_parse_ctx_s *ctx, tlv_parser_t tlv)
goto bailout;
if (opt_verbose > 1)
log_printhex (data, datalen, "ecc q=");
- err = gcry_mpi_scan (ctx->privatekey, GCRYMPI_FMT_USG,
+ err = gcry_mpi_scan (privatekey, GCRYMPI_FMT_USG,
data, datalen, NULL);
if (err)
{
@@ -1623,7 +1634,7 @@ parse_shrouded_key_bag (struct p12_parse_ctx_s *ctx, tlv_parser_t tlv)
}
err = tlv_expect_mpinteger (tlv, firstparam,
- ctx->privatekey+keyelem_count);
+ privatekey+keyelem_count);
if (firstparam && gpg_err_code (err) == GPG_ERR_FALSE)
; /* Ignore the first value iff it is zero. */
else if (err)
@@ -1918,6 +1929,7 @@ p12_parse (const unsigned char *buffer, size_t length, const char *pw,
size_t oidlen;
int intval;
unsigned int startlevel;
+ int i;
*r_badpass = 0;
@@ -2037,6 +2049,15 @@ p12_parse (const unsigned char *buffer, size_t length, const char *pw,
else
gcry_free (ctx.curve);
+ /* We have no way yet to return the second private key. */
+ if (ctx.privatekey2)
+ {
+ for (i=0; ctx.privatekey2[i]; i++)
+ gcry_mpi_release (ctx.privatekey2[i]);
+ gcry_free (ctx.privatekey2);
+ ctx.privatekey2 = NULL;
+ }
+
return ctx.privatekey;
bailout:
@@ -2050,13 +2071,18 @@ p12_parse (const unsigned char *buffer, size_t length, const char *pw,
gpg_strerror (err));
if (ctx.privatekey)
{
- int i;
-
for (i=0; ctx.privatekey[i]; i++)
gcry_mpi_release (ctx.privatekey[i]);
gcry_free (ctx.privatekey);
ctx.privatekey = NULL;
}
+ if (ctx.privatekey2)
+ {
+ for (i=0; ctx.privatekey2[i]; i++)
+ gcry_mpi_release (ctx.privatekey2[i]);
+ gcry_free (ctx.privatekey2);
+ ctx.privatekey2 = NULL;
+ }
tlv_parser_release (tlv);
gcry_free (ctx.curve);
if (r_curve)
@@ -2065,6 +2091,22 @@ p12_parse (const unsigned char *buffer, size_t length, const char *pw,
}
+/* Free the parameters as returned by p12_parse. */
+void
+p12_parse_free_kparms (gcry_mpi_t *kparms)
+{
+ int i;
+
+ if (kparms)
+ {
+ for (i=0; i < 8; i++)
+ gcry_mpi_release (kparms[i]);
+ gcry_free (kparms);
+ }
+}
+
+
+
static size_t
compute_tag_length (size_t n)
diff --git a/sm/minip12.h b/sm/minip12.h
index 654cab0e6..00569cd86 100644
--- a/sm/minip12.h
+++ b/sm/minip12.h
@@ -29,6 +29,7 @@ gcry_mpi_t *p12_parse (const unsigned char *buffer, size_t length,
const char *pw,
void (*certcb)(void*, const unsigned char*, size_t),
void *certcbarg, int *r_badpass, char **r_curve);
+void p12_parse_free_kparms (gcry_mpi_t *kparms);
unsigned char *p12_build (gcry_mpi_t *kparms,
const void *cert, size_t certlen,
diff --git a/sm/t-minip12.c b/sm/t-minip12.c
index bf3177ea0..75c1545d6 100644
--- a/sm/t-minip12.c
+++ b/sm/t-minip12.c
@@ -580,13 +580,7 @@ run_one_test (const char *name, const char *desc, const char *pass,
ret = 0;
}
- if (result)
- {
- int i;
- for (i=0; result[i]; i++)
- gcry_mpi_release (result[i]);
- gcry_free (result);
- }
+ p12_parse_free_kparms (result);
xfree (certstr);
xfree (resulthash);
xfree (curve);
diff --git a/sm/verify.c b/sm/verify.c
index 53d1b468a..39226ed28 100644
--- a/sm/verify.c
+++ b/sm/verify.c
@@ -737,7 +737,12 @@ gpgsm_verify (ctrl_t ctrl, estream_t in_fp, estream_t data_fp,
char numbuf[50];
sprintf (numbuf, "%d", rc );
gpgsm_status2 (ctrl, STATUS_ERROR, "verify.leave",
- numbuf, NULL);
+ numbuf,
+ gpg_err_code (rc) == GPG_ERR_EPIPE?
+ "-- (Broken pipe on input or output)":
+ gpg_err_code (rc) == GPG_ERR_EOF?
+ "-- (End of file)" : NULL,
+ NULL);
}
return rc;