1998-04-20 15:52:20 +00:00
|
|
|
|
/* keyedit.c - keyedit stuff
|
2005-01-11 04:15:55 +00:00
|
|
|
|
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004,
|
|
|
|
|
* 2005 Free Software Foundation, Inc.
|
1998-04-20 15:52:20 +00:00
|
|
|
|
*
|
1998-12-23 12:41:40 +00:00
|
|
|
|
* This file is part of GnuPG.
|
1998-04-20 15:52:20 +00:00
|
|
|
|
*
|
1998-12-23 12:41:40 +00:00
|
|
|
|
* GnuPG is free software; you can redistribute it and/or modify
|
1998-04-20 15:52:20 +00:00
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
|
* (at your option) any later version.
|
|
|
|
|
*
|
1998-12-23 12:41:40 +00:00
|
|
|
|
* GnuPG is distributed in the hope that it will be useful,
|
1998-04-20 15:52:20 +00:00
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
|
*
|
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
|
* along with this program; if not, write to the Free Software
|
2005-05-31 08:39:18 +00:00
|
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
|
|
|
|
* USA.
|
1998-04-20 15:52:20 +00:00
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include <config.h>
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
#include <errno.h>
|
|
|
|
|
#include <assert.h>
|
1998-07-29 19:35:05 +00:00
|
|
|
|
#include <ctype.h>
|
2005-03-18 22:07:12 +00:00
|
|
|
|
#ifdef HAVE_LIBREADLINE
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <readline/readline.h>
|
|
|
|
|
#endif
|
1998-04-20 15:52:20 +00:00
|
|
|
|
#include "options.h"
|
|
|
|
|
#include "packet.h"
|
|
|
|
|
#include "errors.h"
|
|
|
|
|
#include "iobuf.h"
|
|
|
|
|
#include "keydb.h"
|
2002-06-29 13:46:34 +00:00
|
|
|
|
#include "memory.h"
|
|
|
|
|
#include "photoid.h"
|
1998-04-20 15:52:20 +00:00
|
|
|
|
#include "util.h"
|
|
|
|
|
#include "main.h"
|
1998-07-30 17:37:03 +00:00
|
|
|
|
#include "trustdb.h"
|
1998-04-20 15:52:20 +00:00
|
|
|
|
#include "filter.h"
|
|
|
|
|
#include "ttyio.h"
|
1998-07-31 16:45:58 +00:00
|
|
|
|
#include "status.h"
|
1998-04-20 15:52:20 +00:00
|
|
|
|
#include "i18n.h"
|
2004-05-08 13:51:14 +00:00
|
|
|
|
#include "keyserver-internal.h"
|
1998-04-20 15:52:20 +00:00
|
|
|
|
|
2004-09-16 20:55:09 +00:00
|
|
|
|
static void show_prefs( PKT_user_id *uid, PKT_signature *selfsig, int verbose);
|
2005-09-10 16:50:41 +00:00
|
|
|
|
static void show_names(KBNODE keyblock,PKT_public_key *pk,
|
|
|
|
|
unsigned int flag,int with_prefs);
|
2002-06-29 13:46:34 +00:00
|
|
|
|
static void show_key_with_all_names( KBNODE keyblock, int only_marked,
|
|
|
|
|
int with_revoker, int with_fpr, int with_subkeys, int with_prefs );
|
1998-07-29 19:35:05 +00:00
|
|
|
|
static void show_key_and_fingerprint( KBNODE keyblock );
|
2005-09-01 20:51:13 +00:00
|
|
|
|
static int menu_adduid( KBNODE keyblock, KBNODE sec_keyblock,
|
|
|
|
|
int photo, const char *photo_name );
|
1998-07-29 19:35:05 +00:00
|
|
|
|
static void menu_deluid( KBNODE pub_keyblock, KBNODE sec_keyblock );
|
2005-06-10 03:00:57 +00:00
|
|
|
|
static int menu_delsig( KBNODE pub_keyblock );
|
2005-11-18 04:25:07 +00:00
|
|
|
|
static int menu_clean(KBNODE keyblock,int self_only);
|
1998-07-29 19:35:05 +00:00
|
|
|
|
static void menu_delkey( KBNODE pub_keyblock, KBNODE sec_keyblock );
|
2002-07-19 05:08:54 +00:00
|
|
|
|
static int menu_addrevoker( KBNODE pub_keyblock,
|
|
|
|
|
KBNODE sec_keyblock, int sensitive );
|
1998-10-18 15:21:22 +00:00
|
|
|
|
static int menu_expire( KBNODE pub_keyblock, KBNODE sec_keyblock );
|
2005-10-14 04:07:13 +00:00
|
|
|
|
static int menu_backsign(KBNODE pub_keyblock,KBNODE sec_keyblock);
|
2002-06-29 13:46:34 +00:00
|
|
|
|
static int menu_set_primary_uid( KBNODE pub_keyblock, KBNODE sec_keyblock );
|
|
|
|
|
static int menu_set_preferences( KBNODE pub_keyblock, KBNODE sec_keyblock );
|
2004-05-08 13:51:14 +00:00
|
|
|
|
static int menu_set_keyserver_url (const char *url,
|
|
|
|
|
KBNODE pub_keyblock, KBNODE sec_keyblock );
|
1999-02-16 13:16:33 +00:00
|
|
|
|
static int menu_select_uid( KBNODE keyblock, int idx );
|
2005-04-24 16:05:41 +00:00
|
|
|
|
static int menu_select_uid_namehash( KBNODE keyblock, const char *namehash );
|
1999-02-16 13:16:33 +00:00
|
|
|
|
static int menu_select_key( KBNODE keyblock, int idx );
|
1998-07-29 19:35:05 +00:00
|
|
|
|
static int count_uids( KBNODE keyblock );
|
|
|
|
|
static int count_uids_with_flag( KBNODE keyblock, unsigned flag );
|
|
|
|
|
static int count_keys_with_flag( KBNODE keyblock, unsigned flag );
|
|
|
|
|
static int count_selected_uids( KBNODE keyblock );
|
2002-06-29 13:46:34 +00:00
|
|
|
|
static int real_uids_left( KBNODE keyblock );
|
1998-07-29 19:35:05 +00:00
|
|
|
|
static int count_selected_keys( KBNODE keyblock );
|
1999-04-26 15:53:01 +00:00
|
|
|
|
static int menu_revsig( KBNODE keyblock );
|
2002-12-27 13:41:17 +00:00
|
|
|
|
static int menu_revuid( KBNODE keyblock, KBNODE sec_keyblock );
|
1999-04-28 11:06:52 +00:00
|
|
|
|
static int menu_revkey( KBNODE pub_keyblock, KBNODE sec_keyblock );
|
2004-12-19 04:30:16 +00:00
|
|
|
|
static int menu_revsubkey( KBNODE pub_keyblock, KBNODE sec_keyblock );
|
1999-06-29 19:50:54 +00:00
|
|
|
|
static int enable_disable_key( KBNODE keyblock, int disable );
|
2002-06-29 13:46:34 +00:00
|
|
|
|
static void menu_showphoto( KBNODE keyblock );
|
|
|
|
|
|
|
|
|
|
static int update_trust=0;
|
1998-04-20 15:52:20 +00:00
|
|
|
|
|
1998-09-11 05:47:32 +00:00
|
|
|
|
#define CONTROL_D ('D' - 'A' + 1)
|
1998-04-20 15:52:20 +00:00
|
|
|
|
|
1998-07-29 19:35:05 +00:00
|
|
|
|
#define NODFLG_BADSIG (1<<0) /* bad signature */
|
|
|
|
|
#define NODFLG_NOKEY (1<<1) /* no public key */
|
|
|
|
|
#define NODFLG_SIGERR (1<<2) /* other sig error */
|
|
|
|
|
|
|
|
|
|
#define NODFLG_MARK_A (1<<4) /* temporary mark */
|
2002-06-29 13:46:34 +00:00
|
|
|
|
#define NODFLG_DELSIG (1<<5) /* to be deleted */
|
1998-07-29 19:35:05 +00:00
|
|
|
|
|
|
|
|
|
#define NODFLG_SELUID (1<<8) /* indicate the selected userid */
|
|
|
|
|
#define NODFLG_SELKEY (1<<9) /* indicate the selected key */
|
1999-04-26 15:53:01 +00:00
|
|
|
|
#define NODFLG_SELSIG (1<<10) /* indicate a selected signature */
|
1998-04-20 15:52:20 +00:00
|
|
|
|
|
2000-07-14 17:34:53 +00:00
|
|
|
|
struct sign_attrib {
|
2002-06-29 13:46:34 +00:00
|
|
|
|
int non_exportable,non_revocable;
|
2000-07-14 17:34:53 +00:00
|
|
|
|
struct revocation_reason_info *reason;
|
2002-11-03 12:46:52 +00:00
|
|
|
|
byte trust_depth,trust_value;
|
|
|
|
|
char *trust_regexp;
|
1999-03-11 15:42:06 +00:00
|
|
|
|
};
|
|
|
|
|
|
2004-09-13 12:31:25 +00:00
|
|
|
|
|
2004-09-24 14:34:45 +00:00
|
|
|
|
#ifdef ENABLE_CARD_SUPPORT
|
2004-09-23 13:32:31 +00:00
|
|
|
|
/* Given a node SEC_NODE with a secret key or subkey, locate the
|
|
|
|
|
corresponding public key from pub_keyblock. */
|
|
|
|
|
static PKT_public_key *
|
|
|
|
|
find_pk_from_sknode (KBNODE pub_keyblock, KBNODE sec_node)
|
|
|
|
|
{
|
|
|
|
|
KBNODE node = pub_keyblock;
|
|
|
|
|
PKT_secret_key *sk;
|
|
|
|
|
PKT_public_key *pk;
|
|
|
|
|
|
|
|
|
|
if (sec_node->pkt->pkttype == PKT_SECRET_KEY
|
|
|
|
|
&& node->pkt->pkttype == PKT_PUBLIC_KEY)
|
|
|
|
|
return node->pkt->pkt.public_key;
|
|
|
|
|
if (sec_node->pkt->pkttype != PKT_SECRET_SUBKEY)
|
|
|
|
|
return NULL;
|
|
|
|
|
sk = sec_node->pkt->pkt.secret_key;
|
|
|
|
|
for (; node; node = node->next)
|
|
|
|
|
if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
|
|
|
|
|
{
|
|
|
|
|
pk = node->pkt->pkt.public_key;
|
|
|
|
|
if (pk->keyid[0] == sk->keyid[0] && pk->keyid[1] == sk->keyid[1])
|
|
|
|
|
return pk;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
2004-09-24 14:34:45 +00:00
|
|
|
|
#endif /* ENABLE_CARD_SUPPORT */
|
2004-09-23 13:32:31 +00:00
|
|
|
|
|
|
|
|
|
|
2004-09-13 12:31:25 +00:00
|
|
|
|
/* TODO: Fix duplicated code between here and the check-sigs/list-sigs
|
|
|
|
|
code in keylist.c. */
|
|
|
|
|
static int
|
|
|
|
|
print_and_check_one_sig_colon( KBNODE keyblock, KBNODE node,
|
|
|
|
|
int *inv_sigs, int *no_key, int *oth_err,
|
|
|
|
|
int *is_selfsig, int print_without_key )
|
|
|
|
|
{
|
|
|
|
|
PKT_signature *sig = node->pkt->pkt.signature;
|
|
|
|
|
int rc, sigrc;
|
|
|
|
|
|
|
|
|
|
/* TODO: Make sure a cached sig record here still has the pk that
|
|
|
|
|
issued it. See also keylist.c:list_keyblock_print */
|
|
|
|
|
|
|
|
|
|
switch((rc=check_key_signature(keyblock,node,is_selfsig)))
|
|
|
|
|
{
|
|
|
|
|
case 0:
|
|
|
|
|
node->flag &= ~(NODFLG_BADSIG|NODFLG_NOKEY|NODFLG_SIGERR);
|
|
|
|
|
sigrc = '!';
|
|
|
|
|
break;
|
|
|
|
|
case G10ERR_BAD_SIGN:
|
|
|
|
|
node->flag = NODFLG_BADSIG;
|
|
|
|
|
sigrc = '-';
|
|
|
|
|
if( inv_sigs )
|
|
|
|
|
++*inv_sigs;
|
|
|
|
|
break;
|
|
|
|
|
case G10ERR_NO_PUBKEY:
|
|
|
|
|
case G10ERR_UNU_PUBKEY:
|
|
|
|
|
node->flag = NODFLG_NOKEY;
|
|
|
|
|
sigrc = '?';
|
|
|
|
|
if( no_key )
|
|
|
|
|
++*no_key;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
node->flag = NODFLG_SIGERR;
|
|
|
|
|
sigrc = '%';
|
|
|
|
|
if( oth_err )
|
|
|
|
|
++*oth_err;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if( sigrc != '?' || print_without_key )
|
|
|
|
|
{
|
|
|
|
|
printf("sig:%c::%d:%08lX%08lX:%lu:%lu:",
|
2004-10-04 01:17:27 +00:00
|
|
|
|
sigrc,sig->pubkey_algo,(ulong)sig->keyid[0],(ulong)sig->keyid[1],
|
2004-09-13 12:31:25 +00:00
|
|
|
|
(ulong)sig->timestamp,(ulong)sig->expiredate);
|
|
|
|
|
|
|
|
|
|
if(sig->trust_depth || sig->trust_value)
|
|
|
|
|
printf("%d %d",sig->trust_depth,sig->trust_value);
|
|
|
|
|
|
|
|
|
|
printf(":");
|
|
|
|
|
|
|
|
|
|
if(sig->trust_regexp)
|
|
|
|
|
print_string(stdout,sig->trust_regexp,strlen(sig->trust_regexp),':');
|
|
|
|
|
|
|
|
|
|
printf("::%02x%c\n",sig->sig_class,sig->flags.exportable?'x':'l');
|
|
|
|
|
|
|
|
|
|
if(opt.show_subpackets)
|
|
|
|
|
print_subpackets_colon(sig);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return (sigrc == '!');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
1999-05-27 07:45:46 +00:00
|
|
|
|
/****************
|
2002-06-29 13:46:34 +00:00
|
|
|
|
* Print information about a signature, check it and return true
|
1999-05-27 07:45:46 +00:00
|
|
|
|
* if the signature is okay. NODE must be a signature packet.
|
|
|
|
|
*/
|
|
|
|
|
static int
|
|
|
|
|
print_and_check_one_sig( KBNODE keyblock, KBNODE node,
|
|
|
|
|
int *inv_sigs, int *no_key, int *oth_err,
|
1999-06-16 18:25:37 +00:00
|
|
|
|
int *is_selfsig, int print_without_key )
|
1999-05-27 07:45:46 +00:00
|
|
|
|
{
|
|
|
|
|
PKT_signature *sig = node->pkt->pkt.signature;
|
|
|
|
|
int rc, sigrc;
|
|
|
|
|
int is_rev = sig->sig_class == 0x30;
|
|
|
|
|
|
2002-08-20 12:45:57 +00:00
|
|
|
|
/* TODO: Make sure a cached sig record here still has the pk that
|
|
|
|
|
issued it. See also keylist.c:list_keyblock_print */
|
|
|
|
|
|
1999-05-27 07:45:46 +00:00
|
|
|
|
switch( (rc = check_key_signature( keyblock, node, is_selfsig)) ) {
|
|
|
|
|
case 0:
|
|
|
|
|
node->flag &= ~(NODFLG_BADSIG|NODFLG_NOKEY|NODFLG_SIGERR);
|
|
|
|
|
sigrc = '!';
|
|
|
|
|
break;
|
2002-06-29 13:46:34 +00:00
|
|
|
|
case G10ERR_BAD_SIGN:
|
1999-05-27 07:45:46 +00:00
|
|
|
|
node->flag = NODFLG_BADSIG;
|
|
|
|
|
sigrc = '-';
|
|
|
|
|
if( inv_sigs )
|
|
|
|
|
++*inv_sigs;
|
|
|
|
|
break;
|
2002-06-29 13:46:34 +00:00
|
|
|
|
case G10ERR_NO_PUBKEY:
|
|
|
|
|
case G10ERR_UNU_PUBKEY:
|
1999-05-27 07:45:46 +00:00
|
|
|
|
node->flag = NODFLG_NOKEY;
|
|
|
|
|
sigrc = '?';
|
|
|
|
|
if( no_key )
|
|
|
|
|
++*no_key;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
node->flag = NODFLG_SIGERR;
|
|
|
|
|
sigrc = '%';
|
|
|
|
|
if( oth_err )
|
|
|
|
|
++*oth_err;
|
|
|
|
|
break;
|
|
|
|
|
}
|
1999-06-10 12:24:42 +00:00
|
|
|
|
if( sigrc != '?' || print_without_key ) {
|
2004-03-03 05:47:51 +00:00
|
|
|
|
tty_printf("%s%c%c %c%c%c%c%c%c %s %s",
|
2002-06-29 13:46:34 +00:00
|
|
|
|
is_rev? "rev":"sig",sigrc,
|
|
|
|
|
(sig->sig_class-0x10>0 &&
|
|
|
|
|
sig->sig_class-0x10<4)?'0'+sig->sig_class-0x10:' ',
|
|
|
|
|
sig->flags.exportable?' ':'L',
|
|
|
|
|
sig->flags.revocable?' ':'R',
|
|
|
|
|
sig->flags.policy_url?'P':' ',
|
|
|
|
|
sig->flags.notation?'N':' ',
|
|
|
|
|
sig->flags.expired?'X':' ',
|
* keyedit.c (print_and_check_one_sig, show_key_and_fingerprint,
menu_addrevoker), keylist.c (list_keyblock_print, print_fingerprint): Show
"T" or the trust depth for trust signatures, and add spaces to some
strings to make room for it.
* packet.h, parse-packet.c (dump_sig_subpkt, parse_one_sig_subpkt,
parse_signature): Parse trust signature values.
* tdbio.h, tdbio.c (tdbio_read_record, tdbio_write_record): Reserve a byte
for the minimum ownertrust value (for use with trust signatures).
2002-10-29 18:00:07 +00:00
|
|
|
|
(sig->trust_depth>9)?'T':
|
2004-03-03 05:47:51 +00:00
|
|
|
|
(sig->trust_depth>0)?'0'+sig->trust_depth:' ',
|
|
|
|
|
keystr(sig->keyid),datestr_from_sig(sig));
|
2003-08-03 02:37:48 +00:00
|
|
|
|
if(opt.list_options&LIST_SHOW_SIG_EXPIRE)
|
|
|
|
|
tty_printf(" %s",expirestr_from_sig(sig));
|
|
|
|
|
tty_printf(" ");
|
1999-05-27 07:45:46 +00:00
|
|
|
|
if( sigrc == '%' )
|
2002-06-29 13:46:34 +00:00
|
|
|
|
tty_printf("[%s] ", g10_errstr(rc) );
|
1999-05-27 07:45:46 +00:00
|
|
|
|
else if( sigrc == '?' )
|
|
|
|
|
;
|
|
|
|
|
else if( *is_selfsig ) {
|
|
|
|
|
tty_printf( is_rev? _("[revocation]")
|
|
|
|
|
: _("[self-signature]") );
|
|
|
|
|
}
|
2004-03-03 05:47:51 +00:00
|
|
|
|
else
|
|
|
|
|
{
|
1999-05-27 07:45:46 +00:00
|
|
|
|
size_t n;
|
|
|
|
|
char *p = get_user_id( sig->keyid, &n );
|
2004-09-29 03:21:05 +00:00
|
|
|
|
tty_print_utf8_string2(p, n, opt.screen_columns-keystrlen()-26-
|
|
|
|
|
((opt.list_options&LIST_SHOW_SIG_EXPIRE)?11:0));
|
2005-07-27 18:10:56 +00:00
|
|
|
|
xfree(p);
|
2004-03-03 05:47:51 +00:00
|
|
|
|
}
|
1999-05-27 07:45:46 +00:00
|
|
|
|
tty_printf("\n");
|
2002-06-29 13:46:34 +00:00
|
|
|
|
|
2003-11-14 05:06:19 +00:00
|
|
|
|
if(sig->flags.policy_url && (opt.list_options&LIST_SHOW_POLICY_URLS))
|
* mainproc.c (check_sig_and_print), main.h, keylist.c (show_policy,
show_notation): Collapse the old print_notation_data into show_policy()
and show_notation() so there is only one function to print notations and
policy URLs.
* options.h, main.h, g10.c (main), keyedit.c (print_and_check_one_sig),
keylist.c (list_one, list_keyblock_print), pkclist.c (do_edit_ownertrust),
sign.c (mk_notation_and_policy): New "list-options" and "verify-options"
commands. These replace the existing --show-photos/--no-show-photos,
--show-notation/--no-show-notation,
--show-policy-url/--no-show-policy-url, and --show-keyring options. The
new method is more flexible since a user can specify (for example) showing
photos during sig verification, but not in key listings. The old options
are emulated.
2003-05-31 23:23:19 +00:00
|
|
|
|
show_policy_url(sig,3,0);
|
2002-06-29 13:46:34 +00:00
|
|
|
|
|
2003-11-14 05:06:19 +00:00
|
|
|
|
if(sig->flags.notation && (opt.list_options&LIST_SHOW_NOTATIONS))
|
2004-05-05 02:40:27 +00:00
|
|
|
|
show_notation(sig,3,0,
|
|
|
|
|
((opt.list_options&LIST_SHOW_STD_NOTATIONS)?1:0)+
|
|
|
|
|
((opt.list_options&LIST_SHOW_USER_NOTATIONS)?2:0));
|
2003-08-31 03:45:41 +00:00
|
|
|
|
|
2003-11-14 05:06:19 +00:00
|
|
|
|
if(sig->flags.pref_ks && (opt.list_options&LIST_SHOW_KEYSERVER_URLS))
|
2003-08-31 03:45:41 +00:00
|
|
|
|
show_keyserver_url(sig,3,0);
|
1999-05-27 07:45:46 +00:00
|
|
|
|
}
|
2002-06-29 13:46:34 +00:00
|
|
|
|
|
1999-05-27 07:45:46 +00:00
|
|
|
|
return (sigrc == '!');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1998-04-20 15:52:20 +00:00
|
|
|
|
/****************
|
|
|
|
|
* Check the keysigs and set the flags to indicate errors.
|
|
|
|
|
* Returns true if error found.
|
|
|
|
|
*/
|
|
|
|
|
static int
|
1998-07-29 19:35:05 +00:00
|
|
|
|
check_all_keysigs( KBNODE keyblock, int only_selected )
|
1998-04-20 15:52:20 +00:00
|
|
|
|
{
|
|
|
|
|
KBNODE kbctx;
|
|
|
|
|
KBNODE node;
|
|
|
|
|
int inv_sigs = 0;
|
|
|
|
|
int no_key = 0;
|
|
|
|
|
int oth_err = 0;
|
1998-07-29 19:35:05 +00:00
|
|
|
|
int has_selfsig = 0;
|
|
|
|
|
int mis_selfsig = 0;
|
|
|
|
|
int selected = !only_selected;
|
|
|
|
|
int anyuid = 0;
|
1998-04-20 15:52:20 +00:00
|
|
|
|
|
|
|
|
|
for( kbctx=NULL; (node=walk_kbnode( keyblock, &kbctx, 0)) ; ) {
|
1998-07-29 19:35:05 +00:00
|
|
|
|
if( node->pkt->pkttype == PKT_USER_ID ) {
|
|
|
|
|
PKT_user_id *uid = node->pkt->pkt.user_id;
|
|
|
|
|
|
|
|
|
|
if( only_selected )
|
|
|
|
|
selected = (node->flag & NODFLG_SELUID);
|
|
|
|
|
if( selected ) {
|
|
|
|
|
tty_printf("uid ");
|
1999-08-31 15:30:12 +00:00
|
|
|
|
tty_print_utf8_string( uid->name, uid->len );
|
1998-07-29 19:35:05 +00:00
|
|
|
|
tty_printf("\n");
|
|
|
|
|
if( anyuid && !has_selfsig )
|
|
|
|
|
mis_selfsig++;
|
|
|
|
|
has_selfsig = 0;
|
|
|
|
|
anyuid = 1;
|
1998-04-20 15:52:20 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
1998-07-29 19:35:05 +00:00
|
|
|
|
else if( selected && node->pkt->pkttype == PKT_SIGNATURE
|
1999-05-06 12:26:10 +00:00
|
|
|
|
&& ( (node->pkt->pkt.signature->sig_class&~3) == 0x10
|
|
|
|
|
|| node->pkt->pkt.signature->sig_class == 0x30 ) ) {
|
1999-05-27 07:45:46 +00:00
|
|
|
|
int selfsig;
|
1998-04-20 15:52:20 +00:00
|
|
|
|
|
1999-05-27 07:45:46 +00:00
|
|
|
|
if( print_and_check_one_sig( keyblock, node, &inv_sigs,
|
1999-06-16 18:25:37 +00:00
|
|
|
|
&no_key, &oth_err, &selfsig, 0 ) ) {
|
1999-05-27 07:45:46 +00:00
|
|
|
|
if( selfsig )
|
|
|
|
|
has_selfsig = 1;
|
1998-04-20 15:52:20 +00:00
|
|
|
|
}
|
1999-05-27 07:45:46 +00:00
|
|
|
|
/* Hmmm: should we update the trustdb here? */
|
1998-04-20 15:52:20 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
1998-07-29 19:35:05 +00:00
|
|
|
|
if( !has_selfsig )
|
|
|
|
|
mis_selfsig++;
|
|
|
|
|
if( inv_sigs == 1 )
|
2002-06-29 13:46:34 +00:00
|
|
|
|
tty_printf(_("1 bad signature\n") );
|
1998-07-29 19:35:05 +00:00
|
|
|
|
else if( inv_sigs )
|
|
|
|
|
tty_printf(_("%d bad signatures\n"), inv_sigs );
|
|
|
|
|
if( no_key == 1 )
|
|
|
|
|
tty_printf(_("1 signature not checked due to a missing key\n") );
|
|
|
|
|
else if( no_key )
|
|
|
|
|
tty_printf(_("%d signatures not checked due to missing keys\n"), no_key );
|
|
|
|
|
if( oth_err == 1 )
|
|
|
|
|
tty_printf(_("1 signature not checked due to an error\n") );
|
|
|
|
|
else if( oth_err )
|
|
|
|
|
tty_printf(_("%d signatures not checked due to errors\n"), oth_err );
|
|
|
|
|
if( mis_selfsig == 1 )
|
1999-09-01 13:40:07 +00:00
|
|
|
|
tty_printf(_("1 user ID without valid self-signature detected\n"));
|
1998-07-29 19:35:05 +00:00
|
|
|
|
else if( mis_selfsig )
|
1999-09-01 13:40:07 +00:00
|
|
|
|
tty_printf(_("%d user IDs without valid self-signatures detected\n"),
|
1998-07-29 19:35:05 +00:00
|
|
|
|
mis_selfsig);
|
1998-04-20 15:52:20 +00:00
|
|
|
|
|
1998-07-29 19:35:05 +00:00
|
|
|
|
return inv_sigs || no_key || oth_err || mis_selfsig;
|
1998-04-20 15:52:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2000-07-14 17:34:53 +00:00
|
|
|
|
static int
|
|
|
|
|
sign_mk_attrib( PKT_signature *sig, void *opaque )
|
1999-03-11 15:42:06 +00:00
|
|
|
|
{
|
2000-07-14 17:34:53 +00:00
|
|
|
|
struct sign_attrib *attrib = opaque;
|
1999-03-11 15:42:06 +00:00
|
|
|
|
byte buf[8];
|
|
|
|
|
|
|
|
|
|
if( attrib->non_exportable ) {
|
|
|
|
|
buf[0] = 0; /* not exportable */
|
|
|
|
|
build_sig_subpkt( sig, SIGSUBPKT_EXPORTABLE, buf, 1 );
|
|
|
|
|
}
|
2002-06-29 13:46:34 +00:00
|
|
|
|
|
|
|
|
|
if( attrib->non_revocable ) {
|
|
|
|
|
buf[0] = 0; /* not revocable */
|
|
|
|
|
build_sig_subpkt( sig, SIGSUBPKT_REVOCABLE, buf, 1 );
|
|
|
|
|
}
|
|
|
|
|
|
2000-07-14 17:34:53 +00:00
|
|
|
|
if( attrib->reason )
|
|
|
|
|
revocation_reason_build_cb( sig, attrib->reason );
|
1999-03-11 15:42:06 +00:00
|
|
|
|
|
2002-11-03 12:46:52 +00:00
|
|
|
|
if(attrib->trust_depth)
|
|
|
|
|
{
|
|
|
|
|
/* Not critical. If someone doesn't understand trust sigs,
|
|
|
|
|
this can still be a valid regular signature. */
|
|
|
|
|
buf[0] = attrib->trust_depth;
|
|
|
|
|
buf[1] = attrib->trust_value;
|
|
|
|
|
build_sig_subpkt(sig,SIGSUBPKT_TRUST,buf,2);
|
|
|
|
|
|
|
|
|
|
/* Critical. If someone doesn't understands regexps, this
|
|
|
|
|
whole sig should be invalid. Note the +1 for the length -
|
|
|
|
|
regexps are null terminated. */
|
|
|
|
|
if(attrib->trust_regexp)
|
|
|
|
|
build_sig_subpkt(sig,SIGSUBPKT_FLAG_CRITICAL|SIGSUBPKT_REGEXP,
|
|
|
|
|
attrib->trust_regexp,
|
|
|
|
|
strlen(attrib->trust_regexp)+1);
|
|
|
|
|
}
|
|
|
|
|
|
1999-03-11 15:42:06 +00:00
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2002-11-03 12:46:52 +00:00
|
|
|
|
static void
|
|
|
|
|
trustsig_prompt(byte *trust_value,byte *trust_depth,char **regexp)
|
|
|
|
|
{
|
|
|
|
|
char *p;
|
|
|
|
|
|
|
|
|
|
*trust_value=0;
|
|
|
|
|
*trust_depth=0;
|
|
|
|
|
*regexp=NULL;
|
|
|
|
|
|
|
|
|
|
/* Same string as pkclist.c:do_edit_ownertrust */
|
2004-10-13 15:34:52 +00:00
|
|
|
|
tty_printf(_("Please decide how far you trust this user to correctly verify"
|
|
|
|
|
" other users' keys\n(by looking at passports, checking"
|
|
|
|
|
" fingerprints from different sources, etc.)\n"));
|
|
|
|
|
tty_printf("\n");
|
|
|
|
|
tty_printf (_(" %d = I trust marginally\n"), 1);
|
|
|
|
|
tty_printf (_(" %d = I trust fully\n"), 2);
|
2002-11-03 12:46:52 +00:00
|
|
|
|
tty_printf("\n");
|
|
|
|
|
|
|
|
|
|
while(*trust_value==0)
|
|
|
|
|
{
|
|
|
|
|
p = cpr_get("trustsig_prompt.trust_value",_("Your selection? "));
|
|
|
|
|
trim_spaces(p);
|
|
|
|
|
cpr_kill_prompt();
|
|
|
|
|
/* 60 and 120 are as per RFC2440 */
|
|
|
|
|
if(p[0]=='1' && !p[1])
|
|
|
|
|
*trust_value=60;
|
|
|
|
|
else if(p[0]=='2' && !p[1])
|
|
|
|
|
*trust_value=120;
|
2005-07-27 18:10:56 +00:00
|
|
|
|
xfree(p);
|
2002-11-03 12:46:52 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tty_printf("\n");
|
|
|
|
|
|
|
|
|
|
tty_printf(_(
|
|
|
|
|
"Please enter the depth of this trust signature.\n"
|
|
|
|
|
"A depth greater than 1 allows the key you are signing to make\n"
|
|
|
|
|
"trust signatures on your behalf.\n"));
|
|
|
|
|
tty_printf("\n");
|
|
|
|
|
|
|
|
|
|
while(*trust_depth==0)
|
|
|
|
|
{
|
|
|
|
|
p = cpr_get("trustsig_prompt.trust_depth",_("Your selection? "));
|
|
|
|
|
trim_spaces(p);
|
|
|
|
|
cpr_kill_prompt();
|
|
|
|
|
*trust_depth=atoi(p);
|
2005-07-27 18:10:56 +00:00
|
|
|
|
xfree(p);
|
2002-11-03 12:46:52 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tty_printf("\n");
|
|
|
|
|
|
|
|
|
|
tty_printf(_("Please enter a domain to restrict this signature, "
|
|
|
|
|
"or enter for none.\n"));
|
|
|
|
|
|
|
|
|
|
tty_printf("\n");
|
|
|
|
|
|
|
|
|
|
p=cpr_get("trustsig_prompt.trust_regexp",_("Your selection? "));
|
|
|
|
|
trim_spaces(p);
|
|
|
|
|
cpr_kill_prompt();
|
|
|
|
|
|
|
|
|
|
if(strlen(p)>0)
|
|
|
|
|
{
|
|
|
|
|
char *q=p;
|
|
|
|
|
int regexplen=100,ind;
|
1999-03-11 15:42:06 +00:00
|
|
|
|
|
2005-07-27 18:10:56 +00:00
|
|
|
|
*regexp=xmalloc(regexplen);
|
2002-11-03 12:46:52 +00:00
|
|
|
|
|
|
|
|
|
/* Now mangle the domain the user entered into a regexp. To do
|
|
|
|
|
this, \-escape everything that isn't alphanumeric, and attach
|
|
|
|
|
"<[^>]+[@.]" to the front, and ">$" to the end. */
|
|
|
|
|
|
|
|
|
|
strcpy(*regexp,"<[^>]+[@.]");
|
|
|
|
|
ind=strlen(*regexp);
|
|
|
|
|
|
|
|
|
|
while(*q)
|
|
|
|
|
{
|
|
|
|
|
if(!((*q>='A' && *q<='Z')
|
|
|
|
|
|| (*q>='a' && *q<='z') || (*q>='0' && *q<='9')))
|
|
|
|
|
(*regexp)[ind++]='\\';
|
|
|
|
|
|
|
|
|
|
(*regexp)[ind++]=*q;
|
|
|
|
|
|
|
|
|
|
if((regexplen-ind)<3)
|
|
|
|
|
{
|
|
|
|
|
regexplen+=100;
|
2005-07-27 18:10:56 +00:00
|
|
|
|
*regexp=xrealloc(*regexp,regexplen);
|
2002-11-03 12:46:52 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
q++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
(*regexp)[ind]='\0';
|
|
|
|
|
strcat(*regexp,">$");
|
|
|
|
|
}
|
|
|
|
|
|
2005-07-27 18:10:56 +00:00
|
|
|
|
xfree(p);
|
2002-11-03 12:46:52 +00:00
|
|
|
|
tty_printf("\n");
|
|
|
|
|
}
|
1999-03-11 15:42:06 +00:00
|
|
|
|
|
1998-04-20 15:52:20 +00:00
|
|
|
|
/****************
|
1998-07-29 19:35:05 +00:00
|
|
|
|
* 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.
|
1998-04-20 15:52:20 +00:00
|
|
|
|
*/
|
1998-07-29 19:35:05 +00:00
|
|
|
|
static int
|
2002-06-29 13:46:34 +00:00
|
|
|
|
sign_uids( KBNODE keyblock, STRLIST locusr, int *ret_modified,
|
2005-04-22 03:36:20 +00:00
|
|
|
|
int local, int nonrevocable, int trust, int interactive )
|
1998-04-20 15:52:20 +00:00
|
|
|
|
{
|
|
|
|
|
int rc = 0;
|
1998-06-29 12:30:57 +00:00
|
|
|
|
SK_LIST sk_list = NULL;
|
|
|
|
|
SK_LIST sk_rover = NULL;
|
1998-10-07 13:30:43 +00:00
|
|
|
|
PKT_secret_key *sk = NULL;
|
1998-07-29 19:35:05 +00:00
|
|
|
|
KBNODE node, uidnode;
|
1998-11-08 17:23:14 +00:00
|
|
|
|
PKT_public_key *primary_pk=NULL;
|
2005-04-22 03:36:20 +00:00
|
|
|
|
int select_all = !count_selected_uids(keyblock) || interactive;
|
2002-06-29 13:46:34 +00:00
|
|
|
|
int all_v3=1;
|
|
|
|
|
|
|
|
|
|
/* Are there any non-v3 sigs on this key already? */
|
* packet.h, build-packet.c (build_sig_subpkt), export.c
(do_export_stream), import.c (remove_bad_stuff, import), parse-packet.c
(dump_sig_subpkt, parse_one_sig_subpkt): Remove vestigal code for the old
sig cache subpacket. This wasn't completely harmless as it caused
subpacket 101 to disappear on import and export.
* options.h, armor.c, cipher.c, g10.c, keyedit.c, pkclist.c, sign.c,
encode.c, getkey.c, revoke.c: The current flags for different levels of
PGP-ness are massively complex. This is step one in simplifying them. No
functional change yet, just use a macro to check for compliance level.
* sign.c (sign_file): Fix bug that causes spurious compression preference
warning.
* sign.c (clearsign_file): Fix bug that prevents proper warning message
from appearing when clearsigning in --pgp2 mode with a non-v3 RSA key.
* main.h, misc.c (compliance_option_string, compliance_string,
compliance_failure), pkclist.c (build_pk_list), sign.c (sign_file,
clearsign_file), encode.c (encode_crypt, write_pubkey_enc_from_list): New
functions to put the "this message may not be usable...." warning in one
place.
* options.h, g10.c (main): Part two of the simplification. Use a single
enum to indicate what we are compliant to (1991, 2440, PGPx, etc.)
* g10.c (main): Show errors for failure in export, send-keys, recv-keys,
and refresh-keys.
* options.h, g10.c (main): Give algorithm warnings for algorithms chosen
against the --pgpX and --openpgp rules.
* keydb.h, pkclist.c (algo_available): Make TIGER192 invalid in --openpgp
mode.
* sign.c (sign_file), pkclist.c (algo_available): Allow passing a hint of
0.
2003-05-03 04:07:45 +00:00
|
|
|
|
if(PGP2)
|
2002-06-29 13:46:34 +00:00
|
|
|
|
for(node=keyblock;node;node=node->next)
|
|
|
|
|
if(node->pkt->pkttype==PKT_SIGNATURE &&
|
|
|
|
|
node->pkt->pkt.signature->version>3)
|
|
|
|
|
{
|
|
|
|
|
all_v3=0;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* build a list of all signators.
|
|
|
|
|
*
|
|
|
|
|
* We use the CERT flag to request the primary which must always
|
|
|
|
|
* be one which is capable of signing keys. I can't see a reason
|
|
|
|
|
* why to sign keys using a subkey. Implementation of USAGE_CERT
|
|
|
|
|
* is just a hack in getkey.c and does not mean that a subkey
|
2005-08-27 03:09:40 +00:00
|
|
|
|
* marked as certification capable will be used. */
|
|
|
|
|
rc=build_sk_list( locusr, &sk_list, 0, PUBKEY_USAGE_CERT);
|
1998-04-20 15:52:20 +00:00
|
|
|
|
if( rc )
|
|
|
|
|
goto leave;
|
|
|
|
|
|
2002-06-29 13:46:34 +00:00
|
|
|
|
/* loop over all signators */
|
1998-07-29 19:35:05 +00:00
|
|
|
|
for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) {
|
2002-06-29 13:46:34 +00:00
|
|
|
|
u32 sk_keyid[2],pk_keyid[2];
|
2002-11-03 12:46:52 +00:00
|
|
|
|
char *p,*trust_regexp=NULL;
|
2002-06-29 13:46:34 +00:00
|
|
|
|
int force_v4=0,class=0,selfsig=0;
|
|
|
|
|
u32 duration=0,timestamp=0;
|
2002-11-03 12:46:52 +00:00
|
|
|
|
byte trust_depth=0,trust_value=0;
|
2002-06-29 13:46:34 +00:00
|
|
|
|
|
2002-11-03 12:46:52 +00:00
|
|
|
|
if(local || nonrevocable || trust ||
|
2002-06-29 13:46:34 +00:00
|
|
|
|
opt.cert_policy_url || opt.cert_notation_data)
|
|
|
|
|
force_v4=1;
|
1998-04-20 15:52:20 +00:00
|
|
|
|
|
1998-10-07 13:30:43 +00:00
|
|
|
|
/* we have to use a copy of the sk, 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 */
|
|
|
|
|
if( sk )
|
|
|
|
|
free_secret_key(sk);
|
|
|
|
|
sk = copy_secret_key( NULL, sk_rover->sk );
|
|
|
|
|
keyid_from_sk( sk, sk_keyid );
|
1998-07-29 19:35:05 +00:00
|
|
|
|
/* set mark A for all selected user ids */
|
|
|
|
|
for( node=keyblock; node; node = node->next ) {
|
|
|
|
|
if( select_all || (node->flag & NODFLG_SELUID) )
|
|
|
|
|
node->flag |= NODFLG_MARK_A;
|
|
|
|
|
else
|
|
|
|
|
node->flag &= ~NODFLG_MARK_A;
|
1998-04-20 15:52:20 +00:00
|
|
|
|
}
|
1998-07-29 19:35:05 +00:00
|
|
|
|
/* reset mark for uids which are already signed */
|
|
|
|
|
uidnode = NULL;
|
|
|
|
|
for( node=keyblock; node; node = node->next ) {
|
2002-06-29 13:46:34 +00:00
|
|
|
|
if( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
|
|
|
|
|
primary_pk=node->pkt->pkt.public_key;
|
|
|
|
|
keyid_from_pk( primary_pk, pk_keyid );
|
|
|
|
|
|
|
|
|
|
/* Is this a self-sig? */
|
|
|
|
|
if(pk_keyid[0]==sk_keyid[0] && pk_keyid[1]==sk_keyid[1])
|
|
|
|
|
{
|
|
|
|
|
selfsig=1;
|
|
|
|
|
/* Do not force a v4 sig here, otherwise it would
|
|
|
|
|
be difficult to remake a v3 selfsig. If this
|
|
|
|
|
is a v3->v4 promotion case, then we set
|
|
|
|
|
force_v4 later anyway. */
|
|
|
|
|
force_v4=0;
|
|
|
|
|
}
|
|
|
|
|
}
|
2005-04-22 03:36:20 +00:00
|
|
|
|
else if( node->pkt->pkttype == PKT_USER_ID )
|
|
|
|
|
{
|
1998-07-29 19:35:05 +00:00
|
|
|
|
uidnode = (node->flag & NODFLG_MARK_A)? node : NULL;
|
2002-06-29 13:46:34 +00:00
|
|
|
|
if(uidnode)
|
|
|
|
|
{
|
2005-04-22 03:36:20 +00:00
|
|
|
|
int yesreally=0;
|
2002-06-29 13:46:34 +00:00
|
|
|
|
char *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)
|
|
|
|
|
{
|
|
|
|
|
tty_printf(_("User ID \"%s\" is revoked."),user);
|
|
|
|
|
|
2004-07-15 21:16:54 +00:00
|
|
|
|
if(selfsig)
|
|
|
|
|
tty_printf("\n");
|
|
|
|
|
else if(opt.expert)
|
2002-06-29 13:46:34 +00:00
|
|
|
|
{
|
|
|
|
|
tty_printf("\n");
|
|
|
|
|
/* No, so remove the mark and continue */
|
|
|
|
|
if(!cpr_get_answer_is_yes("sign_uid.revoke_okay",
|
|
|
|
|
_("Are you sure you "
|
|
|
|
|
"still want to sign "
|
|
|
|
|
"it? (y/N) ")))
|
2004-07-15 21:16:54 +00:00
|
|
|
|
{
|
|
|
|
|
uidnode->flag &= ~NODFLG_MARK_A;
|
|
|
|
|
uidnode=NULL;
|
|
|
|
|
}
|
2005-04-22 03:36:20 +00:00
|
|
|
|
else if(interactive)
|
|
|
|
|
yesreally=1;
|
2002-06-29 13:46:34 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
uidnode->flag &= ~NODFLG_MARK_A;
|
2004-07-15 21:16:54 +00:00
|
|
|
|
uidnode=NULL;
|
2002-06-29 13:46:34 +00:00
|
|
|
|
tty_printf(_(" Unable to sign.\n"));
|
|
|
|
|
}
|
|
|
|
|
}
|
* parse-packet.c (parse_signature): No need to reserve 8 bytes for the
unhashed signature cache any longer.
* misc.c (pct_expando): Add two new expandos - signer's fingerprint (%g),
and signer's primary fingerprint (%p).
* Makefile.am: Include W32LIBS where appropriate.
* g10.c (main): Add --rfc2440 alias for --openpgp since in a few months,
they won't be the same thing.
* keyserver.c (parse_keyserver_uri): Accept "http" as an alias for "hkp",
since it is occasionally written that way. (keyserver_spawn): Use
ascii_isspace to avoid locale issues.
* keygen.c (ask_user_id): Make --allow-freeform-uid apply to the email
field as well as the name field, and allow mixing fields when it is set.
* options.skel: Use subkeys.pgp.net as the default keyserver.
* trustdb.c (validate_one_keyblock): Certifications on revoked or expired
uids do not count in the web of trust.
* signal.c (init_one_signal, pause_on_sigusr, do_block): Only use
sigprocmask() if we have sigset_t, and only use sigaction() if we have
struct sigaction. This is for Forte c89 on Solaris which seems to define
only the function call half of the two pairs by default.
(pause_on_sigusr): Typo. (do_block): If we can't use sigprocmask() and
sigset_t, try to get the number of signals from NSIG as well as MAXSIG,
and if we can't, fail with an explanation.
* signal.c, tdbio.c: Comment out the transaction code. It was not used in
this version, and was causing some build problems on quasi-posix platforms
(Solaris and Forte c89).
* keylist.c (list_keyblock_colon): Don't include validity values when
listing secret keys since they can be incorrect and/or misleading. This
is a temporary kludge, and will be handled properly in 1.9/2.0.
* mainproc.c (check_sig_and_print): Only show the "key available from"
preferred keyserver line if the key is not currently present.
* keyedit.c (sign_uids): Do not sign expired uids without --expert (same
behavior as revoked uids). Do not allow signing a user ID without a
self-signature. --expert overrides. Add additional prompt to the
signature level question. (menu_expire): When changing expiration dates,
don't replace selfsigs on revoked uids since this would effectively
unrevoke them. There is also no point in replacing expired selfsigs.
This is bug #181
* g10.c (add_notation_data): Make sure that only ascii is passed to
iscntrl. Noted by Christian Biere.
* getkey.c (classify_user_id2): Replaced isspace by spacep
* keygen.c (ask_user_id): Ditto. (get_parameter_algo): Ditto.
* keyedit.c (keyedit_menu): Ditto.
* tdbdump.c (import_ownertrust): Ditto. s/isxdigit/hexdigitp/.
* revoke.c (ask_revocation_reason):
* keyserver.c (keyserver_spawn): Dito.
2003-07-10 14:30:07 +00:00
|
|
|
|
else if(uidnode->pkt->pkt.user_id->is_expired)
|
2002-06-29 13:46:34 +00:00
|
|
|
|
{
|
* parse-packet.c (parse_signature): No need to reserve 8 bytes for the
unhashed signature cache any longer.
* misc.c (pct_expando): Add two new expandos - signer's fingerprint (%g),
and signer's primary fingerprint (%p).
* Makefile.am: Include W32LIBS where appropriate.
* g10.c (main): Add --rfc2440 alias for --openpgp since in a few months,
they won't be the same thing.
* keyserver.c (parse_keyserver_uri): Accept "http" as an alias for "hkp",
since it is occasionally written that way. (keyserver_spawn): Use
ascii_isspace to avoid locale issues.
* keygen.c (ask_user_id): Make --allow-freeform-uid apply to the email
field as well as the name field, and allow mixing fields when it is set.
* options.skel: Use subkeys.pgp.net as the default keyserver.
* trustdb.c (validate_one_keyblock): Certifications on revoked or expired
uids do not count in the web of trust.
* signal.c (init_one_signal, pause_on_sigusr, do_block): Only use
sigprocmask() if we have sigset_t, and only use sigaction() if we have
struct sigaction. This is for Forte c89 on Solaris which seems to define
only the function call half of the two pairs by default.
(pause_on_sigusr): Typo. (do_block): If we can't use sigprocmask() and
sigset_t, try to get the number of signals from NSIG as well as MAXSIG,
and if we can't, fail with an explanation.
* signal.c, tdbio.c: Comment out the transaction code. It was not used in
this version, and was causing some build problems on quasi-posix platforms
(Solaris and Forte c89).
* keylist.c (list_keyblock_colon): Don't include validity values when
listing secret keys since they can be incorrect and/or misleading. This
is a temporary kludge, and will be handled properly in 1.9/2.0.
* mainproc.c (check_sig_and_print): Only show the "key available from"
preferred keyserver line if the key is not currently present.
* keyedit.c (sign_uids): Do not sign expired uids without --expert (same
behavior as revoked uids). Do not allow signing a user ID without a
self-signature. --expert overrides. Add additional prompt to the
signature level question. (menu_expire): When changing expiration dates,
don't replace selfsigs on revoked uids since this would effectively
unrevoke them. There is also no point in replacing expired selfsigs.
This is bug #181
* g10.c (add_notation_data): Make sure that only ascii is passed to
iscntrl. Noted by Christian Biere.
* getkey.c (classify_user_id2): Replaced isspace by spacep
* keygen.c (ask_user_id): Ditto. (get_parameter_algo): Ditto.
* keyedit.c (keyedit_menu): Ditto.
* tdbdump.c (import_ownertrust): Ditto. s/isxdigit/hexdigitp/.
* revoke.c (ask_revocation_reason):
* keyserver.c (keyserver_spawn): Dito.
2003-07-10 14:30:07 +00:00
|
|
|
|
tty_printf(_("User ID \"%s\" is expired."),user);
|
|
|
|
|
|
2004-07-15 21:16:54 +00:00
|
|
|
|
if(selfsig)
|
|
|
|
|
tty_printf("\n");
|
|
|
|
|
else if(opt.expert)
|
* parse-packet.c (parse_signature): No need to reserve 8 bytes for the
unhashed signature cache any longer.
* misc.c (pct_expando): Add two new expandos - signer's fingerprint (%g),
and signer's primary fingerprint (%p).
* Makefile.am: Include W32LIBS where appropriate.
* g10.c (main): Add --rfc2440 alias for --openpgp since in a few months,
they won't be the same thing.
* keyserver.c (parse_keyserver_uri): Accept "http" as an alias for "hkp",
since it is occasionally written that way. (keyserver_spawn): Use
ascii_isspace to avoid locale issues.
* keygen.c (ask_user_id): Make --allow-freeform-uid apply to the email
field as well as the name field, and allow mixing fields when it is set.
* options.skel: Use subkeys.pgp.net as the default keyserver.
* trustdb.c (validate_one_keyblock): Certifications on revoked or expired
uids do not count in the web of trust.
* signal.c (init_one_signal, pause_on_sigusr, do_block): Only use
sigprocmask() if we have sigset_t, and only use sigaction() if we have
struct sigaction. This is for Forte c89 on Solaris which seems to define
only the function call half of the two pairs by default.
(pause_on_sigusr): Typo. (do_block): If we can't use sigprocmask() and
sigset_t, try to get the number of signals from NSIG as well as MAXSIG,
and if we can't, fail with an explanation.
* signal.c, tdbio.c: Comment out the transaction code. It was not used in
this version, and was causing some build problems on quasi-posix platforms
(Solaris and Forte c89).
* keylist.c (list_keyblock_colon): Don't include validity values when
listing secret keys since they can be incorrect and/or misleading. This
is a temporary kludge, and will be handled properly in 1.9/2.0.
* mainproc.c (check_sig_and_print): Only show the "key available from"
preferred keyserver line if the key is not currently present.
* keyedit.c (sign_uids): Do not sign expired uids without --expert (same
behavior as revoked uids). Do not allow signing a user ID without a
self-signature. --expert overrides. Add additional prompt to the
signature level question. (menu_expire): When changing expiration dates,
don't replace selfsigs on revoked uids since this would effectively
unrevoke them. There is also no point in replacing expired selfsigs.
This is bug #181
* g10.c (add_notation_data): Make sure that only ascii is passed to
iscntrl. Noted by Christian Biere.
* getkey.c (classify_user_id2): Replaced isspace by spacep
* keygen.c (ask_user_id): Ditto. (get_parameter_algo): Ditto.
* keyedit.c (keyedit_menu): Ditto.
* tdbdump.c (import_ownertrust): Ditto. s/isxdigit/hexdigitp/.
* revoke.c (ask_revocation_reason):
* keyserver.c (keyserver_spawn): Dito.
2003-07-10 14:30:07 +00:00
|
|
|
|
{
|
|
|
|
|
tty_printf("\n");
|
|
|
|
|
/* No, so remove the mark and continue */
|
|
|
|
|
if(!cpr_get_answer_is_yes("sign_uid.expire_okay",
|
|
|
|
|
_("Are you sure you "
|
|
|
|
|
"still want to sign "
|
|
|
|
|
"it? (y/N) ")))
|
2004-07-15 21:16:54 +00:00
|
|
|
|
{
|
|
|
|
|
uidnode->flag &= ~NODFLG_MARK_A;
|
|
|
|
|
uidnode=NULL;
|
|
|
|
|
}
|
2005-04-22 03:36:20 +00:00
|
|
|
|
else if(interactive)
|
|
|
|
|
yesreally=1;
|
* parse-packet.c (parse_signature): No need to reserve 8 bytes for the
unhashed signature cache any longer.
* misc.c (pct_expando): Add two new expandos - signer's fingerprint (%g),
and signer's primary fingerprint (%p).
* Makefile.am: Include W32LIBS where appropriate.
* g10.c (main): Add --rfc2440 alias for --openpgp since in a few months,
they won't be the same thing.
* keyserver.c (parse_keyserver_uri): Accept "http" as an alias for "hkp",
since it is occasionally written that way. (keyserver_spawn): Use
ascii_isspace to avoid locale issues.
* keygen.c (ask_user_id): Make --allow-freeform-uid apply to the email
field as well as the name field, and allow mixing fields when it is set.
* options.skel: Use subkeys.pgp.net as the default keyserver.
* trustdb.c (validate_one_keyblock): Certifications on revoked or expired
uids do not count in the web of trust.
* signal.c (init_one_signal, pause_on_sigusr, do_block): Only use
sigprocmask() if we have sigset_t, and only use sigaction() if we have
struct sigaction. This is for Forte c89 on Solaris which seems to define
only the function call half of the two pairs by default.
(pause_on_sigusr): Typo. (do_block): If we can't use sigprocmask() and
sigset_t, try to get the number of signals from NSIG as well as MAXSIG,
and if we can't, fail with an explanation.
* signal.c, tdbio.c: Comment out the transaction code. It was not used in
this version, and was causing some build problems on quasi-posix platforms
(Solaris and Forte c89).
* keylist.c (list_keyblock_colon): Don't include validity values when
listing secret keys since they can be incorrect and/or misleading. This
is a temporary kludge, and will be handled properly in 1.9/2.0.
* mainproc.c (check_sig_and_print): Only show the "key available from"
preferred keyserver line if the key is not currently present.
* keyedit.c (sign_uids): Do not sign expired uids without --expert (same
behavior as revoked uids). Do not allow signing a user ID without a
self-signature. --expert overrides. Add additional prompt to the
signature level question. (menu_expire): When changing expiration dates,
don't replace selfsigs on revoked uids since this would effectively
unrevoke them. There is also no point in replacing expired selfsigs.
This is bug #181
* g10.c (add_notation_data): Make sure that only ascii is passed to
iscntrl. Noted by Christian Biere.
* getkey.c (classify_user_id2): Replaced isspace by spacep
* keygen.c (ask_user_id): Ditto. (get_parameter_algo): Ditto.
* keyedit.c (keyedit_menu): Ditto.
* tdbdump.c (import_ownertrust): Ditto. s/isxdigit/hexdigitp/.
* revoke.c (ask_revocation_reason):
* keyserver.c (keyserver_spawn): Dito.
2003-07-10 14:30:07 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
uidnode->flag &= ~NODFLG_MARK_A;
|
2004-07-15 21:16:54 +00:00
|
|
|
|
uidnode=NULL;
|
* parse-packet.c (parse_signature): No need to reserve 8 bytes for the
unhashed signature cache any longer.
* misc.c (pct_expando): Add two new expandos - signer's fingerprint (%g),
and signer's primary fingerprint (%p).
* Makefile.am: Include W32LIBS where appropriate.
* g10.c (main): Add --rfc2440 alias for --openpgp since in a few months,
they won't be the same thing.
* keyserver.c (parse_keyserver_uri): Accept "http" as an alias for "hkp",
since it is occasionally written that way. (keyserver_spawn): Use
ascii_isspace to avoid locale issues.
* keygen.c (ask_user_id): Make --allow-freeform-uid apply to the email
field as well as the name field, and allow mixing fields when it is set.
* options.skel: Use subkeys.pgp.net as the default keyserver.
* trustdb.c (validate_one_keyblock): Certifications on revoked or expired
uids do not count in the web of trust.
* signal.c (init_one_signal, pause_on_sigusr, do_block): Only use
sigprocmask() if we have sigset_t, and only use sigaction() if we have
struct sigaction. This is for Forte c89 on Solaris which seems to define
only the function call half of the two pairs by default.
(pause_on_sigusr): Typo. (do_block): If we can't use sigprocmask() and
sigset_t, try to get the number of signals from NSIG as well as MAXSIG,
and if we can't, fail with an explanation.
* signal.c, tdbio.c: Comment out the transaction code. It was not used in
this version, and was causing some build problems on quasi-posix platforms
(Solaris and Forte c89).
* keylist.c (list_keyblock_colon): Don't include validity values when
listing secret keys since they can be incorrect and/or misleading. This
is a temporary kludge, and will be handled properly in 1.9/2.0.
* mainproc.c (check_sig_and_print): Only show the "key available from"
preferred keyserver line if the key is not currently present.
* keyedit.c (sign_uids): Do not sign expired uids without --expert (same
behavior as revoked uids). Do not allow signing a user ID without a
self-signature. --expert overrides. Add additional prompt to the
signature level question. (menu_expire): When changing expiration dates,
don't replace selfsigs on revoked uids since this would effectively
unrevoke them. There is also no point in replacing expired selfsigs.
This is bug #181
* g10.c (add_notation_data): Make sure that only ascii is passed to
iscntrl. Noted by Christian Biere.
* getkey.c (classify_user_id2): Replaced isspace by spacep
* keygen.c (ask_user_id): Ditto. (get_parameter_algo): Ditto.
* keyedit.c (keyedit_menu): Ditto.
* tdbdump.c (import_ownertrust): Ditto. s/isxdigit/hexdigitp/.
* revoke.c (ask_revocation_reason):
* keyserver.c (keyserver_spawn): Dito.
2003-07-10 14:30:07 +00:00
|
|
|
|
tty_printf(_(" Unable to sign.\n"));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if(!uidnode->pkt->pkt.user_id->created && !selfsig)
|
|
|
|
|
{
|
|
|
|
|
tty_printf(_("User ID \"%s\" is not self-signed."),
|
|
|
|
|
user);
|
|
|
|
|
|
|
|
|
|
if(opt.expert)
|
|
|
|
|
{
|
|
|
|
|
tty_printf("\n");
|
|
|
|
|
/* No, so remove the mark and continue */
|
|
|
|
|
if(!cpr_get_answer_is_yes("sign_uid.nosig_okay",
|
|
|
|
|
_("Are you sure you "
|
|
|
|
|
"still want to sign "
|
|
|
|
|
"it? (y/N) ")))
|
2004-07-15 21:16:54 +00:00
|
|
|
|
{
|
|
|
|
|
uidnode->flag &= ~NODFLG_MARK_A;
|
|
|
|
|
uidnode=NULL;
|
|
|
|
|
}
|
2005-04-22 03:36:20 +00:00
|
|
|
|
else if(interactive)
|
|
|
|
|
yesreally=1;
|
* parse-packet.c (parse_signature): No need to reserve 8 bytes for the
unhashed signature cache any longer.
* misc.c (pct_expando): Add two new expandos - signer's fingerprint (%g),
and signer's primary fingerprint (%p).
* Makefile.am: Include W32LIBS where appropriate.
* g10.c (main): Add --rfc2440 alias for --openpgp since in a few months,
they won't be the same thing.
* keyserver.c (parse_keyserver_uri): Accept "http" as an alias for "hkp",
since it is occasionally written that way. (keyserver_spawn): Use
ascii_isspace to avoid locale issues.
* keygen.c (ask_user_id): Make --allow-freeform-uid apply to the email
field as well as the name field, and allow mixing fields when it is set.
* options.skel: Use subkeys.pgp.net as the default keyserver.
* trustdb.c (validate_one_keyblock): Certifications on revoked or expired
uids do not count in the web of trust.
* signal.c (init_one_signal, pause_on_sigusr, do_block): Only use
sigprocmask() if we have sigset_t, and only use sigaction() if we have
struct sigaction. This is for Forte c89 on Solaris which seems to define
only the function call half of the two pairs by default.
(pause_on_sigusr): Typo. (do_block): If we can't use sigprocmask() and
sigset_t, try to get the number of signals from NSIG as well as MAXSIG,
and if we can't, fail with an explanation.
* signal.c, tdbio.c: Comment out the transaction code. It was not used in
this version, and was causing some build problems on quasi-posix platforms
(Solaris and Forte c89).
* keylist.c (list_keyblock_colon): Don't include validity values when
listing secret keys since they can be incorrect and/or misleading. This
is a temporary kludge, and will be handled properly in 1.9/2.0.
* mainproc.c (check_sig_and_print): Only show the "key available from"
preferred keyserver line if the key is not currently present.
* keyedit.c (sign_uids): Do not sign expired uids without --expert (same
behavior as revoked uids). Do not allow signing a user ID without a
self-signature. --expert overrides. Add additional prompt to the
signature level question. (menu_expire): When changing expiration dates,
don't replace selfsigs on revoked uids since this would effectively
unrevoke them. There is also no point in replacing expired selfsigs.
This is bug #181
* g10.c (add_notation_data): Make sure that only ascii is passed to
iscntrl. Noted by Christian Biere.
* getkey.c (classify_user_id2): Replaced isspace by spacep
* keygen.c (ask_user_id): Ditto. (get_parameter_algo): Ditto.
* keyedit.c (keyedit_menu): Ditto.
* tdbdump.c (import_ownertrust): Ditto. s/isxdigit/hexdigitp/.
* revoke.c (ask_revocation_reason):
* keyserver.c (keyserver_spawn): Dito.
2003-07-10 14:30:07 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
uidnode->flag &= ~NODFLG_MARK_A;
|
2004-07-15 21:16:54 +00:00
|
|
|
|
uidnode=NULL;
|
* parse-packet.c (parse_signature): No need to reserve 8 bytes for the
unhashed signature cache any longer.
* misc.c (pct_expando): Add two new expandos - signer's fingerprint (%g),
and signer's primary fingerprint (%p).
* Makefile.am: Include W32LIBS where appropriate.
* g10.c (main): Add --rfc2440 alias for --openpgp since in a few months,
they won't be the same thing.
* keyserver.c (parse_keyserver_uri): Accept "http" as an alias for "hkp",
since it is occasionally written that way. (keyserver_spawn): Use
ascii_isspace to avoid locale issues.
* keygen.c (ask_user_id): Make --allow-freeform-uid apply to the email
field as well as the name field, and allow mixing fields when it is set.
* options.skel: Use subkeys.pgp.net as the default keyserver.
* trustdb.c (validate_one_keyblock): Certifications on revoked or expired
uids do not count in the web of trust.
* signal.c (init_one_signal, pause_on_sigusr, do_block): Only use
sigprocmask() if we have sigset_t, and only use sigaction() if we have
struct sigaction. This is for Forte c89 on Solaris which seems to define
only the function call half of the two pairs by default.
(pause_on_sigusr): Typo. (do_block): If we can't use sigprocmask() and
sigset_t, try to get the number of signals from NSIG as well as MAXSIG,
and if we can't, fail with an explanation.
* signal.c, tdbio.c: Comment out the transaction code. It was not used in
this version, and was causing some build problems on quasi-posix platforms
(Solaris and Forte c89).
* keylist.c (list_keyblock_colon): Don't include validity values when
listing secret keys since they can be incorrect and/or misleading. This
is a temporary kludge, and will be handled properly in 1.9/2.0.
* mainproc.c (check_sig_and_print): Only show the "key available from"
preferred keyserver line if the key is not currently present.
* keyedit.c (sign_uids): Do not sign expired uids without --expert (same
behavior as revoked uids). Do not allow signing a user ID without a
self-signature. --expert overrides. Add additional prompt to the
signature level question. (menu_expire): When changing expiration dates,
don't replace selfsigs on revoked uids since this would effectively
unrevoke them. There is also no point in replacing expired selfsigs.
This is bug #181
* g10.c (add_notation_data): Make sure that only ascii is passed to
iscntrl. Noted by Christian Biere.
* getkey.c (classify_user_id2): Replaced isspace by spacep
* keygen.c (ask_user_id): Ditto. (get_parameter_algo): Ditto.
* keyedit.c (keyedit_menu): Ditto.
* tdbdump.c (import_ownertrust): Ditto. s/isxdigit/hexdigitp/.
* revoke.c (ask_revocation_reason):
* keyserver.c (keyserver_spawn): Dito.
2003-07-10 14:30:07 +00:00
|
|
|
|
tty_printf(_(" Unable to sign.\n"));
|
|
|
|
|
}
|
2002-06-29 13:46:34 +00:00
|
|
|
|
}
|
|
|
|
|
|
2005-04-22 03:36:20 +00:00
|
|
|
|
if(uidnode && interactive && !yesreally)
|
|
|
|
|
{
|
|
|
|
|
tty_printf(_("User ID \"%s\" is signable. "),user);
|
|
|
|
|
if(!cpr_get_answer_is_yes("sign_uid.sign_okay",
|
|
|
|
|
_("Sign it? (y/N) ")))
|
|
|
|
|
{
|
|
|
|
|
uidnode->flag &= ~NODFLG_MARK_A;
|
|
|
|
|
uidnode=NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2005-07-27 18:10:56 +00:00
|
|
|
|
xfree(user);
|
2002-06-29 13:46:34 +00:00
|
|
|
|
}
|
2005-04-22 03:36:20 +00:00
|
|
|
|
}
|
1998-07-29 19:35:05 +00:00
|
|
|
|
else if( uidnode && node->pkt->pkttype == PKT_SIGNATURE
|
1998-04-20 15:52:20 +00:00
|
|
|
|
&& (node->pkt->pkt.signature->sig_class&~3) == 0x10 ) {
|
1998-07-29 19:35:05 +00:00
|
|
|
|
if( sk_keyid[0] == node->pkt->pkt.signature->keyid[0]
|
|
|
|
|
&& sk_keyid[1] == node->pkt->pkt.signature->keyid[1] ) {
|
2002-06-29 13:46:34 +00:00
|
|
|
|
char buf[50];
|
|
|
|
|
char *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)
|
|
|
|
|
{
|
|
|
|
|
tty_printf(_("The self-signature on \"%s\"\n"
|
|
|
|
|
"is a PGP 2.x-style signature.\n"),user);
|
|
|
|
|
|
|
|
|
|
/* Note that the regular PGP2 warning below
|
|
|
|
|
still applies if there are no v4 sigs on
|
|
|
|
|
this key at all. */
|
|
|
|
|
|
|
|
|
|
if(opt.expert)
|
|
|
|
|
if(cpr_get_answer_is_yes("sign_uid.v4_promote_okay",
|
|
|
|
|
_("Do you want to promote "
|
|
|
|
|
"it to an OpenPGP self-"
|
|
|
|
|
"signature? (y/N) ")))
|
|
|
|
|
{
|
|
|
|
|
force_v4=1;
|
|
|
|
|
node->flag|=NODFLG_DELSIG;
|
2005-07-27 18:10:56 +00:00
|
|
|
|
xfree(user);
|
2002-06-29 13:46:34 +00:00
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2003-04-23 21:18:39 +00:00
|
|
|
|
/* Is the current signature expired? */
|
|
|
|
|
if(node->pkt->pkt.signature->flags.expired)
|
|
|
|
|
{
|
|
|
|
|
tty_printf(_("Your current signature on \"%s\"\n"
|
|
|
|
|
"has expired.\n"),user);
|
|
|
|
|
|
|
|
|
|
if(cpr_get_answer_is_yes("sign_uid.replace_expired_okay",
|
|
|
|
|
_("Do you want to issue a "
|
|
|
|
|
"new signature to replace "
|
|
|
|
|
"the expired one? (y/N) ")))
|
|
|
|
|
{
|
|
|
|
|
/* Mark these for later deletion. We
|
|
|
|
|
don't want to delete them here, just in
|
|
|
|
|
case the replacement signature doesn't
|
|
|
|
|
happen for some reason. We only delete
|
|
|
|
|
these after the replacement is already
|
|
|
|
|
in place. */
|
|
|
|
|
|
|
|
|
|
node->flag|=NODFLG_DELSIG;
|
2005-07-27 18:10:56 +00:00
|
|
|
|
xfree(user);
|
2003-04-23 21:18:39 +00:00
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2002-06-29 13:46:34 +00:00
|
|
|
|
if(!node->pkt->pkt.signature->flags.exportable && !local)
|
|
|
|
|
{
|
|
|
|
|
/* It's a local sig, and we want to make a
|
|
|
|
|
exportable sig. */
|
|
|
|
|
tty_printf(_("Your current signature on \"%s\"\n"
|
|
|
|
|
"is a local signature.\n"),user);
|
|
|
|
|
|
|
|
|
|
if(cpr_get_answer_is_yes("sign_uid.local_promote_okay",
|
|
|
|
|
_("Do you want to promote "
|
|
|
|
|
"it to a full exportable "
|
|
|
|
|
"signature? (y/N) ")))
|
|
|
|
|
{
|
|
|
|
|
/* Mark these for later deletion. We
|
|
|
|
|
don't want to delete them here, just in
|
|
|
|
|
case the replacement signature doesn't
|
|
|
|
|
happen for some reason. We only delete
|
|
|
|
|
these after the replacement is already
|
|
|
|
|
in place. */
|
|
|
|
|
|
|
|
|
|
node->flag|=NODFLG_DELSIG;
|
2005-07-27 18:10:56 +00:00
|
|
|
|
xfree(user);
|
2002-06-29 13:46:34 +00:00
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
1999-04-26 15:53:01 +00:00
|
|
|
|
/* Fixme: see whether there is a revocation in which
|
|
|
|
|
* case we should allow to sign it again. */
|
2002-06-29 13:46:34 +00:00
|
|
|
|
if (!node->pkt->pkt.signature->flags.exportable && local)
|
|
|
|
|
tty_printf(_(
|
2004-03-24 17:34:57 +00:00
|
|
|
|
"\"%s\" was already locally signed by key %s\n"),
|
|
|
|
|
user,keystr_from_sk(sk));
|
2002-06-29 13:46:34 +00:00
|
|
|
|
else
|
2004-03-24 17:34:57 +00:00
|
|
|
|
tty_printf(_("\"%s\" was already signed by key %s\n"),
|
|
|
|
|
user,keystr_from_sk(sk));
|
2003-04-23 21:18:39 +00:00
|
|
|
|
|
|
|
|
|
if(opt.expert
|
|
|
|
|
&& cpr_get_answer_is_yes("sign_uid.dupe_okay",
|
|
|
|
|
_("Do you want to sign it "
|
|
|
|
|
"again anyway? (y/N) ")))
|
|
|
|
|
{
|
|
|
|
|
/* Don't delete the old sig here since this is
|
|
|
|
|
an --expert thing. */
|
2005-07-27 18:10:56 +00:00
|
|
|
|
xfree(user);
|
2003-04-23 21:18:39 +00:00
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2002-06-29 13:46:34 +00:00
|
|
|
|
sprintf (buf, "%08lX%08lX",
|
|
|
|
|
(ulong)sk->keyid[0], (ulong)sk->keyid[1] );
|
|
|
|
|
write_status_text (STATUS_ALREADY_SIGNED, buf);
|
1998-07-29 19:35:05 +00:00
|
|
|
|
uidnode->flag &= ~NODFLG_MARK_A; /* remove mark */
|
2002-06-29 13:46:34 +00:00
|
|
|
|
|
2005-07-27 18:10:56 +00:00
|
|
|
|
xfree(user);
|
1998-04-20 15:52:20 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2004-03-24 17:34:57 +00:00
|
|
|
|
|
1998-07-29 19:35:05 +00:00
|
|
|
|
/* check whether any uids are left for signing */
|
2004-03-24 17:34:57 +00:00
|
|
|
|
if( !count_uids_with_flag(keyblock, NODFLG_MARK_A) )
|
|
|
|
|
{
|
|
|
|
|
tty_printf(_("Nothing to sign with key %s\n"),keystr_from_sk(sk));
|
1998-04-20 15:52:20 +00:00
|
|
|
|
continue;
|
2004-03-24 17:34:57 +00:00
|
|
|
|
}
|
|
|
|
|
|
1998-09-28 19:25:31 +00:00
|
|
|
|
/* Ask whether we really should sign these user id(s) */
|
1998-07-29 19:35:05 +00:00
|
|
|
|
tty_printf("\n");
|
2002-06-29 13:46:34 +00:00
|
|
|
|
show_key_with_all_names( keyblock, 1, 0, 1, 0, 0 );
|
1998-10-07 13:30:43 +00:00
|
|
|
|
tty_printf("\n");
|
2002-06-29 13:46:34 +00:00
|
|
|
|
|
|
|
|
|
if(primary_pk->expiredate && !selfsig)
|
|
|
|
|
{
|
|
|
|
|
u32 now=make_timestamp();
|
|
|
|
|
|
|
|
|
|
if(primary_pk->expiredate<=now)
|
|
|
|
|
{
|
|
|
|
|
tty_printf(_("This key has expired!"));
|
|
|
|
|
|
|
|
|
|
if(opt.expert)
|
|
|
|
|
{
|
|
|
|
|
tty_printf(" ");
|
|
|
|
|
if(!cpr_get_answer_is_yes("sign_uid.expired_okay",
|
|
|
|
|
_("Are you sure you still "
|
|
|
|
|
"want to sign it? (y/N) ")))
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
tty_printf(_(" Unable to sign.\n"));
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
tty_printf(_("This key is due to expire on %s.\n"),
|
|
|
|
|
expirestr_from_pk(primary_pk));
|
|
|
|
|
|
2005-07-22 16:42:48 +00:00
|
|
|
|
if(opt.ask_cert_expire)
|
2002-06-29 13:46:34 +00:00
|
|
|
|
{
|
2005-07-22 16:42:48 +00:00
|
|
|
|
char *answer=cpr_get("sign_uid.expire",
|
|
|
|
|
_("Do you want your signature to "
|
|
|
|
|
"expire at the same time? (Y/n) "));
|
|
|
|
|
if(answer_is_yes_no_default(answer,1))
|
|
|
|
|
{
|
|
|
|
|
/* This fixes the signature timestamp we're
|
|
|
|
|
going to make as now. This is so the
|
|
|
|
|
expiration date is exactly correct, and not
|
|
|
|
|
a few seconds off (due to the time it takes
|
|
|
|
|
to answer the questions, enter the
|
|
|
|
|
passphrase, etc). */
|
|
|
|
|
timestamp=now;
|
|
|
|
|
duration=primary_pk->expiredate-now;
|
|
|
|
|
force_v4=1;
|
|
|
|
|
}
|
2002-06-29 13:46:34 +00:00
|
|
|
|
|
2005-07-22 16:42:48 +00:00
|
|
|
|
cpr_kill_prompt();
|
2005-07-27 18:10:56 +00:00
|
|
|
|
xfree(answer);
|
2005-07-22 16:42:48 +00:00
|
|
|
|
}
|
2002-06-29 13:46:34 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Only ask for duration if we haven't already set it to match
|
|
|
|
|
the expiration of the pk */
|
2005-05-05 19:21:40 +00:00
|
|
|
|
if(!duration && !selfsig)
|
|
|
|
|
{
|
|
|
|
|
if(opt.ask_cert_expire)
|
|
|
|
|
duration=ask_expire_interval(1,opt.def_cert_expire);
|
|
|
|
|
else
|
2005-05-06 19:25:19 +00:00
|
|
|
|
duration=parse_expire_string(opt.def_cert_expire);
|
2005-05-05 19:21:40 +00:00
|
|
|
|
}
|
2002-06-29 13:46:34 +00:00
|
|
|
|
|
|
|
|
|
if(duration)
|
|
|
|
|
force_v4=1;
|
|
|
|
|
|
|
|
|
|
/* Is --pgp2 on, it's a v3 key, all the sigs on the key are
|
|
|
|
|
currently v3 and we're about to sign it with a v4 sig? If
|
|
|
|
|
so, danger! */
|
* packet.h, build-packet.c (build_sig_subpkt), export.c
(do_export_stream), import.c (remove_bad_stuff, import), parse-packet.c
(dump_sig_subpkt, parse_one_sig_subpkt): Remove vestigal code for the old
sig cache subpacket. This wasn't completely harmless as it caused
subpacket 101 to disappear on import and export.
* options.h, armor.c, cipher.c, g10.c, keyedit.c, pkclist.c, sign.c,
encode.c, getkey.c, revoke.c: The current flags for different levels of
PGP-ness are massively complex. This is step one in simplifying them. No
functional change yet, just use a macro to check for compliance level.
* sign.c (sign_file): Fix bug that causes spurious compression preference
warning.
* sign.c (clearsign_file): Fix bug that prevents proper warning message
from appearing when clearsigning in --pgp2 mode with a non-v3 RSA key.
* main.h, misc.c (compliance_option_string, compliance_string,
compliance_failure), pkclist.c (build_pk_list), sign.c (sign_file,
clearsign_file), encode.c (encode_crypt, write_pubkey_enc_from_list): New
functions to put the "this message may not be usable...." warning in one
place.
* options.h, g10.c (main): Part two of the simplification. Use a single
enum to indicate what we are compliant to (1991, 2440, PGPx, etc.)
* g10.c (main): Show errors for failure in export, send-keys, recv-keys,
and refresh-keys.
* options.h, g10.c (main): Give algorithm warnings for algorithms chosen
against the --pgpX and --openpgp rules.
* keydb.h, pkclist.c (algo_available): Make TIGER192 invalid in --openpgp
mode.
* sign.c (sign_file), pkclist.c (algo_available): Allow passing a hint of
0.
2003-05-03 04:07:45 +00:00
|
|
|
|
if(PGP2 && all_v3 &&
|
2002-06-29 13:46:34 +00:00
|
|
|
|
(sk->version>3 || force_v4) && primary_pk->version<=3)
|
|
|
|
|
{
|
|
|
|
|
tty_printf(_("You may not make an OpenPGP signature on a "
|
|
|
|
|
"PGP 2.x key while in --pgp2 mode.\n"));
|
|
|
|
|
tty_printf(_("This would make the key unusable in PGP 2.x.\n"));
|
|
|
|
|
|
|
|
|
|
if(opt.expert)
|
|
|
|
|
{
|
|
|
|
|
if(!cpr_get_answer_is_yes("sign_uid.v4_on_v3_okay",
|
|
|
|
|
_("Are you sure you still "
|
|
|
|
|
"want to sign it? (y/N) ")))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
all_v3=0;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(selfsig)
|
|
|
|
|
;
|
|
|
|
|
else
|
|
|
|
|
{
|
2004-02-24 23:37:18 +00:00
|
|
|
|
if(opt.batch || !opt.ask_cert_level)
|
|
|
|
|
class=0x10+opt.def_cert_level;
|
2002-11-03 12:46:52 +00:00
|
|
|
|
else
|
2002-06-29 13:46:34 +00:00
|
|
|
|
{
|
2002-11-03 12:46:52 +00:00
|
|
|
|
char *answer;
|
2002-06-29 13:46:34 +00:00
|
|
|
|
|
2002-11-03 12:46:52 +00:00
|
|
|
|
tty_printf(_("How carefully have you verified the key you are "
|
|
|
|
|
"about to sign actually belongs\nto the person "
|
|
|
|
|
"named above? If you don't know what to "
|
|
|
|
|
"answer, enter \"0\".\n"));
|
|
|
|
|
tty_printf("\n");
|
|
|
|
|
tty_printf(_(" (0) I will not answer.%s\n"),
|
2004-02-24 23:37:18 +00:00
|
|
|
|
opt.def_cert_level==0?" (default)":"");
|
2002-11-03 12:46:52 +00:00
|
|
|
|
tty_printf(_(" (1) I have not checked at all.%s\n"),
|
2004-02-24 23:37:18 +00:00
|
|
|
|
opt.def_cert_level==1?" (default)":"");
|
2002-11-03 12:46:52 +00:00
|
|
|
|
tty_printf(_(" (2) I have done casual checking.%s\n"),
|
2004-02-24 23:37:18 +00:00
|
|
|
|
opt.def_cert_level==2?" (default)":"");
|
2002-11-03 12:46:52 +00:00
|
|
|
|
tty_printf(_(" (3) I have done very careful checking.%s\n"),
|
2004-02-24 23:37:18 +00:00
|
|
|
|
opt.def_cert_level==3?" (default)":"");
|
2002-11-03 12:46:52 +00:00
|
|
|
|
tty_printf("\n");
|
|
|
|
|
|
|
|
|
|
while(class==0)
|
|
|
|
|
{
|
* parse-packet.c (parse_signature): No need to reserve 8 bytes for the
unhashed signature cache any longer.
* misc.c (pct_expando): Add two new expandos - signer's fingerprint (%g),
and signer's primary fingerprint (%p).
* Makefile.am: Include W32LIBS where appropriate.
* g10.c (main): Add --rfc2440 alias for --openpgp since in a few months,
they won't be the same thing.
* keyserver.c (parse_keyserver_uri): Accept "http" as an alias for "hkp",
since it is occasionally written that way. (keyserver_spawn): Use
ascii_isspace to avoid locale issues.
* keygen.c (ask_user_id): Make --allow-freeform-uid apply to the email
field as well as the name field, and allow mixing fields when it is set.
* options.skel: Use subkeys.pgp.net as the default keyserver.
* trustdb.c (validate_one_keyblock): Certifications on revoked or expired
uids do not count in the web of trust.
* signal.c (init_one_signal, pause_on_sigusr, do_block): Only use
sigprocmask() if we have sigset_t, and only use sigaction() if we have
struct sigaction. This is for Forte c89 on Solaris which seems to define
only the function call half of the two pairs by default.
(pause_on_sigusr): Typo. (do_block): If we can't use sigprocmask() and
sigset_t, try to get the number of signals from NSIG as well as MAXSIG,
and if we can't, fail with an explanation.
* signal.c, tdbio.c: Comment out the transaction code. It was not used in
this version, and was causing some build problems on quasi-posix platforms
(Solaris and Forte c89).
* keylist.c (list_keyblock_colon): Don't include validity values when
listing secret keys since they can be incorrect and/or misleading. This
is a temporary kludge, and will be handled properly in 1.9/2.0.
* mainproc.c (check_sig_and_print): Only show the "key available from"
preferred keyserver line if the key is not currently present.
* keyedit.c (sign_uids): Do not sign expired uids without --expert (same
behavior as revoked uids). Do not allow signing a user ID without a
self-signature. --expert overrides. Add additional prompt to the
signature level question. (menu_expire): When changing expiration dates,
don't replace selfsigs on revoked uids since this would effectively
unrevoke them. There is also no point in replacing expired selfsigs.
This is bug #181
* g10.c (add_notation_data): Make sure that only ascii is passed to
iscntrl. Noted by Christian Biere.
* getkey.c (classify_user_id2): Replaced isspace by spacep
* keygen.c (ask_user_id): Ditto. (get_parameter_algo): Ditto.
* keyedit.c (keyedit_menu): Ditto.
* tdbdump.c (import_ownertrust): Ditto. s/isxdigit/hexdigitp/.
* revoke.c (ask_revocation_reason):
* keyserver.c (keyserver_spawn): Dito.
2003-07-10 14:30:07 +00:00
|
|
|
|
answer = cpr_get("sign_uid.class",_("Your selection? "
|
2004-11-24 05:25:03 +00:00
|
|
|
|
"(enter `?' for more information): "));
|
2002-11-03 12:46:52 +00:00
|
|
|
|
if(answer[0]=='\0')
|
2004-02-24 23:37:18 +00:00
|
|
|
|
class=0x10+opt.def_cert_level; /* Default */
|
2002-11-03 12:46:52 +00:00
|
|
|
|
else if(ascii_strcasecmp(answer,"0")==0)
|
|
|
|
|
class=0x10; /* Generic */
|
|
|
|
|
else if(ascii_strcasecmp(answer,"1")==0)
|
|
|
|
|
class=0x11; /* Persona */
|
|
|
|
|
else if(ascii_strcasecmp(answer,"2")==0)
|
|
|
|
|
class=0x12; /* Casual */
|
|
|
|
|
else if(ascii_strcasecmp(answer,"3")==0)
|
|
|
|
|
class=0x13; /* Positive */
|
|
|
|
|
else
|
|
|
|
|
tty_printf(_("Invalid selection.\n"));
|
|
|
|
|
|
2005-07-27 18:10:56 +00:00
|
|
|
|
xfree(answer);
|
2002-11-03 12:46:52 +00:00
|
|
|
|
}
|
2002-06-29 13:46:34 +00:00
|
|
|
|
}
|
2002-11-03 12:46:52 +00:00
|
|
|
|
|
|
|
|
|
if(trust)
|
|
|
|
|
trustsig_prompt(&trust_value,&trust_depth,&trust_regexp);
|
2002-06-29 13:46:34 +00:00
|
|
|
|
}
|
|
|
|
|
|
2004-10-06 20:40:07 +00:00
|
|
|
|
p=get_user_id_native(sk_keyid);
|
2004-10-14 20:13:16 +00:00
|
|
|
|
tty_printf(_("Are you sure that you want to sign this key with your\n"
|
|
|
|
|
"key \"%s\" (%s)\n"),p,keystr_from_sk(sk));
|
2005-07-27 18:10:56 +00:00
|
|
|
|
xfree(p);
|
2002-06-29 13:46:34 +00:00
|
|
|
|
|
|
|
|
|
if(selfsig)
|
|
|
|
|
{
|
2004-10-15 13:16:58 +00:00
|
|
|
|
tty_printf("\n");
|
|
|
|
|
tty_printf(_("This will be a self-signature.\n"));
|
2002-06-29 13:46:34 +00:00
|
|
|
|
|
|
|
|
|
if( local )
|
2004-10-15 13:16:58 +00:00
|
|
|
|
{
|
|
|
|
|
tty_printf("\n");
|
|
|
|
|
tty_printf(
|
|
|
|
|
_("WARNING: the signature will not be marked "
|
2002-06-29 13:46:34 +00:00
|
|
|
|
"as non-exportable.\n"));
|
2004-10-15 13:16:58 +00:00
|
|
|
|
}
|
2002-06-29 13:46:34 +00:00
|
|
|
|
|
|
|
|
|
if( nonrevocable )
|
2004-10-15 13:16:58 +00:00
|
|
|
|
{
|
|
|
|
|
tty_printf("\n");
|
|
|
|
|
tty_printf(
|
|
|
|
|
_("WARNING: the signature will not be marked "
|
2002-06-29 13:46:34 +00:00
|
|
|
|
"as non-revocable.\n"));
|
2004-10-15 13:16:58 +00:00
|
|
|
|
}
|
2002-06-29 13:46:34 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if( local )
|
2004-10-15 13:16:58 +00:00
|
|
|
|
{
|
|
|
|
|
tty_printf("\n");
|
|
|
|
|
tty_printf(
|
|
|
|
|
_("The signature will be marked as non-exportable.\n"));
|
|
|
|
|
}
|
2002-06-29 13:46:34 +00:00
|
|
|
|
|
|
|
|
|
if( nonrevocable )
|
2004-10-15 13:16:58 +00:00
|
|
|
|
{
|
|
|
|
|
tty_printf("\n");
|
|
|
|
|
tty_printf(
|
|
|
|
|
_("The signature will be marked as non-revocable.\n"));
|
|
|
|
|
}
|
2002-06-29 13:46:34 +00:00
|
|
|
|
|
|
|
|
|
switch(class)
|
|
|
|
|
{
|
|
|
|
|
case 0x11:
|
2004-10-15 13:16:58 +00:00
|
|
|
|
tty_printf("\n");
|
|
|
|
|
tty_printf(_("I have not checked this key at all.\n"));
|
2002-06-29 13:46:34 +00:00
|
|
|
|
break;
|
1998-08-11 17:29:34 +00:00
|
|
|
|
|
2002-06-29 13:46:34 +00:00
|
|
|
|
case 0x12:
|
2004-10-15 13:16:58 +00:00
|
|
|
|
tty_printf("\n");
|
|
|
|
|
tty_printf(_("I have checked this key casually.\n"));
|
2002-06-29 13:46:34 +00:00
|
|
|
|
break;
|
1999-03-11 15:42:06 +00:00
|
|
|
|
|
2002-06-29 13:46:34 +00:00
|
|
|
|
case 0x13:
|
2004-10-15 13:16:58 +00:00
|
|
|
|
tty_printf("\n");
|
|
|
|
|
tty_printf(_("I have checked this key very carefully.\n"));
|
2002-06-29 13:46:34 +00:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tty_printf("\n");
|
1999-04-18 08:18:52 +00:00
|
|
|
|
|
|
|
|
|
if( opt.batch && opt.answer_yes )
|
2002-06-29 13:46:34 +00:00
|
|
|
|
;
|
2004-10-10 15:27:14 +00:00
|
|
|
|
else if( !cpr_get_answer_is_yes("sign_uid.okay",
|
|
|
|
|
_("Really sign? (y/N) ")) )
|
1999-04-18 08:18:52 +00:00
|
|
|
|
continue;
|
2002-06-29 13:46:34 +00:00
|
|
|
|
|
1998-07-29 19:35:05 +00:00
|
|
|
|
/* 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 ) {
|
|
|
|
|
if( node->pkt->pkttype == PKT_PUBLIC_KEY )
|
|
|
|
|
primary_pk = node->pkt->pkt.public_key;
|
|
|
|
|
else if( node->pkt->pkttype == PKT_USER_ID
|
|
|
|
|
&& (node->flag & NODFLG_MARK_A) ) {
|
|
|
|
|
PACKET *pkt;
|
|
|
|
|
PKT_signature *sig;
|
2000-07-14 17:34:53 +00:00
|
|
|
|
struct sign_attrib attrib;
|
1998-07-29 19:35:05 +00:00
|
|
|
|
|
|
|
|
|
assert( primary_pk );
|
1999-03-11 15:42:06 +00:00
|
|
|
|
memset( &attrib, 0, sizeof attrib );
|
|
|
|
|
attrib.non_exportable = local;
|
2002-06-29 13:46:34 +00:00
|
|
|
|
attrib.non_revocable = nonrevocable;
|
2002-11-03 12:46:52 +00:00
|
|
|
|
attrib.trust_depth = trust_depth;
|
|
|
|
|
attrib.trust_value = trust_value;
|
|
|
|
|
attrib.trust_regexp = trust_regexp;
|
1998-07-29 19:35:05 +00:00
|
|
|
|
node->flag &= ~NODFLG_MARK_A;
|
2002-06-29 13:46:34 +00:00
|
|
|
|
|
|
|
|
|
/* we force creation of a v4 signature for local
|
|
|
|
|
* signatures, otherwise we would not generate the
|
|
|
|
|
* subpacket with v3 keys and the signature becomes
|
|
|
|
|
* exportable */
|
|
|
|
|
|
|
|
|
|
if(selfsig)
|
|
|
|
|
rc = make_keysig_packet( &sig, primary_pk,
|
|
|
|
|
node->pkt->pkt.user_id,
|
|
|
|
|
NULL,
|
|
|
|
|
sk,
|
|
|
|
|
0x13, 0, force_v4?4:0, 0, 0,
|
|
|
|
|
keygen_add_std_prefs, primary_pk);
|
|
|
|
|
else
|
|
|
|
|
rc = make_keysig_packet( &sig, primary_pk,
|
|
|
|
|
node->pkt->pkt.user_id,
|
|
|
|
|
NULL,
|
|
|
|
|
sk,
|
|
|
|
|
class, 0, force_v4?4:0,
|
|
|
|
|
timestamp, duration,
|
|
|
|
|
sign_mk_attrib, &attrib );
|
1998-07-29 19:35:05 +00:00
|
|
|
|
if( rc ) {
|
2002-06-29 13:46:34 +00:00
|
|
|
|
log_error(_("signing failed: %s\n"), g10_errstr(rc));
|
1998-07-29 19:35:05 +00:00
|
|
|
|
goto leave;
|
1998-04-20 15:52:20 +00:00
|
|
|
|
}
|
2002-06-29 13:46:34 +00:00
|
|
|
|
|
1998-07-29 19:35:05 +00:00
|
|
|
|
*ret_modified = 1; /* we changed the keyblock */
|
2002-06-29 13:46:34 +00:00
|
|
|
|
update_trust = 1;
|
1998-07-29 19:35:05 +00:00
|
|
|
|
|
2005-07-27 18:10:56 +00:00
|
|
|
|
pkt = xmalloc_clear( sizeof *pkt );
|
1998-07-29 19:35:05 +00:00
|
|
|
|
pkt->pkttype = PKT_SIGNATURE;
|
|
|
|
|
pkt->pkt.signature = sig;
|
|
|
|
|
insert_kbnode( node, new_kbnode(pkt), PKT_SIGNATURE );
|
|
|
|
|
goto reloop;
|
1998-04-20 15:52:20 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
1998-09-14 15:49:56 +00:00
|
|
|
|
|
2002-06-29 13:46:34 +00:00
|
|
|
|
/* Delete any sigs that got promoted */
|
|
|
|
|
for( node=keyblock; node; node = node->next )
|
|
|
|
|
if( node->flag & NODFLG_DELSIG)
|
|
|
|
|
delete_kbnode(node);
|
|
|
|
|
} /* end loop over signators */
|
1998-04-20 15:52:20 +00:00
|
|
|
|
|
|
|
|
|
leave:
|
1998-06-29 12:30:57 +00:00
|
|
|
|
release_sk_list( sk_list );
|
1998-10-07 13:30:43 +00:00
|
|
|
|
if( sk )
|
|
|
|
|
free_secret_key(sk);
|
1998-04-20 15:52:20 +00:00
|
|
|
|
return rc;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1998-07-29 19:35:05 +00:00
|
|
|
|
/****************
|
|
|
|
|
* Change the passphrase of the primary and all secondary keys.
|
|
|
|
|
* We use only one passphrase for all keys.
|
|
|
|
|
*/
|
|
|
|
|
static int
|
|
|
|
|
change_passphrase( KBNODE keyblock )
|
1998-04-20 15:52:20 +00:00
|
|
|
|
{
|
|
|
|
|
int rc = 0;
|
1998-07-29 19:35:05 +00:00
|
|
|
|
int changed=0;
|
1998-04-20 15:52:20 +00:00
|
|
|
|
KBNODE node;
|
1998-06-29 12:30:57 +00:00
|
|
|
|
PKT_secret_key *sk;
|
1998-05-26 13:38:00 +00:00
|
|
|
|
char *passphrase = NULL;
|
2000-07-14 17:34:53 +00:00
|
|
|
|
int no_primary_secrets = 0;
|
2005-01-27 11:48:33 +00:00
|
|
|
|
int any;
|
1998-04-20 15:52:20 +00:00
|
|
|
|
|
1998-06-29 12:30:57 +00:00
|
|
|
|
node = find_kbnode( keyblock, PKT_SECRET_KEY );
|
1998-04-20 15:52:20 +00:00
|
|
|
|
if( !node ) {
|
|
|
|
|
log_error("Oops; secret key not found anymore!\n");
|
|
|
|
|
goto leave;
|
|
|
|
|
}
|
1998-06-29 12:30:57 +00:00
|
|
|
|
sk = node->pkt->pkt.secret_key;
|
1998-04-20 15:52:20 +00:00
|
|
|
|
|
2005-01-27 11:48:33 +00:00
|
|
|
|
for (any = 0, node=keyblock; node; node = node->next) {
|
|
|
|
|
if (node->pkt->pkttype == PKT_SECRET_KEY
|
|
|
|
|
|| node->pkt->pkttype == PKT_SECRET_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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (!any) {
|
|
|
|
|
tty_printf (_("Key has only stub or on-card key items - "
|
|
|
|
|
"no passphrase to change.\n"));
|
|
|
|
|
goto leave;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* See how to handle this key. */
|
1998-06-29 12:30:57 +00:00
|
|
|
|
switch( is_secret_key_protected( sk ) ) {
|
1998-04-20 15:52:20 +00:00
|
|
|
|
case -1:
|
2002-06-29 13:46:34 +00:00
|
|
|
|
rc = G10ERR_PUBKEY_ALGO;
|
1998-04-20 15:52:20 +00:00
|
|
|
|
break;
|
|
|
|
|
case 0:
|
1998-07-06 10:23:57 +00:00
|
|
|
|
tty_printf(_("This key is not protected.\n"));
|
1998-04-20 15:52:20 +00:00
|
|
|
|
break;
|
|
|
|
|
default:
|
2000-07-14 17:34:53 +00:00
|
|
|
|
if( sk->protect.s2k.mode == 1001 ) {
|
|
|
|
|
tty_printf(_("Secret parts of primary key are not available.\n"));
|
|
|
|
|
no_primary_secrets = 1;
|
|
|
|
|
}
|
2005-01-27 11:48:33 +00:00
|
|
|
|
else if( sk->protect.s2k.mode == 1002 ) {
|
2005-01-28 00:50:10 +00:00
|
|
|
|
tty_printf(_("Secret parts of primary key are stored on-card.\n"));
|
2005-01-27 11:48:33 +00:00
|
|
|
|
no_primary_secrets = 1;
|
|
|
|
|
}
|
2000-07-14 17:34:53 +00:00
|
|
|
|
else {
|
|
|
|
|
tty_printf(_("Key is protected.\n"));
|
|
|
|
|
rc = check_secret_key( sk, 0 );
|
|
|
|
|
if( !rc )
|
|
|
|
|
passphrase = get_last_passphrase();
|
|
|
|
|
}
|
1998-04-20 15:52:20 +00:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2005-01-27 11:48:33 +00:00
|
|
|
|
/* Unprotect all subkeys (use the supplied passphrase or ask)*/
|
1998-07-29 19:35:05 +00:00
|
|
|
|
for(node=keyblock; !rc && node; node = node->next ) {
|
1998-06-29 12:30:57 +00:00
|
|
|
|
if( node->pkt->pkttype == PKT_SECRET_SUBKEY ) {
|
|
|
|
|
PKT_secret_key *subsk = node->pkt->pkt.secret_key;
|
2005-01-27 11:48:33 +00:00
|
|
|
|
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();
|
|
|
|
|
}
|
1998-05-26 13:38:00 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
1998-05-05 20:34:20 +00:00
|
|
|
|
|
1998-04-20 15:52:20 +00:00
|
|
|
|
if( rc )
|
2002-06-29 13:46:34 +00:00
|
|
|
|
tty_printf(_("Can't edit this key: %s\n"), g10_errstr(rc));
|
1998-04-20 15:52:20 +00:00
|
|
|
|
else {
|
1998-05-04 18:49:26 +00:00
|
|
|
|
DEK *dek = NULL;
|
2005-07-27 18:10:56 +00:00
|
|
|
|
STRING2KEY *s2k = xmalloc_secure( sizeof *s2k );
|
2002-06-29 13:46:34 +00:00
|
|
|
|
const char *errtext = NULL;
|
1998-04-20 15:52:20 +00:00
|
|
|
|
|
1998-05-04 18:49:26 +00:00
|
|
|
|
tty_printf(_("Enter the new passphrase for this secret key.\n\n") );
|
1998-04-20 15:52:20 +00:00
|
|
|
|
|
1998-05-26 13:38:00 +00:00
|
|
|
|
set_next_passphrase( NULL );
|
1998-04-20 15:52:20 +00:00
|
|
|
|
for(;;) {
|
1998-09-28 19:25:31 +00:00
|
|
|
|
s2k->mode = opt.s2k_mode;
|
* main.h: Create S2K_DIGEST_ALGO macro so we do not need to always set
opt.s2k_digest_algo. This helps fix a problem with PGP 2.x encrypted
symmetric messages. Change all callers (encode.c, g10.c, keyedit.c,
keygen.c, passphrase.c, sign.c).
* armor.c, cardglue.c, getkey.c, import.c, keygen.c: Be consistent in some
more quoted strings. Always use 'user ID', not 'user id', "quotes" for
user IDs, etc.
2004-09-24 20:34:38 +00:00
|
|
|
|
s2k->hash_algo = S2K_DIGEST_ALGO;
|
2002-06-29 13:46:34 +00:00
|
|
|
|
dek = passphrase_to_dek( NULL, 0, opt.s2k_cipher_algo,
|
2003-04-10 09:56:47 +00:00
|
|
|
|
s2k, 2, errtext, NULL);
|
1998-05-04 18:49:26 +00:00
|
|
|
|
if( !dek ) {
|
2003-04-10 09:56:47 +00:00
|
|
|
|
errtext = N_("passphrase not correctly repeated; try again");
|
|
|
|
|
tty_printf ("%s.\n", _(errtext));
|
1998-05-04 18:49:26 +00:00
|
|
|
|
}
|
|
|
|
|
else if( !dek->keylen ) {
|
1998-04-20 15:52:20 +00:00
|
|
|
|
rc = 0;
|
1998-05-04 18:49:26 +00:00
|
|
|
|
tty_printf(_( "You don't want a passphrase -"
|
|
|
|
|
" this is probably a *bad* idea!\n\n"));
|
1998-11-27 11:42:49 +00:00
|
|
|
|
if( cpr_get_answer_is_yes("change_passwd.empty.okay",
|
2004-10-10 15:27:14 +00:00
|
|
|
|
_("Do you really want to do this? (y/N) ")))
|
2003-08-26 04:07:52 +00:00
|
|
|
|
{
|
1998-04-20 15:52:20 +00:00
|
|
|
|
changed++;
|
2003-08-26 04:07:52 +00:00
|
|
|
|
break;
|
|
|
|
|
}
|
1998-04-20 15:52:20 +00:00
|
|
|
|
}
|
|
|
|
|
else { /* okay */
|
2000-07-14 17:34:53 +00:00
|
|
|
|
rc = 0;
|
|
|
|
|
if( !no_primary_secrets ) {
|
|
|
|
|
sk->protect.algo = dek->algo;
|
|
|
|
|
sk->protect.s2k = *s2k;
|
|
|
|
|
rc = protect_secret_key( sk, dek );
|
|
|
|
|
}
|
1998-05-26 13:38:00 +00:00
|
|
|
|
for(node=keyblock; !rc && node; node = node->next ) {
|
1998-06-29 12:30:57 +00:00
|
|
|
|
if( node->pkt->pkttype == PKT_SECRET_SUBKEY ) {
|
|
|
|
|
PKT_secret_key *subsk = node->pkt->pkt.secret_key;
|
2005-01-27 11:48:33 +00:00
|
|
|
|
if ( !(subsk->is_protected
|
|
|
|
|
&& (subsk->protect.s2k.mode == 1001
|
|
|
|
|
|| subsk->protect.s2k.mode == 1002))) {
|
|
|
|
|
subsk->protect.algo = dek->algo;
|
|
|
|
|
subsk->protect.s2k = *s2k;
|
|
|
|
|
rc = protect_secret_key( subsk, dek );
|
|
|
|
|
}
|
1998-05-26 13:38:00 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
1998-04-20 15:52:20 +00:00
|
|
|
|
if( rc )
|
2005-01-27 11:48:33 +00:00
|
|
|
|
log_error("protect_secret_key failed: %s\n",
|
|
|
|
|
g10_errstr(rc) );
|
1998-04-20 15:52:20 +00:00
|
|
|
|
else
|
|
|
|
|
changed++;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2005-07-27 18:10:56 +00:00
|
|
|
|
xfree(s2k);
|
|
|
|
|
xfree(dek);
|
1998-04-20 15:52:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
1998-07-29 19:35:05 +00:00
|
|
|
|
leave:
|
2005-07-27 18:10:56 +00:00
|
|
|
|
xfree( passphrase );
|
1998-07-29 19:35:05 +00:00
|
|
|
|
set_next_passphrase( NULL );
|
|
|
|
|
return changed && !rc;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
1998-10-17 14:47:14 +00:00
|
|
|
|
/****************
|
|
|
|
|
* There are some keys out (due to a bug in gnupg), where the sequence
|
|
|
|
|
* of the packets is wrong. This function fixes that.
|
1999-05-19 14:12:26 +00:00
|
|
|
|
* Returns: true if the keyblock has been fixed.
|
1999-05-22 20:54:54 +00:00
|
|
|
|
*
|
|
|
|
|
* Note: This function does not work if there is more than one user ID.
|
1998-10-17 14:47:14 +00:00
|
|
|
|
*/
|
|
|
|
|
static int
|
|
|
|
|
fix_keyblock( KBNODE keyblock )
|
|
|
|
|
{
|
|
|
|
|
KBNODE node, last, subkey;
|
|
|
|
|
int fixed=0;
|
|
|
|
|
|
|
|
|
|
/* locate key signatures of class 0x10..0x13 behind sub key packets */
|
|
|
|
|
for( subkey=last=NULL, node = keyblock; node;
|
|
|
|
|
last=node, node = node->next ) {
|
|
|
|
|
switch( node->pkt->pkttype ) {
|
|
|
|
|
case PKT_PUBLIC_SUBKEY:
|
|
|
|
|
case PKT_SECRET_SUBKEY:
|
|
|
|
|
if( !subkey )
|
|
|
|
|
subkey = last; /* actually it is the one before the subkey */
|
|
|
|
|
break;
|
|
|
|
|
case PKT_SIGNATURE:
|
|
|
|
|
if( subkey ) {
|
|
|
|
|
PKT_signature *sig = node->pkt->pkt.signature;
|
|
|
|
|
if( sig->sig_class >= 0x10 && sig->sig_class <= 0x13 ) {
|
1998-11-10 12:59:59 +00:00
|
|
|
|
log_info(_(
|
|
|
|
|
"moving a key signature to the correct place\n"));
|
1998-10-17 14:47:14 +00:00
|
|
|
|
last->next = node->next;
|
|
|
|
|
node->next = subkey->next;
|
|
|
|
|
subkey->next = node;
|
|
|
|
|
node = last;
|
|
|
|
|
fixed=1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
default: break;
|
|
|
|
|
}
|
|
|
|
|
}
|
1998-07-29 19:35:05 +00:00
|
|
|
|
|
1998-10-17 14:47:14 +00:00
|
|
|
|
return fixed;
|
|
|
|
|
}
|
1998-07-29 19:35:05 +00:00
|
|
|
|
|
2004-12-14 14:42:41 +00:00
|
|
|
|
static int
|
|
|
|
|
parse_sign_type(const char *str,int *localsig,int *nonrevokesig,int *trustsig)
|
|
|
|
|
{
|
|
|
|
|
const char *p=str;
|
|
|
|
|
|
|
|
|
|
while(*p)
|
|
|
|
|
{
|
|
|
|
|
if(ascii_strncasecmp(p,"l",1)==0)
|
|
|
|
|
{
|
|
|
|
|
*localsig=1;
|
|
|
|
|
p++;
|
|
|
|
|
}
|
|
|
|
|
else if(ascii_strncasecmp(p,"nr",2)==0)
|
|
|
|
|
{
|
|
|
|
|
*nonrevokesig=1;
|
|
|
|
|
p+=2;
|
|
|
|
|
}
|
|
|
|
|
else if(ascii_strncasecmp(p,"t",1)==0)
|
|
|
|
|
{
|
|
|
|
|
*trustsig=1;
|
|
|
|
|
p++;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
2005-03-21 15:24:48 +00:00
|
|
|
|
|
1998-07-29 19:35:05 +00:00
|
|
|
|
/****************
|
2004-02-12 18:32:09 +00:00
|
|
|
|
* Menu driven key editor. If seckey_check is true, then a secret key
|
|
|
|
|
* that matches username will be looked for. If it is false, not all
|
|
|
|
|
* commands will be available.
|
1998-07-29 19:35:05 +00:00
|
|
|
|
*
|
|
|
|
|
* Note: to keep track of some selection we use node->mark MARKBIT_xxxx.
|
|
|
|
|
*/
|
|
|
|
|
|
2004-12-14 14:42:41 +00:00
|
|
|
|
/* Need an SK for this command */
|
|
|
|
|
#define KEYEDIT_NEED_SK 1
|
|
|
|
|
/* Cannot be viewing the SK for this command */
|
|
|
|
|
#define KEYEDIT_NOT_SK 2
|
|
|
|
|
/* Must be viewing the SK for this command */
|
|
|
|
|
#define KEYEDIT_ONLY_SK 4
|
|
|
|
|
/* Match the tail of the string */
|
|
|
|
|
#define KEYEDIT_TAIL_MATCH 8
|
|
|
|
|
|
2005-01-11 04:15:55 +00:00
|
|
|
|
enum cmdids
|
|
|
|
|
{
|
|
|
|
|
cmdNONE = 0,
|
|
|
|
|
cmdQUIT, cmdHELP, cmdFPR, cmdLIST, cmdSELUID, cmdCHECK, cmdSIGN,
|
|
|
|
|
cmdREVSIG, cmdREVKEY, cmdREVUID, cmdDELSIG, cmdPRIMARY, cmdDEBUG,
|
|
|
|
|
cmdSAVE, cmdADDUID, cmdADDPHOTO, cmdDELUID, cmdADDKEY, cmdDELKEY,
|
|
|
|
|
cmdADDREVOKER, cmdTOGGLE, cmdSELKEY, cmdPASSWD, cmdTRUST, cmdPREF,
|
2005-10-14 04:07:13 +00:00
|
|
|
|
cmdEXPIRE, cmdBACKSIGN, cmdENABLEKEY, cmdDISABLEKEY, cmdSHOWPREF,
|
|
|
|
|
cmdSETPREF, cmdPREFKS, cmdINVCMD, cmdSHOWPHOTO, cmdUPDTRUST, cmdCHKTRUST,
|
2005-11-10 23:25:20 +00:00
|
|
|
|
cmdADDCARDKEY, cmdKEYTOCARD, cmdBKUPTOCARD, cmdCLEAN, cmdMINIMIZE, cmdNOP
|
2005-01-11 04:15:55 +00:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static struct
|
|
|
|
|
{
|
|
|
|
|
const char *name;
|
|
|
|
|
enum cmdids id;
|
|
|
|
|
int flags;
|
|
|
|
|
const char *desc;
|
|
|
|
|
} cmds[] =
|
|
|
|
|
{
|
|
|
|
|
{ "quit" , cmdQUIT , 0, N_("quit this menu") },
|
|
|
|
|
{ "q" , cmdQUIT , 0, NULL },
|
|
|
|
|
{ "save" , cmdSAVE , 0, N_("save and quit") },
|
|
|
|
|
{ "help" , cmdHELP , 0, N_("show this help") },
|
|
|
|
|
{ "?" , cmdHELP , 0, NULL },
|
|
|
|
|
{ "fpr" , cmdFPR , 0, N_("show key fingerprint") },
|
|
|
|
|
{ "list" , cmdLIST , 0, N_("list key and user IDs") },
|
|
|
|
|
{ "l" , cmdLIST , 0, NULL },
|
|
|
|
|
{ "uid" , cmdSELUID , 0, N_("select user ID N") },
|
|
|
|
|
{ "key" , cmdSELKEY , 0, N_("select subkey N") },
|
|
|
|
|
{ "check" , cmdCHECK , 0, N_("check signatures") },
|
|
|
|
|
{ "c" , cmdCHECK , 0, NULL },
|
2005-10-14 04:07:13 +00:00
|
|
|
|
{ "backsign", cmdBACKSIGN , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK, NULL },
|
2005-02-15 11:02:32 +00:00
|
|
|
|
{ "sign" , cmdSIGN , KEYEDIT_NOT_SK|KEYEDIT_TAIL_MATCH,
|
|
|
|
|
N_("sign selected user IDs [* see below for related commands]") },
|
2005-01-11 04:15:55 +00:00
|
|
|
|
{ "s" , cmdSIGN , KEYEDIT_NOT_SK, NULL },
|
|
|
|
|
/* "lsign" and friends will never match since "sign" comes first
|
|
|
|
|
and it is a tail match. They are just here so they show up in
|
|
|
|
|
the help menu. */
|
|
|
|
|
{ "lsign" , cmdNOP , 0, N_("sign selected user IDs locally") },
|
2005-02-15 11:02:32 +00:00
|
|
|
|
{ "tsign" , cmdNOP , 0,
|
|
|
|
|
N_("sign selected user IDs with a trust signature") },
|
|
|
|
|
{ "nrsign" , cmdNOP , 0,
|
|
|
|
|
N_("sign selected user IDs with a non-revocable signature") },
|
|
|
|
|
|
2005-01-11 04:15:55 +00:00
|
|
|
|
{ "debug" , cmdDEBUG , 0, NULL },
|
2005-02-15 11:02:32 +00:00
|
|
|
|
{ "adduid" , cmdADDUID , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
|
|
|
|
|
N_("add a user ID") },
|
|
|
|
|
{ "addphoto", cmdADDPHOTO , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
|
|
|
|
|
N_("add a photo ID") },
|
|
|
|
|
{ "deluid" , cmdDELUID , KEYEDIT_NOT_SK,
|
|
|
|
|
N_("delete selected user IDs") },
|
2005-01-11 04:15:55 +00:00
|
|
|
|
/* delphoto is really deluid in disguise */
|
|
|
|
|
{ "delphoto", cmdDELUID , KEYEDIT_NOT_SK, NULL },
|
2005-02-15 11:02:32 +00:00
|
|
|
|
|
|
|
|
|
{ "addkey" , cmdADDKEY , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
|
|
|
|
|
N_("add a subkey") },
|
|
|
|
|
|
2005-01-11 04:15:55 +00:00
|
|
|
|
#ifdef ENABLE_CARD_SUPPORT
|
2005-02-15 11:02:32 +00:00
|
|
|
|
{ "addcardkey", cmdADDCARDKEY , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
|
|
|
|
|
N_("add a key to a smartcard") },
|
|
|
|
|
{ "keytocard", cmdKEYTOCARD , KEYEDIT_NEED_SK|KEYEDIT_ONLY_SK,
|
|
|
|
|
N_("move a key to a smartcard")},
|
|
|
|
|
{ "bkuptocard", cmdBKUPTOCARD , KEYEDIT_NEED_SK|KEYEDIT_ONLY_SK,
|
|
|
|
|
N_("move a backup key to a smartcard")},
|
2005-01-11 04:15:55 +00:00
|
|
|
|
#endif /*ENABLE_CARD_SUPPORT*/
|
2005-02-15 11:02:32 +00:00
|
|
|
|
|
|
|
|
|
{ "delkey" , cmdDELKEY , KEYEDIT_NOT_SK,
|
|
|
|
|
N_("delete selected subkeys") },
|
|
|
|
|
{ "addrevoker",cmdADDREVOKER,KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
|
|
|
|
|
N_("add a revocation key") },
|
|
|
|
|
{ "delsig" , cmdDELSIG , KEYEDIT_NOT_SK,
|
|
|
|
|
N_("delete signatures from the selected user IDs") },
|
|
|
|
|
{ "expire" , cmdEXPIRE , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
|
|
|
|
|
N_("change the expiration date for the key or selected subkeys") },
|
|
|
|
|
{ "primary" , cmdPRIMARY , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
|
|
|
|
|
N_("flag the selected user ID as primary")},
|
|
|
|
|
{ "toggle" , cmdTOGGLE , KEYEDIT_NEED_SK,
|
|
|
|
|
N_("toggle between the secret and public key listings") },
|
2005-01-11 04:15:55 +00:00
|
|
|
|
{ "t" , cmdTOGGLE , KEYEDIT_NEED_SK, NULL },
|
2005-02-15 11:02:32 +00:00
|
|
|
|
{ "pref" , cmdPREF , KEYEDIT_NOT_SK,
|
|
|
|
|
N_("list preferences (expert)")},
|
|
|
|
|
{ "showpref", cmdSHOWPREF , KEYEDIT_NOT_SK,
|
|
|
|
|
N_("list preferences (verbose)") },
|
|
|
|
|
{ "setpref" , cmdSETPREF , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
|
|
|
|
|
N_("set preference list for the selected user IDs") },
|
2005-01-11 04:15:55 +00:00
|
|
|
|
/* Alias */
|
|
|
|
|
{ "updpref" , cmdSETPREF , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK, NULL },
|
2005-02-15 11:02:32 +00:00
|
|
|
|
|
|
|
|
|
{ "keyserver",cmdPREFKS , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
|
|
|
|
|
N_("set preferred keyserver URL for the selected user IDs")},
|
|
|
|
|
{ "passwd" , cmdPASSWD , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
|
|
|
|
|
N_("change the passphrase") },
|
2005-01-11 04:15:55 +00:00
|
|
|
|
/* Alias */
|
|
|
|
|
{ "password", cmdPASSWD , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK, NULL },
|
2005-02-15 11:02:32 +00:00
|
|
|
|
|
2005-01-11 04:15:55 +00:00
|
|
|
|
{ "trust" , cmdTRUST , KEYEDIT_NOT_SK, N_("change the ownertrust") },
|
2005-02-15 11:02:32 +00:00
|
|
|
|
{ "revsig" , cmdREVSIG , KEYEDIT_NOT_SK,
|
|
|
|
|
N_("revoke signatures on the selected user IDs") },
|
|
|
|
|
{ "revuid" , cmdREVUID , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
|
|
|
|
|
N_("revoke selected user IDs") },
|
2005-01-11 04:15:55 +00:00
|
|
|
|
/* Alias */
|
|
|
|
|
{ "revphoto", cmdREVUID , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK, NULL },
|
2005-02-15 11:02:32 +00:00
|
|
|
|
|
|
|
|
|
{ "revkey" , cmdREVKEY , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
|
|
|
|
|
N_("revoke key or selected subkeys") },
|
2005-01-11 04:15:55 +00:00
|
|
|
|
{ "enable" , cmdENABLEKEY , KEYEDIT_NOT_SK, N_("enable key") },
|
|
|
|
|
{ "disable" , cmdDISABLEKEY, KEYEDIT_NOT_SK, N_("disable key") },
|
|
|
|
|
{ "showphoto",cmdSHOWPHOTO , 0, N_("show selected photo IDs") },
|
2005-06-09 02:53:18 +00:00
|
|
|
|
{ "clean", cmdCLEAN , KEYEDIT_NOT_SK,
|
2005-11-18 04:25:07 +00:00
|
|
|
|
N_("compact unusable user IDs and remove unusable signatures from key")},
|
2005-11-10 23:25:20 +00:00
|
|
|
|
{ "minimize", cmdMINIMIZE , KEYEDIT_NOT_SK,
|
2005-11-18 04:25:07 +00:00
|
|
|
|
N_("compact unusable user IDs and remove all signatures from key") },
|
2005-01-11 04:15:55 +00:00
|
|
|
|
{ NULL, cmdNONE, 0, NULL }
|
|
|
|
|
};
|
|
|
|
|
|
2005-03-18 22:07:12 +00:00
|
|
|
|
#ifdef HAVE_LIBREADLINE
|
|
|
|
|
|
|
|
|
|
/* These two functions are used by readline for command completion. */
|
|
|
|
|
|
2005-03-21 15:24:48 +00:00
|
|
|
|
static char *
|
|
|
|
|
command_generator(const char *text,int state)
|
2005-03-18 22:07:12 +00:00
|
|
|
|
{
|
|
|
|
|
static int list_index,len;
|
|
|
|
|
const char *name;
|
|
|
|
|
|
|
|
|
|
/* If this is a new word to complete, initialize now. This includes
|
|
|
|
|
saving the length of TEXT for efficiency, and initializing the
|
|
|
|
|
index variable to 0. */
|
|
|
|
|
if(!state)
|
|
|
|
|
{
|
|
|
|
|
list_index=0;
|
|
|
|
|
len=strlen(text);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Return the next partial match */
|
|
|
|
|
while((name=cmds[list_index].name))
|
|
|
|
|
{
|
|
|
|
|
/* Only complete commands that have help text */
|
|
|
|
|
if(cmds[list_index++].desc && strncmp(name,text,len)==0)
|
|
|
|
|
return strdup(name);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2005-03-21 15:24:48 +00:00
|
|
|
|
static char **
|
|
|
|
|
keyedit_completion(const char *text, int start, int end)
|
2005-03-18 22:07:12 +00:00
|
|
|
|
{
|
|
|
|
|
/* If we are at the start of a line, we try and command-complete.
|
|
|
|
|
If not, just do nothing for now. */
|
|
|
|
|
|
|
|
|
|
if(start==0)
|
|
|
|
|
return rl_completion_matches(text,command_generator);
|
|
|
|
|
|
|
|
|
|
rl_attempted_completion_over=1;
|
|
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
2005-03-21 15:24:48 +00:00
|
|
|
|
#endif /* HAVE_LIBREADLINE */
|
|
|
|
|
|
2005-03-18 22:07:12 +00:00
|
|
|
|
|
1998-07-29 19:35:05 +00:00
|
|
|
|
void
|
2004-02-12 18:32:09 +00:00
|
|
|
|
keyedit_menu( const char *username, STRLIST locusr,
|
|
|
|
|
STRLIST commands, int quiet, int seckey_check )
|
1998-07-29 19:35:05 +00:00
|
|
|
|
{
|
1999-07-07 11:28:26 +00:00
|
|
|
|
enum cmdids cmd = 0;
|
1998-07-29 19:35:05 +00:00
|
|
|
|
int rc = 0;
|
|
|
|
|
KBNODE keyblock = NULL;
|
2002-06-29 13:46:34 +00:00
|
|
|
|
KEYDB_HANDLE kdbhd = NULL;
|
1998-07-29 19:35:05 +00:00
|
|
|
|
KBNODE sec_keyblock = NULL;
|
2002-06-29 13:46:34 +00:00
|
|
|
|
KEYDB_HANDLE sec_kdbhd = NULL;
|
1998-07-29 19:35:05 +00:00
|
|
|
|
KBNODE cur_keyblock;
|
|
|
|
|
char *answer = NULL;
|
|
|
|
|
int redisplay = 1;
|
|
|
|
|
int modified = 0;
|
|
|
|
|
int sec_modified = 0;
|
|
|
|
|
int toggle;
|
1998-11-20 17:42:18 +00:00
|
|
|
|
int have_commands = !!commands;
|
1998-07-29 19:35:05 +00:00
|
|
|
|
|
2002-06-29 13:46:34 +00:00
|
|
|
|
if ( opt.command_fd != -1 )
|
|
|
|
|
;
|
2004-10-28 22:09:09 +00:00
|
|
|
|
else if( opt.batch && !have_commands )
|
2004-10-28 03:57:30 +00:00
|
|
|
|
{
|
|
|
|
|
log_error(_("can't do this in batch mode\n"));
|
1998-07-29 19:35:05 +00:00
|
|
|
|
goto leave;
|
2004-10-28 03:57:30 +00:00
|
|
|
|
}
|
1998-04-20 15:52:20 +00:00
|
|
|
|
|
2005-03-10 18:40:57 +00:00
|
|
|
|
#ifdef HAVE_W32_SYSTEM
|
|
|
|
|
/* Due to Windows peculiarities we need to make sure that the
|
|
|
|
|
trustdb stale check is done before we open another file
|
|
|
|
|
(i.e. by searching for a key). In theory we could make sure
|
|
|
|
|
that the files are closed after use but the open/close caches
|
|
|
|
|
inhibits that and flushing the cache right before the stale
|
|
|
|
|
check is not easy to implement. Thus we take the easy way out
|
|
|
|
|
and run the stale check as early as possible. Note, that for
|
|
|
|
|
non- W32 platforms it is run indirectly trough a call to
|
|
|
|
|
get_validity (). */
|
|
|
|
|
check_trustdb_stale ();
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/* Get the public key */
|
2002-12-26 22:22:50 +00:00
|
|
|
|
rc = get_pubkey_byname (NULL, username, &keyblock, &kdbhd, 1);
|
1998-07-29 19:35:05 +00:00
|
|
|
|
if( rc )
|
|
|
|
|
goto leave;
|
1998-10-17 14:47:14 +00:00
|
|
|
|
if( fix_keyblock( keyblock ) )
|
|
|
|
|
modified++;
|
1999-05-22 20:54:54 +00:00
|
|
|
|
if( collapse_uids( &keyblock ) )
|
|
|
|
|
modified++;
|
2002-12-03 23:31:48 +00:00
|
|
|
|
reorder_keyblock(keyblock);
|
1998-07-29 19:35:05 +00:00
|
|
|
|
|
2004-02-12 18:32:09 +00:00
|
|
|
|
if(seckey_check)
|
|
|
|
|
{/* see whether we have a matching secret key */
|
2002-06-29 13:46:34 +00:00
|
|
|
|
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);
|
|
|
|
|
}
|
2004-10-28 01:58:01 +00:00
|
|
|
|
if (!rc)
|
|
|
|
|
{
|
2002-06-29 13:46:34 +00:00
|
|
|
|
rc = keydb_get_keyblock (sec_kdbhd, &sec_keyblock);
|
2004-10-28 01:58:01 +00:00
|
|
|
|
if (rc)
|
|
|
|
|
{
|
|
|
|
|
log_error (_("error reading secret keyblock \"%s\": %s\n"),
|
|
|
|
|
username, g10_errstr(rc));
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2002-06-29 13:46:34 +00:00
|
|
|
|
merge_keys_and_selfsig( sec_keyblock );
|
|
|
|
|
if( fix_keyblock( sec_keyblock ) )
|
2004-10-28 01:58:01 +00:00
|
|
|
|
sec_modified++;
|
|
|
|
|
}
|
|
|
|
|
}
|
2002-06-29 13:46:34 +00:00
|
|
|
|
|
|
|
|
|
if (rc) {
|
|
|
|
|
sec_keyblock = NULL;
|
|
|
|
|
keydb_release (sec_kdbhd); sec_kdbhd = NULL;
|
|
|
|
|
rc = 0;
|
|
|
|
|
}
|
|
|
|
|
|
2004-02-12 18:32:09 +00:00
|
|
|
|
if( sec_keyblock && !quiet )
|
|
|
|
|
tty_printf(_("Secret key is available.\n"));
|
1998-07-29 19:35:05 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
toggle = 0;
|
|
|
|
|
cur_keyblock = keyblock;
|
|
|
|
|
for(;;) { /* main loop */
|
2002-06-29 13:46:34 +00:00
|
|
|
|
int i, arg_number, photo;
|
|
|
|
|
const char *arg_string = "";
|
1998-07-29 19:35:05 +00:00
|
|
|
|
char *p;
|
2002-06-29 13:46:34 +00:00
|
|
|
|
PKT_public_key *pk=keyblock->pkt->pkt.public_key;
|
1998-07-29 19:35:05 +00:00
|
|
|
|
|
|
|
|
|
tty_printf("\n");
|
2005-04-22 03:36:20 +00:00
|
|
|
|
|
2004-02-12 18:32:09 +00:00
|
|
|
|
if( redisplay && !quiet )
|
|
|
|
|
{
|
2002-06-29 13:46:34 +00:00
|
|
|
|
show_key_with_all_names( cur_keyblock, 0, 1, 0, 1, 0 );
|
1998-07-29 19:35:05 +00:00
|
|
|
|
tty_printf("\n");
|
|
|
|
|
redisplay = 0;
|
2004-02-12 18:32:09 +00:00
|
|
|
|
}
|
1998-10-25 19:00:01 +00:00
|
|
|
|
do {
|
2005-07-27 18:10:56 +00:00
|
|
|
|
xfree(answer);
|
1998-11-20 17:42:18 +00:00
|
|
|
|
if( have_commands ) {
|
|
|
|
|
if( commands ) {
|
2005-07-27 18:10:56 +00:00
|
|
|
|
answer = xstrdup( commands->d );
|
1998-11-20 17:42:18 +00:00
|
|
|
|
commands = commands->next;
|
|
|
|
|
}
|
|
|
|
|
else if( opt.batch ) {
|
2005-07-27 18:10:56 +00:00
|
|
|
|
answer = xstrdup("quit");
|
1998-11-20 17:42:18 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
have_commands = 0;
|
|
|
|
|
}
|
2005-03-18 22:07:12 +00:00
|
|
|
|
if( !have_commands )
|
|
|
|
|
{
|
|
|
|
|
tty_enable_completion(keyedit_completion);
|
2002-06-29 13:46:34 +00:00
|
|
|
|
answer = cpr_get_no_help("keyedit.prompt", _("Command> "));
|
1998-11-20 17:42:18 +00:00
|
|
|
|
cpr_kill_prompt();
|
2005-03-18 22:07:12 +00:00
|
|
|
|
tty_disable_completion();
|
|
|
|
|
}
|
1998-10-25 19:00:01 +00:00
|
|
|
|
trim_spaces(answer);
|
|
|
|
|
} while( *answer == '#' );
|
1998-07-29 19:35:05 +00:00
|
|
|
|
|
2002-06-29 13:46:34 +00:00
|
|
|
|
arg_number = 0; /* Yes, here is the init which egcc complains about */
|
|
|
|
|
photo = 0; /* This too */
|
1998-07-29 19:35:05 +00:00
|
|
|
|
if( !*answer )
|
|
|
|
|
cmd = cmdLIST;
|
1998-09-11 05:47:32 +00:00
|
|
|
|
else if( *answer == CONTROL_D )
|
|
|
|
|
cmd = cmdQUIT;
|
* parse-packet.c (parse_signature): No need to reserve 8 bytes for the
unhashed signature cache any longer.
* misc.c (pct_expando): Add two new expandos - signer's fingerprint (%g),
and signer's primary fingerprint (%p).
* Makefile.am: Include W32LIBS where appropriate.
* g10.c (main): Add --rfc2440 alias for --openpgp since in a few months,
they won't be the same thing.
* keyserver.c (parse_keyserver_uri): Accept "http" as an alias for "hkp",
since it is occasionally written that way. (keyserver_spawn): Use
ascii_isspace to avoid locale issues.
* keygen.c (ask_user_id): Make --allow-freeform-uid apply to the email
field as well as the name field, and allow mixing fields when it is set.
* options.skel: Use subkeys.pgp.net as the default keyserver.
* trustdb.c (validate_one_keyblock): Certifications on revoked or expired
uids do not count in the web of trust.
* signal.c (init_one_signal, pause_on_sigusr, do_block): Only use
sigprocmask() if we have sigset_t, and only use sigaction() if we have
struct sigaction. This is for Forte c89 on Solaris which seems to define
only the function call half of the two pairs by default.
(pause_on_sigusr): Typo. (do_block): If we can't use sigprocmask() and
sigset_t, try to get the number of signals from NSIG as well as MAXSIG,
and if we can't, fail with an explanation.
* signal.c, tdbio.c: Comment out the transaction code. It was not used in
this version, and was causing some build problems on quasi-posix platforms
(Solaris and Forte c89).
* keylist.c (list_keyblock_colon): Don't include validity values when
listing secret keys since they can be incorrect and/or misleading. This
is a temporary kludge, and will be handled properly in 1.9/2.0.
* mainproc.c (check_sig_and_print): Only show the "key available from"
preferred keyserver line if the key is not currently present.
* keyedit.c (sign_uids): Do not sign expired uids without --expert (same
behavior as revoked uids). Do not allow signing a user ID without a
self-signature. --expert overrides. Add additional prompt to the
signature level question. (menu_expire): When changing expiration dates,
don't replace selfsigs on revoked uids since this would effectively
unrevoke them. There is also no point in replacing expired selfsigs.
This is bug #181
* g10.c (add_notation_data): Make sure that only ascii is passed to
iscntrl. Noted by Christian Biere.
* getkey.c (classify_user_id2): Replaced isspace by spacep
* keygen.c (ask_user_id): Ditto. (get_parameter_algo): Ditto.
* keyedit.c (keyedit_menu): Ditto.
* tdbdump.c (import_ownertrust): Ditto. s/isxdigit/hexdigitp/.
* revoke.c (ask_revocation_reason):
* keyserver.c (keyserver_spawn): Dito.
2003-07-10 14:30:07 +00:00
|
|
|
|
else if( digitp(answer ) ) {
|
1998-07-29 19:35:05 +00:00
|
|
|
|
cmd = cmdSELUID;
|
|
|
|
|
arg_number = atoi(answer);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
if( (p=strchr(answer,' ')) ) {
|
|
|
|
|
*p++ = 0;
|
|
|
|
|
trim_spaces(answer);
|
|
|
|
|
trim_spaces(p);
|
|
|
|
|
arg_number = atoi(p);
|
2002-06-29 13:46:34 +00:00
|
|
|
|
arg_string = p;
|
1998-07-29 19:35:05 +00:00
|
|
|
|
}
|
|
|
|
|
|
2004-12-14 14:42:41 +00:00
|
|
|
|
for(i=0; cmds[i].name; i++ )
|
|
|
|
|
{
|
|
|
|
|
if(cmds[i].flags & KEYEDIT_TAIL_MATCH)
|
|
|
|
|
{
|
|
|
|
|
size_t l=strlen(cmds[i].name);
|
|
|
|
|
size_t a=strlen(answer);
|
|
|
|
|
if(a>=l)
|
|
|
|
|
{
|
|
|
|
|
if(ascii_strcasecmp(&answer[a-l],cmds[i].name)==0)
|
|
|
|
|
{
|
|
|
|
|
answer[a-l]='\0';
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if( !ascii_strcasecmp( answer, cmds[i].name ) )
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if((cmds[i].flags & KEYEDIT_NEED_SK) && !sec_keyblock )
|
|
|
|
|
{
|
1998-12-08 12:20:53 +00:00
|
|
|
|
tty_printf(_("Need the secret key to do this.\n"));
|
1998-07-29 19:35:05 +00:00
|
|
|
|
cmd = cmdNOP;
|
2004-12-14 14:42:41 +00:00
|
|
|
|
}
|
|
|
|
|
else if(((cmds[i].flags & KEYEDIT_NOT_SK) && sec_keyblock
|
|
|
|
|
&& toggle)
|
|
|
|
|
||((cmds[i].flags & KEYEDIT_ONLY_SK) && sec_keyblock
|
|
|
|
|
&& !toggle))
|
|
|
|
|
{
|
2000-07-14 17:34:53 +00:00
|
|
|
|
tty_printf(_("Please use the command \"toggle\" first.\n"));
|
|
|
|
|
cmd = cmdNOP;
|
2004-12-14 14:42:41 +00:00
|
|
|
|
}
|
1998-07-29 19:35:05 +00:00
|
|
|
|
else
|
2004-12-14 14:42:41 +00:00
|
|
|
|
cmd = cmds[i].id;
|
1998-07-29 19:35:05 +00:00
|
|
|
|
}
|
2005-01-11 04:15:55 +00:00
|
|
|
|
switch( cmd )
|
|
|
|
|
{
|
1998-07-29 19:35:05 +00:00
|
|
|
|
case cmdHELP:
|
2004-12-14 14:42:41 +00:00
|
|
|
|
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 */
|
|
|
|
|
else if( cmds[i].desc )
|
2004-12-21 04:19:03 +00:00
|
|
|
|
tty_printf("%-11s %s\n", cmds[i].name, _(cmds[i].desc) );
|
2004-12-14 14:42:41 +00:00
|
|
|
|
}
|
2004-12-21 04:19:03 +00:00
|
|
|
|
|
|
|
|
|
tty_printf("\n");
|
|
|
|
|
tty_printf(_(
|
2005-02-15 11:02:32 +00:00
|
|
|
|
"* The `sign' command may be prefixed with an `l' for local "
|
|
|
|
|
"signatures (lsign),\n"
|
2005-01-11 04:15:55 +00:00
|
|
|
|
" a `t' for trust signatures (tsign), an `nr' for non-revocable signatures\n"
|
|
|
|
|
" (nrsign), or any combination thereof (ltsign, tnrsign, etc.).\n"));
|
2004-12-21 04:19:03 +00:00
|
|
|
|
|
1998-07-29 19:35:05 +00:00
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case cmdLIST:
|
|
|
|
|
redisplay = 1;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case cmdFPR:
|
|
|
|
|
show_key_and_fingerprint( keyblock );
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case cmdSELUID:
|
2005-04-24 16:05:41 +00:00
|
|
|
|
if(strlen(arg_string)==NAMEHASH_LEN*2)
|
|
|
|
|
redisplay=menu_select_uid_namehash(cur_keyblock,arg_string);
|
|
|
|
|
else
|
|
|
|
|
redisplay=menu_select_uid(cur_keyblock,arg_number);
|
1998-07-29 19:35:05 +00:00
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case cmdSELKEY:
|
|
|
|
|
if( menu_select_key( cur_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) */
|
2004-12-14 14:42:41 +00:00
|
|
|
|
{
|
2005-04-22 03:36:20 +00:00
|
|
|
|
int localsig=0,nonrevokesig=0,trustsig=0,interactive=0;
|
2002-06-29 13:46:34 +00:00
|
|
|
|
|
2004-12-14 14:42:41 +00:00
|
|
|
|
if( pk->is_revoked )
|
|
|
|
|
{
|
|
|
|
|
tty_printf(_("Key is revoked."));
|
|
|
|
|
|
|
|
|
|
if(opt.expert)
|
|
|
|
|
{
|
|
|
|
|
tty_printf(" ");
|
|
|
|
|
if(!cpr_get_answer_is_yes("keyedit.sign_revoked.okay",
|
|
|
|
|
_("Are you sure you still want"
|
|
|
|
|
" to sign it? (y/N) ")))
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
tty_printf(_(" Unable to sign.\n"));
|
2002-06-29 13:46:34 +00:00
|
|
|
|
break;
|
2004-12-14 14:42:41 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2002-06-29 13:46:34 +00:00
|
|
|
|
|
2005-04-22 03:36:20 +00:00
|
|
|
|
if(count_uids(keyblock) > 1 && !count_selected_uids(keyblock)
|
|
|
|
|
&& !cpr_get_answer_is_yes("keyedit.sign_all.okay",
|
|
|
|
|
_("Really sign all user IDs?"
|
|
|
|
|
" (y/N) ")))
|
2005-06-20 17:03:27 +00:00
|
|
|
|
{
|
2005-07-22 12:52:34 +00:00
|
|
|
|
if(opt.interactive)
|
|
|
|
|
interactive=1;
|
|
|
|
|
else
|
2005-06-20 17:03:27 +00:00
|
|
|
|
{
|
2005-07-22 12:52:34 +00:00
|
|
|
|
tty_printf(_("Hint: Select the user IDs to sign\n"));
|
2005-06-20 17:03:27 +00:00
|
|
|
|
have_commands = 0;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2005-07-22 12:52:34 +00:00
|
|
|
|
|
2005-06-20 17:03:27 +00:00
|
|
|
|
}
|
2004-12-14 14:42:41 +00:00
|
|
|
|
/* What sort of signing are we doing? */
|
|
|
|
|
if(!parse_sign_type(answer,&localsig,&nonrevokesig,&trustsig))
|
|
|
|
|
{
|
|
|
|
|
tty_printf(_("Unknown signature type `%s'\n"),answer);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2004-02-12 18:32:09 +00:00
|
|
|
|
|
2004-12-14 14:42:41 +00:00
|
|
|
|
sign_uids(keyblock, locusr, &modified,
|
2005-04-22 03:36:20 +00:00
|
|
|
|
localsig, nonrevokesig, trustsig, interactive);
|
2004-12-14 14:42:41 +00:00
|
|
|
|
}
|
1998-07-29 19:35:05 +00:00
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case cmdDEBUG:
|
|
|
|
|
dump_kbnode( cur_keyblock );
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case cmdTOGGLE:
|
|
|
|
|
toggle = !toggle;
|
|
|
|
|
cur_keyblock = toggle? sec_keyblock : keyblock;
|
|
|
|
|
redisplay = 1;
|
|
|
|
|
break;
|
|
|
|
|
|
2002-06-29 13:46:34 +00:00
|
|
|
|
case cmdADDPHOTO:
|
* packet.h, build-packet.c (build_sig_subpkt), export.c
(do_export_stream), import.c (remove_bad_stuff, import), parse-packet.c
(dump_sig_subpkt, parse_one_sig_subpkt): Remove vestigal code for the old
sig cache subpacket. This wasn't completely harmless as it caused
subpacket 101 to disappear on import and export.
* options.h, armor.c, cipher.c, g10.c, keyedit.c, pkclist.c, sign.c,
encode.c, getkey.c, revoke.c: The current flags for different levels of
PGP-ness are massively complex. This is step one in simplifying them. No
functional change yet, just use a macro to check for compliance level.
* sign.c (sign_file): Fix bug that causes spurious compression preference
warning.
* sign.c (clearsign_file): Fix bug that prevents proper warning message
from appearing when clearsigning in --pgp2 mode with a non-v3 RSA key.
* main.h, misc.c (compliance_option_string, compliance_string,
compliance_failure), pkclist.c (build_pk_list), sign.c (sign_file,
clearsign_file), encode.c (encode_crypt, write_pubkey_enc_from_list): New
functions to put the "this message may not be usable...." warning in one
place.
* options.h, g10.c (main): Part two of the simplification. Use a single
enum to indicate what we are compliant to (1991, 2440, PGPx, etc.)
* g10.c (main): Show errors for failure in export, send-keys, recv-keys,
and refresh-keys.
* options.h, g10.c (main): Give algorithm warnings for algorithms chosen
against the --pgpX and --openpgp rules.
* keydb.h, pkclist.c (algo_available): Make TIGER192 invalid in --openpgp
mode.
* sign.c (sign_file), pkclist.c (algo_available): Allow passing a hint of
0.
2003-05-03 04:07:45 +00:00
|
|
|
|
if (RFC2440 || RFC1991 || PGP2)
|
2002-06-29 13:46:34 +00:00
|
|
|
|
{
|
|
|
|
|
tty_printf(
|
|
|
|
|
_("This command is not allowed while in %s mode.\n"),
|
* packet.h, build-packet.c (build_sig_subpkt), export.c
(do_export_stream), import.c (remove_bad_stuff, import), parse-packet.c
(dump_sig_subpkt, parse_one_sig_subpkt): Remove vestigal code for the old
sig cache subpacket. This wasn't completely harmless as it caused
subpacket 101 to disappear on import and export.
* options.h, armor.c, cipher.c, g10.c, keyedit.c, pkclist.c, sign.c,
encode.c, getkey.c, revoke.c: The current flags for different levels of
PGP-ness are massively complex. This is step one in simplifying them. No
functional change yet, just use a macro to check for compliance level.
* sign.c (sign_file): Fix bug that causes spurious compression preference
warning.
* sign.c (clearsign_file): Fix bug that prevents proper warning message
from appearing when clearsigning in --pgp2 mode with a non-v3 RSA key.
* main.h, misc.c (compliance_option_string, compliance_string,
compliance_failure), pkclist.c (build_pk_list), sign.c (sign_file,
clearsign_file), encode.c (encode_crypt, write_pubkey_enc_from_list): New
functions to put the "this message may not be usable...." warning in one
place.
* options.h, g10.c (main): Part two of the simplification. Use a single
enum to indicate what we are compliant to (1991, 2440, PGPx, etc.)
* g10.c (main): Show errors for failure in export, send-keys, recv-keys,
and refresh-keys.
* options.h, g10.c (main): Give algorithm warnings for algorithms chosen
against the --pgpX and --openpgp rules.
* keydb.h, pkclist.c (algo_available): Make TIGER192 invalid in --openpgp
mode.
* sign.c (sign_file), pkclist.c (algo_available): Allow passing a hint of
0.
2003-05-03 04:07:45 +00:00
|
|
|
|
RFC2440?"OpenPGP":PGP2?"PGP2":"RFC-1991");
|
2002-06-29 13:46:34 +00:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
photo=1;
|
|
|
|
|
/* fall through */
|
|
|
|
|
|
1998-07-29 19:35:05 +00:00
|
|
|
|
case cmdADDUID:
|
2005-09-01 20:51:13 +00:00
|
|
|
|
if( menu_adduid( keyblock, sec_keyblock, photo, arg_string ) )
|
2004-03-28 05:33:00 +00:00
|
|
|
|
{
|
|
|
|
|
update_trust = 1;
|
1998-07-29 19:35:05 +00:00
|
|
|
|
redisplay = 1;
|
|
|
|
|
sec_modified = modified = 1;
|
2002-06-29 13:46:34 +00:00
|
|
|
|
merge_keys_and_selfsig( sec_keyblock );
|
|
|
|
|
merge_keys_and_selfsig( keyblock );
|
2004-03-28 05:33:00 +00:00
|
|
|
|
}
|
1998-07-29 19:35:05 +00:00
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case cmdDELUID: {
|
|
|
|
|
int n1;
|
|
|
|
|
|
|
|
|
|
if( !(n1=count_selected_uids(keyblock)) )
|
1999-09-01 13:40:07 +00:00
|
|
|
|
tty_printf(_("You must select at least one user ID.\n"));
|
2002-06-29 13:46:34 +00:00
|
|
|
|
else if( real_uids_left(keyblock) < 1 )
|
1999-09-01 13:40:07 +00:00
|
|
|
|
tty_printf(_("You can't delete the last user ID!\n"));
|
2004-10-10 15:27:14 +00:00
|
|
|
|
else if( cpr_get_answer_is_yes("keyedit.remove.uid.okay",
|
|
|
|
|
n1 > 1? _("Really remove all selected user IDs? (y/N) ")
|
|
|
|
|
: _("Really remove this user ID? (y/N) ")
|
1998-07-29 19:35:05 +00:00
|
|
|
|
) ) {
|
|
|
|
|
menu_deluid( keyblock, sec_keyblock );
|
|
|
|
|
redisplay = 1;
|
|
|
|
|
modified = 1;
|
|
|
|
|
if( sec_keyblock )
|
|
|
|
|
sec_modified = 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
1999-05-27 07:45:46 +00:00
|
|
|
|
case cmdDELSIG: {
|
|
|
|
|
int n1;
|
|
|
|
|
|
|
|
|
|
if( !(n1=count_selected_uids(keyblock)) )
|
1999-09-01 13:40:07 +00:00
|
|
|
|
tty_printf(_("You must select at least one user ID.\n"));
|
1999-05-27 07:45:46 +00:00
|
|
|
|
else if( menu_delsig( keyblock ) ) {
|
|
|
|
|
/* no redisplay here, because it may scroll away some
|
|
|
|
|
* status output of delsig */
|
|
|
|
|
modified = 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
1998-07-29 19:35:05 +00:00
|
|
|
|
case cmdADDKEY:
|
|
|
|
|
if( generate_subkeypair( keyblock, sec_keyblock ) ) {
|
|
|
|
|
redisplay = 1;
|
|
|
|
|
sec_modified = modified = 1;
|
2002-06-29 13:46:34 +00:00
|
|
|
|
merge_keys_and_selfsig( sec_keyblock );
|
|
|
|
|
merge_keys_and_selfsig( keyblock );
|
1998-07-29 19:35:05 +00:00
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
2004-09-20 18:38:39 +00:00
|
|
|
|
#ifdef ENABLE_CARD_SUPPORT
|
|
|
|
|
case cmdADDCARDKEY:
|
|
|
|
|
if (card_generate_subkey (keyblock, sec_keyblock)) {
|
|
|
|
|
redisplay = 1;
|
|
|
|
|
sec_modified = modified = 1;
|
|
|
|
|
merge_keys_and_selfsig( sec_keyblock );
|
|
|
|
|
merge_keys_and_selfsig( keyblock );
|
|
|
|
|
}
|
|
|
|
|
break;
|
2004-09-23 13:32:31 +00:00
|
|
|
|
|
|
|
|
|
case cmdKEYTOCARD:
|
2004-09-24 14:34:45 +00:00
|
|
|
|
{
|
|
|
|
|
KBNODE node=NULL;
|
|
|
|
|
switch ( count_selected_keys (sec_keyblock) )
|
|
|
|
|
{
|
|
|
|
|
case 0:
|
|
|
|
|
if (cpr_get_answer_is_yes("keyedit.keytocard.use_primary",
|
2004-10-10 15:27:14 +00:00
|
|
|
|
_("Really move the primary key? (y/N) ")))
|
2004-09-24 14:34:45 +00:00
|
|
|
|
node = sec_keyblock;
|
|
|
|
|
break;
|
|
|
|
|
case 1:
|
|
|
|
|
for (node = sec_keyblock; node; node = node->next )
|
|
|
|
|
{
|
|
|
|
|
if (node->pkt->pkttype == PKT_SECRET_SUBKEY
|
|
|
|
|
&& node->flag & NODFLG_SELKEY)
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
tty_printf(_("You must select exactly one key.\n"));
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (node)
|
|
|
|
|
{
|
|
|
|
|
PKT_public_key *xxpk = find_pk_from_sknode (keyblock, node);
|
|
|
|
|
if (card_store_subkey (node, xxpk?xxpk->pubkey_usage:0))
|
|
|
|
|
{
|
|
|
|
|
redisplay = 1;
|
|
|
|
|
sec_modified = 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2004-09-23 13:32:31 +00:00
|
|
|
|
break;
|
2005-02-15 11:02:32 +00:00
|
|
|
|
|
|
|
|
|
case cmdBKUPTOCARD:
|
|
|
|
|
{
|
|
|
|
|
/* Ask for a filename, check whether this is really a
|
|
|
|
|
backup key as generated by the card generation, parse
|
|
|
|
|
that key and store it on card. */
|
|
|
|
|
KBNODE node;
|
|
|
|
|
const char *fname;
|
|
|
|
|
PACKET *pkt;
|
|
|
|
|
IOBUF a;
|
|
|
|
|
|
|
|
|
|
fname = arg_string;
|
|
|
|
|
if (!*fname)
|
|
|
|
|
{
|
|
|
|
|
tty_printf (_("Command expects a filename argument\n"));
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Open that file. */
|
|
|
|
|
a = iobuf_open (fname);
|
|
|
|
|
if (a && is_secured_file (iobuf_get_fd (a)))
|
|
|
|
|
{
|
|
|
|
|
iobuf_close (a);
|
|
|
|
|
a = NULL;
|
|
|
|
|
errno = EPERM;
|
|
|
|
|
}
|
|
|
|
|
if (!a)
|
|
|
|
|
{
|
|
|
|
|
tty_printf (_("Can't open `%s': %s\n"),
|
|
|
|
|
fname, strerror(errno));
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Parse and check that file. */
|
|
|
|
|
pkt = xmalloc (sizeof *pkt);
|
|
|
|
|
init_packet (pkt);
|
|
|
|
|
rc = parse_packet (a, pkt);
|
|
|
|
|
iobuf_close (a);
|
|
|
|
|
iobuf_ioctl (NULL, 2, 0, (char*)fname); /* (invalidate cache). */
|
|
|
|
|
if (!rc
|
|
|
|
|
&& pkt->pkttype != PKT_SECRET_KEY
|
|
|
|
|
&& pkt->pkttype != PKT_SECRET_SUBKEY)
|
|
|
|
|
rc = G10ERR_NO_SECKEY;
|
|
|
|
|
if (rc)
|
|
|
|
|
{
|
|
|
|
|
tty_printf(_("Error reading backup key from `%s': %s\n"),
|
|
|
|
|
fname, g10_errstr (rc));
|
|
|
|
|
free_packet (pkt);
|
|
|
|
|
xfree (pkt);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
node = new_kbnode (pkt);
|
|
|
|
|
|
|
|
|
|
/* Store it. */
|
|
|
|
|
if (card_store_subkey (node, 0))
|
|
|
|
|
{
|
|
|
|
|
redisplay = 1;
|
|
|
|
|
sec_modified = 1;
|
|
|
|
|
}
|
|
|
|
|
release_kbnode (node);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
2004-09-20 18:38:39 +00:00
|
|
|
|
#endif /* ENABLE_CARD_SUPPORT */
|
1998-07-29 19:35:05 +00:00
|
|
|
|
|
|
|
|
|
case cmdDELKEY: {
|
|
|
|
|
int n1;
|
|
|
|
|
|
|
|
|
|
if( !(n1=count_selected_keys( keyblock )) )
|
|
|
|
|
tty_printf(_("You must select at least one key.\n"));
|
2004-02-11 04:32:52 +00:00
|
|
|
|
else if( !cpr_get_answer_is_yes( "keyedit.remove.subkey.okay",
|
1998-07-29 19:35:05 +00:00
|
|
|
|
n1 > 1?
|
2004-10-10 15:27:14 +00:00
|
|
|
|
_("Do you really want to delete the selected keys? (y/N) "):
|
|
|
|
|
_("Do you really want to delete this key? (y/N) ")
|
1998-07-29 19:35:05 +00:00
|
|
|
|
))
|
|
|
|
|
;
|
|
|
|
|
else {
|
|
|
|
|
menu_delkey( keyblock, sec_keyblock );
|
|
|
|
|
redisplay = 1;
|
|
|
|
|
modified = 1;
|
|
|
|
|
if( sec_keyblock )
|
|
|
|
|
sec_modified = 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
2002-06-29 13:46:34 +00:00
|
|
|
|
case cmdADDREVOKER:
|
2002-07-19 05:08:54 +00:00
|
|
|
|
{
|
|
|
|
|
int sensitive=0;
|
|
|
|
|
|
2005-04-24 18:35:30 +00:00
|
|
|
|
if(ascii_strcasecmp(arg_string,"sensitive")==0)
|
2002-07-19 05:08:54 +00:00
|
|
|
|
sensitive=1;
|
|
|
|
|
if( menu_addrevoker( keyblock, sec_keyblock, sensitive ) ) {
|
2002-06-29 13:46:34 +00:00
|
|
|
|
redisplay = 1;
|
|
|
|
|
sec_modified = modified = 1;
|
|
|
|
|
merge_keys_and_selfsig( sec_keyblock );
|
|
|
|
|
merge_keys_and_selfsig( keyblock );
|
2002-07-19 05:08:54 +00:00
|
|
|
|
}
|
2002-06-29 13:46:34 +00:00
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
2002-12-27 13:41:17 +00:00
|
|
|
|
case cmdREVUID: {
|
|
|
|
|
int n1;
|
|
|
|
|
|
|
|
|
|
if( !(n1=count_selected_uids(keyblock)) )
|
|
|
|
|
tty_printf(_("You must select at least one user ID.\n"));
|
|
|
|
|
else if( cpr_get_answer_is_yes(
|
|
|
|
|
"keyedit.revoke.uid.okay",
|
2004-10-10 15:27:14 +00:00
|
|
|
|
n1 > 1? _("Really revoke all selected user IDs? (y/N) ")
|
|
|
|
|
: _("Really revoke this user ID? (y/N) ")
|
2002-12-27 13:41:17 +00:00
|
|
|
|
) ) {
|
|
|
|
|
if(menu_revuid(keyblock,sec_keyblock))
|
|
|
|
|
{
|
|
|
|
|
modified=1;
|
|
|
|
|
redisplay=1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
2004-12-19 04:30:16 +00:00
|
|
|
|
case cmdREVKEY:
|
|
|
|
|
{
|
|
|
|
|
int n1;
|
1999-04-28 11:06:52 +00:00
|
|
|
|
|
2004-12-19 04:30:16 +00:00
|
|
|
|
if( !(n1=count_selected_keys( keyblock )) )
|
|
|
|
|
{
|
|
|
|
|
if(cpr_get_answer_is_yes("keyedit.revoke.subkey.okay",
|
|
|
|
|
_("Do you really want to revoke"
|
|
|
|
|
" the entire key? (y/N) ")))
|
|
|
|
|
{
|
|
|
|
|
if(menu_revkey(keyblock,sec_keyblock))
|
|
|
|
|
modified=1;
|
|
|
|
|
|
|
|
|
|
redisplay=1;
|
1999-04-28 11:06:52 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2004-12-19 04:30:16 +00:00
|
|
|
|
else if(cpr_get_answer_is_yes("keyedit.revoke.subkey.okay",
|
|
|
|
|
n1 > 1?
|
|
|
|
|
_("Do you really want to revoke"
|
|
|
|
|
" the selected subkeys? (y/N) "):
|
|
|
|
|
_("Do you really want to revoke"
|
|
|
|
|
" this subkey? (y/N) ")))
|
|
|
|
|
{
|
|
|
|
|
if( menu_revsubkey( keyblock, sec_keyblock ) )
|
|
|
|
|
modified = 1;
|
|
|
|
|
|
|
|
|
|
redisplay = 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(modified)
|
|
|
|
|
merge_keys_and_selfsig( keyblock );
|
1999-04-28 11:06:52 +00:00
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
1998-10-18 15:21:22 +00:00
|
|
|
|
case cmdEXPIRE:
|
2004-12-19 05:20:07 +00:00
|
|
|
|
if( menu_expire( keyblock, sec_keyblock ) )
|
|
|
|
|
{
|
1998-10-18 15:21:22 +00:00
|
|
|
|
merge_keys_and_selfsig( sec_keyblock );
|
|
|
|
|
merge_keys_and_selfsig( keyblock );
|
|
|
|
|
sec_modified = 1;
|
|
|
|
|
modified = 1;
|
|
|
|
|
redisplay = 1;
|
2004-12-19 05:20:07 +00:00
|
|
|
|
}
|
1998-10-18 15:21:22 +00:00
|
|
|
|
break;
|
|
|
|
|
|
2005-10-14 04:07:13 +00:00
|
|
|
|
case cmdBACKSIGN:
|
|
|
|
|
if(menu_backsign(keyblock,sec_keyblock))
|
|
|
|
|
{
|
|
|
|
|
sec_modified = 1;
|
|
|
|
|
modified = 1;
|
|
|
|
|
redisplay = 1;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
2002-06-29 13:46:34 +00:00
|
|
|
|
case cmdPRIMARY:
|
|
|
|
|
if( menu_set_primary_uid ( keyblock, sec_keyblock ) ) {
|
|
|
|
|
merge_keys_and_selfsig( keyblock );
|
|
|
|
|
modified = 1;
|
|
|
|
|
redisplay = 1;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
1998-07-29 19:35:05 +00:00
|
|
|
|
case cmdPASSWD:
|
|
|
|
|
if( change_passphrase( sec_keyblock ) )
|
|
|
|
|
sec_modified = 1;
|
|
|
|
|
break;
|
|
|
|
|
|
1998-07-30 17:37:03 +00:00
|
|
|
|
case cmdTRUST:
|
2003-11-15 00:19:49 +00:00
|
|
|
|
if(opt.trust_model==TM_EXTERNAL)
|
|
|
|
|
{
|
|
|
|
|
tty_printf(_("Owner trust may not be set while "
|
|
|
|
|
"using an user provided trust database\n"));
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2002-06-29 13:46:34 +00:00
|
|
|
|
show_key_with_all_names( keyblock, 0, 0, 0, 1, 0 );
|
1998-07-30 17:37:03 +00:00
|
|
|
|
tty_printf("\n");
|
|
|
|
|
if( edit_ownertrust( find_kbnode( keyblock,
|
2002-06-29 13:46:34 +00:00
|
|
|
|
PKT_PUBLIC_KEY )->pkt->pkt.public_key, 1 ) ) {
|
1998-07-30 17:37:03 +00:00
|
|
|
|
redisplay = 1;
|
2002-06-29 13:46:34 +00:00
|
|
|
|
/* No real need to set update_trust here as
|
|
|
|
|
edit_ownertrust() calls revalidation_mark()
|
|
|
|
|
anyway. */
|
|
|
|
|
update_trust=1;
|
|
|
|
|
}
|
1998-07-30 17:37:03 +00:00
|
|
|
|
break;
|
|
|
|
|
|
1998-08-05 16:51:59 +00:00
|
|
|
|
case cmdPREF:
|
2005-09-10 16:50:41 +00:00
|
|
|
|
{
|
|
|
|
|
int count=count_selected_uids(keyblock);
|
|
|
|
|
assert(keyblock->pkt->pkttype==PKT_PUBLIC_KEY);
|
|
|
|
|
show_names(keyblock,keyblock->pkt->pkt.public_key,
|
|
|
|
|
count?NODFLG_SELUID:0,1);
|
|
|
|
|
}
|
2002-06-29 13:46:34 +00:00
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case cmdSHOWPREF:
|
2005-09-10 16:50:41 +00:00
|
|
|
|
{
|
|
|
|
|
int count=count_selected_uids(keyblock);
|
|
|
|
|
assert(keyblock->pkt->pkttype==PKT_PUBLIC_KEY);
|
|
|
|
|
show_names(keyblock,keyblock->pkt->pkt.public_key,
|
|
|
|
|
count?NODFLG_SELUID:0,2);
|
|
|
|
|
}
|
2002-06-29 13:46:34 +00:00
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case cmdSETPREF:
|
2004-12-19 05:20:07 +00:00
|
|
|
|
{
|
|
|
|
|
PKT_user_id *tempuid;
|
2002-06-29 13:46:34 +00:00
|
|
|
|
|
2004-12-19 05:20:07 +00:00
|
|
|
|
keygen_set_std_prefs(!*arg_string?"default" : arg_string, 0);
|
|
|
|
|
|
|
|
|
|
tempuid=keygen_get_std_prefs();
|
2004-02-12 18:32:09 +00:00
|
|
|
|
tty_printf(_("Set preference list to:\n"));
|
2004-12-19 05:20:07 +00:00
|
|
|
|
show_prefs(tempuid,NULL,1);
|
|
|
|
|
free_user_id(tempuid);
|
2004-10-10 15:27:14 +00:00
|
|
|
|
|
2004-12-19 05:20:07 +00:00
|
|
|
|
if(cpr_get_answer_is_yes("keyedit.setpref.okay",
|
|
|
|
|
count_selected_uids (keyblock)?
|
|
|
|
|
_("Really update the preferences"
|
|
|
|
|
" for the selected user IDs? (y/N) "):
|
|
|
|
|
_("Really update the preferences? (y/N) ")))
|
|
|
|
|
{
|
|
|
|
|
if ( menu_set_preferences (keyblock, sec_keyblock) )
|
|
|
|
|
{
|
|
|
|
|
merge_keys_and_selfsig (keyblock);
|
|
|
|
|
modified = 1;
|
|
|
|
|
redisplay = 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
1998-08-05 16:51:59 +00:00
|
|
|
|
break;
|
|
|
|
|
|
2003-08-31 03:45:41 +00:00
|
|
|
|
case cmdPREFKS:
|
2004-05-08 13:51:14 +00:00
|
|
|
|
if( menu_set_keyserver_url ( *arg_string?arg_string:NULL,
|
|
|
|
|
keyblock, sec_keyblock ) )
|
|
|
|
|
{
|
2003-08-31 03:45:41 +00:00
|
|
|
|
merge_keys_and_selfsig( keyblock );
|
|
|
|
|
modified = 1;
|
|
|
|
|
redisplay = 1;
|
2004-05-08 13:51:14 +00:00
|
|
|
|
}
|
2003-08-31 03:45:41 +00:00
|
|
|
|
break;
|
|
|
|
|
|
1998-07-29 19:35:05 +00:00
|
|
|
|
case cmdNOP:
|
|
|
|
|
break;
|
|
|
|
|
|
1999-04-26 15:53:01 +00:00
|
|
|
|
case cmdREVSIG:
|
|
|
|
|
if( menu_revsig( keyblock ) ) {
|
|
|
|
|
redisplay = 1;
|
|
|
|
|
modified = 1;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
1999-06-29 19:50:54 +00:00
|
|
|
|
case cmdENABLEKEY:
|
|
|
|
|
case cmdDISABLEKEY:
|
|
|
|
|
if( enable_disable_key( keyblock, cmd == cmdDISABLEKEY ) ) {
|
|
|
|
|
redisplay = 1;
|
|
|
|
|
modified = 1;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
2005-04-24 18:35:30 +00:00
|
|
|
|
case cmdSHOWPHOTO:
|
|
|
|
|
menu_showphoto(keyblock);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case cmdCLEAN:
|
2005-11-18 04:25:07 +00:00
|
|
|
|
redisplay=modified=menu_clean(keyblock,0);
|
2005-04-24 18:35:30 +00:00
|
|
|
|
break;
|
2002-06-29 13:46:34 +00:00
|
|
|
|
|
2005-11-10 23:25:20 +00:00
|
|
|
|
case cmdMINIMIZE:
|
2005-11-18 04:25:07 +00:00
|
|
|
|
redisplay=modified=menu_clean(keyblock,1);
|
2005-11-10 23:25:20 +00:00
|
|
|
|
break;
|
|
|
|
|
|
1999-07-12 16:49:22 +00:00
|
|
|
|
case cmdQUIT:
|
|
|
|
|
if( have_commands )
|
|
|
|
|
goto leave;
|
|
|
|
|
if( !modified && !sec_modified )
|
|
|
|
|
goto leave;
|
|
|
|
|
if( !cpr_get_answer_is_yes("keyedit.save.okay",
|
2004-10-10 15:27:14 +00:00
|
|
|
|
_("Save changes? (y/N) ")) ) {
|
1999-07-12 16:49:22 +00:00
|
|
|
|
if( cpr_enabled()
|
|
|
|
|
|| cpr_get_answer_is_yes("keyedit.cancel.okay",
|
2004-10-10 15:27:14 +00:00
|
|
|
|
_("Quit without saving? (y/N) ")))
|
1999-07-12 16:49:22 +00:00
|
|
|
|
goto leave;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
/* fall thru */
|
|
|
|
|
case cmdSAVE:
|
|
|
|
|
if( modified || sec_modified ) {
|
|
|
|
|
if( modified ) {
|
2002-06-29 13:46:34 +00:00
|
|
|
|
rc = keydb_update_keyblock (kdbhd, keyblock);
|
1999-07-12 16:49:22 +00:00
|
|
|
|
if( rc ) {
|
2002-06-29 13:46:34 +00:00
|
|
|
|
log_error(_("update failed: %s\n"), g10_errstr(rc) );
|
1999-07-12 16:49:22 +00:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if( sec_modified ) {
|
2002-06-29 13:46:34 +00:00
|
|
|
|
rc = keydb_update_keyblock (sec_kdbhd, sec_keyblock );
|
1999-07-12 16:49:22 +00:00
|
|
|
|
if( rc ) {
|
2002-06-29 13:46:34 +00:00
|
|
|
|
log_error( _("update secret failed: %s\n"),
|
|
|
|
|
g10_errstr(rc) );
|
1999-07-12 16:49:22 +00:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
tty_printf(_("Key not changed so no update needed.\n"));
|
2002-06-29 13:46:34 +00:00
|
|
|
|
|
|
|
|
|
if( update_trust )
|
|
|
|
|
{
|
|
|
|
|
revalidation_mark ();
|
|
|
|
|
update_trust=0;
|
|
|
|
|
}
|
1999-07-12 16:49:22 +00:00
|
|
|
|
goto leave;
|
|
|
|
|
|
|
|
|
|
case cmdINVCMD:
|
1998-07-29 19:35:05 +00:00
|
|
|
|
default:
|
|
|
|
|
tty_printf("\n");
|
|
|
|
|
tty_printf(_("Invalid command (try \"help\")\n"));
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
} /* end main loop */
|
|
|
|
|
|
1998-04-20 15:52:20 +00:00
|
|
|
|
leave:
|
|
|
|
|
release_kbnode( keyblock );
|
1998-07-29 19:35:05 +00:00
|
|
|
|
release_kbnode( sec_keyblock );
|
2002-06-29 13:46:34 +00:00
|
|
|
|
keydb_release (kdbhd);
|
2005-07-27 18:10:56 +00:00
|
|
|
|
xfree(answer);
|
1998-04-20 15:52:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2005-03-21 15:24:48 +00:00
|
|
|
|
|
1998-08-05 16:51:59 +00:00
|
|
|
|
/****************
|
|
|
|
|
* show preferences of a public keyblock.
|
|
|
|
|
*/
|
|
|
|
|
static void
|
2004-09-16 20:55:09 +00:00
|
|
|
|
show_prefs (PKT_user_id *uid, PKT_signature *selfsig, int verbose)
|
1998-08-05 16:51:59 +00:00
|
|
|
|
{
|
2002-06-29 13:46:34 +00:00
|
|
|
|
const prefitem_t fake={0,0};
|
|
|
|
|
const prefitem_t *prefs;
|
1998-08-05 16:51:59 +00:00
|
|
|
|
int i;
|
|
|
|
|
|
2002-06-29 13:46:34 +00:00
|
|
|
|
if( !uid )
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if( uid->prefs )
|
|
|
|
|
prefs=uid->prefs;
|
|
|
|
|
else if(verbose)
|
|
|
|
|
prefs=&fake;
|
|
|
|
|
else
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (verbose) {
|
|
|
|
|
int any, des_seen=0, sha1_seen=0, uncomp_seen=0;
|
2004-09-16 20:55:09 +00:00
|
|
|
|
|
2003-03-04 15:24:12 +00:00
|
|
|
|
tty_printf (" ");
|
|
|
|
|
tty_printf (_("Cipher: "));
|
2002-06-29 13:46:34 +00:00
|
|
|
|
for(i=any=0; prefs[i].type; i++ ) {
|
|
|
|
|
if( prefs[i].type == PREFTYPE_SYM ) {
|
|
|
|
|
const char *s = cipher_algo_to_string (prefs[i].value);
|
|
|
|
|
|
|
|
|
|
if (any)
|
|
|
|
|
tty_printf (", ");
|
|
|
|
|
any = 1;
|
|
|
|
|
/* We don't want to display strings for experimental algos */
|
|
|
|
|
if (s && prefs[i].value < 100 )
|
|
|
|
|
tty_printf ("%s", s );
|
|
|
|
|
else
|
|
|
|
|
tty_printf ("[%d]", prefs[i].value);
|
|
|
|
|
if (prefs[i].value == CIPHER_ALGO_3DES )
|
|
|
|
|
des_seen = 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (!des_seen) {
|
|
|
|
|
if (any)
|
|
|
|
|
tty_printf (", ");
|
|
|
|
|
tty_printf ("%s",cipher_algo_to_string(CIPHER_ALGO_3DES));
|
|
|
|
|
}
|
2003-03-04 15:24:12 +00:00
|
|
|
|
tty_printf ("\n ");
|
|
|
|
|
tty_printf (_("Digest: "));
|
2002-06-29 13:46:34 +00:00
|
|
|
|
for(i=any=0; prefs[i].type; i++ ) {
|
|
|
|
|
if( prefs[i].type == PREFTYPE_HASH ) {
|
|
|
|
|
const char *s = digest_algo_to_string (prefs[i].value);
|
|
|
|
|
|
|
|
|
|
if (any)
|
|
|
|
|
tty_printf (", ");
|
|
|
|
|
any = 1;
|
|
|
|
|
/* We don't want to display strings for experimental algos */
|
|
|
|
|
if (s && prefs[i].value < 100 )
|
|
|
|
|
tty_printf ("%s", s );
|
|
|
|
|
else
|
|
|
|
|
tty_printf ("[%d]", prefs[i].value);
|
|
|
|
|
if (prefs[i].value == DIGEST_ALGO_SHA1 )
|
|
|
|
|
sha1_seen = 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (!sha1_seen) {
|
|
|
|
|
if (any)
|
|
|
|
|
tty_printf (", ");
|
|
|
|
|
tty_printf ("%s",digest_algo_to_string(DIGEST_ALGO_SHA1));
|
|
|
|
|
}
|
2003-03-04 15:24:12 +00:00
|
|
|
|
tty_printf ("\n ");
|
|
|
|
|
tty_printf (_("Compression: "));
|
2002-06-29 13:46:34 +00:00
|
|
|
|
for(i=any=0; prefs[i].type; i++ ) {
|
|
|
|
|
if( prefs[i].type == PREFTYPE_ZIP ) {
|
|
|
|
|
const char *s=compress_algo_to_string(prefs[i].value);
|
|
|
|
|
|
|
|
|
|
if (any)
|
|
|
|
|
tty_printf (", ");
|
|
|
|
|
any = 1;
|
|
|
|
|
/* We don't want to display strings for experimental algos */
|
|
|
|
|
if (s && prefs[i].value < 100 )
|
|
|
|
|
tty_printf ("%s", s );
|
|
|
|
|
else
|
|
|
|
|
tty_printf ("[%d]", prefs[i].value);
|
2004-02-10 22:42:34 +00:00
|
|
|
|
if (prefs[i].value == COMPRESS_ALGO_NONE )
|
2002-06-29 13:46:34 +00:00
|
|
|
|
uncomp_seen = 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (!uncomp_seen) {
|
|
|
|
|
if (any)
|
|
|
|
|
tty_printf (", ");
|
|
|
|
|
else {
|
2004-02-10 22:42:34 +00:00
|
|
|
|
tty_printf ("%s",compress_algo_to_string(COMPRESS_ALGO_ZIP));
|
2002-06-29 13:46:34 +00:00
|
|
|
|
tty_printf (", ");
|
|
|
|
|
}
|
2004-02-10 22:42:34 +00:00
|
|
|
|
tty_printf ("%s",compress_algo_to_string(COMPRESS_ALGO_NONE));
|
2002-06-29 13:46:34 +00:00
|
|
|
|
}
|
2005-11-10 22:50:46 +00:00
|
|
|
|
if(uid->flags.mdc || !uid->flags.ks_modify)
|
2003-02-22 23:58:39 +00:00
|
|
|
|
{
|
2003-03-04 15:24:12 +00:00
|
|
|
|
tty_printf ("\n ");
|
|
|
|
|
tty_printf (_("Features: "));
|
2003-02-22 23:58:39 +00:00
|
|
|
|
any=0;
|
2005-11-10 22:50:46 +00:00
|
|
|
|
if(uid->flags.mdc)
|
2003-02-22 23:58:39 +00:00
|
|
|
|
{
|
|
|
|
|
tty_printf ("MDC");
|
|
|
|
|
any=1;
|
|
|
|
|
}
|
2005-11-10 22:50:46 +00:00
|
|
|
|
if(!uid->flags.ks_modify)
|
2003-02-22 23:58:39 +00:00
|
|
|
|
{
|
|
|
|
|
if(any)
|
|
|
|
|
tty_printf (", ");
|
2003-03-04 15:24:12 +00:00
|
|
|
|
tty_printf (_("Keyserver no-modify"));
|
2003-02-22 23:58:39 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2002-06-29 13:46:34 +00:00
|
|
|
|
tty_printf("\n");
|
2004-09-16 20:55:09 +00:00
|
|
|
|
|
2004-10-04 01:17:27 +00:00
|
|
|
|
if(selfsig)
|
2004-09-16 20:55:09 +00:00
|
|
|
|
{
|
2004-10-04 01:17:27 +00:00
|
|
|
|
const byte *pref_ks;
|
|
|
|
|
size_t pref_ks_len;
|
|
|
|
|
|
|
|
|
|
pref_ks=parse_sig_subpkt(selfsig->hashed,
|
|
|
|
|
SIGSUBPKT_PREF_KS,&pref_ks_len);
|
|
|
|
|
if(pref_ks && pref_ks_len)
|
|
|
|
|
{
|
|
|
|
|
tty_printf (" ");
|
|
|
|
|
tty_printf(_("Preferred keyserver: "));
|
|
|
|
|
tty_print_utf8_string(pref_ks,pref_ks_len);
|
|
|
|
|
tty_printf("\n");
|
|
|
|
|
}
|
2004-09-16 20:55:09 +00:00
|
|
|
|
}
|
2000-07-14 17:34:53 +00:00
|
|
|
|
}
|
|
|
|
|
else {
|
2002-06-29 13:46:34 +00:00
|
|
|
|
tty_printf(" ");
|
|
|
|
|
for(i=0; prefs[i].type; i++ ) {
|
|
|
|
|
tty_printf( " %c%d", prefs[i].type == PREFTYPE_SYM ? 'S' :
|
|
|
|
|
prefs[i].type == PREFTYPE_HASH ? 'H' :
|
|
|
|
|
prefs[i].type == PREFTYPE_ZIP ? 'Z':'?',
|
|
|
|
|
prefs[i].value);
|
|
|
|
|
}
|
2005-11-10 22:50:46 +00:00
|
|
|
|
if (uid->flags.mdc)
|
2002-06-29 13:46:34 +00:00
|
|
|
|
tty_printf (" [mdc]");
|
2005-11-10 22:50:46 +00:00
|
|
|
|
if (!uid->flags.ks_modify)
|
2003-02-22 23:58:39 +00:00
|
|
|
|
tty_printf (" [no-ks-modify]");
|
2002-06-29 13:46:34 +00:00
|
|
|
|
tty_printf("\n");
|
2000-07-14 17:34:53 +00:00
|
|
|
|
}
|
2002-06-29 13:46:34 +00:00
|
|
|
|
}
|
1998-08-05 16:51:59 +00:00
|
|
|
|
|
2002-06-29 13:46:34 +00:00
|
|
|
|
/* 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 */
|
|
|
|
|
static void
|
|
|
|
|
show_key_with_all_names_colon (KBNODE keyblock)
|
|
|
|
|
{
|
|
|
|
|
KBNODE node;
|
2002-11-13 13:23:03 +00:00
|
|
|
|
int i, j, ulti_hack=0;
|
2002-06-29 13:46:34 +00:00
|
|
|
|
byte pk_version=0;
|
2002-11-13 13:23:03 +00:00
|
|
|
|
PKT_public_key *primary=NULL;
|
2002-06-29 13:46:34 +00:00
|
|
|
|
|
|
|
|
|
/* the keys */
|
|
|
|
|
for ( node = keyblock; node; node = node->next )
|
|
|
|
|
{
|
|
|
|
|
if (node->pkt->pkttype == PKT_PUBLIC_KEY
|
|
|
|
|
|| (node->pkt->pkttype == PKT_PUBLIC_SUBKEY) )
|
|
|
|
|
{
|
|
|
|
|
PKT_public_key *pk = node->pkt->pkt.public_key;
|
|
|
|
|
u32 keyid[2];
|
|
|
|
|
|
|
|
|
|
if (node->pkt->pkttype == PKT_PUBLIC_KEY)
|
|
|
|
|
{
|
|
|
|
|
pk_version = pk->version;
|
2002-11-13 13:23:03 +00:00
|
|
|
|
primary=pk;
|
2002-06-29 13:46:34 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
keyid_from_pk (pk, keyid);
|
|
|
|
|
|
|
|
|
|
fputs (node->pkt->pkttype == PKT_PUBLIC_KEY?"pub:":"sub:", stdout);
|
|
|
|
|
if (!pk->is_valid)
|
|
|
|
|
putchar ('i');
|
|
|
|
|
else if (pk->is_revoked)
|
|
|
|
|
putchar ('r');
|
|
|
|
|
else if (pk->has_expired)
|
|
|
|
|
putchar ('e');
|
2002-11-13 13:23:03 +00:00
|
|
|
|
else if (!(opt.fast_list_mode || opt.no_expensive_trust_checks ))
|
|
|
|
|
{
|
|
|
|
|
int trust = get_validity_info (pk, NULL);
|
|
|
|
|
if(trust=='u')
|
|
|
|
|
ulti_hack=1;
|
|
|
|
|
putchar (trust);
|
|
|
|
|
}
|
|
|
|
|
|
2004-01-30 16:49:28 +00:00
|
|
|
|
printf (":%u:%d:%08lX%08lX:%lu:%lu::",
|
2002-06-29 13:46:34 +00:00
|
|
|
|
nbits_from_pk (pk),
|
|
|
|
|
pk->pubkey_algo,
|
|
|
|
|
(ulong)keyid[0], (ulong)keyid[1],
|
|
|
|
|
(ulong)pk->timestamp,
|
|
|
|
|
(ulong)pk->expiredate );
|
2002-11-13 13:23:03 +00:00
|
|
|
|
if (node->pkt->pkttype==PKT_PUBLIC_KEY
|
|
|
|
|
&& !(opt.fast_list_mode || opt.no_expensive_trust_checks ))
|
|
|
|
|
putchar(get_ownertrust_info (pk));
|
2002-06-29 13:46:34 +00:00
|
|
|
|
putchar(':');
|
|
|
|
|
putchar('\n');
|
|
|
|
|
|
|
|
|
|
print_fingerprint (pk, NULL, 0);
|
|
|
|
|
|
|
|
|
|
/* print the revoker record */
|
|
|
|
|
if( !pk->revkey && pk->numrevkeys )
|
|
|
|
|
BUG();
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
for (i=0; i < pk->numrevkeys; i++)
|
|
|
|
|
{
|
|
|
|
|
byte *p;
|
|
|
|
|
|
|
|
|
|
printf ("rvk:::%d::::::", pk->revkey[i].algid);
|
|
|
|
|
p = pk->revkey[i].fpr;
|
|
|
|
|
for (j=0; j < 20; j++, p++ )
|
|
|
|
|
printf ("%02X", *p);
|
2002-07-17 19:48:19 +00:00
|
|
|
|
printf (":%02x%s:\n", pk->revkey[i].class,
|
|
|
|
|
(pk->revkey[i].class&0x40)?"s":"");
|
2002-06-29 13:46:34 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
1998-08-05 16:51:59 +00:00
|
|
|
|
}
|
2002-06-29 13:46:34 +00:00
|
|
|
|
|
|
|
|
|
/* the user ids */
|
|
|
|
|
i = 0;
|
|
|
|
|
for (node = keyblock; node; node = node->next)
|
|
|
|
|
{
|
|
|
|
|
if ( node->pkt->pkttype == PKT_USER_ID )
|
|
|
|
|
{
|
|
|
|
|
PKT_user_id *uid = node->pkt->pkt.user_id;
|
1998-08-05 16:51:59 +00:00
|
|
|
|
|
2002-06-29 13:46:34 +00:00
|
|
|
|
++i;
|
2002-11-13 13:23:03 +00:00
|
|
|
|
|
2002-06-29 13:46:34 +00:00
|
|
|
|
if(uid->attrib_data)
|
2002-11-13 13:23:03 +00:00
|
|
|
|
printf("uat:");
|
|
|
|
|
else
|
|
|
|
|
printf("uid:");
|
|
|
|
|
|
|
|
|
|
if ( uid->is_revoked )
|
|
|
|
|
printf("r::::::::");
|
|
|
|
|
else if ( uid->is_expired )
|
|
|
|
|
printf("e::::::::");
|
|
|
|
|
else if ( opt.fast_list_mode || opt.no_expensive_trust_checks )
|
|
|
|
|
printf("::::::::");
|
2002-06-29 13:46:34 +00:00
|
|
|
|
else
|
|
|
|
|
{
|
2002-11-13 13:23:03 +00:00
|
|
|
|
int uid_validity;
|
|
|
|
|
|
|
|
|
|
if( primary && !ulti_hack )
|
* armor.c (armor_filter): Comment about PGP's end of line tab problem.
* trustdb.h, trustdb.c (trust_letter): Make static. (get_ownertrust_info,
get_validity_info): Don't mask the trust level twice.
* trustdb.h, gpgv.c, trustdb.c (get_validity, get_validity_info),
keylist.c (list_keyblock_colon), keyedit.c (show_key_with_all_names_colon,
menu_revuid): Pass a user ID in rather than a namehash, so we only have to
do the hashing in one place.
* packet.h, pkclist.c (build_pk_list), free-packet.c
(release_public_key_parts): Remove unused namehash element for public
keys.
2003-01-11 03:57:00 +00:00
|
|
|
|
uid_validity = get_validity_info( primary, uid );
|
2002-11-13 13:23:03 +00:00
|
|
|
|
else
|
|
|
|
|
uid_validity = 'u';
|
|
|
|
|
printf("%c::::::::",uid_validity);
|
2002-06-29 13:46:34 +00:00
|
|
|
|
}
|
2002-11-13 13:23:03 +00:00
|
|
|
|
|
|
|
|
|
if(uid->attrib_data)
|
|
|
|
|
printf ("%u %lu",uid->numattribs,uid->attrib_len);
|
|
|
|
|
else
|
|
|
|
|
print_string (stdout, uid->name, uid->len, ':');
|
|
|
|
|
|
2002-06-29 13:46:34 +00:00
|
|
|
|
putchar (':');
|
|
|
|
|
/* signature class */
|
|
|
|
|
putchar (':');
|
|
|
|
|
/* capabilities */
|
|
|
|
|
putchar (':');
|
|
|
|
|
/* preferences */
|
|
|
|
|
if (pk_version>3 || uid->selfsigversion>3)
|
|
|
|
|
{
|
|
|
|
|
const prefitem_t *prefs = uid->prefs;
|
|
|
|
|
|
|
|
|
|
for (j=0; prefs && prefs[j].type; j++)
|
|
|
|
|
{
|
|
|
|
|
if (j)
|
|
|
|
|
putchar (' ');
|
|
|
|
|
printf ("%c%d", prefs[j].type == PREFTYPE_SYM ? 'S' :
|
|
|
|
|
prefs[j].type == PREFTYPE_HASH ? 'H' :
|
|
|
|
|
prefs[j].type == PREFTYPE_ZIP ? 'Z':'?',
|
|
|
|
|
prefs[j].value);
|
|
|
|
|
}
|
2005-11-10 22:50:46 +00:00
|
|
|
|
if (uid->flags.mdc)
|
2002-06-29 13:46:34 +00:00
|
|
|
|
printf (",mdc");
|
2005-11-10 22:50:46 +00:00
|
|
|
|
if (!uid->flags.ks_modify)
|
2003-03-24 20:05:53 +00:00
|
|
|
|
printf (",no-ks-modify");
|
2002-06-29 13:46:34 +00:00
|
|
|
|
}
|
|
|
|
|
putchar (':');
|
|
|
|
|
/* flags */
|
|
|
|
|
printf ("%d,", i);
|
|
|
|
|
if (uid->is_primary)
|
|
|
|
|
putchar ('p');
|
|
|
|
|
if (uid->is_revoked)
|
|
|
|
|
putchar ('r');
|
|
|
|
|
if (uid->is_expired)
|
|
|
|
|
putchar ('e');
|
|
|
|
|
if ((node->flag & NODFLG_SELUID))
|
|
|
|
|
putchar ('s');
|
|
|
|
|
if ((node->flag & NODFLG_MARK_A))
|
|
|
|
|
putchar ('m');
|
|
|
|
|
putchar (':');
|
|
|
|
|
putchar('\n');
|
|
|
|
|
}
|
|
|
|
|
}
|
1998-08-05 16:51:59 +00:00
|
|
|
|
}
|
|
|
|
|
|
2005-09-10 16:50:41 +00:00
|
|
|
|
static void
|
|
|
|
|
show_names(KBNODE keyblock,PKT_public_key *pk,unsigned int flag,int with_prefs)
|
|
|
|
|
{
|
|
|
|
|
KBNODE node;
|
|
|
|
|
int i=0;
|
|
|
|
|
|
|
|
|
|
for( node = keyblock; node; node = node->next )
|
|
|
|
|
{
|
|
|
|
|
if( node->pkt->pkttype == PKT_USER_ID
|
|
|
|
|
&& !is_deleted_kbnode(node))
|
|
|
|
|
{
|
|
|
|
|
PKT_user_id *uid = node->pkt->pkt.user_id;
|
|
|
|
|
++i;
|
|
|
|
|
if(!flag || (flag && (node->flag & flag)))
|
|
|
|
|
{
|
|
|
|
|
if(!(flag&NODFLG_MARK_A) && pk)
|
|
|
|
|
tty_printf("%s ",uid_trust_string_fixed(pk,uid));
|
|
|
|
|
|
|
|
|
|
if( flag & NODFLG_MARK_A )
|
|
|
|
|
tty_printf(" ");
|
|
|
|
|
else if( node->flag & NODFLG_SELUID )
|
|
|
|
|
tty_printf("(%d)* ", i);
|
|
|
|
|
else if( uid->is_primary )
|
|
|
|
|
tty_printf("(%d). ", i);
|
|
|
|
|
else
|
|
|
|
|
tty_printf("(%d) ", i);
|
|
|
|
|
tty_print_utf8_string( uid->name, uid->len );
|
|
|
|
|
tty_printf("\n");
|
|
|
|
|
if(with_prefs && pk)
|
|
|
|
|
{
|
|
|
|
|
if(pk->version>3 || uid->selfsigversion>3)
|
|
|
|
|
{
|
|
|
|
|
PKT_signature *selfsig=NULL;
|
|
|
|
|
KBNODE signode;
|
|
|
|
|
|
|
|
|
|
for(signode=node->next;
|
|
|
|
|
signode && signode->pkt->pkttype==PKT_SIGNATURE;
|
|
|
|
|
signode=signode->next)
|
|
|
|
|
{
|
|
|
|
|
if(signode->pkt->pkt.signature->
|
|
|
|
|
flags.chosen_selfsig)
|
|
|
|
|
{
|
|
|
|
|
selfsig=signode->pkt->pkt.signature;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
show_prefs (uid, selfsig, with_prefs == 2);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
tty_printf(_("There are no preferences on a"
|
|
|
|
|
" PGP 2.x-style user ID.\n"));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
1998-07-29 19:35:05 +00:00
|
|
|
|
|
1998-04-20 15:52:20 +00:00
|
|
|
|
/****************
|
1998-07-29 19:35:05 +00:00
|
|
|
|
* Display the key a the user ids, if only_marked is true, do only
|
|
|
|
|
* so for user ids with mark A flag set and dont display the index number
|
1998-04-20 15:52:20 +00:00
|
|
|
|
*/
|
1998-07-29 19:35:05 +00:00
|
|
|
|
static void
|
2002-06-29 13:46:34 +00:00
|
|
|
|
show_key_with_all_names( KBNODE keyblock, int only_marked, int with_revoker,
|
1998-08-05 16:51:59 +00:00
|
|
|
|
int with_fpr, int with_subkeys, int with_prefs )
|
1998-04-20 15:52:20 +00:00
|
|
|
|
{
|
1998-07-29 19:35:05 +00:00
|
|
|
|
KBNODE node;
|
2004-09-29 03:21:05 +00:00
|
|
|
|
int i;
|
2004-10-05 14:33:02 +00:00
|
|
|
|
int do_warn = 0;
|
2002-06-29 13:46:34 +00:00
|
|
|
|
byte pk_version=0;
|
2003-07-20 17:09:43 +00:00
|
|
|
|
PKT_public_key *primary=NULL;
|
2002-06-29 13:46:34 +00:00
|
|
|
|
|
|
|
|
|
if (opt.with_colons)
|
|
|
|
|
{
|
|
|
|
|
show_key_with_all_names_colon (keyblock);
|
|
|
|
|
return;
|
|
|
|
|
}
|
1998-07-29 19:35:05 +00:00
|
|
|
|
|
|
|
|
|
/* the keys */
|
|
|
|
|
for( node = keyblock; node; node = node->next ) {
|
|
|
|
|
if( node->pkt->pkttype == PKT_PUBLIC_KEY
|
2005-05-31 03:59:24 +00:00
|
|
|
|
|| (with_subkeys && node->pkt->pkttype == PKT_PUBLIC_SUBKEY
|
|
|
|
|
&& !is_deleted_kbnode(node)) ) {
|
1998-07-29 19:35:05 +00:00
|
|
|
|
PKT_public_key *pk = node->pkt->pkt.public_key;
|
2003-01-11 21:13:41 +00:00
|
|
|
|
const char *otrust="err",*trust="err";
|
1998-08-05 16:51:59 +00:00
|
|
|
|
|
|
|
|
|
if( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
|
|
|
|
|
/* do it here, so that debug messages don't clutter the
|
|
|
|
|
* output */
|
2002-06-29 13:46:34 +00:00
|
|
|
|
static int did_warn = 0;
|
|
|
|
|
|
2003-01-11 21:13:41 +00:00
|
|
|
|
trust = get_validity_string (pk, NULL);
|
|
|
|
|
otrust = get_ownertrust_string (pk);
|
2002-06-29 13:46:34 +00:00
|
|
|
|
|
|
|
|
|
/* Show a warning once */
|
|
|
|
|
if (!did_warn
|
|
|
|
|
&& (get_validity (pk, NULL) & TRUST_FLAG_PENDING_CHECK)) {
|
|
|
|
|
did_warn = 1;
|
|
|
|
|
do_warn = 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pk_version=pk->version;
|
2003-07-20 17:09:43 +00:00
|
|
|
|
primary=pk;
|
1998-08-05 16:51:59 +00:00
|
|
|
|
}
|
|
|
|
|
|
2004-12-30 03:26:57 +00:00
|
|
|
|
if(pk->is_revoked)
|
|
|
|
|
{
|
|
|
|
|
char *user=get_user_id_string_native(pk->revoked.keyid);
|
|
|
|
|
const char *algo=pubkey_algo_to_string(pk->revoked.algo);
|
|
|
|
|
tty_printf(_("This key was revoked on %s by %s key %s\n"),
|
|
|
|
|
revokestr_from_pk(pk),algo?algo:"?",user);
|
2005-07-27 18:10:56 +00:00
|
|
|
|
xfree(user);
|
2004-12-30 03:26:57 +00:00
|
|
|
|
}
|
|
|
|
|
|
2004-10-28 22:09:09 +00:00
|
|
|
|
if(with_revoker)
|
|
|
|
|
{
|
2002-06-29 13:46:34 +00:00
|
|
|
|
if( !pk->revkey && pk->numrevkeys )
|
2004-10-28 22:09:09 +00:00
|
|
|
|
BUG();
|
2002-06-29 13:46:34 +00:00
|
|
|
|
else
|
2004-10-28 22:09:09 +00:00
|
|
|
|
for(i=0;i<pk->numrevkeys;i++)
|
|
|
|
|
{
|
|
|
|
|
u32 r_keyid[2];
|
|
|
|
|
char *user;
|
|
|
|
|
const char *algo=
|
|
|
|
|
pubkey_algo_to_string(pk->revkey[i].algid);
|
|
|
|
|
|
|
|
|
|
keyid_from_fingerprint(pk->revkey[i].fpr,
|
|
|
|
|
MAX_FINGERPRINT_LEN,r_keyid);
|
|
|
|
|
|
|
|
|
|
user=get_user_id_string_native(r_keyid);
|
|
|
|
|
tty_printf(_("This key may be revoked by %s key %s"),
|
|
|
|
|
algo?algo:"?",user);
|
|
|
|
|
|
|
|
|
|
if(pk->revkey[i].class&0x40)
|
|
|
|
|
{
|
|
|
|
|
tty_printf(" ");
|
|
|
|
|
tty_printf(_("(sensitive)"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tty_printf ("\n");
|
2005-07-27 18:10:56 +00:00
|
|
|
|
xfree(user);
|
2004-10-28 22:09:09 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2002-06-29 13:46:34 +00:00
|
|
|
|
|
2003-08-30 01:08:08 +00:00
|
|
|
|
keyid_from_pk(pk,NULL);
|
2004-03-03 05:47:51 +00:00
|
|
|
|
tty_printf("%s%c %4u%c/%s ",
|
2003-08-30 01:08:08 +00:00
|
|
|
|
node->pkt->pkttype == PKT_PUBLIC_KEY? "pub":"sub",
|
|
|
|
|
(node->flag & NODFLG_SELKEY)? '*':' ',
|
|
|
|
|
nbits_from_pk( pk ),
|
2004-03-03 05:47:51 +00:00
|
|
|
|
pubkey_letter( pk->pubkey_algo ),
|
|
|
|
|
keystr(pk->keyid));
|
2003-08-30 01:08:08 +00:00
|
|
|
|
|
2004-02-11 04:32:52 +00:00
|
|
|
|
tty_printf(_("created: %s"),datestr_from_pk(pk));
|
|
|
|
|
tty_printf(" ");
|
|
|
|
|
if(pk->is_revoked)
|
2004-10-06 19:51:45 +00:00
|
|
|
|
tty_printf(_("revoked: %s"),revokestr_from_pk(pk));
|
2004-02-11 04:32:52 +00:00
|
|
|
|
else if(pk->has_expired)
|
2004-10-06 19:51:45 +00:00
|
|
|
|
tty_printf(_("expired: %s"),expirestr_from_pk(pk));
|
2004-02-11 04:32:52 +00:00
|
|
|
|
else
|
2004-10-06 19:51:45 +00:00
|
|
|
|
tty_printf(_("expires: %s"),expirestr_from_pk(pk));
|
2004-09-23 13:32:31 +00:00
|
|
|
|
tty_printf(" ");
|
|
|
|
|
tty_printf(_("usage: %s"),usagestr_from_pk(pk));
|
2003-01-11 21:13:41 +00:00
|
|
|
|
tty_printf("\n");
|
|
|
|
|
|
|
|
|
|
if( node->pkt->pkttype == PKT_PUBLIC_KEY )
|
|
|
|
|
{
|
2003-10-14 00:05:44 +00:00
|
|
|
|
if(opt.trust_model!=TM_ALWAYS)
|
|
|
|
|
{
|
2004-12-17 18:51:32 +00:00
|
|
|
|
tty_printf("%*s", (int)keystrlen()+13,"");
|
2003-10-14 00:05:44 +00:00
|
|
|
|
/* Ownertrust is only meaningful for the PGP or
|
|
|
|
|
classic trust models */
|
|
|
|
|
if(opt.trust_model==TM_PGP || opt.trust_model==TM_CLASSIC)
|
2004-02-11 04:32:52 +00:00
|
|
|
|
{
|
|
|
|
|
int width=14-strlen(otrust);
|
|
|
|
|
if(width<=0)
|
|
|
|
|
width=1;
|
|
|
|
|
tty_printf(_("trust: %s"), otrust);
|
|
|
|
|
tty_printf("%*s",width,"");
|
|
|
|
|
}
|
|
|
|
|
|
2003-10-14 00:05:44 +00:00
|
|
|
|
tty_printf(_("validity: %s"), trust );
|
|
|
|
|
tty_printf("\n");
|
|
|
|
|
}
|
1999-07-01 10:53:35 +00:00
|
|
|
|
if( node->pkt->pkttype == PKT_PUBLIC_KEY
|
2003-01-11 21:13:41 +00:00
|
|
|
|
&& (get_ownertrust (pk)&TRUST_FLAG_DISABLED))
|
|
|
|
|
{
|
|
|
|
|
tty_printf("*** ");
|
1999-07-01 10:53:35 +00:00
|
|
|
|
tty_printf(_("This key has been disabled"));
|
1998-10-07 13:30:43 +00:00
|
|
|
|
tty_printf("\n");
|
2003-01-11 21:13:41 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if( node->pkt->pkttype == PKT_PUBLIC_KEY && with_fpr )
|
|
|
|
|
{
|
|
|
|
|
print_fingerprint ( pk, NULL, 2 );
|
|
|
|
|
tty_printf("\n");
|
|
|
|
|
}
|
1998-05-13 17:53:36 +00:00
|
|
|
|
}
|
1998-07-29 19:35:05 +00:00
|
|
|
|
else if( node->pkt->pkttype == PKT_SECRET_KEY
|
2004-05-20 02:51:23 +00:00
|
|
|
|
|| (with_subkeys && node->pkt->pkttype == PKT_SECRET_SUBKEY) )
|
|
|
|
|
{
|
1998-07-29 19:35:05 +00:00
|
|
|
|
PKT_secret_key *sk = node->pkt->pkt.secret_key;
|
2004-05-20 02:51:23 +00:00
|
|
|
|
tty_printf("%s%c %4u%c/%s ",
|
|
|
|
|
node->pkt->pkttype == PKT_SECRET_KEY? "sec":"ssb",
|
|
|
|
|
(node->flag & NODFLG_SELKEY)? '*':' ',
|
|
|
|
|
nbits_from_sk( sk ),
|
|
|
|
|
pubkey_letter( sk->pubkey_algo ),
|
|
|
|
|
keystr_from_sk(sk));
|
|
|
|
|
tty_printf(_("created: %s"),datestr_from_sk(sk));
|
|
|
|
|
tty_printf(" ");
|
2004-10-06 19:51:45 +00:00
|
|
|
|
tty_printf(_("expires: %s"),expirestr_from_sk(sk));
|
2000-07-14 17:34:53 +00:00
|
|
|
|
tty_printf("\n");
|
2004-09-20 18:38:39 +00:00
|
|
|
|
if (sk->is_protected && sk->protect.s2k.mode == 1002)
|
|
|
|
|
{
|
|
|
|
|
tty_printf(" ");
|
|
|
|
|
tty_printf(_("card-no: "));
|
|
|
|
|
if (sk->protect.ivlen == 16
|
|
|
|
|
&& !memcmp (sk->protect.iv, "\xD2\x76\x00\x01\x24\x01", 6))
|
|
|
|
|
{ /* This is an OpenPGP card. */
|
|
|
|
|
for (i=8; i < 14; i++)
|
|
|
|
|
{
|
|
|
|
|
if (i == 10)
|
|
|
|
|
tty_printf (" ");
|
|
|
|
|
tty_printf ("%02X", sk->protect.iv[i]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{ /* Something is wrong: Print all. */
|
|
|
|
|
for (i=0; i < sk->protect.ivlen; i++)
|
|
|
|
|
tty_printf ("%02X", sk->protect.iv[i]);
|
|
|
|
|
}
|
|
|
|
|
tty_printf ("\n");
|
|
|
|
|
}
|
2004-05-20 02:51:23 +00:00
|
|
|
|
}
|
1998-07-29 19:35:05 +00:00
|
|
|
|
}
|
2003-09-24 12:11:17 +00:00
|
|
|
|
|
2005-09-10 16:50:41 +00:00
|
|
|
|
show_names(keyblock,primary,only_marked?NODFLG_MARK_A:0,with_prefs);
|
2002-06-29 13:46:34 +00:00
|
|
|
|
|
|
|
|
|
if (do_warn)
|
2004-11-24 05:25:03 +00:00
|
|
|
|
tty_printf (_("Please note that the shown key validity"
|
|
|
|
|
" is not necessarily correct\n"
|
2002-06-29 13:46:34 +00:00
|
|
|
|
"unless you restart the program.\n"));
|
1998-07-29 19:35:05 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-08-19 08:28:00 +00:00
|
|
|
|
|
2005-09-10 16:50:41 +00:00
|
|
|
|
/* Display basic key information. This function is suitable to show
|
2002-08-19 08:28:00 +00:00
|
|
|
|
information on the key without any dependencies on the trustdb or
|
|
|
|
|
any other internal GnuPG stuff. KEYBLOCK may either be a public or
|
|
|
|
|
a secret key.*/
|
|
|
|
|
void
|
|
|
|
|
show_basic_key_info ( KBNODE keyblock )
|
|
|
|
|
{
|
|
|
|
|
KBNODE node;
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
/* The primary key */
|
|
|
|
|
for (node = keyblock; node; node = node->next)
|
|
|
|
|
{
|
|
|
|
|
if (node->pkt->pkttype == PKT_PUBLIC_KEY)
|
|
|
|
|
{
|
|
|
|
|
PKT_public_key *pk = node->pkt->pkt.public_key;
|
|
|
|
|
|
|
|
|
|
/* Note, we use the same format string as in other show
|
|
|
|
|
functions to make the translation job easier. */
|
2004-05-20 02:51:23 +00:00
|
|
|
|
tty_printf ("%s %4u%c/%s ",
|
2002-08-19 08:28:00 +00:00
|
|
|
|
node->pkt->pkttype == PKT_PUBLIC_KEY? "pub":"sub",
|
|
|
|
|
nbits_from_pk( pk ),
|
|
|
|
|
pubkey_letter( pk->pubkey_algo ),
|
2004-05-20 02:51:23 +00:00
|
|
|
|
keystr_from_pk(pk));
|
|
|
|
|
tty_printf(_("created: %s"),datestr_from_pk(pk));
|
|
|
|
|
tty_printf(" ");
|
2004-10-06 19:51:45 +00:00
|
|
|
|
tty_printf(_("expires: %s"),expirestr_from_pk(pk));
|
2002-08-19 08:28:00 +00:00
|
|
|
|
tty_printf("\n");
|
|
|
|
|
print_fingerprint ( pk, NULL, 3 );
|
|
|
|
|
tty_printf("\n");
|
|
|
|
|
}
|
|
|
|
|
else if (node->pkt->pkttype == PKT_SECRET_KEY)
|
|
|
|
|
{
|
|
|
|
|
PKT_secret_key *sk = node->pkt->pkt.secret_key;
|
2004-05-20 02:51:23 +00:00
|
|
|
|
tty_printf("%s %4u%c/%s",
|
2002-08-19 08:28:00 +00:00
|
|
|
|
node->pkt->pkttype == PKT_SECRET_KEY? "sec":"ssb",
|
|
|
|
|
nbits_from_sk( sk ),
|
|
|
|
|
pubkey_letter( sk->pubkey_algo ),
|
2004-05-20 02:51:23 +00:00
|
|
|
|
keystr_from_sk(sk));
|
|
|
|
|
tty_printf(_("created: %s"),datestr_from_sk(sk));
|
|
|
|
|
tty_printf(" ");
|
2004-10-06 19:51:45 +00:00
|
|
|
|
tty_printf(_("expires: %s"),expirestr_from_sk(sk));
|
2002-08-19 08:28:00 +00:00
|
|
|
|
tty_printf("\n");
|
|
|
|
|
print_fingerprint (NULL, sk, 3 );
|
|
|
|
|
tty_printf("\n");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* The user IDs. */
|
|
|
|
|
for (i=0, node = keyblock; node; node = node->next)
|
|
|
|
|
{
|
|
|
|
|
if (node->pkt->pkttype == PKT_USER_ID)
|
|
|
|
|
{
|
|
|
|
|
PKT_user_id *uid = node->pkt->pkt.user_id;
|
|
|
|
|
++i;
|
|
|
|
|
|
|
|
|
|
tty_printf (" ");
|
|
|
|
|
if (uid->is_revoked)
|
2004-09-29 17:41:58 +00:00
|
|
|
|
tty_printf("[%s] ",_("revoked"));
|
2004-02-10 22:42:34 +00:00
|
|
|
|
else if ( uid->is_expired )
|
2004-09-29 17:41:58 +00:00
|
|
|
|
tty_printf("[%s] ",_("expired"));
|
2002-08-19 08:28:00 +00:00
|
|
|
|
tty_print_utf8_string (uid->name, uid->len);
|
|
|
|
|
tty_printf ("\n");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
1998-07-29 19:35:05 +00:00
|
|
|
|
static void
|
|
|
|
|
show_key_and_fingerprint( KBNODE keyblock )
|
|
|
|
|
{
|
2004-03-24 17:34:57 +00:00
|
|
|
|
KBNODE node;
|
|
|
|
|
PKT_public_key *pk = NULL;
|
1998-05-13 17:53:36 +00:00
|
|
|
|
|
2004-03-24 17:34:57 +00:00
|
|
|
|
for( node = keyblock; node; node = node->next )
|
|
|
|
|
{
|
|
|
|
|
if( node->pkt->pkttype == PKT_PUBLIC_KEY )
|
|
|
|
|
{
|
|
|
|
|
pk = node->pkt->pkt.public_key;
|
|
|
|
|
tty_printf("pub %4u%c/%s %s ",
|
|
|
|
|
nbits_from_pk( pk ),
|
|
|
|
|
pubkey_letter( pk->pubkey_algo ),
|
|
|
|
|
keystr_from_pk(pk),
|
|
|
|
|
datestr_from_pk(pk) );
|
1998-06-25 10:19:08 +00:00
|
|
|
|
}
|
2004-03-24 17:34:57 +00:00
|
|
|
|
else if( node->pkt->pkttype == PKT_USER_ID )
|
|
|
|
|
{
|
|
|
|
|
PKT_user_id *uid = node->pkt->pkt.user_id;
|
|
|
|
|
tty_print_utf8_string( uid->name, uid->len );
|
|
|
|
|
break;
|
1998-07-29 19:35:05 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2004-03-24 17:34:57 +00:00
|
|
|
|
tty_printf("\n");
|
|
|
|
|
if( pk )
|
|
|
|
|
print_fingerprint( pk, NULL, 2 );
|
1998-07-29 19:35:05 +00:00
|
|
|
|
}
|
|
|
|
|
|
1998-04-20 15:52:20 +00:00
|
|
|
|
|
2003-05-31 04:06:06 +00:00
|
|
|
|
/* Show a warning if no uids on the key have the primary uid flag
|
|
|
|
|
set. */
|
|
|
|
|
static void
|
2004-04-16 16:31:19 +00:00
|
|
|
|
no_primary_warning(KBNODE keyblock)
|
2003-05-31 04:06:06 +00:00
|
|
|
|
{
|
|
|
|
|
KBNODE node;
|
2004-04-16 16:31:19 +00:00
|
|
|
|
int have_primary=0,uid_count=0;
|
2003-05-31 04:06:06 +00:00
|
|
|
|
|
|
|
|
|
/* TODO: if we ever start behaving differently with a primary or
|
|
|
|
|
non-primary attribute ID, we will need to check for attributes
|
|
|
|
|
here as well. */
|
|
|
|
|
|
|
|
|
|
for(node=keyblock; node; node = node->next)
|
|
|
|
|
{
|
|
|
|
|
if(node->pkt->pkttype==PKT_USER_ID
|
|
|
|
|
&& node->pkt->pkt.user_id->attrib_data==NULL)
|
|
|
|
|
{
|
|
|
|
|
uid_count++;
|
|
|
|
|
|
2004-04-16 16:31:19 +00:00
|
|
|
|
if(node->pkt->pkt.user_id->is_primary==2)
|
|
|
|
|
{
|
|
|
|
|
have_primary=1;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2003-05-31 04:06:06 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2004-04-16 16:31:19 +00:00
|
|
|
|
if(uid_count>1 && !have_primary)
|
|
|
|
|
log_info(_("WARNING: no user ID has been marked as primary. This command"
|
|
|
|
|
" may\n cause a different user ID to become"
|
|
|
|
|
" the assumed primary.\n"));
|
2003-05-31 04:06:06 +00:00
|
|
|
|
}
|
1998-07-29 19:35:05 +00:00
|
|
|
|
|
|
|
|
|
/****************
|
2002-06-29 13:46:34 +00:00
|
|
|
|
* Ask for a new user id, do the selfsignature and put it into
|
1998-07-29 19:35:05 +00:00
|
|
|
|
* both keyblocks.
|
|
|
|
|
* Return true if there is a new user id
|
|
|
|
|
*/
|
|
|
|
|
static int
|
2005-09-01 20:51:13 +00:00
|
|
|
|
menu_adduid( KBNODE pub_keyblock, KBNODE sec_keyblock,
|
|
|
|
|
int photo, const char *photo_name)
|
1998-07-29 19:35:05 +00:00
|
|
|
|
{
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
|
|
for( node = pub_keyblock; node; pub_where = node, node = node->next ) {
|
|
|
|
|
if( node->pkt->pkttype == PKT_PUBLIC_KEY )
|
|
|
|
|
pk = node->pkt->pkt.public_key;
|
|
|
|
|
else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
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 )
|
1998-10-07 13:30:43 +00:00
|
|
|
|
sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
|
1998-07-29 19:35:05 +00:00
|
|
|
|
else if( node->pkt->pkttype == PKT_SECRET_SUBKEY )
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if( !node ) /* no subkey */
|
|
|
|
|
sec_where = NULL;
|
2002-06-29 13:46:34 +00:00
|
|
|
|
assert(pk && sk);
|
|
|
|
|
|
|
|
|
|
if(photo) {
|
|
|
|
|
int hasattrib=0;
|
|
|
|
|
|
|
|
|
|
for( node = pub_keyblock; node; node = node->next )
|
|
|
|
|
if( node->pkt->pkttype == PKT_USER_ID &&
|
|
|
|
|
node->pkt->pkt.user_id->attrib_data!=NULL)
|
|
|
|
|
{
|
|
|
|
|
hasattrib=1;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* It is legal but bad for compatibility to add a photo ID to a
|
|
|
|
|
v3 key as it means that PGP2 will not be able to use that key
|
2002-09-17 03:21:13 +00:00
|
|
|
|
anymore. Also, PGP may not expect a photo on a v3 key.
|
|
|
|
|
Don't bother to ask this if the key already has a photo - any
|
|
|
|
|
damage has already been done at that point. -dms */
|
2002-06-29 13:46:34 +00:00
|
|
|
|
if(pk->version==3 && !hasattrib)
|
|
|
|
|
{
|
|
|
|
|
if(opt.expert)
|
|
|
|
|
{
|
|
|
|
|
tty_printf(_("WARNING: This is a PGP2-style key. "
|
|
|
|
|
"Adding a photo ID may cause some versions\n"
|
|
|
|
|
" of PGP to reject this key.\n"));
|
|
|
|
|
|
|
|
|
|
if(!cpr_get_answer_is_yes("keyedit.v3_photo.okay",
|
|
|
|
|
_("Are you sure you still want "
|
|
|
|
|
"to add it? (y/N) ")))
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
tty_printf(_("You may not add a photo ID to "
|
|
|
|
|
"a PGP2-style key.\n"));
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
1998-07-29 19:35:05 +00:00
|
|
|
|
|
2005-09-01 20:51:13 +00:00
|
|
|
|
uid = generate_photo_id(pk,photo_name);
|
2002-06-29 13:46:34 +00:00
|
|
|
|
} else
|
|
|
|
|
uid = generate_user_id();
|
|
|
|
|
if( !uid )
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
rc = make_keysig_packet( &sig, pk, uid, NULL, sk, 0x13, 0, 0, 0, 0,
|
1998-11-20 17:42:18 +00:00
|
|
|
|
keygen_add_std_prefs, pk );
|
1998-10-07 13:30:43 +00:00
|
|
|
|
free_secret_key( sk );
|
1998-07-29 19:35:05 +00:00
|
|
|
|
if( rc ) {
|
2002-06-29 13:46:34 +00:00
|
|
|
|
log_error("signing failed: %s\n", g10_errstr(rc) );
|
1998-07-29 19:35:05 +00:00
|
|
|
|
free_user_id(uid);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* insert/append to secret keyblock */
|
2005-07-27 18:10:56 +00:00
|
|
|
|
pkt = xmalloc_clear( sizeof *pkt );
|
1998-07-29 19:35:05 +00:00
|
|
|
|
pkt->pkttype = PKT_USER_ID;
|
2002-06-29 13:46:34 +00:00
|
|
|
|
pkt->pkt.user_id = scopy_user_id(uid);
|
1998-07-29 19:35:05 +00:00
|
|
|
|
node = new_kbnode(pkt);
|
|
|
|
|
if( sec_where )
|
|
|
|
|
insert_kbnode( sec_where, node, 0 );
|
1998-04-20 15:52:20 +00:00
|
|
|
|
else
|
1998-07-29 19:35:05 +00:00
|
|
|
|
add_kbnode( sec_keyblock, node );
|
2005-07-27 18:10:56 +00:00
|
|
|
|
pkt = xmalloc_clear( sizeof *pkt );
|
1998-07-29 19:35:05 +00:00
|
|
|
|
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 */
|
2005-07-27 18:10:56 +00:00
|
|
|
|
pkt = xmalloc_clear( sizeof *pkt );
|
1998-07-29 19:35:05 +00:00
|
|
|
|
pkt->pkttype = PKT_USER_ID;
|
|
|
|
|
pkt->pkt.user_id = uid;
|
|
|
|
|
node = new_kbnode(pkt);
|
|
|
|
|
if( pub_where )
|
|
|
|
|
insert_kbnode( pub_where, node, 0 );
|
|
|
|
|
else
|
|
|
|
|
add_kbnode( pub_keyblock, node );
|
2005-07-27 18:10:56 +00:00
|
|
|
|
pkt = xmalloc_clear( sizeof *pkt );
|
1998-07-29 19:35:05 +00:00
|
|
|
|
pkt->pkttype = PKT_SIGNATURE;
|
|
|
|
|
pkt->pkt.signature = copy_signature(NULL, sig);
|
|
|
|
|
if( pub_where )
|
|
|
|
|
insert_kbnode( node, new_kbnode(pkt), 0 );
|
|
|
|
|
else
|
|
|
|
|
add_kbnode( pub_keyblock, new_kbnode(pkt) );
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/****************
|
2004-09-20 18:38:39 +00:00
|
|
|
|
* Remove all selected userids from the keyrings
|
1998-07-29 19:35:05 +00:00
|
|
|
|
*/
|
|
|
|
|
static void
|
|
|
|
|
menu_deluid( KBNODE pub_keyblock, KBNODE sec_keyblock )
|
|
|
|
|
{
|
|
|
|
|
KBNODE node;
|
|
|
|
|
int selected=0;
|
|
|
|
|
|
|
|
|
|
for( node = pub_keyblock; node; node = node->next ) {
|
|
|
|
|
if( node->pkt->pkttype == PKT_USER_ID ) {
|
|
|
|
|
selected = node->flag & NODFLG_SELUID;
|
|
|
|
|
if( selected ) {
|
2002-06-29 13:46:34 +00:00
|
|
|
|
/* Only cause a trust update if we delete a
|
|
|
|
|
non-revoked user id */
|
|
|
|
|
if(!node->pkt->pkt.user_id->is_revoked)
|
|
|
|
|
update_trust=1;
|
1998-07-29 19:35:05 +00:00
|
|
|
|
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 )
|
|
|
|
|
delete_kbnode( node );
|
|
|
|
|
else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
|
|
|
|
|
selected = 0;
|
|
|
|
|
}
|
|
|
|
|
commit_kbnode( &pub_keyblock );
|
|
|
|
|
if( sec_keyblock )
|
|
|
|
|
commit_kbnode( &sec_keyblock );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
1999-05-27 07:45:46 +00:00
|
|
|
|
static int
|
|
|
|
|
menu_delsig( KBNODE pub_keyblock )
|
|
|
|
|
{
|
|
|
|
|
KBNODE node;
|
|
|
|
|
PKT_user_id *uid = NULL;
|
|
|
|
|
int changed=0;
|
|
|
|
|
|
|
|
|
|
for( node = pub_keyblock; node; node = node->next ) {
|
|
|
|
|
if( node->pkt->pkttype == PKT_USER_ID ) {
|
|
|
|
|
uid = (node->flag & NODFLG_SELUID)? node->pkt->pkt.user_id : NULL;
|
|
|
|
|
}
|
|
|
|
|
else if( uid && node->pkt->pkttype == PKT_SIGNATURE ) {
|
1999-06-16 18:25:37 +00:00
|
|
|
|
int okay, valid, selfsig, inv_sig, no_key, other_err;
|
1999-05-27 07:45:46 +00:00
|
|
|
|
|
|
|
|
|
tty_printf("uid ");
|
1999-08-31 15:30:12 +00:00
|
|
|
|
tty_print_utf8_string( uid->name, uid->len );
|
1999-05-27 07:45:46 +00:00
|
|
|
|
tty_printf("\n");
|
|
|
|
|
|
2004-09-13 12:31:25 +00:00
|
|
|
|
okay = inv_sig = no_key = other_err = 0;
|
|
|
|
|
if(opt.with_colons)
|
|
|
|
|
valid = print_and_check_one_sig_colon( pub_keyblock, node,
|
|
|
|
|
&inv_sig, &no_key, &other_err,
|
|
|
|
|
&selfsig, 1 );
|
|
|
|
|
else
|
|
|
|
|
valid = print_and_check_one_sig( pub_keyblock, node,
|
|
|
|
|
&inv_sig, &no_key, &other_err,
|
|
|
|
|
&selfsig, 1 );
|
1999-06-16 18:25:37 +00:00
|
|
|
|
|
2002-06-29 13:46:34 +00:00
|
|
|
|
if( valid ) {
|
1999-06-16 18:25:37 +00:00
|
|
|
|
okay = cpr_get_answer_yes_no_quit(
|
|
|
|
|
"keyedit.delsig.valid",
|
|
|
|
|
_("Delete this good signature? (y/N/q)"));
|
2002-06-29 13:46:34 +00:00
|
|
|
|
|
|
|
|
|
/* Only update trust if we delete a good signature.
|
|
|
|
|
The other two cases do not affect trust. */
|
|
|
|
|
if(okay)
|
|
|
|
|
update_trust=1;
|
|
|
|
|
}
|
1999-06-16 18:25:37 +00:00
|
|
|
|
else if( inv_sig || other_err )
|
|
|
|
|
okay = cpr_get_answer_yes_no_quit(
|
|
|
|
|
"keyedit.delsig.invalid",
|
|
|
|
|
_("Delete this invalid signature? (y/N/q)"));
|
|
|
|
|
else if( no_key )
|
|
|
|
|
okay = cpr_get_answer_yes_no_quit(
|
|
|
|
|
"keyedit.delsig.unknown",
|
|
|
|
|
_("Delete this unknown signature? (y/N/q)"));
|
|
|
|
|
|
1999-05-27 07:45:46 +00:00
|
|
|
|
if( okay == -1 )
|
|
|
|
|
break;
|
1999-06-16 18:25:37 +00:00
|
|
|
|
if( okay && selfsig && !cpr_get_answer_is_yes(
|
1999-05-27 07:45:46 +00:00
|
|
|
|
"keyedit.delsig.selfsig",
|
|
|
|
|
_("Really delete this self-signature? (y/N)") ))
|
|
|
|
|
okay = 0;
|
|
|
|
|
if( okay ) {
|
|
|
|
|
delete_kbnode( node );
|
|
|
|
|
changed++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
|
|
|
|
|
uid = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if( changed ) {
|
|
|
|
|
commit_kbnode( &pub_keyblock );
|
|
|
|
|
tty_printf( changed == 1? _("Deleted %d signature.\n")
|
|
|
|
|
: _("Deleted %d signatures.\n"), changed );
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
tty_printf( _("Nothing deleted.\n") );
|
|
|
|
|
|
|
|
|
|
return changed;
|
|
|
|
|
}
|
|
|
|
|
|
2005-04-24 18:35:30 +00:00
|
|
|
|
static int
|
2005-11-18 04:25:07 +00:00
|
|
|
|
menu_clean(KBNODE keyblock,int self_only)
|
2005-04-24 18:35:30 +00:00
|
|
|
|
{
|
|
|
|
|
KBNODE uidnode;
|
2005-11-18 04:25:07 +00:00
|
|
|
|
int modified=0,select_all=!count_selected_uids(keyblock);
|
2005-04-24 18:35:30 +00:00
|
|
|
|
|
2005-11-18 04:25:07 +00:00
|
|
|
|
for(uidnode=keyblock->next;
|
|
|
|
|
uidnode && uidnode->pkt->pkttype!=PKT_PUBLIC_SUBKEY;
|
|
|
|
|
uidnode=uidnode->next)
|
2005-04-24 18:35:30 +00:00
|
|
|
|
{
|
|
|
|
|
if(uidnode->pkt->pkttype==PKT_USER_ID
|
|
|
|
|
&& (uidnode->flag&NODFLG_SELUID || select_all))
|
|
|
|
|
{
|
2005-11-18 04:25:07 +00:00
|
|
|
|
int uids=0,sigs=0;
|
2005-04-24 18:35:30 +00:00
|
|
|
|
char *user=utf8_to_native(uidnode->pkt->pkt.user_id->name,
|
|
|
|
|
uidnode->pkt->pkt.user_id->len,
|
|
|
|
|
0);
|
|
|
|
|
|
2005-11-18 04:25:07 +00:00
|
|
|
|
clean_one_uid(keyblock,uidnode,opt.verbose,self_only,&uids,&sigs);
|
|
|
|
|
if(uids)
|
2005-05-30 03:43:30 +00:00
|
|
|
|
{
|
2005-05-31 19:12:10 +00:00
|
|
|
|
const char *reason;
|
2005-05-30 03:43:30 +00:00
|
|
|
|
|
2005-11-18 04:25:07 +00:00
|
|
|
|
if(uidnode->pkt->pkt.user_id->is_revoked)
|
2005-05-30 03:43:30 +00:00
|
|
|
|
reason=_("revoked");
|
2005-11-18 04:25:07 +00:00
|
|
|
|
else if(uidnode->pkt->pkt.user_id->is_expired)
|
2005-05-30 03:43:30 +00:00
|
|
|
|
reason=_("expired");
|
|
|
|
|
else
|
|
|
|
|
reason=_("invalid");
|
|
|
|
|
|
2005-06-09 02:53:18 +00:00
|
|
|
|
tty_printf("User ID \"%s\" compacted: %s\n",user,reason);
|
|
|
|
|
|
2005-11-18 04:25:07 +00:00
|
|
|
|
modified=1;
|
|
|
|
|
}
|
|
|
|
|
else if(sigs)
|
|
|
|
|
{
|
|
|
|
|
tty_printf(sigs==1?
|
|
|
|
|
"User ID \"%s\": %d signature removed\n":
|
|
|
|
|
"User ID \"%s\": %d signatures removed\n",
|
|
|
|
|
user,sigs);
|
|
|
|
|
|
|
|
|
|
modified=1;
|
2005-05-30 03:43:30 +00:00
|
|
|
|
}
|
2005-11-18 04:25:07 +00:00
|
|
|
|
else
|
|
|
|
|
tty_printf(_("User ID \"%s\": already clean\n"),user);
|
|
|
|
|
|
|
|
|
|
xfree(user);
|
2005-05-30 03:43:30 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2005-05-31 03:59:24 +00:00
|
|
|
|
|
|
|
|
|
return modified;
|
|
|
|
|
}
|
|
|
|
|
|
1998-07-29 19:35:05 +00:00
|
|
|
|
/****************
|
|
|
|
|
* Remove some of the secondary keys
|
|
|
|
|
*/
|
|
|
|
|
static void
|
|
|
|
|
menu_delkey( KBNODE pub_keyblock, KBNODE sec_keyblock )
|
|
|
|
|
{
|
|
|
|
|
KBNODE node;
|
|
|
|
|
int selected=0;
|
|
|
|
|
|
|
|
|
|
for( node = pub_keyblock; node; node = node->next ) {
|
|
|
|
|
if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if( selected && node->pkt->pkttype == PKT_SIGNATURE )
|
|
|
|
|
delete_kbnode( node );
|
|
|
|
|
else
|
|
|
|
|
selected = 0;
|
|
|
|
|
}
|
|
|
|
|
commit_kbnode( &pub_keyblock );
|
|
|
|
|
if( sec_keyblock )
|
|
|
|
|
commit_kbnode( &sec_keyblock );
|
2002-06-29 13:46:34 +00:00
|
|
|
|
|
* g10.c (main): Add --no-textmode.
* export.c (do_export_stream), keyedit.c (show_key_with_all_names,
menu_addrevoker), mainproc.c (check_sig_and_print), photoid.c
(show_photos), sign.c (mk_notation_and_policy), trustdb.c (get_validity,
reset_trust_records, validate_keys): Make some strings translatable.
* mainproc.c (check_sig_and_print): Show digest algorithm and sig class
when verifying a sig with --verbose on, and add version, pk and hash
algorithms and sig class to VALIDSIG.
* parse-packet.c (enum_sig_subpkt): Make a warning message a --verbose
warning message since we don't need to warn every time we see an unknown
critical (we only need to invalidate the signature).
* trustdb.c (init_trustdb): Check the trustdb options even with TM_AUTO
since the auto may become TM_CLASSIC or TM_OPENPGP.
2003-04-27 20:22:09 +00:00
|
|
|
|
/* 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 */
|
1998-07-29 19:35:05 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2002-06-29 13:46:34 +00:00
|
|
|
|
/****************
|
|
|
|
|
* Ask for a new revoker, do the selfsignature and put it into
|
|
|
|
|
* both keyblocks.
|
|
|
|
|
* Return true if there is a new revoker
|
|
|
|
|
*/
|
|
|
|
|
static int
|
2002-07-19 05:08:54 +00:00
|
|
|
|
menu_addrevoker( KBNODE pub_keyblock, KBNODE sec_keyblock, int sensitive )
|
2002-06-29 13:46:34 +00:00
|
|
|
|
{
|
|
|
|
|
PKT_public_key *pk=NULL,*revoker_pk=NULL;
|
|
|
|
|
PKT_secret_key *sk=NULL;
|
|
|
|
|
PKT_signature *sig=NULL;
|
|
|
|
|
PACKET *pkt;
|
|
|
|
|
struct revocation_key revkey;
|
|
|
|
|
size_t fprlen;
|
|
|
|
|
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;
|
2002-09-17 03:21:13 +00:00
|
|
|
|
|
|
|
|
|
if(pk->numrevkeys==0 && pk->version==3)
|
|
|
|
|
{
|
|
|
|
|
/* It is legal but bad for compatibility to add a revoker to a
|
|
|
|
|
v3 key as it means that PGP2 will not be able to use that key
|
|
|
|
|
anymore. Also, PGP may not expect a revoker on a v3 key.
|
|
|
|
|
Don't bother to ask this if the key already has a revoker -
|
|
|
|
|
any damage has already been done at that point. -dms */
|
|
|
|
|
if(opt.expert)
|
|
|
|
|
{
|
|
|
|
|
tty_printf(_("WARNING: This is a PGP 2.x-style key. "
|
|
|
|
|
"Adding a designated revoker may cause\n"
|
|
|
|
|
" some versions of PGP to reject this key.\n"));
|
|
|
|
|
|
|
|
|
|
if(!cpr_get_answer_is_yes("keyedit.v3_revoker.okay",
|
|
|
|
|
_("Are you sure you still want "
|
|
|
|
|
"to add it? (y/N) ")))
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
tty_printf(_("You may not add a designated revoker to "
|
|
|
|
|
"a PGP 2.x-style key.\n"));
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2002-06-29 13:46:34 +00:00
|
|
|
|
sk=copy_secret_key(NULL,sec_keyblock->pkt->pkt.secret_key);
|
|
|
|
|
|
|
|
|
|
for(;;)
|
|
|
|
|
{
|
|
|
|
|
char *answer;
|
|
|
|
|
|
|
|
|
|
if(revoker_pk)
|
|
|
|
|
free_public_key(revoker_pk);
|
|
|
|
|
|
2005-07-27 18:10:56 +00:00
|
|
|
|
revoker_pk=xmalloc_clear(sizeof(*revoker_pk));
|
2002-06-29 13:46:34 +00:00
|
|
|
|
|
|
|
|
|
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')
|
2003-08-31 03:45:41 +00:00
|
|
|
|
{
|
2005-07-27 18:10:56 +00:00
|
|
|
|
xfree(answer);
|
2003-08-31 03:45:41 +00:00
|
|
|
|
goto fail;
|
|
|
|
|
}
|
2002-06-29 13:46:34 +00:00
|
|
|
|
|
2005-10-27 16:23:59 +00:00
|
|
|
|
/* 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. */
|
|
|
|
|
revoker_pk->req_usage=PUBKEY_USAGE_CERT;
|
2002-12-26 22:22:50 +00:00
|
|
|
|
rc=get_pubkey_byname(revoker_pk,answer,NULL,NULL,1);
|
2002-06-29 13:46:34 +00:00
|
|
|
|
if(rc)
|
|
|
|
|
{
|
2004-10-28 01:58:01 +00:00
|
|
|
|
log_error (_("key \"%s\" not found: %s\n"),answer,g10_errstr(rc));
|
2005-07-27 18:10:56 +00:00
|
|
|
|
xfree(answer);
|
2002-06-29 13:46:34 +00:00
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2005-07-27 18:10:56 +00:00
|
|
|
|
xfree(answer);
|
2003-08-31 03:45:41 +00:00
|
|
|
|
|
2002-06-29 13:46:34 +00:00
|
|
|
|
fingerprint_from_pk(revoker_pk,revkey.fpr,&fprlen);
|
|
|
|
|
if(fprlen!=20)
|
|
|
|
|
{
|
|
|
|
|
log_error(_("cannot appoint a PGP 2.x style key as a "
|
|
|
|
|
"designated revoker\n"));
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2002-10-11 21:07:03 +00:00
|
|
|
|
revkey.class=0x80;
|
|
|
|
|
if(sensitive)
|
|
|
|
|
revkey.class|=0x40;
|
|
|
|
|
revkey.algid=revoker_pk->pubkey_algo;
|
|
|
|
|
|
2002-06-29 13:46:34 +00:00
|
|
|
|
if(cmp_public_keys(revoker_pk,pk)==0)
|
|
|
|
|
{
|
|
|
|
|
/* This actually causes no harm (after all, a key that
|
|
|
|
|
designates itself as a revoker is the same as a
|
|
|
|
|
regular key), but it's easy enough to check. */
|
|
|
|
|
log_error(_("you cannot appoint a key as its own "
|
|
|
|
|
"designated revoker\n"));
|
2002-10-11 21:07:03 +00:00
|
|
|
|
|
2002-06-29 13:46:34 +00:00
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2002-10-11 21:07:03 +00:00
|
|
|
|
keyid_from_pk(pk,NULL);
|
|
|
|
|
|
|
|
|
|
/* Does this revkey already exist? */
|
|
|
|
|
if(!pk->revkey && pk->numrevkeys)
|
|
|
|
|
BUG();
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
for(i=0;i<pk->numrevkeys;i++)
|
|
|
|
|
{
|
|
|
|
|
if(memcmp(&pk->revkey[i],&revkey,
|
|
|
|
|
sizeof(struct revocation_key))==0)
|
|
|
|
|
{
|
|
|
|
|
char buf[50];
|
|
|
|
|
|
|
|
|
|
log_error(_("this key has already been designated "
|
|
|
|
|
"as a revoker\n"));
|
|
|
|
|
|
|
|
|
|
sprintf(buf,"%08lX%08lX",
|
|
|
|
|
(ulong)pk->keyid[0],(ulong)pk->keyid[1]);
|
|
|
|
|
write_status_text(STATUS_ALREADY_SIGNED,buf);
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(i<pk->numrevkeys)
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2004-03-24 17:34:57 +00:00
|
|
|
|
print_pubkey_info(NULL,revoker_pk);
|
2002-06-29 13:46:34 +00:00
|
|
|
|
print_fingerprint(revoker_pk,NULL,2);
|
|
|
|
|
tty_printf("\n");
|
|
|
|
|
|
* g10.c (main): Add --no-textmode.
* export.c (do_export_stream), keyedit.c (show_key_with_all_names,
menu_addrevoker), mainproc.c (check_sig_and_print), photoid.c
(show_photos), sign.c (mk_notation_and_policy), trustdb.c (get_validity,
reset_trust_records, validate_keys): Make some strings translatable.
* mainproc.c (check_sig_and_print): Show digest algorithm and sig class
when verifying a sig with --verbose on, and add version, pk and hash
algorithms and sig class to VALIDSIG.
* parse-packet.c (enum_sig_subpkt): Make a warning message a --verbose
warning message since we don't need to warn every time we see an unknown
critical (we only need to invalidate the signature).
* trustdb.c (init_trustdb): Check the trustdb options even with TM_AUTO
since the auto may become TM_CLASSIC or TM_OPENPGP.
2003-04-27 20:22:09 +00:00
|
|
|
|
tty_printf(_("WARNING: appointing a key as a designated revoker "
|
|
|
|
|
"cannot be undone!\n"));
|
2002-06-29 13:46:34 +00:00
|
|
|
|
|
|
|
|
|
tty_printf("\n");
|
|
|
|
|
|
|
|
|
|
if(!cpr_get_answer_is_yes("keyedit.add_revoker.okay",
|
* g10.c (main): Add --no-textmode.
* export.c (do_export_stream), keyedit.c (show_key_with_all_names,
menu_addrevoker), mainproc.c (check_sig_and_print), photoid.c
(show_photos), sign.c (mk_notation_and_policy), trustdb.c (get_validity,
reset_trust_records, validate_keys): Make some strings translatable.
* mainproc.c (check_sig_and_print): Show digest algorithm and sig class
when verifying a sig with --verbose on, and add version, pk and hash
algorithms and sig class to VALIDSIG.
* parse-packet.c (enum_sig_subpkt): Make a warning message a --verbose
warning message since we don't need to warn every time we see an unknown
critical (we only need to invalidate the signature).
* trustdb.c (init_trustdb): Check the trustdb options even with TM_AUTO
since the auto may become TM_CLASSIC or TM_OPENPGP.
2003-04-27 20:22:09 +00:00
|
|
|
|
_("Are you sure you want to appoint this "
|
2004-10-10 15:27:14 +00:00
|
|
|
|
"key as a designated revoker? (y/N) ")))
|
2002-06-29 13:46:34 +00:00
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
free_public_key(revoker_pk);
|
2002-10-11 21:07:03 +00:00
|
|
|
|
revoker_pk=NULL;
|
2002-06-29 13:46:34 +00:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2002-09-17 03:21:13 +00:00
|
|
|
|
/* 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,
|
2002-06-29 13:46:34 +00:00
|
|
|
|
keygen_add_revkey,&revkey );
|
|
|
|
|
if( rc )
|
|
|
|
|
{
|
|
|
|
|
log_error("signing failed: %s\n", g10_errstr(rc) );
|
|
|
|
|
goto fail;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
free_secret_key(sk);
|
|
|
|
|
sk=NULL;
|
|
|
|
|
|
|
|
|
|
/* insert into secret keyblock */
|
2005-07-27 18:10:56 +00:00
|
|
|
|
pkt = xmalloc_clear( sizeof *pkt );
|
2002-06-29 13:46:34 +00:00
|
|
|
|
pkt->pkttype = PKT_SIGNATURE;
|
|
|
|
|
pkt->pkt.signature = copy_signature(NULL, sig);
|
|
|
|
|
insert_kbnode( sec_keyblock, new_kbnode(pkt), PKT_SIGNATURE );
|
|
|
|
|
|
|
|
|
|
/* insert into public keyblock */
|
2005-07-27 18:10:56 +00:00
|
|
|
|
pkt = xmalloc_clear( sizeof *pkt );
|
2002-06-29 13:46:34 +00:00
|
|
|
|
pkt->pkttype = PKT_SIGNATURE;
|
|
|
|
|
pkt->pkt.signature = sig;
|
|
|
|
|
insert_kbnode( pub_keyblock, new_kbnode(pkt), PKT_SIGNATURE );
|
|
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
|
|
fail:
|
|
|
|
|
if(sk)
|
|
|
|
|
free_secret_key(sk);
|
|
|
|
|
if(sig)
|
|
|
|
|
free_seckey_enc(sig);
|
|
|
|
|
if(revoker_pk)
|
|
|
|
|
free_public_key(revoker_pk);
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
1998-10-18 15:21:22 +00:00
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
menu_expire( KBNODE pub_keyblock, KBNODE sec_keyblock )
|
|
|
|
|
{
|
1998-11-20 17:42:18 +00:00
|
|
|
|
int n1, signumber, rc;
|
1998-10-18 15:21:22 +00:00
|
|
|
|
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 ) {
|
2004-12-20 05:19:09 +00:00
|
|
|
|
tty_printf(_("Please select at most one subkey.\n"));
|
1998-10-18 15:21:22 +00:00
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
else if( n1 )
|
2004-12-20 05:19:09 +00:00
|
|
|
|
tty_printf(_("Changing expiration time for a subkey.\n"));
|
2004-04-16 16:31:19 +00:00
|
|
|
|
else
|
|
|
|
|
{
|
1999-06-16 18:25:37 +00:00
|
|
|
|
tty_printf(_("Changing expiration time for the primary key.\n"));
|
1998-10-18 15:21:22 +00:00
|
|
|
|
mainkey=1;
|
2004-04-16 16:31:19 +00:00
|
|
|
|
no_primary_warning(pub_keyblock);
|
|
|
|
|
}
|
2003-05-31 04:06:06 +00:00
|
|
|
|
|
1998-10-18 15:21:22 +00:00
|
|
|
|
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) */
|
|
|
|
|
main_pk = sub_pk = NULL;
|
|
|
|
|
uid = NULL;
|
1998-11-20 17:42:18 +00:00
|
|
|
|
signumber = 0;
|
1998-10-18 15:21:22 +00:00
|
|
|
|
for( node=pub_keyblock; node; node = node->next ) {
|
|
|
|
|
if( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
|
|
|
|
|
main_pk = node->pkt->pkt.public_key;
|
|
|
|
|
keyid_from_pk( main_pk, keyid );
|
1998-11-20 17:42:18 +00:00
|
|
|
|
main_pk->expiredate = expiredate;
|
1998-10-18 15:21:22 +00:00
|
|
|
|
}
|
|
|
|
|
else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
|
1998-11-20 17:42:18 +00:00
|
|
|
|
&& (node->flag & NODFLG_SELKEY ) ) {
|
1998-10-18 15:21:22 +00:00
|
|
|
|
sub_pk = node->pkt->pkt.public_key;
|
1998-11-20 17:42:18 +00:00
|
|
|
|
sub_pk->expiredate = expiredate;
|
|
|
|
|
}
|
1998-10-18 15:21:22 +00:00
|
|
|
|
else if( node->pkt->pkttype == PKT_USER_ID )
|
|
|
|
|
uid = node->pkt->pkt.user_id;
|
2000-07-14 17:34:53 +00:00
|
|
|
|
else if( main_pk && node->pkt->pkttype == PKT_SIGNATURE
|
2002-06-29 13:46:34 +00:00
|
|
|
|
&& ( mainkey || sub_pk ) ) {
|
1998-10-18 15:21:22 +00:00
|
|
|
|
PKT_signature *sig = node->pkt->pkt.signature;
|
|
|
|
|
if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
|
* parse-packet.c (parse_signature): No need to reserve 8 bytes for the
unhashed signature cache any longer.
* misc.c (pct_expando): Add two new expandos - signer's fingerprint (%g),
and signer's primary fingerprint (%p).
* Makefile.am: Include W32LIBS where appropriate.
* g10.c (main): Add --rfc2440 alias for --openpgp since in a few months,
they won't be the same thing.
* keyserver.c (parse_keyserver_uri): Accept "http" as an alias for "hkp",
since it is occasionally written that way. (keyserver_spawn): Use
ascii_isspace to avoid locale issues.
* keygen.c (ask_user_id): Make --allow-freeform-uid apply to the email
field as well as the name field, and allow mixing fields when it is set.
* options.skel: Use subkeys.pgp.net as the default keyserver.
* trustdb.c (validate_one_keyblock): Certifications on revoked or expired
uids do not count in the web of trust.
* signal.c (init_one_signal, pause_on_sigusr, do_block): Only use
sigprocmask() if we have sigset_t, and only use sigaction() if we have
struct sigaction. This is for Forte c89 on Solaris which seems to define
only the function call half of the two pairs by default.
(pause_on_sigusr): Typo. (do_block): If we can't use sigprocmask() and
sigset_t, try to get the number of signals from NSIG as well as MAXSIG,
and if we can't, fail with an explanation.
* signal.c, tdbio.c: Comment out the transaction code. It was not used in
this version, and was causing some build problems on quasi-posix platforms
(Solaris and Forte c89).
* keylist.c (list_keyblock_colon): Don't include validity values when
listing secret keys since they can be incorrect and/or misleading. This
is a temporary kludge, and will be handled properly in 1.9/2.0.
* mainproc.c (check_sig_and_print): Only show the "key available from"
preferred keyserver line if the key is not currently present.
* keyedit.c (sign_uids): Do not sign expired uids without --expert (same
behavior as revoked uids). Do not allow signing a user ID without a
self-signature. --expert overrides. Add additional prompt to the
signature level question. (menu_expire): When changing expiration dates,
don't replace selfsigs on revoked uids since this would effectively
unrevoke them. There is also no point in replacing expired selfsigs.
This is bug #181
* g10.c (add_notation_data): Make sure that only ascii is passed to
iscntrl. Noted by Christian Biere.
* getkey.c (classify_user_id2): Replaced isspace by spacep
* keygen.c (ask_user_id): Ditto. (get_parameter_algo): Ditto.
* keyedit.c (keyedit_menu): Ditto.
* tdbdump.c (import_ownertrust): Ditto. s/isxdigit/hexdigitp/.
* revoke.c (ask_revocation_reason):
* keyserver.c (keyserver_spawn): Dito.
2003-07-10 14:30:07 +00:00
|
|
|
|
&& ( (mainkey && uid
|
|
|
|
|
&& uid->created && (sig->sig_class&~3) == 0x10)
|
2004-04-15 00:30:05 +00:00
|
|
|
|
|| (!mainkey && sig->sig_class == 0x18) )
|
|
|
|
|
&& sig->flags.chosen_selfsig )
|
|
|
|
|
{
|
1998-11-20 17:42:18 +00:00
|
|
|
|
/* this is a selfsignature which is to be replaced */
|
1998-10-18 15:21:22 +00:00
|
|
|
|
PKT_signature *newsig;
|
|
|
|
|
PACKET *newpkt;
|
|
|
|
|
KBNODE sn;
|
1998-11-20 17:42:18 +00:00
|
|
|
|
int signumber2 = 0;
|
|
|
|
|
|
|
|
|
|
signumber++;
|
|
|
|
|
|
|
|
|
|
if( (mainkey && main_pk->version < 4)
|
|
|
|
|
|| (!mainkey && sub_pk->version < 4 ) ) {
|
|
|
|
|
log_info(_(
|
|
|
|
|
"You can't change the expiration date of a v3 key\n"));
|
|
|
|
|
free_secret_key( sk );
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
1998-10-18 15:21:22 +00:00
|
|
|
|
|
|
|
|
|
/* find the corresponding secret self-signature */
|
|
|
|
|
for( sn=sec_keyblock; sn; sn = sn->next ) {
|
1998-11-20 17:42:18 +00:00
|
|
|
|
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;
|
|
|
|
|
}
|
1998-10-18 15:21:22 +00:00
|
|
|
|
}
|
|
|
|
|
if( !sn )
|
|
|
|
|
log_info(_("No corresponding signature in secret ring\n"));
|
|
|
|
|
|
|
|
|
|
if( mainkey )
|
2002-12-04 18:50:10 +00:00
|
|
|
|
rc = update_keysig_packet(&newsig, sig, main_pk, uid, NULL,
|
|
|
|
|
sk, keygen_add_key_expire, main_pk);
|
1998-10-18 15:21:22 +00:00
|
|
|
|
else
|
2002-12-04 18:50:10 +00:00
|
|
|
|
rc = update_keysig_packet(&newsig, sig, main_pk, NULL, sub_pk,
|
|
|
|
|
sk, keygen_add_key_expire, sub_pk );
|
1998-10-18 15:21:22 +00:00
|
|
|
|
if( rc ) {
|
|
|
|
|
log_error("make_keysig_packet failed: %s\n",
|
2002-06-29 13:46:34 +00:00
|
|
|
|
g10_errstr(rc));
|
1998-10-18 15:21:22 +00:00
|
|
|
|
free_secret_key( sk );
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
/* replace the packet */
|
2005-07-27 18:10:56 +00:00
|
|
|
|
newpkt = xmalloc_clear( sizeof *newpkt );
|
1998-10-18 15:21:22 +00:00
|
|
|
|
newpkt->pkttype = PKT_SIGNATURE;
|
|
|
|
|
newpkt->pkt.signature = newsig;
|
|
|
|
|
free_packet( node->pkt );
|
2005-07-27 18:10:56 +00:00
|
|
|
|
xfree( node->pkt );
|
1998-10-18 15:21:22 +00:00
|
|
|
|
node->pkt = newpkt;
|
|
|
|
|
if( sn ) {
|
2005-07-27 18:10:56 +00:00
|
|
|
|
newpkt = xmalloc_clear( sizeof *newpkt );
|
1998-10-18 15:21:22 +00:00
|
|
|
|
newpkt->pkttype = PKT_SIGNATURE;
|
|
|
|
|
newpkt->pkt.signature = copy_signature( NULL, newsig );
|
|
|
|
|
free_packet( sn->pkt );
|
2005-07-27 18:10:56 +00:00
|
|
|
|
xfree( sn->pkt );
|
1998-10-18 15:21:22 +00:00
|
|
|
|
sn->pkt = newpkt;
|
|
|
|
|
}
|
2000-07-14 17:34:53 +00:00
|
|
|
|
sub_pk = NULL;
|
1998-10-18 15:21:22 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
free_secret_key( sk );
|
2002-06-29 13:46:34 +00:00
|
|
|
|
update_trust=1;
|
1998-10-18 15:21:22 +00:00
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
2005-10-14 04:07:13 +00:00
|
|
|
|
static int
|
|
|
|
|
menu_backsign(KBNODE pub_keyblock,KBNODE sec_keyblock)
|
|
|
|
|
{
|
|
|
|
|
int rc,modified=0;
|
|
|
|
|
PKT_public_key *main_pk;
|
|
|
|
|
PKT_secret_key *main_sk,*sub_sk=NULL;
|
|
|
|
|
KBNODE node;
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Find a signing subkey with no backsig */
|
|
|
|
|
if(node->pkt->pkttype==PKT_PUBLIC_SUBKEY
|
|
|
|
|
&& (node->pkt->pkt.public_key->pubkey_usage&PUBKEY_USAGE_SIG)
|
|
|
|
|
&& !node->pkt->pkt.public_key->backsig)
|
|
|
|
|
sub_pk=node->pkt->pkt.public_key;
|
|
|
|
|
|
|
|
|
|
if(!sub_pk)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
/* Find the selected selfsig on this subkey */
|
|
|
|
|
for(node2=node->next;
|
|
|
|
|
node2 && node2->pkt->pkttype==PKT_SIGNATURE;
|
|
|
|
|
node2=node2->next)
|
|
|
|
|
if(node2->pkt->pkt.signature->version>=4
|
|
|
|
|
&& node2->pkt->pkt.signature->flags.chosen_selfsig)
|
|
|
|
|
{
|
|
|
|
|
sig_pk=node2;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(!sig_pk)
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(!sub_sk)
|
|
|
|
|
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_SIGNATURE;
|
|
|
|
|
node2=node2->next)
|
|
|
|
|
if(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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(!sig_sk)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
/* Now we can get to work. We have a main key and secret part,
|
|
|
|
|
a signing subkey with signature and secret part 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);
|
|
|
|
|
if(rc==0)
|
|
|
|
|
{
|
|
|
|
|
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)
|
|
|
|
|
{
|
|
|
|
|
/* Put the new sig into place on the pubkey */
|
|
|
|
|
newpkt=xmalloc_clear(sizeof(*newpkt));
|
|
|
|
|
newpkt->pkttype=PKT_SIGNATURE;
|
|
|
|
|
newpkt->pkt.signature=newsig;
|
|
|
|
|
free_packet(sig_pk->pkt);
|
|
|
|
|
xfree(sig_pk->pkt);
|
|
|
|
|
sig_pk->pkt=newpkt;
|
|
|
|
|
|
|
|
|
|
/* 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
|
|
|
|
|
{
|
|
|
|
|
log_error("update_keysig_packet failed: %s\n",g10_errstr(rc));
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
log_error("make_backsig failed: %s\n",g10_errstr(rc));
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
set_next_passphrase(NULL);
|
|
|
|
|
|
|
|
|
|
free_secret_key(main_sk);
|
|
|
|
|
if(sub_sk)
|
|
|
|
|
free_secret_key(sub_sk);
|
|
|
|
|
|
|
|
|
|
return modified;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2002-06-29 13:46:34 +00:00
|
|
|
|
static int
|
|
|
|
|
change_primary_uid_cb ( PKT_signature *sig, void *opaque )
|
|
|
|
|
{
|
|
|
|
|
byte buf[1];
|
|
|
|
|
|
|
|
|
|
/* first clear all primary uid flags so that we are sure none are
|
|
|
|
|
* lingering around */
|
|
|
|
|
delete_sig_subpkt (sig->hashed, SIGSUBPKT_PRIMARY_UID);
|
|
|
|
|
delete_sig_subpkt (sig->unhashed, SIGSUBPKT_PRIMARY_UID);
|
|
|
|
|
|
|
|
|
|
/* if opaque is set,we want to set the primary id */
|
|
|
|
|
if (opaque) {
|
|
|
|
|
buf[0] = 1;
|
|
|
|
|
build_sig_subpkt (sig, SIGSUBPKT_PRIMARY_UID, buf, 1 );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Set the primary uid flag for the selected UID. We will also reset
|
|
|
|
|
* all other primary uid flags. For this to work with have to update
|
|
|
|
|
* all the signature timestamps. If we would do this with the current
|
|
|
|
|
* time, we lose quite a lot of information, so we use a a kludge to
|
|
|
|
|
* do this: Just increment the timestamp by one second which is
|
|
|
|
|
* sufficient to updated a signature during import.
|
|
|
|
|
*/
|
|
|
|
|
static int
|
|
|
|
|
menu_set_primary_uid ( KBNODE pub_keyblock, KBNODE sec_keyblock )
|
|
|
|
|
{
|
|
|
|
|
PKT_secret_key *sk; /* copy of the main sk */
|
|
|
|
|
PKT_public_key *main_pk;
|
|
|
|
|
PKT_user_id *uid;
|
|
|
|
|
KBNODE node;
|
|
|
|
|
u32 keyid[2];
|
|
|
|
|
int selected;
|
|
|
|
|
int attribute = 0;
|
|
|
|
|
int modified = 0;
|
|
|
|
|
|
|
|
|
|
if ( count_selected_uids (pub_keyblock) != 1 ) {
|
|
|
|
|
tty_printf(_("Please select exactly one user ID.\n"));
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
|
|
/* Is our selected uid an attribute packet? */
|
|
|
|
|
for ( node=pub_keyblock; node; node = node->next )
|
|
|
|
|
if (node->pkt->pkttype == PKT_USER_ID && node->flag & NODFLG_SELUID)
|
|
|
|
|
attribute = (node->pkt->pkt.user_id->attrib_data!=NULL);
|
|
|
|
|
|
|
|
|
|
for ( node=pub_keyblock; node; node = node->next ) {
|
|
|
|
|
if ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
|
|
|
|
|
break; /* ready */
|
|
|
|
|
|
|
|
|
|
if ( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
|
|
|
|
|
main_pk = node->pkt->pkt.public_key;
|
|
|
|
|
keyid_from_pk( main_pk, keyid );
|
|
|
|
|
}
|
|
|
|
|
else if ( node->pkt->pkttype == PKT_USER_ID ) {
|
|
|
|
|
uid = node->pkt->pkt.user_id;
|
|
|
|
|
selected = node->flag & NODFLG_SELUID;
|
|
|
|
|
}
|
|
|
|
|
else if ( main_pk && uid && node->pkt->pkttype == PKT_SIGNATURE ) {
|
|
|
|
|
PKT_signature *sig = node->pkt->pkt.signature;
|
|
|
|
|
if ( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
|
2004-04-15 00:30:05 +00:00
|
|
|
|
&& (uid && (sig->sig_class&~3) == 0x10)
|
|
|
|
|
&& attribute == (uid->attrib_data!=NULL)
|
|
|
|
|
&& sig->flags.chosen_selfsig )
|
|
|
|
|
{
|
2002-06-29 13:46:34 +00:00
|
|
|
|
if(sig->version < 4) {
|
|
|
|
|
char *user=utf8_to_native(uid->name,strlen(uid->name),0);
|
|
|
|
|
|
2004-09-22 03:16:41 +00:00
|
|
|
|
log_info(_("skipping v3 self-signature on user ID \"%s\"\n"),
|
2002-06-29 13:46:34 +00:00
|
|
|
|
user);
|
2005-07-27 18:10:56 +00:00
|
|
|
|
xfree(user);
|
2002-06-29 13:46:34 +00:00
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* This is a selfsignature which is to be replaced.
|
|
|
|
|
We can just ignore v3 signatures because they are
|
|
|
|
|
not able to carry the primary ID flag. We also
|
|
|
|
|
ignore self-sigs on user IDs that are not of the
|
|
|
|
|
same type that we are making primary. That is, if
|
|
|
|
|
we are making a user ID primary, we alter user IDs.
|
|
|
|
|
If we are making an attribute packet primary, we
|
|
|
|
|
alter attribute packets. */
|
|
|
|
|
|
|
|
|
|
/* FIXME: We must make sure that we only have one
|
|
|
|
|
self-signature per user ID here (not counting
|
|
|
|
|
revocations) */
|
|
|
|
|
PKT_signature *newsig;
|
|
|
|
|
PACKET *newpkt;
|
|
|
|
|
const byte *p;
|
|
|
|
|
int action;
|
|
|
|
|
|
|
|
|
|
/* see whether this signature has the primary UID flag */
|
|
|
|
|
p = parse_sig_subpkt (sig->hashed,
|
|
|
|
|
SIGSUBPKT_PRIMARY_UID, NULL );
|
|
|
|
|
if ( !p )
|
|
|
|
|
p = parse_sig_subpkt (sig->unhashed,
|
|
|
|
|
SIGSUBPKT_PRIMARY_UID, NULL );
|
|
|
|
|
if ( p && *p ) /* yes */
|
|
|
|
|
action = selected? 0 : -1;
|
|
|
|
|
else /* no */
|
|
|
|
|
action = selected? 1 : 0;
|
|
|
|
|
|
|
|
|
|
if (action) {
|
|
|
|
|
int rc = update_keysig_packet (&newsig, sig,
|
2002-12-04 18:50:10 +00:00
|
|
|
|
main_pk, uid, NULL,
|
2002-06-29 13:46:34 +00:00
|
|
|
|
sk,
|
|
|
|
|
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 */
|
2005-07-27 18:10:56 +00:00
|
|
|
|
newpkt = xmalloc_clear( sizeof *newpkt );
|
2002-06-29 13:46:34 +00:00
|
|
|
|
newpkt->pkttype = PKT_SIGNATURE;
|
|
|
|
|
newpkt->pkt.signature = newsig;
|
|
|
|
|
free_packet( node->pkt );
|
2005-07-27 18:10:56 +00:00
|
|
|
|
xfree( node->pkt );
|
2002-06-29 13:46:34 +00:00
|
|
|
|
node->pkt = newpkt;
|
|
|
|
|
modified = 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
free_secret_key( sk );
|
|
|
|
|
return modified;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Set preferences to new values for the selected user IDs
|
|
|
|
|
*/
|
|
|
|
|
static int
|
|
|
|
|
menu_set_preferences (KBNODE pub_keyblock, KBNODE sec_keyblock )
|
|
|
|
|
{
|
|
|
|
|
PKT_secret_key *sk; /* copy of the main sk */
|
|
|
|
|
PKT_public_key *main_pk;
|
|
|
|
|
PKT_user_id *uid;
|
|
|
|
|
KBNODE node;
|
|
|
|
|
u32 keyid[2];
|
|
|
|
|
int selected, select_all;
|
|
|
|
|
int modified = 0;
|
|
|
|
|
|
2004-04-16 16:31:19 +00:00
|
|
|
|
no_primary_warning(pub_keyblock);
|
2003-05-31 04:06:06 +00:00
|
|
|
|
|
2002-06-29 13:46:34 +00:00
|
|
|
|
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;
|
|
|
|
|
selected = 0;
|
|
|
|
|
for ( node=pub_keyblock; node; node = node->next ) {
|
|
|
|
|
if ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
|
|
|
|
|
break; /* ready */
|
|
|
|
|
|
|
|
|
|
if ( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
|
|
|
|
|
main_pk = node->pkt->pkt.public_key;
|
|
|
|
|
keyid_from_pk( main_pk, keyid );
|
|
|
|
|
}
|
|
|
|
|
else if ( node->pkt->pkttype == PKT_USER_ID ) {
|
|
|
|
|
uid = node->pkt->pkt.user_id;
|
|
|
|
|
selected = select_all || (node->flag & NODFLG_SELUID);
|
|
|
|
|
}
|
|
|
|
|
else if ( main_pk && uid && selected
|
|
|
|
|
&& node->pkt->pkttype == PKT_SIGNATURE ) {
|
|
|
|
|
PKT_signature *sig = node->pkt->pkt.signature;
|
|
|
|
|
if ( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
|
2004-04-15 00:30:05 +00:00
|
|
|
|
&& (uid && (sig->sig_class&~3) == 0x10)
|
|
|
|
|
&& sig->flags.chosen_selfsig ) {
|
2002-06-29 13:46:34 +00:00
|
|
|
|
if( sig->version < 4 ) {
|
|
|
|
|
char *user=utf8_to_native(uid->name,strlen(uid->name),0);
|
|
|
|
|
|
2004-09-22 03:16:41 +00:00
|
|
|
|
log_info(_("skipping v3 self-signature on user ID \"%s\"\n"),
|
2002-06-29 13:46:34 +00:00
|
|
|
|
user);
|
2005-07-27 18:10:56 +00:00
|
|
|
|
xfree(user);
|
2002-06-29 13:46:34 +00:00
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* This is a selfsignature which is to be replaced
|
|
|
|
|
* We have to ignore v3 signatures because they are
|
|
|
|
|
* not able to carry the preferences */
|
|
|
|
|
PKT_signature *newsig;
|
|
|
|
|
PACKET *newpkt;
|
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
|
|
rc = update_keysig_packet (&newsig, sig,
|
2002-12-04 18:50:10 +00:00
|
|
|
|
main_pk, uid, NULL,
|
2002-06-29 13:46:34 +00:00
|
|
|
|
sk,
|
|
|
|
|
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 */
|
2005-07-27 18:10:56 +00:00
|
|
|
|
newpkt = xmalloc_clear( sizeof *newpkt );
|
2002-06-29 13:46:34 +00:00
|
|
|
|
newpkt->pkttype = PKT_SIGNATURE;
|
|
|
|
|
newpkt->pkt.signature = newsig;
|
|
|
|
|
free_packet( node->pkt );
|
2005-07-27 18:10:56 +00:00
|
|
|
|
xfree( node->pkt );
|
2002-06-29 13:46:34 +00:00
|
|
|
|
node->pkt = newpkt;
|
|
|
|
|
modified = 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
free_secret_key( sk );
|
|
|
|
|
return modified;
|
|
|
|
|
}
|
|
|
|
|
|
1998-10-18 15:21:22 +00:00
|
|
|
|
|
2003-08-31 03:45:41 +00:00
|
|
|
|
static int
|
2004-05-08 13:51:14 +00:00
|
|
|
|
menu_set_keyserver_url (const char *url,
|
|
|
|
|
KBNODE pub_keyblock, KBNODE sec_keyblock )
|
2003-08-31 03:45:41 +00:00
|
|
|
|
{
|
2004-05-08 13:51:14 +00:00
|
|
|
|
PKT_secret_key *sk; /* copy of the main sk */
|
|
|
|
|
PKT_public_key *main_pk;
|
|
|
|
|
PKT_user_id *uid;
|
|
|
|
|
KBNODE node;
|
|
|
|
|
u32 keyid[2];
|
|
|
|
|
int selected, select_all;
|
|
|
|
|
int modified = 0;
|
2004-09-16 20:07:42 +00:00
|
|
|
|
char *answer,*uri;
|
2003-08-31 03:45:41 +00:00
|
|
|
|
|
2004-05-08 13:51:14 +00:00
|
|
|
|
no_primary_warning(pub_keyblock);
|
2003-08-31 03:45:41 +00:00
|
|
|
|
|
2004-05-08 13:51:14 +00:00
|
|
|
|
if(url)
|
2005-07-27 18:10:56 +00:00
|
|
|
|
answer=xstrdup(url);
|
2004-05-08 13:51:14 +00:00
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
answer=cpr_get_utf8("keyedit.add_keyserver",
|
|
|
|
|
_("Enter your preferred keyserver URL: "));
|
|
|
|
|
if(answer[0]=='\0' || answer[0]=='\004')
|
|
|
|
|
{
|
2005-07-27 18:10:56 +00:00
|
|
|
|
xfree(answer);
|
2004-05-08 13:51:14 +00:00
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
2003-08-31 03:45:41 +00:00
|
|
|
|
|
2004-09-16 20:07:42 +00:00
|
|
|
|
if(ascii_strcasecmp(answer,"none")==0)
|
|
|
|
|
uri=NULL;
|
|
|
|
|
else
|
2004-05-08 13:51:14 +00:00
|
|
|
|
{
|
2004-09-16 20:07:42 +00:00
|
|
|
|
struct keyserver_spec *keyserver=NULL;
|
|
|
|
|
/* Sanity check the format */
|
|
|
|
|
keyserver=parse_keyserver_uri(answer,1,NULL,0);
|
2005-07-27 18:10:56 +00:00
|
|
|
|
xfree(answer);
|
2004-09-16 20:07:42 +00:00
|
|
|
|
if(!keyserver)
|
|
|
|
|
{
|
|
|
|
|
log_info(_("could not parse keyserver URL\n"));
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2005-07-27 18:10:56 +00:00
|
|
|
|
uri=xstrdup(keyserver->uri);
|
2004-09-16 20:07:42 +00:00
|
|
|
|
free_keyserver_spec(keyserver);
|
2004-05-08 13:51:14 +00:00
|
|
|
|
}
|
2003-08-31 03:45:41 +00:00
|
|
|
|
|
2004-05-08 13:51:14 +00:00
|
|
|
|
select_all = !count_selected_uids (pub_keyblock);
|
2003-08-31 03:45:41 +00:00
|
|
|
|
|
2004-05-08 13:51:14 +00:00
|
|
|
|
node = find_kbnode( sec_keyblock, PKT_SECRET_KEY );
|
|
|
|
|
sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
|
2003-08-31 03:45:41 +00:00
|
|
|
|
|
2004-05-08 13:51:14 +00:00
|
|
|
|
/* Now we can actually change the self signature(s) */
|
|
|
|
|
main_pk = NULL;
|
|
|
|
|
uid = NULL;
|
|
|
|
|
selected = 0;
|
|
|
|
|
for ( node=pub_keyblock; node; node = node->next )
|
|
|
|
|
{
|
|
|
|
|
if ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
|
|
|
|
|
break; /* ready */
|
2003-08-31 03:45:41 +00:00
|
|
|
|
|
2004-05-08 13:51:14 +00:00
|
|
|
|
if ( node->pkt->pkttype == PKT_PUBLIC_KEY )
|
|
|
|
|
{
|
|
|
|
|
main_pk = node->pkt->pkt.public_key;
|
|
|
|
|
keyid_from_pk( main_pk, keyid );
|
|
|
|
|
}
|
|
|
|
|
else if ( node->pkt->pkttype == PKT_USER_ID )
|
|
|
|
|
{
|
|
|
|
|
uid = node->pkt->pkt.user_id;
|
|
|
|
|
selected = select_all || (node->flag & NODFLG_SELUID);
|
|
|
|
|
}
|
|
|
|
|
else if ( main_pk && uid && selected
|
|
|
|
|
&& node->pkt->pkttype == PKT_SIGNATURE )
|
|
|
|
|
{
|
|
|
|
|
PKT_signature *sig = node->pkt->pkt.signature;
|
|
|
|
|
if ( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
|
2004-12-21 15:49:56 +00:00
|
|
|
|
&& (uid && (sig->sig_class&~3) == 0x10)
|
|
|
|
|
&& sig->flags.chosen_selfsig)
|
2004-05-08 13:51:14 +00:00
|
|
|
|
{
|
2004-09-16 19:53:06 +00:00
|
|
|
|
char *user=utf8_to_native(uid->name,strlen(uid->name),0);
|
2004-05-08 13:51:14 +00:00
|
|
|
|
if( sig->version < 4 )
|
2004-09-22 03:16:41 +00:00
|
|
|
|
log_info(_("skipping v3 self-signature on user ID \"%s\"\n"),
|
2004-09-16 19:53:06 +00:00
|
|
|
|
user);
|
2004-05-08 13:51:14 +00:00
|
|
|
|
else
|
|
|
|
|
{
|
2004-09-16 19:53:06 +00:00
|
|
|
|
/* This is a selfsignature which is to be replaced
|
2004-05-08 13:51:14 +00:00
|
|
|
|
* We have to ignore v3 signatures because they are
|
2004-09-16 19:53:06 +00:00
|
|
|
|
* not able to carry the subpacket. */
|
2004-05-08 13:51:14 +00:00
|
|
|
|
PKT_signature *newsig;
|
|
|
|
|
PACKET *newpkt;
|
|
|
|
|
int rc;
|
2004-09-16 19:53:06 +00:00
|
|
|
|
const byte *p;
|
|
|
|
|
size_t plen;
|
|
|
|
|
|
|
|
|
|
p=parse_sig_subpkt(sig->hashed,SIGSUBPKT_PREF_KS,&plen);
|
|
|
|
|
if(p && plen)
|
|
|
|
|
{
|
|
|
|
|
tty_printf("Current preferred keyserver for user"
|
2004-09-22 03:16:41 +00:00
|
|
|
|
" ID \"%s\": ",user);
|
|
|
|
|
tty_print_utf8_string(p,plen);
|
|
|
|
|
tty_printf("\n");
|
2004-09-16 19:53:06 +00:00
|
|
|
|
if(!cpr_get_answer_is_yes("keyedit.confirm_keyserver",
|
2004-09-16 20:07:42 +00:00
|
|
|
|
uri?_("Are you sure you want to replace it? (y/N) "):
|
|
|
|
|
_("Are you sure you want to delete it? (y/N) ")))
|
2004-09-16 19:53:06 +00:00
|
|
|
|
continue;
|
|
|
|
|
}
|
2004-09-16 20:07:42 +00:00
|
|
|
|
else if(uri==NULL)
|
|
|
|
|
{
|
|
|
|
|
/* There is no current keyserver URL, so there
|
|
|
|
|
is no point in trying to un-set it. */
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2004-05-08 13:51:14 +00:00
|
|
|
|
|
|
|
|
|
rc = update_keysig_packet (&newsig, sig,
|
|
|
|
|
main_pk, uid, NULL,
|
|
|
|
|
sk,
|
2004-09-16 20:07:42 +00:00
|
|
|
|
keygen_add_keyserver_url, uri );
|
2004-05-08 13:51:14 +00:00
|
|
|
|
if( rc )
|
|
|
|
|
{
|
|
|
|
|
log_error ("update_keysig_packet failed: %s\n",
|
|
|
|
|
g10_errstr(rc));
|
|
|
|
|
free_secret_key( sk );
|
2005-07-27 18:10:56 +00:00
|
|
|
|
xfree(uri);
|
2004-05-08 13:51:14 +00:00
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
/* replace the packet */
|
2005-07-27 18:10:56 +00:00
|
|
|
|
newpkt = xmalloc_clear( sizeof *newpkt );
|
2004-05-08 13:51:14 +00:00
|
|
|
|
newpkt->pkttype = PKT_SIGNATURE;
|
|
|
|
|
newpkt->pkt.signature = newsig;
|
|
|
|
|
free_packet( node->pkt );
|
2005-07-27 18:10:56 +00:00
|
|
|
|
xfree( node->pkt );
|
2004-05-08 13:51:14 +00:00
|
|
|
|
node->pkt = newpkt;
|
|
|
|
|
modified = 1;
|
|
|
|
|
}
|
2004-09-16 19:53:06 +00:00
|
|
|
|
|
2005-07-27 18:10:56 +00:00
|
|
|
|
xfree(user);
|
2004-05-08 13:51:14 +00:00
|
|
|
|
}
|
2003-08-31 03:45:41 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2005-07-27 18:10:56 +00:00
|
|
|
|
xfree(uri);
|
2004-05-08 13:51:14 +00:00
|
|
|
|
free_secret_key( sk );
|
|
|
|
|
return modified;
|
2003-08-31 03:45:41 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
1998-07-29 19:35:05 +00:00
|
|
|
|
/****************
|
|
|
|
|
* Select one user id or remove all selection if index is 0.
|
|
|
|
|
* Returns: True if the selection changed;
|
|
|
|
|
*/
|
|
|
|
|
static int
|
1999-02-16 13:16:33 +00:00
|
|
|
|
menu_select_uid( KBNODE keyblock, int idx )
|
1998-07-29 19:35:05 +00:00
|
|
|
|
{
|
|
|
|
|
KBNODE node;
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
/* first check that the index is valid */
|
1999-02-16 13:16:33 +00:00
|
|
|
|
if( idx ) {
|
1998-07-29 19:35:05 +00:00
|
|
|
|
for( i=0, node = keyblock; node; node = node->next ) {
|
|
|
|
|
if( node->pkt->pkttype == PKT_USER_ID ) {
|
1999-02-16 13:16:33 +00:00
|
|
|
|
if( ++i == idx )
|
1998-07-29 19:35:05 +00:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if( !node ) {
|
1999-09-01 13:40:07 +00:00
|
|
|
|
tty_printf(_("No user ID with index %d\n"), idx );
|
1998-07-29 19:35:05 +00:00
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else { /* reset all */
|
|
|
|
|
for( i=0, node = keyblock; node; node = node->next ) {
|
|
|
|
|
if( node->pkt->pkttype == PKT_USER_ID )
|
|
|
|
|
node->flag &= ~NODFLG_SELUID;
|
|
|
|
|
}
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
/* and toggle the new index */
|
|
|
|
|
for( i=0, node = keyblock; node; node = node->next ) {
|
|
|
|
|
if( node->pkt->pkttype == PKT_USER_ID ) {
|
1999-02-28 18:14:18 +00:00
|
|
|
|
if( ++i == idx ) {
|
1998-07-29 19:35:05 +00:00
|
|
|
|
if( (node->flag & NODFLG_SELUID) )
|
|
|
|
|
node->flag &= ~NODFLG_SELUID;
|
|
|
|
|
else
|
|
|
|
|
node->flag |= NODFLG_SELUID;
|
1999-02-28 18:14:18 +00:00
|
|
|
|
}
|
1998-07-29 19:35:05 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
2005-04-24 16:05:41 +00:00
|
|
|
|
/* Search in the keyblock for a uid that matches namehash */
|
|
|
|
|
static int
|
|
|
|
|
menu_select_uid_namehash( KBNODE keyblock, const char *namehash )
|
|
|
|
|
{
|
|
|
|
|
byte hash[NAMEHASH_LEN];
|
|
|
|
|
KBNODE node;
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
assert(strlen(namehash)==NAMEHASH_LEN*2);
|
|
|
|
|
|
|
|
|
|
for(i=0;i<NAMEHASH_LEN;i++)
|
|
|
|
|
hash[i]=hextobyte(&namehash[i*2]);
|
|
|
|
|
|
|
|
|
|
for(node=keyblock->next;node;node=node->next)
|
|
|
|
|
{
|
|
|
|
|
if(node->pkt->pkttype==PKT_USER_ID)
|
|
|
|
|
{
|
|
|
|
|
namehash_from_uid(node->pkt->pkt.user_id);
|
|
|
|
|
if(memcmp(node->pkt->pkt.user_id->namehash,hash,NAMEHASH_LEN)==0)
|
|
|
|
|
{
|
|
|
|
|
if(node->flag&NODFLG_SELUID)
|
|
|
|
|
node->flag &= ~NODFLG_SELUID;
|
|
|
|
|
else
|
|
|
|
|
node->flag |= NODFLG_SELUID;
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(!node)
|
|
|
|
|
{
|
|
|
|
|
tty_printf(_("No user ID with hash %s\n"),namehash);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
1998-07-29 19:35:05 +00:00
|
|
|
|
/****************
|
|
|
|
|
* Select secondary keys
|
|
|
|
|
* Returns: True if the selection changed;
|
|
|
|
|
*/
|
|
|
|
|
static int
|
1999-02-16 13:16:33 +00:00
|
|
|
|
menu_select_key( KBNODE keyblock, int idx )
|
1998-07-29 19:35:05 +00:00
|
|
|
|
{
|
|
|
|
|
KBNODE node;
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
/* first check that the index is valid */
|
1999-02-16 13:16:33 +00:00
|
|
|
|
if( idx ) {
|
1998-07-29 19:35:05 +00:00
|
|
|
|
for( i=0, node = keyblock; node; node = node->next ) {
|
|
|
|
|
if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
|
|
|
|
|
|| node->pkt->pkttype == PKT_SECRET_SUBKEY ) {
|
1999-02-16 13:16:33 +00:00
|
|
|
|
if( ++i == idx )
|
1998-07-29 19:35:05 +00:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if( !node ) {
|
2004-12-20 05:19:09 +00:00
|
|
|
|
tty_printf(_("No subkey with index %d\n"), idx );
|
1998-07-29 19:35:05 +00:00
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else { /* reset all */
|
|
|
|
|
for( i=0, node = keyblock; node; node = node->next ) {
|
|
|
|
|
if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
|
|
|
|
|
|| node->pkt->pkttype == PKT_SECRET_SUBKEY )
|
|
|
|
|
node->flag &= ~NODFLG_SELKEY;
|
|
|
|
|
}
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
/* and set the new index */
|
|
|
|
|
for( i=0, node = keyblock; node; node = node->next ) {
|
|
|
|
|
if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
|
|
|
|
|
|| node->pkt->pkttype == PKT_SECRET_SUBKEY ) {
|
1999-02-28 18:14:18 +00:00
|
|
|
|
if( ++i == idx ) {
|
1998-07-29 19:35:05 +00:00
|
|
|
|
if( (node->flag & NODFLG_SELKEY) )
|
|
|
|
|
node->flag &= ~NODFLG_SELKEY;
|
|
|
|
|
else
|
|
|
|
|
node->flag |= NODFLG_SELKEY;
|
1999-02-28 18:14:18 +00:00
|
|
|
|
}
|
1998-07-29 19:35:05 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
count_uids_with_flag( KBNODE keyblock, unsigned flag )
|
|
|
|
|
{
|
|
|
|
|
KBNODE node;
|
|
|
|
|
int i=0;
|
|
|
|
|
|
|
|
|
|
for( node = keyblock; node; node = node->next )
|
|
|
|
|
if( node->pkt->pkttype == PKT_USER_ID && (node->flag & flag) )
|
|
|
|
|
i++;
|
|
|
|
|
return i;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
count_keys_with_flag( KBNODE keyblock, unsigned flag )
|
|
|
|
|
{
|
|
|
|
|
KBNODE node;
|
|
|
|
|
int i=0;
|
|
|
|
|
|
|
|
|
|
for( node = keyblock; node; node = node->next )
|
|
|
|
|
if( ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
|
|
|
|
|
|| node->pkt->pkttype == PKT_SECRET_SUBKEY)
|
|
|
|
|
&& (node->flag & flag) )
|
|
|
|
|
i++;
|
|
|
|
|
return i;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
count_uids( KBNODE keyblock )
|
|
|
|
|
{
|
|
|
|
|
KBNODE node;
|
|
|
|
|
int i=0;
|
|
|
|
|
|
|
|
|
|
for( node = keyblock; node; node = node->next )
|
|
|
|
|
if( node->pkt->pkttype == PKT_USER_ID )
|
|
|
|
|
i++;
|
|
|
|
|
return i;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/****************
|
|
|
|
|
* Returns true if there is at least one selected user id
|
|
|
|
|
*/
|
|
|
|
|
static int
|
|
|
|
|
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);
|
1998-04-20 15:52:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-06-29 13:46:34 +00:00
|
|
|
|
/* returns how many real (i.e. not attribute) uids are unmarked */
|
|
|
|
|
static int
|
|
|
|
|
real_uids_left( KBNODE keyblock )
|
|
|
|
|
{
|
|
|
|
|
KBNODE node;
|
|
|
|
|
int real=0;
|
|
|
|
|
|
|
|
|
|
for(node=keyblock;node;node=node->next)
|
|
|
|
|
if(node->pkt->pkttype==PKT_USER_ID && !(node->flag&NODFLG_SELUID) &&
|
|
|
|
|
!node->pkt->pkt.user_id->attrib_data)
|
|
|
|
|
real++;
|
|
|
|
|
|
|
|
|
|
return real;
|
|
|
|
|
}
|
|
|
|
|
|
1999-04-26 15:53:01 +00:00
|
|
|
|
/*
|
|
|
|
|
* 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.
|
|
|
|
|
*/
|
|
|
|
|
static void
|
|
|
|
|
ask_revoke_sig( KBNODE keyblock, KBNODE node )
|
|
|
|
|
{
|
2002-06-29 13:46:34 +00:00
|
|
|
|
int doit=0;
|
2005-08-27 02:56:51 +00:00
|
|
|
|
PKT_user_id *uid;
|
1999-04-26 15:53:01 +00:00
|
|
|
|
PKT_signature *sig = node->pkt->pkt.signature;
|
|
|
|
|
KBNODE unode = find_prev_kbnode( keyblock, node, PKT_USER_ID );
|
|
|
|
|
|
|
|
|
|
if( !unode ) {
|
|
|
|
|
log_error("Oops: no user ID for signature\n");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2005-08-27 02:56:51 +00:00
|
|
|
|
uid=unode->pkt->pkt.user_id;
|
|
|
|
|
|
|
|
|
|
if(opt.with_colons)
|
|
|
|
|
{
|
|
|
|
|
if(uid->attrib_data)
|
|
|
|
|
printf("uat:::::::::%u %lu",uid->numattribs,uid->attrib_len);
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
printf("uid:::::::::");
|
|
|
|
|
print_string (stdout, uid->name, uid->len, ':');
|
|
|
|
|
}
|
1999-04-26 15:53:01 +00:00
|
|
|
|
|
2005-08-27 02:56:51 +00:00
|
|
|
|
printf("\n");
|
2002-06-29 13:46:34 +00:00
|
|
|
|
|
2005-08-27 02:56:51 +00:00
|
|
|
|
print_and_check_one_sig_colon(keyblock,node,NULL,NULL,NULL,NULL,1);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
char *p=utf8_to_native(unode->pkt->pkt.user_id->name,
|
|
|
|
|
unode->pkt->pkt.user_id->len,0);
|
|
|
|
|
tty_printf(_("user ID: \"%s\"\n"),p);
|
|
|
|
|
xfree(p);
|
|
|
|
|
|
|
|
|
|
tty_printf(_("signed by your key %s on %s%s%s\n"),
|
|
|
|
|
keystr(sig->keyid),datestr_from_sig(sig),
|
|
|
|
|
sig->flags.exportable?"":_(" (non-exportable)"),"");
|
|
|
|
|
}
|
2002-06-29 13:46:34 +00:00
|
|
|
|
if(sig->flags.expired)
|
|
|
|
|
{
|
|
|
|
|
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) "));
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
doit=cpr_get_answer_is_yes("ask_revoke_sig.one",
|
|
|
|
|
_("Create a revocation certificate for this signature? (y/N) "));
|
|
|
|
|
|
|
|
|
|
if(doit) {
|
|
|
|
|
node->flag |= NODFLG_MARK_A;
|
|
|
|
|
unode->flag |= NODFLG_MARK_A;
|
1999-04-26 15:53:01 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/****************
|
|
|
|
|
* 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.
|
|
|
|
|
* Return: True when the keyblock has changed.
|
|
|
|
|
*/
|
|
|
|
|
static int
|
|
|
|
|
menu_revsig( KBNODE keyblock )
|
|
|
|
|
{
|
|
|
|
|
PKT_signature *sig;
|
|
|
|
|
PKT_public_key *primary_pk;
|
|
|
|
|
KBNODE node;
|
|
|
|
|
int changed = 0;
|
2002-07-25 22:59:25 +00:00
|
|
|
|
int rc, any, skip=1, all=!count_selected_uids(keyblock);
|
2000-07-14 17:34:53 +00:00
|
|
|
|
struct revocation_reason_info *reason = NULL;
|
1999-04-26 15:53:01 +00:00
|
|
|
|
|
2004-10-06 20:40:07 +00:00
|
|
|
|
assert(keyblock->pkt->pkttype==PKT_PUBLIC_KEY);
|
|
|
|
|
|
1999-04-26 15:53:01 +00:00
|
|
|
|
/* FIXME: detect duplicates here */
|
2004-10-06 20:40:07 +00:00
|
|
|
|
tty_printf(_("You have signed these user IDs on key %s:\n"),
|
|
|
|
|
keystr_from_pk(keyblock->pkt->pkt.public_key));
|
1999-04-26 15:53:01 +00:00
|
|
|
|
for( node = keyblock; node; node = node->next ) {
|
|
|
|
|
node->flag &= ~(NODFLG_SELSIG | NODFLG_MARK_A);
|
|
|
|
|
if( node->pkt->pkttype == PKT_USER_ID ) {
|
2002-07-25 22:59:25 +00:00
|
|
|
|
if( node->flag&NODFLG_SELUID || all ) {
|
|
|
|
|
PKT_user_id *uid = node->pkt->pkt.user_id;
|
|
|
|
|
/* Hmmm: Should we show only UIDs with a signature? */
|
|
|
|
|
tty_printf(" ");
|
|
|
|
|
tty_print_utf8_string( uid->name, uid->len );
|
|
|
|
|
tty_printf("\n");
|
|
|
|
|
skip=0;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
skip=1;
|
1999-04-26 15:53:01 +00:00
|
|
|
|
}
|
2002-07-25 22:59:25 +00:00
|
|
|
|
else if( !skip && node->pkt->pkttype == PKT_SIGNATURE
|
1999-04-26 15:53:01 +00:00
|
|
|
|
&& ((sig = node->pkt->pkt.signature),
|
2004-03-24 17:34:57 +00:00
|
|
|
|
!seckey_available(sig->keyid) ) )
|
|
|
|
|
{
|
|
|
|
|
if( (sig->sig_class&~3) == 0x10 )
|
|
|
|
|
{
|
2004-10-06 20:40:07 +00:00
|
|
|
|
tty_printf(" ");
|
|
|
|
|
tty_printf(_("signed by your key %s on %s%s%s\n"),
|
2004-03-24 17:34:57 +00:00
|
|
|
|
keystr(sig->keyid), datestr_from_sig(sig),
|
2004-10-06 20:40:07 +00:00
|
|
|
|
sig->flags.exportable?"":_(" (non-exportable)"),
|
|
|
|
|
sig->flags.revocable?"":_(" (non-revocable)"));
|
2002-06-29 13:46:34 +00:00
|
|
|
|
if(sig->flags.revocable)
|
|
|
|
|
node->flag |= NODFLG_SELSIG;
|
2004-03-24 17:34:57 +00:00
|
|
|
|
}
|
|
|
|
|
else if( sig->sig_class == 0x30 )
|
|
|
|
|
{
|
2004-10-06 20:40:07 +00:00
|
|
|
|
tty_printf(" ");
|
|
|
|
|
tty_printf(_("revoked by your key %s on %s\n"),
|
|
|
|
|
keystr(sig->keyid),datestr_from_sig(sig));
|
2004-03-24 17:34:57 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
1999-04-26 15:53:01 +00:00
|
|
|
|
}
|
|
|
|
|
|
2004-10-06 20:40:07 +00:00
|
|
|
|
tty_printf("\n");
|
|
|
|
|
|
1999-04-26 15:53:01 +00:00
|
|
|
|
/* ask */
|
|
|
|
|
for( node = keyblock; node; node = node->next ) {
|
|
|
|
|
if( !(node->flag & NODFLG_SELSIG) )
|
|
|
|
|
continue;
|
|
|
|
|
ask_revoke_sig( keyblock, node );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* present selected */
|
|
|
|
|
any = 0;
|
|
|
|
|
for( node = keyblock; node; node = node->next ) {
|
|
|
|
|
if( !(node->flag & NODFLG_MARK_A) )
|
|
|
|
|
continue;
|
|
|
|
|
if( !any ) {
|
|
|
|
|
any = 1;
|
1999-09-06 18:10:27 +00:00
|
|
|
|
tty_printf(_("You are about to revoke these signatures:\n"));
|
1999-04-26 15:53:01 +00:00
|
|
|
|
}
|
|
|
|
|
if( node->pkt->pkttype == PKT_USER_ID ) {
|
|
|
|
|
PKT_user_id *uid = node->pkt->pkt.user_id;
|
|
|
|
|
tty_printf(" ");
|
1999-08-31 15:30:12 +00:00
|
|
|
|
tty_print_utf8_string( uid->name, uid->len );
|
1999-04-26 15:53:01 +00:00
|
|
|
|
tty_printf("\n");
|
|
|
|
|
}
|
|
|
|
|
else if( node->pkt->pkttype == PKT_SIGNATURE ) {
|
|
|
|
|
sig = node->pkt->pkt.signature;
|
2004-10-06 20:40:07 +00:00
|
|
|
|
tty_printf(" ");
|
|
|
|
|
tty_printf(_("signed by your key %s on %s%s%s\n"),
|
|
|
|
|
keystr(sig->keyid), datestr_from_sig(sig),"",
|
2002-06-29 13:46:34 +00:00
|
|
|
|
sig->flags.exportable?"":_(" (non-exportable)") );
|
1999-04-26 15:53:01 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if( !any )
|
|
|
|
|
return 0; /* none selected */
|
|
|
|
|
|
|
|
|
|
if( !cpr_get_answer_is_yes("ask_revoke_sig.okay",
|
2002-06-29 13:46:34 +00:00
|
|
|
|
_("Really create the revocation certificates? (y/N) ")) )
|
1999-04-26 15:53:01 +00:00
|
|
|
|
return 0; /* forget it */
|
|
|
|
|
|
2000-07-14 17:34:53 +00:00
|
|
|
|
reason = ask_revocation_reason( 0, 1, 0 );
|
|
|
|
|
if( !reason ) { /* user decided to cancel */
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
1999-04-26 15:53:01 +00:00
|
|
|
|
|
|
|
|
|
/* now we can sign the user ids */
|
|
|
|
|
reloop: /* (must use this, because we are modifing the list) */
|
|
|
|
|
primary_pk = keyblock->pkt->pkt.public_key;
|
|
|
|
|
for( node=keyblock; node; node = node->next ) {
|
|
|
|
|
KBNODE unode;
|
|
|
|
|
PACKET *pkt;
|
2000-07-14 17:34:53 +00:00
|
|
|
|
struct sign_attrib attrib;
|
1999-04-26 15:53:01 +00:00
|
|
|
|
PKT_secret_key *sk;
|
|
|
|
|
|
|
|
|
|
if( !(node->flag & NODFLG_MARK_A)
|
|
|
|
|
|| node->pkt->pkttype != PKT_SIGNATURE )
|
|
|
|
|
continue;
|
|
|
|
|
unode = find_prev_kbnode( keyblock, node, PKT_USER_ID );
|
|
|
|
|
assert( unode ); /* we already checked this */
|
|
|
|
|
|
|
|
|
|
memset( &attrib, 0, sizeof attrib );
|
2000-07-14 17:34:53 +00:00
|
|
|
|
attrib.reason = reason;
|
2002-06-29 13:46:34 +00:00
|
|
|
|
attrib.non_exportable=!node->pkt->pkt.signature->flags.exportable;
|
2000-07-14 17:34:53 +00:00
|
|
|
|
|
1999-04-26 15:53:01 +00:00
|
|
|
|
node->flag &= ~NODFLG_MARK_A;
|
2005-07-27 18:10:56 +00:00
|
|
|
|
sk = xmalloc_secure_clear( sizeof *sk );
|
1999-04-26 15:53:01 +00:00
|
|
|
|
if( get_seckey( sk, node->pkt->pkt.signature->keyid ) ) {
|
|
|
|
|
log_info(_("no secret key\n"));
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
rc = make_keysig_packet( &sig, primary_pk,
|
|
|
|
|
unode->pkt->pkt.user_id,
|
|
|
|
|
NULL,
|
|
|
|
|
sk,
|
2002-06-29 13:46:34 +00:00
|
|
|
|
0x30, 0, 0, 0, 0,
|
2000-07-14 17:34:53 +00:00
|
|
|
|
sign_mk_attrib,
|
1999-04-26 15:53:01 +00:00
|
|
|
|
&attrib );
|
|
|
|
|
free_secret_key(sk);
|
|
|
|
|
if( rc ) {
|
2002-06-29 13:46:34 +00:00
|
|
|
|
log_error(_("signing failed: %s\n"), g10_errstr(rc));
|
2000-07-14 17:34:53 +00:00
|
|
|
|
release_revocation_reason_info( reason );
|
1999-04-26 15:53:01 +00:00
|
|
|
|
return changed;
|
|
|
|
|
}
|
|
|
|
|
changed = 1; /* we changed the keyblock */
|
2002-06-29 13:46:34 +00:00
|
|
|
|
update_trust = 1;
|
2002-08-07 15:53:15 +00:00
|
|
|
|
/* Are we revoking our own uid? */
|
|
|
|
|
if(primary_pk->keyid[0]==sig->keyid[0] &&
|
|
|
|
|
primary_pk->keyid[1]==sig->keyid[1])
|
|
|
|
|
unode->pkt->pkt.user_id->is_revoked=1;
|
2005-07-27 18:10:56 +00:00
|
|
|
|
pkt = xmalloc_clear( sizeof *pkt );
|
1999-04-26 15:53:01 +00:00
|
|
|
|
pkt->pkttype = PKT_SIGNATURE;
|
|
|
|
|
pkt->pkt.signature = sig;
|
1999-05-06 12:26:10 +00:00
|
|
|
|
insert_kbnode( unode, new_kbnode(pkt), 0 );
|
1999-04-26 15:53:01 +00:00
|
|
|
|
goto reloop;
|
|
|
|
|
}
|
|
|
|
|
|
2000-07-14 17:34:53 +00:00
|
|
|
|
release_revocation_reason_info( reason );
|
1999-04-26 15:53:01 +00:00
|
|
|
|
return changed;
|
|
|
|
|
}
|
|
|
|
|
|
2002-12-27 13:41:17 +00:00
|
|
|
|
/* Revoke a user ID (i.e. revoke a user ID selfsig). Return true if
|
|
|
|
|
keyblock changed. */
|
|
|
|
|
static int
|
|
|
|
|
menu_revuid( KBNODE pub_keyblock, KBNODE sec_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;
|
|
|
|
|
struct revocation_reason_info *reason = NULL;
|
|
|
|
|
|
|
|
|
|
/* Note that this is correct as per the RFCs, but nevertheless
|
|
|
|
|
somewhat meaningless in the real world. 1991 did define the 0x30
|
|
|
|
|
sig class, but PGP 2.x did not actually implement it, so it would
|
|
|
|
|
probably be safe to use v4 revocations everywhere. -ds */
|
|
|
|
|
|
|
|
|
|
for( node = pub_keyblock; node; node = node->next )
|
2003-02-02 15:47:43 +00:00
|
|
|
|
if(pk->version>3 || (node->pkt->pkttype==PKT_USER_ID &&
|
|
|
|
|
node->pkt->pkt.user_id->selfsigversion>3))
|
2002-12-27 13:41:17 +00:00
|
|
|
|
{
|
|
|
|
|
if((reason = ask_revocation_reason( 0, 1, 4 )))
|
|
|
|
|
break;
|
|
|
|
|
else
|
|
|
|
|
goto leave;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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))
|
|
|
|
|
{
|
|
|
|
|
PKT_user_id *uid=node->pkt->pkt.user_id;
|
|
|
|
|
|
|
|
|
|
if(uid->is_revoked)
|
|
|
|
|
{
|
|
|
|
|
char *user=utf8_to_native(uid->name,uid->len,0);
|
|
|
|
|
log_info(_("user ID \"%s\" is already revoked\n"),user);
|
2005-07-27 18:10:56 +00:00
|
|
|
|
xfree(user);
|
2002-12-27 13:41:17 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
PACKET *pkt;
|
|
|
|
|
PKT_signature *sig;
|
|
|
|
|
struct sign_attrib attrib;
|
|
|
|
|
u32 timestamp=make_timestamp();
|
|
|
|
|
|
|
|
|
|
if(uid->created>=timestamp)
|
|
|
|
|
{
|
|
|
|
|
/* Okay, this is a problem. The user ID selfsig was
|
|
|
|
|
created in the future, so we need to warn the user and
|
|
|
|
|
set our revocation timestamp one second after that so
|
|
|
|
|
everything comes out clean. */
|
|
|
|
|
|
|
|
|
|
log_info(_("WARNING: a user ID signature is dated %d"
|
|
|
|
|
" seconds in the future\n"),uid->created-timestamp);
|
|
|
|
|
|
|
|
|
|
timestamp=uid->created+1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
memset( &attrib, 0, sizeof attrib );
|
|
|
|
|
attrib.reason = reason;
|
|
|
|
|
|
|
|
|
|
node->flag &= ~NODFLG_SELUID;
|
|
|
|
|
|
|
|
|
|
rc = make_keysig_packet( &sig, pk, uid, NULL, sk, 0x30, 0,
|
|
|
|
|
(reason==NULL)?3:0, timestamp, 0,
|
|
|
|
|
sign_mk_attrib, &attrib );
|
|
|
|
|
if( rc )
|
|
|
|
|
{
|
|
|
|
|
log_error(_("signing failed: %s\n"), g10_errstr(rc));
|
|
|
|
|
goto leave;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2005-07-27 18:10:56 +00:00
|
|
|
|
pkt = xmalloc_clear( sizeof *pkt );
|
2002-12-27 13:41:17 +00:00
|
|
|
|
pkt->pkttype = PKT_SIGNATURE;
|
|
|
|
|
pkt->pkt.signature = sig;
|
|
|
|
|
insert_kbnode( node, new_kbnode(pkt), 0 );
|
|
|
|
|
|
2003-02-02 15:47:43 +00:00
|
|
|
|
/* If the trustdb has an entry for this key+uid then the
|
|
|
|
|
trustdb needs an update. */
|
|
|
|
|
if(!update_trust
|
|
|
|
|
&& (get_validity(pk,uid)&TRUST_MASK)>=TRUST_UNDEFINED)
|
|
|
|
|
update_trust=1;
|
2002-12-27 13:41:17 +00:00
|
|
|
|
|
|
|
|
|
changed = 1;
|
|
|
|
|
node->pkt->pkt.user_id->is_revoked=1;
|
|
|
|
|
|
|
|
|
|
goto reloop;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(changed)
|
|
|
|
|
commit_kbnode( &pub_keyblock );
|
|
|
|
|
|
|
|
|
|
leave:
|
|
|
|
|
free_secret_key(sk);
|
|
|
|
|
release_revocation_reason_info( reason );
|
|
|
|
|
return changed;
|
|
|
|
|
}
|
|
|
|
|
|
1999-04-28 11:06:52 +00:00
|
|
|
|
/****************
|
2004-12-19 04:30:16 +00:00
|
|
|
|
* Revoke the whole key.
|
1999-04-28 11:06:52 +00:00
|
|
|
|
*/
|
|
|
|
|
static int
|
|
|
|
|
menu_revkey( KBNODE pub_keyblock, KBNODE sec_keyblock )
|
2004-12-19 04:30:16 +00:00
|
|
|
|
{
|
|
|
|
|
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;
|
|
|
|
|
PKT_signature *sig;
|
|
|
|
|
|
2004-12-19 05:20:07 +00:00
|
|
|
|
if(pk->is_revoked)
|
|
|
|
|
{
|
|
|
|
|
tty_printf(_("Key %s is already revoked.\n"),keystr_from_pk(pk));
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2004-12-19 04:30:16 +00:00
|
|
|
|
reason = ask_revocation_reason( 1, 0, 0 );
|
|
|
|
|
/* user decided to cancel */
|
|
|
|
|
if( !reason )
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
sk = copy_secret_key( NULL, sec_keyblock->pkt->pkt.secret_key );
|
|
|
|
|
rc = make_keysig_packet( &sig, pk, NULL, NULL, sk,
|
|
|
|
|
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));
|
|
|
|
|
goto scram;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
changed = 1; /* we changed the keyblock */
|
|
|
|
|
|
2005-07-27 18:10:56 +00:00
|
|
|
|
pkt = xmalloc_clear( sizeof *pkt );
|
2004-12-19 04:30:16 +00:00
|
|
|
|
pkt->pkttype = PKT_SIGNATURE;
|
|
|
|
|
pkt->pkt.signature = sig;
|
|
|
|
|
insert_kbnode( pub_keyblock, new_kbnode(pkt), 0 );
|
|
|
|
|
commit_kbnode( &pub_keyblock );
|
|
|
|
|
|
2004-12-19 05:20:07 +00:00
|
|
|
|
update_trust=1;
|
2004-12-19 04:30:16 +00:00
|
|
|
|
|
|
|
|
|
scram:
|
|
|
|
|
release_revocation_reason_info( reason );
|
|
|
|
|
return changed;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
menu_revsubkey( KBNODE pub_keyblock, KBNODE sec_keyblock )
|
1999-04-28 11:06:52 +00:00
|
|
|
|
{
|
|
|
|
|
PKT_public_key *mainpk;
|
|
|
|
|
KBNODE node;
|
|
|
|
|
int changed = 0;
|
|
|
|
|
int rc;
|
2000-07-14 17:34:53 +00:00
|
|
|
|
struct revocation_reason_info *reason = NULL;
|
|
|
|
|
|
|
|
|
|
reason = ask_revocation_reason( 1, 0, 0 );
|
|
|
|
|
if( !reason ) { /* user decided to cancel */
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
1999-05-06 12:26:10 +00:00
|
|
|
|
reloop: /* (better this way because we are modifing the keyring) */
|
1999-04-28 11:06:52 +00:00
|
|
|
|
mainpk = pub_keyblock->pkt->pkt.public_key;
|
|
|
|
|
for( node = pub_keyblock; node; node = node->next ) {
|
|
|
|
|
if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
|
|
|
|
|
&& (node->flag & NODFLG_SELKEY) ) {
|
|
|
|
|
PACKET *pkt;
|
|
|
|
|
PKT_signature *sig;
|
|
|
|
|
PKT_secret_key *sk;
|
|
|
|
|
PKT_public_key *subpk = node->pkt->pkt.public_key;
|
2000-07-14 17:34:53 +00:00
|
|
|
|
struct sign_attrib attrib;
|
|
|
|
|
|
2004-12-19 05:20:07 +00:00
|
|
|
|
if(subpk->is_revoked)
|
|
|
|
|
{
|
|
|
|
|
tty_printf(_("Subkey %s is already revoked.\n"),
|
|
|
|
|
keystr_from_pk(subpk));
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2000-07-14 17:34:53 +00:00
|
|
|
|
memset( &attrib, 0, sizeof attrib );
|
|
|
|
|
attrib.reason = reason;
|
1999-04-28 11:06:52 +00:00
|
|
|
|
|
|
|
|
|
node->flag &= ~NODFLG_SELKEY;
|
|
|
|
|
sk = copy_secret_key( NULL, sec_keyblock->pkt->pkt.secret_key );
|
2002-06-29 13:46:34 +00:00
|
|
|
|
rc = make_keysig_packet( &sig, mainpk, NULL, subpk, sk,
|
|
|
|
|
0x28, 0, 0, 0, 0,
|
|
|
|
|
sign_mk_attrib, &attrib );
|
1999-04-28 11:06:52 +00:00
|
|
|
|
free_secret_key(sk);
|
|
|
|
|
if( rc ) {
|
2002-06-29 13:46:34 +00:00
|
|
|
|
log_error(_("signing failed: %s\n"), g10_errstr(rc));
|
2000-07-14 17:34:53 +00:00
|
|
|
|
release_revocation_reason_info( reason );
|
1999-04-28 11:06:52 +00:00
|
|
|
|
return changed;
|
|
|
|
|
}
|
|
|
|
|
changed = 1; /* we changed the keyblock */
|
|
|
|
|
|
2005-07-27 18:10:56 +00:00
|
|
|
|
pkt = xmalloc_clear( sizeof *pkt );
|
1999-04-28 11:06:52 +00:00
|
|
|
|
pkt->pkttype = PKT_SIGNATURE;
|
|
|
|
|
pkt->pkt.signature = sig;
|
1999-05-06 12:26:10 +00:00
|
|
|
|
insert_kbnode( node, new_kbnode(pkt), 0 );
|
1999-04-28 11:06:52 +00:00
|
|
|
|
goto reloop;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
commit_kbnode( &pub_keyblock );
|
|
|
|
|
/*commit_kbnode( &sec_keyblock );*/
|
|
|
|
|
|
2002-06-29 13:46:34 +00:00
|
|
|
|
/* 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
|
|
|
|
|
when revoking/removing them */
|
1999-04-28 11:06:52 +00:00
|
|
|
|
|
2000-07-14 17:34:53 +00:00
|
|
|
|
release_revocation_reason_info( reason );
|
1999-04-28 11:06:52 +00:00
|
|
|
|
return changed;
|
|
|
|
|
}
|
|
|
|
|
|
2002-12-26 22:22:50 +00:00
|
|
|
|
/* 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
|
|
|
|
|
not worth adding extra complexity to change. -ds */
|
1999-06-29 19:50:54 +00:00
|
|
|
|
static int
|
|
|
|
|
enable_disable_key( KBNODE keyblock, int disable )
|
|
|
|
|
{
|
2002-06-29 13:46:34 +00:00
|
|
|
|
PKT_public_key *pk = find_kbnode( keyblock, PKT_PUBLIC_KEY )
|
|
|
|
|
->pkt->pkt.public_key;
|
1999-07-01 10:53:35 +00:00
|
|
|
|
unsigned int trust, newtrust;
|
|
|
|
|
|
2002-06-29 13:46:34 +00:00
|
|
|
|
trust = newtrust = get_ownertrust (pk);
|
1999-07-01 10:53:35 +00:00
|
|
|
|
newtrust &= ~TRUST_FLAG_DISABLED;
|
|
|
|
|
if( disable )
|
|
|
|
|
newtrust |= TRUST_FLAG_DISABLED;
|
|
|
|
|
if( trust == newtrust )
|
|
|
|
|
return 0; /* already in that state */
|
2002-06-29 13:46:34 +00:00
|
|
|
|
update_ownertrust(pk, newtrust );
|
1999-07-01 10:53:35 +00:00
|
|
|
|
return 0;
|
1999-06-29 19:50:54 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-06-29 13:46:34 +00:00
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
menu_showphoto( KBNODE keyblock )
|
|
|
|
|
{
|
|
|
|
|
KBNODE node;
|
|
|
|
|
int select_all = !count_selected_uids(keyblock);
|
|
|
|
|
int count=0;
|
|
|
|
|
PKT_public_key *pk=NULL;
|
|
|
|
|
|
|
|
|
|
/* Look for the public key first. We have to be really, really,
|
|
|
|
|
explicit as to which photo this is, and what key it is a UID on
|
|
|
|
|
since people may want to sign it. */
|
|
|
|
|
|
|
|
|
|
for( node = keyblock; node; node = node->next )
|
|
|
|
|
{
|
|
|
|
|
if( node->pkt->pkttype == PKT_PUBLIC_KEY )
|
2004-03-24 17:34:57 +00:00
|
|
|
|
pk = node->pkt->pkt.public_key;
|
2002-06-29 13:46:34 +00:00
|
|
|
|
else if( node->pkt->pkttype == PKT_USER_ID )
|
|
|
|
|
{
|
|
|
|
|
PKT_user_id *uid = node->pkt->pkt.user_id;
|
|
|
|
|
count++;
|
|
|
|
|
|
|
|
|
|
if((select_all || (node->flag & NODFLG_SELUID)) &&
|
|
|
|
|
uid->attribs!=NULL)
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
for(i=0;i<uid->numattribs;i++)
|
|
|
|
|
{
|
|
|
|
|
byte type;
|
|
|
|
|
u32 size;
|
|
|
|
|
|
|
|
|
|
if(uid->attribs[i].type==ATTRIB_IMAGE &&
|
|
|
|
|
parse_image_header(&uid->attribs[i],&type,&size))
|
|
|
|
|
{
|
|
|
|
|
tty_printf(_("Displaying %s photo ID of size %ld for "
|
2004-03-24 17:34:57 +00:00
|
|
|
|
"key %s (uid %d)\n"),
|
2002-06-29 13:46:34 +00:00
|
|
|
|
image_type_to_string(type,1),
|
2004-03-24 17:34:57 +00:00
|
|
|
|
(ulong)size,keystr_from_pk(pk),count);
|
2002-06-29 13:46:34 +00:00
|
|
|
|
show_photos(&uid->attribs[i],1,pk,NULL);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|