def test_catchesMissingCertificate(self, tmpdir): """ Raises ValueError if no certificate is passed. """ keyFile = tmpdir.join('key.pem') keyFile.write(KEY_PEM) with pytest.raises(ValueError): certificateOptionsFromFiles(str(keyFile))
def test_catchesMissingKey(self, tmpdir): """ Raises ValueError if a key is missing. """ certFile = tmpdir.join('cert_and_chain.pem') certFile.write(''.join(CERT_PEMS)) with pytest.raises(ValueError): certificateOptionsFromFiles(str(certFile))
def test_catchesMultipleKeys(self, tmpdir): """ Raises ValueError if multiple keys are present. """ allFile = tmpdir.join('key_cert_and_chain.pem') allFile.write(KEY_PEM + ''.join(CERT_PEMS) + KEY_PEM2) with pytest.raises(ValueError): certificateOptionsFromFiles(str(allFile))
def test_removedLegacyDHParameterSupport(self, keyCertChainFile): """ Passing dhParameters as an argument raises a TypeError. """ fakeParameters = object() with pytest.raises(TypeError, match="Passing DH parameters"): certificateOptionsFromFiles(str(keyCertChainFile), dhParameters=fakeParameters)
def test_catchesMissingCertificate(self, tmpdir): """ Raises ValueError if no certificate is passed. """ keyFile = tmpdir.join("key.pem") keyFile.write(KEY_PEM) with pytest.raises(ValueError): certificateOptionsFromFiles(str(keyFile))
def test_catchesMultipleKeys(self, tmpdir): """ Raises ValueError if multiple keys are present. """ allFile = tmpdir.join("key_cert_and_chain.pem") allFile.write(KEY_PEM + b"".join(CERT_PEMS) + KEY_PEM2) with pytest.raises(ValueError): certificateOptionsFromFiles(str(allFile))
def test_catchesMissingKey(self, tmpdir): """ Raises ValueError if a key is missing. """ certFile = tmpdir.join("cert_and_chain.pem") certFile.write(b"".join(CERT_PEMS)) with pytest.raises(ValueError): certificateOptionsFromFiles(str(certFile))
def test_catchesKeyCertificateMismatch(self, tmpdir): """ A ValueError is raised when some certificates are present in the pem, but no certificate in the pem matches the key. """ keyFile = tmpdir.join('key.pem') keyFile.write(KEY_PEM + "".join(CERT_PEMS[1:])) with pytest.raises(ValueError) as excinfo: certificateOptionsFromFiles(str(keyFile)) assert str(excinfo.value).startswith("No certificate matching ")
def test_removedLegacyDHParameterSupport(self, keyCertChainFile): """ Passing dhParameters as an argument raises a TypeError. """ fakeParameters = object() with pytest.raises(TypeError, match="Passing DH parameters"): certificateOptionsFromFiles( str(keyCertChainFile), dhParameters=fakeParameters )
def test_catchesKeyCertificateMismatch(self, tmpdir): """ A ValueError is raised when some certificates are present in the pem, but no certificate in the pem matches the key. """ keyFile = tmpdir.join('key.pem') keyFile.write(KEY_PEM + "".join(CERT_PEMS[1:])) with pytest.raises(ValueError) as excinfo: certificateOptionsFromFiles( str(keyFile) ) assert str(excinfo.value).startswith("No certificate matching ")
def test_catchesMultipleDHParams(self, tmpdir): """ A ValueError is raised when more than one set of DH parameters is present. """ pemFile = tmpdir.join('multiple_params.pem') pemFile.write(KEY_PEM + CERT_PEMS[0] + DH_PEM + DH_PEM) with pytest.raises(ValueError) as excinfo: certificateOptionsFromFiles(str(pemFile)) assert ("Supplied PEM file(s) contain(s) *more* than one set of DH " "parameters.") == str(excinfo.value)
def test_catchesMultipleDHParams(self, tmpdir): """ A ValueError is raised when more than one set of DH parameters is present. """ pemFile = tmpdir.join("multiple_params.pem") pemFile.write(KEY_PEM + CERT_PEMS[0] + DH_PEM + DH_PEM) with pytest.raises(ValueError) as excinfo: certificateOptionsFromFiles(str(pemFile)) assert ( "Supplied PEM file(s) contain(s) *more* than one set of DH " "parameters." ) == str(excinfo.value)
def run(self): task.LoopingCall(self.status_check).start(0.25) root = File('www') root.putChild('st', StatusHandler(self)) root.putChild('upd', self.updateHandler) root.putChild('cfg', ConfigHandler(self)) root.putChild('upt', UptimeHandler(self)) root.putChild('clk', ClickHandler(self)) # if self.config['config']['use_auth']: # clk = ClickHandler(self) # args={self.config['site']['username']:self.config['site']['password']} # checker = checkers.InMemoryUsernamePasswordDatabaseDontUse(**args) # realm = HttpPasswordRealm(clk) # p = portal.Portal(realm, [checker]) # credentialFactory = BasicCredentialFactory("Garage Door Controller") # protected_resource = HTTPAuthSessionWrapper(p, [credentialFactory]) # root.putChild('clk', protected_resource) # else: # root.putChild('clk', ClickHandler(self)) site = server.Site(root) #/etc/letsencrypt/live/joe.vpham.com/fullchain.pem contextFactory = certificateOptionsFromFiles( '/etc/letsencrypt/live/joe.vpham.com/privkey.pem', '/etc/letsencrypt/live/joe.vpham.com/fullchain.pem') #reactor.listenTCP(self.config['site']['port'], site) # @UndefinedVariable reactor.listenSSL(443, site, contextFactory) reactor.run() # @UndefinedVariable
def test_fakeDHParameterSupport(self, monkeypatch, keyCertChainFile, recwarn): """ Fake DH parameter support if Twisted doesn't support it for explicitly passed DH parameters. Warns about deprecation. """ fakeCtxFactory = object() recorder = call_recorder(lambda *a, **kw: fakeCtxFactory) monkeypatch.setattr(ssl, "CertificateOptions", recorder) monkeypatch.setattr(pem.twisted, "_DH_PARAMETERS_SUPPORTED", False) fakeParameters = object() with pytest.warns(DeprecationWarning) as ws: ctxFactory = certificateOptionsFromFiles( str(keyCertChainFile), dhParameters=fakeParameters) assert ( "Passing DH parameters as a keyword argument instead of a PEM " "object is deprecated" in str(ws[0].message)) assert ("The backport of DiffieHellmanParameters will be removed." in str(ws[1].message)) assert isinstance(ctxFactory, pem.twisted._DHParamContextFactory) assert ctxFactory.ctxFactory is fakeCtxFactory assert "dhParameters" not in recorder.calls[0].kwargs
def test_realDHParameterSupport(self, monkeypatch, keyCertChainFile, recwarn): """ Pass explicitly supplied DH parameters directly to CertificateOptions if the installed version of Twisted supports it. Warns about deprecation. """ fakeCtxFactory = object() recorder = call_recorder(lambda *a, **kw: fakeCtxFactory) monkeypatch.setattr(ssl, "CertificateOptions", recorder) monkeypatch.setattr(pem.twisted, "_DH_PARAMETERS_SUPPORTED", True) fakeParameters = object() with pytest.warns(DeprecationWarning) as ws: ctxFactory = certificateOptionsFromFiles( str(keyCertChainFile), dhParameters=fakeParameters ) assert ( "Passing DH parameters as a keyword argument instead of a PEM " "object is deprecated" in str(ws[0].message) ) assert ctxFactory is fakeCtxFactory assert recorder.calls[0].kwargs["dhParameters"] == fakeParameters
def test_fakeDHParameterSupport(self, monkeypatch, allFile, recwarn): """ Fake DH parameter support if Twisted doesn't support it. Warns about deprecation. """ fakeCtxFactory = object() recorder = call_recorder(lambda *a, **kw: fakeCtxFactory) monkeypatch.setattr(ssl, "CertificateOptions", recorder) monkeypatch.setattr(pem.twisted, "_DH_PARAMETERS_SUPPORTED", False) fakeParameters = object() ctxFactory = certificateOptionsFromFiles( str(allFile), dhParameters=fakeParameters ) assert isinstance(ctxFactory, pem.twisted._DHParamContextFactory) assert ctxFactory.ctxFactory is fakeCtxFactory assert "dhParameters" not in recorder.calls[0].kwargs w = recwarn.pop(DeprecationWarning) assert ( "The backport of DiffieHellmanParameters will be removed." in str(w.message) )
def get_tls_factory(self): """ If we have paths to a TLS certificate and key, check that we're ready to actually use them: * TLS-related imports worked * cert and key are readable * cert and key can be loaded Then return a SSL contextFactory instance to use for the server. :returns: SSL contextFactory for our server to use :rtype: :py:class:`twisted.internet.ssl.CertificateOptions` """ if not access(self.cert_path, R_OK): raise RuntimeError('Error: cert file at %s is not ' 'readable' % self.cert_path) if not access(self.key_path, R_OK): raise RuntimeError('Error: key file at %s is not ' 'readable' % self.key_path) if not HAVE_PYOPENSSL: raise RuntimeError('Error: running with TLS (cert and key) requires' ' pyOpenSSL, but it does not appear to be ' 'installed. Please "pip install pyOpenSSL".') # check certs are readable cf = certificateOptionsFromFiles(self.key_path, self.cert_path) return cf
def test_realDHParameterSupport(self, monkeypatch, keyCertChainFile, recwarn): """ Pass explicitly supplied DH parameters directly to CertificateOptions if the installed version of Twisted supports it. Warns about deprecation. """ fakeCtxFactory = object() recorder = call_recorder(lambda *a, **kw: fakeCtxFactory) monkeypatch.setattr(ssl, "CertificateOptions", recorder) monkeypatch.setattr(pem.twisted, "_DH_PARAMETERS_SUPPORTED", True) fakeParameters = object() with pytest.warns(DeprecationWarning) as ws: ctxFactory = certificateOptionsFromFiles( str(keyCertChainFile), dhParameters=fakeParameters ) assert ( "Passing DH parameters as a keyword argument instead of a PEM " "object is deprecated" in str(ws[0].message) ) assert ctxFactory is fakeCtxFactory assert recorder.calls[0].kwargs["dhParameters"] == fakeParameters
def test_fakeDHParameterFileSupport(self, monkeypatch, keyCertChainDHFile, recwarn): """ Fake DH parameter support if Twisted doesn't support it for DH parameters loaded from file. Warns about deprecation. """ fakeCtxFactory = object() recorder = call_recorder(lambda *a, **kw: fakeCtxFactory) monkeypatch.setattr(ssl, "CertificateOptions", recorder) monkeypatch.setattr(pem.twisted, "_DH_PARAMETERS_SUPPORTED", False) with pytest.warns(DeprecationWarning) as ws: ctxFactory = certificateOptionsFromFiles( str(keyCertChainDHFile), ) assert ( "The backport of DiffieHellmanParameters will be removed." in str(ws[0].message) ) assert isinstance(ctxFactory, pem.twisted._DHParamContextFactory) assert ctxFactory.ctxFactory is fakeCtxFactory assert "dhParameters" not in recorder.calls[0].kwargs
def get_tls_factory(self): """ If we have paths to a TLS certificate and key, check that we're ready to actually use them: * TLS-related imports worked * cert and key are readable * cert and key can be loaded Then return a SSL contextFactory instance to use for the server. :returns: SSL contextFactory for our server to use :rtype: :py:class:`twisted.internet.ssl.CertificateOptions` """ if not access(self.cert_path, R_OK): raise RuntimeError('Error: cert file at %s is not ' 'readable' % self.cert_path) if not access(self.key_path, R_OK): raise RuntimeError('Error: key file at %s is not ' 'readable' % self.key_path) if not HAVE_PYOPENSSL: raise RuntimeError( 'Error: running with TLS (cert and key) requires' ' pyOpenSSL, but it does not appear to be ' 'installed. Please "pip install pyOpenSSL".') # check certs are readable cf = certificateOptionsFromFiles(self.key_path, self.cert_path) return cf
def test_forwardsKWargs(self, keyCertChainDHFile): """ Extra keyword arguments are passed into CO. """ ctxFactory = certificateOptionsFromFiles(str(keyCertChainDHFile), fixBrokenPeers=True) assert True is ctxFactory.fixBrokenPeers
def test_worksWithEverythingInOneFile(self, keyCertChainDHFile): """ Key, certificate, and chain can also be in a single file. """ ctxFactory = certificateOptionsFromFiles(str(keyCertChainDHFile)) assert 2 == len(ctxFactory.extraCertChain) assert ctxFactory.dhParameters is not None
def test_forwardsKWargs(self, keyCertChainDHFile): """ Extra keyword arguments are passed into CO. """ ctxFactory = certificateOptionsFromFiles(str(keyCertChainDHFile), method=SSL.TLSv1_METHOD) assert SSL.TLSv1_METHOD is ctxFactory.method
def test_worksWithEverythingInOneFile(self, keyCertChainDHFile): """ Key, certificate, and chain can also be in a single file. """ ctxFactory = certificateOptionsFromFiles(str(keyCertChainDHFile)) assert 2 == len(ctxFactory.extraCertChain) assert ctxFactory.dhParameters is not None
def test_forwardsKWargs(self, keyCertChainDHFile): """ Extra keyword arguments are passed into CO. """ ctxFactory = certificateOptionsFromFiles( str(keyCertChainDHFile), fixBrokenPeers=True ) assert True is ctxFactory.fixBrokenPeers
def test_forwardsKWargs(self, allFile): """ Extra keyword arguments are passed into CO. """ ctxFactory = certificateOptionsFromFiles( str(allFile), method=SSL.TLSv1_METHOD, ) assert SSL.TLSv1_METHOD is ctxFactory.method
def test_passesCertsInCorrectFormat(self, allFile): """ PEM objects are correctly detected and passed into CO. """ ctxFactory = certificateOptionsFromFiles(str(allFile)) assert isinstance(ctxFactory.privateKey, crypto.PKey) assert isinstance(ctxFactory.certificate, crypto.X509) assert all(isinstance(cert, crypto.X509) for cert in ctxFactory.extraCertChain)
def test_passesCertsInCorrectFormat(self, keyCertChainDHFile): """ PEM objects are correctly detected and passed into CO. """ ctxFactory = certificateOptionsFromFiles(str(keyCertChainDHFile)) assert isinstance(ctxFactory.privateKey, crypto.PKey) assert isinstance(ctxFactory.certificate, crypto.X509) assert all(isinstance(cert, crypto.X509) for cert in ctxFactory.extraCertChain)
def test_worksWithChainInSameFile(self, tmpdir): """ Chain can be in the same file as the certificate. """ keyFile = tmpdir.join('key.pem') keyFile.write(KEY_PEM) certFile = tmpdir.join('cert_and_chain.pem') certFile.write(''.join(CERT_PEMS)) ctxFactory = certificateOptionsFromFiles(str(keyFile), str(certFile)) assert 2 == len(ctxFactory.extraCertChain)
def test_worksWithChainInSameFile(self, tmpdir): """ Chain can be in the same file as the certificate. """ keyFile = tmpdir.join('key.pem') keyFile.write(KEY_PEM) certFile = tmpdir.join('cert_and_chain.pem') certFile.write(''.join(CERT_PEMS)) ctxFactory = certificateOptionsFromFiles( str(keyFile), str(certFile) ) assert 2 == len(ctxFactory.extraCertChain)
def test_useTypesNotOrdering(self, tmpdir): """ L{pem.certificateOptionsFromFiles} identifies the chain, key, and certificate for Twisted's L{CertificateOptions} based on their types and certificate fingerprints, not their order within the file. """ keyFile = tmpdir.join('key.pem') keyFile.write(KEY_PEM) certFile = tmpdir.join('cert_and_chain.pem') certFile.write(''.join(reversed(CERT_PEMS))) ctxFactory = certificateOptionsFromFiles(str(keyFile), str(certFile)) assert 2 == len(ctxFactory.extraCertChain)
def test_worksWithoutChain(self, tmpdir): """ Creating CO without chain certificates works. """ keyFile = tmpdir.join('key.pem') keyFile.write(KEY_PEM) certFile = tmpdir.join('cert.pem') certFile.write(CERT_PEMS[0]) ctxFactory = certificateOptionsFromFiles( str(keyFile), str(certFile), ) assert [] == ctxFactory.extraCertChain
def test_worksWithoutChain(self, tmpdir): """ Creating CO without chain certificates works. """ keyFile = tmpdir.join("key.pem") keyFile.write(KEY_PEM) certFile = tmpdir.join("cert.pem") certFile.write(CERT_PEMS[0]) ctxFactory = certificateOptionsFromFiles(str(keyFile), str(certFile)) assert [] == ctxFactory.extraCertChain
def test_worksWithChainInExtraFile(self, tmpdir): """ Chain can be in a seperate file. """ keyFile = tmpdir.join('key.pem') keyFile.write(KEY_PEM) certFile = tmpdir.join('cert.pem') certFile.write(CERT_PEMS[0]) chainFile = tmpdir.join('chain.pem') chainFile.write(''.join(CERT_PEMS[1:])) ctxFactory = certificateOptionsFromFiles(str(keyFile), str(certFile), str(chainFile)) assert 2 == len(ctxFactory.extraCertChain)
def test_useTypesNotOrdering(self, tmpdir): """ L{pem.certificateOptionsFromFiles} identifies the chain, key, and certificate for Twisted's L{CertificateOptions} based on their types and certificate fingerprints, not their order within the file. """ keyFile = tmpdir.join('key.pem') keyFile.write(KEY_PEM) certFile = tmpdir.join('cert_and_chain.pem') certFile.write(''.join(reversed(CERT_PEMS))) ctxFactory = certificateOptionsFromFiles( str(keyFile), str(certFile) ) assert 2 == len(ctxFactory.extraCertChain)
def test_worksWithChainInExtraFile(self, tmpdir): """ Chain can be in a seperate file. """ keyFile = tmpdir.join('key.pem') keyFile.write(KEY_PEM) certFile = tmpdir.join('cert.pem') certFile.write(CERT_PEMS[0]) chainFile = tmpdir.join('chain.pem') chainFile.write(''.join(CERT_PEMS[1:])) ctxFactory = certificateOptionsFromFiles( str(keyFile), str(certFile), str(chainFile) ) assert 2 == len(ctxFactory.extraCertChain)
def test_realDHParameterFileSupport(self, monkeypatch, keyCertChainDHFile): """ Pass DH parameters loaded from a file directly to CertificateOptions if the installed version of Twisted supports it. """ fakeCtxFactory = object() recorder = call_recorder(lambda *a, **kw: fakeCtxFactory) monkeypatch.setattr(ssl, "CertificateOptions", recorder) monkeypatch.setattr(pem.twisted, "_DH_PARAMETERS_SUPPORTED", True) ctxFactory = certificateOptionsFromFiles(str(keyCertChainDHFile), ) assert ctxFactory is fakeCtxFactory assert isinstance(recorder.calls[0].kwargs["dhParameters"], pem.twisted.DiffieHellmanParameters)
def test_realDHParameterSupport(self, monkeypatch, allFile): """ Pass DH parameters directly to CertificateOptions if the installed version of Twisted supports it. """ fakeCtxFactory = object() recorder = call_recorder(lambda *a, **kw: fakeCtxFactory) monkeypatch.setattr(ssl, "CertificateOptions", recorder) monkeypatch.setattr(pem.twisted, "_DH_PARAMETERS_SUPPORTED", True) fakeParameters = object() ctxFactory = certificateOptionsFromFiles(str(allFile), dhParameters=fakeParameters) assert ctxFactory is fakeCtxFactory assert recorder.calls[0].kwargs["dhParameters"] == fakeParameters
def test_realDHParameterFileSupport(self, monkeypatch, keyCertChainDHFile): """ Pass DH parameters loaded from a file directly to CertificateOptions if the installed version of Twisted supports it. """ fakeCtxFactory = object() recorder = call_recorder(lambda *a, **kw: fakeCtxFactory) monkeypatch.setattr(ssl, "CertificateOptions", recorder) monkeypatch.setattr(pem.twisted, "_DH_PARAMETERS_SUPPORTED", True) ctxFactory = certificateOptionsFromFiles(str(keyCertChainDHFile)) assert ctxFactory is fakeCtxFactory assert isinstance( recorder.calls[0].kwargs["dhParameters"], pem.twisted.DiffieHellmanParameters, )
def test_realDHParameterSupport(self, monkeypatch, allFile): """ Pass DH parameters directly to CertificateOptions if the installed version of Twisted supports it. """ fakeCtxFactory = object() recorder = call_recorder(lambda *a, **kw: fakeCtxFactory) monkeypatch.setattr(ssl, "CertificateOptions", recorder) monkeypatch.setattr(pem.twisted, "_DH_PARAMETERS_SUPPORTED", True) fakeParameters = object() ctxFactory = certificateOptionsFromFiles( str(allFile), dhParameters=fakeParameters ) assert ctxFactory is fakeCtxFactory assert recorder.calls[0].kwargs["dhParameters"] == fakeParameters
def test_fakeDHParameterSupport(self, monkeypatch, allFile, recwarn): """ Fake DH parameter support if Twisted doesn't support it. Warns about deprecation. """ fakeCtxFactory = object() recorder = call_recorder(lambda *a, **kw: fakeCtxFactory) monkeypatch.setattr(ssl, "CertificateOptions", recorder) monkeypatch.setattr(pem.twisted, "_DH_PARAMETERS_SUPPORTED", False) fakeParameters = object() ctxFactory = certificateOptionsFromFiles(str(allFile), dhParameters=fakeParameters) assert isinstance(ctxFactory, pem.twisted._DHParamContextFactory) assert ctxFactory.ctxFactory is fakeCtxFactory assert "dhParameters" not in recorder.calls[0].kwargs w = recwarn.pop(DeprecationWarning) assert ("The backport of DiffieHellmanParameters will be removed." in str(w.message))
def test_worksWithEverythingInOneFile(self, allFile): """ Key, certificate, and chain can also be in a single file. """ ctxFactory = certificateOptionsFromFiles(str(allFile)) assert 2 == len(ctxFactory.extraCertChain)
def test_worksWithEverythingInOneFile(self, allFile): """ Key, certificate, and chain can also be in a single file. """ ctxFactory = certificateOptionsFromFiles(str(allFile)) assert 2 == len(ctxFactory.extraCertChain)