blob: 89720978db02d0c0205fa83c2a337762eec01c1d [file] [log] [blame]
Abraham Martin82efe3e2015-03-25 10:50:09 +00001from warnings import warn
2from sys import platform, version_info
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05003from functools import wraps, partial
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08004from itertools import count
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08005from weakref import WeakValueDictionary
6from errno import errorcode
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -08007
Jean-Paul Calderone63eab692014-01-18 10:19:56 -05008from six import text_type as _text_type
Konstantinos Koukopoulosc8b13ea2014-01-28 00:21:50 -08009from six import integer_types as integer_types
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
297
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -0800298 # SSL_CTX_set_app_data(self->ctx, self);
299 # SSL_CTX_set_mode(self->ctx, SSL_MODE_ENABLE_PARTIAL_WRITE |
300 # SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
301 # SSL_MODE_AUTO_RETRY);
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500302 self.set_mode(_lib.SSL_MODE_ENABLE_PARTIAL_WRITE)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800303
304
305 def load_verify_locations(self, cafile, capath=None):
306 """
307 Let SSL know where we can find trusted certificates for the certificate
308 chain
309
310 :param cafile: In which file we can find the certificates
311 :param capath: In which directory we can find the certificates
312 :return: None
313 """
Abraham Martine82326c2015-02-04 10:18:10 +0000314
315 # Backward compatibility
316 if isinstance(cafile, _text_type):
Abraham Martin82efe3e2015-03-25 10:50:09 +0000317 if version_info.major == 2:
318 warn("unicode in cafile is no longer accepted, use bytes", DeprecationWarning)
319 elif version_info.major == 3:
320 warn("str in cafile is no longer accepted, use bytes", DeprecationWarning)
321 else:
322 warn("text in cafile is no longer accepted, use bytes", DeprecationWarning)
Abraham Martine82326c2015-02-04 10:18:10 +0000323 cafile = cafile.encode('utf-8')
324
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800325 if cafile is None:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500326 cafile = _ffi.NULL
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800327 elif not isinstance(cafile, bytes):
328 raise TypeError("cafile must be None or a byte string")
329
330 if capath is None:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500331 capath = _ffi.NULL
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800332 elif not isinstance(capath, bytes):
333 raise TypeError("capath must be None or a byte string")
334
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500335 load_result = _lib.SSL_CTX_load_verify_locations(self._context, cafile, capath)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800336 if not load_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500337 _raise_current_error()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800338
339
340 def _wrap_callback(self, callback):
341 @wraps(callback)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800342 def wrapper(size, verify, userdata):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800343 return callback(size, verify, self._passphrase_userdata)
344 return _PassphraseHelper(
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800345 FILETYPE_PEM, wrapper, more_args=True, truncate=True)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800346
347
348 def set_passwd_cb(self, callback, userdata=None):
349 """
350 Set the passphrase callback
351
352 :param callback: The Python callback to use
353 :param userdata: (optional) A Python object which will be given as
354 argument to the callback
355 :return: None
356 """
357 if not callable(callback):
358 raise TypeError("callback must be callable")
359
360 self._passphrase_helper = self._wrap_callback(callback)
361 self._passphrase_callback = self._passphrase_helper.callback
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500362 _lib.SSL_CTX_set_default_passwd_cb(
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800363 self._context, self._passphrase_callback)
364 self._passphrase_userdata = userdata
365
366
367 def set_default_verify_paths(self):
368 """
369 Use the platform-specific CA certificate locations
370
371 :return: None
372 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500373 set_result = _lib.SSL_CTX_set_default_verify_paths(self._context)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800374 if not set_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500375 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500376 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800377
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800378
379 def use_certificate_chain_file(self, certfile):
380 """
381 Load a certificate chain from a file
382
383 :param certfile: The name of the certificate chain file
384 :return: None
385 """
Jean-Paul Calderoned8607982014-01-18 10:30:55 -0500386 if isinstance(certfile, _text_type):
387 # Perhaps sys.getfilesystemencoding() could be better?
388 certfile = certfile.encode("utf-8")
389
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800390 if not isinstance(certfile, bytes):
Jean-Paul Calderoned8607982014-01-18 10:30:55 -0500391 raise TypeError("certfile must be bytes or unicode")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800392
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500393 result = _lib.SSL_CTX_use_certificate_chain_file(self._context, certfile)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800394 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500395 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800396
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800397
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800398 def use_certificate_file(self, certfile, filetype=FILETYPE_PEM):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800399 """
400 Load a certificate from a file
401
402 :param certfile: The name of the certificate file
403 :param filetype: (optional) The encoding of the file, default is PEM
404 :return: None
405 """
Jean-Paul Calderone684baf52014-01-18 10:31:19 -0500406 if isinstance(certfile, _text_type):
407 # Perhaps sys.getfilesystemencoding() could be better?
408 certfile = certfile.encode("utf-8")
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800409 if not isinstance(certfile, bytes):
Jean-Paul Calderone684baf52014-01-18 10:31:19 -0500410 raise TypeError("certfile must be bytes or unicode")
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -0500411 if not isinstance(filetype, integer_types):
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800412 raise TypeError("filetype must be an integer")
413
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500414 use_result = _lib.SSL_CTX_use_certificate_file(self._context, certfile, filetype)
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800415 if not use_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500416 _raise_current_error()
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800417
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800418
419 def use_certificate(self, cert):
420 """
421 Load a certificate from a X509 object
422
423 :param cert: The X509 object
424 :return: None
425 """
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800426 if not isinstance(cert, X509):
427 raise TypeError("cert must be an X509 instance")
428
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500429 use_result = _lib.SSL_CTX_use_certificate(self._context, cert._x509)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800430 if not use_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500431 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800432
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800433
434 def add_extra_chain_cert(self, certobj):
435 """
436 Add certificate to chain
437
438 :param certobj: The X509 certificate object to add to the chain
439 :return: None
440 """
441 if not isinstance(certobj, X509):
442 raise TypeError("certobj must be an X509 instance")
443
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500444 copy = _lib.X509_dup(certobj._x509)
445 add_result = _lib.SSL_CTX_add_extra_chain_cert(self._context, copy)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800446 if not add_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500447 # TODO: This is untested.
448 _lib.X509_free(copy)
449 _raise_current_error()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800450
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800451
452 def _raise_passphrase_exception(self):
453 if self._passphrase_helper is None:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500454 _raise_current_error()
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800455 exception = self._passphrase_helper.raise_if_problem(Error)
456 if exception is not None:
457 raise exception
458
459
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800460 def use_privatekey_file(self, keyfile, filetype=_unspecified):
461 """
462 Load a private key from a file
463
464 :param keyfile: The name of the key file
465 :param filetype: (optional) The encoding of the file, default is PEM
466 :return: None
467 """
Jean-Paul Calderone87e525a2014-01-18 10:31:51 -0500468 if isinstance(keyfile, _text_type):
469 # Perhaps sys.getfilesystemencoding() could be better?
470 keyfile = keyfile.encode("utf-8")
471
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800472 if not isinstance(keyfile, bytes):
473 raise TypeError("keyfile must be a byte string")
474
475 if filetype is _unspecified:
476 filetype = FILETYPE_PEM
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -0500477 elif not isinstance(filetype, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800478 raise TypeError("filetype must be an integer")
479
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500480 use_result = _lib.SSL_CTX_use_PrivateKey_file(
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800481 self._context, keyfile, filetype)
482 if not use_result:
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800483 self._raise_passphrase_exception()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800484
485
486 def use_privatekey(self, pkey):
487 """
488 Load a private key from a PKey object
489
490 :param pkey: The PKey object
491 :return: None
492 """
493 if not isinstance(pkey, PKey):
494 raise TypeError("pkey must be a PKey instance")
495
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500496 use_result = _lib.SSL_CTX_use_PrivateKey(self._context, pkey._pkey)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800497 if not use_result:
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800498 self._raise_passphrase_exception()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800499
500
501 def check_privatekey(self):
502 """
503 Check that the private key and certificate match up
504
505 :return: None (raises an exception if something's wrong)
506 """
Jean-Paul Calderonea0344922014-12-11 14:02:31 -0500507 if not _lib.SSL_CTX_check_private_key(self._context):
508 _raise_current_error()
509
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800510
511 def load_client_ca(self, cafile):
512 """
513 Load the trusted certificates that will be sent to the client (basically
514 telling the client "These are the guys I trust"). Does not actually
515 imply any of the certificates are trusted; that must be configured
516 separately.
517
518 :param cafile: The name of the certificates file
519 :return: None
520 """
521
522 def set_session_id(self, buf):
523 """
524 Set the session identifier. This is needed if you want to do session
525 resumption.
526
527 :param buf: A Python object that can be safely converted to a string
528 :returns: None
529 """
530
531 def set_session_cache_mode(self, mode):
532 """
533 Enable/disable session caching and specify the mode used.
534
535 :param mode: One or more of the SESS_CACHE_* flags (combine using
536 bitwise or)
537 :returns: The previously set caching mode.
538 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500539 if not isinstance(mode, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800540 raise TypeError("mode must be an integer")
541
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500542 return _lib.SSL_CTX_set_session_cache_mode(self._context, mode)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800543
544
545 def get_session_cache_mode(self):
546 """
547 :returns: The currently used cache mode.
548 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500549 return _lib.SSL_CTX_get_session_cache_mode(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800550
551
552 def set_verify(self, mode, callback):
553 """
554 Set the verify mode and verify callback
555
556 :param mode: The verify mode, this is either VERIFY_NONE or
557 VERIFY_PEER combined with possible other flags
558 :param callback: The Python callback to use
559 :return: None
560
561 See SSL_CTX_set_verify(3SSL) for further details.
562 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500563 if not isinstance(mode, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800564 raise TypeError("mode must be an integer")
565
566 if not callable(callback):
567 raise TypeError("callback must be callable")
568
Jean-Paul Calderone6a8cd112014-04-02 21:09:08 -0400569 self._verify_helper = _VerifyHelper(callback)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800570 self._verify_callback = self._verify_helper.callback
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500571 _lib.SSL_CTX_set_verify(self._context, mode, self._verify_callback)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800572
573
574 def set_verify_depth(self, depth):
575 """
576 Set the verify depth
577
578 :param depth: An integer specifying the verify depth
579 :return: None
580 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500581 if not isinstance(depth, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800582 raise TypeError("depth must be an integer")
583
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500584 _lib.SSL_CTX_set_verify_depth(self._context, depth)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800585
586
587 def get_verify_mode(self):
588 """
589 Get the verify mode
590
591 :return: The verify mode
592 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500593 return _lib.SSL_CTX_get_verify_mode(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800594
595
596 def get_verify_depth(self):
597 """
598 Get the verify depth
599
600 :return: The verify depth
601 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500602 return _lib.SSL_CTX_get_verify_depth(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800603
604
605 def load_tmp_dh(self, dhfile):
606 """
607 Load parameters for Ephemeral Diffie-Hellman
608
609 :param dhfile: The file to load EDH parameters from
610 :return: None
611 """
612 if not isinstance(dhfile, bytes):
613 raise TypeError("dhfile must be a byte string")
614
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -0500615 bio = _lib.BIO_new_file(dhfile, b"r")
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500616 if bio == _ffi.NULL:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500617 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500618 bio = _ffi.gc(bio, _lib.BIO_free)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800619
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500620 dh = _lib.PEM_read_bio_DHparams(bio, _ffi.NULL, _ffi.NULL, _ffi.NULL)
621 dh = _ffi.gc(dh, _lib.DH_free)
622 _lib.SSL_CTX_set_tmp_dh(self._context, dh)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800623
624
Jean-Paul Calderone3e4e3352014-04-19 09:28:28 -0400625 def set_tmp_ecdh(self, curve):
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600626 """
Andy Lutomirski76a61332014-03-12 15:02:56 -0700627 Select a curve to use for ECDHE key exchange.
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600628
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -0400629 :param curve: A curve object to use as returned by either
630 :py:meth:`OpenSSL.crypto.get_elliptic_curve` or
631 :py:meth:`OpenSSL.crypto.get_elliptic_curves`.
Andy Lutomirskif05a2732014-03-13 17:22:25 -0700632
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600633 :return: None
634 """
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -0400635 _lib.SSL_CTX_set_tmp_ecdh(self._context, curve._to_EC_KEY())
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600636
637
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800638 def set_cipher_list(self, cipher_list):
639 """
640 Change the cipher list
641
642 :param cipher_list: A cipher list, see ciphers(1)
643 :return: None
644 """
Jean-Paul Calderone63eab692014-01-18 10:19:56 -0500645 if isinstance(cipher_list, _text_type):
646 cipher_list = cipher_list.encode("ascii")
647
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800648 if not isinstance(cipher_list, bytes):
Jean-Paul Calderone63eab692014-01-18 10:19:56 -0500649 raise TypeError("cipher_list must be bytes or unicode")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800650
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500651 result = _lib.SSL_CTX_set_cipher_list(self._context, cipher_list)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800652 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500653 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800654
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800655
656 def set_client_ca_list(self, certificate_authorities):
657 """
658 Set the list of preferred client certificate signers for this server context.
659
660 This list of certificate authorities will be sent to the client when the
661 server requests a client certificate.
662
663 :param certificate_authorities: a sequence of X509Names.
664 :return: None
665 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500666 name_stack = _lib.sk_X509_NAME_new_null()
667 if name_stack == _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 Calderonea63714c2013-03-05 17:02:26 -0800670
671 try:
672 for ca_name in certificate_authorities:
673 if not isinstance(ca_name, X509Name):
674 raise TypeError(
675 "client CAs must be X509Name objects, not %s objects" % (
676 type(ca_name).__name__,))
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500677 copy = _lib.X509_NAME_dup(ca_name._name)
678 if copy == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500679 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500680 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500681 push_result = _lib.sk_X509_NAME_push(name_stack, copy)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800682 if not push_result:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500683 _lib.X509_NAME_free(copy)
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500684 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800685 except:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500686 _lib.sk_X509_NAME_free(name_stack)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800687 raise
688
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500689 _lib.SSL_CTX_set_client_CA_list(self._context, name_stack)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800690
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800691
692 def add_client_ca(self, certificate_authority):
693 """
694 Add the CA certificate to the list of preferred signers for this context.
695
696 The list of certificate authorities will be sent to the client when the
697 server requests a client certificate.
698
699 :param certificate_authority: certificate authority's X509 certificate.
700 :return: None
701 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800702 if not isinstance(certificate_authority, X509):
703 raise TypeError("certificate_authority must be an X509 instance")
704
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500705 add_result = _lib.SSL_CTX_add_client_CA(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800706 self._context, certificate_authority._x509)
707 if not add_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500708 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500709 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800710
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800711
712 def set_timeout(self, timeout):
713 """
714 Set session timeout
715
716 :param timeout: The timeout in seconds
717 :return: The previous session timeout
718 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500719 if not isinstance(timeout, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800720 raise TypeError("timeout must be an integer")
721
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500722 return _lib.SSL_CTX_set_timeout(self._context, timeout)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800723
724
725 def get_timeout(self):
726 """
727 Get the session timeout
728
729 :return: The session timeout
730 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500731 return _lib.SSL_CTX_get_timeout(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800732
733
734 def set_info_callback(self, callback):
735 """
736 Set the info callback
737
738 :param callback: The Python callback to use
739 :return: None
740 """
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800741 @wraps(callback)
742 def wrapper(ssl, where, return_code):
Jean-Paul Calderonef2bbc9c2014-02-02 10:59:14 -0500743 callback(Connection._reverse_mapping[ssl], where, return_code)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500744 self._info_callback = _ffi.callback(
745 "void (*)(const SSL *, int, int)", wrapper)
746 _lib.SSL_CTX_set_info_callback(self._context, self._info_callback)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800747
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800748
749 def get_app_data(self):
750 """
751 Get the application data (supplied via set_app_data())
752
753 :return: The application data
754 """
755 return self._app_data
756
757
758 def set_app_data(self, data):
759 """
760 Set the application data (will be returned from get_app_data())
761
762 :param data: Any Python object
763 :return: None
764 """
765 self._app_data = data
766
767
768 def get_cert_store(self):
769 """
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500770 Get the certificate store for the context.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800771
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500772 :return: A X509Store object or None if it does not have one.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800773 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500774 store = _lib.SSL_CTX_get_cert_store(self._context)
775 if store == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500776 # TODO: This is untested.
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800777 return None
778
779 pystore = X509Store.__new__(X509Store)
780 pystore._store = store
781 return pystore
782
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800783
784 def set_options(self, options):
785 """
786 Add options. Options set before are not cleared!
787
788 :param options: The options to add.
789 :return: The new option bitmask.
790 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500791 if not isinstance(options, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800792 raise TypeError("options must be an integer")
793
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500794 return _lib.SSL_CTX_set_options(self._context, options)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800795
796
797 def set_mode(self, mode):
798 """
799 Add modes via bitmask. Modes set before are not cleared!
800
801 :param mode: The mode to add.
802 :return: The new mode bitmask.
803 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500804 if not isinstance(mode, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800805 raise TypeError("mode must be an integer")
806
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500807 return _lib.SSL_CTX_set_mode(self._context, mode)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800808
809
810 def set_tlsext_servername_callback(self, callback):
811 """
812 Specify a callback function to be called when clients specify a server name.
813
814 :param callback: The callback function. It will be invoked with one
815 argument, the Connection instance.
816 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800817 @wraps(callback)
818 def wrapper(ssl, alert, arg):
819 callback(Connection._reverse_mapping[ssl])
820 return 0
821
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500822 self._tlsext_servername_callback = _ffi.callback(
823 "int (*)(const SSL *, int *, void *)", wrapper)
824 _lib.SSL_CTX_set_tlsext_servername_callback(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800825 self._context, self._tlsext_servername_callback)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800826
827ContextType = Context
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800828
829
830
831class Connection(object):
832 """
833 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800834 _reverse_mapping = WeakValueDictionary()
835
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800836 def __init__(self, context, socket=None):
837 """
838 Create a new Connection object, using the given OpenSSL.SSL.Context
839 instance and socket.
840
841 :param context: An SSL Context to use for this connection
842 :param socket: The socket to use for transport layer
843 """
844 if not isinstance(context, Context):
845 raise TypeError("context must be a Context instance")
846
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500847 ssl = _lib.SSL_new(context._context)
848 self._ssl = _ffi.gc(ssl, _lib.SSL_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800849 self._context = context
850
851 self._reverse_mapping[self._ssl] = self
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800852
853 if socket is None:
854 self._socket = None
Jean-Paul Calderone73b15c22013-03-05 18:30:39 -0800855 # Don't set up any gc for these, SSL_free will take care of them.
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500856 self._into_ssl = _lib.BIO_new(_lib.BIO_s_mem())
857 self._from_ssl = _lib.BIO_new(_lib.BIO_s_mem())
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800858
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500859 if self._into_ssl == _ffi.NULL or self._from_ssl == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500860 # TODO: This is untested.
861 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800862
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500863 _lib.SSL_set_bio(self._ssl, self._into_ssl, self._from_ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800864 else:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800865 self._into_ssl = None
866 self._from_ssl = None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800867 self._socket = socket
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500868 set_result = _lib.SSL_set_fd(self._ssl, _asFileDescriptor(self._socket))
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800869 if not set_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500870 # TODO: This is untested.
871 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800872
873
874 def __getattr__(self, name):
875 """
876 Look up attributes on the wrapped socket object if they are not found on
877 the Connection object.
878 """
879 return getattr(self._socket, name)
880
881
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800882 def _raise_ssl_error(self, ssl, result):
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800883 if self._context._verify_helper is not None:
884 self._context._verify_helper.raise_if_problem()
885
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500886 error = _lib.SSL_get_error(ssl, result)
887 if error == _lib.SSL_ERROR_WANT_READ:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800888 raise WantReadError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500889 elif error == _lib.SSL_ERROR_WANT_WRITE:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -0700890 raise WantWriteError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500891 elif error == _lib.SSL_ERROR_ZERO_RETURN:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800892 raise ZeroReturnError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500893 elif error == _lib.SSL_ERROR_WANT_X509_LOOKUP:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500894 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -0700895 raise WantX509LookupError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500896 elif error == _lib.SSL_ERROR_SYSCALL:
897 if _lib.ERR_peek_error() == 0:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800898 if result < 0:
Konstantinos Koukopoulos541150d2014-01-31 01:00:19 +0200899 if platform == "win32":
900 errno = _ffi.getwinerror()[0]
901 else:
902 errno = _ffi.errno
903 raise SysCallError(errno, errorcode[errno])
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800904 else:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -0700905 raise SysCallError(-1, "Unexpected EOF")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800906 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500907 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500908 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500909 elif error == _lib.SSL_ERROR_NONE:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -0700910 pass
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800911 else:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500912 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800913
914
915 def get_context(self):
916 """
917 Get session context
918 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800919 return self._context
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800920
921
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800922 def set_context(self, context):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800923 """
924 Switch this connection to a new session context
925
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800926 :param context: A :py:class:`Context` instance giving the new session
927 context to use.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800928 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800929 if not isinstance(context, Context):
930 raise TypeError("context must be a Context instance")
931
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500932 _lib.SSL_set_SSL_CTX(self._ssl, context._context)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800933 self._context = context
934
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800935
936 def get_servername(self):
937 """
938 Retrieve the servername extension value if provided in the client hello
939 message, or None if there wasn't one.
940
941 :return: A byte string giving the server name or :py:data:`None`.
942 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500943 name = _lib.SSL_get_servername(self._ssl, _lib.TLSEXT_NAMETYPE_host_name)
944 if name == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800945 return None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800946
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500947 return _ffi.string(name)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800948
949
950 def set_tlsext_host_name(self, name):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800951 """
952 Set the value of the servername extension to send in the client hello.
953
954 :param name: A byte string giving the name.
955 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800956 if not isinstance(name, bytes):
957 raise TypeError("name must be a byte string")
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -0500958 elif b"\0" in name:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800959 raise TypeError("name must not contain NUL byte")
960
961 # XXX I guess this can fail sometimes?
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500962 _lib.SSL_set_tlsext_host_name(self._ssl, name)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800963
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800964
965 def pending(self):
966 """
967 Get the number of bytes that can be safely read from the connection
968
969 :return: The number of bytes available in the receive buffer.
970 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500971 return _lib.SSL_pending(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800972
973
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800974 def send(self, buf, flags=0):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800975 """
976 Send data on the connection. NOTE: If you get one of the WantRead,
977 WantWrite or WantX509Lookup exceptions on this, you have to call the
978 method again with the SAME buffer.
979
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +0200980 :param buf: The string, buffer or memoryview to send
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800981 :param flags: (optional) Included for compatibility with the socket
982 API, the value is ignored
983 :return: The number of bytes written
984 """
Abraham Martine82326c2015-02-04 10:18:10 +0000985
986 # Backward compatibility
987 if isinstance(buf, _text_type):
Abraham Martin82efe3e2015-03-25 10:50:09 +0000988 if version_info.major == 2:
989 warn("unicode in buf is no longer accepted, use bytes", DeprecationWarning)
990 elif version_info.major == 3:
991 warn("str in buf is no longer accepted, use bytes", DeprecationWarning)
992 else:
993 warn("text in buf is no longer accepted, use bytes", DeprecationWarning)
Abraham Martine82326c2015-02-04 10:18:10 +0000994 buf = buf.encode('utf-8')
995
Jean-Paul Calderone8fb53182013-12-30 08:35:49 -0500996 if isinstance(buf, _memoryview):
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -0800997 buf = buf.tobytes()
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +0200998 if isinstance(buf, _buffer):
999 buf = str(buf)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001000 if not isinstance(buf, bytes):
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001001 raise TypeError("data must be a memoryview, buffer or byte string")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001002
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001003 result = _lib.SSL_write(self._ssl, buf, len(buf))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001004 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001005 return result
1006 write = send
1007
1008
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001009 def sendall(self, buf, flags=0):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001010 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001011 Send "all" data on the connection. This calls send() repeatedly until
1012 all data is sent. If an error occurs, it's impossible to tell how much
1013 data has been sent.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001014
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001015 :param buf: The string, buffer or memoryview to send
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001016 :param flags: (optional) Included for compatibility with the socket
1017 API, the value is ignored
1018 :return: The number of bytes written
1019 """
Abraham Martine82326c2015-02-04 10:18:10 +00001020
1021 # Backward compatibility
1022 if isinstance(buf, _text_type):
Abraham Martin82efe3e2015-03-25 10:50:09 +00001023 if version_info.major == 2:
1024 warn("unicode in buf is no longer accepted, use bytes", DeprecationWarning)
1025 elif version_info.major == 3:
1026 warn("str in buf is no longer accepted, use bytes", DeprecationWarning)
1027 else:
1028 warn("text in buf is no longer accepted, use bytes", DeprecationWarning)
Abraham Martine82326c2015-02-04 10:18:10 +00001029 buf = buf.encode('utf-8')
1030
Jean-Paul Calderone8fb53182013-12-30 08:35:49 -05001031 if isinstance(buf, _memoryview):
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -08001032 buf = buf.tobytes()
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001033 if isinstance(buf, _buffer):
1034 buf = str(buf)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001035 if not isinstance(buf, bytes):
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001036 raise TypeError("buf must be a memoryview, buffer or byte string")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001037
1038 left_to_send = len(buf)
1039 total_sent = 0
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001040 data = _ffi.new("char[]", buf)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001041
1042 while left_to_send:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001043 result = _lib.SSL_write(self._ssl, data + total_sent, left_to_send)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001044 self._raise_ssl_error(self._ssl, result)
1045 total_sent += result
1046 left_to_send -= result
1047
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001048
1049 def recv(self, bufsiz, flags=None):
1050 """
1051 Receive data on the connection. NOTE: If you get one of the WantRead,
1052 WantWrite or WantX509Lookup exceptions on this, you have to call the
1053 method again with the SAME buffer.
1054
1055 :param bufsiz: The maximum number of bytes to read
1056 :param flags: (optional) Included for compatibility with the socket
1057 API, the value is ignored
1058 :return: The string read from the Connection
1059 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001060 buf = _ffi.new("char[]", bufsiz)
1061 result = _lib.SSL_read(self._ssl, buf, bufsiz)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001062 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001063 return _ffi.buffer(buf, result)[:]
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001064 read = recv
1065
1066
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001067 def _handle_bio_errors(self, bio, result):
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001068 if _lib.BIO_should_retry(bio):
1069 if _lib.BIO_should_read(bio):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001070 raise WantReadError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001071 elif _lib.BIO_should_write(bio):
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001072 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001073 raise WantWriteError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001074 elif _lib.BIO_should_io_special(bio):
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001075 # TODO: This is untested. I think io_special means the socket
1076 # BIO has a not-yet connected socket.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001077 raise ValueError("BIO_should_io_special")
1078 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001079 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001080 raise ValueError("unknown bio failure")
1081 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001082 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001083 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001084
1085
1086 def bio_read(self, bufsiz):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001087 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001088 When using non-socket connections this function reads the "dirty" data
1089 that would have traveled away on the network.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001090
1091 :param bufsiz: The maximum number of bytes to read
1092 :return: The string read.
1093 """
Jean-Paul Calderone97e041d2013-03-05 21:03:12 -08001094 if self._from_ssl is None:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001095 raise TypeError("Connection sock was not None")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001096
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -05001097 if not isinstance(bufsiz, integer_types):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001098 raise TypeError("bufsiz must be an integer")
1099
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001100 buf = _ffi.new("char[]", bufsiz)
1101 result = _lib.BIO_read(self._from_ssl, buf, bufsiz)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001102 if result <= 0:
1103 self._handle_bio_errors(self._from_ssl, result)
1104
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001105 return _ffi.buffer(buf, result)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001106
1107
1108 def bio_write(self, buf):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001109 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001110 When using non-socket connections this function sends "dirty" data that
1111 would have traveled in on the network.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001112
1113 :param buf: The string to put into the memory BIO.
1114 :return: The number of bytes written
1115 """
Abraham Martine82326c2015-02-04 10:18:10 +00001116
1117 # Backward compatibility
1118 if isinstance(buf, _text_type):
Abraham Martin82efe3e2015-03-25 10:50:09 +00001119 if version_info.major == 2:
1120 warn("unicode in buf is no longer accepted, use bytes", DeprecationWarning)
1121 elif version_info.major == 3:
1122 warn("str in vuf is no longer accepted, use bytes", DeprecationWarning)
1123 else:
1124 warn("text in buf is no longer accepted, use bytes", DeprecationWarning)
Abraham Martine82326c2015-02-04 10:18:10 +00001125 buf = buf.encode("ascii")
1126
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001127 if self._into_ssl is None:
1128 raise TypeError("Connection sock was not None")
1129
1130 if not isinstance(buf, bytes):
1131 raise TypeError("buf must be a byte string")
1132
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001133 result = _lib.BIO_write(self._into_ssl, buf, len(buf))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001134 if result <= 0:
1135 self._handle_bio_errors(self._into_ssl, result)
1136 return result
1137
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001138
1139 def renegotiate(self):
1140 """
1141 Renegotiate the session
1142
1143 :return: True if the renegotiation can be started, false otherwise
1144 """
1145
1146 def do_handshake(self):
1147 """
1148 Perform an SSL handshake (usually called after renegotiate() or one of
1149 set_*_state()). This can raise the same exceptions as send and recv.
1150
1151 :return: None.
1152 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001153 result = _lib.SSL_do_handshake(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001154 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001155
1156
1157 def renegotiate_pending(self):
1158 """
1159 Check if there's a renegotiation in progress, it will return false once
1160 a renegotiation is finished.
1161
1162 :return: Whether there's a renegotiation in progress
1163 """
1164
1165 def total_renegotiations(self):
1166 """
1167 Find out the total number of renegotiations.
1168
1169 :return: The number of renegotiations.
1170 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001171 return _lib.SSL_total_renegotiations(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001172
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001173
1174 def connect(self, addr):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001175 """
1176 Connect to remote host and set up client-side SSL
1177
1178 :param addr: A remote address
1179 :return: What the socket's connect method returns
1180 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001181 _lib.SSL_set_connect_state(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001182 return self._socket.connect(addr)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001183
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001184
1185 def connect_ex(self, addr):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001186 """
1187 Connect to remote host and set up client-side SSL. Note that if the socket's
1188 connect_ex method doesn't return 0, SSL won't be initialized.
1189
1190 :param addr: A remove address
1191 :return: What the socket's connect_ex method returns
1192 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001193 connect_ex = self._socket.connect_ex
1194 self.set_connect_state()
1195 return connect_ex(addr)
1196
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001197
1198 def accept(self):
1199 """
1200 Accept incoming connection and set up SSL on it
1201
1202 :return: A (conn,addr) pair where conn is a Connection and addr is an
1203 address
1204 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001205 client, addr = self._socket.accept()
1206 conn = Connection(self._context, client)
1207 conn.set_accept_state()
1208 return (conn, addr)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001209
1210
1211 def bio_shutdown(self):
1212 """
1213 When using non-socket connections this function signals end of
1214 data on the input for this connection.
1215
1216 :return: None
1217 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001218 if self._from_ssl is None:
1219 raise TypeError("Connection sock was not None")
1220
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001221 _lib.BIO_set_mem_eof_return(self._into_ssl, 0)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001222
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001223
1224 def shutdown(self):
1225 """
1226 Send closure alert
1227
1228 :return: True if the shutdown completed successfully (i.e. both sides
1229 have sent closure alerts), false otherwise (i.e. you have to
1230 wait for a ZeroReturnError on a recv() method call
1231 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001232 result = _lib.SSL_shutdown(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001233 if result < 0:
Paul Aurichbff1d1a2015-01-08 08:36:53 -08001234 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001235 elif result > 0:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001236 return True
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001237 else:
1238 return False
1239
1240
1241 def get_cipher_list(self):
1242 """
1243 Get the session cipher list
1244
1245 :return: A list of cipher strings
1246 """
1247 ciphers = []
1248 for i in count():
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001249 result = _lib.SSL_get_cipher_list(self._ssl, i)
1250 if result == _ffi.NULL:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001251 break
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001252 ciphers.append(_native(_ffi.string(result)))
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001253 return ciphers
1254
1255
1256 def get_client_ca_list(self):
1257 """
1258 Get CAs whose certificates are suggested for client authentication.
1259
1260 :return: If this is a server connection, a list of X509Names representing
1261 the acceptable CAs as set by :py:meth:`OpenSSL.SSL.Context.set_client_ca_list` or
1262 :py:meth:`OpenSSL.SSL.Context.add_client_ca`. If this is a client connection,
1263 the list of such X509Names sent by the server, or an empty list if that
1264 has not yet happened.
1265 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001266 ca_names = _lib.SSL_get_client_CA_list(self._ssl)
1267 if ca_names == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001268 # TODO: This is untested.
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001269 return []
1270
1271 result = []
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001272 for i in range(_lib.sk_X509_NAME_num(ca_names)):
1273 name = _lib.sk_X509_NAME_value(ca_names, i)
1274 copy = _lib.X509_NAME_dup(name)
1275 if copy == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001276 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001277 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001278
1279 pyname = X509Name.__new__(X509Name)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001280 pyname._name = _ffi.gc(copy, _lib.X509_NAME_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001281 result.append(pyname)
1282 return result
1283
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001284
1285 def makefile(self):
1286 """
1287 The makefile() method is not implemented, since there is no dup semantics
1288 for SSL connections
1289
Jean-Paul Calderone6749ec22014-04-17 16:30:21 -04001290 :raise: NotImplementedError
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001291 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001292 raise NotImplementedError("Cannot make file object of OpenSSL.SSL.Connection")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001293
1294
1295 def get_app_data(self):
1296 """
1297 Get application data
1298
1299 :return: The application data
1300 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001301 return self._app_data
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001302
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001303
1304 def set_app_data(self, data):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001305 """
1306 Set application data
1307
1308 :param data - The application data
1309 :return: None
1310 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001311 self._app_data = data
1312
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001313
1314 def get_shutdown(self):
1315 """
1316 Get shutdown state
1317
1318 :return: The shutdown state, a bitvector of SENT_SHUTDOWN, RECEIVED_SHUTDOWN.
1319 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001320 return _lib.SSL_get_shutdown(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001321
1322
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001323 def set_shutdown(self, state):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001324 """
1325 Set shutdown state
1326
1327 :param state - bitvector of SENT_SHUTDOWN, RECEIVED_SHUTDOWN.
1328 :return: None
1329 """
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -05001330 if not isinstance(state, integer_types):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001331 raise TypeError("state must be an integer")
1332
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001333 _lib.SSL_set_shutdown(self._ssl, state)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001334
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001335
1336 def state_string(self):
1337 """
1338 Get a verbose state description
1339
1340 :return: A string representing the state
1341 """
1342
1343 def server_random(self):
1344 """
1345 Get a copy of the server hello nonce.
1346
1347 :return: A string representing the state
1348 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001349 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001350 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001351 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001352 self._ssl.s3.server_random,
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001353 _lib.SSL3_RANDOM_SIZE)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001354
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001355
1356 def client_random(self):
1357 """
1358 Get a copy of the client hello nonce.
1359
1360 :return: A string representing the state
1361 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001362 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001363 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001364 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001365 self._ssl.s3.client_random,
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001366 _lib.SSL3_RANDOM_SIZE)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001367
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001368
1369 def master_key(self):
1370 """
1371 Get a copy of the master key.
1372
1373 :return: A string representing the state
1374 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001375 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001376 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001377 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001378 self._ssl.session.master_key,
1379 self._ssl.session.master_key_length)[:]
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001380
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001381
1382 def sock_shutdown(self, *args, **kwargs):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001383 """
1384 See shutdown(2)
1385
1386 :return: What the socket's shutdown() method returns
1387 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001388 return self._socket.shutdown(*args, **kwargs)
1389
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001390
1391 def get_peer_certificate(self):
1392 """
1393 Retrieve the other side's certificate (if any)
1394
1395 :return: The peer's certificate
1396 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001397 cert = _lib.SSL_get_peer_certificate(self._ssl)
1398 if cert != _ffi.NULL:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001399 pycert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001400 pycert._x509 = _ffi.gc(cert, _lib.X509_free)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001401 return pycert
1402 return None
1403
1404
1405 def get_peer_cert_chain(self):
1406 """
1407 Retrieve the other side's certificate (if any)
1408
1409 :return: A list of X509 instances giving the peer's certificate chain,
1410 or None if it does not have one.
1411 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001412 cert_stack = _lib.SSL_get_peer_cert_chain(self._ssl)
1413 if cert_stack == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001414 return None
1415
1416 result = []
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001417 for i in range(_lib.sk_X509_num(cert_stack)):
Jean-Paul Calderone73b15c22013-03-05 18:30:39 -08001418 # TODO could incref instead of dup here
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001419 cert = _lib.X509_dup(_lib.sk_X509_value(cert_stack, i))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001420 pycert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001421 pycert._x509 = _ffi.gc(cert, _lib.X509_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001422 result.append(pycert)
1423 return result
1424
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001425
1426 def want_read(self):
1427 """
1428 Checks if more data has to be read from the transport layer to complete an
1429 operation.
1430
1431 :return: True iff more data has to be read
1432 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001433 return _lib.SSL_want_read(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001434
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001435
1436 def want_write(self):
1437 """
1438 Checks if there is data to write to the transport layer to complete an
1439 operation.
1440
1441 :return: True iff there is data to write
1442 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001443 return _lib.SSL_want_write(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001444
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001445
1446 def set_accept_state(self):
1447 """
1448 Set the connection to work in server mode. The handshake will be handled
1449 automatically by read/write.
1450
1451 :return: None
1452 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001453 _lib.SSL_set_accept_state(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001454
1455
1456 def set_connect_state(self):
1457 """
1458 Set the connection to work in client mode. The handshake will be handled
1459 automatically by read/write.
1460
1461 :return: None
1462 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001463 _lib.SSL_set_connect_state(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001464
1465
1466 def get_session(self):
1467 """
1468 Returns the Session currently used.
1469
1470 @return: An instance of :py:class:`OpenSSL.SSL.Session` or :py:obj:`None` if
1471 no session exists.
1472 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001473 session = _lib.SSL_get1_session(self._ssl)
1474 if session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001475 return None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001476
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001477 pysession = Session.__new__(Session)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001478 pysession._session = _ffi.gc(session, _lib.SSL_SESSION_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001479 return pysession
1480
1481
1482 def set_session(self, session):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001483 """
1484 Set the session to be used when the TLS/SSL connection is established.
1485
1486 :param session: A Session instance representing the session to use.
1487 :returns: None
1488 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001489 if not isinstance(session, Session):
1490 raise TypeError("session must be a Session instance")
1491
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001492 result = _lib.SSL_set_session(self._ssl, session._session)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001493 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001494 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001495
Jean-Paul Calderonedbd76272014-03-29 18:09:40 -04001496
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001497 def _get_finished_message(self, function):
1498 """
1499 Helper to implement :py:meth:`get_finished` and
1500 :py:meth:`get_peer_finished`.
1501
1502 :param function: Either :py:data:`SSL_get_finished`: or
1503 :py:data:`SSL_get_peer_finished`.
1504
1505 :return: :py:data:`None` if the desired message has not yet been
1506 received, otherwise the contents of the message.
1507 :rtype: :py:class:`bytes` or :py:class:`NoneType`
1508 """
Jean-Paul Calderone01af9042014-03-30 11:40:42 -04001509 # The OpenSSL documentation says nothing about what might happen if the
1510 # count argument given is zero. Specifically, it doesn't say whether
1511 # the output buffer may be NULL in that case or not. Inspection of the
1512 # implementation reveals that it calls memcpy() unconditionally.
1513 # Section 7.1.4, paragraph 1 of the C standard suggests that
1514 # memcpy(NULL, source, 0) is not guaranteed to produce defined (let
1515 # alone desirable) behavior (though it probably does on just about
1516 # every implementation...)
1517 #
1518 # Allocate a tiny buffer to pass in (instead of just passing NULL as
1519 # one might expect) for the initial call so as to be safe against this
1520 # potentially undefined behavior.
1521 empty = _ffi.new("char[]", 0)
1522 size = function(self._ssl, empty, 0)
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001523 if size == 0:
1524 # No Finished message so far.
1525 return None
1526
1527 buf = _ffi.new("char[]", size)
1528 function(self._ssl, buf, size)
1529 return _ffi.buffer(buf, size)[:]
1530
1531
Fedor Brunner5747b932014-03-05 14:22:34 +01001532 def get_finished(self):
1533 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001534 Obtain the latest `handshake finished` message sent to the peer.
Fedor Brunner5747b932014-03-05 14:22:34 +01001535
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001536 :return: The contents of the message or :py:obj:`None` if the TLS
1537 handshake has not yet completed.
1538 :rtype: :py:class:`bytes` or :py:class:`NoneType`
Fedor Brunner5747b932014-03-05 14:22:34 +01001539 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001540 return self._get_finished_message(_lib.SSL_get_finished)
1541
Fedor Brunner5747b932014-03-05 14:22:34 +01001542
1543 def get_peer_finished(self):
1544 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001545 Obtain the latest `handshake finished` message received from the peer.
Fedor Brunner5747b932014-03-05 14:22:34 +01001546
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001547 :return: The contents of the message or :py:obj:`None` if the TLS
1548 handshake has not yet completed.
1549 :rtype: :py:class:`bytes` or :py:class:`NoneType`
Fedor Brunner5747b932014-03-05 14:22:34 +01001550 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001551 return self._get_finished_message(_lib.SSL_get_peer_finished)
Fedor Brunner5747b932014-03-05 14:22:34 +01001552
Jean-Paul Calderone7c556ef2014-03-30 10:45:00 -04001553
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001554 def get_cipher_name(self):
1555 """
1556 Obtain the name of the currently used cipher.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001557
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001558 :returns: The name of the currently used cipher or :py:obj:`None`
1559 if no connection has been established.
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001560 :rtype: :py:class:`unicode` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001561 """
1562 cipher = _lib.SSL_get_current_cipher(self._ssl)
1563 if cipher == _ffi.NULL:
1564 return None
1565 else:
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001566 name = _ffi.string(_lib.SSL_CIPHER_get_name(cipher))
1567 return name.decode("utf-8")
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001568
Jean-Paul Calderonedbd76272014-03-29 18:09:40 -04001569
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001570 def get_cipher_bits(self):
1571 """
1572 Obtain the number of secret bits of the currently used cipher.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001573
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001574 :returns: The number of secret bits of the currently used cipher
1575 or :py:obj:`None` if no connection has been established.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001576 :rtype: :py:class:`int` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001577 """
1578 cipher = _lib.SSL_get_current_cipher(self._ssl)
1579 if cipher == _ffi.NULL:
1580 return None
1581 else:
1582 return _lib.SSL_CIPHER_get_bits(cipher, _ffi.NULL)
1583
Jean-Paul Calderonedbd76272014-03-29 18:09:40 -04001584
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001585 def get_cipher_version(self):
1586 """
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001587 Obtain the protocol version of the currently used cipher.
1588
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001589 :returns: The protocol name of the currently used cipher
1590 or :py:obj:`None` if no connection has been established.
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001591 :rtype: :py:class:`unicode` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001592 """
1593 cipher = _lib.SSL_get_current_cipher(self._ssl)
1594 if cipher == _ffi.NULL:
1595 return None
1596 else:
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001597 version =_ffi.string(_lib.SSL_CIPHER_get_version(cipher))
1598 return version.decode("utf-8")
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001599
1600
1601
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001602ConnectionType = Connection
Jean-Paul Calderone11ed8e82014-01-18 10:21:50 -05001603
Jean-Paul Calderonefab157b2014-01-18 11:21:38 -05001604# This is similar to the initialization calls at the end of OpenSSL/crypto.py
1605# but is exercised mostly by the Context initializer.
Jean-Paul Calderone11ed8e82014-01-18 10:21:50 -05001606_lib.SSL_library_init()