summaryrefslogtreecommitdiffstats
path: root/sm/export.c
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2020-04-27 16:53:30 +0200
committerWerner Koch <wk@gnupg.org>2020-04-27 19:54:39 +0200
commit5da6925a334c68d736804d8f19a684a678409d99 (patch)
treec68a6f6c8ab61d687d32b4f2ce26f97e107ad02e /sm/export.c
parentcommon: Add an easy to use DER builder. (diff)
downloadgnupg2-5da6925a334c68d736804d8f19a684a678409d99.tar.xz
gnupg2-5da6925a334c68d736804d8f19a684a678409d99.zip
sm: Add support to export ECC private keys.
* sm/minip12.c [TEST]: Remove test code. Include util.h, tlv.h. and openpgpdefs.h. Remove the class and tag constants and replace them by those from tlv.h. (builder_add_oid, builder_add_mpi): New. (build_key_sequence): Rename to ... (build_rsa_key_sequence): this. (build_ecc_key_sequence): New. (p12_build): Call RSA or ECC builder. (p12_raw_build): Ditto. * sm/export.c (gpgsm_p12_export): Use correct armor header for ECC. (sexp_to_kparms): Support ECC. * sm/t-minip12.c: New to replace the former TEST code in minip12.h. -- GnuPG-bug-id: 4921
Diffstat (limited to 'sm/export.c')
-rw-r--r--sm/export.c86
1 files changed, 53 insertions, 33 deletions
diff --git a/sm/export.c b/sm/export.c
index f9efe2970..50489304a 100644
--- a/sm/export.c
+++ b/sm/export.c
@@ -428,8 +428,11 @@ gpgsm_p12_export (ctrl_t ctrl, const char *name, estream_t stream, int rawmode)
opt.p12_charset);
}
+
if (rawmode == 0)
ctrl->pem_name = "PKCS12";
+ else if (gpgsm_get_key_algo_info (cert, NULL) == GCRY_PK_ECC)
+ ctrl->pem_name = "EC PRIVATE KEY";
else if (rawmode == 1)
ctrl->pem_name = "PRIVATE KEY";
else
@@ -551,7 +554,6 @@ sexp_to_kparms (gcry_sexp_t sexp)
const char *s;
size_t n;
int idx;
- const char *elems;
gcry_mpi_t *array;
list = gcry_sexp_find_token (sexp, "private-key", 0 );
@@ -561,49 +563,67 @@ sexp_to_kparms (gcry_sexp_t sexp)
gcry_sexp_release (list);
list = l2;
name = gcry_sexp_nth_data (list, 0, &n);
- if(!name || n != 3 || memcmp (name, "rsa", 3))
+ if (name && n == 3 && !memcmp (name, "rsa", 3))
{
- gcry_sexp_release (list);
- return NULL;
- }
+ /* Parameter names used with RSA in the pkcs#12 order. */
+ const char *elems = "nedqp--u";
- /* Parameter names used with RSA in the pkcs#12 order. */
- elems = "nedqp--u";
- array = xtrycalloc (strlen(elems) + 1, sizeof *array);
- if (!array)
- {
- gcry_sexp_release (list);
- return NULL;
+ array = xtrycalloc (strlen(elems) + 1, sizeof *array);
+ if (!array)
+ {
+ gcry_sexp_release (list);
+ return NULL;
+ }
+ for (idx=0, s=elems; *s; s++, idx++ )
+ {
+ if (*s == '-')
+ continue; /* Computed below */
+ l2 = gcry_sexp_find_token (list, s, 1);
+ if (l2)
+ {
+ array[idx] = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
+ gcry_sexp_release (l2);
+ }
+ if (!array[idx]) /* Required parameter not found or invalid. */
+ {
+ for (idx=0; array[idx]; idx++)
+ gcry_mpi_release (array[idx]);
+ xfree (array);
+ gcry_sexp_release (list);
+ return NULL;
+ }
+ }
+
+ array[5] = gcry_mpi_snew (0); /* compute d mod (q-1) */
+ gcry_mpi_sub_ui (array[5], array[3], 1);
+ gcry_mpi_mod (array[5], array[2], array[5]);
+
+ array[6] = gcry_mpi_snew (0); /* compute d mod (p-1) */
+ gcry_mpi_sub_ui (array[6], array[4], 1);
+ gcry_mpi_mod (array[6], array[2], array[6]);
}
- for (idx=0, s=elems; *s; s++, idx++ )
+ else if (name && n == 3 && !memcmp (name, "ecc", 3))
{
- if (*s == '-')
- continue; /* Computed below */
- l2 = gcry_sexp_find_token (list, s, 1);
- if (l2)
+ array = xtrycalloc (3 + 1, sizeof *array);
+ if (!array)
{
- array[idx] = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
- gcry_sexp_release (l2);
+ gcry_sexp_release (list);
+ return NULL;
}
- if (!array[idx]) /* Required parameter not found or invalid. */
+
+ if (gcry_sexp_extract_param (list, NULL, "/'curve'qd",
+ array+0, array+1, array+2, NULL))
{
- for (idx=0; array[idx]; idx++)
- gcry_mpi_release (array[idx]);
xfree (array);
- gcry_sexp_release (list);
- return NULL;
+ array = NULL; /* Error. */
}
}
- gcry_sexp_release (list);
-
- array[5] = gcry_mpi_snew (0); /* compute d mod (q-1) */
- gcry_mpi_sub_ui (array[5], array[3], 1);
- gcry_mpi_mod (array[5], array[2], array[5]);
-
- array[6] = gcry_mpi_snew (0); /* compute d mod (p-1) */
- gcry_mpi_sub_ui (array[6], array[4], 1);
- gcry_mpi_mod (array[6], array[2], array[6]);
+ else
+ {
+ array = NULL;
+ }
+ gcry_sexp_release (list);
return array;
}