Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12:Update
gpg2
gnupg-CVE-2019-13050_2_of_5.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File gnupg-CVE-2019-13050_2_of_5.patch of Package gpg2
commit 3a403ab04eeb45f12b34f9d9c421dac93eaf2160 Author: Werner Koch <wk@gnupg.org> Date: Mon Jul 1 21:53:55 2019 +0200 gpg: Fallback to import with self-sigs-only on too large keyblocks. * g10/import.c (import_one): Rename to ... (import_one_real): this. Do not print and update stats on keyring write errors. (import_one): New. Add fallback code. -- GnuPG-bug-id: 4591 Signed-off-by: Werner Koch <wk@gnupg.org> Index: gnupg-2.0.24/g10/import.c =================================================================== --- gnupg-2.0.24.orig/g10/import.c +++ gnupg-2.0.24/g10/import.c @@ -77,6 +77,7 @@ static int chk_self_sigs( const char *fn PKT_public_key *pk, u32 *keyid, int *non_self ); static int delete_inv_parts( const char *fname, KBNODE keyblock, u32 *keyid, unsigned int options ); +static void remove_all_non_self_sigs (kbnode_t *keyblock, u32 *keyid); static int merge_blocks( const char *fname, KBNODE keyblock_orig, KBNODE keyblock, u32 *keyid, int *n_uids, int *n_sigs, int *n_subk ); @@ -793,8 +794,8 @@ check_prefs(KBNODE keyblock) * internal errorcount, so that invalid input can be detected by programs * which called gpg. */ -static int -import_one( const char *fname, KBNODE keyblock, struct stats_s *stats, +static gpg_error_t +import_one_real (const char *fname, KBNODE keyblock, struct stats_s *stats, unsigned char **fpr,size_t *fpr_len,unsigned int options, int from_sk, import_filter_t filter, void *filter_arg) { @@ -858,6 +859,13 @@ import_one( const char *fname, KBNODE ke return 0; } + /* Remove all non-self-sigs if requested. Noe that this is a NOP if + * that option has been globally set but we may also be called + * latter with the already parsed keyblock and a locally changed + * option. This is why we need to remove them here as well. */ + if ((options & IMPORT_SELF_SIGS_ONLY)) + remove_all_non_self_sigs (&keyblock, keyid); + collapse_uids(&keyblock); /* Clean the key that we're about to import, to cut down on things @@ -1033,8 +1041,10 @@ import_one( const char *fname, KBNODE ke else if(non_self) revalidation_mark (); - /* we are ready */ - if( !opt.quiet ) + /* we are ready. Print and update stats if we got no error. + * An error here comes from writing the keyblock and thus + * very likely means that no update happened. */ + if (!opt.quiet) { char *p=get_user_id_native(keyid); if( n_uids == 1 ) @@ -1151,6 +1161,38 @@ import_one( const char *fname, KBNODE ke return rc; } + +/* Wrapper around import_one_real to retry the import in some cases. */ +static int +import_one (const char *fname, KBNODE keyblock, struct stats_s *stats, + unsigned char **fpr, size_t *fpr_len, unsigned int options, + int from_sk, import_filter_t filter, void *filter_arg) +{ + gpg_error_t err; + + err = import_one_real (fname, keyblock, stats, fpr, fpr_len, options, + from_sk, filter, filter_arg); + if (gpg_err_code (err) == GPG_ERR_TOO_LARGE + && gpg_err_source (err) == GPG_ERR_SOURCE_KEYBOX + && ((options & (IMPORT_SELF_SIGS_ONLY | IMPORT_CLEAN)) + != (IMPORT_SELF_SIGS_ONLY | IMPORT_CLEAN))) + { + /* We hit the maximum image length. Ask the wrapper to do + * everything again but this time with some extra options. */ + u32 keyid[2]; + + keyid_from_pk (keyblock->pkt->pkt.public_key, keyid); + log_info ("key %s: keyblock too large, retrying with self-sigs-only\n", + keystr (keyid)); + options |= IMPORT_SELF_SIGS_ONLY | IMPORT_CLEAN; + err = import_one_real (fname, keyblock, stats, fpr, fpr_len, options, + from_sk, filter, filter_arg); + + } + return err; +} + + /* Walk a secret keyblock and produce a public keyblock out of it. */ static KBNODE sec_to_pub_keyblock(KBNODE sec_keyblock) @@ -1483,6 +1525,38 @@ import_revoke_cert( const char *fname, K } +/* Delete all non-self-sigs from KEYBLOCK. + * Returns: True if the keyblock has changed. */ +static void +remove_all_non_self_sigs (kbnode_t *keyblock, u32 *keyid) +{ + kbnode_t node; + unsigned int dropped = 0; + + for (node = *keyblock; node; node = node->next) + { + if (is_deleted_kbnode (node)) + continue; + + if (node->pkt->pkttype != PKT_SIGNATURE) + continue; + + if (node->pkt->pkt.signature->keyid[0] == keyid[0] + && node->pkt->pkt.signature->keyid[1] == keyid[1]) + continue; + delete_kbnode (node); + dropped++; + } + + if (dropped) + commit_kbnode (keyblock); + + if (dropped && opt.verbose) + log_info ("key %s: number of dropped non-self-signatures: %u\n", + keystr (keyid), dropped); +} + + /* * Loop over the keyblock and check all self signatures. * Mark all user-ids with a self-signature by setting flag bit 0.
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor