From a1412b05debe693e6aabaf2c2c337bc33f7dfd41 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 21 Apr 2010 16:26:17 +0000 Subject: [PATCH] More changes on the way to remove secring.gpg. --- agent/ChangeLog | 10 + agent/agent.h | 1 + agent/command.c | 5 +- agent/findkey.c | 154 +++++--- agent/pksign.c | 108 +++++- common/ChangeLog | 5 +- common/estream.c | 15 +- doc/DETAILS | 2 +- g10/ChangeLog | 35 ++ g10/call-agent.c | 16 +- g10/call-agent.h | 9 +- g10/delkey.c | 7 +- g10/export.c | 2 +- g10/getkey.c | 326 +++++++--------- g10/gpgv.c | 7 + g10/import.c | 38 +- g10/keydb.c | 3 +- g10/keydb.h | 27 +- g10/keyedit.c | 944 ++++++++++++++++------------------------------ g10/keygen.c | 2 +- g10/keylist.c | 4 +- g10/keyserver.c | 2 +- g10/mainproc.c | 2 +- g10/pkclist.c | 12 +- g10/revoke.c | 5 +- g10/sign.c | 3 + g10/trustdb.c | 2 +- kbx/ChangeLog | 5 + kbx/keybox-blob.c | 16 +- po/POTFILES.in | 1 + tools/Makefile.am | 11 +- 31 files changed, 843 insertions(+), 936 deletions(-) diff --git a/agent/ChangeLog b/agent/ChangeLog index 46e0b6fe3..6611a35ad 100644 --- a/agent/ChangeLog +++ b/agent/ChangeLog @@ -1,3 +1,13 @@ +2010-04-19 Werner Koch + + * pksign.c (get_dsa_qbits, do_encode_dsa): New. + (agent_pksign_do): Detect DSA keys and use do_encode_dsa. + * findkey.c (agent_public_key_from_file): Factor some code out to .. + (key_parms_from_sexp): New. + (agent_is_dsa_key): New. + + * command.c (cmd_sethash): Clear digeest.RAW_VALUE. + 2010-04-14 Werner Koch * Makefile.am (libexec_PROGRAMS) [W32CE]: Do not build diff --git a/agent/agent.h b/agent/agent.h index ea0d49465..3f0c19561 100644 --- a/agent/agent.h +++ b/agent/agent.h @@ -232,6 +232,7 @@ gpg_error_t agent_key_from_file (ctrl_t ctrl, gpg_error_t agent_public_key_from_file (ctrl_t ctrl, const unsigned char *grip, gcry_sexp_t *result); +int agent_is_dsa_key (gcry_sexp_t s_key); int agent_key_available (const unsigned char *grip); gpg_error_t agent_key_info_from_file (ctrl_t ctrl, const unsigned char *grip, int *r_keytype, diff --git a/agent/command.c b/agent/command.c index 1e0c5e744..b78dc07d9 100644 --- a/agent/command.c +++ b/agent/command.c @@ -589,7 +589,7 @@ cmd_setkeydesc (assuan_context_t ctx, char *line) static const char hlp_sethash[] = - "SETHASH --hash=| \n" + "SETHASH (--hash=)|() \n" "\n" "The client can use this command to tell the server about the data\n" "(which usually is a hash) to be signed."; @@ -642,6 +642,7 @@ cmd_sethash (assuan_context_t ctx, char *line) return set_error (GPG_ERR_UNSUPPORTED_ALGORITHM, NULL); } ctrl->digest.algo = algo; + ctrl->digest.raw_value = 0; /* Parse the hash value. */ n = 0; @@ -848,7 +849,7 @@ static const char hlp_keyinfo[] = "\n" "TYPE is describes the type of the key:\n" " 'D' - Regular key stored on disk,\n" - " 'T' - Key is stored on a smartcard (token).\n" + " 'T' - Key is stored on a smartcard (token),\n" " '-' - Unknown type.\n" "\n" "SERIALNO is an ASCII string with the serial number of the\n" diff --git a/agent/findkey.c b/agent/findkey.c index 30aa7c938..d6478ac4d 100644 --- a/agent/findkey.c +++ b/agent/findkey.c @@ -1,6 +1,6 @@ /* findkey.c - Locate the secret key - * Copyright (C) 2001, 2002, 2003, 2004, 2005, - * 2007 Free Software Foundation, Inc. + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007, + * 2010 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -626,50 +626,32 @@ agent_key_from_file (ctrl_t ctrl, const char *desc_text, } - -/* Return the public key for the keygrip GRIP. The result is stored - at RESULT. This function extracts the public key from the private - key database. On failure an error code is returned and NULL stored - at RESULT. */ -gpg_error_t -agent_public_key_from_file (ctrl_t ctrl, - const unsigned char *grip, - gcry_sexp_t *result) +/* Return the string name from the S-expression S_KEY as well as a + string describing the names of the parameters. ALGONAMESIZE and + ELEMSSIZE give the allocated size of the provided buffers. The + buffers may be NULL if not required. If R_LIST is not NULL the top + level list will be stored tehre; the caller needs to release it in + this case. */ +static gpg_error_t +key_parms_from_sexp (gcry_sexp_t s_key, gcry_sexp_t *r_list, + char *r_algoname, size_t algonamesize, + char *r_elems, size_t elemssize) { - int i, idx, rc; - gcry_sexp_t s_skey; - const char *algoname; - gcry_sexp_t uri_sexp, comment_sexp; - const char *uri, *comment; - size_t uri_length, comment_length; - char *format, *p; - void *args[4+2+2+1]; /* Size is max. # of elements + 2 for uri + 2 - for comment + end-of-list. */ - int argidx; gcry_sexp_t list, l2; - const char *name; - const char *s; + const char *name, *algoname, *elems; size_t n; - const char *elems; - gcry_mpi_t *array; - (void)ctrl; + if (r_list) + *r_list = NULL; - *result = NULL; - - rc = read_key_file (grip, &s_skey); - if (rc) - return rc; - - list = gcry_sexp_find_token (s_skey, "shadowed-private-key", 0 ); + list = gcry_sexp_find_token (s_key, "shadowed-private-key", 0 ); if (!list) - list = gcry_sexp_find_token (s_skey, "protected-private-key", 0 ); + list = gcry_sexp_find_token (s_key, "protected-private-key", 0 ); if (!list) - list = gcry_sexp_find_token (s_skey, "private-key", 0 ); + list = gcry_sexp_find_token (s_key, "private-key", 0 ); if (!list) { log_error ("invalid private key format\n"); - gcry_sexp_release (s_skey); return gpg_error (GPG_ERR_BAD_SECKEY); } @@ -696,19 +678,99 @@ agent_public_key_from_file (ctrl_t ctrl, { log_error ("unknown private key algorithm\n"); gcry_sexp_release (list); - gcry_sexp_release (s_skey); return gpg_error (GPG_ERR_BAD_SECKEY); } + if (r_algoname) + { + if (strlen (algoname) >= algonamesize) + return gpg_error (GPG_ERR_BUFFER_TOO_SHORT); + strcpy (r_algoname, algoname); + } + if (r_elems) + { + if (strlen (elems) >= elemssize) + return gpg_error (GPG_ERR_BUFFER_TOO_SHORT); + strcpy (r_elems, elems); + } + + if (r_list) + *r_list = list; + else + gcry_sexp_release (list); + + return 0; +} + + +/* Return true if S_KEY is a DSA style key. */ +int +agent_is_dsa_key (gcry_sexp_t s_key) +{ + char algoname[6]; + + if (!s_key) + return 0; + + if (key_parms_from_sexp (s_key, NULL, algoname, sizeof algoname, NULL, 0)) + return 0; /* Error - assume it is not an DSA key. */ + + return (!strcmp (algoname, "dsa") || !strcmp (algoname, "ecdsa")); +} + + + +/* Return the public key for the keygrip GRIP. The result is stored + at RESULT. This function extracts the public key from the private + key database. On failure an error code is returned and NULL stored + at RESULT. */ +gpg_error_t +agent_public_key_from_file (ctrl_t ctrl, + const unsigned char *grip, + gcry_sexp_t *result) +{ + gpg_error_t err; + int i, idx; + gcry_sexp_t s_skey; + char algoname[6]; + char elems[6]; + gcry_sexp_t uri_sexp, comment_sexp; + const char *uri, *comment; + size_t uri_length, comment_length; + char *format, *p; + void *args[4+2+2+1]; /* Size is max. # of elements + 2 for uri + 2 + for comment + end-of-list. */ + int argidx; + gcry_sexp_t list, l2; + const char *s; + gcry_mpi_t *array; + + (void)ctrl; + + *result = NULL; + + err = read_key_file (grip, &s_skey); + if (err) + return err; + + err = key_parms_from_sexp (s_skey, &list, + algoname, sizeof algoname, + elems, sizeof elems); + if (err) + { + gcry_sexp_release (s_skey); + return err; + } + /* Allocate an array for the parameters and copy them out of the secret key. FIXME: We should have a generic copy function. */ array = xtrycalloc (strlen(elems) + 1, sizeof *array); if (!array) { - rc = gpg_error_from_syserror (); + err = gpg_error_from_syserror (); gcry_sexp_release (list); gcry_sexp_release (s_skey); - return rc; + return err; } for (idx=0, s=elems; *s; s++, idx++ ) @@ -757,8 +819,8 @@ agent_public_key_from_file (ctrl_t ctrl, /* FIXME: The following thing is pretty ugly code; we should - investigate how to make it cleaner. Probably code to handle - canonical S-expressions in a memory buffer is better suioted for + investigate how to make it cleaner. Probably code to handle + canonical S-expressions in a memory buffer is better suited for such a task. After all that is what we do in protect.c. Neeed to find common patterns and write a straightformward API to use them. */ @@ -767,13 +829,13 @@ agent_public_key_from_file (ctrl_t ctrl, format = xtrymalloc (15+7*strlen (elems)+10+15+1+1); if (!format) { - rc = gpg_error_from_syserror (); + err = gpg_error_from_syserror (); for (i=0; array[i]; i++) gcry_mpi_release (array[i]); xfree (array); gcry_sexp_release (uri_sexp); gcry_sexp_release (comment_sexp); - return rc; + return err; } argidx = 0; @@ -806,7 +868,7 @@ agent_public_key_from_file (ctrl_t ctrl, assert (argidx < DIM (args)); args[argidx] = NULL; - rc = gcry_sexp_build_array (&list, NULL, format, args); + err = gcry_sexp_build_array (&list, NULL, format, args); xfree (format); for (i=0; array[i]; i++) gcry_mpi_release (array[i]); @@ -814,9 +876,9 @@ agent_public_key_from_file (ctrl_t ctrl, gcry_sexp_release (uri_sexp); gcry_sexp_release (comment_sexp); - if (!rc) + if (!err) *result = list; - return rc; + return err; } diff --git a/agent/pksign.c b/agent/pksign.c index 25cadb29e..7ae50a931 100644 --- a/agent/pksign.c +++ b/agent/pksign.c @@ -1,5 +1,5 @@ /* pksign.c - public key signing (well, actually using a secret key) - * Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. + * Copyright (C) 2001, 2002, 2003, 2004, 2010 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -28,6 +28,7 @@ #include #include "agent.h" +#include "i18n.h" static int @@ -75,6 +76,104 @@ do_encode_md (const byte * md, size_t mdlen, int algo, gcry_sexp_t * r_hash, } +/* Return the number of bits of the Q parameter from the DSA key + KEY. */ +static unsigned int +get_dsa_qbits (gcry_sexp_t key) +{ + gcry_sexp_t l1, l2; + gcry_mpi_t q; + unsigned int nbits; + + l1 = gcry_sexp_find_token (key, "private-key", 0); + if (!l1) + l1 = gcry_sexp_find_token (key, "protected-private-key", 0); + if (!l1) + l1 = gcry_sexp_find_token (key, "shadowed-private-key", 0); + if (!l1) + l1 = gcry_sexp_find_token (key, "public-key", 0); + if (!l1) + return 0; /* Does not contain a key object. */ + l2 = gcry_sexp_cadr (l1); + gcry_sexp_release (l1); + l1 = gcry_sexp_find_token (l2, "q", 1); + gcry_sexp_release (l2); + if (!l1) + return 0; /* Invalid object. */ + q = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG); + gcry_sexp_release (l1); + if (!q) + return 0; /* Missing value. */ + nbits = gcry_mpi_get_nbits (q); + gcry_mpi_release (q); + + return nbits; +} + + +/* 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, + gcry_sexp_t *r_hash) +{ + gpg_error_t err; + gcry_sexp_t hash; + unsigned int qbits; + + *r_hash = NULL; + + if (dsaalgo == GCRY_PK_ECDSA) + qbits = gcry_pk_get_nbits (pkey); + else if (dsaalgo == GCRY_PK_DSA) + qbits = get_dsa_qbits (pkey); + else + return gpg_error (GPG_ERR_WRONG_PUBKEY_ALGO); + + if ((qbits%8)) + { + log_error (_("DSA requires the hash length to be a" + " multiple of 8 bits\n")); + return gpg_error (GPG_ERR_INV_LENGTH); + } + + /* Don't allow any Q smaller than 160 bits. We don't want someone + to issue signatures from a key with a 16-bit Q or something like + that, which would look correct but allow trivial forgeries. Yes, + I know this rules out using MD5 with DSA. ;) */ + if (qbits < 160) + { + log_error (_("%s key uses an unsafe (%u bit) hash\n"), + gcry_pk_algo_name (dsaalgo), qbits); + return gpg_error (GPG_ERR_INV_LENGTH); + } + + /* Check if we're too short. Too long is safe as we'll + automatically left-truncate. */ + if (mdlen < qbits/8) + { + log_error (_("a %zu bit hash is not valid for a %u bit %s key\n"), + mdlen*8, + gcry_pk_get_nbits (pkey), + gcry_pk_algo_name (dsaalgo)); + /* FIXME: we need to check the requirements for ECDSA. */ + if (mdlen < 20 || dsaalgo == GCRY_PK_DSA) + return gpg_error (GPG_ERR_INV_LENGTH); + } + + /* Truncate. */ + if (mdlen > qbits/8) + mdlen = qbits/8; + + /* Create the S-expression. */ + err = gcry_sexp_build (&hash, NULL, + "(data (flags raw) (value %b))", + (int)mdlen, md); + if (!err) + *r_hash = hash; + return err; +} + + /* Special version of do_encode_md to take care of pkcs#1 padding. For TLS-MD5SHA1 we need to do the padding ourself as Libgrypt does not know about this special scheme. Fixme: We should have a @@ -180,8 +279,8 @@ agent_pksign_do (ctrl_t ctrl, const char *desc_text, else { /* No smartcard, but a private key */ - gcry_sexp_t s_hash = NULL; + int dsaalgo; /* Put the hash into a sexp */ if (ctrl->digest.algo == MD_USER_TLS_MD5SHA1) @@ -189,6 +288,11 @@ agent_pksign_do (ctrl_t ctrl, const char *desc_text, ctrl->digest.valuelen, gcry_pk_get_nbits (s_skey), &s_hash); + else if ( (dsaalgo = agent_is_dsa_key (s_skey)) ) + rc = do_encode_dsa (ctrl->digest.value, + ctrl->digest.valuelen, + dsaalgo, s_skey, + &s_hash); else rc = do_encode_md (ctrl->digest.value, ctrl->digest.valuelen, diff --git a/common/ChangeLog b/common/ChangeLog index ce6817470..4dd266e0f 100644 --- a/common/ChangeLog +++ b/common/ChangeLog @@ -1,5 +1,8 @@ 2010-04-20 Werner Koch + * estream.c (es_deinit): New. + (es_init_do): Intll atexit handler to flush all streams. + * Makefile.am (common_sources): Add gettime.h. 2010-04-20 Marcus Brinkmann @@ -16,7 +19,7 @@ 2010-04-15 Werner Koch - * util.h: Factor time related fucntions out to ... + * util.h: Factor time related functions out to ... * gettime.h: New. (gnupg_copy_time): Move to ... * gettime.c (gnupg_copy_time): New. diff --git a/common/estream.c b/common/estream.c index 75d5ad694..47ff94ff2 100644 --- a/common/estream.c +++ b/common/estream.c @@ -423,6 +423,14 @@ es_pth_write (int fd, const void *buffer, size_t size) +static void +es_deinit (void) +{ + /* Flush all streams. */ + es_fflush (NULL); +} + + /* * Initialization. */ @@ -430,17 +438,20 @@ es_pth_write (int fd, const void *buffer, size_t size) static int es_init_do (void) { -#ifdef HAVE_PTH static int initialized; if (!initialized) { +#ifdef HAVE_PTH if (!pth_init () && errno != EPERM ) return -1; if (pth_mutex_init (&estream_list_lock)) initialized = 1; - } +#else + initialized = 1; #endif + atexit (es_deinit); + } return 0; } diff --git a/doc/DETAILS b/doc/DETAILS index ef8d3cdb3..a67e90e53 100644 --- a/doc/DETAILS +++ b/doc/DETAILS @@ -34,7 +34,7 @@ record; gpg2 does this by default and the option is a dummy. rev = revocation signature fpr = fingerprint: (fingerprint is in field 10) pkd = public key data (special field format, see below) - grp = reserved for gpgsm + grp = keygrip rvk = revocation key tru = trust database information spk = signature subpacket diff --git a/g10/ChangeLog b/g10/ChangeLog index d82afa181..5c5a2f588 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,37 @@ +2010-04-21 Werner Koch + + * pkclist.c (default_recipient): Change to use public keys. + + * keydb.c (keydb_new): Remove arg SECRET. Change all callers. + + * getkey.c (get_seckey): Change to take a public key. + (have_secret_key): Rename to have_any_secret_key and make use of + the agent. + (key_byname): Rmemove unused arg SK. + (get_seckey_byname2): Remove and move code to + (get_seckey_byname): .. here. Remove INLOCK arg. + (get_seckey_bynames): Remove. + (get_seckey_next): Remove. + (get_seckey_end): Remove. Use get_pubkey_end instead. + (get_seckey_byfprint, get_seckeyblock_byfprint): Change to use + public keys. + (seckey_available): Rename to .. + (have_secret_key_with_kid): .. this and change to employ the + agent. Change all callers. + (sk_from_block): Remove. + + * call-agent.c (agent_probe_secret_key): New. + (agent_havekey): Remove. + * gpgv.c (agent_probe_secret_key): New. + + * keyedit.c (keyedit_menu) + (sign_uids, menu_adduid, menu_deluid, menu_delkey) + (menu_addrevoker, menu_expire, menu_backsign) + (menu_set_primary_uid, menu_set_preferences) + (menu_set_keyserver_url, menu_set_notation, menu_revsig) + (menu_revuid, menu_revkey, menu_revsubkey): Remove all code to + manage the secret keyring. + 2010-04-20 Werner Koch * keylist.c (list_keyblock_colon): Print the keygrip. @@ -6,6 +40,7 @@ (mpi_from_sexp): New. * keyid.c (keygrip_from_pk, hexkeygrip_from_pk): New. * call-agent.c (agent_pksign): New. + * pkglue.c (pk_sign): Remove. * keygen.c (generate_keypair): Do not ask for a passphrase. diff --git a/g10/call-agent.c b/g10/call-agent.c index 9379fcb52..7ae8fbba5 100644 --- a/g10/call-agent.c +++ b/g10/call-agent.c @@ -1294,23 +1294,25 @@ agent_get_s2k_count (unsigned long *r_count) -/* Ask the agent whether a secret key with the given keygrip is - known. */ +/* Ask the agent whether a secret key for the given public key is + available. Returns 0 if available. */ gpg_error_t -agent_havekey (ctrl_t ctrl, const char *hexkeygrip) +agent_probe_secret_key (ctrl_t ctrl, PKT_public_key *pk) { gpg_error_t err; char line[ASSUAN_LINELENGTH]; + char *hexgrip; err = start_agent (ctrl, 0); if (err) return err; - if (!hexkeygrip || strlen (hexkeygrip) != 40) - return gpg_error (GPG_ERR_INV_VALUE); + err = hexkeygrip_from_pk (pk, &hexgrip); + if (err) + return err; - snprintf (line, DIM(line)-1, "HAVEKEY %s", hexkeygrip); - line[DIM(line)-1] = 0; + snprintf (line, sizeof line, "HAVEKEY %s", hexgrip); + xfree (hexgrip); err = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); return err; diff --git a/g10/call-agent.h b/g10/call-agent.h index d42131f47..bf32d3f28 100644 --- a/g10/call-agent.h +++ b/g10/call-agent.h @@ -140,8 +140,9 @@ gpg_error_t gpg_agent_get_confirmation (const char *desc); /* Return the S2K iteration count as computed by gpg-agent. */ gpg_error_t agent_get_s2k_count (unsigned long *r_count); -/* Check whether a secret key with HEXKEYGRIP is available. */ -gpg_error_t agent_havekey (ctrl_t ctrl, const char *hexkeygrip); +/* Check whether a secret key for public key PK is available. Returns + 0 if the secret key is available. */ +gpg_error_t agent_probe_secret_key (ctrl_t ctrl, PKT_public_key *pk); /* Return infos about the secret key with HEXKEYGRIP. */ gpg_error_t agent_get_keyinfo (ctrl_t ctrl, const char *hexkeygrip, @@ -151,8 +152,8 @@ gpg_error_t agent_get_keyinfo (ctrl_t ctrl, const char *hexkeygrip, gpg_error_t agent_genkey (ctrl_t ctrl, const char *keyparms, gcry_sexp_t *r_pubkey); -/* Create a sigtnature. */ -gpg_error_t agent_pksign (ctrl_t ctrl, const char *keygrip, const char *desc, +/* Create a signature. */ +gpg_error_t agent_pksign (ctrl_t ctrl, const char *hexkeygrip, const char *desc, unsigned char *digest, size_t digestlen, int digestalgo, gcry_sexp_t *r_sigval); diff --git a/g10/delkey.c b/g10/delkey.c index 5d86e7291..2361d8323 100644 --- a/g10/delkey.c +++ b/g10/delkey.c @@ -52,7 +52,7 @@ do_delete_key( const char *username, int secret, int force, int *r_sec_avail ) int rc = 0; KBNODE keyblock = NULL; KBNODE node; - KEYDB_HANDLE hd = keydb_new (secret); + KEYDB_HANDLE hd = keydb_new (); PKT_public_key *pk = NULL; PKT_secret_key *sk = NULL; u32 keyid[2]; @@ -104,15 +104,12 @@ do_delete_key( const char *username, int secret, int force, int *r_sec_avail ) if(!force) { - rc = seckey_available( keyid ); - if( !rc ) + if (have_secret_key_with_kid (keyid)) { *r_sec_avail = 1; rc = -1; goto leave; } - else if( rc != G10ERR_NO_SECKEY ) - log_error("%s: get secret key: %s\n", username, g10_errstr(rc) ); else rc = 0; } diff --git a/g10/export.c b/g10/export.c index 34ab90729..e5a0d9d95 100644 --- a/g10/export.c +++ b/g10/export.c @@ -306,7 +306,7 @@ do_export_stream( IOBUF out, strlist_t users, int secret, *any = 0; init_packet( &pkt ); - kdbhd = keydb_new (secret); + kdbhd = keydb_new (); if (!users) { ndesc = 1; diff --git a/g10/getkey.c b/g10/getkey.c index 78d5a1eb5..4929974a3 100644 --- a/g10/getkey.c +++ b/g10/getkey.c @@ -35,6 +35,7 @@ #include "trustdb.h" #include "i18n.h" #include "keyserver-internal.h" +#include "call-agent.h" #define MAX_PK_CACHE_ENTRIES PK_UID_CACHE_SIZE #define MAX_UID_CACHE_ENTRIES PK_UID_CACHE_SIZE @@ -325,18 +326,6 @@ pk_from_block (GETKEY_CTX ctx, PKT_public_key * pk, KBNODE keyblock) copy_public_key (pk, a->pkt->pkt.public_key); } -static void -sk_from_block (GETKEY_CTX ctx, PKT_secret_key * sk, KBNODE keyblock) -{ - KBNODE a = ctx->found_key ? ctx->found_key : keyblock; - - assert (a->pkt->pkttype == PKT_SECRET_KEY - || a->pkt->pkttype == PKT_SECRET_SUBKEY); - - copy_secret_key (sk, a->pkt->pkt.secret_key); -} - - /* Get a public key and store it into the allocated pk can be called * with PK set to NULL to just read it into some internal * structures. */ @@ -378,7 +367,7 @@ get_pubkey (PKT_public_key * pk, u32 * keyid) memset (&ctx, 0, sizeof ctx); ctx.exact = 1; /* Use the key ID exactly as given. */ ctx.not_allocated = 1; - ctx.kr_handle = keydb_new (0); + ctx.kr_handle = keydb_new (); ctx.nitems = 1; ctx.items[0].mode = KEYDB_SEARCH_MODE_LONG_KID; ctx.items[0].u.kid[0] = keyid[0]; @@ -437,7 +426,7 @@ get_pubkey_fast (PKT_public_key * pk, u32 * keyid) } #endif - hd = keydb_new (0); + hd = keydb_new (); rc = keydb_search_kid (hd, keyid); if (rc == -1) { @@ -480,7 +469,7 @@ get_pubkeyblock (u32 * keyid) memset (&ctx, 0, sizeof ctx); /* No need to set exact here because we want the entire block. */ ctx.not_allocated = 1; - ctx.kr_handle = keydb_new (0); + ctx.kr_handle = keydb_new (); ctx.nitems = 1; ctx.items[0].mode = KEYDB_SEARCH_MODE_LONG_KID; ctx.items[0].u.kid[0] = keyid[0]; @@ -494,67 +483,43 @@ get_pubkeyblock (u32 * keyid) -/**************** - * Get a secret key and store it into sk +/* + * Get a public key and store it into PK. This functions check that a + * corresponding secret key is available. With no secret key it does + * not succeeed. */ -int -get_seckey (PKT_secret_key * sk, u32 * keyid) +gpg_error_t +get_seckey (PKT_public_key *pk, u32 *keyid) { - int rc; + gpg_error_t err; struct getkey_ctx_s ctx; - KBNODE kb = NULL; + kbnode_t keyblock = NULL; memset (&ctx, 0, sizeof ctx); ctx.exact = 1; /* Use the key ID exactly as given. */ ctx.not_allocated = 1; - ctx.kr_handle = keydb_new (1); + ctx.kr_handle = keydb_new (); ctx.nitems = 1; ctx.items[0].mode = KEYDB_SEARCH_MODE_LONG_KID; ctx.items[0].u.kid[0] = keyid[0]; ctx.items[0].u.kid[1] = keyid[1]; - ctx.req_algo = sk->req_algo; - ctx.req_usage = sk->req_usage; - rc = lookup (&ctx, &kb, 1); - if (!rc) + ctx.req_algo = pk->req_algo; + ctx.req_usage = pk->req_usage; + err = lookup (&ctx, &keyblock, 1); + if (!err) { - sk_from_block (&ctx, sk, kb); + pk_from_block (&ctx, pk, keyblock); } - get_seckey_end (&ctx); - release_kbnode (kb); + get_pubkey_end (&ctx); + release_kbnode (keyblock); - if (!rc) - { - /* Check the secret key (this may prompt for a passprase to - * unlock the secret key. */ - /* rc = check_secret_key (sk, 0); */ - } + if (!err) + err = agent_probe_secret_key (/*ctrl*/NULL, pk); - return rc; + return err; } -/* Check whether the secret key is available. This is just a fast - * check and does not tell us whether the secret key is valid. It - * merely tells other whether there is some secret key. - * Returns: - * 0 := key is available - * G10ERR_NO_SECKEY := key not availabe - */ -int -seckey_available (u32 * keyid) -{ - int rc; - KEYDB_HANDLE hd = keydb_new (1); - - rc = keydb_search_kid (hd, keyid); - if (rc == -1) - rc = G10ERR_NO_SECKEY; - keydb_release (hd); - return rc; -} - - - static int skip_unusable (void *dummy, u32 * keyid, PKT_user_id * uid) { @@ -599,16 +564,15 @@ leave: } -/* Try to get the pubkey by the userid. This function looks for the +/* Try to get the pubkey by the userid. This function looks for the * first pubkey certificate which has the given name in a user_id. If - * pk/sk has the pubkey algo set, the function will only return a - * pubkey with that algo. If namelist is NULL, the first key is - * returned. The caller should provide storage for either the pk or - * the sk. If ret_kb is not NULL the function will return the - * keyblock there. */ + * PK has the pubkey algo set, the function will only return a pubkey + * with that algo. If NAMELIST is NULL, the first key is returned. + * The caller should provide storage for the PK. If RET_KB is not + * NULL the function will return the keyblock there. */ static int -key_byname (GETKEY_CTX * retctx, strlist_t namelist, - PKT_public_key * pk, PKT_secret_key * sk, +key_byname (GETKEY_CTX *retctx, strlist_t namelist, + PKT_public_key *pk, int want_secret, int include_unusable, KBNODE * ret_kb, KEYDB_HANDLE * ret_kdbhd) { @@ -618,8 +582,6 @@ key_byname (GETKEY_CTX * retctx, strlist_t namelist, GETKEY_CTX ctx; KBNODE help_kb = NULL; - /* FIXME: Eventually remove the SK argument. */ - if (retctx) { /* Reset the returned context in case of error. */ @@ -671,7 +633,7 @@ key_byname (GETKEY_CTX * retctx, strlist_t namelist, } ctx->want_secret = want_secret; - ctx->kr_handle = keydb_new (0); + ctx->kr_handle = keydb_new (); if (!ret_kb) ret_kb = &help_kb; @@ -680,11 +642,7 @@ key_byname (GETKEY_CTX * retctx, strlist_t namelist, ctx->req_algo = pk->req_algo; ctx->req_usage = pk->req_usage; } - else if (sk) /* FIXME: We should remove this. */ - { - ctx->req_algo = sk->req_algo; - ctx->req_usage = sk->req_usage; - } + rc = lookup (ctx, ret_kb, want_secret); if (!rc && pk) { @@ -771,7 +729,7 @@ get_pubkey_byname (GETKEY_CTX * retctx, PKT_public_key * pk, else { add_to_strlist (&namelist, name); - rc = key_byname (retctx, namelist, pk, NULL, 0, + rc = key_byname (retctx, namelist, pk, 0, include_unusable, ret_keyblock, ret_kdbhd); } @@ -805,7 +763,7 @@ get_pubkey_byname (GETKEY_CTX * retctx, PKT_public_key * pk, } add_to_strlist (&namelist, name); rc = key_byname (anylocalfirst ? retctx : NULL, - namelist, pk, NULL, 0, + namelist, pk, 0, include_unusable, ret_keyblock, ret_kdbhd); break; @@ -904,7 +862,7 @@ get_pubkey_byname (GETKEY_CTX * retctx, PKT_public_key * pk, *retctx = NULL; } rc = key_byname (anylocalfirst ? retctx : NULL, - namelist, pk, NULL, 0, + namelist, pk, 0, include_unusable, ret_keyblock, ret_kdbhd); } if (!rc) @@ -943,7 +901,7 @@ int get_pubkey_bynames (GETKEY_CTX * retctx, PKT_public_key * pk, strlist_t names, KBNODE * ret_keyblock) { - return key_byname (retctx, names, pk, NULL, 0, 1, ret_keyblock, NULL); + return key_byname (retctx, names, pk, 0, 1, ret_keyblock, NULL); } int @@ -991,7 +949,7 @@ get_pubkey_byfprint (PKT_public_key * pk, memset (&ctx, 0, sizeof ctx); ctx.exact = 1; ctx.not_allocated = 1; - ctx.kr_handle = keydb_new (0); + ctx.kr_handle = keydb_new (); ctx.nitems = 1; ctx.items[0].mode = fprint_len == 16 ? KEYDB_SEARCH_MODE_FPR16 : KEYDB_SEARCH_MODE_FPR20; @@ -1028,7 +986,7 @@ get_pubkey_byfprint_fast (PKT_public_key * pk, while (i < MAX_FINGERPRINT_LEN) fprbuf[i++] = 0; - hd = keydb_new (0); + hd = keydb_new (); rc = keydb_search_fpr (hd, fprbuf); if (rc == -1) { @@ -1070,7 +1028,7 @@ get_keyblock_byfprint (KBNODE * ret_keyblock, const byte * fprint, memset (&ctx, 0, sizeof ctx); ctx.not_allocated = 1; - ctx.kr_handle = keydb_new (0); + ctx.kr_handle = keydb_new (); ctx.nitems = 1; ctx.items[0].mode = (fprint_len == 16 ? KEYDB_SEARCH_MODE_FPR16 @@ -1086,15 +1044,15 @@ get_keyblock_byfprint (KBNODE * ret_keyblock, const byte * fprint, } -/* Get a secret key by name and store it into sk. - * If NAME is NULL use the default key. */ -static int -get_seckey_byname2 (GETKEY_CTX * retctx, - PKT_secret_key * sk, const char *name, int unprotect, - KBNODE * retblock) +/* Get a secret key by NAME and store it into PK. If NAME is NULL use + * the default key. This functions checks that a corresponding secret + * key is available. With no secret key it does not succeeed. */ +gpg_error_t +get_seckey_byname (PKT_public_key *pk, const char *name) { + gpg_error_t err; strlist_t namelist = NULL; - int rc, include_unusable = 1; + int include_unusable = 1; /* If we have no name, try to use the default secret key. If we have no default, we'll use the first usable one. */ @@ -1106,110 +1064,73 @@ get_seckey_byname2 (GETKEY_CTX * retctx, else include_unusable = 0; - rc = key_byname (retctx, namelist, NULL, sk, 1, include_unusable, - retblock, NULL); + err = key_byname (NULL, namelist, pk, 1, include_unusable, NULL, NULL); free_strlist (namelist); - /* if (!rc && unprotect) */ - /* rc = check_secret_key (sk, 0); */ - - return rc; + return err; } -int -get_seckey_byname (PKT_secret_key * sk, const char *name, int unlock) -{ - return get_seckey_byname2 (NULL, sk, name, unlock, NULL); -} - - -int -get_seckey_bynames (GETKEY_CTX * retctx, PKT_secret_key * sk, - strlist_t names, KBNODE * ret_keyblock) -{ - return key_byname (retctx, names, NULL, sk, 1, 1, ret_keyblock, NULL); -} - - -int -get_seckey_next (GETKEY_CTX ctx, PKT_secret_key * sk, KBNODE * ret_keyblock) -{ - int rc; - - rc = lookup (ctx, ret_keyblock, 1); - if (!rc && sk && ret_keyblock) - sk_from_block (ctx, sk, *ret_keyblock); - - return rc; -} - - -void -get_seckey_end (GETKEY_CTX ctx) -{ - get_pubkey_end (ctx); -} /* Search for a key with the given fingerprint. * FIXME: - * We should replace this with the _byname function. Thiscsan be done + * We should replace this with the _byname function. This can be done * by creating a userID conforming to the unified fingerprint style. */ -int -get_seckey_byfprint (PKT_secret_key * sk, - const byte * fprint, size_t fprint_len) +gpg_error_t +get_seckey_byfprint (PKT_public_key *pk, const byte * fprint, size_t fprint_len) { - int rc; + gpg_error_t err; if (fprint_len == 20 || fprint_len == 16) { struct getkey_ctx_s ctx; - KBNODE kb = NULL; + kbnode_t kb = NULL; memset (&ctx, 0, sizeof ctx); ctx.exact = 1; ctx.not_allocated = 1; - ctx.kr_handle = keydb_new (1); + ctx.kr_handle = keydb_new (); ctx.nitems = 1; ctx.items[0].mode = fprint_len == 16 ? KEYDB_SEARCH_MODE_FPR16 : KEYDB_SEARCH_MODE_FPR20; memcpy (ctx.items[0].u.fpr, fprint, fprint_len); - rc = lookup (&ctx, &kb, 1); - if (!rc && sk) - sk_from_block (&ctx, sk, kb); + err = lookup (&ctx, &kb, 1); + if (!err && pk) + pk_from_block (&ctx, pk, kb); release_kbnode (kb); - get_seckey_end (&ctx); + get_pubkey_end (&ctx); } else - rc = G10ERR_GENERAL; /* Oops */ - return rc; + err = gpg_error (GPG_ERR_BUG); + return err; } /* Search for a secret key with the given fingerprint and return the - complete keyblock which may have more than only this key. */ -int -get_seckeyblock_byfprint (KBNODE * ret_keyblock, const byte * fprint, - size_t fprint_len) + complete keyblock which may have more than only this key. Return + an error if no corresponding secret key is available. */ +gpg_error_t +get_seckeyblock_byfprint (kbnode_t *ret_keyblock, + const byte *fprint, size_t fprint_len) { - int rc; + gpg_error_t err; struct getkey_ctx_s ctx; if (fprint_len != 20 && fprint_len == 16) - return G10ERR_GENERAL; /* Oops */ + return gpg_error (GPG_ERR_BUG); memset (&ctx, 0, sizeof ctx); ctx.not_allocated = 1; - ctx.kr_handle = keydb_new (1); + ctx.kr_handle = keydb_new (); ctx.nitems = 1; ctx.items[0].mode = (fprint_len == 16 ? KEYDB_SEARCH_MODE_FPR16 : KEYDB_SEARCH_MODE_FPR20); memcpy (ctx.items[0].u.fpr, fprint, fprint_len); - rc = lookup (&ctx, ret_keyblock, 1); - get_seckey_end (&ctx); + err = lookup (&ctx, ret_keyblock, 1); + get_pubkey_end (&ctx); - return rc; + return err; } @@ -1220,7 +1141,7 @@ gpg_error_t getkey_bynames (getkey_ctx_t *retctx, PKT_public_key *pk, strlist_t names, int want_secret, kbnode_t *ret_keyblock) { - return key_byname (retctx, names, pk, NULL, want_secret, 1, + return key_byname (retctx, names, pk, want_secret, 1, ret_keyblock, NULL); } @@ -1238,7 +1159,7 @@ getkey_bynames (getkey_ctx_t *retctx, PKT_public_key *pk, * * FIXME: Explain what is up with unusable keys. * - * FIXME: We also have the get_pubkey_byname fucntion which has a + * FIXME: We also have the get_pubkey_byname function which has a * different semantic. Should be merged with this one. */ gpg_error_t @@ -1256,7 +1177,7 @@ getkey_byname (getkey_ctx_t *retctx, PKT_public_key *pk, else with_unusable = 0; - err = key_byname (retctx, namelist, pk, NULL, want_secret, with_unusable, + err = key_byname (retctx, namelist, pk, want_secret, with_unusable, ret_keyblock, NULL); /* FIXME: Check that we really return GPG_ERR_NO_SECKEY if @@ -2538,7 +2459,7 @@ lookup (getkey_ctx_t ctx, kbnode_t *ret_keyblock, int want_secret) goto skip; } - if (want_secret && have_secret_key (ctx->keyblock)) + if (want_secret && !have_any_secret_key (NULL, ctx->keyblock)) goto skip; /* No secret key available. */ /* Warning: node flag bits 0 and 1 should be preserved by @@ -2586,9 +2507,7 @@ found: /**************** * FIXME: Replace by the generic function * It does not work as it is right now - it is used at - * 2 places: a) to get the key for an anonyous recipient - * b) to get the ultimately trusted keys. - * The a) usage might have some problems. + * one place: to get the key for an anonymous recipient. * * set with_subkeys true to include subkeys * set with_spm true to include secret-parts-missing keys @@ -2606,6 +2525,10 @@ int enum_secret_keys (void **context, PKT_secret_key * sk, int with_subkeys, int with_spm) { + log_debug ("FIXME: Anonymous recipient does not yet work\n"); + return -1; +#if 0 + int rc = 0; struct { @@ -2622,7 +2545,7 @@ enum_secret_keys (void **context, PKT_secret_key * sk, /* Make a new context. */ c = xmalloc_clear (sizeof *c); *context = c; - c->hd = keydb_new (1); + c->hd = keydb_new (1); /*FIXME*/ c->first = 1; c->keyblock = NULL; c->node = NULL; @@ -2676,6 +2599,7 @@ enum_secret_keys (void **context, PKT_secret_key * sk, while (!rc); return rc; /* Error. */ +#endif } @@ -2893,37 +2817,71 @@ parse_auto_key_locate (char *options) } -/* Return 0 if a secret key is available for the key described by - KEYBLOCK. FIXME: How do we handel subkeys? */ -gpg_error_t -have_secret_key (kbnode_t keyblock) +/* Return true if a secret key or secret subkey is available for one + of the public keys in KEYBLOCK. */ +int +have_any_secret_key (ctrl_t ctrl, kbnode_t keyblock) +{ + kbnode_t node; + + for (node = keyblock; node; node = node->next) + if ((node->pkt->pkttype == PKT_PUBLIC_KEY + || node->pkt->pkttype == PKT_PUBLIC_SUBKEY) + && !agent_probe_secret_key (ctrl, node->pkt->pkt.public_key)) + return 1; + return 0; +} + + +/* Return true if a secret key is available for the public key with + * the given KEYID. This is just a fast check and does not tell us + * whether the secret key is valid. It merely tells os whether there + * is some secret key. */ +int +have_secret_key_with_kid (u32 *keyid) { gpg_error_t err; - unsigned char fpr[MAX_FINGERPRINT_LEN]; - size_t fprlen; - KEYDB_HANDLE kdh; + KEYDB_HANDLE kdbhd; + KEYDB_SEARCH_DESC desc; + kbnode_t keyblock; + kbnode_t node; + int result = 0; - if (!keyblock || keyblock->pkt->pkttype != PKT_PUBLIC_KEY) - return gpg_error (GPG_ERR_NO_PUBKEY); /* Should not happen. */ + kdbhd = keydb_new (); + memset (&desc, 0, sizeof desc); + desc.mode = KEYDB_SEARCH_MODE_LONG_KID; + desc.u.kid[0] = keyid[0]; + desc.u.kid[1] = keyid[1]; + while (!result && !(err = keydb_search (kdbhd, &desc, 1))) + { + desc.mode = KEYDB_SEARCH_MODE_NEXT; + err = keydb_get_keyblock (kdbhd, &keyblock); + if (err) + { + log_error (_("error reading keyblock: %s\n"), g10_errstr (err)); + break; + } - fingerprint_from_pk (keyblock->pkt->pkt.public_key, fpr, &fprlen); - while (fprlen < MAX_FINGERPRINT_LEN) - fpr[fprlen++] = 0; + for (node = keyblock; node; node = node->next) + { + /* Bit 0 of the flags is set if the search found the key + using that key or subkey. */ + if ((node->flag & 1)) + { + assert (node->pkt->pkttype == PKT_PUBLIC_KEY + || node->pkt->pkttype == PKT_PUBLIC_SUBKEY); - /* FIXME: Always allocating a new handle is too slow. However this - entire implementation is anyway a temporary solution until we can - ask gpg-agent for the secret key. */ - kdh = keydb_new (1); - if (!kdh) - return gpg_error (GPG_ERR_GENERAL); - - err = keydb_search_fpr (kdh, fpr); - if (err == -1 || gpg_err_code (err) == GPG_ERR_EOF) - err = gpg_error (GPG_ERR_NO_SECKEY); - - keydb_release (kdh); - - return err; + if (!agent_probe_secret_key (NULL, node->pkt->pkt.public_key)) + { + result = 1; + break; + } + } + } + release_kbnode (keyblock); + } + keydb_release (kdbhd); + return result; } diff --git a/g10/gpgv.c b/g10/gpgv.c index ed3752f72..a57844c5f 100644 --- a/g10/gpgv.c +++ b/g10/gpgv.c @@ -533,3 +533,10 @@ remove_lockfiles (void) { } +gpg_error_t +agent_probe_secret_key (ctrl_t ctrl, PKT_public_key *pk) +{ + (void)ctrl; + (void)pk; + return gpg_error (GPG_ERR_NO_SECKEY); +} diff --git a/g10/import.c b/g10/import.c index c1ff93c0f..6d02a4988 100644 --- a/g10/import.c +++ b/g10/import.c @@ -800,7 +800,7 @@ import_one( const char *fname, KBNODE keyblock, struct stats_s *stats, stats->skipped_new_keys++; } else if( rc ) { /* insert this key */ - KEYDB_HANDLE hd = keydb_new (0); + KEYDB_HANDLE hd = keydb_new (); rc = keydb_locate_writable (hd, NULL); if (rc) { @@ -861,7 +861,7 @@ import_one( const char *fname, KBNODE keyblock, struct stats_s *stats, } /* now read the original keyblock */ - hd = keydb_new (0); + hd = keydb_new (); { byte afp[MAX_FINGERPRINT_LEN]; size_t an; @@ -1012,17 +1012,17 @@ import_one( const char *fname, KBNODE keyblock, struct stats_s *stats, need to check if a designated revocation is present or if the prefs are not rational so we can warn the user. */ - if(mod_key) + if (mod_key) { - revocation_present(keyblock_orig); - if(!from_sk && seckey_available(keyid)==0) - check_prefs(keyblock_orig); + revocation_present (keyblock_orig); + if (!from_sk && have_secret_key_with_kid (keyid)) + check_prefs (keyblock_orig); } - else if(new_key) + else if (new_key) { - revocation_present(keyblock); - if(!from_sk && seckey_available(keyid)==0) - check_prefs(keyblock); + revocation_present (keyblock); + if (!from_sk && have_secret_key_with_kid (keyid)) + check_prefs (keyblock); } release_kbnode( keyblock_orig ); @@ -1160,11 +1160,16 @@ import_secret_one( const char *fname, KBNODE keyblock, clear_kbnode_flags( keyblock ); /* do we have this key already in one of our secrings ? */ - rc = seckey_available( keyid ); + rc = -1 /* fixme seckey_available( keyid ) is not anymore + available and has been replaced by + have_secret_key_with_kid. We need to rework the entire + secret key import code. The solution I am currently + thinking about is to move that code into a helper + program. */; if( rc == G10ERR_NO_SECKEY && !(opt.import_options&IMPORT_MERGE_ONLY) ) { /* simply insert this key */ - KEYDB_HANDLE hd = keydb_new (1); + KEYDB_HANDLE hd = keydb_new (); /* FIXME*/ /* get default resource */ rc = keydb_locate_writable (hd, NULL); @@ -1265,7 +1270,7 @@ import_revoke_cert( const char *fname, KBNODE node, struct stats_s *stats ) } /* read the original keyblock */ - hd = keydb_new (0); + hd = keydb_new (); { byte afp[MAX_FINGERPRINT_LEN]; size_t an; @@ -1594,7 +1599,7 @@ delete_inv_parts( const char *fname, KBNODE keyblock, else if( node->pkt->pkttype == PKT_SIGNATURE && !node->pkt->pkt.signature->flags.exportable && !(options&IMPORT_LOCAL_SIGS) && - seckey_available( node->pkt->pkt.signature->keyid ) ) + !have_secret_key_with_kid (node->pkt->pkt.signature->keyid)) { /* here we violate the rfc a bit by still allowing * to import non-exportable signature when we have the @@ -2395,8 +2400,9 @@ auto_create_card_key_stub ( const char *serialnostr, ; else return G10ERR_GENERAL; - - hd = keydb_new (1); + + log_debug ("FIXME: Do we need the stub at all?\n"); + hd = keydb_new (); /* FIXME. */ /* Now check whether there is a secret keyring. */ { diff --git a/g10/keydb.c b/g10/keydb.c index a50a5a9d0..20cf63491 100644 --- a/g10/keydb.c +++ b/g10/keydb.c @@ -348,10 +348,11 @@ keydb_add_resource (const char *url, int flags, int secret) KEYDB_HANDLE -keydb_new (int secret) +keydb_new (void) { KEYDB_HANDLE hd; int i, j; + int secret = 0; /* FIXME: Remove the secret stuff all together. */ hd = xmalloc_clear (sizeof *hd); hd->found = -1; diff --git a/g10/keydb.h b/g10/keydb.h index 508226e94..404102cc4 100644 --- a/g10/keydb.h +++ b/g10/keydb.h @@ -24,6 +24,7 @@ #include #include "types.h" +#include "util.h" #include "packet.h" #include "cipher.h" @@ -132,7 +133,7 @@ union pref_hint Flag 2 == default */ int keydb_add_resource (const char *url, int flags, int secret); -KEYDB_HANDLE keydb_new (int secret); +KEYDB_HANDLE keydb_new (void); void keydb_release (KEYDB_HANDLE hd); const char *keydb_get_resource_name (KEYDB_HANDLE hd); int keydb_get_keyblock (KEYDB_HANDLE hd, KBNODE *ret_kb); @@ -207,26 +208,22 @@ int get_pubkey_bynames( GETKEY_CTX *rx, PKT_public_key *pk, strlist_t names, KBNODE *ret_keyblock ); int get_pubkey_next( GETKEY_CTX ctx, PKT_public_key *pk, KBNODE *ret_keyblock ); void get_pubkey_end( GETKEY_CTX ctx ); -int get_seckey( PKT_secret_key *sk, u32 *keyid ); -int get_primary_seckey( PKT_secret_key *sk, u32 *keyid ); +gpg_error_t get_seckey (PKT_public_key *pk, u32 *keyid); int get_pubkey_byfprint( PKT_public_key *pk, const byte *fprint, size_t fprint_len ); int get_pubkey_byfprint_fast (PKT_public_key *pk, const byte *fprint, size_t fprint_len); int get_keyblock_byfprint( KBNODE *ret_keyblock, const byte *fprint, size_t fprint_len ); -int get_keyblock_bylid( KBNODE *ret_keyblock, ulong lid ); -int seckey_available( u32 *keyid ); -int get_seckey_byname( PKT_secret_key *sk, const char *name, int unlock ); -int get_seckey_bynames( GETKEY_CTX *rx, PKT_secret_key *sk, - strlist_t names, KBNODE *ret_keyblock ); -int get_seckey_next (GETKEY_CTX ctx, PKT_secret_key *sk, KBNODE *ret_keyblock); -void get_seckey_end( GETKEY_CTX ctx ); -int get_seckey_byfprint( PKT_secret_key *sk, - const byte *fprint, size_t fprint_len); -int get_seckeyblock_byfprint (KBNODE *ret_keyblock, const byte *fprint, - size_t fprint_len ); +int have_secret_key_with_kid (u32 *keyid); + +gpg_error_t get_seckey_byname (PKT_public_key *pk, const char *name); + +gpg_error_t get_seckey_byfprint (PKT_public_key *pk, + const byte *fprint, size_t fprint_len); +gpg_error_t get_seckeyblock_byfprint (kbnode_t *ret_keyblock, + const byte *fprint, size_t fprint_len); gpg_error_t getkey_bynames (getkey_ctx_t *retctx, PKT_public_key *pk, strlist_t names, int want_secret, @@ -238,7 +235,7 @@ gpg_error_t getkey_next (getkey_ctx_t ctx, PKT_public_key *pk, kbnode_t *ret_keyblock); void getkey_end (getkey_ctx_t ctx); -gpg_error_t have_secret_key (kbnode_t keyblock); +int have_any_secret_key (ctrl_t ctrl, kbnode_t keyblock); int enum_secret_keys( void **context, PKT_secret_key *sk, diff --git a/g10/keyedit.c b/g10/keyedit.c index 7d54849b3..f9dfe7a4e 100644 --- a/g10/keyedit.c +++ b/g10/keyedit.c @@ -45,6 +45,7 @@ #include "status.h" #include "i18n.h" #include "keyserver-internal.h" +#include "call-agent.h" static void show_prefs (PKT_user_id * uid, PKT_signature * selfsig, int verbose); @@ -54,22 +55,18 @@ static void show_key_with_all_names (KBNODE keyblock, int only_marked, int with_revoker, int with_fpr, int with_subkeys, int with_prefs); static void show_key_and_fingerprint (KBNODE keyblock); -static int menu_adduid (KBNODE keyblock, KBNODE sec_keyblock, - int photo, const char *photo_name); -static void menu_deluid (KBNODE pub_keyblock, KBNODE sec_keyblock); +static int menu_adduid (KBNODE keyblock, int photo, const char *photo_name); +static void menu_deluid (KBNODE pub_keyblock); static int menu_delsig (KBNODE pub_keyblock); static int menu_clean (KBNODE keyblock, int self_only); -static void menu_delkey (KBNODE pub_keyblock, KBNODE sec_keyblock); -static int menu_addrevoker (KBNODE pub_keyblock, - KBNODE sec_keyblock, int sensitive); -static int menu_expire (KBNODE pub_keyblock, KBNODE sec_keyblock); -static int menu_backsign (KBNODE pub_keyblock, KBNODE sec_keyblock); -static int menu_set_primary_uid (KBNODE pub_keyblock, KBNODE sec_keyblock); -static int menu_set_preferences (KBNODE pub_keyblock, KBNODE sec_keyblock); -static int menu_set_keyserver_url (const char *url, - KBNODE pub_keyblock, KBNODE sec_keyblock); -static int menu_set_notation (const char *string, - KBNODE pub_keyblock, KBNODE sec_keyblock); +static void menu_delkey (KBNODE pub_keyblock); +static int menu_addrevoker (KBNODE pub_keyblock, int sensitive); +static int menu_expire (KBNODE pub_keyblock); +static int menu_backsign (KBNODE pub_keyblock); +static int menu_set_primary_uid (KBNODE pub_keyblock); +static int menu_set_preferences (KBNODE pub_keyblock); +static int menu_set_keyserver_url (const char *url, KBNODE pub_keyblock); +static int menu_set_notation (const char *string, KBNODE pub_keyblock); static int menu_select_uid (KBNODE keyblock, int idx); static int menu_select_uid_namehash (KBNODE keyblock, const char *namehash); static int menu_select_key (KBNODE keyblock, int idx); @@ -80,9 +77,9 @@ static int count_selected_uids (KBNODE keyblock); static int real_uids_left (KBNODE keyblock); static int count_selected_keys (KBNODE keyblock); static int menu_revsig (KBNODE keyblock); -static int menu_revuid (KBNODE keyblock, KBNODE sec_keyblock); -static int menu_revkey (KBNODE pub_keyblock, KBNODE sec_keyblock); -static int menu_revsubkey (KBNODE pub_keyblock, KBNODE sec_keyblock); +static int menu_revuid (KBNODE keyblock); +static int menu_revkey (KBNODE pub_keyblock); +static int menu_revsubkey (KBNODE pub_keyblock); static int enable_disable_key (KBNODE keyblock, int disable); static void menu_showphoto (KBNODE keyblock); @@ -120,6 +117,7 @@ find_pk_from_sknode (KBNODE pub_keyblock, KBNODE sec_node) PKT_secret_key *sk; PKT_public_key *pk; +#warning: This is not anymore needed. if (sec_node->pkt->pkttype == PKT_SECRET_KEY && node->pkt->pkttype == PKT_PUBLIC_KEY) return node->pkt->pkt.public_key; @@ -525,7 +523,7 @@ trustsig_prompt (byte * trust_value, byte * trust_depth, char **regexp) /* - * Loop over all locusr and and sign the uids after asking. + * Loop over all LOCUSR and and sign the uids after asking. * If no user id is marked, all user ids will be signed; * if some user_ids are marked those will be signed. */ @@ -572,18 +570,11 @@ sign_uids (KBNODE keyblock, strlist_t locusr, int *ret_modified, u32 duration = 0, timestamp = 0; byte trust_depth = 0, trust_value = 0; - if (local || nonrevocable || trust || - opt.cert_policy_url || opt.cert_notations) + if (local || nonrevocable || trust + || opt.cert_policy_url || opt.cert_notations) force_v4 = 1; - /* We have to use a copy of the pk, because make_keysig_packet - * may remove the protection from sk and if we did other - * changes to the secret key, we would save the unprotected - * version. FIXME: This can be removed because all protection - * is now done by gpg-agent. */ - if (pk) - free_public_key (pk); - pk = copy_public_key (NULL, sk_rover->pk); + pk = sk_rover->pk; keyid_from_pk (pk, sk_keyid); /* Set mark A for all selected user ids. */ @@ -594,6 +585,7 @@ sign_uids (KBNODE keyblock, strlist_t locusr, int *ret_modified, else node->flag &= ~NODFLG_MARK_A; } + /* Reset mark for uids which are already signed. */ uidnode = NULL; for (node = keyblock; node; node = node->next) @@ -620,10 +612,10 @@ sign_uids (KBNODE keyblock, strlist_t locusr, int *ret_modified, if (uidnode) { int yesreally = 0; - char *user = - utf8_to_native (uidnode->pkt->pkt.user_id->name, - uidnode->pkt->pkt.user_id->len, - 0); + char *user; + + user = utf8_to_native (uidnode->pkt->pkt.user_id->name, + uidnode->pkt->pkt.user_id->len, 0); if (uidnode->pkt->pkt.user_id->is_revoked) { @@ -730,10 +722,10 @@ sign_uids (KBNODE keyblock, strlist_t locusr, int *ret_modified, && sk_keyid[1] == node->pkt->pkt.signature->keyid[1]) { char buf[50]; - char *user = - utf8_to_native (uidnode->pkt->pkt.user_id->name, - uidnode->pkt->pkt.user_id->len, - 0); + char *user; + + user = utf8_to_native (uidnode->pkt->pkt.user_id->name, + uidnode->pkt->pkt.user_id->len, 0); /* It's a v3 self-sig. Make it into a v4 self-sig? */ if (node->pkt->pkt.signature->version < 4 && selfsig) @@ -811,9 +803,9 @@ sign_uids (KBNODE keyblock, strlist_t locusr, int *ret_modified, /* Fixme: see whether there is a revocation in which * case we should allow to sign it again. */ if (!node->pkt->pkt.signature->flags.exportable && local) - tty_printf (_ - ("\"%s\" was already locally signed by key %s\n"), - user, keystr_from_pk (pk)); + tty_printf + (_("\"%s\" was already locally signed by key %s\n"), + user, keystr_from_pk (pk)); else tty_printf (_("\"%s\" was already signed by key %s\n"), user, keystr_from_pk (pk)); @@ -1057,7 +1049,7 @@ sign_uids (KBNODE keyblock, strlist_t locusr, int *ret_modified, _("Really sign? (y/N) "))) continue; - /* Now we can sign the user ids */ + /* Now we can sign the user ids. */ reloop: /* (Must use this, because we are modifing the list.) */ primary_pk = NULL; for (node = keyblock; node; node = node->next) @@ -1125,8 +1117,6 @@ sign_uids (KBNODE keyblock, strlist_t locusr, int *ret_modified, leave: release_sk_list (sk_list); - if (pk) - free_public_key (pk); return rc; } @@ -1141,32 +1131,33 @@ change_passphrase (KBNODE keyblock, int *r_err) int rc = 0; int changed = 0; KBNODE node; - PKT_secret_key *sk; + PKT_public_key *pksk; char *passphrase = NULL; int no_primary_secrets = 0; int any; - node = find_kbnode (keyblock, PKT_SECRET_KEY); + node = find_kbnode (keyblock, PKT_PUBLIC_KEY); if (!node) { - log_error ("Oops; secret key not found anymore!\n"); + log_error ("Oops; public key missing!\n"); goto leave; } - sk = node->pkt->pkt.secret_key; + pksk = node->pkt->pkt.public_key; for (any = 0, node = keyblock; node; node = node->next) { - if (node->pkt->pkttype == PKT_SECRET_KEY - || node->pkt->pkttype == PKT_SECRET_SUBKEY) + if (node->pkt->pkttype == PKT_PUBLIC_KEY + || node->pkt->pkttype == PKT_PUBLIC_SUBKEY) { - PKT_secret_key *tmpsk = node->pkt->pkt.secret_key; - if (!(tmpsk->is_protected - && (tmpsk->protect.s2k.mode == 1001 - || tmpsk->protect.s2k.mode == 1002))) - { - any = 1; - break; - } + log_debug ("FIXME\n"); + /* PKT_public_key *tmpsk = node->pkt->pkt.public_key; */ + /* if (!(tmpsk->is_protected */ + /* && (tmpsk->protect.s2k.mode == 1001 */ + /* || tmpsk->protect.s2k.mode == 1002))) */ + /* { */ + /* any = 1; */ + /* break; */ + /* } */ } } if (!any) @@ -1176,59 +1167,61 @@ change_passphrase (KBNODE keyblock, int *r_err) goto leave; } + log_debug ("FIXME\n"); /* See how to handle this key. */ - switch (is_secret_key_protected (sk)) - { - case -1: - rc = G10ERR_PUBKEY_ALGO; - break; - case 0: - tty_printf (_("This key is not protected.\n")); - break; - default: - if (sk->protect.s2k.mode == 1001) - { - tty_printf (_("Secret parts of key are not available.\n")); - no_primary_secrets = 1; - } - else if (sk->protect.s2k.mode == 1002) - { - tty_printf (_("Secret parts of key are stored on-card.\n")); - no_primary_secrets = 1; - } - else - { - u32 keyid[2]; + /* switch (is_secret_key_protected (pksk)) */ + /* { */ + /* case -1: */ + /* rc = G10ERR_PUBKEY_ALGO; */ + /* break; */ + /* case 0: */ + /* tty_printf (_("This key is not protected.\n")); */ + /* break; */ + /* default: */ + /* if (sk->protect.s2k.mode == 1001) */ + /* { */ + /* tty_printf (_("Secret parts of key are not available.\n")); */ + /* no_primary_secrets = 1; */ + /* } */ + /* else if (sk->protect.s2k.mode == 1002) */ + /* { */ + /* tty_printf (_("Secret parts of key are stored on-card.\n")); */ + /* no_primary_secrets = 1; */ + /* } */ + /* else */ + /* { */ + /* u32 keyid[2]; */ - tty_printf (_("Key is protected.\n")); + /* tty_printf (_("Key is protected.\n")); */ - /* Clear the passphrase cache so that the user is required - to enter the old passphrase. */ - keyid_from_sk (sk, keyid); - passphrase_clear_cache (keyid, NULL, 0); + /* /\* Clear the passphrase cache so that the user is required */ + /* to enter the old passphrase. *\/ */ + /* keyid_from_pk (pksk, keyid); */ + /* passphrase_clear_cache (keyid, NULL, 0); */ - /* rc = check_secret_key( sk, 0 ); */ - /* if( !rc ) */ - /* passphrase = get_last_passphrase(); */ - } - break; - } + /* /\* rc = check_secret_key( sk, 0 ); *\/ */ + /* /\* if( !rc ) *\/ */ + /* /\* passphrase = get_last_passphrase(); *\/ */ + /* } */ + /* break; */ + /* } */ /* Unprotect all subkeys (use the supplied passphrase or ask) */ for (node = keyblock; !rc && node; node = node->next) { - if (node->pkt->pkttype == PKT_SECRET_SUBKEY) + if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY) { - PKT_secret_key *subsk = node->pkt->pkt.secret_key; - if (!(subsk->is_protected - && (subsk->protect.s2k.mode == 1001 - || subsk->protect.s2k.mode == 1002))) - { - set_next_passphrase (passphrase); - /* rc = check_secret_key( subsk, 0 ); */ - /* if( !rc && !passphrase ) */ - /* passphrase = get_last_passphrase(); */ - } + log_debug ("FIXME\n"); + /* PKT_pubic_key *subsk = node->pkt->pkt.public_key; */ + /* if (!(subsk->is_protected */ + /* && (subsk->protect.s2k.mode == 1001 */ + /* || subsk->protect.s2k.mode == 1002))) */ + /* { */ + /* set_next_passphrase (passphrase); */ + /* /\* rc = check_secret_key( subsk, 0 ); *\/ */ + /* /\* if( !rc && !passphrase ) *\/ */ + /* /\* passphrase = get_last_passphrase(); *\/ */ + /* } */ } } @@ -1279,9 +1272,8 @@ change_passphrase (KBNODE keyblock, int *r_err) rc = 0; if (!no_primary_secrets) { - sk->protect.algo = dek->algo; - sk->protect.s2k = *s2k; -#warning fixme + /* sk->protect.algo = dek->algo; */ + /* sk->protect.s2k = *s2k; */ rc = 0; /* rc = protect_secret_key( sk, dek ); */ } @@ -1289,17 +1281,18 @@ change_passphrase (KBNODE keyblock, int *r_err) { if (node->pkt->pkttype == PKT_SECRET_SUBKEY) { - PKT_secret_key *subsk = node->pkt->pkt.secret_key; - if (!(subsk->is_protected - && (subsk->protect.s2k.mode == 1001 - || subsk->protect.s2k.mode == 1002))) - { - subsk->protect.algo = dek->algo; - subsk->protect.s2k = *s2k; -#warning fixme - rc = 0; - /* rc = protect_secret_key( subsk, dek ); */ - } + log_debug ("FIXME\n"); +/* PKT_secret_key *subsk = node->pkt->pkt.secret_key; */ +/* if (!(subsk->is_protected */ +/* && (subsk->protect.s2k.mode == 1001 */ +/* || subsk->protect.s2k.mode == 1002))) */ +/* { */ +/* subsk->protect.algo = dek->algo; */ +/* subsk->protect.s2k = *s2k; */ +/* #warning fixme */ +/* rc = 0; */ +/* /\* rc = protect_secret_key( subsk, dek ); *\/ */ +/* } */ } } if (rc) @@ -1312,7 +1305,7 @@ change_passphrase (KBNODE keyblock, int *r_err) /* Clear the cahce again so that the user is required to enter the new passphrase at the next operation. */ - keyid_from_sk (sk, keyid); + /* FIXME keyid_from_sk (sk, keyid); */ passphrase_clear_cache (keyid, NULL, 0); changed++; @@ -1333,6 +1326,7 @@ leave: } + /* * There are some keys out (due to a bug in gnupg), where the sequence * of the packets is wrong. This function fixes that. @@ -1380,6 +1374,7 @@ fix_keyblock (KBNODE keyblock) return fixed; } + static int parse_sign_type (const char *str, int *localsig, int *nonrevokesig, int *trustsig) @@ -1587,23 +1582,22 @@ keyedit_completion (const char *text, int start, int end) +/* Main function of the menu driven key editor. */ void keyedit_menu (const char *username, strlist_t locusr, strlist_t commands, int quiet, int seckey_check) { enum cmdids cmd = 0; - int rc = 0; + gpg_error_t err = 0; KBNODE keyblock = NULL; KEYDB_HANDLE kdbhd = NULL; - KBNODE sec_keyblock = NULL; - KEYDB_HANDLE sec_kdbhd = NULL; - KBNODE cur_keyblock; + int have_seckey = 0; char *answer = NULL; int redisplay = 1; int modified = 0; - int sec_modified = 0; int toggle; int have_commands = !!commands; + ctrl_t ctrl = NULL; /* Dummy for now. */ if (opt.command_fd != -1) ; @@ -1627,8 +1621,8 @@ keyedit_menu (const char *username, strlist_t locusr, #endif /* Get the public key */ - rc = get_pubkey_byname (NULL, NULL, username, &keyblock, &kdbhd, 1, 1); - if (rc) + err = get_pubkey_byname (NULL, NULL, username, &keyblock, &kdbhd, 1, 1); + if (err) goto leave; if (fix_keyblock (keyblock)) modified++; @@ -1640,53 +1634,19 @@ keyedit_menu (const char *username, strlist_t locusr, if (modified) merge_keys_and_selfsig (keyblock); + /* See whether we have a matching secret key. */ if (seckey_check) { - /* See whether we have a matching secret key. */ - PKT_public_key *pk = keyblock->pkt->pkt.public_key; - - sec_kdbhd = keydb_new (1); - { - byte afp[MAX_FINGERPRINT_LEN]; - size_t an; - - fingerprint_from_pk (pk, afp, &an); - while (an < MAX_FINGERPRINT_LEN) - afp[an++] = 0; - rc = keydb_search_fpr (sec_kdbhd, afp); - } - if (!rc) - { - rc = keydb_get_keyblock (sec_kdbhd, &sec_keyblock); - if (rc) - { - log_error (_("error reading secret keyblock \"%s\": %s\n"), - username, g10_errstr (rc)); - } - else - { - merge_keys_and_selfsig (sec_keyblock); - if (fix_keyblock (sec_keyblock)) - sec_modified++; - } - } - - if (rc) - { - sec_keyblock = NULL; - keydb_release (sec_kdbhd); - sec_kdbhd = NULL; - rc = 0; - } - - if (sec_keyblock && !quiet) + have_seckey = have_any_secret_key (ctrl, keyblock); + if (have_seckey && !quiet) tty_printf (_("Secret key is available.\n")); } toggle = 0; - cur_keyblock = keyblock; + + /* Main command loop. */ for (;;) - { /* main loop */ + { int i, arg_number, photo; const char *arg_string = ""; char *p; @@ -1696,7 +1656,7 @@ keyedit_menu (const char *username, strlist_t locusr, if (redisplay && !quiet) { - show_key_with_all_names (cur_keyblock, 0, 1, 0, 1, 0); + show_key_with_all_names (keyblock, 0, 1, 0, 1, 0); tty_printf ("\n"); redisplay = 0; } @@ -1730,8 +1690,8 @@ keyedit_menu (const char *username, strlist_t locusr, } while (*answer == '#'); - arg_number = 0; /* Yes, here is the init which egcc complains about */ - photo = 0; /* This too */ + arg_number = 0; /* Here is the init which egcc complains about. */ + photo = 0; /* Same here. */ if (!*answer) cmd = cmdLIST; else if (*answer == CONTROL_D) @@ -1760,8 +1720,7 @@ keyedit_menu (const char *username, strlist_t locusr, size_t a = strlen (answer); if (a >= l) { - if (ascii_strcasecmp (&answer[a - l], cmds[i].name) == - 0) + if (!ascii_strcasecmp (&answer[a - l], cmds[i].name)) { answer[a - l] = '\0'; break; @@ -1771,14 +1730,13 @@ keyedit_menu (const char *username, strlist_t locusr, else if (!ascii_strcasecmp (answer, cmds[i].name)) break; } - if ((cmds[i].flags & KEYEDIT_NEED_SK) && !sec_keyblock) + if ((cmds[i].flags & KEYEDIT_NEED_SK) && !have_seckey) { tty_printf (_("Need the secret key to do this.\n")); cmd = cmdNOP; } - else if (((cmds[i].flags & KEYEDIT_NOT_SK) && sec_keyblock - && toggle) - || ((cmds[i].flags & KEYEDIT_ONLY_SK) && sec_keyblock + else if (((cmds[i].flags & KEYEDIT_NOT_SK) && have_seckey && toggle) + || ((cmds[i].flags & KEYEDIT_ONLY_SK) && have_seckey && !toggle)) { tty_printf (_("Please use the command \"toggle\" first.\n")); @@ -1787,13 +1745,15 @@ keyedit_menu (const char *username, strlist_t locusr, else cmd = cmds[i].id; } + + /* Dispatch the command. */ switch (cmd) { case cmdHELP: for (i = 0; cmds[i].name; i++) { - if ((cmds[i].flags & KEYEDIT_NEED_SK) && !sec_keyblock) - ; /* skip if we do not have the secret key */ + if ((cmds[i].flags & KEYEDIT_NEED_SK) && !have_seckey) + ; /* Skip those item if we do not have the secret key. */ else if (cmds[i].desc) tty_printf ("%-11s %s\n", cmds[i].name, _(cmds[i].desc)); } @@ -1806,7 +1766,6 @@ keyedit_menu (const char *username, strlist_t locusr, "non-revocable signatures\n" " (nrsign), or any combination thereof (ltsign, " "tnrsign, etc.).\n")); - break; case cmdLIST: @@ -1819,13 +1778,13 @@ keyedit_menu (const char *username, strlist_t locusr, case cmdSELUID: if (strlen (arg_string) == NAMEHASH_LEN * 2) - redisplay = menu_select_uid_namehash (cur_keyblock, arg_string); + redisplay = menu_select_uid_namehash (keyblock, arg_string); else { if (*arg_string == '*' && (!arg_string[1] || spacep (arg_string + 1))) arg_number = -1; /* Select all. */ - redisplay = menu_select_uid (cur_keyblock, arg_number); + redisplay = menu_select_uid (keyblock, arg_number); } break; @@ -1834,19 +1793,16 @@ keyedit_menu (const char *username, strlist_t locusr, if (*arg_string == '*' && (!arg_string[1] || spacep (arg_string + 1))) arg_number = -1; /* Select all. */ - if (menu_select_key (cur_keyblock, arg_number)) + if (menu_select_key (keyblock, arg_number)) redisplay = 1; } break; case cmdCHECK: - /* we can only do this with the public key becuase the - * check functions can't cope with secret keys and it - * is questionable whether this would make sense at all */ check_all_keysigs (keyblock, count_selected_uids (keyblock)); break; - case cmdSIGN: /* sign (only the public key) */ + case cmdSIGN: { int localsig = 0, nonrevokesig = 0, trustsig = 0, interactive = 0; @@ -1898,33 +1854,33 @@ keyedit_menu (const char *username, strlist_t locusr, break; case cmdDEBUG: - dump_kbnode (cur_keyblock); + dump_kbnode (keyblock); break; case cmdTOGGLE: + /* The toggle command is a leftover from old gpg versions + where we worked with a secret and a public keyring. It + is not necessary anymore but we keep this command for the + sake of scripts using it. */ toggle = !toggle; - cur_keyblock = toggle ? sec_keyblock : keyblock; redisplay = 1; break; case cmdADDPHOTO: if (RFC2440 || RFC1991 || PGP2) { - tty_printf (_ - ("This command is not allowed while in %s mode.\n"), + tty_printf (_("This command is not allowed while in %s mode.\n"), compliance_option_string ()); break; } photo = 1; /* fall through */ - case cmdADDUID: - if (menu_adduid (keyblock, sec_keyblock, photo, arg_string)) + if (menu_adduid (keyblock, photo, arg_string)) { update_trust = 1; redisplay = 1; - sec_modified = modified = 1; - merge_keys_and_selfsig (sec_keyblock); + modified = 1; merge_keys_and_selfsig (keyblock); } break; @@ -1942,11 +1898,9 @@ keyedit_menu (const char *username, strlist_t locusr, n1 > 1 ? _("Really remove all selected user IDs? (y/N) ") : _("Really remove this user ID? (y/N) "))) { - menu_deluid (keyblock, sec_keyblock); + menu_deluid (keyblock); redisplay = 1; modified = 1; - if (sec_keyblock) - sec_modified = 1; } } break; @@ -1959,8 +1913,8 @@ keyedit_menu (const char *username, strlist_t locusr, tty_printf (_("You must select at least one user ID.\n")); else if (menu_delsig (keyblock)) { - /* no redisplay here, because it may scroll away some - * status output of delsig */ + /* No redisplay here, because it may scroll away some + * of the status output of this command. */ modified = 1; } } @@ -1970,19 +1924,17 @@ keyedit_menu (const char *username, strlist_t locusr, if (!generate_subkeypair (keyblock)) { redisplay = 1; - sec_modified = modified = 1; - merge_keys_and_selfsig (sec_keyblock); + modified = 1; merge_keys_and_selfsig (keyblock); } break; #ifdef ENABLE_CARD_SUPPORT case cmdADDCARDKEY: - if (card_generate_subkey (keyblock, sec_keyblock)) + if (card_generate_subkey (keyblock)) { redisplay = 1; - sec_modified = modified = 1; - merge_keys_and_selfsig (sec_keyblock); + modified = 1; merge_keys_and_selfsig (keyblock); } break; @@ -1990,7 +1942,7 @@ keyedit_menu (const char *username, strlist_t locusr, case cmdKEYTOCARD: { KBNODE node = NULL; - switch (count_selected_keys (sec_keyblock)) + switch (count_selected_keys (keyblock)) { case 0: if (cpr_get_answer_is_yes @@ -1998,12 +1950,12 @@ keyedit_menu (const char *username, strlist_t locusr, /* TRANSLATORS: Please take care: This is about moving the key and not about removing it. */ _("Really move the primary key? (y/N) "))) - node = sec_keyblock; + node = keyblock; break; case 1: - for (node = sec_keyblock; node; node = node->next) + for (node = keyblock; node; node = node->next) { - if (node->pkt->pkttype == PKT_SECRET_SUBKEY + if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY && node->flag & NODFLG_SELKEY) break; } @@ -2018,7 +1970,8 @@ keyedit_menu (const char *username, strlist_t locusr, if (card_store_subkey (node, xxpk ? xxpk->pubkey_usage : 0)) { redisplay = 1; - sec_modified = 1; + /* Only the secret key has been modified; thus + there is no need to set the modified flag. */ } } } @@ -2026,6 +1979,7 @@ keyedit_menu (const char *username, strlist_t locusr, case cmdBKUPTOCARD: case cmdCHECKBKUPKEY: + log_debug ("FIXME: This needs to be changed\n"); { /* Ask for a filename, check whether this is really a backup key as generated by the card generation, parse @@ -2060,17 +2014,16 @@ keyedit_menu (const char *username, strlist_t locusr, /* Parse and check that file. */ pkt = xmalloc (sizeof *pkt); init_packet (pkt); - rc = parse_packet (a, pkt); + err = parse_packet (a, pkt); iobuf_close (a); - iobuf_ioctl (NULL, IOBUF_IOCTL_INVALIDATE_CACHE, 0, - (char *) fname); - if (!rc && pkt->pkttype != PKT_SECRET_KEY + iobuf_ioctl (NULL, IOBUF_IOCTL_INVALIDATE_CACHE, 0, (char *) fname); + if (!err && pkt->pkttype != PKT_SECRET_KEY && pkt->pkttype != PKT_SECRET_SUBKEY) - rc = G10ERR_NO_SECKEY; - if (rc) + err = G10ERR_NO_SECKEY; + if (err) { tty_printf (_("Error reading backup key from `%s': %s\n"), - fname, g10_errstr (rc)); + fname, g10_errstr (err)); free_packet (pkt); xfree (pkt); break; @@ -2104,7 +2057,7 @@ keyedit_menu (const char *username, strlist_t locusr, if (card_store_subkey (node, 0)) { redisplay = 1; - sec_modified = 1; + /* FIXME:sec_modified = 1;*/ } } release_kbnode (node); @@ -2127,11 +2080,9 @@ keyedit_menu (const char *username, strlist_t locusr, ; else { - menu_delkey (keyblock, sec_keyblock); + menu_delkey (keyblock); redisplay = 1; modified = 1; - if (sec_keyblock) - sec_modified = 1; } } break; @@ -2142,11 +2093,10 @@ keyedit_menu (const char *username, strlist_t locusr, if (ascii_strcasecmp (arg_string, "sensitive") == 0) sensitive = 1; - if (menu_addrevoker (keyblock, sec_keyblock, sensitive)) + if (menu_addrevoker (keyblock, sensitive)) { redisplay = 1; - sec_modified = modified = 1; - merge_keys_and_selfsig (sec_keyblock); + modified = 1; merge_keys_and_selfsig (keyblock); } } @@ -2163,7 +2113,7 @@ keyedit_menu (const char *username, strlist_t locusr, n1 > 1 ? _("Really revoke all selected user IDs? (y/N) ") : _("Really revoke this user ID? (y/N) "))) { - if (menu_revuid (keyblock, sec_keyblock)) + if (menu_revuid (keyblock)) { modified = 1; redisplay = 1; @@ -2182,7 +2132,7 @@ keyedit_menu (const char *username, strlist_t locusr, _("Do you really want to revoke" " the entire key? (y/N) "))) { - if (menu_revkey (keyblock, sec_keyblock)) + if (menu_revkey (keyblock)) modified = 1; redisplay = 1; @@ -2195,7 +2145,7 @@ keyedit_menu (const char *username, strlist_t locusr, : _("Do you really want to revoke" " this subkey? (y/N) "))) { - if (menu_revsubkey (keyblock, sec_keyblock)) + if (menu_revsubkey (keyblock)) modified = 1; redisplay = 1; @@ -2207,27 +2157,24 @@ keyedit_menu (const char *username, strlist_t locusr, break; case cmdEXPIRE: - if (menu_expire (keyblock, sec_keyblock)) + if (menu_expire (keyblock)) { - merge_keys_and_selfsig (sec_keyblock); merge_keys_and_selfsig (keyblock); - sec_modified = 1; modified = 1; redisplay = 1; } break; case cmdBACKSIGN: - if (menu_backsign (keyblock, sec_keyblock)) + if (menu_backsign (keyblock)) { - sec_modified = 1; modified = 1; redisplay = 1; } break; case cmdPRIMARY: - if (menu_set_primary_uid (keyblock, sec_keyblock)) + if (menu_set_primary_uid (keyblock)) { merge_keys_and_selfsig (keyblock); modified = 1; @@ -2236,8 +2183,7 @@ keyedit_menu (const char *username, strlist_t locusr, break; case cmdPASSWD: - if (change_passphrase (sec_keyblock, NULL)) - sec_modified = 1; + change_passphrase (keyblock, NULL); break; case cmdTRUST: @@ -2298,7 +2244,7 @@ keyedit_menu (const char *username, strlist_t locusr, " for the selected user IDs? (y/N) ") : _("Really update the preferences? (y/N) "))) { - if (menu_set_preferences (keyblock, sec_keyblock)) + if (menu_set_preferences (keyblock)) { merge_keys_and_selfsig (keyblock); modified = 1; @@ -2310,7 +2256,7 @@ keyedit_menu (const char *username, strlist_t locusr, case cmdPREFKS: if (menu_set_keyserver_url (*arg_string ? arg_string : NULL, - keyblock, sec_keyblock)) + keyblock)) { merge_keys_and_selfsig (keyblock); modified = 1; @@ -2320,7 +2266,7 @@ keyedit_menu (const char *username, strlist_t locusr, case cmdNOTATION: if (menu_set_notation (*arg_string ? arg_string : NULL, - keyblock, sec_keyblock)) + keyblock)) { merge_keys_and_selfsig (keyblock); modified = 1; @@ -2365,7 +2311,7 @@ keyedit_menu (const char *username, strlist_t locusr, case cmdQUIT: if (have_commands) goto leave; - if (!modified && !sec_modified) + if (!modified) goto leave; if (!cpr_get_answer_is_yes ("keyedit.save.okay", _("Save changes? (y/N) "))) @@ -2378,27 +2324,14 @@ keyedit_menu (const char *username, strlist_t locusr, } /* fall thru */ case cmdSAVE: - if (modified || sec_modified) + if (modified) { - if (modified) - { - rc = keydb_update_keyblock (kdbhd, keyblock); - if (rc) - { - log_error (_("update failed: %s\n"), g10_errstr (rc)); - break; - } - } - if (sec_modified) - { - rc = keydb_update_keyblock (sec_kdbhd, sec_keyblock); - if (rc) - { - log_error (_("update secret failed: %s\n"), - g10_errstr (rc)); - break; - } - } + err = keydb_update_keyblock (kdbhd, keyblock); + if (err) + { + log_error (_("update failed: %s\n"), g10_errstr (err)); + break; + } } else tty_printf (_("Key not changed so no update needed.\n")); @@ -2416,11 +2349,10 @@ keyedit_menu (const char *username, strlist_t locusr, tty_printf (_("Invalid command (try \"help\")\n")); break; } - } /* end main loop */ + } /* End of the main command loop. */ -leave: + leave: release_kbnode (keyblock); - release_kbnode (sec_keyblock); keydb_release (kdbhd); xfree (answer); } @@ -2452,8 +2384,8 @@ keyedit_passwd (const char *username) /* FIXME: Call an agent function instead. */ - kdh = keydb_new (1); - if (!kdh) + kdh = NULL /*keydb_new (1)*/; + if (!kdh) { err = gpg_error (GPG_ERR_GENERAL); goto leave; @@ -2687,6 +2619,7 @@ show_prefs (PKT_user_id * uid, PKT_signature * selfsig, int verbose) } } + /* This is the version of show_key_with_all_names used when opt.with_colons is used. It prints all available data in a easy to parse format and does not translate utf8 */ @@ -3217,22 +3150,19 @@ no_primary_warning (KBNODE keyblock) /* - * Ask for a new user id, do the selfsignature and put it into - * both keyblocks. + * Ask for a new user id, add the self-signature and update the keyblock. * Return true if there is a new user id */ static int -menu_adduid (KBNODE pub_keyblock, KBNODE sec_keyblock, - int photo, const char *photo_name) +menu_adduid (KBNODE pub_keyblock, int photo, const char *photo_name) { PKT_user_id *uid; PKT_public_key *pk = NULL; - PKT_secret_key *sk = NULL; PKT_signature *sig = NULL; PACKET *pkt; KBNODE node; - KBNODE pub_where = NULL, sec_where = NULL; - int rc; + KBNODE pub_where = NULL; + gpg_error_t err; for (node = pub_keyblock; node; pub_where = node, node = node->next) { @@ -3241,18 +3171,9 @@ menu_adduid (KBNODE pub_keyblock, KBNODE sec_keyblock, else if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY) break; } - if (!node) /* no subkey */ + if (!node) /* No subkey. */ pub_where = NULL; - for (node = sec_keyblock; node; sec_where = node, node = node->next) - { - if (node->pkt->pkttype == PKT_SECRET_KEY) - sk = copy_secret_key (NULL, node->pkt->pkt.secret_key); - else if (node->pkt->pkttype == PKT_SECRET_SUBKEY) - break; - } - if (!node) /* no subkey */ - sec_where = NULL; - assert (pk && sk); + assert (pk); if (photo) { @@ -3299,33 +3220,16 @@ menu_adduid (KBNODE pub_keyblock, KBNODE sec_keyblock, if (!uid) return 0; - rc = make_keysig_packet (&sig, pk, uid, NULL, sk, 0x13, 0, 0, 0, 0, - keygen_add_std_prefs, pk); - free_secret_key (sk); - if (rc) + err = make_keysig_packet (&sig, pk, uid, NULL, pk, 0x13, 0, 0, 0, 0, + keygen_add_std_prefs, pk); + if (err) { - log_error ("signing failed: %s\n", g10_errstr (rc)); + log_error ("signing failed: %s\n", g10_errstr (err)); free_user_id (uid); return 0; } - /* insert/append to secret keyblock */ - pkt = xmalloc_clear (sizeof *pkt); - pkt->pkttype = PKT_USER_ID; - pkt->pkt.user_id = scopy_user_id (uid); - node = new_kbnode (pkt); - if (sec_where) - insert_kbnode (sec_where, node, 0); - else - add_kbnode (sec_keyblock, node); - pkt = xmalloc_clear (sizeof *pkt); - pkt->pkttype = PKT_SIGNATURE; - pkt->pkt.signature = copy_signature (NULL, sig); - if (sec_where) - insert_kbnode (node, new_kbnode (pkt), 0); - else - add_kbnode (sec_keyblock, new_kbnode (pkt)); - /* insert/append to public keyblock */ + /* Insert/append to public keyblock */ pkt = xmalloc_clear (sizeof *pkt); pkt->pkttype = PKT_USER_ID; pkt->pkt.user_id = uid; @@ -3345,11 +3249,11 @@ menu_adduid (KBNODE pub_keyblock, KBNODE sec_keyblock, } -/**************** - * Remove all selected userids from the keyrings +/* + * Remove all selected userids from the keyring */ static void -menu_deluid (KBNODE pub_keyblock, KBNODE sec_keyblock) +menu_deluid (KBNODE pub_keyblock) { KBNODE node; int selected = 0; @@ -3366,30 +3270,6 @@ menu_deluid (KBNODE pub_keyblock, KBNODE sec_keyblock) if (!node->pkt->pkt.user_id->is_revoked) update_trust = 1; delete_kbnode (node); - if (sec_keyblock) - { - KBNODE snode; - int s_selected = 0; - PKT_user_id *uid = node->pkt->pkt.user_id; - for (snode = sec_keyblock; snode; snode = snode->next) - { - if (snode->pkt->pkttype == PKT_USER_ID) - { - PKT_user_id *suid = snode->pkt->pkt.user_id; - - s_selected = - (uid->len == suid->len - && !memcmp (uid->name, suid->name, uid->len)); - if (s_selected) - delete_kbnode (snode); - } - else if (s_selected - && snode->pkt->pkttype == PKT_SIGNATURE) - delete_kbnode (snode); - else if (snode->pkt->pkttype == PKT_SECRET_SUBKEY) - s_selected = 0; - } - } } } else if (selected && node->pkt->pkttype == PKT_SIGNATURE) @@ -3398,8 +3278,6 @@ menu_deluid (KBNODE pub_keyblock, KBNODE sec_keyblock) selected = 0; } commit_kbnode (&pub_keyblock); - if (sec_keyblock) - commit_kbnode (&sec_keyblock); } @@ -3543,11 +3421,12 @@ menu_clean (KBNODE keyblock, int self_only) return modified; } -/**************** + +/* * Remove some of the secondary keys */ static void -menu_delkey (KBNODE pub_keyblock, KBNODE sec_keyblock) +menu_delkey (KBNODE pub_keyblock) { KBNODE node; int selected = 0; @@ -3558,34 +3437,7 @@ menu_delkey (KBNODE pub_keyblock, KBNODE sec_keyblock) { selected = node->flag & NODFLG_SELKEY; if (selected) - { - delete_kbnode (node); - if (sec_keyblock) - { - KBNODE snode; - int s_selected = 0; - u32 ki[2]; - - keyid_from_pk (node->pkt->pkt.public_key, ki); - for (snode = sec_keyblock; snode; snode = snode->next) - { - if (snode->pkt->pkttype == PKT_SECRET_SUBKEY) - { - u32 ki2[2]; - - keyid_from_sk (snode->pkt->pkt.secret_key, ki2); - s_selected = (ki[0] == ki2[0] && ki[1] == ki2[1]); - if (s_selected) - delete_kbnode (snode); - } - else if (s_selected - && snode->pkt->pkttype == PKT_SIGNATURE) - delete_kbnode (snode); - else - s_selected = 0; - } - } - } + delete_kbnode (node); } else if (selected && node->pkt->pkttype == PKT_SIGNATURE) delete_kbnode (node); @@ -3593,25 +3445,22 @@ menu_delkey (KBNODE pub_keyblock, KBNODE sec_keyblock) selected = 0; } commit_kbnode (&pub_keyblock); - if (sec_keyblock) - commit_kbnode (&sec_keyblock); /* No need to set update_trust here since signing keys are no longer used to certify other keys, so there is no change in - trust when revoking/removing them */ + trust when revoking/removing them. */ } -/**************** - * Ask for a new revoker, do the selfsignature and put it into - * both keyblocks. - * Return true if there is a new revoker +/* + * Ask for a new revoker, create the self-signature and put it into + * the keyblock. Returns true if there is a new revoker. */ static int -menu_addrevoker (KBNODE pub_keyblock, KBNODE sec_keyblock, int sensitive) +menu_addrevoker (KBNODE pub_keyblock, int sensitive) { - PKT_public_key *pk = NULL, *revoker_pk = NULL; - PKT_secret_key *sk = NULL; + PKT_public_key *pk = NULL; + PKT_public_key *revoker_pk = NULL; PKT_signature *sig = NULL; PACKET *pkt; struct revocation_key revkey; @@ -3619,7 +3468,6 @@ menu_addrevoker (KBNODE pub_keyblock, KBNODE sec_keyblock, int sensitive) int rc; assert (pub_keyblock->pkt->pkttype == PKT_PUBLIC_KEY); - assert (sec_keyblock->pkt->pkttype == PKT_SECRET_KEY); pk = pub_keyblock->pkt->pkt.public_key; @@ -3649,8 +3497,6 @@ menu_addrevoker (KBNODE pub_keyblock, KBNODE sec_keyblock, int sensitive) } } - sk = copy_secret_key (NULL, sec_keyblock->pkt->pkt.secret_key); - for (;;) { char *answer; @@ -3662,10 +3508,10 @@ menu_addrevoker (KBNODE pub_keyblock, KBNODE sec_keyblock, int sensitive) tty_printf ("\n"); - answer = cpr_get_utf8 ("keyedit.add_revoker", - _ - ("Enter the user ID of the designated revoker: ")); - if (answer[0] == '\0' || answer[0] == '\004') + answer = cpr_get_utf8 + ("keyedit.add_revoker", + _("Enter the user ID of the designated revoker: ")); + if (answer[0] == '\0' || answer[0] == CONTROL_D) { xfree (answer); goto fail; @@ -3673,8 +3519,7 @@ menu_addrevoker (KBNODE pub_keyblock, KBNODE sec_keyblock, int sensitive) /* Note that I'm requesting CERT here, which usually implies primary keys only, but some casual testing shows that PGP and - GnuPG both can handle a designated revokation from a - subkey. */ + GnuPG both can handle a designated revocation from a subkey. */ revoker_pk->req_usage = PUBKEY_USAGE_CERT; rc = get_pubkey_byname (NULL, revoker_pk, answer, NULL, NULL, 1, 1); if (rc) @@ -3763,7 +3608,7 @@ menu_addrevoker (KBNODE pub_keyblock, KBNODE sec_keyblock, int sensitive) /* The 1F signature must be at least v4 to carry the revocation key subpacket. */ - rc = make_keysig_packet (&sig, pk, NULL, NULL, sk, 0x1F, 0, 4, 0, 0, + rc = make_keysig_packet (&sig, pk, NULL, NULL, pk, 0x1F, 0, 4, 0, 0, keygen_add_revkey, &revkey); if (rc) { @@ -3771,16 +3616,7 @@ menu_addrevoker (KBNODE pub_keyblock, KBNODE sec_keyblock, int sensitive) goto fail; } - free_secret_key (sk); - sk = NULL; - - /* insert into secret keyblock */ - pkt = xmalloc_clear (sizeof *pkt); - pkt->pkttype = PKT_SIGNATURE; - pkt->pkt.signature = copy_signature (NULL, sig); - insert_kbnode (sec_keyblock, new_kbnode (pkt), PKT_SIGNATURE); - - /* insert into public keyblock */ + /* Insert into public keyblock. */ pkt = xmalloc_clear (sizeof *pkt); pkt->pkttype = PKT_SIGNATURE; pkt->pkt.signature = sig; @@ -3789,8 +3625,6 @@ menu_addrevoker (KBNODE pub_keyblock, KBNODE sec_keyblock, int sensitive) return 1; fail: - if (sk) - free_secret_key (sk); if (sig) free_seckey_enc (sig); if (revoker_pk) @@ -3801,23 +3635,16 @@ fail: static int -menu_expire (KBNODE pub_keyblock, KBNODE sec_keyblock) +menu_expire (KBNODE pub_keyblock) { int n1, signumber, rc; u32 expiredate; int mainkey = 0; - PKT_secret_key *sk; /* copy of the main sk */ PKT_public_key *main_pk, *sub_pk; PKT_user_id *uid; KBNODE node; u32 keyid[2]; - if (count_selected_keys (sec_keyblock)) - { - tty_printf (_("Please remove selections from the secret keys.\n")); - return 0; - } - n1 = count_selected_keys (pub_keyblock); if (n1 > 1) { @@ -3834,10 +3661,8 @@ menu_expire (KBNODE pub_keyblock, KBNODE sec_keyblock) } expiredate = ask_expiredate (); - node = find_kbnode (sec_keyblock, PKT_SECRET_KEY); - sk = copy_secret_key (NULL, node->pkt->pkt.secret_key); - /* Now we can actually change the self signature(s) */ + /* Now we can actually change the self-signature(s) */ main_pk = sub_pk = NULL; uid = NULL; signumber = 0; @@ -3867,11 +3692,9 @@ menu_expire (KBNODE pub_keyblock, KBNODE sec_keyblock) || (!mainkey && sig->sig_class == 0x18)) && sig->flags.chosen_selfsig) { - /* this is a selfsignature which is to be replaced */ + /* This is a self-signature which is to be replaced. */ PKT_signature *newsig; PACKET *newpkt; - KBNODE sn; - int signumber2 = 0; signumber++; @@ -3880,81 +3703,53 @@ menu_expire (KBNODE pub_keyblock, KBNODE sec_keyblock) { log_info (_("You can't change the expiration date of a v3 key\n")); - free_secret_key (sk); return 0; } - /* find the corresponding secret self-signature */ - for (sn = sec_keyblock; sn; sn = sn->next) - { - if (sn->pkt->pkttype == PKT_SIGNATURE) - { - PKT_signature *b = sn->pkt->pkt.signature; - if (keyid[0] == b->keyid[0] && keyid[1] == b->keyid[1] - && sig->sig_class == b->sig_class - && ++signumber2 == signumber) - break; - } - } - if (!sn) - log_info (_("No corresponding signature in secret ring\n")); - if (mainkey) rc = update_keysig_packet (&newsig, sig, main_pk, uid, NULL, - sk, keygen_add_key_expire, + main_pk, keygen_add_key_expire, main_pk); else rc = update_keysig_packet (&newsig, sig, main_pk, NULL, sub_pk, - sk, keygen_add_key_expire, sub_pk); + main_pk, keygen_add_key_expire, sub_pk); if (rc) { log_error ("make_keysig_packet failed: %s\n", g10_errstr (rc)); - free_secret_key (sk); return 0; } - /* replace the packet */ + + /* Replace the packet. */ newpkt = xmalloc_clear (sizeof *newpkt); newpkt->pkttype = PKT_SIGNATURE; newpkt->pkt.signature = newsig; free_packet (node->pkt); xfree (node->pkt); node->pkt = newpkt; - if (sn) - { - newpkt = xmalloc_clear (sizeof *newpkt); - newpkt->pkttype = PKT_SIGNATURE; - newpkt->pkt.signature = copy_signature (NULL, newsig); - free_packet (sn->pkt); - xfree (sn->pkt); - sn->pkt = newpkt; - } sub_pk = NULL; } } } - free_secret_key (sk); update_trust = 1; return 1; } + static int -menu_backsign (KBNODE pub_keyblock, KBNODE sec_keyblock) +menu_backsign (KBNODE pub_keyblock) { int rc, modified = 0; PKT_public_key *main_pk; - PKT_secret_key *main_sk, *sub_sk = NULL; KBNODE node; u32 timestamp; assert (pub_keyblock->pkt->pkttype == PKT_PUBLIC_KEY); - assert (sec_keyblock->pkt->pkttype == PKT_SECRET_KEY); merge_keys_and_selfsig (pub_keyblock); main_pk = pub_keyblock->pkt->pkt.public_key; - main_sk = copy_secret_key (NULL, sec_keyblock->pkt->pkt.secret_key); keyid_from_pk (main_pk, NULL); /* We use the same timestamp for all backsigs so that we don't @@ -3964,14 +3759,8 @@ menu_backsign (KBNODE pub_keyblock, KBNODE sec_keyblock) for (node = pub_keyblock; node; node = node->next) { PKT_public_key *sub_pk = NULL; - KBNODE node2, sig_pk = NULL, sig_sk = NULL; - char *passphrase; - - if (sub_sk) - { - free_secret_key (sub_sk); - sub_sk = NULL; - } + KBNODE node2, sig_pk = NULL /*,sig_sk = NULL*/; + /* char *passphrase; */ /* Find a signing subkey with no backsig */ if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY) @@ -4008,64 +3797,28 @@ menu_backsign (KBNODE pub_keyblock, KBNODE sec_keyblock) continue; /* Find the secret subkey that matches the public subkey */ - for (node2 = sec_keyblock; node2; node2 = node2->next) - if (node2->pkt->pkttype == PKT_SECRET_SUBKEY - && !cmp_public_secret_key (sub_pk, node2->pkt->pkt.secret_key)) - { - sub_sk = copy_secret_key (NULL, node2->pkt->pkt.secret_key); - break; - } + log_debug ("FIXME: Check whether a secret subkey is available.\n"); + /* if (!sub_sk) */ + /* { */ + /* tty_printf (_("no secret subkey for public subkey %s - ignoring\n"), */ + /* keystr_from_pk (sub_pk)); */ + /* continue; */ + /* } */ - if (!sub_sk) - { - tty_printf (_("no secret subkey for public subkey %s - ignoring\n"), - keystr_from_pk (sub_pk)); - continue; - } - /* Now finally find the matching selfsig on the secret subkey. - We can't use chosen_selfsig here (it's not set for secret - keys), so we just pick the selfsig with the right class. - This is what menu_expire does as well. */ - for (node2 = node2->next; - node2 && node2->pkt->pkttype != PKT_SECRET_SUBKEY; - node2 = node2->next) - if (node2->pkt->pkttype == PKT_SIGNATURE - && node2->pkt->pkt.signature->version >= 4 - && node2->pkt->pkt.signature->keyid[0] == - sig_pk->pkt->pkt.signature->keyid[0] - && node2->pkt->pkt.signature->keyid[1] == - sig_pk->pkt->pkt.signature->keyid[1] - && node2->pkt->pkt.signature->sig_class == - sig_pk->pkt->pkt.signature->sig_class) - { - sig_sk = node2; - break; - } + /* Now we can get to work. */ - /* Now we can get to work. We have a main key and secret part, - a signing subkey with signature and secret part possibly with - signature. */ - - passphrase = get_last_passphrase (); - set_next_passphrase (passphrase); - xfree (passphrase); - - rc = make_backsig (sig_pk->pkt->pkt.signature, main_pk, sub_pk, sub_sk, + rc = make_backsig (sig_pk->pkt->pkt.signature, main_pk, sub_pk, sub_pk, timestamp); - if (rc == 0) + if (!rc) { PKT_signature *newsig; PACKET *newpkt; - passphrase = get_last_passphrase (); - set_next_passphrase (passphrase); - xfree (passphrase); - - rc = - update_keysig_packet (&newsig, sig_pk->pkt->pkt.signature, - main_pk, NULL, sub_pk, main_sk, NULL, NULL); - if (rc == 0) + rc = update_keysig_packet (&newsig, sig_pk->pkt->pkt.signature, + main_pk, NULL, sub_pk, main_pk, + NULL, NULL); + if (!rc) { /* Put the new sig into place on the pubkey */ newpkt = xmalloc_clear (sizeof (*newpkt)); @@ -4075,17 +3828,6 @@ menu_backsign (KBNODE pub_keyblock, KBNODE sec_keyblock) xfree (sig_pk->pkt); sig_pk->pkt = newpkt; - if (sig_sk) - { - /* Put the new sig into place on the seckey */ - newpkt = xmalloc_clear (sizeof (*newpkt)); - newpkt->pkttype = PKT_SIGNATURE; - newpkt->pkt.signature = copy_signature (NULL, newsig); - free_packet (sig_sk->pkt); - xfree (sig_sk->pkt); - sig_sk->pkt = newpkt; - } - modified = 1; } else @@ -4102,12 +3844,6 @@ menu_backsign (KBNODE pub_keyblock, KBNODE sec_keyblock) } } - set_next_passphrase (NULL); - - free_secret_key (main_sk); - if (sub_sk) - free_secret_key (sub_sk); - return modified; } @@ -4142,9 +3878,8 @@ change_primary_uid_cb (PKT_signature * sig, void *opaque) * sufficient to updated a signature during import. */ static int -menu_set_primary_uid (KBNODE pub_keyblock, KBNODE sec_keyblock) +menu_set_primary_uid (KBNODE pub_keyblock) { - PKT_secret_key *sk; /* copy of the main sk */ PKT_public_key *main_pk; PKT_user_id *uid; KBNODE node; @@ -4159,10 +3894,6 @@ menu_set_primary_uid (KBNODE pub_keyblock, KBNODE sec_keyblock) return 0; } - node = find_kbnode (sec_keyblock, PKT_SECRET_KEY); - sk = copy_secret_key (NULL, node->pkt->pkt.secret_key); - - /* Now we can actually change the self signature(s) */ main_pk = NULL; uid = NULL; selected = 0; @@ -4175,7 +3906,7 @@ menu_set_primary_uid (KBNODE pub_keyblock, KBNODE sec_keyblock) for (node = pub_keyblock; node; node = node->next) { if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY) - break; /* ready */ + break; /* No more user ids expected - ready. */ if (node->pkt->pkttype == PKT_PUBLIC_KEY) { @@ -4200,9 +3931,8 @@ menu_set_primary_uid (KBNODE pub_keyblock, KBNODE sec_keyblock) char *user = utf8_to_native (uid->name, strlen (uid->name), 0); - log_info (_ - ("skipping v3 self-signature on user ID \"%s\"\n"), - user); + log_info (_("skipping v3 self-signature on user ID \"%s\"\n"), + user); xfree (user); } else @@ -4224,7 +3954,7 @@ menu_set_primary_uid (KBNODE pub_keyblock, KBNODE sec_keyblock) const byte *p; int action; - /* see whether this signature has the primary UID flag */ + /* See whether this signature has the primary UID flag. */ p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_PRIMARY_UID, NULL); if (!p) @@ -4239,14 +3969,13 @@ menu_set_primary_uid (KBNODE pub_keyblock, KBNODE sec_keyblock) { int rc = update_keysig_packet (&newsig, sig, main_pk, uid, NULL, - sk, + main_pk, change_primary_uid_cb, action > 0 ? "x" : NULL); if (rc) { log_error ("update_keysig_packet failed: %s\n", g10_errstr (rc)); - free_secret_key (sk); return 0; } /* replace the packet */ @@ -4263,7 +3992,6 @@ menu_set_primary_uid (KBNODE pub_keyblock, KBNODE sec_keyblock) } } - free_secret_key (sk); return modified; } @@ -4272,9 +4000,8 @@ menu_set_primary_uid (KBNODE pub_keyblock, KBNODE sec_keyblock) * Set preferences to new values for the selected user IDs */ static int -menu_set_preferences (KBNODE pub_keyblock, KBNODE sec_keyblock) +menu_set_preferences (KBNODE pub_keyblock) { - PKT_secret_key *sk; /* copy of the main sk */ PKT_public_key *main_pk; PKT_user_id *uid; KBNODE node; @@ -4286,9 +4013,6 @@ menu_set_preferences (KBNODE pub_keyblock, KBNODE sec_keyblock) select_all = !count_selected_uids (pub_keyblock); - node = find_kbnode (sec_keyblock, PKT_SECRET_KEY); - sk = copy_secret_key (NULL, node->pkt->pkt.secret_key); - /* Now we can actually change the self signature(s) */ main_pk = NULL; uid = NULL; @@ -4296,7 +4020,7 @@ menu_set_preferences (KBNODE pub_keyblock, KBNODE sec_keyblock) for (node = pub_keyblock; node; node = node->next) { if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY) - break; /* ready */ + break; /* No more user-ids expected - ready. */ if (node->pkt->pkttype == PKT_PUBLIC_KEY) { @@ -4321,8 +4045,7 @@ menu_set_preferences (KBNODE pub_keyblock, KBNODE sec_keyblock) char *user = utf8_to_native (uid->name, strlen (uid->name), 0); - log_info (_ - ("skipping v3 self-signature on user ID \"%s\"\n"), + log_info (_("skipping v3 self-signature on user ID \"%s\"\n"), user); xfree (user); } @@ -4330,19 +4053,18 @@ menu_set_preferences (KBNODE pub_keyblock, KBNODE sec_keyblock) { /* This is a selfsignature which is to be replaced * We have to ignore v3 signatures because they are - * not able to carry the preferences */ + * not able to carry the preferences. */ PKT_signature *newsig; PACKET *newpkt; int rc; rc = update_keysig_packet (&newsig, sig, - main_pk, uid, NULL, - sk, keygen_upd_std_prefs, NULL); + main_pk, uid, NULL, main_pk, + keygen_upd_std_prefs, NULL); if (rc) { log_error ("update_keysig_packet failed: %s\n", g10_errstr (rc)); - free_secret_key (sk); return 0; } /* replace the packet */ @@ -4358,16 +4080,13 @@ menu_set_preferences (KBNODE pub_keyblock, KBNODE sec_keyblock) } } - free_secret_key (sk); return modified; } static int -menu_set_keyserver_url (const char *url, - KBNODE pub_keyblock, KBNODE sec_keyblock) +menu_set_keyserver_url (const char *url, KBNODE pub_keyblock) { - PKT_secret_key *sk; /* copy of the main sk */ PKT_public_key *main_pk; PKT_user_id *uid; KBNODE node; @@ -4384,7 +4103,7 @@ menu_set_keyserver_url (const char *url, { answer = cpr_get_utf8 ("keyedit.add_keyserver", _("Enter your preferred keyserver URL: ")); - if (answer[0] == '\0' || answer[0] == '\004') + if (answer[0] == '\0' || answer[0] == CONTROL_D) { xfree (answer); return 0; @@ -4410,9 +4129,6 @@ menu_set_keyserver_url (const char *url, select_all = !count_selected_uids (pub_keyblock); - node = find_kbnode (sec_keyblock, PKT_SECRET_KEY); - sk = copy_secret_key (NULL, node->pkt->pkt.secret_key); - /* Now we can actually change the self signature(s) */ main_pk = NULL; uid = NULL; @@ -4420,7 +4136,7 @@ menu_set_keyserver_url (const char *url, for (node = pub_keyblock; node; node = node->next) { if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY) - break; /* ready */ + break; /* ready */ if (node->pkt->pkttype == PKT_PUBLIC_KEY) { @@ -4455,21 +4171,18 @@ menu_set_keyserver_url (const char *url, const byte *p; size_t plen; - p = - parse_sig_subpkt (sig->hashed, SIGSUBPKT_PREF_KS, &plen); + p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_PREF_KS, &plen); if (p && plen) { tty_printf ("Current preferred keyserver for user" " ID \"%s\": ", user); tty_print_utf8_string (p, plen); tty_printf ("\n"); - if (!cpr_get_answer_is_yes ("keyedit.confirm_keyserver", - uri ? - _ - ("Are you sure you want to replace it? (y/N) ") - : - _ - ("Are you sure you want to delete it? (y/N) "))) + if (!cpr_get_answer_is_yes + ("keyedit.confirm_keyserver", + uri + ? _("Are you sure you want to replace it? (y/N) ") + : _("Are you sure you want to delete it? (y/N) "))) continue; } else if (uri == NULL) @@ -4481,13 +4194,12 @@ menu_set_keyserver_url (const char *url, rc = update_keysig_packet (&newsig, sig, main_pk, uid, NULL, - sk, + main_pk, keygen_add_keyserver_url, uri); if (rc) { log_error ("update_keysig_packet failed: %s\n", g10_errstr (rc)); - free_secret_key (sk); xfree (uri); return 0; } @@ -4507,15 +4219,12 @@ menu_set_keyserver_url (const char *url, } xfree (uri); - free_secret_key (sk); return modified; } static int -menu_set_notation (const char *string, KBNODE pub_keyblock, - KBNODE sec_keyblock) +menu_set_notation (const char *string, KBNODE pub_keyblock) { - PKT_secret_key *sk; /* copy of the main sk */ PKT_public_key *main_pk; PKT_user_id *uid; KBNODE node; @@ -4533,16 +4242,16 @@ menu_set_notation (const char *string, KBNODE pub_keyblock, { answer = cpr_get_utf8 ("keyedit.add_notation", _("Enter the notation: ")); - if (answer[0] == '\0' || answer[0] == '\004') + if (answer[0] == '\0' || answer[0] == CONTROL_D) { xfree (answer); return 0; } } - if (ascii_strcasecmp (answer, "none") == 0 - || ascii_strcasecmp (answer, "-") == 0) - notation = NULL; /* delete them all */ + if (!ascii_strcasecmp (answer, "none") + || !ascii_strcasecmp (answer, "-")) + notation = NULL; /* Delete them all. */ else { notation = string_to_notation (answer, 0); @@ -4557,9 +4266,6 @@ menu_set_notation (const char *string, KBNODE pub_keyblock, select_all = !count_selected_uids (pub_keyblock); - node = find_kbnode (sec_keyblock, PKT_SECRET_KEY); - sk = copy_secret_key (NULL, node->pkt->pkt.secret_key); - /* Now we can actually change the self signature(s) */ main_pk = NULL; uid = NULL; @@ -4567,7 +4273,7 @@ menu_set_notation (const char *string, KBNODE pub_keyblock, for (node = pub_keyblock; node; node = node->next) { if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY) - break; /* ready */ + break; /* ready */ if (node->pkt->pkttype == PKT_PUBLIC_KEY) { @@ -4668,7 +4374,7 @@ menu_set_notation (const char *string, KBNODE pub_keyblock, tty_printf ("Adding notation: %s=%s\n", notation->name, notation->value); - /* We tried to delete, but had no matches */ + /* We tried to delete, but had no matches. */ if (notation->flags.ignore && !deleting) continue; } @@ -4687,13 +4393,12 @@ menu_set_notation (const char *string, KBNODE pub_keyblock, rc = update_keysig_packet (&newsig, sig, main_pk, uid, NULL, - sk, + main_pk, keygen_add_notations, notation); if (rc) { log_error ("update_keysig_packet failed: %s\n", g10_errstr (rc)); - free_secret_key (sk); free_notation (notation); xfree (user); return 0; @@ -4722,7 +4427,6 @@ menu_set_notation (const char *string, KBNODE pub_keyblock, } free_notation (notation); - free_secret_key (sk); return modified; } @@ -4823,7 +4527,8 @@ menu_select_uid_namehash (KBNODE keyblock, const char *namehash) return 1; } -/**************** + +/* * Select secondary keys * Returns: True if the selection changed. */ @@ -4892,6 +4597,7 @@ count_uids_with_flag (KBNODE keyblock, unsigned flag) return i; } + static int count_keys_with_flag (KBNODE keyblock, unsigned flag) { @@ -4905,6 +4611,7 @@ count_keys_with_flag (KBNODE keyblock, unsigned flag) return i; } + static int count_uids (KBNODE keyblock) { @@ -4918,7 +4625,7 @@ count_uids (KBNODE keyblock) } -/**************** +/* * Returns true if there is at least one selected user id */ static int @@ -4927,13 +4634,15 @@ count_selected_uids (KBNODE keyblock) return count_uids_with_flag (keyblock, NODFLG_SELUID); } + static int count_selected_keys (KBNODE keyblock) { return count_keys_with_flag (keyblock, NODFLG_SELKEY); } -/* returns how many real (i.e. not attribute) uids are unmarked */ + +/* Returns how many real (i.e. not attribute) uids are unmarked. */ static int real_uids_left (KBNODE keyblock) { @@ -4948,6 +4657,7 @@ real_uids_left (KBNODE keyblock) return real; } + /* * Ask whether the signature should be revoked. If the user commits this, * flag bit MARK_A is set on the signature and the user ID. @@ -4999,14 +4709,14 @@ ask_revoke_sig (KBNODE keyblock, KBNODE node) tty_printf (_("This signature expired on %s.\n"), expirestr_from_sig (sig)); /* Use a different question so we can have different help text */ - doit = cpr_get_answer_is_yes ("ask_revoke_sig.expired", - _ - ("Are you sure you still want to revoke it? (y/N) ")); + doit = cpr_get_answer_is_yes + ("ask_revoke_sig.expired", + _("Are you sure you still want to revoke it? (y/N) ")); } else - doit = cpr_get_answer_is_yes ("ask_revoke_sig.one", - _ - ("Create a revocation certificate for this signature? (y/N) ")); + doit = cpr_get_answer_is_yes + ("ask_revoke_sig.one", + _("Create a revocation certificate for this signature? (y/N) ")); if (doit) { @@ -5015,7 +4725,8 @@ ask_revoke_sig (KBNODE keyblock, KBNODE node) } } -/**************** + +/* * Display all user ids of the current public key together with signatures * done by one of our keys. Then walk over all this sigs and ask the user * whether he wants to revoke this signature. @@ -5047,7 +4758,7 @@ menu_revsig (KBNODE keyblock) } else if (!skip && node->pkt->pkttype == PKT_SIGNATURE && ((sig = node->pkt->pkt.signature), - !seckey_available (sig->keyid))) + have_secret_key_with_kid (sig->keyid))) { if ((sig->sig_class & ~3) == 0x10) { @@ -5086,7 +4797,7 @@ menu_revsig (KBNODE keyblock) } else if (!skip && node->pkt->pkttype == PKT_SIGNATURE && ((sig = node->pkt->pkt.signature), - !seckey_available (sig->keyid))) + have_secret_key_with_kid (sig->keyid))) { if ((sig->sig_class & ~3) == 0x10) { @@ -5147,9 +4858,9 @@ menu_revsig (KBNODE keyblock) if (!any) return 0; /* none selected */ - if (!cpr_get_answer_is_yes ("ask_revoke_sig.okay", - _ - ("Really create the revocation certificates? (y/N) "))) + if (!cpr_get_answer_is_yes + ("ask_revoke_sig.okay", + _("Really create the revocation certificates? (y/N) "))) return 0; /* forget it */ reason = ask_revocation_reason (0, 1, 0); @@ -5166,7 +4877,7 @@ reloop: /* (must use this, because we are modifing the list) */ KBNODE unode; PACKET *pkt; struct sign_attrib attrib; - PKT_secret_key *sk; + PKT_public_key *signerkey; if (!(node->flag & NODFLG_MARK_A) || node->pkt->pkttype != PKT_SIGNATURE) @@ -5179,17 +4890,18 @@ reloop: /* (must use this, because we are modifing the list) */ attrib.non_exportable = !node->pkt->pkt.signature->flags.exportable; node->flag &= ~NODFLG_MARK_A; - sk = xmalloc_secure_clear (sizeof *sk); - if (get_seckey (sk, node->pkt->pkt.signature->keyid)) + signerkey = xmalloc_secure_clear (sizeof *signerkey); + if (get_seckey (signerkey, node->pkt->pkt.signature->keyid)) { log_info (_("no secret key\n")); + free_public_key (signerkey); continue; } rc = make_keysig_packet (&sig, primary_pk, unode->pkt->pkt.user_id, - NULL, - sk, 0x30, 0, 0, 0, 0, sign_mk_attrib, &attrib); - free_secret_key (sk); + NULL, signerkey, 0x30, 0, 0, 0, 0, + sign_mk_attrib, &attrib); + free_public_key (signerkey); if (rc) { log_error (_("signing failed: %s\n"), g10_errstr (rc)); @@ -5213,14 +4925,13 @@ reloop: /* (must use this, because we are modifing the list) */ return changed; } + /* Revoke a user ID (i.e. revoke a user ID selfsig). Return true if - keyblock changed. */ + keyblock changed. */ static int -menu_revuid (KBNODE pub_keyblock, KBNODE sec_keyblock) +menu_revuid (KBNODE pub_keyblock) { PKT_public_key *pk = pub_keyblock->pkt->pkt.public_key; - PKT_secret_key *sk = copy_secret_key (NULL, - sec_keyblock->pkt->pkt.secret_key); KBNODE node; int changed = 0; int rc; @@ -5241,7 +4952,7 @@ menu_revuid (KBNODE pub_keyblock, KBNODE sec_keyblock) goto leave; } -reloop: /* (better this way because we are modifing the keyring) */ + reloop: /* (better this way because we are modifing the keyring) */ for (node = pub_keyblock; node; node = node->next) if (node->pkt->pkttype == PKT_USER_ID && (node->flag & NODFLG_SELUID)) { @@ -5279,7 +4990,7 @@ reloop: /* (better this way because we are modifing the keyring) */ node->flag &= ~NODFLG_SELUID; - rc = make_keysig_packet (&sig, pk, uid, NULL, sk, 0x30, 0, + rc = make_keysig_packet (&sig, pk, uid, NULL, pk, 0x30, 0, (reason == NULL) ? 3 : 0, timestamp, 0, sign_mk_attrib, &attrib); if (rc) @@ -5313,19 +5024,18 @@ reloop: /* (better this way because we are modifing the keyring) */ commit_kbnode (&pub_keyblock); leave: - free_secret_key (sk); release_revocation_reason_info (reason); return changed; } -/**************** + +/* * Revoke the whole key. */ static int -menu_revkey (KBNODE pub_keyblock, KBNODE sec_keyblock) +menu_revkey (KBNODE pub_keyblock) { PKT_public_key *pk = pub_keyblock->pkt->pkt.public_key; - PKT_secret_key *sk; int rc, changed = 0; struct revocation_reason_info *reason; PACKET *pkt; @@ -5342,11 +5052,9 @@ menu_revkey (KBNODE pub_keyblock, KBNODE sec_keyblock) if (!reason) return 0; - sk = copy_secret_key (NULL, sec_keyblock->pkt->pkt.secret_key); - rc = make_keysig_packet (&sig, pk, NULL, NULL, sk, + rc = make_keysig_packet (&sig, pk, NULL, NULL, pk, 0x20, 0, opt.force_v4_certs ? 4 : 0, 0, 0, revocation_reason_build_cb, reason); - free_secret_key (sk); if (rc) { log_error (_("signing failed: %s\n"), g10_errstr (rc)); @@ -5363,13 +5071,14 @@ menu_revkey (KBNODE pub_keyblock, KBNODE sec_keyblock) update_trust = 1; -scram: + scram: release_revocation_reason_info (reason); return changed; } + static int -menu_revsubkey (KBNODE pub_keyblock, KBNODE sec_keyblock) +menu_revsubkey (KBNODE pub_keyblock) { PKT_public_key *mainpk; KBNODE node; @@ -5379,11 +5088,9 @@ menu_revsubkey (KBNODE pub_keyblock, KBNODE sec_keyblock) reason = ask_revocation_reason (1, 0, 0); if (!reason) - { /* user decided to cancel */ - return 0; - } + return 0; /* User decided to cancel. */ -reloop: /* (better this way because we are modifing the keyring) */ + reloop: /* (better this way because we are modifing the keyring) */ mainpk = pub_keyblock->pkt->pkt.public_key; for (node = pub_keyblock; node; node = node->next) { @@ -5392,7 +5099,6 @@ reloop: /* (better this way because we are modifing the keyring) */ { PACKET *pkt; PKT_signature *sig; - PKT_secret_key *sk; PKT_public_key *subpk = node->pkt->pkt.public_key; struct sign_attrib attrib; @@ -5407,10 +5113,8 @@ reloop: /* (better this way because we are modifing the keyring) */ attrib.reason = reason; node->flag &= ~NODFLG_SELKEY; - sk = copy_secret_key (NULL, sec_keyblock->pkt->pkt.secret_key); - rc = make_keysig_packet (&sig, mainpk, NULL, subpk, sk, + rc = make_keysig_packet (&sig, mainpk, NULL, subpk, mainpk, 0x28, 0, 0, 0, 0, sign_mk_attrib, &attrib); - free_secret_key (sk); if (rc) { log_error (_("signing failed: %s\n"), g10_errstr (rc)); @@ -5418,7 +5122,7 @@ reloop: /* (better this way because we are modifing the keyring) */ return changed; } changed = 1; /* we changed the keyblock */ - + pkt = xmalloc_clear (sizeof *pkt); pkt->pkttype = PKT_SIGNATURE; pkt->pkt.signature = sig; @@ -5427,7 +5131,6 @@ reloop: /* (better this way because we are modifing the keyring) */ } } commit_kbnode (&pub_keyblock); - /*commit_kbnode( &sec_keyblock ); */ /* No need to set update_trust here since signing keys no longer are used to certify other keys, so there is no change in trust @@ -5437,6 +5140,7 @@ reloop: /* (better this way because we are modifing the keyring) */ return changed; } + /* Note that update_ownertrust is going to mark the trustdb dirty when enabling or disabling a key. This is arguably sub-optimal as disabled keys are still counted in the web of trust, but perhaps diff --git a/g10/keygen.c b/g10/keygen.c index 89f5e032d..56a6cc0eb 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -3310,7 +3310,7 @@ do_generate_keypair (struct para_data_s *para, } else if (!err) /* Write to the standard keyrings. */ { - KEYDB_HANDLE pub_hd = keydb_new (0); + KEYDB_HANDLE pub_hd = keydb_new (); err = keydb_locate_writable (pub_hd, NULL); if (err) diff --git a/g10/keylist.c b/g10/keylist.c index 5d08c0d53..969bf50bd 100644 --- a/g10/keylist.c +++ b/g10/keylist.c @@ -420,7 +420,7 @@ list_all (int secret) memset (&stats, 0, sizeof (stats)); - hd = keydb_new (0); + hd = keydb_new (); if (!hd) rc = G10ERR_GENERAL; else @@ -441,7 +441,7 @@ list_all (int secret) log_error ("keydb_get_keyblock failed: %s\n", g10_errstr (rc)); goto leave; } - if (secret && have_secret_key (keyblock)) + if (secret && !have_any_secret_key (NULL, keyblock)) ; /* Secret key listing requested but this isn't one. */ else { diff --git a/g10/keyserver.c b/g10/keyserver.c index 461444f1c..27f52719d 100644 --- a/g10/keyserver.c +++ b/g10/keyserver.c @@ -1719,7 +1719,7 @@ keyidlist(strlist_t users,KEYDB_SEARCH_DESC **klist,int *count,int fakev3) *klist=xmalloc(sizeof(KEYDB_SEARCH_DESC)*num); - kdbhd=keydb_new(0); + kdbhd=keydb_new (); if(!users) { diff --git a/g10/mainproc.c b/g10/mainproc.c index a61325aba..2b2d29dc2 100644 --- a/g10/mainproc.c +++ b/g10/mainproc.c @@ -395,7 +395,7 @@ proc_pubkey_enc( CTX c, PACKET *pkt ) experience if wildcard keyids are used. */ if ( !c->dek && ((!enc->keyid[0] && !enc->keyid[1]) || opt.try_all_secrets - || !seckey_available( enc->keyid )) ) { + || have_secret_key_with_kid (enc->keyid)) ) { if( opt.list_only ) result = -1; else { diff --git a/g10/pkclist.c b/g10/pkclist.c index ca5624a4b..394346cd6 100644 --- a/g10/pkclist.c +++ b/g10/pkclist.c @@ -697,7 +697,7 @@ key_present_in_pk_list(PK_LIST pk_list, PKT_public_key *pk) static char * default_recipient(void) { - PKT_secret_key *sk; + PKT_public_key *pk; byte fpr[MAX_FINGERPRINT_LEN+1]; size_t n; char *p; @@ -707,15 +707,15 @@ default_recipient(void) return xstrdup( opt.def_recipient ); if( !opt.def_recipient_self ) return NULL; - sk = xmalloc_clear( sizeof *sk ); - i = get_seckey_byname( sk, NULL, 0 ); + pk = xmalloc_clear( sizeof *pk ); + i = get_seckey_byname (pk, NULL); if( i ) { - free_secret_key( sk ); + free_public_key( pk ); return NULL; } n = MAX_FINGERPRINT_LEN; - fingerprint_from_sk( sk, fpr, &n ); - free_secret_key( sk ); + fingerprint_from_pk( pk, fpr, &n ); + free_public_key( pk ); p = xmalloc( 2*n+3 ); *p++ = '0'; *p++ = 'x'; diff --git a/g10/revoke.c b/g10/revoke.c index 216c60389..c348a89d5 100644 --- a/g10/revoke.c +++ b/g10/revoke.c @@ -219,7 +219,7 @@ gen_desig_revoke( const char *uname, strlist_t locusr ) afx = new_armor_context (); - kdbhd = keydb_new (0); + kdbhd = keydb_new (); rc = classify_user_id (uname, &desc); if (!rc) rc = keydb_search (kdbhd, &desc, 1); @@ -461,7 +461,8 @@ gen_revoke (const char *uname) init_packet( &pkt ); /* Search the userid; we don't want the whole getkey stuff here. */ - kdbhd = keydb_new (1); + log_debug ("FIXME: This needs to be adjusted for public key based lookups\n"); + kdbhd = keydb_new (); rc = classify_user_id (uname, &desc); if (!rc) rc = keydb_search (kdbhd, &desc, 1); diff --git a/g10/sign.c b/g10/sign.c index eb3ec1f48..8418c5d35 100644 --- a/g10/sign.c +++ b/g10/sign.c @@ -1546,6 +1546,9 @@ make_keysig_packet( PKT_signature **ret_sig, PKT_public_key *pk, /**************** * Create a new signature packet based on an existing one. * Only user ID signatures are supported for now. + * PK is the public key to work on. + * PKSK is the key used to make the signature. + * * TODO: Merge this with make_keysig_packet. */ int diff --git a/g10/trustdb.c b/g10/trustdb.c index f1377aa1f..7226fe4aa 100644 --- a/g10/trustdb.c +++ b/g10/trustdb.c @@ -2283,7 +2283,7 @@ validate_keys (int interactive) used = new_key_hash_table (); full_trust = new_key_hash_table (); - kdb = keydb_new (0); + kdb = keydb_new (); reset_trust_records(); /* Fixme: Instead of always building a UTK list, we could just build it diff --git a/kbx/ChangeLog b/kbx/ChangeLog index c64da6cd6..a64d54cc5 100644 --- a/kbx/ChangeLog +++ b/kbx/ChangeLog @@ -4,6 +4,11 @@ ../common/sysutils.h even then to silence gcc warning about missing declaration of gnupg_remove. +2010-04-15 Werner Koch + + * keybox-blob.c: Include gettime.h + (make_timestamp): Remove. + 2010-03-23 Werner Koch * Makefile.am (extra_libs): New. diff --git a/kbx/keybox-blob.c b/kbx/keybox-blob.c index de2add65a..a14499311 100644 --- a/kbx/keybox-blob.c +++ b/kbx/keybox-blob.c @@ -127,6 +127,8 @@ X.509 specific are noted like [X.509: xxx] #endif +#include "../common/gettime.h" + /* special values of the signature status */ #define SF_NONE(a) ( !(a) ) @@ -307,20 +309,6 @@ add_fixup (KEYBOXBLOB blob, u32 off, u32 val) } } - -/* - Some wrappers -*/ - -static u32 -make_timestamp (void) -{ -#ifdef __GNUC__ -#warning using time and not gnupg_get_time -#endif - return time(NULL); -} - #ifdef KEYBOX_WITH_OPENPGP diff --git a/po/POTFILES.in b/po/POTFILES.in index a14863658..fb2cfbadb 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -9,6 +9,7 @@ agent/preset-passphrase.c agent/protect-tool.c agent/trustlist.c agent/findkey.c +agent/pksign.c common/exechelp-posix.c common/exechelp-w32.c diff --git a/tools/Makefile.am b/tools/Makefile.am index 017bde0c5..b713ad54f 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -48,7 +48,7 @@ if !HAVE_W32_SYSTEM bin_PROGRAMS += watchgnupg gpgparsemail endif if !HAVE_W32CE_SYSTEM -bin_PROGRAMS += gpgkey2ssh +bin_PROGRAMS += gpgkey2ssh gpgtar endif if !DISABLE_REGEX @@ -114,6 +114,15 @@ gpg_check_pattern_LDADD = $(common_libs) $(LIBGCRYPT_LIBS) $(GPG_ERROR_LIBS) \ $(LIBINTL) $(LIBICONV) $(W32SOCKLIBS) endif +gpgtar_SOURCES = \ + gpgtar.c gpgtar.h \ + gpgtar-create.c \ + gpgtar-extract.c \ + gpgtar-list.c \ + no-libgcrypt.c +gpgtar_LDADD = $(common_libs) + + # Make sure that all libs are build before we use them. This is # important for things like make -j2. $(PROGRAMS): $(common_libs) $(pwquery_libs) ../common/libgpgrl.a