diff --git a/g10/import.c b/g10/import.c index e4b05f784..8cfd6eae0 100644 --- a/g10/import.c +++ b/g10/import.c @@ -64,6 +64,18 @@ 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. * @@ -82,32 +94,26 @@ 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); @@ -391,16 +397,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); @@ -464,7 +470,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) @@ -770,8 +776,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; } @@ -1118,7 +1124,7 @@ apply_keep_uid_filter (kbnode_t keyblock, recsel_expr_t selector) */ 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) @@ -1208,26 +1214,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) { @@ -1399,7 +1407,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 ) { @@ -1884,7 +1892,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) @@ -1984,7 +1992,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); @@ -2052,8 +2060,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; @@ -2062,8 +2069,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 ); @@ -2179,18 +2184,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; @@ -2198,9 +2206,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) @@ -2239,7 +2244,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 ) @@ -2259,7 +2264,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)) @@ -2272,7 +2277,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) ) @@ -2286,7 +2291,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 { @@ -2299,19 +2304,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)); @@ -2321,7 +2326,7 @@ chk_self_sigs (const char *fname, kbnode_t keyblock, bsdate = sig->timestamp; } else - n->flag |= 4; /* older */ + n->flag |= NODE_DELETION_MARK; /* older */ } } } @@ -2337,7 +2342,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 { @@ -2350,7 +2355,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 { @@ -2361,7 +2366,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)); @@ -2371,7 +2376,7 @@ chk_self_sigs (const char *fname, kbnode_t keyblock, rsdate = sig->timestamp; } else - n->flag |= 4; /* older */ + n->flag |= NODE_DELETION_MARK; /* older */ } } } @@ -2381,28 +2386,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 ) { @@ -2428,7 +2430,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)); @@ -2516,7 +2519,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 ); } @@ -2743,10 +2746,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; @@ -2779,7 +2782,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) { @@ -2819,7 +2822,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"), @@ -2831,7 +2834,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) @@ -2841,7 +2844,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; } @@ -2861,7 +2864,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; @@ -2883,7 +2886,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; @@ -2899,7 +2902,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; @@ -2910,7 +2913,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)) { @@ -2925,7 +2928,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; } @@ -2936,19 +2939,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 */ @@ -2974,8 +2973,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; @@ -2988,20 +2987,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); @@ -3027,8 +3022,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; } } @@ -3037,19 +3032,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); @@ -3088,8 +3079,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; } } @@ -3098,19 +3089,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); @@ -3120,8 +3107,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;