blob: 1e40917fe342c0d3d4a1542b9d634beb37a4f2c5 [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
Cory Benfield12eae892014-06-07 15:42:56 +0100412 self._alpn_select_callback = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800413
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -0800414 # SSL_CTX_set_app_data(self->ctx, self);
415 # SSL_CTX_set_mode(self->ctx, SSL_MODE_ENABLE_PARTIAL_WRITE |
416 # SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
417 # SSL_MODE_AUTO_RETRY);
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500418 self.set_mode(_lib.SSL_MODE_ENABLE_PARTIAL_WRITE)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800419
420
421 def load_verify_locations(self, cafile, capath=None):
422 """
423 Let SSL know where we can find trusted certificates for the certificate
424 chain
425
Jean-Paul Calderone55f9e882015-04-12 09:31:03 -0400426 :param cafile: In which file we can find the certificates (``bytes`` or
427 ``unicode``).
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800428 :param capath: In which directory we can find the certificates
Jean-Paul Calderone55f9e882015-04-12 09:31:03 -0400429 (``bytes`` or ``unicode``).
430
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800431 :return: None
432 """
433 if cafile is None:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500434 cafile = _ffi.NULL
Jean-Paul Calderone55f9e882015-04-12 09:31:03 -0400435 else:
436 cafile = _path_string(cafile)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800437
438 if capath is None:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500439 capath = _ffi.NULL
Jean-Paul Calderone55f9e882015-04-12 09:31:03 -0400440 else:
441 capath = _path_string(capath)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800442
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500443 load_result = _lib.SSL_CTX_load_verify_locations(self._context, cafile, capath)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800444 if not load_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500445 _raise_current_error()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800446
447
448 def _wrap_callback(self, callback):
449 @wraps(callback)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800450 def wrapper(size, verify, userdata):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800451 return callback(size, verify, self._passphrase_userdata)
452 return _PassphraseHelper(
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800453 FILETYPE_PEM, wrapper, more_args=True, truncate=True)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800454
455
456 def set_passwd_cb(self, callback, userdata=None):
457 """
458 Set the passphrase callback
459
460 :param callback: The Python callback to use
461 :param userdata: (optional) A Python object which will be given as
462 argument to the callback
463 :return: None
464 """
465 if not callable(callback):
466 raise TypeError("callback must be callable")
467
468 self._passphrase_helper = self._wrap_callback(callback)
469 self._passphrase_callback = self._passphrase_helper.callback
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500470 _lib.SSL_CTX_set_default_passwd_cb(
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800471 self._context, self._passphrase_callback)
472 self._passphrase_userdata = userdata
473
474
475 def set_default_verify_paths(self):
476 """
477 Use the platform-specific CA certificate locations
478
479 :return: None
480 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500481 set_result = _lib.SSL_CTX_set_default_verify_paths(self._context)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800482 if not set_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500483 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500484 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800485
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800486
487 def use_certificate_chain_file(self, certfile):
488 """
489 Load a certificate chain from a file
490
Jean-Paul Calderoneb6f8a792015-04-13 10:10:06 -0400491 :param certfile: The name of the certificate chain file (``bytes`` or
492 ``unicode``).
493
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800494 :return: None
495 """
Jean-Paul Calderoneaac43a32015-04-12 09:51:21 -0400496 certfile = _path_string(certfile)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800497
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500498 result = _lib.SSL_CTX_use_certificate_chain_file(self._context, certfile)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800499 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500500 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800501
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800502
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800503 def use_certificate_file(self, certfile, filetype=FILETYPE_PEM):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800504 """
505 Load a certificate from a file
506
Jean-Paul Calderoneb6f8a792015-04-13 10:10:06 -0400507 :param certfile: The name of the certificate file (``bytes`` or
508 ``unicode``).
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800509 :param filetype: (optional) The encoding of the file, default is PEM
Jean-Paul Calderoneb6f8a792015-04-13 10:10:06 -0400510
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800511 :return: None
512 """
Jean-Paul Calderoned57a7b62015-04-12 09:57:36 -0400513 certfile = _path_string(certfile)
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -0500514 if not isinstance(filetype, integer_types):
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800515 raise TypeError("filetype must be an integer")
516
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500517 use_result = _lib.SSL_CTX_use_certificate_file(self._context, certfile, filetype)
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800518 if not use_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500519 _raise_current_error()
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800520
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800521
522 def use_certificate(self, cert):
523 """
524 Load a certificate from a X509 object
525
526 :param cert: The X509 object
527 :return: None
528 """
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800529 if not isinstance(cert, X509):
530 raise TypeError("cert must be an X509 instance")
531
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500532 use_result = _lib.SSL_CTX_use_certificate(self._context, cert._x509)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800533 if not use_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500534 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800535
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800536
537 def add_extra_chain_cert(self, certobj):
538 """
539 Add certificate to chain
540
541 :param certobj: The X509 certificate object to add to the chain
542 :return: None
543 """
544 if not isinstance(certobj, X509):
545 raise TypeError("certobj must be an X509 instance")
546
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500547 copy = _lib.X509_dup(certobj._x509)
548 add_result = _lib.SSL_CTX_add_extra_chain_cert(self._context, copy)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800549 if not add_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500550 # TODO: This is untested.
551 _lib.X509_free(copy)
552 _raise_current_error()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800553
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800554
555 def _raise_passphrase_exception(self):
556 if self._passphrase_helper is None:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500557 _raise_current_error()
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800558 exception = self._passphrase_helper.raise_if_problem(Error)
559 if exception is not None:
560 raise exception
561
562
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800563 def use_privatekey_file(self, keyfile, filetype=_unspecified):
564 """
565 Load a private key from a file
566
Jean-Paul Calderoneb6f8a792015-04-13 10:10:06 -0400567 :param keyfile: The name of the key file (``bytes`` or ``unicode``)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800568 :param filetype: (optional) The encoding of the file, default is PEM
Jean-Paul Calderoneb6f8a792015-04-13 10:10:06 -0400569
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800570 :return: None
571 """
Jean-Paul Calderone69a4e5b2015-04-12 10:04:28 -0400572 keyfile = _path_string(keyfile)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800573
574 if filetype is _unspecified:
575 filetype = FILETYPE_PEM
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -0500576 elif not isinstance(filetype, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800577 raise TypeError("filetype must be an integer")
578
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500579 use_result = _lib.SSL_CTX_use_PrivateKey_file(
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800580 self._context, keyfile, filetype)
581 if not use_result:
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800582 self._raise_passphrase_exception()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800583
584
585 def use_privatekey(self, pkey):
586 """
587 Load a private key from a PKey object
588
589 :param pkey: The PKey object
590 :return: None
591 """
592 if not isinstance(pkey, PKey):
593 raise TypeError("pkey must be a PKey instance")
594
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500595 use_result = _lib.SSL_CTX_use_PrivateKey(self._context, pkey._pkey)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800596 if not use_result:
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800597 self._raise_passphrase_exception()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800598
599
600 def check_privatekey(self):
601 """
602 Check that the private key and certificate match up
603
604 :return: None (raises an exception if something's wrong)
605 """
Jean-Paul Calderonea0344922014-12-11 14:02:31 -0500606 if not _lib.SSL_CTX_check_private_key(self._context):
607 _raise_current_error()
608
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800609
610 def load_client_ca(self, cafile):
611 """
612 Load the trusted certificates that will be sent to the client (basically
613 telling the client "These are the guys I trust"). Does not actually
614 imply any of the certificates are trusted; that must be configured
615 separately.
616
617 :param cafile: The name of the certificates file
618 :return: None
619 """
620
621 def set_session_id(self, buf):
622 """
623 Set the session identifier. This is needed if you want to do session
624 resumption.
625
626 :param buf: A Python object that can be safely converted to a string
627 :returns: None
628 """
629
630 def set_session_cache_mode(self, mode):
631 """
632 Enable/disable session caching and specify the mode used.
633
634 :param mode: One or more of the SESS_CACHE_* flags (combine using
635 bitwise or)
636 :returns: The previously set caching mode.
637 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500638 if not isinstance(mode, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800639 raise TypeError("mode must be an integer")
640
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500641 return _lib.SSL_CTX_set_session_cache_mode(self._context, mode)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800642
643
644 def get_session_cache_mode(self):
645 """
646 :returns: The currently used cache mode.
647 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500648 return _lib.SSL_CTX_get_session_cache_mode(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800649
650
651 def set_verify(self, mode, callback):
652 """
653 Set the verify mode and verify callback
654
655 :param mode: The verify mode, this is either VERIFY_NONE or
656 VERIFY_PEER combined with possible other flags
657 :param callback: The Python callback to use
658 :return: None
659
660 See SSL_CTX_set_verify(3SSL) for further details.
661 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500662 if not isinstance(mode, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800663 raise TypeError("mode must be an integer")
664
665 if not callable(callback):
666 raise TypeError("callback must be callable")
667
Jean-Paul Calderone6a8cd112014-04-02 21:09:08 -0400668 self._verify_helper = _VerifyHelper(callback)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800669 self._verify_callback = self._verify_helper.callback
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500670 _lib.SSL_CTX_set_verify(self._context, mode, self._verify_callback)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800671
672
673 def set_verify_depth(self, depth):
674 """
675 Set the verify depth
676
677 :param depth: An integer specifying the verify depth
678 :return: None
679 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500680 if not isinstance(depth, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800681 raise TypeError("depth must be an integer")
682
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500683 _lib.SSL_CTX_set_verify_depth(self._context, depth)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800684
685
686 def get_verify_mode(self):
687 """
688 Get the verify mode
689
690 :return: The verify mode
691 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500692 return _lib.SSL_CTX_get_verify_mode(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800693
694
695 def get_verify_depth(self):
696 """
697 Get the verify depth
698
699 :return: The verify depth
700 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500701 return _lib.SSL_CTX_get_verify_depth(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800702
703
704 def load_tmp_dh(self, dhfile):
705 """
706 Load parameters for Ephemeral Diffie-Hellman
707
Jean-Paul Calderone4e0c43f2015-04-13 10:15:17 -0400708 :param dhfile: The file to load EDH parameters from (``bytes`` or
709 ``unicode``).
710
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800711 :return: None
712 """
Jean-Paul Calderone9e1c1dd2015-04-12 10:13:13 -0400713 dhfile = _path_string(dhfile)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800714
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -0500715 bio = _lib.BIO_new_file(dhfile, b"r")
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500716 if bio == _ffi.NULL:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500717 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500718 bio = _ffi.gc(bio, _lib.BIO_free)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800719
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500720 dh = _lib.PEM_read_bio_DHparams(bio, _ffi.NULL, _ffi.NULL, _ffi.NULL)
721 dh = _ffi.gc(dh, _lib.DH_free)
722 _lib.SSL_CTX_set_tmp_dh(self._context, dh)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800723
724
Jean-Paul Calderone3e4e3352014-04-19 09:28:28 -0400725 def set_tmp_ecdh(self, curve):
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600726 """
Andy Lutomirski76a61332014-03-12 15:02:56 -0700727 Select a curve to use for ECDHE key exchange.
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600728
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -0400729 :param curve: A curve object to use as returned by either
730 :py:meth:`OpenSSL.crypto.get_elliptic_curve` or
731 :py:meth:`OpenSSL.crypto.get_elliptic_curves`.
Andy Lutomirskif05a2732014-03-13 17:22:25 -0700732
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600733 :return: None
734 """
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -0400735 _lib.SSL_CTX_set_tmp_ecdh(self._context, curve._to_EC_KEY())
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600736
737
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800738 def set_cipher_list(self, cipher_list):
739 """
740 Change the cipher list
741
742 :param cipher_list: A cipher list, see ciphers(1)
743 :return: None
744 """
Jean-Paul Calderone63eab692014-01-18 10:19:56 -0500745 if isinstance(cipher_list, _text_type):
746 cipher_list = cipher_list.encode("ascii")
747
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800748 if not isinstance(cipher_list, bytes):
Jean-Paul Calderone63eab692014-01-18 10:19:56 -0500749 raise TypeError("cipher_list must be bytes or unicode")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800750
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500751 result = _lib.SSL_CTX_set_cipher_list(self._context, cipher_list)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800752 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500753 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800754
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800755
756 def set_client_ca_list(self, certificate_authorities):
757 """
758 Set the list of preferred client certificate signers for this server context.
759
760 This list of certificate authorities will be sent to the client when the
761 server requests a client certificate.
762
763 :param certificate_authorities: a sequence of X509Names.
764 :return: None
765 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500766 name_stack = _lib.sk_X509_NAME_new_null()
767 if name_stack == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500768 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500769 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800770
771 try:
772 for ca_name in certificate_authorities:
773 if not isinstance(ca_name, X509Name):
774 raise TypeError(
775 "client CAs must be X509Name objects, not %s objects" % (
776 type(ca_name).__name__,))
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500777 copy = _lib.X509_NAME_dup(ca_name._name)
778 if copy == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500779 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500780 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500781 push_result = _lib.sk_X509_NAME_push(name_stack, copy)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800782 if not push_result:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500783 _lib.X509_NAME_free(copy)
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500784 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800785 except:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500786 _lib.sk_X509_NAME_free(name_stack)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800787 raise
788
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500789 _lib.SSL_CTX_set_client_CA_list(self._context, name_stack)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800790
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800791
792 def add_client_ca(self, certificate_authority):
793 """
794 Add the CA certificate to the list of preferred signers for this context.
795
796 The list of certificate authorities will be sent to the client when the
797 server requests a client certificate.
798
799 :param certificate_authority: certificate authority's X509 certificate.
800 :return: None
801 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800802 if not isinstance(certificate_authority, X509):
803 raise TypeError("certificate_authority must be an X509 instance")
804
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500805 add_result = _lib.SSL_CTX_add_client_CA(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800806 self._context, certificate_authority._x509)
807 if not add_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500808 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500809 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800810
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800811
812 def set_timeout(self, timeout):
813 """
814 Set session timeout
815
816 :param timeout: The timeout in seconds
817 :return: The previous session timeout
818 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500819 if not isinstance(timeout, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800820 raise TypeError("timeout must be an integer")
821
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500822 return _lib.SSL_CTX_set_timeout(self._context, timeout)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800823
824
825 def get_timeout(self):
826 """
827 Get the session timeout
828
829 :return: The session timeout
830 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500831 return _lib.SSL_CTX_get_timeout(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800832
833
834 def set_info_callback(self, callback):
835 """
836 Set the info callback
837
838 :param callback: The Python callback to use
839 :return: None
840 """
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800841 @wraps(callback)
842 def wrapper(ssl, where, return_code):
Jean-Paul Calderonef2bbc9c2014-02-02 10:59:14 -0500843 callback(Connection._reverse_mapping[ssl], where, return_code)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500844 self._info_callback = _ffi.callback(
845 "void (*)(const SSL *, int, int)", wrapper)
846 _lib.SSL_CTX_set_info_callback(self._context, self._info_callback)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800847
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800848
849 def get_app_data(self):
850 """
851 Get the application data (supplied via set_app_data())
852
853 :return: The application data
854 """
855 return self._app_data
856
857
858 def set_app_data(self, data):
859 """
860 Set the application data (will be returned from get_app_data())
861
862 :param data: Any Python object
863 :return: None
864 """
865 self._app_data = data
866
867
868 def get_cert_store(self):
869 """
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500870 Get the certificate store for the context.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800871
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500872 :return: A X509Store object or None if it does not have one.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800873 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500874 store = _lib.SSL_CTX_get_cert_store(self._context)
875 if store == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500876 # TODO: This is untested.
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800877 return None
878
879 pystore = X509Store.__new__(X509Store)
880 pystore._store = store
881 return pystore
882
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800883
884 def set_options(self, options):
885 """
886 Add options. Options set before are not cleared!
887
888 :param options: The options to add.
889 :return: The new option bitmask.
890 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500891 if not isinstance(options, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800892 raise TypeError("options must be an integer")
893
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500894 return _lib.SSL_CTX_set_options(self._context, options)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800895
896
897 def set_mode(self, mode):
898 """
899 Add modes via bitmask. Modes set before are not cleared!
900
901 :param mode: The mode to add.
902 :return: The new mode bitmask.
903 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500904 if not isinstance(mode, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800905 raise TypeError("mode must be an integer")
906
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500907 return _lib.SSL_CTX_set_mode(self._context, mode)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800908
909
910 def set_tlsext_servername_callback(self, callback):
911 """
912 Specify a callback function to be called when clients specify a server name.
913
914 :param callback: The callback function. It will be invoked with one
915 argument, the Connection instance.
916 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800917 @wraps(callback)
918 def wrapper(ssl, alert, arg):
919 callback(Connection._reverse_mapping[ssl])
920 return 0
921
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500922 self._tlsext_servername_callback = _ffi.callback(
923 "int (*)(const SSL *, int *, void *)", wrapper)
924 _lib.SSL_CTX_set_tlsext_servername_callback(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800925 self._context, self._tlsext_servername_callback)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800926
Cory Benfield84a121e2014-03-31 20:30:25 +0100927 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
Cory Benfield12eae892014-06-07 15:42:56 +0100959 def set_alpn_protos(self, protos):
960 """
Cory Benfielde8e9c382015-04-11 17:33:48 -0400961 Specify the clients ALPN protocol list.
962
963 These protocols are offered to the server during protocol negotiation.
Cory Benfield12eae892014-06-07 15:42:56 +0100964
965 :param protos: A list of the protocols to be offered to the server.
966 This list should be a Python list of bytestrings representing the
967 protocols to offer, e.g. ``[b'http/1.1', b'spdy/2']``.
968 """
969 # Take the list of protocols and join them together, prefixing them
970 # with their lengths.
971 protostr = b''.join(
972 chain.from_iterable((int2byte(len(p)), p) for p in protos)
973 )
974
975 # Build a C string from the list. We don't need to save this off
976 # because OpenSSL immediately copies the data out.
977 input_str = _ffi.new("unsigned char[]", protostr)
Cory Benfielde871af52015-04-11 17:57:50 -0400978 input_str_len = _ffi.cast("unsigned", len(protostr))
979 _lib.SSL_CTX_set_alpn_protos(self._context, input_str, input_str_len)
Cory Benfield12eae892014-06-07 15:42:56 +0100980
981 def set_alpn_select_callback(self, callback):
982 """
Cory Benfielde8e9c382015-04-11 17:33:48 -0400983 Set the callback to handle ALPN protocol choice.
Cory Benfield12eae892014-06-07 15:42:56 +0100984
985 :param callback: The callback function. It will be invoked with two
986 arguments: the Connection, and a list of offered protocols as
987 bytestrings, e.g ``[b'http/1.1', b'spdy/2']``. It should return
Cory Benfielde8e9c382015-04-11 17:33:48 -0400988 one of those bytestrings, the chosen protocol.
Cory Benfield12eae892014-06-07 15:42:56 +0100989 """
990 @wraps(callback)
991 def wrapper(ssl, out, outlen, in_, inlen, arg):
992 conn = Connection._reverse_mapping[ssl]
993
994 # The string passed to us is made up of multiple length-prefixed
995 # bytestrings. We need to split that into a list.
996 instr = _ffi.buffer(in_, inlen)[:]
997 protolist = []
998 while instr:
999 l = indexbytes(instr, 0)
1000 proto = instr[1:l+1]
1001 protolist.append(proto)
1002 instr = instr[l+1:]
1003
1004 # Call the callback
1005 outstr = callback(conn, protolist)
1006
1007 # Save our callback arguments on the connection object to make sure
1008 # that they don't get freed before OpenSSL can use them. Then,
1009 # return them in the appropriate output parameters.
1010 conn._alpn_select_callback_args = [
1011 _ffi.new("unsigned char *", len(outstr)),
1012 _ffi.new("unsigned char[]", outstr),
1013 ]
1014 outlen[0] = conn._alpn_select_callback_args[0][0]
1015 out[0] = conn._alpn_select_callback_args[1]
1016 return 0
1017
1018 self._alpn_select_callback = _ffi.callback(
1019 "int (*)(SSL *, unsigned char **, unsigned char *, "
Cory Benfield9c1979a2015-04-12 08:51:52 -04001020 "const unsigned char *, unsigned int, void *)",
Cory Benfield12eae892014-06-07 15:42:56 +01001021 wrapper)
1022 _lib.SSL_CTX_set_alpn_select_cb(
1023 self._context, self._alpn_select_callback, _ffi.NULL)
1024
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -08001025ContextType = Context
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001026
1027
1028
1029class Connection(object):
1030 """
1031 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001032 _reverse_mapping = WeakValueDictionary()
1033
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001034 def __init__(self, context, socket=None):
1035 """
1036 Create a new Connection object, using the given OpenSSL.SSL.Context
1037 instance and socket.
1038
1039 :param context: An SSL Context to use for this connection
1040 :param socket: The socket to use for transport layer
1041 """
1042 if not isinstance(context, Context):
1043 raise TypeError("context must be a Context instance")
1044
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001045 ssl = _lib.SSL_new(context._context)
1046 self._ssl = _ffi.gc(ssl, _lib.SSL_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001047 self._context = context
1048
Cory Benfieldbe3e7b82014-05-10 09:48:55 +01001049 # References to strings used for Next Protocol Negotiation. OpenSSL's
1050 # header files suggest that these might get copied at some point, but
1051 # doesn't specify when, so we store them here to make sure they don't
1052 # get freed before OpenSSL uses them.
1053 self._npn_advertise_callback_args = None
1054 self._npn_select_callback_args = None
1055
Cory Benfield12eae892014-06-07 15:42:56 +01001056 # References to strings used for Application Layer Protocol
1057 # Negotiation. These strings get copied at some point but it's well
1058 # after the callback returns, so we have to hang them somewhere to
1059 # avoid them getting freed.
1060 self._alpn_select_callback_args = None
1061
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001062 self._reverse_mapping[self._ssl] = self
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001063
1064 if socket is None:
1065 self._socket = None
Jean-Paul Calderone73b15c22013-03-05 18:30:39 -08001066 # Don't set up any gc for these, SSL_free will take care of them.
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001067 self._into_ssl = _lib.BIO_new(_lib.BIO_s_mem())
1068 self._from_ssl = _lib.BIO_new(_lib.BIO_s_mem())
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001069
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001070 if self._into_ssl == _ffi.NULL or self._from_ssl == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001071 # TODO: This is untested.
1072 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001073
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001074 _lib.SSL_set_bio(self._ssl, self._into_ssl, self._from_ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001075 else:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001076 self._into_ssl = None
1077 self._from_ssl = None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001078 self._socket = socket
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001079 set_result = _lib.SSL_set_fd(self._ssl, _asFileDescriptor(self._socket))
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001080 if not set_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001081 # TODO: This is untested.
1082 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001083
1084
1085 def __getattr__(self, name):
1086 """
1087 Look up attributes on the wrapped socket object if they are not found on
1088 the Connection object.
1089 """
1090 return getattr(self._socket, name)
1091
1092
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001093 def _raise_ssl_error(self, ssl, result):
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -08001094 if self._context._verify_helper is not None:
1095 self._context._verify_helper.raise_if_problem()
Cory Benfield0ea76e72015-03-22 09:05:28 +00001096 if self._context._npn_advertise_helper is not None:
1097 self._context._npn_advertise_helper.raise_if_problem()
1098 if self._context._npn_select_helper is not None:
1099 self._context._npn_select_helper.raise_if_problem()
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -08001100
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001101 error = _lib.SSL_get_error(ssl, result)
1102 if error == _lib.SSL_ERROR_WANT_READ:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001103 raise WantReadError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001104 elif error == _lib.SSL_ERROR_WANT_WRITE:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001105 raise WantWriteError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001106 elif error == _lib.SSL_ERROR_ZERO_RETURN:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001107 raise ZeroReturnError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001108 elif error == _lib.SSL_ERROR_WANT_X509_LOOKUP:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001109 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001110 raise WantX509LookupError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001111 elif error == _lib.SSL_ERROR_SYSCALL:
1112 if _lib.ERR_peek_error() == 0:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001113 if result < 0:
Konstantinos Koukopoulos541150d2014-01-31 01:00:19 +02001114 if platform == "win32":
1115 errno = _ffi.getwinerror()[0]
1116 else:
1117 errno = _ffi.errno
1118 raise SysCallError(errno, errorcode[errno])
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001119 else:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001120 raise SysCallError(-1, "Unexpected EOF")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001121 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001122 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001123 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001124 elif error == _lib.SSL_ERROR_NONE:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001125 pass
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001126 else:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001127 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001128
1129
1130 def get_context(self):
1131 """
1132 Get session context
1133 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001134 return self._context
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001135
1136
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001137 def set_context(self, context):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001138 """
1139 Switch this connection to a new session context
1140
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001141 :param context: A :py:class:`Context` instance giving the new session
1142 context to use.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001143 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001144 if not isinstance(context, Context):
1145 raise TypeError("context must be a Context instance")
1146
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001147 _lib.SSL_set_SSL_CTX(self._ssl, context._context)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001148 self._context = context
1149
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001150
1151 def get_servername(self):
1152 """
1153 Retrieve the servername extension value if provided in the client hello
1154 message, or None if there wasn't one.
1155
1156 :return: A byte string giving the server name or :py:data:`None`.
1157 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001158 name = _lib.SSL_get_servername(self._ssl, _lib.TLSEXT_NAMETYPE_host_name)
1159 if name == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001160 return None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001161
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001162 return _ffi.string(name)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001163
1164
1165 def set_tlsext_host_name(self, name):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001166 """
1167 Set the value of the servername extension to send in the client hello.
1168
1169 :param name: A byte string giving the name.
1170 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001171 if not isinstance(name, bytes):
1172 raise TypeError("name must be a byte string")
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001173 elif b"\0" in name:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001174 raise TypeError("name must not contain NUL byte")
1175
1176 # XXX I guess this can fail sometimes?
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001177 _lib.SSL_set_tlsext_host_name(self._ssl, name)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001178
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001179
1180 def pending(self):
1181 """
1182 Get the number of bytes that can be safely read from the connection
1183
1184 :return: The number of bytes available in the receive buffer.
1185 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001186 return _lib.SSL_pending(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001187
1188
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001189 def send(self, buf, flags=0):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001190 """
1191 Send data on the connection. NOTE: If you get one of the WantRead,
1192 WantWrite or WantX509Lookup exceptions on this, you have to call the
1193 method again with the SAME buffer.
1194
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001195 :param buf: The string, buffer or memoryview to send
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001196 :param flags: (optional) Included for compatibility with the socket
1197 API, the value is ignored
1198 :return: The number of bytes written
1199 """
Jean-Paul Calderone8fb53182013-12-30 08:35:49 -05001200 if isinstance(buf, _memoryview):
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -08001201 buf = buf.tobytes()
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001202 if isinstance(buf, _buffer):
1203 buf = str(buf)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001204 if not isinstance(buf, bytes):
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001205 raise TypeError("data must be a memoryview, buffer or byte string")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001206
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001207 result = _lib.SSL_write(self._ssl, buf, len(buf))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001208 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001209 return result
1210 write = send
1211
1212
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001213 def sendall(self, buf, flags=0):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001214 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001215 Send "all" data on the connection. This calls send() repeatedly until
1216 all data is sent. If an error occurs, it's impossible to tell how much
1217 data has been sent.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001218
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001219 :param buf: The string, buffer or memoryview to send
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001220 :param flags: (optional) Included for compatibility with the socket
1221 API, the value is ignored
1222 :return: The number of bytes written
1223 """
Jean-Paul Calderone8fb53182013-12-30 08:35:49 -05001224 if isinstance(buf, _memoryview):
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -08001225 buf = buf.tobytes()
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001226 if isinstance(buf, _buffer):
1227 buf = str(buf)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001228 if not isinstance(buf, bytes):
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001229 raise TypeError("buf must be a memoryview, buffer or byte string")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001230
1231 left_to_send = len(buf)
1232 total_sent = 0
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001233 data = _ffi.new("char[]", buf)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001234
1235 while left_to_send:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001236 result = _lib.SSL_write(self._ssl, data + total_sent, left_to_send)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001237 self._raise_ssl_error(self._ssl, result)
1238 total_sent += result
1239 left_to_send -= result
1240
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001241
1242 def recv(self, bufsiz, flags=None):
1243 """
1244 Receive data on the connection. NOTE: If you get one of the WantRead,
1245 WantWrite or WantX509Lookup exceptions on this, you have to call the
1246 method again with the SAME buffer.
1247
1248 :param bufsiz: The maximum number of bytes to read
1249 :param flags: (optional) Included for compatibility with the socket
1250 API, the value is ignored
1251 :return: The string read from the Connection
1252 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001253 buf = _ffi.new("char[]", bufsiz)
1254 result = _lib.SSL_read(self._ssl, buf, bufsiz)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001255 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001256 return _ffi.buffer(buf, result)[:]
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001257 read = recv
1258
1259
Cory Benfield62d10332014-06-15 10:03:41 +01001260 def recv_into(self, buffer, nbytes=None, flags=None):
1261 """
1262 Receive data on the connection and store the data into a buffer rather
1263 than creating a new string.
1264
1265 :param buffer: The buffer to copy into.
1266 :param nbytes: (optional) The maximum number of bytes to read into the
1267 buffer. If not present, defaults to the size of the buffer. If
1268 larger than the size of the buffer, is reduced to the size of the
1269 buffer.
1270 :param flags: (optional) Included for compatibility with the socket
1271 API, the value is ignored.
1272 :return: The number of bytes read into the buffer.
1273 """
1274 if nbytes is None:
1275 nbytes = len(buffer)
1276 else:
1277 nbytes = min(nbytes, len(buffer))
1278
1279 # We need to create a temporary buffer. This is annoying, it would be
1280 # better if we could pass memoryviews straight into the SSL_read call,
1281 # but right now we can't. Revisit this if CFFI gets that ability.
1282 buf = _ffi.new("char[]", nbytes)
1283 result = _lib.SSL_read(self._ssl, buf, nbytes)
1284 self._raise_ssl_error(self._ssl, result)
1285
1286 # This strange line is all to avoid a memory copy. The buffer protocol
1287 # should allow us to assign a CFFI buffer to the LHS of this line, but
1288 # on CPython 3.3+ that segfaults. As a workaround, we can temporarily
1289 # wrap it in a memoryview, except on Python 2.6 which doesn't have a
1290 # memoryview type.
1291 try:
1292 buffer[:result] = memoryview(_ffi.buffer(buf, result))
1293 except NameError:
1294 buffer[:result] = _ffi.buffer(buf, result)
1295
1296 return result
1297
1298
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001299 def _handle_bio_errors(self, bio, result):
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001300 if _lib.BIO_should_retry(bio):
1301 if _lib.BIO_should_read(bio):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001302 raise WantReadError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001303 elif _lib.BIO_should_write(bio):
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001304 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001305 raise WantWriteError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001306 elif _lib.BIO_should_io_special(bio):
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001307 # TODO: This is untested. I think io_special means the socket
1308 # BIO has a not-yet connected socket.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001309 raise ValueError("BIO_should_io_special")
1310 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001311 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001312 raise ValueError("unknown bio failure")
1313 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001314 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001315 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001316
1317
1318 def bio_read(self, bufsiz):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001319 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001320 When using non-socket connections this function reads the "dirty" data
1321 that would have traveled away on the network.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001322
1323 :param bufsiz: The maximum number of bytes to read
1324 :return: The string read.
1325 """
Jean-Paul Calderone97e041d2013-03-05 21:03:12 -08001326 if self._from_ssl is None:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001327 raise TypeError("Connection sock was not None")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001328
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -05001329 if not isinstance(bufsiz, integer_types):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001330 raise TypeError("bufsiz must be an integer")
1331
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001332 buf = _ffi.new("char[]", bufsiz)
1333 result = _lib.BIO_read(self._from_ssl, buf, bufsiz)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001334 if result <= 0:
1335 self._handle_bio_errors(self._from_ssl, result)
1336
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001337 return _ffi.buffer(buf, result)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001338
1339
1340 def bio_write(self, buf):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001341 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001342 When using non-socket connections this function sends "dirty" data that
1343 would have traveled in on the network.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001344
1345 :param buf: The string to put into the memory BIO.
1346 :return: The number of bytes written
1347 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001348 if self._into_ssl is None:
1349 raise TypeError("Connection sock was not None")
1350
1351 if not isinstance(buf, bytes):
1352 raise TypeError("buf must be a byte string")
1353
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001354 result = _lib.BIO_write(self._into_ssl, buf, len(buf))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001355 if result <= 0:
1356 self._handle_bio_errors(self._into_ssl, result)
1357 return result
1358
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001359
1360 def renegotiate(self):
1361 """
1362 Renegotiate the session
1363
1364 :return: True if the renegotiation can be started, false otherwise
1365 """
1366
1367 def do_handshake(self):
1368 """
1369 Perform an SSL handshake (usually called after renegotiate() or one of
1370 set_*_state()). This can raise the same exceptions as send and recv.
1371
1372 :return: None.
1373 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001374 result = _lib.SSL_do_handshake(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001375 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001376
1377
1378 def renegotiate_pending(self):
1379 """
1380 Check if there's a renegotiation in progress, it will return false once
1381 a renegotiation is finished.
1382
1383 :return: Whether there's a renegotiation in progress
1384 """
1385
1386 def total_renegotiations(self):
1387 """
1388 Find out the total number of renegotiations.
1389
1390 :return: The number of renegotiations.
1391 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001392 return _lib.SSL_total_renegotiations(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001393
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001394
1395 def connect(self, addr):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001396 """
1397 Connect to remote host and set up client-side SSL
1398
1399 :param addr: A remote address
1400 :return: What the socket's connect method returns
1401 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001402 _lib.SSL_set_connect_state(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001403 return self._socket.connect(addr)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001404
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001405
1406 def connect_ex(self, addr):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001407 """
1408 Connect to remote host and set up client-side SSL. Note that if the socket's
1409 connect_ex method doesn't return 0, SSL won't be initialized.
1410
1411 :param addr: A remove address
1412 :return: What the socket's connect_ex method returns
1413 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001414 connect_ex = self._socket.connect_ex
1415 self.set_connect_state()
1416 return connect_ex(addr)
1417
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001418
1419 def accept(self):
1420 """
1421 Accept incoming connection and set up SSL on it
1422
1423 :return: A (conn,addr) pair where conn is a Connection and addr is an
1424 address
1425 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001426 client, addr = self._socket.accept()
1427 conn = Connection(self._context, client)
1428 conn.set_accept_state()
1429 return (conn, addr)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001430
1431
1432 def bio_shutdown(self):
1433 """
1434 When using non-socket connections this function signals end of
1435 data on the input for this connection.
1436
1437 :return: None
1438 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001439 if self._from_ssl is None:
1440 raise TypeError("Connection sock was not None")
1441
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001442 _lib.BIO_set_mem_eof_return(self._into_ssl, 0)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001443
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001444
1445 def shutdown(self):
1446 """
1447 Send closure alert
1448
1449 :return: True if the shutdown completed successfully (i.e. both sides
1450 have sent closure alerts), false otherwise (i.e. you have to
1451 wait for a ZeroReturnError on a recv() method call
1452 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001453 result = _lib.SSL_shutdown(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001454 if result < 0:
Paul Aurichbff1d1a2015-01-08 08:36:53 -08001455 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001456 elif result > 0:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001457 return True
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001458 else:
1459 return False
1460
1461
1462 def get_cipher_list(self):
1463 """
1464 Get the session cipher list
1465
1466 :return: A list of cipher strings
1467 """
1468 ciphers = []
1469 for i in count():
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001470 result = _lib.SSL_get_cipher_list(self._ssl, i)
1471 if result == _ffi.NULL:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001472 break
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001473 ciphers.append(_native(_ffi.string(result)))
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001474 return ciphers
1475
1476
1477 def get_client_ca_list(self):
1478 """
1479 Get CAs whose certificates are suggested for client authentication.
1480
1481 :return: If this is a server connection, a list of X509Names representing
1482 the acceptable CAs as set by :py:meth:`OpenSSL.SSL.Context.set_client_ca_list` or
1483 :py:meth:`OpenSSL.SSL.Context.add_client_ca`. If this is a client connection,
1484 the list of such X509Names sent by the server, or an empty list if that
1485 has not yet happened.
1486 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001487 ca_names = _lib.SSL_get_client_CA_list(self._ssl)
1488 if ca_names == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001489 # TODO: This is untested.
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001490 return []
1491
1492 result = []
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001493 for i in range(_lib.sk_X509_NAME_num(ca_names)):
1494 name = _lib.sk_X509_NAME_value(ca_names, i)
1495 copy = _lib.X509_NAME_dup(name)
1496 if copy == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001497 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001498 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001499
1500 pyname = X509Name.__new__(X509Name)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001501 pyname._name = _ffi.gc(copy, _lib.X509_NAME_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001502 result.append(pyname)
1503 return result
1504
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001505
1506 def makefile(self):
1507 """
1508 The makefile() method is not implemented, since there is no dup semantics
1509 for SSL connections
1510
Jean-Paul Calderone6749ec22014-04-17 16:30:21 -04001511 :raise: NotImplementedError
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001512 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001513 raise NotImplementedError("Cannot make file object of OpenSSL.SSL.Connection")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001514
1515
1516 def get_app_data(self):
1517 """
1518 Get application data
1519
1520 :return: The application data
1521 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001522 return self._app_data
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001523
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001524
1525 def set_app_data(self, data):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001526 """
1527 Set application data
1528
1529 :param data - The application data
1530 :return: None
1531 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001532 self._app_data = data
1533
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001534
1535 def get_shutdown(self):
1536 """
1537 Get shutdown state
1538
1539 :return: The shutdown state, a bitvector of SENT_SHUTDOWN, RECEIVED_SHUTDOWN.
1540 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001541 return _lib.SSL_get_shutdown(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001542
1543
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001544 def set_shutdown(self, state):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001545 """
1546 Set shutdown state
1547
1548 :param state - bitvector of SENT_SHUTDOWN, RECEIVED_SHUTDOWN.
1549 :return: None
1550 """
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -05001551 if not isinstance(state, integer_types):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001552 raise TypeError("state must be an integer")
1553
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001554 _lib.SSL_set_shutdown(self._ssl, state)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001555
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001556
1557 def state_string(self):
1558 """
1559 Get a verbose state description
1560
1561 :return: A string representing the state
1562 """
1563
1564 def server_random(self):
1565 """
1566 Get a copy of the server hello nonce.
1567
1568 :return: A string representing the state
1569 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001570 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001571 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001572 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001573 self._ssl.s3.server_random,
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001574 _lib.SSL3_RANDOM_SIZE)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001575
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001576
1577 def client_random(self):
1578 """
1579 Get a copy of the client hello nonce.
1580
1581 :return: A string representing the state
1582 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001583 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001584 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001585 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001586 self._ssl.s3.client_random,
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001587 _lib.SSL3_RANDOM_SIZE)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001588
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001589
1590 def master_key(self):
1591 """
1592 Get a copy of the master key.
1593
1594 :return: A string representing the state
1595 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001596 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001597 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001598 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001599 self._ssl.session.master_key,
1600 self._ssl.session.master_key_length)[:]
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001601
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001602
1603 def sock_shutdown(self, *args, **kwargs):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001604 """
1605 See shutdown(2)
1606
1607 :return: What the socket's shutdown() method returns
1608 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001609 return self._socket.shutdown(*args, **kwargs)
1610
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001611
1612 def get_peer_certificate(self):
1613 """
1614 Retrieve the other side's certificate (if any)
1615
1616 :return: The peer's certificate
1617 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001618 cert = _lib.SSL_get_peer_certificate(self._ssl)
1619 if cert != _ffi.NULL:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001620 pycert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001621 pycert._x509 = _ffi.gc(cert, _lib.X509_free)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001622 return pycert
1623 return None
1624
1625
1626 def get_peer_cert_chain(self):
1627 """
1628 Retrieve the other side's certificate (if any)
1629
1630 :return: A list of X509 instances giving the peer's certificate chain,
1631 or None if it does not have one.
1632 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001633 cert_stack = _lib.SSL_get_peer_cert_chain(self._ssl)
1634 if cert_stack == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001635 return None
1636
1637 result = []
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001638 for i in range(_lib.sk_X509_num(cert_stack)):
Jean-Paul Calderone73b15c22013-03-05 18:30:39 -08001639 # TODO could incref instead of dup here
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001640 cert = _lib.X509_dup(_lib.sk_X509_value(cert_stack, i))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001641 pycert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001642 pycert._x509 = _ffi.gc(cert, _lib.X509_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001643 result.append(pycert)
1644 return result
1645
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001646
1647 def want_read(self):
1648 """
1649 Checks if more data has to be read from the transport layer to complete an
1650 operation.
1651
1652 :return: True iff more data has to be read
1653 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001654 return _lib.SSL_want_read(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001655
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001656
1657 def want_write(self):
1658 """
1659 Checks if there is data to write to the transport layer to complete an
1660 operation.
1661
1662 :return: True iff there is data to write
1663 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001664 return _lib.SSL_want_write(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001665
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001666
1667 def set_accept_state(self):
1668 """
1669 Set the connection to work in server mode. The handshake will be handled
1670 automatically by read/write.
1671
1672 :return: None
1673 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001674 _lib.SSL_set_accept_state(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001675
1676
1677 def set_connect_state(self):
1678 """
1679 Set the connection to work in client mode. The handshake will be handled
1680 automatically by read/write.
1681
1682 :return: None
1683 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001684 _lib.SSL_set_connect_state(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001685
1686
1687 def get_session(self):
1688 """
1689 Returns the Session currently used.
1690
1691 @return: An instance of :py:class:`OpenSSL.SSL.Session` or :py:obj:`None` if
1692 no session exists.
1693 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001694 session = _lib.SSL_get1_session(self._ssl)
1695 if session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001696 return None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001697
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001698 pysession = Session.__new__(Session)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001699 pysession._session = _ffi.gc(session, _lib.SSL_SESSION_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001700 return pysession
1701
1702
1703 def set_session(self, session):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001704 """
1705 Set the session to be used when the TLS/SSL connection is established.
1706
1707 :param session: A Session instance representing the session to use.
1708 :returns: None
1709 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001710 if not isinstance(session, Session):
1711 raise TypeError("session must be a Session instance")
1712
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001713 result = _lib.SSL_set_session(self._ssl, session._session)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001714 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001715 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001716
Jean-Paul Calderonedbd76272014-03-29 18:09:40 -04001717
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001718 def _get_finished_message(self, function):
1719 """
1720 Helper to implement :py:meth:`get_finished` and
1721 :py:meth:`get_peer_finished`.
1722
1723 :param function: Either :py:data:`SSL_get_finished`: or
1724 :py:data:`SSL_get_peer_finished`.
1725
1726 :return: :py:data:`None` if the desired message has not yet been
1727 received, otherwise the contents of the message.
1728 :rtype: :py:class:`bytes` or :py:class:`NoneType`
1729 """
Jean-Paul Calderone01af9042014-03-30 11:40:42 -04001730 # The OpenSSL documentation says nothing about what might happen if the
1731 # count argument given is zero. Specifically, it doesn't say whether
1732 # the output buffer may be NULL in that case or not. Inspection of the
1733 # implementation reveals that it calls memcpy() unconditionally.
1734 # Section 7.1.4, paragraph 1 of the C standard suggests that
1735 # memcpy(NULL, source, 0) is not guaranteed to produce defined (let
1736 # alone desirable) behavior (though it probably does on just about
1737 # every implementation...)
1738 #
1739 # Allocate a tiny buffer to pass in (instead of just passing NULL as
1740 # one might expect) for the initial call so as to be safe against this
1741 # potentially undefined behavior.
1742 empty = _ffi.new("char[]", 0)
1743 size = function(self._ssl, empty, 0)
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001744 if size == 0:
1745 # No Finished message so far.
1746 return None
1747
1748 buf = _ffi.new("char[]", size)
1749 function(self._ssl, buf, size)
1750 return _ffi.buffer(buf, size)[:]
1751
1752
Fedor Brunner5747b932014-03-05 14:22:34 +01001753 def get_finished(self):
1754 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001755 Obtain the latest `handshake finished` message sent to the peer.
Fedor Brunner5747b932014-03-05 14:22:34 +01001756
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001757 :return: The contents of the message or :py:obj:`None` if the TLS
1758 handshake has not yet completed.
1759 :rtype: :py:class:`bytes` or :py:class:`NoneType`
Fedor Brunner5747b932014-03-05 14:22:34 +01001760 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001761 return self._get_finished_message(_lib.SSL_get_finished)
1762
Fedor Brunner5747b932014-03-05 14:22:34 +01001763
1764 def get_peer_finished(self):
1765 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001766 Obtain the latest `handshake finished` message received from the peer.
Fedor Brunner5747b932014-03-05 14:22:34 +01001767
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001768 :return: The contents of the message or :py:obj:`None` if the TLS
1769 handshake has not yet completed.
1770 :rtype: :py:class:`bytes` or :py:class:`NoneType`
Fedor Brunner5747b932014-03-05 14:22:34 +01001771 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001772 return self._get_finished_message(_lib.SSL_get_peer_finished)
Fedor Brunner5747b932014-03-05 14:22:34 +01001773
Jean-Paul Calderone7c556ef2014-03-30 10:45:00 -04001774
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001775 def get_cipher_name(self):
1776 """
1777 Obtain the name of the currently used cipher.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001778
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001779 :returns: The name of the currently used cipher or :py:obj:`None`
1780 if no connection has been established.
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001781 :rtype: :py:class:`unicode` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001782 """
1783 cipher = _lib.SSL_get_current_cipher(self._ssl)
1784 if cipher == _ffi.NULL:
1785 return None
1786 else:
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001787 name = _ffi.string(_lib.SSL_CIPHER_get_name(cipher))
1788 return name.decode("utf-8")
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001789
Jean-Paul Calderonedbd76272014-03-29 18:09:40 -04001790
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001791 def get_cipher_bits(self):
1792 """
1793 Obtain the number of secret bits of the currently used cipher.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001794
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001795 :returns: The number of secret bits of the currently used cipher
1796 or :py:obj:`None` if no connection has been established.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001797 :rtype: :py:class:`int` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001798 """
1799 cipher = _lib.SSL_get_current_cipher(self._ssl)
1800 if cipher == _ffi.NULL:
1801 return None
1802 else:
1803 return _lib.SSL_CIPHER_get_bits(cipher, _ffi.NULL)
1804
Jean-Paul Calderonedbd76272014-03-29 18:09:40 -04001805
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001806 def get_cipher_version(self):
1807 """
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001808 Obtain the protocol version of the currently used cipher.
1809
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001810 :returns: The protocol name of the currently used cipher
1811 or :py:obj:`None` if no connection has been established.
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001812 :rtype: :py:class:`unicode` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001813 """
1814 cipher = _lib.SSL_get_current_cipher(self._ssl)
1815 if cipher == _ffi.NULL:
1816 return None
1817 else:
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001818 version =_ffi.string(_lib.SSL_CIPHER_get_version(cipher))
1819 return version.decode("utf-8")
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001820
Cory Benfield84a121e2014-03-31 20:30:25 +01001821 def get_next_proto_negotiated(self):
1822 """
1823 Get the protocol that was negotiated by NPN.
1824 """
1825 data = _ffi.new("unsigned char **")
1826 data_len = _ffi.new("unsigned int *")
1827
1828 _lib.SSL_get0_next_proto_negotiated(self._ssl, data, data_len)
1829
Cory Benfieldcd010f62014-05-15 19:00:27 +01001830 return _ffi.buffer(data[0], data_len[0])[:]
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001831
Cory Benfield12eae892014-06-07 15:42:56 +01001832 def set_alpn_protos(self, protos):
1833 """
Cory Benfielde8e9c382015-04-11 17:33:48 -04001834 Specify the client's ALPN protocol list.
1835
1836 These protocols are offered to the server during protocol negotiation.
Cory Benfield12eae892014-06-07 15:42:56 +01001837
1838 :param protos: A list of the protocols to be offered to the server.
1839 This list should be a Python list of bytestrings representing the
1840 protocols to offer, e.g. ``[b'http/1.1', b'spdy/2']``.
1841 """
1842 # Take the list of protocols and join them together, prefixing them
1843 # with their lengths.
1844 protostr = b''.join(
1845 chain.from_iterable((int2byte(len(p)), p) for p in protos)
1846 )
1847
1848 # Build a C string from the list. We don't need to save this off
1849 # because OpenSSL immediately copies the data out.
1850 input_str = _ffi.new("unsigned char[]", protostr)
Cory Benfield9c1979a2015-04-12 08:51:52 -04001851 input_str_len = _ffi.cast("unsigned", len(protostr))
1852 _lib.SSL_set_alpn_protos(self._ssl, input_str, input_str_len)
Cory Benfield12eae892014-06-07 15:42:56 +01001853
1854
1855 def get_alpn_proto_negotiated(self):
Cory Benfielde8e9c382015-04-11 17:33:48 -04001856 """Get the protocol that was negotiated by ALPN."""
Cory Benfield12eae892014-06-07 15:42:56 +01001857 data = _ffi.new("unsigned char **")
1858 data_len = _ffi.new("unsigned int *")
1859
1860 _lib.SSL_get0_alpn_selected(self._ssl, data, data_len)
1861
Cory Benfielde8e9c382015-04-11 17:33:48 -04001862 if not data_len:
1863 return b''
1864
Cory Benfield12eae892014-06-07 15:42:56 +01001865 return _ffi.buffer(data[0], data_len[0])[:]
1866
1867
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001868
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001869ConnectionType = Connection
Jean-Paul Calderone11ed8e82014-01-18 10:21:50 -05001870
Jean-Paul Calderonefab157b2014-01-18 11:21:38 -05001871# This is similar to the initialization calls at the end of OpenSSL/crypto.py
1872# but is exercised mostly by the Context initializer.
Jean-Paul Calderone11ed8e82014-01-18 10:21:50 -05001873_lib.SSL_library_init()