blob: cfe705ab4b59c85ceafbeef61e1b9a981dc90da1 [file] [log] [blame]
Konstantinos Koukopoulos541150d2014-01-31 01:00:19 +02001from sys import platform
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05002from functools import wraps, partial
Cory Benfieldbe3e7b82014-05-10 09:48:55 +01003from itertools import count, chain
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08004from weakref import WeakValueDictionary
5from errno import errorcode
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -08006
Jean-Paul Calderone63eab692014-01-18 10:19:56 -05007from six import text_type as _text_type
Cory Benfield63759dc2015-04-12 08:57:03 -04008from six import binary_type as _binary_type
Konstantinos Koukopoulosc8b13ea2014-01-28 00:21:50 -08009from six import integer_types as integer_types
Cory Benfieldcd010f62014-05-15 19:00:27 +010010from six import int2byte, indexbytes
Jean-Paul Calderone63eab692014-01-18 10:19:56 -050011
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -050012from OpenSSL._util import (
13 ffi as _ffi,
14 lib as _lib,
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -050015 exception_from_error_queue as _exception_from_error_queue,
Jean-Paul Calderone55f9e882015-04-12 09:31:03 -040016 native as _native,
Jean-Paul Calderone39a8d592015-04-13 20:49:50 -040017 text_to_bytes_and_warn as _text_to_bytes_and_warn,
Jean-Paul Calderone55f9e882015-04-12 09:31:03 -040018 path_string as _path_string,
Jean-Paul Calderone00f84eb2015-04-13 12:47:21 -040019 UNSPECIFIED as _UNSPECIFIED,
Jean-Paul Calderone55f9e882015-04-12 09:31:03 -040020)
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080021
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -080022from OpenSSL.crypto import (
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -050023 FILETYPE_PEM, _PassphraseHelper, PKey, X509Name, X509, X509Store)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -080024
Jean-Paul Calderone8fb53182013-12-30 08:35:49 -050025try:
26 _memoryview = memoryview
27except NameError:
28 class _memoryview(object):
29 pass
30
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +020031try:
32 _buffer = buffer
33except NameError:
34 class _buffer(object):
35 pass
36
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050037OPENSSL_VERSION_NUMBER = _lib.OPENSSL_VERSION_NUMBER
38SSLEAY_VERSION = _lib.SSLEAY_VERSION
39SSLEAY_CFLAGS = _lib.SSLEAY_CFLAGS
40SSLEAY_PLATFORM = _lib.SSLEAY_PLATFORM
41SSLEAY_DIR = _lib.SSLEAY_DIR
42SSLEAY_BUILT_ON = _lib.SSLEAY_BUILT_ON
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080043
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050044SENT_SHUTDOWN = _lib.SSL_SENT_SHUTDOWN
45RECEIVED_SHUTDOWN = _lib.SSL_RECEIVED_SHUTDOWN
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080046
47SSLv2_METHOD = 1
48SSLv3_METHOD = 2
49SSLv23_METHOD = 3
50TLSv1_METHOD = 4
Jean-Paul Calderone56bff942013-11-03 11:30:43 -050051TLSv1_1_METHOD = 5
52TLSv1_2_METHOD = 6
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080053
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050054OP_NO_SSLv2 = _lib.SSL_OP_NO_SSLv2
55OP_NO_SSLv3 = _lib.SSL_OP_NO_SSLv3
56OP_NO_TLSv1 = _lib.SSL_OP_NO_TLSv1
Jean-Paul Calderonebe2bb422013-12-29 07:34:08 -050057
58OP_NO_TLSv1_1 = getattr(_lib, "SSL_OP_NO_TLSv1_1", 0)
59OP_NO_TLSv1_2 = getattr(_lib, "SSL_OP_NO_TLSv1_2", 0)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -080060
Jean-Paul Calderone0d7e8a12014-01-08 16:54:13 -050061try:
62 MODE_RELEASE_BUFFERS = _lib.SSL_MODE_RELEASE_BUFFERS
63except AttributeError:
64 pass
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080065
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050066OP_SINGLE_DH_USE = _lib.SSL_OP_SINGLE_DH_USE
67OP_EPHEMERAL_RSA = _lib.SSL_OP_EPHEMERAL_RSA
68OP_MICROSOFT_SESS_ID_BUG = _lib.SSL_OP_MICROSOFT_SESS_ID_BUG
69OP_NETSCAPE_CHALLENGE_BUG = _lib.SSL_OP_NETSCAPE_CHALLENGE_BUG
70OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG = _lib.SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG
71OP_SSLREF2_REUSE_CERT_TYPE_BUG = _lib.SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG
72OP_MICROSOFT_BIG_SSLV3_BUFFER = _lib.SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER
Jean-Paul Calderone0d7e8a12014-01-08 16:54:13 -050073try:
74 OP_MSIE_SSLV2_RSA_PADDING = _lib.SSL_OP_MSIE_SSLV2_RSA_PADDING
75except AttributeError:
76 pass
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050077OP_SSLEAY_080_CLIENT_DH_BUG = _lib.SSL_OP_SSLEAY_080_CLIENT_DH_BUG
78OP_TLS_D5_BUG = _lib.SSL_OP_TLS_D5_BUG
79OP_TLS_BLOCK_PADDING_BUG = _lib.SSL_OP_TLS_BLOCK_PADDING_BUG
80OP_DONT_INSERT_EMPTY_FRAGMENTS = _lib.SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
81OP_CIPHER_SERVER_PREFERENCE = _lib.SSL_OP_CIPHER_SERVER_PREFERENCE
82OP_TLS_ROLLBACK_BUG = _lib.SSL_OP_TLS_ROLLBACK_BUG
83OP_PKCS1_CHECK_1 = _lib.SSL_OP_PKCS1_CHECK_1
84OP_PKCS1_CHECK_2 = _lib.SSL_OP_PKCS1_CHECK_2
85OP_NETSCAPE_CA_DN_BUG = _lib.SSL_OP_NETSCAPE_CA_DN_BUG
86OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG= _lib.SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG
Jean-Paul Calderonec1780342014-01-08 16:59:03 -050087try:
88 OP_NO_COMPRESSION = _lib.SSL_OP_NO_COMPRESSION
89except AttributeError:
90 pass
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -080091
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050092OP_NO_QUERY_MTU = _lib.SSL_OP_NO_QUERY_MTU
93OP_COOKIE_EXCHANGE = _lib.SSL_OP_COOKIE_EXCHANGE
Arturo Filastò5f8c7a82014-03-09 20:01:25 +010094try:
95 OP_NO_TICKET = _lib.SSL_OP_NO_TICKET
96except AttributeError:
97 pass
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -080098
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050099OP_ALL = _lib.SSL_OP_ALL
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -0800100
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500101VERIFY_PEER = _lib.SSL_VERIFY_PEER
102VERIFY_FAIL_IF_NO_PEER_CERT = _lib.SSL_VERIFY_FAIL_IF_NO_PEER_CERT
103VERIFY_CLIENT_ONCE = _lib.SSL_VERIFY_CLIENT_ONCE
104VERIFY_NONE = _lib.SSL_VERIFY_NONE
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -0800105
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500106SESS_CACHE_OFF = _lib.SSL_SESS_CACHE_OFF
107SESS_CACHE_CLIENT = _lib.SSL_SESS_CACHE_CLIENT
108SESS_CACHE_SERVER = _lib.SSL_SESS_CACHE_SERVER
109SESS_CACHE_BOTH = _lib.SSL_SESS_CACHE_BOTH
110SESS_CACHE_NO_AUTO_CLEAR = _lib.SSL_SESS_CACHE_NO_AUTO_CLEAR
111SESS_CACHE_NO_INTERNAL_LOOKUP = _lib.SSL_SESS_CACHE_NO_INTERNAL_LOOKUP
112SESS_CACHE_NO_INTERNAL_STORE = _lib.SSL_SESS_CACHE_NO_INTERNAL_STORE
113SESS_CACHE_NO_INTERNAL = _lib.SSL_SESS_CACHE_NO_INTERNAL
Jean-Paul Calderoned39a3f62013-03-04 12:23:51 -0800114
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500115SSL_ST_CONNECT = _lib.SSL_ST_CONNECT
116SSL_ST_ACCEPT = _lib.SSL_ST_ACCEPT
117SSL_ST_MASK = _lib.SSL_ST_MASK
118SSL_ST_INIT = _lib.SSL_ST_INIT
119SSL_ST_BEFORE = _lib.SSL_ST_BEFORE
120SSL_ST_OK = _lib.SSL_ST_OK
121SSL_ST_RENEGOTIATE = _lib.SSL_ST_RENEGOTIATE
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800122
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500123SSL_CB_LOOP = _lib.SSL_CB_LOOP
124SSL_CB_EXIT = _lib.SSL_CB_EXIT
125SSL_CB_READ = _lib.SSL_CB_READ
126SSL_CB_WRITE = _lib.SSL_CB_WRITE
127SSL_CB_ALERT = _lib.SSL_CB_ALERT
128SSL_CB_READ_ALERT = _lib.SSL_CB_READ_ALERT
129SSL_CB_WRITE_ALERT = _lib.SSL_CB_WRITE_ALERT
130SSL_CB_ACCEPT_LOOP = _lib.SSL_CB_ACCEPT_LOOP
131SSL_CB_ACCEPT_EXIT = _lib.SSL_CB_ACCEPT_EXIT
132SSL_CB_CONNECT_LOOP = _lib.SSL_CB_CONNECT_LOOP
133SSL_CB_CONNECT_EXIT = _lib.SSL_CB_CONNECT_EXIT
134SSL_CB_HANDSHAKE_START = _lib.SSL_CB_HANDSHAKE_START
135SSL_CB_HANDSHAKE_DONE = _lib.SSL_CB_HANDSHAKE_DONE
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800136
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500137class Error(Exception):
Jean-Paul Calderone511cde02013-12-29 10:31:13 -0500138 """
139 An error occurred in an `OpenSSL.SSL` API.
140 """
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500141
142
143
144_raise_current_error = partial(_exception_from_error_queue, Error)
145
146
147class WantReadError(Error):
148 pass
149
150
151
152class WantWriteError(Error):
153 pass
154
155
156
157class WantX509LookupError(Error):
158 pass
159
160
161
162class ZeroReturnError(Error):
163 pass
164
165
166
167class SysCallError(Error):
168 pass
169
170
Cory Benfield0ea76e72015-03-22 09:05:28 +0000171class _CallbackExceptionHelper(object):
172 """
173 A base class for wrapper classes that allow for intelligent exception
174 handling in OpenSSL callbacks.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500175
Jean-Paul Calderone1b172982015-03-22 19:37:11 -0400176 :ivar list _problems: Any exceptions that occurred while executing in a
177 context where they could not be raised in the normal way. Typically
178 this is because OpenSSL has called into some Python code and requires a
179 return value. The exceptions are saved to be raised later when it is
180 possible to do so.
Cory Benfield0ea76e72015-03-22 09:05:28 +0000181 """
Jean-Paul Calderone09540d72015-03-22 19:37:20 -0400182 def __init__(self):
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800183 self._problems = []
184
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800185
Cory Benfield0ea76e72015-03-22 09:05:28 +0000186 def raise_if_problem(self):
Jean-Paul Calderone1b172982015-03-22 19:37:11 -0400187 """
188 Raise an exception from the OpenSSL error queue or that was previously
189 captured whe running a callback.
190 """
Cory Benfield0ea76e72015-03-22 09:05:28 +0000191 if self._problems:
192 try:
193 _raise_current_error()
194 except Error:
195 pass
196 raise self._problems.pop(0)
197
198
199class _VerifyHelper(_CallbackExceptionHelper):
Jean-Paul Calderone1b172982015-03-22 19:37:11 -0400200 """
201 Wrap a callback such that it can be used as a certificate verification
202 callback.
203 """
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800204 def __init__(self, callback):
Jean-Paul Calderone837f4032015-03-22 17:38:28 -0400205 _CallbackExceptionHelper.__init__(self)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800206
207 @wraps(callback)
208 def wrapper(ok, store_ctx):
209 cert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500210 cert._x509 = _lib.X509_STORE_CTX_get_current_cert(store_ctx)
211 error_number = _lib.X509_STORE_CTX_get_error(store_ctx)
212 error_depth = _lib.X509_STORE_CTX_get_error_depth(store_ctx)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800213
Jean-Paul Calderone6a8cd112014-04-02 21:09:08 -0400214 index = _lib.SSL_get_ex_data_X509_STORE_CTX_idx()
215 ssl = _lib.X509_STORE_CTX_get_ex_data(store_ctx, index)
216 connection = Connection._reverse_mapping[ssl]
217
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800218 try:
219 result = callback(connection, cert, error_number, error_depth, ok)
220 except Exception as e:
221 self._problems.append(e)
222 return 0
223 else:
224 if result:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500225 _lib.X509_STORE_CTX_set_error(store_ctx, _lib.X509_V_OK)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800226 return 1
227 else:
228 return 0
229
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500230 self.callback = _ffi.callback(
231 "int (*)(int, X509_STORE_CTX *)", wrapper)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800232
233
Cory Benfield0ea76e72015-03-22 09:05:28 +0000234class _NpnAdvertiseHelper(_CallbackExceptionHelper):
Jean-Paul Calderone1b172982015-03-22 19:37:11 -0400235 """
236 Wrap a callback such that it can be used as an NPN advertisement callback.
237 """
Cory Benfield0ea76e72015-03-22 09:05:28 +0000238 def __init__(self, callback):
Jean-Paul Calderone837f4032015-03-22 17:38:28 -0400239 _CallbackExceptionHelper.__init__(self)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800240
Cory Benfield0ea76e72015-03-22 09:05:28 +0000241 @wraps(callback)
242 def wrapper(ssl, out, outlen, arg):
243 try:
244 conn = Connection._reverse_mapping[ssl]
245 protos = callback(conn)
246
247 # Join the protocols into a Python bytestring, length-prefixing
248 # each element.
249 protostr = b''.join(
250 chain.from_iterable((int2byte(len(p)), p) for p in protos)
251 )
252
253 # Save our callback arguments on the connection object. This is
254 # done to make sure that they don't get freed before OpenSSL
255 # uses them. Then, return them appropriately in the output
256 # parameters.
257 conn._npn_advertise_callback_args = [
258 _ffi.new("unsigned int *", len(protostr)),
259 _ffi.new("unsigned char[]", protostr),
260 ]
261 outlen[0] = conn._npn_advertise_callback_args[0][0]
262 out[0] = conn._npn_advertise_callback_args[1]
263 return 0
264 except Exception as e:
265 self._problems.append(e)
266 return 2 # SSL_TLSEXT_ERR_ALERT_FATAL
267
268 self.callback = _ffi.callback(
269 "int (*)(SSL *, const unsigned char **, unsigned int *, void *)",
270 wrapper
271 )
272
273
274class _NpnSelectHelper(_CallbackExceptionHelper):
Jean-Paul Calderone1b172982015-03-22 19:37:11 -0400275 """
276 Wrap a callback such that it can be used as an NPN selection callback.
277 """
Cory Benfield0ea76e72015-03-22 09:05:28 +0000278 def __init__(self, callback):
Jean-Paul Calderone837f4032015-03-22 17:38:28 -0400279 _CallbackExceptionHelper.__init__(self)
Cory Benfield0ea76e72015-03-22 09:05:28 +0000280
281 @wraps(callback)
282 def wrapper(ssl, out, outlen, in_, inlen, arg):
283 try:
284 conn = Connection._reverse_mapping[ssl]
285
286 # The string passed to us is actually made up of multiple
287 # length-prefixed bytestrings. We need to split that into a
288 # list.
289 instr = _ffi.buffer(in_, inlen)[:]
290 protolist = []
291 while instr:
292 l = indexbytes(instr, 0)
293 proto = instr[1:l+1]
294 protolist.append(proto)
295 instr = instr[l+1:]
296
297 # Call the callback
298 outstr = callback(conn, protolist)
299
300 # Save our callback arguments on the connection object. This is
301 # done to make sure that they don't get freed before OpenSSL
302 # uses them. Then, return them appropriately in the output
303 # parameters.
304 conn._npn_select_callback_args = [
305 _ffi.new("unsigned char *", len(outstr)),
306 _ffi.new("unsigned char[]", outstr),
307 ]
308 outlen[0] = conn._npn_select_callback_args[0][0]
309 out[0] = conn._npn_select_callback_args[1]
310 return 0
311 except Exception as e:
312 self._problems.append(e)
313 return 2 # SSL_TLSEXT_ERR_ALERT_FATAL
314
315 self.callback = _ffi.callback(
316 "int (*)(SSL *, unsigned char **, unsigned char *, "
317 "const unsigned char *, unsigned int, void *)",
318 wrapper
319 )
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800320
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800321
Cory Benfield9da5ffb2015-04-13 17:20:14 -0400322class _ALPNSelectHelper(_CallbackExceptionHelper):
Cory Benfieldf1177e72015-04-12 09:11:49 -0400323 """
324 Wrap a callback such that it can be used as an ALPN selection callback.
325 """
326 def __init__(self, callback):
327 _CallbackExceptionHelper.__init__(self)
328
329 @wraps(callback)
330 def wrapper(ssl, out, outlen, in_, inlen, arg):
331 try:
332 conn = Connection._reverse_mapping[ssl]
333
334 # The string passed to us is made up of multiple
335 # length-prefixed bytestrings. We need to split that into a
336 # list.
337 instr = _ffi.buffer(in_, inlen)[:]
338 protolist = []
339 while instr:
Cory Benfield93134db2015-04-13 17:22:13 -0400340 encoded_len = indexbytes(instr, 0)
341 proto = instr[1:encoded_len + 1]
Cory Benfieldf1177e72015-04-12 09:11:49 -0400342 protolist.append(proto)
Cory Benfield93134db2015-04-13 17:22:13 -0400343 instr = instr[encoded_len + 1:]
Cory Benfieldf1177e72015-04-12 09:11:49 -0400344
345 # Call the callback
346 outstr = callback(conn, protolist)
347
348 if not isinstance(outstr, _binary_type):
349 raise TypeError("ALPN callback must return a bytestring.")
350
351 # Save our callback arguments on the connection object to make
352 # sure that they don't get freed before OpenSSL can use them.
353 # Then, return them in the appropriate output parameters.
354 conn._alpn_select_callback_args = [
355 _ffi.new("unsigned char *", len(outstr)),
356 _ffi.new("unsigned char[]", outstr),
357 ]
358 outlen[0] = conn._alpn_select_callback_args[0][0]
359 out[0] = conn._alpn_select_callback_args[1]
360 return 0
361 except Exception as e:
362 self._problems.append(e)
363 return 2 # SSL_TLSEXT_ERR_ALERT_FATAL
364
365 self.callback = _ffi.callback(
366 "int (*)(SSL *, unsigned char **, unsigned char *, "
367 "const unsigned char *, unsigned int, void *)",
368 wrapper
369 )
370
371
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800372def _asFileDescriptor(obj):
373 fd = None
Konstantinos Koukopoulosc8b13ea2014-01-28 00:21:50 -0800374 if not isinstance(obj, integer_types):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800375 meth = getattr(obj, "fileno", None)
376 if meth is not None:
377 obj = meth()
378
Konstantinos Koukopoulosc8b13ea2014-01-28 00:21:50 -0800379 if isinstance(obj, integer_types):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800380 fd = obj
381
Konstantinos Koukopoulosc8b13ea2014-01-28 00:21:50 -0800382 if not isinstance(fd, integer_types):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800383 raise TypeError("argument must be an int, or have a fileno() method.")
384 elif fd < 0:
385 raise ValueError(
386 "file descriptor cannot be a negative integer (%i)" % (fd,))
387
388 return fd
389
390
391
Jean-Paul Calderoned39a3f62013-03-04 12:23:51 -0800392def SSLeay_version(type):
393 """
394 Return a string describing the version of OpenSSL in use.
395
396 :param type: One of the SSLEAY_ constants defined in this module.
397 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500398 return _ffi.string(_lib.SSLeay_version(type))
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800399
400
401
Cory Benfield7907e332015-04-13 17:18:25 -0400402def _requires_alpn(func):
Cory Benfield9d80a762015-04-13 17:47:33 -0400403 """
404 Wraps any function that requires ALPN support in OpenSSL, ensuring that
405 NotImplementedError is raised if ALPN support is not present.
406 """
Cory Benfield7907e332015-04-13 17:18:25 -0400407 @wraps(func)
408 def wrapper(*args, **kwargs):
409 if not _lib.Cryptography_HAS_ALPN:
410 raise NotImplementedError("ALPN not available.")
411
412 return func(*args, **kwargs)
413
414 return wrapper
415
416
417
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800418class Session(object):
419 pass
420
421
422
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800423class Context(object):
424 """
425 :py:obj:`OpenSSL.SSL.Context` instances define the parameters for setting up
426 new SSL connections.
427 """
428 _methods = {
Andrew Dunhamec84a0a2014-02-24 12:41:37 -0800429 SSLv2_METHOD: "SSLv2_method",
Jean-Paul Calderonebe2bb422013-12-29 07:34:08 -0500430 SSLv3_METHOD: "SSLv3_method",
431 SSLv23_METHOD: "SSLv23_method",
432 TLSv1_METHOD: "TLSv1_method",
433 TLSv1_1_METHOD: "TLSv1_1_method",
434 TLSv1_2_METHOD: "TLSv1_2_method",
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800435 }
Jean-Paul Calderonebe2bb422013-12-29 07:34:08 -0500436 _methods = dict(
437 (identifier, getattr(_lib, name))
438 for (identifier, name) in _methods.items()
439 if getattr(_lib, name, None) is not None)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800440
Jean-Paul Calderone63157872013-03-20 16:43:38 -0700441
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800442 def __init__(self, method):
443 """
444 :param method: One of SSLv2_METHOD, SSLv3_METHOD, SSLv23_METHOD, or
445 TLSv1_METHOD.
446 """
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -0500447 if not isinstance(method, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800448 raise TypeError("method must be an integer")
449
450 try:
451 method_func = self._methods[method]
452 except KeyError:
453 raise ValueError("No such protocol")
454
455 method_obj = method_func()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500456 if method_obj == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500457 # TODO: This is untested.
458 _raise_current_error()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800459
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500460 context = _lib.SSL_CTX_new(method_obj)
461 if context == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500462 # TODO: This is untested.
463 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500464 context = _ffi.gc(context, _lib.SSL_CTX_free)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800465
466 self._context = context
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800467 self._passphrase_helper = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800468 self._passphrase_callback = None
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800469 self._passphrase_userdata = None
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800470 self._verify_helper = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800471 self._verify_callback = None
472 self._info_callback = None
473 self._tlsext_servername_callback = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800474 self._app_data = None
Cory Benfield0ea76e72015-03-22 09:05:28 +0000475 self._npn_advertise_helper = None
Cory Benfield84a121e2014-03-31 20:30:25 +0100476 self._npn_advertise_callback = None
Cory Benfield0ea76e72015-03-22 09:05:28 +0000477 self._npn_select_helper = None
Cory Benfield84a121e2014-03-31 20:30:25 +0100478 self._npn_select_callback = None
Cory Benfieldf1177e72015-04-12 09:11:49 -0400479 self._alpn_select_helper = None
Cory Benfield12eae892014-06-07 15:42:56 +0100480 self._alpn_select_callback = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800481
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -0800482 # SSL_CTX_set_app_data(self->ctx, self);
483 # SSL_CTX_set_mode(self->ctx, SSL_MODE_ENABLE_PARTIAL_WRITE |
484 # SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
485 # SSL_MODE_AUTO_RETRY);
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500486 self.set_mode(_lib.SSL_MODE_ENABLE_PARTIAL_WRITE)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800487
488
489 def load_verify_locations(self, cafile, capath=None):
490 """
491 Let SSL know where we can find trusted certificates for the certificate
492 chain
493
Jean-Paul Calderone55f9e882015-04-12 09:31:03 -0400494 :param cafile: In which file we can find the certificates (``bytes`` or
495 ``unicode``).
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800496 :param capath: In which directory we can find the certificates
Jean-Paul Calderone55f9e882015-04-12 09:31:03 -0400497 (``bytes`` or ``unicode``).
498
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800499 :return: None
500 """
501 if cafile is None:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500502 cafile = _ffi.NULL
Jean-Paul Calderone55f9e882015-04-12 09:31:03 -0400503 else:
504 cafile = _path_string(cafile)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800505
506 if capath is None:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500507 capath = _ffi.NULL
Jean-Paul Calderone55f9e882015-04-12 09:31:03 -0400508 else:
509 capath = _path_string(capath)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800510
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500511 load_result = _lib.SSL_CTX_load_verify_locations(self._context, cafile, capath)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800512 if not load_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500513 _raise_current_error()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800514
515
516 def _wrap_callback(self, callback):
517 @wraps(callback)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800518 def wrapper(size, verify, userdata):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800519 return callback(size, verify, self._passphrase_userdata)
520 return _PassphraseHelper(
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800521 FILETYPE_PEM, wrapper, more_args=True, truncate=True)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800522
523
524 def set_passwd_cb(self, callback, userdata=None):
525 """
526 Set the passphrase callback
527
528 :param callback: The Python callback to use
529 :param userdata: (optional) A Python object which will be given as
530 argument to the callback
531 :return: None
532 """
533 if not callable(callback):
534 raise TypeError("callback must be callable")
535
536 self._passphrase_helper = self._wrap_callback(callback)
537 self._passphrase_callback = self._passphrase_helper.callback
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500538 _lib.SSL_CTX_set_default_passwd_cb(
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800539 self._context, self._passphrase_callback)
540 self._passphrase_userdata = userdata
541
542
543 def set_default_verify_paths(self):
544 """
545 Use the platform-specific CA certificate locations
546
547 :return: None
548 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500549 set_result = _lib.SSL_CTX_set_default_verify_paths(self._context)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800550 if not set_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500551 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500552 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800553
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800554
555 def use_certificate_chain_file(self, certfile):
556 """
557 Load a certificate chain from a file
558
Jean-Paul Calderoneb6f8a792015-04-13 10:10:06 -0400559 :param certfile: The name of the certificate chain file (``bytes`` or
560 ``unicode``).
561
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800562 :return: None
563 """
Jean-Paul Calderoneaac43a32015-04-12 09:51:21 -0400564 certfile = _path_string(certfile)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800565
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500566 result = _lib.SSL_CTX_use_certificate_chain_file(self._context, certfile)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800567 if not result:
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
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800571 def use_certificate_file(self, certfile, filetype=FILETYPE_PEM):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800572 """
573 Load a certificate from a file
574
Jean-Paul Calderoneb6f8a792015-04-13 10:10:06 -0400575 :param certfile: The name of the certificate file (``bytes`` or
576 ``unicode``).
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800577 :param filetype: (optional) The encoding of the file, default is PEM
Jean-Paul Calderoneb6f8a792015-04-13 10:10:06 -0400578
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800579 :return: None
580 """
Jean-Paul Calderoned57a7b62015-04-12 09:57:36 -0400581 certfile = _path_string(certfile)
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -0500582 if not isinstance(filetype, integer_types):
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800583 raise TypeError("filetype must be an integer")
584
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500585 use_result = _lib.SSL_CTX_use_certificate_file(self._context, certfile, filetype)
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800586 if not use_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500587 _raise_current_error()
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800588
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800589
590 def use_certificate(self, cert):
591 """
592 Load a certificate from a X509 object
593
594 :param cert: The X509 object
595 :return: None
596 """
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800597 if not isinstance(cert, X509):
598 raise TypeError("cert must be an X509 instance")
599
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500600 use_result = _lib.SSL_CTX_use_certificate(self._context, cert._x509)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800601 if not use_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500602 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800603
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800604
605 def add_extra_chain_cert(self, certobj):
606 """
607 Add certificate to chain
608
609 :param certobj: The X509 certificate object to add to the chain
610 :return: None
611 """
612 if not isinstance(certobj, X509):
613 raise TypeError("certobj must be an X509 instance")
614
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500615 copy = _lib.X509_dup(certobj._x509)
616 add_result = _lib.SSL_CTX_add_extra_chain_cert(self._context, copy)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800617 if not add_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500618 # TODO: This is untested.
619 _lib.X509_free(copy)
620 _raise_current_error()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800621
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800622
623 def _raise_passphrase_exception(self):
624 if self._passphrase_helper is None:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500625 _raise_current_error()
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800626 exception = self._passphrase_helper.raise_if_problem(Error)
627 if exception is not None:
628 raise exception
629
630
Jean-Paul Calderone00f84eb2015-04-13 12:47:21 -0400631 def use_privatekey_file(self, keyfile, filetype=_UNSPECIFIED):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800632 """
633 Load a private key from a file
634
Jean-Paul Calderoneb6f8a792015-04-13 10:10:06 -0400635 :param keyfile: The name of the key file (``bytes`` or ``unicode``)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800636 :param filetype: (optional) The encoding of the file, default is PEM
Jean-Paul Calderoneb6f8a792015-04-13 10:10:06 -0400637
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800638 :return: None
639 """
Jean-Paul Calderone69a4e5b2015-04-12 10:04:28 -0400640 keyfile = _path_string(keyfile)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800641
Jean-Paul Calderone00f84eb2015-04-13 12:47:21 -0400642 if filetype is _UNSPECIFIED:
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800643 filetype = FILETYPE_PEM
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -0500644 elif not isinstance(filetype, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800645 raise TypeError("filetype must be an integer")
646
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500647 use_result = _lib.SSL_CTX_use_PrivateKey_file(
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800648 self._context, keyfile, filetype)
649 if not use_result:
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800650 self._raise_passphrase_exception()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800651
652
653 def use_privatekey(self, pkey):
654 """
655 Load a private key from a PKey object
656
657 :param pkey: The PKey object
658 :return: None
659 """
660 if not isinstance(pkey, PKey):
661 raise TypeError("pkey must be a PKey instance")
662
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500663 use_result = _lib.SSL_CTX_use_PrivateKey(self._context, pkey._pkey)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800664 if not use_result:
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800665 self._raise_passphrase_exception()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800666
667
668 def check_privatekey(self):
669 """
670 Check that the private key and certificate match up
671
672 :return: None (raises an exception if something's wrong)
673 """
Jean-Paul Calderonea0344922014-12-11 14:02:31 -0500674 if not _lib.SSL_CTX_check_private_key(self._context):
675 _raise_current_error()
676
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800677
678 def load_client_ca(self, cafile):
679 """
680 Load the trusted certificates that will be sent to the client (basically
681 telling the client "These are the guys I trust"). Does not actually
682 imply any of the certificates are trusted; that must be configured
683 separately.
684
685 :param cafile: The name of the certificates file
686 :return: None
687 """
688
689 def set_session_id(self, buf):
690 """
691 Set the session identifier. This is needed if you want to do session
692 resumption.
693
694 :param buf: A Python object that can be safely converted to a string
695 :returns: None
696 """
697
698 def set_session_cache_mode(self, mode):
699 """
700 Enable/disable session caching and specify the mode used.
701
702 :param mode: One or more of the SESS_CACHE_* flags (combine using
703 bitwise or)
704 :returns: The previously set caching mode.
705 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500706 if not isinstance(mode, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800707 raise TypeError("mode must be an integer")
708
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500709 return _lib.SSL_CTX_set_session_cache_mode(self._context, mode)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800710
711
712 def get_session_cache_mode(self):
713 """
714 :returns: The currently used cache mode.
715 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500716 return _lib.SSL_CTX_get_session_cache_mode(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800717
718
719 def set_verify(self, mode, callback):
720 """
721 Set the verify mode and verify callback
722
723 :param mode: The verify mode, this is either VERIFY_NONE or
724 VERIFY_PEER combined with possible other flags
725 :param callback: The Python callback to use
726 :return: None
727
728 See SSL_CTX_set_verify(3SSL) for further details.
729 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500730 if not isinstance(mode, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800731 raise TypeError("mode must be an integer")
732
733 if not callable(callback):
734 raise TypeError("callback must be callable")
735
Jean-Paul Calderone6a8cd112014-04-02 21:09:08 -0400736 self._verify_helper = _VerifyHelper(callback)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800737 self._verify_callback = self._verify_helper.callback
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500738 _lib.SSL_CTX_set_verify(self._context, mode, self._verify_callback)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800739
740
741 def set_verify_depth(self, depth):
742 """
743 Set the verify depth
744
745 :param depth: An integer specifying the verify depth
746 :return: None
747 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500748 if not isinstance(depth, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800749 raise TypeError("depth must be an integer")
750
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500751 _lib.SSL_CTX_set_verify_depth(self._context, depth)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800752
753
754 def get_verify_mode(self):
755 """
756 Get the verify mode
757
758 :return: The verify mode
759 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500760 return _lib.SSL_CTX_get_verify_mode(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800761
762
763 def get_verify_depth(self):
764 """
765 Get the verify depth
766
767 :return: The verify depth
768 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500769 return _lib.SSL_CTX_get_verify_depth(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800770
771
772 def load_tmp_dh(self, dhfile):
773 """
774 Load parameters for Ephemeral Diffie-Hellman
775
Jean-Paul Calderone4e0c43f2015-04-13 10:15:17 -0400776 :param dhfile: The file to load EDH parameters from (``bytes`` or
777 ``unicode``).
778
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800779 :return: None
780 """
Jean-Paul Calderone9e1c1dd2015-04-12 10:13:13 -0400781 dhfile = _path_string(dhfile)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800782
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -0500783 bio = _lib.BIO_new_file(dhfile, b"r")
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500784 if bio == _ffi.NULL:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500785 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500786 bio = _ffi.gc(bio, _lib.BIO_free)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800787
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500788 dh = _lib.PEM_read_bio_DHparams(bio, _ffi.NULL, _ffi.NULL, _ffi.NULL)
789 dh = _ffi.gc(dh, _lib.DH_free)
790 _lib.SSL_CTX_set_tmp_dh(self._context, dh)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800791
792
Jean-Paul Calderone3e4e3352014-04-19 09:28:28 -0400793 def set_tmp_ecdh(self, curve):
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600794 """
Andy Lutomirski76a61332014-03-12 15:02:56 -0700795 Select a curve to use for ECDHE key exchange.
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600796
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -0400797 :param curve: A curve object to use as returned by either
798 :py:meth:`OpenSSL.crypto.get_elliptic_curve` or
799 :py:meth:`OpenSSL.crypto.get_elliptic_curves`.
Andy Lutomirskif05a2732014-03-13 17:22:25 -0700800
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600801 :return: None
802 """
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -0400803 _lib.SSL_CTX_set_tmp_ecdh(self._context, curve._to_EC_KEY())
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600804
805
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800806 def set_cipher_list(self, cipher_list):
807 """
808 Change the cipher list
809
810 :param cipher_list: A cipher list, see ciphers(1)
811 :return: None
812 """
Jean-Paul Calderone63eab692014-01-18 10:19:56 -0500813 if isinstance(cipher_list, _text_type):
814 cipher_list = cipher_list.encode("ascii")
815
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800816 if not isinstance(cipher_list, bytes):
Jean-Paul Calderone63eab692014-01-18 10:19:56 -0500817 raise TypeError("cipher_list must be bytes or unicode")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800818
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500819 result = _lib.SSL_CTX_set_cipher_list(self._context, cipher_list)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800820 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500821 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800822
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800823
824 def set_client_ca_list(self, certificate_authorities):
825 """
826 Set the list of preferred client certificate signers for this server context.
827
828 This list of certificate authorities will be sent to the client when the
829 server requests a client certificate.
830
831 :param certificate_authorities: a sequence of X509Names.
832 :return: None
833 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500834 name_stack = _lib.sk_X509_NAME_new_null()
835 if name_stack == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500836 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500837 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800838
839 try:
840 for ca_name in certificate_authorities:
841 if not isinstance(ca_name, X509Name):
842 raise TypeError(
843 "client CAs must be X509Name objects, not %s objects" % (
844 type(ca_name).__name__,))
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500845 copy = _lib.X509_NAME_dup(ca_name._name)
846 if copy == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500847 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500848 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500849 push_result = _lib.sk_X509_NAME_push(name_stack, copy)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800850 if not push_result:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500851 _lib.X509_NAME_free(copy)
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500852 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800853 except:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500854 _lib.sk_X509_NAME_free(name_stack)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800855 raise
856
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500857 _lib.SSL_CTX_set_client_CA_list(self._context, name_stack)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800858
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800859
860 def add_client_ca(self, certificate_authority):
861 """
862 Add the CA certificate to the list of preferred signers for this context.
863
864 The list of certificate authorities will be sent to the client when the
865 server requests a client certificate.
866
867 :param certificate_authority: certificate authority's X509 certificate.
868 :return: None
869 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800870 if not isinstance(certificate_authority, X509):
871 raise TypeError("certificate_authority must be an X509 instance")
872
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500873 add_result = _lib.SSL_CTX_add_client_CA(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800874 self._context, certificate_authority._x509)
875 if not add_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500876 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500877 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800878
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800879
880 def set_timeout(self, timeout):
881 """
882 Set session timeout
883
884 :param timeout: The timeout in seconds
885 :return: The previous session timeout
886 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500887 if not isinstance(timeout, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800888 raise TypeError("timeout must be an integer")
889
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500890 return _lib.SSL_CTX_set_timeout(self._context, timeout)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800891
892
893 def get_timeout(self):
894 """
895 Get the session timeout
896
897 :return: The session timeout
898 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500899 return _lib.SSL_CTX_get_timeout(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800900
901
902 def set_info_callback(self, callback):
903 """
904 Set the info callback
905
906 :param callback: The Python callback to use
907 :return: None
908 """
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800909 @wraps(callback)
910 def wrapper(ssl, where, return_code):
Jean-Paul Calderonef2bbc9c2014-02-02 10:59:14 -0500911 callback(Connection._reverse_mapping[ssl], where, return_code)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500912 self._info_callback = _ffi.callback(
913 "void (*)(const SSL *, int, int)", wrapper)
914 _lib.SSL_CTX_set_info_callback(self._context, self._info_callback)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800915
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800916
917 def get_app_data(self):
918 """
919 Get the application data (supplied via set_app_data())
920
921 :return: The application data
922 """
923 return self._app_data
924
925
926 def set_app_data(self, data):
927 """
928 Set the application data (will be returned from get_app_data())
929
930 :param data: Any Python object
931 :return: None
932 """
933 self._app_data = data
934
935
936 def get_cert_store(self):
937 """
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500938 Get the certificate store for the context.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800939
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500940 :return: A X509Store object or None if it does not have one.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800941 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500942 store = _lib.SSL_CTX_get_cert_store(self._context)
943 if store == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500944 # TODO: This is untested.
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800945 return None
946
947 pystore = X509Store.__new__(X509Store)
948 pystore._store = store
949 return pystore
950
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800951
952 def set_options(self, options):
953 """
954 Add options. Options set before are not cleared!
955
956 :param options: The options to add.
957 :return: The new option bitmask.
958 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500959 if not isinstance(options, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800960 raise TypeError("options must be an integer")
961
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500962 return _lib.SSL_CTX_set_options(self._context, options)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800963
964
965 def set_mode(self, mode):
966 """
967 Add modes via bitmask. Modes set before are not cleared!
968
969 :param mode: The mode to add.
970 :return: The new mode bitmask.
971 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500972 if not isinstance(mode, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800973 raise TypeError("mode must be an integer")
974
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500975 return _lib.SSL_CTX_set_mode(self._context, mode)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800976
977
978 def set_tlsext_servername_callback(self, callback):
979 """
980 Specify a callback function to be called when clients specify a server name.
981
982 :param callback: The callback function. It will be invoked with one
983 argument, the Connection instance.
984 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800985 @wraps(callback)
986 def wrapper(ssl, alert, arg):
987 callback(Connection._reverse_mapping[ssl])
988 return 0
989
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500990 self._tlsext_servername_callback = _ffi.callback(
991 "int (*)(const SSL *, int *, void *)", wrapper)
992 _lib.SSL_CTX_set_tlsext_servername_callback(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800993 self._context, self._tlsext_servername_callback)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800994
Cory Benfield84a121e2014-03-31 20:30:25 +0100995 def set_npn_advertise_callback(self, callback):
996 """
Cory Benfieldbe3e7b82014-05-10 09:48:55 +0100997 Specify a callback function that will be called when offering `Next
998 Protocol Negotiation
999 <https://technotes.googlecode.com/git/nextprotoneg.html>`_ as a server.
Cory Benfield84a121e2014-03-31 20:30:25 +01001000
1001 :param callback: The callback function. It will be invoked with one
Cory Benfieldbe3e7b82014-05-10 09:48:55 +01001002 argument, the Connection instance. It should return a list of
1003 bytestrings representing the advertised protocols, like
1004 ``[b'http/1.1', b'spdy/2']``.
Cory Benfield84a121e2014-03-31 20:30:25 +01001005 """
Cory Benfield0ea76e72015-03-22 09:05:28 +00001006 self._npn_advertise_helper = _NpnAdvertiseHelper(callback)
1007 self._npn_advertise_callback = self._npn_advertise_helper.callback
Cory Benfield84a121e2014-03-31 20:30:25 +01001008 _lib.SSL_CTX_set_next_protos_advertised_cb(
1009 self._context, self._npn_advertise_callback, _ffi.NULL)
1010
1011
1012 def set_npn_select_callback(self, callback):
1013 """
1014 Specify a callback function that will be called when a server offers
1015 Next Protocol Negotiation options.
1016
1017 :param callback: The callback function. It will be invoked with two
1018 arguments: the Connection, and a list of offered protocols as
Cory Benfieldbe3e7b82014-05-10 09:48:55 +01001019 bytestrings, e.g. ``[b'http/1.1', b'spdy/2']``. It should return
1020 one of those bytestrings, the chosen protocol.
Cory Benfield84a121e2014-03-31 20:30:25 +01001021 """
Cory Benfield0ea76e72015-03-22 09:05:28 +00001022 self._npn_select_helper = _NpnSelectHelper(callback)
1023 self._npn_select_callback = self._npn_select_helper.callback
Cory Benfield84a121e2014-03-31 20:30:25 +01001024 _lib.SSL_CTX_set_next_proto_select_cb(
1025 self._context, self._npn_select_callback, _ffi.NULL)
1026
Cory Benfield7907e332015-04-13 17:18:25 -04001027 @_requires_alpn
Cory Benfield12eae892014-06-07 15:42:56 +01001028 def set_alpn_protos(self, protos):
1029 """
Cory Benfielde8e9c382015-04-11 17:33:48 -04001030 Specify the clients ALPN protocol list.
1031
1032 These protocols are offered to the server during protocol negotiation.
Cory Benfield12eae892014-06-07 15:42:56 +01001033
1034 :param protos: A list of the protocols to be offered to the server.
1035 This list should be a Python list of bytestrings representing the
1036 protocols to offer, e.g. ``[b'http/1.1', b'spdy/2']``.
1037 """
1038 # Take the list of protocols and join them together, prefixing them
1039 # with their lengths.
1040 protostr = b''.join(
1041 chain.from_iterable((int2byte(len(p)), p) for p in protos)
1042 )
1043
1044 # Build a C string from the list. We don't need to save this off
1045 # because OpenSSL immediately copies the data out.
1046 input_str = _ffi.new("unsigned char[]", protostr)
Cory Benfielde871af52015-04-11 17:57:50 -04001047 input_str_len = _ffi.cast("unsigned", len(protostr))
1048 _lib.SSL_CTX_set_alpn_protos(self._context, input_str, input_str_len)
Cory Benfield12eae892014-06-07 15:42:56 +01001049
Cory Benfield7907e332015-04-13 17:18:25 -04001050 @_requires_alpn
Cory Benfield12eae892014-06-07 15:42:56 +01001051 def set_alpn_select_callback(self, callback):
1052 """
Cory Benfielde8e9c382015-04-11 17:33:48 -04001053 Set the callback to handle ALPN protocol choice.
Cory Benfield12eae892014-06-07 15:42:56 +01001054
1055 :param callback: The callback function. It will be invoked with two
1056 arguments: the Connection, and a list of offered protocols as
1057 bytestrings, e.g ``[b'http/1.1', b'spdy/2']``. It should return
Cory Benfielde8e9c382015-04-11 17:33:48 -04001058 one of those bytestrings, the chosen protocol.
Cory Benfield12eae892014-06-07 15:42:56 +01001059 """
Cory Benfield9da5ffb2015-04-13 17:20:14 -04001060 self._alpn_select_helper = _ALPNSelectHelper(callback)
Cory Benfieldf1177e72015-04-12 09:11:49 -04001061 self._alpn_select_callback = self._alpn_select_helper.callback
Cory Benfield12eae892014-06-07 15:42:56 +01001062 _lib.SSL_CTX_set_alpn_select_cb(
1063 self._context, self._alpn_select_callback, _ffi.NULL)
1064
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -08001065ContextType = Context
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001066
1067
1068
1069class Connection(object):
1070 """
1071 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001072 _reverse_mapping = WeakValueDictionary()
1073
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001074 def __init__(self, context, socket=None):
1075 """
1076 Create a new Connection object, using the given OpenSSL.SSL.Context
1077 instance and socket.
1078
1079 :param context: An SSL Context to use for this connection
1080 :param socket: The socket to use for transport layer
1081 """
1082 if not isinstance(context, Context):
1083 raise TypeError("context must be a Context instance")
1084
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001085 ssl = _lib.SSL_new(context._context)
1086 self._ssl = _ffi.gc(ssl, _lib.SSL_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001087 self._context = context
1088
Cory Benfieldbe3e7b82014-05-10 09:48:55 +01001089 # References to strings used for Next Protocol Negotiation. OpenSSL's
1090 # header files suggest that these might get copied at some point, but
1091 # doesn't specify when, so we store them here to make sure they don't
1092 # get freed before OpenSSL uses them.
1093 self._npn_advertise_callback_args = None
1094 self._npn_select_callback_args = None
1095
Cory Benfield12eae892014-06-07 15:42:56 +01001096 # References to strings used for Application Layer Protocol
1097 # Negotiation. These strings get copied at some point but it's well
1098 # after the callback returns, so we have to hang them somewhere to
1099 # avoid them getting freed.
1100 self._alpn_select_callback_args = None
1101
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001102 self._reverse_mapping[self._ssl] = self
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001103
1104 if socket is None:
1105 self._socket = None
Jean-Paul Calderone73b15c22013-03-05 18:30:39 -08001106 # Don't set up any gc for these, SSL_free will take care of them.
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001107 self._into_ssl = _lib.BIO_new(_lib.BIO_s_mem())
1108 self._from_ssl = _lib.BIO_new(_lib.BIO_s_mem())
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001109
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001110 if self._into_ssl == _ffi.NULL or self._from_ssl == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001111 # TODO: This is untested.
1112 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001113
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001114 _lib.SSL_set_bio(self._ssl, self._into_ssl, self._from_ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001115 else:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001116 self._into_ssl = None
1117 self._from_ssl = None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001118 self._socket = socket
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001119 set_result = _lib.SSL_set_fd(self._ssl, _asFileDescriptor(self._socket))
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001120 if not set_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001121 # TODO: This is untested.
1122 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001123
1124
1125 def __getattr__(self, name):
1126 """
1127 Look up attributes on the wrapped socket object if they are not found on
1128 the Connection object.
1129 """
1130 return getattr(self._socket, name)
1131
1132
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001133 def _raise_ssl_error(self, ssl, result):
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -08001134 if self._context._verify_helper is not None:
1135 self._context._verify_helper.raise_if_problem()
Cory Benfield0ea76e72015-03-22 09:05:28 +00001136 if self._context._npn_advertise_helper is not None:
1137 self._context._npn_advertise_helper.raise_if_problem()
1138 if self._context._npn_select_helper is not None:
1139 self._context._npn_select_helper.raise_if_problem()
Cory Benfieldf1177e72015-04-12 09:11:49 -04001140 if self._context._alpn_select_helper is not None:
1141 self._context._alpn_select_helper.raise_if_problem()
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -08001142
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001143 error = _lib.SSL_get_error(ssl, result)
1144 if error == _lib.SSL_ERROR_WANT_READ:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001145 raise WantReadError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001146 elif error == _lib.SSL_ERROR_WANT_WRITE:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001147 raise WantWriteError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001148 elif error == _lib.SSL_ERROR_ZERO_RETURN:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001149 raise ZeroReturnError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001150 elif error == _lib.SSL_ERROR_WANT_X509_LOOKUP:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001151 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001152 raise WantX509LookupError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001153 elif error == _lib.SSL_ERROR_SYSCALL:
1154 if _lib.ERR_peek_error() == 0:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001155 if result < 0:
Konstantinos Koukopoulos541150d2014-01-31 01:00:19 +02001156 if platform == "win32":
1157 errno = _ffi.getwinerror()[0]
1158 else:
1159 errno = _ffi.errno
1160 raise SysCallError(errno, errorcode[errno])
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001161 else:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001162 raise SysCallError(-1, "Unexpected EOF")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001163 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001164 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001165 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001166 elif error == _lib.SSL_ERROR_NONE:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001167 pass
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001168 else:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001169 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001170
1171
1172 def get_context(self):
1173 """
1174 Get session context
1175 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001176 return self._context
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001177
1178
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001179 def set_context(self, context):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001180 """
1181 Switch this connection to a new session context
1182
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001183 :param context: A :py:class:`Context` instance giving the new session
1184 context to use.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001185 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001186 if not isinstance(context, Context):
1187 raise TypeError("context must be a Context instance")
1188
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001189 _lib.SSL_set_SSL_CTX(self._ssl, context._context)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001190 self._context = context
1191
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001192
1193 def get_servername(self):
1194 """
1195 Retrieve the servername extension value if provided in the client hello
1196 message, or None if there wasn't one.
1197
1198 :return: A byte string giving the server name or :py:data:`None`.
1199 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001200 name = _lib.SSL_get_servername(self._ssl, _lib.TLSEXT_NAMETYPE_host_name)
1201 if name == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001202 return None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001203
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001204 return _ffi.string(name)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001205
1206
1207 def set_tlsext_host_name(self, name):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001208 """
1209 Set the value of the servername extension to send in the client hello.
1210
1211 :param name: A byte string giving the name.
1212 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001213 if not isinstance(name, bytes):
1214 raise TypeError("name must be a byte string")
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001215 elif b"\0" in name:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001216 raise TypeError("name must not contain NUL byte")
1217
1218 # XXX I guess this can fail sometimes?
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001219 _lib.SSL_set_tlsext_host_name(self._ssl, name)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001220
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001221
1222 def pending(self):
1223 """
1224 Get the number of bytes that can be safely read from the connection
1225
1226 :return: The number of bytes available in the receive buffer.
1227 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001228 return _lib.SSL_pending(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001229
1230
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001231 def send(self, buf, flags=0):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001232 """
1233 Send data on the connection. NOTE: If you get one of the WantRead,
1234 WantWrite or WantX509Lookup exceptions on this, you have to call the
1235 method again with the SAME buffer.
1236
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001237 :param buf: The string, buffer or memoryview to send
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001238 :param flags: (optional) Included for compatibility with the socket
1239 API, the value is ignored
1240 :return: The number of bytes written
1241 """
Abraham Martine82326c2015-02-04 10:18:10 +00001242 # Backward compatibility
Jean-Paul Calderone39a8d592015-04-13 20:49:50 -04001243 buf = _text_to_bytes_and_warn("buf", buf)
Abraham Martine82326c2015-02-04 10:18:10 +00001244
Jean-Paul Calderone8fb53182013-12-30 08:35:49 -05001245 if isinstance(buf, _memoryview):
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -08001246 buf = buf.tobytes()
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001247 if isinstance(buf, _buffer):
1248 buf = str(buf)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001249 if not isinstance(buf, bytes):
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001250 raise TypeError("data must be a memoryview, buffer or byte string")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001251
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001252 result = _lib.SSL_write(self._ssl, buf, len(buf))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001253 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001254 return result
1255 write = send
1256
1257
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001258 def sendall(self, buf, flags=0):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001259 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001260 Send "all" data on the connection. This calls send() repeatedly until
1261 all data is sent. If an error occurs, it's impossible to tell how much
1262 data has been sent.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001263
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001264 :param buf: The string, buffer or memoryview to send
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001265 :param flags: (optional) Included for compatibility with the socket
1266 API, the value is ignored
1267 :return: The number of bytes written
1268 """
Jean-Paul Calderone39a8d592015-04-13 20:49:50 -04001269 buf = _text_to_bytes_and_warn("buf", buf)
Abraham Martine82326c2015-02-04 10:18:10 +00001270
Jean-Paul Calderone8fb53182013-12-30 08:35:49 -05001271 if isinstance(buf, _memoryview):
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -08001272 buf = buf.tobytes()
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001273 if isinstance(buf, _buffer):
1274 buf = str(buf)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001275 if not isinstance(buf, bytes):
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001276 raise TypeError("buf must be a memoryview, buffer or byte string")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001277
1278 left_to_send = len(buf)
1279 total_sent = 0
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001280 data = _ffi.new("char[]", buf)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001281
1282 while left_to_send:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001283 result = _lib.SSL_write(self._ssl, data + total_sent, left_to_send)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001284 self._raise_ssl_error(self._ssl, result)
1285 total_sent += result
1286 left_to_send -= result
1287
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001288
1289 def recv(self, bufsiz, flags=None):
1290 """
1291 Receive data on the connection. NOTE: If you get one of the WantRead,
1292 WantWrite or WantX509Lookup exceptions on this, you have to call the
1293 method again with the SAME buffer.
1294
1295 :param bufsiz: The maximum number of bytes to read
1296 :param flags: (optional) Included for compatibility with the socket
1297 API, the value is ignored
1298 :return: The string read from the Connection
1299 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001300 buf = _ffi.new("char[]", bufsiz)
1301 result = _lib.SSL_read(self._ssl, buf, bufsiz)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001302 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001303 return _ffi.buffer(buf, result)[:]
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001304 read = recv
1305
1306
Cory Benfield62d10332014-06-15 10:03:41 +01001307 def recv_into(self, buffer, nbytes=None, flags=None):
1308 """
1309 Receive data on the connection and store the data into a buffer rather
1310 than creating a new string.
1311
1312 :param buffer: The buffer to copy into.
1313 :param nbytes: (optional) The maximum number of bytes to read into the
1314 buffer. If not present, defaults to the size of the buffer. If
1315 larger than the size of the buffer, is reduced to the size of the
1316 buffer.
1317 :param flags: (optional) Included for compatibility with the socket
1318 API, the value is ignored.
1319 :return: The number of bytes read into the buffer.
1320 """
1321 if nbytes is None:
1322 nbytes = len(buffer)
1323 else:
1324 nbytes = min(nbytes, len(buffer))
1325
1326 # We need to create a temporary buffer. This is annoying, it would be
1327 # better if we could pass memoryviews straight into the SSL_read call,
1328 # but right now we can't. Revisit this if CFFI gets that ability.
1329 buf = _ffi.new("char[]", nbytes)
1330 result = _lib.SSL_read(self._ssl, buf, nbytes)
1331 self._raise_ssl_error(self._ssl, result)
1332
1333 # This strange line is all to avoid a memory copy. The buffer protocol
1334 # should allow us to assign a CFFI buffer to the LHS of this line, but
1335 # on CPython 3.3+ that segfaults. As a workaround, we can temporarily
1336 # wrap it in a memoryview, except on Python 2.6 which doesn't have a
1337 # memoryview type.
1338 try:
1339 buffer[:result] = memoryview(_ffi.buffer(buf, result))
1340 except NameError:
1341 buffer[:result] = _ffi.buffer(buf, result)
1342
1343 return result
1344
1345
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001346 def _handle_bio_errors(self, bio, result):
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001347 if _lib.BIO_should_retry(bio):
1348 if _lib.BIO_should_read(bio):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001349 raise WantReadError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001350 elif _lib.BIO_should_write(bio):
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001351 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001352 raise WantWriteError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001353 elif _lib.BIO_should_io_special(bio):
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001354 # TODO: This is untested. I think io_special means the socket
1355 # BIO has a not-yet connected socket.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001356 raise ValueError("BIO_should_io_special")
1357 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001358 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001359 raise ValueError("unknown bio failure")
1360 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001361 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001362 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001363
1364
1365 def bio_read(self, bufsiz):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001366 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001367 When using non-socket connections this function reads the "dirty" data
1368 that would have traveled away on the network.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001369
1370 :param bufsiz: The maximum number of bytes to read
1371 :return: The string read.
1372 """
Jean-Paul Calderone97e041d2013-03-05 21:03:12 -08001373 if self._from_ssl is None:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001374 raise TypeError("Connection sock was not None")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001375
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -05001376 if not isinstance(bufsiz, integer_types):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001377 raise TypeError("bufsiz must be an integer")
1378
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001379 buf = _ffi.new("char[]", bufsiz)
1380 result = _lib.BIO_read(self._from_ssl, buf, bufsiz)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001381 if result <= 0:
1382 self._handle_bio_errors(self._from_ssl, result)
1383
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001384 return _ffi.buffer(buf, result)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001385
1386
1387 def bio_write(self, buf):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001388 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001389 When using non-socket connections this function sends "dirty" data that
1390 would have traveled in on the network.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001391
1392 :param buf: The string to put into the memory BIO.
1393 :return: The number of bytes written
1394 """
Jean-Paul Calderone39a8d592015-04-13 20:49:50 -04001395 buf = _text_to_bytes_and_warn("buf", buf)
Abraham Martine82326c2015-02-04 10:18:10 +00001396
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001397 if self._into_ssl is None:
1398 raise TypeError("Connection sock was not None")
1399
1400 if not isinstance(buf, bytes):
1401 raise TypeError("buf must be a byte string")
1402
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001403 result = _lib.BIO_write(self._into_ssl, buf, len(buf))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001404 if result <= 0:
1405 self._handle_bio_errors(self._into_ssl, result)
1406 return result
1407
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001408
1409 def renegotiate(self):
1410 """
1411 Renegotiate the session
1412
1413 :return: True if the renegotiation can be started, false otherwise
1414 """
1415
1416 def do_handshake(self):
1417 """
1418 Perform an SSL handshake (usually called after renegotiate() or one of
1419 set_*_state()). This can raise the same exceptions as send and recv.
1420
1421 :return: None.
1422 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001423 result = _lib.SSL_do_handshake(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001424 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001425
1426
1427 def renegotiate_pending(self):
1428 """
1429 Check if there's a renegotiation in progress, it will return false once
1430 a renegotiation is finished.
1431
1432 :return: Whether there's a renegotiation in progress
1433 """
1434
1435 def total_renegotiations(self):
1436 """
1437 Find out the total number of renegotiations.
1438
1439 :return: The number of renegotiations.
1440 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001441 return _lib.SSL_total_renegotiations(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001442
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001443
1444 def connect(self, addr):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001445 """
1446 Connect to remote host and set up client-side SSL
1447
1448 :param addr: A remote address
1449 :return: What the socket's connect method returns
1450 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001451 _lib.SSL_set_connect_state(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001452 return self._socket.connect(addr)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001453
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001454
1455 def connect_ex(self, addr):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001456 """
1457 Connect to remote host and set up client-side SSL. Note that if the socket's
1458 connect_ex method doesn't return 0, SSL won't be initialized.
1459
1460 :param addr: A remove address
1461 :return: What the socket's connect_ex method returns
1462 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001463 connect_ex = self._socket.connect_ex
1464 self.set_connect_state()
1465 return connect_ex(addr)
1466
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001467
1468 def accept(self):
1469 """
1470 Accept incoming connection and set up SSL on it
1471
1472 :return: A (conn,addr) pair where conn is a Connection and addr is an
1473 address
1474 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001475 client, addr = self._socket.accept()
1476 conn = Connection(self._context, client)
1477 conn.set_accept_state()
1478 return (conn, addr)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001479
1480
1481 def bio_shutdown(self):
1482 """
1483 When using non-socket connections this function signals end of
1484 data on the input for this connection.
1485
1486 :return: None
1487 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001488 if self._from_ssl is None:
1489 raise TypeError("Connection sock was not None")
1490
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001491 _lib.BIO_set_mem_eof_return(self._into_ssl, 0)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001492
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001493
1494 def shutdown(self):
1495 """
1496 Send closure alert
1497
1498 :return: True if the shutdown completed successfully (i.e. both sides
1499 have sent closure alerts), false otherwise (i.e. you have to
1500 wait for a ZeroReturnError on a recv() method call
1501 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001502 result = _lib.SSL_shutdown(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001503 if result < 0:
Paul Aurichbff1d1a2015-01-08 08:36:53 -08001504 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001505 elif result > 0:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001506 return True
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001507 else:
1508 return False
1509
1510
1511 def get_cipher_list(self):
1512 """
1513 Get the session cipher list
1514
1515 :return: A list of cipher strings
1516 """
1517 ciphers = []
1518 for i in count():
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001519 result = _lib.SSL_get_cipher_list(self._ssl, i)
1520 if result == _ffi.NULL:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001521 break
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001522 ciphers.append(_native(_ffi.string(result)))
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001523 return ciphers
1524
1525
1526 def get_client_ca_list(self):
1527 """
1528 Get CAs whose certificates are suggested for client authentication.
1529
1530 :return: If this is a server connection, a list of X509Names representing
1531 the acceptable CAs as set by :py:meth:`OpenSSL.SSL.Context.set_client_ca_list` or
1532 :py:meth:`OpenSSL.SSL.Context.add_client_ca`. If this is a client connection,
1533 the list of such X509Names sent by the server, or an empty list if that
1534 has not yet happened.
1535 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001536 ca_names = _lib.SSL_get_client_CA_list(self._ssl)
1537 if ca_names == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001538 # TODO: This is untested.
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001539 return []
1540
1541 result = []
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001542 for i in range(_lib.sk_X509_NAME_num(ca_names)):
1543 name = _lib.sk_X509_NAME_value(ca_names, i)
1544 copy = _lib.X509_NAME_dup(name)
1545 if copy == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001546 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001547 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001548
1549 pyname = X509Name.__new__(X509Name)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001550 pyname._name = _ffi.gc(copy, _lib.X509_NAME_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001551 result.append(pyname)
1552 return result
1553
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001554
1555 def makefile(self):
1556 """
1557 The makefile() method is not implemented, since there is no dup semantics
1558 for SSL connections
1559
Jean-Paul Calderone6749ec22014-04-17 16:30:21 -04001560 :raise: NotImplementedError
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001561 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001562 raise NotImplementedError("Cannot make file object of OpenSSL.SSL.Connection")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001563
1564
1565 def get_app_data(self):
1566 """
1567 Get application data
1568
1569 :return: The application data
1570 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001571 return self._app_data
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001572
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001573
1574 def set_app_data(self, data):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001575 """
1576 Set application data
1577
1578 :param data - The application data
1579 :return: None
1580 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001581 self._app_data = data
1582
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001583
1584 def get_shutdown(self):
1585 """
1586 Get shutdown state
1587
1588 :return: The shutdown state, a bitvector of SENT_SHUTDOWN, RECEIVED_SHUTDOWN.
1589 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001590 return _lib.SSL_get_shutdown(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001591
1592
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001593 def set_shutdown(self, state):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001594 """
1595 Set shutdown state
1596
1597 :param state - bitvector of SENT_SHUTDOWN, RECEIVED_SHUTDOWN.
1598 :return: None
1599 """
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -05001600 if not isinstance(state, integer_types):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001601 raise TypeError("state must be an integer")
1602
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001603 _lib.SSL_set_shutdown(self._ssl, state)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001604
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001605
1606 def state_string(self):
1607 """
1608 Get a verbose state description
1609
1610 :return: A string representing the state
1611 """
1612
1613 def server_random(self):
1614 """
1615 Get a copy of the server hello nonce.
1616
1617 :return: A string representing the state
1618 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001619 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001620 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001621 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001622 self._ssl.s3.server_random,
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001623 _lib.SSL3_RANDOM_SIZE)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001624
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001625
1626 def client_random(self):
1627 """
1628 Get a copy of the client hello nonce.
1629
1630 :return: A string representing the state
1631 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001632 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001633 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001634 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001635 self._ssl.s3.client_random,
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001636 _lib.SSL3_RANDOM_SIZE)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001637
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001638
1639 def master_key(self):
1640 """
1641 Get a copy of the master key.
1642
1643 :return: A string representing the state
1644 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001645 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001646 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001647 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001648 self._ssl.session.master_key,
1649 self._ssl.session.master_key_length)[:]
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001650
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001651
1652 def sock_shutdown(self, *args, **kwargs):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001653 """
1654 See shutdown(2)
1655
1656 :return: What the socket's shutdown() method returns
1657 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001658 return self._socket.shutdown(*args, **kwargs)
1659
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001660
1661 def get_peer_certificate(self):
1662 """
1663 Retrieve the other side's certificate (if any)
1664
1665 :return: The peer's certificate
1666 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001667 cert = _lib.SSL_get_peer_certificate(self._ssl)
1668 if cert != _ffi.NULL:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001669 pycert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001670 pycert._x509 = _ffi.gc(cert, _lib.X509_free)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001671 return pycert
1672 return None
1673
1674
1675 def get_peer_cert_chain(self):
1676 """
1677 Retrieve the other side's certificate (if any)
1678
1679 :return: A list of X509 instances giving the peer's certificate chain,
1680 or None if it does not have one.
1681 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001682 cert_stack = _lib.SSL_get_peer_cert_chain(self._ssl)
1683 if cert_stack == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001684 return None
1685
1686 result = []
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001687 for i in range(_lib.sk_X509_num(cert_stack)):
Jean-Paul Calderone73b15c22013-03-05 18:30:39 -08001688 # TODO could incref instead of dup here
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001689 cert = _lib.X509_dup(_lib.sk_X509_value(cert_stack, i))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001690 pycert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001691 pycert._x509 = _ffi.gc(cert, _lib.X509_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001692 result.append(pycert)
1693 return result
1694
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001695
1696 def want_read(self):
1697 """
1698 Checks if more data has to be read from the transport layer to complete an
1699 operation.
1700
1701 :return: True iff more data has to be read
1702 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001703 return _lib.SSL_want_read(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001704
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001705
1706 def want_write(self):
1707 """
1708 Checks if there is data to write to the transport layer to complete an
1709 operation.
1710
1711 :return: True iff there is data to write
1712 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001713 return _lib.SSL_want_write(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001714
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001715
1716 def set_accept_state(self):
1717 """
1718 Set the connection to work in server mode. The handshake will be handled
1719 automatically by read/write.
1720
1721 :return: None
1722 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001723 _lib.SSL_set_accept_state(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001724
1725
1726 def set_connect_state(self):
1727 """
1728 Set the connection to work in client mode. The handshake will be handled
1729 automatically by read/write.
1730
1731 :return: None
1732 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001733 _lib.SSL_set_connect_state(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001734
1735
1736 def get_session(self):
1737 """
1738 Returns the Session currently used.
1739
1740 @return: An instance of :py:class:`OpenSSL.SSL.Session` or :py:obj:`None` if
1741 no session exists.
1742 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001743 session = _lib.SSL_get1_session(self._ssl)
1744 if session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001745 return None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001746
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001747 pysession = Session.__new__(Session)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001748 pysession._session = _ffi.gc(session, _lib.SSL_SESSION_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001749 return pysession
1750
1751
1752 def set_session(self, session):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001753 """
1754 Set the session to be used when the TLS/SSL connection is established.
1755
1756 :param session: A Session instance representing the session to use.
1757 :returns: None
1758 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001759 if not isinstance(session, Session):
1760 raise TypeError("session must be a Session instance")
1761
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001762 result = _lib.SSL_set_session(self._ssl, session._session)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001763 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001764 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001765
Jean-Paul Calderonedbd76272014-03-29 18:09:40 -04001766
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001767 def _get_finished_message(self, function):
1768 """
1769 Helper to implement :py:meth:`get_finished` and
1770 :py:meth:`get_peer_finished`.
1771
1772 :param function: Either :py:data:`SSL_get_finished`: or
1773 :py:data:`SSL_get_peer_finished`.
1774
1775 :return: :py:data:`None` if the desired message has not yet been
1776 received, otherwise the contents of the message.
1777 :rtype: :py:class:`bytes` or :py:class:`NoneType`
1778 """
Jean-Paul Calderone01af9042014-03-30 11:40:42 -04001779 # The OpenSSL documentation says nothing about what might happen if the
1780 # count argument given is zero. Specifically, it doesn't say whether
1781 # the output buffer may be NULL in that case or not. Inspection of the
1782 # implementation reveals that it calls memcpy() unconditionally.
1783 # Section 7.1.4, paragraph 1 of the C standard suggests that
1784 # memcpy(NULL, source, 0) is not guaranteed to produce defined (let
1785 # alone desirable) behavior (though it probably does on just about
1786 # every implementation...)
1787 #
1788 # Allocate a tiny buffer to pass in (instead of just passing NULL as
1789 # one might expect) for the initial call so as to be safe against this
1790 # potentially undefined behavior.
1791 empty = _ffi.new("char[]", 0)
1792 size = function(self._ssl, empty, 0)
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001793 if size == 0:
1794 # No Finished message so far.
1795 return None
1796
1797 buf = _ffi.new("char[]", size)
1798 function(self._ssl, buf, size)
1799 return _ffi.buffer(buf, size)[:]
1800
1801
Fedor Brunner5747b932014-03-05 14:22:34 +01001802 def get_finished(self):
1803 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001804 Obtain the latest `handshake finished` message sent to the peer.
Fedor Brunner5747b932014-03-05 14:22:34 +01001805
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001806 :return: The contents of the message or :py:obj:`None` if the TLS
1807 handshake has not yet completed.
1808 :rtype: :py:class:`bytes` or :py:class:`NoneType`
Fedor Brunner5747b932014-03-05 14:22:34 +01001809 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001810 return self._get_finished_message(_lib.SSL_get_finished)
1811
Fedor Brunner5747b932014-03-05 14:22:34 +01001812
1813 def get_peer_finished(self):
1814 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001815 Obtain the latest `handshake finished` message received from the peer.
Fedor Brunner5747b932014-03-05 14:22:34 +01001816
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001817 :return: The contents of the message or :py:obj:`None` if the TLS
1818 handshake has not yet completed.
1819 :rtype: :py:class:`bytes` or :py:class:`NoneType`
Fedor Brunner5747b932014-03-05 14:22:34 +01001820 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001821 return self._get_finished_message(_lib.SSL_get_peer_finished)
Fedor Brunner5747b932014-03-05 14:22:34 +01001822
Jean-Paul Calderone7c556ef2014-03-30 10:45:00 -04001823
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001824 def get_cipher_name(self):
1825 """
1826 Obtain the name of the currently used cipher.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001827
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001828 :returns: The name of the currently used cipher or :py:obj:`None`
1829 if no connection has been established.
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001830 :rtype: :py:class:`unicode` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001831 """
1832 cipher = _lib.SSL_get_current_cipher(self._ssl)
1833 if cipher == _ffi.NULL:
1834 return None
1835 else:
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001836 name = _ffi.string(_lib.SSL_CIPHER_get_name(cipher))
1837 return name.decode("utf-8")
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001838
Jean-Paul Calderonedbd76272014-03-29 18:09:40 -04001839
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001840 def get_cipher_bits(self):
1841 """
1842 Obtain the number of secret bits of the currently used cipher.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001843
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001844 :returns: The number of secret bits of the currently used cipher
1845 or :py:obj:`None` if no connection has been established.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001846 :rtype: :py:class:`int` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001847 """
1848 cipher = _lib.SSL_get_current_cipher(self._ssl)
1849 if cipher == _ffi.NULL:
1850 return None
1851 else:
1852 return _lib.SSL_CIPHER_get_bits(cipher, _ffi.NULL)
1853
Jean-Paul Calderonedbd76272014-03-29 18:09:40 -04001854
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001855 def get_cipher_version(self):
1856 """
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001857 Obtain the protocol version of the currently used cipher.
1858
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001859 :returns: The protocol name of the currently used cipher
1860 or :py:obj:`None` if no connection has been established.
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001861 :rtype: :py:class:`unicode` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001862 """
1863 cipher = _lib.SSL_get_current_cipher(self._ssl)
1864 if cipher == _ffi.NULL:
1865 return None
1866 else:
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001867 version =_ffi.string(_lib.SSL_CIPHER_get_version(cipher))
1868 return version.decode("utf-8")
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001869
Cory Benfield84a121e2014-03-31 20:30:25 +01001870 def get_next_proto_negotiated(self):
1871 """
1872 Get the protocol that was negotiated by NPN.
1873 """
1874 data = _ffi.new("unsigned char **")
1875 data_len = _ffi.new("unsigned int *")
1876
1877 _lib.SSL_get0_next_proto_negotiated(self._ssl, data, data_len)
1878
Cory Benfieldcd010f62014-05-15 19:00:27 +01001879 return _ffi.buffer(data[0], data_len[0])[:]
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001880
Cory Benfield7907e332015-04-13 17:18:25 -04001881 @_requires_alpn
Cory Benfield12eae892014-06-07 15:42:56 +01001882 def set_alpn_protos(self, protos):
1883 """
Cory Benfielde8e9c382015-04-11 17:33:48 -04001884 Specify the client's ALPN protocol list.
1885
1886 These protocols are offered to the server during protocol negotiation.
Cory Benfield12eae892014-06-07 15:42:56 +01001887
1888 :param protos: A list of the protocols to be offered to the server.
1889 This list should be a Python list of bytestrings representing the
1890 protocols to offer, e.g. ``[b'http/1.1', b'spdy/2']``.
1891 """
1892 # Take the list of protocols and join them together, prefixing them
1893 # with their lengths.
1894 protostr = b''.join(
1895 chain.from_iterable((int2byte(len(p)), p) for p in protos)
1896 )
1897
1898 # Build a C string from the list. We don't need to save this off
1899 # because OpenSSL immediately copies the data out.
1900 input_str = _ffi.new("unsigned char[]", protostr)
Cory Benfield9c1979a2015-04-12 08:51:52 -04001901 input_str_len = _ffi.cast("unsigned", len(protostr))
1902 _lib.SSL_set_alpn_protos(self._ssl, input_str, input_str_len)
Cory Benfield12eae892014-06-07 15:42:56 +01001903
1904
1905 def get_alpn_proto_negotiated(self):
Cory Benfield222f30e2015-04-13 18:10:21 -04001906 """
1907 Get the protocol that was negotiated by ALPN.
1908 """
Cory Benfield3e619292015-04-13 12:34:51 -04001909 if not _lib.Cryptography_HAS_ALPN:
1910 raise NotImplementedError("ALPN not available")
1911
Cory Benfield12eae892014-06-07 15:42:56 +01001912 data = _ffi.new("unsigned char **")
1913 data_len = _ffi.new("unsigned int *")
1914
1915 _lib.SSL_get0_alpn_selected(self._ssl, data, data_len)
1916
Cory Benfielde8e9c382015-04-11 17:33:48 -04001917 if not data_len:
1918 return b''
1919
Cory Benfield12eae892014-06-07 15:42:56 +01001920 return _ffi.buffer(data[0], data_len[0])[:]
1921
1922
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001923
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001924ConnectionType = Connection
Jean-Paul Calderone11ed8e82014-01-18 10:21:50 -05001925
Jean-Paul Calderonefab157b2014-01-18 11:21:38 -05001926# This is similar to the initialization calls at the end of OpenSSL/crypto.py
1927# but is exercised mostly by the Context initializer.
Jean-Paul Calderone11ed8e82014-01-18 10:21:50 -05001928_lib.SSL_library_init()