blob: 6dba10cabdf4934d784028f22cefbb768e9f7ed7 [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,
Jean-Paul Calderone00f84eb2015-04-13 12:47:21 -040017 UNSPECIFIED as _UNSPECIFIED,
Jean-Paul Calderone55f9e882015-04-12 09:31:03 -040018)
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080019
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -080020from OpenSSL.crypto import (
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -050021 FILETYPE_PEM, _PassphraseHelper, PKey, X509Name, X509, X509Store)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -080022
Jean-Paul Calderone8fb53182013-12-30 08:35:49 -050023try:
24 _memoryview = memoryview
25except NameError:
26 class _memoryview(object):
27 pass
28
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +020029try:
30 _buffer = buffer
31except NameError:
32 class _buffer(object):
33 pass
34
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050035OPENSSL_VERSION_NUMBER = _lib.OPENSSL_VERSION_NUMBER
36SSLEAY_VERSION = _lib.SSLEAY_VERSION
37SSLEAY_CFLAGS = _lib.SSLEAY_CFLAGS
38SSLEAY_PLATFORM = _lib.SSLEAY_PLATFORM
39SSLEAY_DIR = _lib.SSLEAY_DIR
40SSLEAY_BUILT_ON = _lib.SSLEAY_BUILT_ON
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080041
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050042SENT_SHUTDOWN = _lib.SSL_SENT_SHUTDOWN
43RECEIVED_SHUTDOWN = _lib.SSL_RECEIVED_SHUTDOWN
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080044
45SSLv2_METHOD = 1
46SSLv3_METHOD = 2
47SSLv23_METHOD = 3
48TLSv1_METHOD = 4
Jean-Paul Calderone56bff942013-11-03 11:30:43 -050049TLSv1_1_METHOD = 5
50TLSv1_2_METHOD = 6
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080051
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050052OP_NO_SSLv2 = _lib.SSL_OP_NO_SSLv2
53OP_NO_SSLv3 = _lib.SSL_OP_NO_SSLv3
54OP_NO_TLSv1 = _lib.SSL_OP_NO_TLSv1
Jean-Paul Calderonebe2bb422013-12-29 07:34:08 -050055
56OP_NO_TLSv1_1 = getattr(_lib, "SSL_OP_NO_TLSv1_1", 0)
57OP_NO_TLSv1_2 = getattr(_lib, "SSL_OP_NO_TLSv1_2", 0)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -080058
Jean-Paul Calderone0d7e8a12014-01-08 16:54:13 -050059try:
60 MODE_RELEASE_BUFFERS = _lib.SSL_MODE_RELEASE_BUFFERS
61except AttributeError:
62 pass
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080063
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050064OP_SINGLE_DH_USE = _lib.SSL_OP_SINGLE_DH_USE
65OP_EPHEMERAL_RSA = _lib.SSL_OP_EPHEMERAL_RSA
66OP_MICROSOFT_SESS_ID_BUG = _lib.SSL_OP_MICROSOFT_SESS_ID_BUG
67OP_NETSCAPE_CHALLENGE_BUG = _lib.SSL_OP_NETSCAPE_CHALLENGE_BUG
68OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG = _lib.SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG
69OP_SSLREF2_REUSE_CERT_TYPE_BUG = _lib.SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG
70OP_MICROSOFT_BIG_SSLV3_BUFFER = _lib.SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER
Jean-Paul Calderone0d7e8a12014-01-08 16:54:13 -050071try:
72 OP_MSIE_SSLV2_RSA_PADDING = _lib.SSL_OP_MSIE_SSLV2_RSA_PADDING
73except AttributeError:
74 pass
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050075OP_SSLEAY_080_CLIENT_DH_BUG = _lib.SSL_OP_SSLEAY_080_CLIENT_DH_BUG
76OP_TLS_D5_BUG = _lib.SSL_OP_TLS_D5_BUG
77OP_TLS_BLOCK_PADDING_BUG = _lib.SSL_OP_TLS_BLOCK_PADDING_BUG
78OP_DONT_INSERT_EMPTY_FRAGMENTS = _lib.SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
79OP_CIPHER_SERVER_PREFERENCE = _lib.SSL_OP_CIPHER_SERVER_PREFERENCE
80OP_TLS_ROLLBACK_BUG = _lib.SSL_OP_TLS_ROLLBACK_BUG
81OP_PKCS1_CHECK_1 = _lib.SSL_OP_PKCS1_CHECK_1
82OP_PKCS1_CHECK_2 = _lib.SSL_OP_PKCS1_CHECK_2
83OP_NETSCAPE_CA_DN_BUG = _lib.SSL_OP_NETSCAPE_CA_DN_BUG
84OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG= _lib.SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG
Jean-Paul Calderonec1780342014-01-08 16:59:03 -050085try:
86 OP_NO_COMPRESSION = _lib.SSL_OP_NO_COMPRESSION
87except AttributeError:
88 pass
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -080089
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050090OP_NO_QUERY_MTU = _lib.SSL_OP_NO_QUERY_MTU
91OP_COOKIE_EXCHANGE = _lib.SSL_OP_COOKIE_EXCHANGE
Arturo Filastò5f8c7a82014-03-09 20:01:25 +010092try:
93 OP_NO_TICKET = _lib.SSL_OP_NO_TICKET
94except AttributeError:
95 pass
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -080096
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050097OP_ALL = _lib.SSL_OP_ALL
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080098
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050099VERIFY_PEER = _lib.SSL_VERIFY_PEER
100VERIFY_FAIL_IF_NO_PEER_CERT = _lib.SSL_VERIFY_FAIL_IF_NO_PEER_CERT
101VERIFY_CLIENT_ONCE = _lib.SSL_VERIFY_CLIENT_ONCE
102VERIFY_NONE = _lib.SSL_VERIFY_NONE
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -0800103
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500104SESS_CACHE_OFF = _lib.SSL_SESS_CACHE_OFF
105SESS_CACHE_CLIENT = _lib.SSL_SESS_CACHE_CLIENT
106SESS_CACHE_SERVER = _lib.SSL_SESS_CACHE_SERVER
107SESS_CACHE_BOTH = _lib.SSL_SESS_CACHE_BOTH
108SESS_CACHE_NO_AUTO_CLEAR = _lib.SSL_SESS_CACHE_NO_AUTO_CLEAR
109SESS_CACHE_NO_INTERNAL_LOOKUP = _lib.SSL_SESS_CACHE_NO_INTERNAL_LOOKUP
110SESS_CACHE_NO_INTERNAL_STORE = _lib.SSL_SESS_CACHE_NO_INTERNAL_STORE
111SESS_CACHE_NO_INTERNAL = _lib.SSL_SESS_CACHE_NO_INTERNAL
Jean-Paul Calderoned39a3f62013-03-04 12:23:51 -0800112
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500113SSL_ST_CONNECT = _lib.SSL_ST_CONNECT
114SSL_ST_ACCEPT = _lib.SSL_ST_ACCEPT
115SSL_ST_MASK = _lib.SSL_ST_MASK
116SSL_ST_INIT = _lib.SSL_ST_INIT
117SSL_ST_BEFORE = _lib.SSL_ST_BEFORE
118SSL_ST_OK = _lib.SSL_ST_OK
119SSL_ST_RENEGOTIATE = _lib.SSL_ST_RENEGOTIATE
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800120
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500121SSL_CB_LOOP = _lib.SSL_CB_LOOP
122SSL_CB_EXIT = _lib.SSL_CB_EXIT
123SSL_CB_READ = _lib.SSL_CB_READ
124SSL_CB_WRITE = _lib.SSL_CB_WRITE
125SSL_CB_ALERT = _lib.SSL_CB_ALERT
126SSL_CB_READ_ALERT = _lib.SSL_CB_READ_ALERT
127SSL_CB_WRITE_ALERT = _lib.SSL_CB_WRITE_ALERT
128SSL_CB_ACCEPT_LOOP = _lib.SSL_CB_ACCEPT_LOOP
129SSL_CB_ACCEPT_EXIT = _lib.SSL_CB_ACCEPT_EXIT
130SSL_CB_CONNECT_LOOP = _lib.SSL_CB_CONNECT_LOOP
131SSL_CB_CONNECT_EXIT = _lib.SSL_CB_CONNECT_EXIT
132SSL_CB_HANDSHAKE_START = _lib.SSL_CB_HANDSHAKE_START
133SSL_CB_HANDSHAKE_DONE = _lib.SSL_CB_HANDSHAKE_DONE
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800134
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500135class Error(Exception):
Jean-Paul Calderone511cde02013-12-29 10:31:13 -0500136 """
137 An error occurred in an `OpenSSL.SSL` API.
138 """
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500139
140
141
142_raise_current_error = partial(_exception_from_error_queue, Error)
143
144
145class WantReadError(Error):
146 pass
147
148
149
150class WantWriteError(Error):
151 pass
152
153
154
155class WantX509LookupError(Error):
156 pass
157
158
159
160class ZeroReturnError(Error):
161 pass
162
163
164
165class SysCallError(Error):
166 pass
167
168
Cory Benfield0ea76e72015-03-22 09:05:28 +0000169class _CallbackExceptionHelper(object):
170 """
171 A base class for wrapper classes that allow for intelligent exception
172 handling in OpenSSL callbacks.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500173
Jean-Paul Calderone1b172982015-03-22 19:37:11 -0400174 :ivar list _problems: Any exceptions that occurred while executing in a
175 context where they could not be raised in the normal way. Typically
176 this is because OpenSSL has called into some Python code and requires a
177 return value. The exceptions are saved to be raised later when it is
178 possible to do so.
Cory Benfield0ea76e72015-03-22 09:05:28 +0000179 """
Jean-Paul Calderone09540d72015-03-22 19:37:20 -0400180 def __init__(self):
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800181 self._problems = []
182
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800183
Cory Benfield0ea76e72015-03-22 09:05:28 +0000184 def raise_if_problem(self):
Jean-Paul Calderone1b172982015-03-22 19:37:11 -0400185 """
186 Raise an exception from the OpenSSL error queue or that was previously
187 captured whe running a callback.
188 """
Cory Benfield0ea76e72015-03-22 09:05:28 +0000189 if self._problems:
190 try:
191 _raise_current_error()
192 except Error:
193 pass
194 raise self._problems.pop(0)
195
196
197class _VerifyHelper(_CallbackExceptionHelper):
Jean-Paul Calderone1b172982015-03-22 19:37:11 -0400198 """
199 Wrap a callback such that it can be used as a certificate verification
200 callback.
201 """
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800202 def __init__(self, callback):
Jean-Paul Calderone837f4032015-03-22 17:38:28 -0400203 _CallbackExceptionHelper.__init__(self)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800204
205 @wraps(callback)
206 def wrapper(ok, store_ctx):
207 cert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500208 cert._x509 = _lib.X509_STORE_CTX_get_current_cert(store_ctx)
209 error_number = _lib.X509_STORE_CTX_get_error(store_ctx)
210 error_depth = _lib.X509_STORE_CTX_get_error_depth(store_ctx)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800211
Jean-Paul Calderone6a8cd112014-04-02 21:09:08 -0400212 index = _lib.SSL_get_ex_data_X509_STORE_CTX_idx()
213 ssl = _lib.X509_STORE_CTX_get_ex_data(store_ctx, index)
214 connection = Connection._reverse_mapping[ssl]
215
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800216 try:
217 result = callback(connection, cert, error_number, error_depth, ok)
218 except Exception as e:
219 self._problems.append(e)
220 return 0
221 else:
222 if result:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500223 _lib.X509_STORE_CTX_set_error(store_ctx, _lib.X509_V_OK)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800224 return 1
225 else:
226 return 0
227
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500228 self.callback = _ffi.callback(
229 "int (*)(int, X509_STORE_CTX *)", wrapper)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800230
231
Cory Benfield0ea76e72015-03-22 09:05:28 +0000232class _NpnAdvertiseHelper(_CallbackExceptionHelper):
Jean-Paul Calderone1b172982015-03-22 19:37:11 -0400233 """
234 Wrap a callback such that it can be used as an NPN advertisement callback.
235 """
Cory Benfield0ea76e72015-03-22 09:05:28 +0000236 def __init__(self, callback):
Jean-Paul Calderone837f4032015-03-22 17:38:28 -0400237 _CallbackExceptionHelper.__init__(self)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800238
Cory Benfield0ea76e72015-03-22 09:05:28 +0000239 @wraps(callback)
240 def wrapper(ssl, out, outlen, arg):
241 try:
242 conn = Connection._reverse_mapping[ssl]
243 protos = callback(conn)
244
245 # Join the protocols into a Python bytestring, length-prefixing
246 # each element.
247 protostr = b''.join(
248 chain.from_iterable((int2byte(len(p)), p) for p in protos)
249 )
250
251 # Save our callback arguments on the connection object. This is
252 # done to make sure that they don't get freed before OpenSSL
253 # uses them. Then, return them appropriately in the output
254 # parameters.
255 conn._npn_advertise_callback_args = [
256 _ffi.new("unsigned int *", len(protostr)),
257 _ffi.new("unsigned char[]", protostr),
258 ]
259 outlen[0] = conn._npn_advertise_callback_args[0][0]
260 out[0] = conn._npn_advertise_callback_args[1]
261 return 0
262 except Exception as e:
263 self._problems.append(e)
264 return 2 # SSL_TLSEXT_ERR_ALERT_FATAL
265
266 self.callback = _ffi.callback(
267 "int (*)(SSL *, const unsigned char **, unsigned int *, void *)",
268 wrapper
269 )
270
271
272class _NpnSelectHelper(_CallbackExceptionHelper):
Jean-Paul Calderone1b172982015-03-22 19:37:11 -0400273 """
274 Wrap a callback such that it can be used as an NPN selection callback.
275 """
Cory Benfield0ea76e72015-03-22 09:05:28 +0000276 def __init__(self, callback):
Jean-Paul Calderone837f4032015-03-22 17:38:28 -0400277 _CallbackExceptionHelper.__init__(self)
Cory Benfield0ea76e72015-03-22 09:05:28 +0000278
279 @wraps(callback)
280 def wrapper(ssl, out, outlen, in_, inlen, arg):
281 try:
282 conn = Connection._reverse_mapping[ssl]
283
284 # The string passed to us is actually made up of multiple
285 # length-prefixed bytestrings. We need to split that into a
286 # list.
287 instr = _ffi.buffer(in_, inlen)[:]
288 protolist = []
289 while instr:
290 l = indexbytes(instr, 0)
291 proto = instr[1:l+1]
292 protolist.append(proto)
293 instr = instr[l+1:]
294
295 # Call the callback
296 outstr = callback(conn, protolist)
297
298 # Save our callback arguments on the connection object. This is
299 # done to make sure that they don't get freed before OpenSSL
300 # uses them. Then, return them appropriately in the output
301 # parameters.
302 conn._npn_select_callback_args = [
303 _ffi.new("unsigned char *", len(outstr)),
304 _ffi.new("unsigned char[]", outstr),
305 ]
306 outlen[0] = conn._npn_select_callback_args[0][0]
307 out[0] = conn._npn_select_callback_args[1]
308 return 0
309 except Exception as e:
310 self._problems.append(e)
311 return 2 # SSL_TLSEXT_ERR_ALERT_FATAL
312
313 self.callback = _ffi.callback(
314 "int (*)(SSL *, unsigned char **, unsigned char *, "
315 "const unsigned char *, unsigned int, void *)",
316 wrapper
317 )
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800318
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800319
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800320def _asFileDescriptor(obj):
321 fd = None
Konstantinos Koukopoulosc8b13ea2014-01-28 00:21:50 -0800322 if not isinstance(obj, integer_types):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800323 meth = getattr(obj, "fileno", None)
324 if meth is not None:
325 obj = meth()
326
Konstantinos Koukopoulosc8b13ea2014-01-28 00:21:50 -0800327 if isinstance(obj, integer_types):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800328 fd = obj
329
Konstantinos Koukopoulosc8b13ea2014-01-28 00:21:50 -0800330 if not isinstance(fd, integer_types):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800331 raise TypeError("argument must be an int, or have a fileno() method.")
332 elif fd < 0:
333 raise ValueError(
334 "file descriptor cannot be a negative integer (%i)" % (fd,))
335
336 return fd
337
338
339
Jean-Paul Calderoned39a3f62013-03-04 12:23:51 -0800340def SSLeay_version(type):
341 """
342 Return a string describing the version of OpenSSL in use.
343
344 :param type: One of the SSLEAY_ constants defined in this module.
345 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500346 return _ffi.string(_lib.SSLeay_version(type))
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800347
348
349
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800350class Session(object):
351 pass
352
353
354
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800355class Context(object):
356 """
357 :py:obj:`OpenSSL.SSL.Context` instances define the parameters for setting up
358 new SSL connections.
359 """
360 _methods = {
Andrew Dunhamec84a0a2014-02-24 12:41:37 -0800361 SSLv2_METHOD: "SSLv2_method",
Jean-Paul Calderonebe2bb422013-12-29 07:34:08 -0500362 SSLv3_METHOD: "SSLv3_method",
363 SSLv23_METHOD: "SSLv23_method",
364 TLSv1_METHOD: "TLSv1_method",
365 TLSv1_1_METHOD: "TLSv1_1_method",
366 TLSv1_2_METHOD: "TLSv1_2_method",
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800367 }
Jean-Paul Calderonebe2bb422013-12-29 07:34:08 -0500368 _methods = dict(
369 (identifier, getattr(_lib, name))
370 for (identifier, name) in _methods.items()
371 if getattr(_lib, name, None) is not None)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800372
Jean-Paul Calderone63157872013-03-20 16:43:38 -0700373
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800374 def __init__(self, method):
375 """
376 :param method: One of SSLv2_METHOD, SSLv3_METHOD, SSLv23_METHOD, or
377 TLSv1_METHOD.
378 """
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -0500379 if not isinstance(method, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800380 raise TypeError("method must be an integer")
381
382 try:
383 method_func = self._methods[method]
384 except KeyError:
385 raise ValueError("No such protocol")
386
387 method_obj = method_func()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500388 if method_obj == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500389 # TODO: This is untested.
390 _raise_current_error()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800391
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500392 context = _lib.SSL_CTX_new(method_obj)
393 if context == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500394 # TODO: This is untested.
395 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500396 context = _ffi.gc(context, _lib.SSL_CTX_free)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800397
398 self._context = context
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800399 self._passphrase_helper = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800400 self._passphrase_callback = None
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800401 self._passphrase_userdata = None
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800402 self._verify_helper = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800403 self._verify_callback = None
404 self._info_callback = None
405 self._tlsext_servername_callback = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800406 self._app_data = None
Cory Benfield0ea76e72015-03-22 09:05:28 +0000407 self._npn_advertise_helper = None
Cory Benfield84a121e2014-03-31 20:30:25 +0100408 self._npn_advertise_callback = None
Cory Benfield0ea76e72015-03-22 09:05:28 +0000409 self._npn_select_helper = None
Cory Benfield84a121e2014-03-31 20:30:25 +0100410 self._npn_select_callback = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800411
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -0800412 # SSL_CTX_set_app_data(self->ctx, self);
413 # SSL_CTX_set_mode(self->ctx, SSL_MODE_ENABLE_PARTIAL_WRITE |
414 # SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
415 # SSL_MODE_AUTO_RETRY);
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500416 self.set_mode(_lib.SSL_MODE_ENABLE_PARTIAL_WRITE)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800417
418
419 def load_verify_locations(self, cafile, capath=None):
420 """
421 Let SSL know where we can find trusted certificates for the certificate
422 chain
423
Jean-Paul Calderone55f9e882015-04-12 09:31:03 -0400424 :param cafile: In which file we can find the certificates (``bytes`` or
425 ``unicode``).
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800426 :param capath: In which directory we can find the certificates
Jean-Paul Calderone55f9e882015-04-12 09:31:03 -0400427 (``bytes`` or ``unicode``).
428
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800429 :return: None
430 """
431 if cafile is None:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500432 cafile = _ffi.NULL
Jean-Paul Calderone55f9e882015-04-12 09:31:03 -0400433 else:
434 cafile = _path_string(cafile)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800435
436 if capath is None:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500437 capath = _ffi.NULL
Jean-Paul Calderone55f9e882015-04-12 09:31:03 -0400438 else:
439 capath = _path_string(capath)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800440
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500441 load_result = _lib.SSL_CTX_load_verify_locations(self._context, cafile, capath)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800442 if not load_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500443 _raise_current_error()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800444
445
446 def _wrap_callback(self, callback):
447 @wraps(callback)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800448 def wrapper(size, verify, userdata):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800449 return callback(size, verify, self._passphrase_userdata)
450 return _PassphraseHelper(
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800451 FILETYPE_PEM, wrapper, more_args=True, truncate=True)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800452
453
454 def set_passwd_cb(self, callback, userdata=None):
455 """
456 Set the passphrase callback
457
458 :param callback: The Python callback to use
459 :param userdata: (optional) A Python object which will be given as
460 argument to the callback
461 :return: None
462 """
463 if not callable(callback):
464 raise TypeError("callback must be callable")
465
466 self._passphrase_helper = self._wrap_callback(callback)
467 self._passphrase_callback = self._passphrase_helper.callback
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500468 _lib.SSL_CTX_set_default_passwd_cb(
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800469 self._context, self._passphrase_callback)
470 self._passphrase_userdata = userdata
471
472
473 def set_default_verify_paths(self):
474 """
475 Use the platform-specific CA certificate locations
476
477 :return: None
478 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500479 set_result = _lib.SSL_CTX_set_default_verify_paths(self._context)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800480 if not set_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500481 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500482 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800483
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800484
485 def use_certificate_chain_file(self, certfile):
486 """
487 Load a certificate chain from a file
488
Jean-Paul Calderoneb6f8a792015-04-13 10:10:06 -0400489 :param certfile: The name of the certificate chain file (``bytes`` or
490 ``unicode``).
491
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800492 :return: None
493 """
Jean-Paul Calderoneaac43a32015-04-12 09:51:21 -0400494 certfile = _path_string(certfile)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800495
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500496 result = _lib.SSL_CTX_use_certificate_chain_file(self._context, certfile)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800497 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500498 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800499
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800500
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800501 def use_certificate_file(self, certfile, filetype=FILETYPE_PEM):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800502 """
503 Load a certificate from a file
504
Jean-Paul Calderoneb6f8a792015-04-13 10:10:06 -0400505 :param certfile: The name of the certificate file (``bytes`` or
506 ``unicode``).
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800507 :param filetype: (optional) The encoding of the file, default is PEM
Jean-Paul Calderoneb6f8a792015-04-13 10:10:06 -0400508
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800509 :return: None
510 """
Jean-Paul Calderoned57a7b62015-04-12 09:57:36 -0400511 certfile = _path_string(certfile)
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -0500512 if not isinstance(filetype, integer_types):
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800513 raise TypeError("filetype must be an integer")
514
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500515 use_result = _lib.SSL_CTX_use_certificate_file(self._context, certfile, filetype)
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800516 if not use_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500517 _raise_current_error()
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800518
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800519
520 def use_certificate(self, cert):
521 """
522 Load a certificate from a X509 object
523
524 :param cert: The X509 object
525 :return: None
526 """
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800527 if not isinstance(cert, X509):
528 raise TypeError("cert must be an X509 instance")
529
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500530 use_result = _lib.SSL_CTX_use_certificate(self._context, cert._x509)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800531 if not use_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500532 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800533
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800534
535 def add_extra_chain_cert(self, certobj):
536 """
537 Add certificate to chain
538
539 :param certobj: The X509 certificate object to add to the chain
540 :return: None
541 """
542 if not isinstance(certobj, X509):
543 raise TypeError("certobj must be an X509 instance")
544
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500545 copy = _lib.X509_dup(certobj._x509)
546 add_result = _lib.SSL_CTX_add_extra_chain_cert(self._context, copy)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800547 if not add_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500548 # TODO: This is untested.
549 _lib.X509_free(copy)
550 _raise_current_error()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800551
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800552
553 def _raise_passphrase_exception(self):
554 if self._passphrase_helper is None:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500555 _raise_current_error()
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800556 exception = self._passphrase_helper.raise_if_problem(Error)
557 if exception is not None:
558 raise exception
559
560
Jean-Paul Calderone00f84eb2015-04-13 12:47:21 -0400561 def use_privatekey_file(self, keyfile, filetype=_UNSPECIFIED):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800562 """
563 Load a private key from a file
564
Jean-Paul Calderoneb6f8a792015-04-13 10:10:06 -0400565 :param keyfile: The name of the key file (``bytes`` or ``unicode``)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800566 :param filetype: (optional) The encoding of the file, default is PEM
Jean-Paul Calderoneb6f8a792015-04-13 10:10:06 -0400567
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800568 :return: None
569 """
Jean-Paul Calderone69a4e5b2015-04-12 10:04:28 -0400570 keyfile = _path_string(keyfile)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800571
Jean-Paul Calderone00f84eb2015-04-13 12:47:21 -0400572 if filetype is _UNSPECIFIED:
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800573 filetype = FILETYPE_PEM
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -0500574 elif not isinstance(filetype, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800575 raise TypeError("filetype must be an integer")
576
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500577 use_result = _lib.SSL_CTX_use_PrivateKey_file(
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800578 self._context, keyfile, filetype)
579 if not use_result:
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800580 self._raise_passphrase_exception()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800581
582
583 def use_privatekey(self, pkey):
584 """
585 Load a private key from a PKey object
586
587 :param pkey: The PKey object
588 :return: None
589 """
590 if not isinstance(pkey, PKey):
591 raise TypeError("pkey must be a PKey instance")
592
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500593 use_result = _lib.SSL_CTX_use_PrivateKey(self._context, pkey._pkey)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800594 if not use_result:
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800595 self._raise_passphrase_exception()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800596
597
598 def check_privatekey(self):
599 """
600 Check that the private key and certificate match up
601
602 :return: None (raises an exception if something's wrong)
603 """
Jean-Paul Calderonea0344922014-12-11 14:02:31 -0500604 if not _lib.SSL_CTX_check_private_key(self._context):
605 _raise_current_error()
606
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800607
608 def load_client_ca(self, cafile):
609 """
610 Load the trusted certificates that will be sent to the client (basically
611 telling the client "These are the guys I trust"). Does not actually
612 imply any of the certificates are trusted; that must be configured
613 separately.
614
615 :param cafile: The name of the certificates file
616 :return: None
617 """
618
619 def set_session_id(self, buf):
620 """
621 Set the session identifier. This is needed if you want to do session
622 resumption.
623
624 :param buf: A Python object that can be safely converted to a string
625 :returns: None
626 """
627
628 def set_session_cache_mode(self, mode):
629 """
630 Enable/disable session caching and specify the mode used.
631
632 :param mode: One or more of the SESS_CACHE_* flags (combine using
633 bitwise or)
634 :returns: The previously set caching mode.
635 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500636 if not isinstance(mode, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800637 raise TypeError("mode must be an integer")
638
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500639 return _lib.SSL_CTX_set_session_cache_mode(self._context, mode)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800640
641
642 def get_session_cache_mode(self):
643 """
644 :returns: The currently used cache mode.
645 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500646 return _lib.SSL_CTX_get_session_cache_mode(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800647
648
649 def set_verify(self, mode, callback):
650 """
651 Set the verify mode and verify callback
652
653 :param mode: The verify mode, this is either VERIFY_NONE or
654 VERIFY_PEER combined with possible other flags
655 :param callback: The Python callback to use
656 :return: None
657
658 See SSL_CTX_set_verify(3SSL) for further details.
659 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500660 if not isinstance(mode, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800661 raise TypeError("mode must be an integer")
662
663 if not callable(callback):
664 raise TypeError("callback must be callable")
665
Jean-Paul Calderone6a8cd112014-04-02 21:09:08 -0400666 self._verify_helper = _VerifyHelper(callback)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800667 self._verify_callback = self._verify_helper.callback
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500668 _lib.SSL_CTX_set_verify(self._context, mode, self._verify_callback)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800669
670
671 def set_verify_depth(self, depth):
672 """
673 Set the verify depth
674
675 :param depth: An integer specifying the verify depth
676 :return: None
677 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500678 if not isinstance(depth, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800679 raise TypeError("depth must be an integer")
680
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500681 _lib.SSL_CTX_set_verify_depth(self._context, depth)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800682
683
684 def get_verify_mode(self):
685 """
686 Get the verify mode
687
688 :return: The verify mode
689 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500690 return _lib.SSL_CTX_get_verify_mode(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800691
692
693 def get_verify_depth(self):
694 """
695 Get the verify depth
696
697 :return: The verify depth
698 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500699 return _lib.SSL_CTX_get_verify_depth(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800700
701
702 def load_tmp_dh(self, dhfile):
703 """
704 Load parameters for Ephemeral Diffie-Hellman
705
Jean-Paul Calderone4e0c43f2015-04-13 10:15:17 -0400706 :param dhfile: The file to load EDH parameters from (``bytes`` or
707 ``unicode``).
708
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800709 :return: None
710 """
Jean-Paul Calderone9e1c1dd2015-04-12 10:13:13 -0400711 dhfile = _path_string(dhfile)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800712
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -0500713 bio = _lib.BIO_new_file(dhfile, b"r")
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500714 if bio == _ffi.NULL:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500715 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500716 bio = _ffi.gc(bio, _lib.BIO_free)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800717
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500718 dh = _lib.PEM_read_bio_DHparams(bio, _ffi.NULL, _ffi.NULL, _ffi.NULL)
719 dh = _ffi.gc(dh, _lib.DH_free)
720 _lib.SSL_CTX_set_tmp_dh(self._context, dh)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800721
722
Jean-Paul Calderone3e4e3352014-04-19 09:28:28 -0400723 def set_tmp_ecdh(self, curve):
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600724 """
Andy Lutomirski76a61332014-03-12 15:02:56 -0700725 Select a curve to use for ECDHE key exchange.
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600726
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -0400727 :param curve: A curve object to use as returned by either
728 :py:meth:`OpenSSL.crypto.get_elliptic_curve` or
729 :py:meth:`OpenSSL.crypto.get_elliptic_curves`.
Andy Lutomirskif05a2732014-03-13 17:22:25 -0700730
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600731 :return: None
732 """
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -0400733 _lib.SSL_CTX_set_tmp_ecdh(self._context, curve._to_EC_KEY())
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600734
735
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800736 def set_cipher_list(self, cipher_list):
737 """
738 Change the cipher list
739
740 :param cipher_list: A cipher list, see ciphers(1)
741 :return: None
742 """
Jean-Paul Calderone63eab692014-01-18 10:19:56 -0500743 if isinstance(cipher_list, _text_type):
744 cipher_list = cipher_list.encode("ascii")
745
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800746 if not isinstance(cipher_list, bytes):
Jean-Paul Calderone63eab692014-01-18 10:19:56 -0500747 raise TypeError("cipher_list must be bytes or unicode")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800748
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500749 result = _lib.SSL_CTX_set_cipher_list(self._context, cipher_list)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800750 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500751 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800752
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800753
754 def set_client_ca_list(self, certificate_authorities):
755 """
756 Set the list of preferred client certificate signers for this server context.
757
758 This list of certificate authorities will be sent to the client when the
759 server requests a client certificate.
760
761 :param certificate_authorities: a sequence of X509Names.
762 :return: None
763 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500764 name_stack = _lib.sk_X509_NAME_new_null()
765 if name_stack == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500766 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500767 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800768
769 try:
770 for ca_name in certificate_authorities:
771 if not isinstance(ca_name, X509Name):
772 raise TypeError(
773 "client CAs must be X509Name objects, not %s objects" % (
774 type(ca_name).__name__,))
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500775 copy = _lib.X509_NAME_dup(ca_name._name)
776 if copy == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500777 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500778 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500779 push_result = _lib.sk_X509_NAME_push(name_stack, copy)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800780 if not push_result:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500781 _lib.X509_NAME_free(copy)
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500782 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800783 except:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500784 _lib.sk_X509_NAME_free(name_stack)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800785 raise
786
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500787 _lib.SSL_CTX_set_client_CA_list(self._context, name_stack)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800788
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800789
790 def add_client_ca(self, certificate_authority):
791 """
792 Add the CA certificate to the list of preferred signers for this context.
793
794 The list of certificate authorities will be sent to the client when the
795 server requests a client certificate.
796
797 :param certificate_authority: certificate authority's X509 certificate.
798 :return: None
799 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800800 if not isinstance(certificate_authority, X509):
801 raise TypeError("certificate_authority must be an X509 instance")
802
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500803 add_result = _lib.SSL_CTX_add_client_CA(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800804 self._context, certificate_authority._x509)
805 if not add_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500806 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500807 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800808
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800809
810 def set_timeout(self, timeout):
811 """
812 Set session timeout
813
814 :param timeout: The timeout in seconds
815 :return: The previous session timeout
816 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500817 if not isinstance(timeout, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800818 raise TypeError("timeout must be an integer")
819
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500820 return _lib.SSL_CTX_set_timeout(self._context, timeout)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800821
822
823 def get_timeout(self):
824 """
825 Get the session timeout
826
827 :return: The session timeout
828 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500829 return _lib.SSL_CTX_get_timeout(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800830
831
832 def set_info_callback(self, callback):
833 """
834 Set the info callback
835
836 :param callback: The Python callback to use
837 :return: None
838 """
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800839 @wraps(callback)
840 def wrapper(ssl, where, return_code):
Jean-Paul Calderonef2bbc9c2014-02-02 10:59:14 -0500841 callback(Connection._reverse_mapping[ssl], where, return_code)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500842 self._info_callback = _ffi.callback(
843 "void (*)(const SSL *, int, int)", wrapper)
844 _lib.SSL_CTX_set_info_callback(self._context, self._info_callback)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800845
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800846
847 def get_app_data(self):
848 """
849 Get the application data (supplied via set_app_data())
850
851 :return: The application data
852 """
853 return self._app_data
854
855
856 def set_app_data(self, data):
857 """
858 Set the application data (will be returned from get_app_data())
859
860 :param data: Any Python object
861 :return: None
862 """
863 self._app_data = data
864
865
866 def get_cert_store(self):
867 """
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500868 Get the certificate store for the context.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800869
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500870 :return: A X509Store object or None if it does not have one.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800871 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500872 store = _lib.SSL_CTX_get_cert_store(self._context)
873 if store == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500874 # TODO: This is untested.
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800875 return None
876
877 pystore = X509Store.__new__(X509Store)
878 pystore._store = store
879 return pystore
880
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800881
882 def set_options(self, options):
883 """
884 Add options. Options set before are not cleared!
885
886 :param options: The options to add.
887 :return: The new option bitmask.
888 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500889 if not isinstance(options, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800890 raise TypeError("options must be an integer")
891
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500892 return _lib.SSL_CTX_set_options(self._context, options)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800893
894
895 def set_mode(self, mode):
896 """
897 Add modes via bitmask. Modes set before are not cleared!
898
899 :param mode: The mode to add.
900 :return: The new mode bitmask.
901 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500902 if not isinstance(mode, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800903 raise TypeError("mode must be an integer")
904
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500905 return _lib.SSL_CTX_set_mode(self._context, mode)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800906
907
908 def set_tlsext_servername_callback(self, callback):
909 """
910 Specify a callback function to be called when clients specify a server name.
911
912 :param callback: The callback function. It will be invoked with one
913 argument, the Connection instance.
914 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800915 @wraps(callback)
916 def wrapper(ssl, alert, arg):
917 callback(Connection._reverse_mapping[ssl])
918 return 0
919
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500920 self._tlsext_servername_callback = _ffi.callback(
921 "int (*)(const SSL *, int *, void *)", wrapper)
922 _lib.SSL_CTX_set_tlsext_servername_callback(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800923 self._context, self._tlsext_servername_callback)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800924
Cory Benfield84a121e2014-03-31 20:30:25 +0100925
926 def set_npn_advertise_callback(self, callback):
927 """
Cory Benfieldbe3e7b82014-05-10 09:48:55 +0100928 Specify a callback function that will be called when offering `Next
929 Protocol Negotiation
930 <https://technotes.googlecode.com/git/nextprotoneg.html>`_ as a server.
Cory Benfield84a121e2014-03-31 20:30:25 +0100931
932 :param callback: The callback function. It will be invoked with one
Cory Benfieldbe3e7b82014-05-10 09:48:55 +0100933 argument, the Connection instance. It should return a list of
934 bytestrings representing the advertised protocols, like
935 ``[b'http/1.1', b'spdy/2']``.
Cory Benfield84a121e2014-03-31 20:30:25 +0100936 """
Cory Benfield0ea76e72015-03-22 09:05:28 +0000937 self._npn_advertise_helper = _NpnAdvertiseHelper(callback)
938 self._npn_advertise_callback = self._npn_advertise_helper.callback
Cory Benfield84a121e2014-03-31 20:30:25 +0100939 _lib.SSL_CTX_set_next_protos_advertised_cb(
940 self._context, self._npn_advertise_callback, _ffi.NULL)
941
942
943 def set_npn_select_callback(self, callback):
944 """
945 Specify a callback function that will be called when a server offers
946 Next Protocol Negotiation options.
947
948 :param callback: The callback function. It will be invoked with two
949 arguments: the Connection, and a list of offered protocols as
Cory Benfieldbe3e7b82014-05-10 09:48:55 +0100950 bytestrings, e.g. ``[b'http/1.1', b'spdy/2']``. It should return
951 one of those bytestrings, the chosen protocol.
Cory Benfield84a121e2014-03-31 20:30:25 +0100952 """
Cory Benfield0ea76e72015-03-22 09:05:28 +0000953 self._npn_select_helper = _NpnSelectHelper(callback)
954 self._npn_select_callback = self._npn_select_helper.callback
Cory Benfield84a121e2014-03-31 20:30:25 +0100955 _lib.SSL_CTX_set_next_proto_select_cb(
956 self._context, self._npn_select_callback, _ffi.NULL)
957
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800958ContextType = Context
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800959
960
961
962class Connection(object):
963 """
964 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800965 _reverse_mapping = WeakValueDictionary()
966
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800967 def __init__(self, context, socket=None):
968 """
969 Create a new Connection object, using the given OpenSSL.SSL.Context
970 instance and socket.
971
972 :param context: An SSL Context to use for this connection
973 :param socket: The socket to use for transport layer
974 """
975 if not isinstance(context, Context):
976 raise TypeError("context must be a Context instance")
977
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500978 ssl = _lib.SSL_new(context._context)
979 self._ssl = _ffi.gc(ssl, _lib.SSL_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800980 self._context = context
981
Cory Benfieldbe3e7b82014-05-10 09:48:55 +0100982 # References to strings used for Next Protocol Negotiation. OpenSSL's
983 # header files suggest that these might get copied at some point, but
984 # doesn't specify when, so we store them here to make sure they don't
985 # get freed before OpenSSL uses them.
986 self._npn_advertise_callback_args = None
987 self._npn_select_callback_args = None
988
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800989 self._reverse_mapping[self._ssl] = self
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800990
991 if socket is None:
992 self._socket = None
Jean-Paul Calderone73b15c22013-03-05 18:30:39 -0800993 # Don't set up any gc for these, SSL_free will take care of them.
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500994 self._into_ssl = _lib.BIO_new(_lib.BIO_s_mem())
995 self._from_ssl = _lib.BIO_new(_lib.BIO_s_mem())
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800996
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500997 if self._into_ssl == _ffi.NULL or self._from_ssl == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500998 # TODO: This is untested.
999 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001000
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001001 _lib.SSL_set_bio(self._ssl, self._into_ssl, self._from_ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001002 else:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001003 self._into_ssl = None
1004 self._from_ssl = None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001005 self._socket = socket
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001006 set_result = _lib.SSL_set_fd(self._ssl, _asFileDescriptor(self._socket))
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001007 if not set_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001008 # TODO: This is untested.
1009 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001010
1011
1012 def __getattr__(self, name):
1013 """
1014 Look up attributes on the wrapped socket object if they are not found on
1015 the Connection object.
1016 """
1017 return getattr(self._socket, name)
1018
1019
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001020 def _raise_ssl_error(self, ssl, result):
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -08001021 if self._context._verify_helper is not None:
1022 self._context._verify_helper.raise_if_problem()
Cory Benfield0ea76e72015-03-22 09:05:28 +00001023 if self._context._npn_advertise_helper is not None:
1024 self._context._npn_advertise_helper.raise_if_problem()
1025 if self._context._npn_select_helper is not None:
1026 self._context._npn_select_helper.raise_if_problem()
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -08001027
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001028 error = _lib.SSL_get_error(ssl, result)
1029 if error == _lib.SSL_ERROR_WANT_READ:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001030 raise WantReadError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001031 elif error == _lib.SSL_ERROR_WANT_WRITE:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001032 raise WantWriteError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001033 elif error == _lib.SSL_ERROR_ZERO_RETURN:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001034 raise ZeroReturnError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001035 elif error == _lib.SSL_ERROR_WANT_X509_LOOKUP:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001036 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001037 raise WantX509LookupError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001038 elif error == _lib.SSL_ERROR_SYSCALL:
1039 if _lib.ERR_peek_error() == 0:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001040 if result < 0:
Konstantinos Koukopoulos541150d2014-01-31 01:00:19 +02001041 if platform == "win32":
1042 errno = _ffi.getwinerror()[0]
1043 else:
1044 errno = _ffi.errno
1045 raise SysCallError(errno, errorcode[errno])
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001046 else:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001047 raise SysCallError(-1, "Unexpected EOF")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001048 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001049 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001050 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001051 elif error == _lib.SSL_ERROR_NONE:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001052 pass
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001053 else:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001054 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001055
1056
1057 def get_context(self):
1058 """
1059 Get session context
1060 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001061 return self._context
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001062
1063
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001064 def set_context(self, context):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001065 """
1066 Switch this connection to a new session context
1067
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001068 :param context: A :py:class:`Context` instance giving the new session
1069 context to use.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001070 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001071 if not isinstance(context, Context):
1072 raise TypeError("context must be a Context instance")
1073
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001074 _lib.SSL_set_SSL_CTX(self._ssl, context._context)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001075 self._context = context
1076
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001077
1078 def get_servername(self):
1079 """
1080 Retrieve the servername extension value if provided in the client hello
1081 message, or None if there wasn't one.
1082
1083 :return: A byte string giving the server name or :py:data:`None`.
1084 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001085 name = _lib.SSL_get_servername(self._ssl, _lib.TLSEXT_NAMETYPE_host_name)
1086 if name == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001087 return None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001088
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001089 return _ffi.string(name)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001090
1091
1092 def set_tlsext_host_name(self, name):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001093 """
1094 Set the value of the servername extension to send in the client hello.
1095
1096 :param name: A byte string giving the name.
1097 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001098 if not isinstance(name, bytes):
1099 raise TypeError("name must be a byte string")
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001100 elif b"\0" in name:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001101 raise TypeError("name must not contain NUL byte")
1102
1103 # XXX I guess this can fail sometimes?
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001104 _lib.SSL_set_tlsext_host_name(self._ssl, name)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001105
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001106
1107 def pending(self):
1108 """
1109 Get the number of bytes that can be safely read from the connection
1110
1111 :return: The number of bytes available in the receive buffer.
1112 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001113 return _lib.SSL_pending(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001114
1115
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001116 def send(self, buf, flags=0):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001117 """
1118 Send data on the connection. NOTE: If you get one of the WantRead,
1119 WantWrite or WantX509Lookup exceptions on this, you have to call the
1120 method again with the SAME buffer.
1121
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001122 :param buf: The string, buffer or memoryview to send
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001123 :param flags: (optional) Included for compatibility with the socket
1124 API, the value is ignored
1125 :return: The number of bytes written
1126 """
Jean-Paul Calderone8fb53182013-12-30 08:35:49 -05001127 if isinstance(buf, _memoryview):
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -08001128 buf = buf.tobytes()
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001129 if isinstance(buf, _buffer):
1130 buf = str(buf)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001131 if not isinstance(buf, bytes):
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001132 raise TypeError("data must be a memoryview, buffer or byte string")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001133
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001134 result = _lib.SSL_write(self._ssl, buf, len(buf))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001135 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001136 return result
1137 write = send
1138
1139
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001140 def sendall(self, buf, flags=0):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001141 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001142 Send "all" data on the connection. This calls send() repeatedly until
1143 all data is sent. If an error occurs, it's impossible to tell how much
1144 data has been sent.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001145
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001146 :param buf: The string, buffer or memoryview to send
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001147 :param flags: (optional) Included for compatibility with the socket
1148 API, the value is ignored
1149 :return: The number of bytes written
1150 """
Jean-Paul Calderone8fb53182013-12-30 08:35:49 -05001151 if isinstance(buf, _memoryview):
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -08001152 buf = buf.tobytes()
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001153 if isinstance(buf, _buffer):
1154 buf = str(buf)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001155 if not isinstance(buf, bytes):
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001156 raise TypeError("buf must be a memoryview, buffer or byte string")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001157
1158 left_to_send = len(buf)
1159 total_sent = 0
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001160 data = _ffi.new("char[]", buf)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001161
1162 while left_to_send:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001163 result = _lib.SSL_write(self._ssl, data + total_sent, left_to_send)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001164 self._raise_ssl_error(self._ssl, result)
1165 total_sent += result
1166 left_to_send -= result
1167
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001168
1169 def recv(self, bufsiz, flags=None):
1170 """
1171 Receive data on the connection. NOTE: If you get one of the WantRead,
1172 WantWrite or WantX509Lookup exceptions on this, you have to call the
1173 method again with the SAME buffer.
1174
1175 :param bufsiz: The maximum number of bytes to read
1176 :param flags: (optional) Included for compatibility with the socket
1177 API, the value is ignored
1178 :return: The string read from the Connection
1179 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001180 buf = _ffi.new("char[]", bufsiz)
1181 result = _lib.SSL_read(self._ssl, buf, bufsiz)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001182 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001183 return _ffi.buffer(buf, result)[:]
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001184 read = recv
1185
1186
Cory Benfield62d10332014-06-15 10:03:41 +01001187 def recv_into(self, buffer, nbytes=None, flags=None):
1188 """
1189 Receive data on the connection and store the data into a buffer rather
1190 than creating a new string.
1191
1192 :param buffer: The buffer to copy into.
1193 :param nbytes: (optional) The maximum number of bytes to read into the
1194 buffer. If not present, defaults to the size of the buffer. If
1195 larger than the size of the buffer, is reduced to the size of the
1196 buffer.
1197 :param flags: (optional) Included for compatibility with the socket
1198 API, the value is ignored.
1199 :return: The number of bytes read into the buffer.
1200 """
1201 if nbytes is None:
1202 nbytes = len(buffer)
1203 else:
1204 nbytes = min(nbytes, len(buffer))
1205
1206 # We need to create a temporary buffer. This is annoying, it would be
1207 # better if we could pass memoryviews straight into the SSL_read call,
1208 # but right now we can't. Revisit this if CFFI gets that ability.
1209 buf = _ffi.new("char[]", nbytes)
1210 result = _lib.SSL_read(self._ssl, buf, nbytes)
1211 self._raise_ssl_error(self._ssl, result)
1212
1213 # This strange line is all to avoid a memory copy. The buffer protocol
1214 # should allow us to assign a CFFI buffer to the LHS of this line, but
1215 # on CPython 3.3+ that segfaults. As a workaround, we can temporarily
1216 # wrap it in a memoryview, except on Python 2.6 which doesn't have a
1217 # memoryview type.
1218 try:
1219 buffer[:result] = memoryview(_ffi.buffer(buf, result))
1220 except NameError:
1221 buffer[:result] = _ffi.buffer(buf, result)
1222
1223 return result
1224
1225
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001226 def _handle_bio_errors(self, bio, result):
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001227 if _lib.BIO_should_retry(bio):
1228 if _lib.BIO_should_read(bio):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001229 raise WantReadError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001230 elif _lib.BIO_should_write(bio):
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001231 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001232 raise WantWriteError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001233 elif _lib.BIO_should_io_special(bio):
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001234 # TODO: This is untested. I think io_special means the socket
1235 # BIO has a not-yet connected socket.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001236 raise ValueError("BIO_should_io_special")
1237 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001238 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001239 raise ValueError("unknown bio failure")
1240 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001241 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001242 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001243
1244
1245 def bio_read(self, bufsiz):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001246 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001247 When using non-socket connections this function reads the "dirty" data
1248 that would have traveled away on the network.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001249
1250 :param bufsiz: The maximum number of bytes to read
1251 :return: The string read.
1252 """
Jean-Paul Calderone97e041d2013-03-05 21:03:12 -08001253 if self._from_ssl is None:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001254 raise TypeError("Connection sock was not None")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001255
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -05001256 if not isinstance(bufsiz, integer_types):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001257 raise TypeError("bufsiz must be an integer")
1258
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001259 buf = _ffi.new("char[]", bufsiz)
1260 result = _lib.BIO_read(self._from_ssl, buf, bufsiz)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001261 if result <= 0:
1262 self._handle_bio_errors(self._from_ssl, result)
1263
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001264 return _ffi.buffer(buf, result)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001265
1266
1267 def bio_write(self, buf):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001268 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001269 When using non-socket connections this function sends "dirty" data that
1270 would have traveled in on the network.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001271
1272 :param buf: The string to put into the memory BIO.
1273 :return: The number of bytes written
1274 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001275 if self._into_ssl is None:
1276 raise TypeError("Connection sock was not None")
1277
1278 if not isinstance(buf, bytes):
1279 raise TypeError("buf must be a byte string")
1280
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001281 result = _lib.BIO_write(self._into_ssl, buf, len(buf))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001282 if result <= 0:
1283 self._handle_bio_errors(self._into_ssl, result)
1284 return result
1285
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001286
1287 def renegotiate(self):
1288 """
1289 Renegotiate the session
1290
1291 :return: True if the renegotiation can be started, false otherwise
1292 """
1293
1294 def do_handshake(self):
1295 """
1296 Perform an SSL handshake (usually called after renegotiate() or one of
1297 set_*_state()). This can raise the same exceptions as send and recv.
1298
1299 :return: None.
1300 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001301 result = _lib.SSL_do_handshake(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001302 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001303
1304
1305 def renegotiate_pending(self):
1306 """
1307 Check if there's a renegotiation in progress, it will return false once
1308 a renegotiation is finished.
1309
1310 :return: Whether there's a renegotiation in progress
1311 """
1312
1313 def total_renegotiations(self):
1314 """
1315 Find out the total number of renegotiations.
1316
1317 :return: The number of renegotiations.
1318 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001319 return _lib.SSL_total_renegotiations(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001320
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001321
1322 def connect(self, addr):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001323 """
1324 Connect to remote host and set up client-side SSL
1325
1326 :param addr: A remote address
1327 :return: What the socket's connect method returns
1328 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001329 _lib.SSL_set_connect_state(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001330 return self._socket.connect(addr)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001331
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001332
1333 def connect_ex(self, addr):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001334 """
1335 Connect to remote host and set up client-side SSL. Note that if the socket's
1336 connect_ex method doesn't return 0, SSL won't be initialized.
1337
1338 :param addr: A remove address
1339 :return: What the socket's connect_ex method returns
1340 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001341 connect_ex = self._socket.connect_ex
1342 self.set_connect_state()
1343 return connect_ex(addr)
1344
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001345
1346 def accept(self):
1347 """
1348 Accept incoming connection and set up SSL on it
1349
1350 :return: A (conn,addr) pair where conn is a Connection and addr is an
1351 address
1352 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001353 client, addr = self._socket.accept()
1354 conn = Connection(self._context, client)
1355 conn.set_accept_state()
1356 return (conn, addr)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001357
1358
1359 def bio_shutdown(self):
1360 """
1361 When using non-socket connections this function signals end of
1362 data on the input for this connection.
1363
1364 :return: None
1365 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001366 if self._from_ssl is None:
1367 raise TypeError("Connection sock was not None")
1368
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001369 _lib.BIO_set_mem_eof_return(self._into_ssl, 0)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001370
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001371
1372 def shutdown(self):
1373 """
1374 Send closure alert
1375
1376 :return: True if the shutdown completed successfully (i.e. both sides
1377 have sent closure alerts), false otherwise (i.e. you have to
1378 wait for a ZeroReturnError on a recv() method call
1379 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001380 result = _lib.SSL_shutdown(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001381 if result < 0:
Paul Aurichbff1d1a2015-01-08 08:36:53 -08001382 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001383 elif result > 0:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001384 return True
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001385 else:
1386 return False
1387
1388
1389 def get_cipher_list(self):
1390 """
1391 Get the session cipher list
1392
1393 :return: A list of cipher strings
1394 """
1395 ciphers = []
1396 for i in count():
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001397 result = _lib.SSL_get_cipher_list(self._ssl, i)
1398 if result == _ffi.NULL:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001399 break
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001400 ciphers.append(_native(_ffi.string(result)))
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001401 return ciphers
1402
1403
1404 def get_client_ca_list(self):
1405 """
1406 Get CAs whose certificates are suggested for client authentication.
1407
1408 :return: If this is a server connection, a list of X509Names representing
1409 the acceptable CAs as set by :py:meth:`OpenSSL.SSL.Context.set_client_ca_list` or
1410 :py:meth:`OpenSSL.SSL.Context.add_client_ca`. If this is a client connection,
1411 the list of such X509Names sent by the server, or an empty list if that
1412 has not yet happened.
1413 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001414 ca_names = _lib.SSL_get_client_CA_list(self._ssl)
1415 if ca_names == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001416 # TODO: This is untested.
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001417 return []
1418
1419 result = []
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001420 for i in range(_lib.sk_X509_NAME_num(ca_names)):
1421 name = _lib.sk_X509_NAME_value(ca_names, i)
1422 copy = _lib.X509_NAME_dup(name)
1423 if copy == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001424 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001425 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001426
1427 pyname = X509Name.__new__(X509Name)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001428 pyname._name = _ffi.gc(copy, _lib.X509_NAME_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001429 result.append(pyname)
1430 return result
1431
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001432
1433 def makefile(self):
1434 """
1435 The makefile() method is not implemented, since there is no dup semantics
1436 for SSL connections
1437
Jean-Paul Calderone6749ec22014-04-17 16:30:21 -04001438 :raise: NotImplementedError
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001439 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001440 raise NotImplementedError("Cannot make file object of OpenSSL.SSL.Connection")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001441
1442
1443 def get_app_data(self):
1444 """
1445 Get application data
1446
1447 :return: The application data
1448 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001449 return self._app_data
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001450
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001451
1452 def set_app_data(self, data):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001453 """
1454 Set application data
1455
1456 :param data - The application data
1457 :return: None
1458 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001459 self._app_data = data
1460
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001461
1462 def get_shutdown(self):
1463 """
1464 Get shutdown state
1465
1466 :return: The shutdown state, a bitvector of SENT_SHUTDOWN, RECEIVED_SHUTDOWN.
1467 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001468 return _lib.SSL_get_shutdown(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001469
1470
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001471 def set_shutdown(self, state):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001472 """
1473 Set shutdown state
1474
1475 :param state - bitvector of SENT_SHUTDOWN, RECEIVED_SHUTDOWN.
1476 :return: None
1477 """
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -05001478 if not isinstance(state, integer_types):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001479 raise TypeError("state must be an integer")
1480
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001481 _lib.SSL_set_shutdown(self._ssl, state)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001482
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001483
1484 def state_string(self):
1485 """
1486 Get a verbose state description
1487
1488 :return: A string representing the state
1489 """
1490
1491 def server_random(self):
1492 """
1493 Get a copy of the server hello nonce.
1494
1495 :return: A string representing the state
1496 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001497 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001498 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001499 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001500 self._ssl.s3.server_random,
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001501 _lib.SSL3_RANDOM_SIZE)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001502
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001503
1504 def client_random(self):
1505 """
1506 Get a copy of the client hello nonce.
1507
1508 :return: A string representing the state
1509 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001510 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001511 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001512 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001513 self._ssl.s3.client_random,
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001514 _lib.SSL3_RANDOM_SIZE)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001515
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001516
1517 def master_key(self):
1518 """
1519 Get a copy of the master key.
1520
1521 :return: A string representing the state
1522 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001523 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001524 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001525 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001526 self._ssl.session.master_key,
1527 self._ssl.session.master_key_length)[:]
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001528
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001529
1530 def sock_shutdown(self, *args, **kwargs):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001531 """
1532 See shutdown(2)
1533
1534 :return: What the socket's shutdown() method returns
1535 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001536 return self._socket.shutdown(*args, **kwargs)
1537
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001538
1539 def get_peer_certificate(self):
1540 """
1541 Retrieve the other side's certificate (if any)
1542
1543 :return: The peer's certificate
1544 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001545 cert = _lib.SSL_get_peer_certificate(self._ssl)
1546 if cert != _ffi.NULL:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001547 pycert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001548 pycert._x509 = _ffi.gc(cert, _lib.X509_free)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001549 return pycert
1550 return None
1551
1552
1553 def get_peer_cert_chain(self):
1554 """
1555 Retrieve the other side's certificate (if any)
1556
1557 :return: A list of X509 instances giving the peer's certificate chain,
1558 or None if it does not have one.
1559 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001560 cert_stack = _lib.SSL_get_peer_cert_chain(self._ssl)
1561 if cert_stack == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001562 return None
1563
1564 result = []
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001565 for i in range(_lib.sk_X509_num(cert_stack)):
Jean-Paul Calderone73b15c22013-03-05 18:30:39 -08001566 # TODO could incref instead of dup here
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001567 cert = _lib.X509_dup(_lib.sk_X509_value(cert_stack, i))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001568 pycert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001569 pycert._x509 = _ffi.gc(cert, _lib.X509_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001570 result.append(pycert)
1571 return result
1572
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001573
1574 def want_read(self):
1575 """
1576 Checks if more data has to be read from the transport layer to complete an
1577 operation.
1578
1579 :return: True iff more data has to be read
1580 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001581 return _lib.SSL_want_read(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001582
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001583
1584 def want_write(self):
1585 """
1586 Checks if there is data to write to the transport layer to complete an
1587 operation.
1588
1589 :return: True iff there is data to write
1590 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001591 return _lib.SSL_want_write(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001592
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001593
1594 def set_accept_state(self):
1595 """
1596 Set the connection to work in server mode. The handshake will be handled
1597 automatically by read/write.
1598
1599 :return: None
1600 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001601 _lib.SSL_set_accept_state(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001602
1603
1604 def set_connect_state(self):
1605 """
1606 Set the connection to work in client mode. The handshake will be handled
1607 automatically by read/write.
1608
1609 :return: None
1610 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001611 _lib.SSL_set_connect_state(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001612
1613
1614 def get_session(self):
1615 """
1616 Returns the Session currently used.
1617
1618 @return: An instance of :py:class:`OpenSSL.SSL.Session` or :py:obj:`None` if
1619 no session exists.
1620 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001621 session = _lib.SSL_get1_session(self._ssl)
1622 if session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001623 return None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001624
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001625 pysession = Session.__new__(Session)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001626 pysession._session = _ffi.gc(session, _lib.SSL_SESSION_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001627 return pysession
1628
1629
1630 def set_session(self, session):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001631 """
1632 Set the session to be used when the TLS/SSL connection is established.
1633
1634 :param session: A Session instance representing the session to use.
1635 :returns: None
1636 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001637 if not isinstance(session, Session):
1638 raise TypeError("session must be a Session instance")
1639
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001640 result = _lib.SSL_set_session(self._ssl, session._session)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001641 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001642 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001643
Jean-Paul Calderonedbd76272014-03-29 18:09:40 -04001644
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001645 def _get_finished_message(self, function):
1646 """
1647 Helper to implement :py:meth:`get_finished` and
1648 :py:meth:`get_peer_finished`.
1649
1650 :param function: Either :py:data:`SSL_get_finished`: or
1651 :py:data:`SSL_get_peer_finished`.
1652
1653 :return: :py:data:`None` if the desired message has not yet been
1654 received, otherwise the contents of the message.
1655 :rtype: :py:class:`bytes` or :py:class:`NoneType`
1656 """
Jean-Paul Calderone01af9042014-03-30 11:40:42 -04001657 # The OpenSSL documentation says nothing about what might happen if the
1658 # count argument given is zero. Specifically, it doesn't say whether
1659 # the output buffer may be NULL in that case or not. Inspection of the
1660 # implementation reveals that it calls memcpy() unconditionally.
1661 # Section 7.1.4, paragraph 1 of the C standard suggests that
1662 # memcpy(NULL, source, 0) is not guaranteed to produce defined (let
1663 # alone desirable) behavior (though it probably does on just about
1664 # every implementation...)
1665 #
1666 # Allocate a tiny buffer to pass in (instead of just passing NULL as
1667 # one might expect) for the initial call so as to be safe against this
1668 # potentially undefined behavior.
1669 empty = _ffi.new("char[]", 0)
1670 size = function(self._ssl, empty, 0)
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001671 if size == 0:
1672 # No Finished message so far.
1673 return None
1674
1675 buf = _ffi.new("char[]", size)
1676 function(self._ssl, buf, size)
1677 return _ffi.buffer(buf, size)[:]
1678
1679
Fedor Brunner5747b932014-03-05 14:22:34 +01001680 def get_finished(self):
1681 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001682 Obtain the latest `handshake finished` message sent to the peer.
Fedor Brunner5747b932014-03-05 14:22:34 +01001683
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001684 :return: The contents of the message or :py:obj:`None` if the TLS
1685 handshake has not yet completed.
1686 :rtype: :py:class:`bytes` or :py:class:`NoneType`
Fedor Brunner5747b932014-03-05 14:22:34 +01001687 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001688 return self._get_finished_message(_lib.SSL_get_finished)
1689
Fedor Brunner5747b932014-03-05 14:22:34 +01001690
1691 def get_peer_finished(self):
1692 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001693 Obtain the latest `handshake finished` message received from the peer.
Fedor Brunner5747b932014-03-05 14:22:34 +01001694
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001695 :return: The contents of the message or :py:obj:`None` if the TLS
1696 handshake has not yet completed.
1697 :rtype: :py:class:`bytes` or :py:class:`NoneType`
Fedor Brunner5747b932014-03-05 14:22:34 +01001698 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001699 return self._get_finished_message(_lib.SSL_get_peer_finished)
Fedor Brunner5747b932014-03-05 14:22:34 +01001700
Jean-Paul Calderone7c556ef2014-03-30 10:45:00 -04001701
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001702 def get_cipher_name(self):
1703 """
1704 Obtain the name of the currently used cipher.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001705
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001706 :returns: The name of the currently used cipher or :py:obj:`None`
1707 if no connection has been established.
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001708 :rtype: :py:class:`unicode` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001709 """
1710 cipher = _lib.SSL_get_current_cipher(self._ssl)
1711 if cipher == _ffi.NULL:
1712 return None
1713 else:
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001714 name = _ffi.string(_lib.SSL_CIPHER_get_name(cipher))
1715 return name.decode("utf-8")
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001716
Jean-Paul Calderonedbd76272014-03-29 18:09:40 -04001717
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001718 def get_cipher_bits(self):
1719 """
1720 Obtain the number of secret bits of the currently used cipher.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001721
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001722 :returns: The number of secret bits of the currently used cipher
1723 or :py:obj:`None` if no connection has been established.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001724 :rtype: :py:class:`int` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001725 """
1726 cipher = _lib.SSL_get_current_cipher(self._ssl)
1727 if cipher == _ffi.NULL:
1728 return None
1729 else:
1730 return _lib.SSL_CIPHER_get_bits(cipher, _ffi.NULL)
1731
Jean-Paul Calderonedbd76272014-03-29 18:09:40 -04001732
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001733 def get_cipher_version(self):
1734 """
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001735 Obtain the protocol version of the currently used cipher.
1736
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001737 :returns: The protocol name of the currently used cipher
1738 or :py:obj:`None` if no connection has been established.
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001739 :rtype: :py:class:`unicode` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001740 """
1741 cipher = _lib.SSL_get_current_cipher(self._ssl)
1742 if cipher == _ffi.NULL:
1743 return None
1744 else:
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001745 version =_ffi.string(_lib.SSL_CIPHER_get_version(cipher))
1746 return version.decode("utf-8")
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001747
Cory Benfield84a121e2014-03-31 20:30:25 +01001748 def get_next_proto_negotiated(self):
1749 """
1750 Get the protocol that was negotiated by NPN.
1751 """
1752 data = _ffi.new("unsigned char **")
1753 data_len = _ffi.new("unsigned int *")
1754
1755 _lib.SSL_get0_next_proto_negotiated(self._ssl, data, data_len)
1756
Cory Benfieldcd010f62014-05-15 19:00:27 +01001757 return _ffi.buffer(data[0], data_len[0])[:]
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001758
1759
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001760ConnectionType = Connection
Jean-Paul Calderone11ed8e82014-01-18 10:21:50 -05001761
Jean-Paul Calderonefab157b2014-01-18 11:21:38 -05001762# This is similar to the initialization calls at the end of OpenSSL/crypto.py
1763# but is exercised mostly by the Context initializer.
Jean-Paul Calderone11ed8e82014-01-18 10:21:50 -05001764_lib.SSL_library_init()