@@ -154,6 +154,86 @@ def _ipaddress_match(pattern, host_ip):
154154 return False
155155
156156
157+ def _default_pyopenssl_ssl_method (ssl_module ):
158+ for method_name in ('TLS_CLIENT_METHOD' , 'TLS_METHOD' , 'TLSv1_2_METHOD' ):
159+ method = getattr (ssl_module , method_name , None )
160+ if method is not None :
161+ return method
162+ raise ImportError ('pyOpenSSL does not expose a secure TLS client method' )
163+
164+
165+ def _pyopenssl_ssl_method_from_ssl_version (ssl_version , ssl_module ):
166+ if not isinstance (ssl_version , type (ssl .PROTOCOL_TLS )):
167+ return ssl_version
168+
169+ protocol_method_names = (
170+ ('PROTOCOL_TLS' , None ),
171+ ('PROTOCOL_SSLv23' , None ),
172+ ('PROTOCOL_TLS_CLIENT' , None ),
173+ ('PROTOCOL_TLS_SERVER' , ('TLS_SERVER_METHOD' , 'TLS_METHOD' )),
174+ ('PROTOCOL_TLSv1' , ('TLSv1_METHOD' ,)),
175+ ('PROTOCOL_TLSv1_1' , ('TLSv1_1_METHOD' ,)),
176+ ('PROTOCOL_TLSv1_2' , ('TLSv1_2_METHOD' ,)),
177+ )
178+ for protocol_name , method_names in protocol_method_names :
179+ if getattr (ssl , protocol_name , None ) is ssl_version :
180+ if method_names is None :
181+ return _default_pyopenssl_ssl_method (ssl_module )
182+ for method_name in method_names :
183+ method = getattr (ssl_module , method_name , None )
184+ if method is not None :
185+ return method
186+ raise ValueError ('pyOpenSSL does not expose a method for {}' .format (protocol_name ))
187+
188+ return ssl_version
189+
190+
191+ def _pyopenssl_verify_mode_from_cert_reqs (cert_reqs , ssl_module ):
192+ if not isinstance (cert_reqs , type (ssl .CERT_NONE )):
193+ return cert_reqs
194+ if cert_reqs == ssl .CERT_NONE :
195+ return ssl_module .VERIFY_NONE
196+ if cert_reqs in (ssl .CERT_OPTIONAL , ssl .CERT_REQUIRED ):
197+ return ssl_module .VERIFY_PEER
198+ return cert_reqs
199+
200+
201+ def _build_pyopenssl_context_from_options (ssl_options , ssl_module ):
202+ ssl_version = (ssl_options ['ssl_version' ]
203+ if 'ssl_version' in ssl_options else _default_pyopenssl_ssl_method (ssl_module ))
204+ ssl_version = _pyopenssl_ssl_method_from_ssl_version (ssl_version , ssl_module )
205+ context = ssl_module .Context (ssl_version )
206+ certfile = ssl_options .get ('certfile' , None )
207+ keyfile = ssl_options .get ('keyfile' , None )
208+ if certfile :
209+ use_certificate_chain_file = getattr (context , 'use_certificate_chain_file' , None )
210+ if use_certificate_chain_file :
211+ use_certificate_chain_file (certfile )
212+ else :
213+ context .use_certificate_file (certfile )
214+ context .use_privatekey_file (keyfile or certfile )
215+ context .check_privatekey ()
216+ elif keyfile :
217+ context .use_privatekey_file (keyfile )
218+ ca_certs = ssl_options .get ('ca_certs' , None )
219+ if ca_certs :
220+ context .load_verify_locations (ca_certs )
221+ ciphers = ssl_options .get ('ciphers' , None )
222+ if ciphers :
223+ context .set_cipher_list (ciphers )
224+ cert_reqs = ssl_options .get ('cert_reqs' , None )
225+ if cert_reqs is None :
226+ cert_reqs = (ssl_module .VERIFY_PEER
227+ if (ssl_options .get ('ca_certs' , None ) or ssl_options .get ('check_hostname' , False ))
228+ else ssl_module .VERIFY_NONE )
229+ cert_reqs = _pyopenssl_verify_mode_from_cert_reqs (cert_reqs , ssl_module )
230+ context .set_verify (
231+ cert_reqs ,
232+ callback = lambda _connection , _x509 , _errnum , _errdepth , ok : ok
233+ )
234+ return context
235+
236+
157237segment_codec_no_compression = SegmentCodec ()
158238segment_codec_lz4 = None
159239
0 commit comments