blob: 7187a9bd4f52f9cc577b98c74a6217e263b83db6 [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 Calderonef11e3392014-04-17 16:30:12 -0400645 def _set_tmp_ecdh_curve_by_nid(self, nid):
646 """
647 Select a curve to use by the OpenSSL NID associated with that curve.
648
649 :param nid: The OpenSSL NID to use.
650 :type nid: int
651
652 :raise UnsupportedEllipticCurve: If the given NID does not identify a
653 supported curve.
654 """
655 ecdh = _lib.EC_KEY_new_by_curve_name(nid)
656 if ecdh == _ffi.NULL:
657 raise UnsupportedEllipticCurve(sn)
658 _lib.SSL_CTX_set_tmp_ecdh(self._context, ecdh)
659 _lib.EC_KEY_free(ecdh)
660
661
Andy Lutomirskif05a2732014-03-13 17:22:25 -0700662 def set_tmp_ecdh_curve(self, curve_name):
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600663 """
Andy Lutomirski76a61332014-03-12 15:02:56 -0700664 Select a curve to use for ECDHE key exchange.
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600665
Andy Lutomirskif05a2732014-03-13 17:22:25 -0700666 The valid values of *curve_name* are the keys in
667 :py:data:OpenSSL.SSL.ELLIPTIC_CURVE_DESCRIPTIONS.
668
Andy Lutomirski61d7d392014-04-04 12:16:56 -0700669 Raises a subclass of ``ValueError`` if the linked OpenSSL was
670 not compiled with elliptical curve support or the specified
671 curve is not available. You can check the specific subclass,
672 but, in general, you should just handle ``ValueError``.
Andy Lutomirskif05a2732014-03-13 17:22:25 -0700673
674 :param curve_name: The 'short name' of a curve, e.g. 'prime256v1'
675 :type curve_name: str
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600676 :return: None
677 """
678 if _lib.Cryptography_HAS_EC:
Andy Lutomirski5fb416a2014-04-04 12:19:52 -0700679 nid = _lib.OBJ_sn2nid(curve_name.encode('ascii'))
Andy Lutomirskif05a2732014-03-13 17:22:25 -0700680 if nid == _lib.NID_undef:
Andy Lutomirski61d7d392014-04-04 12:16:56 -0700681 raise UnknownObject(curve_name)
Jean-Paul Calderonef11e3392014-04-17 16:30:12 -0400682 return self._set_tmp_ecdh_curve_by_nid(nid)
683 raise ECNotAvailable()
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600684
685
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800686 def set_cipher_list(self, cipher_list):
687 """
688 Change the cipher list
689
690 :param cipher_list: A cipher list, see ciphers(1)
691 :return: None
692 """
Jean-Paul Calderone63eab692014-01-18 10:19:56 -0500693 if isinstance(cipher_list, _text_type):
694 cipher_list = cipher_list.encode("ascii")
695
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800696 if not isinstance(cipher_list, bytes):
Jean-Paul Calderone63eab692014-01-18 10:19:56 -0500697 raise TypeError("cipher_list must be bytes or unicode")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800698
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500699 result = _lib.SSL_CTX_set_cipher_list(self._context, cipher_list)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800700 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500701 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800702
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800703
704 def set_client_ca_list(self, certificate_authorities):
705 """
706 Set the list of preferred client certificate signers for this server context.
707
708 This list of certificate authorities will be sent to the client when the
709 server requests a client certificate.
710
711 :param certificate_authorities: a sequence of X509Names.
712 :return: None
713 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500714 name_stack = _lib.sk_X509_NAME_new_null()
715 if name_stack == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500716 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500717 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800718
719 try:
720 for ca_name in certificate_authorities:
721 if not isinstance(ca_name, X509Name):
722 raise TypeError(
723 "client CAs must be X509Name objects, not %s objects" % (
724 type(ca_name).__name__,))
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500725 copy = _lib.X509_NAME_dup(ca_name._name)
726 if copy == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500727 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500728 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500729 push_result = _lib.sk_X509_NAME_push(name_stack, copy)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800730 if not push_result:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500731 _lib.X509_NAME_free(copy)
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500732 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800733 except:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500734 _lib.sk_X509_NAME_free(name_stack)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800735 raise
736
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500737 _lib.SSL_CTX_set_client_CA_list(self._context, name_stack)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800738
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800739
740 def add_client_ca(self, certificate_authority):
741 """
742 Add the CA certificate to the list of preferred signers for this context.
743
744 The list of certificate authorities will be sent to the client when the
745 server requests a client certificate.
746
747 :param certificate_authority: certificate authority's X509 certificate.
748 :return: None
749 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800750 if not isinstance(certificate_authority, X509):
751 raise TypeError("certificate_authority must be an X509 instance")
752
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500753 add_result = _lib.SSL_CTX_add_client_CA(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800754 self._context, certificate_authority._x509)
755 if not add_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500756 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500757 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800758
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800759
760 def set_timeout(self, timeout):
761 """
762 Set session timeout
763
764 :param timeout: The timeout in seconds
765 :return: The previous session timeout
766 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500767 if not isinstance(timeout, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800768 raise TypeError("timeout must be an integer")
769
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500770 return _lib.SSL_CTX_set_timeout(self._context, timeout)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800771
772
773 def get_timeout(self):
774 """
775 Get the session timeout
776
777 :return: The session timeout
778 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500779 return _lib.SSL_CTX_get_timeout(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800780
781
782 def set_info_callback(self, callback):
783 """
784 Set the info callback
785
786 :param callback: The Python callback to use
787 :return: None
788 """
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800789 @wraps(callback)
790 def wrapper(ssl, where, return_code):
Jean-Paul Calderonef2bbc9c2014-02-02 10:59:14 -0500791 callback(Connection._reverse_mapping[ssl], where, return_code)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500792 self._info_callback = _ffi.callback(
793 "void (*)(const SSL *, int, int)", wrapper)
794 _lib.SSL_CTX_set_info_callback(self._context, self._info_callback)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800795
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800796
797 def get_app_data(self):
798 """
799 Get the application data (supplied via set_app_data())
800
801 :return: The application data
802 """
803 return self._app_data
804
805
806 def set_app_data(self, data):
807 """
808 Set the application data (will be returned from get_app_data())
809
810 :param data: Any Python object
811 :return: None
812 """
813 self._app_data = data
814
815
816 def get_cert_store(self):
817 """
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500818 Get the certificate store for the context.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800819
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500820 :return: A X509Store object or None if it does not have one.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800821 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500822 store = _lib.SSL_CTX_get_cert_store(self._context)
823 if store == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500824 # TODO: This is untested.
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800825 return None
826
827 pystore = X509Store.__new__(X509Store)
828 pystore._store = store
829 return pystore
830
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800831
832 def set_options(self, options):
833 """
834 Add options. Options set before are not cleared!
835
836 :param options: The options to add.
837 :return: The new option bitmask.
838 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500839 if not isinstance(options, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800840 raise TypeError("options must be an integer")
841
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500842 return _lib.SSL_CTX_set_options(self._context, options)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800843
844
845 def set_mode(self, mode):
846 """
847 Add modes via bitmask. Modes set before are not cleared!
848
849 :param mode: The mode to add.
850 :return: The new mode bitmask.
851 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500852 if not isinstance(mode, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800853 raise TypeError("mode must be an integer")
854
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500855 return _lib.SSL_CTX_set_mode(self._context, mode)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800856
857
858 def set_tlsext_servername_callback(self, callback):
859 """
860 Specify a callback function to be called when clients specify a server name.
861
862 :param callback: The callback function. It will be invoked with one
863 argument, the Connection instance.
864 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800865 @wraps(callback)
866 def wrapper(ssl, alert, arg):
867 callback(Connection._reverse_mapping[ssl])
868 return 0
869
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500870 self._tlsext_servername_callback = _ffi.callback(
871 "int (*)(const SSL *, int *, void *)", wrapper)
872 _lib.SSL_CTX_set_tlsext_servername_callback(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800873 self._context, self._tlsext_servername_callback)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800874
875ContextType = Context
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800876
877
878
879class Connection(object):
880 """
881 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800882 _reverse_mapping = WeakValueDictionary()
883
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800884 def __init__(self, context, socket=None):
885 """
886 Create a new Connection object, using the given OpenSSL.SSL.Context
887 instance and socket.
888
889 :param context: An SSL Context to use for this connection
890 :param socket: The socket to use for transport layer
891 """
892 if not isinstance(context, Context):
893 raise TypeError("context must be a Context instance")
894
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500895 ssl = _lib.SSL_new(context._context)
896 self._ssl = _ffi.gc(ssl, _lib.SSL_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800897 self._context = context
898
899 self._reverse_mapping[self._ssl] = self
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800900
901 if socket is None:
902 self._socket = None
Jean-Paul Calderone73b15c22013-03-05 18:30:39 -0800903 # Don't set up any gc for these, SSL_free will take care of them.
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500904 self._into_ssl = _lib.BIO_new(_lib.BIO_s_mem())
905 self._from_ssl = _lib.BIO_new(_lib.BIO_s_mem())
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800906
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500907 if self._into_ssl == _ffi.NULL or self._from_ssl == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500908 # TODO: This is untested.
909 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800910
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500911 _lib.SSL_set_bio(self._ssl, self._into_ssl, self._from_ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800912 else:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800913 self._into_ssl = None
914 self._from_ssl = None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800915 self._socket = socket
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500916 set_result = _lib.SSL_set_fd(self._ssl, _asFileDescriptor(self._socket))
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800917 if not set_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500918 # TODO: This is untested.
919 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800920
921
922 def __getattr__(self, name):
923 """
924 Look up attributes on the wrapped socket object if they are not found on
925 the Connection object.
926 """
927 return getattr(self._socket, name)
928
929
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800930 def _raise_ssl_error(self, ssl, result):
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800931 if self._context._verify_helper is not None:
932 self._context._verify_helper.raise_if_problem()
933
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500934 error = _lib.SSL_get_error(ssl, result)
935 if error == _lib.SSL_ERROR_WANT_READ:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800936 raise WantReadError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500937 elif error == _lib.SSL_ERROR_WANT_WRITE:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -0700938 raise WantWriteError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500939 elif error == _lib.SSL_ERROR_ZERO_RETURN:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800940 raise ZeroReturnError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500941 elif error == _lib.SSL_ERROR_WANT_X509_LOOKUP:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500942 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -0700943 raise WantX509LookupError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500944 elif error == _lib.SSL_ERROR_SYSCALL:
945 if _lib.ERR_peek_error() == 0:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800946 if result < 0:
Konstantinos Koukopoulos541150d2014-01-31 01:00:19 +0200947 if platform == "win32":
948 errno = _ffi.getwinerror()[0]
949 else:
950 errno = _ffi.errno
951 raise SysCallError(errno, errorcode[errno])
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800952 else:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -0700953 raise SysCallError(-1, "Unexpected EOF")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800954 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500955 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500956 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500957 elif error == _lib.SSL_ERROR_NONE:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -0700958 pass
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800959 else:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500960 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800961
962
963 def get_context(self):
964 """
965 Get session context
966 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800967 return self._context
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800968
969
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800970 def set_context(self, context):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800971 """
972 Switch this connection to a new session context
973
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800974 :param context: A :py:class:`Context` instance giving the new session
975 context to use.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800976 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800977 if not isinstance(context, Context):
978 raise TypeError("context must be a Context instance")
979
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500980 _lib.SSL_set_SSL_CTX(self._ssl, context._context)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800981 self._context = context
982
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800983
984 def get_servername(self):
985 """
986 Retrieve the servername extension value if provided in the client hello
987 message, or None if there wasn't one.
988
989 :return: A byte string giving the server name or :py:data:`None`.
990 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500991 name = _lib.SSL_get_servername(self._ssl, _lib.TLSEXT_NAMETYPE_host_name)
992 if name == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800993 return None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800994
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500995 return _ffi.string(name)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800996
997
998 def set_tlsext_host_name(self, name):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800999 """
1000 Set the value of the servername extension to send in the client hello.
1001
1002 :param name: A byte string giving the name.
1003 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001004 if not isinstance(name, bytes):
1005 raise TypeError("name must be a byte string")
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001006 elif b"\0" in name:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001007 raise TypeError("name must not contain NUL byte")
1008
1009 # XXX I guess this can fail sometimes?
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001010 _lib.SSL_set_tlsext_host_name(self._ssl, name)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001011
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001012
1013 def pending(self):
1014 """
1015 Get the number of bytes that can be safely read from the connection
1016
1017 :return: The number of bytes available in the receive buffer.
1018 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001019 return _lib.SSL_pending(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001020
1021
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001022 def send(self, buf, flags=0):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001023 """
1024 Send data on the connection. NOTE: If you get one of the WantRead,
1025 WantWrite or WantX509Lookup exceptions on this, you have to call the
1026 method again with the SAME buffer.
1027
1028 :param buf: The string to send
1029 :param flags: (optional) Included for compatibility with the socket
1030 API, the value is ignored
1031 :return: The number of bytes written
1032 """
Jean-Paul Calderone8fb53182013-12-30 08:35:49 -05001033 if isinstance(buf, _memoryview):
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -08001034 buf = buf.tobytes()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001035 if not isinstance(buf, bytes):
1036 raise TypeError("data must be a byte string")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001037
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001038 result = _lib.SSL_write(self._ssl, buf, len(buf))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001039 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001040 return result
1041 write = send
1042
1043
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001044 def sendall(self, buf, flags=0):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001045 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001046 Send "all" data on the connection. This calls send() repeatedly until
1047 all data is sent. If an error occurs, it's impossible to tell how much
1048 data has been sent.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001049
1050 :param buf: The string to send
1051 :param flags: (optional) Included for compatibility with the socket
1052 API, the value is ignored
1053 :return: The number of bytes written
1054 """
Jean-Paul Calderone8fb53182013-12-30 08:35:49 -05001055 if isinstance(buf, _memoryview):
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -08001056 buf = buf.tobytes()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001057 if not isinstance(buf, bytes):
1058 raise TypeError("buf must be a byte string")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001059
1060 left_to_send = len(buf)
1061 total_sent = 0
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001062 data = _ffi.new("char[]", buf)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001063
1064 while left_to_send:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001065 result = _lib.SSL_write(self._ssl, data + total_sent, left_to_send)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001066 self._raise_ssl_error(self._ssl, result)
1067 total_sent += result
1068 left_to_send -= result
1069
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001070
1071 def recv(self, bufsiz, flags=None):
1072 """
1073 Receive data on the connection. NOTE: If you get one of the WantRead,
1074 WantWrite or WantX509Lookup exceptions on this, you have to call the
1075 method again with the SAME buffer.
1076
1077 :param bufsiz: The maximum number of bytes to read
1078 :param flags: (optional) Included for compatibility with the socket
1079 API, the value is ignored
1080 :return: The string read from the Connection
1081 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001082 buf = _ffi.new("char[]", bufsiz)
1083 result = _lib.SSL_read(self._ssl, buf, bufsiz)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001084 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001085 return _ffi.buffer(buf, result)[:]
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001086 read = recv
1087
1088
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001089 def _handle_bio_errors(self, bio, result):
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001090 if _lib.BIO_should_retry(bio):
1091 if _lib.BIO_should_read(bio):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001092 raise WantReadError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001093 elif _lib.BIO_should_write(bio):
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001094 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001095 raise WantWriteError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001096 elif _lib.BIO_should_io_special(bio):
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001097 # TODO: This is untested. I think io_special means the socket
1098 # BIO has a not-yet connected socket.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001099 raise ValueError("BIO_should_io_special")
1100 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001101 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001102 raise ValueError("unknown bio failure")
1103 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001104 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001105 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001106
1107
1108 def bio_read(self, bufsiz):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001109 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001110 When using non-socket connections this function reads the "dirty" data
1111 that would have traveled away on the network.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001112
1113 :param bufsiz: The maximum number of bytes to read
1114 :return: The string read.
1115 """
Jean-Paul Calderone97e041d2013-03-05 21:03:12 -08001116 if self._from_ssl is None:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001117 raise TypeError("Connection sock was not None")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001118
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -05001119 if not isinstance(bufsiz, integer_types):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001120 raise TypeError("bufsiz must be an integer")
1121
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001122 buf = _ffi.new("char[]", bufsiz)
1123 result = _lib.BIO_read(self._from_ssl, buf, bufsiz)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001124 if result <= 0:
1125 self._handle_bio_errors(self._from_ssl, result)
1126
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001127 return _ffi.buffer(buf, result)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001128
1129
1130 def bio_write(self, buf):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001131 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001132 When using non-socket connections this function sends "dirty" data that
1133 would have traveled in on the network.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001134
1135 :param buf: The string to put into the memory BIO.
1136 :return: The number of bytes written
1137 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001138 if self._into_ssl is None:
1139 raise TypeError("Connection sock was not None")
1140
1141 if not isinstance(buf, bytes):
1142 raise TypeError("buf must be a byte string")
1143
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001144 result = _lib.BIO_write(self._into_ssl, buf, len(buf))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001145 if result <= 0:
1146 self._handle_bio_errors(self._into_ssl, result)
1147 return result
1148
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001149
1150 def renegotiate(self):
1151 """
1152 Renegotiate the session
1153
1154 :return: True if the renegotiation can be started, false otherwise
1155 """
1156
1157 def do_handshake(self):
1158 """
1159 Perform an SSL handshake (usually called after renegotiate() or one of
1160 set_*_state()). This can raise the same exceptions as send and recv.
1161
1162 :return: None.
1163 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001164 result = _lib.SSL_do_handshake(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001165 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001166
1167
1168 def renegotiate_pending(self):
1169 """
1170 Check if there's a renegotiation in progress, it will return false once
1171 a renegotiation is finished.
1172
1173 :return: Whether there's a renegotiation in progress
1174 """
1175
1176 def total_renegotiations(self):
1177 """
1178 Find out the total number of renegotiations.
1179
1180 :return: The number of renegotiations.
1181 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001182 return _lib.SSL_total_renegotiations(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001183
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001184
1185 def connect(self, addr):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001186 """
1187 Connect to remote host and set up client-side SSL
1188
1189 :param addr: A remote address
1190 :return: What the socket's connect method returns
1191 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001192 _lib.SSL_set_connect_state(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001193 return self._socket.connect(addr)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001194
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001195
1196 def connect_ex(self, addr):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001197 """
1198 Connect to remote host and set up client-side SSL. Note that if the socket's
1199 connect_ex method doesn't return 0, SSL won't be initialized.
1200
1201 :param addr: A remove address
1202 :return: What the socket's connect_ex method returns
1203 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001204 connect_ex = self._socket.connect_ex
1205 self.set_connect_state()
1206 return connect_ex(addr)
1207
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001208
1209 def accept(self):
1210 """
1211 Accept incoming connection and set up SSL on it
1212
1213 :return: A (conn,addr) pair where conn is a Connection and addr is an
1214 address
1215 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001216 client, addr = self._socket.accept()
1217 conn = Connection(self._context, client)
1218 conn.set_accept_state()
1219 return (conn, addr)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001220
1221
1222 def bio_shutdown(self):
1223 """
1224 When using non-socket connections this function signals end of
1225 data on the input for this connection.
1226
1227 :return: None
1228 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001229 if self._from_ssl is None:
1230 raise TypeError("Connection sock was not None")
1231
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001232 _lib.BIO_set_mem_eof_return(self._into_ssl, 0)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001233
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001234
1235 def shutdown(self):
1236 """
1237 Send closure alert
1238
1239 :return: True if the shutdown completed successfully (i.e. both sides
1240 have sent closure alerts), false otherwise (i.e. you have to
1241 wait for a ZeroReturnError on a recv() method call
1242 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001243 result = _lib.SSL_shutdown(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001244 if result < 0:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001245 # TODO: This is untested.
1246 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001247 elif result > 0:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001248 return True
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001249 else:
1250 return False
1251
1252
1253 def get_cipher_list(self):
1254 """
1255 Get the session cipher list
1256
1257 :return: A list of cipher strings
1258 """
1259 ciphers = []
1260 for i in count():
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001261 result = _lib.SSL_get_cipher_list(self._ssl, i)
1262 if result == _ffi.NULL:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001263 break
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001264 ciphers.append(_native(_ffi.string(result)))
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001265 return ciphers
1266
1267
1268 def get_client_ca_list(self):
1269 """
1270 Get CAs whose certificates are suggested for client authentication.
1271
1272 :return: If this is a server connection, a list of X509Names representing
1273 the acceptable CAs as set by :py:meth:`OpenSSL.SSL.Context.set_client_ca_list` or
1274 :py:meth:`OpenSSL.SSL.Context.add_client_ca`. If this is a client connection,
1275 the list of such X509Names sent by the server, or an empty list if that
1276 has not yet happened.
1277 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001278 ca_names = _lib.SSL_get_client_CA_list(self._ssl)
1279 if ca_names == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001280 # TODO: This is untested.
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001281 return []
1282
1283 result = []
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001284 for i in range(_lib.sk_X509_NAME_num(ca_names)):
1285 name = _lib.sk_X509_NAME_value(ca_names, i)
1286 copy = _lib.X509_NAME_dup(name)
1287 if copy == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001288 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001289 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001290
1291 pyname = X509Name.__new__(X509Name)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001292 pyname._name = _ffi.gc(copy, _lib.X509_NAME_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001293 result.append(pyname)
1294 return result
1295
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001296
1297 def makefile(self):
1298 """
1299 The makefile() method is not implemented, since there is no dup semantics
1300 for SSL connections
1301
1302 :raise NotImplementedError
1303 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001304 raise NotImplementedError("Cannot make file object of OpenSSL.SSL.Connection")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001305
1306
1307 def get_app_data(self):
1308 """
1309 Get application data
1310
1311 :return: The application data
1312 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001313 return self._app_data
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001314
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001315
1316 def set_app_data(self, data):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001317 """
1318 Set application data
1319
1320 :param data - The application data
1321 :return: None
1322 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001323 self._app_data = data
1324
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001325
1326 def get_shutdown(self):
1327 """
1328 Get shutdown state
1329
1330 :return: The shutdown state, a bitvector of SENT_SHUTDOWN, RECEIVED_SHUTDOWN.
1331 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001332 return _lib.SSL_get_shutdown(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001333
1334
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001335 def set_shutdown(self, state):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001336 """
1337 Set shutdown state
1338
1339 :param state - bitvector of SENT_SHUTDOWN, RECEIVED_SHUTDOWN.
1340 :return: None
1341 """
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -05001342 if not isinstance(state, integer_types):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001343 raise TypeError("state must be an integer")
1344
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001345 _lib.SSL_set_shutdown(self._ssl, state)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001346
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001347
1348 def state_string(self):
1349 """
1350 Get a verbose state description
1351
1352 :return: A string representing the state
1353 """
1354
1355 def server_random(self):
1356 """
1357 Get a copy of the server hello nonce.
1358
1359 :return: A string representing the state
1360 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001361 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001362 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001363 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001364 self._ssl.s3.server_random,
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001365 _lib.SSL3_RANDOM_SIZE)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001366
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001367
1368 def client_random(self):
1369 """
1370 Get a copy of the client hello nonce.
1371
1372 :return: A string representing the state
1373 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001374 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001375 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001376 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001377 self._ssl.s3.client_random,
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001378 _lib.SSL3_RANDOM_SIZE)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001379
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001380
1381 def master_key(self):
1382 """
1383 Get a copy of the master key.
1384
1385 :return: A string representing the state
1386 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001387 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001388 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001389 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001390 self._ssl.session.master_key,
1391 self._ssl.session.master_key_length)[:]
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001392
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001393
1394 def sock_shutdown(self, *args, **kwargs):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001395 """
1396 See shutdown(2)
1397
1398 :return: What the socket's shutdown() method returns
1399 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001400 return self._socket.shutdown(*args, **kwargs)
1401
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001402
1403 def get_peer_certificate(self):
1404 """
1405 Retrieve the other side's certificate (if any)
1406
1407 :return: The peer's certificate
1408 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001409 cert = _lib.SSL_get_peer_certificate(self._ssl)
1410 if cert != _ffi.NULL:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001411 pycert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001412 pycert._x509 = _ffi.gc(cert, _lib.X509_free)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001413 return pycert
1414 return None
1415
1416
1417 def get_peer_cert_chain(self):
1418 """
1419 Retrieve the other side's certificate (if any)
1420
1421 :return: A list of X509 instances giving the peer's certificate chain,
1422 or None if it does not have one.
1423 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001424 cert_stack = _lib.SSL_get_peer_cert_chain(self._ssl)
1425 if cert_stack == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001426 return None
1427
1428 result = []
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001429 for i in range(_lib.sk_X509_num(cert_stack)):
Jean-Paul Calderone73b15c22013-03-05 18:30:39 -08001430 # TODO could incref instead of dup here
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001431 cert = _lib.X509_dup(_lib.sk_X509_value(cert_stack, i))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001432 pycert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001433 pycert._x509 = _ffi.gc(cert, _lib.X509_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001434 result.append(pycert)
1435 return result
1436
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001437
1438 def want_read(self):
1439 """
1440 Checks if more data has to be read from the transport layer to complete an
1441 operation.
1442
1443 :return: True iff more data has to be read
1444 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001445 return _lib.SSL_want_read(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001446
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001447
1448 def want_write(self):
1449 """
1450 Checks if there is data to write to the transport layer to complete an
1451 operation.
1452
1453 :return: True iff there is data to write
1454 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001455 return _lib.SSL_want_write(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001456
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001457
1458 def set_accept_state(self):
1459 """
1460 Set the connection to work in server mode. The handshake will be handled
1461 automatically by read/write.
1462
1463 :return: None
1464 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001465 _lib.SSL_set_accept_state(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001466
1467
1468 def set_connect_state(self):
1469 """
1470 Set the connection to work in client mode. The handshake will be handled
1471 automatically by read/write.
1472
1473 :return: None
1474 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001475 _lib.SSL_set_connect_state(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001476
1477
1478 def get_session(self):
1479 """
1480 Returns the Session currently used.
1481
1482 @return: An instance of :py:class:`OpenSSL.SSL.Session` or :py:obj:`None` if
1483 no session exists.
1484 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001485 session = _lib.SSL_get1_session(self._ssl)
1486 if session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001487 return None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001488
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001489 pysession = Session.__new__(Session)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001490 pysession._session = _ffi.gc(session, _lib.SSL_SESSION_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001491 return pysession
1492
1493
1494 def set_session(self, session):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001495 """
1496 Set the session to be used when the TLS/SSL connection is established.
1497
1498 :param session: A Session instance representing the session to use.
1499 :returns: None
1500 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001501 if not isinstance(session, Session):
1502 raise TypeError("session must be a Session instance")
1503
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001504 result = _lib.SSL_set_session(self._ssl, session._session)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001505 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001506 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001507
Jean-Paul Calderonedbd76272014-03-29 18:09:40 -04001508
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001509 def _get_finished_message(self, function):
1510 """
1511 Helper to implement :py:meth:`get_finished` and
1512 :py:meth:`get_peer_finished`.
1513
1514 :param function: Either :py:data:`SSL_get_finished`: or
1515 :py:data:`SSL_get_peer_finished`.
1516
1517 :return: :py:data:`None` if the desired message has not yet been
1518 received, otherwise the contents of the message.
1519 :rtype: :py:class:`bytes` or :py:class:`NoneType`
1520 """
Jean-Paul Calderone01af9042014-03-30 11:40:42 -04001521 # The OpenSSL documentation says nothing about what might happen if the
1522 # count argument given is zero. Specifically, it doesn't say whether
1523 # the output buffer may be NULL in that case or not. Inspection of the
1524 # implementation reveals that it calls memcpy() unconditionally.
1525 # Section 7.1.4, paragraph 1 of the C standard suggests that
1526 # memcpy(NULL, source, 0) is not guaranteed to produce defined (let
1527 # alone desirable) behavior (though it probably does on just about
1528 # every implementation...)
1529 #
1530 # Allocate a tiny buffer to pass in (instead of just passing NULL as
1531 # one might expect) for the initial call so as to be safe against this
1532 # potentially undefined behavior.
1533 empty = _ffi.new("char[]", 0)
1534 size = function(self._ssl, empty, 0)
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001535 if size == 0:
1536 # No Finished message so far.
1537 return None
1538
1539 buf = _ffi.new("char[]", size)
1540 function(self._ssl, buf, size)
1541 return _ffi.buffer(buf, size)[:]
1542
1543
Fedor Brunner5747b932014-03-05 14:22:34 +01001544 def get_finished(self):
1545 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001546 Obtain the latest `handshake finished` message sent to the peer.
Fedor Brunner5747b932014-03-05 14:22:34 +01001547
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001548 :return: The contents of the message or :py:obj:`None` if the TLS
1549 handshake has not yet completed.
1550 :rtype: :py:class:`bytes` or :py:class:`NoneType`
Fedor Brunner5747b932014-03-05 14:22:34 +01001551 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001552 return self._get_finished_message(_lib.SSL_get_finished)
1553
Fedor Brunner5747b932014-03-05 14:22:34 +01001554
1555 def get_peer_finished(self):
1556 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001557 Obtain the latest `handshake finished` message received from the peer.
Fedor Brunner5747b932014-03-05 14:22:34 +01001558
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001559 :return: The contents of the message or :py:obj:`None` if the TLS
1560 handshake has not yet completed.
1561 :rtype: :py:class:`bytes` or :py:class:`NoneType`
Fedor Brunner5747b932014-03-05 14:22:34 +01001562 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001563 return self._get_finished_message(_lib.SSL_get_peer_finished)
Fedor Brunner5747b932014-03-05 14:22:34 +01001564
Jean-Paul Calderone7c556ef2014-03-30 10:45:00 -04001565
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001566 def get_cipher_name(self):
1567 """
1568 Obtain the name of the currently used cipher.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001569
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001570 :returns: The name of the currently used cipher or :py:obj:`None`
1571 if no connection has been established.
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001572 :rtype: :py:class:`unicode` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001573 """
1574 cipher = _lib.SSL_get_current_cipher(self._ssl)
1575 if cipher == _ffi.NULL:
1576 return None
1577 else:
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001578 name = _ffi.string(_lib.SSL_CIPHER_get_name(cipher))
1579 return name.decode("utf-8")
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001580
Jean-Paul Calderonedbd76272014-03-29 18:09:40 -04001581
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001582 def get_cipher_bits(self):
1583 """
1584 Obtain the number of secret bits of the currently used cipher.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001585
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001586 :returns: The number of secret bits of the currently used cipher
1587 or :py:obj:`None` if no connection has been established.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001588 :rtype: :py:class:`int` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001589 """
1590 cipher = _lib.SSL_get_current_cipher(self._ssl)
1591 if cipher == _ffi.NULL:
1592 return None
1593 else:
1594 return _lib.SSL_CIPHER_get_bits(cipher, _ffi.NULL)
1595
Jean-Paul Calderonedbd76272014-03-29 18:09:40 -04001596
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001597 def get_cipher_version(self):
1598 """
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001599 Obtain the protocol version of the currently used cipher.
1600
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001601 :returns: The protocol name of the currently used cipher
1602 or :py:obj:`None` if no connection has been established.
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001603 :rtype: :py:class:`unicode` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001604 """
1605 cipher = _lib.SSL_get_current_cipher(self._ssl)
1606 if cipher == _ffi.NULL:
1607 return None
1608 else:
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001609 version =_ffi.string(_lib.SSL_CIPHER_get_version(cipher))
1610 return version.decode("utf-8")
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001611
1612
1613
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001614ConnectionType = Connection
Jean-Paul Calderone11ed8e82014-01-18 10:21:50 -05001615
Jean-Paul Calderonefab157b2014-01-18 11:21:38 -05001616# This is similar to the initialization calls at the end of OpenSSL/crypto.py
1617# but is exercised mostly by the Context initializer.
Jean-Paul Calderone11ed8e82014-01-18 10:21:50 -05001618_lib.SSL_library_init()