gpg: Fix --rebuild-keydb-caches.

* g10/parse-packet.c (parse_key): Store even unsupported packet
versions.
* g10/keyring.c (keyring_rebuild_cache): Do not copy keys with
versions less than 4.
--

That function, which is implicitly called while checking the keydb, led
to corruption of v3 key packets in the keyring which would later spit
out "packet(6)too short" messages.

Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
Werner Koch 2014-10-31 10:29:02 +01:00
parent 433208a553
commit 28ae8ad70b
3 changed files with 43 additions and 30 deletions

3
NEWS
View File

@ -8,7 +8,8 @@ Noteworthy changes in version 2.1.0 (unreleased)
used. used.
* gpg: All support for v3 (PGP 2) keys has been dropped. All * gpg: All support for v3 (PGP 2) keys has been dropped. All
signatures are now created as v4 signatures. signatures are now created as v4 signatures. v3 keys will be
removed from the keyring.
* gpg: With pinentry-0.9.0 the passphrase "enter again" prompt shows * gpg: With pinentry-0.9.0 the passphrase "enter again" prompt shows
up in the same window as the "new passphrase" prompt. up in the same window as the "new passphrase" prompt.

View File

@ -1409,40 +1409,51 @@ keyring_rebuild_cache (void *token,int noisy)
goto leave; goto leave;
} }
/* check all signature to set the signature's cache flags */ if (keyblock->pkt->pkt.public_key->version < 4)
for (node=keyblock; node; node=node->next)
{ {
/* Note that this doesn't cache the result of a revocation /* We do not copy/cache v3 keys or any other unknown
issued by a designated revoker. This is because the pk packets. It is better to remove them from the keyring.
in question does not carry the revkeys as we haven't The code required to keep them in the keyring would be
merged the key and selfsigs. It is questionable whether too complicated. Given that we do not touch the old
this matters very much since there are very very few secring.gpg a suitable backup for decryption of v3 stuff
designated revoker revocation packets out there. */ using an older gpg version will always be available. */
if (node->pkt->pkttype == PKT_SIGNATURE)
{
PKT_signature *sig=node->pkt->pkt.signature;
if(!opt.no_sig_cache && sig->flags.checked && sig->flags.valid
&& (openpgp_md_test_algo(sig->digest_algo)
|| openpgp_pk_test_algo(sig->pubkey_algo)))
sig->flags.checked=sig->flags.valid=0;
else
check_key_signature (keyblock, node, NULL);
sigcount++;
}
} }
else
{
/* Check all signature to set the signature's cache flags. */
for (node=keyblock; node; node=node->next)
{
/* Note that this doesn't cache the result of a
revocation issued by a designated revoker. This is
because the pk in question does not carry the revkeys
as we haven't merged the key and selfsigs. It is
questionable whether this matters very much since
there are very very few designated revoker revocation
packets out there. */
if (node->pkt->pkttype == PKT_SIGNATURE)
{
PKT_signature *sig=node->pkt->pkt.signature;
/* write the keyblock to the temporary file */ if(!opt.no_sig_cache && sig->flags.checked && sig->flags.valid
rc = write_keyblock (tmpfp, keyblock); && (openpgp_md_test_algo(sig->digest_algo)
if (rc) || openpgp_pk_test_algo(sig->pubkey_algo)))
goto leave; sig->flags.checked=sig->flags.valid=0;
else
check_key_signature (keyblock, node, NULL);
if ( !(++count % 50) && noisy && !opt.quiet) sigcount++;
log_info(_("%lu keys cached so far (%lu signatures)\n"), }
count, sigcount ); }
/* Write the keyblock to the temporary file. */
rc = write_keyblock (tmpfp, keyblock);
if (rc)
goto leave;
if ( !(++count % 50) && noisy && !opt.quiet)
log_info(_("%lu keys cached so far (%lu signatures)\n"),
count, sigcount );
}
} /* end main loop */ } /* end main loop */
if (rc == -1) if (rc == -1)
rc = 0; rc = 0;

View File

@ -1953,6 +1953,7 @@ parse_key (IOBUF inp, int pkttype, unsigned long pktlen,
log_info ("packet(%d) with obsolete version %d\n", pkttype, version); log_info ("packet(%d) with obsolete version %d\n", pkttype, version);
if (list_mode) if (list_mode)
es_fprintf (listfp, ":key packet: [obsolete version %d]\n", version); es_fprintf (listfp, ":key packet: [obsolete version %d]\n", version);
pk->version = version;
err = gpg_error (GPG_ERR_INV_PACKET); err = gpg_error (GPG_ERR_INV_PACKET);
goto leave; goto leave;
} }