Skip to content

Commit a669443

Browse files
bpo-40457: Support OpenSSL without TLS 1.0/1.1 (GH-19862)
OpenSSL can be build without support for TLS 1.0 and 1.1. The ssl module now correctly adheres to OPENSSL_NO_TLS1 and OPENSSL_NO_TLS1_1 flags. Also update multissltest to test with latest OpenSSL and LibreSSL releases. Signed-off-by: Christian Heimes <christian@python.org> Automerge-Triggered-By: @tiran (cherry picked from commit 6e8cda9) Co-authored-by: Christian Heimes <christian@python.org>
1 parent c3d025a commit a669443

File tree

3 files changed

+33
-38
lines changed

3 files changed

+33
-38
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
The ssl module now support OpenSSL builds without TLS 1.0 and 1.1 methods.

Modules/_ssl.c

Lines changed: 27 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -149,15 +149,6 @@ static void _PySSLFixErrno(void) {
149149
# define PY_OPENSSL_1_1_API 1
150150
#endif
151151

152-
/* Openssl comes with TLSv1.1 and TLSv1.2 between 1.0.0h and 1.0.1
153-
http://www.openssl.org/news/changelog.html
154-
*/
155-
#if OPENSSL_VERSION_NUMBER >= 0x10001000L
156-
# define HAVE_TLSv1_2 1
157-
#else
158-
# define HAVE_TLSv1_2 0
159-
#endif
160-
161152
/* SNI support (client- and server-side) appeared in OpenSSL 1.0.0 and 0.9.8f
162153
* This includes the SSL_set_SSL_CTX() function.
163154
*/
@@ -328,13 +319,9 @@ enum py_ssl_version {
328319
PY_SSL_VERSION_SSL2,
329320
PY_SSL_VERSION_SSL3=1,
330321
PY_SSL_VERSION_TLS, /* SSLv23 */
331-
#if HAVE_TLSv1_2
332322
PY_SSL_VERSION_TLS1,
333323
PY_SSL_VERSION_TLS1_1,
334324
PY_SSL_VERSION_TLS1_2,
335-
#else
336-
PY_SSL_VERSION_TLS1,
337-
#endif
338325
PY_SSL_VERSION_TLS_CLIENT=0x10,
339326
PY_SSL_VERSION_TLS_SERVER,
340327
};
@@ -3088,35 +3075,45 @@ _ssl__SSLContext_impl(PyTypeObject *type, int proto_version)
30883075
#endif
30893076

30903077
PySSL_BEGIN_ALLOW_THREADS
3091-
if (proto_version == PY_SSL_VERSION_TLS1)
3078+
switch(proto_version) {
3079+
#if defined(SSL3_VERSION) && !defined(OPENSSL_NO_SSL3)
3080+
case PY_SSL_VERSION_SSL3:
3081+
ctx = SSL_CTX_new(SSLv3_method());
3082+
break;
3083+
#endif
3084+
#if defined(TLS1_VERSION) && !defined(OPENSSL_NO_TLS1)
3085+
case PY_SSL_VERSION_TLS1:
30923086
ctx = SSL_CTX_new(TLSv1_method());
3093-
#if HAVE_TLSv1_2
3094-
else if (proto_version == PY_SSL_VERSION_TLS1_1)
3095-
ctx = SSL_CTX_new(TLSv1_1_method());
3096-
else if (proto_version == PY_SSL_VERSION_TLS1_2)
3097-
ctx = SSL_CTX_new(TLSv1_2_method());
3087+
break;
30983088
#endif
3099-
#ifndef OPENSSL_NO_SSL3
3100-
else if (proto_version == PY_SSL_VERSION_SSL3)
3101-
ctx = SSL_CTX_new(SSLv3_method());
3089+
#if defined(TLS1_1_VERSION) && !defined(OPENSSL_NO_TLS1_1)
3090+
case PY_SSL_VERSION_TLS1_1:
3091+
ctx = SSL_CTX_new(TLSv1_1_method());
3092+
break;
31023093
#endif
3103-
#ifndef OPENSSL_NO_SSL2
3104-
else if (proto_version == PY_SSL_VERSION_SSL2)
3105-
ctx = SSL_CTX_new(SSLv2_method());
3094+
#if defined(TLS1_2_VERSION) && !defined(OPENSSL_NO_TLS1_2)
3095+
case PY_SSL_VERSION_TLS1_2:
3096+
ctx = SSL_CTX_new(TLSv1_2_method());
3097+
break;
31063098
#endif
3107-
else if (proto_version == PY_SSL_VERSION_TLS) /* SSLv23 */
3099+
case PY_SSL_VERSION_TLS:
3100+
/* SSLv23 */
31083101
ctx = SSL_CTX_new(TLS_method());
3109-
else if (proto_version == PY_SSL_VERSION_TLS_CLIENT)
3102+
break;
3103+
case PY_SSL_VERSION_TLS_CLIENT:
31103104
ctx = SSL_CTX_new(TLS_client_method());
3111-
else if (proto_version == PY_SSL_VERSION_TLS_SERVER)
3105+
break;
3106+
case PY_SSL_VERSION_TLS_SERVER:
31123107
ctx = SSL_CTX_new(TLS_server_method());
3113-
else
3108+
break;
3109+
default:
31143110
proto_version = -1;
3111+
}
31153112
PySSL_END_ALLOW_THREADS
31163113

31173114
if (proto_version == -1) {
31183115
PyErr_SetString(PyExc_ValueError,
3119-
"invalid protocol version");
3116+
"invalid or unsupported protocol version");
31203117
return NULL;
31213118
}
31223119
if (ctx == NULL) {
@@ -6188,23 +6185,19 @@ PyInit__ssl(void)
61886185
PY_SSL_VERSION_TLS_SERVER);
61896186
PyModule_AddIntConstant(m, "PROTOCOL_TLSv1",
61906187
PY_SSL_VERSION_TLS1);
6191-
#if HAVE_TLSv1_2
61926188
PyModule_AddIntConstant(m, "PROTOCOL_TLSv1_1",
61936189
PY_SSL_VERSION_TLS1_1);
61946190
PyModule_AddIntConstant(m, "PROTOCOL_TLSv1_2",
61956191
PY_SSL_VERSION_TLS1_2);
6196-
#endif
61976192

61986193
/* protocol options */
61996194
PyModule_AddIntConstant(m, "OP_ALL",
62006195
SSL_OP_ALL & ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS);
62016196
PyModule_AddIntConstant(m, "OP_NO_SSLv2", SSL_OP_NO_SSLv2);
62026197
PyModule_AddIntConstant(m, "OP_NO_SSLv3", SSL_OP_NO_SSLv3);
62036198
PyModule_AddIntConstant(m, "OP_NO_TLSv1", SSL_OP_NO_TLSv1);
6204-
#if HAVE_TLSv1_2
62056199
PyModule_AddIntConstant(m, "OP_NO_TLSv1_1", SSL_OP_NO_TLSv1_1);
62066200
PyModule_AddIntConstant(m, "OP_NO_TLSv1_2", SSL_OP_NO_TLSv1_2);
6207-
#endif
62086201
#ifdef SSL_OP_NO_TLSv1_3
62096202
PyModule_AddIntConstant(m, "OP_NO_TLSv1_3", SSL_OP_NO_TLSv1_3);
62106203
#else

Tools/ssl/multissltests.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,20 +43,21 @@
4343
log = logging.getLogger("multissl")
4444

4545
OPENSSL_OLD_VERSIONS = [
46+
"1.0.2u",
47+
"1.1.0l",
4648
]
4749

4850
OPENSSL_RECENT_VERSIONS = [
49-
"1.0.2u",
50-
"1.1.0l",
5151
"1.1.1g",
5252
# "3.0.0-alpha2"
5353
]
5454

5555
LIBRESSL_OLD_VERSIONS = [
56+
"2.9.2",
5657
]
5758

5859
LIBRESSL_RECENT_VERSIONS = [
59-
"2.9.2",
60+
"3.1.0",
6061
]
6162

6263
# store files in ../multissl
@@ -80,7 +81,7 @@
8081
parser.add_argument(
8182
'--disable-ancient',
8283
action='store_true',
83-
help="Don't test OpenSSL < 1.0.2 and LibreSSL < 2.5.3.",
84+
help="Don't test OpenSSL and LibreSSL versions without upstream support",
8485
)
8586
parser.add_argument(
8687
'--openssl',

0 commit comments

Comments
 (0)