This commit fixes netlib's optional (turned off by default)
certificate verification, which previously did not validate the
cert's host name. As it turns out, verifying the connection's host
name on an intercepting proxy is not really straightforward - if
we receive a connection in transparent mode without SNI, we have no
clue which hosts the client intends to connect to. There are two
basic approaches to solve this problem:
1. Exactly mirror the host names presented by the server in the
spoofed certificate presented to the client.
2. Require the client to send the TLS Server Name Indication
extension. While this does not work with older clients,
we can validate the hostname on the proxy.
Approach 1 is problematic in mitmproxy's use case, as we may want
to deliberately divert connections without the client's knowledge.
As a consequence, we opt for approach 2. While mitmproxy does now
require a SNI value to be sent by the client if certificate
verification is turned on, we retain our ability to present
certificates to the client which are accepted with a maximum
likelihood.
fixesmitmproxy/mitmproxy#772
We must use the ipaddress package here, because that's what cryptography
uses. If we opt for something else, we have nasty namespace conflicts.
- Handle wildcard lookup
- Handle lookup of SANs
- Provide hooks for registering override certs and keys for specific
domains (including wildcard specifications)
By default, we now do not request the client cert. We're supposed to be able to
do this with no negative effects - if the client has no cert to present, we're
notified and proceed as usual. Unfortunately, Android seems to have a bug
(tested on 4.2.2) - when an Android client is asked to present a certificate it
does not have, it hangs up, which is frankly bogus. Some time down the track
we may be able to make the proper behaviour the default again, but until then
we're conservative.