blob: 01d654fcaf3da7146bb3b13f7ca7a7fafce26259 [file] [log] [blame]
Abraham Martin82efe3e2015-03-25 10:50:09 +00001from warnings import warn
Abraham Martind2f0b072015-03-25 13:56:25 +00002from sys import platform
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
Abraham Martin9778f412015-03-25 14:02:37 +000010from six import PY2 as _PY2
Jean-Paul Calderone63eab692014-01-18 10:19:56 -050011
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -050012from OpenSSL._util import (
13 ffi as _ffi,
14 lib as _lib,
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -050015 exception_from_error_queue as _exception_from_error_queue,
16 native as _native)
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080017
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -080018from OpenSSL.crypto import (
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -050019 FILETYPE_PEM, _PassphraseHelper, PKey, X509Name, X509, X509Store)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -080020
21_unspecified = object()
22
Jean-Paul Calderone8fb53182013-12-30 08:35:49 -050023try:
24 _memoryview = memoryview
25except NameError:
26 class _memoryview(object):
27 pass
28
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +020029try:
30 _buffer = buffer
31except NameError:
32 class _buffer(object):
33 pass
34
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050035OPENSSL_VERSION_NUMBER = _lib.OPENSSL_VERSION_NUMBER
36SSLEAY_VERSION = _lib.SSLEAY_VERSION
37SSLEAY_CFLAGS = _lib.SSLEAY_CFLAGS
38SSLEAY_PLATFORM = _lib.SSLEAY_PLATFORM
39SSLEAY_DIR = _lib.SSLEAY_DIR
40SSLEAY_BUILT_ON = _lib.SSLEAY_BUILT_ON
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080041
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050042SENT_SHUTDOWN = _lib.SSL_SENT_SHUTDOWN
43RECEIVED_SHUTDOWN = _lib.SSL_RECEIVED_SHUTDOWN
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080044
45SSLv2_METHOD = 1
46SSLv3_METHOD = 2
47SSLv23_METHOD = 3
48TLSv1_METHOD = 4
Jean-Paul Calderone56bff942013-11-03 11:30:43 -050049TLSv1_1_METHOD = 5
50TLSv1_2_METHOD = 6
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080051
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050052OP_NO_SSLv2 = _lib.SSL_OP_NO_SSLv2
53OP_NO_SSLv3 = _lib.SSL_OP_NO_SSLv3
54OP_NO_TLSv1 = _lib.SSL_OP_NO_TLSv1
Jean-Paul Calderonebe2bb422013-12-29 07:34:08 -050055
56OP_NO_TLSv1_1 = getattr(_lib, "SSL_OP_NO_TLSv1_1", 0)
57OP_NO_TLSv1_2 = getattr(_lib, "SSL_OP_NO_TLSv1_2", 0)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -080058
Jean-Paul Calderone0d7e8a12014-01-08 16:54:13 -050059try:
60 MODE_RELEASE_BUFFERS = _lib.SSL_MODE_RELEASE_BUFFERS
61except AttributeError:
62 pass
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080063
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050064OP_SINGLE_DH_USE = _lib.SSL_OP_SINGLE_DH_USE
65OP_EPHEMERAL_RSA = _lib.SSL_OP_EPHEMERAL_RSA
66OP_MICROSOFT_SESS_ID_BUG = _lib.SSL_OP_MICROSOFT_SESS_ID_BUG
67OP_NETSCAPE_CHALLENGE_BUG = _lib.SSL_OP_NETSCAPE_CHALLENGE_BUG
68OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG = _lib.SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG
69OP_SSLREF2_REUSE_CERT_TYPE_BUG = _lib.SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG
70OP_MICROSOFT_BIG_SSLV3_BUFFER = _lib.SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER
Jean-Paul Calderone0d7e8a12014-01-08 16:54:13 -050071try:
72 OP_MSIE_SSLV2_RSA_PADDING = _lib.SSL_OP_MSIE_SSLV2_RSA_PADDING
73except AttributeError:
74 pass
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050075OP_SSLEAY_080_CLIENT_DH_BUG = _lib.SSL_OP_SSLEAY_080_CLIENT_DH_BUG
76OP_TLS_D5_BUG = _lib.SSL_OP_TLS_D5_BUG
77OP_TLS_BLOCK_PADDING_BUG = _lib.SSL_OP_TLS_BLOCK_PADDING_BUG
78OP_DONT_INSERT_EMPTY_FRAGMENTS = _lib.SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
79OP_CIPHER_SERVER_PREFERENCE = _lib.SSL_OP_CIPHER_SERVER_PREFERENCE
80OP_TLS_ROLLBACK_BUG = _lib.SSL_OP_TLS_ROLLBACK_BUG
81OP_PKCS1_CHECK_1 = _lib.SSL_OP_PKCS1_CHECK_1
82OP_PKCS1_CHECK_2 = _lib.SSL_OP_PKCS1_CHECK_2
83OP_NETSCAPE_CA_DN_BUG = _lib.SSL_OP_NETSCAPE_CA_DN_BUG
84OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG= _lib.SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG
Jean-Paul Calderonec1780342014-01-08 16:59:03 -050085try:
86 OP_NO_COMPRESSION = _lib.SSL_OP_NO_COMPRESSION
87except AttributeError:
88 pass
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -080089
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050090OP_NO_QUERY_MTU = _lib.SSL_OP_NO_QUERY_MTU
91OP_COOKIE_EXCHANGE = _lib.SSL_OP_COOKIE_EXCHANGE
Arturo Filastò5f8c7a82014-03-09 20:01:25 +010092try:
93 OP_NO_TICKET = _lib.SSL_OP_NO_TICKET
94except AttributeError:
95 pass
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -080096
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050097OP_ALL = _lib.SSL_OP_ALL
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080098
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050099VERIFY_PEER = _lib.SSL_VERIFY_PEER
100VERIFY_FAIL_IF_NO_PEER_CERT = _lib.SSL_VERIFY_FAIL_IF_NO_PEER_CERT
101VERIFY_CLIENT_ONCE = _lib.SSL_VERIFY_CLIENT_ONCE
102VERIFY_NONE = _lib.SSL_VERIFY_NONE
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -0800103
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500104SESS_CACHE_OFF = _lib.SSL_SESS_CACHE_OFF
105SESS_CACHE_CLIENT = _lib.SSL_SESS_CACHE_CLIENT
106SESS_CACHE_SERVER = _lib.SSL_SESS_CACHE_SERVER
107SESS_CACHE_BOTH = _lib.SSL_SESS_CACHE_BOTH
108SESS_CACHE_NO_AUTO_CLEAR = _lib.SSL_SESS_CACHE_NO_AUTO_CLEAR
109SESS_CACHE_NO_INTERNAL_LOOKUP = _lib.SSL_SESS_CACHE_NO_INTERNAL_LOOKUP
110SESS_CACHE_NO_INTERNAL_STORE = _lib.SSL_SESS_CACHE_NO_INTERNAL_STORE
111SESS_CACHE_NO_INTERNAL = _lib.SSL_SESS_CACHE_NO_INTERNAL
Jean-Paul Calderoned39a3f62013-03-04 12:23:51 -0800112
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500113SSL_ST_CONNECT = _lib.SSL_ST_CONNECT
114SSL_ST_ACCEPT = _lib.SSL_ST_ACCEPT
115SSL_ST_MASK = _lib.SSL_ST_MASK
116SSL_ST_INIT = _lib.SSL_ST_INIT
117SSL_ST_BEFORE = _lib.SSL_ST_BEFORE
118SSL_ST_OK = _lib.SSL_ST_OK
119SSL_ST_RENEGOTIATE = _lib.SSL_ST_RENEGOTIATE
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800120
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500121SSL_CB_LOOP = _lib.SSL_CB_LOOP
122SSL_CB_EXIT = _lib.SSL_CB_EXIT
123SSL_CB_READ = _lib.SSL_CB_READ
124SSL_CB_WRITE = _lib.SSL_CB_WRITE
125SSL_CB_ALERT = _lib.SSL_CB_ALERT
126SSL_CB_READ_ALERT = _lib.SSL_CB_READ_ALERT
127SSL_CB_WRITE_ALERT = _lib.SSL_CB_WRITE_ALERT
128SSL_CB_ACCEPT_LOOP = _lib.SSL_CB_ACCEPT_LOOP
129SSL_CB_ACCEPT_EXIT = _lib.SSL_CB_ACCEPT_EXIT
130SSL_CB_CONNECT_LOOP = _lib.SSL_CB_CONNECT_LOOP
131SSL_CB_CONNECT_EXIT = _lib.SSL_CB_CONNECT_EXIT
132SSL_CB_HANDSHAKE_START = _lib.SSL_CB_HANDSHAKE_START
133SSL_CB_HANDSHAKE_DONE = _lib.SSL_CB_HANDSHAKE_DONE
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800134
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500135class Error(Exception):
Jean-Paul Calderone511cde02013-12-29 10:31:13 -0500136 """
137 An error occurred in an `OpenSSL.SSL` API.
138 """
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500139
140
141
142_raise_current_error = partial(_exception_from_error_queue, Error)
143
144
145class WantReadError(Error):
146 pass
147
148
149
150class WantWriteError(Error):
151 pass
152
153
154
155class WantX509LookupError(Error):
156 pass
157
158
159
160class ZeroReturnError(Error):
161 pass
162
163
164
165class SysCallError(Error):
166 pass
167
168
169
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800170class _VerifyHelper(object):
Jean-Paul Calderone6a8cd112014-04-02 21:09:08 -0400171 def __init__(self, callback):
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800172 self._problems = []
173
174 @wraps(callback)
175 def wrapper(ok, store_ctx):
176 cert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500177 cert._x509 = _lib.X509_STORE_CTX_get_current_cert(store_ctx)
178 error_number = _lib.X509_STORE_CTX_get_error(store_ctx)
179 error_depth = _lib.X509_STORE_CTX_get_error_depth(store_ctx)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800180
Jean-Paul Calderone6a8cd112014-04-02 21:09:08 -0400181 index = _lib.SSL_get_ex_data_X509_STORE_CTX_idx()
182 ssl = _lib.X509_STORE_CTX_get_ex_data(store_ctx, index)
183 connection = Connection._reverse_mapping[ssl]
184
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800185 try:
186 result = callback(connection, cert, error_number, error_depth, ok)
187 except Exception as e:
188 self._problems.append(e)
189 return 0
190 else:
191 if result:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500192 _lib.X509_STORE_CTX_set_error(store_ctx, _lib.X509_V_OK)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800193 return 1
194 else:
195 return 0
196
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500197 self.callback = _ffi.callback(
198 "int (*)(int, X509_STORE_CTX *)", wrapper)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800199
200
201 def raise_if_problem(self):
202 if self._problems:
203 try:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500204 _raise_current_error()
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800205 except Error:
206 pass
207 raise self._problems.pop(0)
208
209
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800210
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800211def _asFileDescriptor(obj):
212 fd = None
Konstantinos Koukopoulosc8b13ea2014-01-28 00:21:50 -0800213 if not isinstance(obj, integer_types):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800214 meth = getattr(obj, "fileno", None)
215 if meth is not None:
216 obj = meth()
217
Konstantinos Koukopoulosc8b13ea2014-01-28 00:21:50 -0800218 if isinstance(obj, integer_types):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800219 fd = obj
220
Konstantinos Koukopoulosc8b13ea2014-01-28 00:21:50 -0800221 if not isinstance(fd, integer_types):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800222 raise TypeError("argument must be an int, or have a fileno() method.")
223 elif fd < 0:
224 raise ValueError(
225 "file descriptor cannot be a negative integer (%i)" % (fd,))
226
227 return fd
228
229
230
Jean-Paul Calderoned39a3f62013-03-04 12:23:51 -0800231def SSLeay_version(type):
232 """
233 Return a string describing the version of OpenSSL in use.
234
235 :param type: One of the SSLEAY_ constants defined in this module.
236 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500237 return _ffi.string(_lib.SSLeay_version(type))
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800238
239
240
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800241class Session(object):
242 pass
243
244
245
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800246class Context(object):
247 """
248 :py:obj:`OpenSSL.SSL.Context` instances define the parameters for setting up
249 new SSL connections.
250 """
251 _methods = {
Andrew Dunhamec84a0a2014-02-24 12:41:37 -0800252 SSLv2_METHOD: "SSLv2_method",
Jean-Paul Calderonebe2bb422013-12-29 07:34:08 -0500253 SSLv3_METHOD: "SSLv3_method",
254 SSLv23_METHOD: "SSLv23_method",
255 TLSv1_METHOD: "TLSv1_method",
256 TLSv1_1_METHOD: "TLSv1_1_method",
257 TLSv1_2_METHOD: "TLSv1_2_method",
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800258 }
Jean-Paul Calderonebe2bb422013-12-29 07:34:08 -0500259 _methods = dict(
260 (identifier, getattr(_lib, name))
261 for (identifier, name) in _methods.items()
262 if getattr(_lib, name, None) is not None)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800263
Jean-Paul Calderone63157872013-03-20 16:43:38 -0700264
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800265 def __init__(self, method):
266 """
267 :param method: One of SSLv2_METHOD, SSLv3_METHOD, SSLv23_METHOD, or
268 TLSv1_METHOD.
269 """
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -0500270 if not isinstance(method, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800271 raise TypeError("method must be an integer")
272
273 try:
274 method_func = self._methods[method]
275 except KeyError:
276 raise ValueError("No such protocol")
277
278 method_obj = method_func()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500279 if method_obj == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500280 # TODO: This is untested.
281 _raise_current_error()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800282
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500283 context = _lib.SSL_CTX_new(method_obj)
284 if context == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500285 # TODO: This is untested.
286 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500287 context = _ffi.gc(context, _lib.SSL_CTX_free)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800288
289 self._context = context
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800290 self._passphrase_helper = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800291 self._passphrase_callback = None
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800292 self._passphrase_userdata = None
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800293 self._verify_helper = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800294 self._verify_callback = None
295 self._info_callback = None
296 self._tlsext_servername_callback = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800297 self._app_data = None
298
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -0800299 # SSL_CTX_set_app_data(self->ctx, self);
300 # SSL_CTX_set_mode(self->ctx, SSL_MODE_ENABLE_PARTIAL_WRITE |
301 # SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
302 # SSL_MODE_AUTO_RETRY);
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500303 self.set_mode(_lib.SSL_MODE_ENABLE_PARTIAL_WRITE)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800304
305
306 def load_verify_locations(self, cafile, capath=None):
307 """
308 Let SSL know where we can find trusted certificates for the certificate
309 chain
310
311 :param cafile: In which file we can find the certificates
312 :param capath: In which directory we can find the certificates
313 :return: None
314 """
Abraham Martine82326c2015-02-04 10:18:10 +0000315
316 # Backward compatibility
317 if isinstance(cafile, _text_type):
Abraham Martin9778f412015-03-25 14:02:37 +0000318 if _PY2:
Abraham Martin82efe3e2015-03-25 10:50:09 +0000319 warn("unicode in cafile is no longer accepted, use bytes", DeprecationWarning)
Abraham Martin82efe3e2015-03-25 10:50:09 +0000320 else:
Abraham Martind2f0b072015-03-25 13:56:25 +0000321 warn("str in cafile is no longer accepted, use bytes", DeprecationWarning)
Abraham Martine82326c2015-02-04 10:18:10 +0000322 cafile = cafile.encode('utf-8')
323
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800324 if cafile is None:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500325 cafile = _ffi.NULL
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800326 elif not isinstance(cafile, bytes):
327 raise TypeError("cafile must be None or a byte string")
328
329 if capath is None:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500330 capath = _ffi.NULL
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800331 elif not isinstance(capath, bytes):
332 raise TypeError("capath must be None or a byte string")
333
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500334 load_result = _lib.SSL_CTX_load_verify_locations(self._context, cafile, capath)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800335 if not load_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500336 _raise_current_error()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800337
338
339 def _wrap_callback(self, callback):
340 @wraps(callback)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800341 def wrapper(size, verify, userdata):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800342 return callback(size, verify, self._passphrase_userdata)
343 return _PassphraseHelper(
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800344 FILETYPE_PEM, wrapper, more_args=True, truncate=True)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800345
346
347 def set_passwd_cb(self, callback, userdata=None):
348 """
349 Set the passphrase callback
350
351 :param callback: The Python callback to use
352 :param userdata: (optional) A Python object which will be given as
353 argument to the callback
354 :return: None
355 """
356 if not callable(callback):
357 raise TypeError("callback must be callable")
358
359 self._passphrase_helper = self._wrap_callback(callback)
360 self._passphrase_callback = self._passphrase_helper.callback
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500361 _lib.SSL_CTX_set_default_passwd_cb(
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800362 self._context, self._passphrase_callback)
363 self._passphrase_userdata = userdata
364
365
366 def set_default_verify_paths(self):
367 """
368 Use the platform-specific CA certificate locations
369
370 :return: None
371 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500372 set_result = _lib.SSL_CTX_set_default_verify_paths(self._context)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800373 if not set_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500374 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500375 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800376
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800377
378 def use_certificate_chain_file(self, certfile):
379 """
380 Load a certificate chain from a file
381
382 :param certfile: The name of the certificate chain file
383 :return: None
384 """
Jean-Paul Calderoned8607982014-01-18 10:30:55 -0500385 if isinstance(certfile, _text_type):
386 # Perhaps sys.getfilesystemencoding() could be better?
387 certfile = certfile.encode("utf-8")
388
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800389 if not isinstance(certfile, bytes):
Jean-Paul Calderoned8607982014-01-18 10:30:55 -0500390 raise TypeError("certfile must be bytes or unicode")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800391
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500392 result = _lib.SSL_CTX_use_certificate_chain_file(self._context, certfile)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800393 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500394 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800395
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800396
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800397 def use_certificate_file(self, certfile, filetype=FILETYPE_PEM):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800398 """
399 Load a certificate from a file
400
401 :param certfile: The name of the certificate file
402 :param filetype: (optional) The encoding of the file, default is PEM
403 :return: None
404 """
Jean-Paul Calderone684baf52014-01-18 10:31:19 -0500405 if isinstance(certfile, _text_type):
406 # Perhaps sys.getfilesystemencoding() could be better?
407 certfile = certfile.encode("utf-8")
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800408 if not isinstance(certfile, bytes):
Jean-Paul Calderone684baf52014-01-18 10:31:19 -0500409 raise TypeError("certfile must be bytes or unicode")
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -0500410 if not isinstance(filetype, integer_types):
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800411 raise TypeError("filetype must be an integer")
412
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500413 use_result = _lib.SSL_CTX_use_certificate_file(self._context, certfile, filetype)
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800414 if not use_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500415 _raise_current_error()
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800416
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800417
418 def use_certificate(self, cert):
419 """
420 Load a certificate from a X509 object
421
422 :param cert: The X509 object
423 :return: None
424 """
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800425 if not isinstance(cert, X509):
426 raise TypeError("cert must be an X509 instance")
427
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500428 use_result = _lib.SSL_CTX_use_certificate(self._context, cert._x509)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800429 if not use_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500430 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800431
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800432
433 def add_extra_chain_cert(self, certobj):
434 """
435 Add certificate to chain
436
437 :param certobj: The X509 certificate object to add to the chain
438 :return: None
439 """
440 if not isinstance(certobj, X509):
441 raise TypeError("certobj must be an X509 instance")
442
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500443 copy = _lib.X509_dup(certobj._x509)
444 add_result = _lib.SSL_CTX_add_extra_chain_cert(self._context, copy)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800445 if not add_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500446 # TODO: This is untested.
447 _lib.X509_free(copy)
448 _raise_current_error()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800449
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800450
451 def _raise_passphrase_exception(self):
452 if self._passphrase_helper is None:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500453 _raise_current_error()
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800454 exception = self._passphrase_helper.raise_if_problem(Error)
455 if exception is not None:
456 raise exception
457
458
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800459 def use_privatekey_file(self, keyfile, filetype=_unspecified):
460 """
461 Load a private key from a file
462
463 :param keyfile: The name of the key file
464 :param filetype: (optional) The encoding of the file, default is PEM
465 :return: None
466 """
Jean-Paul Calderone87e525a2014-01-18 10:31:51 -0500467 if isinstance(keyfile, _text_type):
468 # Perhaps sys.getfilesystemencoding() could be better?
469 keyfile = keyfile.encode("utf-8")
470
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800471 if not isinstance(keyfile, bytes):
472 raise TypeError("keyfile must be a byte string")
473
474 if filetype is _unspecified:
475 filetype = FILETYPE_PEM
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -0500476 elif not isinstance(filetype, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800477 raise TypeError("filetype must be an integer")
478
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500479 use_result = _lib.SSL_CTX_use_PrivateKey_file(
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800480 self._context, keyfile, filetype)
481 if not use_result:
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800482 self._raise_passphrase_exception()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800483
484
485 def use_privatekey(self, pkey):
486 """
487 Load a private key from a PKey object
488
489 :param pkey: The PKey object
490 :return: None
491 """
492 if not isinstance(pkey, PKey):
493 raise TypeError("pkey must be a PKey instance")
494
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500495 use_result = _lib.SSL_CTX_use_PrivateKey(self._context, pkey._pkey)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800496 if not use_result:
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800497 self._raise_passphrase_exception()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800498
499
500 def check_privatekey(self):
501 """
502 Check that the private key and certificate match up
503
504 :return: None (raises an exception if something's wrong)
505 """
Jean-Paul Calderonea0344922014-12-11 14:02:31 -0500506 if not _lib.SSL_CTX_check_private_key(self._context):
507 _raise_current_error()
508
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800509
510 def load_client_ca(self, cafile):
511 """
512 Load the trusted certificates that will be sent to the client (basically
513 telling the client "These are the guys I trust"). Does not actually
514 imply any of the certificates are trusted; that must be configured
515 separately.
516
517 :param cafile: The name of the certificates file
518 :return: None
519 """
520
521 def set_session_id(self, buf):
522 """
523 Set the session identifier. This is needed if you want to do session
524 resumption.
525
526 :param buf: A Python object that can be safely converted to a string
527 :returns: None
528 """
529
530 def set_session_cache_mode(self, mode):
531 """
532 Enable/disable session caching and specify the mode used.
533
534 :param mode: One or more of the SESS_CACHE_* flags (combine using
535 bitwise or)
536 :returns: The previously set caching mode.
537 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500538 if not isinstance(mode, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800539 raise TypeError("mode must be an integer")
540
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500541 return _lib.SSL_CTX_set_session_cache_mode(self._context, mode)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800542
543
544 def get_session_cache_mode(self):
545 """
546 :returns: The currently used cache mode.
547 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500548 return _lib.SSL_CTX_get_session_cache_mode(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800549
550
551 def set_verify(self, mode, callback):
552 """
553 Set the verify mode and verify callback
554
555 :param mode: The verify mode, this is either VERIFY_NONE or
556 VERIFY_PEER combined with possible other flags
557 :param callback: The Python callback to use
558 :return: None
559
560 See SSL_CTX_set_verify(3SSL) for further details.
561 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500562 if not isinstance(mode, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800563 raise TypeError("mode must be an integer")
564
565 if not callable(callback):
566 raise TypeError("callback must be callable")
567
Jean-Paul Calderone6a8cd112014-04-02 21:09:08 -0400568 self._verify_helper = _VerifyHelper(callback)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800569 self._verify_callback = self._verify_helper.callback
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500570 _lib.SSL_CTX_set_verify(self._context, mode, self._verify_callback)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800571
572
573 def set_verify_depth(self, depth):
574 """
575 Set the verify depth
576
577 :param depth: An integer specifying the verify depth
578 :return: None
579 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500580 if not isinstance(depth, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800581 raise TypeError("depth must be an integer")
582
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500583 _lib.SSL_CTX_set_verify_depth(self._context, depth)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800584
585
586 def get_verify_mode(self):
587 """
588 Get the verify mode
589
590 :return: The verify mode
591 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500592 return _lib.SSL_CTX_get_verify_mode(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800593
594
595 def get_verify_depth(self):
596 """
597 Get the verify depth
598
599 :return: The verify depth
600 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500601 return _lib.SSL_CTX_get_verify_depth(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800602
603
604 def load_tmp_dh(self, dhfile):
605 """
606 Load parameters for Ephemeral Diffie-Hellman
607
608 :param dhfile: The file to load EDH parameters from
609 :return: None
610 """
611 if not isinstance(dhfile, bytes):
612 raise TypeError("dhfile must be a byte string")
613
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -0500614 bio = _lib.BIO_new_file(dhfile, b"r")
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500615 if bio == _ffi.NULL:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500616 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500617 bio = _ffi.gc(bio, _lib.BIO_free)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800618
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500619 dh = _lib.PEM_read_bio_DHparams(bio, _ffi.NULL, _ffi.NULL, _ffi.NULL)
620 dh = _ffi.gc(dh, _lib.DH_free)
621 _lib.SSL_CTX_set_tmp_dh(self._context, dh)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800622
623
Jean-Paul Calderone3e4e3352014-04-19 09:28:28 -0400624 def set_tmp_ecdh(self, curve):
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600625 """
Andy Lutomirski76a61332014-03-12 15:02:56 -0700626 Select a curve to use for ECDHE key exchange.
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600627
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -0400628 :param curve: A curve object to use as returned by either
629 :py:meth:`OpenSSL.crypto.get_elliptic_curve` or
630 :py:meth:`OpenSSL.crypto.get_elliptic_curves`.
Andy Lutomirskif05a2732014-03-13 17:22:25 -0700631
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600632 :return: None
633 """
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -0400634 _lib.SSL_CTX_set_tmp_ecdh(self._context, curve._to_EC_KEY())
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600635
636
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800637 def set_cipher_list(self, cipher_list):
638 """
639 Change the cipher list
640
641 :param cipher_list: A cipher list, see ciphers(1)
642 :return: None
643 """
Jean-Paul Calderone63eab692014-01-18 10:19:56 -0500644 if isinstance(cipher_list, _text_type):
645 cipher_list = cipher_list.encode("ascii")
646
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800647 if not isinstance(cipher_list, bytes):
Jean-Paul Calderone63eab692014-01-18 10:19:56 -0500648 raise TypeError("cipher_list must be bytes or unicode")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800649
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500650 result = _lib.SSL_CTX_set_cipher_list(self._context, cipher_list)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800651 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500652 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800653
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800654
655 def set_client_ca_list(self, certificate_authorities):
656 """
657 Set the list of preferred client certificate signers for this server context.
658
659 This list of certificate authorities will be sent to the client when the
660 server requests a client certificate.
661
662 :param certificate_authorities: a sequence of X509Names.
663 :return: None
664 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500665 name_stack = _lib.sk_X509_NAME_new_null()
666 if name_stack == _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 Calderonea63714c2013-03-05 17:02:26 -0800669
670 try:
671 for ca_name in certificate_authorities:
672 if not isinstance(ca_name, X509Name):
673 raise TypeError(
674 "client CAs must be X509Name objects, not %s objects" % (
675 type(ca_name).__name__,))
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500676 copy = _lib.X509_NAME_dup(ca_name._name)
677 if copy == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500678 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500679 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500680 push_result = _lib.sk_X509_NAME_push(name_stack, copy)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800681 if not push_result:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500682 _lib.X509_NAME_free(copy)
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500683 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800684 except:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500685 _lib.sk_X509_NAME_free(name_stack)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800686 raise
687
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500688 _lib.SSL_CTX_set_client_CA_list(self._context, name_stack)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800689
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800690
691 def add_client_ca(self, certificate_authority):
692 """
693 Add the CA certificate to the list of preferred signers for this context.
694
695 The list of certificate authorities will be sent to the client when the
696 server requests a client certificate.
697
698 :param certificate_authority: certificate authority's X509 certificate.
699 :return: None
700 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800701 if not isinstance(certificate_authority, X509):
702 raise TypeError("certificate_authority must be an X509 instance")
703
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500704 add_result = _lib.SSL_CTX_add_client_CA(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800705 self._context, certificate_authority._x509)
706 if not add_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500707 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500708 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800709
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800710
711 def set_timeout(self, timeout):
712 """
713 Set session timeout
714
715 :param timeout: The timeout in seconds
716 :return: The previous session timeout
717 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500718 if not isinstance(timeout, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800719 raise TypeError("timeout must be an integer")
720
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500721 return _lib.SSL_CTX_set_timeout(self._context, timeout)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800722
723
724 def get_timeout(self):
725 """
726 Get the session timeout
727
728 :return: The session timeout
729 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500730 return _lib.SSL_CTX_get_timeout(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800731
732
733 def set_info_callback(self, callback):
734 """
735 Set the info callback
736
737 :param callback: The Python callback to use
738 :return: None
739 """
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800740 @wraps(callback)
741 def wrapper(ssl, where, return_code):
Jean-Paul Calderonef2bbc9c2014-02-02 10:59:14 -0500742 callback(Connection._reverse_mapping[ssl], where, return_code)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500743 self._info_callback = _ffi.callback(
744 "void (*)(const SSL *, int, int)", wrapper)
745 _lib.SSL_CTX_set_info_callback(self._context, self._info_callback)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800746
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800747
748 def get_app_data(self):
749 """
750 Get the application data (supplied via set_app_data())
751
752 :return: The application data
753 """
754 return self._app_data
755
756
757 def set_app_data(self, data):
758 """
759 Set the application data (will be returned from get_app_data())
760
761 :param data: Any Python object
762 :return: None
763 """
764 self._app_data = data
765
766
767 def get_cert_store(self):
768 """
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500769 Get the certificate store for the context.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800770
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500771 :return: A X509Store object or None if it does not have one.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800772 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500773 store = _lib.SSL_CTX_get_cert_store(self._context)
774 if store == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500775 # TODO: This is untested.
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800776 return None
777
778 pystore = X509Store.__new__(X509Store)
779 pystore._store = store
780 return pystore
781
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800782
783 def set_options(self, options):
784 """
785 Add options. Options set before are not cleared!
786
787 :param options: The options to add.
788 :return: The new option bitmask.
789 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500790 if not isinstance(options, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800791 raise TypeError("options must be an integer")
792
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500793 return _lib.SSL_CTX_set_options(self._context, options)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800794
795
796 def set_mode(self, mode):
797 """
798 Add modes via bitmask. Modes set before are not cleared!
799
800 :param mode: The mode to add.
801 :return: The new mode bitmask.
802 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500803 if not isinstance(mode, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800804 raise TypeError("mode must be an integer")
805
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500806 return _lib.SSL_CTX_set_mode(self._context, mode)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800807
808
809 def set_tlsext_servername_callback(self, callback):
810 """
811 Specify a callback function to be called when clients specify a server name.
812
813 :param callback: The callback function. It will be invoked with one
814 argument, the Connection instance.
815 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800816 @wraps(callback)
817 def wrapper(ssl, alert, arg):
818 callback(Connection._reverse_mapping[ssl])
819 return 0
820
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500821 self._tlsext_servername_callback = _ffi.callback(
822 "int (*)(const SSL *, int *, void *)", wrapper)
823 _lib.SSL_CTX_set_tlsext_servername_callback(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800824 self._context, self._tlsext_servername_callback)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800825
826ContextType = Context
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800827
828
829
830class Connection(object):
831 """
832 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800833 _reverse_mapping = WeakValueDictionary()
834
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800835 def __init__(self, context, socket=None):
836 """
837 Create a new Connection object, using the given OpenSSL.SSL.Context
838 instance and socket.
839
840 :param context: An SSL Context to use for this connection
841 :param socket: The socket to use for transport layer
842 """
843 if not isinstance(context, Context):
844 raise TypeError("context must be a Context instance")
845
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500846 ssl = _lib.SSL_new(context._context)
847 self._ssl = _ffi.gc(ssl, _lib.SSL_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800848 self._context = context
849
850 self._reverse_mapping[self._ssl] = self
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800851
852 if socket is None:
853 self._socket = None
Jean-Paul Calderone73b15c22013-03-05 18:30:39 -0800854 # Don't set up any gc for these, SSL_free will take care of them.
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500855 self._into_ssl = _lib.BIO_new(_lib.BIO_s_mem())
856 self._from_ssl = _lib.BIO_new(_lib.BIO_s_mem())
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800857
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500858 if self._into_ssl == _ffi.NULL or self._from_ssl == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500859 # TODO: This is untested.
860 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800861
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500862 _lib.SSL_set_bio(self._ssl, self._into_ssl, self._from_ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800863 else:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800864 self._into_ssl = None
865 self._from_ssl = None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800866 self._socket = socket
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500867 set_result = _lib.SSL_set_fd(self._ssl, _asFileDescriptor(self._socket))
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800868 if not set_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500869 # TODO: This is untested.
870 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800871
872
873 def __getattr__(self, name):
874 """
875 Look up attributes on the wrapped socket object if they are not found on
876 the Connection object.
877 """
878 return getattr(self._socket, name)
879
880
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800881 def _raise_ssl_error(self, ssl, result):
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800882 if self._context._verify_helper is not None:
883 self._context._verify_helper.raise_if_problem()
884
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500885 error = _lib.SSL_get_error(ssl, result)
886 if error == _lib.SSL_ERROR_WANT_READ:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800887 raise WantReadError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500888 elif error == _lib.SSL_ERROR_WANT_WRITE:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -0700889 raise WantWriteError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500890 elif error == _lib.SSL_ERROR_ZERO_RETURN:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800891 raise ZeroReturnError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500892 elif error == _lib.SSL_ERROR_WANT_X509_LOOKUP:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500893 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -0700894 raise WantX509LookupError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500895 elif error == _lib.SSL_ERROR_SYSCALL:
896 if _lib.ERR_peek_error() == 0:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800897 if result < 0:
Konstantinos Koukopoulos541150d2014-01-31 01:00:19 +0200898 if platform == "win32":
899 errno = _ffi.getwinerror()[0]
900 else:
901 errno = _ffi.errno
902 raise SysCallError(errno, errorcode[errno])
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800903 else:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -0700904 raise SysCallError(-1, "Unexpected EOF")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800905 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500906 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500907 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500908 elif error == _lib.SSL_ERROR_NONE:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -0700909 pass
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800910 else:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500911 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800912
913
914 def get_context(self):
915 """
916 Get session context
917 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800918 return self._context
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800919
920
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800921 def set_context(self, context):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800922 """
923 Switch this connection to a new session context
924
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800925 :param context: A :py:class:`Context` instance giving the new session
926 context to use.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800927 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800928 if not isinstance(context, Context):
929 raise TypeError("context must be a Context instance")
930
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500931 _lib.SSL_set_SSL_CTX(self._ssl, context._context)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800932 self._context = context
933
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800934
935 def get_servername(self):
936 """
937 Retrieve the servername extension value if provided in the client hello
938 message, or None if there wasn't one.
939
940 :return: A byte string giving the server name or :py:data:`None`.
941 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500942 name = _lib.SSL_get_servername(self._ssl, _lib.TLSEXT_NAMETYPE_host_name)
943 if name == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800944 return None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800945
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500946 return _ffi.string(name)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800947
948
949 def set_tlsext_host_name(self, name):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800950 """
951 Set the value of the servername extension to send in the client hello.
952
953 :param name: A byte string giving the name.
954 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800955 if not isinstance(name, bytes):
956 raise TypeError("name must be a byte string")
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -0500957 elif b"\0" in name:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800958 raise TypeError("name must not contain NUL byte")
959
960 # XXX I guess this can fail sometimes?
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500961 _lib.SSL_set_tlsext_host_name(self._ssl, name)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800962
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800963
964 def pending(self):
965 """
966 Get the number of bytes that can be safely read from the connection
967
968 :return: The number of bytes available in the receive buffer.
969 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500970 return _lib.SSL_pending(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800971
972
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800973 def send(self, buf, flags=0):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800974 """
975 Send data on the connection. NOTE: If you get one of the WantRead,
976 WantWrite or WantX509Lookup exceptions on this, you have to call the
977 method again with the SAME buffer.
978
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +0200979 :param buf: The string, buffer or memoryview to send
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800980 :param flags: (optional) Included for compatibility with the socket
981 API, the value is ignored
982 :return: The number of bytes written
983 """
Abraham Martine82326c2015-02-04 10:18:10 +0000984
985 # Backward compatibility
986 if isinstance(buf, _text_type):
Abraham Martin9778f412015-03-25 14:02:37 +0000987 if _PY2:
Abraham Martin82efe3e2015-03-25 10:50:09 +0000988 warn("unicode in buf is no longer accepted, use bytes", DeprecationWarning)
Abraham Martin82efe3e2015-03-25 10:50:09 +0000989 else:
Abraham Martind2f0b072015-03-25 13:56:25 +0000990 warn("str in buf is no longer accepted, use bytes", DeprecationWarning)
Abraham Martine82326c2015-02-04 10:18:10 +0000991 buf = buf.encode('utf-8')
992
Jean-Paul Calderone8fb53182013-12-30 08:35:49 -0500993 if isinstance(buf, _memoryview):
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -0800994 buf = buf.tobytes()
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +0200995 if isinstance(buf, _buffer):
996 buf = str(buf)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800997 if not isinstance(buf, bytes):
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +0200998 raise TypeError("data must be a memoryview, buffer or byte string")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800999
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001000 result = _lib.SSL_write(self._ssl, buf, len(buf))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001001 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001002 return result
1003 write = send
1004
1005
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001006 def sendall(self, buf, flags=0):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001007 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001008 Send "all" data on the connection. This calls send() repeatedly until
1009 all data is sent. If an error occurs, it's impossible to tell how much
1010 data has been sent.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001011
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001012 :param buf: The string, buffer or memoryview to send
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001013 :param flags: (optional) Included for compatibility with the socket
1014 API, the value is ignored
1015 :return: The number of bytes written
1016 """
Abraham Martine82326c2015-02-04 10:18:10 +00001017
1018 # Backward compatibility
1019 if isinstance(buf, _text_type):
Abraham Martin9778f412015-03-25 14:02:37 +00001020 if _PY2:
Abraham Martin82efe3e2015-03-25 10:50:09 +00001021 warn("unicode in buf is no longer accepted, use bytes", DeprecationWarning)
Abraham Martin82efe3e2015-03-25 10:50:09 +00001022 else:
Abraham Martind2f0b072015-03-25 13:56:25 +00001023 warn("str in buf is no longer accepted, use bytes", DeprecationWarning)
Abraham Martine82326c2015-02-04 10:18:10 +00001024 buf = buf.encode('utf-8')
1025
Jean-Paul Calderone8fb53182013-12-30 08:35:49 -05001026 if isinstance(buf, _memoryview):
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -08001027 buf = buf.tobytes()
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001028 if isinstance(buf, _buffer):
1029 buf = str(buf)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001030 if not isinstance(buf, bytes):
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001031 raise TypeError("buf must be a memoryview, buffer or byte string")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001032
1033 left_to_send = len(buf)
1034 total_sent = 0
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001035 data = _ffi.new("char[]", buf)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001036
1037 while left_to_send:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001038 result = _lib.SSL_write(self._ssl, data + total_sent, left_to_send)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001039 self._raise_ssl_error(self._ssl, result)
1040 total_sent += result
1041 left_to_send -= result
1042
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001043
1044 def recv(self, bufsiz, flags=None):
1045 """
1046 Receive data on the connection. NOTE: If you get one of the WantRead,
1047 WantWrite or WantX509Lookup exceptions on this, you have to call the
1048 method again with the SAME buffer.
1049
1050 :param bufsiz: The maximum number of bytes to read
1051 :param flags: (optional) Included for compatibility with the socket
1052 API, the value is ignored
1053 :return: The string read from the Connection
1054 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001055 buf = _ffi.new("char[]", bufsiz)
1056 result = _lib.SSL_read(self._ssl, buf, bufsiz)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001057 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001058 return _ffi.buffer(buf, result)[:]
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001059 read = recv
1060
1061
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001062 def _handle_bio_errors(self, bio, result):
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001063 if _lib.BIO_should_retry(bio):
1064 if _lib.BIO_should_read(bio):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001065 raise WantReadError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001066 elif _lib.BIO_should_write(bio):
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001067 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001068 raise WantWriteError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001069 elif _lib.BIO_should_io_special(bio):
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001070 # TODO: This is untested. I think io_special means the socket
1071 # BIO has a not-yet connected socket.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001072 raise ValueError("BIO_should_io_special")
1073 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001074 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001075 raise ValueError("unknown bio failure")
1076 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001077 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001078 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001079
1080
1081 def bio_read(self, bufsiz):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001082 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001083 When using non-socket connections this function reads the "dirty" data
1084 that would have traveled away on the network.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001085
1086 :param bufsiz: The maximum number of bytes to read
1087 :return: The string read.
1088 """
Jean-Paul Calderone97e041d2013-03-05 21:03:12 -08001089 if self._from_ssl is None:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001090 raise TypeError("Connection sock was not None")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001091
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -05001092 if not isinstance(bufsiz, integer_types):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001093 raise TypeError("bufsiz must be an integer")
1094
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001095 buf = _ffi.new("char[]", bufsiz)
1096 result = _lib.BIO_read(self._from_ssl, buf, bufsiz)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001097 if result <= 0:
1098 self._handle_bio_errors(self._from_ssl, result)
1099
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001100 return _ffi.buffer(buf, result)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001101
1102
1103 def bio_write(self, buf):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001104 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001105 When using non-socket connections this function sends "dirty" data that
1106 would have traveled in on the network.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001107
1108 :param buf: The string to put into the memory BIO.
1109 :return: The number of bytes written
1110 """
Abraham Martine82326c2015-02-04 10:18:10 +00001111
1112 # Backward compatibility
1113 if isinstance(buf, _text_type):
Abraham Martin9778f412015-03-25 14:02:37 +00001114 if _PY2:
Abraham Martin82efe3e2015-03-25 10:50:09 +00001115 warn("unicode in buf is no longer accepted, use bytes", DeprecationWarning)
Abraham Martin82efe3e2015-03-25 10:50:09 +00001116 else:
Abraham Martind2f0b072015-03-25 13:56:25 +00001117 warn("str in buf is no longer accepted, use bytes", DeprecationWarning)
Abraham Martine82326c2015-02-04 10:18:10 +00001118 buf = buf.encode("ascii")
1119
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001120 if self._into_ssl is None:
1121 raise TypeError("Connection sock was not None")
1122
1123 if not isinstance(buf, bytes):
1124 raise TypeError("buf must be a byte string")
1125
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001126 result = _lib.BIO_write(self._into_ssl, buf, len(buf))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001127 if result <= 0:
1128 self._handle_bio_errors(self._into_ssl, result)
1129 return result
1130
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001131
1132 def renegotiate(self):
1133 """
1134 Renegotiate the session
1135
1136 :return: True if the renegotiation can be started, false otherwise
1137 """
1138
1139 def do_handshake(self):
1140 """
1141 Perform an SSL handshake (usually called after renegotiate() or one of
1142 set_*_state()). This can raise the same exceptions as send and recv.
1143
1144 :return: None.
1145 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001146 result = _lib.SSL_do_handshake(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001147 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001148
1149
1150 def renegotiate_pending(self):
1151 """
1152 Check if there's a renegotiation in progress, it will return false once
1153 a renegotiation is finished.
1154
1155 :return: Whether there's a renegotiation in progress
1156 """
1157
1158 def total_renegotiations(self):
1159 """
1160 Find out the total number of renegotiations.
1161
1162 :return: The number of renegotiations.
1163 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001164 return _lib.SSL_total_renegotiations(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001165
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001166
1167 def connect(self, addr):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001168 """
1169 Connect to remote host and set up client-side SSL
1170
1171 :param addr: A remote address
1172 :return: What the socket's connect method returns
1173 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001174 _lib.SSL_set_connect_state(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001175 return self._socket.connect(addr)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001176
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001177
1178 def connect_ex(self, addr):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001179 """
1180 Connect to remote host and set up client-side SSL. Note that if the socket's
1181 connect_ex method doesn't return 0, SSL won't be initialized.
1182
1183 :param addr: A remove address
1184 :return: What the socket's connect_ex method returns
1185 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001186 connect_ex = self._socket.connect_ex
1187 self.set_connect_state()
1188 return connect_ex(addr)
1189
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001190
1191 def accept(self):
1192 """
1193 Accept incoming connection and set up SSL on it
1194
1195 :return: A (conn,addr) pair where conn is a Connection and addr is an
1196 address
1197 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001198 client, addr = self._socket.accept()
1199 conn = Connection(self._context, client)
1200 conn.set_accept_state()
1201 return (conn, addr)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001202
1203
1204 def bio_shutdown(self):
1205 """
1206 When using non-socket connections this function signals end of
1207 data on the input for this connection.
1208
1209 :return: None
1210 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001211 if self._from_ssl is None:
1212 raise TypeError("Connection sock was not None")
1213
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001214 _lib.BIO_set_mem_eof_return(self._into_ssl, 0)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001215
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001216
1217 def shutdown(self):
1218 """
1219 Send closure alert
1220
1221 :return: True if the shutdown completed successfully (i.e. both sides
1222 have sent closure alerts), false otherwise (i.e. you have to
1223 wait for a ZeroReturnError on a recv() method call
1224 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001225 result = _lib.SSL_shutdown(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001226 if result < 0:
Paul Aurichbff1d1a2015-01-08 08:36:53 -08001227 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001228 elif result > 0:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001229 return True
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001230 else:
1231 return False
1232
1233
1234 def get_cipher_list(self):
1235 """
1236 Get the session cipher list
1237
1238 :return: A list of cipher strings
1239 """
1240 ciphers = []
1241 for i in count():
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001242 result = _lib.SSL_get_cipher_list(self._ssl, i)
1243 if result == _ffi.NULL:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001244 break
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001245 ciphers.append(_native(_ffi.string(result)))
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001246 return ciphers
1247
1248
1249 def get_client_ca_list(self):
1250 """
1251 Get CAs whose certificates are suggested for client authentication.
1252
1253 :return: If this is a server connection, a list of X509Names representing
1254 the acceptable CAs as set by :py:meth:`OpenSSL.SSL.Context.set_client_ca_list` or
1255 :py:meth:`OpenSSL.SSL.Context.add_client_ca`. If this is a client connection,
1256 the list of such X509Names sent by the server, or an empty list if that
1257 has not yet happened.
1258 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001259 ca_names = _lib.SSL_get_client_CA_list(self._ssl)
1260 if ca_names == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001261 # TODO: This is untested.
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001262 return []
1263
1264 result = []
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001265 for i in range(_lib.sk_X509_NAME_num(ca_names)):
1266 name = _lib.sk_X509_NAME_value(ca_names, i)
1267 copy = _lib.X509_NAME_dup(name)
1268 if copy == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001269 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001270 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001271
1272 pyname = X509Name.__new__(X509Name)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001273 pyname._name = _ffi.gc(copy, _lib.X509_NAME_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001274 result.append(pyname)
1275 return result
1276
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001277
1278 def makefile(self):
1279 """
1280 The makefile() method is not implemented, since there is no dup semantics
1281 for SSL connections
1282
Jean-Paul Calderone6749ec22014-04-17 16:30:21 -04001283 :raise: NotImplementedError
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001284 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001285 raise NotImplementedError("Cannot make file object of OpenSSL.SSL.Connection")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001286
1287
1288 def get_app_data(self):
1289 """
1290 Get application data
1291
1292 :return: The application data
1293 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001294 return self._app_data
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001295
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001296
1297 def set_app_data(self, data):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001298 """
1299 Set application data
1300
1301 :param data - The application data
1302 :return: None
1303 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001304 self._app_data = data
1305
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001306
1307 def get_shutdown(self):
1308 """
1309 Get shutdown state
1310
1311 :return: The shutdown state, a bitvector of SENT_SHUTDOWN, RECEIVED_SHUTDOWN.
1312 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001313 return _lib.SSL_get_shutdown(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001314
1315
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001316 def set_shutdown(self, state):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001317 """
1318 Set shutdown state
1319
1320 :param state - bitvector of SENT_SHUTDOWN, RECEIVED_SHUTDOWN.
1321 :return: None
1322 """
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -05001323 if not isinstance(state, integer_types):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001324 raise TypeError("state must be an integer")
1325
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001326 _lib.SSL_set_shutdown(self._ssl, state)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001327
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001328
1329 def state_string(self):
1330 """
1331 Get a verbose state description
1332
1333 :return: A string representing the state
1334 """
1335
1336 def server_random(self):
1337 """
1338 Get a copy of the server hello nonce.
1339
1340 :return: A string representing the state
1341 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001342 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001343 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001344 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001345 self._ssl.s3.server_random,
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001346 _lib.SSL3_RANDOM_SIZE)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001347
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001348
1349 def client_random(self):
1350 """
1351 Get a copy of the client hello nonce.
1352
1353 :return: A string representing the state
1354 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001355 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001356 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001357 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001358 self._ssl.s3.client_random,
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001359 _lib.SSL3_RANDOM_SIZE)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001360
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001361
1362 def master_key(self):
1363 """
1364 Get a copy of the master key.
1365
1366 :return: A string representing the state
1367 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001368 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001369 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001370 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001371 self._ssl.session.master_key,
1372 self._ssl.session.master_key_length)[:]
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001373
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001374
1375 def sock_shutdown(self, *args, **kwargs):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001376 """
1377 See shutdown(2)
1378
1379 :return: What the socket's shutdown() method returns
1380 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001381 return self._socket.shutdown(*args, **kwargs)
1382
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001383
1384 def get_peer_certificate(self):
1385 """
1386 Retrieve the other side's certificate (if any)
1387
1388 :return: The peer's certificate
1389 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001390 cert = _lib.SSL_get_peer_certificate(self._ssl)
1391 if cert != _ffi.NULL:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001392 pycert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001393 pycert._x509 = _ffi.gc(cert, _lib.X509_free)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001394 return pycert
1395 return None
1396
1397
1398 def get_peer_cert_chain(self):
1399 """
1400 Retrieve the other side's certificate (if any)
1401
1402 :return: A list of X509 instances giving the peer's certificate chain,
1403 or None if it does not have one.
1404 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001405 cert_stack = _lib.SSL_get_peer_cert_chain(self._ssl)
1406 if cert_stack == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001407 return None
1408
1409 result = []
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001410 for i in range(_lib.sk_X509_num(cert_stack)):
Jean-Paul Calderone73b15c22013-03-05 18:30:39 -08001411 # TODO could incref instead of dup here
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001412 cert = _lib.X509_dup(_lib.sk_X509_value(cert_stack, i))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001413 pycert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001414 pycert._x509 = _ffi.gc(cert, _lib.X509_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001415 result.append(pycert)
1416 return result
1417
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001418
1419 def want_read(self):
1420 """
1421 Checks if more data has to be read from the transport layer to complete an
1422 operation.
1423
1424 :return: True iff more data has to be read
1425 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001426 return _lib.SSL_want_read(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001427
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001428
1429 def want_write(self):
1430 """
1431 Checks if there is data to write to the transport layer to complete an
1432 operation.
1433
1434 :return: True iff there is data to write
1435 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001436 return _lib.SSL_want_write(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001437
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001438
1439 def set_accept_state(self):
1440 """
1441 Set the connection to work in server mode. The handshake will be handled
1442 automatically by read/write.
1443
1444 :return: None
1445 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001446 _lib.SSL_set_accept_state(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001447
1448
1449 def set_connect_state(self):
1450 """
1451 Set the connection to work in client mode. The handshake will be handled
1452 automatically by read/write.
1453
1454 :return: None
1455 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001456 _lib.SSL_set_connect_state(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001457
1458
1459 def get_session(self):
1460 """
1461 Returns the Session currently used.
1462
1463 @return: An instance of :py:class:`OpenSSL.SSL.Session` or :py:obj:`None` if
1464 no session exists.
1465 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001466 session = _lib.SSL_get1_session(self._ssl)
1467 if session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001468 return None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001469
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001470 pysession = Session.__new__(Session)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001471 pysession._session = _ffi.gc(session, _lib.SSL_SESSION_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001472 return pysession
1473
1474
1475 def set_session(self, session):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001476 """
1477 Set the session to be used when the TLS/SSL connection is established.
1478
1479 :param session: A Session instance representing the session to use.
1480 :returns: None
1481 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001482 if not isinstance(session, Session):
1483 raise TypeError("session must be a Session instance")
1484
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001485 result = _lib.SSL_set_session(self._ssl, session._session)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001486 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001487 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001488
Jean-Paul Calderonedbd76272014-03-29 18:09:40 -04001489
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001490 def _get_finished_message(self, function):
1491 """
1492 Helper to implement :py:meth:`get_finished` and
1493 :py:meth:`get_peer_finished`.
1494
1495 :param function: Either :py:data:`SSL_get_finished`: or
1496 :py:data:`SSL_get_peer_finished`.
1497
1498 :return: :py:data:`None` if the desired message has not yet been
1499 received, otherwise the contents of the message.
1500 :rtype: :py:class:`bytes` or :py:class:`NoneType`
1501 """
Jean-Paul Calderone01af9042014-03-30 11:40:42 -04001502 # The OpenSSL documentation says nothing about what might happen if the
1503 # count argument given is zero. Specifically, it doesn't say whether
1504 # the output buffer may be NULL in that case or not. Inspection of the
1505 # implementation reveals that it calls memcpy() unconditionally.
1506 # Section 7.1.4, paragraph 1 of the C standard suggests that
1507 # memcpy(NULL, source, 0) is not guaranteed to produce defined (let
1508 # alone desirable) behavior (though it probably does on just about
1509 # every implementation...)
1510 #
1511 # Allocate a tiny buffer to pass in (instead of just passing NULL as
1512 # one might expect) for the initial call so as to be safe against this
1513 # potentially undefined behavior.
1514 empty = _ffi.new("char[]", 0)
1515 size = function(self._ssl, empty, 0)
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001516 if size == 0:
1517 # No Finished message so far.
1518 return None
1519
1520 buf = _ffi.new("char[]", size)
1521 function(self._ssl, buf, size)
1522 return _ffi.buffer(buf, size)[:]
1523
1524
Fedor Brunner5747b932014-03-05 14:22:34 +01001525 def get_finished(self):
1526 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001527 Obtain the latest `handshake finished` message sent to the peer.
Fedor Brunner5747b932014-03-05 14:22:34 +01001528
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001529 :return: The contents of the message or :py:obj:`None` if the TLS
1530 handshake has not yet completed.
1531 :rtype: :py:class:`bytes` or :py:class:`NoneType`
Fedor Brunner5747b932014-03-05 14:22:34 +01001532 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001533 return self._get_finished_message(_lib.SSL_get_finished)
1534
Fedor Brunner5747b932014-03-05 14:22:34 +01001535
1536 def get_peer_finished(self):
1537 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001538 Obtain the latest `handshake finished` message received from the peer.
Fedor Brunner5747b932014-03-05 14:22:34 +01001539
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001540 :return: The contents of the message or :py:obj:`None` if the TLS
1541 handshake has not yet completed.
1542 :rtype: :py:class:`bytes` or :py:class:`NoneType`
Fedor Brunner5747b932014-03-05 14:22:34 +01001543 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001544 return self._get_finished_message(_lib.SSL_get_peer_finished)
Fedor Brunner5747b932014-03-05 14:22:34 +01001545
Jean-Paul Calderone7c556ef2014-03-30 10:45:00 -04001546
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001547 def get_cipher_name(self):
1548 """
1549 Obtain the name of the currently used cipher.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001550
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001551 :returns: The name of the currently used cipher or :py:obj:`None`
1552 if no connection has been established.
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001553 :rtype: :py:class:`unicode` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001554 """
1555 cipher = _lib.SSL_get_current_cipher(self._ssl)
1556 if cipher == _ffi.NULL:
1557 return None
1558 else:
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001559 name = _ffi.string(_lib.SSL_CIPHER_get_name(cipher))
1560 return name.decode("utf-8")
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001561
Jean-Paul Calderonedbd76272014-03-29 18:09:40 -04001562
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001563 def get_cipher_bits(self):
1564 """
1565 Obtain the number of secret bits of the currently used cipher.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001566
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001567 :returns: The number of secret bits of the currently used cipher
1568 or :py:obj:`None` if no connection has been established.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001569 :rtype: :py:class:`int` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001570 """
1571 cipher = _lib.SSL_get_current_cipher(self._ssl)
1572 if cipher == _ffi.NULL:
1573 return None
1574 else:
1575 return _lib.SSL_CIPHER_get_bits(cipher, _ffi.NULL)
1576
Jean-Paul Calderonedbd76272014-03-29 18:09:40 -04001577
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001578 def get_cipher_version(self):
1579 """
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001580 Obtain the protocol version of the currently used cipher.
1581
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001582 :returns: The protocol name of the currently used cipher
1583 or :py:obj:`None` if no connection has been established.
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001584 :rtype: :py:class:`unicode` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001585 """
1586 cipher = _lib.SSL_get_current_cipher(self._ssl)
1587 if cipher == _ffi.NULL:
1588 return None
1589 else:
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001590 version =_ffi.string(_lib.SSL_CIPHER_get_version(cipher))
1591 return version.decode("utf-8")
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001592
1593
1594
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001595ConnectionType = Connection
Jean-Paul Calderone11ed8e82014-01-18 10:21:50 -05001596
Jean-Paul Calderonefab157b2014-01-18 11:21:38 -05001597# This is similar to the initialization calls at the end of OpenSSL/crypto.py
1598# but is exercised mostly by the Context initializer.
Jean-Paul Calderone11ed8e82014-01-18 10:21:50 -05001599_lib.SSL_library_init()