viff
changeset 820:facc9f1f0bb1
Switch to PyOpenSSL for SSL/TLS support.
This removes the dependency on the GnuTLS library and should make it
possible to use VIFF with SSL support under Windows.
This removes the dependency on the GnuTLS library and should make it
possible to use VIFF with SSL support under Windows.
| author | Martin Geisler <mg@daimi.au.dk> |
|---|---|
| date | Sat Jul 12 18:14:38 2008 +0200 (3 years ago) |
| parents | 1ed10c3ce40c |
| children | b767a45cec65 |
| files | viff/runtime.py |
line diff
1.1 --- a/viff/runtime.py Sat Jul 12 16:12:17 2008 +0200 1.2 +++ b/viff/runtime.py Sat Jul 12 18:14:38 2008 +0200 1.3 @@ -257,10 +257,6 @@ 1.4 1.5 def connectionMade(self): 1.6 self.sendString(str(self.factory.runtime.id)) 1.7 - try: 1.8 - self.peer_cert = self.transport.socket.peer_certificate 1.9 - except AttributeError: 1.10 - self.peer_cert = None 1.11 1.12 def connectionLost(self, reason): 1.13 reason.trap(ConnectionDone) 1.14 @@ -275,15 +271,18 @@ 1.15 if self.peer_id is None: 1.16 # TODO: Handle ValueError if the string cannot be decoded. 1.17 self.peer_id = int(string) 1.18 - if self.peer_cert: 1.19 + try: 1.20 + cert = self.transport.getPeerCertificate() 1.21 + except AttributeError: 1.22 + cert = None 1.23 + if cert: 1.24 # The player ID are stored in the serial number of the 1.25 # certificate -- this makes it easy to check that the 1.26 # player is who he claims to be. 1.27 - if self.peer_cert.serial_number != self.peer_id: 1.28 + if cert.get_serial_number() != self.peer_id: 1.29 print "Peer %s claims to be %d, aborting!" \ 1.30 - % (self.peer_cert.subject, self.peer_id) 1.31 + % (cert.get_subject(), self.peer_id) 1.32 self.transport.loseConnection() 1.33 - 1.34 self.factory.identify_peer(self) 1.35 else: 1.36 program_counter, data_type, data = marshal.loads(string) 1.37 @@ -410,25 +409,25 @@ 1.38 group.add_option("-k", "--security-parameter", type="int", metavar="K", 1.39 help=("Security parameter. Comparisons will leak " 1.40 "information with probability 2**-K.")) 1.41 - group.add_option("--no-tls", action="store_false", dest="tls", 1.42 - help="Disable the use of secure TLS connections.") 1.43 - group.add_option("--tls", action="store_true", 1.44 - help=("Enable the use of secure TLS connections " 1.45 - "(if the GNUTLS bindings are available).")) 1.46 + group.add_option("--no-ssl", action="store_false", dest="ssl", 1.47 + help="Disable the use of secure SSL connections.") 1.48 + group.add_option("--ssl", action="store_true", 1.49 + help=("Enable the use of secure SSL connections " 1.50 + "(if the OpenSSL bindings are available).")) 1.51 group.add_option("--deferred-debug", action="store_true", 1.52 help="Enable extra debug output for deferreds.") 1.53 1.54 try: 1.55 # Using __import__ since we do not use the module, we are 1.56 # only interested in the side-effect. 1.57 - __import__('gnutls') 1.58 - have_gnutls = True 1.59 + __import__('OpenSSL') 1.60 + have_openssl = True 1.61 except ImportError: 1.62 - have_gnutls = False 1.63 + have_openssl = False 1.64 1.65 parser.set_defaults(bit_length=32, 1.66 security_parameter=30, 1.67 - tls=have_gnutls, 1.68 + ssl=have_openssl, 1.69 deferred_debug=False) 1.70 1.71 def __init__(self, player, threshold, options=None): 1.72 @@ -1499,27 +1498,40 @@ 1.73 runtime = runtime_class(players[id], threshold, options) 1.74 factory = ShareExchangerFactory(runtime, players, result) 1.75 1.76 - if options and options.tls: 1.77 - print "Using TLS" 1.78 - from gnutls.interfaces.twisted import X509Credentials 1.79 - from gnutls.crypto import X509Certificate, X509PrivateKey 1.80 + if options and options.ssl: 1.81 + print "Using SSL" 1.82 + from twisted.internet.ssl import ContextFactory, ClientContextFactory 1.83 + from OpenSSL import SSL 1.84 1.85 - # TODO: Make the file names configurable. 1.86 - cert = X509Certificate(open('player-%d.cert' % id).read()) 1.87 - key = X509PrivateKey(open('player-%d.key' % id).read()) 1.88 - ca = X509Certificate(open('ca.cert').read()) 1.89 - cred = X509Credentials(cert, key, [ca]) 1.90 - cred.verify_peer = True 1.91 - reactor.listenTLS(players[id].port, factory, cred) 1.92 + class SSLContextFactory(ContextFactory): 1.93 + def __init__(self, id): 1.94 + """Create new SSL context factory for *id*.""" 1.95 + self.id = id 1.96 + ctx = SSL.Context(SSL.SSLv3_METHOD) 1.97 + # TODO: Make the file names configurable. 1.98 + ctx.use_certificate_file('player-%d.cert' % id) 1.99 + ctx.use_privatekey_file('player-%d.key' % id) 1.100 + ctx.check_privatekey() 1.101 + 1.102 + ctx.load_verify_locations('ca.cert') 1.103 + ctx.set_verify(SSL.VERIFY_PEER | SSL.VERIFY_FAIL_IF_NO_PEER_CERT, 1.104 + lambda conn, cert, errnum, depth, ok: ok) 1.105 + self.ctx = ctx 1.106 + 1.107 + def getContext(self): 1.108 + return self.ctx 1.109 + 1.110 + ctx_factory = SSLContextFactory(id) 1.111 + reactor.listenSSL(players[id].port, factory, ctx_factory) 1.112 else: 1.113 - print "Not using TLS" 1.114 + print "Not using SSL" 1.115 reactor.listenTCP(players[id].port, factory) 1.116 1.117 for peer_id, player in players.iteritems(): 1.118 if peer_id > id: 1.119 print "Will connect to %s" % player 1.120 - if options and options.tls: 1.121 - reactor.connectTLS(player.host, player.port, factory, cred) 1.122 + if options and options.ssl: 1.123 + reactor.connectSSL(player.host, player.port, factory, ctx_factory) 1.124 else: 1.125 reactor.connectTCP(player.host, player.port, factory) 1.126
