Implement custom certs.

This commit is contained in:
Aldo Cortesi 2014-03-02 15:13:56 +13:00
parent 091e539a02
commit 234d326080
7 changed files with 68 additions and 43 deletions

View File

@ -22,7 +22,7 @@ class Response:
class Pathoc(tcp.TCPClient):
def __init__(self, address, ssl=None, sni=None, sslversion=1, clientcert=None, ciphers=None):
def __init__(self, address, ssl=None, sni=None, sslversion=4, clientcert=None, ciphers=None):
tcp.TCPClient.__init__(self, address)
self.settings = dict(
staticdir = os.getcwd(),

View File

@ -14,15 +14,18 @@ class PathodError(Exception): pass
class SSLOptions:
def __init__(self, confdir=CONFDIR, cn=None, certfile=None,
def __init__(self, confdir=CONFDIR, cn=None, certfile=None, cacert=None,
not_after_connect=None, request_client_cert=False,
sslversion=tcp.SSLv23_METHOD, ciphers=None):
self.confdir = confdir
self.cn = cn
cacert = os.path.join(confdir, CA_CERT_NAME)
self.cacert = os.path.expanduser(cacert)
if not os.path.exists(self.cacert):
certutils.dummy_ca(self.cacert)
if cacert:
self.cacert = os.path.expanduser(cacert)
else:
cacert = os.path.join(confdir, CA_CERT_NAME)
self.cacert = os.path.expanduser(cacert)
if not os.path.exists(self.cacert):
certutils.dummy_ca(self.cacert)
self.certstore = certutils.CertStore(self.cacert)
self.certfile = certfile
self.not_after_connect = not_after_connect
@ -30,6 +33,15 @@ class SSLOptions:
self.ciphers = ciphers
self.sslversion = sslversion
def get_cert(self, name):
if self.certfile:
return certutils.SSLCert.from_pem(file(self.certfile, "rb").read())
if self.cn:
name = self.cn
elif not name:
name = DEFAULT_CERT_DOMAIN
return self.certstore.get_cert(name, [])
class PathodHandler(tcp.BaseHandler):
@ -91,7 +103,7 @@ class PathodHandler(tcp.BaseHandler):
if not self.server.ssloptions.not_after_connect:
try:
self.convert_to_ssl(
self.server.ssloptions.certstore.get_cert(DEFAULT_CERT_DOMAIN, []),
self.server.ssloptions.get_cert(None),
self.server.ssloptions.cacert,
handle_sni = self.handle_sni,
request_client_cert = self.server.ssloptions.request_client_cert,
@ -199,10 +211,7 @@ class PathodHandler(tcp.BaseHandler):
if self.server.ssl:
try:
self.convert_to_ssl(
self.server.ssloptions.certstore.get_cert(
self.server.ssloptions.cn or DEFAULT_CERT_DOMAIN,
[]
),
self.server.ssloptions.get_cert(None),
self.server.ssloptions.cacert,
handle_sni = self.handle_sni,
request_client_cert = self.server.ssloptions.request_client_cert,

View File

@ -1,14 +0,0 @@
-----BEGIN CERTIFICATE-----
MIICITCCAYoCCQDkPC8Z2YHxuDANBgkqhkiG9w0BAQUFADBVMQswCQYDVQQGEwJO
WjEOMAwGA1UECBMFT3RhZ28xEDAOBgNVBAcTB0R1bmVkaW4xDzANBgNVBAoTBlBh
dGhvZDETMBEGA1UEAxMKcGF0aG9kLm9yZzAeFw0xMjA0MjgyMzEyNTZaFw0yMDA3
MTUyMzEyNTZaMFUxCzAJBgNVBAYTAk5aMQ4wDAYDVQQIEwVPdGFnbzEQMA4GA1UE
BxMHRHVuZWRpbjEPMA0GA1UEChMGUGF0aG9kMRMwEQYDVQQDEwpwYXRob2Qub3Jn
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDrc44bNmzRsfnAXKeaLA/GLc+R
zJUl+CtGghe5K9ESYqmF9JvKegfWpYqTqWZM+WtoQtkR4SLW/6KS2sXO2bwzdC/m
pfTYB+rFf6uRTNILBPkpb2YHh+p1ldwgRJ8ftqZrOyPv1lMP0mCgAMGR75rGvC5D
TbQZU7O8foyQYzz58wIDAQABMA0GCSqGSIb3DQEBBQUAA4GBACkZH6zSOlk1pcLN
9qwDuCG8yw3SR1E+B8n/jOiysqA8eZc5EL7njJMSZZMTHqfIfx6sfHH5aPSgCGCL
EzBz741uKkzuai1GXr34tqf3z1faSws00lJG5jHYevef9Og1RtClPfGcrH25+I1Z
unGdLFYj1i6owrv0UdWyHQxepzKV
-----END CERTIFICATE-----

View File

@ -1,15 +0,0 @@
-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQDrc44bNmzRsfnAXKeaLA/GLc+RzJUl+CtGghe5K9ESYqmF9JvK
egfWpYqTqWZM+WtoQtkR4SLW/6KS2sXO2bwzdC/mpfTYB+rFf6uRTNILBPkpb2YH
h+p1ldwgRJ8ftqZrOyPv1lMP0mCgAMGR75rGvC5DTbQZU7O8foyQYzz58wIDAQAB
AoGAFNKvarCxhwoacGzBVd03t+stRFO3jRgZm669sl6xqtKW84XikVGhh9Y0H0MI
DR6x5RKkZ/RlRGZvVlWK0PRotGjIoepX3D+LBFgCJjVVI+dHjRAZ3758e+iqC7Zy
3gVX7+fqiL56R5lZ02TofM/5I6JoJq/3ZP4SGB1tUO+BVaECQQD/SK/cxxhwdn0U
juPWvAp8iKXiI5YttkzIUdyezv3ZKW8YzcvFokKL0WrFOM3bbJNDomGZgtyZmB+3
c0/dCPwtAkEA7Byge10ovR4/c3t0ELQ/O8mKz48gPkd82Up369amAfkhmGxfYgDr
gMx7ExTKxaa1swjrD/h7jtz5MvukqXACnwJAFw5ai8cThvy8mUG6hCdhjxPMX5s1
MhW345O5KEKrnJRoa0YS9FuORRB54ywZM4sf1cjxpaqy/9BEdQ4eFWl9VQJBANr+
ylLh21Fd5thD3ylHJYdcreVKCUv6nnAkRAp4ss0Nt/1aNzX9SHHUNytBk7mzoMAI
O446mM+vYWvKP7XwcF0CQFFWxyizXOJG7rf72RtXCHf+LdJGJaOa9yLFdrMDBPtX
pDz6hFPxk54zecInfOJwcWkKFSniYLNii6dA3Nf2Ng0=
-----END RSA PRIVATE KEY-----

32
test/data/testkey.pem Normal file
View File

@ -0,0 +1,32 @@
-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQC+6rG6A/BGD0dI+mh2FZIqQZn82z/pGs4f3pyxbHb+ROxjjQOr
fDCw2jc11XDxK7CXpDQAnkO6au/sQ5t50vSZ+PGhFD+t558VV2ausB5OYZsR7RRx
gl1jsxWdde3EHGjxSK+aXRgFpVrZzPLSy6dl8tMoqUMWIBi0u1WTbmyYjwIDAQAB
AoGBAKyqhmK9/Sjf2JDgKGnjyHX/Ls3JXVvtqk6Yfw7YEiaVH1ZJyu/lOgQ414YQ
rDzyTpxXHdERUh/fZ24/FvZvHFgy5gWEQjQPpprIxvqCLKJhX73L2+TnXmfYDApb
J7V/JfnTeOaK9LTpHsofB98A1s9DWX/ccOgKTtZIYMjYpdoBAkEA9hLvtixbO2A2
ZgDcA9ftVX2WwdpRH+mYXl1G60Fem5nlO3Rl3FDoafRvSQNZiqyOlObvKbbYh/S2
L7ihEMMNYQJBAMaeLnAc9jO/z4ApTqSBGUpM9b7ul16aSgq56saUI0VULIZcXeo3
3BwdL2fEOOnzjNy6NpH2BW63h/+2t7lV++8CQQDK+S+1Sr0uKtx0Iv1YRkHEJMW3
vQbxldNS8wnOf6s0GisVcZubsTkkPLWWuiaf1ln9xMc9106gRmAI2PgyRVHBAkA6
iI+C9uYP5i1Oxd2pWWqMnRWnSUVO2gWMF7J7B1lFq0Lb7gi3Z/L0Th2UZR2oxN/0
hORkK676LBhmYgDPG+n9AkAJOnPIFQVAEBAO9bAxFrje8z6GRt332IlgxuiTeDE3
EAlH9tmZma4Tri4sWnhJwCsxl+5hWamI8NL4EIeXRvPw
-----END RSA PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
MIICsDCCAhmgAwIBAgIJAI7G7a/d5YwEMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV
BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX
aWRnaXRzIFB0eSBMdGQwHhcNMTAwMjAyMDM0MTExWhcNMTEwMjAyMDM0MTExWjBF
MQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50
ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB
gQC+6rG6A/BGD0dI+mh2FZIqQZn82z/pGs4f3pyxbHb+ROxjjQOrfDCw2jc11XDx
K7CXpDQAnkO6au/sQ5t50vSZ+PGhFD+t558VV2ausB5OYZsR7RRxgl1jsxWdde3E
HGjxSK+aXRgFpVrZzPLSy6dl8tMoqUMWIBi0u1WTbmyYjwIDAQABo4GnMIGkMB0G
A1UdDgQWBBS+MFJTsriCPNYsj8/4f+PympPEkzB1BgNVHSMEbjBsgBS+MFJTsriC
PNYsj8/4f+PympPEk6FJpEcwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUt
U3RhdGUxITAfBgNVBAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZIIJAI7G7a/d
5YwEMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEAlpan/QX2fpXVRihV
lQic2DktF4xd5unrZnFC8X8ScNX1ClU+AO79ejaobt4YGjeVYs0iQQsUL2E0G43c
mOXfsq1b970Ep6xRS76EmZ+tTdFBd86tFTIhZJrOi67gs+twj5V2elyp3tQpg2ze
G/jwDQS8V1X9CbfqBQriL7x5Tk4=
-----END CERTIFICATE-----

View File

@ -63,6 +63,19 @@ class TestNotAfterConnect(tutils.DaemonTests):
assert r.status_code == 202
class TestCustomCert(tutils.DaemonTests):
ssl = True
ssloptions = dict(
certfile = tutils.test_data.path("data/testkey.pem"),
cacert = tutils.test_data.path("data/testkey.pem"),
)
def test_connect(self):
r = self.pathoc(r"get:/p/202")
assert r.status_code == 202
assert r.sslinfo
class TestSSLCN(tutils.DaemonTests):
ssl = True
ssloptions = dict(

View File

@ -23,9 +23,9 @@ class TestDaemonManual:
def test_startstop_ssl_explicit(self):
ssloptions = dict(
keyfile = utils.data.path("resources/server.key"),
certfile = utils.data.path("resources/server.crt"),
ssl_after_connect = False
certfile = tutils.test_data.path("data/testkey.pem"),
cacert = tutils.test_data.path("data/testkey.pem"),
ssl_after_connect = False
)
d = test.Daemon(ssl=ssloptions)
rsp = requests.get("https://localhost:%s/p/202:da"%d.port, verify=False)