blob: 86410c0a830a8355d143986d25b0d1b294e4b99d [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
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08003from itertools import count
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
Jean-Paul Calderone63eab692014-01-18 10:19:56 -05009
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -050010from OpenSSL._util import (
11 ffi as _ffi,
12 lib as _lib,
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -050013 exception_from_error_queue as _exception_from_error_queue,
14 native as _native)
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080015
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -080016from OpenSSL.crypto import (
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -050017 FILETYPE_PEM, _PassphraseHelper, PKey, X509Name, X509, X509Store)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -080018
19_unspecified = object()
20
Jean-Paul Calderone8fb53182013-12-30 08:35:49 -050021try:
22 _memoryview = memoryview
23except NameError:
24 class _memoryview(object):
25 pass
26
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050027OPENSSL_VERSION_NUMBER = _lib.OPENSSL_VERSION_NUMBER
28SSLEAY_VERSION = _lib.SSLEAY_VERSION
29SSLEAY_CFLAGS = _lib.SSLEAY_CFLAGS
30SSLEAY_PLATFORM = _lib.SSLEAY_PLATFORM
31SSLEAY_DIR = _lib.SSLEAY_DIR
32SSLEAY_BUILT_ON = _lib.SSLEAY_BUILT_ON
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080033
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050034SENT_SHUTDOWN = _lib.SSL_SENT_SHUTDOWN
35RECEIVED_SHUTDOWN = _lib.SSL_RECEIVED_SHUTDOWN
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080036
37SSLv2_METHOD = 1
38SSLv3_METHOD = 2
39SSLv23_METHOD = 3
40TLSv1_METHOD = 4
Jean-Paul Calderone56bff942013-11-03 11:30:43 -050041TLSv1_1_METHOD = 5
42TLSv1_2_METHOD = 6
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080043
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050044OP_NO_SSLv2 = _lib.SSL_OP_NO_SSLv2
45OP_NO_SSLv3 = _lib.SSL_OP_NO_SSLv3
46OP_NO_TLSv1 = _lib.SSL_OP_NO_TLSv1
Jean-Paul Calderonebe2bb422013-12-29 07:34:08 -050047
48OP_NO_TLSv1_1 = getattr(_lib, "SSL_OP_NO_TLSv1_1", 0)
49OP_NO_TLSv1_2 = getattr(_lib, "SSL_OP_NO_TLSv1_2", 0)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -080050
Jean-Paul Calderone0d7e8a12014-01-08 16:54:13 -050051try:
52 MODE_RELEASE_BUFFERS = _lib.SSL_MODE_RELEASE_BUFFERS
53except AttributeError:
54 pass
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080055
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050056OP_SINGLE_DH_USE = _lib.SSL_OP_SINGLE_DH_USE
57OP_EPHEMERAL_RSA = _lib.SSL_OP_EPHEMERAL_RSA
58OP_MICROSOFT_SESS_ID_BUG = _lib.SSL_OP_MICROSOFT_SESS_ID_BUG
59OP_NETSCAPE_CHALLENGE_BUG = _lib.SSL_OP_NETSCAPE_CHALLENGE_BUG
60OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG = _lib.SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG
61OP_SSLREF2_REUSE_CERT_TYPE_BUG = _lib.SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG
62OP_MICROSOFT_BIG_SSLV3_BUFFER = _lib.SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER
Jean-Paul Calderone0d7e8a12014-01-08 16:54:13 -050063try:
64 OP_MSIE_SSLV2_RSA_PADDING = _lib.SSL_OP_MSIE_SSLV2_RSA_PADDING
65except AttributeError:
66 pass
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050067OP_SSLEAY_080_CLIENT_DH_BUG = _lib.SSL_OP_SSLEAY_080_CLIENT_DH_BUG
68OP_TLS_D5_BUG = _lib.SSL_OP_TLS_D5_BUG
69OP_TLS_BLOCK_PADDING_BUG = _lib.SSL_OP_TLS_BLOCK_PADDING_BUG
70OP_DONT_INSERT_EMPTY_FRAGMENTS = _lib.SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
71OP_CIPHER_SERVER_PREFERENCE = _lib.SSL_OP_CIPHER_SERVER_PREFERENCE
72OP_TLS_ROLLBACK_BUG = _lib.SSL_OP_TLS_ROLLBACK_BUG
73OP_PKCS1_CHECK_1 = _lib.SSL_OP_PKCS1_CHECK_1
74OP_PKCS1_CHECK_2 = _lib.SSL_OP_PKCS1_CHECK_2
75OP_NETSCAPE_CA_DN_BUG = _lib.SSL_OP_NETSCAPE_CA_DN_BUG
76OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG= _lib.SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG
Jean-Paul Calderonec1780342014-01-08 16:59:03 -050077try:
78 OP_NO_COMPRESSION = _lib.SSL_OP_NO_COMPRESSION
79except AttributeError:
80 pass
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -080081
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050082OP_NO_QUERY_MTU = _lib.SSL_OP_NO_QUERY_MTU
83OP_COOKIE_EXCHANGE = _lib.SSL_OP_COOKIE_EXCHANGE
Arturo Filastò5f8c7a82014-03-09 20:01:25 +010084try:
85 OP_NO_TICKET = _lib.SSL_OP_NO_TICKET
86except AttributeError:
87 pass
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -080088
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050089OP_ALL = _lib.SSL_OP_ALL
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080090
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050091VERIFY_PEER = _lib.SSL_VERIFY_PEER
92VERIFY_FAIL_IF_NO_PEER_CERT = _lib.SSL_VERIFY_FAIL_IF_NO_PEER_CERT
93VERIFY_CLIENT_ONCE = _lib.SSL_VERIFY_CLIENT_ONCE
94VERIFY_NONE = _lib.SSL_VERIFY_NONE
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080095
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050096SESS_CACHE_OFF = _lib.SSL_SESS_CACHE_OFF
97SESS_CACHE_CLIENT = _lib.SSL_SESS_CACHE_CLIENT
98SESS_CACHE_SERVER = _lib.SSL_SESS_CACHE_SERVER
99SESS_CACHE_BOTH = _lib.SSL_SESS_CACHE_BOTH
100SESS_CACHE_NO_AUTO_CLEAR = _lib.SSL_SESS_CACHE_NO_AUTO_CLEAR
101SESS_CACHE_NO_INTERNAL_LOOKUP = _lib.SSL_SESS_CACHE_NO_INTERNAL_LOOKUP
102SESS_CACHE_NO_INTERNAL_STORE = _lib.SSL_SESS_CACHE_NO_INTERNAL_STORE
103SESS_CACHE_NO_INTERNAL = _lib.SSL_SESS_CACHE_NO_INTERNAL
Jean-Paul Calderoned39a3f62013-03-04 12:23:51 -0800104
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500105SSL_ST_CONNECT = _lib.SSL_ST_CONNECT
106SSL_ST_ACCEPT = _lib.SSL_ST_ACCEPT
107SSL_ST_MASK = _lib.SSL_ST_MASK
108SSL_ST_INIT = _lib.SSL_ST_INIT
109SSL_ST_BEFORE = _lib.SSL_ST_BEFORE
110SSL_ST_OK = _lib.SSL_ST_OK
111SSL_ST_RENEGOTIATE = _lib.SSL_ST_RENEGOTIATE
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800112
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500113SSL_CB_LOOP = _lib.SSL_CB_LOOP
114SSL_CB_EXIT = _lib.SSL_CB_EXIT
115SSL_CB_READ = _lib.SSL_CB_READ
116SSL_CB_WRITE = _lib.SSL_CB_WRITE
117SSL_CB_ALERT = _lib.SSL_CB_ALERT
118SSL_CB_READ_ALERT = _lib.SSL_CB_READ_ALERT
119SSL_CB_WRITE_ALERT = _lib.SSL_CB_WRITE_ALERT
120SSL_CB_ACCEPT_LOOP = _lib.SSL_CB_ACCEPT_LOOP
121SSL_CB_ACCEPT_EXIT = _lib.SSL_CB_ACCEPT_EXIT
122SSL_CB_CONNECT_LOOP = _lib.SSL_CB_CONNECT_LOOP
123SSL_CB_CONNECT_EXIT = _lib.SSL_CB_CONNECT_EXIT
124SSL_CB_HANDSHAKE_START = _lib.SSL_CB_HANDSHAKE_START
125SSL_CB_HANDSHAKE_DONE = _lib.SSL_CB_HANDSHAKE_DONE
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800126
Alex Gaynor807853c2014-01-17 13:03:27 -0600127_Cryptography_HAS_EC = _lib.Cryptography_HAS_EC
Andy Lutomirski9bca0ed2014-03-05 14:41:41 -0800128ELLIPTIC_CURVE_DESCRIPTIONS = {} # In case there's no EC support
129if _Cryptography_HAS_EC:
130 _num_curves = _lib.EC_get_builtin_curves(_ffi.NULL, 0)
131 _curves = _ffi.new('EC_builtin_curve[]', _num_curves)
132 if _lib.EC_get_builtin_curves(_curves, _num_curves) == _num_curves:
Andy Lutomirski5fb416a2014-04-04 12:19:52 -0700133 ELLIPTIC_CURVE_DESCRIPTIONS = dict(
134 (_ffi.string(_lib.OBJ_nid2sn(c.nid)).decode('ascii'),
135 _ffi.string(c.comment).decode('utf-8'))
136 for c in _curves)
Andy Lutomirski9bca0ed2014-03-05 14:41:41 -0800137 del _num_curves
138 del _curves
Alex Gaynor12dc0842014-01-17 12:51:31 -0600139
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800140
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500141class Error(Exception):
Jean-Paul Calderone511cde02013-12-29 10:31:13 -0500142 """
143 An error occurred in an `OpenSSL.SSL` API.
144 """
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500145
146
147
148_raise_current_error = partial(_exception_from_error_queue, Error)
149
150
151class WantReadError(Error):
152 pass
153
154
155
156class WantWriteError(Error):
157 pass
158
159
160
161class WantX509LookupError(Error):
162 pass
163
164
165
166class ZeroReturnError(Error):
167 pass
168
169
170
171class SysCallError(Error):
172 pass
173
174
175
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800176class _VerifyHelper(object):
177 def __init__(self, connection, callback):
178 self._problems = []
179
180 @wraps(callback)
181 def wrapper(ok, store_ctx):
182 cert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500183 cert._x509 = _lib.X509_STORE_CTX_get_current_cert(store_ctx)
184 error_number = _lib.X509_STORE_CTX_get_error(store_ctx)
185 error_depth = _lib.X509_STORE_CTX_get_error_depth(store_ctx)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800186
187 try:
188 result = callback(connection, cert, error_number, error_depth, ok)
189 except Exception as e:
190 self._problems.append(e)
191 return 0
192 else:
193 if result:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500194 _lib.X509_STORE_CTX_set_error(store_ctx, _lib.X509_V_OK)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800195 return 1
196 else:
197 return 0
198
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500199 self.callback = _ffi.callback(
200 "int (*)(int, X509_STORE_CTX *)", wrapper)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800201
202
203 def raise_if_problem(self):
204 if self._problems:
205 try:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500206 _raise_current_error()
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800207 except Error:
208 pass
209 raise self._problems.pop(0)
210
211
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800212
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800213def _asFileDescriptor(obj):
214 fd = None
Konstantinos Koukopoulosc8b13ea2014-01-28 00:21:50 -0800215 if not isinstance(obj, integer_types):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800216 meth = getattr(obj, "fileno", None)
217 if meth is not None:
218 obj = meth()
219
Konstantinos Koukopoulosc8b13ea2014-01-28 00:21:50 -0800220 if isinstance(obj, integer_types):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800221 fd = obj
222
Konstantinos Koukopoulosc8b13ea2014-01-28 00:21:50 -0800223 if not isinstance(fd, integer_types):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800224 raise TypeError("argument must be an int, or have a fileno() method.")
225 elif fd < 0:
226 raise ValueError(
227 "file descriptor cannot be a negative integer (%i)" % (fd,))
228
229 return fd
230
231
232
Andy Lutomirski61d7d392014-04-04 12:16:56 -0700233class ECNotAvailable(ValueError):
234 """
235 Raised if a request for an elliptic curve fails because OpenSSL
236 is compiled without elliptic curve support.
237 """
238 def __init__(self):
239 ValueError.__init__(self, "OpenSSL is compiled without EC support")
240
241
242
243class UnknownObject(ValueError):
244 """
245 Raised if OpenSSL does not recognize the requested object.
246 """
247 def __init__(self, sn):
248 ValueError.__init__(self, "OpenSSL does not recognize %r" % sn)
249 self.sn = sn
250
251
252
253class UnsupportedEllipticCurve(ValueError):
254 """
255 Raised if OpenSSL does not support the requested elliptic curve.
256 """
257 def __init__(self, sn):
258 ValueError.__init__(
259 self, "OpenSSL does not support the elliptic curve %r" % sn)
260 self.sn = sn
261
262
263
Jean-Paul Calderoned39a3f62013-03-04 12:23:51 -0800264def SSLeay_version(type):
265 """
266 Return a string describing the version of OpenSSL in use.
267
268 :param type: One of the SSLEAY_ constants defined in this module.
269 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500270 return _ffi.string(_lib.SSLeay_version(type))
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800271
272
273
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800274class Session(object):
275 pass
276
277
278
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800279class Context(object):
280 """
281 :py:obj:`OpenSSL.SSL.Context` instances define the parameters for setting up
282 new SSL connections.
283 """
284 _methods = {
Andrew Dunhamec84a0a2014-02-24 12:41:37 -0800285 SSLv2_METHOD: "SSLv2_method",
Jean-Paul Calderonebe2bb422013-12-29 07:34:08 -0500286 SSLv3_METHOD: "SSLv3_method",
287 SSLv23_METHOD: "SSLv23_method",
288 TLSv1_METHOD: "TLSv1_method",
289 TLSv1_1_METHOD: "TLSv1_1_method",
290 TLSv1_2_METHOD: "TLSv1_2_method",
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800291 }
Jean-Paul Calderonebe2bb422013-12-29 07:34:08 -0500292 _methods = dict(
293 (identifier, getattr(_lib, name))
294 for (identifier, name) in _methods.items()
295 if getattr(_lib, name, None) is not None)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800296
Jean-Paul Calderone63157872013-03-20 16:43:38 -0700297
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800298 def __init__(self, method):
299 """
300 :param method: One of SSLv2_METHOD, SSLv3_METHOD, SSLv23_METHOD, or
301 TLSv1_METHOD.
302 """
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -0500303 if not isinstance(method, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800304 raise TypeError("method must be an integer")
305
306 try:
307 method_func = self._methods[method]
308 except KeyError:
309 raise ValueError("No such protocol")
310
311 method_obj = method_func()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500312 if method_obj == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500313 # TODO: This is untested.
314 _raise_current_error()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800315
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500316 context = _lib.SSL_CTX_new(method_obj)
317 if context == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500318 # TODO: This is untested.
319 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500320 context = _ffi.gc(context, _lib.SSL_CTX_free)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800321
322 self._context = context
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800323 self._passphrase_helper = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800324 self._passphrase_callback = None
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800325 self._passphrase_userdata = None
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800326 self._verify_helper = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800327 self._verify_callback = None
328 self._info_callback = None
329 self._tlsext_servername_callback = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800330 self._app_data = None
331
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -0800332 # SSL_CTX_set_app_data(self->ctx, self);
333 # SSL_CTX_set_mode(self->ctx, SSL_MODE_ENABLE_PARTIAL_WRITE |
334 # SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
335 # SSL_MODE_AUTO_RETRY);
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500336 self.set_mode(_lib.SSL_MODE_ENABLE_PARTIAL_WRITE)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800337
338
339 def load_verify_locations(self, cafile, capath=None):
340 """
341 Let SSL know where we can find trusted certificates for the certificate
342 chain
343
344 :param cafile: In which file we can find the certificates
345 :param capath: In which directory we can find the certificates
346 :return: None
347 """
348 if cafile is None:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500349 cafile = _ffi.NULL
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800350 elif not isinstance(cafile, bytes):
351 raise TypeError("cafile must be None or a byte string")
352
353 if capath is None:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500354 capath = _ffi.NULL
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800355 elif not isinstance(capath, bytes):
356 raise TypeError("capath must be None or a byte string")
357
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500358 load_result = _lib.SSL_CTX_load_verify_locations(self._context, cafile, capath)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800359 if not load_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500360 _raise_current_error()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800361
362
363 def _wrap_callback(self, callback):
364 @wraps(callback)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800365 def wrapper(size, verify, userdata):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800366 return callback(size, verify, self._passphrase_userdata)
367 return _PassphraseHelper(
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800368 FILETYPE_PEM, wrapper, more_args=True, truncate=True)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800369
370
371 def set_passwd_cb(self, callback, userdata=None):
372 """
373 Set the passphrase callback
374
375 :param callback: The Python callback to use
376 :param userdata: (optional) A Python object which will be given as
377 argument to the callback
378 :return: None
379 """
380 if not callable(callback):
381 raise TypeError("callback must be callable")
382
383 self._passphrase_helper = self._wrap_callback(callback)
384 self._passphrase_callback = self._passphrase_helper.callback
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500385 _lib.SSL_CTX_set_default_passwd_cb(
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800386 self._context, self._passphrase_callback)
387 self._passphrase_userdata = userdata
388
389
390 def set_default_verify_paths(self):
391 """
392 Use the platform-specific CA certificate locations
393
394 :return: None
395 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500396 set_result = _lib.SSL_CTX_set_default_verify_paths(self._context)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800397 if not set_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500398 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500399 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800400
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800401
402 def use_certificate_chain_file(self, certfile):
403 """
404 Load a certificate chain from a file
405
406 :param certfile: The name of the certificate chain file
407 :return: None
408 """
Jean-Paul Calderoned8607982014-01-18 10:30:55 -0500409 if isinstance(certfile, _text_type):
410 # Perhaps sys.getfilesystemencoding() could be better?
411 certfile = certfile.encode("utf-8")
412
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800413 if not isinstance(certfile, bytes):
Jean-Paul Calderoned8607982014-01-18 10:30:55 -0500414 raise TypeError("certfile must be bytes or unicode")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800415
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500416 result = _lib.SSL_CTX_use_certificate_chain_file(self._context, certfile)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800417 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500418 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800419
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800420
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800421 def use_certificate_file(self, certfile, filetype=FILETYPE_PEM):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800422 """
423 Load a certificate from a file
424
425 :param certfile: The name of the certificate file
426 :param filetype: (optional) The encoding of the file, default is PEM
427 :return: None
428 """
Jean-Paul Calderone684baf52014-01-18 10:31:19 -0500429 if isinstance(certfile, _text_type):
430 # Perhaps sys.getfilesystemencoding() could be better?
431 certfile = certfile.encode("utf-8")
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800432 if not isinstance(certfile, bytes):
Jean-Paul Calderone684baf52014-01-18 10:31:19 -0500433 raise TypeError("certfile must be bytes or unicode")
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -0500434 if not isinstance(filetype, integer_types):
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800435 raise TypeError("filetype must be an integer")
436
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500437 use_result = _lib.SSL_CTX_use_certificate_file(self._context, certfile, filetype)
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800438 if not use_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500439 _raise_current_error()
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800440
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800441
442 def use_certificate(self, cert):
443 """
444 Load a certificate from a X509 object
445
446 :param cert: The X509 object
447 :return: None
448 """
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800449 if not isinstance(cert, X509):
450 raise TypeError("cert must be an X509 instance")
451
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500452 use_result = _lib.SSL_CTX_use_certificate(self._context, cert._x509)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800453 if not use_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500454 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800455
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800456
457 def add_extra_chain_cert(self, certobj):
458 """
459 Add certificate to chain
460
461 :param certobj: The X509 certificate object to add to the chain
462 :return: None
463 """
464 if not isinstance(certobj, X509):
465 raise TypeError("certobj must be an X509 instance")
466
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500467 copy = _lib.X509_dup(certobj._x509)
468 add_result = _lib.SSL_CTX_add_extra_chain_cert(self._context, copy)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800469 if not add_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500470 # TODO: This is untested.
471 _lib.X509_free(copy)
472 _raise_current_error()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800473
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800474
475 def _raise_passphrase_exception(self):
476 if self._passphrase_helper is None:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500477 _raise_current_error()
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800478 exception = self._passphrase_helper.raise_if_problem(Error)
479 if exception is not None:
480 raise exception
481
482
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800483 def use_privatekey_file(self, keyfile, filetype=_unspecified):
484 """
485 Load a private key from a file
486
487 :param keyfile: The name of the key file
488 :param filetype: (optional) The encoding of the file, default is PEM
489 :return: None
490 """
Jean-Paul Calderone87e525a2014-01-18 10:31:51 -0500491 if isinstance(keyfile, _text_type):
492 # Perhaps sys.getfilesystemencoding() could be better?
493 keyfile = keyfile.encode("utf-8")
494
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800495 if not isinstance(keyfile, bytes):
496 raise TypeError("keyfile must be a byte string")
497
498 if filetype is _unspecified:
499 filetype = FILETYPE_PEM
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -0500500 elif not isinstance(filetype, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800501 raise TypeError("filetype must be an integer")
502
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500503 use_result = _lib.SSL_CTX_use_PrivateKey_file(
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800504 self._context, keyfile, filetype)
505 if not use_result:
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800506 self._raise_passphrase_exception()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800507
508
509 def use_privatekey(self, pkey):
510 """
511 Load a private key from a PKey object
512
513 :param pkey: The PKey object
514 :return: None
515 """
516 if not isinstance(pkey, PKey):
517 raise TypeError("pkey must be a PKey instance")
518
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500519 use_result = _lib.SSL_CTX_use_PrivateKey(self._context, pkey._pkey)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800520 if not use_result:
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800521 self._raise_passphrase_exception()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800522
523
524 def check_privatekey(self):
525 """
526 Check that the private key and certificate match up
527
528 :return: None (raises an exception if something's wrong)
529 """
530
531 def load_client_ca(self, cafile):
532 """
533 Load the trusted certificates that will be sent to the client (basically
534 telling the client "These are the guys I trust"). Does not actually
535 imply any of the certificates are trusted; that must be configured
536 separately.
537
538 :param cafile: The name of the certificates file
539 :return: None
540 """
541
542 def set_session_id(self, buf):
543 """
544 Set the session identifier. This is needed if you want to do session
545 resumption.
546
547 :param buf: A Python object that can be safely converted to a string
548 :returns: None
549 """
550
551 def set_session_cache_mode(self, mode):
552 """
553 Enable/disable session caching and specify the mode used.
554
555 :param mode: One or more of the SESS_CACHE_* flags (combine using
556 bitwise or)
557 :returns: The previously set caching mode.
558 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500559 if not isinstance(mode, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800560 raise TypeError("mode must be an integer")
561
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500562 return _lib.SSL_CTX_set_session_cache_mode(self._context, mode)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800563
564
565 def get_session_cache_mode(self):
566 """
567 :returns: The currently used cache mode.
568 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500569 return _lib.SSL_CTX_get_session_cache_mode(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800570
571
572 def set_verify(self, mode, callback):
573 """
574 Set the verify mode and verify callback
575
576 :param mode: The verify mode, this is either VERIFY_NONE or
577 VERIFY_PEER combined with possible other flags
578 :param callback: The Python callback to use
579 :return: None
580
581 See SSL_CTX_set_verify(3SSL) for further details.
582 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500583 if not isinstance(mode, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800584 raise TypeError("mode must be an integer")
585
586 if not callable(callback):
587 raise TypeError("callback must be callable")
588
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800589 self._verify_helper = _VerifyHelper(self, callback)
590 self._verify_callback = self._verify_helper.callback
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500591 _lib.SSL_CTX_set_verify(self._context, mode, self._verify_callback)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800592
593
594 def set_verify_depth(self, depth):
595 """
596 Set the verify depth
597
598 :param depth: An integer specifying the verify depth
599 :return: None
600 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500601 if not isinstance(depth, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800602 raise TypeError("depth must be an integer")
603
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500604 _lib.SSL_CTX_set_verify_depth(self._context, depth)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800605
606
607 def get_verify_mode(self):
608 """
609 Get the verify mode
610
611 :return: The verify mode
612 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500613 return _lib.SSL_CTX_get_verify_mode(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800614
615
616 def get_verify_depth(self):
617 """
618 Get the verify depth
619
620 :return: The verify depth
621 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500622 return _lib.SSL_CTX_get_verify_depth(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800623
624
625 def load_tmp_dh(self, dhfile):
626 """
627 Load parameters for Ephemeral Diffie-Hellman
628
629 :param dhfile: The file to load EDH parameters from
630 :return: None
631 """
632 if not isinstance(dhfile, bytes):
633 raise TypeError("dhfile must be a byte string")
634
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -0500635 bio = _lib.BIO_new_file(dhfile, b"r")
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500636 if bio == _ffi.NULL:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500637 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500638 bio = _ffi.gc(bio, _lib.BIO_free)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800639
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500640 dh = _lib.PEM_read_bio_DHparams(bio, _ffi.NULL, _ffi.NULL, _ffi.NULL)
641 dh = _ffi.gc(dh, _lib.DH_free)
642 _lib.SSL_CTX_set_tmp_dh(self._context, dh)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800643
644
Jean-Paul Calderonec48cd812014-04-17 17:00:58 -0400645 def _set_tmp_ecdh_curve_by_nid(self, name, nid):
Jean-Paul Calderonef11e3392014-04-17 16:30:12 -0400646 """
647 Select a curve to use by the OpenSSL NID associated with that curve.
648
Jean-Paul Calderonec48cd812014-04-17 17:00:58 -0400649 :param name: The name of the curve identified by the NID.
650 :type name: str
651
Jean-Paul Calderonef11e3392014-04-17 16:30:12 -0400652 :param nid: The OpenSSL NID to use.
653 :type nid: int
654
655 :raise UnsupportedEllipticCurve: If the given NID does not identify a
656 supported curve.
657 """
658 ecdh = _lib.EC_KEY_new_by_curve_name(nid)
659 if ecdh == _ffi.NULL:
Jean-Paul Calderonec48cd812014-04-17 17:00:58 -0400660 raise UnsupportedEllipticCurve(name)
Jean-Paul Calderonef11e3392014-04-17 16:30:12 -0400661 _lib.SSL_CTX_set_tmp_ecdh(self._context, ecdh)
662 _lib.EC_KEY_free(ecdh)
663
664
Andy Lutomirskif05a2732014-03-13 17:22:25 -0700665 def set_tmp_ecdh_curve(self, curve_name):
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600666 """
Andy Lutomirski76a61332014-03-12 15:02:56 -0700667 Select a curve to use for ECDHE key exchange.
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600668
Andy Lutomirskif05a2732014-03-13 17:22:25 -0700669 The valid values of *curve_name* are the keys in
670 :py:data:OpenSSL.SSL.ELLIPTIC_CURVE_DESCRIPTIONS.
671
Andy Lutomirski61d7d392014-04-04 12:16:56 -0700672 Raises a subclass of ``ValueError`` if the linked OpenSSL was
673 not compiled with elliptical curve support or the specified
674 curve is not available. You can check the specific subclass,
675 but, in general, you should just handle ``ValueError``.
Andy Lutomirskif05a2732014-03-13 17:22:25 -0700676
677 :param curve_name: The 'short name' of a curve, e.g. 'prime256v1'
678 :type curve_name: str
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600679 :return: None
680 """
681 if _lib.Cryptography_HAS_EC:
Andy Lutomirski5fb416a2014-04-04 12:19:52 -0700682 nid = _lib.OBJ_sn2nid(curve_name.encode('ascii'))
Andy Lutomirskif05a2732014-03-13 17:22:25 -0700683 if nid == _lib.NID_undef:
Andy Lutomirski61d7d392014-04-04 12:16:56 -0700684 raise UnknownObject(curve_name)
Jean-Paul Calderonec48cd812014-04-17 17:00:58 -0400685 return self._set_tmp_ecdh_curve_by_nid(curve_name, nid)
Jean-Paul Calderonef11e3392014-04-17 16:30:12 -0400686 raise ECNotAvailable()
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600687
688
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800689 def set_cipher_list(self, cipher_list):
690 """
691 Change the cipher list
692
693 :param cipher_list: A cipher list, see ciphers(1)
694 :return: None
695 """
Jean-Paul Calderone63eab692014-01-18 10:19:56 -0500696 if isinstance(cipher_list, _text_type):
697 cipher_list = cipher_list.encode("ascii")
698
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800699 if not isinstance(cipher_list, bytes):
Jean-Paul Calderone63eab692014-01-18 10:19:56 -0500700 raise TypeError("cipher_list must be bytes or unicode")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800701
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500702 result = _lib.SSL_CTX_set_cipher_list(self._context, cipher_list)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800703 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500704 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800705
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800706
707 def set_client_ca_list(self, certificate_authorities):
708 """
709 Set the list of preferred client certificate signers for this server context.
710
711 This list of certificate authorities will be sent to the client when the
712 server requests a client certificate.
713
714 :param certificate_authorities: a sequence of X509Names.
715 :return: None
716 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500717 name_stack = _lib.sk_X509_NAME_new_null()
718 if name_stack == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500719 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500720 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800721
722 try:
723 for ca_name in certificate_authorities:
724 if not isinstance(ca_name, X509Name):
725 raise TypeError(
726 "client CAs must be X509Name objects, not %s objects" % (
727 type(ca_name).__name__,))
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500728 copy = _lib.X509_NAME_dup(ca_name._name)
729 if copy == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500730 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500731 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500732 push_result = _lib.sk_X509_NAME_push(name_stack, copy)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800733 if not push_result:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500734 _lib.X509_NAME_free(copy)
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500735 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800736 except:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500737 _lib.sk_X509_NAME_free(name_stack)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800738 raise
739
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500740 _lib.SSL_CTX_set_client_CA_list(self._context, name_stack)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800741
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800742
743 def add_client_ca(self, certificate_authority):
744 """
745 Add the CA certificate to the list of preferred signers for this context.
746
747 The list of certificate authorities will be sent to the client when the
748 server requests a client certificate.
749
750 :param certificate_authority: certificate authority's X509 certificate.
751 :return: None
752 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800753 if not isinstance(certificate_authority, X509):
754 raise TypeError("certificate_authority must be an X509 instance")
755
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500756 add_result = _lib.SSL_CTX_add_client_CA(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800757 self._context, certificate_authority._x509)
758 if not add_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500759 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500760 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800761
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800762
763 def set_timeout(self, timeout):
764 """
765 Set session timeout
766
767 :param timeout: The timeout in seconds
768 :return: The previous session timeout
769 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500770 if not isinstance(timeout, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800771 raise TypeError("timeout must be an integer")
772
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500773 return _lib.SSL_CTX_set_timeout(self._context, timeout)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800774
775
776 def get_timeout(self):
777 """
778 Get the session timeout
779
780 :return: The session timeout
781 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500782 return _lib.SSL_CTX_get_timeout(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800783
784
785 def set_info_callback(self, callback):
786 """
787 Set the info callback
788
789 :param callback: The Python callback to use
790 :return: None
791 """
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800792 @wraps(callback)
793 def wrapper(ssl, where, return_code):
Jean-Paul Calderonef2bbc9c2014-02-02 10:59:14 -0500794 callback(Connection._reverse_mapping[ssl], where, return_code)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500795 self._info_callback = _ffi.callback(
796 "void (*)(const SSL *, int, int)", wrapper)
797 _lib.SSL_CTX_set_info_callback(self._context, self._info_callback)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800798
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800799
800 def get_app_data(self):
801 """
802 Get the application data (supplied via set_app_data())
803
804 :return: The application data
805 """
806 return self._app_data
807
808
809 def set_app_data(self, data):
810 """
811 Set the application data (will be returned from get_app_data())
812
813 :param data: Any Python object
814 :return: None
815 """
816 self._app_data = data
817
818
819 def get_cert_store(self):
820 """
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500821 Get the certificate store for the context.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800822
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500823 :return: A X509Store object or None if it does not have one.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800824 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500825 store = _lib.SSL_CTX_get_cert_store(self._context)
826 if store == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500827 # TODO: This is untested.
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800828 return None
829
830 pystore = X509Store.__new__(X509Store)
831 pystore._store = store
832 return pystore
833
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800834
835 def set_options(self, options):
836 """
837 Add options. Options set before are not cleared!
838
839 :param options: The options to add.
840 :return: The new option bitmask.
841 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500842 if not isinstance(options, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800843 raise TypeError("options must be an integer")
844
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500845 return _lib.SSL_CTX_set_options(self._context, options)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800846
847
848 def set_mode(self, mode):
849 """
850 Add modes via bitmask. Modes set before are not cleared!
851
852 :param mode: The mode to add.
853 :return: The new mode bitmask.
854 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500855 if not isinstance(mode, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800856 raise TypeError("mode must be an integer")
857
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500858 return _lib.SSL_CTX_set_mode(self._context, mode)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800859
860
861 def set_tlsext_servername_callback(self, callback):
862 """
863 Specify a callback function to be called when clients specify a server name.
864
865 :param callback: The callback function. It will be invoked with one
866 argument, the Connection instance.
867 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800868 @wraps(callback)
869 def wrapper(ssl, alert, arg):
870 callback(Connection._reverse_mapping[ssl])
871 return 0
872
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500873 self._tlsext_servername_callback = _ffi.callback(
874 "int (*)(const SSL *, int *, void *)", wrapper)
875 _lib.SSL_CTX_set_tlsext_servername_callback(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800876 self._context, self._tlsext_servername_callback)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800877
878ContextType = Context
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800879
880
881
882class Connection(object):
883 """
884 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800885 _reverse_mapping = WeakValueDictionary()
886
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800887 def __init__(self, context, socket=None):
888 """
889 Create a new Connection object, using the given OpenSSL.SSL.Context
890 instance and socket.
891
892 :param context: An SSL Context to use for this connection
893 :param socket: The socket to use for transport layer
894 """
895 if not isinstance(context, Context):
896 raise TypeError("context must be a Context instance")
897
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500898 ssl = _lib.SSL_new(context._context)
899 self._ssl = _ffi.gc(ssl, _lib.SSL_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800900 self._context = context
901
902 self._reverse_mapping[self._ssl] = self
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800903
904 if socket is None:
905 self._socket = None
Jean-Paul Calderone73b15c22013-03-05 18:30:39 -0800906 # Don't set up any gc for these, SSL_free will take care of them.
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500907 self._into_ssl = _lib.BIO_new(_lib.BIO_s_mem())
908 self._from_ssl = _lib.BIO_new(_lib.BIO_s_mem())
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800909
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500910 if self._into_ssl == _ffi.NULL or self._from_ssl == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500911 # TODO: This is untested.
912 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800913
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500914 _lib.SSL_set_bio(self._ssl, self._into_ssl, self._from_ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800915 else:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800916 self._into_ssl = None
917 self._from_ssl = None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800918 self._socket = socket
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500919 set_result = _lib.SSL_set_fd(self._ssl, _asFileDescriptor(self._socket))
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800920 if not set_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500921 # TODO: This is untested.
922 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800923
924
925 def __getattr__(self, name):
926 """
927 Look up attributes on the wrapped socket object if they are not found on
928 the Connection object.
929 """
930 return getattr(self._socket, name)
931
932
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800933 def _raise_ssl_error(self, ssl, result):
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800934 if self._context._verify_helper is not None:
935 self._context._verify_helper.raise_if_problem()
936
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500937 error = _lib.SSL_get_error(ssl, result)
938 if error == _lib.SSL_ERROR_WANT_READ:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800939 raise WantReadError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500940 elif error == _lib.SSL_ERROR_WANT_WRITE:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -0700941 raise WantWriteError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500942 elif error == _lib.SSL_ERROR_ZERO_RETURN:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800943 raise ZeroReturnError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500944 elif error == _lib.SSL_ERROR_WANT_X509_LOOKUP:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500945 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -0700946 raise WantX509LookupError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500947 elif error == _lib.SSL_ERROR_SYSCALL:
948 if _lib.ERR_peek_error() == 0:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800949 if result < 0:
Konstantinos Koukopoulos541150d2014-01-31 01:00:19 +0200950 if platform == "win32":
951 errno = _ffi.getwinerror()[0]
952 else:
953 errno = _ffi.errno
954 raise SysCallError(errno, errorcode[errno])
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800955 else:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -0700956 raise SysCallError(-1, "Unexpected EOF")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800957 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500958 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500959 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500960 elif error == _lib.SSL_ERROR_NONE:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -0700961 pass
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800962 else:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500963 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800964
965
966 def get_context(self):
967 """
968 Get session context
969 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800970 return self._context
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800971
972
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800973 def set_context(self, context):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800974 """
975 Switch this connection to a new session context
976
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800977 :param context: A :py:class:`Context` instance giving the new session
978 context to use.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800979 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800980 if not isinstance(context, Context):
981 raise TypeError("context must be a Context instance")
982
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500983 _lib.SSL_set_SSL_CTX(self._ssl, context._context)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800984 self._context = context
985
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800986
987 def get_servername(self):
988 """
989 Retrieve the servername extension value if provided in the client hello
990 message, or None if there wasn't one.
991
992 :return: A byte string giving the server name or :py:data:`None`.
993 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500994 name = _lib.SSL_get_servername(self._ssl, _lib.TLSEXT_NAMETYPE_host_name)
995 if name == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800996 return None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800997
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500998 return _ffi.string(name)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800999
1000
1001 def set_tlsext_host_name(self, name):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001002 """
1003 Set the value of the servername extension to send in the client hello.
1004
1005 :param name: A byte string giving the name.
1006 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001007 if not isinstance(name, bytes):
1008 raise TypeError("name must be a byte string")
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001009 elif b"\0" in name:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001010 raise TypeError("name must not contain NUL byte")
1011
1012 # XXX I guess this can fail sometimes?
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001013 _lib.SSL_set_tlsext_host_name(self._ssl, name)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001014
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001015
1016 def pending(self):
1017 """
1018 Get the number of bytes that can be safely read from the connection
1019
1020 :return: The number of bytes available in the receive buffer.
1021 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001022 return _lib.SSL_pending(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001023
1024
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001025 def send(self, buf, flags=0):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001026 """
1027 Send data on the connection. NOTE: If you get one of the WantRead,
1028 WantWrite or WantX509Lookup exceptions on this, you have to call the
1029 method again with the SAME buffer.
1030
1031 :param buf: The string to send
1032 :param flags: (optional) Included for compatibility with the socket
1033 API, the value is ignored
1034 :return: The number of bytes written
1035 """
Jean-Paul Calderone8fb53182013-12-30 08:35:49 -05001036 if isinstance(buf, _memoryview):
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -08001037 buf = buf.tobytes()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001038 if not isinstance(buf, bytes):
1039 raise TypeError("data must be a byte string")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001040
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001041 result = _lib.SSL_write(self._ssl, buf, len(buf))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001042 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001043 return result
1044 write = send
1045
1046
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001047 def sendall(self, buf, flags=0):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001048 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001049 Send "all" data on the connection. This calls send() repeatedly until
1050 all data is sent. If an error occurs, it's impossible to tell how much
1051 data has been sent.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001052
1053 :param buf: The string to send
1054 :param flags: (optional) Included for compatibility with the socket
1055 API, the value is ignored
1056 :return: The number of bytes written
1057 """
Jean-Paul Calderone8fb53182013-12-30 08:35:49 -05001058 if isinstance(buf, _memoryview):
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -08001059 buf = buf.tobytes()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001060 if not isinstance(buf, bytes):
1061 raise TypeError("buf must be a byte string")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001062
1063 left_to_send = len(buf)
1064 total_sent = 0
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001065 data = _ffi.new("char[]", buf)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001066
1067 while left_to_send:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001068 result = _lib.SSL_write(self._ssl, data + total_sent, left_to_send)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001069 self._raise_ssl_error(self._ssl, result)
1070 total_sent += result
1071 left_to_send -= result
1072
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001073
1074 def recv(self, bufsiz, flags=None):
1075 """
1076 Receive data on the connection. NOTE: If you get one of the WantRead,
1077 WantWrite or WantX509Lookup exceptions on this, you have to call the
1078 method again with the SAME buffer.
1079
1080 :param bufsiz: The maximum number of bytes to read
1081 :param flags: (optional) Included for compatibility with the socket
1082 API, the value is ignored
1083 :return: The string read from the Connection
1084 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001085 buf = _ffi.new("char[]", bufsiz)
1086 result = _lib.SSL_read(self._ssl, buf, bufsiz)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001087 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001088 return _ffi.buffer(buf, result)[:]
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001089 read = recv
1090
1091
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001092 def _handle_bio_errors(self, bio, result):
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001093 if _lib.BIO_should_retry(bio):
1094 if _lib.BIO_should_read(bio):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001095 raise WantReadError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001096 elif _lib.BIO_should_write(bio):
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001097 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001098 raise WantWriteError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001099 elif _lib.BIO_should_io_special(bio):
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001100 # TODO: This is untested. I think io_special means the socket
1101 # BIO has a not-yet connected socket.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001102 raise ValueError("BIO_should_io_special")
1103 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001104 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001105 raise ValueError("unknown bio failure")
1106 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001107 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001108 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001109
1110
1111 def bio_read(self, bufsiz):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001112 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001113 When using non-socket connections this function reads the "dirty" data
1114 that would have traveled away on the network.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001115
1116 :param bufsiz: The maximum number of bytes to read
1117 :return: The string read.
1118 """
Jean-Paul Calderone97e041d2013-03-05 21:03:12 -08001119 if self._from_ssl is None:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001120 raise TypeError("Connection sock was not None")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001121
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -05001122 if not isinstance(bufsiz, integer_types):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001123 raise TypeError("bufsiz must be an integer")
1124
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001125 buf = _ffi.new("char[]", bufsiz)
1126 result = _lib.BIO_read(self._from_ssl, buf, bufsiz)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001127 if result <= 0:
1128 self._handle_bio_errors(self._from_ssl, result)
1129
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001130 return _ffi.buffer(buf, result)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001131
1132
1133 def bio_write(self, buf):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001134 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001135 When using non-socket connections this function sends "dirty" data that
1136 would have traveled in on the network.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001137
1138 :param buf: The string to put into the memory BIO.
1139 :return: The number of bytes written
1140 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001141 if self._into_ssl is None:
1142 raise TypeError("Connection sock was not None")
1143
1144 if not isinstance(buf, bytes):
1145 raise TypeError("buf must be a byte string")
1146
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001147 result = _lib.BIO_write(self._into_ssl, buf, len(buf))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001148 if result <= 0:
1149 self._handle_bio_errors(self._into_ssl, result)
1150 return result
1151
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001152
1153 def renegotiate(self):
1154 """
1155 Renegotiate the session
1156
1157 :return: True if the renegotiation can be started, false otherwise
1158 """
1159
1160 def do_handshake(self):
1161 """
1162 Perform an SSL handshake (usually called after renegotiate() or one of
1163 set_*_state()). This can raise the same exceptions as send and recv.
1164
1165 :return: None.
1166 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001167 result = _lib.SSL_do_handshake(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001168 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001169
1170
1171 def renegotiate_pending(self):
1172 """
1173 Check if there's a renegotiation in progress, it will return false once
1174 a renegotiation is finished.
1175
1176 :return: Whether there's a renegotiation in progress
1177 """
1178
1179 def total_renegotiations(self):
1180 """
1181 Find out the total number of renegotiations.
1182
1183 :return: The number of renegotiations.
1184 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001185 return _lib.SSL_total_renegotiations(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001186
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001187
1188 def connect(self, addr):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001189 """
1190 Connect to remote host and set up client-side SSL
1191
1192 :param addr: A remote address
1193 :return: What the socket's connect method returns
1194 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001195 _lib.SSL_set_connect_state(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001196 return self._socket.connect(addr)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001197
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001198
1199 def connect_ex(self, addr):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001200 """
1201 Connect to remote host and set up client-side SSL. Note that if the socket's
1202 connect_ex method doesn't return 0, SSL won't be initialized.
1203
1204 :param addr: A remove address
1205 :return: What the socket's connect_ex method returns
1206 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001207 connect_ex = self._socket.connect_ex
1208 self.set_connect_state()
1209 return connect_ex(addr)
1210
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001211
1212 def accept(self):
1213 """
1214 Accept incoming connection and set up SSL on it
1215
1216 :return: A (conn,addr) pair where conn is a Connection and addr is an
1217 address
1218 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001219 client, addr = self._socket.accept()
1220 conn = Connection(self._context, client)
1221 conn.set_accept_state()
1222 return (conn, addr)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001223
1224
1225 def bio_shutdown(self):
1226 """
1227 When using non-socket connections this function signals end of
1228 data on the input for this connection.
1229
1230 :return: None
1231 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001232 if self._from_ssl is None:
1233 raise TypeError("Connection sock was not None")
1234
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001235 _lib.BIO_set_mem_eof_return(self._into_ssl, 0)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001236
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001237
1238 def shutdown(self):
1239 """
1240 Send closure alert
1241
1242 :return: True if the shutdown completed successfully (i.e. both sides
1243 have sent closure alerts), false otherwise (i.e. you have to
1244 wait for a ZeroReturnError on a recv() method call
1245 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001246 result = _lib.SSL_shutdown(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001247 if result < 0:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001248 # TODO: This is untested.
1249 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001250 elif result > 0:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001251 return True
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001252 else:
1253 return False
1254
1255
1256 def get_cipher_list(self):
1257 """
1258 Get the session cipher list
1259
1260 :return: A list of cipher strings
1261 """
1262 ciphers = []
1263 for i in count():
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001264 result = _lib.SSL_get_cipher_list(self._ssl, i)
1265 if result == _ffi.NULL:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001266 break
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001267 ciphers.append(_native(_ffi.string(result)))
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001268 return ciphers
1269
1270
1271 def get_client_ca_list(self):
1272 """
1273 Get CAs whose certificates are suggested for client authentication.
1274
1275 :return: If this is a server connection, a list of X509Names representing
1276 the acceptable CAs as set by :py:meth:`OpenSSL.SSL.Context.set_client_ca_list` or
1277 :py:meth:`OpenSSL.SSL.Context.add_client_ca`. If this is a client connection,
1278 the list of such X509Names sent by the server, or an empty list if that
1279 has not yet happened.
1280 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001281 ca_names = _lib.SSL_get_client_CA_list(self._ssl)
1282 if ca_names == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001283 # TODO: This is untested.
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001284 return []
1285
1286 result = []
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001287 for i in range(_lib.sk_X509_NAME_num(ca_names)):
1288 name = _lib.sk_X509_NAME_value(ca_names, i)
1289 copy = _lib.X509_NAME_dup(name)
1290 if copy == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001291 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001292 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001293
1294 pyname = X509Name.__new__(X509Name)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001295 pyname._name = _ffi.gc(copy, _lib.X509_NAME_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001296 result.append(pyname)
1297 return result
1298
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001299
1300 def makefile(self):
1301 """
1302 The makefile() method is not implemented, since there is no dup semantics
1303 for SSL connections
1304
Jean-Paul Calderone6749ec22014-04-17 16:30:21 -04001305 :raise: NotImplementedError
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001306 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001307 raise NotImplementedError("Cannot make file object of OpenSSL.SSL.Connection")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001308
1309
1310 def get_app_data(self):
1311 """
1312 Get application data
1313
1314 :return: The application data
1315 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001316 return self._app_data
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001317
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001318
1319 def set_app_data(self, data):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001320 """
1321 Set application data
1322
1323 :param data - The application data
1324 :return: None
1325 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001326 self._app_data = data
1327
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001328
1329 def get_shutdown(self):
1330 """
1331 Get shutdown state
1332
1333 :return: The shutdown state, a bitvector of SENT_SHUTDOWN, RECEIVED_SHUTDOWN.
1334 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001335 return _lib.SSL_get_shutdown(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001336
1337
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001338 def set_shutdown(self, state):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001339 """
1340 Set shutdown state
1341
1342 :param state - bitvector of SENT_SHUTDOWN, RECEIVED_SHUTDOWN.
1343 :return: None
1344 """
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -05001345 if not isinstance(state, integer_types):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001346 raise TypeError("state must be an integer")
1347
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001348 _lib.SSL_set_shutdown(self._ssl, state)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001349
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001350
1351 def state_string(self):
1352 """
1353 Get a verbose state description
1354
1355 :return: A string representing the state
1356 """
1357
1358 def server_random(self):
1359 """
1360 Get a copy of the server hello nonce.
1361
1362 :return: A string representing the state
1363 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001364 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001365 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001366 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001367 self._ssl.s3.server_random,
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001368 _lib.SSL3_RANDOM_SIZE)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001369
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001370
1371 def client_random(self):
1372 """
1373 Get a copy of the client hello nonce.
1374
1375 :return: A string representing the state
1376 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001377 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001378 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001379 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001380 self._ssl.s3.client_random,
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001381 _lib.SSL3_RANDOM_SIZE)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001382
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001383
1384 def master_key(self):
1385 """
1386 Get a copy of the master key.
1387
1388 :return: A string representing the state
1389 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001390 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001391 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001392 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001393 self._ssl.session.master_key,
1394 self._ssl.session.master_key_length)[:]
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001395
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001396
1397 def sock_shutdown(self, *args, **kwargs):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001398 """
1399 See shutdown(2)
1400
1401 :return: What the socket's shutdown() method returns
1402 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001403 return self._socket.shutdown(*args, **kwargs)
1404
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001405
1406 def get_peer_certificate(self):
1407 """
1408 Retrieve the other side's certificate (if any)
1409
1410 :return: The peer's certificate
1411 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001412 cert = _lib.SSL_get_peer_certificate(self._ssl)
1413 if cert != _ffi.NULL:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001414 pycert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001415 pycert._x509 = _ffi.gc(cert, _lib.X509_free)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001416 return pycert
1417 return None
1418
1419
1420 def get_peer_cert_chain(self):
1421 """
1422 Retrieve the other side's certificate (if any)
1423
1424 :return: A list of X509 instances giving the peer's certificate chain,
1425 or None if it does not have one.
1426 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001427 cert_stack = _lib.SSL_get_peer_cert_chain(self._ssl)
1428 if cert_stack == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001429 return None
1430
1431 result = []
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001432 for i in range(_lib.sk_X509_num(cert_stack)):
Jean-Paul Calderone73b15c22013-03-05 18:30:39 -08001433 # TODO could incref instead of dup here
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001434 cert = _lib.X509_dup(_lib.sk_X509_value(cert_stack, i))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001435 pycert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001436 pycert._x509 = _ffi.gc(cert, _lib.X509_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001437 result.append(pycert)
1438 return result
1439
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001440
1441 def want_read(self):
1442 """
1443 Checks if more data has to be read from the transport layer to complete an
1444 operation.
1445
1446 :return: True iff more data has to be read
1447 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001448 return _lib.SSL_want_read(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001449
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001450
1451 def want_write(self):
1452 """
1453 Checks if there is data to write to the transport layer to complete an
1454 operation.
1455
1456 :return: True iff there is data to write
1457 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001458 return _lib.SSL_want_write(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001459
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001460
1461 def set_accept_state(self):
1462 """
1463 Set the connection to work in server mode. The handshake will be handled
1464 automatically by read/write.
1465
1466 :return: None
1467 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001468 _lib.SSL_set_accept_state(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001469
1470
1471 def set_connect_state(self):
1472 """
1473 Set the connection to work in client mode. The handshake will be handled
1474 automatically by read/write.
1475
1476 :return: None
1477 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001478 _lib.SSL_set_connect_state(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001479
1480
1481 def get_session(self):
1482 """
1483 Returns the Session currently used.
1484
1485 @return: An instance of :py:class:`OpenSSL.SSL.Session` or :py:obj:`None` if
1486 no session exists.
1487 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001488 session = _lib.SSL_get1_session(self._ssl)
1489 if session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001490 return None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001491
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001492 pysession = Session.__new__(Session)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001493 pysession._session = _ffi.gc(session, _lib.SSL_SESSION_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001494 return pysession
1495
1496
1497 def set_session(self, session):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001498 """
1499 Set the session to be used when the TLS/SSL connection is established.
1500
1501 :param session: A Session instance representing the session to use.
1502 :returns: None
1503 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001504 if not isinstance(session, Session):
1505 raise TypeError("session must be a Session instance")
1506
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001507 result = _lib.SSL_set_session(self._ssl, session._session)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001508 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001509 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001510
Jean-Paul Calderonedbd76272014-03-29 18:09:40 -04001511
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001512 def _get_finished_message(self, function):
1513 """
1514 Helper to implement :py:meth:`get_finished` and
1515 :py:meth:`get_peer_finished`.
1516
1517 :param function: Either :py:data:`SSL_get_finished`: or
1518 :py:data:`SSL_get_peer_finished`.
1519
1520 :return: :py:data:`None` if the desired message has not yet been
1521 received, otherwise the contents of the message.
1522 :rtype: :py:class:`bytes` or :py:class:`NoneType`
1523 """
Jean-Paul Calderone01af9042014-03-30 11:40:42 -04001524 # The OpenSSL documentation says nothing about what might happen if the
1525 # count argument given is zero. Specifically, it doesn't say whether
1526 # the output buffer may be NULL in that case or not. Inspection of the
1527 # implementation reveals that it calls memcpy() unconditionally.
1528 # Section 7.1.4, paragraph 1 of the C standard suggests that
1529 # memcpy(NULL, source, 0) is not guaranteed to produce defined (let
1530 # alone desirable) behavior (though it probably does on just about
1531 # every implementation...)
1532 #
1533 # Allocate a tiny buffer to pass in (instead of just passing NULL as
1534 # one might expect) for the initial call so as to be safe against this
1535 # potentially undefined behavior.
1536 empty = _ffi.new("char[]", 0)
1537 size = function(self._ssl, empty, 0)
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001538 if size == 0:
1539 # No Finished message so far.
1540 return None
1541
1542 buf = _ffi.new("char[]", size)
1543 function(self._ssl, buf, size)
1544 return _ffi.buffer(buf, size)[:]
1545
1546
Fedor Brunner5747b932014-03-05 14:22:34 +01001547 def get_finished(self):
1548 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001549 Obtain the latest `handshake finished` message sent to the peer.
Fedor Brunner5747b932014-03-05 14:22:34 +01001550
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001551 :return: The contents of the message or :py:obj:`None` if the TLS
1552 handshake has not yet completed.
1553 :rtype: :py:class:`bytes` or :py:class:`NoneType`
Fedor Brunner5747b932014-03-05 14:22:34 +01001554 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001555 return self._get_finished_message(_lib.SSL_get_finished)
1556
Fedor Brunner5747b932014-03-05 14:22:34 +01001557
1558 def get_peer_finished(self):
1559 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001560 Obtain the latest `handshake finished` message received from the peer.
Fedor Brunner5747b932014-03-05 14:22:34 +01001561
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001562 :return: The contents of the message or :py:obj:`None` if the TLS
1563 handshake has not yet completed.
1564 :rtype: :py:class:`bytes` or :py:class:`NoneType`
Fedor Brunner5747b932014-03-05 14:22:34 +01001565 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001566 return self._get_finished_message(_lib.SSL_get_peer_finished)
Fedor Brunner5747b932014-03-05 14:22:34 +01001567
Jean-Paul Calderone7c556ef2014-03-30 10:45:00 -04001568
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001569 def get_cipher_name(self):
1570 """
1571 Obtain the name of the currently used cipher.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001572
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001573 :returns: The name of the currently used cipher or :py:obj:`None`
1574 if no connection has been established.
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001575 :rtype: :py:class:`unicode` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001576 """
1577 cipher = _lib.SSL_get_current_cipher(self._ssl)
1578 if cipher == _ffi.NULL:
1579 return None
1580 else:
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001581 name = _ffi.string(_lib.SSL_CIPHER_get_name(cipher))
1582 return name.decode("utf-8")
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001583
Jean-Paul Calderonedbd76272014-03-29 18:09:40 -04001584
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001585 def get_cipher_bits(self):
1586 """
1587 Obtain the number of secret bits of the currently used cipher.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001588
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001589 :returns: The number of secret bits of the currently used cipher
1590 or :py:obj:`None` if no connection has been established.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001591 :rtype: :py:class:`int` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001592 """
1593 cipher = _lib.SSL_get_current_cipher(self._ssl)
1594 if cipher == _ffi.NULL:
1595 return None
1596 else:
1597 return _lib.SSL_CIPHER_get_bits(cipher, _ffi.NULL)
1598
Jean-Paul Calderonedbd76272014-03-29 18:09:40 -04001599
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001600 def get_cipher_version(self):
1601 """
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001602 Obtain the protocol version of the currently used cipher.
1603
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001604 :returns: The protocol name of the currently used cipher
1605 or :py:obj:`None` if no connection has been established.
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001606 :rtype: :py:class:`unicode` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001607 """
1608 cipher = _lib.SSL_get_current_cipher(self._ssl)
1609 if cipher == _ffi.NULL:
1610 return None
1611 else:
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001612 version =_ffi.string(_lib.SSL_CIPHER_get_version(cipher))
1613 return version.decode("utf-8")
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001614
1615
1616
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001617ConnectionType = Connection
Jean-Paul Calderone11ed8e82014-01-18 10:21:50 -05001618
Jean-Paul Calderonefab157b2014-01-18 11:21:38 -05001619# This is similar to the initialization calls at the end of OpenSSL/crypto.py
1620# but is exercised mostly by the Context initializer.
Jean-Paul Calderone11ed8e82014-01-18 10:21:50 -05001621_lib.SSL_library_init()