aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2018-07-04 07:53:10 +0000
committerWerner Koch <[email protected]>2018-07-04 07:58:05 +0000
commit01cd66f9faf1623833e6afac84164de5a136ecff (patch)
tree811f7f08c627fd3c440b315b2a2c01b13cd1a1e5
parentindent: Fix indentation of read_block in g10/import.c (diff)
downloadgnupg-01cd66f9faf1623833e6afac84164de5a136ecff.tar.gz
gnupg-01cd66f9faf1623833e6afac84164de5a136ecff.zip
gpg: Ignore too large user ids during import.
* g10/import.c (read_block): Add special treatment for bad user ids and comment packets. -- See GnuPG-bug-id: 4022 for an example of a bogus user id. Signed-off-by: Werner Koch <[email protected]>
-rw-r--r--g10/import.c31
1 files changed, 30 insertions, 1 deletions
diff --git a/g10/import.c b/g10/import.c
index 62bc6a2af..5be7952d6 100644
--- a/g10/import.c
+++ b/g10/import.c
@@ -780,7 +780,7 @@ read_block( IOBUF a, int with_meta,
struct parse_packet_ctx_s parsectx;
PACKET *pkt;
kbnode_t root = NULL;
- int in_cert, in_v3key;
+ int in_cert, in_v3key, skip_sigs;
*r_v3keys = 0;
@@ -799,6 +799,7 @@ read_block( IOBUF a, int with_meta,
if (!with_meta)
parsectx.skip_meta = 1;
in_v3key = 0;
+ skip_sigs = 0;
while ((rc=parse_packet (&parsectx, pkt)) != -1)
{
if (rc && (gpg_err_code (rc) == GPG_ERR_LEGACY_KEY
@@ -813,8 +814,25 @@ read_block( IOBUF a, int with_meta,
}
else if (rc ) /* (ignore errors) */
{
+ skip_sigs = 0;
if (gpg_err_code (rc) == GPG_ERR_UNKNOWN_PACKET)
; /* Do not show a diagnostic. */
+ else if (gpg_err_code (rc) == GPG_ERR_INV_PACKET
+ && (pkt->pkttype == PKT_USER_ID
+ || pkt->pkttype == PKT_ATTRIBUTE))
+ {
+ /* This indicates a too large user id or attribute
+ * packet. We skip this packet and all following
+ * signatures. Sure, this won't allow to repair a
+ * garbled keyring in case one of the signatures belong
+ * to another user id. However, this better mitigates
+ * DoS using inserted user ids. */
+ skip_sigs = 1;
+ }
+ else if (gpg_err_code (rc) == GPG_ERR_INV_PACKET
+ && (pkt->pkttype == PKT_OLD_COMMENT
+ || pkt->pkttype == PKT_COMMENT))
+ ; /* Ignore too large comment packets. */
else
{
log_error("read_block: read error: %s\n", gpg_strerror (rc) );
@@ -826,6 +844,17 @@ read_block( IOBUF a, int with_meta,
continue;
}
+ if (skip_sigs)
+ {
+ if (pkt->pkttype == PKT_SIGNATURE)
+ {
+ free_packet (pkt, &parsectx);
+ init_packet (pkt);
+ continue;
+ }
+ skip_sigs = 0;
+ }
+
if (in_v3key && !(pkt->pkttype == PKT_PUBLIC_KEY
|| pkt->pkttype == PKT_SECRET_KEY))
{