aboutsummaryrefslogtreecommitdiffstats
path: root/agent/cvt-openpgp.c
diff options
context:
space:
mode:
Diffstat (limited to 'agent/cvt-openpgp.c')
-rw-r--r--agent/cvt-openpgp.c47
1 files changed, 39 insertions, 8 deletions
diff --git a/agent/cvt-openpgp.c b/agent/cvt-openpgp.c
index e6a14c436..02c2bc841 100644
--- a/agent/cvt-openpgp.c
+++ b/agent/cvt-openpgp.c
@@ -28,6 +28,13 @@
#include "i18n.h"
#include "cvt-openpgp.h"
+/* Macros for compatibility with older libgcrypt versions. */
+#ifndef HAVE_GCRY_PK_ECDSA
+# define GCRY_PK_ECDH 302
+#endif
+
+
+
/* Helper to pass data via the callback to do_unprotect. */
struct try_do_unprotect_arg_s
@@ -80,6 +87,12 @@ get_keygrip (int pubkey_algo, gcry_mpi_t *pkey, unsigned char *grip)
"(public-key(rsa(n%m)(e%m)))", pkey[0], pkey[1]);
break;
+ case GCRY_PK_ECDSA:
+ case GCRY_PK_ECDH:
+ err = gcry_sexp_build (&s_pkey, NULL,
+ "(public-key(ecc(c%m)(q%m)))", pkey[0], pkey[1]);
+ break;
+
default:
err = gpg_error (GPG_ERR_PUBKEY_ALGO);
break;
@@ -94,7 +107,9 @@ get_keygrip (int pubkey_algo, gcry_mpi_t *pkey, unsigned char *grip)
/* Convert a secret key given as algorithm id and an array of key
- parameters into our s-expression based format. */
+ parameters into our s-expression based format. Note that
+ PUBKEY_ALGO is a standard id and not an OpenPGP id.
+ */
static gpg_error_t
convert_secret_key (gcry_sexp_t *r_key, int pubkey_algo, gcry_mpi_t *skey)
{
@@ -103,6 +118,9 @@ convert_secret_key (gcry_sexp_t *r_key, int pubkey_algo, gcry_mpi_t *skey)
*r_key = NULL;
+ /* FIXME: This is not consistent with the above comment. */
+ pubkey_algo = map_pk_openpgp_to_gcry (pubkey_algo);
+
switch (pubkey_algo)
{
case GCRY_PK_DSA:
@@ -128,6 +146,18 @@ convert_secret_key (gcry_sexp_t *r_key, int pubkey_algo, gcry_mpi_t *skey)
skey[5]);
break;
+ case GCRY_PK_ECDSA:
+ err = gcry_sexp_build (&s_skey, NULL,
+ "(private-key(ecdsa(c%m)(q%m)(d%m)))",
+ skey[0], skey[1], skey[2]);
+ break;
+
+ case GCRY_PK_ECDH:
+ err = gcry_sexp_build (&s_skey, NULL,
+ "(private-key(ecdh(c%m)(q%m)(p%m)(d%m)))",
+ skey[0], skey[1], skey[2], skey[3]);
+ break;
+
default:
err = gpg_error (GPG_ERR_PUBKEY_ALGO);
break;
@@ -202,6 +232,10 @@ do_unprotect (const char *passphrase,
*r_key = NULL;
+ /* Unfortunately, the OpenPGP PK algorithm numbers need to be
+ re-mapped for Libgcrypt. */
+ pubkey_algo = map_pk_openpgp_to_gcry (pubkey_algo);
+
/* Count the actual number of MPIs is in the array and set the
remainder to NULL for easier processing later on. */
for (skeylen = 0; skey[skeylen]; skeylen++)
@@ -219,9 +253,6 @@ do_unprotect (const char *passphrase,
if (gcry_pk_test_algo (pubkey_algo))
{
- /* The algorithm numbers are Libgcrypt numbers but fortunately
- the OpenPGP algorithm numbers map one-to-one to the Libgcrypt
- numbers. */
log_info (_("public key algorithm %d (%s) is not supported\n"),
pubkey_algo, gcry_pk_algo_name (pubkey_algo));
return gpg_error (GPG_ERR_PUBKEY_ALGO);
@@ -1007,7 +1038,8 @@ convert_to_openpgp (ctrl_t ctrl, gcry_sexp_t s_key, const char *passphrase,
case GCRY_PK_ELG: algoname = "elg"; npkey = 3; elems = "pgyx"; break;
case GCRY_PK_ELG_E: algoname = "elg"; npkey = 3; elems = "pgyx"; break;
case GCRY_PK_DSA: algoname = "dsa"; npkey = 4; elems = "pqgyx"; break;
- case GCRY_PK_ECDSA: algoname = "ecdsa"; npkey = 6; elems = "pabgnqd"; break;
+ case GCRY_PK_ECDSA: algoname = "ecdsa"; npkey = 2; elems = "cqd"; break;
+ case GCRY_PK_ECDH: algoname = "ecdh"; npkey = 3; elems = "cqpd"; break;
default: algoname = ""; npkey = 0; elems = NULL; break;
}
assert (!elems || strlen (elems) < DIM (array) );
@@ -1037,7 +1069,7 @@ convert_to_openpgp (ctrl_t ctrl, gcry_sexp_t s_key, const char *passphrase,
int format_args_buf_int[1];
void *format_args[10+2];
size_t n;
- gcry_sexp_t tmpkey, tmpsexp;
+ gcry_sexp_t tmpkey, tmpsexp = NULL;
snprintf (countbuf, sizeof countbuf, "%lu", s2k_count);
@@ -1085,7 +1117,6 @@ convert_to_openpgp (ctrl_t ctrl, gcry_sexp_t s_key, const char *passphrase,
for (i=0; i < DIM (array); i++)
gcry_mpi_release (array[i]);
-
+
return err;
}
-