summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--doc/gpg.texi18
-rw-r--r--g10/gpg.c25
-rw-r--r--g10/keyedit.c380
-rw-r--r--g10/main.h2
4 files changed, 324 insertions, 101 deletions
diff --git a/doc/gpg.texi b/doc/gpg.texi
index 91186f24a..607a61122 100644
--- a/doc/gpg.texi
+++ b/doc/gpg.texi
@@ -906,6 +906,24 @@ Signs a public key with your secret key but marks it as
non-exportable. This is a shortcut version of the subcommand "lsign"
from @option{--edit-key}.
+@ifset gpgtwoone
+@item --quick-sign-key @code{fpr} [@code{names}]
+@itemx --quick-lsign-key @code{name}
+@opindex quick-sign-key
+@opindex quick-lsign-key
+Directly sign a key from the passphrase without any further user
+interaction. The @code{fpr} must be the verified primary fingerprint
+of a key in the local keyring. If no @code{names} are given, all
+useful user ids are signed; with given [@code{names}] only useful user
+ids matching one of theses names are signed. The command
+@option{--quick-lsign-key} marks the signatures as non-exportable.
+
+This command uses reasonable defaults and thus does not provide the
+full flexibility of the "sign" subcommand from @option{--edit-key}.
+Its intended use to help unattended signing using a list of verified
+fingerprints.
+@end ifset
+
@ifclear gpgone
@item --passwd @var{user_id}
@opindex passwd
diff --git a/g10/gpg.c b/g10/gpg.c
index 7529e81cb..daae3d3ca 100644
--- a/g10/gpg.c
+++ b/g10/gpg.c
@@ -1,6 +1,7 @@
/* gpg.c - The GnuPG utility (main for gpg)
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
* 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
+ * Copyright (C) 2013, 2014 Werner Koch
*
* This file is part of GnuPG.
*
@@ -111,6 +112,8 @@ enum cmd_and_opt_values
aSignSym,
aSignKey,
aLSignKey,
+ aQuickSignKey,
+ aQuickLSignKey,
aListConfig,
aGPGConfList,
aGPGConfTest,
@@ -408,6 +411,10 @@ static ARGPARSE_OPTS opts[] = {
N_("remove keys from the public keyring")),
ARGPARSE_c (aDeleteSecretKeys, "delete-secret-keys",
N_("remove keys from the secret keyring")),
+ ARGPARSE_c (aQuickSignKey, "quick-sign-key" ,
+ N_("quickly sign a key")),
+ ARGPARSE_c (aQuickLSignKey, "quick-lsign-key",
+ N_("quickly sign a key locally")),
ARGPARSE_c (aSignKey, "sign-key" ,N_("sign a key")),
ARGPARSE_c (aLSignKey, "lsign-key" ,N_("sign a key locally")),
ARGPARSE_c (aEditKey, "edit-key" ,N_("sign or edit a key")),
@@ -2264,6 +2271,8 @@ main (int argc, char **argv)
case aDeArmor:
case aEnArmor:
case aSign:
+ case aQuickSignKey:
+ case aQuickLSignKey:
case aSignKey:
case aLSignKey:
case aStore:
@@ -3735,6 +3744,22 @@ main (int argc, char **argv)
}
break;
+ case aQuickSignKey:
+ case aQuickLSignKey:
+ {
+ const char *fpr;
+
+ if (argc < 1)
+ wrong_args ("--quick-[l]sign-key fingerprint [userids]");
+ fpr = *argv++; argc--;
+ sl = NULL;
+ for( ; argc; argc--, argv++)
+ append_to_strlist2 (&sl, *argv, utf8_strings);
+ keyedit_quick_sign (ctrl, fpr, sl, locusr, (cmd == aQuickLSignKey));
+ free_strlist (sl);
+ }
+ break;
+
case aSignKey:
if( argc != 1 )
wrong_args(_("--sign-key user-id"));
diff --git a/g10/keyedit.c b/g10/keyedit.c
index b7f7ad66b..c4d7ca8e3 100644
--- a/g10/keyedit.c
+++ b/g10/keyedit.c
@@ -56,7 +56,8 @@ static void show_names (estream_t fp, KBNODE keyblock, PKT_public_key * pk,
static void show_key_with_all_names (estream_t fp,
KBNODE keyblock, int only_marked,
int with_revoker, int with_fpr,
- int with_subkeys, int with_prefs);
+ int with_subkeys, int with_prefs,
+ int nowarn);
static void show_key_and_fingerprint (KBNODE keyblock);
static int menu_adduid (KBNODE keyblock, int photo, const char *photo_name);
static void menu_deluid (KBNODE pub_keyblock);
@@ -499,13 +500,16 @@ trustsig_prompt (byte * trust_value, byte * trust_depth, char **regexp)
/*
- * 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.
+ * 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 only those will be signed. If QUICK is true the
+ * function won't ask the user and use sensible defaults.
*/
static int
-sign_uids (KBNODE keyblock, strlist_t locusr, int *ret_modified,
- int local, int nonrevocable, int trust, int interactive)
+sign_uids (estream_t fp,
+ kbnode_t keyblock, strlist_t locusr, int *ret_modified,
+ int local, int nonrevocable, int trust, int interactive,
+ int quick)
{
int rc = 0;
SK_LIST sk_list = NULL;
@@ -518,13 +522,15 @@ sign_uids (KBNODE keyblock, strlist_t locusr, int *ret_modified,
/* Are there any non-v3 sigs on this key already? */
if (PGP2)
- for (node = keyblock; node; node = node->next)
- if (node->pkt->pkttype == PKT_SIGNATURE &&
- node->pkt->pkt.signature->version > 3)
- {
- all_v3 = 0;
- break;
- }
+ {
+ 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.
*
@@ -595,13 +601,13 @@ sign_uids (KBNODE keyblock, strlist_t locusr, int *ret_modified,
if (uidnode->pkt->pkt.user_id->is_revoked)
{
- tty_printf (_("User ID \"%s\" is revoked."), user);
+ tty_fprintf (fp, _("User ID \"%s\" is revoked."), user);
if (selfsig)
- tty_printf ("\n");
- else if (opt.expert)
+ tty_fprintf (fp, "\n");
+ else if (opt.expert && !quick)
{
- tty_printf ("\n");
+ tty_fprintf (fp, "\n");
/* No, so remove the mark and continue */
if (!cpr_get_answer_is_yes ("sign_uid.revoke_okay",
_("Are you sure you "
@@ -618,18 +624,18 @@ sign_uids (KBNODE keyblock, strlist_t locusr, int *ret_modified,
{
uidnode->flag &= ~NODFLG_MARK_A;
uidnode = NULL;
- tty_printf (_(" Unable to sign.\n"));
+ tty_fprintf (fp, _(" Unable to sign.\n"));
}
}
else if (uidnode->pkt->pkt.user_id->is_expired)
{
- tty_printf (_("User ID \"%s\" is expired."), user);
+ tty_fprintf (fp, _("User ID \"%s\" is expired."), user);
if (selfsig)
- tty_printf ("\n");
- else if (opt.expert)
+ tty_fprintf (fp, "\n");
+ else if (opt.expert && !quick)
{
- tty_printf ("\n");
+ tty_fprintf (fp, "\n");
/* No, so remove the mark and continue */
if (!cpr_get_answer_is_yes ("sign_uid.expire_okay",
_("Are you sure you "
@@ -646,17 +652,17 @@ sign_uids (KBNODE keyblock, strlist_t locusr, int *ret_modified,
{
uidnode->flag &= ~NODFLG_MARK_A;
uidnode = NULL;
- tty_printf (_(" Unable to sign.\n"));
+ tty_fprintf (fp, _(" Unable to sign.\n"));
}
}
else if (!uidnode->pkt->pkt.user_id->created && !selfsig)
{
- tty_printf (_("User ID \"%s\" is not self-signed."),
- user);
+ tty_fprintf (fp, _("User ID \"%s\" is not self-signed."),
+ user);
- if (opt.expert)
+ if (opt.expert && !quick)
{
- tty_printf ("\n");
+ tty_fprintf (fp, "\n");
/* No, so remove the mark and continue */
if (!cpr_get_answer_is_yes ("sign_uid.nosig_okay",
_("Are you sure you "
@@ -673,13 +679,14 @@ sign_uids (KBNODE keyblock, strlist_t locusr, int *ret_modified,
{
uidnode->flag &= ~NODFLG_MARK_A;
uidnode = NULL;
- tty_printf (_(" Unable to sign.\n"));
+ tty_fprintf (fp, _(" Unable to sign.\n"));
}
}
- if (uidnode && interactive && !yesreally)
+ if (uidnode && interactive && !yesreally && !quick)
{
- tty_printf (_("User ID \"%s\" is signable. "), user);
+ tty_fprintf (fp,
+ _("User ID \"%s\" is signable. "), user);
if (!cpr_get_answer_is_yes ("sign_uid.sign_okay",
_("Sign it? (y/N) ")))
{
@@ -704,10 +711,12 @@ sign_uids (KBNODE keyblock, strlist_t locusr, int *ret_modified,
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)
+ if (node->pkt->pkt.signature->version < 4
+ && selfsig && !quick)
{
- tty_printf (_("The self-signature on \"%s\"\n"
- "is a PGP 2.x-style signature.\n"), user);
+ tty_fprintf (fp,
+ _("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
@@ -729,10 +738,10 @@ sign_uids (KBNODE keyblock, strlist_t locusr, int *ret_modified,
/* Is the current signature expired? */
if (node->pkt->pkt.signature->flags.expired)
{
- tty_printf (_("Your current signature on \"%s\"\n"
- "has expired.\n"), user);
+ tty_fprintf (fp, _("Your current signature on \"%s\"\n"
+ "has expired.\n"), user);
- if (cpr_get_answer_is_yes
+ if (quick || cpr_get_answer_is_yes
("sign_uid.replace_expired_okay",
_("Do you want to issue a "
"new signature to replace "
@@ -755,10 +764,12 @@ sign_uids (KBNODE keyblock, strlist_t locusr, int *ret_modified,
{
/* 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);
+ tty_fprintf (fp, _("Your current signature on \"%s\"\n"
+ "is a local signature.\n"), user);
- if (cpr_get_answer_is_yes
+ if (quick)
+ ;
+ else if (cpr_get_answer_is_yes
("sign_uid.local_promote_okay",
_("Do you want to promote "
"it to a full exportable " "signature? (y/N) ")))
@@ -779,14 +790,15 @@ sign_uids (KBNODE keyblock, strlist_t locusr, int *ret_modified,
/* Fixme: see whether there is a revocation in which
* case we should allow to sign it again. */
if (!node->pkt->pkt.signature->flags.exportable && local)
- tty_printf
- (_("\"%s\" was already locally signed by key %s\n"),
+ tty_fprintf ( fp,
+ _("\"%s\" was already locally signed by key %s\n"),
user, keystr_from_pk (pk));
else
- tty_printf (_("\"%s\" was already signed by key %s\n"),
+ tty_fprintf (fp,
+ _("\"%s\" was already signed by key %s\n"),
user, keystr_from_pk (pk));
- if (opt.expert
+ if (opt.expert && !quick
&& cpr_get_answer_is_yes ("sign_uid.dupe_okay",
_("Do you want to sign it "
"again anyway? (y/N) ")))
@@ -810,15 +822,15 @@ sign_uids (KBNODE keyblock, strlist_t locusr, int *ret_modified,
/* Check whether any uids are left for signing. */
if (!count_uids_with_flag (keyblock, NODFLG_MARK_A))
{
- tty_printf (_("Nothing to sign with key %s\n"),
+ tty_fprintf (fp, _("Nothing to sign with key %s\n"),
keystr_from_pk (pk));
continue;
}
/* Ask whether we really should sign these user id(s). */
- tty_printf ("\n");
- show_key_with_all_names (NULL, keyblock, 1, 0, 1, 0, 0);
- tty_printf ("\n");
+ tty_fprintf (fp, "\n");
+ show_key_with_all_names (fp, keyblock, 1, 0, 1, 0, 0, 0);
+ tty_fprintf (fp, "\n");
if (primary_pk->expiredate && !selfsig)
{
@@ -826,11 +838,11 @@ sign_uids (KBNODE keyblock, strlist_t locusr, int *ret_modified,
if (primary_pk->expiredate <= now)
{
- tty_printf (_("This key has expired!"));
+ tty_fprintf (fp, _("This key has expired!"));
- if (opt.expert)
+ if (opt.expert && !quick)
{
- tty_printf (" ");
+ tty_fprintf (fp, " ");
if (!cpr_get_answer_is_yes ("sign_uid.expired_okay",
_("Are you sure you still "
"want to sign it? (y/N) ")))
@@ -838,16 +850,16 @@ sign_uids (KBNODE keyblock, strlist_t locusr, int *ret_modified,
}
else
{
- tty_printf (_(" Unable to sign.\n"));
+ tty_fprintf (fp, _(" Unable to sign.\n"));
continue;
}
}
else
{
- tty_printf (_("This key is due to expire on %s.\n"),
- expirestr_from_pk (primary_pk));
+ tty_fprintf (fp, _("This key is due to expire on %s.\n"),
+ expirestr_from_pk (primary_pk));
- if (opt.ask_cert_expire)
+ if (opt.ask_cert_expire && !quick)
{
char *answer = cpr_get ("sign_uid.expire",
_("Do you want your signature to "
@@ -875,7 +887,7 @@ sign_uids (KBNODE keyblock, strlist_t locusr, int *ret_modified,
the expiration of the pk */
if (!duration && !selfsig)
{
- if (opt.ask_cert_expire)
+ if (opt.ask_cert_expire && !quick)
duration = ask_expire_interval (1, opt.def_cert_expire);
else
duration = parse_expire_string (opt.def_cert_expire);
@@ -890,11 +902,11 @@ sign_uids (KBNODE keyblock, strlist_t locusr, int *ret_modified,
if (PGP2 && all_v3 &&
(pk->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"));
+ tty_fprintf (fp, _("You may not make an OpenPGP signature on a "
+ "PGP 2.x key while in --pgp2 mode.\n"));
+ tty_fprintf (fp, _("This would make the key unusable in PGP 2.x.\n"));
- if (opt.expert)
+ if (opt.expert && !quick)
{
if (!cpr_get_answer_is_yes ("sign_uid.v4_on_v3_okay",
_("Are you sure you still "
@@ -911,26 +923,28 @@ sign_uids (KBNODE keyblock, strlist_t locusr, int *ret_modified,
;
else
{
- if (opt.batch || !opt.ask_cert_level)
+ if (opt.batch || !opt.ask_cert_level || quick)
class = 0x10 + opt.def_cert_level;
else
{
char *answer;
- tty_printf (_("How carefully have you verified the key you are "
+ tty_fprintf (fp,
+ _("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"),
+ tty_fprintf (fp, "\n");
+ tty_fprintf (fp, _(" (0) I will not answer.%s\n"),
opt.def_cert_level == 0 ? " (default)" : "");
- tty_printf (_(" (1) I have not checked at all.%s\n"),
+ tty_fprintf (fp, _(" (1) I have not checked at all.%s\n"),
opt.def_cert_level == 1 ? " (default)" : "");
- tty_printf (_(" (2) I have done casual checking.%s\n"),
+ tty_fprintf (fp, _(" (2) I have done casual checking.%s\n"),
opt.def_cert_level == 2 ? " (default)" : "");
- tty_printf (_(" (3) I have done very careful checking.%s\n"),
+ tty_fprintf (fp,
+ _(" (3) I have done very careful checking.%s\n"),
opt.def_cert_level == 3 ? " (default)" : "");
- tty_printf ("\n");
+ tty_fprintf (fp, "\n");
while (class == 0)
{
@@ -948,79 +962,85 @@ sign_uids (KBNODE keyblock, strlist_t locusr, int *ret_modified,
else if (ascii_strcasecmp (answer, "3") == 0)
class = 0x13; /* Positive */
else
- tty_printf (_("Invalid selection.\n"));
+ tty_fprintf (fp, _("Invalid selection.\n"));
xfree (answer);
}
}
- if (trust)
+ if (trust && !quick)
trustsig_prompt (&trust_value, &trust_depth, &trust_regexp);
}
- p = get_user_id_native (sk_keyid);
- tty_printf (_("Are you sure that you want to sign this key with your\n"
- "key \"%s\" (%s)\n"), p, keystr_from_pk (pk));
- xfree (p);
+ if (!quick)
+ {
+ p = get_user_id_native (sk_keyid);
+ tty_fprintf (fp,
+ _("Are you sure that you want to sign this key with your\n"
+ "key \"%s\" (%s)\n"), p, keystr_from_pk (pk));
+ xfree (p);
+ }
if (selfsig)
{
- tty_printf ("\n");
- tty_printf (_("This will be a self-signature.\n"));
+ tty_fprintf (fp, "\n");
+ tty_fprintf (fp, _("This will be a self-signature.\n"));
if (local)
{
- tty_printf ("\n");
- tty_printf (_("WARNING: the signature will not be marked "
- "as non-exportable.\n"));
+ tty_fprintf (fp, "\n");
+ tty_fprintf (fp, _("WARNING: the signature will not be marked "
+ "as non-exportable.\n"));
}
if (nonrevocable)
{
- tty_printf ("\n");
- tty_printf (_("WARNING: the signature will not be marked "
- "as non-revocable.\n"));
+ tty_fprintf (fp, "\n");
+ tty_fprintf (fp, _("WARNING: the signature will not be marked "
+ "as non-revocable.\n"));
}
}
else
{
if (local)
{
- tty_printf ("\n");
- tty_printf
- (_("The signature will be marked as non-exportable.\n"));
+ tty_fprintf (fp, "\n");
+ tty_fprintf (fp,
+ _("The signature will be marked as non-exportable.\n"));
}
if (nonrevocable)
{
- tty_printf ("\n");
- tty_printf
- (_("The signature will be marked as non-revocable.\n"));
+ tty_fprintf (fp, "\n");
+ tty_fprintf (fp,
+ _("The signature will be marked as non-revocable.\n"));
}
switch (class)
{
case 0x11:
- tty_printf ("\n");
- tty_printf (_("I have not checked this key at all.\n"));
+ tty_fprintf (fp, "\n");
+ tty_fprintf (fp, _("I have not checked this key at all.\n"));
break;
case 0x12:
- tty_printf ("\n");
- tty_printf (_("I have checked this key casually.\n"));
+ tty_fprintf (fp, "\n");
+ tty_fprintf (fp, _("I have checked this key casually.\n"));
break;
case 0x13:
- tty_printf ("\n");
- tty_printf (_("I have checked this key very carefully.\n"));
+ tty_fprintf (fp, "\n");
+ tty_fprintf (fp, _("I have checked this key very carefully.\n"));
break;
}
}
- tty_printf ("\n");
+ tty_fprintf (fp, "\n");
if (opt.batch && opt.answer_yes)
;
+ else if (quick)
+ ;
else if (!cpr_get_answer_is_yes ("sign_uid.okay",
_("Really sign? (y/N) ")))
continue;
@@ -1093,7 +1113,7 @@ sign_uids (KBNODE keyblock, strlist_t locusr, int *ret_modified,
delete_kbnode (node);
} /* End loop over signators. */
-leave:
+ leave:
release_sk_list (sk_list);
return rc;
}
@@ -1544,7 +1564,7 @@ keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr,
if (redisplay && !quiet)
{
- show_key_with_all_names (NULL, keyblock, 0, 1, 0, 1, 0);
+ show_key_with_all_names (NULL, keyblock, 0, 1, 0, 1, 0, 0);
tty_printf ("\n");
redisplay = 0;
}
@@ -1736,8 +1756,8 @@ keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr,
break;
}
- sign_uids (keyblock, locusr, &modified,
- localsig, nonrevokesig, trustsig, interactive);
+ sign_uids (NULL, keyblock, locusr, &modified,
+ localsig, nonrevokesig, trustsig, interactive, 0);
}
break;
@@ -2083,7 +2103,7 @@ keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr,
break;
}
- show_key_with_all_names (NULL, keyblock, 0, 0, 0, 1, 0);
+ show_key_with_all_names (NULL, keyblock, 0, 0, 0, 1, 0, 0);
tty_printf ("\n");
if (edit_ownertrust (find_kbnode (keyblock,
PKT_PUBLIC_KEY)->pkt->pkt.
@@ -2284,6 +2304,163 @@ leave:
}
+/* Unattended key signing function. If the key specifified by FPR is
+ availabale and FPR is the primary fingerprint all user ids of the
+ user ids of the key are signed using the default signing key. If
+ UIDS is an empty list all usable UIDs are signed, if it is not
+ empty, only those user ids matching one of the entries of the loist
+ are signed. With LOCAL being true kthe signatures are marked as
+ non-exportable. */
+void
+keyedit_quick_sign (ctrl_t ctrl, const char *fpr, strlist_t uids,
+ strlist_t locusr, int local)
+{
+ gpg_error_t err;
+ kbnode_t keyblock = NULL;
+ KEYDB_HANDLE kdbhd = NULL;
+ int modified = 0;
+ KEYDB_SEARCH_DESC desc;
+ PKT_public_key *pk;
+ kbnode_t node;
+ strlist_t sl;
+ int any;
+
+#ifdef HAVE_W32_SYSTEM
+ /* See keyedit_menu for why we need this. */
+ check_trustdb_stale ();
+#endif
+
+ /* We require a fingerprint because only this uniquely identifies a
+ key and may thus be used to select a key for unattended key
+ signing. */
+ if (classify_user_id (fpr, &desc, 1)
+ || !(desc.mode == KEYDB_SEARCH_MODE_FPR
+ || desc.mode == KEYDB_SEARCH_MODE_FPR16
+ || desc.mode == KEYDB_SEARCH_MODE_FPR20))
+ {
+ log_error (_("\"%s\" is not a fingerprint\n"), fpr);
+ goto leave;
+ }
+ err = get_pubkey_byname (ctrl, NULL, NULL, fpr, &keyblock, &kdbhd, 1, 1);
+ if (err)
+ {
+ log_error (_("key \"%s\" not found: %s\n"), fpr, gpg_strerror (err));
+ goto leave;
+ }
+ if (fix_keyblock (keyblock))
+ modified++;
+ if (collapse_uids (&keyblock))
+ modified++;
+ reorder_keyblock (keyblock);
+
+ /* Check that the primary fingerprint has been given. */
+ {
+ byte fprbin[MAX_FINGERPRINT_LEN];
+ size_t fprlen;
+
+ fingerprint_from_pk (keyblock->pkt->pkt.public_key, fprbin, &fprlen);
+ if (fprlen == 16 && desc.mode == KEYDB_SEARCH_MODE_FPR16
+ && !memcmp (fprbin, desc.u.fpr, 16))
+ ;
+ else if (fprlen == 16 && desc.mode == KEYDB_SEARCH_MODE_FPR
+ && !memcmp (fprbin, desc.u.fpr, 16)
+ && !desc.u.fpr[16]
+ && !desc.u.fpr[17]
+ && !desc.u.fpr[18]
+ && !desc.u.fpr[19])
+ ;
+ else if (fprlen == 20 && (desc.mode == KEYDB_SEARCH_MODE_FPR20
+ || desc.mode == KEYDB_SEARCH_MODE_FPR)
+ && !memcmp (fprbin, desc.u.fpr, 20))
+ ;
+ else
+ {
+ log_error (_("\"%s\" is not the primary fingerprint\n"), fpr);
+ goto leave;
+ }
+ }
+
+ /* If we modified the keyblock, make sure the flags are right. */
+ if (modified)
+ merge_keys_and_selfsig (keyblock);
+
+ /* Give some info in verbose. */
+ if (opt.verbose)
+ {
+ show_key_with_all_names (es_stdout, keyblock, 0,
+ 1/*with_revoker*/, 1/*with_fingerprint*/,
+ 0, 0, 1);
+ es_fflush (es_stdout);
+ }
+
+ pk = keyblock->pkt->pkt.public_key;
+ if (pk->flags.revoked)
+ {
+ if (!opt.verbose)
+ show_key_with_all_names (es_stdout, keyblock, 0, 0, 0, 0, 0, 1);
+ log_error ("%s%s", _("Key is revoked."), _(" Unable to sign.\n"));
+ goto leave;
+ }
+
+ /* Set the flags according to the UIDS list. Fixme: We may want to
+ use classify_user_id along with dedicated compare functions so
+ that we match the same way as in the key lookup. */
+ any = 0;
+ menu_select_uid (keyblock, 0); /* Better clear the flags first. */
+ for (sl=uids; sl; sl = sl->next)
+ {
+ for (node = keyblock; node; node = node->next)
+ {
+ if (node->pkt->pkttype == PKT_USER_ID)
+ {
+ PKT_user_id *uid = node->pkt->pkt.user_id;
+
+ if (!uid->attrib_data
+ && ascii_memistr (uid->name, uid->len, sl->d))
+ {
+ node->flag |= NODFLG_SELUID;
+ any = 1;
+ }
+ }
+ }
+ }
+
+ if (uids && !any)
+ {
+ if (!opt.verbose)
+ show_key_with_all_names (es_stdout, keyblock, 0, 0, 0, 0, 0, 1);
+ es_fflush (es_stdout);
+ log_error ("%s %s", _("No matching user IDs."), _("Nothing to sign.\n"));
+ goto leave;
+ }
+
+ /* Sign. */
+ sign_uids (es_stdout, keyblock, locusr, &modified, local, 0, 0, 0, 1);
+ es_fflush (es_stdout);
+
+ if (modified)
+ {
+ err = keydb_update_keyblock (kdbhd, keyblock);
+ if (err)
+ {
+ log_error (_("update failed: %s\n"), gpg_strerror (err));
+ goto leave;
+ }
+ }
+ else
+ log_info (_("Key not changed so no update needed.\n"));
+
+ if (update_trust)
+ revalidation_mark ();
+
+
+ leave:
+ release_kbnode (keyblock);
+ keydb_release (kdbhd);
+}
+
+
+
static void
tty_print_notations (int indent, PKT_signature * sig)
{
@@ -2705,7 +2882,8 @@ show_names (estream_t fp,
static void
show_key_with_all_names (estream_t fp,
KBNODE keyblock, int only_marked, int with_revoker,
- int with_fpr, int with_subkeys, int with_prefs)
+ int with_fpr, int with_subkeys, int with_prefs,
+ int nowarn)
{
KBNODE node;
int i;
@@ -2889,7 +3067,7 @@ show_key_with_all_names (estream_t fp,
show_names (fp,
keyblock, primary, only_marked ? NODFLG_MARK_A : 0, with_prefs);
- if (do_warn)
+ if (do_warn && !nowarn)
tty_fprintf (fp, _("Please note that the shown key validity"
" is not necessarily correct\n"
"unless you restart the program.\n"));
diff --git a/g10/main.h b/g10/main.h
index ad1a9f682..ce77a839b 100644
--- a/g10/main.h
+++ b/g10/main.h
@@ -236,6 +236,8 @@ int delete_keys( strlist_t names, int secret, int allow_both );
void keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr,
strlist_t commands, int quiet, int seckey_check );
void keyedit_passwd (ctrl_t ctrl, const char *username);
+void keyedit_quick_sign (ctrl_t ctrl, const char *fpr,
+ strlist_t uids, strlist_t locusr, int local);
void show_basic_key_info (KBNODE keyblock);
/*-- keygen.c --*/