12
12
import socket
13
13
import select
14
14
import time
15
- import datetime
16
15
import gc
17
16
import os
18
17
import errno
39
38
40
39
PROTOCOLS = sorted (ssl ._PROTOCOL_NAMES )
41
40
HOST = socket_helper .HOST
42
- IS_LIBRESSL = ssl .OPENSSL_VERSION .startswith ('LibreSSL' )
43
- IS_OPENSSL_1_1_1 = not IS_LIBRESSL and ssl .OPENSSL_VERSION_INFO >= (1 , 1 , 1 )
44
- IS_OPENSSL_3_0_0 = not IS_LIBRESSL and ssl .OPENSSL_VERSION_INFO >= (3 , 0 , 0 )
41
+ IS_OPENSSL_3_0_0 = ssl .OPENSSL_VERSION_INFO >= (3 , 0 , 0 )
45
42
PY_SSL_DEFAULT_CIPHERS = sysconfig .get_config_var ('PY_SSL_DEFAULT_CIPHERS' )
46
43
47
44
PROTOCOL_TO_TLS_VERSION = {}
@@ -258,53 +255,18 @@ def wrapper(*args, **kw):
258
255
return decorator
259
256
260
257
261
- requires_minimum_version = unittest .skipUnless (
262
- hasattr (ssl .SSLContext , 'minimum_version' ),
263
- "required OpenSSL >= 1.1.0g"
264
- )
265
-
266
-
267
258
def handle_error (prefix ):
268
259
exc_format = ' ' .join (traceback .format_exception (* sys .exc_info ()))
269
260
if support .verbose :
270
261
sys .stdout .write (prefix + exc_format )
271
262
272
- def _have_secp_curves ():
273
- if not ssl .HAS_ECDH :
274
- return False
275
- ctx = ssl .SSLContext (ssl .PROTOCOL_TLS_SERVER )
276
- try :
277
- ctx .set_ecdh_curve ("secp384r1" )
278
- except ValueError :
279
- return False
280
- else :
281
- return True
282
-
283
-
284
- HAVE_SECP_CURVES = _have_secp_curves ()
285
-
286
263
287
264
def utc_offset (): #NOTE: ignore issues like #1647654
288
265
# local time = utc time + utc offset
289
266
if time .daylight and time .localtime ().tm_isdst > 0 :
290
267
return - time .altzone # seconds
291
268
return - time .timezone
292
269
293
- def asn1time (cert_time ):
294
- # Some versions of OpenSSL ignore seconds, see #18207
295
- # 0.9.8.i
296
- if ssl ._OPENSSL_API_VERSION == (0 , 9 , 8 , 9 , 15 ):
297
- fmt = "%b %d %H:%M:%S %Y GMT"
298
- dt = datetime .datetime .strptime (cert_time , fmt )
299
- dt = dt .replace (second = 0 )
300
- cert_time = dt .strftime (fmt )
301
- # %d adds leading zero but ASN1_TIME_print() uses leading space
302
- if cert_time [4 ] == "0" :
303
- cert_time = cert_time [:4 ] + " " + cert_time [5 :]
304
-
305
- return cert_time
306
-
307
- needs_sni = unittest .skipUnless (ssl .HAS_SNI , "SNI support needed for this test" )
308
270
309
271
ignore_deprecation = warnings_helper .ignore_warnings (
310
272
category = DeprecationWarning
@@ -365,11 +327,12 @@ def test_constants(self):
365
327
ssl .CERT_REQUIRED
366
328
ssl .OP_CIPHER_SERVER_PREFERENCE
367
329
ssl .OP_SINGLE_DH_USE
368
- if ssl .HAS_ECDH :
369
- ssl .OP_SINGLE_ECDH_USE
330
+ ssl .OP_SINGLE_ECDH_USE
370
331
ssl .OP_NO_COMPRESSION
371
- self .assertIn (ssl .HAS_SNI , {True , False })
372
- self .assertIn (ssl .HAS_ECDH , {True , False })
332
+ self .assertEqual (ssl .HAS_SNI , True )
333
+ self .assertEqual (ssl .HAS_ECDH , True )
334
+ self .assertEqual (ssl .HAS_TLSv1_2 , True )
335
+ self .assertEqual (ssl .HAS_TLSv1_3 , True )
373
336
ssl .OP_NO_SSLv2
374
337
ssl .OP_NO_SSLv3
375
338
ssl .OP_NO_TLSv1
@@ -537,8 +500,8 @@ def test_openssl_version(self):
537
500
self .assertIsInstance (t , tuple )
538
501
self .assertIsInstance (s , str )
539
502
# Some sanity checks follow
540
- # >= 0.9
541
- self .assertGreaterEqual (n , 0x900000 )
503
+ # >= 1.1.1
504
+ self .assertGreaterEqual (n , 0x10101000 )
542
505
# < 4.0
543
506
self .assertLess (n , 0x40000000 )
544
507
major , minor , fix , patch , status = t
@@ -552,13 +515,13 @@ def test_openssl_version(self):
552
515
self .assertLessEqual (patch , 63 )
553
516
self .assertGreaterEqual (status , 0 )
554
517
self .assertLessEqual (status , 15 )
555
- # Version string as returned by {Open,Libre}SSL, the format might change
556
- if IS_LIBRESSL :
557
- self . assertTrue ( s . startswith ( "LibreSSL { :d}". format ( major )),
558
- ( s , t , hex ( n )))
559
- else :
560
- self . assertTrue ( s . startswith ( "OpenSSL {:d}.{:d}.{:d}" . format ( major , minor , fix )),
561
- ( s , t , hex ( n )) )
518
+
519
+ libressl_ver = f"LibreSSL { major :d } "
520
+ openssl_ver = f"OpenSSL { major :d } . { minor :d } . { fix :d} "
521
+ self . assertTrue (
522
+ s . startswith (( openssl_ver , libressl_ver )),
523
+ ( s , t , hex ( n ))
524
+ )
562
525
563
526
@support .cpython_only
564
527
def test_refcycle (self ):
@@ -1196,8 +1159,6 @@ def test_hostname_checks_common_name(self):
1196
1159
with self .assertRaises (AttributeError ):
1197
1160
ctx .hostname_checks_common_name = True
1198
1161
1199
- @requires_minimum_version
1200
- @unittest .skipIf (IS_LIBRESSL , "see bpo-34001" )
1201
1162
@ignore_deprecation
1202
1163
def test_min_max_version (self ):
1203
1164
ctx = ssl .SSLContext (ssl .PROTOCOL_TLS_SERVER )
@@ -1523,7 +1484,6 @@ def test_set_ecdh_curve(self):
1523
1484
self .assertRaises (ValueError , ctx .set_ecdh_curve , "foo" )
1524
1485
self .assertRaises (ValueError , ctx .set_ecdh_curve , b"foo" )
1525
1486
1526
- @needs_sni
1527
1487
def test_sni_callback (self ):
1528
1488
ctx = ssl .SSLContext (ssl .PROTOCOL_TLS_SERVER )
1529
1489
@@ -1538,7 +1498,6 @@ def dummycallback(sock, servername, ctx):
1538
1498
ctx .set_servername_callback (None )
1539
1499
ctx .set_servername_callback (dummycallback )
1540
1500
1541
- @needs_sni
1542
1501
def test_sni_callback_refcycle (self ):
1543
1502
# Reference cycles through the servername callback are detected
1544
1503
# and cleared.
@@ -1578,8 +1537,8 @@ def test_get_ca_certs(self):
1578
1537
(('organizationalUnitName' , 'http://www.cacert.org' ),),
1579
1538
(('commonName' , 'CA Cert Signing Authority' ),),
1580
1539
((
'emailAddress' ,
'[email protected] ' ),)),
1581
- 'notAfter' : asn1time ( 'Mar 29 12:29:49 2033 GMT' ) ,
1582
- 'notBefore' : asn1time ( 'Mar 30 12:29:49 2003 GMT' ) ,
1540
+ 'notAfter' : 'Mar 29 12:29:49 2033 GMT' ,
1541
+ 'notBefore' : 'Mar 30 12:29:49 2003 GMT' ,
1583
1542
'serialNumber' : '00' ,
1584
1543
'crlDistributionPoints' : ('https://www.cacert.org/revoke.crl' ,),
1585
1544
'subject' : ((('organizationName' , 'Root CA' ),),
@@ -1609,7 +1568,6 @@ def test_load_default_certs(self):
1609
1568
self .assertRaises (TypeError , ctx .load_default_certs , 'SERVER_AUTH' )
1610
1569
1611
1570
@unittest .skipIf (sys .platform == "win32" , "not-Windows specific" )
1612
- @unittest .skipIf (IS_LIBRESSL , "LibreSSL doesn't support env vars" )
1613
1571
def test_load_default_certs_env (self ):
1614
1572
ctx = ssl .SSLContext (ssl .PROTOCOL_TLS_CLIENT )
1615
1573
with os_helper .EnvironmentVarGuard () as env :
@@ -2145,7 +2103,6 @@ def test_non_blocking_handshake(self):
2145
2103
def test_get_server_certificate (self ):
2146
2104
_test_get_server_certificate (self , * self .server_addr , cert = SIGNING_CA )
2147
2105
2148
- @needs_sni
2149
2106
def test_get_server_certificate_sni (self ):
2150
2107
host , port = self .server_addr
2151
2108
server_names = []
@@ -2198,7 +2155,6 @@ def test_get_ca_certs_capath(self):
2198
2155
self .assertTrue (cert )
2199
2156
self .assertEqual (len (ctx .get_ca_certs ()), 1 )
2200
2157
2201
- @needs_sni
2202
2158
def test_context_setget (self ):
2203
2159
# Check that the context of a connected socket can be replaced.
2204
2160
ctx1 = ssl .SSLContext (ssl .PROTOCOL_TLS_CLIENT )
@@ -3863,7 +3819,6 @@ def test_tls1_3(self):
3863
3819
})
3864
3820
self .assertEqual (s .version (), 'TLSv1.3' )
3865
3821
3866
- @requires_minimum_version
3867
3822
@requires_tls_version ('TLSv1_2' )
3868
3823
@requires_tls_version ('TLSv1' )
3869
3824
@ignore_deprecation
@@ -3882,7 +3837,6 @@ def test_min_max_version_tlsv1_2(self):
3882
3837
s .connect ((HOST , server .port ))
3883
3838
self .assertEqual (s .version (), 'TLSv1.2' )
3884
3839
3885
- @requires_minimum_version
3886
3840
@requires_tls_version ('TLSv1_1' )
3887
3841
@ignore_deprecation
3888
3842
def test_min_max_version_tlsv1_1 (self ):
@@ -3900,7 +3854,6 @@ def test_min_max_version_tlsv1_1(self):
3900
3854
s .connect ((HOST , server .port ))
3901
3855
self .assertEqual (s .version (), 'TLSv1.1' )
3902
3856
3903
- @requires_minimum_version
3904
3857
@requires_tls_version ('TLSv1_2' )
3905
3858
@requires_tls_version ('TLSv1' )
3906
3859
@ignore_deprecation
@@ -3920,7 +3873,6 @@ def test_min_max_version_mismatch(self):
3920
3873
s .connect ((HOST , server .port ))
3921
3874
self .assertIn ("alert" , str (e .exception ))
3922
3875
3923
- @requires_minimum_version
3924
3876
@requires_tls_version ('SSLv3' )
3925
3877
def test_min_max_version_sslv3 (self ):
3926
3878
client_context , server_context , hostname = testing_context ()
@@ -3935,7 +3887,6 @@ def test_min_max_version_sslv3(self):
3935
3887
s .connect ((HOST , server .port ))
3936
3888
self .assertEqual (s .version (), 'SSLv3' )
3937
3889
3938
- @unittest .skipUnless (ssl .HAS_ECDH , "test requires ECDH-enabled OpenSSL" )
3939
3890
def test_default_ecdh_curve (self ):
3940
3891
# Issue #21015: elliptic curve-based Diffie Hellman key exchange
3941
3892
# should be enabled by default on SSL contexts.
@@ -4050,15 +4001,13 @@ def test_dh_params(self):
4050
4001
if "ADH" not in parts and "EDH" not in parts and "DHE" not in parts :
4051
4002
self .fail ("Non-DH cipher: " + cipher [0 ])
4052
4003
4053
- @unittest .skipUnless (HAVE_SECP_CURVES , "needs secp384r1 curve support" )
4054
- @unittest .skipIf (IS_OPENSSL_1_1_1 , "TODO: Test doesn't work on 1.1.1" )
4055
4004
def test_ecdh_curve (self ):
4056
4005
# server secp384r1, client auto
4057
4006
client_context , server_context , hostname = testing_context ()
4058
4007
4059
4008
server_context .set_ecdh_curve ("secp384r1" )
4060
4009
server_context .set_ciphers ("ECDHE:!eNULL:!aNULL" )
4061
- server_context .options | = ssl .OP_NO_TLSv1 | ssl . OP_NO_TLSv1_1
4010
+ server_context .minimum_version = ssl .TLSVersion . TLSv1_2
4062
4011
stats = server_params_test (client_context , server_context ,
4063
4012
chatty = True , connectionchatty = True ,
4064
4013
sni_name = hostname )
@@ -4067,7 +4016,7 @@ def test_ecdh_curve(self):
4067
4016
client_context , server_context , hostname = testing_context ()
4068
4017
client_context .set_ecdh_curve ("secp384r1" )
4069
4018
server_context .set_ciphers ("ECDHE:!eNULL:!aNULL" )
4070
- server_context .options | = ssl .OP_NO_TLSv1 | ssl . OP_NO_TLSv1_1
4019
+ server_context .minimum_version = ssl .TLSVersion . TLSv1_2
4071
4020
stats = server_params_test (client_context , server_context ,
4072
4021
chatty = True , connectionchatty = True ,
4073
4022
sni_name = hostname )
@@ -4077,13 +4026,11 @@ def test_ecdh_curve(self):
4077
4026
client_context .set_ecdh_curve ("prime256v1" )
4078
4027
server_context .set_ecdh_curve ("secp384r1" )
4079
4028
server_context .set_ciphers ("ECDHE:!eNULL:!aNULL" )
4080
- server_context .options | = ssl .OP_NO_TLSv1 | ssl . OP_NO_TLSv1_1
4081
- try :
4029
+ server_context .minimum_version = ssl .TLSVersion . TLSv1_2
4030
+ with self . assertRaises ( ssl . SSLError ) :
4082
4031
server_params_test (client_context , server_context ,
4083
4032
chatty = True , connectionchatty = True ,
4084
4033
sni_name = hostname )
4085
- except ssl .SSLError :
4086
- self .fail ("mismatch curve did not fail" )
4087
4034
4088
4035
def test_selected_alpn_protocol (self ):
4089
4036
# selected_alpn_protocol() is None unless ALPN is used.
@@ -4152,7 +4099,6 @@ def check_common_name(self, stats, name):
4152
4099
cert = stats ['peercert' ]
4153
4100
self .assertIn ((('commonName' , name ),), cert ['subject' ])
4154
4101
4155
- @needs_sni
4156
4102
def test_sni_callback (self ):
4157
4103
calls = []
4158
4104
server_context , other_context , client_context = self .sni_contexts ()
@@ -4193,7 +4139,6 @@ def servername_cb(ssl_sock, server_name, initial_context):
4193
4139
self .check_common_name (stats , SIGNED_CERTFILE_HOSTNAME )
4194
4140
self .assertEqual (calls , [])
4195
4141
4196
- @needs_sni
4197
4142
def test_sni_callback_alert (self ):
4198
4143
# Returning a TLS alert is reflected to the connecting client
4199
4144
server_context , other_context , client_context = self .sni_contexts ()
@@ -4207,7 +4152,6 @@ def cb_returning_alert(ssl_sock, server_name, initial_context):
4207
4152
sni_name = 'supermessage' )
4208
4153
self .assertEqual (cm .exception .reason , 'TLSV1_ALERT_ACCESS_DENIED' )
4209
4154
4210
- @needs_sni
4211
4155
def test_sni_callback_raising (self ):
4212
4156
# Raising fails the connection with a TLS handshake failure alert.
4213
4157
server_context , other_context , client_context = self .sni_contexts ()
@@ -4226,7 +4170,6 @@ def cb_raising(ssl_sock, server_name, initial_context):
4226
4170
'SSLV3_ALERT_HANDSHAKE_FAILURE' )
4227
4171
self .assertEqual (catch .unraisable .exc_type , ZeroDivisionError )
4228
4172
4229
- @needs_sni
4230
4173
def test_sni_callback_wrong_return_type (self ):
4231
4174
# Returning the wrong return type terminates the TLS connection
4232
4175
# with an internal error alert.
0 commit comments