blob: 0cf2fae63362805aa6b7609aada8ff36ee607efb [file] [log] [blame]
Thomas Woutersed03b412007-08-28 21:37:11 +00001# Wrapper module for _ssl, providing some additional facilities
2# implemented in Python. Written by Bill Janssen.
3
Guido van Rossum5b8b1552007-11-16 00:06:11 +00004"""This module provides some more Pythonic support for SSL.
Thomas Woutersed03b412007-08-28 21:37:11 +00005
6Object types:
7
Thomas Wouters1b7f8912007-09-19 03:06:30 +00008 SSLSocket -- subtype of socket.socket which does SSL over the socket
Thomas Woutersed03b412007-08-28 21:37:11 +00009
10Exceptions:
11
Thomas Wouters1b7f8912007-09-19 03:06:30 +000012 SSLError -- exception raised for I/O errors
Thomas Woutersed03b412007-08-28 21:37:11 +000013
14Functions:
15
16 cert_time_to_seconds -- convert time string used for certificate
17 notBefore and notAfter functions to integer
18 seconds past the Epoch (the time values
19 returned from time.time())
20
21 fetch_server_certificate (HOST, PORT) -- fetch the certificate provided
22 by the server running on HOST at port PORT. No
23 validation of the certificate is performed.
24
25Integer constants:
26
27SSL_ERROR_ZERO_RETURN
28SSL_ERROR_WANT_READ
29SSL_ERROR_WANT_WRITE
30SSL_ERROR_WANT_X509_LOOKUP
31SSL_ERROR_SYSCALL
32SSL_ERROR_SSL
33SSL_ERROR_WANT_CONNECT
34
35SSL_ERROR_EOF
36SSL_ERROR_INVALID_ERROR_CODE
37
38The following group define certificate requirements that one side is
39allowing/requiring from the other side:
40
41CERT_NONE - no certificates from the other side are required (or will
42 be looked at if provided)
43CERT_OPTIONAL - certificates are not required, but if provided will be
44 validated, and if validation fails, the connection will
45 also fail
46CERT_REQUIRED - certificates are required, and will be validated, and
47 if validation fails, the connection will also fail
48
49The following constants identify various SSL protocol variants:
50
51PROTOCOL_SSLv2
52PROTOCOL_SSLv3
53PROTOCOL_SSLv23
54PROTOCOL_TLSv1
55"""
56
Christian Heimes05e8be12008-02-23 18:30:17 +000057import textwrap
Antoine Pitrou59fdd672010-10-08 10:37:08 +000058import re
Thomas Woutersed03b412007-08-28 21:37:11 +000059
60import _ssl # if we can't import it, let the error propagate
Thomas Wouters1b7f8912007-09-19 03:06:30 +000061
Antoine Pitrou04f6a322010-04-05 21:40:07 +000062from _ssl import OPENSSL_VERSION_NUMBER, OPENSSL_VERSION_INFO, OPENSSL_VERSION
Antoine Pitrou41032a62011-10-27 23:56:55 +020063from _ssl import _SSLContext
64from _ssl import (
65 SSLError, SSLZeroReturnError, SSLWantReadError, SSLWantWriteError,
66 SSLSyscallError, SSLEOFError,
67 )
Thomas Woutersed03b412007-08-28 21:37:11 +000068from _ssl import CERT_NONE, CERT_OPTIONAL, CERT_REQUIRED
Antoine Pitrou6db49442011-12-19 13:27:11 +010069from _ssl import (
70 OP_ALL, OP_NO_SSLv2, OP_NO_SSLv3, OP_NO_TLSv1,
71 OP_CIPHER_SERVER_PREFERENCE,
72 )
Victor Stinner99c8b162011-05-24 12:05:19 +020073from _ssl import RAND_status, RAND_egd, RAND_add, RAND_bytes, RAND_pseudo_bytes
Guido van Rossum5b8b1552007-11-16 00:06:11 +000074from _ssl import (
75 SSL_ERROR_ZERO_RETURN,
76 SSL_ERROR_WANT_READ,
77 SSL_ERROR_WANT_WRITE,
78 SSL_ERROR_WANT_X509_LOOKUP,
79 SSL_ERROR_SYSCALL,
80 SSL_ERROR_SSL,
81 SSL_ERROR_WANT_CONNECT,
82 SSL_ERROR_EOF,
83 SSL_ERROR_INVALID_ERROR_CODE,
84 )
Antoine Pitroud5323212010-10-22 18:19:07 +000085from _ssl import HAS_SNI
Victor Stinner3de49192011-05-09 00:42:58 +020086from _ssl import (PROTOCOL_SSLv3, PROTOCOL_SSLv23,
87 PROTOCOL_TLSv1)
Antoine Pitroub9ac25d2011-07-08 18:47:06 +020088from _ssl import _OPENSSL_API_VERSION
89
Victor Stinner3de49192011-05-09 00:42:58 +020090_PROTOCOL_NAMES = {
91 PROTOCOL_TLSv1: "TLSv1",
92 PROTOCOL_SSLv23: "SSLv23",
93 PROTOCOL_SSLv3: "SSLv3",
94}
95try:
96 from _ssl import PROTOCOL_SSLv2
97except ImportError:
98 pass
99else:
100 _PROTOCOL_NAMES[PROTOCOL_SSLv2] = "SSLv2"
Thomas Woutersed03b412007-08-28 21:37:11 +0000101
Thomas Wouters47b49bf2007-08-30 22:15:33 +0000102from socket import getnameinfo as _getnameinfo
Bill Janssen6e027db2007-11-15 22:23:56 +0000103from socket import error as socket_error
Antoine Pitrou15399c32011-04-28 19:23:55 +0200104from socket import socket, AF_INET, SOCK_STREAM, create_connection
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000105import base64 # for DER-to-PEM translation
Bill Janssen54cc54c2007-12-14 22:08:56 +0000106import traceback
Antoine Pitroude8cf322010-04-26 17:29:05 +0000107import errno
Thomas Wouters47b49bf2007-08-30 22:15:33 +0000108
Antoine Pitroud6494802011-07-21 01:11:30 +0200109if _ssl.HAS_TLS_UNIQUE:
110 CHANNEL_BINDING_TYPES = ['tls-unique']
111else:
112 CHANNEL_BINDING_TYPES = []
Thomas Woutersed03b412007-08-28 21:37:11 +0000113
Antoine Pitrou59fdd672010-10-08 10:37:08 +0000114class CertificateError(ValueError):
115 pass
116
117
118def _dnsname_to_pat(dn):
119 pats = []
120 for frag in dn.split(r'.'):
121 if frag == '*':
122 # When '*' is a fragment by itself, it matches a non-empty dotless
123 # fragment.
124 pats.append('[^.]+')
125 else:
126 # Otherwise, '*' matches any dotless fragment.
127 frag = re.escape(frag)
128 pats.append(frag.replace(r'\*', '[^.]*'))
129 return re.compile(r'\A' + r'\.'.join(pats) + r'\Z', re.IGNORECASE)
130
131
132def match_hostname(cert, hostname):
133 """Verify that *cert* (in decoded format as returned by
134 SSLSocket.getpeercert()) matches the *hostname*. RFC 2818 rules
135 are mostly followed, but IP addresses are not accepted for *hostname*.
136
137 CertificateError is raised on failure. On success, the function
138 returns nothing.
139 """
140 if not cert:
141 raise ValueError("empty or no certificate")
142 dnsnames = []
143 san = cert.get('subjectAltName', ())
144 for key, value in san:
145 if key == 'DNS':
146 if _dnsname_to_pat(value).match(hostname):
147 return
148 dnsnames.append(value)
Antoine Pitrou1c86b442011-05-06 15:19:49 +0200149 if not dnsnames:
150 # The subject is only checked when there is no dNSName entry
151 # in subjectAltName
Antoine Pitrou59fdd672010-10-08 10:37:08 +0000152 for sub in cert.get('subject', ()):
153 for key, value in sub:
154 # XXX according to RFC 2818, the most specific Common Name
155 # must be used.
156 if key == 'commonName':
157 if _dnsname_to_pat(value).match(hostname):
158 return
159 dnsnames.append(value)
160 if len(dnsnames) > 1:
161 raise CertificateError("hostname %r "
162 "doesn't match either of %s"
163 % (hostname, ', '.join(map(repr, dnsnames))))
164 elif len(dnsnames) == 1:
165 raise CertificateError("hostname %r "
166 "doesn't match %r"
167 % (hostname, dnsnames[0]))
168 else:
169 raise CertificateError("no appropriate commonName or "
170 "subjectAltName fields were found")
171
172
Antoine Pitrou152efa22010-05-16 18:19:27 +0000173class SSLContext(_SSLContext):
174 """An SSLContext holds various SSL-related configuration options and
175 data, such as certificates and possibly a private key."""
176
177 __slots__ = ('protocol',)
178
179 def __new__(cls, protocol, *args, **kwargs):
180 return _SSLContext.__new__(cls, protocol)
181
182 def __init__(self, protocol):
183 self.protocol = protocol
184
185 def wrap_socket(self, sock, server_side=False,
186 do_handshake_on_connect=True,
Antoine Pitroud5323212010-10-22 18:19:07 +0000187 suppress_ragged_eofs=True,
188 server_hostname=None):
Antoine Pitrou152efa22010-05-16 18:19:27 +0000189 return SSLSocket(sock=sock, server_side=server_side,
190 do_handshake_on_connect=do_handshake_on_connect,
191 suppress_ragged_eofs=suppress_ragged_eofs,
Antoine Pitroud5323212010-10-22 18:19:07 +0000192 server_hostname=server_hostname,
Antoine Pitrou152efa22010-05-16 18:19:27 +0000193 _context=self)
194
195
196class SSLSocket(socket):
Thomas Wouters47b49bf2007-08-30 22:15:33 +0000197 """This class implements a subtype of socket.socket that wraps
198 the underlying OS socket in an SSL context when necessary, and
199 provides read and write methods over that channel."""
200
Bill Janssen6e027db2007-11-15 22:23:56 +0000201 def __init__(self, sock=None, keyfile=None, certfile=None,
Thomas Woutersed03b412007-08-28 21:37:11 +0000202 server_side=False, cert_reqs=CERT_NONE,
Bill Janssen6e027db2007-11-15 22:23:56 +0000203 ssl_version=PROTOCOL_SSLv23, ca_certs=None,
204 do_handshake_on_connect=True,
205 family=AF_INET, type=SOCK_STREAM, proto=0, fileno=None,
Antoine Pitrou152efa22010-05-16 18:19:27 +0000206 suppress_ragged_eofs=True, ciphers=None,
Antoine Pitroud5323212010-10-22 18:19:07 +0000207 server_hostname=None,
Antoine Pitrou152efa22010-05-16 18:19:27 +0000208 _context=None):
Bill Janssen6e027db2007-11-15 22:23:56 +0000209
Antoine Pitrou152efa22010-05-16 18:19:27 +0000210 if _context:
211 self.context = _context
212 else:
Giampaolo Rodolà745ab382010-08-29 19:25:49 +0000213 if server_side and not certfile:
214 raise ValueError("certfile must be specified for server-side "
215 "operations")
Giampaolo Rodolà8b7da622010-08-30 18:28:05 +0000216 if keyfile and not certfile:
217 raise ValueError("certfile must be specified")
Antoine Pitrou152efa22010-05-16 18:19:27 +0000218 if certfile and not keyfile:
219 keyfile = certfile
220 self.context = SSLContext(ssl_version)
221 self.context.verify_mode = cert_reqs
222 if ca_certs:
223 self.context.load_verify_locations(ca_certs)
224 if certfile:
225 self.context.load_cert_chain(certfile, keyfile)
226 if ciphers:
227 self.context.set_ciphers(ciphers)
228 self.keyfile = keyfile
229 self.certfile = certfile
230 self.cert_reqs = cert_reqs
231 self.ssl_version = ssl_version
232 self.ca_certs = ca_certs
233 self.ciphers = ciphers
Antoine Pitroud5323212010-10-22 18:19:07 +0000234 if server_side and server_hostname:
235 raise ValueError("server_hostname can only be specified "
236 "in client mode")
Giampaolo Rodolà745ab382010-08-29 19:25:49 +0000237 self.server_side = server_side
Antoine Pitroud5323212010-10-22 18:19:07 +0000238 self.server_hostname = server_hostname
Antoine Pitrou152efa22010-05-16 18:19:27 +0000239 self.do_handshake_on_connect = do_handshake_on_connect
240 self.suppress_ragged_eofs = suppress_ragged_eofs
Antoine Pitroufa2b9382010-04-26 22:17:47 +0000241 connected = False
Bill Janssen6e027db2007-11-15 22:23:56 +0000242 if sock is not None:
Bill Janssen54cc54c2007-12-14 22:08:56 +0000243 socket.__init__(self,
244 family=sock.family,
245 type=sock.type,
246 proto=sock.proto,
Antoine Pitroue43f9d02010-08-08 23:24:50 +0000247 fileno=sock.fileno())
Antoine Pitrou40f08742010-04-24 22:04:40 +0000248 self.settimeout(sock.gettimeout())
Antoine Pitroufa2b9382010-04-26 22:17:47 +0000249 # see if it's connected
250 try:
251 sock.getpeername()
252 except socket_error as e:
253 if e.errno != errno.ENOTCONN:
254 raise
255 else:
256 connected = True
Antoine Pitrou6e451df2010-08-09 20:39:54 +0000257 sock.detach()
Bill Janssen6e027db2007-11-15 22:23:56 +0000258 elif fileno is not None:
259 socket.__init__(self, fileno=fileno)
260 else:
261 socket.__init__(self, family=family, type=type, proto=proto)
262
Antoine Pitroufa2b9382010-04-26 22:17:47 +0000263 self._closed = False
264 self._sslobj = None
Antoine Pitroue93bf7a2011-02-26 23:24:06 +0000265 self._connected = connected
Antoine Pitroufa2b9382010-04-26 22:17:47 +0000266 if connected:
267 # create the SSL object
Bill Janssen6e027db2007-11-15 22:23:56 +0000268 try:
Antoine Pitroud5323212010-10-22 18:19:07 +0000269 self._sslobj = self.context._wrap_socket(self, server_side,
270 server_hostname)
Bill Janssen6e027db2007-11-15 22:23:56 +0000271 if do_handshake_on_connect:
Bill Janssen48dc27c2007-12-05 03:38:10 +0000272 timeout = self.gettimeout()
273 if timeout == 0.0:
274 # non-blocking
275 raise ValueError("do_handshake_on_connect should not be specified for non-blocking sockets")
Bill Janssen6e027db2007-11-15 22:23:56 +0000276 self.do_handshake()
Bill Janssen48dc27c2007-12-05 03:38:10 +0000277
Bill Janssen6e027db2007-11-15 22:23:56 +0000278 except socket_error as x:
279 self.close()
280 raise x
281
Guido van Rossumb7b030e2007-11-16 01:28:45 +0000282 def dup(self):
283 raise NotImplemented("Can't dup() %s instances" %
284 self.__class__.__name__)
285
Bill Janssen6e027db2007-11-15 22:23:56 +0000286 def _checkClosed(self, msg=None):
287 # raise an exception here if you wish to check for spurious closes
288 pass
289
Bill Janssen54cc54c2007-12-14 22:08:56 +0000290 def read(self, len=0, buffer=None):
Thomas Wouters47b49bf2007-08-30 22:15:33 +0000291 """Read up to LEN bytes and return them.
292 Return zero-length string on EOF."""
293
Bill Janssen6e027db2007-11-15 22:23:56 +0000294 self._checkClosed()
295 try:
Antoine Pitrou24e561a2010-09-03 18:38:17 +0000296 if buffer is not None:
297 v = self._sslobj.read(len, buffer)
Bill Janssen6e027db2007-11-15 22:23:56 +0000298 else:
Bill Janssen54cc54c2007-12-14 22:08:56 +0000299 v = self._sslobj.read(len or 1024)
300 return v
Bill Janssen6e027db2007-11-15 22:23:56 +0000301 except SSLError as x:
302 if x.args[0] == SSL_ERROR_EOF and self.suppress_ragged_eofs:
Antoine Pitrou24e561a2010-09-03 18:38:17 +0000303 if buffer is not None:
Bill Janssen54cc54c2007-12-14 22:08:56 +0000304 return 0
305 else:
306 return b''
Bill Janssen6e027db2007-11-15 22:23:56 +0000307 else:
308 raise
Thomas Woutersed03b412007-08-28 21:37:11 +0000309
310 def write(self, data):
Thomas Wouters47b49bf2007-08-30 22:15:33 +0000311 """Write DATA to the underlying SSL channel. Returns
312 number of bytes of DATA actually transmitted."""
313
Bill Janssen6e027db2007-11-15 22:23:56 +0000314 self._checkClosed()
Thomas Woutersed03b412007-08-28 21:37:11 +0000315 return self._sslobj.write(data)
316
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000317 def getpeercert(self, binary_form=False):
Thomas Wouters47b49bf2007-08-30 22:15:33 +0000318 """Returns a formatted version of the data in the
319 certificate provided by the other end of the SSL channel.
320 Return None if no certificate was provided, {} if a
321 certificate was provided, but not validated."""
322
Bill Janssen6e027db2007-11-15 22:23:56 +0000323 self._checkClosed()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000324 return self._sslobj.peer_certificate(binary_form)
325
Guido van Rossum5b8b1552007-11-16 00:06:11 +0000326 def cipher(self):
Bill Janssen6e027db2007-11-15 22:23:56 +0000327 self._checkClosed()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000328 if not self._sslobj:
329 return None
330 else:
331 return self._sslobj.cipher()
Thomas Woutersed03b412007-08-28 21:37:11 +0000332
Guido van Rossum5b8b1552007-11-16 00:06:11 +0000333 def send(self, data, flags=0):
Bill Janssen6e027db2007-11-15 22:23:56 +0000334 self._checkClosed()
Thomas Wouters47b49bf2007-08-30 22:15:33 +0000335 if self._sslobj:
336 if flags != 0:
337 raise ValueError(
338 "non-zero flags not allowed in calls to send() on %s" %
339 self.__class__)
Bill Janssen6e027db2007-11-15 22:23:56 +0000340 while True:
341 try:
342 v = self._sslobj.write(data)
343 except SSLError as x:
344 if x.args[0] == SSL_ERROR_WANT_READ:
345 return 0
346 elif x.args[0] == SSL_ERROR_WANT_WRITE:
347 return 0
348 else:
349 raise
350 else:
351 return v
Thomas Wouters47b49bf2007-08-30 22:15:33 +0000352 else:
353 return socket.send(self, data, flags)
Thomas Woutersed03b412007-08-28 21:37:11 +0000354
Antoine Pitroua468adc2010-09-14 14:43:44 +0000355 def sendto(self, data, flags_or_addr, addr=None):
Bill Janssen6e027db2007-11-15 22:23:56 +0000356 self._checkClosed()
Thomas Wouters47b49bf2007-08-30 22:15:33 +0000357 if self._sslobj:
Bill Janssen980f3142008-06-29 00:05:51 +0000358 raise ValueError("sendto not allowed on instances of %s" %
Thomas Wouters47b49bf2007-08-30 22:15:33 +0000359 self.__class__)
Antoine Pitroua468adc2010-09-14 14:43:44 +0000360 elif addr is None:
361 return socket.sendto(self, data, flags_or_addr)
Thomas Wouters47b49bf2007-08-30 22:15:33 +0000362 else:
Antoine Pitroua468adc2010-09-14 14:43:44 +0000363 return socket.sendto(self, data, flags_or_addr, addr)
Thomas Woutersed03b412007-08-28 21:37:11 +0000364
Nick Coghlan513886a2011-08-28 00:00:27 +1000365 def sendmsg(self, *args, **kwargs):
366 # Ensure programs don't send data unencrypted if they try to
367 # use this method.
368 raise NotImplementedError("sendmsg not allowed on instances of %s" %
369 self.__class__)
370
Guido van Rossum5b8b1552007-11-16 00:06:11 +0000371 def sendall(self, data, flags=0):
Bill Janssen6e027db2007-11-15 22:23:56 +0000372 self._checkClosed()
Thomas Wouters47b49bf2007-08-30 22:15:33 +0000373 if self._sslobj:
Giampaolo Rodolà374f8352010-08-29 12:08:09 +0000374 if flags != 0:
375 raise ValueError(
376 "non-zero flags not allowed in calls to sendall() on %s" %
377 self.__class__)
Bill Janssen6e027db2007-11-15 22:23:56 +0000378 amount = len(data)
379 count = 0
380 while (count < amount):
381 v = self.send(data[count:])
382 count += v
383 return amount
Thomas Wouters47b49bf2007-08-30 22:15:33 +0000384 else:
385 return socket.sendall(self, data, flags)
Thomas Woutersed03b412007-08-28 21:37:11 +0000386
Guido van Rossum5b8b1552007-11-16 00:06:11 +0000387 def recv(self, buflen=1024, flags=0):
Bill Janssen6e027db2007-11-15 22:23:56 +0000388 self._checkClosed()
Thomas Wouters47b49bf2007-08-30 22:15:33 +0000389 if self._sslobj:
390 if flags != 0:
391 raise ValueError(
Antoine Pitrou5733c082010-03-22 14:49:10 +0000392 "non-zero flags not allowed in calls to recv() on %s" %
393 self.__class__)
394 return self.read(buflen)
Thomas Wouters47b49bf2007-08-30 22:15:33 +0000395 else:
396 return socket.recv(self, buflen, flags)
Thomas Woutersed03b412007-08-28 21:37:11 +0000397
Guido van Rossum5b8b1552007-11-16 00:06:11 +0000398 def recv_into(self, buffer, nbytes=None, flags=0):
Bill Janssen6e027db2007-11-15 22:23:56 +0000399 self._checkClosed()
400 if buffer and (nbytes is None):
401 nbytes = len(buffer)
402 elif nbytes is None:
403 nbytes = 1024
404 if self._sslobj:
405 if flags != 0:
406 raise ValueError(
Guido van Rossum5b8b1552007-11-16 00:06:11 +0000407 "non-zero flags not allowed in calls to recv_into() on %s" %
408 self.__class__)
Antoine Pitrou5733c082010-03-22 14:49:10 +0000409 return self.read(nbytes, buffer)
Bill Janssen6e027db2007-11-15 22:23:56 +0000410 else:
411 return socket.recv_into(self, buffer, nbytes, flags)
412
Antoine Pitroua468adc2010-09-14 14:43:44 +0000413 def recvfrom(self, buflen=1024, flags=0):
Bill Janssen6e027db2007-11-15 22:23:56 +0000414 self._checkClosed()
Thomas Wouters47b49bf2007-08-30 22:15:33 +0000415 if self._sslobj:
Bill Janssen980f3142008-06-29 00:05:51 +0000416 raise ValueError("recvfrom not allowed on instances of %s" %
Thomas Wouters47b49bf2007-08-30 22:15:33 +0000417 self.__class__)
418 else:
Antoine Pitroua468adc2010-09-14 14:43:44 +0000419 return socket.recvfrom(self, buflen, flags)
Thomas Woutersed03b412007-08-28 21:37:11 +0000420
Bill Janssen58afe4c2008-09-08 16:45:19 +0000421 def recvfrom_into(self, buffer, nbytes=None, flags=0):
422 self._checkClosed()
423 if self._sslobj:
424 raise ValueError("recvfrom_into not allowed on instances of %s" %
425 self.__class__)
426 else:
427 return socket.recvfrom_into(self, buffer, nbytes, flags)
428
Nick Coghlan513886a2011-08-28 00:00:27 +1000429 def recvmsg(self, *args, **kwargs):
430 raise NotImplementedError("recvmsg not allowed on instances of %s" %
431 self.__class__)
432
433 def recvmsg_into(self, *args, **kwargs):
434 raise NotImplementedError("recvmsg_into not allowed on instances of "
435 "%s" % self.__class__)
436
Guido van Rossum5b8b1552007-11-16 00:06:11 +0000437 def pending(self):
Bill Janssen6e027db2007-11-15 22:23:56 +0000438 self._checkClosed()
439 if self._sslobj:
440 return self._sslobj.pending()
441 else:
442 return 0
443
Guido van Rossum5b8b1552007-11-16 00:06:11 +0000444 def shutdown(self, how):
Bill Janssen6e027db2007-11-15 22:23:56 +0000445 self._checkClosed()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000446 self._sslobj = None
Thomas Wouters47b49bf2007-08-30 22:15:33 +0000447 socket.shutdown(self, how)
Thomas Woutersed03b412007-08-28 21:37:11 +0000448
Ezio Melottidc55e672010-01-18 09:15:14 +0000449 def unwrap(self):
Bill Janssen40a0f662008-08-12 16:56:25 +0000450 if self._sslobj:
451 s = self._sslobj.shutdown()
452 self._sslobj = None
453 return s
454 else:
455 raise ValueError("No SSL wrapper around " + str(self))
456
Guido van Rossum5b8b1552007-11-16 00:06:11 +0000457 def _real_close(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000458 self._sslobj = None
Bill Janssen6e027db2007-11-15 22:23:56 +0000459 # self._closed = True
Bill Janssen54cc54c2007-12-14 22:08:56 +0000460 socket._real_close(self)
Bill Janssen6e027db2007-11-15 22:23:56 +0000461
Bill Janssen48dc27c2007-12-05 03:38:10 +0000462 def do_handshake(self, block=False):
Bill Janssen6e027db2007-11-15 22:23:56 +0000463 """Perform a TLS/SSL handshake."""
464
Bill Janssen48dc27c2007-12-05 03:38:10 +0000465 timeout = self.gettimeout()
Bill Janssen6e027db2007-11-15 22:23:56 +0000466 try:
Bill Janssen48dc27c2007-12-05 03:38:10 +0000467 if timeout == 0.0 and block:
468 self.settimeout(None)
Bill Janssen6e027db2007-11-15 22:23:56 +0000469 self._sslobj.do_handshake()
Bill Janssen48dc27c2007-12-05 03:38:10 +0000470 finally:
471 self.settimeout(timeout)
Thomas Woutersed03b412007-08-28 21:37:11 +0000472
Antoine Pitroub4410db2011-05-18 18:51:06 +0200473 def _real_connect(self, addr, connect_ex):
Giampaolo Rodolà745ab382010-08-29 19:25:49 +0000474 if self.server_side:
475 raise ValueError("can't connect in server-side mode")
Thomas Woutersed03b412007-08-28 21:37:11 +0000476 # Here we assume that the socket is client-side, and not
477 # connected at the time of the call. We connect it, then wrap it.
Antoine Pitroue93bf7a2011-02-26 23:24:06 +0000478 if self._connected:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000479 raise ValueError("attempt to connect already-connected SSLSocket!")
Antoine Pitroud5323212010-10-22 18:19:07 +0000480 self._sslobj = self.context._wrap_socket(self, False, self.server_hostname)
Bill Janssen54cc54c2007-12-14 22:08:56 +0000481 try:
Antoine Pitroub4410db2011-05-18 18:51:06 +0200482 if connect_ex:
483 rc = socket.connect_ex(self, addr)
Antoine Pitroue93bf7a2011-02-26 23:24:06 +0000484 else:
Antoine Pitroub4410db2011-05-18 18:51:06 +0200485 rc = None
486 socket.connect(self, addr)
487 if not rc:
488 if self.do_handshake_on_connect:
489 self.do_handshake()
490 self._connected = True
491 return rc
492 except socket_error:
493 self._sslobj = None
494 raise
Antoine Pitroue93bf7a2011-02-26 23:24:06 +0000495
496 def connect(self, addr):
497 """Connects to remote ADDR, and then wraps the connection in
498 an SSL channel."""
499 self._real_connect(addr, False)
500
501 def connect_ex(self, addr):
502 """Connects to remote ADDR, and then wraps the connection in
503 an SSL channel."""
504 return self._real_connect(addr, True)
Thomas Woutersed03b412007-08-28 21:37:11 +0000505
506 def accept(self):
Thomas Wouters47b49bf2007-08-30 22:15:33 +0000507 """Accepts a new connection from a remote client, and returns
508 a tuple containing that new connection wrapped with a server-side
509 SSL channel, and the address of the remote client."""
510
511 newsock, addr = socket.accept(self)
Bill Janssen6e027db2007-11-15 22:23:56 +0000512 return (SSLSocket(sock=newsock,
513 keyfile=self.keyfile, certfile=self.certfile,
514 server_side=True,
Guido van Rossum5b8b1552007-11-16 00:06:11 +0000515 cert_reqs=self.cert_reqs,
516 ssl_version=self.ssl_version,
Bill Janssen6e027db2007-11-15 22:23:56 +0000517 ca_certs=self.ca_certs,
Antoine Pitrou2d9cb9c2010-04-17 17:40:45 +0000518 ciphers=self.ciphers,
Guido van Rossum5b8b1552007-11-16 00:06:11 +0000519 do_handshake_on_connect=
520 self.do_handshake_on_connect),
Bill Janssen6e027db2007-11-15 22:23:56 +0000521 addr)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000522
Antoine Pitroud6494802011-07-21 01:11:30 +0200523 def get_channel_binding(self, cb_type="tls-unique"):
524 """Get channel binding data for current connection. Raise ValueError
525 if the requested `cb_type` is not supported. Return bytes of the data
526 or None if the data is not available (e.g. before the handshake).
527 """
528 if cb_type not in CHANNEL_BINDING_TYPES:
529 raise ValueError("Unsupported channel binding type")
530 if cb_type != "tls-unique":
531 raise NotImplementedError(
532 "{0} channel binding type not implemented"
533 .format(cb_type))
534 if self._sslobj is None:
535 return None
536 return self._sslobj.tls_unique_cb()
537
Guido van Rossume6650f92007-12-06 19:05:55 +0000538 def __del__(self):
Bill Janssen54cc54c2007-12-14 22:08:56 +0000539 # sys.stderr.write("__del__ on %s\n" % repr(self))
Guido van Rossume6650f92007-12-06 19:05:55 +0000540 self._real_close()
541
Bill Janssen54cc54c2007-12-14 22:08:56 +0000542
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000543def wrap_socket(sock, keyfile=None, certfile=None,
544 server_side=False, cert_reqs=CERT_NONE,
Bill Janssen6e027db2007-11-15 22:23:56 +0000545 ssl_version=PROTOCOL_SSLv23, ca_certs=None,
Bill Janssen48dc27c2007-12-05 03:38:10 +0000546 do_handshake_on_connect=True,
Antoine Pitrou2d9cb9c2010-04-17 17:40:45 +0000547 suppress_ragged_eofs=True, ciphers=None):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000548
Bill Janssen6e027db2007-11-15 22:23:56 +0000549 return SSLSocket(sock=sock, keyfile=keyfile, certfile=certfile,
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000550 server_side=server_side, cert_reqs=cert_reqs,
Bill Janssen6e027db2007-11-15 22:23:56 +0000551 ssl_version=ssl_version, ca_certs=ca_certs,
Bill Janssen48dc27c2007-12-05 03:38:10 +0000552 do_handshake_on_connect=do_handshake_on_connect,
Antoine Pitrou2d9cb9c2010-04-17 17:40:45 +0000553 suppress_ragged_eofs=suppress_ragged_eofs,
554 ciphers=ciphers)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000555
Thomas Woutersed03b412007-08-28 21:37:11 +0000556# some utility functions
557
558def cert_time_to_seconds(cert_time):
Thomas Wouters47b49bf2007-08-30 22:15:33 +0000559 """Takes a date-time string in standard ASN1_print form
560 ("MON DAY 24HOUR:MINUTE:SEC YEAR TIMEZONE") and return
561 a Python time value in seconds past the epoch."""
562
Thomas Woutersed03b412007-08-28 21:37:11 +0000563 import time
564 return time.mktime(time.strptime(cert_time, "%b %d %H:%M:%S %Y GMT"))
565
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000566PEM_HEADER = "-----BEGIN CERTIFICATE-----"
567PEM_FOOTER = "-----END CERTIFICATE-----"
568
569def DER_cert_to_PEM_cert(der_cert_bytes):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000570 """Takes a certificate in binary DER format and returns the
571 PEM version of it as a string."""
572
Bill Janssen6e027db2007-11-15 22:23:56 +0000573 f = str(base64.standard_b64encode(der_cert_bytes), 'ASCII', 'strict')
574 return (PEM_HEADER + '\n' +
575 textwrap.fill(f, 64) + '\n' +
576 PEM_FOOTER + '\n')
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000577
578def PEM_cert_to_DER_cert(pem_cert_string):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000579 """Takes a certificate in ASCII PEM format and returns the
580 DER-encoded version of it as a byte sequence"""
581
582 if not pem_cert_string.startswith(PEM_HEADER):
583 raise ValueError("Invalid PEM encoding; must start with %s"
584 % PEM_HEADER)
585 if not pem_cert_string.strip().endswith(PEM_FOOTER):
586 raise ValueError("Invalid PEM encoding; must end with %s"
587 % PEM_FOOTER)
588 d = pem_cert_string.strip()[len(PEM_HEADER):-len(PEM_FOOTER)]
Georg Brandl706824f2009-06-04 09:42:55 +0000589 return base64.decodebytes(d.encode('ASCII', 'strict'))
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000590
Guido van Rossum5b8b1552007-11-16 00:06:11 +0000591def get_server_certificate(addr, ssl_version=PROTOCOL_SSLv3, ca_certs=None):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000592 """Retrieve the certificate from the server at the specified address,
593 and return it as a PEM-encoded string.
594 If 'ca_certs' is specified, validate the server cert against it.
595 If 'ssl_version' is specified, use it in the connection attempt."""
596
597 host, port = addr
598 if (ca_certs is not None):
599 cert_reqs = CERT_REQUIRED
600 else:
601 cert_reqs = CERT_NONE
Antoine Pitrou15399c32011-04-28 19:23:55 +0200602 s = create_connection(addr)
603 s = wrap_socket(s, ssl_version=ssl_version,
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000604 cert_reqs=cert_reqs, ca_certs=ca_certs)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000605 dercert = s.getpeercert(True)
606 s.close()
607 return DER_cert_to_PEM_cert(dercert)
608
Guido van Rossum5b8b1552007-11-16 00:06:11 +0000609def get_protocol_name(protocol_code):
Victor Stinner3de49192011-05-09 00:42:58 +0200610 return _PROTOCOL_NAMES.get(protocol_code, '<unknown>')