Attached is my current diff for python3.4 in Jessie.

It attempts to fix all security vulnerabilities except:

* CVE-2013-1753
* CVE-2014-9365

As these look invasive, not easy to fix, and where not fixed in Wheezy
either.

The patch for CVE-2018-14647 seems to break compiling. It references a
symbol that was not defined. Considering dropping this patch.

../Modules/_elementtree.c:3244:32: error: 'PyObject' has no member named 
'parser'
         EXPAT(SetHashSalt)(self->parser,

Unfortunately, failing tests do not fail the build. I see a number of
test failures after applying the patches, but I strongly suspect these
failures would also be occuring without applying the patch - as many
look unrelated to the changes I made.

Some tests also appear require networking, as they retrieve remote
files.

It might be worth doing a build with and without these patches and
comparing the diff, in attempt to see if it causes any new tests failed.
-- 
Brian May <b...@debian.org>
diff -u python3.4-3.4.2/debian/changelog python3.4-3.4.2/debian/changelog
--- python3.4-3.4.2/debian/changelog
+++ python3.4-3.4.2/debian/changelog
@@ -1,3 +1,18 @@
+python3.4 (3.4.2-1+deb8u2) UNRELEASED; urgency=high
+
+  * Non-maintainer upload by the LTS Team.
+  * CVE-2016-0772: Check for StartTLS failure.
+  * CVE-2016-5636: Fix integer overflow in the get_data.
+  * CVE-2016-5699: Fix CRLF injection vulnerability in the
+    HTTPConnection.putheader function in urllib2 and urllib.
+  * CVE-2018-14647: Fix Python's elementtree C accelerator failed to
+    initialise Expat's hash salt during initialization.
+  * CVE-2018-20406: Fix Modules/_pickle.c integer overflow.
+  * CVE-2019-5010: Fix NULL pointer dereference using a specially crafted X509
+    certificate.
+
+ -- Brian May <b...@debian.org>  Thu, 10 Jan 2019 17:43:03 +1100
+
 python3.4 (3.4.2-1+deb8u1) jessie-security; urgency=medium
 
   * Non-maintainer upload by the LTS Security Team.
diff -u python3.4-3.4.2/debian/patches/series.in python3.4-3.4.2/debian/patches/series.in
--- python3.4-3.4.2/debian/patches/series.in
+++ python3.4-3.4.2/debian/patches/series.in
@@ -49,0 +50,6 @@
+CVE-2016-0772.patch
+CVE-2016-5636.patch
+CVE-2016-5699.patch
+CVE-2018-14647.patch
+CVE-2018-20406.patch
+CVE-2019-5010.patch
only in patch2:
unchanged:
--- python3.4-3.4.2.orig/debian/patches/CVE-2016-0772.patch
+++ python3.4-3.4.2/debian/patches/CVE-2016-0772.patch
@@ -0,0 +1,22 @@
+
+# HG changeset patch
+# User Benjamin Peterson <benja...@python.org>
+# Date 1465676202 25200
+# Node ID d590114c23940c41f558216f92f9c084d32aa688
+# Parent  90e58a77d386e658b76fd097e8a5efb48e7421e4
+raise an error when STARTTLS fails
+
+--- a/Lib/smtplib.py
++++ b/Lib/smtplib.py
+@@ -696,6 +696,11 @@
+             self.ehlo_resp = None
+             self.esmtp_features = {}
+             self.does_esmtp = 0
++        else:
++            # RFC 3207:
++            # 501 Syntax error (no parameters allowed)
++            # 454 TLS not available due to temporary reason
++            raise SMTPResponseException(resp, reply)
+         return (resp, reply)
+ 
+     def sendmail(self, from_addr, to_addrs, msg, mail_options=[],
only in patch2:
unchanged:
--- python3.4-3.4.2.orig/debian/patches/CVE-2016-5636.patch
+++ python3.4-3.4.2/debian/patches/CVE-2016-5636.patch
@@ -0,0 +1,34 @@
+
+# HG changeset patch
+# User Benjamin Peterson <benja...@python.org>
+# Date 1453357424 28800
+# Node ID 01ddd608b85c85952537d95a43bbabf4fb655057
+# Parent  eb19459ce46a197d160540d4c05f97b8eb780e2e
+prevent buffer overflow in get_data (closes #26171)
+
+--- a/Misc/NEWS
++++ b/Misc/NEWS
+@@ -71,6 +71,9 @@
+ Core and Builtins
+ -----------------
+ 
++- Issue #26171: Fix possible integer overflow and heap corruption in
++  zipimporter.get_data().
++
+ Library
+ -------
+ 
+--- a/Modules/zipimport.c
++++ b/Modules/zipimport.c
+@@ -1111,6 +1111,11 @@
+     }
+     file_offset += l;           /* Start of file data */
+ 
++    if (data_size > LONG_MAX - 1) {
++        fclose(fp);
++        PyErr_NoMemory();
++        return NULL;
++    }
+     bytes_size = compress == 0 ? data_size : data_size + 1;
+     if (bytes_size == 0)
+         bytes_size++;
only in patch2:
unchanged:
--- python3.4-3.4.2.orig/debian/patches/CVE-2016-5699.patch
+++ python3.4-3.4.2/debian/patches/CVE-2016-5699.patch
@@ -0,0 +1,148 @@
+
+# HG changeset patch
+# User Serhiy Storchaka <storch...@gmail.com>
+# Date 1426151616 -7200
+# Node ID bf3e1c9b80e995311ba932e42200f076e03034c0
+# Parent  2b4a04c3681b1210529eb8a224cc007a0b92a890
+Issue #22928: Disabled HTTP header injections in http.client.
+Original patch by Demian Brecht.
+
+--- a/Lib/http/client.py
++++ b/Lib/http/client.py
+@@ -70,6 +70,7 @@
+ import email.message
+ import io
+ import os
++import re
+ import socket
+ import collections
+ from urllib.parse import urlsplit
+@@ -215,6 +216,34 @@
+ _MAXLINE = 65536
+ _MAXHEADERS = 100
+ 
++# Header name/value ABNF (http://tools.ietf.org/html/rfc7230#section-3.2)
++#
++# VCHAR          = %x21-7E
++# obs-text       = %x80-FF
++# header-field   = field-name ":" OWS field-value OWS
++# field-name     = token
++# field-value    = *( field-content / obs-fold )
++# field-content  = field-vchar [ 1*( SP / HTAB ) field-vchar ]
++# field-vchar    = VCHAR / obs-text
++#
++# obs-fold       = CRLF 1*( SP / HTAB )
++#                ; obsolete line folding
++#                ; see Section 3.2.4
++
++# token          = 1*tchar
++#
++# tchar          = "!" / "#" / "$" / "%" / "&" / "'" / "*"
++#                / "+" / "-" / "." / "^" / "_" / "`" / "|" / "~"
++#                / DIGIT / ALPHA
++#                ; any VCHAR, except delimiters
++#
++# VCHAR defined in http://tools.ietf.org/html/rfc5234#appendix-B.1
++
++# the patterns for both name and value are more leniant than RFC
++# definitions to allow for backwards compatibility
++_is_legal_header_name = re.compile(rb'[^:\s][^:\r\n]*').fullmatch
++_is_illegal_header_value = re.compile(rb'\n(?![ \t])|\r(?![ \t\n])').search
++
+ 
+ class HTTPMessage(email.message.Message):
+     # XXX The only usage of this method is in
+@@ -1060,12 +1089,20 @@
+ 
+         if hasattr(header, 'encode'):
+             header = header.encode('ascii')
++
++        if not _is_legal_header_name(header):
++            raise ValueError('Invalid header name %r' % (header,))
++
+         values = list(values)
+         for i, one_value in enumerate(values):
+             if hasattr(one_value, 'encode'):
+                 values[i] = one_value.encode('latin-1')
+             elif isinstance(one_value, int):
+                 values[i] = str(one_value).encode('ascii')
++
++            if _is_illegal_header_value(values[i]):
++                raise ValueError('Invalid header value %r' % (values[i],))
++
+         value = b'\r\n\t'.join(values)
+         header = header + b': ' + value
+         self._output(header)
+--- a/Lib/test/test_httplib.py
++++ b/Lib/test/test_httplib.py
+@@ -141,6 +141,33 @@
+         conn.putheader('Content-length', 42)
+         self.assertIn(b'Content-length: 42', conn._buffer)
+ 
++        conn.putheader('Foo', ' bar ')
++        self.assertIn(b'Foo:  bar ', conn._buffer)
++        conn.putheader('Bar', '\tbaz\t')
++        self.assertIn(b'Bar: \tbaz\t', conn._buffer)
++        conn.putheader('Authorization', 'Bearer mytoken')
++        self.assertIn(b'Authorization: Bearer mytoken', conn._buffer)
++        conn.putheader('IterHeader', 'IterA', 'IterB')
++        self.assertIn(b'IterHeader: IterA\r\n\tIterB', conn._buffer)
++        conn.putheader('LatinHeader', b'\xFF')
++        self.assertIn(b'LatinHeader: \xFF', conn._buffer)
++        conn.putheader('Utf8Header', b'\xc3\x80')
++        self.assertIn(b'Utf8Header: \xc3\x80', conn._buffer)
++        conn.putheader('C1-Control', b'next\x85line')
++        self.assertIn(b'C1-Control: next\x85line', conn._buffer)
++        conn.putheader('Embedded-Fold-Space', 'is\r\n allowed')
++        self.assertIn(b'Embedded-Fold-Space: is\r\n allowed', conn._buffer)
++        conn.putheader('Embedded-Fold-Tab', 'is\r\n\tallowed')
++        self.assertIn(b'Embedded-Fold-Tab: is\r\n\tallowed', conn._buffer)
++        conn.putheader('Key Space', 'value')
++        self.assertIn(b'Key Space: value', conn._buffer)
++        conn.putheader('KeySpace ', 'value')
++        self.assertIn(b'KeySpace : value', conn._buffer)
++        conn.putheader(b'Nonbreak\xa0Space', 'value')
++        self.assertIn(b'Nonbreak\xa0Space: value', conn._buffer)
++        conn.putheader(b'\xa0NonbreakSpace', 'value')
++        self.assertIn(b'\xa0NonbreakSpace: value', conn._buffer)
++
+     def test_ipv6host_header(self):
+         # Default host header on IPv6 transaction should wrapped by [] if
+         # its actual IPv6 address
+@@ -160,6 +187,36 @@
+         conn.request('GET', '/foo')
+         self.assertTrue(sock.data.startswith(expected))
+ 
++    def test_invalid_headers(self):
++        conn = client.HTTPConnection('example.com')
++        conn.sock = FakeSocket('')
++        conn.putrequest('GET', '/')
++
++        # http://tools.ietf.org/html/rfc7230#section-3.2.4, whitespace is no
++        # longer allowed in header names
++        cases = (
++            (b'Invalid\r\nName', b'ValidValue'),
++            (b'Invalid\rName', b'ValidValue'),
++            (b'Invalid\nName', b'ValidValue'),
++            (b'\r\nInvalidName', b'ValidValue'),
++            (b'\rInvalidName', b'ValidValue'),
++            (b'\nInvalidName', b'ValidValue'),
++            (b' InvalidName', b'ValidValue'),
++            (b'\tInvalidName', b'ValidValue'),
++            (b'Invalid:Name', b'ValidValue'),
++            (b':InvalidName', b'ValidValue'),
++            (b'ValidName', b'Invalid\r\nValue'),
++            (b'ValidName', b'Invalid\rValue'),
++            (b'ValidName', b'Invalid\nValue'),
++            (b'ValidName', b'InvalidValue\r\n'),
++            (b'ValidName', b'InvalidValue\r'),
++            (b'ValidName', b'InvalidValue\n'),
++        )
++        for name, value in cases:
++            with self.subTest((name, value)):
++                with self.assertRaisesRegex(ValueError, 'Invalid header'):
++                    conn.putheader(name, value)
++
+ 
+ class BasicTest(TestCase):
+     def test_status_lines(self):
only in patch2:
unchanged:
--- python3.4-3.4.2.orig/debian/patches/CVE-2018-14647.patch
+++ python3.4-3.4.2/debian/patches/CVE-2018-14647.patch
@@ -0,0 +1,76 @@
+From f7666e828cc3d5873136473ea36ba2013d624fa1 Mon Sep 17 00:00:00 2001
+From: "Miss Islington (bot)"
+ <31488909+miss-isling...@users.noreply.github.com>
+Date: Tue, 18 Sep 2018 06:14:13 -0700
+Subject: [PATCH] bpo-34623: Use XML_SetHashSalt in _elementtree (GH-9146)
+
+The C accelerated _elementtree module now initializes hash randomization
+salt from _Py_HashSecret instead of libexpat's default CPRNG.
+
+Signed-off-by: Christian Heimes <christ...@python.org>
+
+https://bugs.python.org/issue34623
+(cherry picked from commit cb5778f00ce48631c7140f33ba242496aaf7102b)
+
+Co-authored-by: Christian Heimes <christ...@python.org>
+---
+ Include/pyexpat.h                                            | 4 +++-
+ .../next/Security/2018-09-10-16-05-39.bpo-34623.Ua9jMv.rst   | 2 ++
+ Modules/_elementtree.c                                       | 5 +++++
+ Modules/pyexpat.c                                            | 5 +++++
+ 4 files changed, 15 insertions(+), 1 deletion(-)
+ create mode 100644 Misc/NEWS.d/next/Security/2018-09-10-16-05-39.bpo-34623.Ua9jMv.rst
+
+--- a/Include/pyexpat.h
++++ b/Include/pyexpat.h
+@@ -3,7 +3,7 @@
+ 
+ /* note: you must import expat.h before importing this module! */
+ 
+-#define PyExpat_CAPI_MAGIC  "pyexpat.expat_CAPI 1.0"
++#define PyExpat_CAPI_MAGIC  "pyexpat.expat_CAPI 1.1"
+ #define PyExpat_CAPSULE_NAME "pyexpat.expat_CAPI"
+ 
+ struct PyExpat_CAPI
+@@ -48,6 +48,8 @@
+     enum XML_Status (*SetEncoding)(XML_Parser parser, const XML_Char *encoding);
+     int (*DefaultUnknownEncodingHandler)(
+         void *encodingHandlerData, const XML_Char *name, XML_Encoding *info);
++    /* might be none for expat < 2.1.0 */
++    int (*SetHashSalt)(XML_Parser parser, unsigned long hash_salt);
+     /* always add new stuff to the end! */
+ };
+ 
+--- /dev/null
++++ b/Misc/NEWS.d/next/Security/2018-09-10-16-05-39.bpo-34623.Ua9jMv.rst
+@@ -0,0 +1,2 @@
++The C accelerated _elementtree module now initializes hash randomization
++salt from _Py_HashSecret instead of libexpat's default CSPRNG.
+--- a/Modules/_elementtree.c
++++ b/Modules/_elementtree.c
+@@ -3239,6 +3239,11 @@
+         PyErr_NoMemory();
+         return -1;
+     }
++    /* expat < 2.1.0 has no XML_SetHashSalt() */
++    if (EXPAT(SetHashSalt) != NULL) {
++        EXPAT(SetHashSalt)(self->parser,
++                           (unsigned long)_Py_HashSecret.expat.hashsalt);
++    }
+ 
+     if (target) {
+         Py_INCREF(target);
+--- a/Modules/pyexpat.c
++++ b/Modules/pyexpat.c
+@@ -1959,6 +1959,11 @@
+     capi.SetStartDoctypeDeclHandler = XML_SetStartDoctypeDeclHandler;
+     capi.SetEncoding = XML_SetEncoding;
+     capi.DefaultUnknownEncodingHandler = PyUnknownEncodingHandler;
++#if XML_COMBINED_VERSION >= 20100
++    capi.SetHashSalt = XML_SetHashSalt;
++#else
++    capi.SetHashSalt = NULL;
++#endif
+ 
+     /* export using capsule */
+     capi_object = PyCapsule_New(&capi, PyExpat_CAPSULE_NAME, NULL);
only in patch2:
unchanged:
--- python3.4-3.4.2.orig/debian/patches/CVE-2018-20406.patch
+++ python3.4-3.4.2/debian/patches/CVE-2018-20406.patch
@@ -0,0 +1,186 @@
+From 71a9c65e74a70b6ed39adc4ba81d311ac1aa2acc Mon Sep 17 00:00:00 2001
+From: "Miss Islington (bot)"
+ <31488909+miss-isling...@users.noreply.github.com>
+Date: Thu, 20 Sep 2018 19:00:37 -0700
+Subject: [PATCH] closes bpo-34656: Avoid relying on signed overflow in _pickle
+ memos. (GH-9261)
+
+(cherry picked from commit a4ae828ee416a66d8c7bf5ee71d653c2cc6a26dd)
+
+Co-authored-by: Benjamin Peterson <benja...@python.org>
+---
+ Modules/_pickle.c | 62 +++++++++++++++++++++++------------------------
+ 1 file changed, 31 insertions(+), 31 deletions(-)
+
+--- a/Modules/_pickle.c
++++ b/Modules/_pickle.c
+@@ -518,9 +518,9 @@
+ } PyMemoEntry;
+ 
+ typedef struct {
+-    Py_ssize_t mt_mask;
+-    Py_ssize_t mt_used;
+-    Py_ssize_t mt_allocated;
++    size_t mt_mask;
++    size_t mt_used;
++    size_t mt_allocated;
+     PyMemoEntry *mt_table;
+ } PyMemoTable;
+ 
+@@ -564,8 +564,8 @@
+     /* The unpickler memo is just an array of PyObject *s. Using a dict
+        is unnecessary, since the keys are contiguous ints. */
+     PyObject **memo;
+-    Py_ssize_t memo_size;       /* Capacity of the memo array */
+-    Py_ssize_t memo_len;        /* Number of objects in the memo */
++    size_t memo_size;       /* Capacity of the memo array */
++    size_t memo_len;        /* Number of objects in the memo */
+ 
+     PyObject *pers_func;        /* persistent_load() method, can be NULL. */
+ 
+@@ -649,7 +649,7 @@
+ static PyMemoTable *
+ PyMemoTable_Copy(PyMemoTable *self)
+ {
+-    Py_ssize_t i;
++    size_t i;
+     PyMemoTable *new = PyMemoTable_New();
+     if (new == NULL)
+         return NULL;
+@@ -712,7 +712,7 @@
+ {
+     size_t i;
+     size_t perturb;
+-    size_t mask = (size_t)self->mt_mask;
++    size_t mask = self->mt_mask;
+     PyMemoEntry *table = self->mt_table;
+     PyMemoEntry *entry;
+     Py_hash_t hash = (Py_hash_t)key >> 3;
+@@ -734,22 +734,24 @@
+ 
+ /* Returns -1 on failure, 0 on success. */
+ static int
+-_PyMemoTable_ResizeTable(PyMemoTable *self, Py_ssize_t min_size)
++_PyMemoTable_ResizeTable(PyMemoTable *self, size_t min_size)
+ {
+     PyMemoEntry *oldtable = NULL;
+     PyMemoEntry *oldentry, *newentry;
+-    Py_ssize_t new_size = MT_MINSIZE;
+-    Py_ssize_t to_process;
++    size_t new_size = MT_MINSIZE;
++    size_t to_process;
+ 
+     assert(min_size > 0);
+ 
+-    /* Find the smallest valid table size >= min_size. */
+-    while (new_size < min_size && new_size > 0)
+-        new_size <<= 1;
+-    if (new_size <= 0) {
++    if (min_size > PY_SSIZE_T_MAX) {
+         PyErr_NoMemory();
+         return -1;
+     }
++
++    /* Find the smallest valid table size >= min_size. */
++    while (new_size < min_size) {
++        new_size <<= 1;
++    }
+     /* new_size needs to be a power of two. */
+     assert((new_size & (new_size - 1)) == 0);
+ 
+@@ -799,6 +801,7 @@
+ PyMemoTable_Set(PyMemoTable *self, PyObject *key, Py_ssize_t value)
+ {
+     PyMemoEntry *entry;
++    size_t desired_size;
+ 
+     assert(key != NULL);
+ 
+@@ -822,10 +825,12 @@
+      * Very large memo tables (over 50K items) use doubling instead.
+      * This may help applications with severe memory constraints.
+      */
+-    if (!(self->mt_used * 3 >= (self->mt_mask + 1) * 2))
++    if (SIZE_MAX / 3 >= self->mt_used && self->mt_used * 3 < self->mt_allocated * 2) {
+         return 0;
+-    return _PyMemoTable_ResizeTable(self,
+-        (self->mt_used > 50000 ? 2 : 4) * self->mt_used);
++    }
++    // self->mt_used is always < PY_SSIZE_T_MAX, so this can't overflow.
++    desired_size = (self->mt_used > 50000 ? 2 : 4) * self->mt_used;
++    return _PyMemoTable_ResizeTable(self, desired_size);
+ }
+ 
+ #undef MT_MINSIZE
+@@ -1258,9 +1263,9 @@
+ /* Returns -1 (with an exception set) on failure, 0 on success. The memo array
+    will be modified in place. */
+ static int
+-_Unpickler_ResizeMemoList(UnpicklerObject *self, Py_ssize_t new_size)
++_Unpickler_ResizeMemoList(UnpicklerObject *self, size_t new_size)
+ {
+-    Py_ssize_t i;
++    size_t i;
+     PyObject **memo;
+ 
+     assert(new_size > self->memo_size);
+@@ -1279,9 +1284,9 @@
+ 
+ /* Returns NULL if idx is out of bounds. */
+ static PyObject *
+-_Unpickler_MemoGet(UnpicklerObject *self, Py_ssize_t idx)
++_Unpickler_MemoGet(UnpicklerObject *self, size_t idx)
+ {
+-    if (idx < 0 || idx >= self->memo_size)
++    if (idx >= self->memo_size)
+         return NULL;
+ 
+     return self->memo[idx];
+@@ -1290,7 +1295,7 @@
+ /* Returns -1 (with an exception set) on failure, 0 on success.
+    This takes its own reference to `value`. */
+ static int
+-_Unpickler_MemoPut(UnpicklerObject *self, Py_ssize_t idx, PyObject *value)
++_Unpickler_MemoPut(UnpicklerObject *self, size_t idx, PyObject *value)
+ {
+     PyObject *old_item;
+ 
+@@ -4097,7 +4102,7 @@
+ _pickle_PicklerMemoProxy_copy_impl(PicklerMemoProxyObject *self)
+ /*[clinic end generated code: output=bb83a919d29225ef input=b73043485ac30b36]*/
+ {
+-    Py_ssize_t i;
++    size_t i;
+     PyMemoTable *memo;
+     PyObject *new_memo = PyDict_New();
+     if (new_memo == NULL)
+@@ -6472,7 +6477,7 @@
+ _pickle_UnpicklerMemoProxy_copy_impl(UnpicklerMemoProxyObject *self)
+ /*[clinic end generated code: output=e12af7e9bc1e4c77 input=97769247ce032c1d]*/
+ {
+-    Py_ssize_t i;
++    size_t i;
+     PyObject *new_memo = PyDict_New();
+     if (new_memo == NULL)
+         return NULL;
+@@ -6623,8 +6628,8 @@
+ Unpickler_set_memo(UnpicklerObject *self, PyObject *obj)
+ {
+     PyObject **new_memo;
+-    Py_ssize_t new_memo_size = 0;
+-    Py_ssize_t i;
++    size_t new_memo_size = 0;
++    size_t i;
+ 
+     if (obj == NULL) {
+         PyErr_SetString(PyExc_TypeError,
+@@ -6689,8 +6694,7 @@
+ 
+   error:
+     if (new_memo_size) {
+-        i = new_memo_size;
+-        while (--i >= 0) {
++        for (i = new_memo_size - 1; i != SIZE_MAX; i--) {
+             Py_XDECREF(new_memo[i]);
+         }
+         PyMem_FREE(new_memo);
only in patch2:
unchanged:
--- python3.4-3.4.2.orig/debian/patches/CVE-2019-5010.patch
+++ python3.4-3.4.2/debian/patches/CVE-2019-5010.patch
@@ -0,0 +1,108 @@
+From 216a4d83c3b72f4fdcd81b588dc3f42cc461739a Mon Sep 17 00:00:00 2001
+From: "Miss Islington (bot)"
+ <31488909+miss-isling...@users.noreply.github.com>
+Date: Tue, 15 Jan 2019 17:16:36 -0800
+Subject: [PATCH] bpo-35746: Fix segfault in ssl's cert parser (GH-11569)
+ (GH-11573)
+
+Fix a NULL pointer deref in ssl module. The cert parser did not handle CRL
+distribution points with empty DP or URI correctly. A malicious or buggy
+certificate can result into segfault.
+
+Signed-off-by: Christian Heimes <christ...@python.org>
+
+https://bugs.python.org/issue35746
+(cherry picked from commit a37f52436f9aa4b9292878b72f3ff1480e2606c3)
+
+Co-authored-by: Christian Heimes <christ...@python.org>
+---
+ Lib/test/talos-2019-0758.pem                  | 22 +++++++++++++++++++
+ Lib/test/test_ssl.py                          | 22 +++++++++++++++++++
+ .../2019-01-15-18-16-05.bpo-35746.nMSd0j.rst  |  3 +++
+ Modules/_ssl.c                                |  4 ++++
+ 4 files changed, 51 insertions(+)
+ create mode 100644 Lib/test/talos-2019-0758.pem
+ create mode 100644 Misc/NEWS.d/next/Security/2019-01-15-18-16-05.bpo-35746.nMSd0j.rst
+
+--- /dev/null
++++ b/Lib/test/talos-2019-0758.pem
+@@ -0,0 +1,22 @@
++-----BEGIN CERTIFICATE-----
++MIIDqDCCApKgAwIBAgIBAjALBgkqhkiG9w0BAQswHzELMAkGA1UEBhMCVUsxEDAO
++BgNVBAMTB2NvZHktY2EwHhcNMTgwNjE4MTgwMDU4WhcNMjgwNjE0MTgwMDU4WjA7
++MQswCQYDVQQGEwJVSzEsMCoGA1UEAxMjY29kZW5vbWljb24tdm0tMi50ZXN0Lmxh
++bC5jaXNjby5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC63fGB
++J80A9Av1GB0bptslKRIUtJm8EeEu34HkDWbL6AJY0P8WfDtlXjlPaLqFa6sqH6ES
++V48prSm1ZUbDSVL8R6BYVYpOlK8/48xk4pGTgRzv69gf5SGtQLwHy8UPBKgjSZoD
++5a5k5wJXGswhKFFNqyyxqCvWmMnJWxXTt2XDCiWc4g4YAWi4O4+6SeeHVAV9rV7C
++1wxqjzKovVe2uZOHjKEzJbbIU6JBPb6TRfMdRdYOw98n1VXDcKVgdX2DuuqjCzHP
++WhU4Tw050M9NaK3eXp4Mh69VuiKoBGOLSOcS8reqHIU46Reg0hqeL8LIL6OhFHIF
++j7HR6V1X6F+BfRS/AgMBAAGjgdYwgdMwCQYDVR0TBAIwADAdBgNVHQ4EFgQUOktp
++HQjxDXXUg8prleY9jeLKeQ4wTwYDVR0jBEgwRoAUx6zgPygZ0ZErF9sPC4+5e2Io
++UU+hI6QhMB8xCzAJBgNVBAYTAlVLMRAwDgYDVQQDEwdjb2R5LWNhggkA1QEAuwb7
++2s0wCQYDVR0SBAIwADAuBgNVHREEJzAlgiNjb2Rlbm9taWNvbi12bS0yLnRlc3Qu
++bGFsLmNpc2NvLmNvbTAOBgNVHQ8BAf8EBAMCBaAwCwYDVR0fBAQwAjAAMAsGCSqG
++SIb3DQEBCwOCAQEAvqantx2yBlM11RoFiCfi+AfSblXPdrIrHvccepV4pYc/yO6p
++t1f2dxHQb8rWH3i6cWag/EgIZx+HJQvo0rgPY1BFJsX1WnYf1/znZpkUBGbVmlJr
++t/dW1gSkNS6sPsM0Q+7HPgEv8CPDNK5eo7vU2seE0iWOkxSyVUuiCEY9ZVGaLVit
++p0C78nZ35Pdv4I+1cosmHl28+es1WI22rrnmdBpH8J1eY6WvUw2xuZHLeNVN0TzV
++Q3qq53AaCWuLOD1AjESWuUCxMZTK9DPS4JKXTK8RLyDeqOvJGjsSWp3kL0y3GaQ+
++10T1rfkKJub2+m9A9duin1fn6tHc2wSvB7m3DA==
++-----END CERTIFICATE-----
+--- a/Lib/test/test_ssl.py
++++ b/Lib/test/test_ssl.py
+@@ -64,6 +64,7 @@
+ BADKEY = data_file("badkey.pem")
+ NOKIACERT = data_file("nokia.pem")
+ NULLBYTECERT = data_file("nullbytecert.pem")
++TALOS_INVALID_CRLDP = data_file("talos-2019-0758.pem")
+ 
+ DHFILE = data_file("dh512.pem")
+ BYTES_DHFILE = os.fsencode(DHFILE)
+@@ -230,6 +231,27 @@
+         self.assertEqual(p['crlDistributionPoints'],
+                          ('http://SVRIntl-G3-crl.verisign.com/SVRIntlG3.crl',))
+ 
++    def test_parse_cert_CVE_2019_5010(self):
++        p = ssl._ssl._test_decode_cert(TALOS_INVALID_CRLDP)
++        if support.verbose:
++            sys.stdout.write("\n" + pprint.pformat(p) + "\n")
++        self.assertEqual(
++            p,
++            {
++                'issuer': (
++                    (('countryName', 'UK'),), (('commonName', 'cody-ca'),)),
++                'notAfter': 'Jun 14 18:00:58 2028 GMT',
++                'notBefore': 'Jun 18 18:00:58 2018 GMT',
++                'serialNumber': '02',
++                'subject': ((('countryName', 'UK'),),
++                            (('commonName',
++                              'codenomicon-vm-2.test.lal.cisco.com'),)),
++                'subjectAltName': (
++                    ('DNS', 'codenomicon-vm-2.test.lal.cisco.com'),),
++                'version': 3
++            }
++        )
++
+     def test_parse_cert_CVE_2013_4238(self):
+         p = ssl._ssl._test_decode_cert(NULLBYTECERT)
+         if support.verbose:
+--- /dev/null
++++ b/Misc/NEWS.d/next/Security/2019-01-15-18-16-05.bpo-35746.nMSd0j.rst
+@@ -0,0 +1,3 @@
++[CVE-2019-5010] Fix a NULL pointer deref in ssl module. The cert parser did
++not handle CRL distribution points with empty DP or URI correctly. A
++malicious or buggy certificate can result into segfault.
+--- a/Modules/_ssl.c
++++ b/Modules/_ssl.c
+@@ -1052,6 +1052,10 @@
+         STACK_OF(GENERAL_NAME) *gns;
+ 
+         dp = sk_DIST_POINT_value(dps, i);
++        if (dp->distpoint == NULL) {
++            /* Ignore empty DP value, CVE-2019-5010 */
++            continue;
++        }
+         gns = dp->distpoint->name.fullname;
+ 
+         for (j=0; j < sk_GENERAL_NAME_num(gns); j++) {

Reply via email to