blob: 1215526e17d83753e6b9f06a468a7374bd34c344 [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
Konstantinos Koukopoulosc8b13ea2014-01-28 00:21:50 -08008from six import integer_types as integer_types
Cory Benfieldcd010f62014-05-15 19:00:27 +01009from six import int2byte, indexbytes
Jean-Paul Calderone63eab692014-01-18 10:19:56 -050010
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -050011from OpenSSL._util import (
12 ffi as _ffi,
13 lib as _lib,
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -050014 exception_from_error_queue as _exception_from_error_queue,
Jean-Paul Calderone55f9e882015-04-12 09:31:03 -040015 native as _native,
16 path_string as _path_string,
17)
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080018
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -080019from OpenSSL.crypto import (
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -050020 FILETYPE_PEM, _PassphraseHelper, PKey, X509Name, X509, X509Store)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -080021
22_unspecified = object()
23
Jean-Paul Calderone8fb53182013-12-30 08:35:49 -050024try:
25 _memoryview = memoryview
26except NameError:
27 class _memoryview(object):
28 pass
29
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +020030try:
31 _buffer = buffer
32except NameError:
33 class _buffer(object):
34 pass
35
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050036OPENSSL_VERSION_NUMBER = _lib.OPENSSL_VERSION_NUMBER
37SSLEAY_VERSION = _lib.SSLEAY_VERSION
38SSLEAY_CFLAGS = _lib.SSLEAY_CFLAGS
39SSLEAY_PLATFORM = _lib.SSLEAY_PLATFORM
40SSLEAY_DIR = _lib.SSLEAY_DIR
41SSLEAY_BUILT_ON = _lib.SSLEAY_BUILT_ON
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080042
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050043SENT_SHUTDOWN = _lib.SSL_SENT_SHUTDOWN
44RECEIVED_SHUTDOWN = _lib.SSL_RECEIVED_SHUTDOWN
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080045
46SSLv2_METHOD = 1
47SSLv3_METHOD = 2
48SSLv23_METHOD = 3
49TLSv1_METHOD = 4
Jean-Paul Calderone56bff942013-11-03 11:30:43 -050050TLSv1_1_METHOD = 5
51TLSv1_2_METHOD = 6
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080052
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050053OP_NO_SSLv2 = _lib.SSL_OP_NO_SSLv2
54OP_NO_SSLv3 = _lib.SSL_OP_NO_SSLv3
55OP_NO_TLSv1 = _lib.SSL_OP_NO_TLSv1
Jean-Paul Calderonebe2bb422013-12-29 07:34:08 -050056
57OP_NO_TLSv1_1 = getattr(_lib, "SSL_OP_NO_TLSv1_1", 0)
58OP_NO_TLSv1_2 = getattr(_lib, "SSL_OP_NO_TLSv1_2", 0)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -080059
Jean-Paul Calderone0d7e8a12014-01-08 16:54:13 -050060try:
61 MODE_RELEASE_BUFFERS = _lib.SSL_MODE_RELEASE_BUFFERS
62except AttributeError:
63 pass
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080064
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050065OP_SINGLE_DH_USE = _lib.SSL_OP_SINGLE_DH_USE
66OP_EPHEMERAL_RSA = _lib.SSL_OP_EPHEMERAL_RSA
67OP_MICROSOFT_SESS_ID_BUG = _lib.SSL_OP_MICROSOFT_SESS_ID_BUG
68OP_NETSCAPE_CHALLENGE_BUG = _lib.SSL_OP_NETSCAPE_CHALLENGE_BUG
69OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG = _lib.SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG
70OP_SSLREF2_REUSE_CERT_TYPE_BUG = _lib.SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG
71OP_MICROSOFT_BIG_SSLV3_BUFFER = _lib.SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER
Jean-Paul Calderone0d7e8a12014-01-08 16:54:13 -050072try:
73 OP_MSIE_SSLV2_RSA_PADDING = _lib.SSL_OP_MSIE_SSLV2_RSA_PADDING
74except AttributeError:
75 pass
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050076OP_SSLEAY_080_CLIENT_DH_BUG = _lib.SSL_OP_SSLEAY_080_CLIENT_DH_BUG
77OP_TLS_D5_BUG = _lib.SSL_OP_TLS_D5_BUG
78OP_TLS_BLOCK_PADDING_BUG = _lib.SSL_OP_TLS_BLOCK_PADDING_BUG
79OP_DONT_INSERT_EMPTY_FRAGMENTS = _lib.SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
80OP_CIPHER_SERVER_PREFERENCE = _lib.SSL_OP_CIPHER_SERVER_PREFERENCE
81OP_TLS_ROLLBACK_BUG = _lib.SSL_OP_TLS_ROLLBACK_BUG
82OP_PKCS1_CHECK_1 = _lib.SSL_OP_PKCS1_CHECK_1
83OP_PKCS1_CHECK_2 = _lib.SSL_OP_PKCS1_CHECK_2
84OP_NETSCAPE_CA_DN_BUG = _lib.SSL_OP_NETSCAPE_CA_DN_BUG
85OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG= _lib.SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG
Jean-Paul Calderonec1780342014-01-08 16:59:03 -050086try:
87 OP_NO_COMPRESSION = _lib.SSL_OP_NO_COMPRESSION
88except AttributeError:
89 pass
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -080090
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050091OP_NO_QUERY_MTU = _lib.SSL_OP_NO_QUERY_MTU
92OP_COOKIE_EXCHANGE = _lib.SSL_OP_COOKIE_EXCHANGE
Arturo Filastò5f8c7a82014-03-09 20:01:25 +010093try:
94 OP_NO_TICKET = _lib.SSL_OP_NO_TICKET
95except AttributeError:
96 pass
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -080097
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050098OP_ALL = _lib.SSL_OP_ALL
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080099
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500100VERIFY_PEER = _lib.SSL_VERIFY_PEER
101VERIFY_FAIL_IF_NO_PEER_CERT = _lib.SSL_VERIFY_FAIL_IF_NO_PEER_CERT
102VERIFY_CLIENT_ONCE = _lib.SSL_VERIFY_CLIENT_ONCE
103VERIFY_NONE = _lib.SSL_VERIFY_NONE
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -0800104
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500105SESS_CACHE_OFF = _lib.SSL_SESS_CACHE_OFF
106SESS_CACHE_CLIENT = _lib.SSL_SESS_CACHE_CLIENT
107SESS_CACHE_SERVER = _lib.SSL_SESS_CACHE_SERVER
108SESS_CACHE_BOTH = _lib.SSL_SESS_CACHE_BOTH
109SESS_CACHE_NO_AUTO_CLEAR = _lib.SSL_SESS_CACHE_NO_AUTO_CLEAR
110SESS_CACHE_NO_INTERNAL_LOOKUP = _lib.SSL_SESS_CACHE_NO_INTERNAL_LOOKUP
111SESS_CACHE_NO_INTERNAL_STORE = _lib.SSL_SESS_CACHE_NO_INTERNAL_STORE
112SESS_CACHE_NO_INTERNAL = _lib.SSL_SESS_CACHE_NO_INTERNAL
Jean-Paul Calderoned39a3f62013-03-04 12:23:51 -0800113
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500114SSL_ST_CONNECT = _lib.SSL_ST_CONNECT
115SSL_ST_ACCEPT = _lib.SSL_ST_ACCEPT
116SSL_ST_MASK = _lib.SSL_ST_MASK
117SSL_ST_INIT = _lib.SSL_ST_INIT
118SSL_ST_BEFORE = _lib.SSL_ST_BEFORE
119SSL_ST_OK = _lib.SSL_ST_OK
120SSL_ST_RENEGOTIATE = _lib.SSL_ST_RENEGOTIATE
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800121
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500122SSL_CB_LOOP = _lib.SSL_CB_LOOP
123SSL_CB_EXIT = _lib.SSL_CB_EXIT
124SSL_CB_READ = _lib.SSL_CB_READ
125SSL_CB_WRITE = _lib.SSL_CB_WRITE
126SSL_CB_ALERT = _lib.SSL_CB_ALERT
127SSL_CB_READ_ALERT = _lib.SSL_CB_READ_ALERT
128SSL_CB_WRITE_ALERT = _lib.SSL_CB_WRITE_ALERT
129SSL_CB_ACCEPT_LOOP = _lib.SSL_CB_ACCEPT_LOOP
130SSL_CB_ACCEPT_EXIT = _lib.SSL_CB_ACCEPT_EXIT
131SSL_CB_CONNECT_LOOP = _lib.SSL_CB_CONNECT_LOOP
132SSL_CB_CONNECT_EXIT = _lib.SSL_CB_CONNECT_EXIT
133SSL_CB_HANDSHAKE_START = _lib.SSL_CB_HANDSHAKE_START
134SSL_CB_HANDSHAKE_DONE = _lib.SSL_CB_HANDSHAKE_DONE
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800135
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500136class Error(Exception):
Jean-Paul Calderone511cde02013-12-29 10:31:13 -0500137 """
138 An error occurred in an `OpenSSL.SSL` API.
139 """
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500140
141
142
143_raise_current_error = partial(_exception_from_error_queue, Error)
144
145
146class WantReadError(Error):
147 pass
148
149
150
151class WantWriteError(Error):
152 pass
153
154
155
156class WantX509LookupError(Error):
157 pass
158
159
160
161class ZeroReturnError(Error):
162 pass
163
164
165
166class SysCallError(Error):
167 pass
168
169
Cory Benfield0ea76e72015-03-22 09:05:28 +0000170class _CallbackExceptionHelper(object):
171 """
172 A base class for wrapper classes that allow for intelligent exception
173 handling in OpenSSL callbacks.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500174
Jean-Paul Calderone1b172982015-03-22 19:37:11 -0400175 :ivar list _problems: Any exceptions that occurred while executing in a
176 context where they could not be raised in the normal way. Typically
177 this is because OpenSSL has called into some Python code and requires a
178 return value. The exceptions are saved to be raised later when it is
179 possible to do so.
Cory Benfield0ea76e72015-03-22 09:05:28 +0000180 """
Jean-Paul Calderone09540d72015-03-22 19:37:20 -0400181 def __init__(self):
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800182 self._problems = []
183
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800184
Cory Benfield0ea76e72015-03-22 09:05:28 +0000185 def raise_if_problem(self):
Jean-Paul Calderone1b172982015-03-22 19:37:11 -0400186 """
187 Raise an exception from the OpenSSL error queue or that was previously
188 captured whe running a callback.
189 """
Cory Benfield0ea76e72015-03-22 09:05:28 +0000190 if self._problems:
191 try:
192 _raise_current_error()
193 except Error:
194 pass
195 raise self._problems.pop(0)
196
197
198class _VerifyHelper(_CallbackExceptionHelper):
Jean-Paul Calderone1b172982015-03-22 19:37:11 -0400199 """
200 Wrap a callback such that it can be used as a certificate verification
201 callback.
202 """
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800203 def __init__(self, callback):
Jean-Paul Calderone837f4032015-03-22 17:38:28 -0400204 _CallbackExceptionHelper.__init__(self)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800205
206 @wraps(callback)
207 def wrapper(ok, store_ctx):
208 cert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500209 cert._x509 = _lib.X509_STORE_CTX_get_current_cert(store_ctx)
210 error_number = _lib.X509_STORE_CTX_get_error(store_ctx)
211 error_depth = _lib.X509_STORE_CTX_get_error_depth(store_ctx)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800212
Jean-Paul Calderone6a8cd112014-04-02 21:09:08 -0400213 index = _lib.SSL_get_ex_data_X509_STORE_CTX_idx()
214 ssl = _lib.X509_STORE_CTX_get_ex_data(store_ctx, index)
215 connection = Connection._reverse_mapping[ssl]
216
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800217 try:
218 result = callback(connection, cert, error_number, error_depth, ok)
219 except Exception as e:
220 self._problems.append(e)
221 return 0
222 else:
223 if result:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500224 _lib.X509_STORE_CTX_set_error(store_ctx, _lib.X509_V_OK)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800225 return 1
226 else:
227 return 0
228
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500229 self.callback = _ffi.callback(
230 "int (*)(int, X509_STORE_CTX *)", wrapper)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800231
232
Cory Benfield0ea76e72015-03-22 09:05:28 +0000233class _NpnAdvertiseHelper(_CallbackExceptionHelper):
Jean-Paul Calderone1b172982015-03-22 19:37:11 -0400234 """
235 Wrap a callback such that it can be used as an NPN advertisement callback.
236 """
Cory Benfield0ea76e72015-03-22 09:05:28 +0000237 def __init__(self, callback):
Jean-Paul Calderone837f4032015-03-22 17:38:28 -0400238 _CallbackExceptionHelper.__init__(self)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800239
Cory Benfield0ea76e72015-03-22 09:05:28 +0000240 @wraps(callback)
241 def wrapper(ssl, out, outlen, arg):
242 try:
243 conn = Connection._reverse_mapping[ssl]
244 protos = callback(conn)
245
246 # Join the protocols into a Python bytestring, length-prefixing
247 # each element.
248 protostr = b''.join(
249 chain.from_iterable((int2byte(len(p)), p) for p in protos)
250 )
251
252 # Save our callback arguments on the connection object. This is
253 # done to make sure that they don't get freed before OpenSSL
254 # uses them. Then, return them appropriately in the output
255 # parameters.
256 conn._npn_advertise_callback_args = [
257 _ffi.new("unsigned int *", len(protostr)),
258 _ffi.new("unsigned char[]", protostr),
259 ]
260 outlen[0] = conn._npn_advertise_callback_args[0][0]
261 out[0] = conn._npn_advertise_callback_args[1]
262 return 0
263 except Exception as e:
264 self._problems.append(e)
265 return 2 # SSL_TLSEXT_ERR_ALERT_FATAL
266
267 self.callback = _ffi.callback(
268 "int (*)(SSL *, const unsigned char **, unsigned int *, void *)",
269 wrapper
270 )
271
272
273class _NpnSelectHelper(_CallbackExceptionHelper):
Jean-Paul Calderone1b172982015-03-22 19:37:11 -0400274 """
275 Wrap a callback such that it can be used as an NPN selection callback.
276 """
Cory Benfield0ea76e72015-03-22 09:05:28 +0000277 def __init__(self, callback):
Jean-Paul Calderone837f4032015-03-22 17:38:28 -0400278 _CallbackExceptionHelper.__init__(self)
Cory Benfield0ea76e72015-03-22 09:05:28 +0000279
280 @wraps(callback)
281 def wrapper(ssl, out, outlen, in_, inlen, arg):
282 try:
283 conn = Connection._reverse_mapping[ssl]
284
285 # The string passed to us is actually made up of multiple
286 # length-prefixed bytestrings. We need to split that into a
287 # list.
288 instr = _ffi.buffer(in_, inlen)[:]
289 protolist = []
290 while instr:
291 l = indexbytes(instr, 0)
292 proto = instr[1:l+1]
293 protolist.append(proto)
294 instr = instr[l+1:]
295
296 # Call the callback
297 outstr = callback(conn, protolist)
298
299 # Save our callback arguments on the connection object. This is
300 # done to make sure that they don't get freed before OpenSSL
301 # uses them. Then, return them appropriately in the output
302 # parameters.
303 conn._npn_select_callback_args = [
304 _ffi.new("unsigned char *", len(outstr)),
305 _ffi.new("unsigned char[]", outstr),
306 ]
307 outlen[0] = conn._npn_select_callback_args[0][0]
308 out[0] = conn._npn_select_callback_args[1]
309 return 0
310 except Exception as e:
311 self._problems.append(e)
312 return 2 # SSL_TLSEXT_ERR_ALERT_FATAL
313
314 self.callback = _ffi.callback(
315 "int (*)(SSL *, unsigned char **, unsigned char *, "
316 "const unsigned char *, unsigned int, void *)",
317 wrapper
318 )
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800319
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800320
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800321def _asFileDescriptor(obj):
322 fd = None
Konstantinos Koukopoulosc8b13ea2014-01-28 00:21:50 -0800323 if not isinstance(obj, integer_types):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800324 meth = getattr(obj, "fileno", None)
325 if meth is not None:
326 obj = meth()
327
Konstantinos Koukopoulosc8b13ea2014-01-28 00:21:50 -0800328 if isinstance(obj, integer_types):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800329 fd = obj
330
Konstantinos Koukopoulosc8b13ea2014-01-28 00:21:50 -0800331 if not isinstance(fd, integer_types):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800332 raise TypeError("argument must be an int, or have a fileno() method.")
333 elif fd < 0:
334 raise ValueError(
335 "file descriptor cannot be a negative integer (%i)" % (fd,))
336
337 return fd
338
339
340
Jean-Paul Calderoned39a3f62013-03-04 12:23:51 -0800341def SSLeay_version(type):
342 """
343 Return a string describing the version of OpenSSL in use.
344
345 :param type: One of the SSLEAY_ constants defined in this module.
346 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500347 return _ffi.string(_lib.SSLeay_version(type))
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800348
349
350
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800351class Session(object):
352 pass
353
354
355
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800356class Context(object):
357 """
358 :py:obj:`OpenSSL.SSL.Context` instances define the parameters for setting up
359 new SSL connections.
360 """
361 _methods = {
Andrew Dunhamec84a0a2014-02-24 12:41:37 -0800362 SSLv2_METHOD: "SSLv2_method",
Jean-Paul Calderonebe2bb422013-12-29 07:34:08 -0500363 SSLv3_METHOD: "SSLv3_method",
364 SSLv23_METHOD: "SSLv23_method",
365 TLSv1_METHOD: "TLSv1_method",
366 TLSv1_1_METHOD: "TLSv1_1_method",
367 TLSv1_2_METHOD: "TLSv1_2_method",
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800368 }
Jean-Paul Calderonebe2bb422013-12-29 07:34:08 -0500369 _methods = dict(
370 (identifier, getattr(_lib, name))
371 for (identifier, name) in _methods.items()
372 if getattr(_lib, name, None) is not None)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800373
Jean-Paul Calderone63157872013-03-20 16:43:38 -0700374
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800375 def __init__(self, method):
376 """
377 :param method: One of SSLv2_METHOD, SSLv3_METHOD, SSLv23_METHOD, or
378 TLSv1_METHOD.
379 """
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -0500380 if not isinstance(method, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800381 raise TypeError("method must be an integer")
382
383 try:
384 method_func = self._methods[method]
385 except KeyError:
386 raise ValueError("No such protocol")
387
388 method_obj = method_func()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500389 if method_obj == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500390 # TODO: This is untested.
391 _raise_current_error()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800392
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500393 context = _lib.SSL_CTX_new(method_obj)
394 if context == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500395 # TODO: This is untested.
396 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500397 context = _ffi.gc(context, _lib.SSL_CTX_free)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800398
399 self._context = context
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800400 self._passphrase_helper = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800401 self._passphrase_callback = None
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800402 self._passphrase_userdata = None
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800403 self._verify_helper = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800404 self._verify_callback = None
405 self._info_callback = None
406 self._tlsext_servername_callback = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800407 self._app_data = None
Cory Benfield0ea76e72015-03-22 09:05:28 +0000408 self._npn_advertise_helper = None
Cory Benfield84a121e2014-03-31 20:30:25 +0100409 self._npn_advertise_callback = None
Cory Benfield0ea76e72015-03-22 09:05:28 +0000410 self._npn_select_helper = None
Cory Benfield84a121e2014-03-31 20:30:25 +0100411 self._npn_select_callback = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800412
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -0800413 # SSL_CTX_set_app_data(self->ctx, self);
414 # SSL_CTX_set_mode(self->ctx, SSL_MODE_ENABLE_PARTIAL_WRITE |
415 # SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
416 # SSL_MODE_AUTO_RETRY);
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500417 self.set_mode(_lib.SSL_MODE_ENABLE_PARTIAL_WRITE)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800418
419
420 def load_verify_locations(self, cafile, capath=None):
421 """
422 Let SSL know where we can find trusted certificates for the certificate
423 chain
424
Jean-Paul Calderone55f9e882015-04-12 09:31:03 -0400425 :param cafile: In which file we can find the certificates (``bytes`` or
426 ``unicode``).
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800427 :param capath: In which directory we can find the certificates
Jean-Paul Calderone55f9e882015-04-12 09:31:03 -0400428 (``bytes`` or ``unicode``).
429
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800430 :return: None
431 """
432 if cafile is None:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500433 cafile = _ffi.NULL
Jean-Paul Calderone55f9e882015-04-12 09:31:03 -0400434 else:
435 cafile = _path_string(cafile)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800436
437 if capath is None:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500438 capath = _ffi.NULL
Jean-Paul Calderone55f9e882015-04-12 09:31:03 -0400439 else:
440 capath = _path_string(capath)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800441
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500442 load_result = _lib.SSL_CTX_load_verify_locations(self._context, cafile, capath)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800443 if not load_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500444 _raise_current_error()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800445
446
447 def _wrap_callback(self, callback):
448 @wraps(callback)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800449 def wrapper(size, verify, userdata):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800450 return callback(size, verify, self._passphrase_userdata)
451 return _PassphraseHelper(
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800452 FILETYPE_PEM, wrapper, more_args=True, truncate=True)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800453
454
455 def set_passwd_cb(self, callback, userdata=None):
456 """
457 Set the passphrase callback
458
459 :param callback: The Python callback to use
460 :param userdata: (optional) A Python object which will be given as
461 argument to the callback
462 :return: None
463 """
464 if not callable(callback):
465 raise TypeError("callback must be callable")
466
467 self._passphrase_helper = self._wrap_callback(callback)
468 self._passphrase_callback = self._passphrase_helper.callback
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500469 _lib.SSL_CTX_set_default_passwd_cb(
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800470 self._context, self._passphrase_callback)
471 self._passphrase_userdata = userdata
472
473
474 def set_default_verify_paths(self):
475 """
476 Use the platform-specific CA certificate locations
477
478 :return: None
479 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500480 set_result = _lib.SSL_CTX_set_default_verify_paths(self._context)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800481 if not set_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500482 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500483 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800484
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800485
486 def use_certificate_chain_file(self, certfile):
487 """
488 Load a certificate chain from a file
489
Jean-Paul Calderoneb6f8a792015-04-13 10:10:06 -0400490 :param certfile: The name of the certificate chain file (``bytes`` or
491 ``unicode``).
492
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800493 :return: None
494 """
Jean-Paul Calderoneaac43a32015-04-12 09:51:21 -0400495 certfile = _path_string(certfile)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800496
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500497 result = _lib.SSL_CTX_use_certificate_chain_file(self._context, certfile)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800498 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500499 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800500
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800501
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800502 def use_certificate_file(self, certfile, filetype=FILETYPE_PEM):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800503 """
504 Load a certificate from a file
505
Jean-Paul Calderoneb6f8a792015-04-13 10:10:06 -0400506 :param certfile: The name of the certificate file (``bytes`` or
507 ``unicode``).
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800508 :param filetype: (optional) The encoding of the file, default is PEM
Jean-Paul Calderoneb6f8a792015-04-13 10:10:06 -0400509
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800510 :return: None
511 """
Jean-Paul Calderoned57a7b62015-04-12 09:57:36 -0400512 certfile = _path_string(certfile)
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -0500513 if not isinstance(filetype, integer_types):
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800514 raise TypeError("filetype must be an integer")
515
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500516 use_result = _lib.SSL_CTX_use_certificate_file(self._context, certfile, filetype)
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800517 if not use_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500518 _raise_current_error()
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800519
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800520
521 def use_certificate(self, cert):
522 """
523 Load a certificate from a X509 object
524
525 :param cert: The X509 object
526 :return: None
527 """
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800528 if not isinstance(cert, X509):
529 raise TypeError("cert must be an X509 instance")
530
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500531 use_result = _lib.SSL_CTX_use_certificate(self._context, cert._x509)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800532 if not use_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500533 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800534
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800535
536 def add_extra_chain_cert(self, certobj):
537 """
538 Add certificate to chain
539
540 :param certobj: The X509 certificate object to add to the chain
541 :return: None
542 """
543 if not isinstance(certobj, X509):
544 raise TypeError("certobj must be an X509 instance")
545
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500546 copy = _lib.X509_dup(certobj._x509)
547 add_result = _lib.SSL_CTX_add_extra_chain_cert(self._context, copy)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800548 if not add_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500549 # TODO: This is untested.
550 _lib.X509_free(copy)
551 _raise_current_error()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800552
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800553
554 def _raise_passphrase_exception(self):
555 if self._passphrase_helper is None:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500556 _raise_current_error()
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800557 exception = self._passphrase_helper.raise_if_problem(Error)
558 if exception is not None:
559 raise exception
560
561
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800562 def use_privatekey_file(self, keyfile, filetype=_unspecified):
563 """
564 Load a private key from a file
565
Jean-Paul Calderoneb6f8a792015-04-13 10:10:06 -0400566 :param keyfile: The name of the key file (``bytes`` or ``unicode``)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800567 :param filetype: (optional) The encoding of the file, default is PEM
Jean-Paul Calderoneb6f8a792015-04-13 10:10:06 -0400568
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800569 :return: None
570 """
Jean-Paul Calderone69a4e5b2015-04-12 10:04:28 -0400571 keyfile = _path_string(keyfile)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800572
573 if filetype is _unspecified:
574 filetype = FILETYPE_PEM
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -0500575 elif not isinstance(filetype, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800576 raise TypeError("filetype must be an integer")
577
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500578 use_result = _lib.SSL_CTX_use_PrivateKey_file(
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800579 self._context, keyfile, filetype)
580 if not use_result:
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800581 self._raise_passphrase_exception()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800582
583
584 def use_privatekey(self, pkey):
585 """
586 Load a private key from a PKey object
587
588 :param pkey: The PKey object
589 :return: None
590 """
591 if not isinstance(pkey, PKey):
592 raise TypeError("pkey must be a PKey instance")
593
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500594 use_result = _lib.SSL_CTX_use_PrivateKey(self._context, pkey._pkey)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800595 if not use_result:
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800596 self._raise_passphrase_exception()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800597
598
599 def check_privatekey(self):
600 """
601 Check that the private key and certificate match up
602
603 :return: None (raises an exception if something's wrong)
604 """
Jean-Paul Calderonea0344922014-12-11 14:02:31 -0500605 if not _lib.SSL_CTX_check_private_key(self._context):
606 _raise_current_error()
607
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800608
609 def load_client_ca(self, cafile):
610 """
611 Load the trusted certificates that will be sent to the client (basically
612 telling the client "These are the guys I trust"). Does not actually
613 imply any of the certificates are trusted; that must be configured
614 separately.
615
616 :param cafile: The name of the certificates file
617 :return: None
618 """
619
620 def set_session_id(self, buf):
621 """
622 Set the session identifier. This is needed if you want to do session
623 resumption.
624
625 :param buf: A Python object that can be safely converted to a string
626 :returns: None
627 """
628
629 def set_session_cache_mode(self, mode):
630 """
631 Enable/disable session caching and specify the mode used.
632
633 :param mode: One or more of the SESS_CACHE_* flags (combine using
634 bitwise or)
635 :returns: The previously set caching mode.
636 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500637 if not isinstance(mode, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800638 raise TypeError("mode must be an integer")
639
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500640 return _lib.SSL_CTX_set_session_cache_mode(self._context, mode)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800641
642
643 def get_session_cache_mode(self):
644 """
645 :returns: The currently used cache mode.
646 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500647 return _lib.SSL_CTX_get_session_cache_mode(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800648
649
650 def set_verify(self, mode, callback):
651 """
652 Set the verify mode and verify callback
653
654 :param mode: The verify mode, this is either VERIFY_NONE or
655 VERIFY_PEER combined with possible other flags
656 :param callback: The Python callback to use
657 :return: None
658
659 See SSL_CTX_set_verify(3SSL) for further details.
660 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500661 if not isinstance(mode, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800662 raise TypeError("mode must be an integer")
663
664 if not callable(callback):
665 raise TypeError("callback must be callable")
666
Jean-Paul Calderone6a8cd112014-04-02 21:09:08 -0400667 self._verify_helper = _VerifyHelper(callback)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800668 self._verify_callback = self._verify_helper.callback
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500669 _lib.SSL_CTX_set_verify(self._context, mode, self._verify_callback)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800670
671
672 def set_verify_depth(self, depth):
673 """
674 Set the verify depth
675
676 :param depth: An integer specifying the verify depth
677 :return: None
678 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500679 if not isinstance(depth, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800680 raise TypeError("depth must be an integer")
681
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500682 _lib.SSL_CTX_set_verify_depth(self._context, depth)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800683
684
685 def get_verify_mode(self):
686 """
687 Get the verify mode
688
689 :return: The verify mode
690 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500691 return _lib.SSL_CTX_get_verify_mode(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800692
693
694 def get_verify_depth(self):
695 """
696 Get the verify depth
697
698 :return: The verify depth
699 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500700 return _lib.SSL_CTX_get_verify_depth(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800701
702
703 def load_tmp_dh(self, dhfile):
704 """
705 Load parameters for Ephemeral Diffie-Hellman
706
Jean-Paul Calderone4e0c43f2015-04-13 10:15:17 -0400707 :param dhfile: The file to load EDH parameters from (``bytes`` or
708 ``unicode``).
709
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800710 :return: None
711 """
Jean-Paul Calderone9e1c1dd2015-04-12 10:13:13 -0400712 dhfile = _path_string(dhfile)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800713
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -0500714 bio = _lib.BIO_new_file(dhfile, b"r")
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500715 if bio == _ffi.NULL:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500716 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500717 bio = _ffi.gc(bio, _lib.BIO_free)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800718
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500719 dh = _lib.PEM_read_bio_DHparams(bio, _ffi.NULL, _ffi.NULL, _ffi.NULL)
720 dh = _ffi.gc(dh, _lib.DH_free)
721 _lib.SSL_CTX_set_tmp_dh(self._context, dh)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800722
723
Jean-Paul Calderone3e4e3352014-04-19 09:28:28 -0400724 def set_tmp_ecdh(self, curve):
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600725 """
Andy Lutomirski76a61332014-03-12 15:02:56 -0700726 Select a curve to use for ECDHE key exchange.
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600727
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -0400728 :param curve: A curve object to use as returned by either
729 :py:meth:`OpenSSL.crypto.get_elliptic_curve` or
730 :py:meth:`OpenSSL.crypto.get_elliptic_curves`.
Andy Lutomirskif05a2732014-03-13 17:22:25 -0700731
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600732 :return: None
733 """
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -0400734 _lib.SSL_CTX_set_tmp_ecdh(self._context, curve._to_EC_KEY())
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600735
736
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800737 def set_cipher_list(self, cipher_list):
738 """
739 Change the cipher list
740
741 :param cipher_list: A cipher list, see ciphers(1)
742 :return: None
743 """
Jean-Paul Calderone63eab692014-01-18 10:19:56 -0500744 if isinstance(cipher_list, _text_type):
745 cipher_list = cipher_list.encode("ascii")
746
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800747 if not isinstance(cipher_list, bytes):
Jean-Paul Calderone63eab692014-01-18 10:19:56 -0500748 raise TypeError("cipher_list must be bytes or unicode")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800749
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500750 result = _lib.SSL_CTX_set_cipher_list(self._context, cipher_list)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800751 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500752 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800753
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800754
755 def set_client_ca_list(self, certificate_authorities):
756 """
757 Set the list of preferred client certificate signers for this server context.
758
759 This list of certificate authorities will be sent to the client when the
760 server requests a client certificate.
761
762 :param certificate_authorities: a sequence of X509Names.
763 :return: None
764 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500765 name_stack = _lib.sk_X509_NAME_new_null()
766 if name_stack == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500767 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500768 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800769
770 try:
771 for ca_name in certificate_authorities:
772 if not isinstance(ca_name, X509Name):
773 raise TypeError(
774 "client CAs must be X509Name objects, not %s objects" % (
775 type(ca_name).__name__,))
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500776 copy = _lib.X509_NAME_dup(ca_name._name)
777 if copy == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500778 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500779 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500780 push_result = _lib.sk_X509_NAME_push(name_stack, copy)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800781 if not push_result:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500782 _lib.X509_NAME_free(copy)
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500783 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800784 except:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500785 _lib.sk_X509_NAME_free(name_stack)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800786 raise
787
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500788 _lib.SSL_CTX_set_client_CA_list(self._context, name_stack)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800789
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800790
791 def add_client_ca(self, certificate_authority):
792 """
793 Add the CA certificate to the list of preferred signers for this context.
794
795 The list of certificate authorities will be sent to the client when the
796 server requests a client certificate.
797
798 :param certificate_authority: certificate authority's X509 certificate.
799 :return: None
800 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800801 if not isinstance(certificate_authority, X509):
802 raise TypeError("certificate_authority must be an X509 instance")
803
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500804 add_result = _lib.SSL_CTX_add_client_CA(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800805 self._context, certificate_authority._x509)
806 if not add_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500807 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500808 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800809
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800810
811 def set_timeout(self, timeout):
812 """
813 Set session timeout
814
815 :param timeout: The timeout in seconds
816 :return: The previous session timeout
817 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500818 if not isinstance(timeout, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800819 raise TypeError("timeout must be an integer")
820
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500821 return _lib.SSL_CTX_set_timeout(self._context, timeout)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800822
823
824 def get_timeout(self):
825 """
826 Get the session timeout
827
828 :return: The session timeout
829 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500830 return _lib.SSL_CTX_get_timeout(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800831
832
833 def set_info_callback(self, callback):
834 """
835 Set the info callback
836
837 :param callback: The Python callback to use
838 :return: None
839 """
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800840 @wraps(callback)
841 def wrapper(ssl, where, return_code):
Jean-Paul Calderonef2bbc9c2014-02-02 10:59:14 -0500842 callback(Connection._reverse_mapping[ssl], where, return_code)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500843 self._info_callback = _ffi.callback(
844 "void (*)(const SSL *, int, int)", wrapper)
845 _lib.SSL_CTX_set_info_callback(self._context, self._info_callback)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800846
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800847
848 def get_app_data(self):
849 """
850 Get the application data (supplied via set_app_data())
851
852 :return: The application data
853 """
854 return self._app_data
855
856
857 def set_app_data(self, data):
858 """
859 Set the application data (will be returned from get_app_data())
860
861 :param data: Any Python object
862 :return: None
863 """
864 self._app_data = data
865
866
867 def get_cert_store(self):
868 """
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500869 Get the certificate store for the context.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800870
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500871 :return: A X509Store object or None if it does not have one.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800872 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500873 store = _lib.SSL_CTX_get_cert_store(self._context)
874 if store == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500875 # TODO: This is untested.
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800876 return None
877
878 pystore = X509Store.__new__(X509Store)
879 pystore._store = store
880 return pystore
881
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800882
883 def set_options(self, options):
884 """
885 Add options. Options set before are not cleared!
886
887 :param options: The options to add.
888 :return: The new option bitmask.
889 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500890 if not isinstance(options, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800891 raise TypeError("options must be an integer")
892
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500893 return _lib.SSL_CTX_set_options(self._context, options)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800894
895
896 def set_mode(self, mode):
897 """
898 Add modes via bitmask. Modes set before are not cleared!
899
900 :param mode: The mode to add.
901 :return: The new mode bitmask.
902 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500903 if not isinstance(mode, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800904 raise TypeError("mode must be an integer")
905
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500906 return _lib.SSL_CTX_set_mode(self._context, mode)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800907
908
909 def set_tlsext_servername_callback(self, callback):
910 """
911 Specify a callback function to be called when clients specify a server name.
912
913 :param callback: The callback function. It will be invoked with one
914 argument, the Connection instance.
915 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800916 @wraps(callback)
917 def wrapper(ssl, alert, arg):
918 callback(Connection._reverse_mapping[ssl])
919 return 0
920
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500921 self._tlsext_servername_callback = _ffi.callback(
922 "int (*)(const SSL *, int *, void *)", wrapper)
923 _lib.SSL_CTX_set_tlsext_servername_callback(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800924 self._context, self._tlsext_servername_callback)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800925
Cory Benfield84a121e2014-03-31 20:30:25 +0100926
927 def set_npn_advertise_callback(self, callback):
928 """
Cory Benfieldbe3e7b82014-05-10 09:48:55 +0100929 Specify a callback function that will be called when offering `Next
930 Protocol Negotiation
931 <https://technotes.googlecode.com/git/nextprotoneg.html>`_ as a server.
Cory Benfield84a121e2014-03-31 20:30:25 +0100932
933 :param callback: The callback function. It will be invoked with one
Cory Benfieldbe3e7b82014-05-10 09:48:55 +0100934 argument, the Connection instance. It should return a list of
935 bytestrings representing the advertised protocols, like
936 ``[b'http/1.1', b'spdy/2']``.
Cory Benfield84a121e2014-03-31 20:30:25 +0100937 """
Cory Benfield0ea76e72015-03-22 09:05:28 +0000938 self._npn_advertise_helper = _NpnAdvertiseHelper(callback)
939 self._npn_advertise_callback = self._npn_advertise_helper.callback
Cory Benfield84a121e2014-03-31 20:30:25 +0100940 _lib.SSL_CTX_set_next_protos_advertised_cb(
941 self._context, self._npn_advertise_callback, _ffi.NULL)
942
943
944 def set_npn_select_callback(self, callback):
945 """
946 Specify a callback function that will be called when a server offers
947 Next Protocol Negotiation options.
948
949 :param callback: The callback function. It will be invoked with two
950 arguments: the Connection, and a list of offered protocols as
Cory Benfieldbe3e7b82014-05-10 09:48:55 +0100951 bytestrings, e.g. ``[b'http/1.1', b'spdy/2']``. It should return
952 one of those bytestrings, the chosen protocol.
Cory Benfield84a121e2014-03-31 20:30:25 +0100953 """
Cory Benfield0ea76e72015-03-22 09:05:28 +0000954 self._npn_select_helper = _NpnSelectHelper(callback)
955 self._npn_select_callback = self._npn_select_helper.callback
Cory Benfield84a121e2014-03-31 20:30:25 +0100956 _lib.SSL_CTX_set_next_proto_select_cb(
957 self._context, self._npn_select_callback, _ffi.NULL)
958
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800959ContextType = Context
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800960
961
962
963class Connection(object):
964 """
965 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800966 _reverse_mapping = WeakValueDictionary()
967
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800968 def __init__(self, context, socket=None):
969 """
970 Create a new Connection object, using the given OpenSSL.SSL.Context
971 instance and socket.
972
973 :param context: An SSL Context to use for this connection
974 :param socket: The socket to use for transport layer
975 """
976 if not isinstance(context, Context):
977 raise TypeError("context must be a Context instance")
978
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500979 ssl = _lib.SSL_new(context._context)
980 self._ssl = _ffi.gc(ssl, _lib.SSL_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800981 self._context = context
982
Cory Benfieldbe3e7b82014-05-10 09:48:55 +0100983 # References to strings used for Next Protocol Negotiation. OpenSSL's
984 # header files suggest that these might get copied at some point, but
985 # doesn't specify when, so we store them here to make sure they don't
986 # get freed before OpenSSL uses them.
987 self._npn_advertise_callback_args = None
988 self._npn_select_callback_args = None
989
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800990 self._reverse_mapping[self._ssl] = self
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800991
992 if socket is None:
993 self._socket = None
Jean-Paul Calderone73b15c22013-03-05 18:30:39 -0800994 # Don't set up any gc for these, SSL_free will take care of them.
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500995 self._into_ssl = _lib.BIO_new(_lib.BIO_s_mem())
996 self._from_ssl = _lib.BIO_new(_lib.BIO_s_mem())
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800997
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500998 if self._into_ssl == _ffi.NULL or self._from_ssl == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500999 # TODO: This is untested.
1000 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001001
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001002 _lib.SSL_set_bio(self._ssl, self._into_ssl, self._from_ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001003 else:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001004 self._into_ssl = None
1005 self._from_ssl = None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001006 self._socket = socket
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001007 set_result = _lib.SSL_set_fd(self._ssl, _asFileDescriptor(self._socket))
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001008 if not set_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001009 # TODO: This is untested.
1010 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001011
1012
1013 def __getattr__(self, name):
1014 """
1015 Look up attributes on the wrapped socket object if they are not found on
1016 the Connection object.
1017 """
1018 return getattr(self._socket, name)
1019
1020
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001021 def _raise_ssl_error(self, ssl, result):
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -08001022 if self._context._verify_helper is not None:
1023 self._context._verify_helper.raise_if_problem()
Cory Benfield0ea76e72015-03-22 09:05:28 +00001024 if self._context._npn_advertise_helper is not None:
1025 self._context._npn_advertise_helper.raise_if_problem()
1026 if self._context._npn_select_helper is not None:
1027 self._context._npn_select_helper.raise_if_problem()
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -08001028
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001029 error = _lib.SSL_get_error(ssl, result)
1030 if error == _lib.SSL_ERROR_WANT_READ:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001031 raise WantReadError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001032 elif error == _lib.SSL_ERROR_WANT_WRITE:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001033 raise WantWriteError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001034 elif error == _lib.SSL_ERROR_ZERO_RETURN:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001035 raise ZeroReturnError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001036 elif error == _lib.SSL_ERROR_WANT_X509_LOOKUP:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001037 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001038 raise WantX509LookupError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001039 elif error == _lib.SSL_ERROR_SYSCALL:
1040 if _lib.ERR_peek_error() == 0:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001041 if result < 0:
Konstantinos Koukopoulos541150d2014-01-31 01:00:19 +02001042 if platform == "win32":
1043 errno = _ffi.getwinerror()[0]
1044 else:
1045 errno = _ffi.errno
1046 raise SysCallError(errno, errorcode[errno])
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001047 else:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001048 raise SysCallError(-1, "Unexpected EOF")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001049 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001050 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001051 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001052 elif error == _lib.SSL_ERROR_NONE:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001053 pass
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001054 else:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001055 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001056
1057
1058 def get_context(self):
1059 """
1060 Get session context
1061 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001062 return self._context
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001063
1064
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001065 def set_context(self, context):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001066 """
1067 Switch this connection to a new session context
1068
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001069 :param context: A :py:class:`Context` instance giving the new session
1070 context to use.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001071 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001072 if not isinstance(context, Context):
1073 raise TypeError("context must be a Context instance")
1074
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001075 _lib.SSL_set_SSL_CTX(self._ssl, context._context)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001076 self._context = context
1077
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001078
1079 def get_servername(self):
1080 """
1081 Retrieve the servername extension value if provided in the client hello
1082 message, or None if there wasn't one.
1083
1084 :return: A byte string giving the server name or :py:data:`None`.
1085 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001086 name = _lib.SSL_get_servername(self._ssl, _lib.TLSEXT_NAMETYPE_host_name)
1087 if name == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001088 return None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001089
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001090 return _ffi.string(name)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001091
1092
1093 def set_tlsext_host_name(self, name):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001094 """
1095 Set the value of the servername extension to send in the client hello.
1096
1097 :param name: A byte string giving the name.
1098 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001099 if not isinstance(name, bytes):
1100 raise TypeError("name must be a byte string")
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001101 elif b"\0" in name:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001102 raise TypeError("name must not contain NUL byte")
1103
1104 # XXX I guess this can fail sometimes?
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001105 _lib.SSL_set_tlsext_host_name(self._ssl, name)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001106
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001107
1108 def pending(self):
1109 """
1110 Get the number of bytes that can be safely read from the connection
1111
1112 :return: The number of bytes available in the receive buffer.
1113 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001114 return _lib.SSL_pending(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001115
1116
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001117 def send(self, buf, flags=0):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001118 """
1119 Send data on the connection. NOTE: If you get one of the WantRead,
1120 WantWrite or WantX509Lookup exceptions on this, you have to call the
1121 method again with the SAME buffer.
1122
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001123 :param buf: The string, buffer or memoryview to send
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001124 :param flags: (optional) Included for compatibility with the socket
1125 API, the value is ignored
1126 :return: The number of bytes written
1127 """
Jean-Paul Calderone8fb53182013-12-30 08:35:49 -05001128 if isinstance(buf, _memoryview):
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -08001129 buf = buf.tobytes()
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001130 if isinstance(buf, _buffer):
1131 buf = str(buf)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001132 if not isinstance(buf, bytes):
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001133 raise TypeError("data must be a memoryview, buffer or byte string")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001134
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001135 result = _lib.SSL_write(self._ssl, buf, len(buf))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001136 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001137 return result
1138 write = send
1139
1140
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001141 def sendall(self, buf, flags=0):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001142 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001143 Send "all" data on the connection. This calls send() repeatedly until
1144 all data is sent. If an error occurs, it's impossible to tell how much
1145 data has been sent.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001146
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001147 :param buf: The string, buffer or memoryview to send
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001148 :param flags: (optional) Included for compatibility with the socket
1149 API, the value is ignored
1150 :return: The number of bytes written
1151 """
Jean-Paul Calderone8fb53182013-12-30 08:35:49 -05001152 if isinstance(buf, _memoryview):
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -08001153 buf = buf.tobytes()
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001154 if isinstance(buf, _buffer):
1155 buf = str(buf)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001156 if not isinstance(buf, bytes):
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001157 raise TypeError("buf must be a memoryview, buffer or byte string")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001158
1159 left_to_send = len(buf)
1160 total_sent = 0
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001161 data = _ffi.new("char[]", buf)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001162
1163 while left_to_send:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001164 result = _lib.SSL_write(self._ssl, data + total_sent, left_to_send)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001165 self._raise_ssl_error(self._ssl, result)
1166 total_sent += result
1167 left_to_send -= result
1168
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001169
1170 def recv(self, bufsiz, flags=None):
1171 """
1172 Receive data on the connection. NOTE: If you get one of the WantRead,
1173 WantWrite or WantX509Lookup exceptions on this, you have to call the
1174 method again with the SAME buffer.
1175
1176 :param bufsiz: The maximum number of bytes to read
1177 :param flags: (optional) Included for compatibility with the socket
1178 API, the value is ignored
1179 :return: The string read from the Connection
1180 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001181 buf = _ffi.new("char[]", bufsiz)
1182 result = _lib.SSL_read(self._ssl, buf, bufsiz)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001183 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001184 return _ffi.buffer(buf, result)[:]
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001185 read = recv
1186
1187
Cory Benfield62d10332014-06-15 10:03:41 +01001188 def recv_into(self, buffer, nbytes=None, flags=None):
1189 """
1190 Receive data on the connection and store the data into a buffer rather
1191 than creating a new string.
1192
1193 :param buffer: The buffer to copy into.
1194 :param nbytes: (optional) The maximum number of bytes to read into the
1195 buffer. If not present, defaults to the size of the buffer. If
1196 larger than the size of the buffer, is reduced to the size of the
1197 buffer.
1198 :param flags: (optional) Included for compatibility with the socket
1199 API, the value is ignored.
1200 :return: The number of bytes read into the buffer.
1201 """
1202 if nbytes is None:
1203 nbytes = len(buffer)
1204 else:
1205 nbytes = min(nbytes, len(buffer))
1206
1207 # We need to create a temporary buffer. This is annoying, it would be
1208 # better if we could pass memoryviews straight into the SSL_read call,
1209 # but right now we can't. Revisit this if CFFI gets that ability.
1210 buf = _ffi.new("char[]", nbytes)
1211 result = _lib.SSL_read(self._ssl, buf, nbytes)
1212 self._raise_ssl_error(self._ssl, result)
1213
1214 # This strange line is all to avoid a memory copy. The buffer protocol
1215 # should allow us to assign a CFFI buffer to the LHS of this line, but
1216 # on CPython 3.3+ that segfaults. As a workaround, we can temporarily
1217 # wrap it in a memoryview, except on Python 2.6 which doesn't have a
1218 # memoryview type.
1219 try:
1220 buffer[:result] = memoryview(_ffi.buffer(buf, result))
1221 except NameError:
1222 buffer[:result] = _ffi.buffer(buf, result)
1223
1224 return result
1225
1226
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001227 def _handle_bio_errors(self, bio, result):
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001228 if _lib.BIO_should_retry(bio):
1229 if _lib.BIO_should_read(bio):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001230 raise WantReadError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001231 elif _lib.BIO_should_write(bio):
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001232 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001233 raise WantWriteError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001234 elif _lib.BIO_should_io_special(bio):
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001235 # TODO: This is untested. I think io_special means the socket
1236 # BIO has a not-yet connected socket.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001237 raise ValueError("BIO_should_io_special")
1238 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001239 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001240 raise ValueError("unknown bio failure")
1241 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001242 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001243 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001244
1245
1246 def bio_read(self, bufsiz):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001247 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001248 When using non-socket connections this function reads the "dirty" data
1249 that would have traveled away on the network.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001250
1251 :param bufsiz: The maximum number of bytes to read
1252 :return: The string read.
1253 """
Jean-Paul Calderone97e041d2013-03-05 21:03:12 -08001254 if self._from_ssl is None:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001255 raise TypeError("Connection sock was not None")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001256
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -05001257 if not isinstance(bufsiz, integer_types):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001258 raise TypeError("bufsiz must be an integer")
1259
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001260 buf = _ffi.new("char[]", bufsiz)
1261 result = _lib.BIO_read(self._from_ssl, buf, bufsiz)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001262 if result <= 0:
1263 self._handle_bio_errors(self._from_ssl, result)
1264
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001265 return _ffi.buffer(buf, result)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001266
1267
1268 def bio_write(self, buf):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001269 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001270 When using non-socket connections this function sends "dirty" data that
1271 would have traveled in on the network.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001272
1273 :param buf: The string to put into the memory BIO.
1274 :return: The number of bytes written
1275 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001276 if self._into_ssl is None:
1277 raise TypeError("Connection sock was not None")
1278
1279 if not isinstance(buf, bytes):
1280 raise TypeError("buf must be a byte string")
1281
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001282 result = _lib.BIO_write(self._into_ssl, buf, len(buf))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001283 if result <= 0:
1284 self._handle_bio_errors(self._into_ssl, result)
1285 return result
1286
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001287
1288 def renegotiate(self):
1289 """
1290 Renegotiate the session
1291
1292 :return: True if the renegotiation can be started, false otherwise
1293 """
1294
1295 def do_handshake(self):
1296 """
1297 Perform an SSL handshake (usually called after renegotiate() or one of
1298 set_*_state()). This can raise the same exceptions as send and recv.
1299
1300 :return: None.
1301 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001302 result = _lib.SSL_do_handshake(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001303 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001304
1305
1306 def renegotiate_pending(self):
1307 """
1308 Check if there's a renegotiation in progress, it will return false once
1309 a renegotiation is finished.
1310
1311 :return: Whether there's a renegotiation in progress
1312 """
1313
1314 def total_renegotiations(self):
1315 """
1316 Find out the total number of renegotiations.
1317
1318 :return: The number of renegotiations.
1319 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001320 return _lib.SSL_total_renegotiations(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001321
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001322
1323 def connect(self, addr):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001324 """
1325 Connect to remote host and set up client-side SSL
1326
1327 :param addr: A remote address
1328 :return: What the socket's connect method returns
1329 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001330 _lib.SSL_set_connect_state(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001331 return self._socket.connect(addr)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001332
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001333
1334 def connect_ex(self, addr):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001335 """
1336 Connect to remote host and set up client-side SSL. Note that if the socket's
1337 connect_ex method doesn't return 0, SSL won't be initialized.
1338
1339 :param addr: A remove address
1340 :return: What the socket's connect_ex method returns
1341 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001342 connect_ex = self._socket.connect_ex
1343 self.set_connect_state()
1344 return connect_ex(addr)
1345
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001346
1347 def accept(self):
1348 """
1349 Accept incoming connection and set up SSL on it
1350
1351 :return: A (conn,addr) pair where conn is a Connection and addr is an
1352 address
1353 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001354 client, addr = self._socket.accept()
1355 conn = Connection(self._context, client)
1356 conn.set_accept_state()
1357 return (conn, addr)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001358
1359
1360 def bio_shutdown(self):
1361 """
1362 When using non-socket connections this function signals end of
1363 data on the input for this connection.
1364
1365 :return: None
1366 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001367 if self._from_ssl is None:
1368 raise TypeError("Connection sock was not None")
1369
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001370 _lib.BIO_set_mem_eof_return(self._into_ssl, 0)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001371
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001372
1373 def shutdown(self):
1374 """
1375 Send closure alert
1376
1377 :return: True if the shutdown completed successfully (i.e. both sides
1378 have sent closure alerts), false otherwise (i.e. you have to
1379 wait for a ZeroReturnError on a recv() method call
1380 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001381 result = _lib.SSL_shutdown(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001382 if result < 0:
Paul Aurichbff1d1a2015-01-08 08:36:53 -08001383 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001384 elif result > 0:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001385 return True
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001386 else:
1387 return False
1388
1389
1390 def get_cipher_list(self):
1391 """
1392 Get the session cipher list
1393
1394 :return: A list of cipher strings
1395 """
1396 ciphers = []
1397 for i in count():
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001398 result = _lib.SSL_get_cipher_list(self._ssl, i)
1399 if result == _ffi.NULL:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001400 break
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001401 ciphers.append(_native(_ffi.string(result)))
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001402 return ciphers
1403
1404
1405 def get_client_ca_list(self):
1406 """
1407 Get CAs whose certificates are suggested for client authentication.
1408
1409 :return: If this is a server connection, a list of X509Names representing
1410 the acceptable CAs as set by :py:meth:`OpenSSL.SSL.Context.set_client_ca_list` or
1411 :py:meth:`OpenSSL.SSL.Context.add_client_ca`. If this is a client connection,
1412 the list of such X509Names sent by the server, or an empty list if that
1413 has not yet happened.
1414 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001415 ca_names = _lib.SSL_get_client_CA_list(self._ssl)
1416 if ca_names == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001417 # TODO: This is untested.
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001418 return []
1419
1420 result = []
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001421 for i in range(_lib.sk_X509_NAME_num(ca_names)):
1422 name = _lib.sk_X509_NAME_value(ca_names, i)
1423 copy = _lib.X509_NAME_dup(name)
1424 if copy == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001425 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001426 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001427
1428 pyname = X509Name.__new__(X509Name)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001429 pyname._name = _ffi.gc(copy, _lib.X509_NAME_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001430 result.append(pyname)
1431 return result
1432
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001433
1434 def makefile(self):
1435 """
1436 The makefile() method is not implemented, since there is no dup semantics
1437 for SSL connections
1438
Jean-Paul Calderone6749ec22014-04-17 16:30:21 -04001439 :raise: NotImplementedError
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001440 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001441 raise NotImplementedError("Cannot make file object of OpenSSL.SSL.Connection")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001442
1443
1444 def get_app_data(self):
1445 """
1446 Get application data
1447
1448 :return: The application data
1449 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001450 return self._app_data
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001451
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001452
1453 def set_app_data(self, data):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001454 """
1455 Set application data
1456
1457 :param data - The application data
1458 :return: None
1459 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001460 self._app_data = data
1461
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001462
1463 def get_shutdown(self):
1464 """
1465 Get shutdown state
1466
1467 :return: The shutdown state, a bitvector of SENT_SHUTDOWN, RECEIVED_SHUTDOWN.
1468 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001469 return _lib.SSL_get_shutdown(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001470
1471
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001472 def set_shutdown(self, state):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001473 """
1474 Set shutdown state
1475
1476 :param state - bitvector of SENT_SHUTDOWN, RECEIVED_SHUTDOWN.
1477 :return: None
1478 """
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -05001479 if not isinstance(state, integer_types):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001480 raise TypeError("state must be an integer")
1481
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001482 _lib.SSL_set_shutdown(self._ssl, state)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001483
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001484
1485 def state_string(self):
1486 """
1487 Get a verbose state description
1488
1489 :return: A string representing the state
1490 """
1491
1492 def server_random(self):
1493 """
1494 Get a copy of the server hello nonce.
1495
1496 :return: A string representing the state
1497 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001498 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001499 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001500 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001501 self._ssl.s3.server_random,
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001502 _lib.SSL3_RANDOM_SIZE)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001503
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001504
1505 def client_random(self):
1506 """
1507 Get a copy of the client hello nonce.
1508
1509 :return: A string representing the state
1510 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001511 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001512 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001513 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001514 self._ssl.s3.client_random,
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001515 _lib.SSL3_RANDOM_SIZE)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001516
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001517
1518 def master_key(self):
1519 """
1520 Get a copy of the master key.
1521
1522 :return: A string representing the state
1523 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001524 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001525 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001526 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001527 self._ssl.session.master_key,
1528 self._ssl.session.master_key_length)[:]
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001529
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001530
1531 def sock_shutdown(self, *args, **kwargs):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001532 """
1533 See shutdown(2)
1534
1535 :return: What the socket's shutdown() method returns
1536 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001537 return self._socket.shutdown(*args, **kwargs)
1538
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001539
1540 def get_peer_certificate(self):
1541 """
1542 Retrieve the other side's certificate (if any)
1543
1544 :return: The peer's certificate
1545 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001546 cert = _lib.SSL_get_peer_certificate(self._ssl)
1547 if cert != _ffi.NULL:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001548 pycert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001549 pycert._x509 = _ffi.gc(cert, _lib.X509_free)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001550 return pycert
1551 return None
1552
1553
1554 def get_peer_cert_chain(self):
1555 """
1556 Retrieve the other side's certificate (if any)
1557
1558 :return: A list of X509 instances giving the peer's certificate chain,
1559 or None if it does not have one.
1560 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001561 cert_stack = _lib.SSL_get_peer_cert_chain(self._ssl)
1562 if cert_stack == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001563 return None
1564
1565 result = []
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001566 for i in range(_lib.sk_X509_num(cert_stack)):
Jean-Paul Calderone73b15c22013-03-05 18:30:39 -08001567 # TODO could incref instead of dup here
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001568 cert = _lib.X509_dup(_lib.sk_X509_value(cert_stack, i))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001569 pycert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001570 pycert._x509 = _ffi.gc(cert, _lib.X509_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001571 result.append(pycert)
1572 return result
1573
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001574
1575 def want_read(self):
1576 """
1577 Checks if more data has to be read from the transport layer to complete an
1578 operation.
1579
1580 :return: True iff more data has to be read
1581 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001582 return _lib.SSL_want_read(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001583
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001584
1585 def want_write(self):
1586 """
1587 Checks if there is data to write to the transport layer to complete an
1588 operation.
1589
1590 :return: True iff there is data to write
1591 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001592 return _lib.SSL_want_write(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001593
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001594
1595 def set_accept_state(self):
1596 """
1597 Set the connection to work in server mode. The handshake will be handled
1598 automatically by read/write.
1599
1600 :return: None
1601 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001602 _lib.SSL_set_accept_state(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001603
1604
1605 def set_connect_state(self):
1606 """
1607 Set the connection to work in client mode. The handshake will be handled
1608 automatically by read/write.
1609
1610 :return: None
1611 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001612 _lib.SSL_set_connect_state(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001613
1614
1615 def get_session(self):
1616 """
1617 Returns the Session currently used.
1618
1619 @return: An instance of :py:class:`OpenSSL.SSL.Session` or :py:obj:`None` if
1620 no session exists.
1621 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001622 session = _lib.SSL_get1_session(self._ssl)
1623 if session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001624 return None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001625
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001626 pysession = Session.__new__(Session)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001627 pysession._session = _ffi.gc(session, _lib.SSL_SESSION_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001628 return pysession
1629
1630
1631 def set_session(self, session):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001632 """
1633 Set the session to be used when the TLS/SSL connection is established.
1634
1635 :param session: A Session instance representing the session to use.
1636 :returns: None
1637 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001638 if not isinstance(session, Session):
1639 raise TypeError("session must be a Session instance")
1640
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001641 result = _lib.SSL_set_session(self._ssl, session._session)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001642 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001643 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001644
Jean-Paul Calderonedbd76272014-03-29 18:09:40 -04001645
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001646 def _get_finished_message(self, function):
1647 """
1648 Helper to implement :py:meth:`get_finished` and
1649 :py:meth:`get_peer_finished`.
1650
1651 :param function: Either :py:data:`SSL_get_finished`: or
1652 :py:data:`SSL_get_peer_finished`.
1653
1654 :return: :py:data:`None` if the desired message has not yet been
1655 received, otherwise the contents of the message.
1656 :rtype: :py:class:`bytes` or :py:class:`NoneType`
1657 """
Jean-Paul Calderone01af9042014-03-30 11:40:42 -04001658 # The OpenSSL documentation says nothing about what might happen if the
1659 # count argument given is zero. Specifically, it doesn't say whether
1660 # the output buffer may be NULL in that case or not. Inspection of the
1661 # implementation reveals that it calls memcpy() unconditionally.
1662 # Section 7.1.4, paragraph 1 of the C standard suggests that
1663 # memcpy(NULL, source, 0) is not guaranteed to produce defined (let
1664 # alone desirable) behavior (though it probably does on just about
1665 # every implementation...)
1666 #
1667 # Allocate a tiny buffer to pass in (instead of just passing NULL as
1668 # one might expect) for the initial call so as to be safe against this
1669 # potentially undefined behavior.
1670 empty = _ffi.new("char[]", 0)
1671 size = function(self._ssl, empty, 0)
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001672 if size == 0:
1673 # No Finished message so far.
1674 return None
1675
1676 buf = _ffi.new("char[]", size)
1677 function(self._ssl, buf, size)
1678 return _ffi.buffer(buf, size)[:]
1679
1680
Fedor Brunner5747b932014-03-05 14:22:34 +01001681 def get_finished(self):
1682 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001683 Obtain the latest `handshake finished` message sent to the peer.
Fedor Brunner5747b932014-03-05 14:22:34 +01001684
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001685 :return: The contents of the message or :py:obj:`None` if the TLS
1686 handshake has not yet completed.
1687 :rtype: :py:class:`bytes` or :py:class:`NoneType`
Fedor Brunner5747b932014-03-05 14:22:34 +01001688 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001689 return self._get_finished_message(_lib.SSL_get_finished)
1690
Fedor Brunner5747b932014-03-05 14:22:34 +01001691
1692 def get_peer_finished(self):
1693 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001694 Obtain the latest `handshake finished` message received from the peer.
Fedor Brunner5747b932014-03-05 14:22:34 +01001695
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001696 :return: The contents of the message or :py:obj:`None` if the TLS
1697 handshake has not yet completed.
1698 :rtype: :py:class:`bytes` or :py:class:`NoneType`
Fedor Brunner5747b932014-03-05 14:22:34 +01001699 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001700 return self._get_finished_message(_lib.SSL_get_peer_finished)
Fedor Brunner5747b932014-03-05 14:22:34 +01001701
Jean-Paul Calderone7c556ef2014-03-30 10:45:00 -04001702
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001703 def get_cipher_name(self):
1704 """
1705 Obtain the name of the currently used cipher.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001706
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001707 :returns: The name of the currently used cipher or :py:obj:`None`
1708 if no connection has been established.
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001709 :rtype: :py:class:`unicode` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001710 """
1711 cipher = _lib.SSL_get_current_cipher(self._ssl)
1712 if cipher == _ffi.NULL:
1713 return None
1714 else:
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001715 name = _ffi.string(_lib.SSL_CIPHER_get_name(cipher))
1716 return name.decode("utf-8")
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001717
Jean-Paul Calderonedbd76272014-03-29 18:09:40 -04001718
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001719 def get_cipher_bits(self):
1720 """
1721 Obtain the number of secret bits of the currently used cipher.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001722
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001723 :returns: The number of secret bits of the currently used cipher
1724 or :py:obj:`None` if no connection has been established.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001725 :rtype: :py:class:`int` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001726 """
1727 cipher = _lib.SSL_get_current_cipher(self._ssl)
1728 if cipher == _ffi.NULL:
1729 return None
1730 else:
1731 return _lib.SSL_CIPHER_get_bits(cipher, _ffi.NULL)
1732
Jean-Paul Calderonedbd76272014-03-29 18:09:40 -04001733
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001734 def get_cipher_version(self):
1735 """
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001736 Obtain the protocol version of the currently used cipher.
1737
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001738 :returns: The protocol name of the currently used cipher
1739 or :py:obj:`None` if no connection has been established.
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001740 :rtype: :py:class:`unicode` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001741 """
1742 cipher = _lib.SSL_get_current_cipher(self._ssl)
1743 if cipher == _ffi.NULL:
1744 return None
1745 else:
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001746 version =_ffi.string(_lib.SSL_CIPHER_get_version(cipher))
1747 return version.decode("utf-8")
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001748
Cory Benfield84a121e2014-03-31 20:30:25 +01001749 def get_next_proto_negotiated(self):
1750 """
1751 Get the protocol that was negotiated by NPN.
1752 """
1753 data = _ffi.new("unsigned char **")
1754 data_len = _ffi.new("unsigned int *")
1755
1756 _lib.SSL_get0_next_proto_negotiated(self._ssl, data, data_len)
1757
Cory Benfieldcd010f62014-05-15 19:00:27 +01001758 return _ffi.buffer(data[0], data_len[0])[:]
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001759
1760
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001761ConnectionType = Connection
Jean-Paul Calderone11ed8e82014-01-18 10:21:50 -05001762
Jean-Paul Calderonefab157b2014-01-18 11:21:38 -05001763# This is similar to the initialization calls at the end of OpenSSL/crypto.py
1764# but is exercised mostly by the Context initializer.
Jean-Paul Calderone11ed8e82014-01-18 10:21:50 -05001765_lib.SSL_library_init()