aboutsummaryrefslogtreecommitdiffstats
path: root/mitmproxy/net/tcp.py
diff options
context:
space:
mode:
Diffstat (limited to 'mitmproxy/net/tcp.py')
-rw-r--r--mitmproxy/net/tcp.py77
1 files changed, 9 insertions, 68 deletions
diff --git a/mitmproxy/net/tcp.py b/mitmproxy/net/tcp.py
index 35d3388f..47c80e80 100644
--- a/mitmproxy/net/tcp.py
+++ b/mitmproxy/net/tcp.py
@@ -5,8 +5,6 @@ import sys
import threading
import time
import traceback
-from ssl import match_hostname
-from ssl import CertificateError
from typing import Optional # noqa
@@ -365,10 +363,13 @@ class TCPClient(_Connection):
self.source_address = source_address
self.cert = None
self.server_certs = []
- self.ssl_verification_error = None # type: Optional[exceptions.InvalidCertificateException]
self.sni = None
self.spoof_source_address = spoof_source_address
+ @property
+ def ssl_verification_error(self) -> Optional[exceptions.InvalidCertificateException]:
+ return getattr(self.connection, "cert_error", None)
+
def close(self):
# Make sure to close the real socket, not the SSL proxy.
# OpenSSL is really good at screwing up, i.e. when trying to recv from a failed connection,
@@ -380,29 +381,8 @@ class TCPClient(_Connection):
else:
close_socket(self.connection)
- def create_ssl_context(self, **sslctx_kwargs):
- def store_err(e):
- self.ssl_verification_error = e
-
- return tls.create_client_context(
- verify_error_callback=store_err,
- **sslctx_kwargs,
- )
-
def convert_to_ssl(self, sni=None, alpn_protos=None, **sslctx_kwargs):
- """
- cert: Path to a file containing both client cert and private key.
-
- options: A bit field consisting of OpenSSL.SSL.OP_* values
- verify_options: A bit field consisting of OpenSSL.SSL.VERIFY_* values
- ca_path: Path to a directory of trusted CA certificates prepared using the c_rehash tool
- ca_pemfile: Path to a PEM formatted trusted CA certificate
- """
- verification_mode = sslctx_kwargs.get('verify_options', None)
- if verification_mode == SSL.VERIFY_PEER and not sni:
- raise exceptions.TlsException("Cannot validate certificate hostname without SNI")
-
- context = self.create_ssl_context(
+ context = tls.create_client_context(
alpn_protos=alpn_protos,
sni=sni,
**sslctx_kwargs
@@ -426,33 +406,6 @@ class TCPClient(_Connection):
for i in self.connection.get_peer_cert_chain():
self.server_certs.append(certs.SSLCert(i))
- # Validate TLS Hostname
- try:
- crt = dict(
- subjectAltName=[("DNS", x.decode("ascii", "strict")) for x in self.cert.altnames]
- )
- if self.cert.cn:
- crt["subject"] = [[["commonName", self.cert.cn.decode("ascii", "strict")]]]
- if sni:
- # SNI hostnames allow support of IDN by using ASCII-Compatible Encoding
- # Conversion algorithm is in RFC 3490 which is implemented by idna codec
- # https://docs.python.org/3/library/codecs.html#text-encodings
- # https://tools.ietf.org/html/rfc6066#section-3
- # https://tools.ietf.org/html/rfc4985#section-3
- hostname = sni.encode("idna").decode("ascii")
- else:
- hostname = "no-hostname"
- match_hostname(crt, hostname)
- except (ValueError, CertificateError) as e:
- self.ssl_verification_error = exceptions.InvalidCertificateException(
- "Certificate Verification Error for {}: {}".format(
- sni or repr(self.address),
- str(e)
- )
- )
- if verification_mode == SSL.VERIFY_PEER:
- raise self.ssl_verification_error
-
self.ssl_established = True
self.rfile.set_descriptor(self.connection)
self.wfile.set_descriptor(self.connection)
@@ -538,28 +491,13 @@ class BaseHandler(_Connection):
self.server = server
self.clientcert = None
- def create_ssl_context(self, **kwargs):
- if kwargs.get("request_client_cert", None) is True:
- def store_clientcert(cert):
- self.clientcert = cert
-
- kwargs["request_client_cert"] = store_clientcert
-
- def store_err(e):
- self.ssl_verification_error = e
-
- return tls.create_server_context(
- **kwargs,
- verify_error_callback=store_err,
- )
-
def convert_to_ssl(self, cert, key, **sslctx_kwargs):
"""
Convert connection to SSL.
For a list of parameters, see tls.create_server_context(...)
"""
- context = self.create_ssl_context(
+ context = tls.create_server_context(
cert=cert,
key=key,
**sslctx_kwargs)
@@ -570,6 +508,9 @@ class BaseHandler(_Connection):
except SSL.Error as v:
raise exceptions.TlsException("SSL handshake error: %s" % repr(v))
self.ssl_established = True
+ cert = self.connection.get_peer_certificate()
+ if cert:
+ self.clientcert = certs.SSLCert(cert)
self.rfile.set_descriptor(self.connection)
self.wfile.set_descriptor(self.connection)