mitmproxy/mitmproxy — pull request #372 by Fuzion24 (2014-10-07 22:13:49+00:00)
Title: Allow a leaf certificate to be used to sign all traffic

The use case here is that I want a certificate issued by a valid CA to sign all my traffic.
Example:

In the following usecase, I control the aaaaaaaaa.me domain and have the proper cert for it. I should be able feed the same .pem to mimproxy that I use to serve the website and have this work.

```
curl -x http://localhost:8080 -v https://aaaaaaaaa.me
* Rebuilt URL to: https://aaaaaaaaa.me/
* Hostname was NOT found in DNS cache
* Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 8080 (#0)
* Establish HTTP proxy tunnel to aaaaaaaaa.me:443
> CONNECT aaaaaaaaa.me:443 HTTP/1.1
> Host: aaaaaaaaa.me:443
> User-Agent: curl/7.35.0
> Proxy-Connection: Keep-Alive
>
< HTTP/1.1 200 Connection established
< Content-Length: 0
< Proxy-agent: mitmproxy 0.11
<
* Proxy replied OK to CONNECT request
* successfully set certificate verify locations:
* CAfile: none
CApath: /etc/ssl/certs
* SSLv3, TLS handshake, Client hello (1):
* SSLv3, TLS handshake, Server hello (2):
* SSLv3, TLS handshake, CERT (11):
* SSLv3, TLS alert, Server hello (2):
* SSL certificate problem: unable to get local issuer certificate
* Closing connection 0
curl: (60) SSL certificate problem: unable to get local issuer certificate
More details here: http://curl.haxx.se/docs/sslcerts.html

curl performs SSL certificate verification by default, using a "bundle"
of Certificate Authority (CA) public keys (CA certs). If the default
bundle file isn't adequate, you can specify an alternate file
using the --cacert option.
If this HTTPS server uses a certificate signed by a CA represented in
the bundle, the certificate verification probably failed due to a
problem with the certificate (it might be expired, or the name might
not match the domain name in the URL).
If you'd like to turn off curl's verification of the certificate, use
the -k (or --insecure) option.
```

The actual behaviour here is that mitmproxy uses the default ca the one in ```~/.mitmproxy```, creates a copy of the cert I passed it via ```--cert``` and signs it with said CA.

Setting the ```ca_file``` to the cert chain/.crt that my CA issued me solves this problem. This may not be a completely proper fix as this issued cert technically isn't a CA.

After applying the following fix, I am able to properly mitm my own server without installing a custom CA anywhere.

```
➜ mitmproxy git:(master) ✗ curl -x http://localhost:8080 -v https://aaaaaaaaa.me
* Rebuilt URL to: https://aaaaaaaaa.me/
* Hostname was NOT found in DNS cache
* Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 8080 (#0)
* Establish HTTP proxy tunnel to aaaaaaaaa.me:443
> CONNECT aaaaaaaaa.me:443 HTTP/1.1
> Host: aaaaaaaaa.me:443
> User-Agent: curl/7.35.0
> Proxy-Connection: Keep-Alive
>
< HTTP/1.1 200 Connection established
< Content-Length: 0
< Proxy-agent: mitmproxy 0.11
<
* Proxy replied OK to CONNECT request
* successfully set certificate verify locations:
* CAfile: none
CApath: /etc/ssl/certs
* SSLv3, TLS handshake, Client hello (1):
* SSLv3, TLS handshake, Server hello (2):
* SSLv3, TLS handshake, CERT (11):
* SSLv3, TLS handshake, Server key exchange (12):
* SSLv3, TLS handshake, Server finished (14):
* SSLv3, TLS handshake, Client key exchange (16):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSL connection using DHE-RSA-AES256-GCM-SHA384
* Server certificate:
* subject: OU=Domain Control Validated; OU=Free SSL; CN=aaaaaaaaa.me
* start date: 2014-10-07 00:00:00 GMT
* expire date: 2015-01-05 23:59:59 GMT
* subjectAltName: aaaaaaaaa.me matched
* issuer: C=GB; ST=Greater Manchester; L=Salford; O=COMODO CA Limited; CN=EssentialSSL CA
* SSL certificate verify ok.
> GET / HTTP/1.1
> User-Agent: curl/7.35.0
> Host: aaaaaaaaa.me
> Accept: */*
>
* HTTP 1.0, assume close after body
< HTTP/1.0 200 OK
```