1 """ndg_httpsclient SSL Context utilities module containing convenience routines
2 for setting SSL context configuration.
3
4 """
5 __author__ = "P J Kershaw (STFC)"
6 __date__ = "09/12/11"
7 __copyright__ = "(C) 2012 Science and Technology Facilities Council"
8 __license__ = "BSD - see LICENSE file in top-level directory"
9 __contact__ = "Philip.Kershaw@stfc.ac.uk"
10 __revision__ = '$Id$'
11 import sys
12
13 if sys.version_info[0] > 2:
14 import urllib.parse as urlparse_
15 else:
16 import urlparse as urlparse_
17
18 from OpenSSL import SSL
19
20 from ndg.httpsclient.ssl_peer_verification import ServerSSLCertVerification
21
22
23 -class SSlContextConfig(object):
24 """
25 Holds configuration options for creating a SSL context. This is used as a
26 template to create the contexts with specific verification callbacks.
27 """
28 - def __init__(self, key_file=None, cert_file=None, pem_file=None, ca_dir=None,
29 verify_peer=False):
30 self.key_file = key_file
31 self.cert_file = cert_file
32 self.pem_file = pem_file
33 self.ca_dir = ca_dir
34 self.verify_peer = verify_peer
35
36
37 -def make_ssl_context_from_config(ssl_config=False, url=None):
38 return make_ssl_context(ssl_config.key_file, ssl_config.cert_file,
39 ssl_config.pem_file, ssl_config.ca_dir,
40 ssl_config.verify_peer, url)
41
42
43 -def make_ssl_context(key_file=None, cert_file=None, pem_file=None, ca_dir=None,
44 verify_peer=False, url=None, method=SSL.TLSv1_METHOD,
45 key_file_passphrase=None):
46 """
47 Creates SSL context containing certificate and key file locations.
48 """
49 ssl_context = SSL.Context(method)
50
51
52 if cert_file:
53 ssl_context.use_certificate_file(cert_file)
54
55 if key_file_passphrase:
56 passwd_cb = lambda max_passphrase_len, set_prompt, userdata: \
57 key_file_passphrase
58 ssl_context.set_passwd_cb(passwd_cb)
59
60 if key_file:
61 ssl_context.use_privatekey_file(key_file)
62 elif cert_file:
63 ssl_context.use_privatekey_file(cert_file)
64
65 if pem_file or ca_dir:
66 ssl_context.load_verify_locations(pem_file, ca_dir)
67
68 def _callback(conn, x509, errnum, errdepth, preverify_ok):
69 """Default certification verification callback.
70 Performs no checks and returns the status passed in.
71 """
72 return preverify_ok
73
74 verify_callback = _callback
75
76 if verify_peer:
77 ssl_context.set_verify_depth(9)
78 if url:
79 set_peer_verification_for_url_hostname(ssl_context, url)
80 else:
81 ssl_context.set_verify(SSL.VERIFY_PEER, verify_callback)
82 else:
83 ssl_context.set_verify(SSL.VERIFY_NONE, verify_callback)
84
85 return ssl_context
86
87
90 '''Convenience routine to set peer verification callback based on
91 ServerSSLCertVerification class'''
92 if not if_verify_enabled or (ssl_context.get_verify_mode() & SSL.VERIFY_PEER):
93 urlObj = urlparse_.urlparse(url)
94 hostname = urlObj.hostname
95 server_ssl_cert_verif = ServerSSLCertVerification(hostname=hostname)
96 verify_callback_ = server_ssl_cert_verif.get_verify_server_cert_func()
97 ssl_context.set_verify(SSL.VERIFY_PEER, verify_callback_)
98