Merge lp:~exarkun/pyopenssl/tlsv1_1or2 into lp:~exarkun/pyopenssl/trunk
- tlsv1_1or2
- Merge into 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 | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Jean-Paul Calderone | Pending | ||
Review via email: mp+189401@code.launchpad.net |
Commit message
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 : | # |
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
1 | === modified file 'OpenSSL/ssl/context.c' | |||
2 | --- OpenSSL/ssl/context.c 2012-03-09 23:04:04 +0000 | |||
3 | +++ OpenSSL/ssl/context.c 2013-10-04 19:07:00 +0000 | |||
4 | @@ -282,9 +282,16 @@ | |||
5 | 282 | #ifdef OPENSSL_NO_SSL2 | 282 | #ifdef OPENSSL_NO_SSL2 |
6 | 283 | #define SSLv2_METHOD_TEXT "" | 283 | #define SSLv2_METHOD_TEXT "" |
7 | 284 | #else | 284 | #else |
11 | 285 | #define SSLv2_METHOD_TEXT "SSLv2_METHOD, " | 285 | #define SSLv2_METHOD_TEXT " SSLv2_METHOD" |
12 | 286 | #endif | 286 | #endif |
13 | 287 | 287 | ||
14 | 288 | #ifdef SSL_OP_NO_TLSv1_1 | ||
15 | 289 | #define TLSv1_1_METHOD_TEXT " TLSv1_1_METHOD" | ||
16 | 290 | #endif | ||
17 | 291 | |||
18 | 292 | #ifdef SSL_OP_NO_TLSv1_2 | ||
19 | 293 | #define TLSv1_2_METHOD_TEXT " TLSv1_2_METHOD" | ||
20 | 294 | #endif | ||
21 | 288 | 295 | ||
22 | 289 | static char ssl_Context_doc[] = "\n\ | 296 | static char ssl_Context_doc[] = "\n\ |
23 | 290 | Context(method) -> Context instance\n\ | 297 | Context(method) -> Context instance\n\ |
24 | @@ -292,11 +299,12 @@ | |||
25 | 292 | OpenSSL.SSL.Context instances define the parameters for setting up new SSL\n\ | 299 | OpenSSL.SSL.Context instances define the parameters for setting up new SSL\n\ |
26 | 293 | connections.\n\ | 300 | connections.\n\ |
27 | 294 | \n\ | 301 | \n\ |
30 | 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\ |
29 | 296 | TLSv1_METHOD.\n\ | ||
31 | 297 | "; | 303 | "; |
32 | 298 | 304 | ||
33 | 299 | #undef SSLv2_METHOD_TEXT | 305 | #undef SSLv2_METHOD_TEXT |
34 | 306 | #undef TLSv1_1_METHOD_TEXT | ||
35 | 307 | #undef TLSv1_2_METHOD_TEXT | ||
36 | 300 | 308 | ||
37 | 301 | static char ssl_Context_load_verify_locations_doc[] = "\n\ | 309 | static char ssl_Context_load_verify_locations_doc[] = "\n\ |
38 | 302 | Let SSL know where we can find trusted certificates for the certificate\n\ | 310 | Let SSL know where we can find trusted certificates for the certificate\n\ |
39 | @@ -1262,6 +1270,22 @@ | |||
40 | 1262 | case ssl_TLSv1_METHOD: | 1270 | case ssl_TLSv1_METHOD: |
41 | 1263 | method = TLSv1_method(); | 1271 | method = TLSv1_method(); |
42 | 1264 | break; | 1272 | break; |
43 | 1273 | case ssl_TLSv1_1_METHOD: | ||
44 | 1274 | #ifdef SSL_OP_NO_TLSv1_1 | ||
45 | 1275 | method = TLSv1_1_method(); | ||
46 | 1276 | #else | ||
47 | 1277 | PyErr_SetString(PyExc_ValueError, "TLSv1_1_method not supported by this version of OpenSSL"); | ||
48 | 1278 | return NULL; | ||
49 | 1279 | #endif | ||
50 | 1280 | break; | ||
51 | 1281 | case ssl_TLSv1_2_METHOD: | ||
52 | 1282 | #ifdef SSL_OP_NO_TLSv1_2 | ||
53 | 1283 | method = TLSv1_2_method(); | ||
54 | 1284 | #else | ||
55 | 1285 | PyErr_SetString(PyExc_ValueError, "TLSv1_2_method not supported by this version of OpenSSL"); | ||
56 | 1286 | return NULL; | ||
57 | 1287 | #endif | ||
58 | 1288 | break; | ||
59 | 1265 | default: | 1289 | default: |
60 | 1266 | PyErr_SetString(PyExc_ValueError, "No such protocol"); | 1290 | PyErr_SetString(PyExc_ValueError, "No such protocol"); |
61 | 1267 | return NULL; | 1291 | return NULL; |
62 | 1268 | 1292 | ||
63 | === modified file 'OpenSSL/ssl/context.h' | |||
64 | --- OpenSSL/ssl/context.h 2011-05-26 22:47:00 +0000 | |||
65 | +++ OpenSSL/ssl/context.h 2013-10-04 19:07:00 +0000 | |||
66 | @@ -38,6 +38,8 @@ | |||
67 | 38 | #define ssl_SSLv3_METHOD (2) | 38 | #define ssl_SSLv3_METHOD (2) |
68 | 39 | #define ssl_SSLv23_METHOD (3) | 39 | #define ssl_SSLv23_METHOD (3) |
69 | 40 | #define ssl_TLSv1_METHOD (4) | 40 | #define ssl_TLSv1_METHOD (4) |
70 | 41 | #define ssl_TLSv1_1_METHOD (5) | ||
71 | 42 | #define ssl_TLSv1_2_METHOD (6) | ||
72 | 41 | 43 | ||
73 | 42 | 44 | ||
74 | 43 | #endif | 45 | #endif |
75 | 44 | 46 | ||
76 | === modified file 'OpenSSL/ssl/ssl.c' | |||
77 | --- OpenSSL/ssl/ssl.c 2012-02-13 14:10:15 +0000 | |||
78 | +++ OpenSSL/ssl/ssl.c 2013-10-04 19:07:00 +0000 | |||
79 | @@ -185,6 +185,8 @@ | |||
80 | 185 | PyModule_AddIntConstant(module, "SSLv3_METHOD", ssl_SSLv3_METHOD); | 185 | PyModule_AddIntConstant(module, "SSLv3_METHOD", ssl_SSLv3_METHOD); |
81 | 186 | PyModule_AddIntConstant(module, "SSLv23_METHOD", ssl_SSLv23_METHOD); | 186 | PyModule_AddIntConstant(module, "SSLv23_METHOD", ssl_SSLv23_METHOD); |
82 | 187 | PyModule_AddIntConstant(module, "TLSv1_METHOD", ssl_TLSv1_METHOD); | 187 | PyModule_AddIntConstant(module, "TLSv1_METHOD", ssl_TLSv1_METHOD); |
83 | 188 | PyModule_AddIntConstant(module, "TLSv1_1_METHOD", ssl_TLSv1_1_METHOD); | ||
84 | 189 | PyModule_AddIntConstant(module, "TLSv1_2_METHOD", ssl_TLSv1_2_METHOD); | ||
85 | 188 | 190 | ||
86 | 189 | /* Verify constants */ | 191 | /* Verify constants */ |
87 | 190 | PyModule_AddIntConstant(module, "VERIFY_NONE", SSL_VERIFY_NONE); | 192 | PyModule_AddIntConstant(module, "VERIFY_NONE", SSL_VERIFY_NONE); |
88 | @@ -204,6 +206,12 @@ | |||
89 | 204 | PyModule_AddIntConstant(module, "OP_NO_SSLv2", SSL_OP_NO_SSLv2); | 206 | PyModule_AddIntConstant(module, "OP_NO_SSLv2", SSL_OP_NO_SSLv2); |
90 | 205 | PyModule_AddIntConstant(module, "OP_NO_SSLv3", SSL_OP_NO_SSLv3); | 207 | PyModule_AddIntConstant(module, "OP_NO_SSLv3", SSL_OP_NO_SSLv3); |
91 | 206 | PyModule_AddIntConstant(module, "OP_NO_TLSv1", SSL_OP_NO_TLSv1); | 208 | PyModule_AddIntConstant(module, "OP_NO_TLSv1", SSL_OP_NO_TLSv1); |
92 | 209 | #ifdef SSL_OP_NO_TLSv1_1 | ||
93 | 210 | PyModule_AddIntConstant(module, "OP_NO_TLSv1_1", SSL_OP_NO_TLSv1_1); | ||
94 | 211 | #endif | ||
95 | 212 | #ifdef SSL_OP_NO_TLSv1_2 | ||
96 | 213 | PyModule_AddIntConstant(module, "OP_NO_TLSv1_2", SSL_OP_NO_TLSv1_2); | ||
97 | 214 | #endif | ||
98 | 207 | 215 | ||
99 | 208 | /* More SSL option constants */ | 216 | /* More SSL option constants */ |
100 | 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); |
101 | 210 | 218 | ||
102 | === modified file 'OpenSSL/test/test_ssl.py' | |||
103 | --- OpenSSL/test/test_ssl.py 2012-03-09 23:27:50 +0000 | |||
104 | +++ OpenSSL/test/test_ssl.py 2013-10-04 19:07:00 +0000 | |||
105 | @@ -10,7 +10,7 @@ | |||
106 | 10 | from sys import platform, version_info | 10 | from sys import platform, version_info |
107 | 11 | from socket import error, socket | 11 | from socket import error, socket |
108 | 12 | from os import makedirs | 12 | from os import makedirs |
110 | 13 | from os.path import join, dirname | 13 | from os.path import join |
111 | 14 | from unittest import main | 14 | from unittest import main |
112 | 15 | from weakref import ref | 15 | from weakref import ref |
113 | 16 | 16 | ||
114 | @@ -22,8 +22,10 @@ | |||
115 | 22 | from OpenSSL.SSL import OPENSSL_VERSION_NUMBER, SSLEAY_VERSION, SSLEAY_CFLAGS | 22 | from OpenSSL.SSL import OPENSSL_VERSION_NUMBER, SSLEAY_VERSION, SSLEAY_CFLAGS |
116 | 23 | from OpenSSL.SSL import SSLEAY_PLATFORM, SSLEAY_DIR, SSLEAY_BUILT_ON | 23 | from OpenSSL.SSL import SSLEAY_PLATFORM, SSLEAY_DIR, SSLEAY_BUILT_ON |
117 | 24 | from OpenSSL.SSL import SENT_SHUTDOWN, RECEIVED_SHUTDOWN | 24 | from OpenSSL.SSL import SENT_SHUTDOWN, RECEIVED_SHUTDOWN |
120 | 25 | from OpenSSL.SSL import SSLv2_METHOD, SSLv3_METHOD, SSLv23_METHOD, TLSv1_METHOD | 25 | from OpenSSL.SSL import ( |
121 | 26 | from OpenSSL.SSL import OP_NO_SSLv2, OP_NO_SSLv3, OP_SINGLE_DH_USE | 26 | SSLv2_METHOD, SSLv3_METHOD, SSLv23_METHOD, TLSv1_METHOD, |
122 | 27 | TLSv1_1_METHOD, TLSv1_2_METHOD) | ||
123 | 28 | from OpenSSL.SSL import OP_SINGLE_DH_USE, OP_NO_SSLv2, OP_NO_SSLv3 | ||
124 | 27 | from OpenSSL.SSL import ( | 29 | from OpenSSL.SSL import ( |
125 | 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) |
126 | 29 | 31 | ||
127 | @@ -67,6 +69,11 @@ | |||
128 | 67 | except ImportError: | 69 | except ImportError: |
129 | 68 | MODE_RELEASE_BUFFERS = None | 70 | MODE_RELEASE_BUFFERS = None |
130 | 69 | 71 | ||
131 | 72 | try: | ||
132 | 73 | from OpenSSL.SSL import OP_NO_TLSv1, OP_NO_TLSv1_1, OP_NO_TLSv1_2 | ||
133 | 74 | except ImportError: | ||
134 | 75 | OP_NO_TLSv1 = OP_NO_TLSv1_1 = OP_NO_TLSv1_2 = None | ||
135 | 76 | |||
136 | 70 | from OpenSSL.SSL import ( | 77 | from OpenSSL.SSL import ( |
137 | 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, |
138 | 72 | SSL_ST_OK, SSL_ST_RENEGOTIATE, | 79 | SSL_ST_OK, SSL_ST_RENEGOTIATE, |
139 | @@ -306,17 +313,23 @@ | |||
140 | 306 | def test_method(self): | 313 | def test_method(self): |
141 | 307 | """ | 314 | """ |
142 | 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`, |
144 | 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`, |
145 | 317 | :py:obj:`TLSv1_1_METHOD`, or :py:obj:`TLSv1_2_METHOD`. | ||
146 | 310 | """ | 318 | """ |
148 | 311 | for meth in [SSLv3_METHOD, SSLv23_METHOD, TLSv1_METHOD]: | 319 | methods = [ |
149 | 320 | SSLv3_METHOD, SSLv23_METHOD, TLSv1_METHOD] | ||
150 | 321 | for meth in methods: | ||
151 | 312 | Context(meth) | 322 | Context(meth) |
152 | 313 | 323 | ||
159 | 314 | try: | 324 | |
160 | 315 | Context(SSLv2_METHOD) | 325 | maybe = [SSLv2_METHOD, TLSv1_1_METHOD, TLSv1_2_METHOD] |
161 | 316 | except (Error, ValueError): | 326 | for meth in maybe: |
162 | 317 | # Some versions of OpenSSL have SSLv2, some don't. | 327 | try: |
163 | 318 | # Difficult to say in advance. | 328 | Context(meth) |
164 | 319 | pass | 329 | except (Error, ValueError): |
165 | 330 | # Some versions of OpenSSL have SSLv2 / TLSv1.1 / TLSv1.2, some | ||
166 | 331 | # don't. Difficult to say in advance. | ||
167 | 332 | pass | ||
168 | 320 | 333 | ||
169 | 321 | self.assertRaises(TypeError, Context, "") | 334 | self.assertRaises(TypeError, Context, "") |
170 | 322 | self.assertRaises(ValueError, Context, 10) | 335 | self.assertRaises(ValueError, Context, 10) |
171 | 323 | 336 | ||
172 | === modified file 'doc/api/ssl.rst' | |||
173 | --- doc/api/ssl.rst 2012-02-16 13:10:04 +0000 | |||
174 | +++ doc/api/ssl.rst 2013-10-04 19:07:00 +0000 | |||
175 | @@ -14,9 +14,13 @@ | |||
176 | 14 | SSLv3_METHOD | 14 | SSLv3_METHOD |
177 | 15 | SSLv23_METHOD | 15 | SSLv23_METHOD |
178 | 16 | TLSv1_METHOD | 16 | TLSv1_METHOD |
179 | 17 | TLSv1_1_METHOD | ||
180 | 18 | TLSv1_2_METHOD | ||
181 | 17 | 19 | ||
182 | 18 | These constants represent the different SSL methods to use when creating a | 20 | These constants represent the different SSL methods to use when creating a |
184 | 19 | context object. | 21 | context object. If the underlying OpenSSL build is missing support for any |
185 | 22 | of these protocols, constructing a :py:class:`Context` using the | ||
186 | 23 | corresponding :py:const:`*_METHOD` will raise an exception. | ||
187 | 20 | 24 | ||
188 | 21 | 25 | ||
189 | 22 | .. py:data:: VERIFY_NONE | 26 | .. py:data:: VERIFY_NONE |
190 | @@ -35,22 +39,48 @@ | |||
191 | 35 | 39 | ||
192 | 36 | 40 | ||
193 | 37 | .. py:data:: OP_SINGLE_DH_USE | 41 | .. py:data:: OP_SINGLE_DH_USE |
196 | 38 | OP_EPHEMERAL_RSA | 42 | |
197 | 39 | OP_NO_SSLv2 | 43 | Constant used with :py:meth:`set_options` of Context objects. |
198 | 44 | |||
199 | 45 | When this option is used, a new key will always be created when using | ||
200 | 46 | ephemeral Diffie-Hellman. | ||
201 | 47 | |||
202 | 48 | |||
203 | 49 | .. py:data:: OP_EPHEMERAL_RSA | ||
204 | 50 | |||
205 | 51 | Constant used with :py:meth:`set_options` of Context objects. | ||
206 | 52 | |||
207 | 53 | When this option is used, ephemeral RSA keys will always be used when doing | ||
208 | 54 | RSA operations. | ||
209 | 55 | |||
210 | 56 | |||
211 | 57 | .. py:data:: OP_NO_TICKET | ||
212 | 58 | |||
213 | 59 | Constant used with :py:meth:`set_options` of Context objects. | ||
214 | 60 | |||
215 | 61 | When this option is used, the session ticket extension will not be used. | ||
216 | 62 | |||
217 | 63 | |||
218 | 64 | .. py:data:: OP_NO_COMPRESSION | ||
219 | 65 | |||
220 | 66 | Constant used with :py:meth:`set_options` of Context objects. | ||
221 | 67 | |||
222 | 68 | When this option is used, compression will not be used. | ||
223 | 69 | |||
224 | 70 | |||
225 | 71 | .. py:data:: OP_NO_SSLv2 | ||
226 | 40 | OP_NO_SSLv3 | 72 | OP_NO_SSLv3 |
227 | 41 | OP_NO_TLSv1 | 73 | OP_NO_TLSv1 |
230 | 42 | OP_NO_TICKET | 74 | OP_NO_TLSv1_1 |
231 | 43 | OP_NO_COMPRESSION | 75 | OP_NO_TLSv1_2 |
232 | 44 | 76 | ||
233 | 45 | Constants used with :py:meth:`set_options` of Context objects. | 77 | Constants used with :py:meth:`set_options` of Context objects. |
234 | 46 | 78 | ||
242 | 47 | :py:const:`OP_SINGLE_DH_USE` means to always create a new key when using | 79 | Each of these options disables one version of the SSL/TLS protocol. This |
243 | 48 | ephemeral Diffie-Hellman. :py:const:`OP_EPHEMERAL_RSA` means to always use | 80 | is interesting if you're using e.g. :py:const:`SSLv23_METHOD` to get an |
244 | 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 |
245 | 50 | :py:const:`OP_NO_SSLv3` and :py:const:`OP_NO_TLSv1` means to disable those | 82 | OpenSSL build is missing support for any of these protocols, the |
246 | 51 | specific protocols. This is interesting if you're using e.g. | 83 | :py:const:`OP_NO_*` constant may be undefined. |
240 | 52 | :py:const:`SSLv23_METHOD` to get an SSLv2-compatible handshake, but don't want | ||
241 | 53 | to use SSLv2. | ||
247 | 54 | 84 | ||
248 | 55 | 85 | ||
249 | 56 | .. py:data:: MODE_NO_COMPRESSION | 86 | .. py:data:: MODE_NO_COMPRESSION |
250 | @@ -69,6 +99,7 @@ | |||
251 | 69 | information to retrieve. See the man page for the :py:func:`SSLeay_version` C | 99 | information to retrieve. See the man page for the :py:func:`SSLeay_version` C |
252 | 70 | API for details. | 100 | API for details. |
253 | 71 | 101 | ||
254 | 102 | |||
255 | 72 | .. py:data:: SESS_CACHE_OFF | 103 | .. py:data:: SESS_CACHE_OFF |
256 | 73 | SESS_CACHE_CLIENT | 104 | SESS_CACHE_CLIENT |
257 | 74 | SESS_CACHE_SERVER | 105 | SESS_CACHE_SERVER |
258 | @@ -84,6 +115,7 @@ | |||
259 | 84 | 115 | ||
260 | 85 | .. versionadded:: 0.14 | 116 | .. versionadded:: 0.14 |
261 | 86 | 117 | ||
262 | 118 | |||
263 | 87 | .. py:data:: OPENSSL_VERSION_NUMBER | 119 | .. py:data:: OPENSSL_VERSION_NUMBER |
264 | 88 | 120 | ||
265 | 89 | An integer giving the version number of the OpenSSL library used to build this | 121 | An integer giving the version number of the OpenSSL library used to build this |
266 | @@ -109,7 +141,8 @@ | |||
267 | 109 | more SSL connections. | 141 | more SSL connections. |
268 | 110 | 142 | ||
269 | 111 | *method* should be :py:const:`SSLv2_METHOD`, :py:const:`SSLv3_METHOD`, | 143 | *method* should be :py:const:`SSLv2_METHOD`, :py:const:`SSLv3_METHOD`, |
271 | 112 | :py:const:`SSLv23_METHOD` or :py:const:`TLSv1_METHOD`. | 144 | :py:const:`SSLv23_METHOD`, :py:const:`TLSv1_METHOD`, :py:const:`TLSv1_1_METHOD`, |
272 | 145 | or :py:const:`TLSv1_2_METHOD`. | ||
273 | 113 | 146 | ||
274 | 114 | 147 | ||
275 | 115 | .. py:class:: Session() | 148 | .. py:class:: Session() |
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?