Skip to content

Commit

Permalink
Merge tls-abstraction-7098-2
Browse files Browse the repository at this point in the history
Author: glyph
Reviewer: habnabit, radix, rwall, reaperhulk, hynek
Fixes: twisted#7098

Refactor client TLS hostname verification support into a new, better
API (`optionsForClientTLS`), with new interfaces that will facilitate
addressing twisted#4888.

git-svn-id: svn:https://svn.twistedmatrix.com/svn/Twisted/trunk@42511 bbbe8e31-12d6-0310-92fd-ac37d47ddeeb
  • Loading branch information
glyph committed Apr 20, 2014
1 parent 0b30e4c commit d9b4ab3
Show file tree
Hide file tree
Showing 17 changed files with 1,090 additions and 468 deletions.
55 changes: 18 additions & 37 deletions docs/core/examples/echoclient_ssl.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,44 +2,25 @@
# Copyright (c) Twisted Matrix Laboratories.
# See LICENSE for details.

if __name__ == '__main__':
import echoclient_ssl
raise SystemExit(echoclient_ssl.main())

import sys

from twisted.internet.protocol import ClientFactory
from twisted.protocols.basic import LineReceiver
from twisted.internet import ssl, reactor

from twisted.internet import ssl, task, protocol, endpoints, defer
from twisted.python.modules import getModule

class EchoClient(LineReceiver):
end="Bye-bye!"
def connectionMade(self):
self.sendLine("Hello, world!")
self.sendLine("What a fine day it is.")
self.sendLine(self.end)
import echoclient

def connectionLost(self, reason):
print 'connection lost (protocol)'
@defer.inlineCallbacks
def main(reactor):
factory = protocol.Factory.forProtocol(echoclient.EchoClient)
certData = getModule(__name__).filePath.sibling('public.pem').getContent()
authority = ssl.Certificate.loadPEM(certData)
options = ssl.optionsForClientTLS(u'example.com', authority)
endpoint = endpoints.SSL4ClientEndpoint(reactor, 'localhost', 8000,
options)
echoClient = yield endpoint.connect(factory)

def lineReceived(self, line):
print "receive:", line
if line==self.end:
self.transport.loseConnection()
done = defer.Deferred()
echoClient.connectionLost = lambda reason: done.callback(None)
yield done

class EchoClientFactory(ClientFactory):
protocol = EchoClient

def clientConnectionFailed(self, connector, reason):
print 'connection failed:', reason.getErrorMessage()
reactor.stop()

def clientConnectionLost(self, connector, reason):
print 'connection lost:', reason.getErrorMessage()
reactor.stop()

def main():
factory = EchoClientFactory()
reactor.connectSSL('localhost', 8000, factory, ssl.CertificateOptions())
reactor.run()
if __name__ == '__main__':
import echoclient_ssl
task.react(echoclient_ssl.main)
27 changes: 12 additions & 15 deletions docs/core/examples/echoserv_ssl.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,22 @@
# Copyright (c) Twisted Matrix Laboratories.
# See LICENSE for details.

if __name__ == '__main__':
import echoserv_ssl
raise SystemExit(echoserv_ssl.main())

import sys

from twisted.internet import reactor
from twisted.internet.protocol import Factory
from twisted.internet import ssl, reactor
from twisted.internet import ssl, protocol, task, defer
from twisted.python import log
from twisted.python.modules import getModule

import echoserv

def main():
with open('server.pem') as keyAndCert:
cert = ssl.PrivateCertificate.loadPEM(keyAndCert.read())

def main(reactor):
log.startLogging(sys.stdout)
factory = Factory()
factory.protocol = echoserv.Echo
reactor.listenSSL(8000, factory, cert.options())
reactor.run()
certData = getModule(__name__).filePath.sibling('server.pem').getContent()
certificate = ssl.PrivateCertificate.loadPEM(certData)
factory = protocol.Factory.forProtocol(echoserv.Echo)
reactor.listenSSL(8000, factory, certificate.options())
return defer.Deferred()

if __name__ == '__main__':
import echoserv_ssl
task.react(echoserv_ssl.main)
16 changes: 16 additions & 0 deletions docs/core/examples/public.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
-----BEGIN CERTIFICATE-----
MIICjzCCAfgCAQEwDQYJKoZIhvcNAQEEBQAwgY8xEDAOBgNVBAsTB2V4YW1wbGUx
EDAOBgNVBAoTB2V4YW1wbGUxFDASBgNVBAMTC2V4YW1wbGUuY29tMRAwDgYDVQQI
EwdleGFtcGxlMQswCQYDVQQGEwJVUzEiMCAGCSqGSIb3DQEJARYTZXhhbXBsZUBl
eGFtcGxlLmNvbTEQMA4GA1UEBxMHZXhhbXBsZTAeFw0xNDAyMTIwMDMxMzlaFw0x
NTAyMTIwMDMxMzlaMIGPMRAwDgYDVQQLEwdleGFtcGxlMRAwDgYDVQQKEwdleGFt
cGxlMRQwEgYDVQQDEwtleGFtcGxlLmNvbTEQMA4GA1UECBMHZXhhbXBsZTELMAkG
A1UEBhMCVVMxIjAgBgkqhkiG9w0BCQEWE2V4YW1wbGVAZXhhbXBsZS5jb20xEDAO
BgNVBAcTB2V4YW1wbGUwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAKkRahIc
Fp0V44QYpO9ue7mjZNbZYPAC8caoQC1jUgL42CT40PcoOiZWLgRk+Qw6P7PoJzO/
T4ufK0qoPUJm1jErDRWy9eWlGLE0grPECM+jxFfLXxJLKdPtuwMA8Ip72JMirFN5
Y/JTBZOR3j5a/mbY5tcRqgffKxm4QQegnhiBAgMBAAEwDQYJKoZIhvcNAQEEBQAD
gYEAWANPpp985nXMoIwHlsSMm8ijkk7XQU3oioCYDcM6pLT+mvBDe1mZc8mUlrWy
Zo/lT6HF44SHIZ0zCgPYwTpWV6C0K+/kKlYBERZ3ajrzGf5ACfUTNyk5P81C68mc
9fQ7lhq1iuNKzVh8b746Z4ufn6iI1VygnyOQ1hZ/lOX56TA=
-----END CERTIFICATE-----
29 changes: 29 additions & 0 deletions docs/core/examples/ssl_clientauth_client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#!/usr/bin/env python
# Copyright (c) Twisted Matrix Laboratories.
# See LICENSE for details.

from twisted.internet import ssl, task, protocol, endpoints, defer
from twisted.python.modules import getModule

import echoclient

@defer.inlineCallbacks
def main(reactor):
factory = protocol.Factory.forProtocol(echoclient.EchoClient)
certData = getModule(__name__).filePath.sibling('public.pem').getContent()
authData = getModule(__name__).filePath.sibling('server.pem').getContent()
clientCertificate = ssl.PrivateCertificate.loadPEM(authData)
authority = ssl.Certificate.loadPEM(certData)
options = ssl.optionsForClientTLS(u'example.com', authority,
clientCertificate)
endpoint = endpoints.SSL4ClientEndpoint(reactor, 'localhost', 8000,
options)
echoClient = yield endpoint.connect(factory)

done = defer.Deferred()
echoClient.connectionLost = lambda reason: done.callback(None)
yield done

if __name__ == '__main__':
import ssl_clientauth_client
task.react(ssl_clientauth_client.main)
25 changes: 25 additions & 0 deletions docs/core/examples/ssl_clientauth_server.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#!/usr/bin/env python
# Copyright (c) Twisted Matrix Laboratories.
# See LICENSE for details.

import sys

from twisted.internet import ssl, protocol, task, defer
from twisted.python import log
from twisted.python.modules import getModule

import echoserv

def main(reactor):
log.startLogging(sys.stdout)
certData = getModule(__name__).filePath.sibling('public.pem').getContent()
authData = getModule(__name__).filePath.sibling('server.pem').getContent()
authority = ssl.Certificate.loadPEM(certData)
certificate = ssl.PrivateCertificate.loadPEM(authData)
factory = protocol.Factory.forProtocol(echoserv.Echo)
reactor.listenSSL(8000, factory, certificate.options(authority))
return defer.Deferred()

if __name__ == '__main__':
import ssl_clientauth_server
task.react(ssl_clientauth_server.main)
33 changes: 33 additions & 0 deletions docs/core/examples/starttls_client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
from twisted.internet import ssl, endpoints, task, protocol, defer
from twisted.protocols.basic import LineReceiver
from twisted.python.modules import getModule

class StartTLSClient(LineReceiver):
def connectionMade(self):
self.sendLine("plain text")
self.sendLine("STARTTLS")

def lineReceived(self, line):
print("received: " + line)
if line == "READY":
self.transport.startTLS(self.factory.options)
self.sendLine("secure text")
self.transport.loseConnection()

@defer.inlineCallbacks
def main(reactor):
factory = protocol.Factory.forProtocol(StartTLSClient)
certData = getModule(__name__).filePath.sibling('server.pem').getContent()
factory.options = ssl.optionsForClientTLS(
u"example.com", ssl.PrivateCertificate.loadPEM(certData)
)
endpoint = endpoints.HostnameEndpoint(reactor, 'localhost', 8000)
startTLSClient = yield endpoint.connect(factory)

done = defer.Deferred()
startTLSClient.connectionLost = lambda reason: done.callback(None)
yield done

if __name__ == "__main__":
import starttls_client
task.react(starttls_client.main)
24 changes: 24 additions & 0 deletions docs/core/examples/starttls_server.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
from twisted.internet import ssl, protocol, defer, task, endpoints
from twisted.protocols.basic import LineReceiver
from twisted.python.modules import getModule

class TLSServer(LineReceiver):
def lineReceived(self, line):
print("received: " + line)
if line == "STARTTLS":
print("-- Switching to TLS")
self.sendLine('READY')
self.transport.startTLS(self.factory.options)

def main(reactor):
certData = getModule(__name__).filePath.sibling('server.pem').getContent()
cert = ssl.PrivateCertificate.loadPEM(certData)
factory = protocol.Factory.forProtocol(TLSServer)
factory.options = cert.options()
endpoint = endpoints.TCP4ServerEndpoint(reactor, 8000)
endpoint.listen(factory)
return defer.Deferred()

if __name__ == '__main__':
import starttls_server
task.react(starttls_server.main)
7 changes: 3 additions & 4 deletions docs/core/howto/listings/ssl/check_echo_certificate.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
)

def main(reactor, host, port=443):
contextFactory = ssl.CertificateOptions(trustRoot=certificate,
hostname=host.decode("utf-8"))
options = ssl.optionsForClientTLS(host.decode("utf-8"),
trustRoot=certificate)
port = int(port)
done = defer.Deferred()

Expand All @@ -25,8 +25,7 @@ def connectionLost(self, reason):
done.callback(None)

endpoints.connectProtocol(
endpoints.SSL4ClientEndpoint(reactor, host, port,
sslContextFactory=contextFactory),
endpoints.SSL4ClientEndpoint(reactor, host, port, options),
ShowCertificate()
)
return done
Expand Down
6 changes: 2 additions & 4 deletions docs/core/howto/listings/ssl/check_server_certificate.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
from twisted.internet import defer, endpoints, protocol, ssl, task, error

def main(reactor, host, port=443):
contextFactory = ssl.CertificateOptions(trustRoot=ssl.platformTrust(),
hostname=host.decode('utf-8'))
options = ssl.optionsForClientTLS(hostname=host.decode('utf-8'))
port = int(port)

class ShowCertificate(protocol.Protocol):
Expand All @@ -22,8 +21,7 @@ def connectionLost(self, reason):
self.done.callback(None)

return endpoints.connectProtocol(
endpoints.SSL4ClientEndpoint(reactor, host, port,
sslContextFactory=contextFactory),
endpoints.SSL4ClientEndpoint(reactor, host, port, options),
ShowCertificate()
).addCallback(lambda protocol: protocol.done)

Expand Down
Loading

0 comments on commit d9b4ab3

Please sign in to comment.