Compare commits
10 Commits
bc0a18eb30
...
fb1f4f7d38
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fb1f4f7d38 | ||
|
|
9f96fcacf6 | ||
|
|
f679c558e3 | ||
|
|
3fa17fcb5d | ||
|
|
4d733ed2ef | ||
|
|
0939804794 | ||
|
|
8254eb1b76 | ||
|
|
93d6ff8f80 | ||
|
|
4e6af19394 | ||
|
|
a3f1223a00 |
52
backport-0001-CVE-2025-30258.patch
Normal file
52
backport-0001-CVE-2025-30258.patch
Normal file
@ -0,0 +1,52 @@
|
||||
From 794950ec755eab3729d5a5905cbbc2e2d98b8699 Mon Sep 17 00:00:00 2001
|
||||
From: Werner Koch <wk@gnupg.org>
|
||||
Date: Thu, 31 Oct 2024 15:11:55 +0100
|
||||
Subject: [PATCH] gpg: Allow the use of an ADSK subkey as ADSK subkey.
|
||||
|
||||
* g10/packet.h (PKT_public_key): Increased size of req_usage to 16.
|
||||
* g10/getkey.c (key_byname): Set allow_adsk in the context if ir was
|
||||
requested via req_usage.
|
||||
(finish_lookup): Allow RENC usage matching.
|
||||
* g10/keyedit.c (append_adsk_to_key): Adjust the assert.
|
||||
* g10/keygen.c (prepare_adsk): Also allow to find an RENC subkey.
|
||||
--
|
||||
|
||||
If an ADSK is to be added it may happen that an ADSK subkey is found
|
||||
first and this should then be used even that it does not have the E
|
||||
usage. However, it used to have that E usage when it was added.
|
||||
|
||||
While testing this I found another pecularity: If you do
|
||||
gpg -k ADSK_SUBKEY_FPR
|
||||
without the '!' suffix and no corresponding encryption subkey is dound,
|
||||
you will get an unusabe key error. I hesitate to fix that due to
|
||||
possible side-effects.
|
||||
|
||||
GnuPG-bug-id: 6882
|
||||
|
||||
Adaptation: only reserve the change "Increased size of req_usage to 16"
|
||||
---
|
||||
g10/packet.h | 7 +++----
|
||||
1 files changed, 3 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/g10/packet.h b/g10/packet.h
|
||||
index 80ba91389..7bc0a6461 100644
|
||||
--- a/g10/packet.h
|
||||
+++ b/g10/packet.h
|
||||
@@ -400,11 +400,10 @@ typedef struct
|
||||
when serializing. (Serialized.) */
|
||||
byte version;
|
||||
byte selfsigversion; /* highest version of all of the self-sigs */
|
||||
- /* The public key algorithm. (Serialized.) */
|
||||
- byte pubkey_algo;
|
||||
- u16 pubkey_usage; /* carries the usage info. */
|
||||
- byte req_usage; /* hack to pass a request to getkey() */
|
||||
byte fprlen; /* 0 or length of FPR. */
|
||||
+ byte pubkey_algo; /* The public key algorithm. (PGP format) */
|
||||
+ u16 pubkey_usage; /* carries the usage info. */
|
||||
+ u16 req_usage; /* hack to pass a request to getkey() */
|
||||
u32 has_expired; /* set to the expiration date if expired */
|
||||
/* keyid of the primary key. Never access this value directly.
|
||||
Instead, use pk_main_keyid(). */
|
||||
--
|
||||
2.33.0
|
||||
|
||||
147
backport-0002-CVE-2025-30258.patch
Normal file
147
backport-0002-CVE-2025-30258.patch
Normal file
@ -0,0 +1,147 @@
|
||||
From 25d748c3dfc0102f9e54afea59ff26b3969bd8c1 Mon Sep 17 00:00:00 2001
|
||||
From: Werner Koch <wk@gnupg.org>
|
||||
Date: Tue, 11 Feb 2025 14:44:23 +0100
|
||||
Subject: [PATCH] gpg: Lookup key for merging/inserting only by primary key.
|
||||
|
||||
* g10/getkey.c (get_keyblock_byfpr_fast): Add arg primary_only and
|
||||
implement.
|
||||
* g10/import.c (import_one_real): Simplify filling the fpr buffer with
|
||||
zeroes.
|
||||
(import_one_real): Find key only by primary fingerprint.
|
||||
--
|
||||
|
||||
This should have been done early: When looking up the original
|
||||
keyblock we want to update, we need to lookup it up only using the
|
||||
primary key. This avoids to find a key which has the primary key also
|
||||
has a subkey.
|
||||
|
||||
GnuPG-bug-id: 7527
|
||||
---
|
||||
g10/getkey.c | 27 ++++++++++++++++++++++-----
|
||||
g10/import.c | 8 ++++----
|
||||
g10/keydb.h | 9 +++++----
|
||||
3 files changed, 31 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/g10/getkey.c b/g10/getkey.c
|
||||
index 618ad13e9..20ae84332 100644
|
||||
--- a/g10/getkey.c
|
||||
+++ b/g10/getkey.c
|
||||
@@ -1946,7 +1946,7 @@ get_pubkey_byfprint_fast (ctrl_t ctrl, PKT_public_key * pk,
|
||||
KBNODE keyblock;
|
||||
|
||||
err = get_keyblock_byfprint_fast (ctrl,
|
||||
- &keyblock, NULL, fprint, fprint_len, 0);
|
||||
+ &keyblock, NULL, 0, fprint, fprint_len, 0);
|
||||
if (!err)
|
||||
{
|
||||
if (pk)
|
||||
@@ -1963,18 +1963,23 @@ get_pubkey_byfprint_fast (ctrl_t ctrl, PKT_public_key * pk,
|
||||
* R_HD may be NULL. If LOCK is set the handle has been opend in
|
||||
* locked mode and keydb_disable_caching () has been called. On error
|
||||
* R_KEYBLOCK is set to NULL but R_HD must be released by the caller;
|
||||
- * it may have a value of NULL, though. This allows to do an insert
|
||||
- * operation on a locked keydb handle. */
|
||||
+ * it may have a value of NULL, though. This allows one to do an
|
||||
+ * insert operation on a locked keydb handle. If PRIMARY_ONLY is set
|
||||
+ * the function returns a keyblock which has the requested fingerprint
|
||||
+ * has primary key. */
|
||||
gpg_error_t
|
||||
get_keyblock_byfprint_fast (ctrl_t ctrl,
|
||||
- kbnode_t *r_keyblock, KEYDB_HANDLE *r_hd,
|
||||
- const byte *fprint, size_t fprint_len, int lock)
|
||||
+ kbnode_t *r_keyblock, KEYDB_HANDLE *r_hd,
|
||||
+ int primary_only,
|
||||
+ const byte *fprint, size_t fprint_len, int lock)
|
||||
{
|
||||
gpg_error_t err;
|
||||
KEYDB_HANDLE hd;
|
||||
kbnode_t keyblock;
|
||||
byte fprbuf[MAX_FINGERPRINT_LEN];
|
||||
int i;
|
||||
+ byte tmpfpr[MAX_FINGERPRINT_LEN];
|
||||
+ size_t tmpfprlen;
|
||||
|
||||
if (r_keyblock)
|
||||
*r_keyblock = NULL;
|
||||
@@ -2006,6 +2011,7 @@ get_keyblock_byfprint_fast (ctrl_t ctrl,
|
||||
if (r_hd)
|
||||
*r_hd = hd;
|
||||
|
||||
+ again:
|
||||
err = keydb_search_fpr (hd, fprbuf, fprint_len);
|
||||
if (gpg_err_code (err) == GPG_ERR_NOT_FOUND)
|
||||
{
|
||||
@@ -2025,6 +2031,17 @@ get_keyblock_byfprint_fast (ctrl_t ctrl,
|
||||
log_assert (keyblock->pkt->pkttype == PKT_PUBLIC_KEY
|
||||
|| keyblock->pkt->pkttype == PKT_PUBLIC_SUBKEY);
|
||||
|
||||
+ if (primary_only)
|
||||
+ {
|
||||
+ fingerprint_from_pk (keyblock->pkt->pkt.public_key, tmpfpr, &tmpfprlen);
|
||||
+ if (fprint_len != tmpfprlen || memcmp (fprint, tmpfpr, fprint_len))
|
||||
+ {
|
||||
+ release_kbnode (keyblock);
|
||||
+ keyblock = NULL;
|
||||
+ goto again;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
/* Not caching key here since it won't have all of the fields
|
||||
properly set. */
|
||||
|
||||
diff --git a/g10/import.c b/g10/import.c
|
||||
index 7e48284c1..9adda3e8c 100644
|
||||
--- a/g10/import.c
|
||||
+++ b/g10/import.c
|
||||
@@ -1993,7 +1993,6 @@ import_one_real (ctrl_t ctrl,
|
||||
int mod_key = 0;
|
||||
int same_key = 0;
|
||||
int non_self = 0;
|
||||
- size_t an;
|
||||
char pkstrbuf[PUBKEY_STRING_SIZE];
|
||||
int merge_keys_done = 0;
|
||||
KEYDB_HANDLE hd = NULL;
|
||||
@@ -2014,8 +2013,8 @@ import_one_real (ctrl_t ctrl,
|
||||
pk = node->pkt->pkt.public_key;
|
||||
|
||||
fingerprint_from_pk (pk, fpr2, &fpr2len);
|
||||
- for (an = fpr2len; an < MAX_FINGERPRINT_LEN; an++)
|
||||
- fpr2[an] = 0;
|
||||
+ if (MAX_FINGERPRINT_LEN > fpr2len)
|
||||
+ memset (fpr2+fpr2len, 0, MAX_FINGERPRINT_LEN - fpr2len);
|
||||
keyid_from_pk( pk, keyid );
|
||||
uidnode = find_next_kbnode( keyblock, PKT_USER_ID );
|
||||
|
||||
@@ -2212,7 +2211,8 @@ import_one_real (ctrl_t ctrl,
|
||||
|
||||
/* Do we have this key already in one of our pubrings ? */
|
||||
err = get_keyblock_byfprint_fast (ctrl, &keyblock_orig, &hd,
|
||||
- fpr2, fpr2len, 1/*locked*/);
|
||||
+ 1 /*primary only */,
|
||||
+ fpr2, fpr2len, 1/*locked*/);
|
||||
if ((err
|
||||
&& gpg_err_code (err) != GPG_ERR_NO_PUBKEY
|
||||
&& gpg_err_code (err) != GPG_ERR_UNUSABLE_PUBKEY)
|
||||
diff --git a/g10/keydb.h b/g10/keydb.h
|
||||
index ac0953659..658c85a29 100644
|
||||
--- a/g10/keydb.h
|
||||
+++ b/g10/keydb.h
|
||||
@@ -420,10 +420,11 @@ gpg_error_t get_pubkey_byfprint_fast (ctrl_t ctrl, PKT_public_key *pk,
|
||||
merge the self-signed data into the public key and subkeys or into
|
||||
the user ids. */
|
||||
gpg_error_t get_keyblock_byfprint_fast (ctrl_t ctrl,
|
||||
- kbnode_t *r_keyblock,
|
||||
- KEYDB_HANDLE *r_hd,
|
||||
- const byte *fprint, size_t fprint_len,
|
||||
- int lock);
|
||||
+ kbnode_t *r_keyblock,
|
||||
+ KEYDB_HANDLE *r_hd,
|
||||
+ int primary_only,
|
||||
+ const byte *fpr, size_t fprlen,
|
||||
+ int lock);
|
||||
|
||||
|
||||
/* Returns true if a secret key is available for the public key with
|
||||
--
|
||||
2.33.0
|
||||
|
||||
127
backport-0003-CVE-2025-30258.patch
Normal file
127
backport-0003-CVE-2025-30258.patch
Normal file
@ -0,0 +1,127 @@
|
||||
From 9cd371b12d80cfc5bc85cb6e5f5eebb4decbe94f Mon Sep 17 00:00:00 2001
|
||||
From: Werner Koch <wk@gnupg.org>
|
||||
Date: Thu, 20 Feb 2025 14:50:20 +0100
|
||||
Subject: [PATCH] gpg: Remove a signature check function wrapper.
|
||||
|
||||
* g10/sig-check.c (check_signature2): Rename to
|
||||
(check_signature): this and remove the old wrapper. Adjust all
|
||||
callers.
|
||||
---
|
||||
g10/mainproc.c | 13 +++++--------
|
||||
g10/packet.h | 6 +-----
|
||||
g10/sig-check.c | 26 ++++++++------------------
|
||||
3 files changed, 14 insertions(+), 31 deletions(-)
|
||||
|
||||
diff --git a/g10/mainproc.c b/g10/mainproc.c
|
||||
index 739ad0a35..86f5a2db9 100644
|
||||
--- a/g10/mainproc.c
|
||||
+++ b/g10/mainproc.c
|
||||
@@ -1240,19 +1240,17 @@ do_check_sig (CTX c, kbnode_t node, const void *extrahash, size_t extrahashlen,
|
||||
|
||||
/* We only get here if we are checking the signature of a binary
|
||||
(0x00) or text document (0x01). */
|
||||
- rc = check_signature2 (c->ctrl, sig, md, extrahash, extrahashlen,
|
||||
- forced_pk,
|
||||
- NULL, is_expkey, is_revkey, r_pk);
|
||||
+ rc = check_signature (c->ctrl, sig, md, extrahash, extrahashlen,
|
||||
+ forced_pk, NULL, is_expkey, is_revkey, r_pk);
|
||||
if (! rc)
|
||||
md_good = md;
|
||||
else if (gpg_err_code (rc) == GPG_ERR_BAD_SIGNATURE && md2)
|
||||
{
|
||||
PKT_public_key *pk2;
|
||||
|
||||
- rc = check_signature2 (c->ctrl, sig, md2, extrahash, extrahashlen,
|
||||
- forced_pk,
|
||||
- NULL, is_expkey, is_revkey,
|
||||
- r_pk? &pk2 : NULL);
|
||||
+ rc = check_signature (c->ctrl, sig, md2, extrahash, extrahashlen,
|
||||
+ forced_pk, NULL, is_expkey, is_revkey,
|
||||
+ r_pk? &pk2 : NULL);
|
||||
if (!rc)
|
||||
{
|
||||
md_good = md2;
|
||||
@@ -1834,7 +1832,6 @@ issuer_fpr_string (PKT_signature *sig)
|
||||
return p? bin2hex (p, n, NULL) : NULL;
|
||||
}
|
||||
|
||||
-
|
||||
static void
|
||||
print_good_bad_signature (int statno, const char *keyid_str, kbnode_t un,
|
||||
PKT_signature *sig, int rc)
|
||||
diff --git a/g10/packet.h b/g10/packet.h
|
||||
index 7bc0a6461..b61c65417 100644
|
||||
--- a/g10/packet.h
|
||||
+++ b/g10/packet.h
|
||||
@@ -907,16 +907,12 @@ int cmp_user_ids( PKT_user_id *a, PKT_user_id *b );
|
||||
|
||||
|
||||
/*-- sig-check.c --*/
|
||||
-/* Check a signature. This is shorthand for check_signature2 with
|
||||
- the unnamed arguments passed as NULL. */
|
||||
-int check_signature (ctrl_t ctrl, PKT_signature *sig, gcry_md_hd_t digest);
|
||||
-
|
||||
/* Check a signature. Looks up the public key from the key db. (If
|
||||
* R_PK is not NULL, it is stored at RET_PK.) DIGEST contains a
|
||||
* valid hash context that already includes the signed data. This
|
||||
* function adds the relevant meta-data to the hash before finalizing
|
||||
* it and verifying the signature. FOCRED_PK is usually NULL. */
|
||||
-gpg_error_t check_signature2 (ctrl_t ctrl,
|
||||
+gpg_error_t check_signature (ctrl_t ctrl,
|
||||
PKT_signature *sig, gcry_md_hd_t digest,
|
||||
const void *extrahash, size_t extrahashlen,
|
||||
PKT_public_key *forced_pk,
|
||||
diff --git a/g10/sig-check.c b/g10/sig-check.c
|
||||
index 06329f659..54db2089a 100644
|
||||
--- a/g10/sig-check.c
|
||||
+++ b/g10/sig-check.c
|
||||
@@ -88,17 +88,6 @@ check_key_verify_compliance (PKT_public_key *pk)
|
||||
}
|
||||
|
||||
|
||||
-
|
||||
-/* Check a signature. This is shorthand for check_signature2 with
|
||||
- the unnamed arguments passed as NULL. */
|
||||
-int
|
||||
-check_signature (ctrl_t ctrl, PKT_signature *sig, gcry_md_hd_t digest)
|
||||
-{
|
||||
- return check_signature2 (ctrl, sig, digest, NULL, 0, NULL,
|
||||
- NULL, NULL, NULL, NULL);
|
||||
-}
|
||||
-
|
||||
-
|
||||
/* Check a signature.
|
||||
*
|
||||
* Looks up the public key that created the signature (SIG->KEYID)
|
||||
@@ -144,12 +133,12 @@ check_signature (ctrl_t ctrl, PKT_signature *sig, gcry_md_hd_t digest)
|
||||
*
|
||||
* Returns 0 on success. An error code otherwise. */
|
||||
gpg_error_t
|
||||
-check_signature2 (ctrl_t ctrl,
|
||||
- PKT_signature *sig, gcry_md_hd_t digest,
|
||||
- const void *extrahash, size_t extrahashlen,
|
||||
- PKT_public_key *forced_pk,
|
||||
- u32 *r_expiredate,
|
||||
- int *r_expired, int *r_revoked, PKT_public_key **r_pk)
|
||||
+check_signature (ctrl_t ctrl,
|
||||
+ PKT_signature *sig, gcry_md_hd_t digest,
|
||||
+ const void *extrahash, size_t extrahashlen,
|
||||
+ PKT_public_key *forced_pk,
|
||||
+ u32 *r_expiredate, int *r_expired, int *r_revoked,
|
||||
+ PKT_public_key **r_pk)
|
||||
{
|
||||
int rc=0;
|
||||
PKT_public_key *pk;
|
||||
@@ -802,7 +791,8 @@ check_revocation_keys (ctrl_t ctrl, PKT_public_key *pk, PKT_signature *sig)
|
||||
hash_public_key(md,pk);
|
||||
/* Note: check_signature only checks that the signature
|
||||
is good. It does not fail if the key is revoked. */
|
||||
- rc = check_signature (ctrl, sig, md);
|
||||
+ rc = check_signature (ctrl, sig, md, NULL, 0, NULL,
|
||||
+ NULL, NULL, NULL, NULL);
|
||||
cache_sig_result(sig,rc);
|
||||
gcry_md_close (md);
|
||||
break;
|
||||
--
|
||||
2.33.0
|
||||
|
||||
625
backport-0004-CVE-2025-30258.patch
Normal file
625
backport-0004-CVE-2025-30258.patch
Normal file
@ -0,0 +1,625 @@
|
||||
From da0164efc7f32013bc24d97b9afa9f8d67c318bb Mon Sep 17 00:00:00 2001
|
||||
From: Werner Koch <wk@gnupg.org>
|
||||
Date: Fri, 21 Feb 2025 12:16:17 +0100
|
||||
Subject: [PATCH] gpg: Fix a verification DoS due to a malicious subkey in the
|
||||
keyring.
|
||||
|
||||
* g10/getkey.c (get_pubkey): Factor code out to ...
|
||||
(get_pubkey_bykid): new. Add feature to return the keyblock.
|
||||
(get_pubkey_for_sig): Add arg r_keyblock to return the used keyblock.
|
||||
Request a signing usage.
|
||||
(get_pubkeyblock_for_sig): Remove.
|
||||
(finish_lookup): Improve debug output.
|
||||
* g10/sig-check.c (check_signature): Add arg r_keyblock and pass it
|
||||
down.
|
||||
* g10/mainproc.c (do_check_sig): Ditto.
|
||||
(check_sig_and_print): Use the keyblock returned by do_check_sig to
|
||||
show further information instead of looking it up again with
|
||||
get_pubkeyblock_for_sig. Also re-check the signature after the import
|
||||
of an included keyblock.
|
||||
--
|
||||
|
||||
The problem here is that it is possible to import a key from someone
|
||||
who added a signature subkey from another public key and thus inhibits
|
||||
that a good signature good be verified.
|
||||
|
||||
Such a malicious key signature subkey must have been created w/o the
|
||||
mandatory backsig which bind a signature subkey to its primary key.
|
||||
For encryption subkeys this is not an issue because the existence of a
|
||||
decryption private key is all you need to decrypt something and then
|
||||
it does not matter if the public subkey or its binding signature has
|
||||
been put below another primary key; in fact we do the latter for
|
||||
ADSKs.
|
||||
|
||||
GnuPG-bug-id: 7527
|
||||
Backported-from-master: 48978ccb4e20866472ef18436a32744350a65158
|
||||
---
|
||||
g10/getkey.c | 108 ++++++++++++++++++++++++++++++------------------
|
||||
g10/gpg.h | 3 +-
|
||||
g10/keydb.h | 10 ++++-
|
||||
g10/mainproc.c | 92 ++++++++++++++++++++++++++---------------
|
||||
g10/packet.h | 2 +-
|
||||
g10/sig-check.c | 23 +++++++----
|
||||
6 files changed, 152 insertions(+), 86 deletions(-)
|
||||
|
||||
diff --git a/g10/getkey.c b/g10/getkey.c
|
||||
index 20ae84332..c4d02fbb1 100644
|
||||
--- a/g10/getkey.c
|
||||
+++ b/g10/getkey.c
|
||||
@@ -316,27 +316,50 @@ pk_from_block (PKT_public_key *pk, kbnode_t keyblock, kbnode_t found_key)
|
||||
|
||||
/* Specialized version of get_pubkey which retrieves the key based on
|
||||
* information in SIG. In contrast to get_pubkey PK is required. IF
|
||||
- * FORCED_PK is not NULL, this public key is used and copied to PK. */
|
||||
+ * FORCED_PK is not NULL, this public key is used and copied to PK.
|
||||
+ * If R_KEYBLOCK is not NULL the entire keyblock is stored there if
|
||||
+ * found and FORCED_PK is not used; if not used or on error NULL is
|
||||
+ * stored there. */
|
||||
gpg_error_t
|
||||
get_pubkey_for_sig (ctrl_t ctrl, PKT_public_key *pk, PKT_signature *sig,
|
||||
- PKT_public_key *forced_pk)
|
||||
+ PKT_public_key *forced_pk, kbnode_t *r_keyblock)
|
||||
{
|
||||
+ gpg_error_t err;
|
||||
const byte *fpr;
|
||||
size_t fprlen;
|
||||
|
||||
+ if (r_keyblock)
|
||||
+ *r_keyblock = NULL;
|
||||
+
|
||||
if (forced_pk)
|
||||
{
|
||||
copy_public_key (pk, forced_pk);
|
||||
return 0;
|
||||
}
|
||||
|
||||
+ /* Make sure to request only keys cabable of signing. This makes
|
||||
+ * sure that a subkey w/o a valid backsig or with bad usage flags
|
||||
+ * will be skipped. */
|
||||
+ pk->req_usage = PUBKEY_USAGE_SIG;
|
||||
+
|
||||
/* First try the ISSUER_FPR info. */
|
||||
fpr = issuer_fpr_raw (sig, &fprlen);
|
||||
- if (fpr && !get_pubkey_byfprint (ctrl, pk, NULL, fpr, fprlen))
|
||||
+ if (fpr && !get_pubkey_byfprint (ctrl, pk, r_keyblock, fpr, fprlen))
|
||||
return 0;
|
||||
+ if (r_keyblock)
|
||||
+ {
|
||||
+ release_kbnode (*r_keyblock);
|
||||
+ *r_keyblock = NULL;
|
||||
+ }
|
||||
|
||||
/* Fallback to use the ISSUER_KEYID. */
|
||||
- return get_pubkey (ctrl, pk, sig->keyid);
|
||||
+ err = get_pubkey_bykid (ctrl, pk, r_keyblock, sig->keyid);
|
||||
+ if (err && r_keyblock)
|
||||
+ {
|
||||
+ release_kbnode (*r_keyblock);
|
||||
+ *r_keyblock = NULL;
|
||||
+ }
|
||||
+ return err;
|
||||
}
|
||||
|
||||
|
||||
@@ -354,6 +377,10 @@ get_pubkey_for_sig (ctrl_t ctrl, PKT_public_key *pk, PKT_signature *sig,
|
||||
* usage will be returned. As such, it is essential that
|
||||
* PK->REQ_USAGE be correctly initialized!
|
||||
*
|
||||
+ * If R_KEYBLOCK is not NULL, then the first result's keyblock is
|
||||
+ * returned in *R_KEYBLOCK. This should be freed using
|
||||
+ * release_kbnode().
|
||||
+ *
|
||||
* Returns 0 on success, GPG_ERR_NO_PUBKEY if there is no public key
|
||||
* with the specified key id, or another error code if an error
|
||||
* occurs.
|
||||
@@ -361,24 +388,30 @@ get_pubkey_for_sig (ctrl_t ctrl, PKT_public_key *pk, PKT_signature *sig,
|
||||
* If the data was not read from the cache, then the self-signed data
|
||||
* has definitely been merged into the public key using
|
||||
* merge_selfsigs. */
|
||||
-int
|
||||
-get_pubkey (ctrl_t ctrl, PKT_public_key * pk, u32 * keyid)
|
||||
+gpg_error_t
|
||||
+get_pubkey_bykid (ctrl_t ctrl, PKT_public_key *pk, kbnode_t *r_keyblock,
|
||||
+ u32 *keyid)
|
||||
{
|
||||
int internal = 0;
|
||||
- int rc = 0;
|
||||
+ gpg_error_t rc = 0;
|
||||
+
|
||||
+ if (r_keyblock)
|
||||
+ *r_keyblock = NULL;
|
||||
|
||||
#if MAX_PK_CACHE_ENTRIES
|
||||
- if (pk)
|
||||
+ if (pk && !r_keyblock)
|
||||
{
|
||||
/* Try to get it from the cache. We don't do this when pk is
|
||||
- NULL as it does not guarantee that the user IDs are
|
||||
- cached. */
|
||||
+ * NULL as it does not guarantee that the user IDs are cached.
|
||||
+ * The old get_pubkey_function did not check PK->REQ_USAGE when
|
||||
+ * reading form the caceh. This is probably a bug. Note that
|
||||
+ * the cache is not used when the caller asked to return the
|
||||
+ * entire keyblock. This is because the cache does not
|
||||
+ * associate the public key wit its primary key. */
|
||||
pk_cache_entry_t ce;
|
||||
for (ce = pk_cache; ce; ce = ce->next)
|
||||
{
|
||||
if (ce->keyid[0] == keyid[0] && ce->keyid[1] == keyid[1])
|
||||
- /* XXX: We don't check PK->REQ_USAGE here, but if we don't
|
||||
- read from the cache, we do check it! */
|
||||
{
|
||||
copy_public_key (pk, ce->pk);
|
||||
return 0;
|
||||
@@ -386,6 +419,7 @@ get_pubkey (ctrl_t ctrl, PKT_public_key * pk, u32 * keyid)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
+
|
||||
/* More init stuff. */
|
||||
if (!pk)
|
||||
{
|
||||
@@ -431,16 +465,18 @@ get_pubkey (ctrl_t ctrl, PKT_public_key * pk, u32 * keyid)
|
||||
ctx.req_usage = pk->req_usage;
|
||||
rc = lookup (ctrl, &ctx, 0, &kb, &found_key);
|
||||
if (!rc)
|
||||
+ pk_from_block (pk, kb, found_key);
|
||||
+ getkey_end (ctrl, &ctx);
|
||||
+ if (!rc && r_keyblock)
|
||||
{
|
||||
- pk_from_block (pk, kb, found_key);
|
||||
+ *r_keyblock = kb;
|
||||
+ kb = NULL;
|
||||
}
|
||||
- getkey_end (ctrl, &ctx);
|
||||
release_kbnode (kb);
|
||||
}
|
||||
- if (!rc)
|
||||
- goto leave;
|
||||
|
||||
- rc = GPG_ERR_NO_PUBKEY;
|
||||
+ if (rc) /* Return a more useful error code. */
|
||||
+ rc = gpg_error (GPG_ERR_NO_PUBKEY);
|
||||
|
||||
leave:
|
||||
if (!rc)
|
||||
@@ -451,6 +487,14 @@ leave:
|
||||
}
|
||||
|
||||
|
||||
+/* Wrapper for get_pubkey_bykid w/o keyblock return feature. */
|
||||
+int
|
||||
+get_pubkey (ctrl_t ctrl, PKT_public_key *pk, u32 *keyid)
|
||||
+{
|
||||
+ return get_pubkey_bykid (ctrl, pk, NULL, keyid);
|
||||
+}
|
||||
+
|
||||
+
|
||||
/* Same as get_pubkey but if the key was not found the function tries
|
||||
* to import it from LDAP. FIXME: We should not need this but swicth
|
||||
* to a fingerprint lookup. */
|
||||
@@ -563,28 +607,6 @@ get_pubkey_fast (ctrl_t ctrl, PKT_public_key * pk, u32 * keyid)
|
||||
}
|
||||
|
||||
|
||||
-/* Return the entire keyblock used to create SIG. This is a
|
||||
- * specialized version of get_pubkeyblock.
|
||||
- *
|
||||
- * FIXME: This is a hack because get_pubkey_for_sig was already called
|
||||
- * and it could have used a cache to hold the key. */
|
||||
-kbnode_t
|
||||
-get_pubkeyblock_for_sig (ctrl_t ctrl, PKT_signature *sig)
|
||||
-{
|
||||
- const byte *fpr;
|
||||
- size_t fprlen;
|
||||
- kbnode_t keyblock;
|
||||
-
|
||||
- /* First try the ISSUER_FPR info. */
|
||||
- fpr = issuer_fpr_raw (sig, &fprlen);
|
||||
- if (fpr && !get_pubkey_byfprint (ctrl, NULL, &keyblock, fpr, fprlen))
|
||||
- return keyblock;
|
||||
-
|
||||
- /* Fallback to use the ISSUER_KEYID. */
|
||||
- return get_pubkeyblock (ctrl, sig->keyid);
|
||||
-}
|
||||
-
|
||||
-
|
||||
/* Return the key block for the key with key id KEYID or NULL, if an
|
||||
* error occurs. Use release_kbnode() to release the key block.
|
||||
*
|
||||
@@ -3701,6 +3723,7 @@ finish_lookup (kbnode_t keyblock, unsigned int req_usage, int want_exact,
|
||||
kbnode_t latest_key;
|
||||
PKT_public_key *pk;
|
||||
int req_prim;
|
||||
+ int diag_exactfound = 0;
|
||||
u32 curtime = make_timestamp ();
|
||||
|
||||
if (r_flags)
|
||||
@@ -3731,11 +3754,10 @@ finish_lookup (kbnode_t keyblock, unsigned int req_usage, int want_exact,
|
||||
{
|
||||
if (want_exact)
|
||||
{
|
||||
- if (DBG_LOOKUP)
|
||||
- log_debug ("finish_lookup: exact search requested and found\n");
|
||||
foundk = k;
|
||||
pk = k->pkt->pkt.public_key;
|
||||
pk->flags.exact = 1;
|
||||
+ diag_exactfound = 1;
|
||||
break;
|
||||
}
|
||||
else if ((k->pkt->pkt.public_key->pubkey_usage == PUBKEY_USAGE_RENC))
|
||||
@@ -3765,10 +3787,14 @@ finish_lookup (kbnode_t keyblock, unsigned int req_usage, int want_exact,
|
||||
log_debug ("finish_lookup: checking key %08lX (%s)(req_usage=%x)\n",
|
||||
(ulong) keyid_from_pk (keyblock->pkt->pkt.public_key, NULL),
|
||||
foundk ? "one" : "all", req_usage);
|
||||
+ if (diag_exactfound && DBG_LOOKUP)
|
||||
+ log_debug ("\texact search requested and found\n");
|
||||
|
||||
if (!req_usage)
|
||||
{
|
||||
latest_key = foundk ? foundk : keyblock;
|
||||
+ if (DBG_LOOKUP)
|
||||
+ log_debug ("\tno usage requested - accepting key\n");
|
||||
goto found;
|
||||
}
|
||||
|
||||
diff --git a/g10/gpg.h b/g10/gpg.h
|
||||
index c51bbbb46..0cdcb8b12 100644
|
||||
--- a/g10/gpg.h
|
||||
+++ b/g10/gpg.h
|
||||
@@ -69,7 +69,8 @@ struct dirmngr_local_s;
|
||||
typedef struct dirmngr_local_s *dirmngr_local_t;
|
||||
|
||||
/* Object used to describe a keyblock node. */
|
||||
-typedef struct kbnode_struct *KBNODE; /* Deprecated use kbnode_t. */typedef struct kbnode_struct *kbnode_t;
|
||||
+typedef struct kbnode_struct *KBNODE; /* Deprecated use kbnode_t. */
|
||||
+typedef struct kbnode_struct *kbnode_t;
|
||||
|
||||
/* The handle for keydb operations. */
|
||||
typedef struct keydb_handle_s *KEYDB_HANDLE;
|
||||
diff --git a/g10/keydb.h b/g10/keydb.h
|
||||
index 658c85a29..7d25b3550 100644
|
||||
--- a/g10/keydb.h
|
||||
+++ b/g10/keydb.h
|
||||
@@ -332,9 +332,15 @@ void getkey_disable_caches(void);
|
||||
/* Return the public key used for signature SIG and store it at PK. */
|
||||
gpg_error_t get_pubkey_for_sig (ctrl_t ctrl,
|
||||
PKT_public_key *pk, PKT_signature *sig,
|
||||
- PKT_public_key *forced_pk);
|
||||
+ PKT_public_key *forced_pk,
|
||||
+ kbnode_t *r_keyblock);
|
||||
|
||||
-/* Return the public key with the key id KEYID and store it at PK. */
|
||||
+/* Return the public key with the key id KEYID and store it at PK.
|
||||
+ * Optionally return the entire keyblock. */
|
||||
+gpg_error_t get_pubkey_bykid (ctrl_t ctrl, PKT_public_key *pk,
|
||||
+ kbnode_t *r_keyblock, u32 *keyid);
|
||||
+
|
||||
+/* Same as get_pubkey_bykid but w/o r_keyblock. */
|
||||
int get_pubkey (ctrl_t ctrl, PKT_public_key *pk, u32 *keyid);
|
||||
|
||||
/* Same as get_pubkey but with auto LDAP fetch. */
|
||||
diff --git a/g10/mainproc.c b/g10/mainproc.c
|
||||
index 86f5a2db9..308738839 100644
|
||||
--- a/g10/mainproc.c
|
||||
+++ b/g10/mainproc.c
|
||||
@@ -1150,12 +1150,15 @@ proc_compressed (CTX c, PACKET *pkt)
|
||||
* used to verify the signature will be stored there, or NULL if not
|
||||
* found. If FORCED_PK is not NULL, this public key is used to verify
|
||||
* _data signatures_ and no key lookup is done. Returns: 0 = valid
|
||||
- * signature or an error code
|
||||
+ * signature or an error code. If R_KEYBLOCK is not NULL the keyblock
|
||||
+ * carries the used PK is stored there. The caller should always free
|
||||
+ * the return value using release_kbnode.
|
||||
*/
|
||||
static int
|
||||
do_check_sig (CTX c, kbnode_t node, const void *extrahash, size_t extrahashlen,
|
||||
PKT_public_key *forced_pk, int *is_selfsig,
|
||||
- int *is_expkey, int *is_revkey, PKT_public_key **r_pk)
|
||||
+ int *is_expkey, int *is_revkey,
|
||||
+ PKT_public_key **r_pk, kbnode_t *r_keyblock)
|
||||
{
|
||||
PKT_signature *sig;
|
||||
gcry_md_hd_t md = NULL;
|
||||
@@ -1165,6 +1168,8 @@ do_check_sig (CTX c, kbnode_t node, const void *extrahash, size_t extrahashlen,
|
||||
|
||||
if (r_pk)
|
||||
*r_pk = NULL;
|
||||
+ if (r_keyblock)
|
||||
+ *r_keyblock = NULL;
|
||||
|
||||
log_assert (node->pkt->pkttype == PKT_SIGNATURE);
|
||||
if (is_selfsig)
|
||||
@@ -1241,16 +1246,19 @@ do_check_sig (CTX c, kbnode_t node, const void *extrahash, size_t extrahashlen,
|
||||
/* We only get here if we are checking the signature of a binary
|
||||
(0x00) or text document (0x01). */
|
||||
rc = check_signature (c->ctrl, sig, md, extrahash, extrahashlen,
|
||||
- forced_pk, NULL, is_expkey, is_revkey, r_pk);
|
||||
+ forced_pk, NULL, is_expkey, is_revkey,
|
||||
+ r_pk, r_keyblock);
|
||||
if (! rc)
|
||||
md_good = md;
|
||||
else if (gpg_err_code (rc) == GPG_ERR_BAD_SIGNATURE && md2)
|
||||
{
|
||||
PKT_public_key *pk2;
|
||||
|
||||
+ if (r_keyblock)
|
||||
+ release_kbnode (*r_keyblock);
|
||||
rc = check_signature (c->ctrl, sig, md2, extrahash, extrahashlen,
|
||||
forced_pk, NULL, is_expkey, is_revkey,
|
||||
- r_pk? &pk2 : NULL);
|
||||
+ r_pk? &pk2 : NULL, r_keyblock);
|
||||
if (!rc)
|
||||
{
|
||||
md_good = md2;
|
||||
@@ -1413,7 +1421,7 @@ list_node (CTX c, kbnode_t node)
|
||||
{
|
||||
fflush (stdout);
|
||||
rc2 = do_check_sig (c, node, NULL, 0, NULL,
|
||||
- &is_selfsig, NULL, NULL, NULL);
|
||||
+ &is_selfsig, NULL, NULL, NULL, NULL);
|
||||
switch (gpg_err_code (rc2))
|
||||
{
|
||||
case 0: sigrc = '!'; break;
|
||||
@@ -1872,7 +1880,7 @@ check_sig_and_print (CTX c, kbnode_t node)
|
||||
PKT_public_key *pk = NULL; /* The public key for the signature or NULL. */
|
||||
const void *extrahash = NULL;
|
||||
size_t extrahashlen = 0;
|
||||
- kbnode_t included_keyblock = NULL;
|
||||
+ kbnode_t keyblock = NULL;
|
||||
|
||||
if (opt.skip_verify)
|
||||
{
|
||||
@@ -1993,7 +2001,8 @@ check_sig_and_print (CTX c, kbnode_t node)
|
||||
{
|
||||
ambiguous:
|
||||
log_error(_("can't handle this ambiguous signature data\n"));
|
||||
- return 0;
|
||||
+ rc = 0;
|
||||
+ goto leave;
|
||||
}
|
||||
} /* End checking signature packet composition. */
|
||||
|
||||
@@ -2029,7 +2038,7 @@ check_sig_and_print (CTX c, kbnode_t node)
|
||||
log_info (_(" issuer \"%s\"\n"), sig->signers_uid);
|
||||
|
||||
rc = do_check_sig (c, node, extrahash, extrahashlen, NULL,
|
||||
- NULL, &is_expkey, &is_revkey, &pk);
|
||||
+ NULL, &is_expkey, &is_revkey, &pk, &keyblock);
|
||||
|
||||
/* If the key is not found but the signature includes a key block we
|
||||
* use that key block for verification and on success import it. */
|
||||
@@ -2037,6 +2046,7 @@ check_sig_and_print (CTX c, kbnode_t node)
|
||||
&& sig->flags.key_block
|
||||
&& opt.flags.auto_key_import)
|
||||
{
|
||||
+ kbnode_t included_keyblock = NULL;
|
||||
PKT_public_key *included_pk;
|
||||
const byte *kblock;
|
||||
size_t kblock_len;
|
||||
@@ -2048,10 +2058,12 @@ check_sig_and_print (CTX c, kbnode_t node)
|
||||
kblock+1, kblock_len-1,
|
||||
sig->keyid, &included_keyblock))
|
||||
{
|
||||
+ /* Note: This is the only place where we use the forced_pk
|
||||
+ * arg (ie. included_pk) with do_check_sig. */
|
||||
rc = do_check_sig (c, node, extrahash, extrahashlen, included_pk,
|
||||
- NULL, &is_expkey, &is_revkey, &pk);
|
||||
+ NULL, &is_expkey, &is_revkey, &pk, NULL);
|
||||
if (opt.verbose)
|
||||
- log_debug ("checked signature using included key block: %s\n",
|
||||
+ log_info ("checked signature using included key block: %s\n",
|
||||
gpg_strerror (rc));
|
||||
if (!rc)
|
||||
{
|
||||
@@ -2061,6 +2073,18 @@ check_sig_and_print (CTX c, kbnode_t node)
|
||||
|
||||
}
|
||||
free_public_key (included_pk);
|
||||
+ release_kbnode (included_keyblock);
|
||||
+
|
||||
+ /* To make sure that nothing strange happened we check the
|
||||
+ * signature again now using our own key store. This also
|
||||
+ * returns the keyblock which we use later on. */
|
||||
+ if (!rc)
|
||||
+ {
|
||||
+ release_kbnode (keyblock);
|
||||
+ keyblock = NULL;
|
||||
+ rc = do_check_sig (c, node, extrahash, extrahashlen, NULL,
|
||||
+ NULL, &is_expkey, &is_revkey, &pk, &keyblock);
|
||||
+ }
|
||||
}
|
||||
|
||||
/* If the key isn't found, check for a preferred keyserver. Note
|
||||
@@ -2107,8 +2131,13 @@ check_sig_and_print (CTX c, kbnode_t node)
|
||||
KEYSERVER_IMPORT_FLAG_QUICK);
|
||||
glo_ctrl.in_auto_key_retrieve--;
|
||||
if (!res)
|
||||
- rc = do_check_sig (c, node, extrahash, extrahashlen, NULL,
|
||||
- NULL, &is_expkey, &is_revkey, &pk);
|
||||
+ {
|
||||
+ release_kbnode (keyblock);
|
||||
+ keyblock = NULL;
|
||||
+ rc = do_check_sig (c, node, extrahash, extrahashlen, NULL,
|
||||
+ NULL, &is_expkey, &is_revkey, &pk,
|
||||
+ &keyblock);
|
||||
+ }
|
||||
else if (DBG_LOOKUP)
|
||||
log_debug ("lookup via %s failed: %s\n", "Pref-KS",
|
||||
gpg_strerror (res));
|
||||
@@ -2149,8 +2178,12 @@ check_sig_and_print (CTX c, kbnode_t node)
|
||||
/* Fixme: If the fingerprint is embedded in the signature,
|
||||
* compare it to the fingerprint of the returned key. */
|
||||
if (!res)
|
||||
- rc = do_check_sig (c, node, extrahash, extrahashlen, NULL,
|
||||
- NULL, &is_expkey, &is_revkey, &pk);
|
||||
+ {
|
||||
+ release_kbnode (keyblock);
|
||||
+ keyblock = NULL;
|
||||
+ rc = do_check_sig (c, node, extrahash, extrahashlen, NULL,
|
||||
+ NULL, &is_expkey, &is_revkey, &pk, &keyblock);
|
||||
+ }
|
||||
else if (DBG_LOOKUP)
|
||||
log_debug ("lookup via %s failed: %s\n", "WKD", gpg_strerror (res));
|
||||
}
|
||||
@@ -2180,8 +2213,13 @@ check_sig_and_print (CTX c, kbnode_t node)
|
||||
KEYSERVER_IMPORT_FLAG_QUICK);
|
||||
glo_ctrl.in_auto_key_retrieve--;
|
||||
if (!res)
|
||||
- rc = do_check_sig (c, node, extrahash, extrahashlen, NULL,
|
||||
- NULL, &is_expkey, &is_revkey, &pk);
|
||||
+ {
|
||||
+ release_kbnode (keyblock);
|
||||
+ keyblock = NULL;
|
||||
+ rc = do_check_sig (c, node, extrahash, extrahashlen, NULL,
|
||||
+ NULL, &is_expkey, &is_revkey, &pk,
|
||||
+ &keyblock);
|
||||
+ }
|
||||
else if (DBG_LOOKUP)
|
||||
log_debug ("lookup via %s failed: %s\n", "KS", gpg_strerror (res));
|
||||
}
|
||||
@@ -2192,7 +2230,7 @@ check_sig_and_print (CTX c, kbnode_t node)
|
||||
{
|
||||
/* We have checked the signature and the result is either a good
|
||||
* signature or a bad signature. Further examination follows. */
|
||||
- kbnode_t un, keyblock;
|
||||
+ kbnode_t un;
|
||||
int count = 0;
|
||||
int keyblock_has_pk = 0; /* For failsafe check. */
|
||||
int statno;
|
||||
@@ -2210,18 +2248,6 @@ check_sig_and_print (CTX c, kbnode_t node)
|
||||
else
|
||||
statno = STATUS_GOODSIG;
|
||||
|
||||
- /* FIXME: We should have the public key in PK and thus the
|
||||
- * keyblock has already been fetched. Thus we could use the
|
||||
- * fingerprint or PK itself to lookup the entire keyblock. That
|
||||
- * would best be done with a cache. */
|
||||
- if (included_keyblock)
|
||||
- {
|
||||
- keyblock = included_keyblock;
|
||||
- included_keyblock = NULL;
|
||||
- }
|
||||
- else
|
||||
- keyblock = get_pubkeyblock_for_sig (c->ctrl, sig);
|
||||
-
|
||||
snprintf (keyid_str, sizeof keyid_str, "%08lX%08lX [uncertain] ",
|
||||
(ulong)sig->keyid[0], (ulong)sig->keyid[1]);
|
||||
|
||||
@@ -2287,10 +2313,10 @@ check_sig_and_print (CTX c, kbnode_t node)
|
||||
* contained in the keyring.*/
|
||||
}
|
||||
|
||||
- log_assert (mainpk);
|
||||
- if (!keyblock_has_pk)
|
||||
+ if (!mainpk || !keyblock_has_pk)
|
||||
{
|
||||
- log_error ("signature key lost from keyblock\n");
|
||||
+ log_error ("signature key lost from keyblock (%p,%p,%d)\n",
|
||||
+ keyblock, mainpk, keyblock_has_pk);
|
||||
rc = gpg_error (GPG_ERR_INTERNAL);
|
||||
}
|
||||
|
||||
@@ -2562,8 +2588,8 @@ check_sig_and_print (CTX c, kbnode_t node)
|
||||
log_error (_("Can't check signature: %s\n"), gpg_strerror (rc));
|
||||
}
|
||||
|
||||
+ leave:
|
||||
free_public_key (pk);
|
||||
- release_kbnode (included_keyblock);
|
||||
xfree (issuer_fpr);
|
||||
return rc;
|
||||
}
|
||||
diff --git a/g10/packet.h b/g10/packet.h
|
||||
index b61c65417..d6cbef4bc 100644
|
||||
--- a/g10/packet.h
|
||||
+++ b/g10/packet.h
|
||||
@@ -917,7 +917,7 @@ gpg_error_t check_signature (ctrl_t ctrl,
|
||||
const void *extrahash, size_t extrahashlen,
|
||||
PKT_public_key *forced_pk,
|
||||
u32 *r_expiredate, int *r_expired, int *r_revoked,
|
||||
- PKT_public_key **r_pk);
|
||||
+ PKT_public_key **r_pk, kbnode_t *r_keyblock);
|
||||
|
||||
|
||||
/*-- pubkey-enc.c --*/
|
||||
diff --git a/g10/sig-check.c b/g10/sig-check.c
|
||||
index 54db2089a..456c29320 100644
|
||||
--- a/g10/sig-check.c
|
||||
+++ b/g10/sig-check.c
|
||||
@@ -131,6 +131,11 @@ check_key_verify_compliance (PKT_public_key *pk)
|
||||
* If R_PK is not NULL, the public key is stored at that address if it
|
||||
* was found; other wise NULL is stored.
|
||||
*
|
||||
+ * If R_KEYBLOCK is not NULL, the entire keyblock used to verify the
|
||||
+ * signature is stored at that address. If no key was found or on
|
||||
+ * some other errors NULL is stored there. The callers needs to
|
||||
+ * release the keyblock using release_kbnode (kb).
|
||||
+ *
|
||||
* Returns 0 on success. An error code otherwise. */
|
||||
gpg_error_t
|
||||
check_signature (ctrl_t ctrl,
|
||||
@@ -138,7 +143,7 @@ check_signature (ctrl_t ctrl,
|
||||
const void *extrahash, size_t extrahashlen,
|
||||
PKT_public_key *forced_pk,
|
||||
u32 *r_expiredate, int *r_expired, int *r_revoked,
|
||||
- PKT_public_key **r_pk)
|
||||
+ PKT_public_key **r_pk, kbnode_t *r_keyblock)
|
||||
{
|
||||
int rc=0;
|
||||
PKT_public_key *pk;
|
||||
@@ -151,6 +156,8 @@ check_signature (ctrl_t ctrl,
|
||||
*r_revoked = 0;
|
||||
if (r_pk)
|
||||
*r_pk = NULL;
|
||||
+ if (r_keyblock)
|
||||
+ *r_keyblock = NULL;
|
||||
|
||||
pk = xtrycalloc (1, sizeof *pk);
|
||||
if (!pk)
|
||||
@@ -181,7 +188,7 @@ check_signature (ctrl_t ctrl,
|
||||
log_info(_("WARNING: signature digest conflict in message\n"));
|
||||
rc = gpg_error (GPG_ERR_GENERAL);
|
||||
}
|
||||
- else if (get_pubkey_for_sig (ctrl, pk, sig, forced_pk))
|
||||
+ else if (get_pubkey_for_sig (ctrl, pk, sig, forced_pk, r_keyblock))
|
||||
rc = gpg_error (GPG_ERR_NO_PUBKEY);
|
||||
else if ((rc = check_key_verify_compliance (pk)))
|
||||
;/* Compliance failure. */
|
||||
@@ -780,9 +787,9 @@ check_revocation_keys (ctrl_t ctrl, PKT_public_key *pk, PKT_signature *sig)
|
||||
keyid_from_fingerprint (ctrl, pk->revkey[i].fpr, pk->revkey[i].fprlen,
|
||||
keyid);
|
||||
|
||||
- if(keyid[0]==sig->keyid[0] && keyid[1]==sig->keyid[1])
|
||||
- /* The signature was generated by a designated revoker.
|
||||
- Verify the signature. */
|
||||
+ /* If the signature was generated by a designated revoker
|
||||
+ * verify the signature. */
|
||||
+ if (keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1])
|
||||
{
|
||||
gcry_md_hd_t md;
|
||||
|
||||
@@ -790,9 +797,9 @@ check_revocation_keys (ctrl_t ctrl, PKT_public_key *pk, PKT_signature *sig)
|
||||
BUG ();
|
||||
hash_public_key(md,pk);
|
||||
/* Note: check_signature only checks that the signature
|
||||
- is good. It does not fail if the key is revoked. */
|
||||
+ * is good. It does not fail if the key is revoked. */
|
||||
rc = check_signature (ctrl, sig, md, NULL, 0, NULL,
|
||||
- NULL, NULL, NULL, NULL);
|
||||
+ NULL, NULL, NULL, NULL, NULL);
|
||||
cache_sig_result(sig,rc);
|
||||
gcry_md_close (md);
|
||||
break;
|
||||
@@ -997,7 +1004,7 @@ check_signature_over_key_or_uid (ctrl_t ctrl, PKT_public_key *signer,
|
||||
if (IS_CERT (sig))
|
||||
signer->req_usage = PUBKEY_USAGE_CERT;
|
||||
|
||||
- rc = get_pubkey_for_sig (ctrl, signer, sig, NULL);
|
||||
+ rc = get_pubkey_for_sig (ctrl, signer, sig, NULL, NULL);
|
||||
if (rc)
|
||||
{
|
||||
xfree (signer);
|
||||
--
|
||||
2.33.0
|
||||
|
||||
177
backport-0005-CVE-2025-30258.patch
Normal file
177
backport-0005-CVE-2025-30258.patch
Normal file
@ -0,0 +1,177 @@
|
||||
From 1e581619bf5315957f2be06b3b1a7f513304c126 Mon Sep 17 00:00:00 2001
|
||||
From: Werner Koch <wk@gnupg.org>
|
||||
Date: Thu, 6 Mar 2025 17:17:17 +0100
|
||||
Subject: [PATCH] gpg: Fix regression for the recent malicious subkey DoS fix.
|
||||
|
||||
* g10/packet.h (PUBKEY_USAGE_VERIFY): New.
|
||||
* g10/getkey.c (get_pubkey_for_sig): Pass new flag also to requested
|
||||
usage.
|
||||
(finish_lookup): Introduce a verify_mode.
|
||||
--
|
||||
|
||||
Fixes-commit: da0164efc7f32013bc24d97b9afa9f8d67c318bb
|
||||
GnuPG-bug-id: 7547
|
||||
---
|
||||
g10/getkey.c | 44 ++++++++++++++++++++++++++++----------------
|
||||
g10/packet.h | 1 +
|
||||
2 files changed, 29 insertions(+), 16 deletions(-)
|
||||
|
||||
diff --git a/g10/getkey.c b/g10/getkey.c
|
||||
index c4d02fbb1..e3264062f 100644
|
||||
--- a/g10/getkey.c
|
||||
+++ b/g10/getkey.c
|
||||
@@ -315,11 +315,12 @@ pk_from_block (PKT_public_key *pk, kbnode_t keyblock, kbnode_t found_key)
|
||||
|
||||
|
||||
/* Specialized version of get_pubkey which retrieves the key based on
|
||||
- * information in SIG. In contrast to get_pubkey PK is required. IF
|
||||
+ * information in SIG. In contrast to get_pubkey PK is required. If
|
||||
* FORCED_PK is not NULL, this public key is used and copied to PK.
|
||||
* If R_KEYBLOCK is not NULL the entire keyblock is stored there if
|
||||
* found and FORCED_PK is not used; if not used or on error NULL is
|
||||
- * stored there. */
|
||||
+ * stored there. Use this function only to find the key for
|
||||
+ * verification; it can't be used to select a key for signing. */
|
||||
gpg_error_t
|
||||
get_pubkey_for_sig (ctrl_t ctrl, PKT_public_key *pk, PKT_signature *sig,
|
||||
PKT_public_key *forced_pk, kbnode_t *r_keyblock)
|
||||
@@ -339,8 +340,9 @@ get_pubkey_for_sig (ctrl_t ctrl, PKT_public_key *pk, PKT_signature *sig,
|
||||
|
||||
/* Make sure to request only keys cabable of signing. This makes
|
||||
* sure that a subkey w/o a valid backsig or with bad usage flags
|
||||
- * will be skipped. */
|
||||
- pk->req_usage = PUBKEY_USAGE_SIG;
|
||||
+ * will be skipped. We also request the verification mode so that
|
||||
+ * expired and reoked keys are returned. */
|
||||
+ pk->req_usage = (PUBKEY_USAGE_SIG | PUBKEY_USAGE_VERIFY);
|
||||
|
||||
/* First try the ISSUER_FPR info. */
|
||||
fpr = issuer_fpr_raw (sig, &fprlen);
|
||||
@@ -404,10 +406,10 @@ get_pubkey_bykid (ctrl_t ctrl, PKT_public_key *pk, kbnode_t *r_keyblock,
|
||||
/* Try to get it from the cache. We don't do this when pk is
|
||||
* NULL as it does not guarantee that the user IDs are cached.
|
||||
* The old get_pubkey_function did not check PK->REQ_USAGE when
|
||||
- * reading form the caceh. This is probably a bug. Note that
|
||||
+ * reading from the cache. This is probably a bug. Note that
|
||||
* the cache is not used when the caller asked to return the
|
||||
* entire keyblock. This is because the cache does not
|
||||
- * associate the public key wit its primary key. */
|
||||
+ * associate the public key with its primary key. */
|
||||
pk_cache_entry_t ce;
|
||||
for (ce = pk_cache; ce; ce = ce->next)
|
||||
{
|
||||
@@ -3724,11 +3726,18 @@ finish_lookup (kbnode_t keyblock, unsigned int req_usage, int want_exact,
|
||||
PKT_public_key *pk;
|
||||
int req_prim;
|
||||
int diag_exactfound = 0;
|
||||
+ int verify_mode = 0;
|
||||
u32 curtime = make_timestamp ();
|
||||
|
||||
if (r_flags)
|
||||
*r_flags = 0;
|
||||
|
||||
+
|
||||
+ /* The verify mode is used to change the behaviour so that we can
|
||||
+ * return an expired or revoked key for signature verification. */
|
||||
+ verify_mode = ((req_usage & PUBKEY_USAGE_VERIFY)
|
||||
+ && (req_usage & PUBKEY_USAGE_SIG));
|
||||
+
|
||||
#define USAGE_MASK (PUBKEY_USAGE_SIG|PUBKEY_USAGE_ENC|PUBKEY_USAGE_CERT)
|
||||
req_usage &= USAGE_MASK;
|
||||
|
||||
@@ -3784,9 +3793,9 @@ finish_lookup (kbnode_t keyblock, unsigned int req_usage, int want_exact,
|
||||
}
|
||||
|
||||
if (DBG_LOOKUP)
|
||||
- log_debug ("finish_lookup: checking key %08lX (%s)(req_usage=%x)\n",
|
||||
+ log_debug ("finish_lookup: checking key %08lX (%s)(req_usage=%x%s)\n",
|
||||
(ulong) keyid_from_pk (keyblock->pkt->pkt.public_key, NULL),
|
||||
- foundk ? "one" : "all", req_usage);
|
||||
+ foundk ? "one" : "all", req_usage, verify_mode? ",verify":"");
|
||||
if (diag_exactfound && DBG_LOOKUP)
|
||||
log_debug ("\texact search requested and found\n");
|
||||
|
||||
@@ -3850,28 +3859,29 @@ finish_lookup (kbnode_t keyblock, unsigned int req_usage, int want_exact,
|
||||
}
|
||||
|
||||
n_subkeys++;
|
||||
- if (pk->flags.revoked)
|
||||
+ if (!verify_mode && pk->flags.revoked)
|
||||
{
|
||||
if (DBG_LOOKUP)
|
||||
log_debug ("\tsubkey has been revoked\n");
|
||||
n_revoked_or_expired++;
|
||||
continue;
|
||||
}
|
||||
- if (pk->has_expired && !opt.ignore_expiration)
|
||||
+ if (!verify_mode && pk->has_expired && !opt.ignore_expiration)
|
||||
{
|
||||
if (DBG_LOOKUP)
|
||||
log_debug ("\tsubkey has expired\n");
|
||||
n_revoked_or_expired++;
|
||||
continue;
|
||||
}
|
||||
- if (pk->timestamp > curtime && !opt.ignore_valid_from)
|
||||
+ if (!verify_mode && pk->timestamp > curtime && !opt.ignore_valid_from)
|
||||
{
|
||||
if (DBG_LOOKUP)
|
||||
log_debug ("\tsubkey not yet valid\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
- if (want_secret)
|
||||
+
|
||||
+ if (!verify_mode && want_secret)
|
||||
{
|
||||
int secret_key_avail = agent_probe_secret_key (NULL, pk);
|
||||
|
||||
@@ -3898,7 +3908,8 @@ finish_lookup (kbnode_t keyblock, unsigned int req_usage, int want_exact,
|
||||
}
|
||||
|
||||
if (DBG_LOOKUP)
|
||||
- log_debug ("\tsubkey might be fine\n");
|
||||
+ log_debug ("\tsubkey might be fine%s\n",
|
||||
+ verify_mode? " for verification":"");
|
||||
/* In case a key has a timestamp of 0 set, we make sure
|
||||
that it is used. A better change would be to compare
|
||||
">=" but that might also change the selected keys and
|
||||
@@ -3939,12 +3950,12 @@ finish_lookup (kbnode_t keyblock, unsigned int req_usage, int want_exact,
|
||||
log_debug ("\tprimary key usage does not match: "
|
||||
"want=%x have=%x\n", req_usage, pk->pubkey_usage);
|
||||
}
|
||||
- else if (pk->flags.revoked)
|
||||
+ else if (!verify_mode && pk->flags.revoked)
|
||||
{
|
||||
if (DBG_LOOKUP)
|
||||
log_debug ("\tprimary key has been revoked\n");
|
||||
}
|
||||
- else if (pk->has_expired)
|
||||
+ else if (!verify_mode && pk->has_expired)
|
||||
{
|
||||
if (DBG_LOOKUP)
|
||||
log_debug ("\tprimary key has expired\n");
|
||||
@@ -3952,7 +3963,8 @@ finish_lookup (kbnode_t keyblock, unsigned int req_usage, int want_exact,
|
||||
else /* Okay. */
|
||||
{
|
||||
if (DBG_LOOKUP)
|
||||
- log_debug ("\tprimary key may be used\n");
|
||||
+ log_debug ("\tprimary key may be used%s\n",
|
||||
+ verify_mode? " for verification":"");
|
||||
latest_key = keyblock;
|
||||
}
|
||||
}
|
||||
diff --git a/g10/packet.h b/g10/packet.h
|
||||
index d6cbef4bc..9a1198d4a 100644
|
||||
--- a/g10/packet.h
|
||||
+++ b/g10/packet.h
|
||||
@@ -60,6 +60,7 @@
|
||||
#define PUBKEY_USAGE_RENC 1024 /* Restricted encryption. */
|
||||
#define PUBKEY_USAGE_TIME 2048 /* Timestamp use. */
|
||||
|
||||
+#define PUBKEY_USAGE_VERIFY 16384 /* Verify only modifier. */
|
||||
/* Bitflags to convey hints on what kind of signature is created. */
|
||||
#define SIGNHINT_KEYSIG 1
|
||||
#define SIGNHINT_SELFSIG 2
|
||||
--
|
||||
2.33.0
|
||||
|
||||
48
backport-0006-CVE-2025-30258.patch
Normal file
48
backport-0006-CVE-2025-30258.patch
Normal file
@ -0,0 +1,48 @@
|
||||
From 9b7c067717d815e16f9ea3cec88bca09a6cce7cb Mon Sep 17 00:00:00 2001
|
||||
From: Werner Koch <wk@gnupg.org>
|
||||
Date: Fri, 2 May 2025 11:11:05 +0200
|
||||
Subject: [PATCH] gpg: Fix another regression due to the T7547 fix.
|
||||
|
||||
* g10/getkey.c (get_pubkey_for_sig): Keep a requested
|
||||
PUBKEY_USAGE_CERT.
|
||||
(finish_lookup): For correctness in future use cases allow
|
||||
PUBKEY_USAGE_CERT to also trigger verify mode.
|
||||
--
|
||||
|
||||
The case here was that a cert-only primary key was removed with
|
||||
export-clean.
|
||||
|
||||
GnuPG-bug-id: 7583
|
||||
---
|
||||
g10/getkey.c | 8 +++++---
|
||||
1 file changed, 5 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/g10/getkey.c b/g10/getkey.c
|
||||
index e3264062f..ae0e00220 100644
|
||||
--- a/g10/getkey.c
|
||||
+++ b/g10/getkey.c
|
||||
@@ -341,8 +341,10 @@ get_pubkey_for_sig (ctrl_t ctrl, PKT_public_key *pk, PKT_signature *sig,
|
||||
/* Make sure to request only keys cabable of signing. This makes
|
||||
* sure that a subkey w/o a valid backsig or with bad usage flags
|
||||
* will be skipped. We also request the verification mode so that
|
||||
- * expired and reoked keys are returned. */
|
||||
- pk->req_usage = (PUBKEY_USAGE_SIG | PUBKEY_USAGE_VERIFY);
|
||||
+ * expired and revoked keys are returned. We keep only a requested
|
||||
+ * CERT usage in PK for the sake of key signatures. */
|
||||
+ pk->req_usage = (PUBKEY_USAGE_SIG | PUBKEY_USAGE_VERIFY
|
||||
+ | (pk->req_usage & PUBKEY_USAGE_CERT));
|
||||
|
||||
/* First try the ISSUER_FPR info. */
|
||||
fpr = issuer_fpr_raw (sig, &fprlen);
|
||||
@@ -3736,7 +3738,7 @@ finish_lookup (kbnode_t keyblock, unsigned int req_usage, int want_exact,
|
||||
/* The verify mode is used to change the behaviour so that we can
|
||||
* return an expired or revoked key for signature verification. */
|
||||
verify_mode = ((req_usage & PUBKEY_USAGE_VERIFY)
|
||||
- && (req_usage & PUBKEY_USAGE_SIG));
|
||||
+ && (req_usage & (PUBKEY_USAGE_CERT|PUBKEY_USAGE_SIG)));
|
||||
|
||||
#define USAGE_MASK (PUBKEY_USAGE_SIG|PUBKEY_USAGE_ENC|PUBKEY_USAGE_CERT)
|
||||
req_usage &= USAGE_MASK;
|
||||
--
|
||||
2.43.0
|
||||
|
||||
32
backport-gpg-Fix-double-free-of-internal-data.patch
Normal file
32
backport-gpg-Fix-double-free-of-internal-data.patch
Normal file
@ -0,0 +1,32 @@
|
||||
From 4be25979a6b3e2a79d7c9667b07db8b09fb046e9 Mon Sep 17 00:00:00 2001
|
||||
From: Werner Koch <wk@gnupg.org>
|
||||
Date: Thu, 13 Mar 2025 11:35:34 +0100
|
||||
Subject: [PATCH] gpg: Fix double free of internal data.
|
||||
|
||||
* g10/sig-check.c (check_signature_over_key_or_uid): Do not free in
|
||||
no-sig-cache mode if allocated by caller.
|
||||
--
|
||||
|
||||
GnuPG-bug-id: 7547
|
||||
Fixes-commit: 44cdb9d73f1a0b7d2c8483a119b9c4d6caabc1ec
|
||||
---
|
||||
g10/sig-check.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/g10/sig-check.c b/g10/sig-check.c
|
||||
index 456c29320..ed83c23f9 100644
|
||||
--- a/g10/sig-check.c
|
||||
+++ b/g10/sig-check.c
|
||||
@@ -1007,7 +1007,8 @@ check_signature_over_key_or_uid (ctrl_t ctrl, PKT_public_key *signer,
|
||||
rc = get_pubkey_for_sig (ctrl, signer, sig, NULL, NULL);
|
||||
if (rc)
|
||||
{
|
||||
- xfree (signer);
|
||||
+ if (signer_alloced != 1)
|
||||
+ xfree (signer);
|
||||
signer = NULL;
|
||||
signer_alloced = 0;
|
||||
goto leave;
|
||||
--
|
||||
2.33.0
|
||||
|
||||
@ -0,0 +1,47 @@
|
||||
From 95b9a31f81e4a56518269d2476b54a1f10fe8b3e Mon Sep 17 00:00:00 2001
|
||||
From: Werner Koch <wk@gnupg.org>
|
||||
Date: Fri, 27 Oct 2023 14:20:47 +0200
|
||||
Subject: [PATCH] gpg: Fix minor memory leak during certain smartcard
|
||||
operations.
|
||||
|
||||
* g10/keygen.c (card_store_key_with_backup): Fix memory leak on error.
|
||||
---
|
||||
g10/keygen.c | 13 +++++++++++--
|
||||
1 file changed, 11 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/g10/keygen.c b/g10/keygen.c
|
||||
index 87940722d..2f8528278 100644
|
||||
--- a/g10/keygen.c
|
||||
+++ b/g10/keygen.c
|
||||
@@ -5386,17 +5386,26 @@ card_store_key_with_backup (ctrl_t ctrl, PKT_public_key *sub_psk,
|
||||
{
|
||||
ecdh_param_str = ecdh_param_str_from_pk (sk);
|
||||
if (!ecdh_param_str)
|
||||
- return gpg_error_from_syserror ();
|
||||
+ {
|
||||
+ free_public_key (sk);
|
||||
+ return gpg_error_from_syserror ();
|
||||
+ }
|
||||
}
|
||||
|
||||
err = hexkeygrip_from_pk (sk, &hexgrip);
|
||||
if (err)
|
||||
- goto leave;
|
||||
+ {
|
||||
+ xfree (ecdh_param_str);
|
||||
+ free_public_key (sk);
|
||||
+ goto leave;
|
||||
+ }
|
||||
|
||||
memset(&info, 0, sizeof (info));
|
||||
rc = agent_scd_getattr ("SERIALNO", &info);
|
||||
if (rc)
|
||||
{
|
||||
+ xfree (ecdh_param_str);
|
||||
+ free_public_key (sk);
|
||||
err = (gpg_error_t)rc;
|
||||
goto leave;
|
||||
}
|
||||
--
|
||||
2.33.0
|
||||
|
||||
111
backport-gpg-Make-no-literal-work-again-for-c-and-store.patch
Normal file
111
backport-gpg-Make-no-literal-work-again-for-c-and-store.patch
Normal file
@ -0,0 +1,111 @@
|
||||
From 9a741aba3d9040d2bb367db79e9021ba6abc12dd Mon Sep 17 00:00:00 2001
|
||||
From: Werner Koch <wk@gnupg.org>
|
||||
Date: Fri, 6 Sep 2024 15:46:41 +0200
|
||||
Subject: [PATCH] gpg: Make --no-literal work again for -c and --store.
|
||||
|
||||
* g10/dearmor.c (dearmor_file): Check for errors of iobuf_copy.
|
||||
(enarmor_file): Ditto.
|
||||
* g10/encrypt.c (encrypt_simple): Fix error check of iobuf_copy
|
||||
(encrypt_crypt): Use iobuf_copy.
|
||||
--
|
||||
|
||||
Fixes-commit: 756c0bd5d89bd0a773f844fbc2ec508c1a36c63d
|
||||
GnuPG-bug-id: 5852
|
||||
---
|
||||
g10/dearmor.c | 12 ++++++++++++
|
||||
g10/encrypt.c | 35 +++++++++++++++++------------------
|
||||
2 files changed, 29 insertions(+), 18 deletions(-)
|
||||
|
||||
diff --git a/g10/dearmor.c b/g10/dearmor.c
|
||||
index f6bb59ef6..667888362 100644
|
||||
--- a/g10/dearmor.c
|
||||
+++ b/g10/dearmor.c
|
||||
@@ -67,6 +67,12 @@ dearmor_file( const char *fname )
|
||||
goto leave;
|
||||
|
||||
iobuf_copy (out, inp);
|
||||
+ if ((rc = iobuf_error (inp)))
|
||||
+ log_error (_("error reading '%s': %s\n"),
|
||||
+ iobuf_get_fname_nonnull (inp), gpg_strerror (rc));
|
||||
+ else if ((rc = iobuf_error (out)))
|
||||
+ log_error (_("error writing '%s': %s\n"),
|
||||
+ iobuf_get_fname_nonnull (out), gpg_strerror (rc));
|
||||
|
||||
leave:
|
||||
if( rc )
|
||||
@@ -115,6 +121,12 @@ enarmor_file( const char *fname )
|
||||
push_armor_filter ( afx, out );
|
||||
|
||||
iobuf_copy (out, inp);
|
||||
+ if ((rc = iobuf_error (inp)))
|
||||
+ log_error (_("error reading '%s': %s\n"),
|
||||
+ iobuf_get_fname_nonnull (inp), gpg_strerror (rc));
|
||||
+ else if ((rc = iobuf_error (out)))
|
||||
+ log_error (_("error writing '%s': %s\n"),
|
||||
+ iobuf_get_fname_nonnull (out), gpg_strerror (rc));
|
||||
|
||||
leave:
|
||||
if( rc )
|
||||
diff --git a/g10/encrypt.c b/g10/encrypt.c
|
||||
index 3fc10a7b8..cc8f37fe2 100644
|
||||
--- a/g10/encrypt.c
|
||||
+++ b/g10/encrypt.c
|
||||
@@ -633,9 +633,13 @@ encrypt_simple (const char *filename, int mode, int use_seskey)
|
||||
{
|
||||
/* User requested not to create a literal packet, so we copy the
|
||||
plain data. */
|
||||
- rc = iobuf_copy (out, inp);
|
||||
- if (rc)
|
||||
- log_error ("copying input to output failed: %s\n", gpg_strerror (rc));
|
||||
+ iobuf_copy (out, inp);
|
||||
+ if ((rc = iobuf_error (inp)))
|
||||
+ log_error (_("error reading '%s': %s\n"),
|
||||
+ iobuf_get_fname_nonnull (inp), gpg_strerror (rc));
|
||||
+ else if ((rc = iobuf_error (out)))
|
||||
+ log_error (_("error writing '%s': %s\n"),
|
||||
+ iobuf_get_fname_nonnull (out), gpg_strerror (rc));
|
||||
}
|
||||
|
||||
/* Finish the stuff. */
|
||||
@@ -760,8 +764,8 @@ write_symkey_enc (STRING2KEY *symkey_s2k, aead_algo_t aead_algo,
|
||||
* The caller may provide a checked list of public keys in
|
||||
* PROVIDED_PKS; if not the function builds a list of keys on its own.
|
||||
*
|
||||
- * Note that FILEFD is currently only used by cmd_encrypt in the
|
||||
- * not yet finished server.c.
|
||||
+ * Note that FILEFD and OUTPUTFD are currently only used by
|
||||
+ * cmd_encrypt in the not yet finished server.c.
|
||||
*/
|
||||
int
|
||||
encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename,
|
||||
@@ -996,19 +1000,14 @@ encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename,
|
||||
{
|
||||
/* User requested not to create a literal packet, so we copy the
|
||||
plain data. */
|
||||
- byte copy_buffer[4096];
|
||||
- int bytes_copied;
|
||||
- while ((bytes_copied = iobuf_read (inp, copy_buffer, 4096)) != -1)
|
||||
- {
|
||||
- rc = iobuf_write (out, copy_buffer, bytes_copied);
|
||||
- if (rc)
|
||||
- {
|
||||
- log_error ("copying input to output failed: %s\n",
|
||||
- gpg_strerror (rc));
|
||||
- break;
|
||||
- }
|
||||
- }
|
||||
- wipememory (copy_buffer, 4096); /* Burn the buffer. */
|
||||
+ iobuf_copy (out, inp);
|
||||
+ if ((rc = iobuf_error (inp)))
|
||||
+ log_error (_("error reading '%s': %s\n"),
|
||||
+ iobuf_get_fname_nonnull (inp), gpg_strerror (rc));
|
||||
+ else if ((rc = iobuf_error (out)))
|
||||
+ log_error (_("error writing '%s': %s\n"),
|
||||
+ iobuf_get_fname_nonnull (out), gpg_strerror (rc));
|
||||
+
|
||||
}
|
||||
|
||||
/* Finish the stuff. */
|
||||
--
|
||||
2.33.0
|
||||
|
||||
26
gnupg2.spec
26
gnupg2.spec
@ -1,6 +1,6 @@
|
||||
Name: gnupg2
|
||||
Version: 2.4.3
|
||||
Release: 2
|
||||
Release: 7
|
||||
Summary: Utility for secure communication and data storage
|
||||
|
||||
License: GPLv3+
|
||||
@ -18,6 +18,15 @@ Patch7: gnupg-2.2.20-file-is-digest.patch
|
||||
Patch8: gnupg-2.2.21-coverity.patch
|
||||
Patch9: gnupg2-revert-rfc4880bis.patch
|
||||
Patch10: backport-dirmngr-Enable-the-call-of-ks_ldap_help_variables-wh.patch
|
||||
Patch11: backport-gpg-Make-no-literal-work-again-for-c-and-store.patch
|
||||
Patch12: backport-gpg-Fix-minor-memory-leak-during-certain-smartcard-o.patch
|
||||
Patch13: backport-0001-CVE-2025-30258.patch
|
||||
Patch14: backport-0002-CVE-2025-30258.patch
|
||||
Patch15: backport-0003-CVE-2025-30258.patch
|
||||
Patch16: backport-0004-CVE-2025-30258.patch
|
||||
Patch17: backport-0005-CVE-2025-30258.patch
|
||||
Patch18: backport-0006-CVE-2025-30258.patch
|
||||
Patch19: backport-gpg-Fix-double-free-of-internal-data.patch
|
||||
|
||||
BuildRequires: gcc
|
||||
BuildRequires: zlib-devel, npth-devel, texinfo
|
||||
@ -119,6 +128,21 @@ make check
|
||||
|
||||
|
||||
%changelog
|
||||
* Tue May 6 2025 yixiangzhike <yixiangzhike007@163.com> - 2.4.3-7
|
||||
- backport follow-up patch for CVE-2025-30258
|
||||
|
||||
* Thu Mar 27 2025 yixiangzhike <yixiangzhike007@163.com> - 2.4.3-6
|
||||
- fix CVE-2025-30258
|
||||
|
||||
* Fri Mar 21 2025 yixiangzhike <yixiangzhike007@163.com> - 2.4.3-5
|
||||
- backport upstream patch to fix double free
|
||||
|
||||
* Mon Sep 30 2024 yixiangzhike <yixiangzhike007@163.com> - 2.4.3-4
|
||||
- backport upstream patch to fix minor memory leak
|
||||
|
||||
* Wed Sep 25 2024 yixiangzhike <yixiangzhike007@163.com> - 2.4.3-3
|
||||
- gpg Make --no-literal work again for -c and --store
|
||||
|
||||
* Tue Jan 2 2024 yixiangzhike <yixiangzhike007@163.com> - 2.4.3-2
|
||||
- use gpgtar to replace gpg-zip
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user