blob: 9b27013681791c5f0b32d2f2b02a846ea46e5618 [file] [log] [blame]
Maximilian Hils1d95dea2015-08-17 19:27:20 +02001import socket
Konstantinos Koukopoulos541150d2014-01-31 01:00:19 +02002from sys import platform
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05003from functools import wraps, partial
Cory Benfieldbe3e7b82014-05-10 09:48:55 +01004from itertools import count, chain
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08005from weakref import WeakValueDictionary
6from errno import errorcode
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -08007
Jean-Paul Calderone63eab692014-01-18 10:19:56 -05008from six import text_type as _text_type
Cory Benfield63759dc2015-04-12 08:57:03 -04009from six import binary_type as _binary_type
Konstantinos Koukopoulosc8b13ea2014-01-28 00:21:50 -080010from six import integer_types as integer_types
Cory Benfieldcd010f62014-05-15 19:00:27 +010011from six import int2byte, indexbytes
Jean-Paul Calderone63eab692014-01-18 10:19:56 -050012
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -050013from OpenSSL._util import (
14 ffi as _ffi,
15 lib as _lib,
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -050016 exception_from_error_queue as _exception_from_error_queue,
Jean-Paul Calderone55f9e882015-04-12 09:31:03 -040017 native as _native,
Jean-Paul Calderone39a8d592015-04-13 20:49:50 -040018 text_to_bytes_and_warn as _text_to_bytes_and_warn,
Jean-Paul Calderone55f9e882015-04-12 09:31:03 -040019 path_string as _path_string,
Jean-Paul Calderone00f84eb2015-04-13 12:47:21 -040020 UNSPECIFIED as _UNSPECIFIED,
Jean-Paul Calderone55f9e882015-04-12 09:31:03 -040021)
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080022
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -080023from OpenSSL.crypto import (
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -050024 FILETYPE_PEM, _PassphraseHelper, PKey, X509Name, X509, X509Store)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -080025
Jean-Paul Calderone8fb53182013-12-30 08:35:49 -050026try:
27 _memoryview = memoryview
28except NameError:
29 class _memoryview(object):
30 pass
31
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +020032try:
33 _buffer = buffer
34except NameError:
35 class _buffer(object):
36 pass
37
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050038OPENSSL_VERSION_NUMBER = _lib.OPENSSL_VERSION_NUMBER
39SSLEAY_VERSION = _lib.SSLEAY_VERSION
40SSLEAY_CFLAGS = _lib.SSLEAY_CFLAGS
41SSLEAY_PLATFORM = _lib.SSLEAY_PLATFORM
42SSLEAY_DIR = _lib.SSLEAY_DIR
43SSLEAY_BUILT_ON = _lib.SSLEAY_BUILT_ON
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080044
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050045SENT_SHUTDOWN = _lib.SSL_SENT_SHUTDOWN
46RECEIVED_SHUTDOWN = _lib.SSL_RECEIVED_SHUTDOWN
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080047
48SSLv2_METHOD = 1
49SSLv3_METHOD = 2
50SSLv23_METHOD = 3
51TLSv1_METHOD = 4
Jean-Paul Calderone56bff942013-11-03 11:30:43 -050052TLSv1_1_METHOD = 5
53TLSv1_2_METHOD = 6
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080054
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050055OP_NO_SSLv2 = _lib.SSL_OP_NO_SSLv2
56OP_NO_SSLv3 = _lib.SSL_OP_NO_SSLv3
57OP_NO_TLSv1 = _lib.SSL_OP_NO_TLSv1
Jean-Paul Calderonebe2bb422013-12-29 07:34:08 -050058
59OP_NO_TLSv1_1 = getattr(_lib, "SSL_OP_NO_TLSv1_1", 0)
60OP_NO_TLSv1_2 = getattr(_lib, "SSL_OP_NO_TLSv1_2", 0)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -080061
Jean-Paul Calderone0d7e8a12014-01-08 16:54:13 -050062try:
63 MODE_RELEASE_BUFFERS = _lib.SSL_MODE_RELEASE_BUFFERS
64except AttributeError:
65 pass
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080066
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050067OP_SINGLE_DH_USE = _lib.SSL_OP_SINGLE_DH_USE
68OP_EPHEMERAL_RSA = _lib.SSL_OP_EPHEMERAL_RSA
69OP_MICROSOFT_SESS_ID_BUG = _lib.SSL_OP_MICROSOFT_SESS_ID_BUG
70OP_NETSCAPE_CHALLENGE_BUG = _lib.SSL_OP_NETSCAPE_CHALLENGE_BUG
71OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG = _lib.SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG
72OP_SSLREF2_REUSE_CERT_TYPE_BUG = _lib.SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG
73OP_MICROSOFT_BIG_SSLV3_BUFFER = _lib.SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER
Jean-Paul Calderone0d7e8a12014-01-08 16:54:13 -050074try:
75 OP_MSIE_SSLV2_RSA_PADDING = _lib.SSL_OP_MSIE_SSLV2_RSA_PADDING
76except AttributeError:
77 pass
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050078OP_SSLEAY_080_CLIENT_DH_BUG = _lib.SSL_OP_SSLEAY_080_CLIENT_DH_BUG
79OP_TLS_D5_BUG = _lib.SSL_OP_TLS_D5_BUG
80OP_TLS_BLOCK_PADDING_BUG = _lib.SSL_OP_TLS_BLOCK_PADDING_BUG
81OP_DONT_INSERT_EMPTY_FRAGMENTS = _lib.SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
82OP_CIPHER_SERVER_PREFERENCE = _lib.SSL_OP_CIPHER_SERVER_PREFERENCE
83OP_TLS_ROLLBACK_BUG = _lib.SSL_OP_TLS_ROLLBACK_BUG
84OP_PKCS1_CHECK_1 = _lib.SSL_OP_PKCS1_CHECK_1
85OP_PKCS1_CHECK_2 = _lib.SSL_OP_PKCS1_CHECK_2
86OP_NETSCAPE_CA_DN_BUG = _lib.SSL_OP_NETSCAPE_CA_DN_BUG
87OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG= _lib.SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG
Jean-Paul Calderonec1780342014-01-08 16:59:03 -050088try:
89 OP_NO_COMPRESSION = _lib.SSL_OP_NO_COMPRESSION
90except AttributeError:
91 pass
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -080092
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050093OP_NO_QUERY_MTU = _lib.SSL_OP_NO_QUERY_MTU
94OP_COOKIE_EXCHANGE = _lib.SSL_OP_COOKIE_EXCHANGE
Arturo Filastò5f8c7a82014-03-09 20:01:25 +010095try:
96 OP_NO_TICKET = _lib.SSL_OP_NO_TICKET
97except AttributeError:
98 pass
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -080099
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500100OP_ALL = _lib.SSL_OP_ALL
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -0800101
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500102VERIFY_PEER = _lib.SSL_VERIFY_PEER
103VERIFY_FAIL_IF_NO_PEER_CERT = _lib.SSL_VERIFY_FAIL_IF_NO_PEER_CERT
104VERIFY_CLIENT_ONCE = _lib.SSL_VERIFY_CLIENT_ONCE
105VERIFY_NONE = _lib.SSL_VERIFY_NONE
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -0800106
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500107SESS_CACHE_OFF = _lib.SSL_SESS_CACHE_OFF
108SESS_CACHE_CLIENT = _lib.SSL_SESS_CACHE_CLIENT
109SESS_CACHE_SERVER = _lib.SSL_SESS_CACHE_SERVER
110SESS_CACHE_BOTH = _lib.SSL_SESS_CACHE_BOTH
111SESS_CACHE_NO_AUTO_CLEAR = _lib.SSL_SESS_CACHE_NO_AUTO_CLEAR
112SESS_CACHE_NO_INTERNAL_LOOKUP = _lib.SSL_SESS_CACHE_NO_INTERNAL_LOOKUP
113SESS_CACHE_NO_INTERNAL_STORE = _lib.SSL_SESS_CACHE_NO_INTERNAL_STORE
114SESS_CACHE_NO_INTERNAL = _lib.SSL_SESS_CACHE_NO_INTERNAL
Jean-Paul Calderoned39a3f62013-03-04 12:23:51 -0800115
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500116SSL_ST_CONNECT = _lib.SSL_ST_CONNECT
117SSL_ST_ACCEPT = _lib.SSL_ST_ACCEPT
118SSL_ST_MASK = _lib.SSL_ST_MASK
119SSL_ST_INIT = _lib.SSL_ST_INIT
120SSL_ST_BEFORE = _lib.SSL_ST_BEFORE
121SSL_ST_OK = _lib.SSL_ST_OK
122SSL_ST_RENEGOTIATE = _lib.SSL_ST_RENEGOTIATE
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800123
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500124SSL_CB_LOOP = _lib.SSL_CB_LOOP
125SSL_CB_EXIT = _lib.SSL_CB_EXIT
126SSL_CB_READ = _lib.SSL_CB_READ
127SSL_CB_WRITE = _lib.SSL_CB_WRITE
128SSL_CB_ALERT = _lib.SSL_CB_ALERT
129SSL_CB_READ_ALERT = _lib.SSL_CB_READ_ALERT
130SSL_CB_WRITE_ALERT = _lib.SSL_CB_WRITE_ALERT
131SSL_CB_ACCEPT_LOOP = _lib.SSL_CB_ACCEPT_LOOP
132SSL_CB_ACCEPT_EXIT = _lib.SSL_CB_ACCEPT_EXIT
133SSL_CB_CONNECT_LOOP = _lib.SSL_CB_CONNECT_LOOP
134SSL_CB_CONNECT_EXIT = _lib.SSL_CB_CONNECT_EXIT
135SSL_CB_HANDSHAKE_START = _lib.SSL_CB_HANDSHAKE_START
136SSL_CB_HANDSHAKE_DONE = _lib.SSL_CB_HANDSHAKE_DONE
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800137
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500138class Error(Exception):
Jean-Paul Calderone511cde02013-12-29 10:31:13 -0500139 """
140 An error occurred in an `OpenSSL.SSL` API.
141 """
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500142
143
144
145_raise_current_error = partial(_exception_from_error_queue, Error)
146
147
148class WantReadError(Error):
149 pass
150
151
152
153class WantWriteError(Error):
154 pass
155
156
157
158class WantX509LookupError(Error):
159 pass
160
161
162
163class ZeroReturnError(Error):
164 pass
165
166
167
168class SysCallError(Error):
169 pass
170
171
Cory Benfield0ea76e72015-03-22 09:05:28 +0000172class _CallbackExceptionHelper(object):
173 """
174 A base class for wrapper classes that allow for intelligent exception
175 handling in OpenSSL callbacks.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500176
Jean-Paul Calderone1b172982015-03-22 19:37:11 -0400177 :ivar list _problems: Any exceptions that occurred while executing in a
178 context where they could not be raised in the normal way. Typically
179 this is because OpenSSL has called into some Python code and requires a
180 return value. The exceptions are saved to be raised later when it is
181 possible to do so.
Cory Benfield0ea76e72015-03-22 09:05:28 +0000182 """
Jean-Paul Calderone09540d72015-03-22 19:37:20 -0400183 def __init__(self):
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800184 self._problems = []
185
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800186
Cory Benfield0ea76e72015-03-22 09:05:28 +0000187 def raise_if_problem(self):
Jean-Paul Calderone1b172982015-03-22 19:37:11 -0400188 """
189 Raise an exception from the OpenSSL error queue or that was previously
190 captured whe running a callback.
191 """
Cory Benfield0ea76e72015-03-22 09:05:28 +0000192 if self._problems:
193 try:
194 _raise_current_error()
195 except Error:
196 pass
197 raise self._problems.pop(0)
198
199
200class _VerifyHelper(_CallbackExceptionHelper):
Jean-Paul Calderone1b172982015-03-22 19:37:11 -0400201 """
202 Wrap a callback such that it can be used as a certificate verification
203 callback.
204 """
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800205 def __init__(self, callback):
Jean-Paul Calderone837f4032015-03-22 17:38:28 -0400206 _CallbackExceptionHelper.__init__(self)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800207
208 @wraps(callback)
209 def wrapper(ok, store_ctx):
210 cert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500211 cert._x509 = _lib.X509_STORE_CTX_get_current_cert(store_ctx)
212 error_number = _lib.X509_STORE_CTX_get_error(store_ctx)
213 error_depth = _lib.X509_STORE_CTX_get_error_depth(store_ctx)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800214
Jean-Paul Calderone6a8cd112014-04-02 21:09:08 -0400215 index = _lib.SSL_get_ex_data_X509_STORE_CTX_idx()
216 ssl = _lib.X509_STORE_CTX_get_ex_data(store_ctx, index)
217 connection = Connection._reverse_mapping[ssl]
218
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800219 try:
220 result = callback(connection, cert, error_number, error_depth, ok)
221 except Exception as e:
222 self._problems.append(e)
223 return 0
224 else:
225 if result:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500226 _lib.X509_STORE_CTX_set_error(store_ctx, _lib.X509_V_OK)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800227 return 1
228 else:
229 return 0
230
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500231 self.callback = _ffi.callback(
232 "int (*)(int, X509_STORE_CTX *)", wrapper)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800233
234
Cory Benfield0ea76e72015-03-22 09:05:28 +0000235class _NpnAdvertiseHelper(_CallbackExceptionHelper):
Jean-Paul Calderone1b172982015-03-22 19:37:11 -0400236 """
237 Wrap a callback such that it can be used as an NPN advertisement callback.
238 """
Cory Benfield0ea76e72015-03-22 09:05:28 +0000239 def __init__(self, callback):
Jean-Paul Calderone837f4032015-03-22 17:38:28 -0400240 _CallbackExceptionHelper.__init__(self)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800241
Cory Benfield0ea76e72015-03-22 09:05:28 +0000242 @wraps(callback)
243 def wrapper(ssl, out, outlen, arg):
244 try:
245 conn = Connection._reverse_mapping[ssl]
246 protos = callback(conn)
247
248 # Join the protocols into a Python bytestring, length-prefixing
249 # each element.
250 protostr = b''.join(
251 chain.from_iterable((int2byte(len(p)), p) for p in protos)
252 )
253
254 # Save our callback arguments on the connection object. This is
255 # done to make sure that they don't get freed before OpenSSL
256 # uses them. Then, return them appropriately in the output
257 # parameters.
258 conn._npn_advertise_callback_args = [
259 _ffi.new("unsigned int *", len(protostr)),
260 _ffi.new("unsigned char[]", protostr),
261 ]
262 outlen[0] = conn._npn_advertise_callback_args[0][0]
263 out[0] = conn._npn_advertise_callback_args[1]
264 return 0
265 except Exception as e:
266 self._problems.append(e)
267 return 2 # SSL_TLSEXT_ERR_ALERT_FATAL
268
269 self.callback = _ffi.callback(
270 "int (*)(SSL *, const unsigned char **, unsigned int *, void *)",
271 wrapper
272 )
273
274
275class _NpnSelectHelper(_CallbackExceptionHelper):
Jean-Paul Calderone1b172982015-03-22 19:37:11 -0400276 """
277 Wrap a callback such that it can be used as an NPN selection callback.
278 """
Cory Benfield0ea76e72015-03-22 09:05:28 +0000279 def __init__(self, callback):
Jean-Paul Calderone837f4032015-03-22 17:38:28 -0400280 _CallbackExceptionHelper.__init__(self)
Cory Benfield0ea76e72015-03-22 09:05:28 +0000281
282 @wraps(callback)
283 def wrapper(ssl, out, outlen, in_, inlen, arg):
284 try:
285 conn = Connection._reverse_mapping[ssl]
286
287 # The string passed to us is actually made up of multiple
288 # length-prefixed bytestrings. We need to split that into a
289 # list.
290 instr = _ffi.buffer(in_, inlen)[:]
291 protolist = []
292 while instr:
293 l = indexbytes(instr, 0)
294 proto = instr[1:l+1]
295 protolist.append(proto)
296 instr = instr[l+1:]
297
298 # Call the callback
299 outstr = callback(conn, protolist)
300
301 # Save our callback arguments on the connection object. This is
302 # done to make sure that they don't get freed before OpenSSL
303 # uses them. Then, return them appropriately in the output
304 # parameters.
305 conn._npn_select_callback_args = [
306 _ffi.new("unsigned char *", len(outstr)),
307 _ffi.new("unsigned char[]", outstr),
308 ]
309 outlen[0] = conn._npn_select_callback_args[0][0]
310 out[0] = conn._npn_select_callback_args[1]
311 return 0
312 except Exception as e:
313 self._problems.append(e)
314 return 2 # SSL_TLSEXT_ERR_ALERT_FATAL
315
316 self.callback = _ffi.callback(
317 "int (*)(SSL *, unsigned char **, unsigned char *, "
318 "const unsigned char *, unsigned int, void *)",
319 wrapper
320 )
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800321
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800322
Cory Benfield9da5ffb2015-04-13 17:20:14 -0400323class _ALPNSelectHelper(_CallbackExceptionHelper):
Cory Benfieldf1177e72015-04-12 09:11:49 -0400324 """
325 Wrap a callback such that it can be used as an ALPN selection callback.
326 """
327 def __init__(self, callback):
328 _CallbackExceptionHelper.__init__(self)
329
330 @wraps(callback)
331 def wrapper(ssl, out, outlen, in_, inlen, arg):
332 try:
333 conn = Connection._reverse_mapping[ssl]
334
335 # The string passed to us is made up of multiple
336 # length-prefixed bytestrings. We need to split that into a
337 # list.
338 instr = _ffi.buffer(in_, inlen)[:]
339 protolist = []
340 while instr:
Cory Benfield93134db2015-04-13 17:22:13 -0400341 encoded_len = indexbytes(instr, 0)
342 proto = instr[1:encoded_len + 1]
Cory Benfieldf1177e72015-04-12 09:11:49 -0400343 protolist.append(proto)
Cory Benfield93134db2015-04-13 17:22:13 -0400344 instr = instr[encoded_len + 1:]
Cory Benfieldf1177e72015-04-12 09:11:49 -0400345
346 # Call the callback
347 outstr = callback(conn, protolist)
348
349 if not isinstance(outstr, _binary_type):
350 raise TypeError("ALPN callback must return a bytestring.")
351
352 # Save our callback arguments on the connection object to make
353 # sure that they don't get freed before OpenSSL can use them.
354 # Then, return them in the appropriate output parameters.
355 conn._alpn_select_callback_args = [
356 _ffi.new("unsigned char *", len(outstr)),
357 _ffi.new("unsigned char[]", outstr),
358 ]
359 outlen[0] = conn._alpn_select_callback_args[0][0]
360 out[0] = conn._alpn_select_callback_args[1]
361 return 0
362 except Exception as e:
363 self._problems.append(e)
364 return 2 # SSL_TLSEXT_ERR_ALERT_FATAL
365
366 self.callback = _ffi.callback(
367 "int (*)(SSL *, unsigned char **, unsigned char *, "
368 "const unsigned char *, unsigned int, void *)",
369 wrapper
370 )
371
372
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800373def _asFileDescriptor(obj):
374 fd = None
Konstantinos Koukopoulosc8b13ea2014-01-28 00:21:50 -0800375 if not isinstance(obj, integer_types):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800376 meth = getattr(obj, "fileno", None)
377 if meth is not None:
378 obj = meth()
379
Konstantinos Koukopoulosc8b13ea2014-01-28 00:21:50 -0800380 if isinstance(obj, integer_types):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800381 fd = obj
382
Konstantinos Koukopoulosc8b13ea2014-01-28 00:21:50 -0800383 if not isinstance(fd, integer_types):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800384 raise TypeError("argument must be an int, or have a fileno() method.")
385 elif fd < 0:
386 raise ValueError(
387 "file descriptor cannot be a negative integer (%i)" % (fd,))
388
389 return fd
390
391
392
Jean-Paul Calderoned39a3f62013-03-04 12:23:51 -0800393def SSLeay_version(type):
394 """
395 Return a string describing the version of OpenSSL in use.
396
397 :param type: One of the SSLEAY_ constants defined in this module.
398 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500399 return _ffi.string(_lib.SSLeay_version(type))
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800400
401
Cory Benfield10b277f2015-04-13 17:12:42 -0400402def _requires_npn(func):
Cory Benfielda876cef2015-04-13 17:29:12 -0400403 """
404 Wraps any function that requires NPN support in OpenSSL, ensuring that
405 NotImplementedError is raised if NPN is not present.
406 """
Cory Benfield10b277f2015-04-13 17:12:42 -0400407 @wraps(func)
408 def wrapper(*args, **kwargs):
409 if not _lib.Cryptography_HAS_NEXTPROTONEG:
410 raise NotImplementedError("NPN not available.")
411
412 return func(*args, **kwargs)
413
414 return wrapper
415
416
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800417
Cory Benfield7907e332015-04-13 17:18:25 -0400418def _requires_alpn(func):
Cory Benfield9d80a762015-04-13 17:47:33 -0400419 """
420 Wraps any function that requires ALPN support in OpenSSL, ensuring that
421 NotImplementedError is raised if ALPN support is not present.
422 """
Cory Benfield7907e332015-04-13 17:18:25 -0400423 @wraps(func)
424 def wrapper(*args, **kwargs):
425 if not _lib.Cryptography_HAS_ALPN:
426 raise NotImplementedError("ALPN not available.")
427
428 return func(*args, **kwargs)
429
430 return wrapper
431
432
433
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800434class Session(object):
435 pass
436
437
438
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800439class Context(object):
440 """
441 :py:obj:`OpenSSL.SSL.Context` instances define the parameters for setting up
442 new SSL connections.
443 """
444 _methods = {
Andrew Dunhamec84a0a2014-02-24 12:41:37 -0800445 SSLv2_METHOD: "SSLv2_method",
Jean-Paul Calderonebe2bb422013-12-29 07:34:08 -0500446 SSLv3_METHOD: "SSLv3_method",
447 SSLv23_METHOD: "SSLv23_method",
448 TLSv1_METHOD: "TLSv1_method",
449 TLSv1_1_METHOD: "TLSv1_1_method",
450 TLSv1_2_METHOD: "TLSv1_2_method",
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800451 }
Jean-Paul Calderonebe2bb422013-12-29 07:34:08 -0500452 _methods = dict(
453 (identifier, getattr(_lib, name))
454 for (identifier, name) in _methods.items()
455 if getattr(_lib, name, None) is not None)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800456
Jean-Paul Calderone63157872013-03-20 16:43:38 -0700457
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800458 def __init__(self, method):
459 """
460 :param method: One of SSLv2_METHOD, SSLv3_METHOD, SSLv23_METHOD, or
461 TLSv1_METHOD.
462 """
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -0500463 if not isinstance(method, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800464 raise TypeError("method must be an integer")
465
466 try:
467 method_func = self._methods[method]
468 except KeyError:
469 raise ValueError("No such protocol")
470
471 method_obj = method_func()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500472 if method_obj == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500473 # TODO: This is untested.
474 _raise_current_error()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800475
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500476 context = _lib.SSL_CTX_new(method_obj)
477 if context == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500478 # TODO: This is untested.
479 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500480 context = _ffi.gc(context, _lib.SSL_CTX_free)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800481
482 self._context = context
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800483 self._passphrase_helper = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800484 self._passphrase_callback = None
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800485 self._passphrase_userdata = None
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800486 self._verify_helper = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800487 self._verify_callback = None
488 self._info_callback = None
489 self._tlsext_servername_callback = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800490 self._app_data = None
Cory Benfield0ea76e72015-03-22 09:05:28 +0000491 self._npn_advertise_helper = None
Cory Benfield84a121e2014-03-31 20:30:25 +0100492 self._npn_advertise_callback = None
Cory Benfield0ea76e72015-03-22 09:05:28 +0000493 self._npn_select_helper = None
Cory Benfield84a121e2014-03-31 20:30:25 +0100494 self._npn_select_callback = None
Cory Benfieldf1177e72015-04-12 09:11:49 -0400495 self._alpn_select_helper = None
Cory Benfield12eae892014-06-07 15:42:56 +0100496 self._alpn_select_callback = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800497
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -0800498 # SSL_CTX_set_app_data(self->ctx, self);
499 # SSL_CTX_set_mode(self->ctx, SSL_MODE_ENABLE_PARTIAL_WRITE |
500 # SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
501 # SSL_MODE_AUTO_RETRY);
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500502 self.set_mode(_lib.SSL_MODE_ENABLE_PARTIAL_WRITE)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800503
504
505 def load_verify_locations(self, cafile, capath=None):
506 """
507 Let SSL know where we can find trusted certificates for the certificate
508 chain
509
Jean-Paul Calderone55f9e882015-04-12 09:31:03 -0400510 :param cafile: In which file we can find the certificates (``bytes`` or
511 ``unicode``).
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800512 :param capath: In which directory we can find the certificates
Jean-Paul Calderone55f9e882015-04-12 09:31:03 -0400513 (``bytes`` or ``unicode``).
514
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800515 :return: None
516 """
517 if cafile is None:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500518 cafile = _ffi.NULL
Jean-Paul Calderone55f9e882015-04-12 09:31:03 -0400519 else:
520 cafile = _path_string(cafile)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800521
522 if capath is None:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500523 capath = _ffi.NULL
Jean-Paul Calderone55f9e882015-04-12 09:31:03 -0400524 else:
525 capath = _path_string(capath)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800526
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500527 load_result = _lib.SSL_CTX_load_verify_locations(self._context, cafile, capath)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800528 if not load_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500529 _raise_current_error()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800530
531
532 def _wrap_callback(self, callback):
533 @wraps(callback)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800534 def wrapper(size, verify, userdata):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800535 return callback(size, verify, self._passphrase_userdata)
536 return _PassphraseHelper(
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800537 FILETYPE_PEM, wrapper, more_args=True, truncate=True)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800538
539
540 def set_passwd_cb(self, callback, userdata=None):
541 """
542 Set the passphrase callback
543
544 :param callback: The Python callback to use
545 :param userdata: (optional) A Python object which will be given as
546 argument to the callback
547 :return: None
548 """
549 if not callable(callback):
550 raise TypeError("callback must be callable")
551
552 self._passphrase_helper = self._wrap_callback(callback)
553 self._passphrase_callback = self._passphrase_helper.callback
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500554 _lib.SSL_CTX_set_default_passwd_cb(
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800555 self._context, self._passphrase_callback)
556 self._passphrase_userdata = userdata
557
558
559 def set_default_verify_paths(self):
560 """
561 Use the platform-specific CA certificate locations
562
563 :return: None
564 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500565 set_result = _lib.SSL_CTX_set_default_verify_paths(self._context)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800566 if not set_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500567 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500568 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800569
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800570
571 def use_certificate_chain_file(self, certfile):
572 """
573 Load a certificate chain from a file
574
Jean-Paul Calderoneb6f8a792015-04-13 10:10:06 -0400575 :param certfile: The name of the certificate chain file (``bytes`` or
576 ``unicode``).
577
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800578 :return: None
579 """
Jean-Paul Calderoneaac43a32015-04-12 09:51:21 -0400580 certfile = _path_string(certfile)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800581
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500582 result = _lib.SSL_CTX_use_certificate_chain_file(self._context, certfile)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800583 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500584 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800585
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800586
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800587 def use_certificate_file(self, certfile, filetype=FILETYPE_PEM):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800588 """
589 Load a certificate from a file
590
Jean-Paul Calderoneb6f8a792015-04-13 10:10:06 -0400591 :param certfile: The name of the certificate file (``bytes`` or
592 ``unicode``).
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800593 :param filetype: (optional) The encoding of the file, default is PEM
Jean-Paul Calderoneb6f8a792015-04-13 10:10:06 -0400594
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800595 :return: None
596 """
Jean-Paul Calderoned57a7b62015-04-12 09:57:36 -0400597 certfile = _path_string(certfile)
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -0500598 if not isinstance(filetype, integer_types):
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800599 raise TypeError("filetype must be an integer")
600
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500601 use_result = _lib.SSL_CTX_use_certificate_file(self._context, certfile, filetype)
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800602 if not use_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500603 _raise_current_error()
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800604
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800605
606 def use_certificate(self, cert):
607 """
608 Load a certificate from a X509 object
609
610 :param cert: The X509 object
611 :return: None
612 """
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800613 if not isinstance(cert, X509):
614 raise TypeError("cert must be an X509 instance")
615
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500616 use_result = _lib.SSL_CTX_use_certificate(self._context, cert._x509)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800617 if not use_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500618 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800619
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800620
621 def add_extra_chain_cert(self, certobj):
622 """
623 Add certificate to chain
624
625 :param certobj: The X509 certificate object to add to the chain
626 :return: None
627 """
628 if not isinstance(certobj, X509):
629 raise TypeError("certobj must be an X509 instance")
630
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500631 copy = _lib.X509_dup(certobj._x509)
632 add_result = _lib.SSL_CTX_add_extra_chain_cert(self._context, copy)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800633 if not add_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500634 # TODO: This is untested.
635 _lib.X509_free(copy)
636 _raise_current_error()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800637
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800638
639 def _raise_passphrase_exception(self):
640 if self._passphrase_helper is None:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500641 _raise_current_error()
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800642 exception = self._passphrase_helper.raise_if_problem(Error)
643 if exception is not None:
644 raise exception
645
646
Jean-Paul Calderone00f84eb2015-04-13 12:47:21 -0400647 def use_privatekey_file(self, keyfile, filetype=_UNSPECIFIED):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800648 """
649 Load a private key from a file
650
Jean-Paul Calderoneb6f8a792015-04-13 10:10:06 -0400651 :param keyfile: The name of the key file (``bytes`` or ``unicode``)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800652 :param filetype: (optional) The encoding of the file, default is PEM
Jean-Paul Calderoneb6f8a792015-04-13 10:10:06 -0400653
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800654 :return: None
655 """
Jean-Paul Calderone69a4e5b2015-04-12 10:04:28 -0400656 keyfile = _path_string(keyfile)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800657
Jean-Paul Calderone00f84eb2015-04-13 12:47:21 -0400658 if filetype is _UNSPECIFIED:
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800659 filetype = FILETYPE_PEM
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -0500660 elif not isinstance(filetype, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800661 raise TypeError("filetype must be an integer")
662
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500663 use_result = _lib.SSL_CTX_use_PrivateKey_file(
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800664 self._context, keyfile, filetype)
665 if not use_result:
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800666 self._raise_passphrase_exception()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800667
668
669 def use_privatekey(self, pkey):
670 """
671 Load a private key from a PKey object
672
673 :param pkey: The PKey object
674 :return: None
675 """
676 if not isinstance(pkey, PKey):
677 raise TypeError("pkey must be a PKey instance")
678
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500679 use_result = _lib.SSL_CTX_use_PrivateKey(self._context, pkey._pkey)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800680 if not use_result:
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800681 self._raise_passphrase_exception()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800682
683
684 def check_privatekey(self):
685 """
686 Check that the private key and certificate match up
687
688 :return: None (raises an exception if something's wrong)
689 """
Jean-Paul Calderonea0344922014-12-11 14:02:31 -0500690 if not _lib.SSL_CTX_check_private_key(self._context):
691 _raise_current_error()
692
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800693
694 def load_client_ca(self, cafile):
695 """
696 Load the trusted certificates that will be sent to the client (basically
697 telling the client "These are the guys I trust"). Does not actually
698 imply any of the certificates are trusted; that must be configured
699 separately.
700
701 :param cafile: The name of the certificates file
702 :return: None
703 """
704
705 def set_session_id(self, buf):
706 """
707 Set the session identifier. This is needed if you want to do session
708 resumption.
709
710 :param buf: A Python object that can be safely converted to a string
711 :returns: None
712 """
713
714 def set_session_cache_mode(self, mode):
715 """
716 Enable/disable session caching and specify the mode used.
717
718 :param mode: One or more of the SESS_CACHE_* flags (combine using
719 bitwise or)
720 :returns: The previously set caching mode.
721 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500722 if not isinstance(mode, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800723 raise TypeError("mode must be an integer")
724
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500725 return _lib.SSL_CTX_set_session_cache_mode(self._context, mode)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800726
727
728 def get_session_cache_mode(self):
729 """
730 :returns: The currently used cache mode.
731 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500732 return _lib.SSL_CTX_get_session_cache_mode(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800733
734
735 def set_verify(self, mode, callback):
736 """
737 Set the verify mode and verify callback
738
739 :param mode: The verify mode, this is either VERIFY_NONE or
740 VERIFY_PEER combined with possible other flags
741 :param callback: The Python callback to use
742 :return: None
743
744 See SSL_CTX_set_verify(3SSL) for further details.
745 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500746 if not isinstance(mode, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800747 raise TypeError("mode must be an integer")
748
749 if not callable(callback):
750 raise TypeError("callback must be callable")
751
Jean-Paul Calderone6a8cd112014-04-02 21:09:08 -0400752 self._verify_helper = _VerifyHelper(callback)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800753 self._verify_callback = self._verify_helper.callback
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500754 _lib.SSL_CTX_set_verify(self._context, mode, self._verify_callback)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800755
756
757 def set_verify_depth(self, depth):
758 """
759 Set the verify depth
760
761 :param depth: An integer specifying the verify depth
762 :return: None
763 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500764 if not isinstance(depth, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800765 raise TypeError("depth must be an integer")
766
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500767 _lib.SSL_CTX_set_verify_depth(self._context, depth)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800768
769
770 def get_verify_mode(self):
771 """
772 Get the verify mode
773
774 :return: The verify mode
775 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500776 return _lib.SSL_CTX_get_verify_mode(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800777
778
779 def get_verify_depth(self):
780 """
781 Get the verify depth
782
783 :return: The verify depth
784 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500785 return _lib.SSL_CTX_get_verify_depth(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800786
787
788 def load_tmp_dh(self, dhfile):
789 """
790 Load parameters for Ephemeral Diffie-Hellman
791
Jean-Paul Calderone4e0c43f2015-04-13 10:15:17 -0400792 :param dhfile: The file to load EDH parameters from (``bytes`` or
793 ``unicode``).
794
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800795 :return: None
796 """
Jean-Paul Calderone9e1c1dd2015-04-12 10:13:13 -0400797 dhfile = _path_string(dhfile)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800798
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -0500799 bio = _lib.BIO_new_file(dhfile, b"r")
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500800 if bio == _ffi.NULL:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500801 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500802 bio = _ffi.gc(bio, _lib.BIO_free)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800803
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500804 dh = _lib.PEM_read_bio_DHparams(bio, _ffi.NULL, _ffi.NULL, _ffi.NULL)
805 dh = _ffi.gc(dh, _lib.DH_free)
806 _lib.SSL_CTX_set_tmp_dh(self._context, dh)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800807
808
Jean-Paul Calderone3e4e3352014-04-19 09:28:28 -0400809 def set_tmp_ecdh(self, curve):
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600810 """
Andy Lutomirski76a61332014-03-12 15:02:56 -0700811 Select a curve to use for ECDHE key exchange.
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600812
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -0400813 :param curve: A curve object to use as returned by either
814 :py:meth:`OpenSSL.crypto.get_elliptic_curve` or
815 :py:meth:`OpenSSL.crypto.get_elliptic_curves`.
Andy Lutomirskif05a2732014-03-13 17:22:25 -0700816
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600817 :return: None
818 """
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -0400819 _lib.SSL_CTX_set_tmp_ecdh(self._context, curve._to_EC_KEY())
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600820
821
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800822 def set_cipher_list(self, cipher_list):
823 """
824 Change the cipher list
825
826 :param cipher_list: A cipher list, see ciphers(1)
827 :return: None
828 """
Jean-Paul Calderone63eab692014-01-18 10:19:56 -0500829 if isinstance(cipher_list, _text_type):
830 cipher_list = cipher_list.encode("ascii")
831
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800832 if not isinstance(cipher_list, bytes):
Jean-Paul Calderone63eab692014-01-18 10:19:56 -0500833 raise TypeError("cipher_list must be bytes or unicode")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800834
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500835 result = _lib.SSL_CTX_set_cipher_list(self._context, cipher_list)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800836 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500837 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800838
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800839
840 def set_client_ca_list(self, certificate_authorities):
841 """
842 Set the list of preferred client certificate signers for this server context.
843
844 This list of certificate authorities will be sent to the client when the
845 server requests a client certificate.
846
847 :param certificate_authorities: a sequence of X509Names.
848 :return: None
849 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500850 name_stack = _lib.sk_X509_NAME_new_null()
851 if name_stack == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500852 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500853 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800854
855 try:
856 for ca_name in certificate_authorities:
857 if not isinstance(ca_name, X509Name):
858 raise TypeError(
859 "client CAs must be X509Name objects, not %s objects" % (
860 type(ca_name).__name__,))
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500861 copy = _lib.X509_NAME_dup(ca_name._name)
862 if copy == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500863 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500864 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500865 push_result = _lib.sk_X509_NAME_push(name_stack, copy)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800866 if not push_result:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500867 _lib.X509_NAME_free(copy)
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500868 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800869 except:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500870 _lib.sk_X509_NAME_free(name_stack)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800871 raise
872
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500873 _lib.SSL_CTX_set_client_CA_list(self._context, name_stack)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800874
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800875
876 def add_client_ca(self, certificate_authority):
877 """
878 Add the CA certificate to the list of preferred signers for this context.
879
880 The list of certificate authorities will be sent to the client when the
881 server requests a client certificate.
882
883 :param certificate_authority: certificate authority's X509 certificate.
884 :return: None
885 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800886 if not isinstance(certificate_authority, X509):
887 raise TypeError("certificate_authority must be an X509 instance")
888
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500889 add_result = _lib.SSL_CTX_add_client_CA(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800890 self._context, certificate_authority._x509)
891 if not add_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500892 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500893 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800894
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800895
896 def set_timeout(self, timeout):
897 """
898 Set session timeout
899
900 :param timeout: The timeout in seconds
901 :return: The previous session timeout
902 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500903 if not isinstance(timeout, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800904 raise TypeError("timeout must be an integer")
905
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500906 return _lib.SSL_CTX_set_timeout(self._context, timeout)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800907
908
909 def get_timeout(self):
910 """
911 Get the session timeout
912
913 :return: The session timeout
914 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500915 return _lib.SSL_CTX_get_timeout(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800916
917
918 def set_info_callback(self, callback):
919 """
920 Set the info callback
921
922 :param callback: The Python callback to use
923 :return: None
924 """
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800925 @wraps(callback)
926 def wrapper(ssl, where, return_code):
Jean-Paul Calderonef2bbc9c2014-02-02 10:59:14 -0500927 callback(Connection._reverse_mapping[ssl], where, return_code)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500928 self._info_callback = _ffi.callback(
929 "void (*)(const SSL *, int, int)", wrapper)
930 _lib.SSL_CTX_set_info_callback(self._context, self._info_callback)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800931
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800932
933 def get_app_data(self):
934 """
935 Get the application data (supplied via set_app_data())
936
937 :return: The application data
938 """
939 return self._app_data
940
941
942 def set_app_data(self, data):
943 """
944 Set the application data (will be returned from get_app_data())
945
946 :param data: Any Python object
947 :return: None
948 """
949 self._app_data = data
950
951
952 def get_cert_store(self):
953 """
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500954 Get the certificate store for the context.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800955
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500956 :return: A X509Store object or None if it does not have one.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800957 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500958 store = _lib.SSL_CTX_get_cert_store(self._context)
959 if store == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500960 # TODO: This is untested.
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800961 return None
962
963 pystore = X509Store.__new__(X509Store)
964 pystore._store = store
965 return pystore
966
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800967
968 def set_options(self, options):
969 """
970 Add options. Options set before are not cleared!
971
972 :param options: The options to add.
973 :return: The new option bitmask.
974 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500975 if not isinstance(options, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800976 raise TypeError("options must be an integer")
977
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500978 return _lib.SSL_CTX_set_options(self._context, options)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800979
980
981 def set_mode(self, mode):
982 """
983 Add modes via bitmask. Modes set before are not cleared!
984
985 :param mode: The mode to add.
986 :return: The new mode bitmask.
987 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500988 if not isinstance(mode, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800989 raise TypeError("mode must be an integer")
990
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500991 return _lib.SSL_CTX_set_mode(self._context, mode)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800992
993
994 def set_tlsext_servername_callback(self, callback):
995 """
996 Specify a callback function to be called when clients specify a server name.
997
998 :param callback: The callback function. It will be invoked with one
999 argument, the Connection instance.
1000 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001001 @wraps(callback)
1002 def wrapper(ssl, alert, arg):
1003 callback(Connection._reverse_mapping[ssl])
1004 return 0
1005
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001006 self._tlsext_servername_callback = _ffi.callback(
1007 "int (*)(const SSL *, int *, void *)", wrapper)
1008 _lib.SSL_CTX_set_tlsext_servername_callback(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001009 self._context, self._tlsext_servername_callback)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -08001010
Cory Benfield84a121e2014-03-31 20:30:25 +01001011
Cory Benfield10b277f2015-04-13 17:12:42 -04001012 @_requires_npn
Cory Benfield84a121e2014-03-31 20:30:25 +01001013 def set_npn_advertise_callback(self, callback):
1014 """
Cory Benfieldbe3e7b82014-05-10 09:48:55 +01001015 Specify a callback function that will be called when offering `Next
1016 Protocol Negotiation
1017 <https://technotes.googlecode.com/git/nextprotoneg.html>`_ as a server.
Cory Benfield84a121e2014-03-31 20:30:25 +01001018
1019 :param callback: The callback function. It will be invoked with one
Cory Benfieldbe3e7b82014-05-10 09:48:55 +01001020 argument, the Connection instance. It should return a list of
1021 bytestrings representing the advertised protocols, like
1022 ``[b'http/1.1', b'spdy/2']``.
Cory Benfield84a121e2014-03-31 20:30:25 +01001023 """
Cory Benfield0ea76e72015-03-22 09:05:28 +00001024 self._npn_advertise_helper = _NpnAdvertiseHelper(callback)
1025 self._npn_advertise_callback = self._npn_advertise_helper.callback
Cory Benfield84a121e2014-03-31 20:30:25 +01001026 _lib.SSL_CTX_set_next_protos_advertised_cb(
1027 self._context, self._npn_advertise_callback, _ffi.NULL)
1028
1029
Cory Benfield10b277f2015-04-13 17:12:42 -04001030 @_requires_npn
Cory Benfield84a121e2014-03-31 20:30:25 +01001031 def set_npn_select_callback(self, callback):
1032 """
1033 Specify a callback function that will be called when a server offers
1034 Next Protocol Negotiation options.
1035
1036 :param callback: The callback function. It will be invoked with two
1037 arguments: the Connection, and a list of offered protocols as
Cory Benfieldbe3e7b82014-05-10 09:48:55 +01001038 bytestrings, e.g. ``[b'http/1.1', b'spdy/2']``. It should return
1039 one of those bytestrings, the chosen protocol.
Cory Benfield84a121e2014-03-31 20:30:25 +01001040 """
Cory Benfield0ea76e72015-03-22 09:05:28 +00001041 self._npn_select_helper = _NpnSelectHelper(callback)
1042 self._npn_select_callback = self._npn_select_helper.callback
Cory Benfield84a121e2014-03-31 20:30:25 +01001043 _lib.SSL_CTX_set_next_proto_select_cb(
1044 self._context, self._npn_select_callback, _ffi.NULL)
1045
Cory Benfield7907e332015-04-13 17:18:25 -04001046 @_requires_alpn
Cory Benfield12eae892014-06-07 15:42:56 +01001047 def set_alpn_protos(self, protos):
1048 """
Cory Benfielde8e9c382015-04-11 17:33:48 -04001049 Specify the clients ALPN protocol list.
1050
1051 These protocols are offered to the server during protocol negotiation.
Cory Benfield12eae892014-06-07 15:42:56 +01001052
1053 :param protos: A list of the protocols to be offered to the server.
1054 This list should be a Python list of bytestrings representing the
1055 protocols to offer, e.g. ``[b'http/1.1', b'spdy/2']``.
1056 """
1057 # Take the list of protocols and join them together, prefixing them
1058 # with their lengths.
1059 protostr = b''.join(
1060 chain.from_iterable((int2byte(len(p)), p) for p in protos)
1061 )
1062
1063 # Build a C string from the list. We don't need to save this off
1064 # because OpenSSL immediately copies the data out.
1065 input_str = _ffi.new("unsigned char[]", protostr)
Cory Benfielde871af52015-04-11 17:57:50 -04001066 input_str_len = _ffi.cast("unsigned", len(protostr))
1067 _lib.SSL_CTX_set_alpn_protos(self._context, input_str, input_str_len)
Cory Benfield12eae892014-06-07 15:42:56 +01001068
Cory Benfield7907e332015-04-13 17:18:25 -04001069 @_requires_alpn
Cory Benfield12eae892014-06-07 15:42:56 +01001070 def set_alpn_select_callback(self, callback):
1071 """
Cory Benfielde8e9c382015-04-11 17:33:48 -04001072 Set the callback to handle ALPN protocol choice.
Cory Benfield12eae892014-06-07 15:42:56 +01001073
1074 :param callback: The callback function. It will be invoked with two
1075 arguments: the Connection, and a list of offered protocols as
1076 bytestrings, e.g ``[b'http/1.1', b'spdy/2']``. It should return
Cory Benfielde8e9c382015-04-11 17:33:48 -04001077 one of those bytestrings, the chosen protocol.
Cory Benfield12eae892014-06-07 15:42:56 +01001078 """
Cory Benfield9da5ffb2015-04-13 17:20:14 -04001079 self._alpn_select_helper = _ALPNSelectHelper(callback)
Cory Benfieldf1177e72015-04-12 09:11:49 -04001080 self._alpn_select_callback = self._alpn_select_helper.callback
Cory Benfield12eae892014-06-07 15:42:56 +01001081 _lib.SSL_CTX_set_alpn_select_cb(
1082 self._context, self._alpn_select_callback, _ffi.NULL)
1083
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -08001084ContextType = Context
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001085
1086
1087
1088class Connection(object):
1089 """
1090 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001091 _reverse_mapping = WeakValueDictionary()
1092
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001093 def __init__(self, context, socket=None):
1094 """
1095 Create a new Connection object, using the given OpenSSL.SSL.Context
1096 instance and socket.
1097
1098 :param context: An SSL Context to use for this connection
1099 :param socket: The socket to use for transport layer
1100 """
1101 if not isinstance(context, Context):
1102 raise TypeError("context must be a Context instance")
1103
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001104 ssl = _lib.SSL_new(context._context)
1105 self._ssl = _ffi.gc(ssl, _lib.SSL_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001106 self._context = context
1107
Cory Benfieldbe3e7b82014-05-10 09:48:55 +01001108 # References to strings used for Next Protocol Negotiation. OpenSSL's
1109 # header files suggest that these might get copied at some point, but
1110 # doesn't specify when, so we store them here to make sure they don't
1111 # get freed before OpenSSL uses them.
1112 self._npn_advertise_callback_args = None
1113 self._npn_select_callback_args = None
1114
Cory Benfield12eae892014-06-07 15:42:56 +01001115 # References to strings used for Application Layer Protocol
1116 # Negotiation. These strings get copied at some point but it's well
1117 # after the callback returns, so we have to hang them somewhere to
1118 # avoid them getting freed.
1119 self._alpn_select_callback_args = None
1120
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001121 self._reverse_mapping[self._ssl] = self
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001122
1123 if socket is None:
1124 self._socket = None
Jean-Paul Calderone73b15c22013-03-05 18:30:39 -08001125 # Don't set up any gc for these, SSL_free will take care of them.
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001126 self._into_ssl = _lib.BIO_new(_lib.BIO_s_mem())
1127 self._from_ssl = _lib.BIO_new(_lib.BIO_s_mem())
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001128
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001129 if self._into_ssl == _ffi.NULL or self._from_ssl == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001130 # TODO: This is untested.
1131 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001132
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001133 _lib.SSL_set_bio(self._ssl, self._into_ssl, self._from_ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001134 else:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001135 self._into_ssl = None
1136 self._from_ssl = None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001137 self._socket = socket
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001138 set_result = _lib.SSL_set_fd(self._ssl, _asFileDescriptor(self._socket))
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001139 if not set_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001140 # TODO: This is untested.
1141 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001142
1143
1144 def __getattr__(self, name):
1145 """
1146 Look up attributes on the wrapped socket object if they are not found on
1147 the Connection object.
1148 """
1149 return getattr(self._socket, name)
1150
1151
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001152 def _raise_ssl_error(self, ssl, result):
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -08001153 if self._context._verify_helper is not None:
1154 self._context._verify_helper.raise_if_problem()
Cory Benfield0ea76e72015-03-22 09:05:28 +00001155 if self._context._npn_advertise_helper is not None:
1156 self._context._npn_advertise_helper.raise_if_problem()
1157 if self._context._npn_select_helper is not None:
1158 self._context._npn_select_helper.raise_if_problem()
Cory Benfieldf1177e72015-04-12 09:11:49 -04001159 if self._context._alpn_select_helper is not None:
1160 self._context._alpn_select_helper.raise_if_problem()
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -08001161
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001162 error = _lib.SSL_get_error(ssl, result)
1163 if error == _lib.SSL_ERROR_WANT_READ:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001164 raise WantReadError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001165 elif error == _lib.SSL_ERROR_WANT_WRITE:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001166 raise WantWriteError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001167 elif error == _lib.SSL_ERROR_ZERO_RETURN:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001168 raise ZeroReturnError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001169 elif error == _lib.SSL_ERROR_WANT_X509_LOOKUP:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001170 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001171 raise WantX509LookupError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001172 elif error == _lib.SSL_ERROR_SYSCALL:
1173 if _lib.ERR_peek_error() == 0:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001174 if result < 0:
Konstantinos Koukopoulos541150d2014-01-31 01:00:19 +02001175 if platform == "win32":
1176 errno = _ffi.getwinerror()[0]
1177 else:
1178 errno = _ffi.errno
Glyph3afdba82015-04-14 17:30:53 -04001179 raise SysCallError(errno, errorcode.get(errno))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001180 else:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001181 raise SysCallError(-1, "Unexpected EOF")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001182 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001183 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001184 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001185 elif error == _lib.SSL_ERROR_NONE:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001186 pass
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001187 else:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001188 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001189
1190
1191 def get_context(self):
1192 """
1193 Get session context
1194 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001195 return self._context
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001196
1197
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001198 def set_context(self, context):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001199 """
1200 Switch this connection to a new session context
1201
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001202 :param context: A :py:class:`Context` instance giving the new session
1203 context to use.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001204 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001205 if not isinstance(context, Context):
1206 raise TypeError("context must be a Context instance")
1207
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001208 _lib.SSL_set_SSL_CTX(self._ssl, context._context)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001209 self._context = context
1210
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001211
1212 def get_servername(self):
1213 """
1214 Retrieve the servername extension value if provided in the client hello
1215 message, or None if there wasn't one.
1216
1217 :return: A byte string giving the server name or :py:data:`None`.
1218 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001219 name = _lib.SSL_get_servername(self._ssl, _lib.TLSEXT_NAMETYPE_host_name)
1220 if name == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001221 return None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001222
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001223 return _ffi.string(name)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001224
1225
1226 def set_tlsext_host_name(self, name):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001227 """
1228 Set the value of the servername extension to send in the client hello.
1229
1230 :param name: A byte string giving the name.
1231 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001232 if not isinstance(name, bytes):
1233 raise TypeError("name must be a byte string")
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001234 elif b"\0" in name:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001235 raise TypeError("name must not contain NUL byte")
1236
1237 # XXX I guess this can fail sometimes?
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001238 _lib.SSL_set_tlsext_host_name(self._ssl, name)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001239
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001240
1241 def pending(self):
1242 """
1243 Get the number of bytes that can be safely read from the connection
1244
1245 :return: The number of bytes available in the receive buffer.
1246 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001247 return _lib.SSL_pending(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001248
1249
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001250 def send(self, buf, flags=0):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001251 """
1252 Send data on the connection. NOTE: If you get one of the WantRead,
1253 WantWrite or WantX509Lookup exceptions on this, you have to call the
1254 method again with the SAME buffer.
1255
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001256 :param buf: The string, buffer or memoryview to send
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001257 :param flags: (optional) Included for compatibility with the socket
1258 API, the value is ignored
1259 :return: The number of bytes written
1260 """
Abraham Martine82326c2015-02-04 10:18:10 +00001261 # Backward compatibility
Jean-Paul Calderone39a8d592015-04-13 20:49:50 -04001262 buf = _text_to_bytes_and_warn("buf", buf)
Abraham Martine82326c2015-02-04 10:18:10 +00001263
Jean-Paul Calderone8fb53182013-12-30 08:35:49 -05001264 if isinstance(buf, _memoryview):
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -08001265 buf = buf.tobytes()
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001266 if isinstance(buf, _buffer):
1267 buf = str(buf)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001268 if not isinstance(buf, bytes):
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001269 raise TypeError("data must be a memoryview, buffer or byte string")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001270
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001271 result = _lib.SSL_write(self._ssl, buf, len(buf))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001272 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001273 return result
1274 write = send
1275
1276
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001277 def sendall(self, buf, flags=0):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001278 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001279 Send "all" data on the connection. This calls send() repeatedly until
1280 all data is sent. If an error occurs, it's impossible to tell how much
1281 data has been sent.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001282
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001283 :param buf: The string, buffer or memoryview to send
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001284 :param flags: (optional) Included for compatibility with the socket
1285 API, the value is ignored
1286 :return: The number of bytes written
1287 """
Jean-Paul Calderone39a8d592015-04-13 20:49:50 -04001288 buf = _text_to_bytes_and_warn("buf", buf)
Abraham Martine82326c2015-02-04 10:18:10 +00001289
Jean-Paul Calderone8fb53182013-12-30 08:35:49 -05001290 if isinstance(buf, _memoryview):
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -08001291 buf = buf.tobytes()
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001292 if isinstance(buf, _buffer):
1293 buf = str(buf)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001294 if not isinstance(buf, bytes):
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001295 raise TypeError("buf must be a memoryview, buffer or byte string")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001296
1297 left_to_send = len(buf)
1298 total_sent = 0
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001299 data = _ffi.new("char[]", buf)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001300
1301 while left_to_send:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001302 result = _lib.SSL_write(self._ssl, data + total_sent, left_to_send)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001303 self._raise_ssl_error(self._ssl, result)
1304 total_sent += result
1305 left_to_send -= result
1306
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001307
1308 def recv(self, bufsiz, flags=None):
1309 """
1310 Receive data on the connection. NOTE: If you get one of the WantRead,
1311 WantWrite or WantX509Lookup exceptions on this, you have to call the
1312 method again with the SAME buffer.
1313
1314 :param bufsiz: The maximum number of bytes to read
Maximilian Hils1d95dea2015-08-17 19:27:20 +02001315 :param flags: (optional) The only supported flag is ``MSG_PEEK``,
1316 all other flags are ignored.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001317 :return: The string read from the Connection
1318 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001319 buf = _ffi.new("char[]", bufsiz)
Maximilian Hils1d95dea2015-08-17 19:27:20 +02001320 if flags is not None and flags & socket.MSG_PEEK:
1321 result = _lib.SSL_peek(self._ssl, buf, bufsiz)
1322 else:
1323 result = _lib.SSL_read(self._ssl, buf, bufsiz)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001324 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001325 return _ffi.buffer(buf, result)[:]
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001326 read = recv
1327
1328
Cory Benfield62d10332014-06-15 10:03:41 +01001329 def recv_into(self, buffer, nbytes=None, flags=None):
1330 """
1331 Receive data on the connection and store the data into a buffer rather
1332 than creating a new string.
1333
1334 :param buffer: The buffer to copy into.
1335 :param nbytes: (optional) The maximum number of bytes to read into the
1336 buffer. If not present, defaults to the size of the buffer. If
1337 larger than the size of the buffer, is reduced to the size of the
1338 buffer.
Maximilian Hils1d95dea2015-08-17 19:27:20 +02001339 :param flags: (optional) The only supported flag is ``MSG_PEEK``,
1340 all other flags are ignored.
Cory Benfield62d10332014-06-15 10:03:41 +01001341 :return: The number of bytes read into the buffer.
1342 """
1343 if nbytes is None:
1344 nbytes = len(buffer)
1345 else:
1346 nbytes = min(nbytes, len(buffer))
1347
1348 # We need to create a temporary buffer. This is annoying, it would be
1349 # better if we could pass memoryviews straight into the SSL_read call,
1350 # but right now we can't. Revisit this if CFFI gets that ability.
1351 buf = _ffi.new("char[]", nbytes)
Maximilian Hils1d95dea2015-08-17 19:27:20 +02001352 if flags is not None and flags & socket.MSG_PEEK:
1353 result = _lib.SSL_peek(self._ssl, buf, nbytes)
1354 else:
1355 result = _lib.SSL_read(self._ssl, buf, nbytes)
Cory Benfield62d10332014-06-15 10:03:41 +01001356 self._raise_ssl_error(self._ssl, result)
1357
1358 # This strange line is all to avoid a memory copy. The buffer protocol
1359 # should allow us to assign a CFFI buffer to the LHS of this line, but
1360 # on CPython 3.3+ that segfaults. As a workaround, we can temporarily
1361 # wrap it in a memoryview, except on Python 2.6 which doesn't have a
1362 # memoryview type.
1363 try:
1364 buffer[:result] = memoryview(_ffi.buffer(buf, result))
1365 except NameError:
1366 buffer[:result] = _ffi.buffer(buf, result)
1367
1368 return result
1369
1370
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001371 def _handle_bio_errors(self, bio, result):
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001372 if _lib.BIO_should_retry(bio):
1373 if _lib.BIO_should_read(bio):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001374 raise WantReadError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001375 elif _lib.BIO_should_write(bio):
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001376 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001377 raise WantWriteError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001378 elif _lib.BIO_should_io_special(bio):
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001379 # TODO: This is untested. I think io_special means the socket
1380 # BIO has a not-yet connected socket.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001381 raise ValueError("BIO_should_io_special")
1382 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001383 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001384 raise ValueError("unknown bio failure")
1385 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001386 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001387 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001388
1389
1390 def bio_read(self, bufsiz):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001391 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001392 When using non-socket connections this function reads the "dirty" data
1393 that would have traveled away on the network.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001394
1395 :param bufsiz: The maximum number of bytes to read
1396 :return: The string read.
1397 """
Jean-Paul Calderone97e041d2013-03-05 21:03:12 -08001398 if self._from_ssl is None:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001399 raise TypeError("Connection sock was not None")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001400
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -05001401 if not isinstance(bufsiz, integer_types):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001402 raise TypeError("bufsiz must be an integer")
1403
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001404 buf = _ffi.new("char[]", bufsiz)
1405 result = _lib.BIO_read(self._from_ssl, buf, bufsiz)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001406 if result <= 0:
1407 self._handle_bio_errors(self._from_ssl, result)
1408
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001409 return _ffi.buffer(buf, result)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001410
1411
1412 def bio_write(self, buf):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001413 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001414 When using non-socket connections this function sends "dirty" data that
1415 would have traveled in on the network.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001416
1417 :param buf: The string to put into the memory BIO.
1418 :return: The number of bytes written
1419 """
Jean-Paul Calderone39a8d592015-04-13 20:49:50 -04001420 buf = _text_to_bytes_and_warn("buf", buf)
Abraham Martine82326c2015-02-04 10:18:10 +00001421
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001422 if self._into_ssl is None:
1423 raise TypeError("Connection sock was not None")
1424
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001425 result = _lib.BIO_write(self._into_ssl, buf, len(buf))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001426 if result <= 0:
1427 self._handle_bio_errors(self._into_ssl, result)
1428 return result
1429
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001430
1431 def renegotiate(self):
1432 """
1433 Renegotiate the session
1434
1435 :return: True if the renegotiation can be started, false otherwise
1436 """
1437
1438 def do_handshake(self):
1439 """
1440 Perform an SSL handshake (usually called after renegotiate() or one of
1441 set_*_state()). This can raise the same exceptions as send and recv.
1442
1443 :return: None.
1444 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001445 result = _lib.SSL_do_handshake(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001446 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001447
1448
1449 def renegotiate_pending(self):
1450 """
1451 Check if there's a renegotiation in progress, it will return false once
1452 a renegotiation is finished.
1453
1454 :return: Whether there's a renegotiation in progress
1455 """
1456
1457 def total_renegotiations(self):
1458 """
1459 Find out the total number of renegotiations.
1460
1461 :return: The number of renegotiations.
1462 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001463 return _lib.SSL_total_renegotiations(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001464
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001465
1466 def connect(self, addr):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001467 """
1468 Connect to remote host and set up client-side SSL
1469
1470 :param addr: A remote address
1471 :return: What the socket's connect method returns
1472 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001473 _lib.SSL_set_connect_state(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001474 return self._socket.connect(addr)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001475
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001476
1477 def connect_ex(self, addr):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001478 """
1479 Connect to remote host and set up client-side SSL. Note that if the socket's
1480 connect_ex method doesn't return 0, SSL won't be initialized.
1481
1482 :param addr: A remove address
1483 :return: What the socket's connect_ex method returns
1484 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001485 connect_ex = self._socket.connect_ex
1486 self.set_connect_state()
1487 return connect_ex(addr)
1488
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001489
1490 def accept(self):
1491 """
1492 Accept incoming connection and set up SSL on it
1493
1494 :return: A (conn,addr) pair where conn is a Connection and addr is an
1495 address
1496 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001497 client, addr = self._socket.accept()
1498 conn = Connection(self._context, client)
1499 conn.set_accept_state()
1500 return (conn, addr)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001501
1502
1503 def bio_shutdown(self):
1504 """
1505 When using non-socket connections this function signals end of
1506 data on the input for this connection.
1507
1508 :return: None
1509 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001510 if self._from_ssl is None:
1511 raise TypeError("Connection sock was not None")
1512
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001513 _lib.BIO_set_mem_eof_return(self._into_ssl, 0)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001514
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001515
1516 def shutdown(self):
1517 """
1518 Send closure alert
1519
1520 :return: True if the shutdown completed successfully (i.e. both sides
1521 have sent closure alerts), false otherwise (i.e. you have to
1522 wait for a ZeroReturnError on a recv() method call
1523 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001524 result = _lib.SSL_shutdown(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001525 if result < 0:
Paul Aurichbff1d1a2015-01-08 08:36:53 -08001526 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001527 elif result > 0:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001528 return True
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001529 else:
1530 return False
1531
1532
1533 def get_cipher_list(self):
1534 """
1535 Get the session cipher list
1536
1537 :return: A list of cipher strings
1538 """
1539 ciphers = []
1540 for i in count():
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001541 result = _lib.SSL_get_cipher_list(self._ssl, i)
1542 if result == _ffi.NULL:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001543 break
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001544 ciphers.append(_native(_ffi.string(result)))
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001545 return ciphers
1546
1547
1548 def get_client_ca_list(self):
1549 """
1550 Get CAs whose certificates are suggested for client authentication.
1551
1552 :return: If this is a server connection, a list of X509Names representing
1553 the acceptable CAs as set by :py:meth:`OpenSSL.SSL.Context.set_client_ca_list` or
1554 :py:meth:`OpenSSL.SSL.Context.add_client_ca`. If this is a client connection,
1555 the list of such X509Names sent by the server, or an empty list if that
1556 has not yet happened.
1557 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001558 ca_names = _lib.SSL_get_client_CA_list(self._ssl)
1559 if ca_names == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001560 # TODO: This is untested.
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001561 return []
1562
1563 result = []
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001564 for i in range(_lib.sk_X509_NAME_num(ca_names)):
1565 name = _lib.sk_X509_NAME_value(ca_names, i)
1566 copy = _lib.X509_NAME_dup(name)
1567 if copy == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001568 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001569 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001570
1571 pyname = X509Name.__new__(X509Name)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001572 pyname._name = _ffi.gc(copy, _lib.X509_NAME_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001573 result.append(pyname)
1574 return result
1575
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001576
1577 def makefile(self):
1578 """
1579 The makefile() method is not implemented, since there is no dup semantics
1580 for SSL connections
1581
Jean-Paul Calderone6749ec22014-04-17 16:30:21 -04001582 :raise: NotImplementedError
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001583 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001584 raise NotImplementedError("Cannot make file object of OpenSSL.SSL.Connection")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001585
1586
1587 def get_app_data(self):
1588 """
1589 Get application data
1590
1591 :return: The application data
1592 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001593 return self._app_data
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001594
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001595
1596 def set_app_data(self, data):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001597 """
1598 Set application data
1599
1600 :param data - The application data
1601 :return: None
1602 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001603 self._app_data = data
1604
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001605
1606 def get_shutdown(self):
1607 """
1608 Get shutdown state
1609
1610 :return: The shutdown state, a bitvector of SENT_SHUTDOWN, RECEIVED_SHUTDOWN.
1611 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001612 return _lib.SSL_get_shutdown(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001613
1614
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001615 def set_shutdown(self, state):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001616 """
1617 Set shutdown state
1618
1619 :param state - bitvector of SENT_SHUTDOWN, RECEIVED_SHUTDOWN.
1620 :return: None
1621 """
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -05001622 if not isinstance(state, integer_types):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001623 raise TypeError("state must be an integer")
1624
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001625 _lib.SSL_set_shutdown(self._ssl, state)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001626
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001627
1628 def state_string(self):
1629 """
1630 Get a verbose state description
1631
1632 :return: A string representing the state
1633 """
1634
1635 def server_random(self):
1636 """
1637 Get a copy of the server hello nonce.
1638
1639 :return: A string representing the state
1640 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001641 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001642 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001643 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001644 self._ssl.s3.server_random,
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001645 _lib.SSL3_RANDOM_SIZE)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001646
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001647
1648 def client_random(self):
1649 """
1650 Get a copy of the client hello nonce.
1651
1652 :return: A string representing the state
1653 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001654 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001655 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001656 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001657 self._ssl.s3.client_random,
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001658 _lib.SSL3_RANDOM_SIZE)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001659
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001660
1661 def master_key(self):
1662 """
1663 Get a copy of the master key.
1664
1665 :return: A string representing the state
1666 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001667 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001668 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001669 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001670 self._ssl.session.master_key,
1671 self._ssl.session.master_key_length)[:]
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001672
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001673
1674 def sock_shutdown(self, *args, **kwargs):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001675 """
1676 See shutdown(2)
1677
1678 :return: What the socket's shutdown() method returns
1679 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001680 return self._socket.shutdown(*args, **kwargs)
1681
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001682
1683 def get_peer_certificate(self):
1684 """
1685 Retrieve the other side's certificate (if any)
1686
1687 :return: The peer's certificate
1688 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001689 cert = _lib.SSL_get_peer_certificate(self._ssl)
1690 if cert != _ffi.NULL:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001691 pycert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001692 pycert._x509 = _ffi.gc(cert, _lib.X509_free)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001693 return pycert
1694 return None
1695
1696
1697 def get_peer_cert_chain(self):
1698 """
1699 Retrieve the other side's certificate (if any)
1700
1701 :return: A list of X509 instances giving the peer's certificate chain,
1702 or None if it does not have one.
1703 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001704 cert_stack = _lib.SSL_get_peer_cert_chain(self._ssl)
1705 if cert_stack == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001706 return None
1707
1708 result = []
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001709 for i in range(_lib.sk_X509_num(cert_stack)):
Jean-Paul Calderone73b15c22013-03-05 18:30:39 -08001710 # TODO could incref instead of dup here
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001711 cert = _lib.X509_dup(_lib.sk_X509_value(cert_stack, i))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001712 pycert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001713 pycert._x509 = _ffi.gc(cert, _lib.X509_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001714 result.append(pycert)
1715 return result
1716
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001717
1718 def want_read(self):
1719 """
1720 Checks if more data has to be read from the transport layer to complete an
1721 operation.
1722
1723 :return: True iff more data has to be read
1724 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001725 return _lib.SSL_want_read(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001726
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001727
1728 def want_write(self):
1729 """
1730 Checks if there is data to write to the transport layer to complete an
1731 operation.
1732
1733 :return: True iff there is data to write
1734 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001735 return _lib.SSL_want_write(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001736
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001737
1738 def set_accept_state(self):
1739 """
1740 Set the connection to work in server mode. The handshake will be handled
1741 automatically by read/write.
1742
1743 :return: None
1744 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001745 _lib.SSL_set_accept_state(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001746
1747
1748 def set_connect_state(self):
1749 """
1750 Set the connection to work in client mode. The handshake will be handled
1751 automatically by read/write.
1752
1753 :return: None
1754 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001755 _lib.SSL_set_connect_state(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001756
1757
1758 def get_session(self):
1759 """
1760 Returns the Session currently used.
1761
1762 @return: An instance of :py:class:`OpenSSL.SSL.Session` or :py:obj:`None` if
1763 no session exists.
1764 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001765 session = _lib.SSL_get1_session(self._ssl)
1766 if session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001767 return None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001768
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001769 pysession = Session.__new__(Session)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001770 pysession._session = _ffi.gc(session, _lib.SSL_SESSION_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001771 return pysession
1772
1773
1774 def set_session(self, session):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001775 """
1776 Set the session to be used when the TLS/SSL connection is established.
1777
1778 :param session: A Session instance representing the session to use.
1779 :returns: None
1780 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001781 if not isinstance(session, Session):
1782 raise TypeError("session must be a Session instance")
1783
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001784 result = _lib.SSL_set_session(self._ssl, session._session)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001785 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001786 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001787
Jean-Paul Calderonedbd76272014-03-29 18:09:40 -04001788
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001789 def _get_finished_message(self, function):
1790 """
1791 Helper to implement :py:meth:`get_finished` and
1792 :py:meth:`get_peer_finished`.
1793
1794 :param function: Either :py:data:`SSL_get_finished`: or
1795 :py:data:`SSL_get_peer_finished`.
1796
1797 :return: :py:data:`None` if the desired message has not yet been
1798 received, otherwise the contents of the message.
1799 :rtype: :py:class:`bytes` or :py:class:`NoneType`
1800 """
Jean-Paul Calderone01af9042014-03-30 11:40:42 -04001801 # The OpenSSL documentation says nothing about what might happen if the
1802 # count argument given is zero. Specifically, it doesn't say whether
1803 # the output buffer may be NULL in that case or not. Inspection of the
1804 # implementation reveals that it calls memcpy() unconditionally.
1805 # Section 7.1.4, paragraph 1 of the C standard suggests that
1806 # memcpy(NULL, source, 0) is not guaranteed to produce defined (let
1807 # alone desirable) behavior (though it probably does on just about
1808 # every implementation...)
1809 #
1810 # Allocate a tiny buffer to pass in (instead of just passing NULL as
1811 # one might expect) for the initial call so as to be safe against this
1812 # potentially undefined behavior.
1813 empty = _ffi.new("char[]", 0)
1814 size = function(self._ssl, empty, 0)
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001815 if size == 0:
1816 # No Finished message so far.
1817 return None
1818
1819 buf = _ffi.new("char[]", size)
1820 function(self._ssl, buf, size)
1821 return _ffi.buffer(buf, size)[:]
1822
1823
Fedor Brunner5747b932014-03-05 14:22:34 +01001824 def get_finished(self):
1825 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001826 Obtain the latest `handshake finished` message sent to the peer.
Fedor Brunner5747b932014-03-05 14:22:34 +01001827
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001828 :return: The contents of the message or :py:obj:`None` if the TLS
1829 handshake has not yet completed.
1830 :rtype: :py:class:`bytes` or :py:class:`NoneType`
Fedor Brunner5747b932014-03-05 14:22:34 +01001831 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001832 return self._get_finished_message(_lib.SSL_get_finished)
1833
Fedor Brunner5747b932014-03-05 14:22:34 +01001834
1835 def get_peer_finished(self):
1836 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001837 Obtain the latest `handshake finished` message received from the peer.
Fedor Brunner5747b932014-03-05 14:22:34 +01001838
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001839 :return: The contents of the message or :py:obj:`None` if the TLS
1840 handshake has not yet completed.
1841 :rtype: :py:class:`bytes` or :py:class:`NoneType`
Fedor Brunner5747b932014-03-05 14:22:34 +01001842 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001843 return self._get_finished_message(_lib.SSL_get_peer_finished)
Fedor Brunner5747b932014-03-05 14:22:34 +01001844
Jean-Paul Calderone7c556ef2014-03-30 10:45:00 -04001845
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001846 def get_cipher_name(self):
1847 """
1848 Obtain the name of the currently used cipher.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001849
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001850 :returns: The name of the currently used cipher or :py:obj:`None`
1851 if no connection has been established.
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001852 :rtype: :py:class:`unicode` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001853 """
1854 cipher = _lib.SSL_get_current_cipher(self._ssl)
1855 if cipher == _ffi.NULL:
1856 return None
1857 else:
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001858 name = _ffi.string(_lib.SSL_CIPHER_get_name(cipher))
1859 return name.decode("utf-8")
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001860
Jean-Paul Calderonedbd76272014-03-29 18:09:40 -04001861
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001862 def get_cipher_bits(self):
1863 """
1864 Obtain the number of secret bits of the currently used cipher.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001865
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001866 :returns: The number of secret bits of the currently used cipher
1867 or :py:obj:`None` if no connection has been established.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001868 :rtype: :py:class:`int` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001869 """
1870 cipher = _lib.SSL_get_current_cipher(self._ssl)
1871 if cipher == _ffi.NULL:
1872 return None
1873 else:
1874 return _lib.SSL_CIPHER_get_bits(cipher, _ffi.NULL)
1875
Jean-Paul Calderonedbd76272014-03-29 18:09:40 -04001876
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001877 def get_cipher_version(self):
1878 """
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001879 Obtain the protocol version of the currently used cipher.
1880
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001881 :returns: The protocol name of the currently used cipher
1882 or :py:obj:`None` if no connection has been established.
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001883 :rtype: :py:class:`unicode` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001884 """
1885 cipher = _lib.SSL_get_current_cipher(self._ssl)
1886 if cipher == _ffi.NULL:
1887 return None
1888 else:
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001889 version =_ffi.string(_lib.SSL_CIPHER_get_version(cipher))
1890 return version.decode("utf-8")
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001891
Cory Benfield10b277f2015-04-13 17:12:42 -04001892
Jim Shaverabff1882015-05-27 09:15:55 -04001893 def get_protocol_version_name(self):
Jim Shaverba65e662015-04-26 12:23:40 -04001894 """
1895 Obtain the protocol version of the current connection.
1896
1897 :returns: The TLS version of the current connection, for example
Jim Shaver58d25732015-05-28 11:52:32 -04001898 the value for TLS 1.2 would be ``TLSv1.2``or ``Unknown``
Jim Shaverb5b6b0e2015-05-28 16:47:36 -04001899 for connections that were not successfully established.
Jim Shaver58d25732015-05-28 11:52:32 -04001900 :rtype: :py:class:`unicode`
Jim Shaverba65e662015-04-26 12:23:40 -04001901 """
Jim Shaverd1c896e2015-05-27 17:50:21 -04001902 version = _ffi.string(_lib.SSL_get_version(self._ssl))
Jim Shaver58d25732015-05-28 11:52:32 -04001903 return version.decode("utf-8")
Jim Shaverb2967922015-04-26 23:58:52 -04001904
Jim Shaverba65e662015-04-26 12:23:40 -04001905
Jim Shaver208438c2015-05-28 09:52:38 -04001906 def get_protocol_version(self):
1907 """
1908 Obtain the protocol version of the current connection.
1909
1910 :returns: The TLS version of the current connection, for example
1911 the value for TLS 1 would be 0x769.
1912 :rtype: :py:class:`int`
1913 """
1914 version = _lib.SSL_version(self._ssl)
1915 return version
1916
1917
Cory Benfield10b277f2015-04-13 17:12:42 -04001918 @_requires_npn
Cory Benfield84a121e2014-03-31 20:30:25 +01001919 def get_next_proto_negotiated(self):
1920 """
1921 Get the protocol that was negotiated by NPN.
1922 """
1923 data = _ffi.new("unsigned char **")
1924 data_len = _ffi.new("unsigned int *")
1925
1926 _lib.SSL_get0_next_proto_negotiated(self._ssl, data, data_len)
1927
Cory Benfieldcd010f62014-05-15 19:00:27 +01001928 return _ffi.buffer(data[0], data_len[0])[:]
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001929
Hynek Schlawackc3717b92015-04-18 12:13:16 +02001930
Cory Benfield7907e332015-04-13 17:18:25 -04001931 @_requires_alpn
Cory Benfield12eae892014-06-07 15:42:56 +01001932 def set_alpn_protos(self, protos):
1933 """
Cory Benfielde8e9c382015-04-11 17:33:48 -04001934 Specify the client's ALPN protocol list.
1935
1936 These protocols are offered to the server during protocol negotiation.
Cory Benfield12eae892014-06-07 15:42:56 +01001937
1938 :param protos: A list of the protocols to be offered to the server.
1939 This list should be a Python list of bytestrings representing the
1940 protocols to offer, e.g. ``[b'http/1.1', b'spdy/2']``.
1941 """
1942 # Take the list of protocols and join them together, prefixing them
1943 # with their lengths.
1944 protostr = b''.join(
1945 chain.from_iterable((int2byte(len(p)), p) for p in protos)
1946 )
1947
1948 # Build a C string from the list. We don't need to save this off
1949 # because OpenSSL immediately copies the data out.
1950 input_str = _ffi.new("unsigned char[]", protostr)
Cory Benfield9c1979a2015-04-12 08:51:52 -04001951 input_str_len = _ffi.cast("unsigned", len(protostr))
1952 _lib.SSL_set_alpn_protos(self._ssl, input_str, input_str_len)
Cory Benfield12eae892014-06-07 15:42:56 +01001953
1954
1955 def get_alpn_proto_negotiated(self):
Cory Benfield222f30e2015-04-13 18:10:21 -04001956 """
1957 Get the protocol that was negotiated by ALPN.
1958 """
Cory Benfield3e619292015-04-13 12:34:51 -04001959 if not _lib.Cryptography_HAS_ALPN:
1960 raise NotImplementedError("ALPN not available")
1961
Cory Benfield12eae892014-06-07 15:42:56 +01001962 data = _ffi.new("unsigned char **")
1963 data_len = _ffi.new("unsigned int *")
1964
1965 _lib.SSL_get0_alpn_selected(self._ssl, data, data_len)
1966
Cory Benfielde8e9c382015-04-11 17:33:48 -04001967 if not data_len:
1968 return b''
1969
Cory Benfield12eae892014-06-07 15:42:56 +01001970 return _ffi.buffer(data[0], data_len[0])[:]
1971
1972
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001973
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001974ConnectionType = Connection
Jean-Paul Calderone11ed8e82014-01-18 10:21:50 -05001975
Jean-Paul Calderonefab157b2014-01-18 11:21:38 -05001976# This is similar to the initialization calls at the end of OpenSSL/crypto.py
1977# but is exercised mostly by the Context initializer.
Jean-Paul Calderone11ed8e82014-01-18 10:21:50 -05001978_lib.SSL_library_init()