1
0
mirror of git://git.gnupg.org/gnupg.git synced 2024-06-15 00:29:49 +02:00

gpg: Use only OpenPGP public key algo ids and add the EdDSA algo id.

* common/sexputil.c (get_pk_algo_from_canon_sexp): Change to return a
string.
* g10/keygen.c (check_keygrip): Adjust for change.
* sm/certreqgen-ui.c (check_keygrip): Likewise.

* agent/pksign.c (do_encode_dsa): Remove bogus map_pk_openpgp_to_gcry.

* g10/misc.c (map_pk_openpgp_to_gcry): Remove.
(openpgp_pk_test_algo): Change to a wrapper for openpgp_pk_test_algo2.
(openpgp_pk_test_algo2): Rewrite.
(openpgp_pk_algo_usage, pubkey_nbits): Add support for EdDSA.
(openpgp_pk_algo_name): Rewrite to remove need for gcry calls.
(pubkey_get_npkey, pubkey_get_nskey): Ditto.
(pubkey_get_nsig, pubkey_get_nenc): Ditto.
* g10/keygen.c(do_create_from_keygrip):  Support EdDSA.
(common_gen, gen_ecc, ask_keysize, generate_keypair): Ditto.
* g10/build-packet.c (do_key): Ditto.
* g10/export.c (transfer_format_to_openpgp): Ditto.
* g10/getkey.c (cache_public_key): Ditto.
* g10/import.c (transfer_secret_keys): Ditto.
* g10/keylist.c (list_keyblock_print, list_keyblock_colon): Ditto.
* g10/mainproc.c (proc_pubkey_enc): Ditto.
* g10/parse-packet.c (parse_key): Ditto,
* g10/sign.c (hash_for, sign_file, make_keysig_packet): Ditto.
* g10/keyserver.c (print_keyrec): Use openpgp_pk_algo_name.
* g10/pkglue.c (pk_verify, pk_encrypt, pk_check_secret_key): Use only
OpenPGP algo ids and support EdDSA.
* g10/pubkey-enc.c (get_it): Use only OpenPGP algo ids.
* g10/seskey.c (encode_md_value): Ditto.
--

This patch separates Libgcrypt and OpenPGP public key algorithms ids
and in most cases completely removes the Libgcrypt ones.  This is
useful because for Libgcrypt we specify the algorithm in the
S-expressions and the public key ids are not anymore needed.

This patch also adds some support for PUBKEY_ALGO_EDDSA which will
eventually be used instead of merging EdDSA with ECDSA.  As of now an
experimental algorithm id is used but the plan is to write an I-D so
that we can get a new id from the IETF.  Note that EdDSA (Ed25519)
does not yet work and that more changes are required.

The ECC support is still broken right now.  Needs to be fixed.

Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
Werner Koch 2014-01-30 18:48:37 +01:00
parent ea8a1685f7
commit b7f8dec632
21 changed files with 323 additions and 253 deletions

View File

@ -151,18 +151,15 @@ do_encode_eddsa (const byte *md, size_t mdlen, gcry_sexp_t *r_hash)
/* Encode a message digest for use with an DSA algorithm. */ /* Encode a message digest for use with an DSA algorithm. */
static gpg_error_t static gpg_error_t
do_encode_dsa (const byte *md, size_t mdlen, int dsaalgo, gcry_sexp_t pkey, do_encode_dsa (const byte *md, size_t mdlen, int pkalgo, gcry_sexp_t pkey,
gcry_sexp_t *r_hash) gcry_sexp_t *r_hash)
{ {
gpg_error_t err; gpg_error_t err;
gcry_sexp_t hash; gcry_sexp_t hash;
unsigned int qbits; unsigned int qbits;
int pkalgo;
*r_hash = NULL; *r_hash = NULL;
pkalgo = map_pk_openpgp_to_gcry (dsaalgo);
if (pkalgo == GCRY_PK_ECDSA) if (pkalgo == GCRY_PK_ECDSA)
qbits = gcry_pk_get_nbits (pkey); qbits = gcry_pk_get_nbits (pkey);
else if (pkalgo == GCRY_PK_DSA) else if (pkalgo == GCRY_PK_DSA)

View File

@ -512,17 +512,18 @@ get_rsa_pk_from_canon_sexp (const unsigned char *keydata, size_t keydatalen,
/* Return the algo of a public RSA expressed as an canonical encoded /* Return the algo of a public RSA expressed as an canonical encoded
S-expression. On error the algo is set to 0. */ S-expression. The return value is a statically allocated
string. On error that string is set to NULL. */
gpg_error_t gpg_error_t
get_pk_algo_from_canon_sexp (const unsigned char *keydata, size_t keydatalen, get_pk_algo_from_canon_sexp (const unsigned char *keydata, size_t keydatalen,
int *r_algo) const char **r_algo)
{ {
gpg_error_t err; gpg_error_t err;
const unsigned char *buf, *tok; const unsigned char *buf, *tok;
size_t buflen, toklen; size_t buflen, toklen;
int depth; int depth;
*r_algo = 0; *r_algo = NULL;
buf = keydata; buf = keydata;
buflen = keydatalen; buflen = keydatalen;
@ -541,15 +542,17 @@ get_pk_algo_from_canon_sexp (const unsigned char *keydata, size_t keydatalen,
return gpg_error (GPG_ERR_BAD_PUBKEY); return gpg_error (GPG_ERR_BAD_PUBKEY);
if (toklen == 3 && !memcmp ("rsa", tok, toklen)) if (toklen == 3 && !memcmp ("rsa", tok, toklen))
*r_algo = GCRY_PK_RSA; *r_algo = "rsa";
else if (toklen == 3 && !memcmp ("dsa", tok, toklen)) else if (toklen == 3 && !memcmp ("dsa", tok, toklen))
*r_algo = GCRY_PK_DSA; *r_algo = "dsa";
else if (toklen == 3 && !memcmp ("elg", tok, toklen)) else if (toklen == 3 && !memcmp ("elg", tok, toklen))
*r_algo = GCRY_PK_ELG; *r_algo = "elg";
else if (toklen == 5 && !memcmp ("ecdsa", tok, toklen)) else if (toklen == 5 && !memcmp ("ecdsa", tok, toklen))
*r_algo = GCRY_PK_ECDSA; *r_algo = "ecdsa";
else if (toklen == 5 && !memcmp ("eddsa", tok, toklen))
*r_algo = "eddsa";
else else
return gpg_error (GPG_ERR_PUBKEY_ALGO); return gpg_error (GPG_ERR_PUBKEY_ALGO);
return 0; return 0;
} }

View File

@ -193,7 +193,7 @@ gpg_error_t get_rsa_pk_from_canon_sexp (const unsigned char *keydata,
size_t *r_elen); size_t *r_elen);
gpg_error_t get_pk_algo_from_canon_sexp (const unsigned char *keydata, gpg_error_t get_pk_algo_from_canon_sexp (const unsigned char *keydata,
size_t keydatalen, size_t keydatalen,
int *r_algo); const char **r_algo);
/*-- convert.c --*/ /*-- convert.c --*/
int hex2bin (const char *string, void *buffer, size_t length); int hex2bin (const char *string, void *buffer, size_t length);

View File

@ -329,8 +329,9 @@ do_key (iobuf_t out, int ctb, PKT_public_key *pk)
for (i=0; i < npkey; i++ ) for (i=0; i < npkey; i++ )
{ {
if ((pk->pubkey_algo == PUBKEY_ALGO_ECDSA && (i == 0)) if ( (pk->pubkey_algo == PUBKEY_ALGO_ECDSA && (i == 0))
|| ((pk->pubkey_algo == PUBKEY_ALGO_ECDH) && (i == 0 || i == 2))) || (pk->pubkey_algo == PUBKEY_ALGO_EDDSA && (i == 0))
|| (pk->pubkey_algo == PUBKEY_ALGO_ECDH && (i == 0 || i == 2)))
err = gpg_mpi_write_nohdr (a, pk->pkey[i]); err = gpg_mpi_write_nohdr (a, pk->pkey[i]);
else else
err = gpg_mpi_write (a, pk->pkey[i]); err = gpg_mpi_write (a, pk->pkey[i]);

View File

@ -561,7 +561,9 @@ transfer_format_to_openpgp (gcry_sexp_t s_pgp, PKT_public_key *pk)
/* We need to change the received parameters for ECC algorithms. /* We need to change the received parameters for ECC algorithms.
The transfer format has all parameters but OpenPGP defines that The transfer format has all parameters but OpenPGP defines that
only the OID of the curve is to be used. */ only the OID of the curve is to be used. */
if (pubkey_algo == PUBKEY_ALGO_ECDSA || pubkey_algo == PUBKEY_ALGO_ECDH) if (pubkey_algo == PUBKEY_ALGO_ECDSA
|| pubkey_algo == PUBKEY_ALGO_EDDSA
|| pubkey_algo == PUBKEY_ALGO_ECDH)
{ {
gcry_sexp_t s_pubkey; gcry_sexp_t s_pubkey;
const char *curvename, *curveoidstr; const char *curvename, *curveoidstr;

View File

@ -140,6 +140,7 @@ cache_public_key (PKT_public_key * pk)
if (is_ELGAMAL (pk->pubkey_algo) if (is_ELGAMAL (pk->pubkey_algo)
|| pk->pubkey_algo == PUBKEY_ALGO_DSA || pk->pubkey_algo == PUBKEY_ALGO_DSA
|| pk->pubkey_algo == PUBKEY_ALGO_ECDSA || pk->pubkey_algo == PUBKEY_ALGO_ECDSA
|| pk->pubkey_algo == PUBKEY_ALGO_EDDSA
|| pk->pubkey_algo == PUBKEY_ALGO_ECDH || pk->pubkey_algo == PUBKEY_ALGO_ECDH
|| is_RSA (pk->pubkey_algo)) || is_RSA (pk->pubkey_algo))
{ {

View File

@ -1260,6 +1260,7 @@ transfer_secret_keys (ctrl_t ctrl, struct stats_s *stats, kbnode_t sec_keyblock)
init_membuf (&mbuf, 50); init_membuf (&mbuf, 50);
put_membuf_str (&mbuf, "(skey"); put_membuf_str (&mbuf, "(skey");
if (pk->pubkey_algo == PUBKEY_ALGO_ECDSA if (pk->pubkey_algo == PUBKEY_ALGO_ECDSA
|| pk->pubkey_algo == PUBKEY_ALGO_EDDSA
|| pk->pubkey_algo == PUBKEY_ALGO_ECDH) || pk->pubkey_algo == PUBKEY_ALGO_ECDH)
{ {
/* We need special treatment for ECC algorithms. OpenPGP /* We need special treatment for ECC algorithms. OpenPGP
@ -1274,7 +1275,7 @@ transfer_secret_keys (ctrl_t ctrl, struct stats_s *stats, kbnode_t sec_keyblock)
err = gpg_error_from_syserror (); err = gpg_error_from_syserror ();
else else
{ {
gcry_sexp_t cparam = gcry_pk_get_param (GCRY_PK_ECDSA, curve); gcry_sexp_t cparam = gcry_pk_get_param (GCRY_PK_ECC, curve);
xfree (curve); xfree (curve);
if (!cparam) if (!cparam)

View File

@ -1235,6 +1235,7 @@ do_create_from_keygrip (ctrl_t ctrl, int algo, const char *hexkeygrip,
case PUBKEY_ALGO_ELGAMAL_E: algoelem = "pgy"; break; case PUBKEY_ALGO_ELGAMAL_E: algoelem = "pgy"; break;
case PUBKEY_ALGO_ECDH: case PUBKEY_ALGO_ECDH:
case PUBKEY_ALGO_ECDSA: algoelem = ""; break; case PUBKEY_ALGO_ECDSA: algoelem = ""; break;
case PUBKEY_ALGO_EDDSA: algoelem = ""; break;
default: return gpg_error (GPG_ERR_INTERNAL); default: return gpg_error (GPG_ERR_INTERNAL);
} }
@ -1268,7 +1269,9 @@ do_create_from_keygrip (ctrl_t ctrl, int algo, const char *hexkeygrip,
pk->expiredate = pk->timestamp + expireval; pk->expiredate = pk->timestamp + expireval;
pk->pubkey_algo = algo; pk->pubkey_algo = algo;
if (algo == PUBKEY_ALGO_ECDSA || algo == PUBKEY_ALGO_ECDH) if (algo == PUBKEY_ALGO_ECDSA
|| algo == PUBKEY_ALGO_EDDSA
|| algo == PUBKEY_ALGO_ECDH )
err = ecckey_from_sexp (pk->pkey, s_key, algo); err = ecckey_from_sexp (pk->pkey, s_key, algo);
else else
err = key_from_sexp (pk->pkey, s_key, "public-key", algoelem); err = key_from_sexp (pk->pkey, s_key, "public-key", algoelem);
@ -1330,7 +1333,9 @@ common_gen (const char *keyparms, int algo, const char *algoelem,
pk->expiredate = pk->timestamp + expireval; pk->expiredate = pk->timestamp + expireval;
pk->pubkey_algo = algo; pk->pubkey_algo = algo;
if (algo == PUBKEY_ALGO_ECDSA || algo == PUBKEY_ALGO_ECDH) if (algo == PUBKEY_ALGO_ECDSA
|| algo == PUBKEY_ALGO_EDDSA
|| algo == PUBKEY_ALGO_ECDH )
err = ecckey_from_sexp (pk->pkey, s_key, algo); err = ecckey_from_sexp (pk->pkey, s_key, algo);
else else
err = key_from_sexp (pk->pkey, s_key, "public-key", algoelem); err = key_from_sexp (pk->pkey, s_key, "public-key", algoelem);
@ -1508,7 +1513,9 @@ gen_ecc (int algo, const char *curve, kbnode_t pub_root,
gpg_error_t err; gpg_error_t err;
char *keyparms; char *keyparms;
assert (algo == PUBKEY_ALGO_ECDSA || algo == PUBKEY_ALGO_ECDH); assert (algo == PUBKEY_ALGO_ECDSA
|| algo == PUBKEY_ALGO_EDDSA
|| algo == PUBKEY_ALGO_ECDH);
if (!curve || !*curve) if (!curve || !*curve)
return gpg_error (GPG_ERR_UNKNOWN_CURVE); return gpg_error (GPG_ERR_UNKNOWN_CURVE);
@ -1735,7 +1742,7 @@ check_keygrip (ctrl_t ctrl, const char *hexgrip)
gpg_error_t err; gpg_error_t err;
unsigned char *public; unsigned char *public;
size_t publiclen; size_t publiclen;
int algo; const char *algostr;
if (hexgrip[0] == '&') if (hexgrip[0] == '&')
hexgrip++; hexgrip++;
@ -1745,18 +1752,26 @@ check_keygrip (ctrl_t ctrl, const char *hexgrip)
return 0; return 0;
publiclen = gcry_sexp_canon_len (public, 0, NULL, NULL); publiclen = gcry_sexp_canon_len (public, 0, NULL, NULL);
get_pk_algo_from_canon_sexp (public, publiclen, &algo); get_pk_algo_from_canon_sexp (public, publiclen, &algostr);
xfree (public); xfree (public);
switch (algo) /* FIXME: Mapping of ECC algorithms is probably not correct. */
{ if (!algostr)
case GCRY_PK_RSA: return PUBKEY_ALGO_RSA; return 0;
case GCRY_PK_DSA: return PUBKEY_ALGO_DSA; else if (!strcmp (algostr, "rsa"))
case GCRY_PK_ELG_E: return PUBKEY_ALGO_ELGAMAL_E; return PUBKEY_ALGO_RSA;
case GCRY_PK_ECDH: return PUBKEY_ALGO_ECDH; else if (!strcmp (algostr, "dsa"))
case GCRY_PK_ECDSA: return PUBKEY_ALGO_ECDSA; return PUBKEY_ALGO_DSA;
default: return 0; else if (!strcmp (algostr, "elg"))
} return PUBKEY_ALGO_ELGAMAL_E;
else if (!strcmp (algostr, "ecc"))
return PUBKEY_ALGO_ECDH;
else if (!strcmp (algostr, "ecdsa"))
return PUBKEY_ALGO_ECDSA;
else if (!strcmp (algostr, "eddsa"))
return PUBKEY_ALGO_EDDSA;
else
return 0;
} }
@ -1803,13 +1818,13 @@ ask_algo (ctrl_t ctrl, int addmode, int *r_subkey_algo, unsigned int *r_usage,
} }
if (opt.expert && !addmode) if (opt.expert && !addmode)
tty_printf (_(" (%d) ECDSA and ECDH\n"), 9 ); tty_printf (_(" (%d) ECC\n"), 9 );
if (opt.expert) if (opt.expert)
tty_printf (_(" (%d) ECDSA (sign only)\n"), 10 ); tty_printf (_(" (%d) ECC (sign only)\n"), 10 );
if (opt.expert) if (opt.expert)
tty_printf (_(" (%d) ECDSA (set your own capabilities)\n"), 11 ); tty_printf (_(" (%d) ECC (set your own capabilities)\n"), 11 );
if (opt.expert && addmode) if (opt.expert && addmode)
tty_printf (_(" (%d) ECDH (encrypt only)\n"), 12 ); tty_printf (_(" (%d) ECC (encrypt only)\n"), 12 );
if (opt.expert && r_keygrip) if (opt.expert && r_keygrip)
tty_printf (_(" (%d) Existing key\n"), 13 ); tty_printf (_(" (%d) Existing key\n"), 13 );
@ -1978,6 +1993,12 @@ ask_keysize (int algo, unsigned int primary_keysize)
max=521; max=521;
break; break;
case PUBKEY_ALGO_EDDSA:
min=255;
def=255;
max=441;
break;
case PUBKEY_ALGO_RSA: case PUBKEY_ALGO_RSA:
min=1024; min=1024;
break; break;
@ -2017,6 +2038,18 @@ ask_keysize (int algo, unsigned int primary_keysize)
if (!autocomp) if (!autocomp)
tty_printf (_("rounded up to %u bits\n"), nbits); tty_printf (_("rounded up to %u bits\n"), nbits);
} }
else if (algo == PUBKEY_ALGO_EDDSA)
{
if (nbits != 255 && nbits != 441)
{
if (nbits < 256)
nbits = 255;
else
nbits = 441;
if (!autocomp)
tty_printf (_("rounded to %u bits\n"), nbits);
}
}
else if (algo == PUBKEY_ALGO_ECDH || algo == PUBKEY_ALGO_ECDSA) else if (algo == PUBKEY_ALGO_ECDH || algo == PUBKEY_ALGO_ECDSA)
{ {
if (nbits != 256 && nbits != 384 && nbits != 521) if (nbits != 256 && nbits != 384 && nbits != 521)
@ -2613,7 +2646,9 @@ do_create (int algo, unsigned int nbits, const char *curve, KBNODE pub_root,
else if (algo == PUBKEY_ALGO_DSA) else if (algo == PUBKEY_ALGO_DSA)
err = gen_dsa (nbits, pub_root, timestamp, expiredate, is_subkey, err = gen_dsa (nbits, pub_root, timestamp, expiredate, is_subkey,
keygen_flags, cache_nonce_addr); keygen_flags, cache_nonce_addr);
else if (algo == PUBKEY_ALGO_ECDSA || algo == PUBKEY_ALGO_ECDH) else if (algo == PUBKEY_ALGO_ECDSA
|| algo == PUBKEY_ALGO_EDDSA
|| algo == PUBKEY_ALGO_ECDH)
err = gen_ecc (algo, curve, pub_root, timestamp, expiredate, is_subkey, err = gen_ecc (algo, curve, pub_root, timestamp, expiredate, is_subkey,
keygen_flags, cache_nonce_addr); keygen_flags, cache_nonce_addr);
else if (algo == PUBKEY_ALGO_RSA) else if (algo == PUBKEY_ALGO_RSA)
@ -3410,9 +3445,12 @@ generate_keypair (ctrl_t ctrl, const char *fname, const char *card_serialno,
sprintf( r->u.value, "%d", algo ); sprintf( r->u.value, "%d", algo );
r->next = para; r->next = para;
para = r; para = r;
if (algo == PUBKEY_ALGO_ECDSA || algo == PUBKEY_ALGO_ECDH) if (algo == PUBKEY_ALGO_ECDSA
|| algo == PUBKEY_ALGO_EDDSA
|| algo == PUBKEY_ALGO_ECDH)
{ {
curve = ask_curve (); curve = ask_curve ();
nbits = 0;
r = xmalloc_clear (sizeof *r + strlen (curve)); r = xmalloc_clear (sizeof *r + strlen (curve));
r->key = pKEYCURVE; r->key = pKEYCURVE;
strcpy (r->u.value, curve); strcpy (r->u.value, curve);
@ -3467,7 +3505,9 @@ generate_keypair (ctrl_t ctrl, const char *fname, const char *card_serialno,
nbits = 0; nbits = 0;
} }
if (algo == PUBKEY_ALGO_ECDSA || algo == PUBKEY_ALGO_ECDH) if (algo == PUBKEY_ALGO_ECDSA
|| algo == PUBKEY_ALGO_EDDSA
|| algo == PUBKEY_ALGO_ECDH)
{ {
if (!both) if (!both)
curve = ask_curve (); curve = ask_curve ();
@ -3969,7 +4009,9 @@ generate_subkeypair (ctrl_t ctrl, kbnode_t keyblock)
if (hexgrip) if (hexgrip)
nbits = 0; nbits = 0;
else if (algo == PUBKEY_ALGO_ECDSA || algo == PUBKEY_ALGO_ECDH) else if (algo == PUBKEY_ALGO_ECDSA
|| algo == PUBKEY_ALGO_EDDSA
|| algo == PUBKEY_ALGO_ECDH)
curve = ask_curve (); curve = ask_curve ();
else else
nbits = ask_keysize (algo, 0); nbits = ask_keysize (algo, 0);

View File

@ -57,6 +57,7 @@ pubkey_letter( int algo )
case PUBKEY_ALGO_ELGAMAL_E: return 'g' ; case PUBKEY_ALGO_ELGAMAL_E: return 'g' ;
case PUBKEY_ALGO_ELGAMAL: return 'G' ; case PUBKEY_ALGO_ELGAMAL: return 'G' ;
case PUBKEY_ALGO_DSA: return 'D' ; case PUBKEY_ALGO_DSA: return 'D' ;
case PUBKEY_ALGO_EDDSA: return 'E' ; /* ECC EdDSA (sign only) */
case PUBKEY_ALGO_ECDSA: return 'E' ; /* ECC DSA (sign only) */ case PUBKEY_ALGO_ECDSA: return 'E' ; /* ECC DSA (sign only) */
case PUBKEY_ALGO_ECDH: return 'e' ; /* ECC DH (encrypt only) */ case PUBKEY_ALGO_ECDH: return 'e' ; /* ECC DH (encrypt only) */
default: return '?'; default: return '?';
@ -733,6 +734,7 @@ keygrip_from_pk (PKT_public_key *pk, unsigned char *array)
pk->pkey[0], pk->pkey[1]); pk->pkey[0], pk->pkey[1]);
break; break;
case PUBKEY_ALGO_EDDSA:
case PUBKEY_ALGO_ECDSA: case PUBKEY_ALGO_ECDSA:
case PUBKEY_ALGO_ECDH: case PUBKEY_ALGO_ECDH:
{ {

View File

@ -818,6 +818,7 @@ list_keyblock_print (KBNODE keyblock, int secret, int fpr, void *opaque)
keystr_from_pk (pk), datestr_from_pk (pk)); keystr_from_pk (pk), datestr_from_pk (pk));
if (pk->pubkey_algo == PUBKEY_ALGO_ECDSA if (pk->pubkey_algo == PUBKEY_ALGO_ECDSA
|| pk->pubkey_algo == PUBKEY_ALGO_EDDSA
|| pk->pubkey_algo == PUBKEY_ALGO_ECDH) || pk->pubkey_algo == PUBKEY_ALGO_ECDH)
{ {
char *curve = openpgp_oid_to_str (pk->pkey[0]); char *curve = openpgp_oid_to_str (pk->pkey[0]);
@ -953,6 +954,7 @@ list_keyblock_print (KBNODE keyblock, int secret, int fpr, void *opaque)
keystr_from_pk (pk2), datestr_from_pk (pk2)); keystr_from_pk (pk2), datestr_from_pk (pk2));
if (pk2->pubkey_algo == PUBKEY_ALGO_ECDSA if (pk2->pubkey_algo == PUBKEY_ALGO_ECDSA
|| pk2->pubkey_algo == PUBKEY_ALGO_EDDSA
|| pk2->pubkey_algo == PUBKEY_ALGO_ECDH) || pk2->pubkey_algo == PUBKEY_ALGO_ECDH)
{ {
char *curve = openpgp_oid_to_str (pk2->pkey[0]); char *curve = openpgp_oid_to_str (pk2->pkey[0]);
@ -1207,6 +1209,7 @@ list_keyblock_colon (KBNODE keyblock, int secret, int fpr)
es_putc (':', es_stdout); /* End of field 15. */ es_putc (':', es_stdout); /* End of field 15. */
es_putc (':', es_stdout); /* End of field 16. */ es_putc (':', es_stdout); /* End of field 16. */
if (pk->pubkey_algo == PUBKEY_ALGO_ECDSA if (pk->pubkey_algo == PUBKEY_ALGO_ECDSA
|| pk->pubkey_algo == PUBKEY_ALGO_EDDSA
|| pk->pubkey_algo == PUBKEY_ALGO_ECDH) || pk->pubkey_algo == PUBKEY_ALGO_ECDH)
{ {
char *curve = openpgp_oid_to_str (pk->pkey[0]); char *curve = openpgp_oid_to_str (pk->pkey[0]);
@ -1332,6 +1335,7 @@ list_keyblock_colon (KBNODE keyblock, int secret, int fpr)
es_putc (':', es_stdout); /* End of field 15. */ es_putc (':', es_stdout); /* End of field 15. */
es_putc (':', es_stdout); /* End of field 16. */ es_putc (':', es_stdout); /* End of field 16. */
if (pk->pubkey_algo == PUBKEY_ALGO_ECDSA if (pk->pubkey_algo == PUBKEY_ALGO_ECDSA
|| pk->pubkey_algo == PUBKEY_ALGO_EDDSA
|| pk->pubkey_algo == PUBKEY_ALGO_ECDH) || pk->pubkey_algo == PUBKEY_ALGO_ECDH)
{ {
char *curve = openpgp_oid_to_str (pk->pkey[0]); char *curve = openpgp_oid_to_str (pk->pkey[0]);

View File

@ -508,7 +508,7 @@ print_keyrec(int number,struct keyrec *keyrec)
{ {
const char *str; const char *str;
str = gcry_pk_algo_name (map_pk_openpgp_to_gcry (keyrec->type)); str = openpgp_pk_algo_name (keyrec->type);
if (str && strcmp (str, "?")) if (str && strcmp (str, "?"))
es_printf ("%s ",str); es_printf ("%s ",str);

View File

@ -100,13 +100,12 @@ int map_cipher_openpgp_to_gcry (int algo);
int openpgp_cipher_blocklen (int algo); int openpgp_cipher_blocklen (int algo);
int openpgp_cipher_test_algo( int algo ); int openpgp_cipher_test_algo( int algo );
const char *openpgp_cipher_algo_name (int algo); const char *openpgp_cipher_algo_name (int algo);
int map_pk_openpgp_to_gcry (int algo);
int map_pk_gcry_to_openpgp (enum gcry_pk_algos algo); int map_pk_gcry_to_openpgp (enum gcry_pk_algos algo);
int openpgp_pk_test_algo( int algo ); int openpgp_pk_test_algo (pubkey_algo_t algo);
int openpgp_pk_test_algo2 ( int algo, unsigned int use ); int openpgp_pk_test_algo2 (pubkey_algo_t algo, unsigned int use);
int openpgp_pk_algo_usage ( int algo ); int openpgp_pk_algo_usage ( int algo );
int openpgp_md_test_algo( int algo ); int openpgp_md_test_algo( int algo );
const char *openpgp_pk_algo_name (int algo); const char *openpgp_pk_algo_name (pubkey_algo_t algo);
const char *openpgp_md_algo_name (int algo); const char *openpgp_md_algo_name (int algo);
struct expando_args struct expando_args
@ -153,10 +152,10 @@ int is_valid_mailbox (const char *name);
const char *get_libexecdir (void); const char *get_libexecdir (void);
int path_access(const char *file,int mode); int path_access(const char *file,int mode);
int pubkey_get_npkey( int algo ); int pubkey_get_npkey (pubkey_algo_t algo);
int pubkey_get_nskey( int algo ); int pubkey_get_nskey (pubkey_algo_t algo);
int pubkey_get_nsig( int algo ); int pubkey_get_nsig (pubkey_algo_t algo);
int pubkey_get_nenc( int algo ); int pubkey_get_nenc (pubkey_algo_t algo);
/* Temporary helpers. */ /* Temporary helpers. */
unsigned int pubkey_nbits( int algo, gcry_mpi_t *pkey ); unsigned int pubkey_nbits( int algo, gcry_mpi_t *pkey );

View File

@ -389,6 +389,7 @@ proc_pubkey_enc( CTX c, PACKET *pkt )
else if( is_ELGAMAL(enc->pubkey_algo) else if( is_ELGAMAL(enc->pubkey_algo)
|| enc->pubkey_algo == PUBKEY_ALGO_DSA || enc->pubkey_algo == PUBKEY_ALGO_DSA
|| enc->pubkey_algo == PUBKEY_ALGO_ECDSA || enc->pubkey_algo == PUBKEY_ALGO_ECDSA
|| enc->pubkey_algo == PUBKEY_ALGO_EDDSA
|| enc->pubkey_algo == PUBKEY_ALGO_ECDH || enc->pubkey_algo == PUBKEY_ALGO_ECDH
|| is_RSA(enc->pubkey_algo) || is_RSA(enc->pubkey_algo)
|| enc->pubkey_algo == PUBKEY_ALGO_ELGAMAL) { || enc->pubkey_algo == PUBKEY_ALGO_ELGAMAL) {

View File

@ -366,21 +366,9 @@ map_cipher_gcry_to_openpgp (int algo)
} }
} }
/* Map OpenPGP public key algorithm numbers to those used by /* Map Gcrypt public key algorithm numbers to those used by OpenPGP.
Libgcrypt. */ FIXME: This mapping is used at only two places - we should get rid
int of it. */
map_pk_openpgp_to_gcry (int algo)
{
switch (algo)
{
case PUBKEY_ALGO_ECDSA: return GCRY_PK_ECDSA;
case PUBKEY_ALGO_ECDH: return GCRY_PK_ECDH;
default: return algo;
}
}
/* Map Gcrypt public key algorithm numbers to those used by
OpenPGP. */
int int
map_pk_gcry_to_openpgp (enum gcry_pk_algos algo) map_pk_gcry_to_openpgp (enum gcry_pk_algos algo)
{ {
@ -439,41 +427,49 @@ openpgp_cipher_algo_name (int algo)
return gnupg_cipher_algo_name (map_cipher_openpgp_to_gcry (algo)); return gnupg_cipher_algo_name (map_cipher_openpgp_to_gcry (algo));
} }
/* Return 0 if ALGO is a supported OpenPGP public key algorithm. */
int int
openpgp_pk_test_algo( int algo ) openpgp_pk_test_algo (pubkey_algo_t algo)
{ {
/* Dont't allow type 20 keys unless in rfc2440 mode. */ return openpgp_pk_test_algo2 (algo, 0);
if (!RFC2440 && algo == 20)
return gpg_error (GPG_ERR_PUBKEY_ALGO);
if (algo == GCRY_PK_ELG_E)
algo = GCRY_PK_ELG;
if (algo < 0 || algo > 110)
return gpg_error (GPG_ERR_PUBKEY_ALGO);
return gcry_pk_test_algo (map_pk_openpgp_to_gcry (algo));
} }
/* Return 0 if ALGO is a supported OpenPGP public key algorithm and
allows the usage USE. */
int int
openpgp_pk_test_algo2( int algo, unsigned int use ) openpgp_pk_test_algo2 (pubkey_algo_t algo, unsigned int use)
{ {
enum gcry_pk_algos ga = 0;
size_t use_buf = use; size_t use_buf = use;
/* Dont't allow type 20 keys unless in rfc2440 mode. */ switch (algo)
if (!RFC2440 && algo == 20) {
case PUBKEY_ALGO_RSA: ga = GCRY_PK_RSA; break;
case PUBKEY_ALGO_RSA_E: ga = GCRY_PK_RSA_E; break;
case PUBKEY_ALGO_RSA_S: ga = GCRY_PK_RSA_S; break;
case PUBKEY_ALGO_ELGAMAL_E: ga = GCRY_PK_ELG; break;
case PUBKEY_ALGO_DSA: ga = GCRY_PK_DSA; break;
case PUBKEY_ALGO_ECDH:
case PUBKEY_ALGO_ECDSA:
case PUBKEY_ALGO_EDDSA: ga = GCRY_PK_ECC; break;
case PUBKEY_ALGO_ELGAMAL:
/* Dont't allow type 20 keys unless in rfc2440 mode. */
if (RFC2440)
ga = GCRY_PK_ELG;
break;
}
if (!ga)
return gpg_error (GPG_ERR_PUBKEY_ALGO); return gpg_error (GPG_ERR_PUBKEY_ALGO);
if (algo == GCRY_PK_ELG_E) /* No check whether Libgcrypt has support for the algorithm. */
algo = GCRY_PK_ELG; return gcry_pk_algo_info (ga, GCRYCTL_TEST_ALGO, NULL, &use_buf);
if (algo < 0 || algo > 110)
return gpg_error (GPG_ERR_PUBKEY_ALGO);
return gcry_pk_algo_info (map_pk_openpgp_to_gcry (algo),
GCRYCTL_TEST_ALGO, NULL, &use_buf);
} }
int int
openpgp_pk_algo_usage ( int algo ) openpgp_pk_algo_usage ( int algo )
{ {
@ -503,6 +499,7 @@ openpgp_pk_algo_usage ( int algo )
use = PUBKEY_USAGE_CERT | PUBKEY_USAGE_SIG | PUBKEY_USAGE_AUTH; use = PUBKEY_USAGE_CERT | PUBKEY_USAGE_SIG | PUBKEY_USAGE_AUTH;
break; break;
case PUBKEY_ALGO_ECDSA: case PUBKEY_ALGO_ECDSA:
case PUBKEY_ALGO_EDDSA:
use = PUBKEY_USAGE_CERT | PUBKEY_USAGE_SIG | PUBKEY_USAGE_AUTH; use = PUBKEY_USAGE_CERT | PUBKEY_USAGE_SIG | PUBKEY_USAGE_AUTH;
default: default:
break; break;
@ -514,9 +511,21 @@ openpgp_pk_algo_usage ( int algo )
string representation of the algorithm name. For unknown algorithm string representation of the algorithm name. For unknown algorithm
IDs this function returns "?". */ IDs this function returns "?". */
const char * const char *
openpgp_pk_algo_name (int algo) openpgp_pk_algo_name (pubkey_algo_t algo)
{ {
return gcry_pk_algo_name (map_pk_openpgp_to_gcry (algo)); switch (algo)
{
case PUBKEY_ALGO_RSA:
case PUBKEY_ALGO_RSA_E:
case PUBKEY_ALGO_RSA_S: return "RSA";
case PUBKEY_ALGO_ELGAMAL:
case PUBKEY_ALGO_ELGAMAL_E: return "ELG";
case PUBKEY_ALGO_DSA: return "DSA";
case PUBKEY_ALGO_ECDH:
case PUBKEY_ALGO_ECDSA:
case PUBKEY_ALGO_EDDSA: return "ECC";
}
return "?";
} }
@ -1346,94 +1355,80 @@ path_access(const char *file,int mode)
/* Return the number of public key parameters as used by OpenPGP. */ /* Return the number of public key parameters as used by OpenPGP. */
int int
pubkey_get_npkey (int algo) pubkey_get_npkey (pubkey_algo_t algo)
{ {
size_t n; switch (algo)
{
/* ECC is special. */ case PUBKEY_ALGO_RSA:
if (algo == PUBKEY_ALGO_ECDSA) case PUBKEY_ALGO_RSA_E:
return 2; case PUBKEY_ALGO_RSA_S: return 2;
else if (algo == PUBKEY_ALGO_ECDH) case PUBKEY_ALGO_ELGAMAL_E: return 3;
return 3; case PUBKEY_ALGO_DSA: return 4;
case PUBKEY_ALGO_ECDH: return 3;
/* All other algorithms match those of Libgcrypt. */ case PUBKEY_ALGO_ECDSA: return 2;
if (algo == GCRY_PK_ELG_E) case PUBKEY_ALGO_ELGAMAL: return 3;
algo = GCRY_PK_ELG; case PUBKEY_ALGO_EDDSA: return 2;
else if (is_RSA (algo)) }
algo = GCRY_PK_RSA; return 0;
if (gcry_pk_algo_info (algo, GCRYCTL_GET_ALGO_NPKEY, NULL, &n))
n = 0;
return n;
} }
/* Return the number of secret key parameters as used by OpenPGP. */ /* Return the number of secret key parameters as used by OpenPGP. */
int int
pubkey_get_nskey (int algo) pubkey_get_nskey (pubkey_algo_t algo)
{ {
size_t n; switch (algo)
{
/* ECC is special. */ case PUBKEY_ALGO_RSA:
if (algo == PUBKEY_ALGO_ECDSA) case PUBKEY_ALGO_RSA_E:
return 3; case PUBKEY_ALGO_RSA_S: return 6;
else if (algo == PUBKEY_ALGO_ECDH) case PUBKEY_ALGO_ELGAMAL_E: return 4;
return 4; case PUBKEY_ALGO_DSA: return 5;
case PUBKEY_ALGO_ECDH: return 4;
/* All other algorithms match those of Libgcrypt. */ case PUBKEY_ALGO_ECDSA: return 3;
if (algo == GCRY_PK_ELG_E) case PUBKEY_ALGO_ELGAMAL: return 4;
algo = GCRY_PK_ELG; case PUBKEY_ALGO_EDDSA: return 3;
else if (is_RSA (algo)) }
algo = GCRY_PK_RSA; return 0;
if (gcry_pk_algo_info( algo, GCRYCTL_GET_ALGO_NSKEY, NULL, &n ))
n = 0;
return n;
} }
/* Temporary helper. */ /* Temporary helper. */
int int
pubkey_get_nsig (int algo) pubkey_get_nsig (pubkey_algo_t algo)
{ {
size_t n; switch (algo)
{
/* ECC is special. */ case PUBKEY_ALGO_RSA:
if (algo == PUBKEY_ALGO_ECDSA) case PUBKEY_ALGO_RSA_E:
return 2; case PUBKEY_ALGO_RSA_S: return 1;
else if (algo == PUBKEY_ALGO_ECDH) case PUBKEY_ALGO_ELGAMAL_E: return 0;
return 0; case PUBKEY_ALGO_DSA: return 2;
case PUBKEY_ALGO_ECDH: return 0;
if (algo == GCRY_PK_ELG_E) case PUBKEY_ALGO_ECDSA: return 2;
algo = GCRY_PK_ELG; case PUBKEY_ALGO_ELGAMAL: return 2;
else if (is_RSA (algo)) case PUBKEY_ALGO_EDDSA: return 2;
algo = GCRY_PK_RSA; }
return 0;
if (gcry_pk_algo_info( algo, GCRYCTL_GET_ALGO_NSIGN, NULL, &n))
n = 0;
return n;
} }
/* Temporary helper. */ /* Temporary helper. */
int int
pubkey_get_nenc (int algo) pubkey_get_nenc (pubkey_algo_t algo)
{ {
size_t n; switch (algo)
{
/* ECC is special. */ case PUBKEY_ALGO_RSA:
if (algo == PUBKEY_ALGO_ECDSA) case PUBKEY_ALGO_RSA_E:
return 0; case PUBKEY_ALGO_RSA_S: return 1;
else if (algo == PUBKEY_ALGO_ECDH) case PUBKEY_ALGO_ELGAMAL_E: return 2;
return 2; case PUBKEY_ALGO_DSA: return 0;
case PUBKEY_ALGO_ECDH: return 2;
if (algo == GCRY_PK_ELG_E) case PUBKEY_ALGO_ECDSA: return 0;
algo = GCRY_PK_ELG; case PUBKEY_ALGO_ELGAMAL: return 2;
else if (is_RSA (algo)) case PUBKEY_ALGO_EDDSA: return 0;
algo = GCRY_PK_RSA; }
return 0;
if (gcry_pk_algo_info( algo, GCRYCTL_GET_ALGO_NENCR, NULL, &n ))
n = 0;
return n;
} }
@ -1459,7 +1454,8 @@ pubkey_nbits( int algo, gcry_mpi_t *key )
"(public-key(rsa(n%m)(e%m)))", "(public-key(rsa(n%m)(e%m)))",
key[0], key[1] ); key[0], key[1] );
} }
else if( algo == PUBKEY_ALGO_ECDSA || algo == PUBKEY_ALGO_ECDH ) { else if (algo == PUBKEY_ALGO_ECDSA || algo == PUBKEY_ALGO_ECDH
|| algo == PUBKEY_ALGO_EDDSA) {
char *curve = openpgp_oid_to_str (key[0]); char *curve = openpgp_oid_to_str (key[0]);
if (!curve) if (!curve)
rc = gpg_error_from_syserror (); rc = gpg_error_from_syserror ();

View File

@ -1989,9 +1989,11 @@ parse_key (IOBUF inp, int pkttype, unsigned long pktlen,
{ {
for (i = 0; i < npkey; i++) for (i = 0; i < npkey; i++)
{ {
if ((algorithm == PUBKEY_ALGO_ECDSA && (i == 0)) if ( (algorithm == PUBKEY_ALGO_ECDSA && (i == 0))
|| ((algorithm == PUBKEY_ALGO_ECDH) && (i == 0 || i == 2))) || (algorithm == PUBKEY_ALGO_EDDSA && (i == 0))
|| (algorithm == PUBKEY_ALGO_ECDH && (i == 0 || i == 2)))
{ {
/* Read the OID (i==1) or the KDF params (i==2). */
size_t n; size_t n;
err = read_size_body (inp, pktlen, &n, pk->pkey+i); err = read_size_body (inp, pktlen, &n, pk->pkey+i);
pktlen -= n; pktlen -= n;
@ -2011,6 +2013,7 @@ parse_key (IOBUF inp, int pkttype, unsigned long pktlen,
es_fprintf (listfp, "\tpkey[%d]: ", i); es_fprintf (listfp, "\tpkey[%d]: ", i);
mpi_print (listfp, pk->pkey[i], mpi_print_mode); mpi_print (listfp, pk->pkey[i], mpi_print_mode);
if ((algorithm == PUBKEY_ALGO_ECDSA if ((algorithm == PUBKEY_ALGO_ECDSA
|| algorithm == PUBKEY_ALGO_EDDSA
|| algorithm == PUBKEY_ALGO_ECDH) && i==0) || algorithm == PUBKEY_ALGO_ECDH) && i==0)
{ {
char *curve = openpgp_oid_to_str (pk->pkey[0]); char *curve = openpgp_oid_to_str (pk->pkey[0]);

View File

@ -1,5 +1,6 @@
/* pkglue.c - public key operations glue code /* pkglue.c - public key operations glue code
* Copyright (C) 2000, 2003, 2010 Free Software Foundation, Inc. * Copyright (C) 2000, 2003, 2010 Free Software Foundation, Inc.
* Copyright (C) 2014 Werner Koch
* *
* This file is part of GnuPG. * This file is part of GnuPG.
* *
@ -53,51 +54,55 @@ get_mpi_from_sexp (gcry_sexp_t sexp, const char *item, int mpifmt)
* change the internal design to directly fit to libgcrypt. * change the internal design to directly fit to libgcrypt.
*/ */
int int
pk_verify (int algo, gcry_mpi_t hash, gcry_mpi_t *data, gcry_mpi_t *pkey) pk_verify (pubkey_algo_t pkalgo, gcry_mpi_t hash,
gcry_mpi_t *data, gcry_mpi_t *pkey)
{ {
gcry_sexp_t s_sig, s_hash, s_pkey; gcry_sexp_t s_sig, s_hash, s_pkey;
int rc; int rc;
const int pkalgo = map_pk_openpgp_to_gcry (algo);
int is_ed25519 = 0;
/* Make a sexp from pkey. */ /* Make a sexp from pkey. */
if (pkalgo == GCRY_PK_DSA) if (pkalgo == PUBKEY_ALGO_DSA)
{ {
rc = gcry_sexp_build (&s_pkey, NULL, rc = gcry_sexp_build (&s_pkey, NULL,
"(public-key(dsa(p%m)(q%m)(g%m)(y%m)))", "(public-key(dsa(p%m)(q%m)(g%m)(y%m)))",
pkey[0], pkey[1], pkey[2], pkey[3]); pkey[0], pkey[1], pkey[2], pkey[3]);
} }
else if (pkalgo == GCRY_PK_ELG || pkalgo == GCRY_PK_ELG_E) else if (pkalgo == PUBKEY_ALGO_ELGAMAL_E || pkalgo == PUBKEY_ALGO_ELGAMAL)
{ {
rc = gcry_sexp_build (&s_pkey, NULL, rc = gcry_sexp_build (&s_pkey, NULL,
"(public-key(elg(p%m)(g%m)(y%m)))", "(public-key(elg(p%m)(g%m)(y%m)))",
pkey[0], pkey[1], pkey[2]); pkey[0], pkey[1], pkey[2]);
} }
else if (pkalgo == GCRY_PK_RSA || pkalgo == GCRY_PK_RSA_S) else if (pkalgo == PUBKEY_ALGO_RSA || pkalgo == PUBKEY_ALGO_RSA_S)
{ {
rc = gcry_sexp_build (&s_pkey, NULL, rc = gcry_sexp_build (&s_pkey, NULL,
"(public-key(rsa(n%m)(e%m)))", pkey[0], pkey[1]); "(public-key(rsa(n%m)(e%m)))", pkey[0], pkey[1]);
} }
else if (pkalgo == GCRY_PK_ECDSA) /* Same as GCRY_PK_ECDH */ else if (pkalgo == PUBKEY_ALGO_ECDSA)
{ {
is_ed25519 = openpgp_oid_is_ed25519 (pkey[0]); char *curve = openpgp_oid_to_str (pkey[0]);
if (is_ed25519) if (!curve)
rc = gcry_sexp_build (&s_pkey, NULL, rc = gpg_error_from_syserror ();
"(public-key(ecc(curve Ed25519)"
"(flags eddsa)(q%m)))",
pkey[1]);
else else
{ {
char *curve = openpgp_oid_to_str (pkey[0]); rc = gcry_sexp_build (&s_pkey, NULL,
if (!curve) "(public-key(ecdsa(curve %s)(q%m)))",
rc = gpg_error_from_syserror (); curve, pkey[1]);
else xfree (curve);
{ }
rc = gcry_sexp_build (&s_pkey, NULL, }
"(public-key(ecdsa(curve %s)(q%m)))", else if (pkalgo == PUBKEY_ALGO_EDDSA)
curve, pkey[1]); {
xfree (curve); char *curve = openpgp_oid_to_str (pkey[0]);
} if (!curve)
rc = gpg_error_from_syserror ();
else
{
rc = gcry_sexp_build (&s_pkey, NULL,
"(public-key(ecc(curve %s)"
"(flags eddsa)(q%m)))",
curve, pkey[1]);
xfree (curve);
} }
} }
else else
@ -107,7 +112,7 @@ pk_verify (int algo, gcry_mpi_t hash, gcry_mpi_t *data, gcry_mpi_t *pkey)
BUG (); /* gcry_sexp_build should never fail. */ BUG (); /* gcry_sexp_build should never fail. */
/* Put hash into a S-Exp s_hash. */ /* Put hash into a S-Exp s_hash. */
if (is_ed25519) if (pkalgo == PUBKEY_ALGO_EDDSA)
{ {
if (gcry_sexp_build (&s_hash, NULL, if (gcry_sexp_build (&s_hash, NULL,
"(data(flags eddsa)(hash-algo sha512)(value %m))", "(data(flags eddsa)(hash-algo sha512)(value %m))",
@ -122,7 +127,7 @@ pk_verify (int algo, gcry_mpi_t hash, gcry_mpi_t *data, gcry_mpi_t *pkey)
/* Put data into a S-Exp s_sig. */ /* Put data into a S-Exp s_sig. */
s_sig = NULL; s_sig = NULL;
if (pkalgo == GCRY_PK_DSA) if (pkalgo == PUBKEY_ALGO_DSA)
{ {
if (!data[0] || !data[1]) if (!data[0] || !data[1])
rc = gpg_error (GPG_ERR_BAD_MPI); rc = gpg_error (GPG_ERR_BAD_MPI);
@ -130,18 +135,23 @@ pk_verify (int algo, gcry_mpi_t hash, gcry_mpi_t *data, gcry_mpi_t *pkey)
rc = gcry_sexp_build (&s_sig, NULL, rc = gcry_sexp_build (&s_sig, NULL,
"(sig-val(dsa(r%m)(s%m)))", data[0], data[1]); "(sig-val(dsa(r%m)(s%m)))", data[0], data[1]);
} }
else if (pkalgo == GCRY_PK_ECDSA) else if (pkalgo == PUBKEY_ALGO_ECDSA)
{ {
if (!data[0] || !data[1]) if (!data[0] || !data[1])
rc = gpg_error (GPG_ERR_BAD_MPI); rc = gpg_error (GPG_ERR_BAD_MPI);
else if (is_ed25519)
rc = gcry_sexp_build (&s_sig, NULL,
"(sig-val(eddsa(r%M)(s%M)))", data[0], data[1]);
else else
rc = gcry_sexp_build (&s_sig, NULL, rc = gcry_sexp_build (&s_sig, NULL,
"(sig-val(ecdsa(r%m)(s%m)))", data[0], data[1]); "(sig-val(ecdsa(r%m)(s%m)))", data[0], data[1]);
} }
else if (pkalgo == GCRY_PK_ELG || pkalgo == GCRY_PK_ELG_E) else if (pkalgo == PUBKEY_ALGO_EDDSA)
{
if (!data[0] || !data[1])
rc = gpg_error (GPG_ERR_BAD_MPI);
else
rc = gcry_sexp_build (&s_sig, NULL,
"(sig-val(eddsa(r%M)(s%M)))", data[0], data[1]);
}
else if (pkalgo == PUBKEY_ALGO_ELGAMAL || pkalgo == PUBKEY_ALGO_ELGAMAL_E)
{ {
if (!data[0] || !data[1]) if (!data[0] || !data[1])
rc = gpg_error (GPG_ERR_BAD_MPI); rc = gpg_error (GPG_ERR_BAD_MPI);
@ -149,7 +159,7 @@ pk_verify (int algo, gcry_mpi_t hash, gcry_mpi_t *data, gcry_mpi_t *pkey)
rc = gcry_sexp_build (&s_sig, NULL, rc = gcry_sexp_build (&s_sig, NULL,
"(sig-val(elg(r%m)(s%m)))", data[0], data[1]); "(sig-val(elg(r%m)(s%m)))", data[0], data[1]);
} }
else if (pkalgo == GCRY_PK_RSA || pkalgo == GCRY_PK_RSA_S) else if (pkalgo == PUBKEY_ALGO_RSA || pkalgo == PUBKEY_ALGO_RSA_S)
{ {
if (!data[0]) if (!data[0])
rc = gpg_error (GPG_ERR_BAD_MPI); rc = gpg_error (GPG_ERR_BAD_MPI);
@ -177,14 +187,14 @@ pk_verify (int algo, gcry_mpi_t hash, gcry_mpi_t *data, gcry_mpi_t *pkey)
* PK is only required to compute the fingerprint for ECDH. * PK is only required to compute the fingerprint for ECDH.
*/ */
int int
pk_encrypt (int algo, gcry_mpi_t *resarr, gcry_mpi_t data, pk_encrypt (pubkey_algo_t algo, gcry_mpi_t *resarr, gcry_mpi_t data,
PKT_public_key *pk, gcry_mpi_t *pkey) PKT_public_key *pk, gcry_mpi_t *pkey)
{ {
gcry_sexp_t s_ciph, s_data, s_pkey; gcry_sexp_t s_ciph, s_data, s_pkey;
int rc; int rc;
/* Make a sexp from pkey. */ /* Make a sexp from pkey. */
if (algo == GCRY_PK_ELG || algo == GCRY_PK_ELG_E) if (algo == PUBKEY_ALGO_ELGAMAL || algo == PUBKEY_ALGO_ELGAMAL_E)
{ {
rc = gcry_sexp_build (&s_pkey, NULL, rc = gcry_sexp_build (&s_pkey, NULL,
"(public-key(elg(p%m)(g%m)(y%m)))", "(public-key(elg(p%m)(g%m)(y%m)))",
@ -194,7 +204,7 @@ pk_encrypt (int algo, gcry_mpi_t *resarr, gcry_mpi_t data,
BUG (); BUG ();
} }
else if (algo == GCRY_PK_RSA || algo == GCRY_PK_RSA_E) else if (algo == PUBKEY_ALGO_RSA || algo == PUBKEY_ALGO_RSA_E)
{ {
rc = gcry_sexp_build (&s_pkey, NULL, rc = gcry_sexp_build (&s_pkey, NULL,
"(public-key(rsa(n%m)(e%m)))", "(public-key(rsa(n%m)(e%m)))",
@ -280,7 +290,7 @@ pk_encrypt (int algo, gcry_mpi_t *resarr, gcry_mpi_t data,
{ /* Fixme: Add better error handling or make gnupg use { /* Fixme: Add better error handling or make gnupg use
S-expressions directly. */ S-expressions directly. */
resarr[0] = get_mpi_from_sexp (s_ciph, "a", GCRYMPI_FMT_USG); resarr[0] = get_mpi_from_sexp (s_ciph, "a", GCRYMPI_FMT_USG);
if (algo != GCRY_PK_RSA && algo != GCRY_PK_RSA_E) if (!is_RSA (algo))
resarr[1] = get_mpi_from_sexp (s_ciph, "b", GCRYMPI_FMT_USG); resarr[1] = get_mpi_from_sexp (s_ciph, "b", GCRYMPI_FMT_USG);
} }
@ -291,53 +301,55 @@ pk_encrypt (int algo, gcry_mpi_t *resarr, gcry_mpi_t data,
/* Check whether SKEY is a suitable secret key. */ /* Check whether SKEY is a suitable secret key. */
int int
pk_check_secret_key (int algo, gcry_mpi_t *skey) pk_check_secret_key (pubkey_algo_t pkalgo, gcry_mpi_t *skey)
{ {
gcry_sexp_t s_skey; gcry_sexp_t s_skey;
int rc; int rc;
const int gcry_pkalgo = map_pk_openpgp_to_gcry( algo );
if (gcry_pkalgo == GCRY_PK_DSA) if (pkalgo == PUBKEY_ALGO_DSA)
{ {
rc = gcry_sexp_build (&s_skey, NULL, rc = gcry_sexp_build (&s_skey, NULL,
"(private-key(dsa(p%m)(q%m)(g%m)(y%m)(x%m)))", "(private-key(dsa(p%m)(q%m)(g%m)(y%m)(x%m)))",
skey[0], skey[1], skey[2], skey[3], skey[4]); skey[0], skey[1], skey[2], skey[3], skey[4]);
} }
else if (gcry_pkalgo == GCRY_PK_ELG || gcry_pkalgo == GCRY_PK_ELG_E) else if (pkalgo == PUBKEY_ALGO_ELGAMAL || pkalgo == PUBKEY_ALGO_ELGAMAL_E)
{ {
rc = gcry_sexp_build (&s_skey, NULL, rc = gcry_sexp_build (&s_skey, NULL,
"(private-key(elg(p%m)(g%m)(y%m)(x%m)))", "(private-key(elg(p%m)(g%m)(y%m)(x%m)))",
skey[0], skey[1], skey[2], skey[3]); skey[0], skey[1], skey[2], skey[3]);
} }
else if (gcry_pkalgo == GCRY_PK_RSA else if (is_RSA (pkalgo))
|| gcry_pkalgo == GCRY_PK_RSA_S || gcry_pkalgo == GCRY_PK_RSA_E)
{ {
rc = gcry_sexp_build (&s_skey, NULL, rc = gcry_sexp_build (&s_skey, NULL,
"(private-key(rsa(n%m)(e%m)(d%m)(p%m)(q%m)(u%m)))", "(private-key(rsa(n%m)(e%m)(d%m)(p%m)(q%m)(u%m)))",
skey[0], skey[1], skey[2], skey[3], skey[4], skey[0], skey[1], skey[2], skey[3], skey[4],
skey[5]); skey[5]);
} }
else if (gcry_pkalgo == GCRY_PK_ECDSA || gcry_pkalgo == GCRY_PK_ECDH) else if (pkalgo == PUBKEY_ALGO_ECDSA || pkalgo == PUBKEY_ALGO_ECDH)
{ {
if (openpgp_oid_is_ed25519 (skey[0])) char *curve = openpgp_oid_to_str (skey[0]);
{ if (!curve)
rc = gcry_sexp_build (&s_skey, NULL, rc = gpg_error_from_syserror ();
"(private-key(ecc(curve Ed25519)"
"(flags eddsa)(q%m)(d%m)))",
skey[1], skey[2]);
}
else else
{ {
char *curve = openpgp_oid_to_str (skey[0]); rc = gcry_sexp_build (&s_skey, NULL,
if (!curve) "(private-key(ecc(curve%s)(q%m)(d%m)))",
rc = gpg_error_from_syserror (); curve, skey[1], skey[2]);
else xfree (curve);
{ }
rc = gcry_sexp_build (&s_skey, NULL, }
"(private-key(ecdsa(curve%s)(q%m)(d%m)))", else if (pkalgo == PUBKEY_ALGO_EDDSA)
curve, skey[1], skey[2]); {
xfree (curve); char *curve = openpgp_oid_to_str (skey[0]);
} if (!curve)
rc = gpg_error_from_syserror ();
else
{
rc = gcry_sexp_build (&s_skey, NULL,
"(private-key(ecc(curve %s)"
"(flags eddsa)(q%m)(d%m)))",
curve, skey[1], skey[2]);
xfree (curve);
} }
} }
else else

View File

@ -25,11 +25,11 @@
/*-- pkglue.c --*/ /*-- pkglue.c --*/
gcry_mpi_t get_mpi_from_sexp (gcry_sexp_t sexp, const char *item, int mpifmt); gcry_mpi_t get_mpi_from_sexp (gcry_sexp_t sexp, const char *item, int mpifmt);
int pk_verify (int algo, gcry_mpi_t hash, gcry_mpi_t *data, int pk_verify (pubkey_algo_t algo, gcry_mpi_t hash, gcry_mpi_t *data,
gcry_mpi_t *pkey); gcry_mpi_t *pkey);
int pk_encrypt (int algo, gcry_mpi_t *resarr, gcry_mpi_t data, int pk_encrypt (pubkey_algo_t algo, gcry_mpi_t *resarr, gcry_mpi_t data,
PKT_public_key *pk, gcry_mpi_t *pkey); PKT_public_key *pk, gcry_mpi_t *pkey);
int pk_check_secret_key (int algo, gcry_mpi_t *skey); int pk_check_secret_key (pubkey_algo_t algo, gcry_mpi_t *skey);
/*-- ecdh.c --*/ /*-- ecdh.c --*/

View File

@ -151,7 +151,6 @@ get_it (PKT_pubkey_enc *enc, DEK *dek, PKT_public_key *sk, u32 *keyid)
char *keygrip; char *keygrip;
byte fp[MAX_FINGERPRINT_LEN]; byte fp[MAX_FINGERPRINT_LEN];
size_t fpn; size_t fpn;
const int pkalgo = map_pk_openpgp_to_gcry (sk->pubkey_algo);
if (DBG_CLOCK) if (DBG_CLOCK)
log_clock ("decryption start"); log_clock ("decryption start");
@ -162,7 +161,8 @@ get_it (PKT_pubkey_enc *enc, DEK *dek, PKT_public_key *sk, u32 *keyid)
goto leave; goto leave;
/* Convert the data to an S-expression. */ /* Convert the data to an S-expression. */
if (pkalgo == GCRY_PK_ELG || pkalgo == GCRY_PK_ELG_E) if (sk->pubkey_algo == PUBKEY_ALGO_ELGAMAL
|| sk->pubkey_algo == PUBKEY_ALGO_ELGAMAL_E)
{ {
if (!enc->data[0] || !enc->data[1]) if (!enc->data[0] || !enc->data[1])
err = gpg_error (GPG_ERR_BAD_MPI); err = gpg_error (GPG_ERR_BAD_MPI);
@ -170,7 +170,8 @@ get_it (PKT_pubkey_enc *enc, DEK *dek, PKT_public_key *sk, u32 *keyid)
err = gcry_sexp_build (&s_data, NULL, "(enc-val(elg(a%m)(b%m)))", err = gcry_sexp_build (&s_data, NULL, "(enc-val(elg(a%m)(b%m)))",
enc->data[0], enc->data[1]); enc->data[0], enc->data[1]);
} }
else if (pkalgo == GCRY_PK_RSA || pkalgo == GCRY_PK_RSA_E) else if (sk->pubkey_algo == PUBKEY_ALGO_RSA
|| sk->pubkey_algo == PUBKEY_ALGO_RSA_E)
{ {
if (!enc->data[0]) if (!enc->data[0])
err = gpg_error (GPG_ERR_BAD_MPI); err = gpg_error (GPG_ERR_BAD_MPI);
@ -178,7 +179,7 @@ get_it (PKT_pubkey_enc *enc, DEK *dek, PKT_public_key *sk, u32 *keyid)
err = gcry_sexp_build (&s_data, NULL, "(enc-val(rsa(a%m)))", err = gcry_sexp_build (&s_data, NULL, "(enc-val(rsa(a%m)))",
enc->data[0]); enc->data[0]);
} }
else if (pkalgo == GCRY_PK_ECDH) else if (sk->pubkey_algo == PUBKEY_ALGO_ECDH)
{ {
if (!enc->data[0] || !enc->data[1]) if (!enc->data[0] || !enc->data[1])
err = gpg_error (GPG_ERR_BAD_MPI); err = gpg_error (GPG_ERR_BAD_MPI);

View File

@ -255,20 +255,20 @@ gcry_mpi_t
encode_md_value (PKT_public_key *pk, gcry_md_hd_t md, int hash_algo) encode_md_value (PKT_public_key *pk, gcry_md_hd_t md, int hash_algo)
{ {
gcry_mpi_t frame; gcry_mpi_t frame;
int pkalgo;
size_t mdlen; size_t mdlen;
assert (hash_algo); assert (hash_algo);
assert (pk); assert (pk);
pkalgo = map_pk_openpgp_to_gcry (pk->pubkey_algo); if (pk->pubkey_algo == PUBKEY_ALGO_EDDSA)
if (pkalgo == GCRY_PK_ECDSA && openpgp_oid_is_ed25519 (pk->pkey[0]))
{ {
/* EdDSA signs data of arbitrary length. Thus no special
treatment is required. */
frame = gcry_mpi_set_opaque_copy (NULL, gcry_md_read (md, hash_algo), frame = gcry_mpi_set_opaque_copy (NULL, gcry_md_read (md, hash_algo),
8*gcry_md_get_algo_dlen (hash_algo)); 8*gcry_md_get_algo_dlen (hash_algo));
} }
else if (pkalgo == GCRY_PK_DSA || pkalgo == GCRY_PK_ECDSA) else if (pk->pubkey_algo == PUBKEY_ALGO_DSA
|| pk->pubkey_algo == PUBKEY_ALGO_ECDSA)
{ {
/* It's a DSA signature, so find out the size of q. */ /* It's a DSA signature, so find out the size of q. */
@ -276,11 +276,10 @@ encode_md_value (PKT_public_key *pk, gcry_md_hd_t md, int hash_algo)
/* pkey[1] is Q for ECDSA, which is an uncompressed point, /* pkey[1] is Q for ECDSA, which is an uncompressed point,
i.e. 04 <x> <y> */ i.e. 04 <x> <y> */
if (pkalgo == GCRY_PK_ECDSA) if (pk->pubkey_algo == PUBKEY_ALGO_ECDSA)
qbits = ecdsa_qbits_from_Q (qbits); qbits = ecdsa_qbits_from_Q (qbits);
/* Make sure it is a multiple of 8 bits. */ /* Make sure it is a multiple of 8 bits. */
if ((qbits%8)) if ((qbits%8))
{ {
log_error(_("DSA requires the hash length to be a" log_error(_("DSA requires the hash length to be a"
@ -297,7 +296,8 @@ encode_md_value (PKT_public_key *pk, gcry_md_hd_t md, int hash_algo)
if (qbits < 160) if (qbits < 160)
{ {
log_error (_("%s key %s uses an unsafe (%zu bit) hash\n"), log_error (_("%s key %s uses an unsafe (%zu bit) hash\n"),
gcry_pk_algo_name (pkalgo), keystr_from_pk (pk), qbits); openpgp_pk_algo_name (pk->pubkey_algo),
keystr_from_pk (pk), qbits);
return NULL; return NULL;
} }
@ -305,7 +305,7 @@ encode_md_value (PKT_public_key *pk, gcry_md_hd_t md, int hash_algo)
/* ECDSA 521 is special has it is larger than the largest hash /* ECDSA 521 is special has it is larger than the largest hash
we have (SHA-512). Thus we chnage the size for further we have (SHA-512). Thus we chnage the size for further
processing to 512. */ processing to 512. */
if (pkalgo == GCRY_PK_ECDSA && qbits > 512) if (pk->pubkey_algo == PUBKEY_ALGO_ECDSA && qbits > 512)
qbits = 512; qbits = 512;
/* Check if we're too short. Too long is safe as we'll /* Check if we're too short. Too long is safe as we'll
@ -315,8 +315,8 @@ encode_md_value (PKT_public_key *pk, gcry_md_hd_t md, int hash_algo)
{ {
log_error (_("%s key %s requires a %zu bit or larger hash " log_error (_("%s key %s requires a %zu bit or larger hash "
"(hash is %s)\n"), "(hash is %s)\n"),
gcry_pk_algo_name (pkalgo), openpgp_pk_algo_name (pk->pubkey_algo),
keystr_from_pk(pk), qbits, keystr_from_pk (pk), qbits,
gcry_md_algo_name (hash_algo)); gcry_md_algo_name (hash_algo));
return NULL; return NULL;
} }

View File

@ -446,7 +446,7 @@ hash_for (PKT_public_key *pk)
{ {
return recipient_digest_algo; return recipient_digest_algo;
} }
else if (pk->pubkey_algo == PUBKEY_ALGO_ECDSA else if (pk->pubkey_algo == PUBKEY_ALGO_EDDSA
&& openpgp_oid_is_ed25519 (pk->pkey[0])) && openpgp_oid_is_ed25519 (pk->pkey[0]))
{ {
if (opt.personal_digest_prefs) if (opt.personal_digest_prefs)
@ -944,13 +944,13 @@ sign_file (ctrl_t ctrl, strlist_t filenames, int detached, strlist_t locusr,
for (sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) for (sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next )
{ {
if (sk_rover->pk->pubkey_algo == PUBKEY_ALGO_DSA if (sk_rover->pk->pubkey_algo == PUBKEY_ALGO_DSA
|| (sk_rover->pk->pubkey_algo == PUBKEY_ALGO_ECDSA || (sk_rover->pk->pubkey_algo == PUBKEY_ALGO_EDDSA
&& !openpgp_oid_is_ed25519 (sk_rover->pk->pkey[1]))) && !openpgp_oid_is_ed25519 (sk_rover->pk->pkey[1])))
{ {
int temp_hashlen = (gcry_mpi_get_nbits int temp_hashlen = (gcry_mpi_get_nbits
(sk_rover->pk->pkey[1])); (sk_rover->pk->pkey[1]));
if (sk_rover->pk->pubkey_algo == PUBKEY_ALGO_ECDSA) if (sk_rover->pk->pubkey_algo == PUBKEY_ALGO_EDDSA)
temp_hashlen = ecdsa_qbits_from_Q (temp_hashlen); temp_hashlen = ecdsa_qbits_from_Q (temp_hashlen);
temp_hashlen = (temp_hashlen+7)/8; temp_hashlen = (temp_hashlen+7)/8;
@ -1510,7 +1510,8 @@ make_keysig_packet( PKT_signature **ret_sig, PKT_public_key *pk,
digest_algo = DIGEST_ALGO_MD5; digest_algo = DIGEST_ALGO_MD5;
else if(pksk->pubkey_algo == PUBKEY_ALGO_DSA) else if(pksk->pubkey_algo == PUBKEY_ALGO_DSA)
digest_algo = match_dsa_hash (gcry_mpi_get_nbits (pksk->pkey[1])/8); digest_algo = match_dsa_hash (gcry_mpi_get_nbits (pksk->pkey[1])/8);
else if(pksk->pubkey_algo == PUBKEY_ALGO_ECDSA ) else if (pksk->pubkey_algo == PUBKEY_ALGO_ECDSA
|| pksk->pubkey_algo == PUBKEY_ALGO_EDDSA)
{ {
if (openpgp_oid_is_ed25519 (pksk->pkey[0])) if (openpgp_oid_is_ed25519 (pksk->pkey[0]))
digest_algo = DIGEST_ALGO_SHA256; digest_algo = DIGEST_ALGO_SHA256;

View File

@ -95,7 +95,7 @@ check_keygrip (ctrl_t ctrl, const char *hexgrip)
gpg_error_t err; gpg_error_t err;
ksba_sexp_t public; ksba_sexp_t public;
size_t publiclen; size_t publiclen;
int algo; const char *algostr;
if (hexgrip[0] == '&') if (hexgrip[0] == '&')
hexgrip++; hexgrip++;
@ -105,17 +105,21 @@ check_keygrip (ctrl_t ctrl, const char *hexgrip)
return NULL; return NULL;
publiclen = gcry_sexp_canon_len (public, 0, NULL, NULL); publiclen = gcry_sexp_canon_len (public, 0, NULL, NULL);
get_pk_algo_from_canon_sexp (public, publiclen, &algo); get_pk_algo_from_canon_sexp (public, publiclen, &algostr);
xfree (public); xfree (public);
switch (algo) if (!algostr)
{ return NULL;
case GCRY_PK_RSA: return "RSA"; else if (!strcmp (algostr, "rsa"))
case GCRY_PK_DSA: return "DSA"; return "RSA";
case GCRY_PK_ELG: return "ELG"; else if (!strcmp (algostr, "dsa"))
case GCRY_PK_ECDSA: return "ECDSA"; return "DSA";
default: return NULL; else if (!strcmp (algostr, "elg"))
} return "ELG";
else if (!strcmp (algostr, "ecdsa"))
return "ECDSA";
else
return NULL;
} }