blob: f04f732a8697c68e4952748440016dc8d1d8834c [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
Andy Lutomirskif05a2732014-03-13 17:22:25 -0700645 def set_tmp_ecdh_curve(self, curve_name):
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600646 """
Andy Lutomirski76a61332014-03-12 15:02:56 -0700647 Select a curve to use for ECDHE key exchange.
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600648
Andy Lutomirskif05a2732014-03-13 17:22:25 -0700649 The valid values of *curve_name* are the keys in
650 :py:data:OpenSSL.SSL.ELLIPTIC_CURVE_DESCRIPTIONS.
651
Andy Lutomirski61d7d392014-04-04 12:16:56 -0700652 Raises a subclass of ``ValueError`` if the linked OpenSSL was
653 not compiled with elliptical curve support or the specified
654 curve is not available. You can check the specific subclass,
655 but, in general, you should just handle ``ValueError``.
Andy Lutomirskif05a2732014-03-13 17:22:25 -0700656
657 :param curve_name: The 'short name' of a curve, e.g. 'prime256v1'
658 :type curve_name: str
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600659 :return: None
660 """
661 if _lib.Cryptography_HAS_EC:
Andy Lutomirski5fb416a2014-04-04 12:19:52 -0700662 nid = _lib.OBJ_sn2nid(curve_name.encode('ascii'))
Andy Lutomirskif05a2732014-03-13 17:22:25 -0700663 if nid == _lib.NID_undef:
Andy Lutomirski61d7d392014-04-04 12:16:56 -0700664 raise UnknownObject(curve_name)
Andy Lutomirskif05a2732014-03-13 17:22:25 -0700665 ecdh = _lib.EC_KEY_new_by_curve_name(nid)
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600666 if ecdh == _ffi.NULL:
Andy Lutomirski61d7d392014-04-04 12:16:56 -0700667 raise UnsupportedEllipticCurve(sn)
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600668 _lib.SSL_CTX_set_tmp_ecdh(self._context, ecdh)
669 _lib.EC_KEY_free(ecdh)
670 else:
Andy Lutomirski61d7d392014-04-04 12:16:56 -0700671 raise ECNotAvailable()
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600672
673
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800674 def set_cipher_list(self, cipher_list):
675 """
676 Change the cipher list
677
678 :param cipher_list: A cipher list, see ciphers(1)
679 :return: None
680 """
Jean-Paul Calderone63eab692014-01-18 10:19:56 -0500681 if isinstance(cipher_list, _text_type):
682 cipher_list = cipher_list.encode("ascii")
683
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800684 if not isinstance(cipher_list, bytes):
Jean-Paul Calderone63eab692014-01-18 10:19:56 -0500685 raise TypeError("cipher_list must be bytes or unicode")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800686
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500687 result = _lib.SSL_CTX_set_cipher_list(self._context, cipher_list)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800688 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500689 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800690
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800691
692 def set_client_ca_list(self, certificate_authorities):
693 """
694 Set the list of preferred client certificate signers for this server context.
695
696 This list of certificate authorities will be sent to the client when the
697 server requests a client certificate.
698
699 :param certificate_authorities: a sequence of X509Names.
700 :return: None
701 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500702 name_stack = _lib.sk_X509_NAME_new_null()
703 if name_stack == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500704 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500705 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800706
707 try:
708 for ca_name in certificate_authorities:
709 if not isinstance(ca_name, X509Name):
710 raise TypeError(
711 "client CAs must be X509Name objects, not %s objects" % (
712 type(ca_name).__name__,))
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500713 copy = _lib.X509_NAME_dup(ca_name._name)
714 if copy == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500715 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500716 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500717 push_result = _lib.sk_X509_NAME_push(name_stack, copy)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800718 if not push_result:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500719 _lib.X509_NAME_free(copy)
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500720 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800721 except:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500722 _lib.sk_X509_NAME_free(name_stack)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800723 raise
724
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500725 _lib.SSL_CTX_set_client_CA_list(self._context, name_stack)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800726
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800727
728 def add_client_ca(self, certificate_authority):
729 """
730 Add the CA certificate to the list of preferred signers for this context.
731
732 The list of certificate authorities will be sent to the client when the
733 server requests a client certificate.
734
735 :param certificate_authority: certificate authority's X509 certificate.
736 :return: None
737 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800738 if not isinstance(certificate_authority, X509):
739 raise TypeError("certificate_authority must be an X509 instance")
740
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500741 add_result = _lib.SSL_CTX_add_client_CA(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800742 self._context, certificate_authority._x509)
743 if not add_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500744 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500745 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800746
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800747
748 def set_timeout(self, timeout):
749 """
750 Set session timeout
751
752 :param timeout: The timeout in seconds
753 :return: The previous session timeout
754 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500755 if not isinstance(timeout, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800756 raise TypeError("timeout must be an integer")
757
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500758 return _lib.SSL_CTX_set_timeout(self._context, timeout)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800759
760
761 def get_timeout(self):
762 """
763 Get the session timeout
764
765 :return: The session timeout
766 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500767 return _lib.SSL_CTX_get_timeout(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800768
769
770 def set_info_callback(self, callback):
771 """
772 Set the info callback
773
774 :param callback: The Python callback to use
775 :return: None
776 """
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800777 @wraps(callback)
778 def wrapper(ssl, where, return_code):
Jean-Paul Calderonef2bbc9c2014-02-02 10:59:14 -0500779 callback(Connection._reverse_mapping[ssl], where, return_code)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500780 self._info_callback = _ffi.callback(
781 "void (*)(const SSL *, int, int)", wrapper)
782 _lib.SSL_CTX_set_info_callback(self._context, self._info_callback)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800783
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800784
785 def get_app_data(self):
786 """
787 Get the application data (supplied via set_app_data())
788
789 :return: The application data
790 """
791 return self._app_data
792
793
794 def set_app_data(self, data):
795 """
796 Set the application data (will be returned from get_app_data())
797
798 :param data: Any Python object
799 :return: None
800 """
801 self._app_data = data
802
803
804 def get_cert_store(self):
805 """
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500806 Get the certificate store for the context.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800807
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500808 :return: A X509Store object or None if it does not have one.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800809 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500810 store = _lib.SSL_CTX_get_cert_store(self._context)
811 if store == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500812 # TODO: This is untested.
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800813 return None
814
815 pystore = X509Store.__new__(X509Store)
816 pystore._store = store
817 return pystore
818
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800819
820 def set_options(self, options):
821 """
822 Add options. Options set before are not cleared!
823
824 :param options: The options to add.
825 :return: The new option bitmask.
826 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500827 if not isinstance(options, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800828 raise TypeError("options must be an integer")
829
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500830 return _lib.SSL_CTX_set_options(self._context, options)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800831
832
833 def set_mode(self, mode):
834 """
835 Add modes via bitmask. Modes set before are not cleared!
836
837 :param mode: The mode to add.
838 :return: The new mode bitmask.
839 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500840 if not isinstance(mode, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800841 raise TypeError("mode must be an integer")
842
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500843 return _lib.SSL_CTX_set_mode(self._context, mode)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800844
845
846 def set_tlsext_servername_callback(self, callback):
847 """
848 Specify a callback function to be called when clients specify a server name.
849
850 :param callback: The callback function. It will be invoked with one
851 argument, the Connection instance.
852 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800853 @wraps(callback)
854 def wrapper(ssl, alert, arg):
855 callback(Connection._reverse_mapping[ssl])
856 return 0
857
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500858 self._tlsext_servername_callback = _ffi.callback(
859 "int (*)(const SSL *, int *, void *)", wrapper)
860 _lib.SSL_CTX_set_tlsext_servername_callback(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800861 self._context, self._tlsext_servername_callback)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800862
863ContextType = Context
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800864
865
866
867class Connection(object):
868 """
869 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800870 _reverse_mapping = WeakValueDictionary()
871
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800872 def __init__(self, context, socket=None):
873 """
874 Create a new Connection object, using the given OpenSSL.SSL.Context
875 instance and socket.
876
877 :param context: An SSL Context to use for this connection
878 :param socket: The socket to use for transport layer
879 """
880 if not isinstance(context, Context):
881 raise TypeError("context must be a Context instance")
882
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500883 ssl = _lib.SSL_new(context._context)
884 self._ssl = _ffi.gc(ssl, _lib.SSL_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800885 self._context = context
886
887 self._reverse_mapping[self._ssl] = self
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800888
889 if socket is None:
890 self._socket = None
Jean-Paul Calderone73b15c22013-03-05 18:30:39 -0800891 # Don't set up any gc for these, SSL_free will take care of them.
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500892 self._into_ssl = _lib.BIO_new(_lib.BIO_s_mem())
893 self._from_ssl = _lib.BIO_new(_lib.BIO_s_mem())
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800894
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500895 if self._into_ssl == _ffi.NULL or self._from_ssl == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500896 # TODO: This is untested.
897 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800898
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500899 _lib.SSL_set_bio(self._ssl, self._into_ssl, self._from_ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800900 else:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800901 self._into_ssl = None
902 self._from_ssl = None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800903 self._socket = socket
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500904 set_result = _lib.SSL_set_fd(self._ssl, _asFileDescriptor(self._socket))
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800905 if not set_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500906 # TODO: This is untested.
907 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800908
909
910 def __getattr__(self, name):
911 """
912 Look up attributes on the wrapped socket object if they are not found on
913 the Connection object.
914 """
915 return getattr(self._socket, name)
916
917
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800918 def _raise_ssl_error(self, ssl, result):
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800919 if self._context._verify_helper is not None:
920 self._context._verify_helper.raise_if_problem()
921
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500922 error = _lib.SSL_get_error(ssl, result)
923 if error == _lib.SSL_ERROR_WANT_READ:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800924 raise WantReadError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500925 elif error == _lib.SSL_ERROR_WANT_WRITE:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -0700926 raise WantWriteError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500927 elif error == _lib.SSL_ERROR_ZERO_RETURN:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800928 raise ZeroReturnError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500929 elif error == _lib.SSL_ERROR_WANT_X509_LOOKUP:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500930 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -0700931 raise WantX509LookupError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500932 elif error == _lib.SSL_ERROR_SYSCALL:
933 if _lib.ERR_peek_error() == 0:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800934 if result < 0:
Konstantinos Koukopoulos541150d2014-01-31 01:00:19 +0200935 if platform == "win32":
936 errno = _ffi.getwinerror()[0]
937 else:
938 errno = _ffi.errno
939 raise SysCallError(errno, errorcode[errno])
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800940 else:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -0700941 raise SysCallError(-1, "Unexpected EOF")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800942 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500943 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500944 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500945 elif error == _lib.SSL_ERROR_NONE:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -0700946 pass
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800947 else:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500948 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800949
950
951 def get_context(self):
952 """
953 Get session context
954 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800955 return self._context
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800956
957
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800958 def set_context(self, context):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800959 """
960 Switch this connection to a new session context
961
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800962 :param context: A :py:class:`Context` instance giving the new session
963 context to use.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800964 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800965 if not isinstance(context, Context):
966 raise TypeError("context must be a Context instance")
967
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500968 _lib.SSL_set_SSL_CTX(self._ssl, context._context)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800969 self._context = context
970
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800971
972 def get_servername(self):
973 """
974 Retrieve the servername extension value if provided in the client hello
975 message, or None if there wasn't one.
976
977 :return: A byte string giving the server name or :py:data:`None`.
978 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500979 name = _lib.SSL_get_servername(self._ssl, _lib.TLSEXT_NAMETYPE_host_name)
980 if name == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800981 return None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800982
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500983 return _ffi.string(name)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800984
985
986 def set_tlsext_host_name(self, name):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800987 """
988 Set the value of the servername extension to send in the client hello.
989
990 :param name: A byte string giving the name.
991 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800992 if not isinstance(name, bytes):
993 raise TypeError("name must be a byte string")
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -0500994 elif b"\0" in name:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800995 raise TypeError("name must not contain NUL byte")
996
997 # XXX I guess this can fail sometimes?
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500998 _lib.SSL_set_tlsext_host_name(self._ssl, name)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800999
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001000
1001 def pending(self):
1002 """
1003 Get the number of bytes that can be safely read from the connection
1004
1005 :return: The number of bytes available in the receive buffer.
1006 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001007 return _lib.SSL_pending(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001008
1009
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001010 def send(self, buf, flags=0):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001011 """
1012 Send data on the connection. NOTE: If you get one of the WantRead,
1013 WantWrite or WantX509Lookup exceptions on this, you have to call the
1014 method again with the SAME buffer.
1015
1016 :param buf: The string to send
1017 :param flags: (optional) Included for compatibility with the socket
1018 API, the value is ignored
1019 :return: The number of bytes written
1020 """
Jean-Paul Calderone8fb53182013-12-30 08:35:49 -05001021 if isinstance(buf, _memoryview):
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -08001022 buf = buf.tobytes()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001023 if not isinstance(buf, bytes):
1024 raise TypeError("data must be a byte string")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001025
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001026 result = _lib.SSL_write(self._ssl, buf, len(buf))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001027 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001028 return result
1029 write = send
1030
1031
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001032 def sendall(self, buf, flags=0):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001033 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001034 Send "all" data on the connection. This calls send() repeatedly until
1035 all data is sent. If an error occurs, it's impossible to tell how much
1036 data has been sent.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001037
1038 :param buf: The string to send
1039 :param flags: (optional) Included for compatibility with the socket
1040 API, the value is ignored
1041 :return: The number of bytes written
1042 """
Jean-Paul Calderone8fb53182013-12-30 08:35:49 -05001043 if isinstance(buf, _memoryview):
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -08001044 buf = buf.tobytes()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001045 if not isinstance(buf, bytes):
1046 raise TypeError("buf must be a byte string")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001047
1048 left_to_send = len(buf)
1049 total_sent = 0
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001050 data = _ffi.new("char[]", buf)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001051
1052 while left_to_send:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001053 result = _lib.SSL_write(self._ssl, data + total_sent, left_to_send)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001054 self._raise_ssl_error(self._ssl, result)
1055 total_sent += result
1056 left_to_send -= result
1057
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001058
1059 def recv(self, bufsiz, flags=None):
1060 """
1061 Receive data on the connection. NOTE: If you get one of the WantRead,
1062 WantWrite or WantX509Lookup exceptions on this, you have to call the
1063 method again with the SAME buffer.
1064
1065 :param bufsiz: The maximum number of bytes to read
1066 :param flags: (optional) Included for compatibility with the socket
1067 API, the value is ignored
1068 :return: The string read from the Connection
1069 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001070 buf = _ffi.new("char[]", bufsiz)
1071 result = _lib.SSL_read(self._ssl, buf, bufsiz)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001072 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001073 return _ffi.buffer(buf, result)[:]
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001074 read = recv
1075
1076
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001077 def _handle_bio_errors(self, bio, result):
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001078 if _lib.BIO_should_retry(bio):
1079 if _lib.BIO_should_read(bio):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001080 raise WantReadError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001081 elif _lib.BIO_should_write(bio):
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001082 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001083 raise WantWriteError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001084 elif _lib.BIO_should_io_special(bio):
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001085 # TODO: This is untested. I think io_special means the socket
1086 # BIO has a not-yet connected socket.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001087 raise ValueError("BIO_should_io_special")
1088 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001089 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001090 raise ValueError("unknown bio failure")
1091 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001092 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001093 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001094
1095
1096 def bio_read(self, bufsiz):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001097 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001098 When using non-socket connections this function reads the "dirty" data
1099 that would have traveled away on the network.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001100
1101 :param bufsiz: The maximum number of bytes to read
1102 :return: The string read.
1103 """
Jean-Paul Calderone97e041d2013-03-05 21:03:12 -08001104 if self._from_ssl is None:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001105 raise TypeError("Connection sock was not None")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001106
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -05001107 if not isinstance(bufsiz, integer_types):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001108 raise TypeError("bufsiz must be an integer")
1109
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001110 buf = _ffi.new("char[]", bufsiz)
1111 result = _lib.BIO_read(self._from_ssl, buf, bufsiz)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001112 if result <= 0:
1113 self._handle_bio_errors(self._from_ssl, result)
1114
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001115 return _ffi.buffer(buf, result)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001116
1117
1118 def bio_write(self, buf):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001119 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001120 When using non-socket connections this function sends "dirty" data that
1121 would have traveled in on the network.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001122
1123 :param buf: The string to put into the memory BIO.
1124 :return: The number of bytes written
1125 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001126 if self._into_ssl is None:
1127 raise TypeError("Connection sock was not None")
1128
1129 if not isinstance(buf, bytes):
1130 raise TypeError("buf must be a byte string")
1131
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001132 result = _lib.BIO_write(self._into_ssl, buf, len(buf))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001133 if result <= 0:
1134 self._handle_bio_errors(self._into_ssl, result)
1135 return result
1136
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001137
1138 def renegotiate(self):
1139 """
1140 Renegotiate the session
1141
1142 :return: True if the renegotiation can be started, false otherwise
1143 """
1144
1145 def do_handshake(self):
1146 """
1147 Perform an SSL handshake (usually called after renegotiate() or one of
1148 set_*_state()). This can raise the same exceptions as send and recv.
1149
1150 :return: None.
1151 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001152 result = _lib.SSL_do_handshake(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001153 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001154
1155
1156 def renegotiate_pending(self):
1157 """
1158 Check if there's a renegotiation in progress, it will return false once
1159 a renegotiation is finished.
1160
1161 :return: Whether there's a renegotiation in progress
1162 """
1163
1164 def total_renegotiations(self):
1165 """
1166 Find out the total number of renegotiations.
1167
1168 :return: The number of renegotiations.
1169 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001170 return _lib.SSL_total_renegotiations(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001171
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001172
1173 def connect(self, addr):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001174 """
1175 Connect to remote host and set up client-side SSL
1176
1177 :param addr: A remote address
1178 :return: What the socket's connect method returns
1179 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001180 _lib.SSL_set_connect_state(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001181 return self._socket.connect(addr)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001182
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001183
1184 def connect_ex(self, addr):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001185 """
1186 Connect to remote host and set up client-side SSL. Note that if the socket's
1187 connect_ex method doesn't return 0, SSL won't be initialized.
1188
1189 :param addr: A remove address
1190 :return: What the socket's connect_ex method returns
1191 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001192 connect_ex = self._socket.connect_ex
1193 self.set_connect_state()
1194 return connect_ex(addr)
1195
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001196
1197 def accept(self):
1198 """
1199 Accept incoming connection and set up SSL on it
1200
1201 :return: A (conn,addr) pair where conn is a Connection and addr is an
1202 address
1203 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001204 client, addr = self._socket.accept()
1205 conn = Connection(self._context, client)
1206 conn.set_accept_state()
1207 return (conn, addr)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001208
1209
1210 def bio_shutdown(self):
1211 """
1212 When using non-socket connections this function signals end of
1213 data on the input for this connection.
1214
1215 :return: None
1216 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001217 if self._from_ssl is None:
1218 raise TypeError("Connection sock was not None")
1219
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001220 _lib.BIO_set_mem_eof_return(self._into_ssl, 0)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001221
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001222
1223 def shutdown(self):
1224 """
1225 Send closure alert
1226
1227 :return: True if the shutdown completed successfully (i.e. both sides
1228 have sent closure alerts), false otherwise (i.e. you have to
1229 wait for a ZeroReturnError on a recv() method call
1230 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001231 result = _lib.SSL_shutdown(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001232 if result < 0:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001233 # TODO: This is untested.
1234 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001235 elif result > 0:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001236 return True
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001237 else:
1238 return False
1239
1240
1241 def get_cipher_list(self):
1242 """
1243 Get the session cipher list
1244
1245 :return: A list of cipher strings
1246 """
1247 ciphers = []
1248 for i in count():
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001249 result = _lib.SSL_get_cipher_list(self._ssl, i)
1250 if result == _ffi.NULL:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001251 break
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001252 ciphers.append(_native(_ffi.string(result)))
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001253 return ciphers
1254
1255
1256 def get_client_ca_list(self):
1257 """
1258 Get CAs whose certificates are suggested for client authentication.
1259
1260 :return: If this is a server connection, a list of X509Names representing
1261 the acceptable CAs as set by :py:meth:`OpenSSL.SSL.Context.set_client_ca_list` or
1262 :py:meth:`OpenSSL.SSL.Context.add_client_ca`. If this is a client connection,
1263 the list of such X509Names sent by the server, or an empty list if that
1264 has not yet happened.
1265 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001266 ca_names = _lib.SSL_get_client_CA_list(self._ssl)
1267 if ca_names == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001268 # TODO: This is untested.
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001269 return []
1270
1271 result = []
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001272 for i in range(_lib.sk_X509_NAME_num(ca_names)):
1273 name = _lib.sk_X509_NAME_value(ca_names, i)
1274 copy = _lib.X509_NAME_dup(name)
1275 if copy == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001276 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001277 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001278
1279 pyname = X509Name.__new__(X509Name)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001280 pyname._name = _ffi.gc(copy, _lib.X509_NAME_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001281 result.append(pyname)
1282 return result
1283
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001284
1285 def makefile(self):
1286 """
1287 The makefile() method is not implemented, since there is no dup semantics
1288 for SSL connections
1289
1290 :raise NotImplementedError
1291 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001292 raise NotImplementedError("Cannot make file object of OpenSSL.SSL.Connection")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001293
1294
1295 def get_app_data(self):
1296 """
1297 Get application data
1298
1299 :return: The application data
1300 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001301 return self._app_data
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001302
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001303
1304 def set_app_data(self, data):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001305 """
1306 Set application data
1307
1308 :param data - The application data
1309 :return: None
1310 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001311 self._app_data = data
1312
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001313
1314 def get_shutdown(self):
1315 """
1316 Get shutdown state
1317
1318 :return: The shutdown state, a bitvector of SENT_SHUTDOWN, RECEIVED_SHUTDOWN.
1319 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001320 return _lib.SSL_get_shutdown(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001321
1322
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001323 def set_shutdown(self, state):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001324 """
1325 Set shutdown state
1326
1327 :param state - bitvector of SENT_SHUTDOWN, RECEIVED_SHUTDOWN.
1328 :return: None
1329 """
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -05001330 if not isinstance(state, integer_types):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001331 raise TypeError("state must be an integer")
1332
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001333 _lib.SSL_set_shutdown(self._ssl, state)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001334
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001335
1336 def state_string(self):
1337 """
1338 Get a verbose state description
1339
1340 :return: A string representing the state
1341 """
1342
1343 def server_random(self):
1344 """
1345 Get a copy of the server hello nonce.
1346
1347 :return: A string representing the state
1348 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001349 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001350 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001351 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001352 self._ssl.s3.server_random,
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001353 _lib.SSL3_RANDOM_SIZE)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001354
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001355
1356 def client_random(self):
1357 """
1358 Get a copy of the client hello nonce.
1359
1360 :return: A string representing the state
1361 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001362 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001363 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001364 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001365 self._ssl.s3.client_random,
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001366 _lib.SSL3_RANDOM_SIZE)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001367
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001368
1369 def master_key(self):
1370 """
1371 Get a copy of the master key.
1372
1373 :return: A string representing the state
1374 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001375 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001376 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001377 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001378 self._ssl.session.master_key,
1379 self._ssl.session.master_key_length)[:]
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001380
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001381
1382 def sock_shutdown(self, *args, **kwargs):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001383 """
1384 See shutdown(2)
1385
1386 :return: What the socket's shutdown() method returns
1387 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001388 return self._socket.shutdown(*args, **kwargs)
1389
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001390
1391 def get_peer_certificate(self):
1392 """
1393 Retrieve the other side's certificate (if any)
1394
1395 :return: The peer's certificate
1396 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001397 cert = _lib.SSL_get_peer_certificate(self._ssl)
1398 if cert != _ffi.NULL:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001399 pycert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001400 pycert._x509 = _ffi.gc(cert, _lib.X509_free)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001401 return pycert
1402 return None
1403
1404
1405 def get_peer_cert_chain(self):
1406 """
1407 Retrieve the other side's certificate (if any)
1408
1409 :return: A list of X509 instances giving the peer's certificate chain,
1410 or None if it does not have one.
1411 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001412 cert_stack = _lib.SSL_get_peer_cert_chain(self._ssl)
1413 if cert_stack == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001414 return None
1415
1416 result = []
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001417 for i in range(_lib.sk_X509_num(cert_stack)):
Jean-Paul Calderone73b15c22013-03-05 18:30:39 -08001418 # TODO could incref instead of dup here
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001419 cert = _lib.X509_dup(_lib.sk_X509_value(cert_stack, i))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001420 pycert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001421 pycert._x509 = _ffi.gc(cert, _lib.X509_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001422 result.append(pycert)
1423 return result
1424
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001425
1426 def want_read(self):
1427 """
1428 Checks if more data has to be read from the transport layer to complete an
1429 operation.
1430
1431 :return: True iff more data has to be read
1432 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001433 return _lib.SSL_want_read(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001434
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001435
1436 def want_write(self):
1437 """
1438 Checks if there is data to write to the transport layer to complete an
1439 operation.
1440
1441 :return: True iff there is data to write
1442 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001443 return _lib.SSL_want_write(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001444
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001445
1446 def set_accept_state(self):
1447 """
1448 Set the connection to work in server mode. The handshake will be handled
1449 automatically by read/write.
1450
1451 :return: None
1452 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001453 _lib.SSL_set_accept_state(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001454
1455
1456 def set_connect_state(self):
1457 """
1458 Set the connection to work in client mode. The handshake will be handled
1459 automatically by read/write.
1460
1461 :return: None
1462 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001463 _lib.SSL_set_connect_state(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001464
1465
1466 def get_session(self):
1467 """
1468 Returns the Session currently used.
1469
1470 @return: An instance of :py:class:`OpenSSL.SSL.Session` or :py:obj:`None` if
1471 no session exists.
1472 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001473 session = _lib.SSL_get1_session(self._ssl)
1474 if session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001475 return None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001476
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001477 pysession = Session.__new__(Session)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001478 pysession._session = _ffi.gc(session, _lib.SSL_SESSION_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001479 return pysession
1480
1481
1482 def set_session(self, session):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001483 """
1484 Set the session to be used when the TLS/SSL connection is established.
1485
1486 :param session: A Session instance representing the session to use.
1487 :returns: None
1488 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001489 if not isinstance(session, Session):
1490 raise TypeError("session must be a Session instance")
1491
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001492 result = _lib.SSL_set_session(self._ssl, session._session)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001493 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001494 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001495
Jean-Paul Calderonedbd76272014-03-29 18:09:40 -04001496
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001497 def _get_finished_message(self, function):
1498 """
1499 Helper to implement :py:meth:`get_finished` and
1500 :py:meth:`get_peer_finished`.
1501
1502 :param function: Either :py:data:`SSL_get_finished`: or
1503 :py:data:`SSL_get_peer_finished`.
1504
1505 :return: :py:data:`None` if the desired message has not yet been
1506 received, otherwise the contents of the message.
1507 :rtype: :py:class:`bytes` or :py:class:`NoneType`
1508 """
Jean-Paul Calderone01af9042014-03-30 11:40:42 -04001509 # The OpenSSL documentation says nothing about what might happen if the
1510 # count argument given is zero. Specifically, it doesn't say whether
1511 # the output buffer may be NULL in that case or not. Inspection of the
1512 # implementation reveals that it calls memcpy() unconditionally.
1513 # Section 7.1.4, paragraph 1 of the C standard suggests that
1514 # memcpy(NULL, source, 0) is not guaranteed to produce defined (let
1515 # alone desirable) behavior (though it probably does on just about
1516 # every implementation...)
1517 #
1518 # Allocate a tiny buffer to pass in (instead of just passing NULL as
1519 # one might expect) for the initial call so as to be safe against this
1520 # potentially undefined behavior.
1521 empty = _ffi.new("char[]", 0)
1522 size = function(self._ssl, empty, 0)
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001523 if size == 0:
1524 # No Finished message so far.
1525 return None
1526
1527 buf = _ffi.new("char[]", size)
1528 function(self._ssl, buf, size)
1529 return _ffi.buffer(buf, size)[:]
1530
1531
Fedor Brunner5747b932014-03-05 14:22:34 +01001532 def get_finished(self):
1533 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001534 Obtain the latest `handshake finished` message sent to the peer.
Fedor Brunner5747b932014-03-05 14:22:34 +01001535
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001536 :return: The contents of the message or :py:obj:`None` if the TLS
1537 handshake has not yet completed.
1538 :rtype: :py:class:`bytes` or :py:class:`NoneType`
Fedor Brunner5747b932014-03-05 14:22:34 +01001539 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001540 return self._get_finished_message(_lib.SSL_get_finished)
1541
Fedor Brunner5747b932014-03-05 14:22:34 +01001542
1543 def get_peer_finished(self):
1544 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001545 Obtain the latest `handshake finished` message received from the peer.
Fedor Brunner5747b932014-03-05 14:22:34 +01001546
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001547 :return: The contents of the message or :py:obj:`None` if the TLS
1548 handshake has not yet completed.
1549 :rtype: :py:class:`bytes` or :py:class:`NoneType`
Fedor Brunner5747b932014-03-05 14:22:34 +01001550 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001551 return self._get_finished_message(_lib.SSL_get_peer_finished)
Fedor Brunner5747b932014-03-05 14:22:34 +01001552
Jean-Paul Calderone7c556ef2014-03-30 10:45:00 -04001553
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001554 def get_cipher_name(self):
1555 """
1556 Obtain the name of the currently used cipher.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001557
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001558 :returns: The name of the currently used cipher or :py:obj:`None`
1559 if no connection has been established.
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001560 :rtype: :py:class:`unicode` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001561 """
1562 cipher = _lib.SSL_get_current_cipher(self._ssl)
1563 if cipher == _ffi.NULL:
1564 return None
1565 else:
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001566 name = _ffi.string(_lib.SSL_CIPHER_get_name(cipher))
1567 return name.decode("utf-8")
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001568
Jean-Paul Calderonedbd76272014-03-29 18:09:40 -04001569
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001570 def get_cipher_bits(self):
1571 """
1572 Obtain the number of secret bits of the currently used cipher.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001573
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001574 :returns: The number of secret bits of the currently used cipher
1575 or :py:obj:`None` if no connection has been established.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001576 :rtype: :py:class:`int` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001577 """
1578 cipher = _lib.SSL_get_current_cipher(self._ssl)
1579 if cipher == _ffi.NULL:
1580 return None
1581 else:
1582 return _lib.SSL_CIPHER_get_bits(cipher, _ffi.NULL)
1583
Jean-Paul Calderonedbd76272014-03-29 18:09:40 -04001584
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001585 def get_cipher_version(self):
1586 """
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001587 Obtain the protocol version of the currently used cipher.
1588
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001589 :returns: The protocol name of the currently used cipher
1590 or :py:obj:`None` if no connection has been established.
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001591 :rtype: :py:class:`unicode` 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:
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001597 version =_ffi.string(_lib.SSL_CIPHER_get_version(cipher))
1598 return version.decode("utf-8")
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001599
1600
1601
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001602ConnectionType = Connection
Jean-Paul Calderone11ed8e82014-01-18 10:21:50 -05001603
Jean-Paul Calderonefab157b2014-01-18 11:21:38 -05001604# This is similar to the initialization calls at the end of OpenSSL/crypto.py
1605# but is exercised mostly by the Context initializer.
Jean-Paul Calderone11ed8e82014-01-18 10:21:50 -05001606_lib.SSL_library_init()