diff options
Diffstat (limited to 'scd/app-openpgp.c')
-rw-r--r-- | scd/app-openpgp.c | 119 |
1 files changed, 62 insertions, 57 deletions
diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c index 637f6b19d..461c71033 100644 --- a/scd/app-openpgp.c +++ b/scd/app-openpgp.c @@ -235,7 +235,7 @@ struct app_local_s { } keyattr[3]; }; -#define ECC_FLAG_EDDSA (1 << 0) +#define ECC_FLAG_DJB_TWEAK (1 << 0) /***** Local prototypes *****/ @@ -909,8 +909,9 @@ send_key_attr (ctrl_t ctrl, app_t app, const char *keyword, int keyno) { snprintf (buffer, sizeof buffer, "%d %d %s", keyno+1, - app->app_local->keyattr[keyno].ecc.flags? PUBKEY_ALGO_EDDSA: - (keyno==1? PUBKEY_ALGO_ECDH: PUBKEY_ALGO_ECDSA), + keyno==1? PUBKEY_ALGO_ECDH : + app->app_local->keyattr[keyno].ecc.flags? + PUBKEY_ALGO_EDDSA : PUBKEY_ALGO_ECDSA, openpgp_oid_to_curve (app->app_local->keyattr[keyno].ecc.oid, 0)); } else @@ -1378,59 +1379,52 @@ get_public_key (app_t app, int keyno) } } - - mbuf = xtrymalloc ( mlen + 1); + mbuf = xtrymalloc (mlen + 1); if (!mbuf) { err = gpg_error_from_syserror (); goto leave; } - /* Prepend numbers with a 0 if needed. */ + if ((app->app_local->keyattr[keyno].key_type == KEY_TYPE_RSA || (app->app_local->keyattr[keyno].key_type == KEY_TYPE_ECC && !app->app_local->keyattr[keyno].ecc.flags)) && mlen && (*m & 0x80)) - { + { /* Prepend numbers with a 0 if needed for MPI. */ *mbuf = 0; memcpy (mbuf+1, m, mlen); mlen++; } - else - memcpy (mbuf, m, mlen); - - ebuf = xtrymalloc ( elen + 1); - if (!ebuf) - { - err = gpg_error_from_syserror (); - goto leave; - } - /* Prepend numbers with a 0 if needed. */ - if (elen && (*e & 0x80)) - { - *ebuf = 0; - memcpy (ebuf+1, e, elen); - elen++; + else if (app->app_local->keyattr[keyno].key_type == KEY_TYPE_ECC + && app->app_local->keyattr[keyno].ecc.flags) + { /* Prepend 0x40 prefix. */ + *mbuf = 0x40; + memcpy (mbuf+1, m, mlen); + mlen++; } else - memcpy (ebuf, e, elen); + memcpy (mbuf, m, mlen); if (app->app_local->keyattr[keyno].key_type == KEY_TYPE_RSA) { - err = gcry_sexp_build (&s_pkey, NULL, "(public-key(rsa(n%b)(e%b)))", - (int)mlen, mbuf, (int)elen, ebuf); - if (err) - goto leave; - - len = gcry_sexp_sprint (s_pkey, GCRYSEXP_FMT_CANON, NULL, 0); - keybuf = xtrymalloc (len); - if (!keybuf) + ebuf = xtrymalloc (elen + 1); + if (!ebuf) { - gcry_sexp_release (s_pkey); err = gpg_error_from_syserror (); goto leave; } - gcry_sexp_sprint (s_pkey, GCRYSEXP_FMT_CANON, keybuf, len); - gcry_sexp_release (s_pkey); + /* Prepend numbers with a 0 if needed. */ + if (elen && (*e & 0x80)) + { + *ebuf = 0; + memcpy (ebuf+1, e, elen); + elen++; + } + else + memcpy (ebuf, e, elen); + + err = gcry_sexp_build (&s_pkey, NULL, "(public-key(rsa(n%b)(e%b)))", + (int)mlen, mbuf, (int)elen, ebuf); } else if (app->app_local->keyattr[keyno].key_type == KEY_TYPE_ECC) { @@ -1438,32 +1432,32 @@ get_public_key (app_t app, int keyno) if (!app->app_local->keyattr[keyno].ecc.flags) format = "(public-key(ecc(curve%s)(q%b)))"; + else if (keyno == 1) + format = "(public-key(ecc(curve%s)(flags djb-tweak)(q%b)))"; else format = "(public-key(ecc(curve%s)(flags eddsa)(q%b)))"; err = gcry_sexp_build (&s_pkey, NULL, format, openpgp_oid_to_curve (app->app_local->keyattr[keyno].ecc.oid, 1), (int)mlen, mbuf); - if (err) - goto leave; - - len = gcry_sexp_sprint (s_pkey, GCRYSEXP_FMT_CANON, NULL, 0); - - keybuf = xtrymalloc (len); - if (!keybuf) - { - gcry_sexp_release (s_pkey); - err = gpg_error_from_syserror (); - goto leave; - } - gcry_sexp_sprint (s_pkey, GCRYSEXP_FMT_CANON, keybuf, len); - gcry_sexp_release (s_pkey); } else + err = gpg_error (GPG_ERR_NOT_IMPLEMENTED); + + if (err) + goto leave; + + len = gcry_sexp_sprint (s_pkey, GCRYSEXP_FMT_CANON, NULL, 0); + + keybuf = xtrymalloc (len); + if (!keybuf) { - err = gpg_error (GPG_ERR_NOT_IMPLEMENTED); + gcry_sexp_release (s_pkey); + err = gpg_error_from_syserror (); goto leave; } + gcry_sexp_sprint (s_pkey, GCRYSEXP_FMT_CANON, keybuf, len); + gcry_sexp_release (s_pkey); app->app_local->pk[keyno].key = (unsigned char*)keybuf; app->app_local->pk[keyno].keylen = len - 1; /* Decrement for trailing '\0' */ @@ -3171,7 +3165,7 @@ ecc_writekey (app_t app, gpg_error_t (*pincb)(void*, const char *, char **), size_t ecc_q_len, ecc_d_len; u32 created_at = 0; const char *oidstr = NULL; - int flag_eddsa = 0; + int flag_djb_tweak = 0; int algo; /* (private-key(ecc(curve%s)(q%m)(d%m))(created-at%d)): @@ -3216,8 +3210,12 @@ ecc_writekey (app_t app, gpg_error_t (*pincb)(void*, const char *, char **), if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen))) goto leave; - if (tok && toklen == 5 && !memcmp (tok, "eddsa", 5)) - flag_eddsa = 1; + if (tok) + { + if ((toklen == 5 && !memcmp (tok, "eddsa", 5)) + || (toklen == 9 && !memcmp (tok, "djb-tweak", 9))) + flag_djb_tweak = 1; + } } else if (tok && toklen == 1) { @@ -3237,7 +3235,7 @@ ecc_writekey (app_t app, gpg_error_t (*pincb)(void*, const char *, char **), } if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen))) goto leave; - if (tok && buf2 && !flag_eddsa) + if (tok && buf2 && !flag_djb_tweak) /* It's MPI. Strip off leading zero bytes and save. */ for (;toklen && !*tok; toklen--, tok++) ; @@ -3300,7 +3298,7 @@ ecc_writekey (app_t app, gpg_error_t (*pincb)(void*, const char *, char **), err = gpg_error (GPG_ERR_INV_VALUE); goto leave; } - if (flag_eddsa && keyno != 1) + if (flag_djb_tweak && keyno != 1) algo = PUBKEY_ALGO_EDDSA; else if (keyno == 1) algo = PUBKEY_ALGO_ECDH; @@ -3309,7 +3307,7 @@ ecc_writekey (app_t app, gpg_error_t (*pincb)(void*, const char *, char **), if (app->app_local->keyattr[keyno].key_type != KEY_TYPE_ECC || app->app_local->keyattr[keyno].ecc.oid != oidstr - || app->app_local->keyattr[keyno].ecc.flags != flag_eddsa) + || app->app_local->keyattr[keyno].ecc.flags != flag_djb_tweak) { log_error ("key attribute on card doesn't match\n"); err = gpg_error (GPG_ERR_INV_VALUE); @@ -4469,11 +4467,18 @@ parse_algorithm_attribute (app_t app, int keyno) { app->app_local->keyattr[keyno].key_type = KEY_TYPE_ECC; app->app_local->keyattr[keyno].ecc.oid = oid; - app->app_local->keyattr[keyno].ecc.flags = (*buffer == PUBKEY_ALGO_EDDSA); + if (*buffer == PUBKEY_ALGO_EDDSA + || (*buffer == PUBKEY_ALGO_ECDH + && !strcmp (app->app_local->keyattr[keyno].ecc.oid, + "1.3.6.1.4.1.3029.1.5.1"))) + app->app_local->keyattr[keyno].ecc.flags = ECC_FLAG_DJB_TWEAK; + else + app->app_local->keyattr[keyno].ecc.flags = 0; if (opt.verbose) log_printf ("ECC, curve=%s%s\n", app->app_local->keyattr[keyno].ecc.oid, - app->app_local->keyattr[keyno].ecc.flags ? " (eddsa)": ""); + !app->app_local->keyattr[keyno].ecc.flags ? "": + keyno==1? " (djb-tweak)": " (eddsa)"); } } else if (opt.verbose) |