aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHenrik Nordstrom <henrik@henriknordstrom.net>2011-02-08 18:00:59 +0100
committerHenrik Nordstrom <henrik@henriknordstrom.net>2011-02-10 02:59:51 +0100
commit32adee8743526875c894007c89a988a19d12109f (patch)
tree33b6233040ef6c388e121de51a03f83b2a91c2b1
parent4ffaadd4355e943d7fa46f3050a1fb780f4d261d (diff)
downloadmitmproxy-32adee8743526875c894007c89a988a19d12109f.tar.gz
mitmproxy-32adee8743526875c894007c89a988a19d12109f.tar.bz2
mitmproxy-32adee8743526875c894007c89a988a19d12109f.zip
Implement a dummy CA
-rw-r--r--libmproxy/proxy.py27
-rw-r--r--libmproxy/resources/bogus_template11
-rw-r--r--libmproxy/utils.py171
-rwxr-xr-xmitmdump25
-rwxr-xr-xmitmplayback42
-rwxr-xr-xmitmproxy42
-rwxr-xr-xmitmrecord42
7 files changed, 294 insertions, 66 deletions
diff --git a/libmproxy/proxy.py b/libmproxy/proxy.py
index f3ea2ed2..8200c725 100644
--- a/libmproxy/proxy.py
+++ b/libmproxy/proxy.py
@@ -22,9 +22,11 @@ class ProxyError(Exception):
class Config:
- def __init__(self, pemfile, ciphers = None):
- self.pemfile = pemfile
+ def __init__(self, certfile = None, certpath = None, ciphers = None, cacert = None):
+ self.certfile = certfile
+ self.certpath = certpath
self.ciphers = ciphers
+ self.cacert = cacert
def read_chunked(fp):
@@ -495,6 +497,23 @@ class ProxyHandler(SocketServer.StreamRequestHandler):
if server:
server.terminate()
+ def find_cert(self, host, port=443):
+ #return config.certpath + "/" + host + ":" + port + ".pem"
+ if config.certpath is not None:
+ cert = config.certpath + "/" + host + ".pem"
+ if not os.path.exists(cert) and config.cacert is not None:
+ utils.make_bogus_cert(cert, ca=config.cacert, commonName=host)
+ if os.path.exists(cert):
+ return cert
+ print >> sys.stderr, "WARNING: Certificate missing for %s:%d! (%s)\n" % (host, port, cert)
+ return config.certfile
+
+ def find_key(self, host, port=443):
+ if config.cacert is not None:
+ return config.cacert
+ else:
+ return config.certfile
+
def read_request(self, client_conn):
line = self.rfile.readline()
if line == "\r\n" or line == "\n": # Possible leftover from previous message
@@ -517,8 +536,8 @@ class ProxyHandler(SocketServer.StreamRequestHandler):
self.wfile.flush()
self.connection = ssl.wrap_socket(
self.connection,
- certfile = config.pemfile,
- keyfile = config.pemfile,
+ certfile = self.find_cert(host,port),
+ keyfile = self.find_key(host,port),
server_side = True,
ssl_version = ssl.PROTOCOL_SSLv23,
ciphers = config.ciphers,
diff --git a/libmproxy/resources/bogus_template b/libmproxy/resources/bogus_template
deleted file mode 100644
index afa7281c..00000000
--- a/libmproxy/resources/bogus_template
+++ /dev/null
@@ -1,11 +0,0 @@
-[ req ]
-prompt = no
-distinguished_name = req_distinguished_name
-
-[ req_distinguished_name ]
-C = NZ
-ST = none
-L = none
-O = none
-OU = none
-emailAddress = none
diff --git a/libmproxy/utils.py b/libmproxy/utils.py
index 87fca5ce..39279e04 100644
--- a/libmproxy/utils.py
+++ b/libmproxy/utils.py
@@ -14,7 +14,6 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import re, os, subprocess, datetime, textwrap, errno
-
def format_timestamp(s):
d = datetime.datetime.fromtimestamp(s)
return d.strftime("%Y-%m-%d %H:%M:%S")
@@ -314,32 +313,166 @@ class Data:
data = Data(__name__)
-def make_bogus_cert(path):
+def make_openssl_conf(path, countryName=None, stateOrProvinceName=None, localityName=None, organizationName=None, organizationalUnitName=None, commonName=None, emailAddress=None, ca=False):
+ cnf = open(path, "w")
+ cnf.write("[ req ]\n")
+ cnf.write("prompt = no\n")
+ cnf.write("distinguished_name = req_distinguished_name\n")
+ if ca:
+ cnf.write("x509_extensions = v3_ca # The extentions to add to the self signed cert\n")
+ cnf.write("\n")
+ cnf.write("[ req_distinguished_name ]\n")
+ if countryName is not None:
+ cnf.write("countryName = %s\n" % (countryName) )
+ cnf.write("stateOrProvinceName = %s\n" % (stateOrProvinceName) )
+ cnf.write("localityName = %s\n" % (localityName) )
+ cnf.write("organizationName = %s\n" % (organizationName) )
+ cnf.write("organizationalUnitName = %s\n" % (organizationalUnitName) )
+ cnf.write("commonName = %s\n" % (commonName) )
+ cnf.write("emailAddress = %s\n" % (emailAddress) )
+ cnf.write("\n")
+ cnf.write("[ v3_ca ]\n")
+ cnf.write("subjectKeyIdentifier=hash\n")
+ cnf.write("authorityKeyIdentifier=keyid:always,issuer\n")
+ if ca:
+ cnf.write("basicConstraints = critical,CA:true\n")
+ cnf.write("keyUsage = cRLSign, keyCertSign\n")
+ #cnf.write("nsCertType = sslCA, emailCA\n")
+ #cnf.write("subjectAltName=email:copy\n")
+ #cnf.write("issuerAltName=issuer:copy\n")
+
+def make_bogus_cert(certpath, countryName=None, stateOrProvinceName=None, localityName=None, organizationName="mitmproxy", organizationalUnitName=None, commonName="Dummy Certificate", emailAddress=None, ca=None, newca=False):
# Generates a bogus certificate like so:
# openssl req -config template -x509 -nodes -days 9999 -newkey rsa:1024 \
# -keyout cert.pem -out cert.pem
+ (path, ext) = os.path.splitext(certpath)
d = os.path.dirname(path)
if not os.path.exists(d):
os.makedirs(d)
- cmd = [
- "openssl",
- "req",
- "-config", data.path("resources/bogus_template"),
- "-x509" ,
- "-nodes",
- "-days", "9999",
- "-newkey", "rsa:1024",
- "-keyout", path,
- "-out", path,
- ]
- subprocess.call(
- cmd,
- stderr=subprocess.PIPE,
- stdout=subprocess.PIPE,
- stdin=subprocess.PIPE
- )
+ cnf = open(path+".cnf", "w")
+ cnf.write("[ req ]\n")
+ cnf.write("prompt = no\n")
+ cnf.write("distinguished_name = req_distinguished_name\n")
+ if newca:
+ cnf.write("x509_extensions = v3_ca\n")
+ cnf.write("req_extensions = v3_ca_req\n")
+ else:
+ cnf.write("x509_extensions = v3_cert\n")
+ cnf.write("req_extensions = v3_cert_req\n")
+ cnf.write("\n")
+ cnf.write("[ req_distinguished_name ]\n")
+ if countryName is not None:
+ cnf.write("countryName = %s\n" % (countryName) )
+ if stateOrProvinceName is not None:
+ cnf.write("stateOrProvinceName = %s\n" % (stateOrProvinceName) )
+ if localityName is not None:
+ cnf.write("localityName = %s\n" % (localityName) )
+ if organizationName is not None:
+ cnf.write("organizationName = %s\n" % (organizationName) )
+ if organizationalUnitName is not None:
+ cnf.write("organizationalUnitName = %s\n" % (organizationalUnitName) )
+ if commonName is not None:
+ cnf.write("commonName = %s\n" % (commonName) )
+ if emailAddress is not None:
+ cnf.write("emailAddress = %s\n" % (emailAddress) )
+ cnf.write("\n")
+ cnf.write("[ v3_ca ]\n")
+ cnf.write("subjectKeyIdentifier=hash\n")
+ cnf.write("authorityKeyIdentifier=keyid:always,issuer\n")
+ cnf.write("basicConstraints = critical,CA:true\n")
+ cnf.write("keyUsage = cRLSign, keyCertSign\n")
+ cnf.write("nsCertType = sslCA\n")
+ #cnf.write("subjectAltName=email:copy\n")
+ #cnf.write("issuerAltName=issuer:copy\n")
+ cnf.write("\n")
+ cnf.write("[ v3_ca_req ]\n")
+ cnf.write("basicConstraints = critical,CA:true\n")
+ cnf.write("keyUsage = cRLSign, keyCertSign\n")
+ cnf.write("nsCertType = sslCA\n")
+ #cnf.write("subjectAltName=email:copy\n")
+ cnf.write("\n")
+ cnf.write("[ v3_cert ]\n")
+ cnf.write("basicConstraints = CA:false\n")
+ cnf.write("keyUsage = nonRepudiation, digitalSignature, keyEncipherment\n")
+ cnf.write("nsCertType = server\n")
+ cnf.write("subjectKeyIdentifier=hash\n")
+ cnf.write("authorityKeyIdentifier=keyid:always,issuer\n")
+ cnf.write("\n")
+ cnf.write("[ v3_cert_req ]\n")
+ cnf.write("basicConstraints = CA:false\n")
+ cnf.write("keyUsage = nonRepudiation, digitalSignature, keyEncipherment\n")
+ cnf.write("nsCertType = server\n")
+ cnf.write("\n")
+
+ cnf.close()
+
+ if ca is None:
+ # Create a new selfsigned certificate + key
+ cmd = [
+ "openssl",
+ "req",
+ "-new",
+ "-x509",
+ "-config", path+".cnf",
+ "-nodes",
+ "-days", "9999",
+ "-out", certpath,
+ "-newkey", "rsa:1024",
+ "-keyout", certpath,
+ ]
+ #print " ".join(cmd)
+ subprocess.call(
+ cmd,
+ stderr=subprocess.PIPE,
+ stdout=subprocess.PIPE,
+ stdin=subprocess.PIPE
+ )
+ else:
+ # Create a dummy signed certificate. Uses same key as the signing CA
+ cmd = [
+ "openssl",
+ "req",
+ "-new",
+ "-config", path+".cnf",
+ "-out", path+".req",
+ "-key", ca,
+ ]
+ #print " ".join(cmd)
+ subprocess.call(
+ cmd,
+ stderr=subprocess.PIPE,
+ stdout=subprocess.PIPE,
+ stdin=subprocess.PIPE
+ )
+ cmd = [
+ "openssl",
+ "x509",
+ "-req",
+ "-in", path+".req",
+ "-days", "9999",
+ "-out", certpath,
+ "-CA", ca,
+ "-CAcreateserial",
+ "-extfile", path+".cnf"
+ ]
+ if newca:
+ cmd.extend([
+ "-extensions", "v3_ca",
+ ])
+ else:
+ cmd.extend([
+ "-extensions", "v3_cert",
+ ])
+
+ #print " ".join(cmd)
+ subprocess.call(
+ cmd,
+ stderr=subprocess.PIPE,
+ stdout=subprocess.PIPE,
+ stdin=subprocess.PIPE
+ )
def mkdir_p(path):
try:
diff --git a/mitmdump b/mitmdump
index 26686afd..11b71568 100755
--- a/mitmdump
+++ b/mitmdump
@@ -27,11 +27,21 @@ if __name__ == '__main__':
version="%%prog %s"%VERSION,
)
parser.add_option(
- "-c", "--cert", action="store",
- type = "str", dest="cert", default="~/.mitmproxy/cert.pem",
+ "--cert", action="store",
+ type = "str", dest="cert", default="~/.mitmproxy/default.pem",
help = "SSL certificate file."
)
parser.add_option(
+ "-c", "--cacert", action="store",
+ type = "str", dest="cacert", default="~/.mitmproxy/ca.pem",
+ help = "SSL CA certificate file."
+ )
+ parser.add_option(
+ "--certpath", action="store",
+ type = "str", dest="certpath", default="~/.mitmproxy/",
+ help = "SSL certificate store path."
+ )
+ parser.add_option(
"--ciphers", action="store",
type = "str", dest="ciphers", default=None,
help = "SSL ciphers."
@@ -52,14 +62,17 @@ if __name__ == '__main__':
if options.quiet:
options.verbose = 0
- certpath = os.path.expanduser(options.cert)
+ options.cert = os.path.expanduser(options.cert)
+ options.certpath = os.path.expanduser(options.certpath)
- if not os.path.exists(certpath):
+ if not os.path.exists(options.cert):
print >> sys.stderr, "Creating bogus certificate at %s"%options.cert
- utils.make_bogus_cert(certpath)
+ utils.make_bogus_cert(options.cert)
proxy.config = proxy.Config(
- certpath,
+ certfile = options.cert,
+ certpath = options.certpath,
+ cacert = options.cacert,
ciphers = options.ciphers
)
server = proxy.ProxyServer(options.port)
diff --git a/mitmplayback b/mitmplayback
index eb147cd9..9d4fe11a 100755
--- a/mitmplayback
+++ b/mitmplayback
@@ -31,12 +31,24 @@ if __name__ == '__main__':
)
parser.add_option(
- "-c", "--cert", action="store",
- type = "str", dest="cert", default="~/.mitmproxy/cert.pem",
+ "--cert", action="store",
+ type = "str", dest="cert", default="~/.mitmproxy/default.pem",
help = "SSL certificate file."
)
parser.add_option(
+ "-c", "--cacert", action="store",
+ type = "str", dest="cacert", default="~/.mitmproxy/ca.pem",
+ help = "SSL CA certificate file."
+ )
+
+ parser.add_option(
+ "--certpath", action="store",
+ type = "str", dest="certpath", default=None,
+ help = "SSL certificate store path."
+ )
+
+ parser.add_option(
"--ciphers", action="store",
type = "str", dest="ciphers", default=None,
help = "SSL ciphers."
@@ -66,15 +78,27 @@ if __name__ == '__main__':
if options.quiet:
options.verbose = 0
- certpath = os.path.expanduser(options.cert)
- options.cache = os.path.expanduser(options.cache)
+ if options.cert is not None:
+ options.cert = os.path.expanduser(options.cert)
+ if not os.path.exists(options.cert):
+ print >> sys.stderr, "Creating bogus certificate at %s"%options.cert
+ utils.make_bogus_cert(options.cert)
+ if options.cacert is not None:
+ options.cacert = os.path.expanduser(options.cacert)
+ if not os.path.exists(options.cacert):
+ print >> sys.stderr, "Creating bogus CA certificate at %s"%options.cacert
+ utils.make_bogus_cert(options.cacert, newca=True, commonName="Dummy CA")
+ if options.certpath is not None:
+ options.certpath = os.path.expanduser(options.certpath)
+ elif options.cacert is not None:
+ options.certpath = os.path.dirname(options.cacert)
+ if options.cache is not None:
+ options.cache = os.path.expanduser(options.cache)
- if not os.path.exists(certpath):
- print >> sys.stderr, "Creating bogus certificate at %s"%options.cert
- utils.make_bogus_cert(certpath)
-
proxy.config = proxy.Config(
- certpath,
+ certfile = options.cert,
+ certpath = options.certpath,
+ cacert = options.cacert,
ciphers = options.ciphers
)
server = proxy.ProxyServer(options.port)
diff --git a/mitmproxy b/mitmproxy
index e3ec9d9e..cf746e38 100755
--- a/mitmproxy
+++ b/mitmproxy
@@ -34,12 +34,24 @@ if __name__ == '__main__':
)
parser.add_option(
- "-c", "--cert", action="store",
- type = "str", dest="cert", default="~/.mitmproxy/cert.pem",
+ "--cert", action="store",
+ type = "str", dest="cert", default="~/.mitmproxy/default.pem",
help = "SSL certificate file."
)
parser.add_option(
+ "-c", "--cacert", action="store",
+ type = "str", dest="cacert", default="~/.mitmproxy/ca.pem",
+ help = "SSL CA certificate file."
+ )
+
+ parser.add_option(
+ "--certpath", action="store",
+ type = "str", dest="certpath", default="~/.mitmproxy/",
+ help = "SSL certificate store path."
+ )
+
+ parser.add_option(
"--ciphers", action="store",
type = "str", dest="ciphers", default=None,
help = "SSL ciphers."
@@ -96,14 +108,28 @@ if __name__ == '__main__':
parser.add_option_group(group)
options, args = parser.parse_args()
- certpath = os.path.expanduser(options.cert)
-
- if not os.path.exists(certpath):
- print >> sys.stderr, "Creating bogus certificate at %s"%options.cert
- utils.make_bogus_cert(certpath)
+
+ if options.cert is not None:
+ options.cert = os.path.expanduser(options.cert)
+ if not os.path.exists(options.cert):
+ print >> sys.stderr, "Creating bogus certificate at %s"%options.cert
+ utils.make_bogus_cert(options.cert)
+ if options.cacert is not None:
+ options.cacert = os.path.expanduser(options.cacert)
+ if not os.path.exists(options.cacert):
+ print >> sys.stderr, "Creating bogus CA certificate at %s"%options.cacert
+ utils.make_bogus_cert(options.cacert, newca=True, commonName="Dummy CA")
+ if options.certpath is not None:
+ options.certpath = os.path.expanduser(options.certpath)
+ elif options.cacert is not None:
+ options.certpath = os.path.dirname(options.cacert)
+ if options.cache is not None:
+ options.cache = os.path.expanduser(options.cache)
proxy.config = proxy.Config(
- certpath,
+ certfile = options.cert,
+ certpath = options.certpath,
+ cacert = options.cacert,
ciphers = options.ciphers
)
if options.cache is not None:
diff --git a/mitmrecord b/mitmrecord
index 11c7b6ca..1f81633c 100755
--- a/mitmrecord
+++ b/mitmrecord
@@ -30,12 +30,24 @@ if __name__ == '__main__':
)
parser.add_option(
- "-c", "--cert", action="store",
- type = "str", dest="cert", default="~/.mitmproxy/cert.pem",
+ "--cert", action="store",
+ type = "str", dest="cert", default="~/.mitmproxy/default.pem",
help = "SSL certificate file."
)
parser.add_option(
+ "-c", "--cacert", action="store",
+ type = "str", dest="cacert", default="~/.mitmproxy/ca.pem",
+ help = "SSL CA certificate file."
+ )
+
+ parser.add_option(
+ "--certpath", action="store",
+ type = "str", dest="certpath", default=None,
+ help = "SSL certificate store path."
+ )
+
+ parser.add_option(
"--ciphers", action="store",
type = "str", dest="ciphers", default=None,
help = "SSL ciphers."
@@ -71,15 +83,27 @@ if __name__ == '__main__':
if options.quiet:
options.verbose = 0
- certpath = os.path.expanduser(options.cert)
- options.cache = os.path.expanduser(options.cache)
-
- if not os.path.exists(certpath):
- print >> sys.stderr, "Creating bogus certificate at %s"%options.cert
- utils.make_bogus_cert(certpath)
+ if options.cert is not None:
+ options.cert = os.path.expanduser(options.cert)
+ if not os.path.exists(options.cert):
+ print >> sys.stderr, "Creating bogus certificate at %s"%options.cert
+ utils.make_bogus_cert(options.cert)
+ if options.cacert is not None:
+ options.cacert = os.path.expanduser(options.cacert)
+ if not os.path.exists(options.cacert):
+ print >> sys.stderr, "Creating bogus CA certificate at %s"%options.cacert
+ utils.make_bogus_cert(options.cacert, newca=True, commonName="Dummy CA")
+ if options.certpath is not None:
+ options.certpath = os.path.expanduser(options.certpath)
+ elif options.cacert is not None:
+ options.certpath = os.path.dirname(options.cacert)
+ if options.cache is not None:
+ options.cache = os.path.expanduser(options.cache)
proxy.config = proxy.Config(
- certpath,
+ certfile = options.cert,
+ certpath = options.certpath,
+ cacert = options.cacert,
ciphers = options.ciphers
)
server = proxy.ProxyServer(options.port)