blob: e754a7e5dfc3a856dd14102eb80c187518a2551f [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
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +020027try:
28 _buffer = buffer
29except NameError:
30 class _buffer(object):
31 pass
32
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050033OPENSSL_VERSION_NUMBER = _lib.OPENSSL_VERSION_NUMBER
34SSLEAY_VERSION = _lib.SSLEAY_VERSION
35SSLEAY_CFLAGS = _lib.SSLEAY_CFLAGS
36SSLEAY_PLATFORM = _lib.SSLEAY_PLATFORM
37SSLEAY_DIR = _lib.SSLEAY_DIR
38SSLEAY_BUILT_ON = _lib.SSLEAY_BUILT_ON
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080039
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050040SENT_SHUTDOWN = _lib.SSL_SENT_SHUTDOWN
41RECEIVED_SHUTDOWN = _lib.SSL_RECEIVED_SHUTDOWN
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080042
43SSLv2_METHOD = 1
44SSLv3_METHOD = 2
45SSLv23_METHOD = 3
46TLSv1_METHOD = 4
Jean-Paul Calderone56bff942013-11-03 11:30:43 -050047TLSv1_1_METHOD = 5
48TLSv1_2_METHOD = 6
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080049
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050050OP_NO_SSLv2 = _lib.SSL_OP_NO_SSLv2
51OP_NO_SSLv3 = _lib.SSL_OP_NO_SSLv3
52OP_NO_TLSv1 = _lib.SSL_OP_NO_TLSv1
Jean-Paul Calderonebe2bb422013-12-29 07:34:08 -050053
54OP_NO_TLSv1_1 = getattr(_lib, "SSL_OP_NO_TLSv1_1", 0)
55OP_NO_TLSv1_2 = getattr(_lib, "SSL_OP_NO_TLSv1_2", 0)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -080056
Jean-Paul Calderone0d7e8a12014-01-08 16:54:13 -050057try:
58 MODE_RELEASE_BUFFERS = _lib.SSL_MODE_RELEASE_BUFFERS
59except AttributeError:
60 pass
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080061
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050062OP_SINGLE_DH_USE = _lib.SSL_OP_SINGLE_DH_USE
63OP_EPHEMERAL_RSA = _lib.SSL_OP_EPHEMERAL_RSA
64OP_MICROSOFT_SESS_ID_BUG = _lib.SSL_OP_MICROSOFT_SESS_ID_BUG
65OP_NETSCAPE_CHALLENGE_BUG = _lib.SSL_OP_NETSCAPE_CHALLENGE_BUG
66OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG = _lib.SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG
67OP_SSLREF2_REUSE_CERT_TYPE_BUG = _lib.SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG
68OP_MICROSOFT_BIG_SSLV3_BUFFER = _lib.SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER
Jean-Paul Calderone0d7e8a12014-01-08 16:54:13 -050069try:
70 OP_MSIE_SSLV2_RSA_PADDING = _lib.SSL_OP_MSIE_SSLV2_RSA_PADDING
71except AttributeError:
72 pass
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050073OP_SSLEAY_080_CLIENT_DH_BUG = _lib.SSL_OP_SSLEAY_080_CLIENT_DH_BUG
74OP_TLS_D5_BUG = _lib.SSL_OP_TLS_D5_BUG
75OP_TLS_BLOCK_PADDING_BUG = _lib.SSL_OP_TLS_BLOCK_PADDING_BUG
76OP_DONT_INSERT_EMPTY_FRAGMENTS = _lib.SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
77OP_CIPHER_SERVER_PREFERENCE = _lib.SSL_OP_CIPHER_SERVER_PREFERENCE
78OP_TLS_ROLLBACK_BUG = _lib.SSL_OP_TLS_ROLLBACK_BUG
79OP_PKCS1_CHECK_1 = _lib.SSL_OP_PKCS1_CHECK_1
80OP_PKCS1_CHECK_2 = _lib.SSL_OP_PKCS1_CHECK_2
81OP_NETSCAPE_CA_DN_BUG = _lib.SSL_OP_NETSCAPE_CA_DN_BUG
82OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG= _lib.SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG
Jean-Paul Calderonec1780342014-01-08 16:59:03 -050083try:
84 OP_NO_COMPRESSION = _lib.SSL_OP_NO_COMPRESSION
85except AttributeError:
86 pass
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -080087
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050088OP_NO_QUERY_MTU = _lib.SSL_OP_NO_QUERY_MTU
89OP_COOKIE_EXCHANGE = _lib.SSL_OP_COOKIE_EXCHANGE
Arturo Filastò5f8c7a82014-03-09 20:01:25 +010090try:
91 OP_NO_TICKET = _lib.SSL_OP_NO_TICKET
92except AttributeError:
93 pass
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -080094
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050095OP_ALL = _lib.SSL_OP_ALL
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080096
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050097VERIFY_PEER = _lib.SSL_VERIFY_PEER
98VERIFY_FAIL_IF_NO_PEER_CERT = _lib.SSL_VERIFY_FAIL_IF_NO_PEER_CERT
99VERIFY_CLIENT_ONCE = _lib.SSL_VERIFY_CLIENT_ONCE
100VERIFY_NONE = _lib.SSL_VERIFY_NONE
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -0800101
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500102SESS_CACHE_OFF = _lib.SSL_SESS_CACHE_OFF
103SESS_CACHE_CLIENT = _lib.SSL_SESS_CACHE_CLIENT
104SESS_CACHE_SERVER = _lib.SSL_SESS_CACHE_SERVER
105SESS_CACHE_BOTH = _lib.SSL_SESS_CACHE_BOTH
106SESS_CACHE_NO_AUTO_CLEAR = _lib.SSL_SESS_CACHE_NO_AUTO_CLEAR
107SESS_CACHE_NO_INTERNAL_LOOKUP = _lib.SSL_SESS_CACHE_NO_INTERNAL_LOOKUP
108SESS_CACHE_NO_INTERNAL_STORE = _lib.SSL_SESS_CACHE_NO_INTERNAL_STORE
109SESS_CACHE_NO_INTERNAL = _lib.SSL_SESS_CACHE_NO_INTERNAL
Jean-Paul Calderoned39a3f62013-03-04 12:23:51 -0800110
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500111SSL_ST_CONNECT = _lib.SSL_ST_CONNECT
112SSL_ST_ACCEPT = _lib.SSL_ST_ACCEPT
113SSL_ST_MASK = _lib.SSL_ST_MASK
114SSL_ST_INIT = _lib.SSL_ST_INIT
115SSL_ST_BEFORE = _lib.SSL_ST_BEFORE
116SSL_ST_OK = _lib.SSL_ST_OK
117SSL_ST_RENEGOTIATE = _lib.SSL_ST_RENEGOTIATE
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800118
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500119SSL_CB_LOOP = _lib.SSL_CB_LOOP
120SSL_CB_EXIT = _lib.SSL_CB_EXIT
121SSL_CB_READ = _lib.SSL_CB_READ
122SSL_CB_WRITE = _lib.SSL_CB_WRITE
123SSL_CB_ALERT = _lib.SSL_CB_ALERT
124SSL_CB_READ_ALERT = _lib.SSL_CB_READ_ALERT
125SSL_CB_WRITE_ALERT = _lib.SSL_CB_WRITE_ALERT
126SSL_CB_ACCEPT_LOOP = _lib.SSL_CB_ACCEPT_LOOP
127SSL_CB_ACCEPT_EXIT = _lib.SSL_CB_ACCEPT_EXIT
128SSL_CB_CONNECT_LOOP = _lib.SSL_CB_CONNECT_LOOP
129SSL_CB_CONNECT_EXIT = _lib.SSL_CB_CONNECT_EXIT
130SSL_CB_HANDSHAKE_START = _lib.SSL_CB_HANDSHAKE_START
131SSL_CB_HANDSHAKE_DONE = _lib.SSL_CB_HANDSHAKE_DONE
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800132
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500133class Error(Exception):
Jean-Paul Calderone511cde02013-12-29 10:31:13 -0500134 """
135 An error occurred in an `OpenSSL.SSL` API.
136 """
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500137
138
139
140_raise_current_error = partial(_exception_from_error_queue, Error)
141
142
143class WantReadError(Error):
144 pass
145
146
147
148class WantWriteError(Error):
149 pass
150
151
152
153class WantX509LookupError(Error):
154 pass
155
156
157
158class ZeroReturnError(Error):
159 pass
160
161
162
163class SysCallError(Error):
164 pass
165
166
167
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800168class _VerifyHelper(object):
Jean-Paul Calderone6a8cd112014-04-02 21:09:08 -0400169 def __init__(self, callback):
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800170 self._problems = []
171
172 @wraps(callback)
173 def wrapper(ok, store_ctx):
174 cert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500175 cert._x509 = _lib.X509_STORE_CTX_get_current_cert(store_ctx)
176 error_number = _lib.X509_STORE_CTX_get_error(store_ctx)
177 error_depth = _lib.X509_STORE_CTX_get_error_depth(store_ctx)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800178
Jean-Paul Calderone6a8cd112014-04-02 21:09:08 -0400179 index = _lib.SSL_get_ex_data_X509_STORE_CTX_idx()
180 ssl = _lib.X509_STORE_CTX_get_ex_data(store_ctx, index)
181 connection = Connection._reverse_mapping[ssl]
182
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800183 try:
184 result = callback(connection, cert, error_number, error_depth, ok)
185 except Exception as e:
186 self._problems.append(e)
187 return 0
188 else:
189 if result:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500190 _lib.X509_STORE_CTX_set_error(store_ctx, _lib.X509_V_OK)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800191 return 1
192 else:
193 return 0
194
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500195 self.callback = _ffi.callback(
196 "int (*)(int, X509_STORE_CTX *)", wrapper)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800197
198
199 def raise_if_problem(self):
200 if self._problems:
201 try:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500202 _raise_current_error()
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800203 except Error:
204 pass
205 raise self._problems.pop(0)
206
207
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800208
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800209def _asFileDescriptor(obj):
210 fd = None
Konstantinos Koukopoulosc8b13ea2014-01-28 00:21:50 -0800211 if not isinstance(obj, integer_types):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800212 meth = getattr(obj, "fileno", None)
213 if meth is not None:
214 obj = meth()
215
Konstantinos Koukopoulosc8b13ea2014-01-28 00:21:50 -0800216 if isinstance(obj, integer_types):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800217 fd = obj
218
Konstantinos Koukopoulosc8b13ea2014-01-28 00:21:50 -0800219 if not isinstance(fd, integer_types):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800220 raise TypeError("argument must be an int, or have a fileno() method.")
221 elif fd < 0:
222 raise ValueError(
223 "file descriptor cannot be a negative integer (%i)" % (fd,))
224
225 return fd
226
227
228
Jean-Paul Calderoned39a3f62013-03-04 12:23:51 -0800229def SSLeay_version(type):
230 """
231 Return a string describing the version of OpenSSL in use.
232
233 :param type: One of the SSLEAY_ constants defined in this module.
234 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500235 return _ffi.string(_lib.SSLeay_version(type))
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800236
237
238
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800239class Session(object):
240 pass
241
242
243
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800244class Context(object):
245 """
246 :py:obj:`OpenSSL.SSL.Context` instances define the parameters for setting up
247 new SSL connections.
248 """
249 _methods = {
Andrew Dunhamec84a0a2014-02-24 12:41:37 -0800250 SSLv2_METHOD: "SSLv2_method",
Jean-Paul Calderonebe2bb422013-12-29 07:34:08 -0500251 SSLv3_METHOD: "SSLv3_method",
252 SSLv23_METHOD: "SSLv23_method",
253 TLSv1_METHOD: "TLSv1_method",
254 TLSv1_1_METHOD: "TLSv1_1_method",
255 TLSv1_2_METHOD: "TLSv1_2_method",
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800256 }
Jean-Paul Calderonebe2bb422013-12-29 07:34:08 -0500257 _methods = dict(
258 (identifier, getattr(_lib, name))
259 for (identifier, name) in _methods.items()
260 if getattr(_lib, name, None) is not None)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800261
Jean-Paul Calderone63157872013-03-20 16:43:38 -0700262
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800263 def __init__(self, method):
264 """
265 :param method: One of SSLv2_METHOD, SSLv3_METHOD, SSLv23_METHOD, or
266 TLSv1_METHOD.
267 """
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -0500268 if not isinstance(method, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800269 raise TypeError("method must be an integer")
270
271 try:
272 method_func = self._methods[method]
273 except KeyError:
274 raise ValueError("No such protocol")
275
276 method_obj = method_func()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500277 if method_obj == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500278 # TODO: This is untested.
279 _raise_current_error()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800280
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500281 context = _lib.SSL_CTX_new(method_obj)
282 if context == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500283 # TODO: This is untested.
284 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500285 context = _ffi.gc(context, _lib.SSL_CTX_free)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800286
287 self._context = context
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800288 self._passphrase_helper = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800289 self._passphrase_callback = None
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800290 self._passphrase_userdata = None
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800291 self._verify_helper = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800292 self._verify_callback = None
293 self._info_callback = None
294 self._tlsext_servername_callback = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800295 self._app_data = None
Cory Benfield84a121e2014-03-31 20:30:25 +0100296 self._npn_advertise_callback = None
297 self._npn_advertise_callback_args = None
298 self._npn_select_callback = None
299 self._npn_select_callback_args = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800300
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -0800301 # SSL_CTX_set_app_data(self->ctx, self);
302 # SSL_CTX_set_mode(self->ctx, SSL_MODE_ENABLE_PARTIAL_WRITE |
303 # SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
304 # SSL_MODE_AUTO_RETRY);
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500305 self.set_mode(_lib.SSL_MODE_ENABLE_PARTIAL_WRITE)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800306
307
308 def load_verify_locations(self, cafile, capath=None):
309 """
310 Let SSL know where we can find trusted certificates for the certificate
311 chain
312
313 :param cafile: In which file we can find the certificates
314 :param capath: In which directory we can find the certificates
315 :return: None
316 """
317 if cafile is None:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500318 cafile = _ffi.NULL
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800319 elif not isinstance(cafile, bytes):
320 raise TypeError("cafile must be None or a byte string")
321
322 if capath is None:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500323 capath = _ffi.NULL
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800324 elif not isinstance(capath, bytes):
325 raise TypeError("capath must be None or a byte string")
326
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500327 load_result = _lib.SSL_CTX_load_verify_locations(self._context, cafile, capath)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800328 if not load_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500329 _raise_current_error()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800330
331
332 def _wrap_callback(self, callback):
333 @wraps(callback)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800334 def wrapper(size, verify, userdata):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800335 return callback(size, verify, self._passphrase_userdata)
336 return _PassphraseHelper(
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800337 FILETYPE_PEM, wrapper, more_args=True, truncate=True)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800338
339
340 def set_passwd_cb(self, callback, userdata=None):
341 """
342 Set the passphrase callback
343
344 :param callback: The Python callback to use
345 :param userdata: (optional) A Python object which will be given as
346 argument to the callback
347 :return: None
348 """
349 if not callable(callback):
350 raise TypeError("callback must be callable")
351
352 self._passphrase_helper = self._wrap_callback(callback)
353 self._passphrase_callback = self._passphrase_helper.callback
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500354 _lib.SSL_CTX_set_default_passwd_cb(
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800355 self._context, self._passphrase_callback)
356 self._passphrase_userdata = userdata
357
358
359 def set_default_verify_paths(self):
360 """
361 Use the platform-specific CA certificate locations
362
363 :return: None
364 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500365 set_result = _lib.SSL_CTX_set_default_verify_paths(self._context)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800366 if not set_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500367 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500368 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800369
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800370
371 def use_certificate_chain_file(self, certfile):
372 """
373 Load a certificate chain from a file
374
375 :param certfile: The name of the certificate chain file
376 :return: None
377 """
Jean-Paul Calderoned8607982014-01-18 10:30:55 -0500378 if isinstance(certfile, _text_type):
379 # Perhaps sys.getfilesystemencoding() could be better?
380 certfile = certfile.encode("utf-8")
381
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800382 if not isinstance(certfile, bytes):
Jean-Paul Calderoned8607982014-01-18 10:30:55 -0500383 raise TypeError("certfile must be bytes or unicode")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800384
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500385 result = _lib.SSL_CTX_use_certificate_chain_file(self._context, certfile)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800386 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500387 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800388
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800389
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800390 def use_certificate_file(self, certfile, filetype=FILETYPE_PEM):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800391 """
392 Load a certificate from a file
393
394 :param certfile: The name of the certificate file
395 :param filetype: (optional) The encoding of the file, default is PEM
396 :return: None
397 """
Jean-Paul Calderone684baf52014-01-18 10:31:19 -0500398 if isinstance(certfile, _text_type):
399 # Perhaps sys.getfilesystemencoding() could be better?
400 certfile = certfile.encode("utf-8")
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800401 if not isinstance(certfile, bytes):
Jean-Paul Calderone684baf52014-01-18 10:31:19 -0500402 raise TypeError("certfile must be bytes or unicode")
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -0500403 if not isinstance(filetype, integer_types):
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800404 raise TypeError("filetype must be an integer")
405
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500406 use_result = _lib.SSL_CTX_use_certificate_file(self._context, certfile, filetype)
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800407 if not use_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500408 _raise_current_error()
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800409
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800410
411 def use_certificate(self, cert):
412 """
413 Load a certificate from a X509 object
414
415 :param cert: The X509 object
416 :return: None
417 """
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800418 if not isinstance(cert, X509):
419 raise TypeError("cert must be an X509 instance")
420
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500421 use_result = _lib.SSL_CTX_use_certificate(self._context, cert._x509)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800422 if not use_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500423 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800424
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800425
426 def add_extra_chain_cert(self, certobj):
427 """
428 Add certificate to chain
429
430 :param certobj: The X509 certificate object to add to the chain
431 :return: None
432 """
433 if not isinstance(certobj, X509):
434 raise TypeError("certobj must be an X509 instance")
435
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500436 copy = _lib.X509_dup(certobj._x509)
437 add_result = _lib.SSL_CTX_add_extra_chain_cert(self._context, copy)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800438 if not add_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500439 # TODO: This is untested.
440 _lib.X509_free(copy)
441 _raise_current_error()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800442
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800443
444 def _raise_passphrase_exception(self):
445 if self._passphrase_helper is None:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500446 _raise_current_error()
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800447 exception = self._passphrase_helper.raise_if_problem(Error)
448 if exception is not None:
449 raise exception
450
451
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800452 def use_privatekey_file(self, keyfile, filetype=_unspecified):
453 """
454 Load a private key from a file
455
456 :param keyfile: The name of the key file
457 :param filetype: (optional) The encoding of the file, default is PEM
458 :return: None
459 """
Jean-Paul Calderone87e525a2014-01-18 10:31:51 -0500460 if isinstance(keyfile, _text_type):
461 # Perhaps sys.getfilesystemencoding() could be better?
462 keyfile = keyfile.encode("utf-8")
463
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800464 if not isinstance(keyfile, bytes):
465 raise TypeError("keyfile must be a byte string")
466
467 if filetype is _unspecified:
468 filetype = FILETYPE_PEM
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -0500469 elif not isinstance(filetype, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800470 raise TypeError("filetype must be an integer")
471
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500472 use_result = _lib.SSL_CTX_use_PrivateKey_file(
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800473 self._context, keyfile, filetype)
474 if not use_result:
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800475 self._raise_passphrase_exception()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800476
477
478 def use_privatekey(self, pkey):
479 """
480 Load a private key from a PKey object
481
482 :param pkey: The PKey object
483 :return: None
484 """
485 if not isinstance(pkey, PKey):
486 raise TypeError("pkey must be a PKey instance")
487
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500488 use_result = _lib.SSL_CTX_use_PrivateKey(self._context, pkey._pkey)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800489 if not use_result:
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800490 self._raise_passphrase_exception()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800491
492
493 def check_privatekey(self):
494 """
495 Check that the private key and certificate match up
496
497 :return: None (raises an exception if something's wrong)
498 """
499
500 def load_client_ca(self, cafile):
501 """
502 Load the trusted certificates that will be sent to the client (basically
503 telling the client "These are the guys I trust"). Does not actually
504 imply any of the certificates are trusted; that must be configured
505 separately.
506
507 :param cafile: The name of the certificates file
508 :return: None
509 """
510
511 def set_session_id(self, buf):
512 """
513 Set the session identifier. This is needed if you want to do session
514 resumption.
515
516 :param buf: A Python object that can be safely converted to a string
517 :returns: None
518 """
519
520 def set_session_cache_mode(self, mode):
521 """
522 Enable/disable session caching and specify the mode used.
523
524 :param mode: One or more of the SESS_CACHE_* flags (combine using
525 bitwise or)
526 :returns: The previously set caching mode.
527 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500528 if not isinstance(mode, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800529 raise TypeError("mode must be an integer")
530
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500531 return _lib.SSL_CTX_set_session_cache_mode(self._context, mode)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800532
533
534 def get_session_cache_mode(self):
535 """
536 :returns: The currently used cache mode.
537 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500538 return _lib.SSL_CTX_get_session_cache_mode(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800539
540
541 def set_verify(self, mode, callback):
542 """
543 Set the verify mode and verify callback
544
545 :param mode: The verify mode, this is either VERIFY_NONE or
546 VERIFY_PEER combined with possible other flags
547 :param callback: The Python callback to use
548 :return: None
549
550 See SSL_CTX_set_verify(3SSL) for further details.
551 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500552 if not isinstance(mode, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800553 raise TypeError("mode must be an integer")
554
555 if not callable(callback):
556 raise TypeError("callback must be callable")
557
Jean-Paul Calderone6a8cd112014-04-02 21:09:08 -0400558 self._verify_helper = _VerifyHelper(callback)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800559 self._verify_callback = self._verify_helper.callback
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500560 _lib.SSL_CTX_set_verify(self._context, mode, self._verify_callback)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800561
562
563 def set_verify_depth(self, depth):
564 """
565 Set the verify depth
566
567 :param depth: An integer specifying the verify depth
568 :return: None
569 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500570 if not isinstance(depth, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800571 raise TypeError("depth must be an integer")
572
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500573 _lib.SSL_CTX_set_verify_depth(self._context, depth)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800574
575
576 def get_verify_mode(self):
577 """
578 Get the verify mode
579
580 :return: The verify mode
581 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500582 return _lib.SSL_CTX_get_verify_mode(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800583
584
585 def get_verify_depth(self):
586 """
587 Get the verify depth
588
589 :return: The verify depth
590 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500591 return _lib.SSL_CTX_get_verify_depth(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800592
593
594 def load_tmp_dh(self, dhfile):
595 """
596 Load parameters for Ephemeral Diffie-Hellman
597
598 :param dhfile: The file to load EDH parameters from
599 :return: None
600 """
601 if not isinstance(dhfile, bytes):
602 raise TypeError("dhfile must be a byte string")
603
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -0500604 bio = _lib.BIO_new_file(dhfile, b"r")
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500605 if bio == _ffi.NULL:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500606 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500607 bio = _ffi.gc(bio, _lib.BIO_free)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800608
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500609 dh = _lib.PEM_read_bio_DHparams(bio, _ffi.NULL, _ffi.NULL, _ffi.NULL)
610 dh = _ffi.gc(dh, _lib.DH_free)
611 _lib.SSL_CTX_set_tmp_dh(self._context, dh)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800612
613
Jean-Paul Calderone3e4e3352014-04-19 09:28:28 -0400614 def set_tmp_ecdh(self, curve):
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600615 """
Andy Lutomirski76a61332014-03-12 15:02:56 -0700616 Select a curve to use for ECDHE key exchange.
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600617
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -0400618 :param curve: A curve object to use as returned by either
619 :py:meth:`OpenSSL.crypto.get_elliptic_curve` or
620 :py:meth:`OpenSSL.crypto.get_elliptic_curves`.
Andy Lutomirskif05a2732014-03-13 17:22:25 -0700621
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600622 :return: None
623 """
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -0400624 _lib.SSL_CTX_set_tmp_ecdh(self._context, curve._to_EC_KEY())
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600625
626
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800627 def set_cipher_list(self, cipher_list):
628 """
629 Change the cipher list
630
631 :param cipher_list: A cipher list, see ciphers(1)
632 :return: None
633 """
Jean-Paul Calderone63eab692014-01-18 10:19:56 -0500634 if isinstance(cipher_list, _text_type):
635 cipher_list = cipher_list.encode("ascii")
636
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800637 if not isinstance(cipher_list, bytes):
Jean-Paul Calderone63eab692014-01-18 10:19:56 -0500638 raise TypeError("cipher_list must be bytes or unicode")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800639
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500640 result = _lib.SSL_CTX_set_cipher_list(self._context, cipher_list)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800641 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500642 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800643
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800644
645 def set_client_ca_list(self, certificate_authorities):
646 """
647 Set the list of preferred client certificate signers for this server context.
648
649 This list of certificate authorities will be sent to the client when the
650 server requests a client certificate.
651
652 :param certificate_authorities: a sequence of X509Names.
653 :return: None
654 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500655 name_stack = _lib.sk_X509_NAME_new_null()
656 if name_stack == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500657 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500658 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800659
660 try:
661 for ca_name in certificate_authorities:
662 if not isinstance(ca_name, X509Name):
663 raise TypeError(
664 "client CAs must be X509Name objects, not %s objects" % (
665 type(ca_name).__name__,))
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500666 copy = _lib.X509_NAME_dup(ca_name._name)
667 if copy == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500668 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500669 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500670 push_result = _lib.sk_X509_NAME_push(name_stack, copy)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800671 if not push_result:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500672 _lib.X509_NAME_free(copy)
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500673 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800674 except:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500675 _lib.sk_X509_NAME_free(name_stack)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800676 raise
677
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500678 _lib.SSL_CTX_set_client_CA_list(self._context, name_stack)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800679
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800680
681 def add_client_ca(self, certificate_authority):
682 """
683 Add the CA certificate to the list of preferred signers for this context.
684
685 The list of certificate authorities will be sent to the client when the
686 server requests a client certificate.
687
688 :param certificate_authority: certificate authority's X509 certificate.
689 :return: None
690 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800691 if not isinstance(certificate_authority, X509):
692 raise TypeError("certificate_authority must be an X509 instance")
693
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500694 add_result = _lib.SSL_CTX_add_client_CA(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800695 self._context, certificate_authority._x509)
696 if not add_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500697 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500698 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800699
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800700
701 def set_timeout(self, timeout):
702 """
703 Set session timeout
704
705 :param timeout: The timeout in seconds
706 :return: The previous session timeout
707 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500708 if not isinstance(timeout, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800709 raise TypeError("timeout must be an integer")
710
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500711 return _lib.SSL_CTX_set_timeout(self._context, timeout)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800712
713
714 def get_timeout(self):
715 """
716 Get the session timeout
717
718 :return: The session timeout
719 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500720 return _lib.SSL_CTX_get_timeout(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800721
722
723 def set_info_callback(self, callback):
724 """
725 Set the info callback
726
727 :param callback: The Python callback to use
728 :return: None
729 """
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800730 @wraps(callback)
731 def wrapper(ssl, where, return_code):
Jean-Paul Calderonef2bbc9c2014-02-02 10:59:14 -0500732 callback(Connection._reverse_mapping[ssl], where, return_code)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500733 self._info_callback = _ffi.callback(
734 "void (*)(const SSL *, int, int)", wrapper)
735 _lib.SSL_CTX_set_info_callback(self._context, self._info_callback)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800736
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800737
738 def get_app_data(self):
739 """
740 Get the application data (supplied via set_app_data())
741
742 :return: The application data
743 """
744 return self._app_data
745
746
747 def set_app_data(self, data):
748 """
749 Set the application data (will be returned from get_app_data())
750
751 :param data: Any Python object
752 :return: None
753 """
754 self._app_data = data
755
756
757 def get_cert_store(self):
758 """
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500759 Get the certificate store for the context.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800760
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500761 :return: A X509Store object or None if it does not have one.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800762 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500763 store = _lib.SSL_CTX_get_cert_store(self._context)
764 if store == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500765 # TODO: This is untested.
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800766 return None
767
768 pystore = X509Store.__new__(X509Store)
769 pystore._store = store
770 return pystore
771
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800772
773 def set_options(self, options):
774 """
775 Add options. Options set before are not cleared!
776
777 :param options: The options to add.
778 :return: The new option bitmask.
779 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500780 if not isinstance(options, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800781 raise TypeError("options must be an integer")
782
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500783 return _lib.SSL_CTX_set_options(self._context, options)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800784
785
786 def set_mode(self, mode):
787 """
788 Add modes via bitmask. Modes set before are not cleared!
789
790 :param mode: The mode to add.
791 :return: The new mode bitmask.
792 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500793 if not isinstance(mode, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800794 raise TypeError("mode must be an integer")
795
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500796 return _lib.SSL_CTX_set_mode(self._context, mode)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800797
798
799 def set_tlsext_servername_callback(self, callback):
800 """
801 Specify a callback function to be called when clients specify a server name.
802
803 :param callback: The callback function. It will be invoked with one
804 argument, the Connection instance.
805 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800806 @wraps(callback)
807 def wrapper(ssl, alert, arg):
808 callback(Connection._reverse_mapping[ssl])
809 return 0
810
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500811 self._tlsext_servername_callback = _ffi.callback(
812 "int (*)(const SSL *, int *, void *)", wrapper)
813 _lib.SSL_CTX_set_tlsext_servername_callback(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800814 self._context, self._tlsext_servername_callback)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800815
Cory Benfield84a121e2014-03-31 20:30:25 +0100816
817 def set_npn_advertise_callback(self, callback):
818 """
819 Specify a callback function that will be called when offering Next
820 Protocol Negotiation.
821
822 :param callback: The callback function. It will be invoked with one
823 argument, the Connection instance. It should return a Python
824 bytestring, like b'\\x08http/1.1\\x06spdy/2'.
825 """
826 @wraps(callback)
827 def wrapper(ssl, out, outlen, arg):
828 outstr = callback(Connection._reverse_mapping[ssl])
829 self._npn_advertise_callback_args = [
830 _ffi.new("unsigned int *", len(outstr)),
831 _ffi.new("unsigned char[]", outstr),
832 ]
833 outlen[0] = self._npn_advertise_callback_args[0][0]
834 out[0] = self._npn_advertise_callback_args[1]
835 return 0
836
837 self._npn_advertise_callback = _ffi.callback(
838 "int (*)(SSL *, const unsigned char **, unsigned int *, void *)",
839 wrapper)
840 _lib.SSL_CTX_set_next_protos_advertised_cb(
841 self._context, self._npn_advertise_callback, _ffi.NULL)
842
843
844 def set_npn_select_callback(self, callback):
845 """
846 Specify a callback function that will be called when a server offers
847 Next Protocol Negotiation options.
848
849 :param callback: The callback function. It will be invoked with two
850 arguments: the Connection, and a list of offered protocols as
851 length-prefixed strings in a bytestring, e.g.
852 b'\\x08http/1.1\\x06spdy/2'. It should return one of those
853 bytestrings, the chosen protocol.
854 """
855 @wraps(callback)
856 def wrapper(ssl, out, outlen, in_, inlen, arg):
857 outstr = callback(
858 Connection._reverse_mapping[ssl], _ffi.string(in_))
859 self._npn_select_callback_args = [
860 _ffi.new("unsigned char *", len(outstr)),
861 _ffi.new("unsigned char[]", outstr),
862 ]
863 outlen[0] = self._npn_select_callback_args[0][0]
864 out[0] = self._npn_select_callback_args[1]
865 return 0
866
867 self._npn_select_callback = _ffi.callback(
868 "int (*)(SSL *, unsigned char **, unsigned char *, "
869 "const unsigned char *, unsigned int, void *)",
870 wrapper)
871 _lib.SSL_CTX_set_next_proto_select_cb(
872 self._context, self._npn_select_callback, _ffi.NULL)
873
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800874ContextType = Context
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800875
876
877
878class Connection(object):
879 """
880 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800881 _reverse_mapping = WeakValueDictionary()
882
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800883 def __init__(self, context, socket=None):
884 """
885 Create a new Connection object, using the given OpenSSL.SSL.Context
886 instance and socket.
887
888 :param context: An SSL Context to use for this connection
889 :param socket: The socket to use for transport layer
890 """
891 if not isinstance(context, Context):
892 raise TypeError("context must be a Context instance")
893
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500894 ssl = _lib.SSL_new(context._context)
895 self._ssl = _ffi.gc(ssl, _lib.SSL_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800896 self._context = context
897
898 self._reverse_mapping[self._ssl] = self
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800899
900 if socket is None:
901 self._socket = None
Jean-Paul Calderone73b15c22013-03-05 18:30:39 -0800902 # Don't set up any gc for these, SSL_free will take care of them.
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500903 self._into_ssl = _lib.BIO_new(_lib.BIO_s_mem())
904 self._from_ssl = _lib.BIO_new(_lib.BIO_s_mem())
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800905
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500906 if self._into_ssl == _ffi.NULL or self._from_ssl == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500907 # TODO: This is untested.
908 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800909
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500910 _lib.SSL_set_bio(self._ssl, self._into_ssl, self._from_ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800911 else:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800912 self._into_ssl = None
913 self._from_ssl = None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800914 self._socket = socket
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500915 set_result = _lib.SSL_set_fd(self._ssl, _asFileDescriptor(self._socket))
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800916 if not set_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500917 # TODO: This is untested.
918 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800919
920
921 def __getattr__(self, name):
922 """
923 Look up attributes on the wrapped socket object if they are not found on
924 the Connection object.
925 """
926 return getattr(self._socket, name)
927
928
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800929 def _raise_ssl_error(self, ssl, result):
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800930 if self._context._verify_helper is not None:
931 self._context._verify_helper.raise_if_problem()
932
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500933 error = _lib.SSL_get_error(ssl, result)
934 if error == _lib.SSL_ERROR_WANT_READ:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800935 raise WantReadError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500936 elif error == _lib.SSL_ERROR_WANT_WRITE:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -0700937 raise WantWriteError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500938 elif error == _lib.SSL_ERROR_ZERO_RETURN:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800939 raise ZeroReturnError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500940 elif error == _lib.SSL_ERROR_WANT_X509_LOOKUP:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500941 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -0700942 raise WantX509LookupError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500943 elif error == _lib.SSL_ERROR_SYSCALL:
944 if _lib.ERR_peek_error() == 0:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800945 if result < 0:
Konstantinos Koukopoulos541150d2014-01-31 01:00:19 +0200946 if platform == "win32":
947 errno = _ffi.getwinerror()[0]
948 else:
949 errno = _ffi.errno
950 raise SysCallError(errno, errorcode[errno])
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800951 else:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -0700952 raise SysCallError(-1, "Unexpected EOF")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800953 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500954 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500955 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500956 elif error == _lib.SSL_ERROR_NONE:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -0700957 pass
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800958 else:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500959 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800960
961
962 def get_context(self):
963 """
964 Get session context
965 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800966 return self._context
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800967
968
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800969 def set_context(self, context):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800970 """
971 Switch this connection to a new session context
972
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800973 :param context: A :py:class:`Context` instance giving the new session
974 context to use.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800975 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800976 if not isinstance(context, Context):
977 raise TypeError("context must be a Context instance")
978
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500979 _lib.SSL_set_SSL_CTX(self._ssl, context._context)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800980 self._context = context
981
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800982
983 def get_servername(self):
984 """
985 Retrieve the servername extension value if provided in the client hello
986 message, or None if there wasn't one.
987
988 :return: A byte string giving the server name or :py:data:`None`.
989 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500990 name = _lib.SSL_get_servername(self._ssl, _lib.TLSEXT_NAMETYPE_host_name)
991 if name == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800992 return None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800993
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500994 return _ffi.string(name)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800995
996
997 def set_tlsext_host_name(self, name):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800998 """
999 Set the value of the servername extension to send in the client hello.
1000
1001 :param name: A byte string giving the name.
1002 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001003 if not isinstance(name, bytes):
1004 raise TypeError("name must be a byte string")
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001005 elif b"\0" in name:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001006 raise TypeError("name must not contain NUL byte")
1007
1008 # XXX I guess this can fail sometimes?
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001009 _lib.SSL_set_tlsext_host_name(self._ssl, name)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001010
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001011
1012 def pending(self):
1013 """
1014 Get the number of bytes that can be safely read from the connection
1015
1016 :return: The number of bytes available in the receive buffer.
1017 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001018 return _lib.SSL_pending(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001019
1020
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001021 def send(self, buf, flags=0):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001022 """
1023 Send data on the connection. NOTE: If you get one of the WantRead,
1024 WantWrite or WantX509Lookup exceptions on this, you have to call the
1025 method again with the SAME buffer.
1026
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001027 :param buf: The string, buffer or memoryview to send
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001028 :param flags: (optional) Included for compatibility with the socket
1029 API, the value is ignored
1030 :return: The number of bytes written
1031 """
Jean-Paul Calderone8fb53182013-12-30 08:35:49 -05001032 if isinstance(buf, _memoryview):
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -08001033 buf = buf.tobytes()
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001034 if isinstance(buf, _buffer):
1035 buf = str(buf)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001036 if not isinstance(buf, bytes):
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001037 raise TypeError("data must be a memoryview, buffer or byte string")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001038
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001039 result = _lib.SSL_write(self._ssl, buf, len(buf))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001040 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001041 return result
1042 write = send
1043
1044
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001045 def sendall(self, buf, flags=0):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001046 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001047 Send "all" data on the connection. This calls send() repeatedly until
1048 all data is sent. If an error occurs, it's impossible to tell how much
1049 data has been sent.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001050
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001051 :param buf: The string, buffer or memoryview to send
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001052 :param flags: (optional) Included for compatibility with the socket
1053 API, the value is ignored
1054 :return: The number of bytes written
1055 """
Jean-Paul Calderone8fb53182013-12-30 08:35:49 -05001056 if isinstance(buf, _memoryview):
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -08001057 buf = buf.tobytes()
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001058 if isinstance(buf, _buffer):
1059 buf = str(buf)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001060 if not isinstance(buf, bytes):
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001061 raise TypeError("buf must be a memoryview, buffer or byte string")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001062
1063 left_to_send = len(buf)
1064 total_sent = 0
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001065 data = _ffi.new("char[]", buf)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001066
1067 while left_to_send:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001068 result = _lib.SSL_write(self._ssl, data + total_sent, left_to_send)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001069 self._raise_ssl_error(self._ssl, result)
1070 total_sent += result
1071 left_to_send -= result
1072
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001073
1074 def recv(self, bufsiz, flags=None):
1075 """
1076 Receive data on the connection. NOTE: If you get one of the WantRead,
1077 WantWrite or WantX509Lookup exceptions on this, you have to call the
1078 method again with the SAME buffer.
1079
1080 :param bufsiz: The maximum number of bytes to read
1081 :param flags: (optional) Included for compatibility with the socket
1082 API, the value is ignored
1083 :return: The string read from the Connection
1084 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001085 buf = _ffi.new("char[]", bufsiz)
1086 result = _lib.SSL_read(self._ssl, buf, bufsiz)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001087 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001088 return _ffi.buffer(buf, result)[:]
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001089 read = recv
1090
1091
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001092 def _handle_bio_errors(self, bio, result):
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001093 if _lib.BIO_should_retry(bio):
1094 if _lib.BIO_should_read(bio):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001095 raise WantReadError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001096 elif _lib.BIO_should_write(bio):
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001097 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001098 raise WantWriteError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001099 elif _lib.BIO_should_io_special(bio):
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001100 # TODO: This is untested. I think io_special means the socket
1101 # BIO has a not-yet connected socket.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001102 raise ValueError("BIO_should_io_special")
1103 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001104 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001105 raise ValueError("unknown bio failure")
1106 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001107 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001108 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001109
1110
1111 def bio_read(self, bufsiz):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001112 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001113 When using non-socket connections this function reads the "dirty" data
1114 that would have traveled away on the network.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001115
1116 :param bufsiz: The maximum number of bytes to read
1117 :return: The string read.
1118 """
Jean-Paul Calderone97e041d2013-03-05 21:03:12 -08001119 if self._from_ssl is None:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001120 raise TypeError("Connection sock was not None")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001121
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -05001122 if not isinstance(bufsiz, integer_types):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001123 raise TypeError("bufsiz must be an integer")
1124
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001125 buf = _ffi.new("char[]", bufsiz)
1126 result = _lib.BIO_read(self._from_ssl, buf, bufsiz)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001127 if result <= 0:
1128 self._handle_bio_errors(self._from_ssl, result)
1129
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001130 return _ffi.buffer(buf, result)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001131
1132
1133 def bio_write(self, buf):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001134 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001135 When using non-socket connections this function sends "dirty" data that
1136 would have traveled in on the network.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001137
1138 :param buf: The string to put into the memory BIO.
1139 :return: The number of bytes written
1140 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001141 if self._into_ssl is None:
1142 raise TypeError("Connection sock was not None")
1143
1144 if not isinstance(buf, bytes):
1145 raise TypeError("buf must be a byte string")
1146
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001147 result = _lib.BIO_write(self._into_ssl, buf, len(buf))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001148 if result <= 0:
1149 self._handle_bio_errors(self._into_ssl, result)
1150 return result
1151
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001152
1153 def renegotiate(self):
1154 """
1155 Renegotiate the session
1156
1157 :return: True if the renegotiation can be started, false otherwise
1158 """
1159
1160 def do_handshake(self):
1161 """
1162 Perform an SSL handshake (usually called after renegotiate() or one of
1163 set_*_state()). This can raise the same exceptions as send and recv.
1164
1165 :return: None.
1166 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001167 result = _lib.SSL_do_handshake(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001168 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001169
1170
1171 def renegotiate_pending(self):
1172 """
1173 Check if there's a renegotiation in progress, it will return false once
1174 a renegotiation is finished.
1175
1176 :return: Whether there's a renegotiation in progress
1177 """
1178
1179 def total_renegotiations(self):
1180 """
1181 Find out the total number of renegotiations.
1182
1183 :return: The number of renegotiations.
1184 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001185 return _lib.SSL_total_renegotiations(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001186
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001187
1188 def connect(self, addr):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001189 """
1190 Connect to remote host and set up client-side SSL
1191
1192 :param addr: A remote address
1193 :return: What the socket's connect method returns
1194 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001195 _lib.SSL_set_connect_state(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001196 return self._socket.connect(addr)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001197
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001198
1199 def connect_ex(self, addr):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001200 """
1201 Connect to remote host and set up client-side SSL. Note that if the socket's
1202 connect_ex method doesn't return 0, SSL won't be initialized.
1203
1204 :param addr: A remove address
1205 :return: What the socket's connect_ex method returns
1206 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001207 connect_ex = self._socket.connect_ex
1208 self.set_connect_state()
1209 return connect_ex(addr)
1210
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001211
1212 def accept(self):
1213 """
1214 Accept incoming connection and set up SSL on it
1215
1216 :return: A (conn,addr) pair where conn is a Connection and addr is an
1217 address
1218 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001219 client, addr = self._socket.accept()
1220 conn = Connection(self._context, client)
1221 conn.set_accept_state()
1222 return (conn, addr)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001223
1224
1225 def bio_shutdown(self):
1226 """
1227 When using non-socket connections this function signals end of
1228 data on the input for this connection.
1229
1230 :return: None
1231 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001232 if self._from_ssl is None:
1233 raise TypeError("Connection sock was not None")
1234
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001235 _lib.BIO_set_mem_eof_return(self._into_ssl, 0)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001236
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001237
1238 def shutdown(self):
1239 """
1240 Send closure alert
1241
1242 :return: True if the shutdown completed successfully (i.e. both sides
1243 have sent closure alerts), false otherwise (i.e. you have to
1244 wait for a ZeroReturnError on a recv() method call
1245 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001246 result = _lib.SSL_shutdown(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001247 if result < 0:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001248 # TODO: This is untested.
1249 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001250 elif result > 0:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001251 return True
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001252 else:
1253 return False
1254
1255
1256 def get_cipher_list(self):
1257 """
1258 Get the session cipher list
1259
1260 :return: A list of cipher strings
1261 """
1262 ciphers = []
1263 for i in count():
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001264 result = _lib.SSL_get_cipher_list(self._ssl, i)
1265 if result == _ffi.NULL:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001266 break
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001267 ciphers.append(_native(_ffi.string(result)))
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001268 return ciphers
1269
1270
1271 def get_client_ca_list(self):
1272 """
1273 Get CAs whose certificates are suggested for client authentication.
1274
1275 :return: If this is a server connection, a list of X509Names representing
1276 the acceptable CAs as set by :py:meth:`OpenSSL.SSL.Context.set_client_ca_list` or
1277 :py:meth:`OpenSSL.SSL.Context.add_client_ca`. If this is a client connection,
1278 the list of such X509Names sent by the server, or an empty list if that
1279 has not yet happened.
1280 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001281 ca_names = _lib.SSL_get_client_CA_list(self._ssl)
1282 if ca_names == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001283 # TODO: This is untested.
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001284 return []
1285
1286 result = []
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001287 for i in range(_lib.sk_X509_NAME_num(ca_names)):
1288 name = _lib.sk_X509_NAME_value(ca_names, i)
1289 copy = _lib.X509_NAME_dup(name)
1290 if copy == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001291 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001292 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001293
1294 pyname = X509Name.__new__(X509Name)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001295 pyname._name = _ffi.gc(copy, _lib.X509_NAME_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001296 result.append(pyname)
1297 return result
1298
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001299
1300 def makefile(self):
1301 """
1302 The makefile() method is not implemented, since there is no dup semantics
1303 for SSL connections
1304
Jean-Paul Calderone6749ec22014-04-17 16:30:21 -04001305 :raise: NotImplementedError
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001306 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001307 raise NotImplementedError("Cannot make file object of OpenSSL.SSL.Connection")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001308
1309
1310 def get_app_data(self):
1311 """
1312 Get application data
1313
1314 :return: The application data
1315 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001316 return self._app_data
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001317
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001318
1319 def set_app_data(self, data):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001320 """
1321 Set application data
1322
1323 :param data - The application data
1324 :return: None
1325 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001326 self._app_data = data
1327
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001328
1329 def get_shutdown(self):
1330 """
1331 Get shutdown state
1332
1333 :return: The shutdown state, a bitvector of SENT_SHUTDOWN, RECEIVED_SHUTDOWN.
1334 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001335 return _lib.SSL_get_shutdown(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001336
1337
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001338 def set_shutdown(self, state):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001339 """
1340 Set shutdown state
1341
1342 :param state - bitvector of SENT_SHUTDOWN, RECEIVED_SHUTDOWN.
1343 :return: None
1344 """
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -05001345 if not isinstance(state, integer_types):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001346 raise TypeError("state must be an integer")
1347
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001348 _lib.SSL_set_shutdown(self._ssl, state)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001349
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001350
1351 def state_string(self):
1352 """
1353 Get a verbose state description
1354
1355 :return: A string representing the state
1356 """
1357
1358 def server_random(self):
1359 """
1360 Get a copy of the server hello nonce.
1361
1362 :return: A string representing the state
1363 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001364 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001365 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001366 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001367 self._ssl.s3.server_random,
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001368 _lib.SSL3_RANDOM_SIZE)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001369
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001370
1371 def client_random(self):
1372 """
1373 Get a copy of the client hello nonce.
1374
1375 :return: A string representing the state
1376 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001377 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001378 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001379 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001380 self._ssl.s3.client_random,
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001381 _lib.SSL3_RANDOM_SIZE)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001382
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001383
1384 def master_key(self):
1385 """
1386 Get a copy of the master key.
1387
1388 :return: A string representing the state
1389 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001390 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001391 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001392 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001393 self._ssl.session.master_key,
1394 self._ssl.session.master_key_length)[:]
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001395
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001396
1397 def sock_shutdown(self, *args, **kwargs):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001398 """
1399 See shutdown(2)
1400
1401 :return: What the socket's shutdown() method returns
1402 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001403 return self._socket.shutdown(*args, **kwargs)
1404
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001405
1406 def get_peer_certificate(self):
1407 """
1408 Retrieve the other side's certificate (if any)
1409
1410 :return: The peer's certificate
1411 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001412 cert = _lib.SSL_get_peer_certificate(self._ssl)
1413 if cert != _ffi.NULL:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001414 pycert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001415 pycert._x509 = _ffi.gc(cert, _lib.X509_free)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001416 return pycert
1417 return None
1418
1419
1420 def get_peer_cert_chain(self):
1421 """
1422 Retrieve the other side's certificate (if any)
1423
1424 :return: A list of X509 instances giving the peer's certificate chain,
1425 or None if it does not have one.
1426 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001427 cert_stack = _lib.SSL_get_peer_cert_chain(self._ssl)
1428 if cert_stack == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001429 return None
1430
1431 result = []
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001432 for i in range(_lib.sk_X509_num(cert_stack)):
Jean-Paul Calderone73b15c22013-03-05 18:30:39 -08001433 # TODO could incref instead of dup here
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001434 cert = _lib.X509_dup(_lib.sk_X509_value(cert_stack, i))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001435 pycert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001436 pycert._x509 = _ffi.gc(cert, _lib.X509_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001437 result.append(pycert)
1438 return result
1439
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001440
1441 def want_read(self):
1442 """
1443 Checks if more data has to be read from the transport layer to complete an
1444 operation.
1445
1446 :return: True iff more data has to be read
1447 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001448 return _lib.SSL_want_read(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001449
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001450
1451 def want_write(self):
1452 """
1453 Checks if there is data to write to the transport layer to complete an
1454 operation.
1455
1456 :return: True iff there is data to write
1457 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001458 return _lib.SSL_want_write(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001459
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001460
1461 def set_accept_state(self):
1462 """
1463 Set the connection to work in server mode. The handshake will be handled
1464 automatically by read/write.
1465
1466 :return: None
1467 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001468 _lib.SSL_set_accept_state(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001469
1470
1471 def set_connect_state(self):
1472 """
1473 Set the connection to work in client mode. The handshake will be handled
1474 automatically by read/write.
1475
1476 :return: None
1477 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001478 _lib.SSL_set_connect_state(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001479
1480
1481 def get_session(self):
1482 """
1483 Returns the Session currently used.
1484
1485 @return: An instance of :py:class:`OpenSSL.SSL.Session` or :py:obj:`None` if
1486 no session exists.
1487 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001488 session = _lib.SSL_get1_session(self._ssl)
1489 if session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001490 return None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001491
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001492 pysession = Session.__new__(Session)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001493 pysession._session = _ffi.gc(session, _lib.SSL_SESSION_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001494 return pysession
1495
1496
1497 def set_session(self, session):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001498 """
1499 Set the session to be used when the TLS/SSL connection is established.
1500
1501 :param session: A Session instance representing the session to use.
1502 :returns: None
1503 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001504 if not isinstance(session, Session):
1505 raise TypeError("session must be a Session instance")
1506
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001507 result = _lib.SSL_set_session(self._ssl, session._session)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001508 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001509 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001510
Jean-Paul Calderonedbd76272014-03-29 18:09:40 -04001511
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001512 def _get_finished_message(self, function):
1513 """
1514 Helper to implement :py:meth:`get_finished` and
1515 :py:meth:`get_peer_finished`.
1516
1517 :param function: Either :py:data:`SSL_get_finished`: or
1518 :py:data:`SSL_get_peer_finished`.
1519
1520 :return: :py:data:`None` if the desired message has not yet been
1521 received, otherwise the contents of the message.
1522 :rtype: :py:class:`bytes` or :py:class:`NoneType`
1523 """
Jean-Paul Calderone01af9042014-03-30 11:40:42 -04001524 # The OpenSSL documentation says nothing about what might happen if the
1525 # count argument given is zero. Specifically, it doesn't say whether
1526 # the output buffer may be NULL in that case or not. Inspection of the
1527 # implementation reveals that it calls memcpy() unconditionally.
1528 # Section 7.1.4, paragraph 1 of the C standard suggests that
1529 # memcpy(NULL, source, 0) is not guaranteed to produce defined (let
1530 # alone desirable) behavior (though it probably does on just about
1531 # every implementation...)
1532 #
1533 # Allocate a tiny buffer to pass in (instead of just passing NULL as
1534 # one might expect) for the initial call so as to be safe against this
1535 # potentially undefined behavior.
1536 empty = _ffi.new("char[]", 0)
1537 size = function(self._ssl, empty, 0)
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001538 if size == 0:
1539 # No Finished message so far.
1540 return None
1541
1542 buf = _ffi.new("char[]", size)
1543 function(self._ssl, buf, size)
1544 return _ffi.buffer(buf, size)[:]
1545
1546
Fedor Brunner5747b932014-03-05 14:22:34 +01001547 def get_finished(self):
1548 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001549 Obtain the latest `handshake finished` message sent to the peer.
Fedor Brunner5747b932014-03-05 14:22:34 +01001550
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001551 :return: The contents of the message or :py:obj:`None` if the TLS
1552 handshake has not yet completed.
1553 :rtype: :py:class:`bytes` or :py:class:`NoneType`
Fedor Brunner5747b932014-03-05 14:22:34 +01001554 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001555 return self._get_finished_message(_lib.SSL_get_finished)
1556
Fedor Brunner5747b932014-03-05 14:22:34 +01001557
1558 def get_peer_finished(self):
1559 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001560 Obtain the latest `handshake finished` message received from the peer.
Fedor Brunner5747b932014-03-05 14:22:34 +01001561
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001562 :return: The contents of the message or :py:obj:`None` if the TLS
1563 handshake has not yet completed.
1564 :rtype: :py:class:`bytes` or :py:class:`NoneType`
Fedor Brunner5747b932014-03-05 14:22:34 +01001565 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001566 return self._get_finished_message(_lib.SSL_get_peer_finished)
Fedor Brunner5747b932014-03-05 14:22:34 +01001567
Jean-Paul Calderone7c556ef2014-03-30 10:45:00 -04001568
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001569 def get_cipher_name(self):
1570 """
1571 Obtain the name of the currently used cipher.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001572
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001573 :returns: The name of the currently used cipher or :py:obj:`None`
1574 if no connection has been established.
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001575 :rtype: :py:class:`unicode` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001576 """
1577 cipher = _lib.SSL_get_current_cipher(self._ssl)
1578 if cipher == _ffi.NULL:
1579 return None
1580 else:
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001581 name = _ffi.string(_lib.SSL_CIPHER_get_name(cipher))
1582 return name.decode("utf-8")
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001583
Jean-Paul Calderonedbd76272014-03-29 18:09:40 -04001584
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001585 def get_cipher_bits(self):
1586 """
1587 Obtain the number of secret bits of the currently used cipher.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001588
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001589 :returns: The number of secret bits of the currently used cipher
1590 or :py:obj:`None` if no connection has been established.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001591 :rtype: :py:class:`int` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001592 """
1593 cipher = _lib.SSL_get_current_cipher(self._ssl)
1594 if cipher == _ffi.NULL:
1595 return None
1596 else:
1597 return _lib.SSL_CIPHER_get_bits(cipher, _ffi.NULL)
1598
Jean-Paul Calderonedbd76272014-03-29 18:09:40 -04001599
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001600 def get_cipher_version(self):
1601 """
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001602 Obtain the protocol version of the currently used cipher.
1603
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001604 :returns: The protocol name of the currently used cipher
1605 or :py:obj:`None` if no connection has been established.
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001606 :rtype: :py:class:`unicode` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001607 """
1608 cipher = _lib.SSL_get_current_cipher(self._ssl)
1609 if cipher == _ffi.NULL:
1610 return None
1611 else:
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001612 version =_ffi.string(_lib.SSL_CIPHER_get_version(cipher))
1613 return version.decode("utf-8")
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001614
Cory Benfield84a121e2014-03-31 20:30:25 +01001615 def get_next_proto_negotiated(self):
1616 """
1617 Get the protocol that was negotiated by NPN.
1618 """
1619 data = _ffi.new("unsigned char **")
1620 data_len = _ffi.new("unsigned int *")
1621
1622 _lib.SSL_get0_next_proto_negotiated(self._ssl, data, data_len)
1623
1624 if not data_len[0]:
1625 return ""
1626 else:
1627 return _ffi.string(data[0])
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001628
1629
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001630ConnectionType = Connection
Jean-Paul Calderone11ed8e82014-01-18 10:21:50 -05001631
Jean-Paul Calderonefab157b2014-01-18 11:21:38 -05001632# This is similar to the initialization calls at the end of OpenSSL/crypto.py
1633# but is exercised mostly by the Context initializer.
Jean-Paul Calderone11ed8e82014-01-18 10:21:50 -05001634_lib.SSL_library_init()