aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--common/sexputil.c5
-rw-r--r--scd/app-openpgp.c35
2 files changed, 34 insertions, 6 deletions
diff --git a/common/sexputil.c b/common/sexputil.c
index b7ddea8fc..29fe508b6 100644
--- a/common/sexputil.c
+++ b/common/sexputil.c
@@ -536,7 +536,8 @@ get_rsa_pk_from_canon_sexp (const unsigned char *keydata, size_t keydatalen,
return err;
if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
return err;
- if (!tok || toklen != 10 || memcmp ("public-key", tok, toklen))
+ if (!tok || !((toklen == 10 && !memcmp ("public-key", tok, toklen))
+ || (toklen == 11 && !memcmp ("private-key", tok, toklen))))
return gpg_error (GPG_ERR_BAD_PUBKEY);
if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
return err;
@@ -1075,6 +1076,8 @@ pubkey_algo_string (gcry_sexp_t s_pkey, enum gcry_pk_algos *r_algoid)
l1 = gcry_sexp_find_token (s_pkey, "public-key", 0);
if (!l1)
+ l1 = gcry_sexp_find_token (s_pkey, "private-key", 0);
+ if (!l1)
return xtrystrdup ("E_no_key");
{
gcry_sexp_t l_tmp = gcry_sexp_cadr (l1);
diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c
index f5d0b5111..d3f460106 100644
--- a/scd/app-openpgp.c
+++ b/scd/app-openpgp.c
@@ -4824,6 +4824,7 @@ do_writekey (app_t app, ctrl_t ctrl,
const unsigned char *buf, *tok;
size_t buflen, toklen;
int depth;
+ char *algostr = NULL;
(void)ctrl;
@@ -4866,17 +4867,41 @@ do_writekey (app_t app, ctrl_t ctrl,
goto leave;
if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
goto leave;
- if (tok && toklen == 3 && memcmp ("rsa", tok, toklen) == 0)
- err = rsa_writekey (app, ctrl, pincb, pincb_arg, keyno, buf, buflen, depth);
- else if (tok && toklen == 3 && memcmp ("ecc", tok, toklen) == 0)
- err = ecc_writekey (app, ctrl, pincb, pincb_arg, keyno, buf, buflen, depth);
+
+ if (tok && toklen == 3 && (!memcmp ("rsa", tok, toklen)
+ || !memcmp ("ecc", tok, toklen)))
+ {
+ gcry_sexp_t stmp;
+ if (!gcry_sexp_new (&stmp, keydata, keydatalen, 0))
+ algostr = pubkey_algo_string (stmp, NULL);
+ else
+ algostr = NULL;
+ gcry_sexp_release (stmp);
+ if (app->app_local->keyattr[keyno].keyalgo && algostr
+ && strcmp (app->app_local->keyattr[keyno].keyalgo, algostr))
+ {
+ log_info ("openpgp: changing key attribute from %s to %s\n",
+ app->app_local->keyattr[keyno].keyalgo, algostr);
+ err = change_keyattr_from_string (app, ctrl, pincb, pincb_arg,
+ keyid, algostr, NULL, 0);
+ if (err)
+ return err;
+ }
+
+ if (*tok == 'r')
+ err = rsa_writekey (app, ctrl, pincb, pincb_arg, keyno,
+ buf,buflen,depth);
+ else
+ err = ecc_writekey (app, ctrl, pincb, pincb_arg, keyno,
+ buf, buflen, depth);
+ }
else
{
err = gpg_error (GPG_ERR_WRONG_PUBKEY_ALGO);
- goto leave;
}
leave:
+ xfree (algostr);
return err;
}