11356St.nateldemoura@f5.comimport io 2781Szelenkov@nginx.comimport re 3781Szelenkov@nginx.comimport ssl 4781Szelenkov@nginx.comimport subprocess 51886Szelenkov@nginx.comimport time 61477Szelenkov@nginx.com 71635Szelenkov@nginx.comimport pytest 81019Szelenkov@nginx.comfrom unit.applications.tls import TestApplicationTLS 91863Szelenkov@nginx.comfrom unit.option import option 10781Szelenkov@nginx.com 111017Szelenkov@nginx.com 121019Szelenkov@nginx.comclass TestTLS(TestApplicationTLS): 131467Szelenkov@nginx.com prerequisites = {'modules': {'python': 'any', 'openssl': 'any'}} 14781Szelenkov@nginx.com 15781Szelenkov@nginx.com def openssl_date_to_sec_epoch(self, date): 16*2144Szelenkov@nginx.com return self.date_to_sec_epoch(date, '%b %d %X %Y %Z') 17781Szelenkov@nginx.com 18781Szelenkov@nginx.com def add_tls(self, application='empty', cert='default', port=7080): 191775Szelenkov@nginx.com assert 'success' in self.conf( 201041Svbart@nginx.com { 211041Svbart@nginx.com "pass": "applications/" + application, 221848Szelenkov@nginx.com "tls": {"certificate": cert}, 231041Svbart@nginx.com }, 241017Szelenkov@nginx.com 'listeners/*:' + str(port), 251017Szelenkov@nginx.com ) 26781Szelenkov@nginx.com 27781Szelenkov@nginx.com def remove_tls(self, application='empty', port=7080): 281775Szelenkov@nginx.com assert 'success' in self.conf( 291041Svbart@nginx.com {"pass": "applications/" + application}, 'listeners/*:' + str(port) 301041Svbart@nginx.com ) 31781Szelenkov@nginx.com 321863Szelenkov@nginx.com def req(self, name='localhost', subject=None, x509=False): 331863Szelenkov@nginx.com subj = subject if subject is not None else '/CN=' + name + '/' 341863Szelenkov@nginx.com 352004Szelenkov@nginx.com subprocess.check_output( 361863Szelenkov@nginx.com [ 371863Szelenkov@nginx.com 'openssl', 381863Szelenkov@nginx.com 'req', 391863Szelenkov@nginx.com '-new', 401863Szelenkov@nginx.com '-subj', 411863Szelenkov@nginx.com subj, 421863Szelenkov@nginx.com '-config', 431863Szelenkov@nginx.com option.temp_dir + '/openssl.conf', 441863Szelenkov@nginx.com '-out', 451863Szelenkov@nginx.com option.temp_dir + '/' + name + '.csr', 461863Szelenkov@nginx.com '-keyout', 471863Szelenkov@nginx.com option.temp_dir + '/' + name + '.key', 481863Szelenkov@nginx.com ], 491863Szelenkov@nginx.com stderr=subprocess.STDOUT, 501863Szelenkov@nginx.com ) 511863Szelenkov@nginx.com 521863Szelenkov@nginx.com def generate_ca_conf(self): 531863Szelenkov@nginx.com with open(option.temp_dir + '/ca.conf', 'w') as f: 541863Szelenkov@nginx.com f.write( 551863Szelenkov@nginx.com """[ ca ] 561863Szelenkov@nginx.comdefault_ca = myca 571863Szelenkov@nginx.com 581863Szelenkov@nginx.com[ myca ] 591863Szelenkov@nginx.comnew_certs_dir = %(dir)s 601863Szelenkov@nginx.comdatabase = %(database)s 611863Szelenkov@nginx.comdefault_md = sha256 621863Szelenkov@nginx.compolicy = myca_policy 631863Szelenkov@nginx.comserial = %(certserial)s 641863Szelenkov@nginx.comdefault_days = 1 651863Szelenkov@nginx.comx509_extensions = myca_extensions 661863Szelenkov@nginx.comcopy_extensions = copy 671863Szelenkov@nginx.com 681863Szelenkov@nginx.com[ myca_policy ] 691863Szelenkov@nginx.comcommonName = optional 701863Szelenkov@nginx.com 711863Szelenkov@nginx.com[ myca_extensions ] 721863Szelenkov@nginx.combasicConstraints = critical,CA:TRUE""" 731863Szelenkov@nginx.com % { 741863Szelenkov@nginx.com 'dir': option.temp_dir, 751863Szelenkov@nginx.com 'database': option.temp_dir + '/certindex', 761863Szelenkov@nginx.com 'certserial': option.temp_dir + '/certserial', 771863Szelenkov@nginx.com } 781863Szelenkov@nginx.com ) 791863Szelenkov@nginx.com 801863Szelenkov@nginx.com with open(option.temp_dir + '/certserial', 'w') as f: 811863Szelenkov@nginx.com f.write('1000') 821863Szelenkov@nginx.com 831863Szelenkov@nginx.com with open(option.temp_dir + '/certindex', 'w') as f: 841863Szelenkov@nginx.com f.write('') 851863Szelenkov@nginx.com 861863Szelenkov@nginx.com with open(option.temp_dir + '/certindex.attr', 'w') as f: 871863Szelenkov@nginx.com f.write('') 881863Szelenkov@nginx.com 891863Szelenkov@nginx.com def ca(self, cert='root', out='localhost'): 902004Szelenkov@nginx.com subprocess.check_output( 911863Szelenkov@nginx.com [ 921863Szelenkov@nginx.com 'openssl', 931863Szelenkov@nginx.com 'ca', 941863Szelenkov@nginx.com '-batch', 951863Szelenkov@nginx.com '-config', 961863Szelenkov@nginx.com option.temp_dir + '/ca.conf', 971863Szelenkov@nginx.com '-keyfile', 981863Szelenkov@nginx.com option.temp_dir + '/' + cert + '.key', 991863Szelenkov@nginx.com '-cert', 1001863Szelenkov@nginx.com option.temp_dir + '/' + cert + '.crt', 1011863Szelenkov@nginx.com '-in', 1021863Szelenkov@nginx.com option.temp_dir + '/' + out + '.csr', 1031863Szelenkov@nginx.com '-out', 1041863Szelenkov@nginx.com option.temp_dir + '/' + out + '.crt', 1051863Szelenkov@nginx.com ], 1061863Szelenkov@nginx.com stderr=subprocess.STDOUT, 1071863Szelenkov@nginx.com ) 1081863Szelenkov@nginx.com 1091863Szelenkov@nginx.com def set_certificate_req_context(self, cert='root'): 1101863Szelenkov@nginx.com self.context = ssl.create_default_context() 1111863Szelenkov@nginx.com self.context.check_hostname = False 1121863Szelenkov@nginx.com self.context.verify_mode = ssl.CERT_REQUIRED 1131863Szelenkov@nginx.com self.context.load_verify_locations( 1141863Szelenkov@nginx.com option.temp_dir + '/' + cert + '.crt' 1151863Szelenkov@nginx.com ) 1161863Szelenkov@nginx.com 117781Szelenkov@nginx.com def test_tls_listener_option_add(self): 118781Szelenkov@nginx.com self.load('empty') 119781Szelenkov@nginx.com 120781Szelenkov@nginx.com self.certificate() 121781Szelenkov@nginx.com 122781Szelenkov@nginx.com self.add_tls() 123781Szelenkov@nginx.com 1241596Szelenkov@nginx.com assert self.get_ssl()['status'] == 200, 'add listener option' 125781Szelenkov@nginx.com 126781Szelenkov@nginx.com def test_tls_listener_option_remove(self): 127781Szelenkov@nginx.com self.load('empty') 128781Szelenkov@nginx.com 129781Szelenkov@nginx.com self.certificate() 130781Szelenkov@nginx.com 131781Szelenkov@nginx.com self.add_tls() 132781Szelenkov@nginx.com 133781Szelenkov@nginx.com self.get_ssl() 134781Szelenkov@nginx.com 135781Szelenkov@nginx.com self.remove_tls() 136781Szelenkov@nginx.com 1371596Szelenkov@nginx.com assert self.get()['status'] == 200, 'remove listener option' 138781Szelenkov@nginx.com 139781Szelenkov@nginx.com def test_tls_certificate_remove(self): 140781Szelenkov@nginx.com self.load('empty') 141781Szelenkov@nginx.com 142781Szelenkov@nginx.com self.certificate() 143781Szelenkov@nginx.com 1441596Szelenkov@nginx.com assert 'success' in self.conf_delete( 1451596Szelenkov@nginx.com '/certificates/default' 1461596Szelenkov@nginx.com ), 'remove certificate' 147781Szelenkov@nginx.com 148781Szelenkov@nginx.com def test_tls_certificate_remove_used(self): 149781Szelenkov@nginx.com self.load('empty') 150781Szelenkov@nginx.com 151781Szelenkov@nginx.com self.certificate() 152781Szelenkov@nginx.com 153781Szelenkov@nginx.com self.add_tls() 154781Szelenkov@nginx.com 1551596Szelenkov@nginx.com assert 'error' in self.conf_delete( 1561596Szelenkov@nginx.com '/certificates/default' 1571596Szelenkov@nginx.com ), 'remove certificate' 158781Szelenkov@nginx.com 159781Szelenkov@nginx.com def test_tls_certificate_remove_nonexisting(self): 160781Szelenkov@nginx.com self.load('empty') 161781Szelenkov@nginx.com 162781Szelenkov@nginx.com self.certificate() 163781Szelenkov@nginx.com 164781Szelenkov@nginx.com self.add_tls() 165781Szelenkov@nginx.com 1661596Szelenkov@nginx.com assert 'error' in self.conf_delete( 1671596Szelenkov@nginx.com '/certificates/blah' 1681596Szelenkov@nginx.com ), 'remove nonexistings certificate' 169781Szelenkov@nginx.com 1701596Szelenkov@nginx.com @pytest.mark.skip('not yet') 171781Szelenkov@nginx.com def test_tls_certificate_update(self): 172781Szelenkov@nginx.com self.load('empty') 173781Szelenkov@nginx.com 174781Szelenkov@nginx.com self.certificate() 175781Szelenkov@nginx.com 176781Szelenkov@nginx.com self.add_tls() 177781Szelenkov@nginx.com 1782066Szelenkov@nginx.com cert_old = ssl.get_server_certificate(('127.0.0.1', 7080)) 179781Szelenkov@nginx.com 180781Szelenkov@nginx.com self.certificate() 181781Szelenkov@nginx.com 1822066Szelenkov@nginx.com assert cert_old != ssl.get_server_certificate( 1832066Szelenkov@nginx.com ('127.0.0.1', 7080) 1842066Szelenkov@nginx.com ), 'update certificate' 185781Szelenkov@nginx.com 1861596Szelenkov@nginx.com @pytest.mark.skip('not yet') 187781Szelenkov@nginx.com def test_tls_certificate_key_incorrect(self): 188781Szelenkov@nginx.com self.load('empty') 189781Szelenkov@nginx.com 190781Szelenkov@nginx.com self.certificate('first', False) 191781Szelenkov@nginx.com self.certificate('second', False) 192781Szelenkov@nginx.com 1931596Szelenkov@nginx.com assert 'error' in self.certificate_load( 1941596Szelenkov@nginx.com 'first', 'second' 1951596Szelenkov@nginx.com ), 'key incorrect' 196781Szelenkov@nginx.com 197781Szelenkov@nginx.com def test_tls_certificate_change(self): 198781Szelenkov@nginx.com self.load('empty') 199781Szelenkov@nginx.com 200781Szelenkov@nginx.com self.certificate() 201781Szelenkov@nginx.com self.certificate('new') 202781Szelenkov@nginx.com 203781Szelenkov@nginx.com self.add_tls() 204781Szelenkov@nginx.com 2052066Szelenkov@nginx.com cert_old = ssl.get_server_certificate(('127.0.0.1', 7080)) 206781Szelenkov@nginx.com 207781Szelenkov@nginx.com self.add_tls(cert='new') 208781Szelenkov@nginx.com 2092066Szelenkov@nginx.com assert cert_old != ssl.get_server_certificate( 2102066Szelenkov@nginx.com ('127.0.0.1', 7080) 2112066Szelenkov@nginx.com ), 'change certificate' 212781Szelenkov@nginx.com 213781Szelenkov@nginx.com def test_tls_certificate_key_rsa(self): 214781Szelenkov@nginx.com self.load('empty') 215781Szelenkov@nginx.com 216781Szelenkov@nginx.com self.certificate() 217781Szelenkov@nginx.com 2181596Szelenkov@nginx.com assert ( 2191596Szelenkov@nginx.com self.conf_get('/certificates/default/key') == 'RSA (2048 bits)' 2201596Szelenkov@nginx.com ), 'certificate key rsa' 221781Szelenkov@nginx.com 2221654Szelenkov@nginx.com def test_tls_certificate_key_ec(self, temp_dir): 223807Spluknet@nginx.com self.load('empty') 224807Spluknet@nginx.com 2251100Szelenkov@nginx.com self.openssl_conf() 2261100Szelenkov@nginx.com 2272004Szelenkov@nginx.com subprocess.check_output( 2281017Szelenkov@nginx.com [ 2291017Szelenkov@nginx.com 'openssl', 2301017Szelenkov@nginx.com 'ecparam', 2311017Szelenkov@nginx.com '-noout', 2321017Szelenkov@nginx.com '-genkey', 2331596Szelenkov@nginx.com '-out', 2341654Szelenkov@nginx.com temp_dir + '/ec.key', 2351596Szelenkov@nginx.com '-name', 2361596Szelenkov@nginx.com 'prime256v1', 2371388Szelenkov@nginx.com ], 2381388Szelenkov@nginx.com stderr=subprocess.STDOUT, 2391017Szelenkov@nginx.com ) 240781Szelenkov@nginx.com 2412004Szelenkov@nginx.com subprocess.check_output( 2421017Szelenkov@nginx.com [ 2431017Szelenkov@nginx.com 'openssl', 2441017Szelenkov@nginx.com 'req', 2451017Szelenkov@nginx.com '-x509', 2461017Szelenkov@nginx.com '-new', 2471596Szelenkov@nginx.com '-subj', 2481596Szelenkov@nginx.com '/CN=ec/', 2491596Szelenkov@nginx.com '-config', 2501654Szelenkov@nginx.com temp_dir + '/openssl.conf', 2511596Szelenkov@nginx.com '-key', 2521654Szelenkov@nginx.com temp_dir + '/ec.key', 2531596Szelenkov@nginx.com '-out', 2541654Szelenkov@nginx.com temp_dir + '/ec.crt', 2551388Szelenkov@nginx.com ], 2561388Szelenkov@nginx.com stderr=subprocess.STDOUT, 2571017Szelenkov@nginx.com ) 258781Szelenkov@nginx.com 259781Szelenkov@nginx.com self.certificate_load('ec') 260781Szelenkov@nginx.com 2611596Szelenkov@nginx.com assert ( 2621596Szelenkov@nginx.com self.conf_get('/certificates/ec/key') == 'ECDH' 2631596Szelenkov@nginx.com ), 'certificate key ec' 264781Szelenkov@nginx.com 265781Szelenkov@nginx.com def test_tls_certificate_chain_options(self): 266781Szelenkov@nginx.com self.load('empty') 267781Szelenkov@nginx.com 268781Szelenkov@nginx.com self.certificate() 269781Szelenkov@nginx.com 270781Szelenkov@nginx.com chain = self.conf_get('/certificates/default/chain') 271781Szelenkov@nginx.com 2721596Szelenkov@nginx.com assert len(chain) == 1, 'certificate chain length' 273781Szelenkov@nginx.com 274781Szelenkov@nginx.com cert = chain[0] 275781Szelenkov@nginx.com 2761596Szelenkov@nginx.com assert ( 2771596Szelenkov@nginx.com cert['subject']['common_name'] == 'default' 2781596Szelenkov@nginx.com ), 'certificate subject common name' 2791596Szelenkov@nginx.com assert ( 2801596Szelenkov@nginx.com cert['issuer']['common_name'] == 'default' 2811596Szelenkov@nginx.com ), 'certificate issuer common name' 282781Szelenkov@nginx.com 2831596Szelenkov@nginx.com assert ( 2841017Szelenkov@nginx.com abs( 2851017Szelenkov@nginx.com self.sec_epoch() 2861017Szelenkov@nginx.com - self.openssl_date_to_sec_epoch(cert['validity']['since']) 2871596Szelenkov@nginx.com ) 2881803Szelenkov@nginx.com < 60 2891596Szelenkov@nginx.com ), 'certificate validity since' 2901596Szelenkov@nginx.com assert ( 2911017Szelenkov@nginx.com self.openssl_date_to_sec_epoch(cert['validity']['until']) 2921596Szelenkov@nginx.com - self.openssl_date_to_sec_epoch(cert['validity']['since']) 2931596Szelenkov@nginx.com == 2592000 2941596Szelenkov@nginx.com ), 'certificate validity until' 295781Szelenkov@nginx.com 2961654Szelenkov@nginx.com def test_tls_certificate_chain(self, temp_dir): 297781Szelenkov@nginx.com self.load('empty') 298781Szelenkov@nginx.com 299781Szelenkov@nginx.com self.certificate('root', False) 300781Szelenkov@nginx.com 3011863Szelenkov@nginx.com self.req('int') 3021863Szelenkov@nginx.com self.req('end') 303781Szelenkov@nginx.com 3041863Szelenkov@nginx.com self.generate_ca_conf() 305781Szelenkov@nginx.com 3061863Szelenkov@nginx.com self.ca(cert='root', out='int') 3071863Szelenkov@nginx.com self.ca(cert='int', out='end') 308781Szelenkov@nginx.com 3091654Szelenkov@nginx.com crt_path = temp_dir + '/end-int.crt' 3101654Szelenkov@nginx.com end_path = temp_dir + '/end.crt' 3111654Szelenkov@nginx.com int_path = temp_dir + '/int.crt' 3121017Szelenkov@nginx.com 3131596Szelenkov@nginx.com with open(crt_path, 'wb') as crt, open(end_path, 'rb') as end, open( 3141596Szelenkov@nginx.com int_path, 'rb' 3151596Szelenkov@nginx.com ) as int: 3161017Szelenkov@nginx.com crt.write(end.read() + int.read()) 317781Szelenkov@nginx.com 3181863Szelenkov@nginx.com self.set_certificate_req_context() 319781Szelenkov@nginx.com 320781Szelenkov@nginx.com # incomplete chain 321781Szelenkov@nginx.com 3221596Szelenkov@nginx.com assert 'success' in self.certificate_load( 3231596Szelenkov@nginx.com 'end', 'end' 3241596Szelenkov@nginx.com ), 'certificate chain end upload' 325781Szelenkov@nginx.com 326781Szelenkov@nginx.com chain = self.conf_get('/certificates/end/chain') 3271596Szelenkov@nginx.com assert len(chain) == 1, 'certificate chain end length' 3281596Szelenkov@nginx.com assert ( 3291596Szelenkov@nginx.com chain[0]['subject']['common_name'] == 'end' 3301596Szelenkov@nginx.com ), 'certificate chain end subject common name' 3311596Szelenkov@nginx.com assert ( 3321596Szelenkov@nginx.com chain[0]['issuer']['common_name'] == 'int' 3331596Szelenkov@nginx.com ), 'certificate chain end issuer common name' 334781Szelenkov@nginx.com 335781Szelenkov@nginx.com self.add_tls(cert='end') 336781Szelenkov@nginx.com 337781Szelenkov@nginx.com try: 338781Szelenkov@nginx.com resp = self.get_ssl() 339781Szelenkov@nginx.com except ssl.SSLError: 340781Szelenkov@nginx.com resp = None 341781Szelenkov@nginx.com 3421596Szelenkov@nginx.com assert resp == None, 'certificate chain incomplete chain' 343781Szelenkov@nginx.com 344781Szelenkov@nginx.com # intermediate 345781Szelenkov@nginx.com 3461596Szelenkov@nginx.com assert 'success' in self.certificate_load( 3471596Szelenkov@nginx.com 'int', 'int' 3481596Szelenkov@nginx.com ), 'certificate chain int upload' 349781Szelenkov@nginx.com 350781Szelenkov@nginx.com chain = self.conf_get('/certificates/int/chain') 3511596Szelenkov@nginx.com assert len(chain) == 1, 'certificate chain int length' 3521596Szelenkov@nginx.com assert ( 3531596Szelenkov@nginx.com chain[0]['subject']['common_name'] == 'int' 3541596Szelenkov@nginx.com ), 'certificate chain int subject common name' 3551596Szelenkov@nginx.com assert ( 3561596Szelenkov@nginx.com chain[0]['issuer']['common_name'] == 'root' 3571596Szelenkov@nginx.com ), 'certificate chain int issuer common name' 358781Szelenkov@nginx.com 359781Szelenkov@nginx.com self.add_tls(cert='int') 360781Szelenkov@nginx.com 3612073Szelenkov@nginx.com assert self.get_ssl()['status'] == 200, 'certificate chain intermediate' 362781Szelenkov@nginx.com 363781Szelenkov@nginx.com # intermediate server 364781Szelenkov@nginx.com 3651596Szelenkov@nginx.com assert 'success' in self.certificate_load( 3661596Szelenkov@nginx.com 'end-int', 'end' 3671596Szelenkov@nginx.com ), 'certificate chain end-int upload' 368781Szelenkov@nginx.com 369781Szelenkov@nginx.com chain = self.conf_get('/certificates/end-int/chain') 3701596Szelenkov@nginx.com assert len(chain) == 2, 'certificate chain end-int length' 3711596Szelenkov@nginx.com assert ( 3721596Szelenkov@nginx.com chain[0]['subject']['common_name'] == 'end' 3731596Szelenkov@nginx.com ), 'certificate chain end-int int subject common name' 3741596Szelenkov@nginx.com assert ( 3751596Szelenkov@nginx.com chain[0]['issuer']['common_name'] == 'int' 3761596Szelenkov@nginx.com ), 'certificate chain end-int int issuer common name' 3771596Szelenkov@nginx.com assert ( 3781596Szelenkov@nginx.com chain[1]['subject']['common_name'] == 'int' 3791596Szelenkov@nginx.com ), 'certificate chain end-int end subject common name' 3801596Szelenkov@nginx.com assert ( 3811596Szelenkov@nginx.com chain[1]['issuer']['common_name'] == 'root' 3821596Szelenkov@nginx.com ), 'certificate chain end-int end issuer common name' 383781Szelenkov@nginx.com 384781Szelenkov@nginx.com self.add_tls(cert='end-int') 385781Szelenkov@nginx.com 3861596Szelenkov@nginx.com assert ( 3871596Szelenkov@nginx.com self.get_ssl()['status'] == 200 3881596Szelenkov@nginx.com ), 'certificate chain intermediate server' 389781Szelenkov@nginx.com 3902071Szelenkov@nginx.com def test_tls_certificate_chain_long(self, temp_dir): 3912071Szelenkov@nginx.com self.load('empty') 3922071Szelenkov@nginx.com 3932071Szelenkov@nginx.com self.generate_ca_conf() 3942071Szelenkov@nginx.com 3952071Szelenkov@nginx.com # Minimum chain length is 3. 3962071Szelenkov@nginx.com chain_length = 10 3972071Szelenkov@nginx.com 3982071Szelenkov@nginx.com for i in range(chain_length): 3992071Szelenkov@nginx.com if i == 0: 4002071Szelenkov@nginx.com self.certificate('root', False) 4012071Szelenkov@nginx.com elif i == chain_length - 1: 4022071Szelenkov@nginx.com self.req('end') 4032071Szelenkov@nginx.com else: 4042071Szelenkov@nginx.com self.req('int{}'.format(i)) 4052071Szelenkov@nginx.com 4062071Szelenkov@nginx.com for i in range(chain_length - 1): 4072071Szelenkov@nginx.com if i == 0: 4082071Szelenkov@nginx.com self.ca(cert='root', out='int1') 4092071Szelenkov@nginx.com elif i == chain_length - 2: 4102071Szelenkov@nginx.com self.ca(cert='int{}'.format(chain_length - 2), out='end') 4112071Szelenkov@nginx.com else: 4122071Szelenkov@nginx.com self.ca(cert='int{}'.format(i), out='int{}'.format(i + 1)) 4132071Szelenkov@nginx.com 4142071Szelenkov@nginx.com for i in range(chain_length - 1, 0, -1): 4152071Szelenkov@nginx.com path = temp_dir + ( 4162071Szelenkov@nginx.com '/end.crt' if i == chain_length - 1 else '/int{}.crt'.format(i) 4172071Szelenkov@nginx.com ) 4182071Szelenkov@nginx.com 4192071Szelenkov@nginx.com with open(temp_dir + '/all.crt', 'a') as chain, open(path) as cert: 4202071Szelenkov@nginx.com chain.write(cert.read()) 4212071Szelenkov@nginx.com 4222071Szelenkov@nginx.com self.set_certificate_req_context() 4232071Szelenkov@nginx.com 4242071Szelenkov@nginx.com assert 'success' in self.certificate_load( 4252071Szelenkov@nginx.com 'all', 'end' 4262071Szelenkov@nginx.com ), 'certificate chain upload' 4272071Szelenkov@nginx.com 4282071Szelenkov@nginx.com chain = self.conf_get('/certificates/all/chain') 4292071Szelenkov@nginx.com assert len(chain) == chain_length - 1, 'certificate chain length' 4302071Szelenkov@nginx.com 4312071Szelenkov@nginx.com self.add_tls(cert='all') 4322071Szelenkov@nginx.com 4332071Szelenkov@nginx.com assert self.get_ssl()['status'] == 200, 'certificate chain long' 4342071Szelenkov@nginx.com 4351863Szelenkov@nginx.com def test_tls_certificate_empty_cn(self, temp_dir): 4361863Szelenkov@nginx.com self.certificate('root', False) 4371863Szelenkov@nginx.com 4381863Szelenkov@nginx.com self.req(subject='/') 4391863Szelenkov@nginx.com 4401863Szelenkov@nginx.com self.generate_ca_conf() 4411863Szelenkov@nginx.com self.ca() 4421863Szelenkov@nginx.com 4431863Szelenkov@nginx.com self.set_certificate_req_context() 4441863Szelenkov@nginx.com 4451863Szelenkov@nginx.com assert 'success' in self.certificate_load('localhost', 'localhost') 4461863Szelenkov@nginx.com 4471863Szelenkov@nginx.com cert = self.conf_get('/certificates/localhost') 4481863Szelenkov@nginx.com assert cert['chain'][0]['subject'] == {}, 'empty subject' 4491863Szelenkov@nginx.com assert cert['chain'][0]['issuer']['common_name'] == 'root', 'issuer' 4501863Szelenkov@nginx.com 4511863Szelenkov@nginx.com def test_tls_certificate_empty_cn_san(self, temp_dir): 4521863Szelenkov@nginx.com self.certificate('root', False) 4531863Szelenkov@nginx.com 4541863Szelenkov@nginx.com self.openssl_conf( 4551863Szelenkov@nginx.com rewrite=True, alt_names=["example.com", "www.example.net"] 4561863Szelenkov@nginx.com ) 4571863Szelenkov@nginx.com 4581863Szelenkov@nginx.com self.req(subject='/') 4591863Szelenkov@nginx.com 4601863Szelenkov@nginx.com self.generate_ca_conf() 4611863Szelenkov@nginx.com self.ca() 4621863Szelenkov@nginx.com 4631863Szelenkov@nginx.com self.set_certificate_req_context() 4641863Szelenkov@nginx.com 4651863Szelenkov@nginx.com assert 'success' in self.certificate_load('localhost', 'localhost') 4661863Szelenkov@nginx.com 4671863Szelenkov@nginx.com cert = self.conf_get('/certificates/localhost') 4681863Szelenkov@nginx.com assert cert['chain'][0]['subject'] == { 4691863Szelenkov@nginx.com 'alt_names': ['example.com', 'www.example.net'] 4701863Szelenkov@nginx.com }, 'subject alt_names' 4711863Szelenkov@nginx.com assert cert['chain'][0]['issuer']['common_name'] == 'root', 'issuer' 4721863Szelenkov@nginx.com 4731866Szelenkov@nginx.com def test_tls_certificate_empty_cn_san_ip(self): 4741866Szelenkov@nginx.com self.certificate('root', False) 4751866Szelenkov@nginx.com 4761866Szelenkov@nginx.com self.openssl_conf( 4771866Szelenkov@nginx.com rewrite=True, 4781866Szelenkov@nginx.com alt_names=['example.com', 'www.example.net', 'IP|10.0.0.1'], 4791866Szelenkov@nginx.com ) 4801866Szelenkov@nginx.com 4811866Szelenkov@nginx.com self.req(subject='/') 4821866Szelenkov@nginx.com 4831866Szelenkov@nginx.com self.generate_ca_conf() 4841866Szelenkov@nginx.com self.ca() 4851866Szelenkov@nginx.com 4861866Szelenkov@nginx.com self.set_certificate_req_context() 4871866Szelenkov@nginx.com 4881866Szelenkov@nginx.com assert 'success' in self.certificate_load('localhost', 'localhost') 4891866Szelenkov@nginx.com 4901866Szelenkov@nginx.com cert = self.conf_get('/certificates/localhost') 4911866Szelenkov@nginx.com assert cert['chain'][0]['subject'] == { 4921866Szelenkov@nginx.com 'alt_names': ['example.com', 'www.example.net'] 4931866Szelenkov@nginx.com }, 'subject alt_names' 4941866Szelenkov@nginx.com assert cert['chain'][0]['issuer']['common_name'] == 'root', 'issuer' 4951866Szelenkov@nginx.com 496781Szelenkov@nginx.com def test_tls_keepalive(self): 497781Szelenkov@nginx.com self.load('mirror') 498781Szelenkov@nginx.com 4991596Szelenkov@nginx.com assert self.get()['status'] == 200, 'init' 5001029Szelenkov@nginx.com 501781Szelenkov@nginx.com self.certificate() 502781Szelenkov@nginx.com 503781Szelenkov@nginx.com self.add_tls(application='mirror') 504781Szelenkov@nginx.com 5051017Szelenkov@nginx.com (resp, sock) = self.post_ssl( 5061017Szelenkov@nginx.com headers={ 5071017Szelenkov@nginx.com 'Host': 'localhost', 5081017Szelenkov@nginx.com 'Connection': 'keep-alive', 5091017Szelenkov@nginx.com 'Content-Type': 'text/html', 5101017Szelenkov@nginx.com }, 5111017Szelenkov@nginx.com start=True, 5121017Szelenkov@nginx.com body='0123456789', 5131029Szelenkov@nginx.com read_timeout=1, 5141017Szelenkov@nginx.com ) 515781Szelenkov@nginx.com 5161596Szelenkov@nginx.com assert resp['body'] == '0123456789', 'keepalive 1' 517781Szelenkov@nginx.com 5181017Szelenkov@nginx.com resp = self.post_ssl( 5191017Szelenkov@nginx.com headers={ 5201017Szelenkov@nginx.com 'Host': 'localhost', 5211017Szelenkov@nginx.com 'Connection': 'close', 5221017Szelenkov@nginx.com 'Content-Type': 'text/html', 5231017Szelenkov@nginx.com }, 5241017Szelenkov@nginx.com sock=sock, 5251017Szelenkov@nginx.com body='0123456789', 5261017Szelenkov@nginx.com ) 527781Szelenkov@nginx.com 5281596Szelenkov@nginx.com assert resp['body'] == '0123456789', 'keepalive 2' 529781Szelenkov@nginx.com 5301886Szelenkov@nginx.com def test_tls_no_close_notify(self): 5311886Szelenkov@nginx.com self.certificate() 5321886Szelenkov@nginx.com 5331886Szelenkov@nginx.com assert 'success' in self.conf( 5341886Szelenkov@nginx.com { 5351886Szelenkov@nginx.com "listeners": { 5361886Szelenkov@nginx.com "*:7080": { 5371886Szelenkov@nginx.com "pass": "routes", 5381886Szelenkov@nginx.com "tls": {"certificate": "default"}, 5391886Szelenkov@nginx.com } 5401886Szelenkov@nginx.com }, 5411886Szelenkov@nginx.com "routes": [{"action": {"return": 200}}], 5421886Szelenkov@nginx.com "applications": {}, 5431886Szelenkov@nginx.com } 5441886Szelenkov@nginx.com ), 'load application configuration' 5451886Szelenkov@nginx.com 5461886Szelenkov@nginx.com (resp, sock) = self.get_ssl(start=True) 5471886Szelenkov@nginx.com 5481886Szelenkov@nginx.com time.sleep(5) 5491886Szelenkov@nginx.com 5501886Szelenkov@nginx.com sock.close() 5511886Szelenkov@nginx.com 5521596Szelenkov@nginx.com @pytest.mark.skip('not yet') 553781Szelenkov@nginx.com def test_tls_keepalive_certificate_remove(self): 554781Szelenkov@nginx.com self.load('empty') 555781Szelenkov@nginx.com 5561596Szelenkov@nginx.com assert self.get()['status'] == 200, 'init' 5571029Szelenkov@nginx.com 558781Szelenkov@nginx.com self.certificate() 559781Szelenkov@nginx.com 560781Szelenkov@nginx.com self.add_tls() 561781Szelenkov@nginx.com 5621017Szelenkov@nginx.com (resp, sock) = self.get_ssl( 5631017Szelenkov@nginx.com headers={'Host': 'localhost', 'Connection': 'keep-alive'}, 5641017Szelenkov@nginx.com start=True, 5651029Szelenkov@nginx.com read_timeout=1, 5661017Szelenkov@nginx.com ) 567781Szelenkov@nginx.com 5681775Szelenkov@nginx.com assert 'success' in self.conf( 5691775Szelenkov@nginx.com {"pass": "applications/empty"}, 'listeners/*:7080' 5701775Szelenkov@nginx.com ) 5711775Szelenkov@nginx.com assert 'success' in self.conf_delete('/certificates/default') 572781Szelenkov@nginx.com 573781Szelenkov@nginx.com try: 5741017Szelenkov@nginx.com resp = self.get_ssl( 5751017Szelenkov@nginx.com headers={'Host': 'localhost', 'Connection': 'close'}, sock=sock 5761017Szelenkov@nginx.com ) 5771706Smax.romanov@nginx.com 5781706Smax.romanov@nginx.com except KeyboardInterrupt: 5791706Smax.romanov@nginx.com raise 5801706Smax.romanov@nginx.com 581781Szelenkov@nginx.com except: 582781Szelenkov@nginx.com resp = None 583781Szelenkov@nginx.com 5841596Szelenkov@nginx.com assert resp == None, 'keepalive remove certificate' 585781Szelenkov@nginx.com 5861596Szelenkov@nginx.com @pytest.mark.skip('not yet') 587781Szelenkov@nginx.com def test_tls_certificates_remove_all(self): 588781Szelenkov@nginx.com self.load('empty') 589781Szelenkov@nginx.com 590781Szelenkov@nginx.com self.certificate() 591781Szelenkov@nginx.com 5921596Szelenkov@nginx.com assert 'success' in self.conf_delete( 5931596Szelenkov@nginx.com '/certificates' 5941596Szelenkov@nginx.com ), 'remove all certificates' 595781Szelenkov@nginx.com 5961736Szelenkov@nginx.com def test_tls_application_respawn(self, skip_alert): 597781Szelenkov@nginx.com self.load('mirror') 598781Szelenkov@nginx.com 599781Szelenkov@nginx.com self.certificate() 600781Szelenkov@nginx.com 6011775Szelenkov@nginx.com assert 'success' in self.conf('1', 'applications/mirror/processes') 602781Szelenkov@nginx.com 603781Szelenkov@nginx.com self.add_tls(application='mirror') 604781Szelenkov@nginx.com 6051453Szelenkov@nginx.com (_, sock) = self.post_ssl( 6061017Szelenkov@nginx.com headers={ 6071017Szelenkov@nginx.com 'Host': 'localhost', 6081017Szelenkov@nginx.com 'Connection': 'keep-alive', 6091017Szelenkov@nginx.com 'Content-Type': 'text/html', 6101017Szelenkov@nginx.com }, 6111017Szelenkov@nginx.com start=True, 6121017Szelenkov@nginx.com body='0123456789', 6131029Szelenkov@nginx.com read_timeout=1, 6141017Szelenkov@nginx.com ) 615781Szelenkov@nginx.com 616781Szelenkov@nginx.com app_id = self.findall(r'(\d+)#\d+ "mirror" application started')[0] 617781Szelenkov@nginx.com 6182004Szelenkov@nginx.com subprocess.check_output(['kill', '-9', app_id]) 619781Szelenkov@nginx.com 6201999Smax.romanov@nginx.com skip_alert(r'process .* %s.* exited on signal 9' % app_id) 6211453Szelenkov@nginx.com 6221017Szelenkov@nginx.com self.wait_for_record( 6231017Szelenkov@nginx.com re.compile( 6241635Szelenkov@nginx.com r' (?!' + app_id + r'#)(\d+)#\d+ "mirror" application started' 6251017Szelenkov@nginx.com ) 6261017Szelenkov@nginx.com ) 627781Szelenkov@nginx.com 6281017Szelenkov@nginx.com resp = self.post_ssl( 6291017Szelenkov@nginx.com headers={ 6301017Szelenkov@nginx.com 'Host': 'localhost', 6311017Szelenkov@nginx.com 'Connection': 'close', 6321017Szelenkov@nginx.com 'Content-Type': 'text/html', 6331017Szelenkov@nginx.com }, 6341017Szelenkov@nginx.com sock=sock, 6351017Szelenkov@nginx.com body='0123456789', 6361017Szelenkov@nginx.com ) 637781Szelenkov@nginx.com 6381596Szelenkov@nginx.com assert resp['status'] == 200, 'application respawn status' 6391596Szelenkov@nginx.com assert resp['body'] == '0123456789', 'application respawn body' 640781Szelenkov@nginx.com 6411011Smax.romanov@nginx.com def test_tls_url_scheme(self): 6421011Smax.romanov@nginx.com self.load('variables') 6431011Smax.romanov@nginx.com 6441596Szelenkov@nginx.com assert ( 6451017Szelenkov@nginx.com self.post( 6461017Szelenkov@nginx.com headers={ 6471017Szelenkov@nginx.com 'Host': 'localhost', 6481017Szelenkov@nginx.com 'Content-Type': 'text/html', 6491017Szelenkov@nginx.com 'Custom-Header': '', 6501017Szelenkov@nginx.com 'Connection': 'close', 6511017Szelenkov@nginx.com } 6521596Szelenkov@nginx.com )['headers']['Wsgi-Url-Scheme'] 6531596Szelenkov@nginx.com == 'http' 6541596Szelenkov@nginx.com ), 'url scheme http' 6551011Smax.romanov@nginx.com 6561011Smax.romanov@nginx.com self.certificate() 6571011Smax.romanov@nginx.com 6581011Smax.romanov@nginx.com self.add_tls(application='variables') 6591011Smax.romanov@nginx.com 6601596Szelenkov@nginx.com assert ( 6611017Szelenkov@nginx.com self.post_ssl( 6621017Szelenkov@nginx.com headers={ 6631017Szelenkov@nginx.com 'Host': 'localhost', 6641017Szelenkov@nginx.com 'Content-Type': 'text/html', 6651017Szelenkov@nginx.com 'Custom-Header': '', 6661017Szelenkov@nginx.com 'Connection': 'close', 6671017Szelenkov@nginx.com } 6681596Szelenkov@nginx.com )['headers']['Wsgi-Url-Scheme'] 6691596Szelenkov@nginx.com == 'https' 6701596Szelenkov@nginx.com ), 'url scheme https' 6711011Smax.romanov@nginx.com 6721356St.nateldemoura@f5.com def test_tls_big_upload(self): 6731356St.nateldemoura@f5.com self.load('upload') 6741356St.nateldemoura@f5.com 6751356St.nateldemoura@f5.com self.certificate() 6761356St.nateldemoura@f5.com 6771356St.nateldemoura@f5.com self.add_tls(application='upload') 6781356St.nateldemoura@f5.com 6791356St.nateldemoura@f5.com filename = 'test.txt' 6801356St.nateldemoura@f5.com data = '0123456789' * 9000 6811356St.nateldemoura@f5.com 6821596Szelenkov@nginx.com res = self.post_ssl( 6831596Szelenkov@nginx.com body={ 6841596Szelenkov@nginx.com 'file': { 6851596Szelenkov@nginx.com 'filename': filename, 6861596Szelenkov@nginx.com 'type': 'text/plain', 6871596Szelenkov@nginx.com 'data': io.StringIO(data), 6881596Szelenkov@nginx.com } 6891356St.nateldemoura@f5.com } 6901596Szelenkov@nginx.com ) 6911596Szelenkov@nginx.com assert res['status'] == 200, 'status ok' 6921596Szelenkov@nginx.com assert res['body'] == filename + data 6931904Smax.romanov@nginx.com 6941904Smax.romanov@nginx.com def test_tls_multi_listener(self): 6951904Smax.romanov@nginx.com self.load('empty') 6961904Smax.romanov@nginx.com 6971904Smax.romanov@nginx.com self.certificate() 6981904Smax.romanov@nginx.com 6991904Smax.romanov@nginx.com self.add_tls() 7001904Smax.romanov@nginx.com self.add_tls(port=7081) 7011904Smax.romanov@nginx.com 7021904Smax.romanov@nginx.com assert self.get_ssl()['status'] == 200, 'listener #1' 7031904Smax.romanov@nginx.com 7041904Smax.romanov@nginx.com assert self.get_ssl(port=7081)['status'] == 200, 'listener #2' 705