From b7f8dec6325f1c80640f878ed3080bbc194fbc78 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 30 Jan 2014 18:48:37 +0100 Subject: [PATCH] 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 --- agent/pksign.c | 5 +- common/sexputil.c | 19 ++-- common/util.h | 2 +- g10/build-packet.c | 5 +- g10/export.c | 4 +- g10/getkey.c | 1 + g10/import.c | 3 +- g10/keygen.c | 86 +++++++++++++----- g10/keyid.c | 2 + g10/keylist.c | 4 + g10/keyserver.c | 2 +- g10/main.h | 15 ++-- g10/mainproc.c | 1 + g10/misc.c | 218 ++++++++++++++++++++++----------------------- g10/parse-packet.c | 7 +- g10/pkglue.c | 132 ++++++++++++++------------- g10/pkglue.h | 6 +- g10/pubkey-enc.c | 9 +- g10/seskey.c | 22 ++--- g10/sign.c | 9 +- sm/certreqgen-ui.c | 24 ++--- 21 files changed, 323 insertions(+), 253 deletions(-) diff --git a/agent/pksign.c b/agent/pksign.c index b2ee28f22..4d0a240e9 100644 --- a/agent/pksign.c +++ b/agent/pksign.c @@ -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. */ 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) { gpg_error_t err; gcry_sexp_t hash; unsigned int qbits; - int pkalgo; *r_hash = NULL; - pkalgo = map_pk_openpgp_to_gcry (dsaalgo); - if (pkalgo == GCRY_PK_ECDSA) qbits = gcry_pk_get_nbits (pkey); else if (pkalgo == GCRY_PK_DSA) diff --git a/common/sexputil.c b/common/sexputil.c index e18756a89..f15b94c66 100644 --- a/common/sexputil.c +++ b/common/sexputil.c @@ -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 - 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 get_pk_algo_from_canon_sexp (const unsigned char *keydata, size_t keydatalen, - int *r_algo) + const char **r_algo) { gpg_error_t err; const unsigned char *buf, *tok; size_t buflen, toklen; int depth; - *r_algo = 0; + *r_algo = NULL; buf = keydata; 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); if (toklen == 3 && !memcmp ("rsa", tok, toklen)) - *r_algo = GCRY_PK_RSA; + *r_algo = "rsa"; else if (toklen == 3 && !memcmp ("dsa", tok, toklen)) - *r_algo = GCRY_PK_DSA; + *r_algo = "dsa"; else if (toklen == 3 && !memcmp ("elg", tok, toklen)) - *r_algo = GCRY_PK_ELG; + *r_algo = "elg"; 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 - return gpg_error (GPG_ERR_PUBKEY_ALGO); + return gpg_error (GPG_ERR_PUBKEY_ALGO); return 0; } diff --git a/common/util.h b/common/util.h index f93888837..c4acb0bd3 100644 --- a/common/util.h +++ b/common/util.h @@ -193,7 +193,7 @@ gpg_error_t get_rsa_pk_from_canon_sexp (const unsigned char *keydata, size_t *r_elen); gpg_error_t get_pk_algo_from_canon_sexp (const unsigned char *keydata, size_t keydatalen, - int *r_algo); + const char **r_algo); /*-- convert.c --*/ int hex2bin (const char *string, void *buffer, size_t length); diff --git a/g10/build-packet.c b/g10/build-packet.c index f31ca888f..7464979cf 100644 --- a/g10/build-packet.c +++ b/g10/build-packet.c @@ -329,8 +329,9 @@ do_key (iobuf_t out, int ctb, PKT_public_key *pk) for (i=0; i < npkey; i++ ) { - if ((pk->pubkey_algo == PUBKEY_ALGO_ECDSA && (i == 0)) - || ((pk->pubkey_algo == PUBKEY_ALGO_ECDH) && (i == 0 || i == 2))) + if ( (pk->pubkey_algo == PUBKEY_ALGO_ECDSA && (i == 0)) + || (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]); else err = gpg_mpi_write (a, pk->pkey[i]); diff --git a/g10/export.c b/g10/export.c index 01bdd5e82..a7d1cf873 100644 --- a/g10/export.c +++ b/g10/export.c @@ -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. The transfer format has all parameters but OpenPGP defines that 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; const char *curvename, *curveoidstr; diff --git a/g10/getkey.c b/g10/getkey.c index 4453a92d5..9cad71b37 100644 --- a/g10/getkey.c +++ b/g10/getkey.c @@ -140,6 +140,7 @@ cache_public_key (PKT_public_key * pk) if (is_ELGAMAL (pk->pubkey_algo) || pk->pubkey_algo == PUBKEY_ALGO_DSA || pk->pubkey_algo == PUBKEY_ALGO_ECDSA + || pk->pubkey_algo == PUBKEY_ALGO_EDDSA || pk->pubkey_algo == PUBKEY_ALGO_ECDH || is_RSA (pk->pubkey_algo)) { diff --git a/g10/import.c b/g10/import.c index 3846c213f..7ba7303b7 100644 --- a/g10/import.c +++ b/g10/import.c @@ -1260,6 +1260,7 @@ transfer_secret_keys (ctrl_t ctrl, struct stats_s *stats, kbnode_t sec_keyblock) init_membuf (&mbuf, 50); put_membuf_str (&mbuf, "(skey"); if (pk->pubkey_algo == PUBKEY_ALGO_ECDSA + || pk->pubkey_algo == PUBKEY_ALGO_EDDSA || pk->pubkey_algo == PUBKEY_ALGO_ECDH) { /* 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 (); 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); if (!cparam) diff --git a/g10/keygen.c b/g10/keygen.c index bbd02c517..50919fdaf 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -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_ECDH: case PUBKEY_ALGO_ECDSA: algoelem = ""; break; + case PUBKEY_ALGO_EDDSA: algoelem = ""; break; 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->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); else 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->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); else 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; 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) return gpg_error (GPG_ERR_UNKNOWN_CURVE); @@ -1735,7 +1742,7 @@ check_keygrip (ctrl_t ctrl, const char *hexgrip) gpg_error_t err; unsigned char *public; size_t publiclen; - int algo; + const char *algostr; if (hexgrip[0] == '&') hexgrip++; @@ -1745,18 +1752,26 @@ check_keygrip (ctrl_t ctrl, const char *hexgrip) return 0; 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); - switch (algo) - { - case GCRY_PK_RSA: return PUBKEY_ALGO_RSA; - case GCRY_PK_DSA: return PUBKEY_ALGO_DSA; - case GCRY_PK_ELG_E: return PUBKEY_ALGO_ELGAMAL_E; - case GCRY_PK_ECDH: return PUBKEY_ALGO_ECDH; - case GCRY_PK_ECDSA: return PUBKEY_ALGO_ECDSA; - default: return 0; - } + /* FIXME: Mapping of ECC algorithms is probably not correct. */ + if (!algostr) + return 0; + else if (!strcmp (algostr, "rsa")) + return PUBKEY_ALGO_RSA; + else if (!strcmp (algostr, "dsa")) + return PUBKEY_ALGO_DSA; + 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) - tty_printf (_(" (%d) ECDSA and ECDH\n"), 9 ); + tty_printf (_(" (%d) ECC\n"), 9 ); if (opt.expert) - tty_printf (_(" (%d) ECDSA (sign only)\n"), 10 ); + tty_printf (_(" (%d) ECC (sign only)\n"), 10 ); 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) - tty_printf (_(" (%d) ECDH (encrypt only)\n"), 12 ); + tty_printf (_(" (%d) ECC (encrypt only)\n"), 12 ); if (opt.expert && r_keygrip) tty_printf (_(" (%d) Existing key\n"), 13 ); @@ -1978,6 +1993,12 @@ ask_keysize (int algo, unsigned int primary_keysize) max=521; break; + case PUBKEY_ALGO_EDDSA: + min=255; + def=255; + max=441; + break; + case PUBKEY_ALGO_RSA: min=1024; break; @@ -2017,6 +2038,18 @@ ask_keysize (int algo, unsigned int primary_keysize) if (!autocomp) 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) { 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) err = gen_dsa (nbits, pub_root, timestamp, expiredate, is_subkey, 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, keygen_flags, cache_nonce_addr); 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 ); r->next = para; 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 (); + nbits = 0; r = xmalloc_clear (sizeof *r + strlen (curve)); r->key = pKEYCURVE; strcpy (r->u.value, curve); @@ -3467,7 +3505,9 @@ generate_keypair (ctrl_t ctrl, const char *fname, const char *card_serialno, 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) curve = ask_curve (); @@ -3969,7 +4009,9 @@ generate_subkeypair (ctrl_t ctrl, kbnode_t keyblock) if (hexgrip) 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 (); else nbits = ask_keysize (algo, 0); diff --git a/g10/keyid.c b/g10/keyid.c index d08cceeb2..5fa44ef9c 100644 --- a/g10/keyid.c +++ b/g10/keyid.c @@ -57,6 +57,7 @@ pubkey_letter( int algo ) case PUBKEY_ALGO_ELGAMAL_E: return 'g' ; case PUBKEY_ALGO_ELGAMAL: return 'G' ; 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_ECDH: return 'e' ; /* ECC DH (encrypt only) */ default: return '?'; @@ -733,6 +734,7 @@ keygrip_from_pk (PKT_public_key *pk, unsigned char *array) pk->pkey[0], pk->pkey[1]); break; + case PUBKEY_ALGO_EDDSA: case PUBKEY_ALGO_ECDSA: case PUBKEY_ALGO_ECDH: { diff --git a/g10/keylist.c b/g10/keylist.c index 356fac320..9a96c872e 100644 --- a/g10/keylist.c +++ b/g10/keylist.c @@ -818,6 +818,7 @@ list_keyblock_print (KBNODE keyblock, int secret, int fpr, void *opaque) keystr_from_pk (pk), datestr_from_pk (pk)); if (pk->pubkey_algo == PUBKEY_ALGO_ECDSA + || pk->pubkey_algo == PUBKEY_ALGO_EDDSA || pk->pubkey_algo == PUBKEY_ALGO_ECDH) { 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)); if (pk2->pubkey_algo == PUBKEY_ALGO_ECDSA + || pk2->pubkey_algo == PUBKEY_ALGO_EDDSA || pk2->pubkey_algo == PUBKEY_ALGO_ECDH) { 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 16. */ if (pk->pubkey_algo == PUBKEY_ALGO_ECDSA + || pk->pubkey_algo == PUBKEY_ALGO_EDDSA || pk->pubkey_algo == PUBKEY_ALGO_ECDH) { 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 16. */ if (pk->pubkey_algo == PUBKEY_ALGO_ECDSA + || pk->pubkey_algo == PUBKEY_ALGO_EDDSA || pk->pubkey_algo == PUBKEY_ALGO_ECDH) { char *curve = openpgp_oid_to_str (pk->pkey[0]); diff --git a/g10/keyserver.c b/g10/keyserver.c index 0ec616bc0..0f60f7d37 100644 --- a/g10/keyserver.c +++ b/g10/keyserver.c @@ -508,7 +508,7 @@ print_keyrec(int number,struct keyrec *keyrec) { 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, "?")) es_printf ("%s ",str); diff --git a/g10/main.h b/g10/main.h index 4d3ab1b32..26283a783 100644 --- a/g10/main.h +++ b/g10/main.h @@ -100,13 +100,12 @@ int map_cipher_openpgp_to_gcry (int algo); int openpgp_cipher_blocklen (int algo); int openpgp_cipher_test_algo( 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 openpgp_pk_test_algo( int algo ); -int openpgp_pk_test_algo2 ( int algo, unsigned int use ); +int openpgp_pk_test_algo (pubkey_algo_t algo); +int openpgp_pk_test_algo2 (pubkey_algo_t algo, unsigned int use); int openpgp_pk_algo_usage ( 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); struct expando_args @@ -153,10 +152,10 @@ int is_valid_mailbox (const char *name); const char *get_libexecdir (void); int path_access(const char *file,int mode); -int pubkey_get_npkey( int algo ); -int pubkey_get_nskey( int algo ); -int pubkey_get_nsig( int algo ); -int pubkey_get_nenc( int algo ); +int pubkey_get_npkey (pubkey_algo_t algo); +int pubkey_get_nskey (pubkey_algo_t algo); +int pubkey_get_nsig (pubkey_algo_t algo); +int pubkey_get_nenc (pubkey_algo_t algo); /* Temporary helpers. */ unsigned int pubkey_nbits( int algo, gcry_mpi_t *pkey ); diff --git a/g10/mainproc.c b/g10/mainproc.c index d8606cdf5..5f8d1197b 100644 --- a/g10/mainproc.c +++ b/g10/mainproc.c @@ -389,6 +389,7 @@ proc_pubkey_enc( CTX c, PACKET *pkt ) else if( is_ELGAMAL(enc->pubkey_algo) || enc->pubkey_algo == PUBKEY_ALGO_DSA || enc->pubkey_algo == PUBKEY_ALGO_ECDSA + || enc->pubkey_algo == PUBKEY_ALGO_EDDSA || enc->pubkey_algo == PUBKEY_ALGO_ECDH || is_RSA(enc->pubkey_algo) || enc->pubkey_algo == PUBKEY_ALGO_ELGAMAL) { diff --git a/g10/misc.c b/g10/misc.c index 9f6ff1e6b..1ac5430a2 100644 --- a/g10/misc.c +++ b/g10/misc.c @@ -366,21 +366,9 @@ map_cipher_gcry_to_openpgp (int algo) } } -/* Map OpenPGP public key algorithm numbers to those used by - Libgcrypt. */ -int -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. */ +/* Map Gcrypt public key algorithm numbers to those used by OpenPGP. + FIXME: This mapping is used at only two places - we should get rid + of it. */ int 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 0 if ALGO is a supported OpenPGP public key algorithm. */ 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. */ - 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 openpgp_pk_test_algo2 (algo, 0); } + +/* Return 0 if ALGO is a supported OpenPGP public key algorithm and + allows the usage USE. */ 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; - /* Dont't allow type 20 keys unless in rfc2440 mode. */ - if (!RFC2440 && algo == 20) + switch (algo) + { + 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); - 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_algo_info (map_pk_openpgp_to_gcry (algo), - GCRYCTL_TEST_ALGO, NULL, &use_buf); + /* No check whether Libgcrypt has support for the algorithm. */ + return gcry_pk_algo_info (ga, GCRYCTL_TEST_ALGO, NULL, &use_buf); } + int 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; break; case PUBKEY_ALGO_ECDSA: + case PUBKEY_ALGO_EDDSA: use = PUBKEY_USAGE_CERT | PUBKEY_USAGE_SIG | PUBKEY_USAGE_AUTH; default: break; @@ -514,9 +511,21 @@ openpgp_pk_algo_usage ( int algo ) string representation of the algorithm name. For unknown algorithm IDs this function returns "?". */ 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. */ int -pubkey_get_npkey (int algo) +pubkey_get_npkey (pubkey_algo_t algo) { - size_t n; - - /* ECC is special. */ - if (algo == PUBKEY_ALGO_ECDSA) - return 2; - else if (algo == PUBKEY_ALGO_ECDH) - return 3; - - /* All other algorithms match those of Libgcrypt. */ - if (algo == GCRY_PK_ELG_E) - algo = GCRY_PK_ELG; - else if (is_RSA (algo)) - algo = GCRY_PK_RSA; - - if (gcry_pk_algo_info (algo, GCRYCTL_GET_ALGO_NPKEY, NULL, &n)) - n = 0; - return n; + switch (algo) + { + case PUBKEY_ALGO_RSA: + case PUBKEY_ALGO_RSA_E: + case PUBKEY_ALGO_RSA_S: return 2; + case PUBKEY_ALGO_ELGAMAL_E: return 3; + case PUBKEY_ALGO_DSA: return 4; + case PUBKEY_ALGO_ECDH: return 3; + case PUBKEY_ALGO_ECDSA: return 2; + case PUBKEY_ALGO_ELGAMAL: return 3; + case PUBKEY_ALGO_EDDSA: return 2; + } + return 0; } /* Return the number of secret key parameters as used by OpenPGP. */ int -pubkey_get_nskey (int algo) +pubkey_get_nskey (pubkey_algo_t algo) { - size_t n; - - /* ECC is special. */ - if (algo == PUBKEY_ALGO_ECDSA) - return 3; - else if (algo == PUBKEY_ALGO_ECDH) - return 4; - - /* All other algorithms match those of Libgcrypt. */ - if (algo == GCRY_PK_ELG_E) - algo = GCRY_PK_ELG; - else if (is_RSA (algo)) - algo = GCRY_PK_RSA; - - if (gcry_pk_algo_info( algo, GCRYCTL_GET_ALGO_NSKEY, NULL, &n )) - n = 0; - return n; + switch (algo) + { + case PUBKEY_ALGO_RSA: + case PUBKEY_ALGO_RSA_E: + case PUBKEY_ALGO_RSA_S: return 6; + case PUBKEY_ALGO_ELGAMAL_E: return 4; + case PUBKEY_ALGO_DSA: return 5; + case PUBKEY_ALGO_ECDH: return 4; + case PUBKEY_ALGO_ECDSA: return 3; + case PUBKEY_ALGO_ELGAMAL: return 4; + case PUBKEY_ALGO_EDDSA: return 3; + } + return 0; } /* Temporary helper. */ int -pubkey_get_nsig (int algo) +pubkey_get_nsig (pubkey_algo_t algo) { - size_t n; - - /* ECC is special. */ - if (algo == PUBKEY_ALGO_ECDSA) - return 2; - else if (algo == PUBKEY_ALGO_ECDH) - return 0; - - if (algo == GCRY_PK_ELG_E) - algo = GCRY_PK_ELG; - else if (is_RSA (algo)) - algo = GCRY_PK_RSA; - - if (gcry_pk_algo_info( algo, GCRYCTL_GET_ALGO_NSIGN, NULL, &n)) - n = 0; - return n; + switch (algo) + { + case PUBKEY_ALGO_RSA: + case PUBKEY_ALGO_RSA_E: + case PUBKEY_ALGO_RSA_S: return 1; + case PUBKEY_ALGO_ELGAMAL_E: return 0; + case PUBKEY_ALGO_DSA: return 2; + case PUBKEY_ALGO_ECDH: return 0; + case PUBKEY_ALGO_ECDSA: return 2; + case PUBKEY_ALGO_ELGAMAL: return 2; + case PUBKEY_ALGO_EDDSA: return 2; + } + return 0; } /* Temporary helper. */ int -pubkey_get_nenc (int algo) +pubkey_get_nenc (pubkey_algo_t algo) { - size_t n; - - /* ECC is special. */ - if (algo == PUBKEY_ALGO_ECDSA) - return 0; - else if (algo == PUBKEY_ALGO_ECDH) - return 2; - - if (algo == GCRY_PK_ELG_E) - algo = GCRY_PK_ELG; - else if (is_RSA (algo)) - algo = GCRY_PK_RSA; - - if (gcry_pk_algo_info( algo, GCRYCTL_GET_ALGO_NENCR, NULL, &n )) - n = 0; - return n; + switch (algo) + { + case PUBKEY_ALGO_RSA: + case PUBKEY_ALGO_RSA_E: + case PUBKEY_ALGO_RSA_S: return 1; + case PUBKEY_ALGO_ELGAMAL_E: return 2; + case PUBKEY_ALGO_DSA: return 0; + case PUBKEY_ALGO_ECDH: return 2; + case PUBKEY_ALGO_ECDSA: return 0; + case PUBKEY_ALGO_ELGAMAL: return 2; + case PUBKEY_ALGO_EDDSA: return 0; + } + return 0; } @@ -1459,7 +1454,8 @@ pubkey_nbits( int algo, gcry_mpi_t *key ) "(public-key(rsa(n%m)(e%m)))", 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]); if (!curve) rc = gpg_error_from_syserror (); diff --git a/g10/parse-packet.c b/g10/parse-packet.c index 32fbbd60d..f70878846 100644 --- a/g10/parse-packet.c +++ b/g10/parse-packet.c @@ -1989,9 +1989,11 @@ parse_key (IOBUF inp, int pkttype, unsigned long pktlen, { for (i = 0; i < npkey; i++) { - if ((algorithm == PUBKEY_ALGO_ECDSA && (i == 0)) - || ((algorithm == PUBKEY_ALGO_ECDH) && (i == 0 || i == 2))) + if ( (algorithm == PUBKEY_ALGO_ECDSA && (i == 0)) + || (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; err = read_size_body (inp, pktlen, &n, pk->pkey+i); pktlen -= n; @@ -2011,6 +2013,7 @@ parse_key (IOBUF inp, int pkttype, unsigned long pktlen, es_fprintf (listfp, "\tpkey[%d]: ", i); mpi_print (listfp, pk->pkey[i], mpi_print_mode); if ((algorithm == PUBKEY_ALGO_ECDSA + || algorithm == PUBKEY_ALGO_EDDSA || algorithm == PUBKEY_ALGO_ECDH) && i==0) { char *curve = openpgp_oid_to_str (pk->pkey[0]); diff --git a/g10/pkglue.c b/g10/pkglue.c index 7e50a1c3d..67d2efd39 100644 --- a/g10/pkglue.c +++ b/g10/pkglue.c @@ -1,5 +1,6 @@ /* 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. * @@ -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. */ 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; int rc; - const int pkalgo = map_pk_openpgp_to_gcry (algo); - int is_ed25519 = 0; /* Make a sexp from pkey. */ - if (pkalgo == GCRY_PK_DSA) + if (pkalgo == PUBKEY_ALGO_DSA) { rc = gcry_sexp_build (&s_pkey, NULL, "(public-key(dsa(p%m)(q%m)(g%m)(y%m)))", 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, "(public-key(elg(p%m)(g%m)(y%m)))", 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, "(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]); - if (is_ed25519) - rc = gcry_sexp_build (&s_pkey, NULL, - "(public-key(ecc(curve Ed25519)" - "(flags eddsa)(q%m)))", - pkey[1]); + char *curve = openpgp_oid_to_str (pkey[0]); + if (!curve) + rc = gpg_error_from_syserror (); else { - 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(ecdsa(curve %s)(q%m)))", - curve, pkey[1]); - xfree (curve); - } + rc = gcry_sexp_build (&s_pkey, NULL, + "(public-key(ecdsa(curve %s)(q%m)))", + curve, pkey[1]); + xfree (curve); + } + } + else if (pkalgo == PUBKEY_ALGO_EDDSA) + { + 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 @@ -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. */ /* Put hash into a S-Exp s_hash. */ - if (is_ed25519) + if (pkalgo == PUBKEY_ALGO_EDDSA) { if (gcry_sexp_build (&s_hash, NULL, "(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. */ s_sig = NULL; - if (pkalgo == GCRY_PK_DSA) + if (pkalgo == PUBKEY_ALGO_DSA) { if (!data[0] || !data[1]) 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, "(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]) 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 rc = gcry_sexp_build (&s_sig, NULL, "(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]) 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, "(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]) 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. */ 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) { gcry_sexp_t s_ciph, s_data, s_pkey; int rc; /* 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, "(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 (); } - 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, "(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 S-expressions directly. */ 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); } @@ -291,53 +301,55 @@ pk_encrypt (int algo, gcry_mpi_t *resarr, gcry_mpi_t data, /* Check whether SKEY is a suitable secret key. */ 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; 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, "(private-key(dsa(p%m)(q%m)(g%m)(y%m)(x%m)))", 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, "(private-key(elg(p%m)(g%m)(y%m)(x%m)))", skey[0], skey[1], skey[2], skey[3]); } - else if (gcry_pkalgo == GCRY_PK_RSA - || gcry_pkalgo == GCRY_PK_RSA_S || gcry_pkalgo == GCRY_PK_RSA_E) + else if (is_RSA (pkalgo)) { rc = gcry_sexp_build (&s_skey, NULL, "(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[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])) - { - rc = gcry_sexp_build (&s_skey, NULL, - "(private-key(ecc(curve Ed25519)" - "(flags eddsa)(q%m)(d%m)))", - skey[1], skey[2]); - } + char *curve = openpgp_oid_to_str (skey[0]); + if (!curve) + rc = gpg_error_from_syserror (); else { - 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(ecdsa(curve%s)(q%m)(d%m)))", - curve, skey[1], skey[2]); - xfree (curve); - } + rc = gcry_sexp_build (&s_skey, NULL, + "(private-key(ecc(curve%s)(q%m)(d%m)))", + curve, skey[1], skey[2]); + xfree (curve); + } + } + else if (pkalgo == PUBKEY_ALGO_EDDSA) + { + 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 diff --git a/g10/pkglue.h b/g10/pkglue.h index 48bfbb5e0..ba1097c2e 100644 --- a/g10/pkglue.h +++ b/g10/pkglue.h @@ -25,11 +25,11 @@ /*-- pkglue.c --*/ 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); -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); -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 --*/ diff --git a/g10/pubkey-enc.c b/g10/pubkey-enc.c index ab18ed716..042a25598 100644 --- a/g10/pubkey-enc.c +++ b/g10/pubkey-enc.c @@ -151,7 +151,6 @@ get_it (PKT_pubkey_enc *enc, DEK *dek, PKT_public_key *sk, u32 *keyid) char *keygrip; byte fp[MAX_FINGERPRINT_LEN]; size_t fpn; - const int pkalgo = map_pk_openpgp_to_gcry (sk->pubkey_algo); if (DBG_CLOCK) log_clock ("decryption start"); @@ -162,7 +161,8 @@ get_it (PKT_pubkey_enc *enc, DEK *dek, PKT_public_key *sk, u32 *keyid) goto leave; /* 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]) 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)))", 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]) 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)))", enc->data[0]); } - else if (pkalgo == GCRY_PK_ECDH) + else if (sk->pubkey_algo == PUBKEY_ALGO_ECDH) { if (!enc->data[0] || !enc->data[1]) err = gpg_error (GPG_ERR_BAD_MPI); diff --git a/g10/seskey.c b/g10/seskey.c index 7d0429278..410f0bfa6 100644 --- a/g10/seskey.c +++ b/g10/seskey.c @@ -255,20 +255,20 @@ gcry_mpi_t encode_md_value (PKT_public_key *pk, gcry_md_hd_t md, int hash_algo) { gcry_mpi_t frame; - int pkalgo; size_t mdlen; assert (hash_algo); assert (pk); - pkalgo = map_pk_openpgp_to_gcry (pk->pubkey_algo); - - if (pkalgo == GCRY_PK_ECDSA && openpgp_oid_is_ed25519 (pk->pkey[0])) + if (pk->pubkey_algo == PUBKEY_ALGO_EDDSA) { + /* 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), 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. */ @@ -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, i.e. 04 */ - if (pkalgo == GCRY_PK_ECDSA) + if (pk->pubkey_algo == PUBKEY_ALGO_ECDSA) qbits = ecdsa_qbits_from_Q (qbits); /* Make sure it is a multiple of 8 bits. */ - if ((qbits%8)) { 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) { 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; } @@ -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 we have (SHA-512). Thus we chnage the size for further processing to 512. */ - if (pkalgo == GCRY_PK_ECDSA && qbits > 512) + if (pk->pubkey_algo == PUBKEY_ALGO_ECDSA && qbits > 512) qbits = 512; /* 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 " "(hash is %s)\n"), - gcry_pk_algo_name (pkalgo), - keystr_from_pk(pk), qbits, + openpgp_pk_algo_name (pk->pubkey_algo), + keystr_from_pk (pk), qbits, gcry_md_algo_name (hash_algo)); return NULL; } diff --git a/g10/sign.c b/g10/sign.c index e4d329067..098655dce 100644 --- a/g10/sign.c +++ b/g10/sign.c @@ -446,7 +446,7 @@ hash_for (PKT_public_key *pk) { 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])) { 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 ) { 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]))) { int temp_hashlen = (gcry_mpi_get_nbits (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 = (temp_hashlen+7)/8; @@ -1510,7 +1510,8 @@ make_keysig_packet( PKT_signature **ret_sig, PKT_public_key *pk, digest_algo = DIGEST_ALGO_MD5; else if(pksk->pubkey_algo == PUBKEY_ALGO_DSA) 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])) digest_algo = DIGEST_ALGO_SHA256; diff --git a/sm/certreqgen-ui.c b/sm/certreqgen-ui.c index 1035404cd..368dc5567 100644 --- a/sm/certreqgen-ui.c +++ b/sm/certreqgen-ui.c @@ -95,7 +95,7 @@ check_keygrip (ctrl_t ctrl, const char *hexgrip) gpg_error_t err; ksba_sexp_t public; size_t publiclen; - int algo; + const char *algostr; if (hexgrip[0] == '&') hexgrip++; @@ -105,17 +105,21 @@ check_keygrip (ctrl_t ctrl, const char *hexgrip) return 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); - switch (algo) - { - case GCRY_PK_RSA: return "RSA"; - case GCRY_PK_DSA: return "DSA"; - case GCRY_PK_ELG: return "ELG"; - case GCRY_PK_ECDSA: return "ECDSA"; - default: return NULL; - } + if (!algostr) + return NULL; + else if (!strcmp (algostr, "rsa")) + return "RSA"; + else if (!strcmp (algostr, "dsa")) + return "DSA"; + else if (!strcmp (algostr, "elg")) + return "ELG"; + else if (!strcmp (algostr, "ecdsa")) + return "ECDSA"; + else + return NULL; }