Implement a dummy CA

This commit is contained in:
Henrik Nordstrom 2011-02-08 18:00:59 +01:00
parent 4ffaadd435
commit 32adee8743
7 changed files with 294 additions and 66 deletions

View File

@ -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,

View File

@ -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

View File

@ -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:

View File

@ -27,10 +27,20 @@ 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,
@ -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)

View File

@ -31,11 +31,23 @@ 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,
@ -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)

View File

@ -34,11 +34,23 @@ 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,
@ -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:

View File

@ -30,11 +30,23 @@ 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,
@ -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)