Index: common/openpgpdefs.h =================================================================== --- common/openpgpdefs.h +++ common/openpgpdefs.h @@ -52,8 +52,10 @@ PKT_ENCRYPTED_MDC = 18, /* Integrity protected encrypted data. */ PKT_MDC = 19, /* Manipulation detection code packet. */ PKT_ENCRYPTED_AEAD= 20, /* AEAD encrypted data packet. */ + PKT_PADDING = 21, /* Padding packet. */ + PKT_FIRST_NON_CRITICAL = 40, /* First non-critical packet */ PKT_COMMENT = 61, /* new comment packet (GnuPG specific). */ - PKT_GPG_CONTROL = 63 /* internal control packet (GnuPG specific). */ + PKT_GPG_CONTROL = 63, /* internal control packet (GnuPG specific). */ } pkttype_t; Index: g10/import.c =================================================================== --- g10/import.c +++ g10/import.c @@ -1042,22 +1042,8 @@ switch (pkt->pkttype) { case PKT_COMPRESSED: - if (check_compress_algo (pkt->pkt.compressed->algorithm)) - { - rc = GPG_ERR_COMPR_ALGO; - goto ready; - } - else - { - compress_filter_context_t *cfx = xmalloc_clear( sizeof *cfx ); - pkt->pkt.compressed->buf = NULL; - if (push_compress_filter2 (a, cfx, - pkt->pkt.compressed->algorithm, 1)) - xfree (cfx); /* e.g. in case of compression_algo NONE. */ - } - free_packet (pkt, &parsectx); - init_packet(pkt); - break; + rc = GPG_ERR_UNEXPECTED; + goto ready; case PKT_RING_TRUST: /* Skip those packets unless we are in restore mode. */ Index: g10/mainproc.c =================================================================== --- g10/mainproc.c +++ g10/mainproc.c @@ -1596,6 +1596,7 @@ c->iobuf = a; init_packet(pkt); init_parse_packet (&parsectx, a); + parsectx.sigs_only = c->sigs_only && c->signed_data.used; while ((rc=parse_packet (&parsectx, pkt)) != -1) { any_data = 1; @@ -1607,6 +1608,12 @@ if (gpg_err_code (rc) == GPG_ERR_INV_PACKET && opt.list_packets == 0) break; + + if (gpg_err_code (rc) == GPG_ERR_UNEXPECTED) + { + write_status_text( STATUS_UNEXPECTED, "0" ); + goto leave; + } continue; } newpkt = -1; Index: g10/packet.h =================================================================== --- g10/packet.h +++ g10/packet.h @@ -657,6 +657,7 @@ int free_last_pkt; /* Indicates that LAST_PKT must be freed. */ int skip_meta; /* Skip ring trust packets. */ unsigned int n_parsed_packets; /* Number of parsed packets. */ + int sigs_only; /* Only accept detached signature packets */ }; typedef struct parse_packet_ctx_s *parse_packet_ctx_t; @@ -667,6 +668,7 @@ (a)->free_last_pkt = 0; \ (a)->skip_meta = 0; \ (a)->n_parsed_packets = 0; \ + (a)->sigs_only = 0; \ } while (0) #define deinit_parse_packet(a) do { \ Index: g10/parse-packet.c =================================================================== --- g10/parse-packet.c +++ g10/parse-packet.c @@ -729,6 +729,14 @@ pktlen = buf32_to_ulong (value); } + else if (ctx->sigs_only || onlykeypkts) + { + log_error ("%s: partial length found for packet type %d" + " when reading signature, certificate, or key", + iobuf_where(inp), pkttype); + rc = gpg_error (GPG_ERR_UNEXPECTED); + goto leave; + } else /* Partial body length. */ { switch (pkttype) @@ -775,6 +783,14 @@ rc = gpg_error (GPG_ERR_INV_PACKET); goto leave; } + else if (ctx->sigs_only || onlykeypkts) + { + log_error ("%s: indeterminate length when reading" + " key or signature\n", + iobuf_where (inp)); + rc = gpg_error (GPG_ERR_UNEXPECTED); + goto leave; + } } else { @@ -828,7 +844,19 @@ goto leave; } - if (with_uid && pkttype == PKT_USER_ID) + if (pkttype == PKT_PADDING || + (pkttype >= PKT_FIRST_NON_CRITICAL && + pkttype != PKT_COMMENT && pkttype != PKT_GPG_CONTROL)) + goto again; /* Skip this packet */ + else if (ctx->sigs_only && pkttype != PKT_SIGNATURE + && pkttype != PKT_PADDING && pkttype != PKT_MARKER) + { + iobuf_skip_rest (inp, pktlen, partial); + *skip = 1; + rc = GPG_ERR_UNEXPECTED; + goto leave; + } + else if (with_uid && pkttype == PKT_USER_ID) /* If ONLYKEYPKTS is set to 2, then we never skip user id packets, even if DO_SKIP is set. */ ;