[Python-checkins] cpython (merge 2.7 -> 2.7): Merge heads
serhiy.storchaka
python-checkins at python.org
Mon Jan 26 09:28:18 CET 2015
https://hg.python.org/cpython/rev/36ca5e765704
changeset: 94295:36ca5e765704
branch: 2.7
parent: 94292:1e12c9e5bc89
parent: 94284:9a4882b12218
user: Serhiy Storchaka <storchaka at gmail.com>
date: Mon Jan 26 10:27:31 2015 +0200
summary:
Merge heads
files:
Doc/library/argparse.rst | 9 +-
Doc/library/logging.handlers.rst | 19 +-
Doc/library/ssl.rst | 35 ++-
Doc/library/time.rst | 13 +-
Lib/httplib.py | 9 +-
Lib/rfc822.py | 7 +-
Lib/ssl.py | 20 +-
Lib/test/test_httplib.py | 39 ++-
Lib/test/test_rfc822.py | 6 +
Lib/test/test_ssl.py | 64 +++-
Misc/NEWS | 8 +
Modules/_ssl.c | 139 +++++++-
Modules/_ssl_data.h | 297 ++++++++++++++++++-
Tools/ssl/make_ssl_data.py | 57 ++-
setup.py | 2 +-
15 files changed, 651 insertions(+), 73 deletions(-)
diff --git a/Doc/library/argparse.rst b/Doc/library/argparse.rst
--- a/Doc/library/argparse.rst
+++ b/Doc/library/argparse.rst
@@ -1499,12 +1499,15 @@
* parser_class - class which will be used to create sub-parser instances, by
default the class of the current parser (e.g. ArgumentParser)
- * dest - name of the attribute under which sub-command name will be
+ * action_ - the basic type of action to be taken when this argument is
+ encountered at the command line
+
+ * dest_ - name of the attribute under which sub-command name will be
stored; by default None and no value is stored
- * help - help for sub-parser group in help output, by default None
+ * help_ - help for sub-parser group in help output, by default None
- * metavar - string presenting available sub-commands in help; by default it
+ * metavar_ - string presenting available sub-commands in help; by default it
is None and presents sub-commands in form {cmd1, cmd2, ..}
Some example usage::
diff --git a/Doc/library/logging.handlers.rst b/Doc/library/logging.handlers.rst
--- a/Doc/library/logging.handlers.rst
+++ b/Doc/library/logging.handlers.rst
@@ -185,15 +185,16 @@
You can use the *maxBytes* and *backupCount* values to allow the file to
:dfn:`rollover` at a predetermined size. When the size is about to be exceeded,
the file is closed and a new file is silently opened for output. Rollover occurs
- whenever the current log file is nearly *maxBytes* in length; if *maxBytes* is
- zero, rollover never occurs. If *backupCount* is non-zero, the system will save
- old log files by appending the extensions '.1', '.2' etc., to the filename. For
- example, with a *backupCount* of 5 and a base file name of :file:`app.log`, you
- would get :file:`app.log`, :file:`app.log.1`, :file:`app.log.2`, up to
- :file:`app.log.5`. The file being written to is always :file:`app.log`. When
- this file is filled, it is closed and renamed to :file:`app.log.1`, and if files
- :file:`app.log.1`, :file:`app.log.2`, etc. exist, then they are renamed to
- :file:`app.log.2`, :file:`app.log.3` etc. respectively.
+ whenever the current log file is nearly *maxBytes* in length; if either of
+ *maxBytes* or *backupCount* is zero, rollover never occurs. If *backupCount*
+ is non-zero, the system will save old log files by appending the extensions
+ '.1', '.2' etc., to the filename. For example, with a *backupCount* of 5 and
+ a base file name of :file:`app.log`, you would get :file:`app.log`,
+ :file:`app.log.1`, :file:`app.log.2`, up to :file:`app.log.5`. The file being
+ written to is always :file:`app.log`. When this file is filled, it is closed
+ and renamed to :file:`app.log.1`, and if files :file:`app.log.1`,
+ :file:`app.log.2`, etc. exist, then they are renamed to :file:`app.log.2`,
+ :file:`app.log.3` etc. respectively.
.. versionchanged:: 2.6
*delay* was added.
diff --git a/Doc/library/ssl.rst b/Doc/library/ssl.rst
--- a/Doc/library/ssl.rst
+++ b/Doc/library/ssl.rst
@@ -638,6 +638,13 @@
.. versionadded:: 2.7.9
+.. data:: HAS_ALPN
+
+ Whether the OpenSSL library has built-in support for the *Application-Layer
+ Protocol Negotiation* TLS extension as described in :rfc:`7301`.
+
+ .. versionadded:: 2.7.10
+
.. data:: HAS_ECDH
Whether the OpenSSL library has built-in support for Elliptic Curve-based
@@ -864,9 +871,19 @@
.. versionadded:: 2.7.9
+.. method:: SSLSocket.selected_alpn_protocol()
+
+ Return the protocol that was selected during the TLS handshake. If
+ :meth:`SSLContext.set_alpn_protocols` was not called, if the other party does
+ not support ALPN, if this socket does not support any of the client's
+ proposed protocols, or if the handshake has not happened yet, ``None`` is
+ returned.
+
+ .. versionadded:: 2.7.10
+
.. method:: SSLSocket.selected_npn_protocol()
- Returns the higher-level protocol that was selected during the TLS/SSL
+ Return the higher-level protocol that was selected during the TLS/SSL
handshake. If :meth:`SSLContext.set_npn_protocols` was not called, or
if the other party does not support NPN, or if the handshake has not yet
happened, this will return ``None``.
@@ -1034,6 +1051,20 @@
when connected, the :meth:`SSLSocket.cipher` method of SSL sockets will
give the currently selected cipher.
+.. method:: SSLContext.set_alpn_protocols(protocols)
+
+ Specify which protocols the socket should advertise during the SSL/TLS
+ handshake. It should be a list of ASCII strings, like ``['http/1.1',
+ 'spdy/2']``, ordered by preference. The selection of a protocol will happen
+ during the handshake, and will play out according to :rfc:`7301`. After a
+ successful handshake, the :meth:`SSLSocket.selected_alpn_protocol` method will
+ return the agreed-upon protocol.
+
+ This method will raise :exc:`NotImplementedError` if :data:`HAS_ALPN` is
+ False.
+
+ .. versionadded:: 2.7.10
+
.. method:: SSLContext.set_npn_protocols(protocols)
Specify which protocols the socket should advertise during the SSL/TLS
@@ -1072,7 +1103,7 @@
Due to the early negotiation phase of the TLS connection, only limited
methods and attributes are usable like
- :meth:`SSLSocket.selected_npn_protocol` and :attr:`SSLSocket.context`.
+ :meth:`SSLSocket.selected_alpn_protocol` and :attr:`SSLSocket.context`.
:meth:`SSLSocket.getpeercert`, :meth:`SSLSocket.getpeercert`,
:meth:`SSLSocket.cipher` and :meth:`SSLSocket.compress` methods require that
the TLS connection has progressed beyond the TLS Client Hello and therefore
diff --git a/Doc/library/time.rst b/Doc/library/time.rst
--- a/Doc/library/time.rst
+++ b/Doc/library/time.rst
@@ -222,12 +222,13 @@
.. function:: sleep(secs)
- Suspend execution for the given number of seconds. The argument may be a
- floating point number to indicate a more precise sleep time. The actual
- suspension time may be less than that requested because any caught signal will
- terminate the :func:`sleep` following execution of that signal's catching
- routine. Also, the suspension time may be longer than requested by an arbitrary
- amount because of the scheduling of other activity in the system.
+ Suspend execution of the current thread for the given number of seconds.
+ The argument may be a floating point number to indicate a more precise sleep
+ time. The actual suspension time may be less than that requested because any
+ caught signal will terminate the :func:`sleep` following execution of that
+ signal's catching routine. Also, the suspension time may be longer than
+ requested by an arbitrary amount because of the scheduling of other activity
+ in the system.
.. function:: strftime(format[, t])
diff --git a/Lib/httplib.py b/Lib/httplib.py
--- a/Lib/httplib.py
+++ b/Lib/httplib.py
@@ -313,6 +313,11 @@
hlist.append(line)
self.addheader(headerseen, line[len(headerseen)+1:].strip())
continue
+ elif headerseen is not None:
+ # An empty header name. These aren't allowed in HTTP, but it's
+ # probably a benign mistake. Don't add the header, just keep
+ # going.
+ continue
else:
# It's not a header line; throw it back and stop here.
if not self.dict:
@@ -723,7 +728,7 @@
endpoint passed to set_tunnel. This is done by sending a HTTP CONNECT
request to the proxy server when the connection is established.
- This method must be called before the HTML connection has been
+ This method must be called before the HTTP connection has been
established.
The headers argument should be a mapping of extra HTTP headers
@@ -1129,7 +1134,7 @@
"Accept arguments to set the host/port, since the superclass doesn't."
if host is not None:
- self._conn._set_hostport(host, port)
+ (self._conn.host, self._conn.port) = self._conn._get_hostport(host, port)
self._conn.connect()
def getfile(self):
diff --git a/Lib/rfc822.py b/Lib/rfc822.py
--- a/Lib/rfc822.py
+++ b/Lib/rfc822.py
@@ -179,6 +179,11 @@
lst.append(line)
self.dict[headerseen] = line[len(headerseen)+1:].strip()
continue
+ elif headerseen is not None:
+ # An empty header name. These aren't allowed in HTTP, but it's
+ # probably a benign mistake. Don't add the header, just keep
+ # going.
+ continue
else:
# It's not a header line; throw it back and stop here.
if not self.dict:
@@ -202,7 +207,7 @@
data in RFC 2822-like formats with special header formats.
"""
i = line.find(':')
- if i > 0:
+ if i > -1:
return line[:i].lower()
return None
diff --git a/Lib/ssl.py b/Lib/ssl.py
--- a/Lib/ssl.py
+++ b/Lib/ssl.py
@@ -123,7 +123,7 @@
_import_symbols('SSL_ERROR_')
_import_symbols('PROTOCOL_')
-from _ssl import HAS_SNI, HAS_ECDH, HAS_NPN
+from _ssl import HAS_SNI, HAS_ECDH, HAS_NPN, HAS_ALPN
from _ssl import _OPENSSL_API_VERSION
@@ -365,6 +365,17 @@
self._set_npn_protocols(protos)
+ def set_alpn_protocols(self, alpn_protocols):
+ protos = bytearray()
+ for protocol in alpn_protocols:
+ b = protocol.encode('ascii')
+ if len(b) == 0 or len(b) > 255:
+ raise SSLError('ALPN protocols must be 1 to 255 in length')
+ protos.append(len(b))
+ protos.extend(b)
+
+ self._set_alpn_protocols(protos)
+
def _load_windows_store_certs(self, storename, purpose):
certs = bytearray()
for cert, encoding, trust in enum_certificates(storename):
@@ -647,6 +658,13 @@
else:
return self._sslobj.selected_npn_protocol()
+ def selected_alpn_protocol(self):
+ self._checkClosed()
+ if not self._sslobj or not _ssl.HAS_ALPN:
+ return None
+ else:
+ return self._sslobj.selected_alpn_protocol()
+
def cipher(self):
self._checkClosed()
if not self._sslobj:
diff --git a/Lib/test/test_httplib.py b/Lib/test/test_httplib.py
--- a/Lib/test/test_httplib.py
+++ b/Lib/test/test_httplib.py
@@ -164,6 +164,16 @@
conn.request('GET', '/foo')
self.assertTrue(sock.data.startswith(expected))
+ def test_malformed_headers_coped_with(self):
+ # Issue 19996
+ body = "HTTP/1.1 200 OK\r\nFirst: val\r\n: nval\r\nSecond: val\r\n\r\n"
+ sock = FakeSocket(body)
+ resp = httplib.HTTPResponse(sock)
+ resp.begin()
+
+ self.assertEqual(resp.getheader('First'), 'val')
+ self.assertEqual(resp.getheader('Second'), 'val')
+
class BasicTest(TestCase):
def test_status_lines(self):
@@ -461,7 +471,11 @@
self.assertEqual(httplib.responses[httplib.NOT_FOUND], "Not Found")
-class SourceAddressTest(TestCase):
+class TestServerMixin:
+ """A limited socket server mixin.
+
+ This is used by test cases for testing http connection end points.
+ """
def setUp(self):
self.serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.port = test_support.bind_port(self.serv)
@@ -476,6 +490,7 @@
self.serv.close()
self.serv = None
+class SourceAddressTest(TestServerMixin, TestCase):
def testHTTPConnectionSourceAddress(self):
self.conn = httplib.HTTPConnection(HOST, self.port,
source_address=('', self.source_port))
@@ -492,6 +507,24 @@
# for an ssl_wrapped connect() to actually return from.
+class HTTPTest(TestServerMixin, TestCase):
+ def testHTTPConnection(self):
+ self.conn = httplib.HTTP(host=HOST, port=self.port, strict=None)
+ self.conn.connect()
+ self.assertEqual(self.conn._conn.host, HOST)
+ self.assertEqual(self.conn._conn.port, self.port)
+
+ def testHTTPWithConnectHostPort(self):
+ testhost = 'unreachable.test.domain'
+ testport = '80'
+ self.conn = httplib.HTTP(host=testhost, port=testport)
+ self.conn.connect(host=HOST, port=self.port)
+ self.assertNotEqual(self.conn._conn.host, testhost)
+ self.assertNotEqual(self.conn._conn.port, testport)
+ self.assertEqual(self.conn._conn.host, HOST)
+ self.assertEqual(self.conn._conn.port, self.port)
+
+
class TimeoutTest(TestCase):
PORT = None
@@ -537,6 +570,7 @@
self.assertEqual(httpConn.sock.gettimeout(), 30)
httpConn.close()
+
class HTTPSTest(TestCase):
def setUp(self):
@@ -713,7 +747,8 @@
@test_support.reap_threads
def test_main(verbose=None):
test_support.run_unittest(HeaderTests, OfflineTest, BasicTest, TimeoutTest,
- HTTPSTest, SourceAddressTest, TunnelTests)
+ HTTPTest, HTTPSTest, SourceAddressTest,
+ TunnelTests)
if __name__ == '__main__':
test_main()
diff --git a/Lib/test/test_rfc822.py b/Lib/test/test_rfc822.py
--- a/Lib/test/test_rfc822.py
+++ b/Lib/test/test_rfc822.py
@@ -248,6 +248,12 @@
eq(rfc822.quote('foo\\wacky"name'), 'foo\\\\wacky\\"name')
eq(rfc822.unquote('"foo\\\\wacky\\"name"'), 'foo\\wacky"name')
+ def test_invalid_headers(self):
+ eq = self.assertEqual
+ msg = self.create_message("First: val\n: otherval\nSecond: val2\n")
+ eq(msg.getheader('First'), 'val')
+ eq(msg.getheader('Second'), 'val2')
+
def test_main():
test_support.run_unittest(MessageTestCase)
diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py
--- a/Lib/test/test_ssl.py
+++ b/Lib/test/test_ssl.py
@@ -1569,7 +1569,8 @@
try:
self.sslconn = self.server.context.wrap_socket(
self.sock, server_side=True)
- self.server.selected_protocols.append(self.sslconn.selected_npn_protocol())
+ self.server.selected_npn_protocols.append(self.sslconn.selected_npn_protocol())
+ self.server.selected_alpn_protocols.append(self.sslconn.selected_alpn_protocol())
except socket.error as e:
# We treat ConnectionResetError as though it were an
# SSLError - OpenSSL on Ubuntu abruptly closes the
@@ -1678,7 +1679,8 @@
def __init__(self, certificate=None, ssl_version=None,
certreqs=None, cacerts=None,
chatty=True, connectionchatty=False, starttls_server=False,
- npn_protocols=None, ciphers=None, context=None):
+ npn_protocols=None, alpn_protocols=None,
+ ciphers=None, context=None):
if context:
self.context = context
else:
@@ -1693,6 +1695,8 @@
self.context.load_cert_chain(certificate)
if npn_protocols:
self.context.set_npn_protocols(npn_protocols)
+ if alpn_protocols:
+ self.context.set_alpn_protocols(alpn_protocols)
if ciphers:
self.context.set_ciphers(ciphers)
self.chatty = chatty
@@ -1702,7 +1706,8 @@
self.port = support.bind_port(self.sock)
self.flag = None
self.active = False
- self.selected_protocols = []
+ self.selected_npn_protocols = []
+ self.selected_alpn_protocols = []
self.conn_errors = []
threading.Thread.__init__(self)
self.daemon = True
@@ -1927,11 +1932,13 @@
'compression': s.compression(),
'cipher': s.cipher(),
'peercert': s.getpeercert(),
+ 'client_alpn_protocol': s.selected_alpn_protocol(),
'client_npn_protocol': s.selected_npn_protocol(),
'version': s.version(),
})
s.close()
- stats['server_npn_protocols'] = server.selected_protocols
+ stats['server_alpn_protocols'] = server.selected_alpn_protocols
+ stats['server_npn_protocols'] = server.selected_npn_protocols
return stats
def try_protocol_combo(server_protocol, client_protocol, expect_success,
@@ -2787,6 +2794,55 @@
if "ADH" not in parts and "EDH" not in parts and "DHE" not in parts:
self.fail("Non-DH cipher: " + cipher[0])
+ def test_selected_alpn_protocol(self):
+ # selected_alpn_protocol() is None unless ALPN is used.
+ context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
+ context.load_cert_chain(CERTFILE)
+ stats = server_params_test(context, context,
+ chatty=True, connectionchatty=True)
+ self.assertIs(stats['client_alpn_protocol'], None)
+
+ @unittest.skipUnless(ssl.HAS_ALPN, "ALPN support required")
+ def test_selected_alpn_protocol_if_server_uses_alpn(self):
+ # selected_alpn_protocol() is None unless ALPN is used by the client.
+ client_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
+ client_context.load_verify_locations(CERTFILE)
+ server_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
+ server_context.load_cert_chain(CERTFILE)
+ server_context.set_alpn_protocols(['foo', 'bar'])
+ stats = server_params_test(client_context, server_context,
+ chatty=True, connectionchatty=True)
+ self.assertIs(stats['client_alpn_protocol'], None)
+
+ @unittest.skipUnless(ssl.HAS_ALPN, "ALPN support needed for this test")
+ def test_alpn_protocols(self):
+ server_protocols = ['foo', 'bar', 'milkshake']
+ protocol_tests = [
+ (['foo', 'bar'], 'foo'),
+ (['bar', 'foo'], 'foo'),
+ (['milkshake'], 'milkshake'),
+ (['http/3.0', 'http/4.0'], None)
+ ]
+ for client_protocols, expected in protocol_tests:
+ server_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
+ server_context.load_cert_chain(CERTFILE)
+ server_context.set_alpn_protocols(server_protocols)
+ client_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
+ client_context.load_cert_chain(CERTFILE)
+ client_context.set_alpn_protocols(client_protocols)
+ stats = server_params_test(client_context, server_context,
+ chatty=True, connectionchatty=True)
+
+ msg = "failed trying %s (s) and %s (c).\n" \
+ "was expecting %s, but got %%s from the %%s" \
+ % (str(server_protocols), str(client_protocols),
+ str(expected))
+ client_result = stats['client_alpn_protocol']
+ self.assertEqual(client_result, expected, msg % (client_result, "client"))
+ server_result = stats['server_alpn_protocols'][-1] \
+ if len(stats['server_alpn_protocols']) else 'nothing'
+ self.assertEqual(server_result, expected, msg % (server_result, "server"))
+
def test_selected_npn_protocol(self):
# selected_npn_protocol() is None unless NPN is used
context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -15,6 +15,14 @@
Library
-------
+- Issue #19996: Make :mod:`httplib` ignore headers with no name rather than
+ assuming the body has started.
+
+- Issue #20188: Support Application-Layer Protocol Negotiation (ALPN) in the ssl
+ module.
+
+- Issue #23248: Update ssl error codes from latest OpenSSL git master.
+
- Issue #23098: 64-bit dev_t is now supported in the os module.
- Issue #23063: In the disutils' check command, fix parsing of reST with code or
diff --git a/Modules/_ssl.c b/Modules/_ssl.c
--- a/Modules/_ssl.c
+++ b/Modules/_ssl.c
@@ -105,6 +105,11 @@
# define HAVE_SNI 0
#endif
+/* ALPN added in OpenSSL 1.0.2 */
+#if OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined(OPENSSL_NO_TLSEXT)
+# define HAVE_ALPN
+#endif
+
enum py_ssl_error {
/* these mirror ssl.h */
PY_SSL_ERROR_NONE,
@@ -205,9 +210,13 @@
PyObject_HEAD
SSL_CTX *ctx;
#ifdef OPENSSL_NPN_NEGOTIATED
- char *npn_protocols;
+ unsigned char *npn_protocols;
int npn_protocols_len;
#endif
+#ifdef HAVE_ALPN
+ unsigned char *alpn_protocols;
+ int alpn_protocols_len;
+#endif
#ifndef OPENSSL_NO_TLSEXT
PyObject *set_hostname;
#endif
@@ -1408,7 +1417,20 @@
if (out == NULL)
Py_RETURN_NONE;
- return PyUnicode_FromStringAndSize((char *) out, outlen);
+ return PyString_FromStringAndSize((char *)out, outlen);
+}
+#endif
+
+#ifdef HAVE_ALPN
+static PyObject *PySSL_selected_alpn_protocol(PySSLSocket *self) {
+ const unsigned char *out;
+ unsigned int outlen;
+
+ SSL_get0_alpn_selected(self->ssl, &out, &outlen);
+
+ if (out == NULL)
+ Py_RETURN_NONE;
+ return PyString_FromStringAndSize((char *)out, outlen);
}
#endif
@@ -1925,6 +1947,9 @@
#ifdef OPENSSL_NPN_NEGOTIATED
{"selected_npn_protocol", (PyCFunction)PySSL_selected_npn_protocol, METH_NOARGS},
#endif
+#ifdef HAVE_ALPN
+ {"selected_alpn_protocol", (PyCFunction)PySSL_selected_alpn_protocol, METH_NOARGS},
+#endif
{"compression", (PyCFunction)PySSL_compression, METH_NOARGS},
{"shutdown", (PyCFunction)PySSL_SSLshutdown, METH_NOARGS,
PySSL_SSLshutdown_doc},
@@ -2032,6 +2057,9 @@
#ifdef OPENSSL_NPN_NEGOTIATED
self->npn_protocols = NULL;
#endif
+#ifdef HAVE_ALPN
+ self->alpn_protocols = NULL;
+#endif
#ifndef OPENSSL_NO_TLSEXT
self->set_hostname = NULL;
#endif
@@ -2091,7 +2119,10 @@
context_clear(self);
SSL_CTX_free(self->ctx);
#ifdef OPENSSL_NPN_NEGOTIATED
- PyMem_Free(self->npn_protocols);
+ PyMem_FREE(self->npn_protocols);
+#endif
+#ifdef HAVE_ALPN
+ PyMem_FREE(self->alpn_protocols);
#endif
Py_TYPE(self)->tp_free(self);
}
@@ -2117,6 +2148,30 @@
Py_RETURN_NONE;
}
+static int
+do_protocol_selection(int alpn, unsigned char **out, unsigned char *outlen,
+ const unsigned char *server_protocols, unsigned int server_protocols_len,
+ const unsigned char *client_protocols, unsigned int client_protocols_len)
+{
+ int ret;
+ if (client_protocols == NULL) {
+ client_protocols = (unsigned char *)"";
+ client_protocols_len = 0;
+ }
+ if (server_protocols == NULL) {
+ server_protocols = (unsigned char *)"";
+ server_protocols_len = 0;
+ }
+
+ ret = SSL_select_next_proto(out, outlen,
+ server_protocols, server_protocols_len,
+ client_protocols, client_protocols_len);
+ if (alpn && ret != OPENSSL_NPN_NEGOTIATED)
+ return SSL_TLSEXT_ERR_NOACK;
+
+ return SSL_TLSEXT_ERR_OK;
+}
+
#ifdef OPENSSL_NPN_NEGOTIATED
/* this callback gets passed to SSL_CTX_set_next_protos_advertise_cb */
static int
@@ -2127,10 +2182,10 @@
PySSLContext *ssl_ctx = (PySSLContext *) args;
if (ssl_ctx->npn_protocols == NULL) {
- *data = (unsigned char *) "";
+ *data = (unsigned char *)"";
*len = 0;
} else {
- *data = (unsigned char *) ssl_ctx->npn_protocols;
+ *data = ssl_ctx->npn_protocols;
*len = ssl_ctx->npn_protocols_len;
}
@@ -2143,23 +2198,9 @@
const unsigned char *server, unsigned int server_len,
void *args)
{
- PySSLContext *ssl_ctx = (PySSLContext *) args;
-
- unsigned char *client = (unsigned char *) ssl_ctx->npn_protocols;
- int client_len;
-
- if (client == NULL) {
- client = (unsigned char *) "";
- client_len = 0;
- } else {
- client_len = ssl_ctx->npn_protocols_len;
- }
-
- SSL_select_next_proto(out, outlen,
- server, server_len,
- client, client_len);
-
- return SSL_TLSEXT_ERR_OK;
+ PySSLContext *ctx = (PySSLContext *)args;
+ return do_protocol_selection(0, out, outlen, server, server_len,
+ ctx->npn_protocols, ctx->npn_protocols_len);
}
#endif
@@ -2202,6 +2243,50 @@
#endif
}
+#ifdef HAVE_ALPN
+static int
+_selectALPN_cb(SSL *s,
+ const unsigned char **out, unsigned char *outlen,
+ const unsigned char *client_protocols, unsigned int client_protocols_len,
+ void *args)
+{
+ PySSLContext *ctx = (PySSLContext *)args;
+ return do_protocol_selection(1, (unsigned char **)out, outlen,
+ ctx->alpn_protocols, ctx->alpn_protocols_len,
+ client_protocols, client_protocols_len);
+}
+#endif
+
+static PyObject *
+_set_alpn_protocols(PySSLContext *self, PyObject *args)
+{
+#ifdef HAVE_ALPN
+ Py_buffer protos;
+
+ if (!PyArg_ParseTuple(args, "s*:set_npn_protocols", &protos))
+ return NULL;
+
+ PyMem_FREE(self->alpn_protocols);
+ self->alpn_protocols = PyMem_Malloc(protos.len);
+ if (!self->alpn_protocols)
+ return PyErr_NoMemory();
+ memcpy(self->alpn_protocols, protos.buf, protos.len);
+ self->alpn_protocols_len = protos.len;
+ PyBuffer_Release(&protos);
+
+ if (SSL_CTX_set_alpn_protos(self->ctx, self->alpn_protocols, self->alpn_protocols_len))
+ return PyErr_NoMemory();
+ SSL_CTX_set_alpn_select_cb(self->ctx, _selectALPN_cb, self);
+
+ PyBuffer_Release(&protos);
+ Py_RETURN_NONE;
+#else
+ PyErr_SetString(PyExc_NotImplementedError,
+ "The ALPN extension requires OpenSSL 1.0.2 or later.");
+ return NULL;
+#endif
+}
+
static PyObject *
get_verify_mode(PySSLContext *self, void *c)
{
@@ -3188,6 +3273,8 @@
METH_VARARGS | METH_KEYWORDS, NULL},
{"set_ciphers", (PyCFunction) set_ciphers,
METH_VARARGS, NULL},
+ {"_set_alpn_protocols", (PyCFunction) _set_alpn_protocols,
+ METH_VARARGS, NULL},
{"_set_npn_protocols", (PyCFunction) _set_npn_protocols,
METH_VARARGS, NULL},
{"load_cert_chain", (PyCFunction) load_cert_chain,
@@ -4100,6 +4187,14 @@
Py_INCREF(r);
PyModule_AddObject(m, "HAS_NPN", r);
+#ifdef HAVE_ALPN
+ r = Py_True;
+#else
+ r = Py_False;
+#endif
+ Py_INCREF(r);
+ PyModule_AddObject(m, "HAS_ALPN", r);
+
/* Mappings for error codes */
err_codes_to_names = PyDict_New();
err_names_to_codes = PyDict_New();
diff --git a/Modules/_ssl_data.h b/Modules/_ssl_data.h
--- a/Modules/_ssl_data.h
+++ b/Modules/_ssl_data.h
@@ -1,5 +1,5 @@
/* File generated by Tools/ssl/make_ssl_data.py */
-/* Generated on 2012-05-16T23:56:40.981382 */
+/* Generated on 2015-01-17T20:33:43.377453 */
static struct py_ssl_library_code library_codes[] = {
{"PEM", ERR_LIB_PEM},
@@ -179,6 +179,11 @@
#else
{"BAD_CHECKSUM", ERR_LIB_SSL, 104},
#endif
+ #ifdef SSL_R_BAD_DATA
+ {"BAD_DATA", ERR_LIB_SSL, SSL_R_BAD_DATA},
+ #else
+ {"BAD_DATA", ERR_LIB_SSL, 390},
+ #endif
#ifdef SSL_R_BAD_DATA_RETURNED_BY_CALLBACK
{"BAD_DATA_RETURNED_BY_CALLBACK", ERR_LIB_SSL, SSL_R_BAD_DATA_RETURNED_BY_CALLBACK},
#else
@@ -309,6 +314,46 @@
#else
{"BAD_SIGNATURE", ERR_LIB_SSL, 123},
#endif
+ #ifdef SSL_R_BAD_SRP_A_LENGTH
+ {"BAD_SRP_A_LENGTH", ERR_LIB_SSL, SSL_R_BAD_SRP_A_LENGTH},
+ #else
+ {"BAD_SRP_A_LENGTH", ERR_LIB_SSL, 347},
+ #endif
+ #ifdef SSL_R_BAD_SRP_B_LENGTH
+ {"BAD_SRP_B_LENGTH", ERR_LIB_SSL, SSL_R_BAD_SRP_B_LENGTH},
+ #else
+ {"BAD_SRP_B_LENGTH", ERR_LIB_SSL, 348},
+ #endif
+ #ifdef SSL_R_BAD_SRP_G_LENGTH
+ {"BAD_SRP_G_LENGTH", ERR_LIB_SSL, SSL_R_BAD_SRP_G_LENGTH},
+ #else
+ {"BAD_SRP_G_LENGTH", ERR_LIB_SSL, 349},
+ #endif
+ #ifdef SSL_R_BAD_SRP_N_LENGTH
+ {"BAD_SRP_N_LENGTH", ERR_LIB_SSL, SSL_R_BAD_SRP_N_LENGTH},
+ #else
+ {"BAD_SRP_N_LENGTH", ERR_LIB_SSL, 350},
+ #endif
+ #ifdef SSL_R_BAD_SRP_PARAMETERS
+ {"BAD_SRP_PARAMETERS", ERR_LIB_SSL, SSL_R_BAD_SRP_PARAMETERS},
+ #else
+ {"BAD_SRP_PARAMETERS", ERR_LIB_SSL, 371},
+ #endif
+ #ifdef SSL_R_BAD_SRP_S_LENGTH
+ {"BAD_SRP_S_LENGTH", ERR_LIB_SSL, SSL_R_BAD_SRP_S_LENGTH},
+ #else
+ {"BAD_SRP_S_LENGTH", ERR_LIB_SSL, 351},
+ #endif
+ #ifdef SSL_R_BAD_SRTP_MKI_VALUE
+ {"BAD_SRTP_MKI_VALUE", ERR_LIB_SSL, SSL_R_BAD_SRTP_MKI_VALUE},
+ #else
+ {"BAD_SRTP_MKI_VALUE", ERR_LIB_SSL, 352},
+ #endif
+ #ifdef SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST
+ {"BAD_SRTP_PROTECTION_PROFILE_LIST", ERR_LIB_SSL, SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST},
+ #else
+ {"BAD_SRTP_PROTECTION_PROFILE_LIST", ERR_LIB_SSL, 353},
+ #endif
#ifdef SSL_R_BAD_SSL_FILETYPE
{"BAD_SSL_FILETYPE", ERR_LIB_SSL, SSL_R_BAD_SSL_FILETYPE},
#else
@@ -324,6 +369,11 @@
#else
{"BAD_STATE", ERR_LIB_SSL, 126},
#endif
+ #ifdef SSL_R_BAD_VALUE
+ {"BAD_VALUE", ERR_LIB_SSL, SSL_R_BAD_VALUE},
+ #else
+ {"BAD_VALUE", ERR_LIB_SSL, 384},
+ #endif
#ifdef SSL_R_BAD_WRITE_RETRY
{"BAD_WRITE_RETRY", ERR_LIB_SSL, SSL_R_BAD_WRITE_RETRY},
#else
@@ -354,6 +404,16 @@
#else
{"CA_DN_TOO_LONG", ERR_LIB_SSL, 132},
#endif
+ #ifdef SSL_R_CA_KEY_TOO_SMALL
+ {"CA_KEY_TOO_SMALL", ERR_LIB_SSL, SSL_R_CA_KEY_TOO_SMALL},
+ #else
+ {"CA_KEY_TOO_SMALL", ERR_LIB_SSL, 397},
+ #endif
+ #ifdef SSL_R_CA_MD_TOO_WEAK
+ {"CA_MD_TOO_WEAK", ERR_LIB_SSL, SSL_R_CA_MD_TOO_WEAK},
+ #else
+ {"CA_MD_TOO_WEAK", ERR_LIB_SSL, 398},
+ #endif
#ifdef SSL_R_CCS_RECEIVED_EARLY
{"CCS_RECEIVED_EARLY", ERR_LIB_SSL, SSL_R_CCS_RECEIVED_EARLY},
#else
@@ -364,6 +424,11 @@
#else
{"CERTIFICATE_VERIFY_FAILED", ERR_LIB_SSL, 134},
#endif
+ #ifdef SSL_R_CERT_CB_ERROR
+ {"CERT_CB_ERROR", ERR_LIB_SSL, SSL_R_CERT_CB_ERROR},
+ #else
+ {"CERT_CB_ERROR", ERR_LIB_SSL, 377},
+ #endif
#ifdef SSL_R_CERT_LENGTH_MISMATCH
{"CERT_LENGTH_MISMATCH", ERR_LIB_SSL, SSL_R_CERT_LENGTH_MISMATCH},
#else
@@ -454,6 +519,11 @@
#else
{"DECRYPTION_FAILED_OR_BAD_RECORD_MAC", ERR_LIB_SSL, 281},
#endif
+ #ifdef SSL_R_DH_KEY_TOO_SMALL
+ {"DH_KEY_TOO_SMALL", ERR_LIB_SSL, SSL_R_DH_KEY_TOO_SMALL},
+ #else
+ {"DH_KEY_TOO_SMALL", ERR_LIB_SSL, 394},
+ #endif
#ifdef SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG
{"DH_PUBLIC_VALUE_LENGTH_IS_WRONG", ERR_LIB_SSL, SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG},
#else
@@ -494,11 +564,26 @@
#else
{"ECC_CERT_SHOULD_HAVE_SHA1_SIGNATURE", ERR_LIB_SSL, 323},
#endif
+ #ifdef SSL_R_ECDH_REQUIRED_FOR_SUITEB_MODE
+ {"ECDH_REQUIRED_FOR_SUITEB_MODE", ERR_LIB_SSL, SSL_R_ECDH_REQUIRED_FOR_SUITEB_MODE},
+ #else
+ {"ECDH_REQUIRED_FOR_SUITEB_MODE", ERR_LIB_SSL, 374},
+ #endif
#ifdef SSL_R_ECGROUP_TOO_LARGE_FOR_CIPHER
{"ECGROUP_TOO_LARGE_FOR_CIPHER", ERR_LIB_SSL, SSL_R_ECGROUP_TOO_LARGE_FOR_CIPHER},
#else
{"ECGROUP_TOO_LARGE_FOR_CIPHER", ERR_LIB_SSL, 310},
#endif
+ #ifdef SSL_R_EE_KEY_TOO_SMALL
+ {"EE_KEY_TOO_SMALL", ERR_LIB_SSL, SSL_R_EE_KEY_TOO_SMALL},
+ #else
+ {"EE_KEY_TOO_SMALL", ERR_LIB_SSL, 399},
+ #endif
+ #ifdef SSL_R_EMPTY_SRTP_PROTECTION_PROFILE_LIST
+ {"EMPTY_SRTP_PROTECTION_PROFILE_LIST", ERR_LIB_SSL, SSL_R_EMPTY_SRTP_PROTECTION_PROFILE_LIST},
+ #else
+ {"EMPTY_SRTP_PROTECTION_PROFILE_LIST", ERR_LIB_SSL, 354},
+ #endif
#ifdef SSL_R_ENCRYPTED_LENGTH_TOO_LONG
{"ENCRYPTED_LENGTH_TOO_LONG", ERR_LIB_SSL, SSL_R_ENCRYPTED_LENGTH_TOO_LONG},
#else
@@ -529,6 +614,16 @@
#else
{"GOT_A_FIN_BEFORE_A_CCS", ERR_LIB_SSL, 154},
#endif
+ #ifdef SSL_R_GOT_NEXT_PROTO_BEFORE_A_CCS
+ {"GOT_NEXT_PROTO_BEFORE_A_CCS", ERR_LIB_SSL, SSL_R_GOT_NEXT_PROTO_BEFORE_A_CCS},
+ #else
+ {"GOT_NEXT_PROTO_BEFORE_A_CCS", ERR_LIB_SSL, 355},
+ #endif
+ #ifdef SSL_R_GOT_NEXT_PROTO_WITHOUT_EXTENSION
+ {"GOT_NEXT_PROTO_WITHOUT_EXTENSION", ERR_LIB_SSL, SSL_R_GOT_NEXT_PROTO_WITHOUT_EXTENSION},
+ #else
+ {"GOT_NEXT_PROTO_WITHOUT_EXTENSION", ERR_LIB_SSL, 356},
+ #endif
#ifdef SSL_R_HTTPS_PROXY_REQUEST
{"HTTPS_PROXY_REQUEST", ERR_LIB_SSL, SSL_R_HTTPS_PROXY_REQUEST},
#else
@@ -544,6 +639,16 @@
#else
{"ILLEGAL_PADDING", ERR_LIB_SSL, 283},
#endif
+ #ifdef SSL_R_ILLEGAL_SUITEB_DIGEST
+ {"ILLEGAL_SUITEB_DIGEST", ERR_LIB_SSL, SSL_R_ILLEGAL_SUITEB_DIGEST},
+ #else
+ {"ILLEGAL_SUITEB_DIGEST", ERR_LIB_SSL, 380},
+ #endif
+ #ifdef SSL_R_INAPPROPRIATE_FALLBACK
+ {"INAPPROPRIATE_FALLBACK", ERR_LIB_SSL, SSL_R_INAPPROPRIATE_FALLBACK},
+ #else
+ {"INAPPROPRIATE_FALLBACK", ERR_LIB_SSL, 373},
+ #endif
#ifdef SSL_R_INCONSISTENT_COMPRESSION
{"INCONSISTENT_COMPRESSION", ERR_LIB_SSL, SSL_R_INCONSISTENT_COMPRESSION},
#else
@@ -564,11 +669,26 @@
#else
{"INVALID_COMPRESSION_ALGORITHM", ERR_LIB_SSL, 341},
#endif
+ #ifdef SSL_R_INVALID_NULL_CMD_NAME
+ {"INVALID_NULL_CMD_NAME", ERR_LIB_SSL, SSL_R_INVALID_NULL_CMD_NAME},
+ #else
+ {"INVALID_NULL_CMD_NAME", ERR_LIB_SSL, 385},
+ #endif
#ifdef SSL_R_INVALID_PURPOSE
{"INVALID_PURPOSE", ERR_LIB_SSL, SSL_R_INVALID_PURPOSE},
#else
{"INVALID_PURPOSE", ERR_LIB_SSL, 278},
#endif
+ #ifdef SSL_R_INVALID_SERVERINFO_DATA
+ {"INVALID_SERVERINFO_DATA", ERR_LIB_SSL, SSL_R_INVALID_SERVERINFO_DATA},
+ #else
+ {"INVALID_SERVERINFO_DATA", ERR_LIB_SSL, 388},
+ #endif
+ #ifdef SSL_R_INVALID_SRP_USERNAME
+ {"INVALID_SRP_USERNAME", ERR_LIB_SSL, SSL_R_INVALID_SRP_USERNAME},
+ #else
+ {"INVALID_SRP_USERNAME", ERR_LIB_SSL, 357},
+ #endif
#ifdef SSL_R_INVALID_STATUS_RESPONSE
{"INVALID_STATUS_RESPONSE", ERR_LIB_SSL, SSL_R_INVALID_STATUS_RESPONSE},
#else
@@ -689,6 +809,16 @@
#else
{"MISSING_DSA_SIGNING_CERT", ERR_LIB_SSL, 165},
#endif
+ #ifdef SSL_R_MISSING_ECDH_CERT
+ {"MISSING_ECDH_CERT", ERR_LIB_SSL, SSL_R_MISSING_ECDH_CERT},
+ #else
+ {"MISSING_ECDH_CERT", ERR_LIB_SSL, 382},
+ #endif
+ #ifdef SSL_R_MISSING_ECDSA_SIGNING_CERT
+ {"MISSING_ECDSA_SIGNING_CERT", ERR_LIB_SSL, SSL_R_MISSING_ECDSA_SIGNING_CERT},
+ #else
+ {"MISSING_ECDSA_SIGNING_CERT", ERR_LIB_SSL, 381},
+ #endif
#ifdef SSL_R_MISSING_EXPORT_TMP_DH_KEY
{"MISSING_EXPORT_TMP_DH_KEY", ERR_LIB_SSL, SSL_R_MISSING_EXPORT_TMP_DH_KEY},
#else
@@ -714,6 +844,11 @@
#else
{"MISSING_RSA_SIGNING_CERT", ERR_LIB_SSL, 170},
#endif
+ #ifdef SSL_R_MISSING_SRP_PARAM
+ {"MISSING_SRP_PARAM", ERR_LIB_SSL, SSL_R_MISSING_SRP_PARAM},
+ #else
+ {"MISSING_SRP_PARAM", ERR_LIB_SSL, 358},
+ #endif
#ifdef SSL_R_MISSING_TMP_DH_KEY
{"MISSING_TMP_DH_KEY", ERR_LIB_SSL, SSL_R_MISSING_TMP_DH_KEY},
#else
@@ -739,6 +874,11 @@
#else
{"MISSING_VERIFY_MESSAGE", ERR_LIB_SSL, 174},
#endif
+ #ifdef SSL_R_MULTIPLE_SGC_RESTARTS
+ {"MULTIPLE_SGC_RESTARTS", ERR_LIB_SSL, SSL_R_MULTIPLE_SGC_RESTARTS},
+ #else
+ {"MULTIPLE_SGC_RESTARTS", ERR_LIB_SSL, 346},
+ #endif
#ifdef SSL_R_NON_SSLV2_INITIAL_PACKET
{"NON_SSLV2_INITIAL_PACKET", ERR_LIB_SSL, SSL_R_NON_SSLV2_INITIAL_PACKET},
#else
@@ -819,6 +959,11 @@
#else
{"NO_METHOD_SPECIFIED", ERR_LIB_SSL, 188},
#endif
+ #ifdef SSL_R_NO_PEM_EXTENSIONS
+ {"NO_PEM_EXTENSIONS", ERR_LIB_SSL, SSL_R_NO_PEM_EXTENSIONS},
+ #else
+ {"NO_PEM_EXTENSIONS", ERR_LIB_SSL, 389},
+ #endif
#ifdef SSL_R_NO_PRIVATEKEY
{"NO_PRIVATEKEY", ERR_LIB_SSL, SSL_R_NO_PRIVATEKEY},
#else
@@ -854,6 +999,16 @@
#else
{"NO_SHARED_CIPHER", ERR_LIB_SSL, 193},
#endif
+ #ifdef SSL_R_NO_SHARED_SIGATURE_ALGORITHMS
+ {"NO_SHARED_SIGATURE_ALGORITHMS", ERR_LIB_SSL, SSL_R_NO_SHARED_SIGATURE_ALGORITHMS},
+ #else
+ {"NO_SHARED_SIGATURE_ALGORITHMS", ERR_LIB_SSL, 376},
+ #endif
+ #ifdef SSL_R_NO_SRTP_PROFILES
+ {"NO_SRTP_PROFILES", ERR_LIB_SSL, SSL_R_NO_SRTP_PROFILES},
+ #else
+ {"NO_SRTP_PROFILES", ERR_LIB_SSL, 359},
+ #endif
#ifdef SSL_R_NO_VERIFY_CALLBACK
{"NO_VERIFY_CALLBACK", ERR_LIB_SSL, SSL_R_NO_VERIFY_CALLBACK},
#else
@@ -879,6 +1034,16 @@
#else
{"OLD_SESSION_COMPRESSION_ALGORITHM_NOT_RETURNED", ERR_LIB_SSL, 344},
#endif
+ #ifdef SSL_R_ONLY_DTLS_1_2_ALLOWED_IN_SUITEB_MODE
+ {"ONLY_DTLS_1_2_ALLOWED_IN_SUITEB_MODE", ERR_LIB_SSL, SSL_R_ONLY_DTLS_1_2_ALLOWED_IN_SUITEB_MODE},
+ #else
+ {"ONLY_DTLS_1_2_ALLOWED_IN_SUITEB_MODE", ERR_LIB_SSL, 387},
+ #endif
+ #ifdef SSL_R_ONLY_TLS_1_2_ALLOWED_IN_SUITEB_MODE
+ {"ONLY_TLS_1_2_ALLOWED_IN_SUITEB_MODE", ERR_LIB_SSL, SSL_R_ONLY_TLS_1_2_ALLOWED_IN_SUITEB_MODE},
+ #else
+ {"ONLY_TLS_1_2_ALLOWED_IN_SUITEB_MODE", ERR_LIB_SSL, 379},
+ #endif
#ifdef SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE
{"ONLY_TLS_ALLOWED_IN_FIPS_MODE", ERR_LIB_SSL, SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE},
#else
@@ -934,6 +1099,16 @@
#else
{"PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE", ERR_LIB_SSL, 204},
#endif
+ #ifdef SSL_R_PEM_NAME_BAD_PREFIX
+ {"PEM_NAME_BAD_PREFIX", ERR_LIB_SSL, SSL_R_PEM_NAME_BAD_PREFIX},
+ #else
+ {"PEM_NAME_BAD_PREFIX", ERR_LIB_SSL, 391},
+ #endif
+ #ifdef SSL_R_PEM_NAME_TOO_SHORT
+ {"PEM_NAME_TOO_SHORT", ERR_LIB_SSL, SSL_R_PEM_NAME_TOO_SHORT},
+ #else
+ {"PEM_NAME_TOO_SHORT", ERR_LIB_SSL, 392},
+ #endif
#ifdef SSL_R_PRE_MAC_LENGTH_TOO_LONG
{"PRE_MAC_LENGTH_TOO_LONG", ERR_LIB_SSL, SSL_R_PRE_MAC_LENGTH_TOO_LONG},
#else
@@ -1069,11 +1244,36 @@
#else
{"SHORT_READ", ERR_LIB_SSL, 219},
#endif
+ #ifdef SSL_R_SIGNATURE_ALGORITHMS_ERROR
+ {"SIGNATURE_ALGORITHMS_ERROR", ERR_LIB_SSL, SSL_R_SIGNATURE_ALGORITHMS_ERROR},
+ #else
+ {"SIGNATURE_ALGORITHMS_ERROR", ERR_LIB_SSL, 360},
+ #endif
#ifdef SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE
{"SIGNATURE_FOR_NON_SIGNING_CERTIFICATE", ERR_LIB_SSL, SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE},
#else
{"SIGNATURE_FOR_NON_SIGNING_CERTIFICATE", ERR_LIB_SSL, 220},
#endif
+ #ifdef SSL_R_SRP_A_CALC
+ {"SRP_A_CALC", ERR_LIB_SSL, SSL_R_SRP_A_CALC},
+ #else
+ {"SRP_A_CALC", ERR_LIB_SSL, 361},
+ #endif
+ #ifdef SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES
+ {"SRTP_COULD_NOT_ALLOCATE_PROFILES", ERR_LIB_SSL, SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES},
+ #else
+ {"SRTP_COULD_NOT_ALLOCATE_PROFILES", ERR_LIB_SSL, 362},
+ #endif
+ #ifdef SSL_R_SRTP_PROTECTION_PROFILE_LIST_TOO_LONG
+ {"SRTP_PROTECTION_PROFILE_LIST_TOO_LONG", ERR_LIB_SSL, SSL_R_SRTP_PROTECTION_PROFILE_LIST_TOO_LONG},
+ #else
+ {"SRTP_PROTECTION_PROFILE_LIST_TOO_LONG", ERR_LIB_SSL, 363},
+ #endif
+ #ifdef SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE
+ {"SRTP_UNKNOWN_PROTECTION_PROFILE", ERR_LIB_SSL, SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE},
+ #else
+ {"SRTP_UNKNOWN_PROTECTION_PROFILE", ERR_LIB_SSL, 364},
+ #endif
#ifdef SSL_R_SSL23_DOING_SESSION_ID_REUSE
{"SSL23_DOING_SESSION_ID_REUSE", ERR_LIB_SSL, SSL_R_SSL23_DOING_SESSION_ID_REUSE},
#else
@@ -1179,6 +1379,11 @@
#else
{"SSL_LIBRARY_HAS_NO_CIPHERS", ERR_LIB_SSL, 230},
#endif
+ #ifdef SSL_R_SSL_NEGATIVE_LENGTH
+ {"SSL_NEGATIVE_LENGTH", ERR_LIB_SSL, SSL_R_SSL_NEGATIVE_LENGTH},
+ #else
+ {"SSL_NEGATIVE_LENGTH", ERR_LIB_SSL, 372},
+ #endif
#ifdef SSL_R_SSL_SESSION_ID_CALLBACK_FAILED
{"SSL_SESSION_ID_CALLBACK_FAILED", ERR_LIB_SSL, SSL_R_SSL_SESSION_ID_CALLBACK_FAILED},
#else
@@ -1229,6 +1434,11 @@
#else
{"TLSV1_ALERT_EXPORT_RESTRICTION", ERR_LIB_SSL, 1060},
#endif
+ #ifdef SSL_R_TLSV1_ALERT_INAPPROPRIATE_FALLBACK
+ {"TLSV1_ALERT_INAPPROPRIATE_FALLBACK", ERR_LIB_SSL, SSL_R_TLSV1_ALERT_INAPPROPRIATE_FALLBACK},
+ #else
+ {"TLSV1_ALERT_INAPPROPRIATE_FALLBACK", ERR_LIB_SSL, 1086},
+ #endif
#ifdef SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY
{"TLSV1_ALERT_INSUFFICIENT_SECURITY", ERR_LIB_SSL, SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY},
#else
@@ -1294,6 +1504,21 @@
#else
{"TLS_CLIENT_CERT_REQ_WITH_ANON_CIPHER", ERR_LIB_SSL, 232},
#endif
+ #ifdef SSL_R_TLS_HEARTBEAT_PEER_DOESNT_ACCEPT
+ {"TLS_HEARTBEAT_PEER_DOESNT_ACCEPT", ERR_LIB_SSL, SSL_R_TLS_HEARTBEAT_PEER_DOESNT_ACCEPT},
+ #else
+ {"TLS_HEARTBEAT_PEER_DOESNT_ACCEPT", ERR_LIB_SSL, 365},
+ #endif
+ #ifdef SSL_R_TLS_HEARTBEAT_PENDING
+ {"TLS_HEARTBEAT_PENDING", ERR_LIB_SSL, SSL_R_TLS_HEARTBEAT_PENDING},
+ #else
+ {"TLS_HEARTBEAT_PENDING", ERR_LIB_SSL, 366},
+ #endif
+ #ifdef SSL_R_TLS_ILLEGAL_EXPORTER_LABEL
+ {"TLS_ILLEGAL_EXPORTER_LABEL", ERR_LIB_SSL, SSL_R_TLS_ILLEGAL_EXPORTER_LABEL},
+ #else
+ {"TLS_ILLEGAL_EXPORTER_LABEL", ERR_LIB_SSL, 367},
+ #endif
#ifdef SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST
{"TLS_INVALID_ECPOINTFORMAT_LIST", ERR_LIB_SSL, SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST},
#else
@@ -1399,6 +1624,16 @@
#else
{"UNKNOWN_CIPHER_TYPE", ERR_LIB_SSL, 249},
#endif
+ #ifdef SSL_R_UNKNOWN_CMD_NAME
+ {"UNKNOWN_CMD_NAME", ERR_LIB_SSL, SSL_R_UNKNOWN_CMD_NAME},
+ #else
+ {"UNKNOWN_CMD_NAME", ERR_LIB_SSL, 386},
+ #endif
+ #ifdef SSL_R_UNKNOWN_DIGEST
+ {"UNKNOWN_DIGEST", ERR_LIB_SSL, SSL_R_UNKNOWN_DIGEST},
+ #else
+ {"UNKNOWN_DIGEST", ERR_LIB_SSL, 368},
+ #endif
#ifdef SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE
{"UNKNOWN_KEY_EXCHANGE_TYPE", ERR_LIB_SSL, SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE},
#else
@@ -1469,16 +1704,36 @@
#else
{"UNSUPPORTED_STATUS_TYPE", ERR_LIB_SSL, 329},
#endif
+ #ifdef SSL_R_USE_SRTP_NOT_NEGOTIATED
+ {"USE_SRTP_NOT_NEGOTIATED", ERR_LIB_SSL, SSL_R_USE_SRTP_NOT_NEGOTIATED},
+ #else
+ {"USE_SRTP_NOT_NEGOTIATED", ERR_LIB_SSL, 369},
+ #endif
+ #ifdef SSL_R_VERSION_TOO_LOW
+ {"VERSION_TOO_LOW", ERR_LIB_SSL, SSL_R_VERSION_TOO_LOW},
+ #else
+ {"VERSION_TOO_LOW", ERR_LIB_SSL, 396},
+ #endif
#ifdef SSL_R_WRITE_BIO_NOT_SET
{"WRITE_BIO_NOT_SET", ERR_LIB_SSL, SSL_R_WRITE_BIO_NOT_SET},
#else
{"WRITE_BIO_NOT_SET", ERR_LIB_SSL, 260},
#endif
+ #ifdef SSL_R_WRONG_CERTIFICATE_TYPE
+ {"WRONG_CERTIFICATE_TYPE", ERR_LIB_SSL, SSL_R_WRONG_CERTIFICATE_TYPE},
+ #else
+ {"WRONG_CERTIFICATE_TYPE", ERR_LIB_SSL, 383},
+ #endif
#ifdef SSL_R_WRONG_CIPHER_RETURNED
{"WRONG_CIPHER_RETURNED", ERR_LIB_SSL, SSL_R_WRONG_CIPHER_RETURNED},
#else
{"WRONG_CIPHER_RETURNED", ERR_LIB_SSL, 261},
#endif
+ #ifdef SSL_R_WRONG_CURVE
+ {"WRONG_CURVE", ERR_LIB_SSL, SSL_R_WRONG_CURVE},
+ #else
+ {"WRONG_CURVE", ERR_LIB_SSL, 378},
+ #endif
#ifdef SSL_R_WRONG_MESSAGE_TYPE
{"WRONG_MESSAGE_TYPE", ERR_LIB_SSL, SSL_R_WRONG_MESSAGE_TYPE},
#else
@@ -1499,6 +1754,11 @@
#else
{"WRONG_SIGNATURE_SIZE", ERR_LIB_SSL, 265},
#endif
+ #ifdef SSL_R_WRONG_SIGNATURE_TYPE
+ {"WRONG_SIGNATURE_TYPE", ERR_LIB_SSL, SSL_R_WRONG_SIGNATURE_TYPE},
+ #else
+ {"WRONG_SIGNATURE_TYPE", ERR_LIB_SSL, 370},
+ #endif
#ifdef SSL_R_WRONG_SSL_VERSION
{"WRONG_SSL_VERSION", ERR_LIB_SSL, SSL_R_WRONG_SSL_VERSION},
#else
@@ -1519,6 +1779,11 @@
#else
{"X509_VERIFICATION_SETUP_PROBLEMS", ERR_LIB_SSL, 269},
#endif
+ #ifdef X509_R_AKID_MISMATCH
+ {"AKID_MISMATCH", ERR_LIB_X509, X509_R_AKID_MISMATCH},
+ #else
+ {"AKID_MISMATCH", ERR_LIB_X509, 110},
+ #endif
#ifdef X509_R_BAD_X509_FILETYPE
{"BAD_X509_FILETYPE", ERR_LIB_X509, X509_R_BAD_X509_FILETYPE},
#else
@@ -1539,11 +1804,26 @@
#else
{"CERT_ALREADY_IN_HASH_TABLE", ERR_LIB_X509, 101},
#endif
+ #ifdef X509_R_CRL_ALREADY_DELTA
+ {"CRL_ALREADY_DELTA", ERR_LIB_X509, X509_R_CRL_ALREADY_DELTA},
+ #else
+ {"CRL_ALREADY_DELTA", ERR_LIB_X509, 127},
+ #endif
+ #ifdef X509_R_CRL_VERIFY_FAILURE
+ {"CRL_VERIFY_FAILURE", ERR_LIB_X509, X509_R_CRL_VERIFY_FAILURE},
+ #else
+ {"CRL_VERIFY_FAILURE", ERR_LIB_X509, 131},
+ #endif
#ifdef X509_R_ERR_ASN1_LIB
{"ERR_ASN1_LIB", ERR_LIB_X509, X509_R_ERR_ASN1_LIB},
#else
{"ERR_ASN1_LIB", ERR_LIB_X509, 102},
#endif
+ #ifdef X509_R_IDP_MISMATCH
+ {"IDP_MISMATCH", ERR_LIB_X509, X509_R_IDP_MISMATCH},
+ #else
+ {"IDP_MISMATCH", ERR_LIB_X509, 128},
+ #endif
#ifdef X509_R_INVALID_DIRECTORY
{"INVALID_DIRECTORY", ERR_LIB_X509, X509_R_INVALID_DIRECTORY},
#else
@@ -1559,6 +1839,11 @@
#else
{"INVALID_TRUST", ERR_LIB_X509, 123},
#endif
+ #ifdef X509_R_ISSUER_MISMATCH
+ {"ISSUER_MISMATCH", ERR_LIB_X509, X509_R_ISSUER_MISMATCH},
+ #else
+ {"ISSUER_MISMATCH", ERR_LIB_X509, 129},
+ #endif
#ifdef X509_R_KEY_TYPE_MISMATCH
{"KEY_TYPE_MISMATCH", ERR_LIB_X509, X509_R_KEY_TYPE_MISMATCH},
#else
@@ -1584,11 +1869,21 @@
#else
{"METHOD_NOT_SUPPORTED", ERR_LIB_X509, 124},
#endif
+ #ifdef X509_R_NEWER_CRL_NOT_NEWER
+ {"NEWER_CRL_NOT_NEWER", ERR_LIB_X509, X509_R_NEWER_CRL_NOT_NEWER},
+ #else
+ {"NEWER_CRL_NOT_NEWER", ERR_LIB_X509, 132},
+ #endif
#ifdef X509_R_NO_CERT_SET_FOR_US_TO_VERIFY
{"NO_CERT_SET_FOR_US_TO_VERIFY", ERR_LIB_X509, X509_R_NO_CERT_SET_FOR_US_TO_VERIFY},
#else
{"NO_CERT_SET_FOR_US_TO_VERIFY", ERR_LIB_X509, 105},
#endif
+ #ifdef X509_R_NO_CRL_NUMBER
+ {"NO_CRL_NUMBER", ERR_LIB_X509, X509_R_NO_CRL_NUMBER},
+ #else
+ {"NO_CRL_NUMBER", ERR_LIB_X509, 130},
+ #endif
#ifdef X509_R_PUBLIC_KEY_DECODE_ERROR
{"PUBLIC_KEY_DECODE_ERROR", ERR_LIB_X509, X509_R_PUBLIC_KEY_DECODE_ERROR},
#else
diff --git a/Tools/ssl/make_ssl_data.py b/Tools/ssl/make_ssl_data.py
--- a/Tools/ssl/make_ssl_data.py
+++ b/Tools/ssl/make_ssl_data.py
@@ -5,8 +5,7 @@
`library` and `reason` mnemnonics to a more recent OpenSSL version.
It takes two arguments:
-- the path to the OpenSSL include files' directory
- (e.g. openssl-1.0.1-beta3/include/openssl/)
+- the path to the OpenSSL source tree (e.g. git checkout)
- the path to the C file to be generated
(probably Modules/_ssl_data.h)
"""
@@ -15,9 +14,10 @@
import os
import re
import sys
+import _ssl
-def parse_error_codes(h_file, prefix):
+def parse_error_codes(h_file, prefix, libcode):
pat = re.compile(r"#define\W+(%s([\w]+))\W+(\d+)\b" % re.escape(prefix))
codes = []
with open(h_file, "r", encoding="latin1") as f:
@@ -26,7 +26,8 @@
if match:
code, name, num = match.groups()
num = int(num)
- codes.append((code, name, num))
+ # e.g. ("SSL_R_BAD_DATA", ("ERR_LIB_SSL", "BAD_DATA", 390))
+ codes.append((code, (libcode, name, num)))
return codes
if __name__ == "__main__":
@@ -34,12 +35,32 @@
outfile = sys.argv[2]
use_stdout = outfile == '-'
f = sys.stdout if use_stdout else open(outfile, "w")
- error_libraries = (
- # (library code, mnemonic, error prefix, header file)
- ('ERR_LIB_PEM', 'PEM', 'PEM_R_', 'pem.h'),
- ('ERR_LIB_SSL', 'SSL', 'SSL_R_', 'ssl.h'),
- ('ERR_LIB_X509', 'X509', 'X509_R_', 'x509.h'),
- )
+ error_libraries = {
+ # mnemonic -> (library code, error prefix, header file)
+ 'PEM': ('ERR_LIB_PEM', 'PEM_R_', 'crypto/pem/pem.h'),
+ 'SSL': ('ERR_LIB_SSL', 'SSL_R_', 'ssl/ssl.h'),
+ 'X509': ('ERR_LIB_X509', 'X509_R_', 'crypto/x509/x509.h'),
+ }
+
+ # Read codes from libraries
+ new_codes = []
+ for libcode, prefix, h_file in sorted(error_libraries.values()):
+ new_codes += parse_error_codes(os.path.join(openssl_inc, h_file),
+ prefix, libcode)
+ new_code_nums = set((libcode, num)
+ for (code, (libcode, name, num)) in new_codes)
+
+ # Merge with existing codes (in case some old codes disappeared).
+ codes = {}
+ for errname, (libnum, errnum) in _ssl.err_names_to_codes.items():
+ lib = error_libraries[_ssl.lib_codes_to_names[libnum]]
+ libcode = lib[0] # e.g. ERR_LIB_PEM
+ errcode = lib[1] + errname # e.g. SSL_R_BAD_SSL_SESSION_ID_LENGTH
+ # Only keep it if the numeric codes weren't reused
+ if (libcode, errnum) not in new_code_nums:
+ codes[errcode] = libcode, errname, errnum
+ codes.update(dict(new_codes))
+
def w(l):
f.write(l + "\n")
w("/* File generated by Tools/ssl/make_ssl_data.py */")
@@ -47,21 +68,19 @@
w("")
w("static struct py_ssl_library_code library_codes[] = {")
- for libcode, mnemo, _, _ in error_libraries:
+ for mnemo, (libcode, _, _) in sorted(error_libraries.items()):
w(' {"%s", %s},' % (mnemo, libcode))
w(' { NULL }')
w('};')
w("")
w("static struct py_ssl_error_code error_codes[] = {")
- for libcode, _, prefix, h_file in error_libraries:
- codes = parse_error_codes(os.path.join(openssl_inc, h_file), prefix)
- for code, name, num in sorted(codes):
- w(' #ifdef %s' % (code))
- w(' {"%s", %s, %s},' % (name, libcode, code))
- w(' #else')
- w(' {"%s", %s, %d},' % (name, libcode, num))
- w(' #endif')
+ for errcode, (libcode, name, num) in sorted(codes.items()):
+ w(' #ifdef %s' % (errcode))
+ w(' {"%s", %s, %s},' % (name, libcode, errcode))
+ w(' #else')
+ w(' {"%s", %s, %d},' % (name, libcode, num))
+ w(' #endif')
w(' { NULL }')
w('};')
if not use_stdout:
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -696,7 +696,7 @@
exts.append( Extension('audioop', ['audioop.c']) )
# Disabled on 64-bit platforms
- if sys.maxint != 9223372036854775807L:
+ if sys.maxsize != 9223372036854775807L:
# Operations on images
exts.append( Extension('imageop', ['imageop.c']) )
else:
--
Repository URL: https://hg.python.org/cpython
More information about the Python-checkins
mailing list