2626 load_pem_private_key ,
2727)
2828
29+ import cheroot .ssl as _cheroot_ssl
2930from cheroot .ssl import Adapter
3031
3132from .._compat import (
@@ -149,10 +150,15 @@ def make_tls_http_server(bind_addr, ssl_adapter, request):
149150 return httpserver
150151
151152
153+ def get_key_password ():
154+ """Provide hardcoded password for private key as callable."""
155+ return 'криївка'
156+
157+
152158@pytest .fixture (scope = 'session' )
153159def private_key_password ():
154160 """Provide hardcoded password for private key."""
155- return 'криївка'
161+ return get_key_password ()
156162
157163
158164@pytest .fixture
@@ -810,8 +816,8 @@ def test_http_over_https_error(
810816)
811817@pytest .mark .parametrize (
812818 'password_as_bytes' ,
813- (True , False ),
814- ids = ('with-bytes-password' , 'with-str-password' ),
819+ (True , False , None ),
820+ ids = ('with-bytes-password' , 'with-str-password' , 'with-callable-password' ),
815821)
816822# pylint: disable-next=too-many-positional-arguments
817823def test_ssl_adapters_with_private_key_password (
@@ -833,9 +839,13 @@ def test_ssl_adapters_with_private_key_password(
833839 else tls_certificate_private_key_pem_path
834840 )
835841 key_pass = (
836- private_key_password .encode ('utf-8' )
842+ private_key_password .encode ('utf-8' ) # use bytes
837843 if password_as_bytes
838- else private_key_password
844+ else (
845+ get_key_password # use callable
846+ if password_as_bytes is None
847+ else private_key_password # use str
848+ )
839849 )
840850
841851 tls_adapter_cls = get_ssl_adapter_class (name = adapter_type )
@@ -924,6 +934,50 @@ def test_openssl_adapter_with_false_key_password(
924934 )
925935
926936
937+ @pytest .mark .parametrize (
938+ 'adapter_type' ,
939+ ('pyopenssl' , 'builtin' ),
940+ )
941+ # pylint: disable-next=too-many-positional-arguments
942+ def test_openssl_adapter_with_none_key_password (
943+ http_request_timeout ,
944+ tls_certificate_chain_pem_path ,
945+ tls_certificate_passwd_private_key_pem_path ,
946+ tls_ca_certificate_pem_path ,
947+ tls_http_server ,
948+ private_key_password ,
949+ adapter_type ,
950+ monkeypatch ,
951+ ):
952+ """Check that openssl ssl-adapter prompts password when set as None."""
953+ tls_adapter_cls = get_ssl_adapter_class (name = adapter_type )
954+ monkeypatch .setattr (
955+ _cheroot_ssl ,
956+ '_ask_for_password_interactively' ,
957+ lambda prompt : private_key_password ,
958+ )
959+ tls_adapter = tls_adapter_cls (
960+ certificate = tls_certificate_chain_pem_path ,
961+ private_key = tls_certificate_passwd_private_key_pem_path ,
962+ )
963+
964+ interface , _host , port = _get_conn_data (
965+ tls_http_server (
966+ (ANY_INTERFACE_IPV4 , EPHEMERAL_PORT ),
967+ tls_adapter ,
968+ ).bind_addr ,
969+ )
970+
971+ resp = requests .get (
972+ f'https://{ interface !s} :{ port !s} /' ,
973+ timeout = http_request_timeout ,
974+ verify = tls_ca_certificate_pem_path ,
975+ )
976+
977+ assert resp .status_code == 200
978+ assert resp .text == 'Hello world!'
979+
980+
927981@pytest .fixture
928982def dummy_adapter (monkeypatch ):
929983 """Provide a dummy SSL adapter instance."""
0 commit comments