blob: e97df8be671252dc932944c9ee8c8b7b3a7ea312 [file] [log] [blame]
Konstantinos Koukopoulos541150d2014-01-31 01:00:19 +02001from sys import platform
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05002from functools import wraps, partial
Cory Benfieldbe3e7b82014-05-10 09:48:55 +01003from itertools import count, chain
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08004from weakref import WeakValueDictionary
5from errno import errorcode
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -08006
Jean-Paul Calderone63eab692014-01-18 10:19:56 -05007from six import text_type as _text_type
Konstantinos Koukopoulosc8b13ea2014-01-28 00:21:50 -08008from six import integer_types as integer_types
Cory Benfieldcd010f62014-05-15 19:00:27 +01009from six import int2byte, indexbytes
Jean-Paul Calderone63eab692014-01-18 10:19:56 -050010
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -050011from OpenSSL._util import (
12 ffi as _ffi,
13 lib as _lib,
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -050014 exception_from_error_queue as _exception_from_error_queue,
15 native as _native)
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080016
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -080017from OpenSSL.crypto import (
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -050018 FILETYPE_PEM, _PassphraseHelper, PKey, X509Name, X509, X509Store)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -080019
20_unspecified = object()
21
Jean-Paul Calderone8fb53182013-12-30 08:35:49 -050022try:
23 _memoryview = memoryview
24except NameError:
25 class _memoryview(object):
26 pass
27
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +020028try:
29 _buffer = buffer
30except NameError:
31 class _buffer(object):
32 pass
33
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050034OPENSSL_VERSION_NUMBER = _lib.OPENSSL_VERSION_NUMBER
35SSLEAY_VERSION = _lib.SSLEAY_VERSION
36SSLEAY_CFLAGS = _lib.SSLEAY_CFLAGS
37SSLEAY_PLATFORM = _lib.SSLEAY_PLATFORM
38SSLEAY_DIR = _lib.SSLEAY_DIR
39SSLEAY_BUILT_ON = _lib.SSLEAY_BUILT_ON
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080040
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050041SENT_SHUTDOWN = _lib.SSL_SENT_SHUTDOWN
42RECEIVED_SHUTDOWN = _lib.SSL_RECEIVED_SHUTDOWN
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080043
44SSLv2_METHOD = 1
45SSLv3_METHOD = 2
46SSLv23_METHOD = 3
47TLSv1_METHOD = 4
Jean-Paul Calderone56bff942013-11-03 11:30:43 -050048TLSv1_1_METHOD = 5
49TLSv1_2_METHOD = 6
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080050
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050051OP_NO_SSLv2 = _lib.SSL_OP_NO_SSLv2
52OP_NO_SSLv3 = _lib.SSL_OP_NO_SSLv3
53OP_NO_TLSv1 = _lib.SSL_OP_NO_TLSv1
Jean-Paul Calderonebe2bb422013-12-29 07:34:08 -050054
55OP_NO_TLSv1_1 = getattr(_lib, "SSL_OP_NO_TLSv1_1", 0)
56OP_NO_TLSv1_2 = getattr(_lib, "SSL_OP_NO_TLSv1_2", 0)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -080057
Jean-Paul Calderone0d7e8a12014-01-08 16:54:13 -050058try:
59 MODE_RELEASE_BUFFERS = _lib.SSL_MODE_RELEASE_BUFFERS
60except AttributeError:
61 pass
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080062
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050063OP_SINGLE_DH_USE = _lib.SSL_OP_SINGLE_DH_USE
64OP_EPHEMERAL_RSA = _lib.SSL_OP_EPHEMERAL_RSA
65OP_MICROSOFT_SESS_ID_BUG = _lib.SSL_OP_MICROSOFT_SESS_ID_BUG
66OP_NETSCAPE_CHALLENGE_BUG = _lib.SSL_OP_NETSCAPE_CHALLENGE_BUG
67OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG = _lib.SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG
68OP_SSLREF2_REUSE_CERT_TYPE_BUG = _lib.SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG
69OP_MICROSOFT_BIG_SSLV3_BUFFER = _lib.SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER
Jean-Paul Calderone0d7e8a12014-01-08 16:54:13 -050070try:
71 OP_MSIE_SSLV2_RSA_PADDING = _lib.SSL_OP_MSIE_SSLV2_RSA_PADDING
72except AttributeError:
73 pass
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050074OP_SSLEAY_080_CLIENT_DH_BUG = _lib.SSL_OP_SSLEAY_080_CLIENT_DH_BUG
75OP_TLS_D5_BUG = _lib.SSL_OP_TLS_D5_BUG
76OP_TLS_BLOCK_PADDING_BUG = _lib.SSL_OP_TLS_BLOCK_PADDING_BUG
77OP_DONT_INSERT_EMPTY_FRAGMENTS = _lib.SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
78OP_CIPHER_SERVER_PREFERENCE = _lib.SSL_OP_CIPHER_SERVER_PREFERENCE
79OP_TLS_ROLLBACK_BUG = _lib.SSL_OP_TLS_ROLLBACK_BUG
80OP_PKCS1_CHECK_1 = _lib.SSL_OP_PKCS1_CHECK_1
81OP_PKCS1_CHECK_2 = _lib.SSL_OP_PKCS1_CHECK_2
82OP_NETSCAPE_CA_DN_BUG = _lib.SSL_OP_NETSCAPE_CA_DN_BUG
83OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG= _lib.SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG
Jean-Paul Calderonec1780342014-01-08 16:59:03 -050084try:
85 OP_NO_COMPRESSION = _lib.SSL_OP_NO_COMPRESSION
86except AttributeError:
87 pass
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -080088
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050089OP_NO_QUERY_MTU = _lib.SSL_OP_NO_QUERY_MTU
90OP_COOKIE_EXCHANGE = _lib.SSL_OP_COOKIE_EXCHANGE
Arturo Filastò5f8c7a82014-03-09 20:01:25 +010091try:
92 OP_NO_TICKET = _lib.SSL_OP_NO_TICKET
93except AttributeError:
94 pass
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -080095
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050096OP_ALL = _lib.SSL_OP_ALL
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080097
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050098VERIFY_PEER = _lib.SSL_VERIFY_PEER
99VERIFY_FAIL_IF_NO_PEER_CERT = _lib.SSL_VERIFY_FAIL_IF_NO_PEER_CERT
100VERIFY_CLIENT_ONCE = _lib.SSL_VERIFY_CLIENT_ONCE
101VERIFY_NONE = _lib.SSL_VERIFY_NONE
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -0800102
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500103SESS_CACHE_OFF = _lib.SSL_SESS_CACHE_OFF
104SESS_CACHE_CLIENT = _lib.SSL_SESS_CACHE_CLIENT
105SESS_CACHE_SERVER = _lib.SSL_SESS_CACHE_SERVER
106SESS_CACHE_BOTH = _lib.SSL_SESS_CACHE_BOTH
107SESS_CACHE_NO_AUTO_CLEAR = _lib.SSL_SESS_CACHE_NO_AUTO_CLEAR
108SESS_CACHE_NO_INTERNAL_LOOKUP = _lib.SSL_SESS_CACHE_NO_INTERNAL_LOOKUP
109SESS_CACHE_NO_INTERNAL_STORE = _lib.SSL_SESS_CACHE_NO_INTERNAL_STORE
110SESS_CACHE_NO_INTERNAL = _lib.SSL_SESS_CACHE_NO_INTERNAL
Jean-Paul Calderoned39a3f62013-03-04 12:23:51 -0800111
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500112SSL_ST_CONNECT = _lib.SSL_ST_CONNECT
113SSL_ST_ACCEPT = _lib.SSL_ST_ACCEPT
114SSL_ST_MASK = _lib.SSL_ST_MASK
115SSL_ST_INIT = _lib.SSL_ST_INIT
116SSL_ST_BEFORE = _lib.SSL_ST_BEFORE
117SSL_ST_OK = _lib.SSL_ST_OK
118SSL_ST_RENEGOTIATE = _lib.SSL_ST_RENEGOTIATE
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800119
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500120SSL_CB_LOOP = _lib.SSL_CB_LOOP
121SSL_CB_EXIT = _lib.SSL_CB_EXIT
122SSL_CB_READ = _lib.SSL_CB_READ
123SSL_CB_WRITE = _lib.SSL_CB_WRITE
124SSL_CB_ALERT = _lib.SSL_CB_ALERT
125SSL_CB_READ_ALERT = _lib.SSL_CB_READ_ALERT
126SSL_CB_WRITE_ALERT = _lib.SSL_CB_WRITE_ALERT
127SSL_CB_ACCEPT_LOOP = _lib.SSL_CB_ACCEPT_LOOP
128SSL_CB_ACCEPT_EXIT = _lib.SSL_CB_ACCEPT_EXIT
129SSL_CB_CONNECT_LOOP = _lib.SSL_CB_CONNECT_LOOP
130SSL_CB_CONNECT_EXIT = _lib.SSL_CB_CONNECT_EXIT
131SSL_CB_HANDSHAKE_START = _lib.SSL_CB_HANDSHAKE_START
132SSL_CB_HANDSHAKE_DONE = _lib.SSL_CB_HANDSHAKE_DONE
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800133
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500134class Error(Exception):
Jean-Paul Calderone511cde02013-12-29 10:31:13 -0500135 """
136 An error occurred in an `OpenSSL.SSL` API.
137 """
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500138
139
140
141_raise_current_error = partial(_exception_from_error_queue, Error)
142
143
144class WantReadError(Error):
145 pass
146
147
148
149class WantWriteError(Error):
150 pass
151
152
153
154class WantX509LookupError(Error):
155 pass
156
157
158
159class ZeroReturnError(Error):
160 pass
161
162
163
164class SysCallError(Error):
165 pass
166
167
168
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800169class _VerifyHelper(object):
Jean-Paul Calderone6a8cd112014-04-02 21:09:08 -0400170 def __init__(self, callback):
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800171 self._problems = []
172
173 @wraps(callback)
174 def wrapper(ok, store_ctx):
175 cert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500176 cert._x509 = _lib.X509_STORE_CTX_get_current_cert(store_ctx)
177 error_number = _lib.X509_STORE_CTX_get_error(store_ctx)
178 error_depth = _lib.X509_STORE_CTX_get_error_depth(store_ctx)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800179
Jean-Paul Calderone6a8cd112014-04-02 21:09:08 -0400180 index = _lib.SSL_get_ex_data_X509_STORE_CTX_idx()
181 ssl = _lib.X509_STORE_CTX_get_ex_data(store_ctx, index)
182 connection = Connection._reverse_mapping[ssl]
183
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800184 try:
185 result = callback(connection, cert, error_number, error_depth, ok)
186 except Exception as e:
187 self._problems.append(e)
188 return 0
189 else:
190 if result:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500191 _lib.X509_STORE_CTX_set_error(store_ctx, _lib.X509_V_OK)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800192 return 1
193 else:
194 return 0
195
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500196 self.callback = _ffi.callback(
197 "int (*)(int, X509_STORE_CTX *)", wrapper)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800198
199
200 def raise_if_problem(self):
201 if self._problems:
202 try:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500203 _raise_current_error()
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800204 except Error:
205 pass
206 raise self._problems.pop(0)
207
208
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800209
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800210def _asFileDescriptor(obj):
211 fd = None
Konstantinos Koukopoulosc8b13ea2014-01-28 00:21:50 -0800212 if not isinstance(obj, integer_types):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800213 meth = getattr(obj, "fileno", None)
214 if meth is not None:
215 obj = meth()
216
Konstantinos Koukopoulosc8b13ea2014-01-28 00:21:50 -0800217 if isinstance(obj, integer_types):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800218 fd = obj
219
Konstantinos Koukopoulosc8b13ea2014-01-28 00:21:50 -0800220 if not isinstance(fd, integer_types):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800221 raise TypeError("argument must be an int, or have a fileno() method.")
222 elif fd < 0:
223 raise ValueError(
224 "file descriptor cannot be a negative integer (%i)" % (fd,))
225
226 return fd
227
228
229
Jean-Paul Calderoned39a3f62013-03-04 12:23:51 -0800230def SSLeay_version(type):
231 """
232 Return a string describing the version of OpenSSL in use.
233
234 :param type: One of the SSLEAY_ constants defined in this module.
235 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500236 return _ffi.string(_lib.SSLeay_version(type))
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800237
238
239
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800240class Session(object):
241 pass
242
243
244
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800245class Context(object):
246 """
247 :py:obj:`OpenSSL.SSL.Context` instances define the parameters for setting up
248 new SSL connections.
249 """
250 _methods = {
Andrew Dunhamec84a0a2014-02-24 12:41:37 -0800251 SSLv2_METHOD: "SSLv2_method",
Jean-Paul Calderonebe2bb422013-12-29 07:34:08 -0500252 SSLv3_METHOD: "SSLv3_method",
253 SSLv23_METHOD: "SSLv23_method",
254 TLSv1_METHOD: "TLSv1_method",
255 TLSv1_1_METHOD: "TLSv1_1_method",
256 TLSv1_2_METHOD: "TLSv1_2_method",
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800257 }
Jean-Paul Calderonebe2bb422013-12-29 07:34:08 -0500258 _methods = dict(
259 (identifier, getattr(_lib, name))
260 for (identifier, name) in _methods.items()
261 if getattr(_lib, name, None) is not None)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800262
Jean-Paul Calderone63157872013-03-20 16:43:38 -0700263
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800264 def __init__(self, method):
265 """
266 :param method: One of SSLv2_METHOD, SSLv3_METHOD, SSLv23_METHOD, or
267 TLSv1_METHOD.
268 """
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -0500269 if not isinstance(method, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800270 raise TypeError("method must be an integer")
271
272 try:
273 method_func = self._methods[method]
274 except KeyError:
275 raise ValueError("No such protocol")
276
277 method_obj = method_func()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500278 if method_obj == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500279 # TODO: This is untested.
280 _raise_current_error()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800281
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500282 context = _lib.SSL_CTX_new(method_obj)
283 if context == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500284 # TODO: This is untested.
285 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500286 context = _ffi.gc(context, _lib.SSL_CTX_free)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800287
288 self._context = context
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800289 self._passphrase_helper = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800290 self._passphrase_callback = None
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800291 self._passphrase_userdata = None
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800292 self._verify_helper = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800293 self._verify_callback = None
294 self._info_callback = None
295 self._tlsext_servername_callback = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800296 self._app_data = None
Cory Benfield84a121e2014-03-31 20:30:25 +0100297 self._npn_advertise_callback = None
Cory Benfield84a121e2014-03-31 20:30:25 +0100298 self._npn_select_callback = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800299
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -0800300 # SSL_CTX_set_app_data(self->ctx, self);
301 # SSL_CTX_set_mode(self->ctx, SSL_MODE_ENABLE_PARTIAL_WRITE |
302 # SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
303 # SSL_MODE_AUTO_RETRY);
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500304 self.set_mode(_lib.SSL_MODE_ENABLE_PARTIAL_WRITE)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800305
306
307 def load_verify_locations(self, cafile, capath=None):
308 """
309 Let SSL know where we can find trusted certificates for the certificate
310 chain
311
312 :param cafile: In which file we can find the certificates
313 :param capath: In which directory we can find the certificates
314 :return: None
315 """
316 if cafile is None:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500317 cafile = _ffi.NULL
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800318 elif not isinstance(cafile, bytes):
319 raise TypeError("cafile must be None or a byte string")
320
321 if capath is None:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500322 capath = _ffi.NULL
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800323 elif not isinstance(capath, bytes):
324 raise TypeError("capath must be None or a byte string")
325
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500326 load_result = _lib.SSL_CTX_load_verify_locations(self._context, cafile, capath)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800327 if not load_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500328 _raise_current_error()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800329
330
331 def _wrap_callback(self, callback):
332 @wraps(callback)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800333 def wrapper(size, verify, userdata):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800334 return callback(size, verify, self._passphrase_userdata)
335 return _PassphraseHelper(
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800336 FILETYPE_PEM, wrapper, more_args=True, truncate=True)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800337
338
339 def set_passwd_cb(self, callback, userdata=None):
340 """
341 Set the passphrase callback
342
343 :param callback: The Python callback to use
344 :param userdata: (optional) A Python object which will be given as
345 argument to the callback
346 :return: None
347 """
348 if not callable(callback):
349 raise TypeError("callback must be callable")
350
351 self._passphrase_helper = self._wrap_callback(callback)
352 self._passphrase_callback = self._passphrase_helper.callback
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500353 _lib.SSL_CTX_set_default_passwd_cb(
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800354 self._context, self._passphrase_callback)
355 self._passphrase_userdata = userdata
356
357
358 def set_default_verify_paths(self):
359 """
360 Use the platform-specific CA certificate locations
361
362 :return: None
363 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500364 set_result = _lib.SSL_CTX_set_default_verify_paths(self._context)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800365 if not set_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500366 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500367 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800368
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800369
370 def use_certificate_chain_file(self, certfile):
371 """
372 Load a certificate chain from a file
373
374 :param certfile: The name of the certificate chain file
375 :return: None
376 """
Jean-Paul Calderoned8607982014-01-18 10:30:55 -0500377 if isinstance(certfile, _text_type):
378 # Perhaps sys.getfilesystemencoding() could be better?
379 certfile = certfile.encode("utf-8")
380
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800381 if not isinstance(certfile, bytes):
Jean-Paul Calderoned8607982014-01-18 10:30:55 -0500382 raise TypeError("certfile must be bytes or unicode")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800383
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500384 result = _lib.SSL_CTX_use_certificate_chain_file(self._context, certfile)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800385 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500386 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800387
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800388
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800389 def use_certificate_file(self, certfile, filetype=FILETYPE_PEM):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800390 """
391 Load a certificate from a file
392
393 :param certfile: The name of the certificate file
394 :param filetype: (optional) The encoding of the file, default is PEM
395 :return: None
396 """
Jean-Paul Calderone684baf52014-01-18 10:31:19 -0500397 if isinstance(certfile, _text_type):
398 # Perhaps sys.getfilesystemencoding() could be better?
399 certfile = certfile.encode("utf-8")
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800400 if not isinstance(certfile, bytes):
Jean-Paul Calderone684baf52014-01-18 10:31:19 -0500401 raise TypeError("certfile must be bytes or unicode")
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -0500402 if not isinstance(filetype, integer_types):
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800403 raise TypeError("filetype must be an integer")
404
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500405 use_result = _lib.SSL_CTX_use_certificate_file(self._context, certfile, filetype)
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800406 if not use_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500407 _raise_current_error()
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800408
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800409
410 def use_certificate(self, cert):
411 """
412 Load a certificate from a X509 object
413
414 :param cert: The X509 object
415 :return: None
416 """
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800417 if not isinstance(cert, X509):
418 raise TypeError("cert must be an X509 instance")
419
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500420 use_result = _lib.SSL_CTX_use_certificate(self._context, cert._x509)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800421 if not use_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500422 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800423
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800424
425 def add_extra_chain_cert(self, certobj):
426 """
427 Add certificate to chain
428
429 :param certobj: The X509 certificate object to add to the chain
430 :return: None
431 """
432 if not isinstance(certobj, X509):
433 raise TypeError("certobj must be an X509 instance")
434
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500435 copy = _lib.X509_dup(certobj._x509)
436 add_result = _lib.SSL_CTX_add_extra_chain_cert(self._context, copy)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800437 if not add_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500438 # TODO: This is untested.
439 _lib.X509_free(copy)
440 _raise_current_error()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800441
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800442
443 def _raise_passphrase_exception(self):
444 if self._passphrase_helper is None:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500445 _raise_current_error()
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800446 exception = self._passphrase_helper.raise_if_problem(Error)
447 if exception is not None:
448 raise exception
449
450
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800451 def use_privatekey_file(self, keyfile, filetype=_unspecified):
452 """
453 Load a private key from a file
454
455 :param keyfile: The name of the key file
456 :param filetype: (optional) The encoding of the file, default is PEM
457 :return: None
458 """
Jean-Paul Calderone87e525a2014-01-18 10:31:51 -0500459 if isinstance(keyfile, _text_type):
460 # Perhaps sys.getfilesystemencoding() could be better?
461 keyfile = keyfile.encode("utf-8")
462
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800463 if not isinstance(keyfile, bytes):
464 raise TypeError("keyfile must be a byte string")
465
466 if filetype is _unspecified:
467 filetype = FILETYPE_PEM
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -0500468 elif not isinstance(filetype, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800469 raise TypeError("filetype must be an integer")
470
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500471 use_result = _lib.SSL_CTX_use_PrivateKey_file(
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800472 self._context, keyfile, filetype)
473 if not use_result:
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800474 self._raise_passphrase_exception()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800475
476
477 def use_privatekey(self, pkey):
478 """
479 Load a private key from a PKey object
480
481 :param pkey: The PKey object
482 :return: None
483 """
484 if not isinstance(pkey, PKey):
485 raise TypeError("pkey must be a PKey instance")
486
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500487 use_result = _lib.SSL_CTX_use_PrivateKey(self._context, pkey._pkey)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800488 if not use_result:
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800489 self._raise_passphrase_exception()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800490
491
492 def check_privatekey(self):
493 """
494 Check that the private key and certificate match up
495
496 :return: None (raises an exception if something's wrong)
497 """
498
499 def load_client_ca(self, cafile):
500 """
501 Load the trusted certificates that will be sent to the client (basically
502 telling the client "These are the guys I trust"). Does not actually
503 imply any of the certificates are trusted; that must be configured
504 separately.
505
506 :param cafile: The name of the certificates file
507 :return: None
508 """
509
510 def set_session_id(self, buf):
511 """
512 Set the session identifier. This is needed if you want to do session
513 resumption.
514
515 :param buf: A Python object that can be safely converted to a string
516 :returns: None
517 """
518
519 def set_session_cache_mode(self, mode):
520 """
521 Enable/disable session caching and specify the mode used.
522
523 :param mode: One or more of the SESS_CACHE_* flags (combine using
524 bitwise or)
525 :returns: The previously set caching mode.
526 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500527 if not isinstance(mode, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800528 raise TypeError("mode must be an integer")
529
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500530 return _lib.SSL_CTX_set_session_cache_mode(self._context, mode)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800531
532
533 def get_session_cache_mode(self):
534 """
535 :returns: The currently used cache mode.
536 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500537 return _lib.SSL_CTX_get_session_cache_mode(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800538
539
540 def set_verify(self, mode, callback):
541 """
542 Set the verify mode and verify callback
543
544 :param mode: The verify mode, this is either VERIFY_NONE or
545 VERIFY_PEER combined with possible other flags
546 :param callback: The Python callback to use
547 :return: None
548
549 See SSL_CTX_set_verify(3SSL) for further details.
550 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500551 if not isinstance(mode, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800552 raise TypeError("mode must be an integer")
553
554 if not callable(callback):
555 raise TypeError("callback must be callable")
556
Jean-Paul Calderone6a8cd112014-04-02 21:09:08 -0400557 self._verify_helper = _VerifyHelper(callback)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800558 self._verify_callback = self._verify_helper.callback
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500559 _lib.SSL_CTX_set_verify(self._context, mode, self._verify_callback)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800560
561
562 def set_verify_depth(self, depth):
563 """
564 Set the verify depth
565
566 :param depth: An integer specifying the verify depth
567 :return: None
568 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500569 if not isinstance(depth, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800570 raise TypeError("depth must be an integer")
571
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500572 _lib.SSL_CTX_set_verify_depth(self._context, depth)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800573
574
575 def get_verify_mode(self):
576 """
577 Get the verify mode
578
579 :return: The verify mode
580 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500581 return _lib.SSL_CTX_get_verify_mode(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800582
583
584 def get_verify_depth(self):
585 """
586 Get the verify depth
587
588 :return: The verify depth
589 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500590 return _lib.SSL_CTX_get_verify_depth(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800591
592
593 def load_tmp_dh(self, dhfile):
594 """
595 Load parameters for Ephemeral Diffie-Hellman
596
597 :param dhfile: The file to load EDH parameters from
598 :return: None
599 """
600 if not isinstance(dhfile, bytes):
601 raise TypeError("dhfile must be a byte string")
602
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -0500603 bio = _lib.BIO_new_file(dhfile, b"r")
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500604 if bio == _ffi.NULL:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500605 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500606 bio = _ffi.gc(bio, _lib.BIO_free)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800607
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500608 dh = _lib.PEM_read_bio_DHparams(bio, _ffi.NULL, _ffi.NULL, _ffi.NULL)
609 dh = _ffi.gc(dh, _lib.DH_free)
610 _lib.SSL_CTX_set_tmp_dh(self._context, dh)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800611
612
Jean-Paul Calderone3e4e3352014-04-19 09:28:28 -0400613 def set_tmp_ecdh(self, curve):
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600614 """
Andy Lutomirski76a61332014-03-12 15:02:56 -0700615 Select a curve to use for ECDHE key exchange.
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600616
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -0400617 :param curve: A curve object to use as returned by either
618 :py:meth:`OpenSSL.crypto.get_elliptic_curve` or
619 :py:meth:`OpenSSL.crypto.get_elliptic_curves`.
Andy Lutomirskif05a2732014-03-13 17:22:25 -0700620
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600621 :return: None
622 """
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -0400623 _lib.SSL_CTX_set_tmp_ecdh(self._context, curve._to_EC_KEY())
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600624
625
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800626 def set_cipher_list(self, cipher_list):
627 """
628 Change the cipher list
629
630 :param cipher_list: A cipher list, see ciphers(1)
631 :return: None
632 """
Jean-Paul Calderone63eab692014-01-18 10:19:56 -0500633 if isinstance(cipher_list, _text_type):
634 cipher_list = cipher_list.encode("ascii")
635
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800636 if not isinstance(cipher_list, bytes):
Jean-Paul Calderone63eab692014-01-18 10:19:56 -0500637 raise TypeError("cipher_list must be bytes or unicode")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800638
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500639 result = _lib.SSL_CTX_set_cipher_list(self._context, cipher_list)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800640 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500641 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800642
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800643
644 def set_client_ca_list(self, certificate_authorities):
645 """
646 Set the list of preferred client certificate signers for this server context.
647
648 This list of certificate authorities will be sent to the client when the
649 server requests a client certificate.
650
651 :param certificate_authorities: a sequence of X509Names.
652 :return: None
653 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500654 name_stack = _lib.sk_X509_NAME_new_null()
655 if name_stack == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500656 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500657 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800658
659 try:
660 for ca_name in certificate_authorities:
661 if not isinstance(ca_name, X509Name):
662 raise TypeError(
663 "client CAs must be X509Name objects, not %s objects" % (
664 type(ca_name).__name__,))
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500665 copy = _lib.X509_NAME_dup(ca_name._name)
666 if copy == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500667 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500668 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500669 push_result = _lib.sk_X509_NAME_push(name_stack, copy)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800670 if not push_result:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500671 _lib.X509_NAME_free(copy)
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500672 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800673 except:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500674 _lib.sk_X509_NAME_free(name_stack)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800675 raise
676
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500677 _lib.SSL_CTX_set_client_CA_list(self._context, name_stack)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800678
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800679
680 def add_client_ca(self, certificate_authority):
681 """
682 Add the CA certificate to the list of preferred signers for this context.
683
684 The list of certificate authorities will be sent to the client when the
685 server requests a client certificate.
686
687 :param certificate_authority: certificate authority's X509 certificate.
688 :return: None
689 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800690 if not isinstance(certificate_authority, X509):
691 raise TypeError("certificate_authority must be an X509 instance")
692
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500693 add_result = _lib.SSL_CTX_add_client_CA(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800694 self._context, certificate_authority._x509)
695 if not add_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500696 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500697 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800698
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800699
700 def set_timeout(self, timeout):
701 """
702 Set session timeout
703
704 :param timeout: The timeout in seconds
705 :return: The previous session timeout
706 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500707 if not isinstance(timeout, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800708 raise TypeError("timeout must be an integer")
709
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500710 return _lib.SSL_CTX_set_timeout(self._context, timeout)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800711
712
713 def get_timeout(self):
714 """
715 Get the session timeout
716
717 :return: The session timeout
718 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500719 return _lib.SSL_CTX_get_timeout(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800720
721
722 def set_info_callback(self, callback):
723 """
724 Set the info callback
725
726 :param callback: The Python callback to use
727 :return: None
728 """
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800729 @wraps(callback)
730 def wrapper(ssl, where, return_code):
Jean-Paul Calderonef2bbc9c2014-02-02 10:59:14 -0500731 callback(Connection._reverse_mapping[ssl], where, return_code)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500732 self._info_callback = _ffi.callback(
733 "void (*)(const SSL *, int, int)", wrapper)
734 _lib.SSL_CTX_set_info_callback(self._context, self._info_callback)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800735
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800736
737 def get_app_data(self):
738 """
739 Get the application data (supplied via set_app_data())
740
741 :return: The application data
742 """
743 return self._app_data
744
745
746 def set_app_data(self, data):
747 """
748 Set the application data (will be returned from get_app_data())
749
750 :param data: Any Python object
751 :return: None
752 """
753 self._app_data = data
754
755
756 def get_cert_store(self):
757 """
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500758 Get the certificate store for the context.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800759
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500760 :return: A X509Store object or None if it does not have one.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800761 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500762 store = _lib.SSL_CTX_get_cert_store(self._context)
763 if store == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500764 # TODO: This is untested.
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800765 return None
766
767 pystore = X509Store.__new__(X509Store)
768 pystore._store = store
769 return pystore
770
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800771
772 def set_options(self, options):
773 """
774 Add options. Options set before are not cleared!
775
776 :param options: The options to add.
777 :return: The new option bitmask.
778 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500779 if not isinstance(options, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800780 raise TypeError("options must be an integer")
781
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500782 return _lib.SSL_CTX_set_options(self._context, options)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800783
784
785 def set_mode(self, mode):
786 """
787 Add modes via bitmask. Modes set before are not cleared!
788
789 :param mode: The mode to add.
790 :return: The new mode bitmask.
791 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500792 if not isinstance(mode, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800793 raise TypeError("mode must be an integer")
794
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500795 return _lib.SSL_CTX_set_mode(self._context, mode)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800796
797
798 def set_tlsext_servername_callback(self, callback):
799 """
800 Specify a callback function to be called when clients specify a server name.
801
802 :param callback: The callback function. It will be invoked with one
803 argument, the Connection instance.
804 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800805 @wraps(callback)
806 def wrapper(ssl, alert, arg):
807 callback(Connection._reverse_mapping[ssl])
808 return 0
809
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500810 self._tlsext_servername_callback = _ffi.callback(
811 "int (*)(const SSL *, int *, void *)", wrapper)
812 _lib.SSL_CTX_set_tlsext_servername_callback(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800813 self._context, self._tlsext_servername_callback)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800814
Cory Benfield84a121e2014-03-31 20:30:25 +0100815
816 def set_npn_advertise_callback(self, callback):
817 """
Cory Benfieldbe3e7b82014-05-10 09:48:55 +0100818 Specify a callback function that will be called when offering `Next
819 Protocol Negotiation
820 <https://technotes.googlecode.com/git/nextprotoneg.html>`_ as a server.
Cory Benfield84a121e2014-03-31 20:30:25 +0100821
822 :param callback: The callback function. It will be invoked with one
Cory Benfieldbe3e7b82014-05-10 09:48:55 +0100823 argument, the Connection instance. It should return a list of
824 bytestrings representing the advertised protocols, like
825 ``[b'http/1.1', b'spdy/2']``.
Cory Benfield84a121e2014-03-31 20:30:25 +0100826 """
827 @wraps(callback)
828 def wrapper(ssl, out, outlen, arg):
Cory Benfieldbe3e7b82014-05-10 09:48:55 +0100829 conn = Connection._reverse_mapping[ssl]
830 protos = callback(conn)
831
832 # Join the protocols into a Python bytestring, length-prefixing
833 # each element.
834 protostr = b''.join(
835 chain.from_iterable((int2byte(len(p)), p) for p in protos)
836 )
837
838 # Save our callback arguments on the connection object. This is
839 # done to make sure that they don't get freed before OpenSSL uses
840 # them. Then, return them appropriately in the output parameters.
841 conn._npn_advertise_callback_args = [
842 _ffi.new("unsigned int *", len(protostr)),
843 _ffi.new("unsigned char[]", protostr),
Cory Benfield84a121e2014-03-31 20:30:25 +0100844 ]
Cory Benfieldbe3e7b82014-05-10 09:48:55 +0100845 outlen[0] = conn._npn_advertise_callback_args[0][0]
846 out[0] = conn._npn_advertise_callback_args[1]
Cory Benfield84a121e2014-03-31 20:30:25 +0100847 return 0
848
849 self._npn_advertise_callback = _ffi.callback(
850 "int (*)(SSL *, const unsigned char **, unsigned int *, void *)",
851 wrapper)
852 _lib.SSL_CTX_set_next_protos_advertised_cb(
853 self._context, self._npn_advertise_callback, _ffi.NULL)
854
855
856 def set_npn_select_callback(self, callback):
857 """
858 Specify a callback function that will be called when a server offers
859 Next Protocol Negotiation options.
860
861 :param callback: The callback function. It will be invoked with two
862 arguments: the Connection, and a list of offered protocols as
Cory Benfieldbe3e7b82014-05-10 09:48:55 +0100863 bytestrings, e.g. ``[b'http/1.1', b'spdy/2']``. It should return
864 one of those bytestrings, the chosen protocol.
Cory Benfield84a121e2014-03-31 20:30:25 +0100865 """
866 @wraps(callback)
867 def wrapper(ssl, out, outlen, in_, inlen, arg):
Cory Benfieldbe3e7b82014-05-10 09:48:55 +0100868 conn = Connection._reverse_mapping[ssl]
869
870 # The string passed to us is actually made up of multiple
871 # length-prefixed bytestrings. We need to split that into a list.
Cory Benfield4969c222014-05-27 14:19:34 +0100872 instr = _ffi.buffer(in_, inlen)[:]
Cory Benfieldbe3e7b82014-05-10 09:48:55 +0100873 protolist = []
874 while instr:
Cory Benfieldcd010f62014-05-15 19:00:27 +0100875 l = indexbytes(instr, 0)
Cory Benfieldbe3e7b82014-05-10 09:48:55 +0100876 proto = instr[1:l+1]
877 protolist.append(proto)
878 instr = instr[l+1:]
879
880 # Call the callback
881 outstr = callback(conn, protolist)
882
883 # Save our callback arguments on the connection object. This is
884 # done to make sure that they don't get freed before OpenSSL uses
885 # them. Then, return them appropriately in the output parameters.
886 conn._npn_select_callback_args = [
Cory Benfield84a121e2014-03-31 20:30:25 +0100887 _ffi.new("unsigned char *", len(outstr)),
888 _ffi.new("unsigned char[]", outstr),
889 ]
Cory Benfieldbe3e7b82014-05-10 09:48:55 +0100890 outlen[0] = conn._npn_select_callback_args[0][0]
891 out[0] = conn._npn_select_callback_args[1]
Cory Benfield84a121e2014-03-31 20:30:25 +0100892 return 0
893
894 self._npn_select_callback = _ffi.callback(
895 "int (*)(SSL *, unsigned char **, unsigned char *, "
896 "const unsigned char *, unsigned int, void *)",
897 wrapper)
898 _lib.SSL_CTX_set_next_proto_select_cb(
899 self._context, self._npn_select_callback, _ffi.NULL)
900
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800901ContextType = Context
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800902
903
904
905class Connection(object):
906 """
907 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800908 _reverse_mapping = WeakValueDictionary()
909
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800910 def __init__(self, context, socket=None):
911 """
912 Create a new Connection object, using the given OpenSSL.SSL.Context
913 instance and socket.
914
915 :param context: An SSL Context to use for this connection
916 :param socket: The socket to use for transport layer
917 """
918 if not isinstance(context, Context):
919 raise TypeError("context must be a Context instance")
920
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500921 ssl = _lib.SSL_new(context._context)
922 self._ssl = _ffi.gc(ssl, _lib.SSL_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800923 self._context = context
924
Cory Benfieldbe3e7b82014-05-10 09:48:55 +0100925 # References to strings used for Next Protocol Negotiation. OpenSSL's
926 # header files suggest that these might get copied at some point, but
927 # doesn't specify when, so we store them here to make sure they don't
928 # get freed before OpenSSL uses them.
929 self._npn_advertise_callback_args = None
930 self._npn_select_callback_args = None
931
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800932 self._reverse_mapping[self._ssl] = self
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800933
934 if socket is None:
935 self._socket = None
Jean-Paul Calderone73b15c22013-03-05 18:30:39 -0800936 # Don't set up any gc for these, SSL_free will take care of them.
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500937 self._into_ssl = _lib.BIO_new(_lib.BIO_s_mem())
938 self._from_ssl = _lib.BIO_new(_lib.BIO_s_mem())
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800939
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500940 if self._into_ssl == _ffi.NULL or self._from_ssl == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500941 # TODO: This is untested.
942 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800943
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500944 _lib.SSL_set_bio(self._ssl, self._into_ssl, self._from_ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800945 else:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800946 self._into_ssl = None
947 self._from_ssl = None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800948 self._socket = socket
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500949 set_result = _lib.SSL_set_fd(self._ssl, _asFileDescriptor(self._socket))
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800950 if not set_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500951 # TODO: This is untested.
952 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800953
954
955 def __getattr__(self, name):
956 """
957 Look up attributes on the wrapped socket object if they are not found on
958 the Connection object.
959 """
960 return getattr(self._socket, name)
961
962
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800963 def _raise_ssl_error(self, ssl, result):
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800964 if self._context._verify_helper is not None:
965 self._context._verify_helper.raise_if_problem()
966
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500967 error = _lib.SSL_get_error(ssl, result)
968 if error == _lib.SSL_ERROR_WANT_READ:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800969 raise WantReadError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500970 elif error == _lib.SSL_ERROR_WANT_WRITE:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -0700971 raise WantWriteError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500972 elif error == _lib.SSL_ERROR_ZERO_RETURN:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800973 raise ZeroReturnError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500974 elif error == _lib.SSL_ERROR_WANT_X509_LOOKUP:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500975 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -0700976 raise WantX509LookupError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500977 elif error == _lib.SSL_ERROR_SYSCALL:
978 if _lib.ERR_peek_error() == 0:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800979 if result < 0:
Konstantinos Koukopoulos541150d2014-01-31 01:00:19 +0200980 if platform == "win32":
981 errno = _ffi.getwinerror()[0]
982 else:
983 errno = _ffi.errno
984 raise SysCallError(errno, errorcode[errno])
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800985 else:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -0700986 raise SysCallError(-1, "Unexpected EOF")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800987 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500988 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500989 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500990 elif error == _lib.SSL_ERROR_NONE:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -0700991 pass
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800992 else:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500993 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800994
995
996 def get_context(self):
997 """
998 Get session context
999 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001000 return self._context
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001001
1002
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001003 def set_context(self, context):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001004 """
1005 Switch this connection to a new session context
1006
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001007 :param context: A :py:class:`Context` instance giving the new session
1008 context to use.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001009 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001010 if not isinstance(context, Context):
1011 raise TypeError("context must be a Context instance")
1012
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001013 _lib.SSL_set_SSL_CTX(self._ssl, context._context)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001014 self._context = context
1015
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001016
1017 def get_servername(self):
1018 """
1019 Retrieve the servername extension value if provided in the client hello
1020 message, or None if there wasn't one.
1021
1022 :return: A byte string giving the server name or :py:data:`None`.
1023 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001024 name = _lib.SSL_get_servername(self._ssl, _lib.TLSEXT_NAMETYPE_host_name)
1025 if name == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001026 return None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001027
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001028 return _ffi.string(name)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001029
1030
1031 def set_tlsext_host_name(self, name):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001032 """
1033 Set the value of the servername extension to send in the client hello.
1034
1035 :param name: A byte string giving the name.
1036 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001037 if not isinstance(name, bytes):
1038 raise TypeError("name must be a byte string")
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001039 elif b"\0" in name:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001040 raise TypeError("name must not contain NUL byte")
1041
1042 # XXX I guess this can fail sometimes?
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001043 _lib.SSL_set_tlsext_host_name(self._ssl, name)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001044
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001045
1046 def pending(self):
1047 """
1048 Get the number of bytes that can be safely read from the connection
1049
1050 :return: The number of bytes available in the receive buffer.
1051 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001052 return _lib.SSL_pending(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001053
1054
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001055 def send(self, buf, flags=0):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001056 """
1057 Send data on the connection. NOTE: If you get one of the WantRead,
1058 WantWrite or WantX509Lookup exceptions on this, you have to call the
1059 method again with the SAME buffer.
1060
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001061 :param buf: The string, buffer or memoryview to send
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001062 :param flags: (optional) Included for compatibility with the socket
1063 API, the value is ignored
1064 :return: The number of bytes written
1065 """
Jean-Paul Calderone8fb53182013-12-30 08:35:49 -05001066 if isinstance(buf, _memoryview):
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -08001067 buf = buf.tobytes()
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001068 if isinstance(buf, _buffer):
1069 buf = str(buf)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001070 if not isinstance(buf, bytes):
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001071 raise TypeError("data must be a memoryview, buffer or byte string")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001072
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001073 result = _lib.SSL_write(self._ssl, buf, len(buf))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001074 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001075 return result
1076 write = send
1077
1078
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001079 def sendall(self, buf, flags=0):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001080 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001081 Send "all" data on the connection. This calls send() repeatedly until
1082 all data is sent. If an error occurs, it's impossible to tell how much
1083 data has been sent.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001084
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001085 :param buf: The string, buffer or memoryview to send
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001086 :param flags: (optional) Included for compatibility with the socket
1087 API, the value is ignored
1088 :return: The number of bytes written
1089 """
Jean-Paul Calderone8fb53182013-12-30 08:35:49 -05001090 if isinstance(buf, _memoryview):
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -08001091 buf = buf.tobytes()
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001092 if isinstance(buf, _buffer):
1093 buf = str(buf)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001094 if not isinstance(buf, bytes):
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001095 raise TypeError("buf must be a memoryview, buffer or byte string")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001096
1097 left_to_send = len(buf)
1098 total_sent = 0
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001099 data = _ffi.new("char[]", buf)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001100
1101 while left_to_send:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001102 result = _lib.SSL_write(self._ssl, data + total_sent, left_to_send)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001103 self._raise_ssl_error(self._ssl, result)
1104 total_sent += result
1105 left_to_send -= result
1106
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001107
1108 def recv(self, bufsiz, flags=None):
1109 """
1110 Receive data on the connection. NOTE: If you get one of the WantRead,
1111 WantWrite or WantX509Lookup exceptions on this, you have to call the
1112 method again with the SAME buffer.
1113
1114 :param bufsiz: The maximum number of bytes to read
1115 :param flags: (optional) Included for compatibility with the socket
1116 API, the value is ignored
1117 :return: The string read from the Connection
1118 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001119 buf = _ffi.new("char[]", bufsiz)
1120 result = _lib.SSL_read(self._ssl, buf, bufsiz)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001121 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001122 return _ffi.buffer(buf, result)[:]
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001123 read = recv
1124
1125
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001126 def _handle_bio_errors(self, bio, result):
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001127 if _lib.BIO_should_retry(bio):
1128 if _lib.BIO_should_read(bio):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001129 raise WantReadError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001130 elif _lib.BIO_should_write(bio):
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001131 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001132 raise WantWriteError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001133 elif _lib.BIO_should_io_special(bio):
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001134 # TODO: This is untested. I think io_special means the socket
1135 # BIO has a not-yet connected socket.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001136 raise ValueError("BIO_should_io_special")
1137 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001138 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001139 raise ValueError("unknown bio failure")
1140 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001141 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001142 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001143
1144
1145 def bio_read(self, bufsiz):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001146 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001147 When using non-socket connections this function reads the "dirty" data
1148 that would have traveled away on the network.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001149
1150 :param bufsiz: The maximum number of bytes to read
1151 :return: The string read.
1152 """
Jean-Paul Calderone97e041d2013-03-05 21:03:12 -08001153 if self._from_ssl is None:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001154 raise TypeError("Connection sock was not None")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001155
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -05001156 if not isinstance(bufsiz, integer_types):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001157 raise TypeError("bufsiz must be an integer")
1158
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001159 buf = _ffi.new("char[]", bufsiz)
1160 result = _lib.BIO_read(self._from_ssl, buf, bufsiz)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001161 if result <= 0:
1162 self._handle_bio_errors(self._from_ssl, result)
1163
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001164 return _ffi.buffer(buf, result)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001165
1166
1167 def bio_write(self, buf):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001168 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001169 When using non-socket connections this function sends "dirty" data that
1170 would have traveled in on the network.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001171
1172 :param buf: The string to put into the memory BIO.
1173 :return: The number of bytes written
1174 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001175 if self._into_ssl is None:
1176 raise TypeError("Connection sock was not None")
1177
1178 if not isinstance(buf, bytes):
1179 raise TypeError("buf must be a byte string")
1180
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001181 result = _lib.BIO_write(self._into_ssl, buf, len(buf))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001182 if result <= 0:
1183 self._handle_bio_errors(self._into_ssl, result)
1184 return result
1185
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001186
1187 def renegotiate(self):
1188 """
1189 Renegotiate the session
1190
1191 :return: True if the renegotiation can be started, false otherwise
1192 """
1193
1194 def do_handshake(self):
1195 """
1196 Perform an SSL handshake (usually called after renegotiate() or one of
1197 set_*_state()). This can raise the same exceptions as send and recv.
1198
1199 :return: None.
1200 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001201 result = _lib.SSL_do_handshake(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001202 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001203
1204
1205 def renegotiate_pending(self):
1206 """
1207 Check if there's a renegotiation in progress, it will return false once
1208 a renegotiation is finished.
1209
1210 :return: Whether there's a renegotiation in progress
1211 """
1212
1213 def total_renegotiations(self):
1214 """
1215 Find out the total number of renegotiations.
1216
1217 :return: The number of renegotiations.
1218 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001219 return _lib.SSL_total_renegotiations(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001220
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001221
1222 def connect(self, addr):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001223 """
1224 Connect to remote host and set up client-side SSL
1225
1226 :param addr: A remote address
1227 :return: What the socket's connect method returns
1228 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001229 _lib.SSL_set_connect_state(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001230 return self._socket.connect(addr)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001231
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001232
1233 def connect_ex(self, addr):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001234 """
1235 Connect to remote host and set up client-side SSL. Note that if the socket's
1236 connect_ex method doesn't return 0, SSL won't be initialized.
1237
1238 :param addr: A remove address
1239 :return: What the socket's connect_ex method returns
1240 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001241 connect_ex = self._socket.connect_ex
1242 self.set_connect_state()
1243 return connect_ex(addr)
1244
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001245
1246 def accept(self):
1247 """
1248 Accept incoming connection and set up SSL on it
1249
1250 :return: A (conn,addr) pair where conn is a Connection and addr is an
1251 address
1252 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001253 client, addr = self._socket.accept()
1254 conn = Connection(self._context, client)
1255 conn.set_accept_state()
1256 return (conn, addr)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001257
1258
1259 def bio_shutdown(self):
1260 """
1261 When using non-socket connections this function signals end of
1262 data on the input for this connection.
1263
1264 :return: None
1265 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001266 if self._from_ssl is None:
1267 raise TypeError("Connection sock was not None")
1268
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001269 _lib.BIO_set_mem_eof_return(self._into_ssl, 0)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001270
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001271
1272 def shutdown(self):
1273 """
1274 Send closure alert
1275
1276 :return: True if the shutdown completed successfully (i.e. both sides
1277 have sent closure alerts), false otherwise (i.e. you have to
1278 wait for a ZeroReturnError on a recv() method call
1279 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001280 result = _lib.SSL_shutdown(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001281 if result < 0:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001282 # TODO: This is untested.
1283 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001284 elif result > 0:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001285 return True
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001286 else:
1287 return False
1288
1289
1290 def get_cipher_list(self):
1291 """
1292 Get the session cipher list
1293
1294 :return: A list of cipher strings
1295 """
1296 ciphers = []
1297 for i in count():
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001298 result = _lib.SSL_get_cipher_list(self._ssl, i)
1299 if result == _ffi.NULL:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001300 break
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001301 ciphers.append(_native(_ffi.string(result)))
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001302 return ciphers
1303
1304
1305 def get_client_ca_list(self):
1306 """
1307 Get CAs whose certificates are suggested for client authentication.
1308
1309 :return: If this is a server connection, a list of X509Names representing
1310 the acceptable CAs as set by :py:meth:`OpenSSL.SSL.Context.set_client_ca_list` or
1311 :py:meth:`OpenSSL.SSL.Context.add_client_ca`. If this is a client connection,
1312 the list of such X509Names sent by the server, or an empty list if that
1313 has not yet happened.
1314 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001315 ca_names = _lib.SSL_get_client_CA_list(self._ssl)
1316 if ca_names == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001317 # TODO: This is untested.
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001318 return []
1319
1320 result = []
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001321 for i in range(_lib.sk_X509_NAME_num(ca_names)):
1322 name = _lib.sk_X509_NAME_value(ca_names, i)
1323 copy = _lib.X509_NAME_dup(name)
1324 if copy == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001325 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001326 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001327
1328 pyname = X509Name.__new__(X509Name)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001329 pyname._name = _ffi.gc(copy, _lib.X509_NAME_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001330 result.append(pyname)
1331 return result
1332
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001333
1334 def makefile(self):
1335 """
1336 The makefile() method is not implemented, since there is no dup semantics
1337 for SSL connections
1338
Jean-Paul Calderone6749ec22014-04-17 16:30:21 -04001339 :raise: NotImplementedError
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001340 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001341 raise NotImplementedError("Cannot make file object of OpenSSL.SSL.Connection")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001342
1343
1344 def get_app_data(self):
1345 """
1346 Get application data
1347
1348 :return: The application data
1349 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001350 return self._app_data
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001351
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001352
1353 def set_app_data(self, data):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001354 """
1355 Set application data
1356
1357 :param data - The application data
1358 :return: None
1359 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001360 self._app_data = data
1361
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001362
1363 def get_shutdown(self):
1364 """
1365 Get shutdown state
1366
1367 :return: The shutdown state, a bitvector of SENT_SHUTDOWN, RECEIVED_SHUTDOWN.
1368 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001369 return _lib.SSL_get_shutdown(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001370
1371
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001372 def set_shutdown(self, state):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001373 """
1374 Set shutdown state
1375
1376 :param state - bitvector of SENT_SHUTDOWN, RECEIVED_SHUTDOWN.
1377 :return: None
1378 """
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -05001379 if not isinstance(state, integer_types):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001380 raise TypeError("state must be an integer")
1381
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001382 _lib.SSL_set_shutdown(self._ssl, state)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001383
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001384
1385 def state_string(self):
1386 """
1387 Get a verbose state description
1388
1389 :return: A string representing the state
1390 """
1391
1392 def server_random(self):
1393 """
1394 Get a copy of the server hello nonce.
1395
1396 :return: A string representing the state
1397 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001398 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001399 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001400 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001401 self._ssl.s3.server_random,
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001402 _lib.SSL3_RANDOM_SIZE)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001403
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001404
1405 def client_random(self):
1406 """
1407 Get a copy of the client hello nonce.
1408
1409 :return: A string representing the state
1410 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001411 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001412 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001413 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001414 self._ssl.s3.client_random,
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001415 _lib.SSL3_RANDOM_SIZE)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001416
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001417
1418 def master_key(self):
1419 """
1420 Get a copy of the master key.
1421
1422 :return: A string representing the state
1423 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001424 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001425 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001426 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001427 self._ssl.session.master_key,
1428 self._ssl.session.master_key_length)[:]
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001429
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001430
1431 def sock_shutdown(self, *args, **kwargs):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001432 """
1433 See shutdown(2)
1434
1435 :return: What the socket's shutdown() method returns
1436 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001437 return self._socket.shutdown(*args, **kwargs)
1438
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001439
1440 def get_peer_certificate(self):
1441 """
1442 Retrieve the other side's certificate (if any)
1443
1444 :return: The peer's certificate
1445 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001446 cert = _lib.SSL_get_peer_certificate(self._ssl)
1447 if cert != _ffi.NULL:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001448 pycert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001449 pycert._x509 = _ffi.gc(cert, _lib.X509_free)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001450 return pycert
1451 return None
1452
1453
1454 def get_peer_cert_chain(self):
1455 """
1456 Retrieve the other side's certificate (if any)
1457
1458 :return: A list of X509 instances giving the peer's certificate chain,
1459 or None if it does not have one.
1460 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001461 cert_stack = _lib.SSL_get_peer_cert_chain(self._ssl)
1462 if cert_stack == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001463 return None
1464
1465 result = []
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001466 for i in range(_lib.sk_X509_num(cert_stack)):
Jean-Paul Calderone73b15c22013-03-05 18:30:39 -08001467 # TODO could incref instead of dup here
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001468 cert = _lib.X509_dup(_lib.sk_X509_value(cert_stack, i))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001469 pycert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001470 pycert._x509 = _ffi.gc(cert, _lib.X509_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001471 result.append(pycert)
1472 return result
1473
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001474
1475 def want_read(self):
1476 """
1477 Checks if more data has to be read from the transport layer to complete an
1478 operation.
1479
1480 :return: True iff more data has to be read
1481 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001482 return _lib.SSL_want_read(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001483
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001484
1485 def want_write(self):
1486 """
1487 Checks if there is data to write to the transport layer to complete an
1488 operation.
1489
1490 :return: True iff there is data to write
1491 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001492 return _lib.SSL_want_write(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001493
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001494
1495 def set_accept_state(self):
1496 """
1497 Set the connection to work in server mode. The handshake will be handled
1498 automatically by read/write.
1499
1500 :return: None
1501 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001502 _lib.SSL_set_accept_state(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001503
1504
1505 def set_connect_state(self):
1506 """
1507 Set the connection to work in client mode. The handshake will be handled
1508 automatically by read/write.
1509
1510 :return: None
1511 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001512 _lib.SSL_set_connect_state(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001513
1514
1515 def get_session(self):
1516 """
1517 Returns the Session currently used.
1518
1519 @return: An instance of :py:class:`OpenSSL.SSL.Session` or :py:obj:`None` if
1520 no session exists.
1521 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001522 session = _lib.SSL_get1_session(self._ssl)
1523 if session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001524 return None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001525
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001526 pysession = Session.__new__(Session)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001527 pysession._session = _ffi.gc(session, _lib.SSL_SESSION_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001528 return pysession
1529
1530
1531 def set_session(self, session):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001532 """
1533 Set the session to be used when the TLS/SSL connection is established.
1534
1535 :param session: A Session instance representing the session to use.
1536 :returns: None
1537 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001538 if not isinstance(session, Session):
1539 raise TypeError("session must be a Session instance")
1540
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001541 result = _lib.SSL_set_session(self._ssl, session._session)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001542 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001543 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001544
Jean-Paul Calderonedbd76272014-03-29 18:09:40 -04001545
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001546 def _get_finished_message(self, function):
1547 """
1548 Helper to implement :py:meth:`get_finished` and
1549 :py:meth:`get_peer_finished`.
1550
1551 :param function: Either :py:data:`SSL_get_finished`: or
1552 :py:data:`SSL_get_peer_finished`.
1553
1554 :return: :py:data:`None` if the desired message has not yet been
1555 received, otherwise the contents of the message.
1556 :rtype: :py:class:`bytes` or :py:class:`NoneType`
1557 """
Jean-Paul Calderone01af9042014-03-30 11:40:42 -04001558 # The OpenSSL documentation says nothing about what might happen if the
1559 # count argument given is zero. Specifically, it doesn't say whether
1560 # the output buffer may be NULL in that case or not. Inspection of the
1561 # implementation reveals that it calls memcpy() unconditionally.
1562 # Section 7.1.4, paragraph 1 of the C standard suggests that
1563 # memcpy(NULL, source, 0) is not guaranteed to produce defined (let
1564 # alone desirable) behavior (though it probably does on just about
1565 # every implementation...)
1566 #
1567 # Allocate a tiny buffer to pass in (instead of just passing NULL as
1568 # one might expect) for the initial call so as to be safe against this
1569 # potentially undefined behavior.
1570 empty = _ffi.new("char[]", 0)
1571 size = function(self._ssl, empty, 0)
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001572 if size == 0:
1573 # No Finished message so far.
1574 return None
1575
1576 buf = _ffi.new("char[]", size)
1577 function(self._ssl, buf, size)
1578 return _ffi.buffer(buf, size)[:]
1579
1580
Fedor Brunner5747b932014-03-05 14:22:34 +01001581 def get_finished(self):
1582 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001583 Obtain the latest `handshake finished` message sent to the peer.
Fedor Brunner5747b932014-03-05 14:22:34 +01001584
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001585 :return: The contents of the message or :py:obj:`None` if the TLS
1586 handshake has not yet completed.
1587 :rtype: :py:class:`bytes` or :py:class:`NoneType`
Fedor Brunner5747b932014-03-05 14:22:34 +01001588 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001589 return self._get_finished_message(_lib.SSL_get_finished)
1590
Fedor Brunner5747b932014-03-05 14:22:34 +01001591
1592 def get_peer_finished(self):
1593 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001594 Obtain the latest `handshake finished` message received from the peer.
Fedor Brunner5747b932014-03-05 14:22:34 +01001595
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001596 :return: The contents of the message or :py:obj:`None` if the TLS
1597 handshake has not yet completed.
1598 :rtype: :py:class:`bytes` or :py:class:`NoneType`
Fedor Brunner5747b932014-03-05 14:22:34 +01001599 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001600 return self._get_finished_message(_lib.SSL_get_peer_finished)
Fedor Brunner5747b932014-03-05 14:22:34 +01001601
Jean-Paul Calderone7c556ef2014-03-30 10:45:00 -04001602
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001603 def get_cipher_name(self):
1604 """
1605 Obtain the name of the currently used cipher.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001606
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001607 :returns: The name of the currently used cipher or :py:obj:`None`
1608 if no connection has been established.
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001609 :rtype: :py:class:`unicode` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001610 """
1611 cipher = _lib.SSL_get_current_cipher(self._ssl)
1612 if cipher == _ffi.NULL:
1613 return None
1614 else:
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001615 name = _ffi.string(_lib.SSL_CIPHER_get_name(cipher))
1616 return name.decode("utf-8")
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001617
Jean-Paul Calderonedbd76272014-03-29 18:09:40 -04001618
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001619 def get_cipher_bits(self):
1620 """
1621 Obtain the number of secret bits of the currently used cipher.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001622
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001623 :returns: The number of secret bits of the currently used cipher
1624 or :py:obj:`None` if no connection has been established.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001625 :rtype: :py:class:`int` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001626 """
1627 cipher = _lib.SSL_get_current_cipher(self._ssl)
1628 if cipher == _ffi.NULL:
1629 return None
1630 else:
1631 return _lib.SSL_CIPHER_get_bits(cipher, _ffi.NULL)
1632
Jean-Paul Calderonedbd76272014-03-29 18:09:40 -04001633
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001634 def get_cipher_version(self):
1635 """
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001636 Obtain the protocol version of the currently used cipher.
1637
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001638 :returns: The protocol name of the currently used cipher
1639 or :py:obj:`None` if no connection has been established.
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001640 :rtype: :py:class:`unicode` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001641 """
1642 cipher = _lib.SSL_get_current_cipher(self._ssl)
1643 if cipher == _ffi.NULL:
1644 return None
1645 else:
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001646 version =_ffi.string(_lib.SSL_CIPHER_get_version(cipher))
1647 return version.decode("utf-8")
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001648
Cory Benfield84a121e2014-03-31 20:30:25 +01001649 def get_next_proto_negotiated(self):
1650 """
1651 Get the protocol that was negotiated by NPN.
1652 """
1653 data = _ffi.new("unsigned char **")
1654 data_len = _ffi.new("unsigned int *")
1655
1656 _lib.SSL_get0_next_proto_negotiated(self._ssl, data, data_len)
1657
Cory Benfieldcd010f62014-05-15 19:00:27 +01001658 return _ffi.buffer(data[0], data_len[0])[:]
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001659
1660
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001661ConnectionType = Connection
Jean-Paul Calderone11ed8e82014-01-18 10:21:50 -05001662
Jean-Paul Calderonefab157b2014-01-18 11:21:38 -05001663# This is similar to the initialization calls at the end of OpenSSL/crypto.py
1664# but is exercised mostly by the Context initializer.
Jean-Paul Calderone11ed8e82014-01-18 10:21:50 -05001665_lib.SSL_library_init()