diff --git a/mitmproxy/certs.py b/mitmproxy/certs.py index eebd144e1..be801b92e 100644 --- a/mitmproxy/certs.py +++ b/mitmproxy/certs.py @@ -302,16 +302,16 @@ class CertStore: # we could use cryptography for this, but it's unclear how to convert cryptography's object to pyOpenSSL's # expected format. - bio = OpenSSL.SSL._lib.BIO_new_file(str(path).encode(sys.getfilesystemencoding()), b"r") - if bio != OpenSSL.SSL._ffi.NULL: - bio = OpenSSL.SSL._ffi.gc(bio, OpenSSL.SSL._lib.BIO_free) - dh = OpenSSL.SSL._lib.PEM_read_bio_DHparams( + bio = OpenSSL.SSL._lib.BIO_new_file(str(path).encode(sys.getfilesystemencoding()), b"r") # type: ignore + if bio != OpenSSL.SSL._ffi.NULL: # type: ignore + bio = OpenSSL.SSL._ffi.gc(bio, OpenSSL.SSL._lib.BIO_free) # type: ignore + dh = OpenSSL.SSL._lib.PEM_read_bio_DHparams( # type: ignore bio, - OpenSSL.SSL._ffi.NULL, - OpenSSL.SSL._ffi.NULL, - OpenSSL.SSL._ffi.NULL + OpenSSL.SSL._ffi.NULL, # type: ignore + OpenSSL.SSL._ffi.NULL, # type: ignore + OpenSSL.SSL._ffi.NULL # type: ignore ) - dh = OpenSSL.SSL._ffi.gc(dh, OpenSSL.SSL._lib.DH_free) + dh = OpenSSL.SSL._ffi.gc(dh, OpenSSL.SSL._lib.DH_free) # type: ignore return dh raise RuntimeError("Error loading DH Params.") # pragma: no cover diff --git a/mitmproxy/net/tls.py b/mitmproxy/net/tls.py index abd2273f6..0cdffef4d 100644 --- a/mitmproxy/net/tls.py +++ b/mitmproxy/net/tls.py @@ -7,6 +7,8 @@ from pathlib import Path from typing import Iterable, Callable, Optional, Sequence, Tuple, List, Any, BinaryIO import certifi + +from OpenSSL.crypto import X509 from cryptography.hazmat.primitives.asymmetric import rsa from kaitaistruct import KaitaiStream @@ -25,12 +27,12 @@ class Method(Enum): # TODO: remove once https://github.com/pyca/pyopenssl/pull/985 has landed. try: - SSL._lib.TLS_server_method + SSL._lib.TLS_server_method # type: ignore except AttributeError as e: # pragma: no cover raise RuntimeError("Your installation of the cryptography Python package is outdated.") from e -SSL.Context._methods.setdefault(Method.TLS_SERVER_METHOD.value, SSL._lib.TLS_server_method) -SSL.Context._methods.setdefault(Method.TLS_CLIENT_METHOD.value, SSL._lib.TLS_client_method) +SSL.Context._methods.setdefault(Method.TLS_SERVER_METHOD.value, SSL._lib.TLS_server_method) # type: ignore +SSL.Context._methods.setdefault(Method.TLS_CLIENT_METHOD.value, SSL._lib.TLS_client_method) # type: ignore class Version(Enum): @@ -100,8 +102,8 @@ def _create_ssl_context( ) -> SSL.Context: context = SSL.Context(method.value) - ok = SSL._lib.SSL_CTX_set_min_proto_version(context._context, min_version.value) - ok += SSL._lib.SSL_CTX_set_max_proto_version(context._context, max_version.value) + ok = SSL._lib.SSL_CTX_set_min_proto_version(context._context, min_version.value) # type: ignore + ok += SSL._lib.SSL_CTX_set_max_proto_version(context._context, max_version.value) # type: ignore if ok != 2: raise RuntimeError( f"Error setting TLS versions ({min_version=}, {max_version=}). " @@ -152,22 +154,22 @@ def create_proxy_server_context( assert isinstance(hostname, str) # Manually enable hostname verification on the context object. # https://wiki.openssl.org/index.php/Hostname_validation - param = SSL._lib.SSL_CTX_get0_param(context._context) + param = SSL._lib.SSL_CTX_get0_param(context._context) # type: ignore # Matching on the CN is disabled in both Chrome and Firefox, so we disable it, too. # https://www.chromestatus.com/feature/4981025180483584 - SSL._lib.X509_VERIFY_PARAM_set_hostflags( + SSL._lib.X509_VERIFY_PARAM_set_hostflags( # type: ignore param, - SSL._lib.X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS | SSL._lib.X509_CHECK_FLAG_NEVER_CHECK_SUBJECT + SSL._lib.X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS | SSL._lib.X509_CHECK_FLAG_NEVER_CHECK_SUBJECT # type: ignore ) try: ip: bytes = ipaddress.ip_address(hostname).packed except ValueError: - SSL._openssl_assert( - SSL._lib.X509_VERIFY_PARAM_set1_host(param, hostname.encode(), 0) == 1 + SSL._openssl_assert( # type: ignore + SSL._lib.X509_VERIFY_PARAM_set1_host(param, hostname.encode(), 0) == 1 # type: ignore ) else: - SSL._openssl_assert( - SSL._lib.X509_VERIFY_PARAM_set1_ip(param, ip, len(ip)) == 1 + SSL._openssl_assert( # type: ignore + SSL._lib.X509_VERIFY_PARAM_set1_ip(param, ip, len(ip)) == 1 # type: ignore ) if ca_path is None and ca_pemfile is None: @@ -238,20 +240,20 @@ def create_client_proxy_context( context.set_verify(Verify.VERIFY_NONE.value, None) for i in extra_chain_certs: - context.add_extra_chain_cert(i._cert) + context.add_extra_chain_cert(i.to_pyopenssl()) if dhparams: - SSL._lib.SSL_CTX_set_tmp_dh(context._context, dhparams) + SSL._lib.SSL_CTX_set_tmp_dh(context._context, dhparams) # type: ignore return context def accept_all( conn_: SSL.Connection, - x509: SSL.X509, + x509: X509, errno: int, err_depth: int, - is_cert_verified: bool, + is_cert_verified: int, ) -> bool: # Return true to prevent cert verification error return True diff --git a/mitmproxy/proxy/layers/tls.py b/mitmproxy/proxy/layers/tls.py index 1551978cf..497e44cc4 100644 --- a/mitmproxy/proxy/layers/tls.py +++ b/mitmproxy/proxy/layers/tls.py @@ -133,7 +133,7 @@ class TlsStartHook(StartHook): class _TLSLayer(tunnel.TunnelLayer): - tls: SSL.Connection = None + tls: SSL.Connection = None # type: ignore """The OpenSSL connection object""" def __init__(self, context: context.Context, conn: connection.Connection): @@ -181,8 +181,8 @@ class _TLSLayer(tunnel.TunnelLayer): # provide more detailed information for some errors. last_err = e.args and isinstance(e.args[0], list) and e.args[0] and e.args[0][-1] if last_err == ('SSL routines', 'tls_process_server_certificate', 'certificate verify failed'): - verify_result = SSL._lib.SSL_get_verify_result(self.tls._ssl) - error = SSL._ffi.string(SSL._lib.X509_verify_cert_error_string(verify_result)).decode() + verify_result = SSL._lib.SSL_get_verify_result(self.tls._ssl) # type: ignore + error = SSL._ffi.string(SSL._lib.X509_verify_cert_error_string(verify_result)).decode() # type: ignore err = f"Certificate verify failed: {error}" elif last_err in [ ('SSL routines', 'ssl3_read_bytes', 'tlsv1 alert unknown ca'), diff --git a/mitmproxy/test/tflow.py b/mitmproxy/test/tflow.py index 496e380b5..7189adcef 100644 --- a/mitmproxy/test/tflow.py +++ b/mitmproxy/test/tflow.py @@ -6,7 +6,7 @@ from mitmproxy import flow from mitmproxy import http from mitmproxy import tcp from mitmproxy import websocket -from mitmproxy.test import tutils +from mitmproxy.test.tutils import treq, tresp from wsproto.frame_protocol import Opcode @@ -95,9 +95,9 @@ def tflow(client_conn=True, server_conn=True, req=True, resp=None, err=None): if server_conn is True: server_conn = tserver_conn() if req is True: - req = tutils.treq() + req = treq() if resp is True: - resp = tutils.tresp() + resp = tresp() if err is True: err = terr() diff --git a/tox.ini b/tox.ini index 6ba9cc0c2..104f27f3f 100644 --- a/tox.ini +++ b/tox.ini @@ -29,12 +29,13 @@ commands = [testenv:mypy] deps = - mypy==0.902 + mypy==0.910 types-certifi==0.1.4 types-Flask==1.1.1 types-Werkzeug==1.0.2 types-requests==2.25.0 types-cryptography==3.3.3 + types-pyOpenSSL==20.0.3 commands = mypy {posargs}