def test_failedCertificateVerification(self): """ Check that connecting with a certificate not accepted by the server CA fails. """ onServerLost = defer.Deferred() onClientLost = defer.Deferred() self.loopback( sslverify.OpenSSLCertificateOptions(privateKey=self.sKey, certificate=self.sCert, verify=False, requireCertificate=False), sslverify.OpenSSLCertificateOptions(verify=True, requireCertificate=False, caCerts=[self.cCert]), onServerLost=onServerLost, onClientLost=onClientLost) d = defer.DeferredList([onClientLost, onServerLost], consumeErrors=True) def afterLost(((cSuccess, cResult), (sSuccess, sResult))): self.failIf(cSuccess) self.failIf(sSuccess)
def test_refusedAnonymousClientConnection(self): """ Check that anonymous connections are refused when certificates are required on the server. """ onServerLost = defer.Deferred() onClientLost = defer.Deferred() self.loopback( sslverify.OpenSSLCertificateOptions(privateKey=self.sKey, certificate=self.sCert, verify=True, caCerts=[self.sCert], requireCertificate=True), sslverify.OpenSSLCertificateOptions(requireCertificate=False), onServerLost=onServerLost, onClientLost=onClientLost) d = defer.DeferredList([onClientLost, onServerLost], consumeErrors=True) def afterLost(((cSuccess, cResult), (sSuccess, sResult))): self.failIf(cSuccess) self.failIf(sSuccess) # Win32 fails to report the SSL Error, and report a connection lost # instead: there is a race condition so that's not totally # surprising (see ticket #2877 in the tracker) cResult.trap(SSL.Error, ConnectionLost) sResult.trap(SSL.Error)
def testRefusedAnonymousClientConnection(self): onServerLost = defer.Deferred() onClientLost = defer.Deferred() self.loopback( sslverify.OpenSSLCertificateOptions(privateKey=self.sKey, certificate=self.sCert, verify=True, caCerts=[self.sCert], requireCertificate=True), sslverify.OpenSSLCertificateOptions(requireCertificate=False), onServerLost=onServerLost, onClientLost=onClientLost) d = defer.DeferredList([onClientLost, onServerLost], consumeErrors=True) def afterLost(((cSuccess, cResult), (sSuccess, sResult))): self.failIf(cSuccess) self.failIf(sSuccess) # XXX Twisted doesn't report SSL errors as SSL errors, but in the # future it will. # cResult.trap(SSL.Error) # sResult.trap(SSL.Error) # Twisted trunk will do the correct thing here, and not log any # errors. Twisted 2.1 will do the wrong thing. We're flushing # errors until the buildbot is updated to a reasonable facsimilie # of 2.2. log.flushErrors(SSL.Error)
def testFailedCertificateVerification(self): onServerLost = defer.Deferred() onClientLost = defer.Deferred() self.loopback( sslverify.OpenSSLCertificateOptions(privateKey=self.sKey, certificate=self.sCert, verify=False, requireCertificate=False), sslverify.OpenSSLCertificateOptions(verify=True, requireCertificate=False, caCerts=[self.cCert]), onServerLost=onServerLost, onClientLost=onClientLost) d = defer.DeferredList([onClientLost, onServerLost], consumeErrors=True) def afterLost(((cSuccess, cResult), (sSuccess, sResult))): self.failIf(cSuccess) self.failIf(sSuccess) # Twisted trunk will do the correct thing here, and not log any # errors. Twisted 2.1 will do the wrong thing. We're flushing # errors until the buildbot is updated to a reasonable facsimilie # of 2.2. log.flushErrors(SSL.Error)
def testAllowedAnonymousClientConnection(self): onData = defer.Deferred() self.loopback( sslverify.OpenSSLCertificateOptions(privateKey=self.sKey, certificate=self.sCert, requireCertificate=False), sslverify.OpenSSLCertificateOptions(requireCertificate=False), onData=onData) return onData.addCallback( lambda result: self.assertEquals(result, WritingProtocol.byte))
def test_allowedAnonymousClientConnection(self): """ Check that anonymous connections are allowed when certificates aren't required on the server. """ onData = defer.Deferred() self.loopback(sslverify.OpenSSLCertificateOptions(privateKey=self.sKey, certificate=self.sCert, requireCertificate=False), sslverify.OpenSSLCertificateOptions( requireCertificate=False), onData=onData) return onData.addCallback( lambda result: self.assertEqual(result, WritingProtocol.byte))
def testSuccessfulCertificateVerification(self): onData = defer.Deferred() self.loopback( sslverify.OpenSSLCertificateOptions(privateKey=self.sKey, certificate=self.sCert, verify=False, requireCertificate=False), sslverify.OpenSSLCertificateOptions(verify=True, requireCertificate=True, caCerts=[self.sCert]), onData=onData) return onData.addCallback( lambda result: self.assertEquals(result, WritingProtocol.byte))
def test_successfulCertificateVerification(self): """ Test a successful connection with client certificate validation on server side. """ onData = defer.Deferred() self.loopback(sslverify.OpenSSLCertificateOptions(privateKey=self.sKey, certificate=self.sCert, verify=False, requireCertificate=False), sslverify.OpenSSLCertificateOptions(verify=True, requireCertificate=True, caCerts=[self.sCert]), onData=onData) return onData.addCallback( lambda result: self.assertEqual(result, WritingProtocol.byte))
def test_successfulSymmetricSelfSignedCertificateVerification(self): """ Test a successful connection with validation on both server and client sides. """ onData = defer.Deferred() self.loopback(sslverify.OpenSSLCertificateOptions(privateKey=self.sKey, certificate=self.sCert, verify=True, requireCertificate=True, caCerts=[self.cCert]), sslverify.OpenSSLCertificateOptions(privateKey=self.cKey, certificate=self.cCert, verify=True, requireCertificate=True, caCerts=[self.sCert]), onData=onData) return onData.addCallback( lambda result: self.assertEqual(result, WritingProtocol.byte))
def test_certificateOptionsSessionTicketsDisabled(self): """ Enabling session tickets should set the OP_NO_TICKET option. """ opts = sslverify.OpenSSLCertificateOptions(enableSessionTickets=False) ctx = opts.getContext() self.assertEqual(0x00004000, ctx.set_options(0) & 0x00004000)
def test_constructorWithCertificateAndPrivateKey(self): """ Specifying C{privateKey} and C{certificate} initializes correctly. """ opts = sslverify.OpenSSLCertificateOptions(privateKey=self.sKey, certificate=self.sCert) self.assertEqual(opts.privateKey, self.sKey) self.assertEqual(opts.certificate, self.sCert)
def test_SSLv2IsDisabledForSSLv23(self): """ SSLv2 is insecure and should be disabled so when users use SSLv23_METHOD, they get at least SSLV3. It does nothing if SSLv2_METHOD chosen explicitly. """ opts = sslverify.OpenSSLCertificateOptions() ctx = opts.getContext() self.assertEqual(SSL.OP_NO_SSLv2, ctx.set_options(0) & SSL.OP_NO_SSLv2)
def test_constructorAllowsCACertsWithoutVerify(self): """ It's currently a NOP, but valid. """ opts = sslverify.OpenSSLCertificateOptions(privateKey=self.sKey, certificate=self.sCert, caCerts=self.caCerts) self.assertFalse(opts.verify) self.assertEqual(self.caCerts, opts.caCerts)
def test_constructorWithVerifyAndCACerts(self): """ Specifying C{verify} and C{caCerts} initializes correctly. """ opts = sslverify.OpenSSLCertificateOptions(privateKey=self.sKey, certificate=self.sCert, verify=True, caCerts=self.caCerts) self.assertTrue(opts.verify) self.assertEqual(self.caCerts, opts.caCerts)
def test_default(self): """ When L{sslverify.OpenSSLCertificateOptions} is initialized with no specific protocol versions all versions of TLS are allowed and no versions of SSL are allowed. """ self.assertEqual( set([ ProtocolVersion.TLSv1_0, ProtocolVersion.TLSv1_1, ProtocolVersion.TLSv1_2 ]), self._protocols(sslverify.OpenSSLCertificateOptions()))
def test_constructorSetsExtraChain(self): """ Setting C{extraCertChain} works if C{certificate} and C{privateKey} are set along with it. """ opts = sslverify.OpenSSLCertificateOptions( privateKey=self.sKey, certificate=self.sCert, extraCertChain=self.extraCertChain, ) self.assertEqual(self.extraCertChain, opts.extraCertChain)
def test_extraChainDoesNotBreakPyOpenSSL(self): """ C{extraCertChain} doesn't break C{OpenSSL.SSL.Context} creation. """ opts = sslverify.OpenSSLCertificateOptions( privateKey=self.sKey, certificate=self.sCert, extraCertChain=self.extraCertChain, ) ctx = opts.getContext() self.assertIsInstance(ctx, SSL.Context)
def test_SSLv23(self): """ When L{sslverify.OpenSSLCertificateOptions} is initialized with C{SSLv23_METHOD} all versions of TLS and SSLv3 are allowed. """ self.assertEqual( set([ ProtocolVersion.SSLv3, ProtocolVersion.TLSv1_0, ProtocolVersion.TLSv1_1, ProtocolVersion.TLSv1_2 ]), self._protocols( sslverify.OpenSSLCertificateOptions(method=SSL.SSLv23_METHOD)))
def test_acceptableCiphersAreAlwaysSet(self): """ If the user doesn't supply custom acceptable ciphers, a shipped secure default is used. We can't check directly for it because the effective cipher string we set varies with platforms. """ opts = sslverify.OpenSSLCertificateOptions( privateKey=self.sKey, certificate=self.sCert, ) opts._contextFactory = FakeContext ctx = opts.getContext() self.assertEqual(opts._cipherString, ctx._cipherList)
def test_certificateOptionsSerialization(self): """ Test that __setstate__(__getstate__()) round-trips properly. """ firstOpts = sslverify.OpenSSLCertificateOptions( privateKey=self.sKey, certificate=self.sCert, method=SSL.SSLv3_METHOD, verify=True, caCerts=[self.sCert], verifyDepth=2, requireCertificate=False, verifyOnce=False, enableSingleUseKeys=False, enableSessions=False, fixBrokenPeers=True, enableSessionTickets=True) context = firstOpts.getContext() state = firstOpts.__getstate__() # The context shouldn't be in the state to serialize self.failIf(objgrep(state, context, isSame), objgrep(state, context, isSame)) opts = sslverify.OpenSSLCertificateOptions() opts.__setstate__(state) self.assertEqual(opts.privateKey, self.sKey) self.assertEqual(opts.certificate, self.sCert) self.assertEqual(opts.method, SSL.SSLv3_METHOD) self.assertEqual(opts.verify, True) self.assertEqual(opts.caCerts, [self.sCert]) self.assertEqual(opts.verifyDepth, 2) self.assertEqual(opts.requireCertificate, False) self.assertEqual(opts.verifyOnce, False) self.assertEqual(opts.enableSingleUseKeys, False) self.assertEqual(opts.enableSessions, False) self.assertEqual(opts.fixBrokenPeers, True) self.assertEqual(opts.enableSessionTickets, True)
def test_basicSecurityOptionsAreSet(self): """ Every context must have C{OP_NO_SSLv2}, C{OP_NO_COMPRESSION}, and C{OP_CIPHER_SERVER_PREFERENCE} set. """ opts = sslverify.OpenSSLCertificateOptions( privateKey=self.sKey, certificate=self.sCert, ) opts._contextFactory = FakeContext ctx = opts.getContext() options = (SSL.OP_NO_SSLv2 | opts._OP_NO_COMPRESSION | opts._OP_CIPHER_SERVER_PREFERENCE) self.assertEqual(options, ctx._options & options)
def test_singleUseKeys(self): """ If C{singleUseKeys} is set, every context must have C{OP_SINGLE_DH_USE} and C{OP_SINGLE_ECDH_USE} set. """ opts = sslverify.OpenSSLCertificateOptions( privateKey=self.sKey, certificate=self.sCert, enableSingleUseKeys=True, ) opts._contextFactory = FakeContext ctx = opts.getContext() options = SSL.OP_SINGLE_DH_USE | opts._OP_SINGLE_ECDH_USE self.assertEqual(options, ctx._options & options)
def test_certificateOptionsSerialization(self): """ Test that __setstate__(__getstate__()) round-trips properly. """ firstOpts = sslverify.OpenSSLCertificateOptions( privateKey=self.sKey, certificate=self.sCert, method=SSL.SSLv3_METHOD, verify=True, caCerts=[self.sCert], verifyDepth=2, requireCertificate=False, verifyOnce=False, enableSingleUseKeys=False, enableSessions=False, fixBrokenPeers=True, enableSessionTickets=True) context = firstOpts.getContext() self.assertIdentical(context, firstOpts._context) self.assertNotIdentical(context, None) state = firstOpts.__getstate__() self.assertNotIn("_context", state) opts = sslverify.OpenSSLCertificateOptions() opts.__setstate__(state) self.assertEqual(opts.privateKey, self.sKey) self.assertEqual(opts.certificate, self.sCert) self.assertEqual(opts.method, SSL.SSLv3_METHOD) self.assertEqual(opts.verify, True) self.assertEqual(opts.caCerts, [self.sCert]) self.assertEqual(opts.verifyDepth, 2) self.assertEqual(opts.requireCertificate, False) self.assertEqual(opts.verifyOnce, False) self.assertEqual(opts.enableSingleUseKeys, False) self.assertEqual(opts.enableSessions, False) self.assertEqual(opts.fixBrokenPeers, True) self.assertEqual(opts.enableSessionTickets, True)
def test_extraChainFilesAreAddedIfSupplied(self): """ If C{extraCertChain} is set and all prerequisites are met, the specified chain certificates are added to C{Context}s that get created. """ opts = sslverify.OpenSSLCertificateOptions( privateKey=self.sKey, certificate=self.sCert, extraCertChain=self.extraCertChain, ) opts._contextFactory = FakeContext ctx = opts.getContext() self.assertEqual(self.sKey, ctx._privateKey) self.assertEqual(self.sCert, ctx._certificate) self.assertEqual(self.extraCertChain, ctx._extraCertChain)
def test_honorsAcceptableCiphersArgument(self): """ If acceptable ciphers are passed, they are used. """ @implementer(interfaces.IAcceptableCiphers) class FakeAcceptableCiphers(object): def selectCiphers(self, _): return [sslverify.OpenSSLCipher(u'sentinel')] opts = sslverify.OpenSSLCertificateOptions( privateKey=self.sKey, certificate=self.sCert, acceptableCiphers=FakeAcceptableCiphers(), ) opts._contextFactory = FakeContext ctx = opts.getContext() self.assertEqual(u'sentinel', ctx._cipherList)
def test_dhParams(self): """ If C{dhParams} is set, they are loaded into each new context. """ class FakeDiffieHellmanParameters(object): _dhFile = FilePath(b'dh.params') dhParams = FakeDiffieHellmanParameters() opts = sslverify.OpenSSLCertificateOptions( privateKey=self.sKey, certificate=self.sCert, dhParameters=dhParams, ) opts._contextFactory = FakeContext ctx = opts.getContext() self.assertEqual(FakeDiffieHellmanParameters._dhFile.path, ctx._dhFilename)