aboutsummaryrefslogtreecommitdiffstats
path: root/g10/import.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--g10/import.c507
1 files changed, 387 insertions, 120 deletions
diff --git a/g10/import.c b/g10/import.c
index 7c0d1e2cc..375bd03f8 100644
--- a/g10/import.c
+++ b/g10/import.c
@@ -1,6 +1,6 @@
/* import.c - import a key into our key storage.
* Copyright (C) 1998-2007, 2010-2011 Free Software Foundation, Inc.
- * Copyright (C) 2014 Werner Koch
+ * Copyright (C) 2014, 2016 Werner Koch
*
* This file is part of GnuPG.
*
@@ -35,9 +35,13 @@
#include "i18n.h"
#include "ttyio.h"
#include "status.h"
+#include "recsel.h"
#include "keyserver-internal.h"
#include "call-agent.h"
#include "../common/membuf.h"
+#include "../common/init.h"
+#include "../common/mbox-util.h"
+
struct import_stats_s
{
@@ -60,6 +64,28 @@ struct import_stats_s
};
+/* Node flag to indicate that a user ID or a subkey has a
+ * valid self-signature. */
+#define NODE_GOOD_SELFSIG 1
+/* Node flag to indicate that a user ID or subkey has
+ * an invalid self-signature. */
+#define NODE_BAD_SELFSIG 2
+/* Node flag to indicate that the node shall be deleted. */
+#define NODE_DELETION_MARK 4
+/* A node flag used to temporary mark a node. */
+#define NODE_FLAG_A 8
+
+
+/* A global variable to store the selector created from
+ * --import-filter keep-uid=EXPR.
+ *
+ * FIXME: We should put this into the CTRL object but that requires a
+ * lot more changes right now.
+ */
+static recsel_expr_t import_keep_uid;
+
+
+
static int import (ctrl_t ctrl,
IOBUF inp, const char* fname, struct import_stats_s *stats,
unsigned char **fpr, size_t *fpr_len, unsigned int options,
@@ -68,32 +94,36 @@ static int read_block (IOBUF a, PACKET **pending_pkt, kbnode_t *ret_root,
int *r_v3keys);
static void revocation_present (ctrl_t ctrl, kbnode_t keyblock);
static int import_one (ctrl_t ctrl,
- const char *fname, kbnode_t keyblock,
+ kbnode_t keyblock,
struct import_stats_s *stats,
unsigned char **fpr, size_t *fpr_len,
unsigned int options, int from_sk, int silent,
import_screener_t screener, void *screener_arg);
-static int import_secret_one (ctrl_t ctrl, const char *fname, kbnode_t keyblock,
+static int import_secret_one (ctrl_t ctrl, kbnode_t keyblock,
struct import_stats_s *stats, int batch,
unsigned int options, int for_migration,
import_screener_t screener, void *screener_arg);
-static int import_revoke_cert( const char *fname, kbnode_t node,
- struct import_stats_s *stats);
-static int chk_self_sigs (const char *fname, kbnode_t keyblock,
- PKT_public_key *pk, u32 *keyid, int *non_self );
-static int delete_inv_parts (const char *fname, kbnode_t keyblock,
- u32 *keyid, unsigned int options );
-static int merge_blocks (const char *fname, kbnode_t keyblock_orig,
+static int import_revoke_cert (kbnode_t node, struct import_stats_s *stats);
+static int chk_self_sigs (kbnode_t keyblock, u32 *keyid, int *non_self);
+static int delete_inv_parts (kbnode_t keyblock,
+ u32 *keyid, unsigned int options);
+static int merge_blocks (kbnode_t keyblock_orig,
kbnode_t keyblock, u32 *keyid,
int *n_uids, int *n_sigs, int *n_subk );
-static int append_uid (kbnode_t keyblock, kbnode_t node, int *n_sigs,
- const char *fname, u32 *keyid );
-static int append_key (kbnode_t keyblock, kbnode_t node, int *n_sigs,
- const char *fname, u32 *keyid );
-static int merge_sigs (kbnode_t dst, kbnode_t src, int *n_sigs,
- const char *fname, u32 *keyid );
-static int merge_keysigs (kbnode_t dst, kbnode_t src, int *n_sigs,
- const char *fname, u32 *keyid );
+static int append_uid (kbnode_t keyblock, kbnode_t node, int *n_sigs);
+static int append_key (kbnode_t keyblock, kbnode_t node, int *n_sigs);
+static int merge_sigs (kbnode_t dst, kbnode_t src, int *n_sigs);
+static int merge_keysigs (kbnode_t dst, kbnode_t src, int *n_sigs);
+
+
+
+static void
+cleanup_import_globals (void)
+{
+ recsel_release (import_keep_uid);
+ import_keep_uid = NULL;
+}
+
int
parse_import_options(char *str,unsigned int *options,int noisy)
@@ -112,6 +142,9 @@ parse_import_options(char *str,unsigned int *options,int noisy)
{"fast-import",IMPORT_FAST,NULL,
N_("do not update the trustdb after import")},
+ {"import-show",IMPORT_SHOW,NULL,
+ N_("show key during import")},
+
{"merge-only",IMPORT_MERGE_ONLY,NULL,
N_("only accept updates to existing keys")},
@@ -121,6 +154,9 @@ parse_import_options(char *str,unsigned int *options,int noisy)
{"import-minimal",IMPORT_MINIMAL|IMPORT_CLEAN,NULL,
N_("remove as much as possible from key after import")},
+ {"import-export", IMPORT_EXPORT, NULL,
+ N_("run import filters and export key immediately")},
+
/* Aliases for backward compatibility */
{"allow-local-sigs",IMPORT_LOCAL_SIGS,NULL,NULL},
{"repair-hkp-subkey-bug",IMPORT_REPAIR_PKS_SUBKEY_BUG,NULL,NULL},
@@ -137,6 +173,39 @@ parse_import_options(char *str,unsigned int *options,int noisy)
}
+/* Parse and set an import filter from string. STRING has the format
+ * "NAME=EXPR" with NAME being the name of the filter. Spaces before
+ * and after NAME are not allowed. If this function is all called
+ * several times all expressions for the same NAME are concatenated.
+ * Supported filter names are:
+ *
+ * - keep-uid :: If the expression evaluates to true for a certain
+ * user ID packet, that packet and all it dependencies
+ * will be imported. The expression may use these
+ * variables:
+ *
+ * - uid :: The entire user ID.
+ * - mbox :: The mail box part of the user ID.
+ * - primary :: Evaluate to true for the primary user ID.
+ */
+gpg_error_t
+parse_and_set_import_filter (const char *string)
+{
+ gpg_error_t err;
+
+ /* Auto register the cleanup function. */
+ register_mem_cleanup_func (cleanup_import_globals);
+
+ if (!strncmp (string, "keep-uid=", 9))
+ err = recsel_parse_expr (&import_keep_uid, string+9);
+ else
+ err = gpg_error (GPG_ERR_INV_NAME);
+
+ return err;
+}
+
+
+
import_stats_t
import_new_stats_handle (void)
{
@@ -151,6 +220,113 @@ import_release_stats_handle (import_stats_t p)
}
+/* Read a key from a file. Only the first key in the file is
+ * considered and stored at R_KEYBLOCK. FNAME is the name of the
+ * file.
+ */
+gpg_error_t
+read_key_from_file (ctrl_t ctrl, const char *fname, kbnode_t *r_keyblock)
+{
+ gpg_error_t err;
+ iobuf_t inp;
+ PACKET *pending_pkt = NULL;
+ kbnode_t keyblock = NULL;
+ u32 keyid[2];
+ int v3keys; /* Dummy */
+ int non_self; /* Dummy */
+
+ (void)ctrl;
+
+ *r_keyblock = NULL;
+
+ inp = iobuf_open (fname);
+ if (!inp)
+ err = gpg_error_from_syserror ();
+ else if (is_secured_file (iobuf_get_fd (inp)))
+ {
+ iobuf_close (inp);
+ inp = NULL;
+ err = gpg_error (GPG_ERR_EPERM);
+ }
+ else
+ err = 0;
+ if (err)
+ {
+ log_error (_("can't open '%s': %s\n"),
+ iobuf_is_pipe_filename (fname)? "[stdin]": fname,
+ gpg_strerror (err));
+ if (gpg_err_code (err) == GPG_ERR_ENOENT)
+ err = gpg_error (GPG_ERR_NO_PUBKEY);
+ goto leave;
+ }
+
+ /* Push the armor filter. */
+ {
+ armor_filter_context_t *afx;
+ afx = new_armor_context ();
+ afx->only_keyblocks = 1;
+ push_armor_filter (afx, inp);
+ release_armor_context (afx);
+ }
+
+ /* Read the first non-v3 keyblock. */
+ while (!(err = read_block (inp, &pending_pkt, &keyblock, &v3keys)))
+ {
+ if (keyblock->pkt->pkttype == PKT_PUBLIC_KEY)
+ break;
+ log_info (_("skipping block of type %d\n"), keyblock->pkt->pkttype);
+ release_kbnode (keyblock);
+ keyblock = NULL;
+ }
+ if (err)
+ {
+ if (gpg_err_code (err) != GPG_ERR_INV_KEYRING)
+ log_error (_("error reading '%s': %s\n"),
+ iobuf_is_pipe_filename (fname)? "[stdin]": fname,
+ gpg_strerror (err));
+ goto leave;
+ }
+
+ keyid_from_pk (keyblock->pkt->pkt.public_key, keyid);
+
+ if (!find_next_kbnode (keyblock, PKT_USER_ID))
+ {
+ err = gpg_error (GPG_ERR_NO_USER_ID);
+ goto leave;
+ }
+
+ collapse_uids (&keyblock);
+
+ clear_kbnode_flags (keyblock);
+ if (chk_self_sigs (keyblock, keyid, &non_self))
+ {
+ err = gpg_error (GPG_ERR_INV_KEYRING);
+ goto leave;
+ }
+
+ if (!delete_inv_parts (keyblock, keyid, 0) )
+ {
+ err = gpg_error (GPG_ERR_NO_USER_ID);
+ goto leave;
+ }
+
+ *r_keyblock = keyblock;
+ keyblock = NULL;
+
+ leave:
+ if (inp)
+ {
+ iobuf_close (inp);
+ /* Must invalidate that ugly cache to actually close the file. */
+ iobuf_ioctl (NULL, IOBUF_IOCTL_INVALIDATE_CACHE, 0, (char*)fname);
+ }
+ release_kbnode (keyblock);
+ /* FIXME: Do we need to free PENDING_PKT ? */
+ return err;
+}
+
+
+
/*
* Import the public keys from the given filename. Input may be armored.
* This function rejects all keys which are not validly self signed on at
@@ -328,16 +504,16 @@ import (ctrl_t ctrl, IOBUF inp, const char* fname,struct import_stats_s *stats,
{
stats->v3keys += v3keys;
if (keyblock->pkt->pkttype == PKT_PUBLIC_KEY)
- rc = import_one (ctrl, fname, keyblock,
+ rc = import_one (ctrl, keyblock,
stats, fpr, fpr_len, options, 0, 0,
screener, screener_arg);
else if (keyblock->pkt->pkttype == PKT_SECRET_KEY)
- rc = import_secret_one (ctrl, fname, keyblock, stats,
+ rc = import_secret_one (ctrl, keyblock, stats,
opt.batch, options, 0,
screener, screener_arg);
else if (keyblock->pkt->pkttype == PKT_SIGNATURE
&& keyblock->pkt->pkt.signature->sig_class == 0x20 )
- rc = import_revoke_cert( fname, keyblock, stats );
+ rc = import_revoke_cert (keyblock, stats);
else
{
log_info (_("skipping block of type %d\n"), keyblock->pkt->pkttype);
@@ -401,7 +577,7 @@ import_old_secring (ctrl_t ctrl, const char *fname)
while (!(err = read_block (inp, &pending_pkt, &keyblock, &v3keys)))
{
if (keyblock->pkt->pkttype == PKT_SECRET_KEY)
- err = import_secret_one (ctrl, fname, keyblock, stats, 1, 0, 1,
+ err = import_secret_one (ctrl, keyblock, stats, 1, 0, 1,
NULL, NULL);
release_kbnode (keyblock);
if (err)
@@ -707,8 +883,8 @@ fix_pks_corruption (kbnode_t keyblock)
}
else
{
- sknode->flag |= 1; /* Mark it good so we don't need to
- check it again */
+ /* Mark it good so we don't need to check it again */
+ sknode->flag |= NODE_GOOD_SELFSIG;
changed = 1;
break;
}
@@ -921,6 +1097,74 @@ check_prefs (ctrl_t ctrl, kbnode_t keyblock)
}
+/* Helper for apply_keep_uid_filter. */
+static const char *
+filter_getval (void *cookie, const char *propname)
+{
+ kbnode_t node = cookie;
+ const char *result;
+
+ if (node->pkt->pkttype == PKT_USER_ID)
+ {
+ if (!strcmp (propname, "uid"))
+ result = node->pkt->pkt.user_id->name;
+ else if (!strcmp (propname, "mbox"))
+ {
+ if (!node->pkt->pkt.user_id->mbox)
+ {
+ node->pkt->pkt.user_id->mbox
+ = mailbox_from_userid (node->pkt->pkt.user_id->name);
+ }
+ return node->pkt->pkt.user_id->mbox;
+ }
+ else if (!strcmp (propname, "primary"))
+ result = node->pkt->pkt.user_id->is_primary? "1":"0";
+ else
+ result = NULL;
+ }
+ else
+ result = NULL;
+
+ return result;
+}
+
+/*
+ * Apply the keep-uid filter to the keyblock. The deleted nodes are
+ * marked and thus the caller should call commit_kbnode afterwards.
+ * KEYBLOCK must not have any blocks marked as deleted.
+ */
+static void
+apply_keep_uid_filter (kbnode_t keyblock, recsel_expr_t selector)
+{
+ kbnode_t node;
+
+ for (node = keyblock->next; node; node = node->next )
+ {
+ if (node->pkt->pkttype == PKT_USER_ID)
+ {
+ if (!recsel_select (selector, filter_getval, node))
+ {
+
+ /* log_debug ("keep-uid: deleting '%s'\n", */
+ /* node->pkt->pkt.user_id->name); */
+ /* The UID packet and all following packets up to the
+ * next UID or a subkey. */
+ delete_kbnode (node);
+ for (; node->next
+ && node->next->pkt->pkttype != PKT_USER_ID
+ && node->next->pkt->pkttype != PKT_PUBLIC_SUBKEY
+ && node->next->pkt->pkttype != PKT_SECRET_SUBKEY ;
+ node = node->next)
+ delete_kbnode (node->next);
+ }
+ /* else */
+ /* log_debug ("keep-uid: keeping '%s'\n", */
+ /* node->pkt->pkt.user_id->name); */
+ }
+ }
+}
+
+
/*
* Try to import one keyblock. Return an error only in serious cases,
* but never for an invalid keyblock. It uses log_error to increase
@@ -930,13 +1174,13 @@ check_prefs (ctrl_t ctrl, kbnode_t keyblock)
*/
static int
import_one (ctrl_t ctrl,
- const char *fname, kbnode_t keyblock, struct import_stats_s *stats,
+ kbnode_t keyblock, struct import_stats_s *stats,
unsigned char **fpr, size_t *fpr_len, unsigned int options,
int from_sk, int silent,
import_screener_t screener, void *screener_arg)
{
PKT_public_key *pk;
- PKT_public_key *pk_orig;
+ PKT_public_key *pk_orig = NULL;
kbnode_t node, uidnode;
kbnode_t keyblock_orig = NULL;
byte fpr2[MAX_FINGERPRINT_LEN];
@@ -949,6 +1193,7 @@ import_one (ctrl_t ctrl,
int non_self = 0;
size_t an;
char pkstrbuf[PUBKEY_STRING_SIZE];
+ int merge_keys_done = 0;
/* Get the key and print some info about it. */
node = find_kbnode( keyblock, PKT_PUBLIC_KEY );
@@ -1019,26 +1264,28 @@ import_one (ctrl_t ctrl,
log_info (_("key %s: PKS subkey corruption repaired\n"),
keystr_from_pk(pk));
- rc = chk_self_sigs( fname, keyblock , pk, keyid, &non_self );
- if (rc )
- return rc== -1? 0:rc;
+ if (chk_self_sigs (keyblock, keyid, &non_self))
+ return 0; /* Invalid keyblock - error already printed. */
/* If we allow such a thing, mark unsigned uids as valid */
if (opt.allow_non_selfsigned_uid)
{
for (node=keyblock; node; node = node->next )
- if (node->pkt->pkttype == PKT_USER_ID && !(node->flag & 1) )
+ if (node->pkt->pkttype == PKT_USER_ID
+ && !(node->flag & NODE_GOOD_SELFSIG)
+ && !(node->flag & NODE_BAD_SELFSIG) )
{
char *user=utf8_to_native(node->pkt->pkt.user_id->name,
node->pkt->pkt.user_id->len,0);
- node->flag |= 1;
+ /* Fake a good signature status for the user id. */
+ node->flag |= NODE_GOOD_SELFSIG;
log_info( _("key %s: accepted non self-signed user ID \"%s\"\n"),
keystr_from_pk(pk),user);
xfree(user);
}
}
- if (!delete_inv_parts( fname, keyblock, keyid, options ) )
+ if (!delete_inv_parts (keyblock, keyid, options ) )
{
if (!silent)
{
@@ -1050,6 +1297,46 @@ import_one (ctrl_t ctrl,
return 0;
}
+ /* Get rid of deleted nodes. */
+ commit_kbnode (&keyblock);
+
+ /* Apply import filter. */
+ if (import_keep_uid)
+ {
+ apply_keep_uid_filter (keyblock, import_keep_uid);
+ commit_kbnode (&keyblock);
+ }
+
+
+ /* Show the key in the form it is merged or inserted. We skip this
+ * if "import-export" is also active without --armor or the output
+ * file has explicily been given. */
+ if ((options & IMPORT_SHOW)
+ && !((options & IMPORT_EXPORT) && !opt.armor && !opt.outfile))
+ {
+ merge_keys_and_selfsig (keyblock);
+ merge_keys_done = 1;
+ /* Note that we do not want to show the validity because the key
+ * has not yet imported. */
+ list_keyblock_direct (ctrl, keyblock, 0, 0, 1, 1);
+ es_fflush (es_stdout);
+ }
+
+ /* Write the keyblock to the output and do not actually import. */
+ if ((options & IMPORT_EXPORT))
+ {
+ if (!merge_keys_done)
+ {
+ merge_keys_and_selfsig (keyblock);
+ merge_keys_done = 1;
+ }
+ rc = write_keyblock_to_output (keyblock, opt.armor, opt.export_options);
+ goto leave;
+ }
+
+ if (opt.dry_run)
+ goto leave;
+
/* Do we have this key already in one of our pubrings ? */
pk_orig = xmalloc_clear( sizeof *pk_orig );
rc = get_pubkey_byfprint_fast (pk_orig, fpr2, fpr2len);
@@ -1170,7 +1457,7 @@ import_one (ctrl_t ctrl,
clear_kbnode_flags( keyblock_orig );
clear_kbnode_flags( keyblock );
n_uids = n_sigs = n_subk = n_uids_cleaned = 0;
- rc = merge_blocks( fname, keyblock_orig, keyblock,
+ rc = merge_blocks (keyblock_orig, keyblock,
keyid, &n_uids, &n_sigs, &n_subk );
if (rc )
{
@@ -1258,7 +1545,7 @@ import_one (ctrl_t ctrl,
keydb_release (hd); hd = NULL;
}
- leave:
+ leave:
if (mod_key || new_key || same_key)
{
/* A little explanation for this: we fill in the fingerprint
@@ -1429,6 +1716,7 @@ transfer_secret_keys (ctrl_t ctrl, struct import_stats_s *stats,
else
{
const char *curvename = openpgp_oid_to_curve (curvestr, 1);
+ gcry_sexp_release (curve);
err = gcry_sexp_build (&curve, NULL, "(curve %s)",
curvename?curvename:curvestr);
xfree (curvestr);
@@ -1654,7 +1942,7 @@ sec_to_pub_keyblock (kbnode_t sec_keyblock)
* with the trust calculation.
*/
static int
-import_secret_one (ctrl_t ctrl, const char *fname, kbnode_t keyblock,
+import_secret_one (ctrl_t ctrl, kbnode_t keyblock,
struct import_stats_s *stats, int batch, unsigned int options,
int for_migration,
import_screener_t screener, void *screener_arg)
@@ -1754,7 +2042,7 @@ import_secret_one (ctrl_t ctrl, const char *fname, kbnode_t keyblock,
/* Note that this outputs an IMPORT_OK status message for the
public key block, and below we will output another one for
the secret keys. FIXME? */
- import_one (ctrl, fname, pub_keyblock, stats,
+ import_one (ctrl, pub_keyblock, stats,
NULL, NULL, options, 1, for_migration,
screener, screener_arg);
@@ -1822,8 +2110,7 @@ import_secret_one (ctrl_t ctrl, const char *fname, kbnode_t keyblock,
* Import a revocation certificate; this is a single signature packet.
*/
static int
-import_revoke_cert (const char *fname, kbnode_t node,
- struct import_stats_s *stats)
+import_revoke_cert (kbnode_t node, struct import_stats_s *stats)
{
PKT_public_key *pk = NULL;
kbnode_t onode;
@@ -1832,8 +2119,6 @@ import_revoke_cert (const char *fname, kbnode_t node,
u32 keyid[2];
int rc = 0;
- (void)fname;
-
log_assert (!node->next );
log_assert (node->pkt->pkttype == PKT_SIGNATURE );
log_assert (node->pkt->pkt.signature->sig_class == 0x20 );
@@ -1949,18 +2234,21 @@ import_revoke_cert (const char *fname, kbnode_t node,
}
-/*
- * Loop over the keyblock and check all self signatures.
- * Mark all user-ids with a self-signature by setting flag bit 0.
- * Mark all user-ids with an invalid self-signature by setting bit 1.
- * This works also for subkeys, here the subkey is marked. Invalid or
- * extra subkey sigs (binding or revocation) are marked for deletion.
- * non_self is set to true if there are any sigs other than self-sigs
+/* Loop over the keyblock and check all self signatures. On return
+ * the following bis in the node flags are set:
+ *
+ * - NODE_GOOD_SELFSIG :: User ID or subkey has a self-signature
+ * - NODE_BAD_SELFSIG :: Used ID or subkey has an invalid self-signature
+ * - NODE_DELETION_MARK :: This node shall be deleted
+ *
+ * NON_SELF is set to true if there are any sigs other than self-sigs
* in this keyblock.
+ *
+ * Returns 0 on success or -1 (but not an error code) if the keyblock
+ * is invalid.
*/
static int
-chk_self_sigs (const char *fname, kbnode_t keyblock,
- PKT_public_key *pk, u32 *keyid, int *non_self )
+chk_self_sigs (kbnode_t keyblock, u32 *keyid, int *non_self )
{
kbnode_t n, knode = NULL;
PKT_signature *sig;
@@ -1968,9 +2256,6 @@ chk_self_sigs (const char *fname, kbnode_t keyblock,
u32 bsdate=0, rsdate=0;
kbnode_t bsnode = NULL, rsnode = NULL;
- (void)fname;
- (void)pk;
-
for (n=keyblock; (n = find_next_kbnode (n, 0)); )
{
if (n->pkt->pkttype == PKT_PUBLIC_SUBKEY)
@@ -2009,7 +2294,7 @@ chk_self_sigs (const char *fname, kbnode_t keyblock,
}
/* If it hasn't been marked valid yet, keep trying. */
- if (!(unode->flag&1))
+ if (!(unode->flag & NODE_GOOD_SELFSIG))
{
rc = check_key_signature (keyblock, n, NULL);
if ( rc )
@@ -2029,7 +2314,7 @@ chk_self_sigs (const char *fname, kbnode_t keyblock,
}
}
else
- unode->flag |= 1; /* Mark that signature checked. */
+ unode->flag |= NODE_GOOD_SELFSIG;
}
}
else if (IS_KEY_SIG (sig))
@@ -2042,7 +2327,7 @@ chk_self_sigs (const char *fname, kbnode_t keyblock,
_("key %s: unsupported public key algorithm\n"):
_("key %s: invalid direct key signature\n"),
keystr (keyid));
- n->flag |= 4;
+ n->flag |= NODE_DELETION_MARK;
}
}
else if ( IS_SUBKEY_SIG (sig) )
@@ -2056,7 +2341,7 @@ chk_self_sigs (const char *fname, kbnode_t keyblock,
if (opt.verbose)
log_info (_("key %s: no subkey for key binding\n"),
keystr (keyid));
- n->flag |= 4; /* delete this */
+ n->flag |= NODE_DELETION_MARK;
}
else
{
@@ -2069,19 +2354,19 @@ chk_self_sigs (const char *fname, kbnode_t keyblock,
" algorithm\n"):
_("key %s: invalid subkey binding\n"),
keystr (keyid));
- n->flag |= 4;
+ n->flag |= NODE_DELETION_MARK;
}
else
{
/* It's valid, so is it newer? */
if (sig->timestamp >= bsdate)
{
- knode->flag |= 1; /* The subkey is valid. */
+ knode->flag |= NODE_GOOD_SELFSIG; /* Subkey is valid. */
if (bsnode)
{
/* Delete the last binding sig since this
one is newer */
- bsnode->flag |= 4;
+ bsnode->flag |= NODE_DELETION_MARK;
if (opt.verbose)
log_info (_("key %s: removed multiple subkey"
" binding\n"),keystr(keyid));
@@ -2091,7 +2376,7 @@ chk_self_sigs (const char *fname, kbnode_t keyblock,
bsdate = sig->timestamp;
}
else
- n->flag |= 4; /* older */
+ n->flag |= NODE_DELETION_MARK; /* older */
}
}
}
@@ -2107,7 +2392,7 @@ chk_self_sigs (const char *fname, kbnode_t keyblock,
if (opt.verbose)
log_info (_("key %s: no subkey for key revocation\n"),
keystr(keyid));
- n->flag |= 4; /* delete this */
+ n->flag |= NODE_DELETION_MARK;
}
else
{
@@ -2120,7 +2405,7 @@ chk_self_sigs (const char *fname, kbnode_t keyblock,
" key algorithm\n"):
_("key %s: invalid subkey revocation\n"),
keystr(keyid));
- n->flag |= 4;
+ n->flag |= NODE_DELETION_MARK;
}
else
{
@@ -2131,7 +2416,7 @@ chk_self_sigs (const char *fname, kbnode_t keyblock,
{
/* Delete the last revocation sig since
this one is newer. */
- rsnode->flag |= 4;
+ rsnode->flag |= NODE_DELETION_MARK;
if (opt.verbose)
log_info (_("key %s: removed multiple subkey"
" revocation\n"),keystr(keyid));
@@ -2141,7 +2426,7 @@ chk_self_sigs (const char *fname, kbnode_t keyblock,
rsdate = sig->timestamp;
}
else
- n->flag |= 4; /* older */
+ n->flag |= NODE_DELETION_MARK; /* older */
}
}
}
@@ -2151,28 +2436,25 @@ chk_self_sigs (const char *fname, kbnode_t keyblock,
}
-/****************
- * delete all parts which are invalid and those signatures whose
- * public key algorithm is not available in this implemenation;
- * but consider RSA as valid, because parse/build_packets knows
- * about it.
- * returns: true if at least one valid user-id is left over.
+/* Delete all parts which are invalid and those signatures whose
+ * public key algorithm is not available in this implemenation; but
+ * consider RSA as valid, because parse/build_packets knows about it.
+ *
+ * Returns: True if at least one valid user-id is left over.
*/
static int
-delete_inv_parts( const char *fname, kbnode_t keyblock,
- u32 *keyid, unsigned int options)
+delete_inv_parts (kbnode_t keyblock, u32 *keyid, unsigned int options)
{
kbnode_t node;
int nvalid=0, uid_seen=0, subkey_seen=0;
- (void)fname;
-
for (node=keyblock->next; node; node = node->next )
{
if (node->pkt->pkttype == PKT_USER_ID)
{
uid_seen = 1;
- if ((node->flag & 2) || !(node->flag & 1) )
+ if ((node->flag & NODE_BAD_SELFSIG)
+ || !(node->flag & NODE_GOOD_SELFSIG))
{
if (opt.verbose )
{
@@ -2198,7 +2480,8 @@ delete_inv_parts( const char *fname, kbnode_t keyblock,
else if ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
|| node->pkt->pkttype == PKT_SECRET_SUBKEY )
{
- if ((node->flag & 2) || !(node->flag & 1) )
+ if ((node->flag & NODE_BAD_SELFSIG)
+ || !(node->flag & NODE_GOOD_SELFSIG))
{
if (opt.verbose )
log_info( _("key %s: skipped subkey\n"),keystr(keyid));
@@ -2286,7 +2569,7 @@ delete_inv_parts( const char *fname, kbnode_t keyblock,
node->pkt->pkt.signature->sig_class);
delete_kbnode(node);
}
- else if ((node->flag & 4) ) /* marked for deletion */
+ else if ((node->flag & NODE_DELETION_MARK))
delete_kbnode( node );
}
@@ -2513,10 +2796,10 @@ revocation_present (ctrl_t ctrl, kbnode_t keyblock)
* the signature's public key yet; verification is done when putting it
* into the trustdb, which is done automagically as soon as this pubkey
* is used.
- * Note: We indicate newly inserted packets with flag bit 0
+ * Note: We indicate newly inserted packets with NODE_FLAG_A.
*/
static int
-merge_blocks (const char *fname, kbnode_t keyblock_orig, kbnode_t keyblock,
+merge_blocks (kbnode_t keyblock_orig, kbnode_t keyblock,
u32 *keyid, int *n_uids, int *n_sigs, int *n_subk )
{
kbnode_t onode, node;
@@ -2549,7 +2832,7 @@ merge_blocks (const char *fname, kbnode_t keyblock_orig, kbnode_t keyblock,
{
kbnode_t n2 = clone_kbnode(node);
insert_kbnode( keyblock_orig, n2, 0 );
- n2->flag |= 1;
+ n2->flag |= NODE_FLAG_A;
++*n_sigs;
if(!opt.quiet)
{
@@ -2589,7 +2872,7 @@ merge_blocks (const char *fname, kbnode_t keyblock_orig, kbnode_t keyblock,
{
kbnode_t n2 = clone_kbnode(node);
insert_kbnode( keyblock_orig, n2, 0 );
- n2->flag |= 1;
+ n2->flag |= NODE_FLAG_A;
++*n_sigs;
if(!opt.quiet)
log_info( _("key %s: direct key signature added\n"),
@@ -2601,7 +2884,7 @@ merge_blocks (const char *fname, kbnode_t keyblock_orig, kbnode_t keyblock,
/* 3rd: try to merge new certificates in */
for (onode=keyblock_orig->next; onode; onode=onode->next)
{
- if (!(onode->flag & 1) && onode->pkt->pkttype == PKT_USER_ID)
+ if (!(onode->flag & NODE_FLAG_A) && onode->pkt->pkttype == PKT_USER_ID)
{
/* find the user id in the imported keyblock */
for (node=keyblock->next; node; node=node->next)
@@ -2611,7 +2894,7 @@ merge_blocks (const char *fname, kbnode_t keyblock_orig, kbnode_t keyblock,
break;
if (node ) /* found: merge */
{
- rc = merge_sigs( onode, node, n_sigs, fname, keyid );
+ rc = merge_sigs (onode, node, n_sigs);
if (rc )
return rc;
}
@@ -2631,7 +2914,7 @@ merge_blocks (const char *fname, kbnode_t keyblock_orig, kbnode_t keyblock,
break;
if (!onode ) /* this is a new user id: append */
{
- rc = append_uid( keyblock_orig, node, n_sigs, fname, keyid);
+ rc = append_uid (keyblock_orig, node, n_sigs);
if (rc )
return rc;
++*n_uids;
@@ -2653,7 +2936,7 @@ merge_blocks (const char *fname, kbnode_t keyblock_orig, kbnode_t keyblock,
break;
if (!onode ) /* This is a new subkey: append. */
{
- rc = append_key (keyblock_orig, node, n_sigs, fname, keyid);
+ rc = append_key (keyblock_orig, node, n_sigs);
if (rc)
return rc;
++*n_subk;
@@ -2669,7 +2952,7 @@ merge_blocks (const char *fname, kbnode_t keyblock_orig, kbnode_t keyblock,
break;
if (!onode ) /* This is a new subkey: append. */
{
- rc = append_key (keyblock_orig, node, n_sigs, fname, keyid);
+ rc = append_key (keyblock_orig, node, n_sigs);
if (rc )
return rc;
++*n_subk;
@@ -2680,7 +2963,7 @@ merge_blocks (const char *fname, kbnode_t keyblock_orig, kbnode_t keyblock,
/* 6th: merge subkey certificates */
for (onode=keyblock_orig->next; onode; onode=onode->next)
{
- if (!(onode->flag & 1)
+ if (!(onode->flag & NODE_FLAG_A)
&& (onode->pkt->pkttype == PKT_PUBLIC_SUBKEY
|| onode->pkt->pkttype == PKT_SECRET_SUBKEY))
{
@@ -2695,7 +2978,7 @@ merge_blocks (const char *fname, kbnode_t keyblock_orig, kbnode_t keyblock,
}
if (node) /* Found: merge. */
{
- rc = merge_keysigs( onode, node, n_sigs, fname, keyid );
+ rc = merge_keysigs( onode, node, n_sigs);
if (rc )
return rc;
}
@@ -2706,19 +2989,15 @@ merge_blocks (const char *fname, kbnode_t keyblock_orig, kbnode_t keyblock,
}
-/*
+/* Helper function for merge_blocks.
* Append the userid starting with NODE and all signatures to KEYBLOCK.
*/
static int
-append_uid (kbnode_t keyblock, kbnode_t node, int *n_sigs,
- const char *fname, u32 *keyid )
+append_uid (kbnode_t keyblock, kbnode_t node, int *n_sigs)
{
kbnode_t n;
kbnode_t n_where = NULL;
- (void)fname;
- (void)keyid;
-
log_assert (node->pkt->pkttype == PKT_USER_ID );
/* find the position */
@@ -2744,8 +3023,8 @@ append_uid (kbnode_t keyblock, kbnode_t node, int *n_sigs,
}
else
add_kbnode( keyblock, n );
- n->flag |= 1;
- node->flag |= 1;
+ n->flag |= NODE_FLAG_A;
+ node->flag |= NODE_FLAG_A;
if (n->pkt->pkttype == PKT_SIGNATURE )
++*n_sigs;
@@ -2758,20 +3037,16 @@ append_uid (kbnode_t keyblock, kbnode_t node, int *n_sigs,
}
-/*
+/* Helper function for merge_blocks
* Merge the sigs from SRC onto DST. SRC and DST are both a PKT_USER_ID.
* (how should we handle comment packets here?)
*/
static int
-merge_sigs (kbnode_t dst, kbnode_t src, int *n_sigs,
- const char *fname, u32 *keyid)
+merge_sigs (kbnode_t dst, kbnode_t src, int *n_sigs)
{
kbnode_t n, n2;
int found = 0;
- (void)fname;
- (void)keyid;
-
log_assert (dst->pkt->pkttype == PKT_USER_ID);
log_assert (src->pkt->pkttype == PKT_USER_ID);
@@ -2797,8 +3072,8 @@ merge_sigs (kbnode_t dst, kbnode_t src, int *n_sigs,
* one is released first */
n2 = clone_kbnode(n);
insert_kbnode( dst, n2, PKT_SIGNATURE );
- n2->flag |= 1;
- n->flag |= 1;
+ n2->flag |= NODE_FLAG_A;
+ n->flag |= NODE_FLAG_A;
++*n_sigs;
}
}
@@ -2807,19 +3082,15 @@ merge_sigs (kbnode_t dst, kbnode_t src, int *n_sigs,
}
-/*
+/* Helper function for merge_blocks
* Merge the sigs from SRC onto DST. SRC and DST are both a PKT_xxx_SUBKEY.
*/
static int
-merge_keysigs (kbnode_t dst, kbnode_t src, int *n_sigs,
- const char *fname, u32 *keyid)
+merge_keysigs (kbnode_t dst, kbnode_t src, int *n_sigs)
{
kbnode_t n, n2;
int found = 0;
- (void)fname;
- (void)keyid;
-
log_assert (dst->pkt->pkttype == PKT_PUBLIC_SUBKEY
|| dst->pkt->pkttype == PKT_SECRET_SUBKEY);
@@ -2858,8 +3129,8 @@ merge_keysigs (kbnode_t dst, kbnode_t src, int *n_sigs,
* one is released first */
n2 = clone_kbnode(n);
insert_kbnode( dst, n2, PKT_SIGNATURE );
- n2->flag |= 1;
- n->flag |= 1;
+ n2->flag |= NODE_FLAG_A;
+ n->flag |= NODE_FLAG_A;
++*n_sigs;
}
}
@@ -2868,19 +3139,15 @@ merge_keysigs (kbnode_t dst, kbnode_t src, int *n_sigs,
}
-/*
+/* Helper function for merge_blocks.
* Append the subkey starting with NODE and all signatures to KEYBLOCK.
* Mark all new and copied packets by setting flag bit 0.
*/
static int
-append_key (kbnode_t keyblock, kbnode_t node, int *n_sigs,
- const char *fname, u32 *keyid)
+append_key (kbnode_t keyblock, kbnode_t node, int *n_sigs)
{
kbnode_t n;
- (void)fname;
- (void)keyid;
-
log_assert (node->pkt->pkttype == PKT_PUBLIC_SUBKEY
|| node->pkt->pkttype == PKT_SECRET_SUBKEY);
@@ -2890,8 +3157,8 @@ append_key (kbnode_t keyblock, kbnode_t node, int *n_sigs,
* one is released first */
n = clone_kbnode(node);
add_kbnode( keyblock, n );
- n->flag |= 1;
- node->flag |= 1;
+ n->flag |= NODE_FLAG_A;
+ node->flag |= NODE_FLAG_A;
if (n->pkt->pkttype == PKT_SIGNATURE )
++*n_sigs;