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
This commit is contained in:
Christian Heimes 2020-05-16 03:33:05 +02:00 committed by GitHub
parent 6b6092f533
commit 6e8cda91d9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 34 additions and 39 deletions

View File

@ -0,0 +1 @@
The ssl module now support OpenSSL builds without TLS 1.0 and 1.1 methods.

View File

@ -147,15 +147,6 @@ static void _PySSLFixErrno(void) {
# define PY_OPENSSL_1_1_API 1 # define PY_OPENSSL_1_1_API 1
#endif #endif
/* Openssl comes with TLSv1.1 and TLSv1.2 between 1.0.0h and 1.0.1
http://www.openssl.org/news/changelog.html
*/
#if OPENSSL_VERSION_NUMBER >= 0x10001000L
# define HAVE_TLSv1_2 1
#else
# define HAVE_TLSv1_2 0
#endif
/* SNI support (client- and server-side) appeared in OpenSSL 1.0.0 and 0.9.8f /* SNI support (client- and server-side) appeared in OpenSSL 1.0.0 and 0.9.8f
* This includes the SSL_set_SSL_CTX() function. * This includes the SSL_set_SSL_CTX() function.
*/ */
@ -326,13 +317,9 @@ enum py_ssl_version {
PY_SSL_VERSION_SSL2, PY_SSL_VERSION_SSL2,
PY_SSL_VERSION_SSL3=1, PY_SSL_VERSION_SSL3=1,
PY_SSL_VERSION_TLS, /* SSLv23 */ PY_SSL_VERSION_TLS, /* SSLv23 */
#if HAVE_TLSv1_2
PY_SSL_VERSION_TLS1, PY_SSL_VERSION_TLS1,
PY_SSL_VERSION_TLS1_1, PY_SSL_VERSION_TLS1_1,
PY_SSL_VERSION_TLS1_2, PY_SSL_VERSION_TLS1_2,
#else
PY_SSL_VERSION_TLS1,
#endif
PY_SSL_VERSION_TLS_CLIENT=0x10, PY_SSL_VERSION_TLS_CLIENT=0x10,
PY_SSL_VERSION_TLS_SERVER, PY_SSL_VERSION_TLS_SERVER,
}; };
@ -3086,35 +3073,45 @@ _ssl__SSLContext_impl(PyTypeObject *type, int proto_version)
#endif #endif
PySSL_BEGIN_ALLOW_THREADS PySSL_BEGIN_ALLOW_THREADS
if (proto_version == PY_SSL_VERSION_TLS1) switch(proto_version) {
ctx = SSL_CTX_new(TLSv1_method()); #if defined(SSL3_VERSION) && !defined(OPENSSL_NO_SSL3)
#if HAVE_TLSv1_2 case PY_SSL_VERSION_SSL3:
else if (proto_version == PY_SSL_VERSION_TLS1_1)
ctx = SSL_CTX_new(TLSv1_1_method());
else if (proto_version == PY_SSL_VERSION_TLS1_2)
ctx = SSL_CTX_new(TLSv1_2_method());
#endif
#ifndef OPENSSL_NO_SSL3
else if (proto_version == PY_SSL_VERSION_SSL3)
ctx = SSL_CTX_new(SSLv3_method()); ctx = SSL_CTX_new(SSLv3_method());
break;
#endif #endif
#ifndef OPENSSL_NO_SSL2 #if defined(TLS1_VERSION) && !defined(OPENSSL_NO_TLS1)
else if (proto_version == PY_SSL_VERSION_SSL2) case PY_SSL_VERSION_TLS1:
ctx = SSL_CTX_new(SSLv2_method()); ctx = SSL_CTX_new(TLSv1_method());
break;
#endif #endif
else if (proto_version == PY_SSL_VERSION_TLS) /* SSLv23 */ #if defined(TLS1_1_VERSION) && !defined(OPENSSL_NO_TLS1_1)
case PY_SSL_VERSION_TLS1_1:
ctx = SSL_CTX_new(TLSv1_1_method());
break;
#endif
#if defined(TLS1_2_VERSION) && !defined(OPENSSL_NO_TLS1_2)
case PY_SSL_VERSION_TLS1_2:
ctx = SSL_CTX_new(TLSv1_2_method());
break;
#endif
case PY_SSL_VERSION_TLS:
/* SSLv23 */
ctx = SSL_CTX_new(TLS_method()); ctx = SSL_CTX_new(TLS_method());
else if (proto_version == PY_SSL_VERSION_TLS_CLIENT) break;
case PY_SSL_VERSION_TLS_CLIENT:
ctx = SSL_CTX_new(TLS_client_method()); ctx = SSL_CTX_new(TLS_client_method());
else if (proto_version == PY_SSL_VERSION_TLS_SERVER) break;
case PY_SSL_VERSION_TLS_SERVER:
ctx = SSL_CTX_new(TLS_server_method()); ctx = SSL_CTX_new(TLS_server_method());
else break;
default:
proto_version = -1; proto_version = -1;
}
PySSL_END_ALLOW_THREADS PySSL_END_ALLOW_THREADS
if (proto_version == -1) { if (proto_version == -1) {
PyErr_SetString(PyExc_ValueError, PyErr_SetString(PyExc_ValueError,
"invalid protocol version"); "invalid or unsupported protocol version");
return NULL; return NULL;
} }
if (ctx == NULL) { if (ctx == NULL) {
@ -6185,12 +6182,10 @@ PyInit__ssl(void)
PY_SSL_VERSION_TLS_SERVER); PY_SSL_VERSION_TLS_SERVER);
PyModule_AddIntConstant(m, "PROTOCOL_TLSv1", PyModule_AddIntConstant(m, "PROTOCOL_TLSv1",
PY_SSL_VERSION_TLS1); PY_SSL_VERSION_TLS1);
#if HAVE_TLSv1_2
PyModule_AddIntConstant(m, "PROTOCOL_TLSv1_1", PyModule_AddIntConstant(m, "PROTOCOL_TLSv1_1",
PY_SSL_VERSION_TLS1_1); PY_SSL_VERSION_TLS1_1);
PyModule_AddIntConstant(m, "PROTOCOL_TLSv1_2", PyModule_AddIntConstant(m, "PROTOCOL_TLSv1_2",
PY_SSL_VERSION_TLS1_2); PY_SSL_VERSION_TLS1_2);
#endif
/* protocol options */ /* protocol options */
PyModule_AddIntConstant(m, "OP_ALL", PyModule_AddIntConstant(m, "OP_ALL",
@ -6198,10 +6193,8 @@ PyInit__ssl(void)
PyModule_AddIntConstant(m, "OP_NO_SSLv2", SSL_OP_NO_SSLv2); PyModule_AddIntConstant(m, "OP_NO_SSLv2", SSL_OP_NO_SSLv2);
PyModule_AddIntConstant(m, "OP_NO_SSLv3", SSL_OP_NO_SSLv3); PyModule_AddIntConstant(m, "OP_NO_SSLv3", SSL_OP_NO_SSLv3);
PyModule_AddIntConstant(m, "OP_NO_TLSv1", SSL_OP_NO_TLSv1); PyModule_AddIntConstant(m, "OP_NO_TLSv1", SSL_OP_NO_TLSv1);
#if HAVE_TLSv1_2
PyModule_AddIntConstant(m, "OP_NO_TLSv1_1", SSL_OP_NO_TLSv1_1); PyModule_AddIntConstant(m, "OP_NO_TLSv1_1", SSL_OP_NO_TLSv1_1);
PyModule_AddIntConstant(m, "OP_NO_TLSv1_2", SSL_OP_NO_TLSv1_2); PyModule_AddIntConstant(m, "OP_NO_TLSv1_2", SSL_OP_NO_TLSv1_2);
#endif
#ifdef SSL_OP_NO_TLSv1_3 #ifdef SSL_OP_NO_TLSv1_3
PyModule_AddIntConstant(m, "OP_NO_TLSv1_3", SSL_OP_NO_TLSv1_3); PyModule_AddIntConstant(m, "OP_NO_TLSv1_3", SSL_OP_NO_TLSv1_3);
#else #else

View File

@ -43,20 +43,21 @@ import tarfile
log = logging.getLogger("multissl") log = logging.getLogger("multissl")
OPENSSL_OLD_VERSIONS = [ OPENSSL_OLD_VERSIONS = [
"1.0.2u",
"1.1.0l",
] ]
OPENSSL_RECENT_VERSIONS = [ OPENSSL_RECENT_VERSIONS = [
"1.0.2u",
"1.1.0l",
"1.1.1g", "1.1.1g",
# "3.0.0-alpha2" # "3.0.0-alpha2"
] ]
LIBRESSL_OLD_VERSIONS = [ LIBRESSL_OLD_VERSIONS = [
"2.9.2",
] ]
LIBRESSL_RECENT_VERSIONS = [ LIBRESSL_RECENT_VERSIONS = [
"2.9.2", "3.1.0",
] ]
# store files in ../multissl # store files in ../multissl
@ -80,7 +81,7 @@ parser.add_argument(
parser.add_argument( parser.add_argument(
'--disable-ancient', '--disable-ancient',
action='store_true', action='store_true',
help="Don't test OpenSSL < 1.0.2 and LibreSSL < 2.5.3.", help="Don't test OpenSSL and LibreSSL versions without upstream support",
) )
parser.add_argument( parser.add_argument(
'--openssl', '--openssl',