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; @@ -1074,6 +1075,8 @@ pubkey_algo_string (gcry_sexp_t s_pkey, enum gcry_pk_algos *r_algoid) *r_algoid = 0; 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"); { 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; }