Merge lp:~exarkun/pyopenssl/tlsv1_1or2 into lp:~exarkun/pyopenssl/trunk

Proposed by Jean-Paul Calderone
Status: Merged
Merged at revision: 171
Proposed branch: lp:~exarkun/pyopenssl/tlsv1_1or2
Merge into: lp:~exarkun/pyopenssl/trunk
Diff against target: 275 lines (+109/-29)
5 files modified
OpenSSL/ssl/context.c (+29/-5)
OpenSSL/ssl/context.h (+2/-0)
OpenSSL/ssl/ssl.c (+8/-0)
OpenSSL/test/test_ssl.py (+24/-11)
doc/api/ssl.rst (+46/-13)
To merge this branch: bzr merge lp:~exarkun/pyopenssl/tlsv1_1or2
Reviewer Review Type Date Requested Status
Jean-Paul Calderone Pending
Review via email: mp+189401@code.launchpad.net

Description of the change

Introduces conditional support for TLSv1.1 and TLSv1.2 (conditional on whether the wrapped version of OpenSSL supports them).

To post a comment you must log in.
lp:~exarkun/pyopenssl/tlsv1_1or2 updated
172. By Jean-Paul Calderone

Oops.

Revision history for this message
Zooko Wilcox-O'Hearn (zooko) wrote :

I don't understand this code very well, but this looks suspicious:

18 +#ifdef SSL_OP_NO_TLSv1_1
19 +#define TLSv1_2_METHOD_TEXT " TLSv1_2_METHOD"
20 +#endif

Shouldn't it be SSL_OP_NO_TLSv1_2 instead? And if so, and this is a bug, does this mean there isn't an automated test that tries to build pyOpenSSL against some version of OpenSSL that has or doesn't have the #defines necessary to trigger this bug?

Revision history for this message
Jean-Paul Calderone (exarkun) wrote :

> Shouldn't it be SSL_OP_NO_TLSv1_2 instead?

Almost certainly. Although I don't know whether there are versions of OpenSSL that define one of these (SSL_OP_NO_TLSv1_1, SSL_OP_NO_TLSv1_2) but not the other - so I don't know what the real world consequences of this bug (now fixed) would be.

> does this mean there isn't an automated test that tries to build pyOpenSSL against some version of OpenSSL that has or doesn't have the #defines necessary to trigger this bug?

Yes.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'OpenSSL/ssl/context.c'
--- OpenSSL/ssl/context.c 2012-03-09 23:04:04 +0000
+++ OpenSSL/ssl/context.c 2013-10-04 19:07:00 +0000
@@ -282,9 +282,16 @@
282#ifdef OPENSSL_NO_SSL2282#ifdef OPENSSL_NO_SSL2
283#define SSLv2_METHOD_TEXT ""283#define SSLv2_METHOD_TEXT ""
284#else284#else
285#define SSLv2_METHOD_TEXT "SSLv2_METHOD, "285#define SSLv2_METHOD_TEXT " SSLv2_METHOD"
286#endif286#endif
287287
288#ifdef SSL_OP_NO_TLSv1_1
289#define TLSv1_1_METHOD_TEXT " TLSv1_1_METHOD"
290#endif
291
292#ifdef SSL_OP_NO_TLSv1_2
293#define TLSv1_2_METHOD_TEXT " TLSv1_2_METHOD"
294#endif
288295
289static char ssl_Context_doc[] = "\n\296static char ssl_Context_doc[] = "\n\
290Context(method) -> Context instance\n\297Context(method) -> Context instance\n\
@@ -292,11 +299,12 @@
292OpenSSL.SSL.Context instances define the parameters for setting up new SSL\n\299OpenSSL.SSL.Context instances define the parameters for setting up new SSL\n\
293connections.\n\300connections.\n\
294\n\301\n\
295:param method: One of " SSLv2_METHOD_TEXT "SSLv3_METHOD, SSLv23_METHOD, or\n\302:param method: One of:" SSLv2_METHOD_TEXT " SSLv3_METHOD SSLv23_METHOD TLSv1_METHOD" TLSv1_1_METHOD_TEXT TLSv1_2_METHOD_TEXT "\n\
296 TLSv1_METHOD.\n\
297";303";
298304
299#undef SSLv2_METHOD_TEXT305#undef SSLv2_METHOD_TEXT
306#undef TLSv1_1_METHOD_TEXT
307#undef TLSv1_2_METHOD_TEXT
300308
301static char ssl_Context_load_verify_locations_doc[] = "\n\309static char ssl_Context_load_verify_locations_doc[] = "\n\
302Let SSL know where we can find trusted certificates for the certificate\n\310Let SSL know where we can find trusted certificates for the certificate\n\
@@ -1262,6 +1270,22 @@
1262 case ssl_TLSv1_METHOD:1270 case ssl_TLSv1_METHOD:
1263 method = TLSv1_method();1271 method = TLSv1_method();
1264 break;1272 break;
1273 case ssl_TLSv1_1_METHOD:
1274#ifdef SSL_OP_NO_TLSv1_1
1275 method = TLSv1_1_method();
1276#else
1277 PyErr_SetString(PyExc_ValueError, "TLSv1_1_method not supported by this version of OpenSSL");
1278 return NULL;
1279#endif
1280 break;
1281 case ssl_TLSv1_2_METHOD:
1282#ifdef SSL_OP_NO_TLSv1_2
1283 method = TLSv1_2_method();
1284#else
1285 PyErr_SetString(PyExc_ValueError, "TLSv1_2_method not supported by this version of OpenSSL");
1286 return NULL;
1287#endif
1288 break;
1265 default:1289 default:
1266 PyErr_SetString(PyExc_ValueError, "No such protocol");1290 PyErr_SetString(PyExc_ValueError, "No such protocol");
1267 return NULL;1291 return NULL;
12681292
=== modified file 'OpenSSL/ssl/context.h'
--- OpenSSL/ssl/context.h 2011-05-26 22:47:00 +0000
+++ OpenSSL/ssl/context.h 2013-10-04 19:07:00 +0000
@@ -38,6 +38,8 @@
38#define ssl_SSLv3_METHOD (2)38#define ssl_SSLv3_METHOD (2)
39#define ssl_SSLv23_METHOD (3)39#define ssl_SSLv23_METHOD (3)
40#define ssl_TLSv1_METHOD (4)40#define ssl_TLSv1_METHOD (4)
41#define ssl_TLSv1_1_METHOD (5)
42#define ssl_TLSv1_2_METHOD (6)
4143
4244
43#endif45#endif
4446
=== modified file 'OpenSSL/ssl/ssl.c'
--- OpenSSL/ssl/ssl.c 2012-02-13 14:10:15 +0000
+++ OpenSSL/ssl/ssl.c 2013-10-04 19:07:00 +0000
@@ -185,6 +185,8 @@
185 PyModule_AddIntConstant(module, "SSLv3_METHOD", ssl_SSLv3_METHOD);185 PyModule_AddIntConstant(module, "SSLv3_METHOD", ssl_SSLv3_METHOD);
186 PyModule_AddIntConstant(module, "SSLv23_METHOD", ssl_SSLv23_METHOD);186 PyModule_AddIntConstant(module, "SSLv23_METHOD", ssl_SSLv23_METHOD);
187 PyModule_AddIntConstant(module, "TLSv1_METHOD", ssl_TLSv1_METHOD);187 PyModule_AddIntConstant(module, "TLSv1_METHOD", ssl_TLSv1_METHOD);
188 PyModule_AddIntConstant(module, "TLSv1_1_METHOD", ssl_TLSv1_1_METHOD);
189 PyModule_AddIntConstant(module, "TLSv1_2_METHOD", ssl_TLSv1_2_METHOD);
188190
189 /* Verify constants */191 /* Verify constants */
190 PyModule_AddIntConstant(module, "VERIFY_NONE", SSL_VERIFY_NONE);192 PyModule_AddIntConstant(module, "VERIFY_NONE", SSL_VERIFY_NONE);
@@ -204,6 +206,12 @@
204 PyModule_AddIntConstant(module, "OP_NO_SSLv2", SSL_OP_NO_SSLv2);206 PyModule_AddIntConstant(module, "OP_NO_SSLv2", SSL_OP_NO_SSLv2);
205 PyModule_AddIntConstant(module, "OP_NO_SSLv3", SSL_OP_NO_SSLv3);207 PyModule_AddIntConstant(module, "OP_NO_SSLv3", SSL_OP_NO_SSLv3);
206 PyModule_AddIntConstant(module, "OP_NO_TLSv1", SSL_OP_NO_TLSv1);208 PyModule_AddIntConstant(module, "OP_NO_TLSv1", SSL_OP_NO_TLSv1);
209#ifdef SSL_OP_NO_TLSv1_1
210 PyModule_AddIntConstant(module, "OP_NO_TLSv1_1", SSL_OP_NO_TLSv1_1);
211#endif
212#ifdef SSL_OP_NO_TLSv1_2
213 PyModule_AddIntConstant(module, "OP_NO_TLSv1_2", SSL_OP_NO_TLSv1_2);
214#endif
207215
208 /* More SSL option constants */216 /* More SSL option constants */
209 PyModule_AddIntConstant(module, "OP_MICROSOFT_SESS_ID_BUG", SSL_OP_MICROSOFT_SESS_ID_BUG);217 PyModule_AddIntConstant(module, "OP_MICROSOFT_SESS_ID_BUG", SSL_OP_MICROSOFT_SESS_ID_BUG);
210218
=== modified file 'OpenSSL/test/test_ssl.py'
--- OpenSSL/test/test_ssl.py 2012-03-09 23:27:50 +0000
+++ OpenSSL/test/test_ssl.py 2013-10-04 19:07:00 +0000
@@ -10,7 +10,7 @@
10from sys import platform, version_info10from sys import platform, version_info
11from socket import error, socket11from socket import error, socket
12from os import makedirs12from os import makedirs
13from os.path import join, dirname13from os.path import join
14from unittest import main14from unittest import main
15from weakref import ref15from weakref import ref
1616
@@ -22,8 +22,10 @@
22from OpenSSL.SSL import OPENSSL_VERSION_NUMBER, SSLEAY_VERSION, SSLEAY_CFLAGS22from OpenSSL.SSL import OPENSSL_VERSION_NUMBER, SSLEAY_VERSION, SSLEAY_CFLAGS
23from OpenSSL.SSL import SSLEAY_PLATFORM, SSLEAY_DIR, SSLEAY_BUILT_ON23from OpenSSL.SSL import SSLEAY_PLATFORM, SSLEAY_DIR, SSLEAY_BUILT_ON
24from OpenSSL.SSL import SENT_SHUTDOWN, RECEIVED_SHUTDOWN24from OpenSSL.SSL import SENT_SHUTDOWN, RECEIVED_SHUTDOWN
25from OpenSSL.SSL import SSLv2_METHOD, SSLv3_METHOD, SSLv23_METHOD, TLSv1_METHOD25from OpenSSL.SSL import (
26from OpenSSL.SSL import OP_NO_SSLv2, OP_NO_SSLv3, OP_SINGLE_DH_USE26 SSLv2_METHOD, SSLv3_METHOD, SSLv23_METHOD, TLSv1_METHOD,
27 TLSv1_1_METHOD, TLSv1_2_METHOD)
28from OpenSSL.SSL import OP_SINGLE_DH_USE, OP_NO_SSLv2, OP_NO_SSLv3
27from OpenSSL.SSL import (29from OpenSSL.SSL import (
28 VERIFY_PEER, VERIFY_FAIL_IF_NO_PEER_CERT, VERIFY_CLIENT_ONCE, VERIFY_NONE)30 VERIFY_PEER, VERIFY_FAIL_IF_NO_PEER_CERT, VERIFY_CLIENT_ONCE, VERIFY_NONE)
2931
@@ -67,6 +69,11 @@
67except ImportError:69except ImportError:
68 MODE_RELEASE_BUFFERS = None70 MODE_RELEASE_BUFFERS = None
6971
72try:
73 from OpenSSL.SSL import OP_NO_TLSv1, OP_NO_TLSv1_1, OP_NO_TLSv1_2
74except ImportError:
75 OP_NO_TLSv1 = OP_NO_TLSv1_1 = OP_NO_TLSv1_2 = None
76
70from OpenSSL.SSL import (77from OpenSSL.SSL import (
71 SSL_ST_CONNECT, SSL_ST_ACCEPT, SSL_ST_MASK, SSL_ST_INIT, SSL_ST_BEFORE,78 SSL_ST_CONNECT, SSL_ST_ACCEPT, SSL_ST_MASK, SSL_ST_INIT, SSL_ST_BEFORE,
72 SSL_ST_OK, SSL_ST_RENEGOTIATE,79 SSL_ST_OK, SSL_ST_RENEGOTIATE,
@@ -306,17 +313,23 @@
306 def test_method(self):313 def test_method(self):
307 """314 """
308 :py:obj:`Context` can be instantiated with one of :py:obj:`SSLv2_METHOD`,315 :py:obj:`Context` can be instantiated with one of :py:obj:`SSLv2_METHOD`,
309 :py:obj:`SSLv3_METHOD`, :py:obj:`SSLv23_METHOD`, or :py:obj:`TLSv1_METHOD`.316 :py:obj:`SSLv3_METHOD`, :py:obj:`SSLv23_METHOD`, :py:obj:`TLSv1_METHOD`,
317 :py:obj:`TLSv1_1_METHOD`, or :py:obj:`TLSv1_2_METHOD`.
310 """318 """
311 for meth in [SSLv3_METHOD, SSLv23_METHOD, TLSv1_METHOD]:319 methods = [
320 SSLv3_METHOD, SSLv23_METHOD, TLSv1_METHOD]
321 for meth in methods:
312 Context(meth)322 Context(meth)
313323
314 try:324
315 Context(SSLv2_METHOD)325 maybe = [SSLv2_METHOD, TLSv1_1_METHOD, TLSv1_2_METHOD]
316 except (Error, ValueError):326 for meth in maybe:
317 # Some versions of OpenSSL have SSLv2, some don't.327 try:
318 # Difficult to say in advance.328 Context(meth)
319 pass329 except (Error, ValueError):
330 # Some versions of OpenSSL have SSLv2 / TLSv1.1 / TLSv1.2, some
331 # don't. Difficult to say in advance.
332 pass
320333
321 self.assertRaises(TypeError, Context, "")334 self.assertRaises(TypeError, Context, "")
322 self.assertRaises(ValueError, Context, 10)335 self.assertRaises(ValueError, Context, 10)
323336
=== modified file 'doc/api/ssl.rst'
--- doc/api/ssl.rst 2012-02-16 13:10:04 +0000
+++ doc/api/ssl.rst 2013-10-04 19:07:00 +0000
@@ -14,9 +14,13 @@
14 SSLv3_METHOD14 SSLv3_METHOD
15 SSLv23_METHOD15 SSLv23_METHOD
16 TLSv1_METHOD16 TLSv1_METHOD
17 TLSv1_1_METHOD
18 TLSv1_2_METHOD
1719
18 These constants represent the different SSL methods to use when creating a20 These constants represent the different SSL methods to use when creating a
19 context object.21 context object. If the underlying OpenSSL build is missing support for any
22 of these protocols, constructing a :py:class:`Context` using the
23 corresponding :py:const:`*_METHOD` will raise an exception.
2024
2125
22.. py:data:: VERIFY_NONE26.. py:data:: VERIFY_NONE
@@ -35,22 +39,48 @@
3539
3640
37.. py:data:: OP_SINGLE_DH_USE41.. py:data:: OP_SINGLE_DH_USE
38 OP_EPHEMERAL_RSA42
39 OP_NO_SSLv243 Constant used with :py:meth:`set_options` of Context objects.
44
45 When this option is used, a new key will always be created when using
46 ephemeral Diffie-Hellman.
47
48
49.. py:data:: OP_EPHEMERAL_RSA
50
51 Constant used with :py:meth:`set_options` of Context objects.
52
53 When this option is used, ephemeral RSA keys will always be used when doing
54 RSA operations.
55
56
57.. py:data:: OP_NO_TICKET
58
59 Constant used with :py:meth:`set_options` of Context objects.
60
61 When this option is used, the session ticket extension will not be used.
62
63
64.. py:data:: OP_NO_COMPRESSION
65
66 Constant used with :py:meth:`set_options` of Context objects.
67
68 When this option is used, compression will not be used.
69
70
71.. py:data:: OP_NO_SSLv2
40 OP_NO_SSLv372 OP_NO_SSLv3
41 OP_NO_TLSv173 OP_NO_TLSv1
42 OP_NO_TICKET74 OP_NO_TLSv1_1
43 OP_NO_COMPRESSION75 OP_NO_TLSv1_2
4476
45 Constants used with :py:meth:`set_options` of Context objects.77 Constants used with :py:meth:`set_options` of Context objects.
4678
47 :py:const:`OP_SINGLE_DH_USE` means to always create a new key when using79 Each of these options disables one version of the SSL/TLS protocol. This
48 ephemeral Diffie-Hellman. :py:const:`OP_EPHEMERAL_RSA` means to always use80 is interesting if you're using e.g. :py:const:`SSLv23_METHOD` to get an
49 ephemeral RSA keys when doing RSA operations. :py:const:`OP_NO_SSLv2`,81 SSLv2-compatible handshake, but don't want to use SSLv2. If the underlying
50 :py:const:`OP_NO_SSLv3` and :py:const:`OP_NO_TLSv1` means to disable those82 OpenSSL build is missing support for any of these protocols, the
51 specific protocols. This is interesting if you're using e.g.83 :py:const:`OP_NO_*` constant may be undefined.
52 :py:const:`SSLv23_METHOD` to get an SSLv2-compatible handshake, but don't want
53 to use SSLv2.
5484
5585
56.. py:data:: MODE_NO_COMPRESSION86.. py:data:: MODE_NO_COMPRESSION
@@ -69,6 +99,7 @@
69 information to retrieve. See the man page for the :py:func:`SSLeay_version` C99 information to retrieve. See the man page for the :py:func:`SSLeay_version` C
70 API for details.100 API for details.
71101
102
72.. py:data:: SESS_CACHE_OFF103.. py:data:: SESS_CACHE_OFF
73 SESS_CACHE_CLIENT104 SESS_CACHE_CLIENT
74 SESS_CACHE_SERVER105 SESS_CACHE_SERVER
@@ -84,6 +115,7 @@
84115
85 .. versionadded:: 0.14116 .. versionadded:: 0.14
86117
118
87.. py:data:: OPENSSL_VERSION_NUMBER119.. py:data:: OPENSSL_VERSION_NUMBER
88120
89 An integer giving the version number of the OpenSSL library used to build this121 An integer giving the version number of the OpenSSL library used to build this
@@ -109,7 +141,8 @@
109 more SSL connections.141 more SSL connections.
110142
111 *method* should be :py:const:`SSLv2_METHOD`, :py:const:`SSLv3_METHOD`,143 *method* should be :py:const:`SSLv2_METHOD`, :py:const:`SSLv3_METHOD`,
112 :py:const:`SSLv23_METHOD` or :py:const:`TLSv1_METHOD`.144 :py:const:`SSLv23_METHOD`, :py:const:`TLSv1_METHOD`, :py:const:`TLSv1_1_METHOD`,
145 or :py:const:`TLSv1_2_METHOD`.
113146
114147
115.. py:class:: Session()148.. py:class:: Session()

Subscribers

People subscribed via source and target branches

to status/vote changes: