blob: 5d9c3604c36e5914a2f9e4caeb4977c61abf5b0e [file] [log] [blame]
Abraham Martin2403ef52015-03-25 10:35:44 +00001import warnings
Konstantinos Koukopoulos541150d2014-01-31 01:00:19 +02002from 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
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 Martin2403ef52015-03-25 10:35:44 +0000317 warnings.warn("str object in cafile is no longer accepted, use bytes", DeprecationWarning)
Abraham Martine82326c2015-02-04 10:18:10 +0000318 cafile = cafile.encode('utf-8')
319
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800320 if cafile is None:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500321 cafile = _ffi.NULL
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800322 elif not isinstance(cafile, bytes):
323 raise TypeError("cafile must be None or a byte string")
324
325 if capath is None:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500326 capath = _ffi.NULL
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800327 elif not isinstance(capath, bytes):
328 raise TypeError("capath must be None or a byte string")
329
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500330 load_result = _lib.SSL_CTX_load_verify_locations(self._context, cafile, capath)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800331 if not load_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500332 _raise_current_error()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800333
334
335 def _wrap_callback(self, callback):
336 @wraps(callback)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800337 def wrapper(size, verify, userdata):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800338 return callback(size, verify, self._passphrase_userdata)
339 return _PassphraseHelper(
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800340 FILETYPE_PEM, wrapper, more_args=True, truncate=True)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800341
342
343 def set_passwd_cb(self, callback, userdata=None):
344 """
345 Set the passphrase callback
346
347 :param callback: The Python callback to use
348 :param userdata: (optional) A Python object which will be given as
349 argument to the callback
350 :return: None
351 """
352 if not callable(callback):
353 raise TypeError("callback must be callable")
354
355 self._passphrase_helper = self._wrap_callback(callback)
356 self._passphrase_callback = self._passphrase_helper.callback
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500357 _lib.SSL_CTX_set_default_passwd_cb(
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800358 self._context, self._passphrase_callback)
359 self._passphrase_userdata = userdata
360
361
362 def set_default_verify_paths(self):
363 """
364 Use the platform-specific CA certificate locations
365
366 :return: None
367 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500368 set_result = _lib.SSL_CTX_set_default_verify_paths(self._context)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800369 if not set_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500370 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500371 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800372
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800373
374 def use_certificate_chain_file(self, certfile):
375 """
376 Load a certificate chain from a file
377
378 :param certfile: The name of the certificate chain file
379 :return: None
380 """
Jean-Paul Calderoned8607982014-01-18 10:30:55 -0500381 if isinstance(certfile, _text_type):
382 # Perhaps sys.getfilesystemencoding() could be better?
383 certfile = certfile.encode("utf-8")
384
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800385 if not isinstance(certfile, bytes):
Jean-Paul Calderoned8607982014-01-18 10:30:55 -0500386 raise TypeError("certfile must be bytes or unicode")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800387
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500388 result = _lib.SSL_CTX_use_certificate_chain_file(self._context, certfile)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800389 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500390 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800391
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800392
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800393 def use_certificate_file(self, certfile, filetype=FILETYPE_PEM):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800394 """
395 Load a certificate from a file
396
397 :param certfile: The name of the certificate file
398 :param filetype: (optional) The encoding of the file, default is PEM
399 :return: None
400 """
Jean-Paul Calderone684baf52014-01-18 10:31:19 -0500401 if isinstance(certfile, _text_type):
402 # Perhaps sys.getfilesystemencoding() could be better?
403 certfile = certfile.encode("utf-8")
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800404 if not isinstance(certfile, bytes):
Jean-Paul Calderone684baf52014-01-18 10:31:19 -0500405 raise TypeError("certfile must be bytes or unicode")
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -0500406 if not isinstance(filetype, integer_types):
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800407 raise TypeError("filetype must be an integer")
408
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500409 use_result = _lib.SSL_CTX_use_certificate_file(self._context, certfile, filetype)
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800410 if not use_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500411 _raise_current_error()
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800412
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800413
414 def use_certificate(self, cert):
415 """
416 Load a certificate from a X509 object
417
418 :param cert: The X509 object
419 :return: None
420 """
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800421 if not isinstance(cert, X509):
422 raise TypeError("cert must be an X509 instance")
423
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500424 use_result = _lib.SSL_CTX_use_certificate(self._context, cert._x509)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800425 if not use_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500426 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800427
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800428
429 def add_extra_chain_cert(self, certobj):
430 """
431 Add certificate to chain
432
433 :param certobj: The X509 certificate object to add to the chain
434 :return: None
435 """
436 if not isinstance(certobj, X509):
437 raise TypeError("certobj must be an X509 instance")
438
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500439 copy = _lib.X509_dup(certobj._x509)
440 add_result = _lib.SSL_CTX_add_extra_chain_cert(self._context, copy)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800441 if not add_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500442 # TODO: This is untested.
443 _lib.X509_free(copy)
444 _raise_current_error()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800445
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800446
447 def _raise_passphrase_exception(self):
448 if self._passphrase_helper is None:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500449 _raise_current_error()
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800450 exception = self._passphrase_helper.raise_if_problem(Error)
451 if exception is not None:
452 raise exception
453
454
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800455 def use_privatekey_file(self, keyfile, filetype=_unspecified):
456 """
457 Load a private key from a file
458
459 :param keyfile: The name of the key file
460 :param filetype: (optional) The encoding of the file, default is PEM
461 :return: None
462 """
Jean-Paul Calderone87e525a2014-01-18 10:31:51 -0500463 if isinstance(keyfile, _text_type):
464 # Perhaps sys.getfilesystemencoding() could be better?
465 keyfile = keyfile.encode("utf-8")
466
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800467 if not isinstance(keyfile, bytes):
468 raise TypeError("keyfile must be a byte string")
469
470 if filetype is _unspecified:
471 filetype = FILETYPE_PEM
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -0500472 elif not isinstance(filetype, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800473 raise TypeError("filetype must be an integer")
474
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500475 use_result = _lib.SSL_CTX_use_PrivateKey_file(
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800476 self._context, keyfile, filetype)
477 if not use_result:
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800478 self._raise_passphrase_exception()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800479
480
481 def use_privatekey(self, pkey):
482 """
483 Load a private key from a PKey object
484
485 :param pkey: The PKey object
486 :return: None
487 """
488 if not isinstance(pkey, PKey):
489 raise TypeError("pkey must be a PKey instance")
490
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500491 use_result = _lib.SSL_CTX_use_PrivateKey(self._context, pkey._pkey)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800492 if not use_result:
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800493 self._raise_passphrase_exception()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800494
495
496 def check_privatekey(self):
497 """
498 Check that the private key and certificate match up
499
500 :return: None (raises an exception if something's wrong)
501 """
Jean-Paul Calderonea0344922014-12-11 14:02:31 -0500502 if not _lib.SSL_CTX_check_private_key(self._context):
503 _raise_current_error()
504
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800505
506 def load_client_ca(self, cafile):
507 """
508 Load the trusted certificates that will be sent to the client (basically
509 telling the client "These are the guys I trust"). Does not actually
510 imply any of the certificates are trusted; that must be configured
511 separately.
512
513 :param cafile: The name of the certificates file
514 :return: None
515 """
516
517 def set_session_id(self, buf):
518 """
519 Set the session identifier. This is needed if you want to do session
520 resumption.
521
522 :param buf: A Python object that can be safely converted to a string
523 :returns: None
524 """
525
526 def set_session_cache_mode(self, mode):
527 """
528 Enable/disable session caching and specify the mode used.
529
530 :param mode: One or more of the SESS_CACHE_* flags (combine using
531 bitwise or)
532 :returns: The previously set caching mode.
533 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500534 if not isinstance(mode, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800535 raise TypeError("mode must be an integer")
536
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500537 return _lib.SSL_CTX_set_session_cache_mode(self._context, mode)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800538
539
540 def get_session_cache_mode(self):
541 """
542 :returns: The currently used cache mode.
543 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500544 return _lib.SSL_CTX_get_session_cache_mode(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800545
546
547 def set_verify(self, mode, callback):
548 """
549 Set the verify mode and verify callback
550
551 :param mode: The verify mode, this is either VERIFY_NONE or
552 VERIFY_PEER combined with possible other flags
553 :param callback: The Python callback to use
554 :return: None
555
556 See SSL_CTX_set_verify(3SSL) for further details.
557 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500558 if not isinstance(mode, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800559 raise TypeError("mode must be an integer")
560
561 if not callable(callback):
562 raise TypeError("callback must be callable")
563
Jean-Paul Calderone6a8cd112014-04-02 21:09:08 -0400564 self._verify_helper = _VerifyHelper(callback)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800565 self._verify_callback = self._verify_helper.callback
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500566 _lib.SSL_CTX_set_verify(self._context, mode, self._verify_callback)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800567
568
569 def set_verify_depth(self, depth):
570 """
571 Set the verify depth
572
573 :param depth: An integer specifying the verify depth
574 :return: None
575 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500576 if not isinstance(depth, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800577 raise TypeError("depth must be an integer")
578
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500579 _lib.SSL_CTX_set_verify_depth(self._context, depth)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800580
581
582 def get_verify_mode(self):
583 """
584 Get the verify mode
585
586 :return: The verify mode
587 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500588 return _lib.SSL_CTX_get_verify_mode(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800589
590
591 def get_verify_depth(self):
592 """
593 Get the verify depth
594
595 :return: The verify depth
596 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500597 return _lib.SSL_CTX_get_verify_depth(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800598
599
600 def load_tmp_dh(self, dhfile):
601 """
602 Load parameters for Ephemeral Diffie-Hellman
603
604 :param dhfile: The file to load EDH parameters from
605 :return: None
606 """
607 if not isinstance(dhfile, bytes):
608 raise TypeError("dhfile must be a byte string")
609
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -0500610 bio = _lib.BIO_new_file(dhfile, b"r")
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500611 if bio == _ffi.NULL:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500612 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500613 bio = _ffi.gc(bio, _lib.BIO_free)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800614
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500615 dh = _lib.PEM_read_bio_DHparams(bio, _ffi.NULL, _ffi.NULL, _ffi.NULL)
616 dh = _ffi.gc(dh, _lib.DH_free)
617 _lib.SSL_CTX_set_tmp_dh(self._context, dh)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800618
619
Jean-Paul Calderone3e4e3352014-04-19 09:28:28 -0400620 def set_tmp_ecdh(self, curve):
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600621 """
Andy Lutomirski76a61332014-03-12 15:02:56 -0700622 Select a curve to use for ECDHE key exchange.
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600623
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -0400624 :param curve: A curve object to use as returned by either
625 :py:meth:`OpenSSL.crypto.get_elliptic_curve` or
626 :py:meth:`OpenSSL.crypto.get_elliptic_curves`.
Andy Lutomirskif05a2732014-03-13 17:22:25 -0700627
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600628 :return: None
629 """
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -0400630 _lib.SSL_CTX_set_tmp_ecdh(self._context, curve._to_EC_KEY())
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600631
632
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800633 def set_cipher_list(self, cipher_list):
634 """
635 Change the cipher list
636
637 :param cipher_list: A cipher list, see ciphers(1)
638 :return: None
639 """
Jean-Paul Calderone63eab692014-01-18 10:19:56 -0500640 if isinstance(cipher_list, _text_type):
641 cipher_list = cipher_list.encode("ascii")
642
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800643 if not isinstance(cipher_list, bytes):
Jean-Paul Calderone63eab692014-01-18 10:19:56 -0500644 raise TypeError("cipher_list must be bytes or unicode")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800645
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500646 result = _lib.SSL_CTX_set_cipher_list(self._context, cipher_list)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800647 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500648 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800649
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800650
651 def set_client_ca_list(self, certificate_authorities):
652 """
653 Set the list of preferred client certificate signers for this server context.
654
655 This list of certificate authorities will be sent to the client when the
656 server requests a client certificate.
657
658 :param certificate_authorities: a sequence of X509Names.
659 :return: None
660 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500661 name_stack = _lib.sk_X509_NAME_new_null()
662 if name_stack == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500663 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500664 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800665
666 try:
667 for ca_name in certificate_authorities:
668 if not isinstance(ca_name, X509Name):
669 raise TypeError(
670 "client CAs must be X509Name objects, not %s objects" % (
671 type(ca_name).__name__,))
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500672 copy = _lib.X509_NAME_dup(ca_name._name)
673 if copy == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500674 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500675 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500676 push_result = _lib.sk_X509_NAME_push(name_stack, copy)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800677 if not push_result:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500678 _lib.X509_NAME_free(copy)
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500679 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800680 except:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500681 _lib.sk_X509_NAME_free(name_stack)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800682 raise
683
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500684 _lib.SSL_CTX_set_client_CA_list(self._context, name_stack)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800685
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800686
687 def add_client_ca(self, certificate_authority):
688 """
689 Add the CA certificate to the list of preferred signers for this context.
690
691 The list of certificate authorities will be sent to the client when the
692 server requests a client certificate.
693
694 :param certificate_authority: certificate authority's X509 certificate.
695 :return: None
696 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800697 if not isinstance(certificate_authority, X509):
698 raise TypeError("certificate_authority must be an X509 instance")
699
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500700 add_result = _lib.SSL_CTX_add_client_CA(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800701 self._context, certificate_authority._x509)
702 if not add_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500703 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500704 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800705
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800706
707 def set_timeout(self, timeout):
708 """
709 Set session timeout
710
711 :param timeout: The timeout in seconds
712 :return: The previous session timeout
713 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500714 if not isinstance(timeout, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800715 raise TypeError("timeout must be an integer")
716
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500717 return _lib.SSL_CTX_set_timeout(self._context, timeout)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800718
719
720 def get_timeout(self):
721 """
722 Get the session timeout
723
724 :return: The session timeout
725 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500726 return _lib.SSL_CTX_get_timeout(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800727
728
729 def set_info_callback(self, callback):
730 """
731 Set the info callback
732
733 :param callback: The Python callback to use
734 :return: None
735 """
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800736 @wraps(callback)
737 def wrapper(ssl, where, return_code):
Jean-Paul Calderonef2bbc9c2014-02-02 10:59:14 -0500738 callback(Connection._reverse_mapping[ssl], where, return_code)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500739 self._info_callback = _ffi.callback(
740 "void (*)(const SSL *, int, int)", wrapper)
741 _lib.SSL_CTX_set_info_callback(self._context, self._info_callback)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800742
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800743
744 def get_app_data(self):
745 """
746 Get the application data (supplied via set_app_data())
747
748 :return: The application data
749 """
750 return self._app_data
751
752
753 def set_app_data(self, data):
754 """
755 Set the application data (will be returned from get_app_data())
756
757 :param data: Any Python object
758 :return: None
759 """
760 self._app_data = data
761
762
763 def get_cert_store(self):
764 """
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500765 Get the certificate store for the context.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800766
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500767 :return: A X509Store object or None if it does not have one.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800768 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500769 store = _lib.SSL_CTX_get_cert_store(self._context)
770 if store == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500771 # TODO: This is untested.
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800772 return None
773
774 pystore = X509Store.__new__(X509Store)
775 pystore._store = store
776 return pystore
777
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800778
779 def set_options(self, options):
780 """
781 Add options. Options set before are not cleared!
782
783 :param options: The options to add.
784 :return: The new option bitmask.
785 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500786 if not isinstance(options, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800787 raise TypeError("options must be an integer")
788
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500789 return _lib.SSL_CTX_set_options(self._context, options)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800790
791
792 def set_mode(self, mode):
793 """
794 Add modes via bitmask. Modes set before are not cleared!
795
796 :param mode: The mode to add.
797 :return: The new mode bitmask.
798 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500799 if not isinstance(mode, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800800 raise TypeError("mode must be an integer")
801
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500802 return _lib.SSL_CTX_set_mode(self._context, mode)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800803
804
805 def set_tlsext_servername_callback(self, callback):
806 """
807 Specify a callback function to be called when clients specify a server name.
808
809 :param callback: The callback function. It will be invoked with one
810 argument, the Connection instance.
811 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800812 @wraps(callback)
813 def wrapper(ssl, alert, arg):
814 callback(Connection._reverse_mapping[ssl])
815 return 0
816
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500817 self._tlsext_servername_callback = _ffi.callback(
818 "int (*)(const SSL *, int *, void *)", wrapper)
819 _lib.SSL_CTX_set_tlsext_servername_callback(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800820 self._context, self._tlsext_servername_callback)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800821
822ContextType = Context
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800823
824
825
826class Connection(object):
827 """
828 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800829 _reverse_mapping = WeakValueDictionary()
830
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800831 def __init__(self, context, socket=None):
832 """
833 Create a new Connection object, using the given OpenSSL.SSL.Context
834 instance and socket.
835
836 :param context: An SSL Context to use for this connection
837 :param socket: The socket to use for transport layer
838 """
839 if not isinstance(context, Context):
840 raise TypeError("context must be a Context instance")
841
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500842 ssl = _lib.SSL_new(context._context)
843 self._ssl = _ffi.gc(ssl, _lib.SSL_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800844 self._context = context
845
846 self._reverse_mapping[self._ssl] = self
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800847
848 if socket is None:
849 self._socket = None
Jean-Paul Calderone73b15c22013-03-05 18:30:39 -0800850 # Don't set up any gc for these, SSL_free will take care of them.
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500851 self._into_ssl = _lib.BIO_new(_lib.BIO_s_mem())
852 self._from_ssl = _lib.BIO_new(_lib.BIO_s_mem())
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800853
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500854 if self._into_ssl == _ffi.NULL or self._from_ssl == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500855 # TODO: This is untested.
856 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800857
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500858 _lib.SSL_set_bio(self._ssl, self._into_ssl, self._from_ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800859 else:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800860 self._into_ssl = None
861 self._from_ssl = None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800862 self._socket = socket
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500863 set_result = _lib.SSL_set_fd(self._ssl, _asFileDescriptor(self._socket))
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800864 if not set_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500865 # TODO: This is untested.
866 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800867
868
869 def __getattr__(self, name):
870 """
871 Look up attributes on the wrapped socket object if they are not found on
872 the Connection object.
873 """
874 return getattr(self._socket, name)
875
876
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800877 def _raise_ssl_error(self, ssl, result):
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800878 if self._context._verify_helper is not None:
879 self._context._verify_helper.raise_if_problem()
880
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500881 error = _lib.SSL_get_error(ssl, result)
882 if error == _lib.SSL_ERROR_WANT_READ:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800883 raise WantReadError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500884 elif error == _lib.SSL_ERROR_WANT_WRITE:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -0700885 raise WantWriteError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500886 elif error == _lib.SSL_ERROR_ZERO_RETURN:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800887 raise ZeroReturnError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500888 elif error == _lib.SSL_ERROR_WANT_X509_LOOKUP:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500889 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -0700890 raise WantX509LookupError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500891 elif error == _lib.SSL_ERROR_SYSCALL:
892 if _lib.ERR_peek_error() == 0:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800893 if result < 0:
Konstantinos Koukopoulos541150d2014-01-31 01:00:19 +0200894 if platform == "win32":
895 errno = _ffi.getwinerror()[0]
896 else:
897 errno = _ffi.errno
898 raise SysCallError(errno, errorcode[errno])
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800899 else:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -0700900 raise SysCallError(-1, "Unexpected EOF")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800901 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500902 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500903 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500904 elif error == _lib.SSL_ERROR_NONE:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -0700905 pass
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800906 else:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500907 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800908
909
910 def get_context(self):
911 """
912 Get session context
913 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800914 return self._context
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800915
916
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800917 def set_context(self, context):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800918 """
919 Switch this connection to a new session context
920
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800921 :param context: A :py:class:`Context` instance giving the new session
922 context to use.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800923 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800924 if not isinstance(context, Context):
925 raise TypeError("context must be a Context instance")
926
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500927 _lib.SSL_set_SSL_CTX(self._ssl, context._context)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800928 self._context = context
929
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800930
931 def get_servername(self):
932 """
933 Retrieve the servername extension value if provided in the client hello
934 message, or None if there wasn't one.
935
936 :return: A byte string giving the server name or :py:data:`None`.
937 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500938 name = _lib.SSL_get_servername(self._ssl, _lib.TLSEXT_NAMETYPE_host_name)
939 if name == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800940 return None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800941
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500942 return _ffi.string(name)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800943
944
945 def set_tlsext_host_name(self, name):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800946 """
947 Set the value of the servername extension to send in the client hello.
948
949 :param name: A byte string giving the name.
950 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800951 if not isinstance(name, bytes):
952 raise TypeError("name must be a byte string")
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -0500953 elif b"\0" in name:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800954 raise TypeError("name must not contain NUL byte")
955
956 # XXX I guess this can fail sometimes?
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500957 _lib.SSL_set_tlsext_host_name(self._ssl, name)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800958
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800959
960 def pending(self):
961 """
962 Get the number of bytes that can be safely read from the connection
963
964 :return: The number of bytes available in the receive buffer.
965 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500966 return _lib.SSL_pending(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800967
968
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800969 def send(self, buf, flags=0):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800970 """
971 Send data on the connection. NOTE: If you get one of the WantRead,
972 WantWrite or WantX509Lookup exceptions on this, you have to call the
973 method again with the SAME buffer.
974
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +0200975 :param buf: The string, buffer or memoryview to send
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800976 :param flags: (optional) Included for compatibility with the socket
977 API, the value is ignored
978 :return: The number of bytes written
979 """
Abraham Martine82326c2015-02-04 10:18:10 +0000980
981 # Backward compatibility
982 if isinstance(buf, _text_type):
Abraham Martin2403ef52015-03-25 10:35:44 +0000983 warnings.warn("str object in buf is no longer accepted, use bytes", DeprecationWarning)
Abraham Martine82326c2015-02-04 10:18:10 +0000984 buf = buf.encode('utf-8')
985
Jean-Paul Calderone8fb53182013-12-30 08:35:49 -0500986 if isinstance(buf, _memoryview):
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -0800987 buf = buf.tobytes()
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +0200988 if isinstance(buf, _buffer):
989 buf = str(buf)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800990 if not isinstance(buf, bytes):
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +0200991 raise TypeError("data must be a memoryview, buffer or byte string")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800992
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500993 result = _lib.SSL_write(self._ssl, buf, len(buf))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800994 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800995 return result
996 write = send
997
998
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800999 def sendall(self, buf, flags=0):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001000 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001001 Send "all" data on the connection. This calls send() repeatedly until
1002 all data is sent. If an error occurs, it's impossible to tell how much
1003 data has been sent.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001004
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001005 :param buf: The string, buffer or memoryview to send
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001006 :param flags: (optional) Included for compatibility with the socket
1007 API, the value is ignored
1008 :return: The number of bytes written
1009 """
Abraham Martine82326c2015-02-04 10:18:10 +00001010
1011 # Backward compatibility
1012 if isinstance(buf, _text_type):
Abraham Martin2403ef52015-03-25 10:35:44 +00001013 warnings.warn("str object in buf is no longer accepted, use bytes", DeprecationWarning)
Abraham Martine82326c2015-02-04 10:18:10 +00001014 buf = buf.encode('utf-8')
1015
Jean-Paul Calderone8fb53182013-12-30 08:35:49 -05001016 if isinstance(buf, _memoryview):
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -08001017 buf = buf.tobytes()
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001018 if isinstance(buf, _buffer):
1019 buf = str(buf)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001020 if not isinstance(buf, bytes):
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001021 raise TypeError("buf must be a memoryview, buffer or byte string")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001022
1023 left_to_send = len(buf)
1024 total_sent = 0
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001025 data = _ffi.new("char[]", buf)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001026
1027 while left_to_send:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001028 result = _lib.SSL_write(self._ssl, data + total_sent, left_to_send)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001029 self._raise_ssl_error(self._ssl, result)
1030 total_sent += result
1031 left_to_send -= result
1032
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001033
1034 def recv(self, bufsiz, flags=None):
1035 """
1036 Receive data on the connection. NOTE: If you get one of the WantRead,
1037 WantWrite or WantX509Lookup exceptions on this, you have to call the
1038 method again with the SAME buffer.
1039
1040 :param bufsiz: The maximum number of bytes to read
1041 :param flags: (optional) Included for compatibility with the socket
1042 API, the value is ignored
1043 :return: The string read from the Connection
1044 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001045 buf = _ffi.new("char[]", bufsiz)
1046 result = _lib.SSL_read(self._ssl, buf, bufsiz)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001047 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001048 return _ffi.buffer(buf, result)[:]
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001049 read = recv
1050
1051
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001052 def _handle_bio_errors(self, bio, result):
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001053 if _lib.BIO_should_retry(bio):
1054 if _lib.BIO_should_read(bio):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001055 raise WantReadError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001056 elif _lib.BIO_should_write(bio):
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001057 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001058 raise WantWriteError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001059 elif _lib.BIO_should_io_special(bio):
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001060 # TODO: This is untested. I think io_special means the socket
1061 # BIO has a not-yet connected socket.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001062 raise ValueError("BIO_should_io_special")
1063 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001064 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001065 raise ValueError("unknown bio failure")
1066 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001067 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001068 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001069
1070
1071 def bio_read(self, bufsiz):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001072 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001073 When using non-socket connections this function reads the "dirty" data
1074 that would have traveled away on the network.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001075
1076 :param bufsiz: The maximum number of bytes to read
1077 :return: The string read.
1078 """
Jean-Paul Calderone97e041d2013-03-05 21:03:12 -08001079 if self._from_ssl is None:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001080 raise TypeError("Connection sock was not None")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001081
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -05001082 if not isinstance(bufsiz, integer_types):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001083 raise TypeError("bufsiz must be an integer")
1084
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001085 buf = _ffi.new("char[]", bufsiz)
1086 result = _lib.BIO_read(self._from_ssl, buf, bufsiz)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001087 if result <= 0:
1088 self._handle_bio_errors(self._from_ssl, result)
1089
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001090 return _ffi.buffer(buf, result)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001091
1092
1093 def bio_write(self, buf):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001094 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001095 When using non-socket connections this function sends "dirty" data that
1096 would have traveled in on the network.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001097
1098 :param buf: The string to put into the memory BIO.
1099 :return: The number of bytes written
1100 """
Abraham Martine82326c2015-02-04 10:18:10 +00001101
1102 # Backward compatibility
1103 if isinstance(buf, _text_type):
Abraham Martin2403ef52015-03-25 10:35:44 +00001104 warnings.warn("str object in buf is no longer accepted, use bytes", DeprecationWarning)
Abraham Martine82326c2015-02-04 10:18:10 +00001105 buf = buf.encode("ascii")
1106
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001107 if self._into_ssl is None:
1108 raise TypeError("Connection sock was not None")
1109
1110 if not isinstance(buf, bytes):
1111 raise TypeError("buf must be a byte string")
1112
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001113 result = _lib.BIO_write(self._into_ssl, buf, len(buf))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001114 if result <= 0:
1115 self._handle_bio_errors(self._into_ssl, result)
1116 return result
1117
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001118
1119 def renegotiate(self):
1120 """
1121 Renegotiate the session
1122
1123 :return: True if the renegotiation can be started, false otherwise
1124 """
1125
1126 def do_handshake(self):
1127 """
1128 Perform an SSL handshake (usually called after renegotiate() or one of
1129 set_*_state()). This can raise the same exceptions as send and recv.
1130
1131 :return: None.
1132 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001133 result = _lib.SSL_do_handshake(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001134 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001135
1136
1137 def renegotiate_pending(self):
1138 """
1139 Check if there's a renegotiation in progress, it will return false once
1140 a renegotiation is finished.
1141
1142 :return: Whether there's a renegotiation in progress
1143 """
1144
1145 def total_renegotiations(self):
1146 """
1147 Find out the total number of renegotiations.
1148
1149 :return: The number of renegotiations.
1150 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001151 return _lib.SSL_total_renegotiations(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001152
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001153
1154 def connect(self, addr):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001155 """
1156 Connect to remote host and set up client-side SSL
1157
1158 :param addr: A remote address
1159 :return: What the socket's connect method returns
1160 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001161 _lib.SSL_set_connect_state(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001162 return self._socket.connect(addr)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001163
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001164
1165 def connect_ex(self, addr):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001166 """
1167 Connect to remote host and set up client-side SSL. Note that if the socket's
1168 connect_ex method doesn't return 0, SSL won't be initialized.
1169
1170 :param addr: A remove address
1171 :return: What the socket's connect_ex method returns
1172 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001173 connect_ex = self._socket.connect_ex
1174 self.set_connect_state()
1175 return connect_ex(addr)
1176
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001177
1178 def accept(self):
1179 """
1180 Accept incoming connection and set up SSL on it
1181
1182 :return: A (conn,addr) pair where conn is a Connection and addr is an
1183 address
1184 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001185 client, addr = self._socket.accept()
1186 conn = Connection(self._context, client)
1187 conn.set_accept_state()
1188 return (conn, addr)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001189
1190
1191 def bio_shutdown(self):
1192 """
1193 When using non-socket connections this function signals end of
1194 data on the input for this connection.
1195
1196 :return: None
1197 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001198 if self._from_ssl is None:
1199 raise TypeError("Connection sock was not None")
1200
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001201 _lib.BIO_set_mem_eof_return(self._into_ssl, 0)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001202
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001203
1204 def shutdown(self):
1205 """
1206 Send closure alert
1207
1208 :return: True if the shutdown completed successfully (i.e. both sides
1209 have sent closure alerts), false otherwise (i.e. you have to
1210 wait for a ZeroReturnError on a recv() method call
1211 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001212 result = _lib.SSL_shutdown(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001213 if result < 0:
Paul Aurichbff1d1a2015-01-08 08:36:53 -08001214 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001215 elif result > 0:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001216 return True
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001217 else:
1218 return False
1219
1220
1221 def get_cipher_list(self):
1222 """
1223 Get the session cipher list
1224
1225 :return: A list of cipher strings
1226 """
1227 ciphers = []
1228 for i in count():
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001229 result = _lib.SSL_get_cipher_list(self._ssl, i)
1230 if result == _ffi.NULL:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001231 break
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001232 ciphers.append(_native(_ffi.string(result)))
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001233 return ciphers
1234
1235
1236 def get_client_ca_list(self):
1237 """
1238 Get CAs whose certificates are suggested for client authentication.
1239
1240 :return: If this is a server connection, a list of X509Names representing
1241 the acceptable CAs as set by :py:meth:`OpenSSL.SSL.Context.set_client_ca_list` or
1242 :py:meth:`OpenSSL.SSL.Context.add_client_ca`. If this is a client connection,
1243 the list of such X509Names sent by the server, or an empty list if that
1244 has not yet happened.
1245 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001246 ca_names = _lib.SSL_get_client_CA_list(self._ssl)
1247 if ca_names == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001248 # TODO: This is untested.
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001249 return []
1250
1251 result = []
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001252 for i in range(_lib.sk_X509_NAME_num(ca_names)):
1253 name = _lib.sk_X509_NAME_value(ca_names, i)
1254 copy = _lib.X509_NAME_dup(name)
1255 if copy == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001256 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001257 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001258
1259 pyname = X509Name.__new__(X509Name)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001260 pyname._name = _ffi.gc(copy, _lib.X509_NAME_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001261 result.append(pyname)
1262 return result
1263
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001264
1265 def makefile(self):
1266 """
1267 The makefile() method is not implemented, since there is no dup semantics
1268 for SSL connections
1269
Jean-Paul Calderone6749ec22014-04-17 16:30:21 -04001270 :raise: NotImplementedError
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001271 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001272 raise NotImplementedError("Cannot make file object of OpenSSL.SSL.Connection")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001273
1274
1275 def get_app_data(self):
1276 """
1277 Get application data
1278
1279 :return: The application data
1280 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001281 return self._app_data
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001282
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001283
1284 def set_app_data(self, data):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001285 """
1286 Set application data
1287
1288 :param data - The application data
1289 :return: None
1290 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001291 self._app_data = data
1292
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001293
1294 def get_shutdown(self):
1295 """
1296 Get shutdown state
1297
1298 :return: The shutdown state, a bitvector of SENT_SHUTDOWN, RECEIVED_SHUTDOWN.
1299 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001300 return _lib.SSL_get_shutdown(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001301
1302
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001303 def set_shutdown(self, state):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001304 """
1305 Set shutdown state
1306
1307 :param state - bitvector of SENT_SHUTDOWN, RECEIVED_SHUTDOWN.
1308 :return: None
1309 """
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -05001310 if not isinstance(state, integer_types):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001311 raise TypeError("state must be an integer")
1312
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001313 _lib.SSL_set_shutdown(self._ssl, state)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001314
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001315
1316 def state_string(self):
1317 """
1318 Get a verbose state description
1319
1320 :return: A string representing the state
1321 """
1322
1323 def server_random(self):
1324 """
1325 Get a copy of the server hello nonce.
1326
1327 :return: A string representing the state
1328 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001329 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001330 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001331 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001332 self._ssl.s3.server_random,
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001333 _lib.SSL3_RANDOM_SIZE)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001334
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001335
1336 def client_random(self):
1337 """
1338 Get a copy of the client 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.client_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 master_key(self):
1350 """
1351 Get a copy of the master key.
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.session.master_key,
1359 self._ssl.session.master_key_length)[:]
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001360
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001361
1362 def sock_shutdown(self, *args, **kwargs):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001363 """
1364 See shutdown(2)
1365
1366 :return: What the socket's shutdown() method returns
1367 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001368 return self._socket.shutdown(*args, **kwargs)
1369
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001370
1371 def get_peer_certificate(self):
1372 """
1373 Retrieve the other side's certificate (if any)
1374
1375 :return: The peer's certificate
1376 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001377 cert = _lib.SSL_get_peer_certificate(self._ssl)
1378 if cert != _ffi.NULL:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001379 pycert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001380 pycert._x509 = _ffi.gc(cert, _lib.X509_free)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001381 return pycert
1382 return None
1383
1384
1385 def get_peer_cert_chain(self):
1386 """
1387 Retrieve the other side's certificate (if any)
1388
1389 :return: A list of X509 instances giving the peer's certificate chain,
1390 or None if it does not have one.
1391 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001392 cert_stack = _lib.SSL_get_peer_cert_chain(self._ssl)
1393 if cert_stack == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001394 return None
1395
1396 result = []
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001397 for i in range(_lib.sk_X509_num(cert_stack)):
Jean-Paul Calderone73b15c22013-03-05 18:30:39 -08001398 # TODO could incref instead of dup here
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001399 cert = _lib.X509_dup(_lib.sk_X509_value(cert_stack, i))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001400 pycert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001401 pycert._x509 = _ffi.gc(cert, _lib.X509_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001402 result.append(pycert)
1403 return result
1404
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001405
1406 def want_read(self):
1407 """
1408 Checks if more data has to be read from the transport layer to complete an
1409 operation.
1410
1411 :return: True iff more data has to be read
1412 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001413 return _lib.SSL_want_read(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001414
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001415
1416 def want_write(self):
1417 """
1418 Checks if there is data to write to the transport layer to complete an
1419 operation.
1420
1421 :return: True iff there is data to write
1422 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001423 return _lib.SSL_want_write(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001424
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001425
1426 def set_accept_state(self):
1427 """
1428 Set the connection to work in server mode. The handshake will be handled
1429 automatically by read/write.
1430
1431 :return: None
1432 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001433 _lib.SSL_set_accept_state(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001434
1435
1436 def set_connect_state(self):
1437 """
1438 Set the connection to work in client mode. The handshake will be handled
1439 automatically by read/write.
1440
1441 :return: None
1442 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001443 _lib.SSL_set_connect_state(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001444
1445
1446 def get_session(self):
1447 """
1448 Returns the Session currently used.
1449
1450 @return: An instance of :py:class:`OpenSSL.SSL.Session` or :py:obj:`None` if
1451 no session exists.
1452 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001453 session = _lib.SSL_get1_session(self._ssl)
1454 if session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001455 return None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001456
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001457 pysession = Session.__new__(Session)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001458 pysession._session = _ffi.gc(session, _lib.SSL_SESSION_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001459 return pysession
1460
1461
1462 def set_session(self, session):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001463 """
1464 Set the session to be used when the TLS/SSL connection is established.
1465
1466 :param session: A Session instance representing the session to use.
1467 :returns: None
1468 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001469 if not isinstance(session, Session):
1470 raise TypeError("session must be a Session instance")
1471
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001472 result = _lib.SSL_set_session(self._ssl, session._session)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001473 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001474 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001475
Jean-Paul Calderonedbd76272014-03-29 18:09:40 -04001476
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001477 def _get_finished_message(self, function):
1478 """
1479 Helper to implement :py:meth:`get_finished` and
1480 :py:meth:`get_peer_finished`.
1481
1482 :param function: Either :py:data:`SSL_get_finished`: or
1483 :py:data:`SSL_get_peer_finished`.
1484
1485 :return: :py:data:`None` if the desired message has not yet been
1486 received, otherwise the contents of the message.
1487 :rtype: :py:class:`bytes` or :py:class:`NoneType`
1488 """
Jean-Paul Calderone01af9042014-03-30 11:40:42 -04001489 # The OpenSSL documentation says nothing about what might happen if the
1490 # count argument given is zero. Specifically, it doesn't say whether
1491 # the output buffer may be NULL in that case or not. Inspection of the
1492 # implementation reveals that it calls memcpy() unconditionally.
1493 # Section 7.1.4, paragraph 1 of the C standard suggests that
1494 # memcpy(NULL, source, 0) is not guaranteed to produce defined (let
1495 # alone desirable) behavior (though it probably does on just about
1496 # every implementation...)
1497 #
1498 # Allocate a tiny buffer to pass in (instead of just passing NULL as
1499 # one might expect) for the initial call so as to be safe against this
1500 # potentially undefined behavior.
1501 empty = _ffi.new("char[]", 0)
1502 size = function(self._ssl, empty, 0)
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001503 if size == 0:
1504 # No Finished message so far.
1505 return None
1506
1507 buf = _ffi.new("char[]", size)
1508 function(self._ssl, buf, size)
1509 return _ffi.buffer(buf, size)[:]
1510
1511
Fedor Brunner5747b932014-03-05 14:22:34 +01001512 def get_finished(self):
1513 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001514 Obtain the latest `handshake finished` message sent to the peer.
Fedor Brunner5747b932014-03-05 14:22:34 +01001515
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001516 :return: The contents of the message or :py:obj:`None` if the TLS
1517 handshake has not yet completed.
1518 :rtype: :py:class:`bytes` or :py:class:`NoneType`
Fedor Brunner5747b932014-03-05 14:22:34 +01001519 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001520 return self._get_finished_message(_lib.SSL_get_finished)
1521
Fedor Brunner5747b932014-03-05 14:22:34 +01001522
1523 def get_peer_finished(self):
1524 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001525 Obtain the latest `handshake finished` message received from the peer.
Fedor Brunner5747b932014-03-05 14:22:34 +01001526
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001527 :return: The contents of the message or :py:obj:`None` if the TLS
1528 handshake has not yet completed.
1529 :rtype: :py:class:`bytes` or :py:class:`NoneType`
Fedor Brunner5747b932014-03-05 14:22:34 +01001530 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001531 return self._get_finished_message(_lib.SSL_get_peer_finished)
Fedor Brunner5747b932014-03-05 14:22:34 +01001532
Jean-Paul Calderone7c556ef2014-03-30 10:45:00 -04001533
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001534 def get_cipher_name(self):
1535 """
1536 Obtain the name of the currently used cipher.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001537
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001538 :returns: The name of the currently used cipher or :py:obj:`None`
1539 if no connection has been established.
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001540 :rtype: :py:class:`unicode` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001541 """
1542 cipher = _lib.SSL_get_current_cipher(self._ssl)
1543 if cipher == _ffi.NULL:
1544 return None
1545 else:
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001546 name = _ffi.string(_lib.SSL_CIPHER_get_name(cipher))
1547 return name.decode("utf-8")
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001548
Jean-Paul Calderonedbd76272014-03-29 18:09:40 -04001549
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001550 def get_cipher_bits(self):
1551 """
1552 Obtain the number of secret bits of the currently used cipher.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001553
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001554 :returns: The number of secret bits of the currently used cipher
1555 or :py:obj:`None` if no connection has been established.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001556 :rtype: :py:class:`int` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001557 """
1558 cipher = _lib.SSL_get_current_cipher(self._ssl)
1559 if cipher == _ffi.NULL:
1560 return None
1561 else:
1562 return _lib.SSL_CIPHER_get_bits(cipher, _ffi.NULL)
1563
Jean-Paul Calderonedbd76272014-03-29 18:09:40 -04001564
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001565 def get_cipher_version(self):
1566 """
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001567 Obtain the protocol version of the currently used cipher.
1568
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001569 :returns: The protocol name of the currently used cipher
1570 or :py:obj:`None` if no connection has been established.
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001571 :rtype: :py:class:`unicode` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001572 """
1573 cipher = _lib.SSL_get_current_cipher(self._ssl)
1574 if cipher == _ffi.NULL:
1575 return None
1576 else:
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001577 version =_ffi.string(_lib.SSL_CIPHER_get_version(cipher))
1578 return version.decode("utf-8")
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001579
1580
1581
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001582ConnectionType = Connection
Jean-Paul Calderone11ed8e82014-01-18 10:21:50 -05001583
Jean-Paul Calderonefab157b2014-01-18 11:21:38 -05001584# This is similar to the initialization calls at the end of OpenSSL/crypto.py
1585# but is exercised mostly by the Context initializer.
Jean-Paul Calderone11ed8e82014-01-18 10:21:50 -05001586_lib.SSL_library_init()