Package: release.debian.org Severity: normal User: release.debian....@packages.debian.org Usertags: unblock
Please unblock gnupg. It fixes CVE-2015-1607, CVE-2015-1606, CVE-2015-0837 and CVE-2014-3591. unblock gnupg/1.4.18-7 debdiff: diff -Nru gnupg-1.4.18/debian/changelog gnupg-1.4.18/debian/changelog --- gnupg-1.4.18/debian/changelog 2014-12-04 21:58:21.000000000 +0100 +++ gnupg-1.4.18/debian/changelog 2015-03-02 19:30:21.000000000 +0100 @@ -1,3 +1,10 @@ +gnupg (1.4.18-7) unstable; urgency=medium + + * import a series of DoS and vulnerabilities from upstream, including + CVE-2014-3591 + + -- Daniel Kahn Gillmor <d...@fifthhorseman.net> Mon, 02 Mar 2015 19:29:26 +0100 + gnupg (1.4.18-6) unstable; urgency=medium * revert to debhelper 7 diff -Nru gnupg-1.4.18/debian/patches/0019-gpg-release-DEK-soon-after-its-use.patch gnupg-1.4.18/debian/patches/0019-gpg-release-DEK-soon-after-its-use.patch --- gnupg-1.4.18/debian/patches/0019-gpg-release-DEK-soon-after-its-use.patch 1970-01-01 01:00:00.000000000 +0100 +++ gnupg-1.4.18/debian/patches/0019-gpg-release-DEK-soon-after-its-use.patch 2015-03-02 18:47:01.000000000 +0100 @@ -0,0 +1,42 @@ +From da66ad5bba4215b9ddd0cb927a89aa75355632aa Mon Sep 17 00:00:00 2001 +From: NIIBE Yutaka <gni...@fsij.org> +Date: Fri, 12 Dec 2014 17:41:56 +0900 +Subject: [PATCH 19/45] gpg: release DEK soon after its use. + +* g10/keygen.c (generate_subkeypair): Release DEK soon. + +-- + +This fixes the out_of_core error in the test case of adding +RSA-4096 subkey to RSA-4096 primary key with configuration: + + s2k-cipher-algo S10 + +Debian-bug-id: 772780 +--- + g10/keygen.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/g10/keygen.c b/g10/keygen.c +index 9020908..5af0043 100644 +--- a/g10/keygen.c ++++ b/g10/keygen.c +@@ -3447,6 +3447,7 @@ generate_subkeypair( KBNODE pub_keyblock, KBNODE sec_keyblock ) + + rc = do_create (algo, nbits, pub_keyblock, sec_keyblock, + dek, s2k, &sub_sk, timestamp, expire, 1 ); ++ xfree( dek ); + if (!rc) + rc = write_keybinding (pub_keyblock, pub_keyblock, pri_sk, sub_sk, + use, timestamp); +@@ -3463,7 +3464,6 @@ generate_subkeypair( KBNODE pub_keyblock, KBNODE sec_keyblock ) + if( rc ) + log_error(_("Key generation failed: %s\n"), g10_errstr(rc) ); + xfree( passphrase ); +- xfree( dek ); + xfree( s2k ); + /* release the copy of the (now unprotected) secret keys */ + if( pri_sk ) +-- +2.1.4 + diff -Nru gnupg-1.4.18/debian/patches/0020-scd-fix-get_public_key-for-OpenPGPcard-v1.0.patch gnupg-1.4.18/debian/patches/0020-scd-fix-get_public_key-for-OpenPGPcard-v1.0.patch --- gnupg-1.4.18/debian/patches/0020-scd-fix-get_public_key-for-OpenPGPcard-v1.0.patch 1970-01-01 01:00:00.000000000 +0100 +++ gnupg-1.4.18/debian/patches/0020-scd-fix-get_public_key-for-OpenPGPcard-v1.0.patch 2015-03-02 18:47:01.000000000 +0100 @@ -0,0 +1,33 @@ +From 3ca1f4098c70d322658cfaaa0d12164e6ac6d5ad Mon Sep 17 00:00:00 2001 +From: Joshua Rogers <g...@internot.info> +Date: Sat, 20 Dec 2014 11:38:53 +1100 +Subject: [PATCH 20/45] scd: fix get_public_key for OpenPGPcard v1.0. + +* scd/app-openpgp.c (get_public_key): correctly close 'fp' upon use. + +-- + +Inside the get_public_key function, 'fp' was opened using popen, but +incorrectly closed using fclose. + +Debian-Bug-Id: 773474 +--- + g10/app-openpgp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/g10/app-openpgp.c b/g10/app-openpgp.c +index a3a977b..b51d418 100644 +--- a/g10/app-openpgp.c ++++ b/g10/app-openpgp.c +@@ -1250,7 +1250,7 @@ get_public_key (app_t app, int keyno) + } + + err = retrieve_key_material (fp, hexkeyid, &m, &mlen, &e, &elen); +- fclose (fp); ++ pclose (fp); + if (err) + { + log_error ("error while retrieving key material through pipe: %s\n", +-- +2.1.4 + diff -Nru gnupg-1.4.18/debian/patches/0021-scd-Fix-possibly-inhibited-checkpin-of-the-admin-pin.patch gnupg-1.4.18/debian/patches/0021-scd-Fix-possibly-inhibited-checkpin-of-the-admin-pin.patch --- gnupg-1.4.18/debian/patches/0021-scd-Fix-possibly-inhibited-checkpin-of-the-admin-pin.patch 1970-01-01 01:00:00.000000000 +0100 +++ gnupg-1.4.18/debian/patches/0021-scd-Fix-possibly-inhibited-checkpin-of-the-admin-pin.patch 2015-03-02 18:47:01.000000000 +0100 @@ -0,0 +1,29 @@ +From c83e250ef36c28a275de74d96e89898e9f99cb1e Mon Sep 17 00:00:00 2001 +From: Werner Koch <w...@gnupg.org> +Date: Fri, 12 Dec 2014 20:08:45 +0100 +Subject: [PATCH 21/45] scd: Fix possibly inhibited checkpin of the admin pin. + +* scd/app-openpgp.c (do_check_pin): Do not check a byte of a released +buffer. + +Signed-off-by: Werner Koch <w...@gnupg.org> +--- + g10/app-openpgp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/g10/app-openpgp.c b/g10/app-openpgp.c +index b51d418..c3b4fae 100644 +--- a/g10/app-openpgp.c ++++ b/g10/app-openpgp.c +@@ -3497,7 +3497,7 @@ do_check_pin (app_t app, const char *keyidstr, + log_info (_("card is permanently locked!\n")); + return gpg_error (GPG_ERR_BAD_PIN); + } +- else if (value[6] < 3) ++ else if (count < 3) + { + log_info (_("verification of Admin PIN is currently prohibited " + "through this command\n")); +-- +2.1.4 + diff -Nru gnupg-1.4.18/debian/patches/0022-gpg-Fix-possible-read-of-unallocated-memory.patch gnupg-1.4.18/debian/patches/0022-gpg-Fix-possible-read-of-unallocated-memory.patch --- gnupg-1.4.18/debian/patches/0022-gpg-Fix-possible-read-of-unallocated-memory.patch 1970-01-01 01:00:00.000000000 +0100 +++ gnupg-1.4.18/debian/patches/0022-gpg-Fix-possible-read-of-unallocated-memory.patch 2015-03-02 18:47:01.000000000 +0100 @@ -0,0 +1,48 @@ +From aab282855ada8dddee99c777c91829344e91f31a Mon Sep 17 00:00:00 2001 +From: Werner Koch <w...@gnupg.org> +Date: Fri, 12 Dec 2014 10:41:25 +0100 +Subject: [PATCH 22/45] gpg: Fix possible read of unallocated memory + +* g10/parse-packet.c (can_handle_critical): Check content length +before calling can_handle_critical_notation. +-- + +The problem was found by Jan Bee and gniibe proposed the used fix. +Thanks. + +This bug can't be exploited: Only if the announced length of the +notation is 21 or 32 a memcmp against fixed strings using that length +would be done. The compared data is followed by the actual signature +and thus it is highly likely that not even read of unallocated memory +will happen. Nevertheless such a bug needs to be fixed. + +Signed-off-by: Werner Koch <w...@gnupg.org> +--- + g10/parse-packet.c | 11 +++++++---- + 1 file changed, 7 insertions(+), 4 deletions(-) + +diff --git a/g10/parse-packet.c b/g10/parse-packet.c +index 01600e4..e4e524c 100644 +--- a/g10/parse-packet.c ++++ b/g10/parse-packet.c +@@ -1123,10 +1123,13 @@ can_handle_critical( const byte *buffer, size_t n, int type ) + switch( type ) + { + case SIGSUBPKT_NOTATION: +- if(n>=8) +- return can_handle_critical_notation(buffer+8,(buffer[4]<<8)|buffer[5]); +- else +- return 0; ++ if (n >= 8) ++ { ++ size_t notation_len = ((buffer[4] << 8) | buffer[5]); ++ if (n - 8 >= notation_len) ++ return can_handle_critical_notation (buffer + 8, notation_len); ++ } ++ return 0; + case SIGSUBPKT_SIGNATURE: + case SIGSUBPKT_SIG_CREATED: + case SIGSUBPKT_SIG_EXPIRE: +-- +2.1.4 + diff -Nru gnupg-1.4.18/debian/patches/0023-doc-Fix-memory-leak-in-yat2m.patch gnupg-1.4.18/debian/patches/0023-doc-Fix-memory-leak-in-yat2m.patch --- gnupg-1.4.18/debian/patches/0023-doc-Fix-memory-leak-in-yat2m.patch 1970-01-01 01:00:00.000000000 +0100 +++ gnupg-1.4.18/debian/patches/0023-doc-Fix-memory-leak-in-yat2m.patch 2015-03-02 18:47:01.000000000 +0100 @@ -0,0 +1,28 @@ +From e2e822d22526c1545e095bc24173b732137f5737 Mon Sep 17 00:00:00 2001 +From: Werner Koch <w...@gnupg.org> +Date: Mon, 22 Dec 2014 12:44:13 +0100 +Subject: [PATCH 23/45] doc: Fix memory leak in yat2m. + +* doc/yat2m.c (write_th): Free NAME. +-- + +Reported-by: Joshua Rogers <g...@internot.info> +--- + doc/yat2m.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/doc/yat2m.c b/doc/yat2m.c +index f780952..86c3c70 100644 +--- a/doc/yat2m.c ++++ b/doc/yat2m.c +@@ -656,6 +656,7 @@ write_th (FILE *fp) + *p++ = 0; + fprintf (fp, ".TH %s %s %s \"%s\" \"%s\"\n", + name, p, isodatestring (), opt_release, opt_source); ++ free (name); + return 0; + } + +-- +2.1.4 + diff -Nru gnupg-1.4.18/debian/patches/0024-avoid-future-chance-of-using-uninitialized-memory.patch gnupg-1.4.18/debian/patches/0024-avoid-future-chance-of-using-uninitialized-memory.patch --- gnupg-1.4.18/debian/patches/0024-avoid-future-chance-of-using-uninitialized-memory.patch 1970-01-01 01:00:00.000000000 +0100 +++ gnupg-1.4.18/debian/patches/0024-avoid-future-chance-of-using-uninitialized-memory.patch 2015-03-02 18:47:01.000000000 +0100 @@ -0,0 +1,44 @@ +From e7cbce8fb2b7417fd1048f916b3e3281f5b9dd7b Mon Sep 17 00:00:00 2001 +From: Daniel Kahn Gillmor <d...@fifthhorseman.net> +Date: Fri, 19 Dec 2014 17:53:36 -0500 +Subject: [PATCH 24/45] avoid future chance of using uninitialized memory + +* util/iobuf.c: (iobuf_open): initialize len + +-- + +Cherry-pick 367b073ab5f439ccf0750461d10c69f36998bd62. + +In iobuf_open, IOBUFCTRL_DESC and IOBUFCTRL_INIT commands are invoked +(via file_filter()) on fcx, passing in a pointer to an uninitialized +len. + +With these two commands, file_filter doesn't actually do anything with +the value of len, so there's no actual risk of use of uninitialized +memory in the code as it stands. + +However, some static analysis tools might flag this situation with a +warning, and initializing the value doesn't hurt anything, so i think +this trivial cleanup is warranted. + +Debian-Bug-Id: 773469 +--- + util/iobuf.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/util/iobuf.c b/util/iobuf.c +index 35de020..a330460 100644 +--- a/util/iobuf.c ++++ b/util/iobuf.c +@@ -1107,7 +1107,7 @@ iobuf_open( const char *fname ) + IOBUF a; + FILEP_OR_FD fp; + file_filter_ctx_t *fcx; +- size_t len; ++ size_t len = 0; + int print_only = 0; + int fd; + +-- +2.1.4 + diff -Nru gnupg-1.4.18/debian/patches/0029-Use-ciphertext-blinding-for-Elgamal-decryption.patch gnupg-1.4.18/debian/patches/0029-Use-ciphertext-blinding-for-Elgamal-decryption.patch --- gnupg-1.4.18/debian/patches/0029-Use-ciphertext-blinding-for-Elgamal-decryption.patch 1970-01-01 01:00:00.000000000 +0100 +++ gnupg-1.4.18/debian/patches/0029-Use-ciphertext-blinding-for-Elgamal-decryption.patch 2015-03-02 18:47:01.000000000 +0100 @@ -0,0 +1,114 @@ +From ff53cf06e966dce0daba5f2c84e03ab9db2c3c8b Mon Sep 17 00:00:00 2001 +From: Werner Koch <w...@gnupg.org> +Date: Mon, 11 Aug 2014 16:15:40 +0200 +Subject: [PATCH 29/45] Use ciphertext blinding for Elgamal decryption. + +* cipher/elgamal.c (USE_BLINDING): New. +(decrypt): Rewrite to use ciphertext blinding. +-- + +CVE-id: CVE-2014-3591 + +As a countermeasure to a new side-channel attacks on sliding windows +exponentiation we blind the ciphertext for Elgamal decryption. This +is similar to what we are doing with RSA. + +Unfortunately, the performance impact of Elgamal blinding is quite +noticeable: For a 3072 bit Elgamal key the decryption used to take +13ms; with the blinding it takes 24ms. This has been measured using +time(1), calling gpg with a 100 byte message, and having gpg modified +to run the pubkey_decrypt function 100 times and finally scale the +result (using an i5-2410M CPU @ 2.30GHz TP 220). +--- + cipher/elgamal.c | 63 +++++++++++++++++++++++++++++++++++++++++++------------- + 1 file changed, 49 insertions(+), 14 deletions(-) + +diff --git a/cipher/elgamal.c b/cipher/elgamal.c +index 5143ecc..2ec5217 100644 +--- a/cipher/elgamal.c ++++ b/cipher/elgamal.c +@@ -31,6 +31,11 @@ + #include "cipher.h" + #include "elgamal.h" + ++/* Blinding is used to mitigate side-channel attacks. You may undef ++ this to speed up the operation in case the system is secured ++ against physical and network mounted side-channel attacks. */ ++#define USE_BLINDING 1 ++ + typedef struct { + MPI p; /* prime */ + MPI g; /* group generator */ +@@ -372,25 +377,55 @@ do_encrypt(MPI a, MPI b, MPI input, ELG_public_key *pkey ) + static void + decrypt(MPI output, MPI a, MPI b, ELG_secret_key *skey ) + { +- MPI t1 = mpi_alloc_secure( mpi_get_nlimbs( skey->p ) ); ++ MPI t1, t2, r; ++ unsigned int nbits = mpi_get_nbits (skey->p); ++ ++ mpi_normalize (a); ++ mpi_normalize (b); ++ ++ t1 = mpi_alloc_secure (mpi_nlimb_hint_from_nbits (nbits)); ++#ifdef USE_BLINDING ++ ++ t2 = mpi_alloc_secure (mpi_nlimb_hint_from_nbits (nbits)); ++ r = mpi_alloc (mpi_nlimb_hint_from_nbits (nbits)); ++ ++ /* We need a random number of about the prime size. The random ++ number merely needs to be unpredictable; thus we use level 0. */ ++ randomize_mpi (r, nbits, 0); ++ ++ /* t1 = r^x mod p */ ++ mpi_powm (t1, r, skey->x, skey->p); ++ /* t2 = (a * r)^-x mod p */ ++ mpi_mulm (t2, a, r, skey->p); ++ mpi_powm (t2, t2, skey->x, skey->p); ++ mpi_invm (t2, t2, skey->p); ++ /* t1 = (t1 * t2) mod p*/ ++ mpi_mulm (t1, t1, t2, skey->p); + +- mpi_normalize (a); +- mpi_normalize (b); ++ mpi_free (r); ++ mpi_free (t2); ++ ++#else /*!USE_BLINDING*/ ++ ++ /* output = b/(a^x) mod p */ ++ mpi_powm (t1, a, skey->x, skey->p); ++ mpi_invm (t1, t1, skey->p); ++ ++#endif /*!USE_BLINDING*/ ++ ++ mpi_mulm (output, b, t1, skey->p); + +- /* output = b/(a^x) mod p */ +- mpi_powm( t1, a, skey->x, skey->p ); +- mpi_invm( t1, t1, skey->p ); +- mpi_mulm( output, b, t1, skey->p ); + #if 0 +- if( DBG_CIPHER ) { +- log_mpidump("elg decrypted x= ", skey->x); +- log_mpidump("elg decrypted p= ", skey->p); +- log_mpidump("elg decrypted a= ", a); +- log_mpidump("elg decrypted b= ", b); +- log_mpidump("elg decrypted M= ", output); ++ if (DBG_CIPHER) ++ { ++ log_mpidump("elg decrypted x= ", skey->x); ++ log_mpidump("elg decrypted p= ", skey->p); ++ log_mpidump("elg decrypted a= ", a); ++ log_mpidump("elg decrypted b= ", b); ++ log_mpidump("elg decrypted M= ", output); + } + #endif +- mpi_free(t1); ++ mpi_free (t1); + } + + +-- +2.1.4 + diff -Nru gnupg-1.4.18/debian/patches/0032-gpg-Limit-the-size-of-key-packets-to-a-sensible-valu.patch gnupg-1.4.18/debian/patches/0032-gpg-Limit-the-size-of-key-packets-to-a-sensible-valu.patch --- gnupg-1.4.18/debian/patches/0032-gpg-Limit-the-size-of-key-packets-to-a-sensible-valu.patch 1970-01-01 01:00:00.000000000 +0100 +++ gnupg-1.4.18/debian/patches/0032-gpg-Limit-the-size-of-key-packets-to-a-sensible-valu.patch 2015-03-02 18:47:01.000000000 +0100 @@ -0,0 +1,109 @@ +From 27d7addccf782d5cb0084cb17522d712d4a6d6b6 Mon Sep 17 00:00:00 2001 +From: Werner Koch <w...@gnupg.org> +Date: Sat, 21 Feb 2015 23:10:27 -0500 +Subject: [PATCH 32/45] gpg: Limit the size of key packets to a sensible value. +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +* g10/parse-packet.c (MAX_KEY_PACKET_LENGTH): New. +(MAX_UID_PACKET_LENGTH): New. +(MAX_COMMENT_PACKET_LENGTH): New. +(MAX_ATTR_PACKET_LENGTH): New. +(parse_key): Limit the size of a key packet to 256k. +(parse_user_id): Use macro for the packet size limit. +(parse_attribute): Ditto. +(parse_comment): Ditto. +-- + +Without that it is possible to force gpg to allocate large amounts of +memory by using a bad encoded MPI. This would be an too easy DoS. +Another way to mitigate would be to change the MPI read function to +allocate memory dynamically while reading the MPI. However, that +complicates and possibly slows down the code. A too large key packet +is in any case a sign for broken data and thus gpg should not use it. + +Reported-by: Hanno Böck +GnuPG-bug-id: 1823 +Signed-off-by: Werner Koch <w...@gnupg.org> + +(back ported from commit 382ba4b137b42d5f25a7e256bb7c053ee5ac7b64) + +[dkg: rebased to STABLE-BRANCH-1-4] +Signed-off-by: Daniel Kahn Gillmor <d...@fifthhorseman.net> +--- + g10/parse-packet.c | 30 ++++++++++++++++++++++++++++-- + 1 file changed, 28 insertions(+), 2 deletions(-) + +diff --git a/g10/parse-packet.c b/g10/parse-packet.c +index e4e524c..c0b6ad6 100644 +--- a/g10/parse-packet.c ++++ b/g10/parse-packet.c +@@ -40,6 +40,12 @@ + #define MAX_EXTERN_MPI_BITS 16384 + #endif + ++/* Maximum length of packets to avoid excessive memory allocation. */ ++#define MAX_KEY_PACKET_LENGTH (256 * 1024) ++#define MAX_UID_PACKET_LENGTH ( 2 * 1024) ++#define MAX_COMMENT_PACKET_LENGTH ( 64 * 1024) ++#define MAX_ATTR_PACKET_LENGTH ( 16 * 1024*1024) ++ + + static int mpi_print_mode; + static int list_mode; +@@ -1663,6 +1669,13 @@ parse_key( IOBUF inp, int pkttype, unsigned long pktlen, + rc = G10ERR_INVALID_PACKET; + goto leave; + } ++ else if (pktlen > MAX_KEY_PACKET_LENGTH) { ++ log_error ("packet(%d) too large\n", pkttype); ++ if (list_mode) ++ fputs (":key packet: [too large]\n", listfp); ++ rc = G10ERR_INVALID_PACKET; ++ goto leave; ++ } + + timestamp = read_32(inp); pktlen -= 4; + if( is_v4 ) { +@@ -2083,7 +2096,7 @@ parse_user_id( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet ) + allocatable, and a very large pktlen could actually cause our + allocation to wrap around in xmalloc to a small number. */ + +- if(pktlen>2048) ++ if (pktlen > MAX_UID_PACKET_LENGTH) + { + log_error("packet(%d) too large\n", pkttype); + iobuf_skip_rest(inp, pktlen, 0); +@@ -2152,6 +2165,19 @@ parse_attribute( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet ) + { + byte *p; + ++ (void)pkttype; ++ ++ /* We better cap the size of an attribute packet to make DoS not ++ too easy. 16MB should be more then enough for one attribute ++ packet (ie. a photo). */ ++ if (pktlen > MAX_ATTR_PACKET_LENGTH) { ++ log_error ("packet(%d) too large\n", pkttype); ++ if (list_mode) ++ fprintf (listfp, ":attribute packet: [too large]\n"); ++ iobuf_skip_rest (inp, pktlen, 0); ++ return G10ERR_INVALID_PACKET; ++ } ++ + #define EXTRA_UID_NAME_SPACE 71 + packet->pkt.user_id = xmalloc_clear(sizeof *packet->pkt.user_id + + EXTRA_UID_NAME_SPACE); +@@ -2186,7 +2212,7 @@ parse_comment( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet ) + overflow in the malloc below. Comment packets are actually not + anymore define my OpenPGP and we even stopped to use our + private comment packet. */ +- if (pktlen>65536) ++ if (pktlen > MAX_COMMENT_PACKET_LENGTH) + { + log_error ("packet(%d) too large\n", pkttype); + iobuf_skip_rest (inp, pktlen, 0); +-- +2.1.4 + diff -Nru gnupg-1.4.18/debian/patches/0033-gpg-Fix-a-NULL-deref-due-to-empty-ring-trust-packets.patch gnupg-1.4.18/debian/patches/0033-gpg-Fix-a-NULL-deref-due-to-empty-ring-trust-packets.patch --- gnupg-1.4.18/debian/patches/0033-gpg-Fix-a-NULL-deref-due-to-empty-ring-trust-packets.patch 1970-01-01 01:00:00.000000000 +0100 +++ gnupg-1.4.18/debian/patches/0033-gpg-Fix-a-NULL-deref-due-to-empty-ring-trust-packets.patch 2015-03-02 18:47:01.000000000 +0100 @@ -0,0 +1,57 @@ +From 2e8db53854506572e9d5b5908e143b5ca28f30f5 Mon Sep 17 00:00:00 2001 +From: Werner Koch <w...@gnupg.org> +Date: Sat, 21 Feb 2015 23:10:28 -0500 +Subject: [PATCH 33/45] gpg: Fix a NULL-deref due to empty ring trust packets. +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +* g10/parse-packet.c (parse_trust): Always allocate a packet. +-- + +Reported-by: Hanno Böck <ha...@hboeck.de> +Signed-off-by: Werner Koch <w...@gnupg.org> + +(back ported from commit 39978487863066e59bb657f5fe4e8baab510da7e) + +[dkg: rebased to STABLE-BRANCH-1-4] +Signed-off-by: Daniel Kahn Gillmor <d...@fifthhorseman.net> +--- + g10/parse-packet.c | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +diff --git a/g10/parse-packet.c b/g10/parse-packet.c +index c0b6ad6..e7e923b 100644 +--- a/g10/parse-packet.c ++++ b/g10/parse-packet.c +@@ -2245,11 +2245,13 @@ parse_trust( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *pkt ) + { + int c; + ++ (void)pkttype; ++ ++ pkt->pkt.ring_trust = xmalloc( sizeof *pkt->pkt.ring_trust ); + if (pktlen) + { + c = iobuf_get_noeof(inp); + pktlen--; +- pkt->pkt.ring_trust = xmalloc( sizeof *pkt->pkt.ring_trust ); + pkt->pkt.ring_trust->trustval = c; + pkt->pkt.ring_trust->sigcache = 0; + if (!c && pktlen==1) +@@ -2267,8 +2269,10 @@ parse_trust( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *pkt ) + } + else + { +- if( list_mode ) +- fprintf (listfp, ":trust packet: empty\n"); ++ pkt->pkt.ring_trust->trustval = 0; ++ pkt->pkt.ring_trust->sigcache = 0; ++ if (list_mode) ++ fprintf (listfp, ":trust packet: empty\n"); + } + iobuf_skip_rest (inp, pktlen, 0); + } +-- +2.1.4 + diff -Nru gnupg-1.4.18/debian/patches/0034-gpg-Fix-a-NULL-deref-in-export-due-to-invalid-packet.patch gnupg-1.4.18/debian/patches/0034-gpg-Fix-a-NULL-deref-in-export-due-to-invalid-packet.patch --- gnupg-1.4.18/debian/patches/0034-gpg-Fix-a-NULL-deref-in-export-due-to-invalid-packet.patch 1970-01-01 01:00:00.000000000 +0100 +++ gnupg-1.4.18/debian/patches/0034-gpg-Fix-a-NULL-deref-in-export-due-to-invalid-packet.patch 2015-03-02 18:47:01.000000000 +0100 @@ -0,0 +1,40 @@ +From 68f260f77a9e4f5cacf0a58e4f55ddee125d3f00 Mon Sep 17 00:00:00 2001 +From: Werner Koch <w...@gnupg.org> +Date: Sat, 21 Feb 2015 23:10:29 -0500 +Subject: [PATCH 34/45] gpg: Fix a NULL-deref in export due to invalid packet + lengths. +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +* g10/build-packet.c (write_fake_data): Take care of a NULL stored as +opaque MPI. +-- + +Reported-by: Hanno Böck <ha...@hboeck.de> + +(back ported from commit 0835d2f44ef62eab51fce6a927908f544e01cf8f) + +[dkg: rebased to STABLE-BRANCH-1-4] +Signed-off-by: Daniel Kahn Gillmor <d...@fifthhorseman.net> +--- + g10/build-packet.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/g10/build-packet.c b/g10/build-packet.c +index abe0181..499dd68 100644 +--- a/g10/build-packet.c ++++ b/g10/build-packet.c +@@ -193,7 +193,8 @@ write_fake_data( IOBUF out, MPI a ) + void *p; + + p = mpi_get_opaque( a, &i ); +- iobuf_write( out, p, i ); ++ if (p) ++ iobuf_write( out, p, i ); + } + } + +-- +2.1.4 + diff -Nru gnupg-1.4.18/debian/patches/0035-gpg-Prevent-an-invalid-memory-read-using-a-garbled-k.patch gnupg-1.4.18/debian/patches/0035-gpg-Prevent-an-invalid-memory-read-using-a-garbled-k.patch --- gnupg-1.4.18/debian/patches/0035-gpg-Prevent-an-invalid-memory-read-using-a-garbled-k.patch 1970-01-01 01:00:00.000000000 +0100 +++ gnupg-1.4.18/debian/patches/0035-gpg-Prevent-an-invalid-memory-read-using-a-garbled-k.patch 2015-03-02 18:47:01.000000000 +0100 @@ -0,0 +1,78 @@ +From 81d3e541326e94d26a953aa70afc3cb149d11ebe Mon Sep 17 00:00:00 2001 +From: Werner Koch <w...@gnupg.org> +Date: Sat, 21 Feb 2015 23:10:30 -0500 +Subject: [PATCH 35/45] gpg: Prevent an invalid memory read using a garbled + keyring. +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +* g10/keyring.c (keyring_get_keyblock): Whitelist allowed packet +types. +-- + +The keyring DB code did not reject packets which don't belong into a +keyring. If for example the keyblock contains a literal data packet +it is expected that the processing code stops at the data packet and +reads from the input stream which is referenced from the data packets. +Obviously the keyring processing code does not and cannot do that. +However, when exporting this messes up the IOBUF and leads to an +invalid read of sizeof (int). + +We now skip all packets which are not allowed in a keyring. + +Reported-by: Hanno Böck <ha...@hboeck.de> + +(back ported from commit f0f71a721ccd7ab9e40b8b6b028b59632c0cc648) + +[dkg: rebased to STABLE-BRANCH-1-4] +Signed-off-by: Daniel Kahn Gillmor <d...@fifthhorseman.net> +--- + g10/keyring.c | 24 +++++++++++++++++++++--- + 1 file changed, 21 insertions(+), 3 deletions(-) + +diff --git a/g10/keyring.c b/g10/keyring.c +index 108e107..270bf8e 100644 +--- a/g10/keyring.c ++++ b/g10/keyring.c +@@ -400,8 +400,26 @@ keyring_get_keyblock (KEYRING_HANDLE hd, KBNODE *ret_kb) + rc = G10ERR_INV_KEYRING; + break; + } +- if (pkt->pkttype == PKT_COMPRESSED) { +- log_error ("skipped compressed packet in keyring\n"); ++ ++ /* Filter allowed packets. */ ++ switch (pkt->pkttype){ ++ case PKT_PUBLIC_KEY: ++ case PKT_PUBLIC_SUBKEY: ++ case PKT_SECRET_KEY: ++ case PKT_SECRET_SUBKEY: ++ case PKT_USER_ID: ++ case PKT_ATTRIBUTE: ++ case PKT_SIGNATURE: ++ break; /* Allowed per RFC. */ ++ case PKT_RING_TRUST: ++ case PKT_OLD_COMMENT: ++ case PKT_COMMENT: ++ case PKT_GPG_CONTROL: ++ break; /* Allowed by us. */ ++ ++ default: ++ log_error ("skipped packet of type %d in keyring\n", ++ (int)pkt->pkttype); + free_packet(pkt); + init_packet(pkt); + continue; +@@ -467,7 +485,7 @@ keyring_get_keyblock (KEYRING_HANDLE hd, KBNODE *ret_kb) + if (rc || !ret_kb) + release_kbnode (keyblock); + else { +- /*(duplicated form the loop body)*/ ++ /*(duplicated from the loop body)*/ + if ( pkt && pkt->pkttype == PKT_RING_TRUST + && lastnode + && lastnode->pkt->pkttype == PKT_SIGNATURE +-- +2.1.4 + diff -Nru gnupg-1.4.18/debian/patches/0036-doc-Change-remaining-http-links-to-gnupg.org-to-http.patch gnupg-1.4.18/debian/patches/0036-doc-Change-remaining-http-links-to-gnupg.org-to-http.patch --- gnupg-1.4.18/debian/patches/0036-doc-Change-remaining-http-links-to-gnupg.org-to-http.patch 1970-01-01 01:00:00.000000000 +0100 +++ gnupg-1.4.18/debian/patches/0036-doc-Change-remaining-http-links-to-gnupg.org-to-http.patch 2015-03-02 18:47:01.000000000 +0100 @@ -0,0 +1,67 @@ +From 7106165fd3161b614445d459df3b333d557d9d02 Mon Sep 17 00:00:00 2001 +From: Werner Koch <w...@gnupg.org> +Date: Sat, 21 Feb 2015 23:10:31 -0500 +Subject: [PATCH 36/45] doc: Change remaining http links to gnupg.org to https + +-- +GnuPG-bug-id: 1830 + +[dkg: rebased to STABLE-BRANCH-1-4] +Signed-off-by: Daniel Kahn Gillmor <d...@fifthhorseman.net> +--- + doc/gpg.texi | 2 +- + g10/misc.c | 4 ++-- + g10/sig-check.c | 2 +- + 3 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/doc/gpg.texi b/doc/gpg.texi +index 7d08756..67dc3d0 100644 +--- a/doc/gpg.texi ++++ b/doc/gpg.texi +@@ -321,7 +321,7 @@ useful for debugging. + Present a menu to work with a smartcard. The subcommand "help" provides + an overview on available commands. For a detailed description, please + see the Card HOWTO at +-http://www.gnupg.org/documentation/howtos.html#GnuPG-cardHOWTO . ++https://gnupg.org/documentation/howtos.html#GnuPG-cardHOWTO . + + @item --card-status + @opindex card-status +diff --git a/g10/misc.c b/g10/misc.c +index 68b4cea..60ecf96 100644 +--- a/g10/misc.c ++++ b/g10/misc.c +@@ -462,7 +462,7 @@ md5_digest_warn (int show) + log_info (_("WARNING: digest algorithm %s is deprecated\n"), + digest_algo_to_string (DIGEST_ALGO_MD5)); + log_info (_("please see %s for more information\n"), +- "http://www.gnupg.org/faq/weak-digest-algos.html"); ++ "https://gnupg.org/faq/weak-digest-algos.html"); + warned = 1; + } + } +@@ -477,7 +477,7 @@ not_in_gpg1_notice (void) + { + log_info (_("NOTE: This feature is not available in %s\n"), "GnuPG 1.x"); + log_info (_("please see %s for more information\n"), +- "http://www.gnupg.org/faq/features-not-in-gnupg-1.html"); ++ "https://gnupg.org/faq/features-not-in-gnupg-1.html"); + warned = 1; + } + } +diff --git a/g10/sig-check.c b/g10/sig-check.c +index d6bbb92..b7709c1 100644 +--- a/g10/sig-check.c ++++ b/g10/sig-check.c +@@ -99,7 +99,7 @@ signature_check2( PKT_signature *sig, MD_HANDLE digest, u32 *r_expiredate, + log_info(_("WARNING: signing subkey %s is not" + " cross-certified\n"),keystr_from_pk(pk)); + log_info(_("please see %s for more information\n"), +- "http://www.gnupg.org/faq/subkey-cross-certify.html"); ++ "https://gnupg.org/faq/subkey-cross-certify.html"); + /* --require-cross-certification makes this warning an + error. TODO: change the default to require this + after more keys have backsigs. */ +-- +2.1.4 + diff -Nru gnupg-1.4.18/debian/patches/0037-Use-inline-functions-to-convert-buffer-data-to-scala.patch gnupg-1.4.18/debian/patches/0037-Use-inline-functions-to-convert-buffer-data-to-scala.patch --- gnupg-1.4.18/debian/patches/0037-Use-inline-functions-to-convert-buffer-data-to-scala.patch 1970-01-01 01:00:00.000000000 +0100 +++ gnupg-1.4.18/debian/patches/0037-Use-inline-functions-to-convert-buffer-data-to-scala.patch 2015-03-02 18:47:01.000000000 +0100 @@ -0,0 +1,741 @@ +From 57af33d9e7c9b20b413b96882e670e75a67a5e65 Mon Sep 17 00:00:00 2001 +From: Werner Koch <w...@gnupg.org> +Date: Sat, 21 Feb 2015 23:10:32 -0500 +Subject: [PATCH 37/45] Use inline functions to convert buffer data to scalars. +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +* include/host2net.h (buf16_to_ulong, buf16_to_uint): New. +(buf16_to_ushort, buf16_to_u16): New. +(buf32_to_size_t, buf32_to_ulong, buf32_to_uint, buf32_to_u32): New. +-- + +This fixes sign extension on shift problems. Hanno Böck found a case +with an invalid read due to this problem. To fix that almost all uses +of "<< 24" and "<< 8" are changed by this patch to use an inline +function from host2net.h. + +(back ported from commit 2183683bd633818dd031b090b5530951de76f392) + +Signed-off-by: Werner Koch <w...@gnupg.org> + +[dkg: rebased to STABLE-BRANCH-1-4] +Signed-off-by: Daniel Kahn Gillmor <d...@fifthhorseman.net> +--- + g10/apdu.c | 27 ++++++++---------- + g10/app-openpgp.c | 3 +- + g10/build-packet.c | 6 ++-- + g10/ccid-driver.c | 3 +- + g10/getkey.c | 17 ++++++------ + g10/keygen.c | 14 ++++------ + g10/keyid.c | 28 ++++++++----------- + g10/misc.c | 11 -------- + g10/parse-packet.c | 41 ++++++++++++++-------------- + g10/tdbio.c | 22 +++++++-------- + g10/trustdb.c | 2 +- + include/host2net.h | 80 +++++++++++++++++++++++++++++++++++++++++++++++------- + 12 files changed, 148 insertions(+), 106 deletions(-) + +diff --git a/g10/apdu.c b/g10/apdu.c +index 66cf30b..ffc7d36 100644 +--- a/g10/apdu.c ++++ b/g10/apdu.c +@@ -60,6 +60,7 @@ + #include "scdaemon.h" + #include "exechelp.h" + #endif /* GNUPG_MAJOR_VERSION != 1 */ ++#include "../include/host2net.h" + + #include "apdu.h" + #include "ccid-driver.h" +@@ -916,15 +917,14 @@ pcsc_get_status_wrapped (int slot, unsigned int *status) + i? strerror (errno) : "premature EOF"); + goto command_failed; + } +- len = (msgbuf[1] << 24) | (msgbuf[2] << 16) | (msgbuf[3] << 8 ) | msgbuf[4]; ++ len = buf32_to_size_t (msgbuf+1); + if (msgbuf[0] != 0x81 || len < 4) + { + log_error ("invalid response header from PC/SC received\n"); + goto command_failed; + } + len -= 4; /* Already read the error code. */ +- err = PCSC_ERR_MASK ((msgbuf[5] << 24) | (msgbuf[6] << 16) +- | (msgbuf[7] << 8 ) | msgbuf[8]); ++ err = PCSC_ERR_MASK (buf32_to_ulong (msgbuf+5)); + if (err) + { + log_error ("pcsc_status failed: %s (0x%lx)\n", +@@ -1084,15 +1084,14 @@ pcsc_send_apdu_wrapped (int slot, unsigned char *apdu, size_t apdulen, + i? strerror (errno) : "premature EOF"); + goto command_failed; + } +- len = (msgbuf[1] << 24) | (msgbuf[2] << 16) | (msgbuf[3] << 8 ) | msgbuf[4]; ++ len = buf32_to_size_t (msgbuf+1); + if (msgbuf[0] != 0x81 || len < 4) + { + log_error ("invalid response header from PC/SC received\n"); + goto command_failed; + } + len -= 4; /* Already read the error code. */ +- err = PCSC_ERR_MASK ((msgbuf[5] << 24) | (msgbuf[6] << 16) +- | (msgbuf[7] << 8 ) | msgbuf[8]); ++ err = PCSC_ERR_MASK (buf32_to_ulong (msgbuf+5)); + if (err) + { + log_error ("pcsc_transmit failed: %s (0x%lx)\n", +@@ -1217,15 +1216,14 @@ close_pcsc_reader_wrapped (int slot) + i? strerror (errno) : "premature EOF"); + goto command_failed; + } +- len = (msgbuf[1] << 24) | (msgbuf[2] << 16) | (msgbuf[3] << 8 ) | msgbuf[4]; ++ len = buf32_to_size_t (msgbuf+1); + if (msgbuf[0] != 0x81 || len < 4) + { + log_error ("invalid response header from PC/SC received\n"); + goto command_failed; + } + len -= 4; /* Already read the error code. */ +- err = PCSC_ERR_MASK ((msgbuf[5] << 24) | (msgbuf[6] << 16) +- | (msgbuf[7] << 8 ) | msgbuf[8]); ++ err = PCSC_ERR_MASK (buf32_to_ulong (msgbuf+5)); + if (err) + log_error ("pcsc_close failed: %s (0x%lx)\n", + pcsc_error_string (err), err); +@@ -1405,7 +1403,7 @@ reset_pcsc_reader_wrapped (int slot) + i? strerror (errno) : "premature EOF"); + goto command_failed; + } +- len = (msgbuf[1] << 24) | (msgbuf[2] << 16) | (msgbuf[3] << 8 ) | msgbuf[4]; ++ len = buf32_to_size_t (msgbuf+1); + if (msgbuf[0] != 0x81 || len < 4) + { + log_error ("invalid response header from PC/SC received\n"); +@@ -1419,8 +1417,7 @@ reset_pcsc_reader_wrapped (int slot) + sw = SW_HOST_GENERAL_ERROR; + goto command_failed; + } +- err = PCSC_ERR_MASK ((msgbuf[5] << 24) | (msgbuf[6] << 16) +- | (msgbuf[7] << 8 ) | msgbuf[8]); ++ err = PCSC_ERR_MASK (buf32_to_ulong (msgbuf+5)); + if (err) + { + log_error ("PC/SC RESET failed: %s (0x%lx)\n", +@@ -1719,7 +1716,7 @@ open_pcsc_reader_wrapped (const char *portstr) + i? strerror (errno) : "premature EOF"); + goto command_failed; + } +- len = (msgbuf[1] << 24) | (msgbuf[2] << 16) | (msgbuf[3] << 8 ) | msgbuf[4]; ++ len = buf32_to_size_t (msgbuf+1); + if (msgbuf[0] != 0x81 || len < 4) + { + log_error ("invalid response header from PC/SC received\n"); +@@ -1732,8 +1729,8 @@ open_pcsc_reader_wrapped (const char *portstr) + (unsigned long)len); + goto command_failed; + } +- err = PCSC_ERR_MASK ((msgbuf[5] << 24) | (msgbuf[6] << 16) +- | (msgbuf[7] << 8 ) | msgbuf[8]); ++ err = PCSC_ERR_MASK (buf32_to_ulong (msgbuf+5)); ++ + if (err) + { + log_error ("PC/SC OPEN failed: %s\n", pcsc_error_string (err)); +diff --git a/g10/app-openpgp.c b/g10/app-openpgp.c +index c3b4fae..192680c 100644 +--- a/g10/app-openpgp.c ++++ b/g10/app-openpgp.c +@@ -68,6 +68,7 @@ + #include "iso7816.h" + #include "app-common.h" + #include "tlv.h" ++#include "../include/host2net.h" + + + /* A table describing the DOs of the card. */ +@@ -744,7 +745,7 @@ send_fprtime_if_not_null (ctrl_t ctrl, const char *keyword, + char numbuf1[50], numbuf2[50]; + unsigned long value; + +- value = (stamp[0] << 24) | (stamp[1]<<16) | (stamp[2]<<8) | stamp[3]; ++ value = buf32_to_ulong (stamp); + if (!value) + return; + sprintf (numbuf1, "%d", number); +diff --git a/g10/build-packet.c b/g10/build-packet.c +index 499dd68..60eb3c8 100644 +--- a/g10/build-packet.c ++++ b/g10/build-packet.c +@@ -34,6 +34,7 @@ + #include "memory.h" + #include "i18n.h" + #include "options.h" ++#include "../include/host2net.h" + + static int do_user_id( IOBUF out, int ctb, PKT_user_id *uid ); + static int do_public_key( IOBUF out, int ctb, PKT_public_key *pk ); +@@ -586,8 +587,7 @@ delete_sig_subpkt (subpktarea_t *area, sigsubpkttype_t reqtype ) + if( n == 255 ) { + if( buflen < 4 ) + break; +- n = (buffer[0] << 24) | (buffer[1] << 16) +- | (buffer[2] << 8) | buffer[3]; ++ n = buf32_to_size_t (buffer); + buffer += 4; + buflen -= 4; + } +@@ -710,7 +710,7 @@ build_sig_subpkt (PKT_signature *sig, sigsubpkttype_t type, + /* This should never happen since we don't currently allow + creating such a subpacket, but just in case... */ + case SIGSUBPKT_SIG_EXPIRE: +- if(buffer_to_u32(buffer)+sig->timestamp<=make_timestamp()) ++ if (buf32_to_u32 (buffer) + sig->timestamp <= make_timestamp()) + sig->flags.expired=1; + else + sig->flags.expired=0; +diff --git a/g10/ccid-driver.c b/g10/ccid-driver.c +index 8c362d7..515b15a 100644 +--- a/g10/ccid-driver.c ++++ b/g10/ccid-driver.c +@@ -92,6 +92,7 @@ + #include <usb.h> + + #include "ccid-driver.h" ++#include "../include/host2net.h" + + #define DRVNAME "ccid-driver: " + +@@ -292,7 +293,7 @@ static int abort_cmd (ccid_driver_t handle, int seqno); + static unsigned int + convert_le_u32 (const unsigned char *buf) + { +- return buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24); ++ return buf[0] | (buf[1] << 8) | (buf[2] << 16) | ((unsigned int)buf[3] << 24); + } + + +diff --git a/g10/getkey.c b/g10/getkey.c +index 3c953d6..9870710 100644 +--- a/g10/getkey.c ++++ b/g10/getkey.c +@@ -34,6 +34,7 @@ + #include "trustdb.h" + #include "i18n.h" + #include "keyserver-internal.h" ++#include "../include/host2net.h" + + #define MAX_PK_CACHE_ENTRIES PK_UID_CACHE_SIZE + #define MAX_UID_CACHE_ENTRIES PK_UID_CACHE_SIZE +@@ -1427,14 +1428,14 @@ merge_keys_and_selfsig( KBNODE keyblock ) + + p = parse_sig_subpkt( sig->hashed, SIGSUBPKT_KEY_EXPIRE, NULL ); + if( pk ) { +- ed = p? pk->timestamp + buffer_to_u32(p):0; ++ ed = p? pk->timestamp + buf32_to_u32(p):0; + if( sig->timestamp > sigdate ) { + pk->expiredate = ed; + sigdate = sig->timestamp; + } + } + else { +- ed = p? sk->timestamp + buffer_to_u32(p):0; ++ ed = p? sk->timestamp + buf32_to_u32(p):0; + if( sig->timestamp > sigdate ) { + sk->expiredate = ed; + sigdate = sig->timestamp; +@@ -1559,8 +1560,8 @@ fixup_uidnode ( KBNODE uidnode, KBNODE signode, u32 keycreated ) + + /* ditto for the key expiration */ + p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_KEY_EXPIRE, NULL); +- if( p && buffer_to_u32(p) ) +- uid->help_key_expire = keycreated + buffer_to_u32(p); ++ if( p && buf32_to_u32 (p) ) ++ uid->help_key_expire = keycreated + buf32_to_u32(p); + else + uid->help_key_expire = 0; + +@@ -1774,9 +1775,9 @@ merge_selfsigs_main(KBNODE keyblock, int *r_revoked, struct revoke_info *rinfo) + key_usage=parse_key_usage(sig); + + p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_KEY_EXPIRE, NULL); +- if( p && buffer_to_u32(p) ) ++ if( p && buf32_to_u32 (p) ) + { +- key_expire = keytimestamp + buffer_to_u32(p); ++ key_expire = keytimestamp + buf32_to_u32 (p); + key_expire_seen = 1; + } + +@@ -2198,8 +2199,8 @@ merge_selfsigs_subkey( KBNODE keyblock, KBNODE subnode ) + subpk->pubkey_usage = key_usage; + + p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_KEY_EXPIRE, NULL); +- if ( p && buffer_to_u32(p) ) +- key_expire = keytimestamp + buffer_to_u32(p); ++ if ( p && buf32_to_u32 (p) ) ++ key_expire = keytimestamp + buf32_to_u32 (p); + else + key_expire = 0; + subpk->has_expired = key_expire >= curtime? 0 : key_expire; +diff --git a/g10/keygen.c b/g10/keygen.c +index 995ba63..76ee74e 100644 +--- a/g10/keygen.c ++++ b/g10/keygen.c +@@ -40,6 +40,7 @@ + #include "i18n.h" + #include "cardglue.h" + #include "keyserver-internal.h" ++#include "host2net.h" + + #define MAX_PREFS 30 + +@@ -832,10 +833,7 @@ make_backsig (PKT_signature *sig, PKT_public_key *pk, + } + else if(buf[1]==255) + { +- pktlen =buf[2] << 24; +- pktlen|=buf[3] << 16; +- pktlen|=buf[4] << 8; +- pktlen|=buf[5]; ++ pktlen = buf32_to_size_t (buf+2); + buf+=6; + } + else +@@ -852,14 +850,14 @@ make_backsig (PKT_signature *sig, PKT_public_key *pk, + break; + + case 2: +- pktlen =buf[mark++] << 24; +- pktlen|=buf[mark++] << 16; ++ pktlen = (size_t)buf[mark++] << 24; ++ pktlen |= buf[mark++] << 16; + + case 1: +- pktlen|=buf[mark++] << 8; ++ pktlen |= buf[mark++] << 8; + + case 0: +- pktlen|=buf[mark++]; ++ pktlen |= buf[mark++]; + } + + buf+=mark; +diff --git a/g10/keyid.c b/g10/keyid.c +index d7072d4..ed30cff 100644 +--- a/g10/keyid.c ++++ b/g10/keyid.c +@@ -32,6 +32,7 @@ + #include "mpi.h" + #include "keydb.h" + #include "i18n.h" ++#include "host2net.h" + + #ifdef HAVE_UNSIGNED_TIME_T + # define INVALID_TIME_CHECK(a) ((a) == (time_t)(-1)) +@@ -241,15 +242,8 @@ keystr_from_desc(KEYDB_SEARCH_DESC *desc) + { + u32 keyid[2]; + +- keyid[0] = (unsigned char)desc->u.fpr[12] << 24 +- | (unsigned char)desc->u.fpr[13] << 16 +- | (unsigned char)desc->u.fpr[14] << 8 +- | (unsigned char)desc->u.fpr[15] ; +- keyid[1] = (unsigned char)desc->u.fpr[16] << 24 +- | (unsigned char)desc->u.fpr[17] << 16 +- | (unsigned char)desc->u.fpr[18] << 8 +- | (unsigned char)desc->u.fpr[19] ; +- ++ keyid[0] = buf32_to_u32 (desc->u.fpr+12); ++ keyid[1] = buf32_to_u32 (desc->u.fpr+16); + return keystr(keyid); + } + +@@ -300,8 +294,8 @@ keyid_from_sk( PKT_secret_key *sk, u32 *keyid ) + if(md) + { + dp = md_read( md, 0 ); +- keyid[0] = dp[12] << 24 | dp[13] << 16 | dp[14] << 8 | dp[15] ; +- keyid[1] = dp[16] << 24 | dp[17] << 16 | dp[18] << 8 | dp[19] ; ++ keyid[0] = buf32_to_u32 (dp+12); ++ keyid[1] = buf32_to_u32 (dp+16); + lowbits = keyid[1]; + md_close(md); + sk->keyid[0] = keyid[0]; +@@ -354,8 +348,8 @@ keyid_from_pk( PKT_public_key *pk, u32 *keyid ) + if(md) + { + dp = md_read( md, 0 ); +- keyid[0] = dp[12] << 24 | dp[13] << 16 | dp[14] << 8 | dp[15] ; +- keyid[1] = dp[16] << 24 | dp[17] << 16 | dp[18] << 8 | dp[19] ; ++ keyid[0] = buf32_to_u32 (dp+12); ++ keyid[1] = buf32_to_u32 (dp+16); + lowbits = keyid[1]; + md_close(md); + pk->keyid[0] = keyid[0]; +@@ -398,8 +392,8 @@ keyid_from_fingerprint( const byte *fprint, size_t fprint_len, u32 *keyid ) + } + else { + const byte *dp = fprint; +- keyid[0] = dp[12] << 24 | dp[13] << 16 | dp[14] << 8 | dp[15] ; +- keyid[1] = dp[16] << 24 | dp[17] << 16 | dp[18] << 8 | dp[19] ; ++ keyid[0] = buf32_to_u32 (dp+12); ++ keyid[1] = buf32_to_u32 (dp+16); + } + + return keyid[1]; +@@ -687,8 +681,8 @@ fingerprint_from_pk( PKT_public_key *pk, byte *array, size_t *ret_len ) + if( !array ) + array = xmalloc( len ); + memcpy(array, dp, len ); +- pk->keyid[0] = dp[12] << 24 | dp[13] << 16 | dp[14] << 8 | dp[15] ; +- pk->keyid[1] = dp[16] << 24 | dp[17] << 16 | dp[18] << 8 | dp[19] ; ++ pk->keyid[0] = buf32_to_u32 (dp+12); ++ pk->keyid[1] = buf32_to_u32 (dp+16); + md_close(md); + } + +diff --git a/g10/misc.c b/g10/misc.c +index 60ecf96..2c5c6cc 100644 +--- a/g10/misc.c ++++ b/g10/misc.c +@@ -295,17 +295,6 @@ checksum_mpi( MPI a ) + return csum; + } + +-u32 +-buffer_to_u32( const byte *buffer ) +-{ +- unsigned long a; +- a = *buffer << 24; +- a |= buffer[1] << 16; +- a |= buffer[2] << 8; +- a |= buffer[3]; +- return a; +-} +- + void + print_pubkey_algo_note( int algo ) + { +diff --git a/g10/parse-packet.c b/g10/parse-packet.c +index e7e923b..862ec6e 100644 +--- a/g10/parse-packet.c ++++ b/g10/parse-packet.c +@@ -35,6 +35,7 @@ + #include "options.h" + #include "main.h" + #include "i18n.h" ++#include "host2net.h" + + #ifndef MAX_EXTERN_MPI_BITS + #define MAX_EXTERN_MPI_BITS 16384 +@@ -94,7 +95,7 @@ static unsigned short + read_16(IOBUF inp) + { + unsigned short a; +- a = iobuf_get_noeof(inp) << 8; ++ a = (unsigned short)iobuf_get_noeof(inp) << 8; + a |= iobuf_get_noeof(inp); + return a; + } +@@ -103,7 +104,7 @@ static unsigned long + read_32(IOBUF inp) + { + unsigned long a; +- a = iobuf_get_noeof(inp) << 24; ++ a = (unsigned long)iobuf_get_noeof(inp) << 24; + a |= iobuf_get_noeof(inp) << 16; + a |= iobuf_get_noeof(inp) << 8; + a |= iobuf_get_noeof(inp); +@@ -383,7 +384,8 @@ parse( IOBUF inp, PACKET *pkt, int onlykeypkts, off_t *retpos, + } + else if( c == 255 ) + { +- pktlen = (hdr[hdrlen++] = iobuf_get_noeof(inp)) << 24; ++ pktlen = ++ (unsigned long)(hdr[hdrlen++] = iobuf_get_noeof(inp)) << 24; + pktlen |= (hdr[hdrlen++] = iobuf_get_noeof(inp)) << 16; + pktlen |= (hdr[hdrlen++] = iobuf_get_noeof(inp)) << 8; + if( (c = iobuf_get(inp)) == -1 ) +@@ -878,14 +880,15 @@ dump_sig_subpkt( int hashed, int type, int critical, + switch( type ) { + case SIGSUBPKT_SIG_CREATED: + if( length >= 4 ) +- fprintf (listfp, "sig created %s", strtimestamp( buffer_to_u32(buffer) ) ); ++ fprintf (listfp, "sig created %s", ++ strtimestamp (buf32_to_u32(buffer)) ); + break; + case SIGSUBPKT_SIG_EXPIRE: + if( length >= 4 ) + { +- if(buffer_to_u32(buffer)) ++ if(buf32_to_u32(buffer)) + fprintf (listfp, "sig expires after %s", +- strtimevalue( buffer_to_u32(buffer) ) ); ++ strtimevalue( buf32_to_u32(buffer) ) ); + else + fprintf (listfp, "sig does not expire"); + } +@@ -918,9 +921,9 @@ dump_sig_subpkt( int hashed, int type, int critical, + case SIGSUBPKT_KEY_EXPIRE: + if( length >= 4 ) + { +- if(buffer_to_u32(buffer)) ++ if(buf32_to_u32(buffer)) + fprintf (listfp, "key expires after %s", +- strtimevalue( buffer_to_u32(buffer) ) ); ++ strtimevalue( buf32_to_u32(buffer) ) ); + else + fprintf (listfp, "key does not expire"); + } +@@ -943,8 +946,8 @@ dump_sig_subpkt( int hashed, int type, int critical, + case SIGSUBPKT_ISSUER: + if( length >= 8 ) + fprintf (listfp, "issuer key ID %08lX%08lX", +- (ulong)buffer_to_u32(buffer), +- (ulong)buffer_to_u32(buffer+4) ); ++ buf32_to_ulong (buffer), ++ buf32_to_ulong (buffer+4)); + break; + case SIGSUBPKT_NOTATION: + { +@@ -1192,8 +1195,7 @@ enum_sig_subpkt( const subpktarea_t *pktbuf, sigsubpkttype_t reqtype, + if( n == 255 ) { /* 4 byte length header */ + if( buflen < 4 ) + goto too_short; +- n = (buffer[0] << 24) | (buffer[1] << 16) +- | (buffer[2] << 8) | buffer[3]; ++ n = buf32_to_size_t (buffer); + buffer += 4; + buflen -= 4; + } +@@ -1415,7 +1417,7 @@ parse_signature( IOBUF inp, int pkttype, unsigned long pktlen, + + p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_SIG_CREATED, NULL ); + if(p) +- sig->timestamp = buffer_to_u32(p); ++ sig->timestamp = buf32_to_u32 (p); + else if(!(sig->pubkey_algo>=100 && sig->pubkey_algo<=110) + && opt.verbose) + log_info ("signature packet without timestamp\n"); +@@ -1423,16 +1425,16 @@ parse_signature( IOBUF inp, int pkttype, unsigned long pktlen, + p = parse_sig_subpkt2( sig, SIGSUBPKT_ISSUER, NULL ); + if(p) + { +- sig->keyid[0] = buffer_to_u32(p); +- sig->keyid[1] = buffer_to_u32(p+4); ++ sig->keyid[0] = buf32_to_u32 (p); ++ sig->keyid[1] = buf32_to_u32 (p+4); + } + else if(!(sig->pubkey_algo>=100 && sig->pubkey_algo<=110) + && opt.verbose) + log_info ("signature packet without keyid\n"); + + p=parse_sig_subpkt(sig->hashed,SIGSUBPKT_SIG_EXPIRE,NULL); +- if(p && buffer_to_u32(p)) +- sig->expiredate=sig->timestamp+buffer_to_u32(p); ++ if(p && buf32_to_u32 (p)) ++ sig->expiredate = sig->timestamp + buf32_to_u32 (p); + if(sig->expiredate && sig->expiredate<=make_timestamp()) + sig->flags.expired=1; + +@@ -2032,9 +2034,8 @@ parse_attribute_subpkts(PKT_user_id *uid) + if( n == 255 ) { /* 4 byte length header */ + if( buflen < 4 ) + goto too_short; +- n = (buffer[0] << 24) | (buffer[1] << 16) +- | (buffer[2] << 8) | buffer[3]; +- buffer += 4; ++ n = buf32_to_size_t (buffer); ++ buffer += 4; + buflen -= 4; + } + else if( n >= 192 ) { /* 2 byte special encoded length header */ +diff --git a/g10/tdbio.c b/g10/tdbio.c +index f109dde..403b608 100644 +--- a/g10/tdbio.c ++++ b/g10/tdbio.c +@@ -1219,13 +1219,13 @@ tdbio_read_record( ulong recnum, TRUSTREC *rec, int expected ) + rec->r.ver.trust_model = *p++; + rec->r.ver.min_cert_level = *p++; + p += 2; +- rec->r.ver.created = buftoulong(p); p += 4; +- rec->r.ver.nextcheck = buftoulong(p); p += 4; ++ rec->r.ver.created = buf32_to_ulong (p); p += 4; ++ rec->r.ver.nextcheck = buf32_to_ulong (p); p += 4; + p += 4; + p += 4; +- rec->r.ver.firstfree =buftoulong(p); p += 4; ++ rec->r.ver.firstfree =buf32_to_ulong (p); p += 4; + p += 4; +- rec->r.ver.trusthashtbl =buftoulong(p); p += 4; ++ rec->r.ver.trusthashtbl =buf32_to_ulong (p); p += 4; + if( recnum ) { + log_error( _("%s: version record with recnum %lu\n"), db_name, + (ulong)recnum ); +@@ -1238,17 +1238,17 @@ tdbio_read_record( ulong recnum, TRUSTREC *rec, int expected ) + } + break; + case RECTYPE_FREE: +- rec->r.free.next = buftoulong(p); p += 4; ++ rec->r.free.next = buf32_to_ulong (p); p += 4; + break; + case RECTYPE_HTBL: + for(i=0; i < ITEMS_PER_HTBL_RECORD; i++ ) { +- rec->r.htbl.item[i] = buftoulong(p); p += 4; ++ rec->r.htbl.item[i] = buf32_to_ulong (p); p += 4; + } + break; + case RECTYPE_HLST: +- rec->r.hlst.next = buftoulong(p); p += 4; ++ rec->r.hlst.next = buf32_to_ulong (p); p += 4; + for(i=0; i < ITEMS_PER_HLST_RECORD; i++ ) { +- rec->r.hlst.rnum[i] = buftoulong(p); p += 4; ++ rec->r.hlst.rnum[i] = buf32_to_ulong (p); p += 4; + } + break; + case RECTYPE_TRUST: +@@ -1257,12 +1257,12 @@ tdbio_read_record( ulong recnum, TRUSTREC *rec, int expected ) + rec->r.trust.depth = *p++; + rec->r.trust.min_ownertrust = *p++; + p++; +- rec->r.trust.validlist = buftoulong(p); p += 4; ++ rec->r.trust.validlist = buf32_to_ulong (p); p += 4; + break; + case RECTYPE_VALID: + memcpy( rec->r.valid.namehash, p, 20); p+=20; + rec->r.valid.validity = *p++; +- rec->r.valid.next = buftoulong(p); p += 4; ++ rec->r.valid.next = buf32_to_ulong (p); p += 4; + rec->r.valid.full_count = *p++; + rec->r.valid.marginal_count = *p++; + break; +@@ -1570,7 +1570,7 @@ migrate_from_v2 () + ottable_size += 1000; + ottable = xrealloc (ottable, ottable_size * sizeof *ottable); + } +- ottable[ottable_used].keyrecno = buftoulong (oldbuf+6); ++ ottable[ottable_used].keyrecno = buf32_to_ulong (oldbuf+6); + ottable[ottable_used].ot = oldbuf[18]; + ottable[ottable_used].okay = 0; + memset (ottable[ottable_used].fpr,0, 20); +diff --git a/g10/trustdb.c b/g10/trustdb.c +index a541106..e4317e2 100644 +--- a/g10/trustdb.c ++++ b/g10/trustdb.c +@@ -1624,7 +1624,7 @@ mark_usable_uid_certs (KBNODE keyblock, KBNODE uidnode, + u32 expire; + + p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_SIG_EXPIRE, NULL ); +- expire = p? sig->timestamp + buffer_to_u32(p) : 0; ++ expire = p? sig->timestamp + buf32_to_u32 (p) : 0; + + if (expire==0 || expire > curtime ) + { +diff --git a/include/host2net.h b/include/host2net.h +index fe0ec41..ecb00dc 100644 +--- a/include/host2net.h ++++ b/include/host2net.h +@@ -1,5 +1,5 @@ +-/* host2net.h - Some macros +- * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. ++/* host2net.h - Endian conversion macros ++ * Copyright (C) 1998, 2014, 2015 Werner Koch + * + * This file is part of GNUPG. + * +@@ -17,14 +17,11 @@ + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +-#ifndef G10_HOST2NET_H +-#define G10_HOST2NET_H ++#ifndef GNUPG_COMMON_HOST2NET_H ++#define GNUPG_COMMON_HOST2NET_H + + #include "types.h" + +-#define buftoulong( p ) ((*(byte*)(p) << 24) | (*((byte*)(p)+1)<< 16) | \ +- (*((byte*)(p)+2) << 8) | (*((byte*)(p)+3))) +-#define buftoushort( p ) ((*((byte*)(p)) << 8) | (*((byte*)(p)+1))) + #define ulongtobuf( p, a ) do { \ + ((byte*)p)[0] = a >> 24; \ + ((byte*)p)[1] = a >> 16; \ +@@ -35,8 +32,71 @@ + ((byte*)p)[0] = a >> 8; \ + ((byte*)p)[1] = a ; \ + } while(0) +-#define buftou32( p) buftoulong( (p) ) +-#define u32tobuf( p, a) ulongtobuf( (p), (a) ) + + +-#endif /*G10_HOST2NET_H*/ ++static inline unsigned long ++buf16_to_ulong (const void *buffer) ++{ ++ const unsigned char *p = buffer; ++ ++ return (((unsigned long)p[0] << 8) | p[1]); ++} ++ ++static inline unsigned int ++buf16_to_uint (const void *buffer) ++{ ++ const unsigned char *p = buffer; ++ ++ return (((unsigned int)p[0] << 8) | p[1]); ++} ++ ++static inline unsigned short ++buf16_to_ushort (const void *buffer) ++{ ++ const unsigned char *p = buffer; ++ ++ return (((unsigned short)p[0] << 8) | p[1]); ++} ++ ++static inline u16 ++buf16_to_u16 (const void *buffer) ++{ ++ const unsigned char *p = buffer; ++ ++ return (((u16)p[0] << 8) | p[1]); ++} ++ ++static inline size_t ++buf32_to_size_t (const void *buffer) ++{ ++ const unsigned char *p = buffer; ++ ++ return (((size_t)p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]); ++} ++ ++static inline unsigned long ++buf32_to_ulong (const void *buffer) ++{ ++ const unsigned char *p = buffer; ++ ++ return (((unsigned long)p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]); ++} ++ ++static inline unsigned int ++buf32_to_uint (const void *buffer) ++{ ++ const unsigned char *p = buffer; ++ ++ return (((unsigned int)p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]); ++} ++ ++static inline u32 ++buf32_to_u32 (const void *buffer) ++{ ++ const unsigned char *p = buffer; ++ ++ return (((u32)p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]); ++} ++ ++ ++#endif /*GNUPG_COMMON_HOST2NET_H*/ +-- +2.1.4 + diff -Nru gnupg-1.4.18/debian/patches/0039-curl-shim-clean-up-varargs.patch gnupg-1.4.18/debian/patches/0039-curl-shim-clean-up-varargs.patch --- gnupg-1.4.18/debian/patches/0039-curl-shim-clean-up-varargs.patch 1970-01-01 01:00:00.000000000 +0100 +++ gnupg-1.4.18/debian/patches/0039-curl-shim-clean-up-varargs.patch 2015-03-02 18:47:01.000000000 +0100 @@ -0,0 +1,40 @@ +From 2b2f2767851eccb12e591c7a3fa432e6bf9db8f2 Mon Sep 17 00:00:00 2001 +From: Daniel Kahn Gillmor <d...@fifthhorseman.net> +Date: Sat, 21 Feb 2015 23:10:35 -0500 +Subject: [PATCH 39/45] curl-shim: clean up varargs + +* keyserver/curl-shim.c (curl_easy_setopt) : ensure that va_end is + called. + +-- + +stdarg(3) says: + Each invocation of va_start() must be matched by a + corresponding invocation of va_end() in the same function. + +Observed by Joshua Rogers <ho...@internot.info> + +Debian-Bug-Id: #773475 + +[dkg: rebased to STABLE-BRANCH-1-4] +Signed-off-by: Daniel Kahn Gillmor <d...@fifthhorseman.net> +--- + keyserver/curl-shim.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/keyserver/curl-shim.c b/keyserver/curl-shim.c +index ce510cb..72c0f04 100644 +--- a/keyserver/curl-shim.c ++++ b/keyserver/curl-shim.c +@@ -155,6 +155,8 @@ curl_easy_setopt(CURL *curl,CURLoption option,...) + break; + } + ++ va_end(ap); ++ + return handle_error(curl,CURLE_OK,NULL); + } + +-- +2.1.4 + diff -Nru gnupg-1.4.18/debian/patches/0041-gpg-Fix-segv-due-to-NULL-value-stored-as-opaque-MPI.patch gnupg-1.4.18/debian/patches/0041-gpg-Fix-segv-due-to-NULL-value-stored-as-opaque-MPI.patch --- gnupg-1.4.18/debian/patches/0041-gpg-Fix-segv-due-to-NULL-value-stored-as-opaque-MPI.patch 1970-01-01 01:00:00.000000000 +0100 +++ gnupg-1.4.18/debian/patches/0041-gpg-Fix-segv-due-to-NULL-value-stored-as-opaque-MPI.patch 2015-03-02 18:47:01.000000000 +0100 @@ -0,0 +1,89 @@ +From 6f032181ba78c5eeb14f9aab4307a75bbaf0b115 Mon Sep 17 00:00:00 2001 +From: Daniel Kahn Gillmor <d...@fifthhorseman.net> +Date: Sat, 21 Feb 2015 23:10:37 -0500 +Subject: [PATCH 41/45] gpg: Fix segv due to NULL value stored as opaque MPI + +* g10/build-packet.c (do_secret_key): Check for NULL return from +gcry_mpi_get_opaque. +* g10/keyid.c (hash_public_key): Ditto. +-- + +This is a backport of 76c8122adfed0f0f443cce7bda702ba2b39661b3 from +master to the STABLE-BRANCH-1-4 + +On the STABLE-BRANCH-1-4, we may also want to patch g10/seckey-cert.c, +but that has not been done in this patch. + +This fix extends commmit 0835d2f44ef62eab51fce6a927908f544e01cf8f. + + gpg2 --export --no-default-keyring --keyring TESTDATA + +With TESTDATA being below after unpacking. + +-----BEGIN PGP ARMORED FILE----- + +mBMEhdkMmS8BcX8F//8F5voEhQAQmBMEnAAAZwAAo4D/f/8EhQAAAIAEnP8EhQAQ +iBMEnP8AAAAABf8jIID///8EhQYQmBMEnIUAEIgTBKT/AAAAAAUAACCA/f//BIUA +EJgTBJx/AP8ABPPzBJx/AP8ABPPz +=2yE0 +-----END PGP ARMORED FILE----- + +Reported-by: Jodie Cunningham +[dkg: rebased to STABLE-BRANCH-1-4] +Signed-off-by: Daniel Kahn Gillmor <d...@fifthhorseman.net> +--- + g10/build-packet.c | 6 ++++-- + g10/keyid.c | 8 ++++++-- + 2 files changed, 10 insertions(+), 4 deletions(-) + +diff --git a/g10/build-packet.c b/g10/build-packet.c +index 60eb3c8..028d064 100644 +--- a/g10/build-packet.c ++++ b/g10/build-packet.c +@@ -356,7 +356,8 @@ do_secret_key( IOBUF out, int ctb, PKT_secret_key *sk ) + + assert( mpi_is_opaque( sk->skey[npkey] ) ); + p = mpi_get_opaque( sk->skey[npkey], &ndata ); +- iobuf_write(a, p, ndata ); ++ if (p) ++ iobuf_write(a, p, ndata ); + } + else if( sk->is_protected ) { + /* The secret key is protected te old v4 way. */ +@@ -366,7 +367,8 @@ do_secret_key( IOBUF out, int ctb, PKT_secret_key *sk ) + + assert (mpi_is_opaque (sk->skey[i])); + p = mpi_get_opaque (sk->skey[i], &ndata); +- iobuf_write (a, p, ndata); ++ if (p) ++ iobuf_write (a, p, ndata); + } + write_16(a, sk->csum ); + } +diff --git a/g10/keyid.c b/g10/keyid.c +index ed30cff..a86ac94 100644 +--- a/g10/keyid.c ++++ b/g10/keyid.c +@@ -112,13 +112,17 @@ hash_public_key( MD_HANDLE md, PKT_public_key *pk ) + md_putc( md, pk->pubkey_algo ); + + if(npkey==0 && pk->pkey[0] && mpi_is_opaque(pk->pkey[0])) +- md_write(md,pp[0],nn[0]); ++ { ++ if (pp[0]) ++ md_write(md,pp[0],nn[0]); ++ } + else + for(i=0; i < npkey; i++ ) + { + md_putc( md, nb[i]>>8); + md_putc( md, nb[i] ); +- md_write( md, pp[i], nn[i] ); ++ if (pp[i]) ++ md_write( md, pp[i], nn[i] ); + xfree(pp[i]); + } + } +-- +2.1.4 + diff -Nru gnupg-1.4.18/debian/patches/0042-Protect-against-NULL-return-of-mpi_get_opaque.patch gnupg-1.4.18/debian/patches/0042-Protect-against-NULL-return-of-mpi_get_opaque.patch --- gnupg-1.4.18/debian/patches/0042-Protect-against-NULL-return-of-mpi_get_opaque.patch 1970-01-01 01:00:00.000000000 +0100 +++ gnupg-1.4.18/debian/patches/0042-Protect-against-NULL-return-of-mpi_get_opaque.patch 2015-03-02 18:47:01.000000000 +0100 @@ -0,0 +1,55 @@ +From e0c13ad5f290aec05706797b8f6c9e13d613eb66 Mon Sep 17 00:00:00 2001 +From: Werner Koch <w...@gnupg.org> +Date: Mon, 23 Feb 2015 11:04:35 +0100 +Subject: [PATCH 42/45] Protect against NULL return of mpi_get_opaque. + +* g10/seckey-cert.c (do_check): Call BUG for NULL return of +get_opaque. +-- + +This is the suggested addition from commit 6f03218. We better run +into an fatal error than into a segv. + +Signed-off-by: Werner Koch <w...@gnupg.org> +--- + g10/seckey-cert.c | 17 ++++++++++++----- + 1 file changed, 12 insertions(+), 5 deletions(-) + +diff --git a/g10/seckey-cert.c b/g10/seckey-cert.c +index cad4e63..4edd74e 100644 +--- a/g10/seckey-cert.c ++++ b/g10/seckey-cert.c +@@ -91,8 +91,12 @@ do_check( PKT_secret_key *sk, const char *tryagain_text, int mode, + u16 csumc = 0; + + i = pubkey_get_npkey(sk->pubkey_algo); +- assert( mpi_is_opaque( sk->skey[i] ) ); +- p = mpi_get_opaque( sk->skey[i], &ndata ); ++ if (!mpi_is_opaque (sk->skey[i])) ++ p = NULL; ++ else ++ p = mpi_get_opaque (sk->skey[i], &ndata); ++ if (!p) ++ BUG (); + if ( ndata > 1 ) + csumc = p[ndata-2] << 8 | p[ndata-1]; + data = xmalloc_secure( ndata ); +@@ -169,9 +173,12 @@ do_check( PKT_secret_key *sk, const char *tryagain_text, int mode, + byte *p; + unsigned int ndata; + +- assert (mpi_is_opaque (sk->skey[i])); +- p = mpi_get_opaque (sk->skey[i], &ndata); +- assert (ndata >= 2); ++ if (!mpi_is_opaque (sk->skey[i])) ++ p = NULL; ++ else ++ p = mpi_get_opaque (sk->skey[i], &ndata); ++ if (!p || !(ndata >= 2)) ++ BUG (); + assert (ndata == ((p[0] << 8 | p[1]) + 7)/8 + 2); + buffer = xmalloc_secure (ndata); + cipher_sync (cipher_hd); +-- +2.1.4 + diff -Nru gnupg-1.4.18/debian/patches/0043-doc-Add-warning-note-about-not-acting-as-an-oracle-t.patch gnupg-1.4.18/debian/patches/0043-doc-Add-warning-note-about-not-acting-as-an-oracle-t.patch --- gnupg-1.4.18/debian/patches/0043-doc-Add-warning-note-about-not-acting-as-an-oracle-t.patch 1970-01-01 01:00:00.000000000 +0100 +++ gnupg-1.4.18/debian/patches/0043-doc-Add-warning-note-about-not-acting-as-an-oracle-t.patch 2015-03-02 18:47:01.000000000 +0100 @@ -0,0 +1,48 @@ +From 6186637cc9a4cbe4964ae0ca2aa00ed1738fc6a4 Mon Sep 17 00:00:00 2001 +From: Werner Koch <w...@gnupg.org> +Date: Mon, 23 Feb 2015 13:10:57 +0100 +Subject: [PATCH 43/45] doc: Add warning note about not acting as an oracle to + --batch. + +-- +--- + doc/gpg.texi | 23 +++++++++++++++++------ + 1 file changed, 17 insertions(+), 6 deletions(-) + +diff --git a/doc/gpg.texi b/doc/gpg.texi +index 67dc3d0..d311732 100644 +--- a/doc/gpg.texi ++++ b/doc/gpg.texi +@@ -949,12 +949,23 @@ Try to be as quiet as possible. + @opindex batch + @opindex no-batch + Use batch mode. Never ask, do not allow interactive commands. +-@option{--no-batch} disables this option. Note that even with a +-filename given on the command line, gpg might still need to read from +-STDIN (in particular if gpg figures that the input is a +-detached signature and no data file has been specified). Thus if you +-do not want to feed data via STDIN, you should connect STDIN to +-@file{/dev/null}. ++@option{--no-batch} disables this option. This option is commonly ++used for unattended operations. ++ ++WARNING: Unattended operation bears a higher risk of being exposed to ++security attacks. In particular any unattended use of GnuPG which ++involves the use of secret keys should take care not to provide an ++decryption oracle. There are several standard pre-cautions against ++being used as an oracle. For example never return detailed error ++messages or any diagnostics printed by your software to the remote ++site. Consult with an expert in case of doubt. ++ ++Note that even with a filename given on the command line, gpg might ++still need to read from STDIN (in particular if gpg figures that the ++input is a detached signature and no data file has been specified). ++Thus if you do not want to feed data via STDIN, you should connect ++STDIN to @file{/dev/null}. ++ + + @item --no-tty + @opindex no-tty +-- +2.1.4 + diff -Nru gnupg-1.4.18/debian/patches/0044-mpi-Avoid-data-dependent-timing-variations-in-mpi_po.patch gnupg-1.4.18/debian/patches/0044-mpi-Avoid-data-dependent-timing-variations-in-mpi_po.patch --- gnupg-1.4.18/debian/patches/0044-mpi-Avoid-data-dependent-timing-variations-in-mpi_po.patch 1970-01-01 01:00:00.000000000 +0100 +++ gnupg-1.4.18/debian/patches/0044-mpi-Avoid-data-dependent-timing-variations-in-mpi_po.patch 2015-03-02 18:47:01.000000000 +0100 @@ -0,0 +1,237 @@ +From 6cbc75e71295f23431c4ab95edc7573f2fc28476 Mon Sep 17 00:00:00 2001 +From: NIIBE Yutaka <gni...@fsij.org> +Date: Thu, 26 Feb 2015 21:00:05 +0900 +Subject: [PATCH 44/45] mpi: Avoid data-dependent timing variations in + mpi_powm. + +* include/mpi.h, mpi/mpiutils.c (mpi_set_cond): New. +* mpi/mpi-pow.c (SIZE_PRECOMP): Rename from SIZE_B_2I3. +(mpi_powm): Access all data in the table and use mpi_set_cond. + +-- + +Access to the precomputed table was indexed by a portion of EXPO, +which could be mounted by a side channel attack. This change fixes +this particular data-dependent access pattern. +--- + include/mpi.h | 1 + + mpi/mpi-pow.c | 93 ++++++++++++++++++++++++++++++++++------------------------- + mpi/mpiutil.c | 28 ++++++++++++++++++ + 3 files changed, 82 insertions(+), 40 deletions(-) + +diff --git a/include/mpi.h b/include/mpi.h +index a027d2a..a4c16f5 100644 +--- a/include/mpi.h ++++ b/include/mpi.h +@@ -81,6 +81,7 @@ void *mpi_get_opaque( MPI a, unsigned int *len ); + void mpi_set_secure( MPI a ); + void mpi_clear( MPI a ); + void mpi_set( MPI w, MPI u); ++void mpi_set_cond( MPI w, MPI u, unsigned long set); + void mpi_set_ui( MPI w, ulong u); + MPI mpi_alloc_set_ui( unsigned long u); + void mpi_m_check( MPI a ); +diff --git a/mpi/mpi-pow.c b/mpi/mpi-pow.c +index 1c3fadb..7f23a5a 100644 +--- a/mpi/mpi-pow.c ++++ b/mpi/mpi-pow.c +@@ -344,7 +344,7 @@ mul_mod (mpi_ptr_t xp, mpi_size_t *xsize_p, + *xsize_p = rsize + ssize; + } + +-#define SIZE_B_2I3 ((1 << (5 - 1)) - 1) ++#define SIZE_PRECOMP ((1 << (5 - 1))) + + /**************** + * RES = BASE ^ EXPO mod MOD +@@ -375,11 +375,12 @@ mpi_powm (MPI res, MPI base, MPI expo, MPI mod) + mpi_ptr_t bp_marker = NULL; + mpi_ptr_t ep_marker = NULL; + mpi_ptr_t xp_marker = NULL; +- mpi_ptr_t b_2i3[SIZE_B_2I3]; /* Pre-computed array: BASE^3, ^5, ^7, ... */ +- mpi_size_t b_2i3size[SIZE_B_2I3]; ++ mpi_ptr_t precomp[SIZE_PRECOMP]; /* Pre-computed array: BASE^1, ^3, ^5, ... */ ++ mpi_size_t precomp_size[SIZE_PRECOMP]; + mpi_size_t W; + mpi_ptr_t base_u; + mpi_size_t base_u_size; ++ mpi_size_t max_u_size; + + esize = expo->nlimbs; + msize = mod->nlimbs; +@@ -493,7 +494,7 @@ mpi_powm (MPI res, MPI base, MPI expo, MPI mod) + + /* Main processing. */ + { +- mpi_size_t i, j; ++ mpi_size_t i, j, k; + mpi_ptr_t xp; + mpi_size_t xsize; + int c; +@@ -507,33 +508,29 @@ mpi_powm (MPI res, MPI base, MPI expo, MPI mod) + memset( &karactx, 0, sizeof karactx ); + negative_result = (ep[0] & 1) && bsign; + +- /* Precompute B_2I3[], BASE^(2 * i + 3), BASE^3, ^5, ^7, ... */ ++ /* Precompute PRECOMP[], BASE^(2 * i + 1), BASE^1, ^3, ^5, ... */ + if (W > 1) /* X := BASE^2 */ + mul_mod (xp, &xsize, bp, bsize, bp, bsize, mp, msize, &karactx); +- for (i = 0; i < (1 << (W - 1)) - 1; i++) +- { /* B_2I3[i] = BASE^(2 * i + 3) */ +- if (i == 0) +- { +- base_u = bp; +- base_u_size = bsize; +- } +- else +- { +- base_u = b_2i3[i-1]; +- base_u_size = b_2i3size[i-1]; +- } +- ++ base_u = precomp[0] = mpi_alloc_limb_space (bsize, esec); ++ base_u_size = max_u_size = precomp_size[0] = bsize; ++ MPN_COPY (precomp[0], bp, bsize); ++ for (i = 1; i < (1 << (W - 1)); i++) ++ { /* PRECOMP[i] = BASE^(2 * i + 1) */ + if (xsize >= base_u_size) + mul_mod (rp, &rsize, xp, xsize, base_u, base_u_size, + mp, msize, &karactx); + else + mul_mod (rp, &rsize, base_u, base_u_size, xp, xsize, + mp, msize, &karactx); +- b_2i3[i] = mpi_alloc_limb_space (rsize, esec); +- b_2i3size[i] = rsize; +- MPN_COPY (b_2i3[i], rp, rsize); ++ base_u = precomp[i] = mpi_alloc_limb_space (rsize, esec); ++ base_u_size = precomp_size[i] = rsize; ++ if (max_u_size < base_u_size) ++ max_u_size = base_u_size; ++ MPN_COPY (precomp[i], rp, rsize); + } + ++ base_u = mpi_alloc_limb_space (max_u_size, esec); ++ + i = esize - 1; + + /* Main loop. +@@ -619,17 +616,26 @@ mpi_powm (MPI res, MPI base, MPI expo, MPI mod) + rsize = xsize; + } + +- if (e0 == 0) ++ /* ++ * base_u <= precomp[e0] ++ * base_u_size <= precomp_size[e0]; ++ */ ++ base_u_size = 0; ++ for (k = 0; k < (1<< (W - 1)); k++) + { +- base_u = bp; +- base_u_size = bsize; ++ struct gcry_mpi w, u; ++ w.alloced = w.nlimbs = precomp_size[k]; ++ u.alloced = u.nlimbs = precomp_size[k]; ++ w.nbits = w.nlimbs * BITS_PER_MPI_LIMB; ++ u.nbits = u.nlimbs * BITS_PER_MPI_LIMB; ++ w.sign = u.sign = 0; ++ w.flags = u.flags = 0; ++ w.d = base_u; ++ u.d = precomp[k]; ++ ++ mpi_set_cond (&w, &u, k == e0); ++ base_u_size |= (precomp_size[k] & ((mpi_size_t)0 - (k == e0)) ); + } +- else +- { +- base_u = b_2i3[e0 - 1]; +- base_u_size = b_2i3size[e0 -1]; +- } +- + mul_mod (xp, &xsize, rp, rsize, base_u, base_u_size, + mp, msize, &karactx); + tp = rp; rp = xp; xp = tp; +@@ -655,15 +661,21 @@ mpi_powm (MPI res, MPI base, MPI expo, MPI mod) + + if (e != 0) + { +- if ((e>>1) == 0) +- { +- base_u = bp; +- base_u_size = bsize; +- } +- else ++ base_u_size = 0; ++ for (k = 0; k < (1<< (W - 1)); k++) + { +- base_u = b_2i3[(e>>1) - 1]; +- base_u_size = b_2i3size[(e>>1) -1]; ++ struct gcry_mpi w, u; ++ w.alloced = w.nlimbs = precomp_size[k]; ++ u.alloced = u.nlimbs = precomp_size[k]; ++ w.nbits = w.nlimbs * BITS_PER_MPI_LIMB; ++ u.nbits = u.nlimbs * BITS_PER_MPI_LIMB; ++ w.sign = u.sign = 0; ++ w.flags = u.flags = 0; ++ w.d = base_u; ++ u.d = precomp[k]; ++ ++ mpi_set_cond (&w, &u, k == (e>>1)); ++ base_u_size |= (precomp_size[k] & ((mpi_size_t)0 - (k == (e>>1))) ); + } + + mul_mod (xp, &xsize, rp, rsize, base_u, base_u_size, +@@ -713,8 +725,9 @@ mpi_powm (MPI res, MPI base, MPI expo, MPI mod) + MPN_NORMALIZE (rp, rsize); + + mpihelp_release_karatsuba_ctx (&karactx ); +- for (i = 0; i < (1 << (W - 1)) - 1; i++) +- mpi_free_limb_space (b_2i3[i]); ++ for (i = 0; i < (1 << (W - 1)); i++) ++ mpi_free_limb_space (precomp[i]); ++ mpi_free_limb_space (base_u); + } + + /* Fixup for negative results. */ +diff --git a/mpi/mpiutil.c b/mpi/mpiutil.c +index 3a1d71f..8b2071a 100644 +--- a/mpi/mpiutil.c ++++ b/mpi/mpiutil.c +@@ -433,6 +433,34 @@ mpi_set( MPI w, MPI u) + + + void ++mpi_set_cond( MPI w, MPI u, unsigned long set) ++{ ++ mpi_size_t i; ++ mpi_size_t nlimbs = u->alloced; ++ mpi_limb_t mask = ((mpi_limb_t)0) - !!set; ++ mpi_limb_t x; ++ ++ if (w->alloced != u->alloced) ++ log_bug ("mpi_set_cond: different sizes\n"); ++ ++ for (i = 0; i < nlimbs; i++) ++ { ++ x = mask & (w->d[i] ^ u->d[i]); ++ w->d[i] = w->d[i] ^ x; ++ } ++ ++ x = mask & (w->nlimbs ^ u->nlimbs); ++ w->nlimbs = w->nlimbs ^ x; ++ ++ x = mask & (w->nbits ^ u->nbits); ++ w->nbits = w->nbits ^ x; ++ ++ x = mask & (w->sign ^ u->sign); ++ w->sign = w->sign ^ x; ++} ++ ++ ++void + mpi_set_ui( MPI w, unsigned long u) + { + RESIZE_IF_NEEDED(w, 1); +-- +2.1.4 + diff -Nru gnupg-1.4.18/debian/patches/series gnupg-1.4.18/debian/patches/series --- gnupg-1.4.18/debian/patches/series 2014-12-04 21:55:41.000000000 +0100 +++ gnupg-1.4.18/debian/patches/series 2015-03-02 19:25:14.000000000 +0100 @@ -19,3 +19,21 @@ 0018-gpg-Fix-use-of-uninit.value-in-listing-sig-subpkts.patch 0015-gpg-Make-the-use-of-verify-FILE-for-detached-sigs-ha.patch sync-docs-with-upstream.patch +0019-gpg-release-DEK-soon-after-its-use.patch +0020-scd-fix-get_public_key-for-OpenPGPcard-v1.0.patch +0021-scd-Fix-possibly-inhibited-checkpin-of-the-admin-pin.patch +0022-gpg-Fix-possible-read-of-unallocated-memory.patch +0023-doc-Fix-memory-leak-in-yat2m.patch +0024-avoid-future-chance-of-using-uninitialized-memory.patch +0029-Use-ciphertext-blinding-for-Elgamal-decryption.patch +0032-gpg-Limit-the-size-of-key-packets-to-a-sensible-valu.patch +0033-gpg-Fix-a-NULL-deref-due-to-empty-ring-trust-packets.patch +0034-gpg-Fix-a-NULL-deref-in-export-due-to-invalid-packet.patch +0035-gpg-Prevent-an-invalid-memory-read-using-a-garbled-k.patch +0036-doc-Change-remaining-http-links-to-gnupg.org-to-http.patch +0037-Use-inline-functions-to-convert-buffer-data-to-scala.patch +0039-curl-shim-clean-up-varargs.patch +0041-gpg-Fix-segv-due-to-NULL-value-stored-as-opaque-MPI.patch +0042-Protect-against-NULL-return-of-mpi_get_opaque.patch +0043-doc-Add-warning-note-about-not-acting-as-an-oracle-t.patch +0044-mpi-Avoid-data-dependent-timing-variations-in-mpi_po.patch -- System Information: Debian Release: 8.0 APT prefers unstable APT policy: (500, 'unstable') Architecture: amd64 (x86_64) Foreign Architectures: i386 Kernel: Linux 3.16.0-4-amd64 (SMP w/2 CPU cores) Locale: LANG=de_DE.UTF-8, LC_CTYPE=de_DE.UTF-8 (charmap=UTF-8) Shell: /bin/sh linked to /bin/dash Init: systemd (via /run/systemd/system) -- To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org