Extend algo selection menu.

This allows to add an ECC key and to set the capabilities of an ECDSA
key.

Fix printing of the ECC algorithm when creating a signature.
This commit is contained in:
Werner Koch 2011-02-03 17:40:43 +01:00
parent d9bd013a1f
commit d9e2dcc1a9
3 changed files with 75 additions and 42 deletions

View File

@ -1,3 +1,11 @@
2011-02-03 Werner Koch <wk@g10code.com>
* sign.c (do_sign): Use openpgp_pk_algo_name.
* keygen.c (ask_algo): Show ECC algos only in expert mode. Add
non-combined menu entries for ECDSA and ECDH.
(ask_key_flags): Use openpgp_pk_algo_name.
2011-02-03 Werner Koch <wk@g10code.com>
Finished ECC integration.

View File

@ -1629,7 +1629,7 @@ ask_key_flags(int algo,int subkey)
{
tty_printf("\n");
tty_printf(_("Possible actions for a %s key: "),
gcry_pk_algo_name (algo));
openpgp_pk_algo_name (algo));
print_key_flags(possible);
tty_printf("\n");
tty_printf(_("Current allowed actions: "));
@ -1727,9 +1727,16 @@ ask_algo (int addmode, int *r_subkey_algo, unsigned int *r_usage)
tty_printf (_(" (%d) RSA (set your own capabilities)\n"), 8 );
}
tty_printf (_(" (%d) ECDSA and ECDH\n"), 9 );
if (opt.expert && !addmode)
tty_printf (_(" (%d) ECDSA and ECDH\n"), 9 );
if (opt.expert)
tty_printf (_(" (%d) ECDSA (sign only)\n"), 10 );
if (opt.expert)
tty_printf (_(" (%d) ECDSA (set your own capabilities)\n"), 11 );
if (opt.expert && addmode)
tty_printf (_(" (%d) ECDH (encrypt only)\n"), 12 );
for(;;)
for (;;)
{
*r_usage = 0;
*r_subkey_algo = 0;
@ -1785,12 +1792,30 @@ ask_algo (int addmode, int *r_subkey_algo, unsigned int *r_usage)
*r_usage = ask_key_flags (algo, addmode);
break;
}
else if (algo == 9)
else if (algo == 9 && opt.expert && !addmode)
{
algo = PUBKEY_ALGO_ECDSA;
*r_subkey_algo = PUBKEY_ALGO_ECDH;
break;
}
else if (algo == 10 && opt.expert)
{
algo = PUBKEY_ALGO_ECDSA;
*r_usage = PUBKEY_USAGE_SIG;
break;
}
else if (algo == 11 && opt.expert)
{
algo = PUBKEY_ALGO_ECDSA;
*r_usage = ask_key_flags (algo, addmode);
break;
}
else if (algo == 12 && opt.expert && addmode)
{
algo = PUBKEY_ALGO_ECDH;
*r_usage = PUBKEY_USAGE_ENC;
break;
}
else
tty_printf (_("Invalid selection.\n"));
}

View File

@ -150,7 +150,7 @@ mk_notation_policy_etc (PKT_signature *sig,
/*
* Helper to hash a user ID packet.
* Helper to hash a user ID packet.
*/
static void
hash_uid (gcry_md_hd_t md, int sigversion, const PKT_user_id *uid)
@ -188,7 +188,7 @@ hash_uid (gcry_md_hd_t md, int sigversion, const PKT_user_id *uid)
static void
hash_sigversion_to_magic (gcry_md_hd_t md, const PKT_signature *sig)
{
if (sig->version >= 4)
if (sig->version >= 4)
gcry_md_putc (md, sig->version);
gcry_md_putc (md, sig->sig_class);
if (sig->version < 4) {
@ -201,7 +201,7 @@ hash_sigversion_to_magic (gcry_md_hd_t md, const PKT_signature *sig)
else {
byte buf[6];
size_t n;
gcry_md_putc (md, sig->pubkey_algo);
gcry_md_putc (md, sig->digest_algo);
if (sig->hashed) {
@ -249,7 +249,7 @@ do_sign (PKT_public_key *pksk, PKT_signature *sig,
return gpg_error (GPG_ERR_TIME_CONFLICT);
}
print_pubkey_algo_note (pksk->pubkey_algo);
if (!mdalgo)
@ -263,19 +263,19 @@ do_sign (PKT_public_key *pksk, PKT_signature *sig,
sig->data[0] = NULL;
sig->data[1] = NULL;
err = hexkeygrip_from_pk (pksk, &hexgrip);
if (!err)
{
char *desc;
gcry_sexp_t s_sigval;
desc = gpg_format_keydesc (pksk, 0, 1);
err = agent_pksign (NULL/*ctrl*/, cache_nonce, hexgrip, desc,
err = agent_pksign (NULL/*ctrl*/, cache_nonce, hexgrip, desc,
dp, gcry_md_get_algo_dlen (mdalgo), mdalgo,
&s_sigval);
xfree (desc);
if (err)
;
else if (pksk->pubkey_algo == GCRY_PK_RSA
@ -286,7 +286,7 @@ do_sign (PKT_public_key *pksk, PKT_signature *sig,
sig->data[0] = mpi_from_sexp (s_sigval, "r");
sig->data[1] = mpi_from_sexp (s_sigval, "s");
}
gcry_sexp_release (s_sigval);
}
xfree (hexgrip);
@ -300,7 +300,7 @@ do_sign (PKT_public_key *pksk, PKT_signature *sig,
if (get_pubkey (pk, sig->keyid ))
err = gpg_error (GPG_ERR_NO_PUBKEY);
else
else
{
frame = encode_md_value (pk, md, sig->digest_algo );
if (!frame)
@ -317,14 +317,14 @@ do_sign (PKT_public_key *pksk, PKT_signature *sig,
if (err)
log_error (_("signing failed: %s\n"), g10_errstr (err));
else
else
{
if (opt.verbose)
{
char *ustr = get_user_id_string_native (sig->keyid);
log_info (_("%s/%s signature from: \"%s\"\n"),
gcry_pk_algo_name (pksk->pubkey_algo),
gcry_md_algo_name (sig->digest_algo),
openpgp_pk_algo_name (pksk->pubkey_algo),
openpgp_md_algo_name (sig->digest_algo),
ustr);
xfree (ustr);
}
@ -444,7 +444,7 @@ hash_for (PKT_public_key *pk)
if (pk->pubkey_algo == PUBKEY_ALGO_ECDSA)
qbytes = ecdsa_qbits_from_Q (qbytes);
qbytes = qbytes/8;
/* It's a DSA key, so find a hash that is the same size as q or
larger. If q is 160, assume it is an old DSA key and use a
160-bit hash unless --enable-dsa2 is set, in which case act
@ -513,7 +513,7 @@ only_old_style (SK_LIST sk_list)
{
SK_LIST sk_rover = NULL;
int old_style = 0;
for (sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next)
{
PKT_public_key *pk = sk_rover->pk;
@ -533,13 +533,13 @@ print_status_sig_created (PKT_public_key *pk, PKT_signature *sig, int what)
byte array[MAX_FINGERPRINT_LEN];
char buf[100+MAX_FINGERPRINT_LEN*2];
size_t n;
snprintf (buf, sizeof buf - 2*MAX_FINGERPRINT_LEN, "%c %d %d %02x %lu ",
what, sig->pubkey_algo, sig->digest_algo, sig->sig_class,
(ulong)sig->timestamp );
fingerprint_from_pk (pk, array, &n);
bin2hex (array, n, buf + strlen (buf));
write_status_text( STATUS_SIG_CREATED, buf );
}
@ -548,7 +548,7 @@ print_status_sig_created (PKT_public_key *pk, PKT_signature *sig, int what)
* Loop over the secret certificates in SK_LIST and build the one pass
* signature packets. OpenPGP says that the data should be bracket by
* the onepass-sig and signature-packet; so we build these onepass
* packet here in reverse order
* packet here in reverse order
*/
static int
write_onepass_sig_packets (SK_LIST sk_list, IOBUF out, int sigclass )
@ -564,7 +564,7 @@ write_onepass_sig_packets (SK_LIST sk_list, IOBUF out, int sigclass )
PKT_onepass_sig *ops;
PACKET pkt;
int i, rc;
for (i=0, sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) {
if (++i == skcount)
break;
@ -577,7 +577,7 @@ write_onepass_sig_packets (SK_LIST sk_list, IOBUF out, int sigclass )
ops->pubkey_algo = pk->pubkey_algo;
keyid_from_pk (pk, ops->keyid);
ops->last = (skcount == 1);
init_packet(&pkt);
pkt.pkttype = PKT_ONEPASS_SIG;
pkt.pkt.onepass_sig = ops;
@ -665,7 +665,7 @@ write_plaintext_packet (IOBUF out, IOBUF inp, const char *fname, int ptmode)
wipememory(copy_buffer,4096); /* burn buffer */
}
/* fixme: it seems that we never freed pt/pkt */
return rc;
}
@ -679,7 +679,7 @@ write_signature_packets (SK_LIST sk_list, IOBUF out, gcry_md_hd_t hash,
int status_letter, const char *cache_nonce)
{
SK_LIST sk_rover;
/* Loop over the certificates with secret keys. */
for (sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next)
{
@ -713,23 +713,23 @@ write_signature_packets (SK_LIST sk_list, IOBUF out, gcry_md_hd_t hash,
if (gcry_md_copy (&md, hash))
BUG ();
if (sig->version >= 4)
{
build_sig_subpkt_from_sig (sig);
mk_notation_policy_etc (sig, pk, NULL);
}
hash_sigversion_to_magic (md, sig);
gcry_md_final (md);
rc = do_sign (pk, sig, md, hash_for (pk), cache_nonce);
gcry_md_close (md);
if (!rc)
{
{
/* Write the packet. */
PACKET pkt;
init_packet (&pkt);
pkt.pkttype = PKT_SIGNATURE;
pkt.pkt.signature = sig;
@ -743,7 +743,7 @@ write_signature_packets (SK_LIST sk_list, IOBUF out, gcry_md_hd_t hash,
if (rc)
return rc;
}
return 0;
}
@ -836,7 +836,7 @@ sign_file (ctrl_t ctrl, strlist_t filenames, int detached, strlist_t locusr,
inp = NULL;
gpg_err_set_errno (EPERM);
}
if( !inp )
if( !inp )
{
rc = gpg_error_from_syserror ();
log_error (_("can't open `%s': %s\n"), fname? fname: "[stdin]",
@ -992,7 +992,7 @@ sign_file (ctrl_t ctrl, strlist_t filenames, int detached, strlist_t locusr,
there is an assumed preference for uncompressed data.
Still, if it did fail, we'll also end up with the
default. */
if((compr_algo=
select_algo_from_prefs(pk_list,PREFTYPE_ZIP,-1,NULL))==-1)
compr_algo=default_compress_algo();
@ -1157,7 +1157,7 @@ clearsign_file( const char *fname, strlist_t locusr, const char *outfile )
}
if( !inp ) {
rc = gpg_error_from_syserror ();
log_error (_("can't open `%s': %s\n"),
log_error (_("can't open `%s': %s\n"),
fname? fname: "[stdin]", strerror(errno) );
goto leave;
}
@ -1168,7 +1168,7 @@ clearsign_file( const char *fname, strlist_t locusr, const char *outfile )
outfile = NULL;
gpg_err_set_errno (EPERM);
}
else
else
out = iobuf_create( outfile );
if( !out )
{
@ -1188,7 +1188,7 @@ clearsign_file( const char *fname, strlist_t locusr, const char *outfile )
{
if (hash_for (sk_rover->pk) == DIGEST_ALGO_MD5)
only_md5 = 1;
else
else
{
only_md5 = 0;
break;
@ -1256,7 +1256,7 @@ clearsign_file( const char *fname, strlist_t locusr, const char *outfile )
gcry_md_close ( textmd );
release_sk_list( sk_list );
release_progress_context (pfx);
release_armor_context (afx);
release_armor_context (afx);
return rc;
}
@ -1302,7 +1302,7 @@ sign_symencrypt_file (const char *fname, strlist_t locusr)
/* Note: In the old non-agent version the following call used to
unprotect the secret key. This is now done on demand by the agent. */
rc = build_sk_list (locusr, &sk_list, PUBKEY_USAGE_SIG);
if (rc)
if (rc)
goto leave;
/* prepare iobufs */
@ -1315,7 +1315,7 @@ sign_symencrypt_file (const char *fname, strlist_t locusr)
}
if( !inp ) {
rc = gpg_error_from_syserror ();
log_error (_("can't open `%s': %s\n"),
log_error (_("can't open `%s': %s\n"),
fname? fname: "[stdin]", strerror(errno) );
goto leave;
}
@ -1404,7 +1404,7 @@ sign_symencrypt_file (const char *fname, strlist_t locusr)
rc = write_plaintext_packet (out, inp, fname, opt.textmode ? 't':'b');
if (rc)
goto leave;
/* Write the signatures */
/*(current filters: zip - encrypt - armor)*/
rc = write_signature_packets (sk_list, out, mfx.md,
@ -1569,7 +1569,7 @@ int
update_keysig_packet( PKT_signature **ret_sig,
PKT_signature *orig_sig,
PKT_public_key *pk,
PKT_user_id *uid,
PKT_user_id *uid,
PKT_public_key *subpk,
PKT_public_key *pksk,
int (*mksubpkt)(PKT_signature *, void *),
@ -1597,7 +1597,7 @@ update_keysig_packet( PKT_signature **ret_sig,
/* create a new signature packet */
sig = copy_signature (NULL, orig_sig);
/* We need to create a new timestamp so that new sig expiration
calculations are done correctly... */
sig->timestamp=make_timestamp();