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. */
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)

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
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;
}

View File

@ -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);

View File

@ -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]);

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.
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;

View File

@ -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))
{

View File

@ -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)

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_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);

View File

@ -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:
{

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));
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]);

View File

@ -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);

View File

@ -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 );

View File

@ -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) {

View File

@ -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 ();

View File

@ -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]);

View File

@ -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

View File

@ -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 --*/

View File

@ -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);

View File

@ -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 <x> <y> */
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;
}

View File

@ -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;

View File

@ -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;
}