33hyper/ssl_compat
44~~~~~~~~~
55
6- Shoves pyOpenSSL into an API that looks like the standard Python 3.x ssl module.
6+ Shoves pyOpenSSL into an API that looks like the standard Python 3.x ssl
7+ module.
78
89Currently exposes exactly those attributes, classes, and methods that we
910actually use in hyper (all method signatures are complete, however). May be
1617import errno
1718import socket
1819import time
19- import re
2020
2121from OpenSSL import SSL as ossl
2222from service_identity .pyopenssl import verify_hostname as _verify
3636 locals ()[external ] = value
3737
3838OP_ALL = 0
39- for bit in [31 ] + list (range (10 )): # TODO figure out the names of these other flags
39+ # TODO: Find out the names of these other flags.
40+ for bit in [31 ] + list (range (10 )):
4041 OP_ALL |= 1 << bit
4142
4243HAS_NPN = True
4344
45+
4446def _proxy (method ):
45- return lambda self , * args , ** kwargs : getattr (self ._conn , method )(* args , ** kwargs )
47+ def inner (self , * args , ** kwargs ):
48+ getattr (self ._conn , method )(* args , ** kwargs )
49+ return inner
50+
4651
4752# TODO missing some attributes
4853class SSLError (OSError ):
4954 pass
5055
56+
5157class CertificateError (SSLError ):
5258 pass
5359
@@ -76,9 +82,12 @@ def __init__(self, conn, server_side, do_handshake_on_connect,
7682 self ._conn .set_accept_state ()
7783 else :
7884 if server_hostname :
79- self ._conn .set_tlsext_host_name (server_hostname .encode ('utf-8' ))
85+ self ._conn .set_tlsext_host_name (
86+ server_hostname .encode ('utf-8' )
87+ )
8088 self ._server_hostname = server_hostname
81- self ._conn .set_connect_state () # FIXME does this override do_handshake_on_connect=False?
89+ # FIXME does this override do_handshake_on_connect=False?
90+ self ._conn .set_connect_state ()
8291
8392 if self .connected and self ._do_handshake_on_connect :
8493 self .do_handshake ()
@@ -95,7 +104,8 @@ def connected(self):
95104 return False
96105 return True
97106
98- # Lovingly stolen from CherryPy (http://svn.cherrypy.org/tags/cherrypy-3.2.1/cherrypy/wsgiserver/ssl_pyopenssl.py).
107+ # Lovingly stolen from CherryPy
108+ # (http://svn.cherrypy.org/tags/cherrypy-3.2.1/cherrypy/wsgiserver/ssl_pyopenssl.py).
99109 def _safe_ssl_call (self , suppress_ragged_eofs , call , * args , ** kwargs ):
100110 """Wrap the given call with SSL error-trapping."""
101111 start = time .time ()
@@ -127,8 +137,12 @@ def do_handshake(self):
127137 verify_hostname (self , self ._server_hostname )
128138
129139 def recv (self , bufsize , flags = None ):
130- return self ._safe_ssl_call (self ._suppress_ragged_eofs , self ._conn .recv ,
131- bufsize , flags )
140+ return self ._safe_ssl_call (
141+ self ._suppress_ragged_eofs ,
142+ self ._conn .recv ,
143+ bufsize ,
144+ flags
145+ )
132146
133147 def recv_into (self , buffer , bufsize = None , flags = None ):
134148 # A temporary recv_into implementation. Should be replaced when
@@ -173,9 +187,15 @@ def resolve_alias(alias):
173187 ).get (alias , alias )
174188
175189 def to_components (name ):
176- # TODO Verify that these are actually *supposed* to all be single-element
177- # tuples, and that's not just a quirk of the examples I've seen.
178- return tuple ([((resolve_alias (name .decode ('utf-8' )), value .decode ('utf-8' )),) for name , value in name .get_components ()])
190+ # TODO Verify that these are actually *supposed* to all be
191+ # single-element tuples, and that's not just a quirk of the
192+ # examples I've seen.
193+ return tuple (
194+ [
195+ (resolve_alias (k .decode ('utf-8' ), v .decode ('utf-8' )),)
196+ for k , v in name .get_components ()
197+ ]
198+ )
179199
180200 # The standard getpeercert() takes the nice X509 object tree returned
181201 # by OpenSSL and turns it into a dict according to some format it seems
@@ -189,11 +209,13 @@ def to_components(name):
189209 notBefore = cert .get_notBefore (),
190210 notAfter = cert .get_notAfter (),
191211 )
192- # TODO extensions, including subjectAltName (see _decode_certificate in _ssl.c)
212+ # TODO extensions, including subjectAltName
213+ # (see _decode_certificate in _ssl.c)
193214 return result
194215
195216 # a dash of magic to reduce boilerplate
196- for method in ['accept' , 'bind' , 'close' , 'getsockname' , 'listen' , 'fileno' ]:
217+ methods = ['accept' , 'bind' , 'close' , 'getsockname' , 'listen' , 'fileno' ]
218+ for method in methods :
197219 locals ()[method ] = _proxy (method )
198220
199221
@@ -221,7 +243,9 @@ def verify_mode(self):
221243 @verify_mode .setter
222244 def verify_mode (self , value ):
223245 # TODO verify exception is raised on failure
224- self ._ctx .set_verify (value , lambda conn , cert , errnum , errdepth , ok : ok )
246+ self ._ctx .set_verify (
247+ value , lambda conn , cert , errnum , errdepth , ok : ok
248+ )
225249
226250 def set_default_verify_paths (self ):
227251 self ._ctx .set_default_verify_paths ()
@@ -239,11 +263,13 @@ def load_verify_locations(self, cafile=None, capath=None, cadata=None):
239263 def load_cert_chain (self , certfile , keyfile = None , password = None ):
240264 self ._ctx .use_certificate_file (certfile )
241265 if password is not None :
242- self ._ctx .set_passwd_cb (lambda max_length , prompt_twice , userdata : password )
266+ self ._ctx .set_passwd_cb (
267+ lambda max_length , prompt_twice , userdata : password
268+ )
243269 self ._ctx .use_privatekey_file (keyfile or certfile )
244270
245271 def set_npn_protocols (self , protocols ):
246- self .protocols = list (map (lambda x :x .encode ('ascii' ), protocols ))
272+ self .protocols = list (map (lambda x : x .encode ('ascii' ), protocols ))
247273
248274 def cb (conn , protos ):
249275 # Detect the overlapping set of protocols.
@@ -262,8 +288,12 @@ def set_alpn_protocols(self, protocols):
262288 protocols = list (map (lambda x : x .encode ('ascii' ), protocols ))
263289 self ._ctx .set_alpn_protos (protocols )
264290
265- def wrap_socket (self , sock , server_side = False , do_handshake_on_connect = True ,
266- suppress_ragged_eofs = True , server_hostname = None ):
291+ def wrap_socket (self ,
292+ sock ,
293+ server_side = False ,
294+ do_handshake_on_connect = True ,
295+ suppress_ragged_eofs = True ,
296+ server_hostname = None ):
267297 conn = ossl .Connection (self ._ctx , sock )
268298 return SSLSocket (conn , server_side , do_handshake_on_connect ,
269299 suppress_ragged_eofs , server_hostname ,
0 commit comments