summaryrefslogtreecommitdiffstats
path: root/meta
diff options
context:
space:
mode:
authorYogita Urade <yogita.urade@windriver.com>2025-07-22 16:16:29 +0530
committerSteve Sakoman <steve@sakoman.com>2025-07-30 07:47:48 -0700
commit87e1bc09cabe609981d5ee7ea4919755e2072ad9 (patch)
tree5458aab689c389ee58dfc9e069e0bb0348b21d65 /meta
parentdb3621b9837ae1efe7c30e359e5a64a4ca1cbbd2 (diff)
downloadpoky-87e1bc09cabe609981d5ee7ea4919755e2072ad9.tar.gz
gnupg: fix CVE-2025-30258
In GnuPG before 2.5.5, if a user chooses to import a certificate with certain crafted subkey data that lacks a valid backsig or that has incorrect usage flags, the user loses the ability to verify signatures made from certain other signing keys, aka a "verification DoS." CVE-2025-30258-0002 is the dependent commit while rest are CVE fixes. Reference: https://nvd.nist.gov/vuln/detail/CVE-2025-30258 Upstream patches: https://dev.gnupg.org/rG25d748c3dfc0102f9e54afea59ff26b3969bd8c1 https://dev.gnupg.org/rG9cd371b12d80cfc5bc85cb6e5f5eebb4decbe94f https://dev.gnupg.org/rGda0164efc7f32013bc24d97b9afa9f8d67c318bb https://dev.gnupg.org/rG1e581619bf5315957f2be06b3b1a7f513304c126 https://dev.gnupg.org/rG4be25979a6b3e2a79d7c9667b07db8b09fb046e9 (From OE-Core rev: 467081219407cd30bcc9e575bedcb127b6bcea65) Signed-off-by: Yogita Urade <yogita.urade@windriver.com> Signed-off-by: Steve Sakoman <steve@sakoman.com>
Diffstat (limited to 'meta')
-rw-r--r--meta/recipes-support/gnupg/gnupg/CVE-2025-30258-0001.patch141
-rw-r--r--meta/recipes-support/gnupg/gnupg/CVE-2025-30258-0002.patch131
-rw-r--r--meta/recipes-support/gnupg/gnupg/CVE-2025-30258-0003.patch624
-rw-r--r--meta/recipes-support/gnupg/gnupg/CVE-2025-30258-0004.patch193
-rw-r--r--meta/recipes-support/gnupg/gnupg/CVE-2025-30258-0005.patch36
-rw-r--r--meta/recipes-support/gnupg/gnupg_2.3.7.bb5
6 files changed, 1130 insertions, 0 deletions
diff --git a/meta/recipes-support/gnupg/gnupg/CVE-2025-30258-0001.patch b/meta/recipes-support/gnupg/gnupg/CVE-2025-30258-0001.patch
new file mode 100644
index 0000000000..56aa2ce3e1
--- /dev/null
+++ b/meta/recipes-support/gnupg/gnupg/CVE-2025-30258-0001.patch
@@ -0,0 +1,141 @@
1From 25d748c3dfc0102f9e54afea59ff26b3969bd8c1 Mon Sep 17 00:00:00 2001
2From: Werner Koch <wk@gnupg.org>
3Date: Tue, 11 Feb 2025 14:44:23 +0100
4Subject: [PATCH] gpg: Lookup key for merging/inserting only by primary key.
5
6* g10/getkey.c (get_keyblock_byfpr_fast): Add arg primary_only and
7implement.
8* g10/import.c (import_one_real): Simplify filling the fpr buffer with
9zeroes.
10(import_one_real): Find key only by primary fingerprint.
11--
12
13This should have been done early: When looking up the original
14keyblock we want to update, we need to lookup it up only using the
15primary key. This avoids to find a key which has the primary key also
16has a subkey.
17
18GnuPG-bug-id: 7527
19
20CVE: CVE-2025-30258
21Upstream-Status: Backport [https://dev.gnupg.org/rG25d748c3dfc0102f9e54afea59ff26b3969bd8c1]
22
23Signed-off-by: Yogita Urade <yogita.urade@windriver.com>
24---
25 g10/getkey.c | 23 ++++++++++++++++++++---
26 g10/import.c | 6 +++---
27 g10/keydb.h | 3 ++-
28 3 files changed, 25 insertions(+), 7 deletions(-)
29
30diff --git a/g10/getkey.c b/g10/getkey.c
31index e49718e..7a25643 100644
32--- a/g10/getkey.c
33+++ b/g10/getkey.c
34@@ -1895,7 +1895,7 @@ get_pubkey_byfprint_fast (ctrl_t ctrl, PKT_public_key * pk,
35 KBNODE keyblock;
36
37 err = get_keyblock_byfprint_fast (ctrl,
38- &keyblock, NULL, fprint, fprint_len, 0);
39+ &keyblock, NULL, 0, fprint, fprint_len, 0);
40 if (!err)
41 {
42 if (pk)
43@@ -1912,11 +1912,14 @@ get_pubkey_byfprint_fast (ctrl_t ctrl, PKT_public_key * pk,
44 * R_HD may be NULL. If LOCK is set the handle has been opend in
45 * locked mode and keydb_disable_caching () has been called. On error
46 * R_KEYBLOCK is set to NULL but R_HD must be released by the caller;
47- * it may have a value of NULL, though. This allows to do an insert
48- * operation on a locked keydb handle. */
49+ * it may have a value of NULL, though. This allows to do an
50+ * insert operation on a locked keydb handle. If PRIMARY_ONLY is set
51+ * the function returns a keyblock which has the requested fingerprint
52+ * has primary key. */
53 gpg_error_t
54 get_keyblock_byfprint_fast (ctrl_t ctrl,
55 kbnode_t *r_keyblock, KEYDB_HANDLE *r_hd,
56+ int primary_only,
57 const byte *fprint, size_t fprint_len, int lock)
58 {
59 gpg_error_t err;
60@@ -1924,6 +1927,8 @@ get_keyblock_byfprint_fast (ctrl_t ctrl,
61 kbnode_t keyblock;
62 byte fprbuf[MAX_FINGERPRINT_LEN];
63 int i;
64+ byte tmpfpr[MAX_FINGERPRINT_LEN];
65+ size_t tmpfprlen;
66
67 if (r_keyblock)
68 *r_keyblock = NULL;
69@@ -1955,6 +1960,7 @@ get_keyblock_byfprint_fast (ctrl_t ctrl,
70 if (r_hd)
71 *r_hd = hd;
72
73+again:
74 err = keydb_search_fpr (hd, fprbuf, fprint_len);
75 if (gpg_err_code (err) == GPG_ERR_NOT_FOUND)
76 {
77@@ -1974,6 +1980,17 @@ get_keyblock_byfprint_fast (ctrl_t ctrl,
78 log_assert (keyblock->pkt->pkttype == PKT_PUBLIC_KEY
79 || keyblock->pkt->pkttype == PKT_PUBLIC_SUBKEY);
80
81+ if (primary_only)
82+ {
83+ fingerprint_from_pk (keyblock->pkt->pkt.public_key, tmpfpr, &tmpfprlen);
84+ if (fprint_len != tmpfprlen || memcmp (fprint, tmpfpr, fprint_len))
85+ {
86+ release_kbnode (keyblock);
87+ keyblock = NULL;
88+ goto again;
89+ }
90+ }
91+
92 /* Not caching key here since it won't have all of the fields
93 properly set. */
94
95diff --git a/g10/import.c b/g10/import.c
96index bb0bf67..fb0e2ee 100644
97--- a/g10/import.c
98+++ b/g10/import.c
99@@ -1893,7 +1893,6 @@ import_one_real (ctrl_t ctrl,
100 int mod_key = 0;
101 int same_key = 0;
102 int non_self = 0;
103- size_t an;
104 char pkstrbuf[PUBKEY_STRING_SIZE];
105 int merge_keys_done = 0;
106 int any_filter = 0;
107@@ -1914,8 +1913,8 @@ import_one_real (ctrl_t ctrl,
108 pk = node->pkt->pkt.public_key;
109
110 fingerprint_from_pk (pk, fpr2, &fpr2len);
111- for (an = fpr2len; an < MAX_FINGERPRINT_LEN; an++)
112- fpr2[an] = 0;
113+ if (MAX_FINGERPRINT_LEN > fpr2len)
114+ memset (fpr2+fpr2len, 0, MAX_FINGERPRINT_LEN - fpr2len);
115 keyid_from_pk( pk, keyid );
116 uidnode = find_next_kbnode( keyblock, PKT_USER_ID );
117
118@@ -2097,6 +2096,7 @@ import_one_real (ctrl_t ctrl,
119
120 /* Do we have this key already in one of our pubrings ? */
121 err = get_keyblock_byfprint_fast (ctrl, &keyblock_orig, &hd,
122+ 1 /*primary only */,
123 fpr2, fpr2len, 1/*locked*/);
124 if ((err
125 && gpg_err_code (err) != GPG_ERR_NO_PUBKEY
126diff --git a/g10/keydb.h b/g10/keydb.h
127index a91309a..51dfece 100644
128--- a/g10/keydb.h
129+++ b/g10/keydb.h
130@@ -418,7 +418,8 @@ gpg_error_t get_pubkey_byfprint_fast (ctrl_t ctrl, PKT_public_key *pk,
131 gpg_error_t get_keyblock_byfprint_fast (ctrl_t ctrl,
132 kbnode_t *r_keyblock,
133 KEYDB_HANDLE *r_hd,
134- const byte *fprint, size_t fprint_len,
135+ int primary_only,
136+ const byte *fpr, size_t fprlen,
137 int lock);
138
139
140--
1412.40.0
diff --git a/meta/recipes-support/gnupg/gnupg/CVE-2025-30258-0002.patch b/meta/recipes-support/gnupg/gnupg/CVE-2025-30258-0002.patch
new file mode 100644
index 0000000000..58e50fabac
--- /dev/null
+++ b/meta/recipes-support/gnupg/gnupg/CVE-2025-30258-0002.patch
@@ -0,0 +1,131 @@
1From 9cd371b12d80cfc5bc85cb6e5f5eebb4decbe94f Mon Sep 17 00:00:00 2001
2From: Werner Koch <wk@gnupg.org>
3Date: Thu, 20 Feb 2025 14:50:20 +0100
4Subject: [PATCH] gpg: Remove a signature check function wrapper.
5
6* g10/sig-check.c (check_signature2): Rename to
7(check_signature): this and remove the old wrapper. Adjust all
8callers.
9
10CVE: CVE-2025-30258
11Upstream-Status: Backport [https://dev.gnupg.org/rG9cd371b12d80cfc5bc85cb6e5f5eebb4decbe94f]
12
13Signed-off-by: Yogita Urade <yogita.urade@windriver.com>
14---
15 g10/mainproc.c | 13 +++++--------
16 g10/packet.h | 6 +-----
17 g10/sig-check.c | 26 ++++++++------------------
18 3 files changed, 14 insertions(+), 31 deletions(-)
19
20diff --git a/g10/mainproc.c b/g10/mainproc.c
21index af11877..79d9ff2 100644
22--- a/g10/mainproc.c
23+++ b/g10/mainproc.c
24@@ -1198,19 +1198,17 @@ do_check_sig (CTX c, kbnode_t node, const void *extrahash, size_t extrahashlen,
25
26 /* We only get here if we are checking the signature of a binary
27 (0x00) or text document (0x01). */
28- rc = check_signature2 (c->ctrl, sig, md, extrahash, extrahashlen,
29- forced_pk,
30- NULL, is_expkey, is_revkey, r_pk);
31+ rc = check_signature (c->ctrl, sig, md, extrahash, extrahashlen,
32+ forced_pk, NULL, is_expkey, is_revkey, r_pk);
33 if (! rc)
34 md_good = md;
35 else if (gpg_err_code (rc) == GPG_ERR_BAD_SIGNATURE && md2)
36 {
37 PKT_public_key *pk2;
38
39- rc = check_signature2 (c->ctrl, sig, md2, extrahash, extrahashlen,
40- forced_pk,
41- NULL, is_expkey, is_revkey,
42- r_pk? &pk2 : NULL);
43+ rc = check_signature (c->ctrl, sig, md2, extrahash, extrahashlen,
44+ forced_pk, NULL, is_expkey, is_revkey,
45+ r_pk? &pk2 : NULL);
46 if (!rc)
47 {
48 md_good = md2;
49@@ -1792,7 +1790,6 @@ issuer_fpr_string (PKT_signature *sig)
50 return p? bin2hex (p, n, NULL) : NULL;
51 }
52
53-
54 static void
55 print_good_bad_signature (int statno, const char *keyid_str, kbnode_t un,
56 PKT_signature *sig, int rc)
57diff --git a/g10/packet.h b/g10/packet.h
58index 5a14015..8aaf32d 100644
59--- a/g10/packet.h
60+++ b/g10/packet.h
61@@ -889,16 +889,12 @@ int cmp_user_ids( PKT_user_id *a, PKT_user_id *b );
62
63
64 /*-- sig-check.c --*/
65-/* Check a signature. This is shorthand for check_signature2 with
66- the unnamed arguments passed as NULL. */
67-int check_signature (ctrl_t ctrl, PKT_signature *sig, gcry_md_hd_t digest);
68-
69 /* Check a signature. Looks up the public key from the key db. (If
70 * R_PK is not NULL, it is stored at RET_PK.) DIGEST contains a
71 * valid hash context that already includes the signed data. This
72 * function adds the relevant meta-data to the hash before finalizing
73 * it and verifying the signature. FOCRED_PK is usually NULL. */
74-gpg_error_t check_signature2 (ctrl_t ctrl,
75+gpg_error_t check_signature (ctrl_t ctrl,
76 PKT_signature *sig, gcry_md_hd_t digest,
77 const void *extrahash, size_t extrahashlen,
78 PKT_public_key *forced_pk,
79diff --git a/g10/sig-check.c b/g10/sig-check.c
80index eb6c966..2272fa4 100644
81--- a/g10/sig-check.c
82+++ b/g10/sig-check.c
83@@ -95,17 +95,6 @@ check_key_verify_compliance (PKT_public_key *pk)
84 }
85
86
87-
88-/* Check a signature. This is shorthand for check_signature2 with
89- the unnamed arguments passed as NULL. */
90-int
91-check_signature (ctrl_t ctrl, PKT_signature *sig, gcry_md_hd_t digest)
92-{
93- return check_signature2 (ctrl, sig, digest, NULL, 0, NULL,
94- NULL, NULL, NULL, NULL);
95-}
96-
97-
98 /* Check a signature.
99 *
100 * Looks up the public key that created the signature (SIG->KEYID)
101@@ -151,12 +140,12 @@ check_signature (ctrl_t ctrl, PKT_signature *sig, gcry_md_hd_t digest)
102 *
103 * Returns 0 on success. An error code otherwise. */
104 gpg_error_t
105-check_signature2 (ctrl_t ctrl,
106- PKT_signature *sig, gcry_md_hd_t digest,
107- const void *extrahash, size_t extrahashlen,
108- PKT_public_key *forced_pk,
109- u32 *r_expiredate,
110- int *r_expired, int *r_revoked, PKT_public_key **r_pk)
111+check_signature (ctrl_t ctrl,
112+ PKT_signature *sig, gcry_md_hd_t digest,
113+ const void *extrahash, size_t extrahashlen,
114+ PKT_public_key *forced_pk,
115+ u32 *r_expiredate, int *r_expired, int *r_revoked,
116+ PKT_public_key **r_pk)
117 {
118 int rc=0;
119 PKT_public_key *pk;
120@@ -808,7 +797,8 @@ check_revocation_keys (ctrl_t ctrl, PKT_public_key *pk, PKT_signature *sig)
121 hash_public_key(md,pk);
122 /* Note: check_signature only checks that the signature
123 is good. It does not fail if the key is revoked. */
124- rc = check_signature (ctrl, sig, md);
125+ rc = check_signature (ctrl, sig, md, NULL, 0, NULL,
126+ NULL, NULL, NULL, NULL);
127 cache_sig_result(sig,rc);
128 gcry_md_close (md);
129 break;
130--
1312.40.0
diff --git a/meta/recipes-support/gnupg/gnupg/CVE-2025-30258-0003.patch b/meta/recipes-support/gnupg/gnupg/CVE-2025-30258-0003.patch
new file mode 100644
index 0000000000..223972788f
--- /dev/null
+++ b/meta/recipes-support/gnupg/gnupg/CVE-2025-30258-0003.patch
@@ -0,0 +1,624 @@
1From da0164efc7f32013bc24d97b9afa9f8d67c318bb Mon Sep 17 00:00:00 2001
2rom: Werner Koch <wk@gnupg.org>
3Date: Fri, 21 Feb 2025 12:16:17 +0100
4Subject: [PATCH] gpg: Fix a verification DoS due to a malicious subkey in the
5 keyring.
6
7* g10/getkey.c (get_pubkey): Factor code out to ...
8(get_pubkey_bykid): new. Add feature to return the keyblock.
9(get_pubkey_for_sig): Add arg r_keyblock to return the used keyblock.
10Request a signing usage.
11(get_pubkeyblock_for_sig): Remove.
12(finish_lookup): Improve debug output.
13* g10/sig-check.c (check_signature): Add arg r_keyblock and pass it
14down.
15* g10/mainproc.c (do_check_sig): Ditto.
16(check_sig_and_print): Use the keyblock returned by do_check_sig to
17show further information instead of looking it up again with
18get_pubkeyblock_for_sig. Also re-check the signature after the import
19of an included keyblock.
20--
21
22The problem here is that it is possible to import a key from someone
23who added a signature subkey from another public key and thus inhibits
24that a good signature good be verified.
25
26Such a malicious key signature subkey must have been created w/o the
27mandatory backsig which bind a signature subkey to its primary key.
28For encryption subkeys this is not an issue because the existence of a
29decryption private key is all you need to decrypt something and then
30it does not matter if the public subkey or its binding signature has
31been put below another primary key; in fact we do the latter for
32ADSKs.
33
34GnuPG-bug-id: 7527
35Backported-from-master: 48978ccb4e20866472ef18436a32744350a65158
36
37CVE: CVE-2025-30258
38Upstream-Status: Backport [https://dev.gnupg.org/rGda0164efc7f32013bc24d97b9afa9f8d67c318bb]
39
40Signed-off-by: Yogita Urade <yogita.urade@windriver.com>
41---
42 g10/getkey.c | 106 ++++++++++++++++++++++++++++++------------------
43 g10/gpg.h | 3 +-
44 g10/keydb.h | 10 ++++-
45 g10/mainproc.c | 92 ++++++++++++++++++++++++++---------------
46 g10/packet.h | 2 +-
47 g10/sig-check.c | 23 +++++++----
48 6 files changed, 152 insertions(+), 84 deletions(-)
49
50diff --git a/g10/getkey.c b/g10/getkey.c
51index 7a25643..0fa763a 100644
52--- a/g10/getkey.c
53+++ b/g10/getkey.c
54@@ -310,27 +310,50 @@ pk_from_block (PKT_public_key *pk, kbnode_t keyblock, kbnode_t found_key)
55
56 /* Specialized version of get_pubkey which retrieves the key based on
57 * information in SIG. In contrast to get_pubkey PK is required. IF
58- * FORCED_PK is not NULL, this public key is used and copied to PK. */
59+ * FORCED_PK is not NULL, this public key is used and copied to PK.
60+ * If R_KEYBLOCK is not NULL the entire keyblock is stored there if
61+ * found and FORCED_PK is not used; if not used or on error NULL is
62+ * stored there. */
63 gpg_error_t
64 get_pubkey_for_sig (ctrl_t ctrl, PKT_public_key *pk, PKT_signature *sig,
65- PKT_public_key *forced_pk)
66+ PKT_public_key *forced_pk, kbnode_t *r_keyblock)
67 {
68+ gpg_error_t err;
69 const byte *fpr;
70 size_t fprlen;
71
72+ if (r_keyblock)
73+ *r_keyblock = NULL;
74+
75 if (forced_pk)
76 {
77 copy_public_key (pk, forced_pk);
78 return 0;
79 }
80
81+ /* Make sure to request only keys cabable of signing. This makes
82+ * sure that a subkey w/o a valid backsig or with bad usage flags
83+ * will be skipped. */
84+ pk->req_usage = PUBKEY_USAGE_SIG;
85+
86 /* First try the ISSUER_FPR info. */
87 fpr = issuer_fpr_raw (sig, &fprlen);
88- if (fpr && !get_pubkey_byfprint (ctrl, pk, NULL, fpr, fprlen))
89+ if (fpr && !get_pubkey_byfprint (ctrl, pk, r_keyblock, fpr, fprlen))
90 return 0;
91+ if (r_keyblock)
92+ {
93+ release_kbnode (*r_keyblock);
94+ *r_keyblock = NULL;
95+ }
96
97 /* Fallback to use the ISSUER_KEYID. */
98- return get_pubkey (ctrl, pk, sig->keyid);
99+ err = get_pubkey_bykid (ctrl, pk, r_keyblock, sig->keyid);
100+ if (err && r_keyblock)
101+ {
102+ release_kbnode (*r_keyblock);
103+ *r_keyblock = NULL;
104+ }
105+ return err;
106 }
107
108
109@@ -348,6 +371,10 @@ get_pubkey_for_sig (ctrl_t ctrl, PKT_public_key *pk, PKT_signature *sig,
110 * usage will be returned. As such, it is essential that
111 * PK->REQ_USAGE be correctly initialized!
112 *
113+ * If R_KEYBLOCK is not NULL, then the first result's keyblock is
114+ * returned in *R_KEYBLOCK. This should be freed using
115+ * release_kbnode().
116+ *
117 * Returns 0 on success, GPG_ERR_NO_PUBKEY if there is no public key
118 * with the specified key id, or another error code if an error
119 * occurs.
120@@ -355,24 +382,30 @@ get_pubkey_for_sig (ctrl_t ctrl, PKT_public_key *pk, PKT_signature *sig,
121 * If the data was not read from the cache, then the self-signed data
122 * has definitely been merged into the public key using
123 * merge_selfsigs. */
124-int
125-get_pubkey (ctrl_t ctrl, PKT_public_key * pk, u32 * keyid)
126+gpg_error_t
127+get_pubkey_bykid (ctrl_t ctrl, PKT_public_key *pk, kbnode_t *r_keyblock,
128+ u32 *keyid)
129 {
130 int internal = 0;
131- int rc = 0;
132+ gpg_error_t rc = 0;
133+
134+ if (r_keyblock)
135+ *r_keyblock = NULL;
136
137 #if MAX_PK_CACHE_ENTRIES
138- if (pk)
139+ if (pk && !r_keyblock)
140 {
141 /* Try to get it from the cache. We don't do this when pk is
142- NULL as it does not guarantee that the user IDs are
143- cached. */
144+ * NULL as it does not guarantee that the user IDs are cached.
145+ * The old get_pubkey_function did not check PK->REQ_USAGE when
146+ * reading form the caceh. This is probably a bug. Note that
147+ * the cache is not used when the caller asked to return the
148+ * entire keyblock. This is because the cache does not
149+ * associate the public key wit its primary key. */
150 pk_cache_entry_t ce;
151 for (ce = pk_cache; ce; ce = ce->next)
152 {
153 if (ce->keyid[0] == keyid[0] && ce->keyid[1] == keyid[1])
154- /* XXX: We don't check PK->REQ_USAGE here, but if we don't
155- read from the cache, we do check it! */
156 {
157 copy_public_key (pk, ce->pk);
158 return 0;
159@@ -380,6 +413,7 @@ get_pubkey (ctrl_t ctrl, PKT_public_key * pk, u32 * keyid)
160 }
161 }
162 #endif
163+
164 /* More init stuff. */
165 if (!pk)
166 {
167@@ -425,16 +459,18 @@ get_pubkey (ctrl_t ctrl, PKT_public_key * pk, u32 * keyid)
168 ctx.req_usage = pk->req_usage;
169 rc = lookup (ctrl, &ctx, 0, &kb, &found_key);
170 if (!rc)
171+ pk_from_block (pk, kb, found_key);
172+ getkey_end (ctrl, &ctx);
173+ if (!rc && r_keyblock)
174 {
175- pk_from_block (pk, kb, found_key);
176+ *r_keyblock = kb;
177+ kb = NULL;
178 }
179- getkey_end (ctrl, &ctx);
180 release_kbnode (kb);
181 }
182- if (!rc)
183- goto leave;
184
185- rc = GPG_ERR_NO_PUBKEY;
186+ if (rc) /* Return a more useful error code. */
187+ rc = gpg_error (GPG_ERR_NO_PUBKEY);
188
189 leave:
190 if (!rc)
191@@ -445,6 +481,14 @@ leave:
192 }
193
194
195+/* Wrapper for get_pubkey_bykid w/o keyblock return feature. */
196+int
197+get_pubkey (ctrl_t ctrl, PKT_public_key *pk, u32 *keyid)
198+{
199+ return get_pubkey_bykid (ctrl, pk, NULL, keyid);
200+}
201+
202+
203 /* Same as get_pubkey but if the key was not found the function tries
204 * to import it from LDAP. FIXME: We should not need this but swicth
205 * to a fingerprint lookup. */
206@@ -557,28 +601,6 @@ get_pubkey_fast (ctrl_t ctrl, PKT_public_key * pk, u32 * keyid)
207 }
208
209
210-/* Return the entire keyblock used to create SIG. This is a
211- * specialized version of get_pubkeyblock.
212- *
213- * FIXME: This is a hack because get_pubkey_for_sig was already called
214- * and it could have used a cache to hold the key. */
215-kbnode_t
216-get_pubkeyblock_for_sig (ctrl_t ctrl, PKT_signature *sig)
217-{
218- const byte *fpr;
219- size_t fprlen;
220- kbnode_t keyblock;
221-
222- /* First try the ISSUER_FPR info. */
223- fpr = issuer_fpr_raw (sig, &fprlen);
224- if (fpr && !get_pubkey_byfprint (ctrl, NULL, &keyblock, fpr, fprlen))
225- return keyblock;
226-
227- /* Fallback to use the ISSUER_KEYID. */
228- return get_pubkeyblock (ctrl, sig->keyid);
229-}
230-
231-
232 /* Return the key block for the key with key id KEYID or NULL, if an
233 * error occurs. Use release_kbnode() to release the key block.
234 *
235@@ -3611,6 +3633,7 @@ finish_lookup (kbnode_t keyblock, unsigned int req_usage, int want_exact,
236 kbnode_t latest_key;
237 PKT_public_key *pk;
238 int req_prim;
239+ int diag_exactfound = 0;
240 u32 curtime = make_timestamp ();
241
242 if (r_flags)
243@@ -3641,6 +3664,7 @@ finish_lookup (kbnode_t keyblock, unsigned int req_usage, int want_exact,
244 foundk = k;
245 pk = k->pkt->pkt.public_key;
246 pk->flags.exact = 1;
247+ diag_exactfound = 1;
248 break;
249 }
250 }
251@@ -3661,10 +3685,14 @@ finish_lookup (kbnode_t keyblock, unsigned int req_usage, int want_exact,
252 log_debug ("finish_lookup: checking key %08lX (%s)(req_usage=%x)\n",
253 (ulong) keyid_from_pk (keyblock->pkt->pkt.public_key, NULL),
254 foundk ? "one" : "all", req_usage);
255+ if (diag_exactfound && DBG_LOOKUP)
256+ log_debug ("\texact search requested and found\n");
257
258 if (!req_usage)
259 {
260 latest_key = foundk ? foundk : keyblock;
261+ if (DBG_LOOKUP)
262+ log_debug ("\tno usage requested - accepting key\n");
263 goto found;
264 }
265
266diff --git a/g10/gpg.h b/g10/gpg.h
267index c51bbbb..0cdcb8b 100644
268--- a/g10/gpg.h
269+++ b/g10/gpg.h
270@@ -69,7 +69,8 @@ struct dirmngr_local_s;
271 typedef struct dirmngr_local_s *dirmngr_local_t;
272
273 /* Object used to describe a keyblock node. */
274-typedef struct kbnode_struct *KBNODE; /* Deprecated use kbnode_t. */typedef struct kbnode_struct *kbnode_t;
275+typedef struct kbnode_struct *KBNODE; /* Deprecated use kbnode_t. */
276+typedef struct kbnode_struct *kbnode_t;
277
278 /* The handle for keydb operations. */
279 typedef struct keydb_handle_s *KEYDB_HANDLE;
280diff --git a/g10/keydb.h b/g10/keydb.h
281index 51dfece..8e494f6 100644
282--- a/g10/keydb.h
283+++ b/g10/keydb.h
284@@ -332,9 +332,15 @@ void getkey_disable_caches(void);
285 /* Return the public key used for signature SIG and store it at PK. */
286 gpg_error_t get_pubkey_for_sig (ctrl_t ctrl,
287 PKT_public_key *pk, PKT_signature *sig,
288- PKT_public_key *forced_pk);
289+ PKT_public_key *forced_pk,
290+ kbnode_t *r_keyblock);
291
292-/* Return the public key with the key id KEYID and store it at PK. */
293+/* Return the public key with the key id KEYID and store it at PK.
294+ * Optionally return the entire keyblock. */
295+gpg_error_t get_pubkey_bykid (ctrl_t ctrl, PKT_public_key *pk,
296+ kbnode_t *r_keyblock, u32 *keyid);
297+
298+/* Same as get_pubkey_bykid but w/o r_keyblock. */
299 int get_pubkey (ctrl_t ctrl, PKT_public_key *pk, u32 *keyid);
300
301 /* Same as get_pubkey but with auto LDAP fetch. */
302diff --git a/g10/mainproc.c b/g10/mainproc.c
303index 79d9ff2..6e114d2 100644
304--- a/g10/mainproc.c
305+++ b/g10/mainproc.c
306@@ -1108,12 +1108,15 @@ proc_compressed (CTX c, PACKET *pkt)
307 * used to verify the signature will be stored there, or NULL if not
308 * found. If FORCED_PK is not NULL, this public key is used to verify
309 * _data signatures_ and no key lookup is done. Returns: 0 = valid
310- * signature or an error code
311+ * signature or an error code. If R_KEYBLOCK is not NULL the keyblock
312+ * carries the used PK is stored there. The caller should always free
313+ * the return value using release_kbnode.
314 */
315 static int
316 do_check_sig (CTX c, kbnode_t node, const void *extrahash, size_t extrahashlen,
317 PKT_public_key *forced_pk, int *is_selfsig,
318- int *is_expkey, int *is_revkey, PKT_public_key **r_pk)
319+ int *is_expkey, int *is_revkey,
320+ PKT_public_key **r_pk, kbnode_t *r_keyblock)
321 {
322 PKT_signature *sig;
323 gcry_md_hd_t md = NULL;
324@@ -1123,6 +1126,8 @@ do_check_sig (CTX c, kbnode_t node, const void *extrahash, size_t extrahashlen,
325
326 if (r_pk)
327 *r_pk = NULL;
328+ if (r_keyblock)
329+ *r_keyblock = NULL;
330
331 log_assert (node->pkt->pkttype == PKT_SIGNATURE);
332 if (is_selfsig)
333@@ -1199,16 +1204,19 @@ do_check_sig (CTX c, kbnode_t node, const void *extrahash, size_t extrahashlen,
334 /* We only get here if we are checking the signature of a binary
335 (0x00) or text document (0x01). */
336 rc = check_signature (c->ctrl, sig, md, extrahash, extrahashlen,
337- forced_pk, NULL, is_expkey, is_revkey, r_pk);
338+ forced_pk, NULL, is_expkey, is_revkey,
339+ r_pk, r_keyblock);
340 if (! rc)
341 md_good = md;
342 else if (gpg_err_code (rc) == GPG_ERR_BAD_SIGNATURE && md2)
343 {
344 PKT_public_key *pk2;
345
346+ if (r_keyblock)
347+ release_kbnode (*r_keyblock);
348 rc = check_signature (c->ctrl, sig, md2, extrahash, extrahashlen,
349 forced_pk, NULL, is_expkey, is_revkey,
350- r_pk? &pk2 : NULL);
351+ r_pk? &pk2 : NULL, r_keyblock);
352 if (!rc)
353 {
354 md_good = md2;
355@@ -1371,7 +1379,7 @@ list_node (CTX c, kbnode_t node)
356 {
357 fflush (stdout);
358 rc2 = do_check_sig (c, node, NULL, 0, NULL,
359- &is_selfsig, NULL, NULL, NULL);
360+ &is_selfsig, NULL, NULL, NULL, NULL);
361 switch (gpg_err_code (rc2))
362 {
363 case 0: sigrc = '!'; break;
364@@ -1830,7 +1838,7 @@ check_sig_and_print (CTX c, kbnode_t node)
365 PKT_public_key *pk = NULL; /* The public key for the signature or NULL. */
366 const void *extrahash = NULL;
367 size_t extrahashlen = 0;
368- kbnode_t included_keyblock = NULL;
369+ kbnode_t keyblock = NULL;
370
371 if (opt.skip_verify)
372 {
373@@ -1949,7 +1957,8 @@ check_sig_and_print (CTX c, kbnode_t node)
374 {
375 ambiguous:
376 log_error(_("can't handle this ambiguous signature data\n"));
377- return 0;
378+ rc = 0;
379+ goto leave;
380 }
381 } /* End checking signature packet composition. */
382
383@@ -1985,7 +1994,7 @@ check_sig_and_print (CTX c, kbnode_t node)
384 log_info (_(" issuer \"%s\"\n"), sig->signers_uid);
385
386 rc = do_check_sig (c, node, extrahash, extrahashlen, NULL,
387- NULL, &is_expkey, &is_revkey, &pk);
388+ NULL, &is_expkey, &is_revkey, &pk, &keyblock);
389
390 /* If the key is not found but the signature includes a key block we
391 * use that key block for verification and on success import it. */
392@@ -1993,6 +2002,7 @@ check_sig_and_print (CTX c, kbnode_t node)
393 && sig->flags.key_block
394 && opt.flags.auto_key_import)
395 {
396+ kbnode_t included_keyblock = NULL;
397 PKT_public_key *included_pk;
398 const byte *kblock;
399 size_t kblock_len;
400@@ -2004,10 +2014,12 @@ check_sig_and_print (CTX c, kbnode_t node)
401 kblock+1, kblock_len-1,
402 sig->keyid, &included_keyblock))
403 {
404+ /* Note: This is the only place where we use the forced_pk
405+ * arg (ie. included_pk) with do_check_sig. */
406 rc = do_check_sig (c, node, extrahash, extrahashlen, included_pk,
407- NULL, &is_expkey, &is_revkey, &pk);
408+ NULL, &is_expkey, &is_revkey, &pk, NULL);
409 if (opt.verbose)
410- log_debug ("checked signature using included key block: %s\n",
411+ log_info ("checked signature using included key block: %s\n",
412 gpg_strerror (rc));
413 if (!rc)
414 {
415@@ -2017,6 +2029,18 @@ check_sig_and_print (CTX c, kbnode_t node)
416
417 }
418 free_public_key (included_pk);
419+ release_kbnode (included_keyblock);
420+
421+ /* To make sure that nothing strange happened we check the
422+ * signature again now using our own key store. This also
423+ * returns the keyblock which we use later on. */
424+ if (!rc)
425+ {
426+ release_kbnode (keyblock);
427+ keyblock = NULL;
428+ rc = do_check_sig (c, node, extrahash, extrahashlen, NULL,
429+ NULL, &is_expkey, &is_revkey, &pk, &keyblock);
430+ }
431 }
432
433 /* If the key isn't found, check for a preferred keyserver. Note
434@@ -2063,8 +2087,13 @@ check_sig_and_print (CTX c, kbnode_t node)
435 KEYSERVER_IMPORT_FLAG_QUICK);
436 glo_ctrl.in_auto_key_retrieve--;
437 if (!res)
438- rc = do_check_sig (c, node, extrahash, extrahashlen, NULL,
439- NULL, &is_expkey, &is_revkey, &pk);
440+ {
441+ release_kbnode (keyblock);
442+ keyblock = NULL;
443+ rc = do_check_sig (c, node, extrahash, extrahashlen, NULL,
444+ NULL, &is_expkey, &is_revkey, &pk,
445+ &keyblock);
446+ }
447 else if (DBG_LOOKUP)
448 log_debug ("lookup via %s failed: %s\n", "Pref-KS",
449 gpg_strerror (res));
450@@ -2105,8 +2134,12 @@ check_sig_and_print (CTX c, kbnode_t node)
451 /* Fixme: If the fingerprint is embedded in the signature,
452 * compare it to the fingerprint of the returned key. */
453 if (!res)
454- rc = do_check_sig (c, node, extrahash, extrahashlen, NULL,
455- NULL, &is_expkey, &is_revkey, &pk);
456+ {
457+ release_kbnode (keyblock);
458+ keyblock = NULL;
459+ rc = do_check_sig (c, node, extrahash, extrahashlen, NULL,
460+ NULL, &is_expkey, &is_revkey, &pk, &keyblock);
461+ }
462 else if (DBG_LOOKUP)
463 log_debug ("lookup via %s failed: %s\n", "WKD", gpg_strerror (res));
464 }
465@@ -2136,8 +2169,13 @@ check_sig_and_print (CTX c, kbnode_t node)
466 KEYSERVER_IMPORT_FLAG_QUICK);
467 glo_ctrl.in_auto_key_retrieve--;
468 if (!res)
469- rc = do_check_sig (c, node, extrahash, extrahashlen, NULL,
470- NULL, &is_expkey, &is_revkey, &pk);
471+ {
472+ release_kbnode (keyblock);
473+ keyblock = NULL;
474+ rc = do_check_sig (c, node, extrahash, extrahashlen, NULL,
475+ NULL, &is_expkey, &is_revkey, &pk,
476+ &keyblock);
477+ }
478 else if (DBG_LOOKUP)
479 log_debug ("lookup via %s failed: %s\n", "KS", gpg_strerror (res));
480 }
481@@ -2148,7 +2186,7 @@ check_sig_and_print (CTX c, kbnode_t node)
482 {
483 /* We have checked the signature and the result is either a good
484 * signature or a bad signature. Further examination follows. */
485- kbnode_t un, keyblock;
486+ kbnode_t un;
487 int count = 0;
488 int keyblock_has_pk = 0; /* For failsafe check. */
489 int statno;
490@@ -2166,18 +2204,6 @@ check_sig_and_print (CTX c, kbnode_t node)
491 else
492 statno = STATUS_GOODSIG;
493
494- /* FIXME: We should have the public key in PK and thus the
495- * keyblock has already been fetched. Thus we could use the
496- * fingerprint or PK itself to lookup the entire keyblock. That
497- * would best be done with a cache. */
498- if (included_keyblock)
499- {
500- keyblock = included_keyblock;
501- included_keyblock = NULL;
502- }
503- else
504- keyblock = get_pubkeyblock_for_sig (c->ctrl, sig);
505-
506 snprintf (keyid_str, sizeof keyid_str, "%08lX%08lX [uncertain] ",
507 (ulong)sig->keyid[0], (ulong)sig->keyid[1]);
508
509@@ -2243,10 +2269,10 @@ check_sig_and_print (CTX c, kbnode_t node)
510 * contained in the keyring.*/
511 }
512
513- log_assert (mainpk);
514- if (!keyblock_has_pk)
515+ if (!mainpk || !keyblock_has_pk)
516 {
517- log_error ("signature key lost from keyblock\n");
518+ log_error ("signature key lost from keyblock (%p,%p,%d)\n",
519+ keyblock, mainpk, keyblock_has_pk);
520 rc = gpg_error (GPG_ERR_INTERNAL);
521 }
522
523@@ -2514,8 +2540,8 @@ check_sig_and_print (CTX c, kbnode_t node)
524 log_error (_("Can't check signature: %s\n"), gpg_strerror (rc));
525 }
526
527+ leave:
528 free_public_key (pk);
529- release_kbnode (included_keyblock);
530 xfree (issuer_fpr);
531 return rc;
532 }
533diff --git a/g10/packet.h b/g10/packet.h
534index 8aaf32d..669739a 100644
535--- a/g10/packet.h
536+++ b/g10/packet.h
537@@ -899,7 +899,7 @@ gpg_error_t check_signature (ctrl_t ctrl,
538 const void *extrahash, size_t extrahashlen,
539 PKT_public_key *forced_pk,
540 u32 *r_expiredate, int *r_expired, int *r_revoked,
541- PKT_public_key **r_pk);
542+ PKT_public_key **r_pk, kbnode_t *r_keyblock);
543
544
545 /*-- pubkey-enc.c --*/
546diff --git a/g10/sig-check.c b/g10/sig-check.c
547index 2272fa4..11f3e0c 100644
548--- a/g10/sig-check.c
549+++ b/g10/sig-check.c
550@@ -138,6 +138,11 @@ check_key_verify_compliance (PKT_public_key *pk)
551 * If R_PK is not NULL, the public key is stored at that address if it
552 * was found; other wise NULL is stored.
553 *
554+ * If R_KEYBLOCK is not NULL, the entire keyblock used to verify the
555+ * signature is stored at that address. If no key was found or on
556+ * some other errors NULL is stored there. The callers needs to
557+ * release the keyblock using release_kbnode (kb).
558+ *
559 * Returns 0 on success. An error code otherwise. */
560 gpg_error_t
561 check_signature (ctrl_t ctrl,
562@@ -145,7 +150,7 @@ check_signature (ctrl_t ctrl,
563 const void *extrahash, size_t extrahashlen,
564 PKT_public_key *forced_pk,
565 u32 *r_expiredate, int *r_expired, int *r_revoked,
566- PKT_public_key **r_pk)
567+ PKT_public_key **r_pk, kbnode_t *r_keyblock)
568 {
569 int rc=0;
570 PKT_public_key *pk;
571@@ -158,6 +163,8 @@ check_signature (ctrl_t ctrl,
572 *r_revoked = 0;
573 if (r_pk)
574 *r_pk = NULL;
575+ if (r_keyblock)
576+ *r_keyblock = NULL;
577
578 pk = xtrycalloc (1, sizeof *pk);
579 if (!pk)
580@@ -188,7 +195,7 @@ check_signature (ctrl_t ctrl,
581 log_info(_("WARNING: signature digest conflict in message\n"));
582 rc = gpg_error (GPG_ERR_GENERAL);
583 }
584- else if (get_pubkey_for_sig (ctrl, pk, sig, forced_pk))
585+ else if (get_pubkey_for_sig (ctrl, pk, sig, forced_pk, r_keyblock))
586 rc = gpg_error (GPG_ERR_NO_PUBKEY);
587 else if ((rc = check_key_verify_compliance (pk)))
588 ;/* Compliance failure. */
589@@ -786,9 +793,9 @@ check_revocation_keys (ctrl_t ctrl, PKT_public_key *pk, PKT_signature *sig)
590 keyid_from_fingerprint (ctrl, pk->revkey[i].fpr, pk->revkey[i].fprlen,
591 keyid);
592
593- if(keyid[0]==sig->keyid[0] && keyid[1]==sig->keyid[1])
594- /* The signature was generated by a designated revoker.
595- Verify the signature. */
596+ /* If the signature was generated by a designated revoker
597+ * verify the signature. */
598+ if (keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1])
599 {
600 gcry_md_hd_t md;
601
602@@ -796,9 +803,9 @@ check_revocation_keys (ctrl_t ctrl, PKT_public_key *pk, PKT_signature *sig)
603 BUG ();
604 hash_public_key(md,pk);
605 /* Note: check_signature only checks that the signature
606- is good. It does not fail if the key is revoked. */
607+ * is good. It does not fail if the key is revoked. */
608 rc = check_signature (ctrl, sig, md, NULL, 0, NULL,
609- NULL, NULL, NULL, NULL);
610+ NULL, NULL, NULL, NULL, NULL);
611 cache_sig_result(sig,rc);
612 gcry_md_close (md);
613 break;
614@@ -1003,7 +1010,7 @@ check_signature_over_key_or_uid (ctrl_t ctrl, PKT_public_key *signer,
615 if (IS_CERT (sig))
616 signer->req_usage = PUBKEY_USAGE_CERT;
617
618- rc = get_pubkey_for_sig (ctrl, signer, sig, NULL);
619+ rc = get_pubkey_for_sig (ctrl, signer, sig, NULL, NULL);
620 if (rc)
621 {
622 xfree (signer);
623--
6242.40.0
diff --git a/meta/recipes-support/gnupg/gnupg/CVE-2025-30258-0004.patch b/meta/recipes-support/gnupg/gnupg/CVE-2025-30258-0004.patch
new file mode 100644
index 0000000000..67cf6efb6e
--- /dev/null
+++ b/meta/recipes-support/gnupg/gnupg/CVE-2025-30258-0004.patch
@@ -0,0 +1,193 @@
1From 1e581619bf5315957f2be06b3b1a7f513304c126 Mon Sep 17 00:00:00 2001
2From: Werner Koch <wk@gnupg.org>
3Date: Thu, 6 Mar 2025 17:17:17 +0100
4Subject: [PATCH] gpg: Fix regression for the recent malicious subkey DoS fix.
5
6* g10/packet.h (PUBKEY_USAGE_VERIFY): New.
7* g10/getkey.c (get_pubkey_for_sig): Pass new flag also to requested
8usage.
9(finish_lookup): Introduce a verify_mode.
10--
11
12Fixes-commit: da0164efc7f32013bc24d97b9afa9f8d67c318bb
13GnuPG-bug-id: 7547
14
15CVE: CVE-2025-30258
16Upstream-Status: Backport [https://dev.gnupg.org/rG1e581619bf5315957f2be06b3b1a7f513304c126]
17
18Reference:
19https://git.launchpad.net/ubuntu/+source/gnupg2/commit/?id=d086c55a85faafdf8448c12ed726d587e729d2d0
20
21Signed-off-by: Yogita Urade <yogita.urade@windriver.com>
22---
23 g10/getkey.c | 42 ++++++++++++++++++++++++++----------------
24 g10/packet.h | 5 +++--
25 2 files changed, 29 insertions(+), 18 deletions(-)
26
27diff --git a/g10/getkey.c b/g10/getkey.c
28index 0fa763a..2a1b330 100644
29--- a/g10/getkey.c
30+++ b/g10/getkey.c
31@@ -309,11 +309,12 @@ pk_from_block (PKT_public_key *pk, kbnode_t keyblock, kbnode_t found_key)
32
33
34 /* Specialized version of get_pubkey which retrieves the key based on
35- * information in SIG. In contrast to get_pubkey PK is required. IF
36+ * information in SIG. In contrast to get_pubkey PK is required. If
37 * FORCED_PK is not NULL, this public key is used and copied to PK.
38 * If R_KEYBLOCK is not NULL the entire keyblock is stored there if
39 * found and FORCED_PK is not used; if not used or on error NULL is
40- * stored there. */
41+ * stored there. Use this function only to find the key for
42+ * verification; it can't be used to select a key for signing. */
43 gpg_error_t
44 get_pubkey_for_sig (ctrl_t ctrl, PKT_public_key *pk, PKT_signature *sig,
45 PKT_public_key *forced_pk, kbnode_t *r_keyblock)
46@@ -333,8 +334,9 @@ get_pubkey_for_sig (ctrl_t ctrl, PKT_public_key *pk, PKT_signature *sig,
47
48 /* Make sure to request only keys cabable of signing. This makes
49 * sure that a subkey w/o a valid backsig or with bad usage flags
50- * will be skipped. */
51- pk->req_usage = PUBKEY_USAGE_SIG;
52+ * will be skipped. We also request the verification mode so that
53+ * expired and reoked keys are returned. */
54+ pk->req_usage = (PUBKEY_USAGE_SIG | PUBKEY_USAGE_VERIFY);
55
56 /* First try the ISSUER_FPR info. */
57 fpr = issuer_fpr_raw (sig, &fprlen);
58@@ -398,10 +400,10 @@ get_pubkey_bykid (ctrl_t ctrl, PKT_public_key *pk, kbnode_t *r_keyblock,
59 /* Try to get it from the cache. We don't do this when pk is
60 * NULL as it does not guarantee that the user IDs are cached.
61 * The old get_pubkey_function did not check PK->REQ_USAGE when
62- * reading form the caceh. This is probably a bug. Note that
63+ * reading from the cache. This is probably a bug. Note that
64 * the cache is not used when the caller asked to return the
65 * entire keyblock. This is because the cache does not
66- * associate the public key wit its primary key. */
67+ * associate the public key with its primary key. */
68 pk_cache_entry_t ce;
69 for (ce = pk_cache; ce; ce = ce->next)
70 {
71@@ -3634,11 +3636,17 @@ finish_lookup (kbnode_t keyblock, unsigned int req_usage, int want_exact,
72 PKT_public_key *pk;
73 int req_prim;
74 int diag_exactfound = 0;
75+ int verify_mode = 0;
76 u32 curtime = make_timestamp ();
77
78 if (r_flags)
79 *r_flags = 0;
80
81+ /* The verify mode is used to change the behaviour so that we can
82+ * return an expired or revoked key for signature verification. */
83+ verify_mode = ((req_usage & PUBKEY_USAGE_VERIFY)
84+ && (req_usage & PUBKEY_USAGE_SIG));
85+
86 #define USAGE_MASK (PUBKEY_USAGE_SIG|PUBKEY_USAGE_ENC|PUBKEY_USAGE_CERT)
87 req_usage &= USAGE_MASK;
88
89@@ -3682,9 +3690,9 @@ finish_lookup (kbnode_t keyblock, unsigned int req_usage, int want_exact,
90 }
91
92 if (DBG_LOOKUP)
93- log_debug ("finish_lookup: checking key %08lX (%s)(req_usage=%x)\n",
94+ log_debug ("finish_lookup: checking key %08lX (%s)(req_usage=%x%s)\n",
95 (ulong) keyid_from_pk (keyblock->pkt->pkt.public_key, NULL),
96- foundk ? "one" : "all", req_usage);
97+ foundk ? "one" : "all", req_usage, verify_mode? ",verify":"");
98 if (diag_exactfound && DBG_LOOKUP)
99 log_debug ("\texact search requested and found\n");
100
101@@ -3747,28 +3755,28 @@ finish_lookup (kbnode_t keyblock, unsigned int req_usage, int want_exact,
102 }
103
104 n_subkeys++;
105- if (pk->flags.revoked)
106+ if (!verify_mode && pk->flags.revoked)
107 {
108 if (DBG_LOOKUP)
109 log_debug ("\tsubkey has been revoked\n");
110 n_revoked_or_expired++;
111 continue;
112 }
113- if (pk->has_expired)
114+ if (!verify_mode && pk->has_expired)
115 {
116 if (DBG_LOOKUP)
117 log_debug ("\tsubkey has expired\n");
118 n_revoked_or_expired++;
119 continue;
120 }
121- if (pk->timestamp > curtime && !opt.ignore_valid_from)
122+ if (!verify_mode && pk->timestamp > curtime && !opt.ignore_valid_from)
123 {
124 if (DBG_LOOKUP)
125 log_debug ("\tsubkey not yet valid\n");
126 continue;
127 }
128
129- if (want_secret)
130+ if (!verify_mode && want_secret)
131 {
132 int secret_key_avail = agent_probe_secret_key (NULL, pk);
133
134@@ -3788,7 +3796,8 @@ finish_lookup (kbnode_t keyblock, unsigned int req_usage, int want_exact,
135 }
136
137 if (DBG_LOOKUP)
138- log_debug ("\tsubkey might be fine\n");
139+ log_debug ("\tsubkey might be fine%s\n",
140+ verify_mode? " for verification":"");
141 /* In case a key has a timestamp of 0 set, we make sure
142 that it is used. A better change would be to compare
143 ">=" but that might also change the selected keys and
144@@ -3829,12 +3838,12 @@ finish_lookup (kbnode_t keyblock, unsigned int req_usage, int want_exact,
145 log_debug ("\tprimary key usage does not match: "
146 "want=%x have=%x\n", req_usage, pk->pubkey_usage);
147 }
148- else if (pk->flags.revoked)
149+ else if (!verify_mode && pk->flags.revoked)
150 {
151 if (DBG_LOOKUP)
152 log_debug ("\tprimary key has been revoked\n");
153 }
154- else if (pk->has_expired)
155+ else if (!verify_mode && pk->has_expired)
156 {
157 if (DBG_LOOKUP)
158 log_debug ("\tprimary key has expired\n");
159@@ -3842,7 +3851,8 @@ finish_lookup (kbnode_t keyblock, unsigned int req_usage, int want_exact,
160 else /* Okay. */
161 {
162 if (DBG_LOOKUP)
163- log_debug ("\tprimary key may be used\n");
164+ log_debug ("\tprimary key may be used%s\n",
165+ verify_mode? " for verification":"");
166 latest_key = keyblock;
167 }
168 }
169diff --git a/g10/packet.h b/g10/packet.h
170index 669739a..061a9b1 100644
171--- a/g10/packet.h
172+++ b/g10/packet.h
173@@ -135,6 +135,7 @@ typedef struct {
174 gcry_mpi_t data[PUBKEY_MAX_NENC];
175 } PKT_pubkey_enc;
176
177+#define PUBKEY_USAGE_VERIFY 16384 /* Verify only modifier. */
178
179 /* An object to build a list of public-key encrypted session key. */
180 struct pubkey_enc_list
181@@ -385,8 +386,8 @@ typedef struct
182 byte selfsigversion; /* highest version of all of the self-sigs */
183 /* The public key algorithm. (Serialized.) */
184 byte pubkey_algo;
185- byte pubkey_usage; /* for now only used to pass it to getkey() */
186- byte req_usage; /* hack to pass a request to getkey() */
187+ u16 pubkey_usage; /* for now only used to pass it to getkey() */
188+ u16 req_usage; /* hack to pass a request to getkey() */
189 byte fprlen; /* 0 or length of FPR. */
190 u32 has_expired; /* set to the expiration date if expired */
191 /* keyid of the primary key. Never access this value directly.
192--
1932.40.0
diff --git a/meta/recipes-support/gnupg/gnupg/CVE-2025-30258-0005.patch b/meta/recipes-support/gnupg/gnupg/CVE-2025-30258-0005.patch
new file mode 100644
index 0000000000..527ef47cf4
--- /dev/null
+++ b/meta/recipes-support/gnupg/gnupg/CVE-2025-30258-0005.patch
@@ -0,0 +1,36 @@
1From 4be25979a6b3e2a79d7c9667b07db8b09fb046e9 Mon Sep 17 00:00:00 2001
2From: Werner Koch <wk@gnupg.org>
3Date: Thu, 13 Mar 2025 11:35:34 +0100
4Subject: [PATCH] gpg: Fix double free of internal data.
5
6* g10/sig-check.c (check_signature_over_key_or_uid): Do not free in
7no-sig-cache mode if allocated by caller.
8--
9
10GnuPG-bug-id: 7547
11Fixes-commit: 44cdb9d73f1a0b7d2c8483a119b9c4d6caabc1ec
12
13CVE: CVE-2025-30258
14Upstream-Status: Backport [https://dev.gnupg.org/rG4be25979a6b3e2a79d7c9667b07db8b09fb046e9]
15
16Signed-off-by: Yogita Urade <yogita.urade@windriver.com>
17---
18 g10/sig-check.c | 3 ++-
19 1 file changed, 2 insertions(+), 1 deletion(-)
20
21diff --git a/g10/sig-check.c b/g10/sig-check.c
22index 11f3e0c..a8fbdc7 100644
23--- a/g10/sig-check.c
24+++ b/g10/sig-check.c
25@@ -1013,7 +1013,8 @@ check_signature_over_key_or_uid (ctrl_t ctrl, PKT_public_key *signer,
26 rc = get_pubkey_for_sig (ctrl, signer, sig, NULL, NULL);
27 if (rc)
28 {
29- xfree (signer);
30+ if (signer_alloced != 1)
31+ xfree (signer);
32 signer = NULL;
33 signer_alloced = 0;
34 goto leave;
35--
362.40.0
diff --git a/meta/recipes-support/gnupg/gnupg_2.3.7.bb b/meta/recipes-support/gnupg/gnupg_2.3.7.bb
index 7075a61898..461ec6687c 100644
--- a/meta/recipes-support/gnupg/gnupg_2.3.7.bb
+++ b/meta/recipes-support/gnupg/gnupg_2.3.7.bb
@@ -18,6 +18,11 @@ SRC_URI = "${GNUPG_MIRROR}/${BPN}/${BPN}-${PV}.tar.bz2 \
18 file://0002-use-pkgconfig-instead-of-npth-config.patch \ 18 file://0002-use-pkgconfig-instead-of-npth-config.patch \
19 file://0004-autogen.sh-fix-find-version-for-beta-checking.patch \ 19 file://0004-autogen.sh-fix-find-version-for-beta-checking.patch \
20 file://0001-Woverride-init-is-not-needed-with-gcc-9.patch \ 20 file://0001-Woverride-init-is-not-needed-with-gcc-9.patch \
21 file://CVE-2025-30258-0001.patch \
22 file://CVE-2025-30258-0002.patch \
23 file://CVE-2025-30258-0003.patch \
24 file://CVE-2025-30258-0004.patch \
25 file://CVE-2025-30258-0005.patch \
21 " 26 "
22SRC_URI:append:class-native = " file://0001-configure.ac-use-a-custom-value-for-the-location-of-.patch \ 27SRC_URI:append:class-native = " file://0001-configure.ac-use-a-custom-value-for-the-location-of-.patch \
23 file://relocate.patch" 28 file://relocate.patch"