1
2
3
4
5
6
7 """
8 A helper class for using TLS Lite with stdlib clients
9 (httplib, xmlrpclib, imaplib, poplib).
10 """
11
12 from tlslite.checker import Checker
13 from tlslite.utils.dns_utils import is_valid_hostname
16 """This is a helper class used to integrate TLS Lite with various
17 TLS clients (e.g. poplib, smtplib, httplib, etc.)"""
18
19 - def __init__(self,
20 username=None, password=None,
21 certChain=None, privateKey=None,
22 checker=None,
23 settings=None,
24 anon=False,
25 host=None):
26 """
27 For client authentication, use one of these argument
28 combinations:
29 - username, password (SRP)
30 - certChain, privateKey (certificate)
31
32 For server authentication, you can either rely on the
33 implicit mutual authentication performed by SRP,
34 or you can do certificate-based server
35 authentication with one of these argument combinations:
36 - x509Fingerprint
37
38 Certificate-based server authentication is compatible with
39 SRP or certificate-based client authentication.
40
41 The constructor does not perform the TLS handshake itself, but
42 simply stores these arguments for later. The handshake is
43 performed only when this class needs to connect with the
44 server. Then you should be prepared to handle TLS-specific
45 exceptions. See the client handshake functions in
46 L{tlslite.TLSConnection.TLSConnection} for details on which
47 exceptions might be raised.
48
49 @type username: str
50 @param username: SRP username. Requires the
51 'password' argument.
52
53 @type password: str
54 @param password: SRP password for mutual authentication.
55 Requires the 'username' argument.
56
57 @type certChain: L{tlslite.x509certchain.X509CertChain}
58 @param certChain: Certificate chain for client authentication.
59 Requires the 'privateKey' argument. Excludes the SRP arguments.
60
61 @type privateKey: L{tlslite.utils.rsakey.RSAKey}
62 @param privateKey: Private key for client authentication.
63 Requires the 'certChain' argument. Excludes the SRP arguments.
64
65 @type checker: L{tlslite.checker.Checker}
66 @param checker: Callable object called after handshaking to
67 evaluate the connection and raise an Exception if necessary.
68
69 @type settings: L{tlslite.handshakesettings.HandshakeSettings}
70 @param settings: Various settings which can be used to control
71 the ciphersuites, certificate types, and SSL/TLS versions
72 offered by the client.
73
74 @type anon: bool
75 @param anon: set to True if the negotiation should advertise only
76 anonymous TLS ciphersuites. Mutually exclusive with client certificate
77 authentication or SRP authentication
78
79 @type host: str or None
80 @param host: the hostname that the connection is made to. Can be an
81 IP address (in which case the SNI extension won't be sent). Can
82 include the port (in which case the port will be stripped and ignored).
83 """
84
85 self.username = None
86 self.password = None
87 self.certChain = None
88 self.privateKey = None
89 self.checker = None
90 self.anon = anon
91
92
93 if username and password and not \
94 (certChain or privateKey):
95 self.username = username
96 self.password = password
97
98
99 elif certChain and privateKey and not \
100 (username or password):
101 self.certChain = certChain
102 self.privateKey = privateKey
103
104
105 elif not password and not username and not \
106 certChain and not privateKey:
107 pass
108
109 else:
110 raise ValueError("Bad parameters")
111
112 self.checker = checker
113 self.settings = settings
114
115 self.tlsSession = None
116
117 if host is not None and not self._isIP(host):
118
119 colon = host.find(':')
120 if colon > 0:
121 host = host[:colon]
122 self.serverName = host
123 if host and not is_valid_hostname(host):
124 raise ValueError("Invalid hostname: {0}".format(host))
125 else:
126 self.serverName = None
127
128 @staticmethod
130 """Return True if the address is an IPv4 address"""
131 if not address:
132 return False
133 vals = address.split('.')
134 if len(vals) != 4:
135 return False
136 for i in vals:
137 if not i.isdigit():
138 return False
139 j = int(i)
140 if not 0 <= j <= 255:
141 return False
142 return True
143
145 if self.username and self.password:
146 tlsConnection.handshakeClientSRP(username=self.username,
147 password=self.password,
148 checker=self.checker,
149 settings=self.settings,
150 session=self.tlsSession,
151 serverName=self.serverName)
152 elif self.anon:
153 tlsConnection.handshakeClientAnonymous(session=self.tlsSession,
154 settings=self.settings,
155 checker=self.checker,
156 serverName=self.serverName)
157 else:
158 tlsConnection.handshakeClientCert(certChain=self.certChain,
159 privateKey=self.privateKey,
160 checker=self.checker,
161 settings=self.settings,
162 session=self.tlsSession,
163 serverName=self.serverName)
164 self.tlsSession = tlsConnection.session
165