diff options
Diffstat (limited to 'g10/import.c')
-rw-r--r-- | g10/import.c | 579 |
1 files changed, 464 insertions, 115 deletions
diff --git a/g10/import.c b/g10/import.c index 73f795cd9..c2a1dd033 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, 2016, 2017 Werner Koch + * Copyright (C) 2014, 2016, 2017, 2019 Werner Koch * * This file is part of GnuPG. * @@ -75,6 +75,8 @@ struct import_stats_s #define NODE_DELETION_MARK 4 /* A node flag used to temporary mark a node. */ #define NODE_FLAG_A 8 +/* A flag used by transfer_secret_keys. */ +#define NODE_TRANSFER_SECKEY 16 /* An object and a global instance to store selectors created from @@ -109,11 +111,16 @@ static gpg_error_t import_one (ctrl_t ctrl, unsigned char **fpr, size_t *fpr_len, unsigned int options, int from_sk, int silent, import_screener_t screener, void *screener_arg, - int origin, const char *url); -static int import_secret_one (ctrl_t ctrl, kbnode_t keyblock, + int origin, const char *url, int *r_valid); +static gpg_error_t import_matching_seckeys ( + ctrl_t ctrl, kbnode_t seckeys, + const byte *mainfpr, size_t mainfprlen, + struct import_stats_s *stats, int batch); +static gpg_error_t 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); + import_screener_t screener, void *screener_arg, + kbnode_t *r_secattic); static int import_revoke_cert (ctrl_t ctrl, kbnode_t node, unsigned int options, struct import_stats_s *stats); static int chk_self_sigs (ctrl_t ctrl, kbnode_t keyblock, u32 *keyid, @@ -121,6 +128,7 @@ static int chk_self_sigs (ctrl_t ctrl, kbnode_t keyblock, u32 *keyid, static int delete_inv_parts (ctrl_t ctrl, kbnode_t keyblock, u32 *keyid, unsigned int options); static int any_uid_left (kbnode_t keyblock); +static int remove_all_uids (kbnode_t *keyblock); static int merge_blocks (ctrl_t ctrl, unsigned int options, kbnode_t keyblock_orig, kbnode_t keyblock, u32 *keyid, @@ -181,6 +189,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-drop-uids", IMPORT_DROP_UIDS, NULL, + N_("Do not import user id or attribute packets")}, + {"import-export", IMPORT_EXPORT, NULL, N_("run import filters and export key immediately")}, @@ -562,6 +573,7 @@ import (ctrl_t ctrl, IOBUF inp, const char* fname,struct import_stats_s *stats, kbnode_t keyblock = NULL; /* Need to initialize because gcc can't grasp the return semantics of read_block. */ + kbnode_t secattic = NULL; /* Kludge for PGP desktop percularity */ int rc = 0; int v3keys; @@ -582,18 +594,63 @@ 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, keyblock, - stats, fpr, fpr_len, options, 0, 0, - screener, screener_arg, origin, url); + { + rc = import_one (ctrl, keyblock, + stats, fpr, fpr_len, options, 0, 0, + screener, screener_arg, origin, url, NULL); + if (secattic) + { + byte tmpfpr[MAX_FINGERPRINT_LEN]; + size_t tmpfprlen; + + if (!rc && !(opt.dry_run || (options & IMPORT_DRY_RUN))) + { + /* Kudge for PGP desktop - see below. */ + fingerprint_from_pk (keyblock->pkt->pkt.public_key, + tmpfpr, &tmpfprlen); + rc = import_matching_seckeys (ctrl, secattic, + tmpfpr, tmpfprlen, + stats, opt.batch); + } + release_kbnode (secattic); + secattic = NULL; + } + } else if (keyblock->pkt->pkttype == PKT_SECRET_KEY) - rc = import_secret_one (ctrl, keyblock, stats, - opt.batch, options, 0, - screener, screener_arg); + { + release_kbnode (secattic); + secattic = NULL; + rc = import_secret_one (ctrl, keyblock, stats, + opt.batch, options, 0, + screener, screener_arg, &secattic); + keyblock = NULL; /* Ownership was transferred. */ + if (secattic) + { + if (gpg_err_code (rc) == GPG_ERR_NO_PUBKEY) + rc = 0; /* Try import after the next pubkey. */ + + /* The attic is a workaround for the peculiar PGP + * Desktop method of exporting a secret key: The + * exported file is the concatenation of two armored + * keyblocks; first the private one and then the public + * one. The strange thing is that the secret one has no + * binding signatures at all and thus we have not + * imported it. The attic stores that secret keys and + * we try to import it once after the very next public + * keyblock. */ + } + } else if (keyblock->pkt->pkttype == PKT_SIGNATURE && IS_KEY_REV (keyblock->pkt->pkt.signature) ) - rc = import_revoke_cert (ctrl, keyblock, options, stats); + { + release_kbnode (secattic); + secattic = NULL; + rc = import_revoke_cert (ctrl, keyblock, options, stats); + } else { + release_kbnode (secattic); + secattic = NULL; log_info (_("skipping block of type %d\n"), keyblock->pkt->pkttype); } release_kbnode (keyblock); @@ -619,6 +676,7 @@ import (ctrl_t ctrl, IOBUF inp, const char* fname,struct import_stats_s *stats, else if (rc && gpg_err_code (rc) != GPG_ERR_INV_KEYRING) log_error (_("error reading '%s': %s\n"), fname, gpg_strerror (rc)); + release_kbnode (secattic); return rc; } @@ -655,8 +713,11 @@ import_old_secring (ctrl_t ctrl, const char *fname) while (!(err = read_block (inp, 0, &pending_pkt, &keyblock, &v3keys))) { if (keyblock->pkt->pkttype == PKT_SECRET_KEY) - err = import_secret_one (ctrl, keyblock, stats, 1, 0, 1, - NULL, NULL); + { + err = import_secret_one (ctrl, keyblock, stats, 1, 0, 1, + NULL, NULL, NULL); + keyblock = NULL; /* Ownership was transferred. */ + } release_kbnode (keyblock); if (err) break; @@ -924,6 +985,8 @@ read_block( IOBUF a, int with_meta, add_kbnode (root, new_kbnode (pkt)); pkt = xmalloc (sizeof *pkt); } + else + free_packet (pkt, &parsectx); init_packet(pkt); break; } @@ -1078,23 +1141,14 @@ print_import_ok (PKT_public_key *pk, unsigned int reason) static void print_import_check (PKT_public_key * pk, PKT_user_id * id) { - char * buf; - byte fpr[24]; + byte hexfpr[2*MAX_FINGERPRINT_LEN+1]; u32 keyid[2]; - size_t i, n; - size_t pos = 0; - buf = xmalloc (17+41+id->len+32); keyid_from_pk (pk, keyid); - sprintf (buf, "%08X%08X ", keyid[0], keyid[1]); - pos = 17; - fingerprint_from_pk (pk, fpr, &n); - for (i = 0; i < n; i++, pos += 2) - sprintf (buf+pos, "%02X", fpr[i]); - strcat (buf, " "); - strcat (buf, id->name); - write_status_text (STATUS_IMPORT_CHECK, buf); - xfree (buf); + hexfingerprint (pk, hexfpr, sizeof hexfpr); + write_status_printf (STATUS_IMPORT_CHECK, "%08X%08X %s %s", + keyid[0], keyid[1], hexfpr, id->name); + } @@ -1258,7 +1312,7 @@ impex_filter_getval (void *cookie, const char *propname) { if (!uid->mbox) { - uid->mbox = mailbox_from_userid (uid->name); + uid->mbox = mailbox_from_userid (uid->name, 0); } result = uid->mbox; } @@ -1669,7 +1723,10 @@ update_key_origin (kbnode_t keyblock, u32 curtime, int origin, const char *url) * the internal errorcount, so that invalid input can be detected by * programs which called gpg. If SILENT is no messages are printed - * even most error messages are suppressed. ORIGIN is the origin of - * the key (0 for unknown) and URL the corresponding URL. + * the key (0 for unknown) and URL the corresponding URL. FROM_SK + * indicates that the key has been made from a secret key. If R_SAVED + * is not NULL a boolean will be stored indicating whether the keyblock + * has valid parts. */ static gpg_error_t import_one (ctrl_t ctrl, @@ -1677,7 +1734,7 @@ import_one (ctrl_t ctrl, unsigned char **fpr, size_t *fpr_len, unsigned int options, int from_sk, int silent, import_screener_t screener, void *screener_arg, - int origin, const char *url) + int origin, const char *url, int *r_valid) { gpg_error_t err = 0; PKT_public_key *pk; @@ -1696,6 +1753,9 @@ import_one (ctrl_t ctrl, int any_filter = 0; KEYDB_HANDLE hd = NULL; + if (r_valid) + *r_valid = 0; + /* If show-only is active we don't won't any extra output. */ if ((options & (IMPORT_SHOW | IMPORT_DRY_RUN))) silent = 1; @@ -1713,9 +1773,11 @@ import_one (ctrl_t ctrl, keyid_from_pk( pk, keyid ); uidnode = find_next_kbnode( keyblock, PKT_USER_ID ); - if (opt.verbose && !opt.interactive && !silent) + if (opt.verbose && !opt.interactive && !silent && !from_sk) { - log_info( "pub %s/%s %s ", + /* Note that we do not print this info in FROM_SK mode + * because import_secret_one already printed that. */ + log_info ("pub %s/%s %s ", pubkey_string (pk, pkstrbuf, sizeof pkstrbuf), keystr_from_pk(pk), datestr_from_pk(pk) ); if (uidnode) @@ -1726,7 +1788,9 @@ import_one (ctrl_t ctrl, } - if (!uidnode ) + /* Unless import-drop-uids has been requested we don't allow import + * of a key without UIDs. */ + if (!uidnode && !(options & IMPORT_DROP_UIDS)) { if (!silent) log_error( _("key %s: no user ID\n"), keystr_from_pk(pk)); @@ -1746,14 +1810,18 @@ import_one (ctrl_t ctrl, print_import_check (pk, uidnode->pkt->pkt.user_id); merge_keys_and_selfsig (ctrl, keyblock); tty_printf ("\n"); - show_basic_key_info (ctrl, keyblock); + show_basic_key_info (ctrl, keyblock, from_sk); tty_printf ("\n"); if (!cpr_get_answer_is_yes ("import.okay", "Do you want to import this key? (y/N) ")) return 0; } - collapse_uids(&keyblock); + /* Remove or collapse the user ids. */ + if ((options & IMPORT_DROP_UIDS)) + remove_all_uids (&keyblock); + else + collapse_uids (&keyblock); /* Clean the key that we're about to import, to cut down on things that we have to clean later. This has no practical impact on the @@ -1800,7 +1868,10 @@ import_one (ctrl_t ctrl, } } - if (!delete_inv_parts (ctrl, keyblock, keyid, options ) ) + /* Delete invalid parts and without the drop option bail out if + * there are no user ids. */ + if (!delete_inv_parts (ctrl, keyblock, keyid, options) + && !(options & IMPORT_DROP_UIDS) ) { if (!silent) { @@ -1840,6 +1911,10 @@ import_one (ctrl_t ctrl, return 0; } + /* The keyblock is valid and ready for real import. */ + if (r_valid) + *r_valid = 1; + /* 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. */ @@ -2163,12 +2238,15 @@ import_one (ctrl_t ctrl, /* Transfer all the secret keys in SEC_KEYBLOCK to the gpg-agent. The - function prints diagnostics and returns an error code. If BATCH is - true the secret keys are stored by gpg-agent in the transfer format - (i.e. no re-protection and aksing for passphrases). */ + * function prints diagnostics and returns an error code. If BATCH is + * true the secret keys are stored by gpg-agent in the transfer format + * (i.e. no re-protection and aksing for passphrases). If ONLY_MARKED + * is set, only those nodes with flag NODE_TRANSFER_SECKEY are + * processed. */ gpg_error_t transfer_secret_keys (ctrl_t ctrl, struct import_stats_s *stats, - kbnode_t sec_keyblock, int batch, int force) + kbnode_t sec_keyblock, int batch, int force, + int only_marked) { gpg_error_t err = 0; void *kek = NULL; @@ -2209,12 +2287,16 @@ transfer_secret_keys (ctrl_t ctrl, struct import_stats_s *stats, xfree (kek); kek = NULL; + /* Note: We need to use walk_kbnode so that we skip nodes which are + * marked as deleted. */ main_pk = NULL; while ((node = walk_kbnode (sec_keyblock, &ctx, 0))) { if (node->pkt->pkttype != PKT_SECRET_KEY && node->pkt->pkttype != PKT_SECRET_SUBKEY) continue; + if (only_marked && !(node->flag & NODE_TRANSFER_SECKEY)) + continue; pk = node->pkt->pkt.public_key; if (!main_pk) main_pk = pk; @@ -2454,14 +2536,21 @@ transfer_secret_keys (ctrl_t ctrl, struct import_stats_s *stats, /* Walk a secret keyblock and produce a public keyblock out of it. - Returns a new node or NULL on error. */ + * Returns a new node or NULL on error. Modifies the tag field of the + * nodes. */ static kbnode_t sec_to_pub_keyblock (kbnode_t sec_keyblock) { kbnode_t pub_keyblock = NULL; kbnode_t ctx = NULL; kbnode_t secnode, pubnode; + unsigned int tag = 0; + + /* Set a tag to all nodes. */ + for (secnode = sec_keyblock; secnode; secnode = secnode->next) + secnode->tag = ++tag; + /* Copy. */ while ((secnode = walk_kbnode (sec_keyblock, &ctx, 0))) { if (secnode->pkt->pkttype == PKT_SECRET_KEY @@ -2491,6 +2580,7 @@ sec_to_pub_keyblock (kbnode_t sec_keyblock) { pubnode = clone_kbnode (secnode); } + pubnode->tag = secnode->tag; if (!pub_keyblock) pub_keyblock = pubnode; @@ -2501,25 +2591,223 @@ sec_to_pub_keyblock (kbnode_t sec_keyblock) return pub_keyblock; } -/**************** - * Ditto for secret keys. Handling is simpler than for public keys. - * We allow secret key importing only when allow is true, this is so - * that a secret key can not be imported accidentally and thereby tampering - * with the trust calculation. + +/* Delete all notes in the keyblock at R_KEYBLOCK which are not in + * PUB_KEYBLOCK. Modifies the tags of both keyblock's nodes. */ +static gpg_error_t +resync_sec_with_pub_keyblock (kbnode_t *r_keyblock, kbnode_t pub_keyblock, + kbnode_t *r_removedsecs) +{ + kbnode_t sec_keyblock = *r_keyblock; + kbnode_t node, prevnode; + unsigned int *taglist; + unsigned int ntaglist, n; + kbnode_t attic = NULL; + kbnode_t *attic_head = &attic; + + /* Collect all tags in an array for faster searching. */ + for (ntaglist = 0, node = pub_keyblock; node; node = node->next) + ntaglist++; + taglist = xtrycalloc (ntaglist, sizeof *taglist); + if (!taglist) + return gpg_error_from_syserror (); + for (ntaglist = 0, node = pub_keyblock; node; node = node->next) + taglist[ntaglist++] = node->tag; + + /* Walks over the secret keyblock and delete all nodes which are not + * in the tag list. Those nodes have been deleted in the + * pub_keyblock. Sequential search is a bit lazy and could be + * optimized by sorting and bsearch; however secret keyrings are + * short and there are easier ways to DoS the import. */ + again: + for (prevnode=NULL, node=sec_keyblock; node; prevnode=node, node=node->next) + { + for (n=0; n < ntaglist; n++) + if (taglist[n] == node->tag) + break; + if (n == ntaglist) /* Not in public keyblock. */ + { + if (node->pkt->pkttype == PKT_SECRET_KEY + || node->pkt->pkttype == PKT_SECRET_SUBKEY) + { + if (!prevnode) + sec_keyblock = node->next; + else + prevnode->next = node->next; + node->next = NULL; + *attic_head = node; + attic_head = &node->next; + goto again; /* That's lame; I know. */ + } + else + delete_kbnode (node); + } + } + + xfree (taglist); + + /* Commit the as deleted marked nodes and return the possibly + * modified keyblock and a list of removed secret key nodes. */ + commit_kbnode (&sec_keyblock); + *r_keyblock = sec_keyblock; + *r_removedsecs = attic; + return 0; +} + + +/* Helper for import_secret_one. */ +static gpg_error_t +do_transfer (ctrl_t ctrl, kbnode_t keyblock, PKT_public_key *pk, + struct import_stats_s *stats, int batch, int only_marked) + +{ + gpg_error_t err; + struct import_stats_s subkey_stats = {0}; + + err = transfer_secret_keys (ctrl, &subkey_stats, keyblock, + batch, 0, only_marked); + if (gpg_err_code (err) == GPG_ERR_NOT_PROCESSED) + { + /* TRANSLATORS: For a smartcard, each private key on host has a + * reference (stub) to a smartcard and actual private key data + * is stored on the card. A single smartcard can have up to + * three private key data. Importing private key stub is always + * skipped in 2.1, and it returns GPG_ERR_NOT_PROCESSED. + * Instead, user should be suggested to run 'gpg --card-status', + * then, references to a card will be automatically created + * again. */ + log_info (_("To migrate '%s', with each smartcard, " + "run: %s\n"), "secring.gpg", "gpg --card-status"); + err = 0; + } + + if (!err) + { + int status = 16; + + if (!opt.quiet) + log_info (_("key %s: secret key imported\n"), keystr_from_pk (pk)); + if (subkey_stats.secret_imported) + { + status |= 1; + stats->secret_imported += 1; + } + if (subkey_stats.secret_dups) + stats->secret_dups += 1; + + if (is_status_enabled ()) + print_import_ok (pk, status); + } + + return err; +} + + +/* If the secret keys (main or subkey) in SECKEYS have a corresponding + * public key in the public key described by (FPR,FPRLEN) import these + * parts. */ -static int +static gpg_error_t +import_matching_seckeys (ctrl_t ctrl, kbnode_t seckeys, + const byte *mainfpr, size_t mainfprlen, + struct import_stats_s *stats, int batch) +{ + gpg_error_t err; + kbnode_t pub_keyblock = NULL; + kbnode_t node; + struct { byte fpr[MAX_FINGERPRINT_LEN]; size_t fprlen; } *fprlist = NULL; + size_t n, nfprlist; + byte fpr[MAX_FINGERPRINT_LEN]; + size_t fprlen; + PKT_public_key *pk; + + /* Get the entire public key block from our keystore and put all its + * fingerprints into an array. */ + err = get_pubkey_byfprint (ctrl, NULL, &pub_keyblock, mainfpr, mainfprlen); + if (err) + goto leave; + log_assert (pub_keyblock && pub_keyblock->pkt->pkttype == PKT_PUBLIC_KEY); + pk = pub_keyblock->pkt->pkt.public_key; + + for (nfprlist = 0, node = pub_keyblock; node; node = node->next) + if (node->pkt->pkttype == PKT_PUBLIC_KEY + || node->pkt->pkttype == PKT_PUBLIC_SUBKEY) + nfprlist++; + log_assert (nfprlist); + fprlist = xtrycalloc (nfprlist, sizeof *fprlist); + if (!fprlist) + { + err = gpg_error_from_syserror (); + goto leave; + } + for (n = 0, node = pub_keyblock; node; node = node->next) + if (node->pkt->pkttype == PKT_PUBLIC_KEY + || node->pkt->pkttype == PKT_PUBLIC_SUBKEY) + { + fingerprint_from_pk (node->pkt->pkt.public_key, + fprlist[n].fpr, &fprlist[n].fprlen); + n++; + } + log_assert (n == nfprlist); + + /* for (n=0; n < nfprlist; n++) */ + /* log_printhex (fprlist[n].fpr, fprlist[n].fprlen, "pubkey %zu:", n); */ + + /* Mark all secret keys which have a matching public key part in + * PUB_KEYBLOCK. */ + for (node = seckeys; node; node = node->next) + { + if (node->pkt->pkttype != PKT_SECRET_KEY + && node->pkt->pkttype != PKT_SECRET_SUBKEY) + continue; /* Should not happen. */ + fingerprint_from_pk (node->pkt->pkt.public_key, fpr, &fprlen); + node->flag &= ~NODE_TRANSFER_SECKEY; + for (n=0; n < nfprlist; n++) + if (fprlist[n].fprlen == fprlen && !memcmp (fprlist[n].fpr,fpr,fprlen)) + { + node->flag |= NODE_TRANSFER_SECKEY; + /* log_debug ("found matching seckey\n"); */ + break; + } + } + + /* Transfer all marked keys. */ + err = do_transfer (ctrl, seckeys, pk, stats, batch, 1); + + leave: + xfree (fprlist); + release_kbnode (pub_keyblock); + return err; +} + + +/* Import function for a single secret keyblock. Handling is simpler + * than for public keys. We allow secret key importing only when + * allow is true, this is so that a secret key can not be imported + * accidentally and thereby tampering with the trust calculation. + * + * Ownership of KEYBLOCK is transferred to this function! + * + * If R_SECATTIC is not null the last special sec_keyblock is stored + * there. + */ +static gpg_error_t 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) + struct import_stats_s *stats, int batch, + unsigned int options, int for_migration, + import_screener_t screener, void *screener_arg, + kbnode_t *r_secattic) { PKT_public_key *pk; struct seckey_info *ski; kbnode_t node, uidnode; u32 keyid[2]; - int rc = 0; + gpg_error_t err = 0; int nr_prev; kbnode_t pub_keyblock; + kbnode_t attic = NULL; + byte fpr[MAX_FINGERPRINT_LEN]; + size_t fprlen; char pkstrbuf[PUBKEY_STRING_SIZE]; /* Get the key and print some info about it */ @@ -2529,6 +2817,7 @@ import_secret_one (ctrl_t ctrl, kbnode_t keyblock, pk = node->pkt->pkt.public_key; + fingerprint_from_pk (pk, fpr, &fprlen); keyid_from_pk (pk, keyid); uidnode = find_next_kbnode (keyblock, PKT_USER_ID); @@ -2536,12 +2825,13 @@ import_secret_one (ctrl_t ctrl, kbnode_t keyblock, { log_error (_("secret key %s: %s\n"), keystr_from_pk (pk), _("rejected by import screener")); + release_kbnode (keyblock); return 0; } if (opt.verbose && !for_migration) { - log_info ("sec %s/%s %s ", + log_info ("sec %s/%s %s ", pubkey_string (pk, pkstrbuf, sizeof pkstrbuf), keystr_from_pk (pk), datestr_from_pk (pk)); if (uidnode) @@ -2555,6 +2845,7 @@ import_secret_one (ctrl_t ctrl, kbnode_t keyblock, { if (!for_migration) log_error (_("importing secret keys not allowed\n")); + release_kbnode (keyblock); return 0; } @@ -2562,6 +2853,7 @@ import_secret_one (ctrl_t ctrl, kbnode_t keyblock, { if (!for_migration) log_error( _("key %s: no user ID\n"), keystr_from_pk (pk)); + release_kbnode (keyblock); return 0; } @@ -2570,6 +2862,7 @@ import_secret_one (ctrl_t ctrl, kbnode_t keyblock, { /* Actually an internal error. */ log_error ("key %s: secret key info missing\n", keystr_from_pk (pk)); + release_kbnode (keyblock); return 0; } @@ -2580,6 +2873,7 @@ import_secret_one (ctrl_t ctrl, kbnode_t keyblock, if (!for_migration) log_error (_("key %s: secret key with invalid cipher %d" " - skipped\n"), keystr_from_pk (pk), ski->algo); + release_kbnode (keyblock); return 0; } @@ -2590,6 +2884,7 @@ import_secret_one (ctrl_t ctrl, kbnode_t keyblock, to put a secret key into the keyring and the user might later be tricked into signing stuff with that key. */ log_error (_("importing secret keys not allowed\n")); + release_kbnode (keyblock); return 0; } #endif @@ -2601,20 +2896,62 @@ import_secret_one (ctrl_t ctrl, kbnode_t keyblock, /* Make a public key out of the key. */ pub_keyblock = sec_to_pub_keyblock (keyblock); if (!pub_keyblock) - log_error ("key %s: failed to create public key from secret key\n", - keystr_from_pk (pk)); + { + err = gpg_error_from_syserror (); + log_error ("key %s: failed to create public key from secret key\n", + keystr_from_pk (pk)); + } else { + int valid; + /* 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, pub_keyblock, stats, NULL, NULL, options, 1, for_migration, - screener, screener_arg, 0, NULL); + screener, screener_arg, 0, NULL, &valid); + + /* The secret keyblock may not have nodes which are deleted in + * the public keyblock. Otherwise we would import just the + * secret key without having the public key. That would be + * surprising and clutters out private-keys-v1.d. */ + err = resync_sec_with_pub_keyblock (&keyblock, pub_keyblock, &attic); + if (err) + goto leave; + + if (!valid) + { + /* If the block was not valid the primary key is left in the + * original keyblock because we require that for the first + * node. Move it to ATTIC. */ + if (keyblock && keyblock->pkt->pkttype == PKT_SECRET_KEY) + { + node = keyblock; + keyblock = node->next; + node->next = NULL; + if (attic) + { + node->next = attic; + attic = node; + } + else + attic = node; + } + + /* Try to import the secret key iff we have a public key. */ + if (attic && !(opt.dry_run || (options & IMPORT_DRY_RUN))) + err = import_matching_seckeys (ctrl, attic, fpr, fprlen, + stats, batch); + else + err = gpg_error (GPG_ERR_NO_SECKEY); + goto leave; + } - /* Fixme: We should check for an invalid keyblock and - cancel the secret key import in this case. */ - release_kbnode (pub_keyblock); + /* log_debug ("attic is:\n"); */ + /* dump_kbnode (attic); */ + + /* Proceed with the valid parts of PUBKEYBLOCK. */ /* At least we cancel the secret key import when the public key import was skipped due to MERGE_ONLY option and a new @@ -2622,63 +2959,40 @@ import_secret_one (ctrl_t ctrl, kbnode_t keyblock, if (!(opt.dry_run || (options & IMPORT_DRY_RUN)) && stats->skipped_new_keys <= nr_prev) { - /* Read the keyblock again to get the effects of a merge. */ - /* Fixme: we should do this based on the fingerprint or - even better let import_one return the merged - keyblock. */ - node = get_pubkeyblock (ctrl, keyid); - if (!node) - log_error ("key %s: failed to re-lookup public key\n", - keystr_from_pk (pk)); + /* Read the keyblock again to get the effects of a merge for + * the public key. */ + err = get_pubkey_byfprint (ctrl, NULL, &node, fpr, fprlen); + if (err || !node) + log_error ("key %s: failed to re-lookup public key: %s\n", + keystr_from_pk (pk), gpg_strerror (err)); else { - gpg_error_t err; - - /* transfer_secret_keys collects subkey stats. */ - struct import_stats_s subkey_stats = {0}; + err = do_transfer (ctrl, keyblock, pk, stats, batch, 0); + if (!err) + check_prefs (ctrl, node); + release_kbnode (node); - err = transfer_secret_keys (ctrl, &subkey_stats, keyblock, - batch, 0); - if (gpg_err_code (err) == GPG_ERR_NOT_PROCESSED) + if (!err && attic) { - /* TRANSLATORS: For smartcard, each private key on - host has a reference (stub) to a smartcard and - actual private key data is stored on the card. A - single smartcard can have up to three private key - data. Importing private key stub is always - skipped in 2.1, and it returns - GPG_ERR_NOT_PROCESSED. Instead, user should be - suggested to run 'gpg --card-status', then, - references to a card will be automatically - created again. */ - log_info (_("To migrate '%s', with each smartcard, " - "run: %s\n"), "secring.gpg", "gpg --card-status"); - err = 0; + /* Try to import invalid subkeys. This can be the + * case if the primary secret key was imported due + * to --allow-non-selfsigned-uid. */ + err = import_matching_seckeys (ctrl, attic, fpr, fprlen, + stats, batch); } - if (!err) - { - int status = 16; - if (!opt.quiet) - log_info (_("key %s: secret key imported\n"), - keystr_from_pk (pk)); - if (subkey_stats.secret_imported) - { - status |= 1; - stats->secret_imported += 1; - } - if (subkey_stats.secret_dups) - stats->secret_dups += 1; - if (is_status_enabled ()) - print_import_ok (pk, status); - check_prefs (ctrl, node); - } - release_kbnode (node); } } } - return rc; + leave: + release_kbnode (keyblock); + release_kbnode (pub_keyblock); + if (r_secattic) + *r_secattic = attic; + else + release_kbnode (attic); + return err; } @@ -2942,9 +3256,7 @@ import_revoke_cert (ctrl_t ctrl, kbnode_t node, unsigned int options, size_t an; fingerprint_from_pk (pk, afp, &an); - while (an < MAX_FINGERPRINT_LEN) - afp[an++] = 0; - rc = keydb_search_fpr (hd, afp); + rc = keydb_search_fpr (hd, afp, an); } if (rc) { @@ -3058,7 +3370,7 @@ chk_self_sigs (ctrl_t ctrl, kbnode_t keyblock, u32 *keyid, int *non_self) kbnode_t bsnode = NULL; /* Subkey binding signature node. */ u32 bsdate = 0; /* Timestamp of that node. */ kbnode_t rsnode = NULL; /* Subkey recocation signature node. */ - u32 rsdate = 0; /* Timestamp of tha node. */ + u32 rsdate = 0; /* Timestamp of that node. */ PKT_signature *sig; int rc; kbnode_t n; @@ -3415,14 +3727,51 @@ any_uid_left (kbnode_t keyblock) -/**************** +/* Delete all user ids from KEYBLOCK. + * Returns: True if the keyblock has changed. */ +static int +remove_all_uids (kbnode_t *keyblock) +{ + kbnode_t node; + int any = 0; + + for (node = *keyblock; node; node = node->next) + { + if (is_deleted_kbnode (node)) + continue; + + if (node->pkt->pkttype != PKT_USER_ID) + continue; + + /* We are at the first user id. Delete everything up to the + * first subkey. */ + for (; node; node = node->next) + { + if (is_deleted_kbnode (node)) + continue; + + if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY + || node->pkt->pkttype == PKT_SECRET_SUBKEY) + break; + delete_kbnode (node); + any = 1; + } + break; /* All done. */ + } + + commit_kbnode (keyblock); + return any; +} + + +/* * It may happen that the imported keyblock has duplicated user IDs. * We check this here and collapse those user IDs together with their * sigs into one. * Returns: True if the keyblock has changed. */ int -collapse_uids( kbnode_t *keyblock ) +collapse_uids (kbnode_t *keyblock) { kbnode_t uid1; int any=0; @@ -3562,7 +3911,7 @@ revocation_present (ctrl_t ctrl, kbnode_t keyblock) u32 keyid[2]; keyid_from_fingerprint (ctrl, sig->revkey[idx].fpr, - MAX_FINGERPRINT_LEN, keyid); + sig->revkey[idx].fprlen, keyid); for(inode=keyblock->next;inode;inode=inode->next) { @@ -3582,7 +3931,7 @@ revocation_present (ctrl_t ctrl, kbnode_t keyblock) err = get_pubkey_byfprint_fast (NULL, sig->revkey[idx].fpr, - MAX_FINGERPRINT_LEN); + sig->revkey[idx].fprlen); if (gpg_err_code (err) == GPG_ERR_NO_PUBKEY || gpg_err_code (err) == GPG_ERR_UNUSABLE_PUBKEY) { @@ -3598,13 +3947,13 @@ revocation_present (ctrl_t ctrl, kbnode_t keyblock) tempkeystr,keystr(keyid)); keyserver_import_fprint (ctrl, sig->revkey[idx].fpr, - MAX_FINGERPRINT_LEN, + sig->revkey[idx].fprlen, opt.keyserver, 0); /* Do we have it now? */ err = get_pubkey_byfprint_fast (NULL, sig->revkey[idx].fpr, - MAX_FINGERPRINT_LEN); + sig->revkey[idx].fprlen); } if (gpg_err_code (err) == GPG_ERR_NO_PUBKEY |