blob: 2731d64a8801a6e74172e8b4a0a964c6e31e3143 [file] [log] [blame]
Konstantinos Koukopoulos541150d2014-01-31 01:00:19 +02001from sys import platform
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05002from functools import wraps, partial
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08003from itertools import count
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08004from weakref import WeakValueDictionary
5from errno import errorcode
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -08006
Jean-Paul Calderone63eab692014-01-18 10:19:56 -05007from six import text_type as _text_type
Konstantinos Koukopoulosc8b13ea2014-01-28 00:21:50 -08008from six import integer_types as integer_types
Jean-Paul Calderone63eab692014-01-18 10:19:56 -05009
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -050010from OpenSSL._util import (
11 ffi as _ffi,
12 lib as _lib,
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -050013 exception_from_error_queue as _exception_from_error_queue,
14 native as _native)
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080015
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -080016from OpenSSL.crypto import (
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -050017 FILETYPE_PEM, _PassphraseHelper, PKey, X509Name, X509, X509Store)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -080018
19_unspecified = object()
20
Jean-Paul Calderone8fb53182013-12-30 08:35:49 -050021try:
22 _memoryview = memoryview
23except NameError:
24 class _memoryview(object):
25 pass
26
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +020027try:
28 _buffer = buffer
29except NameError:
30 class _buffer(object):
31 pass
32
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050033OPENSSL_VERSION_NUMBER = _lib.OPENSSL_VERSION_NUMBER
34SSLEAY_VERSION = _lib.SSLEAY_VERSION
35SSLEAY_CFLAGS = _lib.SSLEAY_CFLAGS
36SSLEAY_PLATFORM = _lib.SSLEAY_PLATFORM
37SSLEAY_DIR = _lib.SSLEAY_DIR
38SSLEAY_BUILT_ON = _lib.SSLEAY_BUILT_ON
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080039
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050040SENT_SHUTDOWN = _lib.SSL_SENT_SHUTDOWN
41RECEIVED_SHUTDOWN = _lib.SSL_RECEIVED_SHUTDOWN
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080042
43SSLv2_METHOD = 1
44SSLv3_METHOD = 2
45SSLv23_METHOD = 3
46TLSv1_METHOD = 4
Jean-Paul Calderone56bff942013-11-03 11:30:43 -050047TLSv1_1_METHOD = 5
48TLSv1_2_METHOD = 6
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080049
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050050OP_NO_SSLv2 = _lib.SSL_OP_NO_SSLv2
51OP_NO_SSLv3 = _lib.SSL_OP_NO_SSLv3
52OP_NO_TLSv1 = _lib.SSL_OP_NO_TLSv1
Jean-Paul Calderonebe2bb422013-12-29 07:34:08 -050053
54OP_NO_TLSv1_1 = getattr(_lib, "SSL_OP_NO_TLSv1_1", 0)
55OP_NO_TLSv1_2 = getattr(_lib, "SSL_OP_NO_TLSv1_2", 0)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -080056
Jean-Paul Calderone0d7e8a12014-01-08 16:54:13 -050057try:
58 MODE_RELEASE_BUFFERS = _lib.SSL_MODE_RELEASE_BUFFERS
59except AttributeError:
60 pass
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080061
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050062OP_SINGLE_DH_USE = _lib.SSL_OP_SINGLE_DH_USE
63OP_EPHEMERAL_RSA = _lib.SSL_OP_EPHEMERAL_RSA
64OP_MICROSOFT_SESS_ID_BUG = _lib.SSL_OP_MICROSOFT_SESS_ID_BUG
65OP_NETSCAPE_CHALLENGE_BUG = _lib.SSL_OP_NETSCAPE_CHALLENGE_BUG
66OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG = _lib.SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG
67OP_SSLREF2_REUSE_CERT_TYPE_BUG = _lib.SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG
68OP_MICROSOFT_BIG_SSLV3_BUFFER = _lib.SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER
Jean-Paul Calderone0d7e8a12014-01-08 16:54:13 -050069try:
70 OP_MSIE_SSLV2_RSA_PADDING = _lib.SSL_OP_MSIE_SSLV2_RSA_PADDING
71except AttributeError:
72 pass
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050073OP_SSLEAY_080_CLIENT_DH_BUG = _lib.SSL_OP_SSLEAY_080_CLIENT_DH_BUG
74OP_TLS_D5_BUG = _lib.SSL_OP_TLS_D5_BUG
75OP_TLS_BLOCK_PADDING_BUG = _lib.SSL_OP_TLS_BLOCK_PADDING_BUG
76OP_DONT_INSERT_EMPTY_FRAGMENTS = _lib.SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
77OP_CIPHER_SERVER_PREFERENCE = _lib.SSL_OP_CIPHER_SERVER_PREFERENCE
78OP_TLS_ROLLBACK_BUG = _lib.SSL_OP_TLS_ROLLBACK_BUG
79OP_PKCS1_CHECK_1 = _lib.SSL_OP_PKCS1_CHECK_1
80OP_PKCS1_CHECK_2 = _lib.SSL_OP_PKCS1_CHECK_2
81OP_NETSCAPE_CA_DN_BUG = _lib.SSL_OP_NETSCAPE_CA_DN_BUG
82OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG= _lib.SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG
Jean-Paul Calderonec1780342014-01-08 16:59:03 -050083try:
84 OP_NO_COMPRESSION = _lib.SSL_OP_NO_COMPRESSION
85except AttributeError:
86 pass
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -080087
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050088OP_NO_QUERY_MTU = _lib.SSL_OP_NO_QUERY_MTU
89OP_COOKIE_EXCHANGE = _lib.SSL_OP_COOKIE_EXCHANGE
Arturo Filastò5f8c7a82014-03-09 20:01:25 +010090try:
91 OP_NO_TICKET = _lib.SSL_OP_NO_TICKET
92except AttributeError:
93 pass
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -080094
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050095OP_ALL = _lib.SSL_OP_ALL
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080096
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050097VERIFY_PEER = _lib.SSL_VERIFY_PEER
98VERIFY_FAIL_IF_NO_PEER_CERT = _lib.SSL_VERIFY_FAIL_IF_NO_PEER_CERT
99VERIFY_CLIENT_ONCE = _lib.SSL_VERIFY_CLIENT_ONCE
100VERIFY_NONE = _lib.SSL_VERIFY_NONE
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -0800101
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500102SESS_CACHE_OFF = _lib.SSL_SESS_CACHE_OFF
103SESS_CACHE_CLIENT = _lib.SSL_SESS_CACHE_CLIENT
104SESS_CACHE_SERVER = _lib.SSL_SESS_CACHE_SERVER
105SESS_CACHE_BOTH = _lib.SSL_SESS_CACHE_BOTH
106SESS_CACHE_NO_AUTO_CLEAR = _lib.SSL_SESS_CACHE_NO_AUTO_CLEAR
107SESS_CACHE_NO_INTERNAL_LOOKUP = _lib.SSL_SESS_CACHE_NO_INTERNAL_LOOKUP
108SESS_CACHE_NO_INTERNAL_STORE = _lib.SSL_SESS_CACHE_NO_INTERNAL_STORE
109SESS_CACHE_NO_INTERNAL = _lib.SSL_SESS_CACHE_NO_INTERNAL
Jean-Paul Calderoned39a3f62013-03-04 12:23:51 -0800110
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500111SSL_ST_CONNECT = _lib.SSL_ST_CONNECT
112SSL_ST_ACCEPT = _lib.SSL_ST_ACCEPT
113SSL_ST_MASK = _lib.SSL_ST_MASK
114SSL_ST_INIT = _lib.SSL_ST_INIT
115SSL_ST_BEFORE = _lib.SSL_ST_BEFORE
116SSL_ST_OK = _lib.SSL_ST_OK
117SSL_ST_RENEGOTIATE = _lib.SSL_ST_RENEGOTIATE
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800118
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500119SSL_CB_LOOP = _lib.SSL_CB_LOOP
120SSL_CB_EXIT = _lib.SSL_CB_EXIT
121SSL_CB_READ = _lib.SSL_CB_READ
122SSL_CB_WRITE = _lib.SSL_CB_WRITE
123SSL_CB_ALERT = _lib.SSL_CB_ALERT
124SSL_CB_READ_ALERT = _lib.SSL_CB_READ_ALERT
125SSL_CB_WRITE_ALERT = _lib.SSL_CB_WRITE_ALERT
126SSL_CB_ACCEPT_LOOP = _lib.SSL_CB_ACCEPT_LOOP
127SSL_CB_ACCEPT_EXIT = _lib.SSL_CB_ACCEPT_EXIT
128SSL_CB_CONNECT_LOOP = _lib.SSL_CB_CONNECT_LOOP
129SSL_CB_CONNECT_EXIT = _lib.SSL_CB_CONNECT_EXIT
130SSL_CB_HANDSHAKE_START = _lib.SSL_CB_HANDSHAKE_START
131SSL_CB_HANDSHAKE_DONE = _lib.SSL_CB_HANDSHAKE_DONE
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800132
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500133class Error(Exception):
Jean-Paul Calderone511cde02013-12-29 10:31:13 -0500134 """
135 An error occurred in an `OpenSSL.SSL` API.
136 """
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500137
138
139
140_raise_current_error = partial(_exception_from_error_queue, Error)
141
142
143class WantReadError(Error):
144 pass
145
146
147
148class WantWriteError(Error):
149 pass
150
151
152
153class WantX509LookupError(Error):
154 pass
155
156
157
158class ZeroReturnError(Error):
159 pass
160
161
162
163class SysCallError(Error):
164 pass
165
166
167
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800168class _VerifyHelper(object):
Jean-Paul Calderone6a8cd112014-04-02 21:09:08 -0400169 def __init__(self, callback):
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800170 self._problems = []
171
172 @wraps(callback)
173 def wrapper(ok, store_ctx):
174 cert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500175 cert._x509 = _lib.X509_STORE_CTX_get_current_cert(store_ctx)
176 error_number = _lib.X509_STORE_CTX_get_error(store_ctx)
177 error_depth = _lib.X509_STORE_CTX_get_error_depth(store_ctx)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800178
Jean-Paul Calderone6a8cd112014-04-02 21:09:08 -0400179 index = _lib.SSL_get_ex_data_X509_STORE_CTX_idx()
180 ssl = _lib.X509_STORE_CTX_get_ex_data(store_ctx, index)
181 connection = Connection._reverse_mapping[ssl]
182
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800183 try:
184 result = callback(connection, cert, error_number, error_depth, ok)
185 except Exception as e:
186 self._problems.append(e)
187 return 0
188 else:
189 if result:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500190 _lib.X509_STORE_CTX_set_error(store_ctx, _lib.X509_V_OK)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800191 return 1
192 else:
193 return 0
194
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500195 self.callback = _ffi.callback(
196 "int (*)(int, X509_STORE_CTX *)", wrapper)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800197
198
199 def raise_if_problem(self):
200 if self._problems:
201 try:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500202 _raise_current_error()
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800203 except Error:
204 pass
205 raise self._problems.pop(0)
206
207
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800208
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800209def _asFileDescriptor(obj):
210 fd = None
Konstantinos Koukopoulosc8b13ea2014-01-28 00:21:50 -0800211 if not isinstance(obj, integer_types):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800212 meth = getattr(obj, "fileno", None)
213 if meth is not None:
214 obj = meth()
215
Konstantinos Koukopoulosc8b13ea2014-01-28 00:21:50 -0800216 if isinstance(obj, integer_types):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800217 fd = obj
218
Konstantinos Koukopoulosc8b13ea2014-01-28 00:21:50 -0800219 if not isinstance(fd, integer_types):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800220 raise TypeError("argument must be an int, or have a fileno() method.")
221 elif fd < 0:
222 raise ValueError(
223 "file descriptor cannot be a negative integer (%i)" % (fd,))
224
225 return fd
226
227
228
Jean-Paul Calderoned39a3f62013-03-04 12:23:51 -0800229def SSLeay_version(type):
230 """
231 Return a string describing the version of OpenSSL in use.
232
233 :param type: One of the SSLEAY_ constants defined in this module.
234 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500235 return _ffi.string(_lib.SSLeay_version(type))
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800236
237
238
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800239class Session(object):
240 pass
241
242
243
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800244class Context(object):
245 """
246 :py:obj:`OpenSSL.SSL.Context` instances define the parameters for setting up
247 new SSL connections.
248 """
249 _methods = {
Andrew Dunhamec84a0a2014-02-24 12:41:37 -0800250 SSLv2_METHOD: "SSLv2_method",
Jean-Paul Calderonebe2bb422013-12-29 07:34:08 -0500251 SSLv3_METHOD: "SSLv3_method",
252 SSLv23_METHOD: "SSLv23_method",
253 TLSv1_METHOD: "TLSv1_method",
254 TLSv1_1_METHOD: "TLSv1_1_method",
255 TLSv1_2_METHOD: "TLSv1_2_method",
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800256 }
Jean-Paul Calderonebe2bb422013-12-29 07:34:08 -0500257 _methods = dict(
258 (identifier, getattr(_lib, name))
259 for (identifier, name) in _methods.items()
260 if getattr(_lib, name, None) is not None)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800261
Jean-Paul Calderone63157872013-03-20 16:43:38 -0700262
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800263 def __init__(self, method):
264 """
265 :param method: One of SSLv2_METHOD, SSLv3_METHOD, SSLv23_METHOD, or
266 TLSv1_METHOD.
267 """
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -0500268 if not isinstance(method, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800269 raise TypeError("method must be an integer")
270
271 try:
272 method_func = self._methods[method]
273 except KeyError:
274 raise ValueError("No such protocol")
275
276 method_obj = method_func()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500277 if method_obj == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500278 # TODO: This is untested.
279 _raise_current_error()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800280
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500281 context = _lib.SSL_CTX_new(method_obj)
282 if context == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500283 # TODO: This is untested.
284 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500285 context = _ffi.gc(context, _lib.SSL_CTX_free)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800286
287 self._context = context
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800288 self._passphrase_helper = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800289 self._passphrase_callback = None
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800290 self._passphrase_userdata = None
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800291 self._verify_helper = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800292 self._verify_callback = None
293 self._info_callback = None
294 self._tlsext_servername_callback = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800295 self._app_data = None
296
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -0800297 # SSL_CTX_set_app_data(self->ctx, self);
298 # SSL_CTX_set_mode(self->ctx, SSL_MODE_ENABLE_PARTIAL_WRITE |
299 # SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
300 # SSL_MODE_AUTO_RETRY);
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500301 self.set_mode(_lib.SSL_MODE_ENABLE_PARTIAL_WRITE)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800302
303
304 def load_verify_locations(self, cafile, capath=None):
305 """
306 Let SSL know where we can find trusted certificates for the certificate
307 chain
308
309 :param cafile: In which file we can find the certificates
310 :param capath: In which directory we can find the certificates
311 :return: None
312 """
313 if cafile is None:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500314 cafile = _ffi.NULL
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800315 elif not isinstance(cafile, bytes):
316 raise TypeError("cafile must be None or a byte string")
317
318 if capath is None:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500319 capath = _ffi.NULL
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800320 elif not isinstance(capath, bytes):
321 raise TypeError("capath must be None or a byte string")
322
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500323 load_result = _lib.SSL_CTX_load_verify_locations(self._context, cafile, capath)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800324 if not load_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500325 _raise_current_error()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800326
327
328 def _wrap_callback(self, callback):
329 @wraps(callback)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800330 def wrapper(size, verify, userdata):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800331 return callback(size, verify, self._passphrase_userdata)
332 return _PassphraseHelper(
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800333 FILETYPE_PEM, wrapper, more_args=True, truncate=True)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800334
335
336 def set_passwd_cb(self, callback, userdata=None):
337 """
338 Set the passphrase callback
339
340 :param callback: The Python callback to use
341 :param userdata: (optional) A Python object which will be given as
342 argument to the callback
343 :return: None
344 """
345 if not callable(callback):
346 raise TypeError("callback must be callable")
347
348 self._passphrase_helper = self._wrap_callback(callback)
349 self._passphrase_callback = self._passphrase_helper.callback
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500350 _lib.SSL_CTX_set_default_passwd_cb(
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800351 self._context, self._passphrase_callback)
352 self._passphrase_userdata = userdata
353
354
355 def set_default_verify_paths(self):
356 """
357 Use the platform-specific CA certificate locations
358
359 :return: None
360 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500361 set_result = _lib.SSL_CTX_set_default_verify_paths(self._context)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800362 if not set_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500363 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500364 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800365
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800366
367 def use_certificate_chain_file(self, certfile):
368 """
369 Load a certificate chain from a file
370
371 :param certfile: The name of the certificate chain file
372 :return: None
373 """
Jean-Paul Calderoned8607982014-01-18 10:30:55 -0500374 if isinstance(certfile, _text_type):
375 # Perhaps sys.getfilesystemencoding() could be better?
376 certfile = certfile.encode("utf-8")
377
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800378 if not isinstance(certfile, bytes):
Jean-Paul Calderoned8607982014-01-18 10:30:55 -0500379 raise TypeError("certfile must be bytes or unicode")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800380
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500381 result = _lib.SSL_CTX_use_certificate_chain_file(self._context, certfile)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800382 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500383 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800384
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800385
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800386 def use_certificate_file(self, certfile, filetype=FILETYPE_PEM):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800387 """
388 Load a certificate from a file
389
390 :param certfile: The name of the certificate file
391 :param filetype: (optional) The encoding of the file, default is PEM
392 :return: None
393 """
Jean-Paul Calderone684baf52014-01-18 10:31:19 -0500394 if isinstance(certfile, _text_type):
395 # Perhaps sys.getfilesystemencoding() could be better?
396 certfile = certfile.encode("utf-8")
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800397 if not isinstance(certfile, bytes):
Jean-Paul Calderone684baf52014-01-18 10:31:19 -0500398 raise TypeError("certfile must be bytes or unicode")
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -0500399 if not isinstance(filetype, integer_types):
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800400 raise TypeError("filetype must be an integer")
401
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500402 use_result = _lib.SSL_CTX_use_certificate_file(self._context, certfile, filetype)
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800403 if not use_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500404 _raise_current_error()
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800405
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800406
407 def use_certificate(self, cert):
408 """
409 Load a certificate from a X509 object
410
411 :param cert: The X509 object
412 :return: None
413 """
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800414 if not isinstance(cert, X509):
415 raise TypeError("cert must be an X509 instance")
416
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500417 use_result = _lib.SSL_CTX_use_certificate(self._context, cert._x509)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800418 if not use_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500419 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800420
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800421
422 def add_extra_chain_cert(self, certobj):
423 """
424 Add certificate to chain
425
426 :param certobj: The X509 certificate object to add to the chain
427 :return: None
428 """
429 if not isinstance(certobj, X509):
430 raise TypeError("certobj must be an X509 instance")
431
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500432 copy = _lib.X509_dup(certobj._x509)
433 add_result = _lib.SSL_CTX_add_extra_chain_cert(self._context, copy)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800434 if not add_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500435 # TODO: This is untested.
436 _lib.X509_free(copy)
437 _raise_current_error()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800438
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800439
440 def _raise_passphrase_exception(self):
441 if self._passphrase_helper is None:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500442 _raise_current_error()
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800443 exception = self._passphrase_helper.raise_if_problem(Error)
444 if exception is not None:
445 raise exception
446
447
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800448 def use_privatekey_file(self, keyfile, filetype=_unspecified):
449 """
450 Load a private key from a file
451
452 :param keyfile: The name of the key file
453 :param filetype: (optional) The encoding of the file, default is PEM
454 :return: None
455 """
Jean-Paul Calderone87e525a2014-01-18 10:31:51 -0500456 if isinstance(keyfile, _text_type):
457 # Perhaps sys.getfilesystemencoding() could be better?
458 keyfile = keyfile.encode("utf-8")
459
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800460 if not isinstance(keyfile, bytes):
461 raise TypeError("keyfile must be a byte string")
462
463 if filetype is _unspecified:
464 filetype = FILETYPE_PEM
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -0500465 elif not isinstance(filetype, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800466 raise TypeError("filetype must be an integer")
467
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500468 use_result = _lib.SSL_CTX_use_PrivateKey_file(
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800469 self._context, keyfile, filetype)
470 if not use_result:
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800471 self._raise_passphrase_exception()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800472
473
474 def use_privatekey(self, pkey):
475 """
476 Load a private key from a PKey object
477
478 :param pkey: The PKey object
479 :return: None
480 """
481 if not isinstance(pkey, PKey):
482 raise TypeError("pkey must be a PKey instance")
483
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500484 use_result = _lib.SSL_CTX_use_PrivateKey(self._context, pkey._pkey)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800485 if not use_result:
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800486 self._raise_passphrase_exception()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800487
488
489 def check_privatekey(self):
490 """
491 Check that the private key and certificate match up
492
493 :return: None (raises an exception if something's wrong)
494 """
Jean-Paul Calderonea0344922014-12-11 14:02:31 -0500495 if not _lib.SSL_CTX_check_private_key(self._context):
496 _raise_current_error()
497
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800498
499 def load_client_ca(self, cafile):
500 """
501 Load the trusted certificates that will be sent to the client (basically
502 telling the client "These are the guys I trust"). Does not actually
503 imply any of the certificates are trusted; that must be configured
504 separately.
505
506 :param cafile: The name of the certificates file
507 :return: None
508 """
509
510 def set_session_id(self, buf):
511 """
512 Set the session identifier. This is needed if you want to do session
513 resumption.
514
515 :param buf: A Python object that can be safely converted to a string
516 :returns: None
517 """
518
519 def set_session_cache_mode(self, mode):
520 """
521 Enable/disable session caching and specify the mode used.
522
523 :param mode: One or more of the SESS_CACHE_* flags (combine using
524 bitwise or)
525 :returns: The previously set caching mode.
526 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500527 if not isinstance(mode, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800528 raise TypeError("mode must be an integer")
529
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500530 return _lib.SSL_CTX_set_session_cache_mode(self._context, mode)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800531
532
533 def get_session_cache_mode(self):
534 """
535 :returns: The currently used cache mode.
536 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500537 return _lib.SSL_CTX_get_session_cache_mode(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800538
539
540 def set_verify(self, mode, callback):
541 """
542 Set the verify mode and verify callback
543
544 :param mode: The verify mode, this is either VERIFY_NONE or
545 VERIFY_PEER combined with possible other flags
546 :param callback: The Python callback to use
547 :return: None
548
549 See SSL_CTX_set_verify(3SSL) for further details.
550 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500551 if not isinstance(mode, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800552 raise TypeError("mode must be an integer")
553
554 if not callable(callback):
555 raise TypeError("callback must be callable")
556
Jean-Paul Calderone6a8cd112014-04-02 21:09:08 -0400557 self._verify_helper = _VerifyHelper(callback)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800558 self._verify_callback = self._verify_helper.callback
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500559 _lib.SSL_CTX_set_verify(self._context, mode, self._verify_callback)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800560
561
562 def set_verify_depth(self, depth):
563 """
564 Set the verify depth
565
566 :param depth: An integer specifying the verify depth
567 :return: None
568 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500569 if not isinstance(depth, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800570 raise TypeError("depth must be an integer")
571
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500572 _lib.SSL_CTX_set_verify_depth(self._context, depth)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800573
574
575 def get_verify_mode(self):
576 """
577 Get the verify mode
578
579 :return: The verify mode
580 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500581 return _lib.SSL_CTX_get_verify_mode(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800582
583
584 def get_verify_depth(self):
585 """
586 Get the verify depth
587
588 :return: The verify depth
589 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500590 return _lib.SSL_CTX_get_verify_depth(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800591
592
593 def load_tmp_dh(self, dhfile):
594 """
595 Load parameters for Ephemeral Diffie-Hellman
596
597 :param dhfile: The file to load EDH parameters from
598 :return: None
599 """
600 if not isinstance(dhfile, bytes):
601 raise TypeError("dhfile must be a byte string")
602
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -0500603 bio = _lib.BIO_new_file(dhfile, b"r")
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500604 if bio == _ffi.NULL:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500605 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500606 bio = _ffi.gc(bio, _lib.BIO_free)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800607
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500608 dh = _lib.PEM_read_bio_DHparams(bio, _ffi.NULL, _ffi.NULL, _ffi.NULL)
609 dh = _ffi.gc(dh, _lib.DH_free)
610 _lib.SSL_CTX_set_tmp_dh(self._context, dh)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800611
612
Jean-Paul Calderone3e4e3352014-04-19 09:28:28 -0400613 def set_tmp_ecdh(self, curve):
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600614 """
Andy Lutomirski76a61332014-03-12 15:02:56 -0700615 Select a curve to use for ECDHE key exchange.
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600616
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -0400617 :param curve: A curve object to use as returned by either
618 :py:meth:`OpenSSL.crypto.get_elliptic_curve` or
619 :py:meth:`OpenSSL.crypto.get_elliptic_curves`.
Andy Lutomirskif05a2732014-03-13 17:22:25 -0700620
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600621 :return: None
622 """
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -0400623 _lib.SSL_CTX_set_tmp_ecdh(self._context, curve._to_EC_KEY())
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600624
625
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800626 def set_cipher_list(self, cipher_list):
627 """
628 Change the cipher list
629
630 :param cipher_list: A cipher list, see ciphers(1)
631 :return: None
632 """
Jean-Paul Calderone63eab692014-01-18 10:19:56 -0500633 if isinstance(cipher_list, _text_type):
634 cipher_list = cipher_list.encode("ascii")
635
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800636 if not isinstance(cipher_list, bytes):
Jean-Paul Calderone63eab692014-01-18 10:19:56 -0500637 raise TypeError("cipher_list must be bytes or unicode")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800638
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500639 result = _lib.SSL_CTX_set_cipher_list(self._context, cipher_list)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800640 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500641 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800642
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800643
644 def set_client_ca_list(self, certificate_authorities):
645 """
646 Set the list of preferred client certificate signers for this server context.
647
648 This list of certificate authorities will be sent to the client when the
649 server requests a client certificate.
650
651 :param certificate_authorities: a sequence of X509Names.
652 :return: None
653 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500654 name_stack = _lib.sk_X509_NAME_new_null()
655 if name_stack == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500656 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500657 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800658
659 try:
660 for ca_name in certificate_authorities:
661 if not isinstance(ca_name, X509Name):
662 raise TypeError(
663 "client CAs must be X509Name objects, not %s objects" % (
664 type(ca_name).__name__,))
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500665 copy = _lib.X509_NAME_dup(ca_name._name)
666 if copy == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500667 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500668 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500669 push_result = _lib.sk_X509_NAME_push(name_stack, copy)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800670 if not push_result:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500671 _lib.X509_NAME_free(copy)
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500672 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800673 except:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500674 _lib.sk_X509_NAME_free(name_stack)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800675 raise
676
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500677 _lib.SSL_CTX_set_client_CA_list(self._context, name_stack)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800678
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800679
680 def add_client_ca(self, certificate_authority):
681 """
682 Add the CA certificate to the list of preferred signers for this context.
683
684 The list of certificate authorities will be sent to the client when the
685 server requests a client certificate.
686
687 :param certificate_authority: certificate authority's X509 certificate.
688 :return: None
689 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800690 if not isinstance(certificate_authority, X509):
691 raise TypeError("certificate_authority must be an X509 instance")
692
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500693 add_result = _lib.SSL_CTX_add_client_CA(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800694 self._context, certificate_authority._x509)
695 if not add_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500696 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500697 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800698
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800699
700 def set_timeout(self, timeout):
701 """
702 Set session timeout
703
704 :param timeout: The timeout in seconds
705 :return: The previous session timeout
706 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500707 if not isinstance(timeout, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800708 raise TypeError("timeout must be an integer")
709
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500710 return _lib.SSL_CTX_set_timeout(self._context, timeout)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800711
712
713 def get_timeout(self):
714 """
715 Get the session timeout
716
717 :return: The session timeout
718 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500719 return _lib.SSL_CTX_get_timeout(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800720
721
722 def set_info_callback(self, callback):
723 """
724 Set the info callback
725
726 :param callback: The Python callback to use
727 :return: None
728 """
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800729 @wraps(callback)
730 def wrapper(ssl, where, return_code):
Jean-Paul Calderonef2bbc9c2014-02-02 10:59:14 -0500731 callback(Connection._reverse_mapping[ssl], where, return_code)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500732 self._info_callback = _ffi.callback(
733 "void (*)(const SSL *, int, int)", wrapper)
734 _lib.SSL_CTX_set_info_callback(self._context, self._info_callback)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800735
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800736
737 def get_app_data(self):
738 """
739 Get the application data (supplied via set_app_data())
740
741 :return: The application data
742 """
743 return self._app_data
744
745
746 def set_app_data(self, data):
747 """
748 Set the application data (will be returned from get_app_data())
749
750 :param data: Any Python object
751 :return: None
752 """
753 self._app_data = data
754
755
756 def get_cert_store(self):
757 """
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500758 Get the certificate store for the context.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800759
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500760 :return: A X509Store object or None if it does not have one.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800761 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500762 store = _lib.SSL_CTX_get_cert_store(self._context)
763 if store == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500764 # TODO: This is untested.
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800765 return None
766
767 pystore = X509Store.__new__(X509Store)
768 pystore._store = store
769 return pystore
770
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800771
772 def set_options(self, options):
773 """
774 Add options. Options set before are not cleared!
775
776 :param options: The options to add.
777 :return: The new option bitmask.
778 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500779 if not isinstance(options, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800780 raise TypeError("options must be an integer")
781
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500782 return _lib.SSL_CTX_set_options(self._context, options)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800783
784
785 def set_mode(self, mode):
786 """
787 Add modes via bitmask. Modes set before are not cleared!
788
789 :param mode: The mode to add.
790 :return: The new mode bitmask.
791 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500792 if not isinstance(mode, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800793 raise TypeError("mode must be an integer")
794
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500795 return _lib.SSL_CTX_set_mode(self._context, mode)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800796
797
798 def set_tlsext_servername_callback(self, callback):
799 """
800 Specify a callback function to be called when clients specify a server name.
801
802 :param callback: The callback function. It will be invoked with one
803 argument, the Connection instance.
804 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800805 @wraps(callback)
806 def wrapper(ssl, alert, arg):
807 callback(Connection._reverse_mapping[ssl])
808 return 0
809
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500810 self._tlsext_servername_callback = _ffi.callback(
811 "int (*)(const SSL *, int *, void *)", wrapper)
812 _lib.SSL_CTX_set_tlsext_servername_callback(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800813 self._context, self._tlsext_servername_callback)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800814
815ContextType = Context
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800816
817
818
819class Connection(object):
820 """
821 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800822 _reverse_mapping = WeakValueDictionary()
823
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800824 def __init__(self, context, socket=None):
825 """
826 Create a new Connection object, using the given OpenSSL.SSL.Context
827 instance and socket.
828
829 :param context: An SSL Context to use for this connection
830 :param socket: The socket to use for transport layer
831 """
832 if not isinstance(context, Context):
833 raise TypeError("context must be a Context instance")
834
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500835 ssl = _lib.SSL_new(context._context)
836 self._ssl = _ffi.gc(ssl, _lib.SSL_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800837 self._context = context
838
839 self._reverse_mapping[self._ssl] = self
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800840
841 if socket is None:
842 self._socket = None
Jean-Paul Calderone73b15c22013-03-05 18:30:39 -0800843 # Don't set up any gc for these, SSL_free will take care of them.
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500844 self._into_ssl = _lib.BIO_new(_lib.BIO_s_mem())
845 self._from_ssl = _lib.BIO_new(_lib.BIO_s_mem())
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800846
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500847 if self._into_ssl == _ffi.NULL or self._from_ssl == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500848 # TODO: This is untested.
849 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800850
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500851 _lib.SSL_set_bio(self._ssl, self._into_ssl, self._from_ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800852 else:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800853 self._into_ssl = None
854 self._from_ssl = None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800855 self._socket = socket
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500856 set_result = _lib.SSL_set_fd(self._ssl, _asFileDescriptor(self._socket))
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800857 if not set_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500858 # TODO: This is untested.
859 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800860
861
862 def __getattr__(self, name):
863 """
864 Look up attributes on the wrapped socket object if they are not found on
865 the Connection object.
866 """
867 return getattr(self._socket, name)
868
869
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800870 def _raise_ssl_error(self, ssl, result):
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800871 if self._context._verify_helper is not None:
872 self._context._verify_helper.raise_if_problem()
873
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500874 error = _lib.SSL_get_error(ssl, result)
875 if error == _lib.SSL_ERROR_WANT_READ:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800876 raise WantReadError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500877 elif error == _lib.SSL_ERROR_WANT_WRITE:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -0700878 raise WantWriteError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500879 elif error == _lib.SSL_ERROR_ZERO_RETURN:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800880 raise ZeroReturnError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500881 elif error == _lib.SSL_ERROR_WANT_X509_LOOKUP:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500882 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -0700883 raise WantX509LookupError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500884 elif error == _lib.SSL_ERROR_SYSCALL:
885 if _lib.ERR_peek_error() == 0:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800886 if result < 0:
Konstantinos Koukopoulos541150d2014-01-31 01:00:19 +0200887 if platform == "win32":
888 errno = _ffi.getwinerror()[0]
889 else:
890 errno = _ffi.errno
891 raise SysCallError(errno, errorcode[errno])
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800892 else:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -0700893 raise SysCallError(-1, "Unexpected EOF")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800894 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500895 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500896 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500897 elif error == _lib.SSL_ERROR_NONE:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -0700898 pass
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800899 else:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500900 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800901
902
903 def get_context(self):
904 """
905 Get session context
906 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800907 return self._context
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800908
909
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800910 def set_context(self, context):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800911 """
912 Switch this connection to a new session context
913
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800914 :param context: A :py:class:`Context` instance giving the new session
915 context to use.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800916 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800917 if not isinstance(context, Context):
918 raise TypeError("context must be a Context instance")
919
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500920 _lib.SSL_set_SSL_CTX(self._ssl, context._context)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800921 self._context = context
922
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800923
924 def get_servername(self):
925 """
926 Retrieve the servername extension value if provided in the client hello
927 message, or None if there wasn't one.
928
929 :return: A byte string giving the server name or :py:data:`None`.
930 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500931 name = _lib.SSL_get_servername(self._ssl, _lib.TLSEXT_NAMETYPE_host_name)
932 if name == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800933 return None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800934
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500935 return _ffi.string(name)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800936
937
938 def set_tlsext_host_name(self, name):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800939 """
940 Set the value of the servername extension to send in the client hello.
941
942 :param name: A byte string giving the name.
943 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800944 if not isinstance(name, bytes):
945 raise TypeError("name must be a byte string")
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -0500946 elif b"\0" in name:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800947 raise TypeError("name must not contain NUL byte")
948
949 # XXX I guess this can fail sometimes?
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500950 _lib.SSL_set_tlsext_host_name(self._ssl, name)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800951
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800952
953 def pending(self):
954 """
955 Get the number of bytes that can be safely read from the connection
956
957 :return: The number of bytes available in the receive buffer.
958 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500959 return _lib.SSL_pending(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800960
961
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800962 def send(self, buf, flags=0):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800963 """
964 Send data on the connection. NOTE: If you get one of the WantRead,
965 WantWrite or WantX509Lookup exceptions on this, you have to call the
966 method again with the SAME buffer.
967
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +0200968 :param buf: The string, buffer or memoryview to send
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800969 :param flags: (optional) Included for compatibility with the socket
970 API, the value is ignored
971 :return: The number of bytes written
972 """
Jean-Paul Calderone8fb53182013-12-30 08:35:49 -0500973 if isinstance(buf, _memoryview):
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -0800974 buf = buf.tobytes()
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +0200975 if isinstance(buf, _buffer):
976 buf = str(buf)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800977 if not isinstance(buf, bytes):
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +0200978 raise TypeError("data must be a memoryview, buffer or byte string")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800979
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500980 result = _lib.SSL_write(self._ssl, buf, len(buf))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800981 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800982 return result
983 write = send
984
985
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800986 def sendall(self, buf, flags=0):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800987 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800988 Send "all" data on the connection. This calls send() repeatedly until
989 all data is sent. If an error occurs, it's impossible to tell how much
990 data has been sent.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800991
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +0200992 :param buf: The string, buffer or memoryview to send
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800993 :param flags: (optional) Included for compatibility with the socket
994 API, the value is ignored
995 :return: The number of bytes written
996 """
Jean-Paul Calderone8fb53182013-12-30 08:35:49 -0500997 if isinstance(buf, _memoryview):
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -0800998 buf = buf.tobytes()
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +0200999 if isinstance(buf, _buffer):
1000 buf = str(buf)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001001 if not isinstance(buf, bytes):
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001002 raise TypeError("buf must be a memoryview, buffer or byte string")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001003
1004 left_to_send = len(buf)
1005 total_sent = 0
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001006 data = _ffi.new("char[]", buf)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001007
1008 while left_to_send:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001009 result = _lib.SSL_write(self._ssl, data + total_sent, left_to_send)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001010 self._raise_ssl_error(self._ssl, result)
1011 total_sent += result
1012 left_to_send -= result
1013
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001014
1015 def recv(self, bufsiz, flags=None):
1016 """
1017 Receive data on the connection. NOTE: If you get one of the WantRead,
1018 WantWrite or WantX509Lookup exceptions on this, you have to call the
1019 method again with the SAME buffer.
1020
1021 :param bufsiz: The maximum number of bytes to read
1022 :param flags: (optional) Included for compatibility with the socket
1023 API, the value is ignored
1024 :return: The string read from the Connection
1025 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001026 buf = _ffi.new("char[]", bufsiz)
1027 result = _lib.SSL_read(self._ssl, buf, bufsiz)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001028 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001029 return _ffi.buffer(buf, result)[:]
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001030 read = recv
1031
1032
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001033 def _handle_bio_errors(self, bio, result):
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001034 if _lib.BIO_should_retry(bio):
1035 if _lib.BIO_should_read(bio):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001036 raise WantReadError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001037 elif _lib.BIO_should_write(bio):
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001038 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001039 raise WantWriteError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001040 elif _lib.BIO_should_io_special(bio):
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001041 # TODO: This is untested. I think io_special means the socket
1042 # BIO has a not-yet connected socket.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001043 raise ValueError("BIO_should_io_special")
1044 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001045 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001046 raise ValueError("unknown bio failure")
1047 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001048 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001049 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001050
1051
1052 def bio_read(self, bufsiz):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001053 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001054 When using non-socket connections this function reads the "dirty" data
1055 that would have traveled away on the network.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001056
1057 :param bufsiz: The maximum number of bytes to read
1058 :return: The string read.
1059 """
Jean-Paul Calderone97e041d2013-03-05 21:03:12 -08001060 if self._from_ssl is None:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001061 raise TypeError("Connection sock was not None")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001062
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -05001063 if not isinstance(bufsiz, integer_types):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001064 raise TypeError("bufsiz must be an integer")
1065
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001066 buf = _ffi.new("char[]", bufsiz)
1067 result = _lib.BIO_read(self._from_ssl, buf, bufsiz)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001068 if result <= 0:
1069 self._handle_bio_errors(self._from_ssl, result)
1070
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001071 return _ffi.buffer(buf, result)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001072
1073
1074 def bio_write(self, buf):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001075 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001076 When using non-socket connections this function sends "dirty" data that
1077 would have traveled in on the network.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001078
1079 :param buf: The string to put into the memory BIO.
1080 :return: The number of bytes written
1081 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001082 if self._into_ssl is None:
1083 raise TypeError("Connection sock was not None")
1084
1085 if not isinstance(buf, bytes):
1086 raise TypeError("buf must be a byte string")
1087
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001088 result = _lib.BIO_write(self._into_ssl, buf, len(buf))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001089 if result <= 0:
1090 self._handle_bio_errors(self._into_ssl, result)
1091 return result
1092
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001093
1094 def renegotiate(self):
1095 """
1096 Renegotiate the session
1097
1098 :return: True if the renegotiation can be started, false otherwise
1099 """
1100
1101 def do_handshake(self):
1102 """
1103 Perform an SSL handshake (usually called after renegotiate() or one of
1104 set_*_state()). This can raise the same exceptions as send and recv.
1105
1106 :return: None.
1107 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001108 result = _lib.SSL_do_handshake(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001109 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001110
1111
1112 def renegotiate_pending(self):
1113 """
1114 Check if there's a renegotiation in progress, it will return false once
1115 a renegotiation is finished.
1116
1117 :return: Whether there's a renegotiation in progress
1118 """
1119
1120 def total_renegotiations(self):
1121 """
1122 Find out the total number of renegotiations.
1123
1124 :return: The number of renegotiations.
1125 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001126 return _lib.SSL_total_renegotiations(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001127
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001128
1129 def connect(self, addr):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001130 """
1131 Connect to remote host and set up client-side SSL
1132
1133 :param addr: A remote address
1134 :return: What the socket's connect method returns
1135 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001136 _lib.SSL_set_connect_state(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001137 return self._socket.connect(addr)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001138
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001139
1140 def connect_ex(self, addr):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001141 """
1142 Connect to remote host and set up client-side SSL. Note that if the socket's
1143 connect_ex method doesn't return 0, SSL won't be initialized.
1144
1145 :param addr: A remove address
1146 :return: What the socket's connect_ex method returns
1147 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001148 connect_ex = self._socket.connect_ex
1149 self.set_connect_state()
1150 return connect_ex(addr)
1151
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001152
1153 def accept(self):
1154 """
1155 Accept incoming connection and set up SSL on it
1156
1157 :return: A (conn,addr) pair where conn is a Connection and addr is an
1158 address
1159 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001160 client, addr = self._socket.accept()
1161 conn = Connection(self._context, client)
1162 conn.set_accept_state()
1163 return (conn, addr)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001164
1165
1166 def bio_shutdown(self):
1167 """
1168 When using non-socket connections this function signals end of
1169 data on the input for this connection.
1170
1171 :return: None
1172 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001173 if self._from_ssl is None:
1174 raise TypeError("Connection sock was not None")
1175
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001176 _lib.BIO_set_mem_eof_return(self._into_ssl, 0)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001177
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001178
1179 def shutdown(self):
1180 """
1181 Send closure alert
1182
1183 :return: True if the shutdown completed successfully (i.e. both sides
1184 have sent closure alerts), false otherwise (i.e. you have to
1185 wait for a ZeroReturnError on a recv() method call
1186 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001187 result = _lib.SSL_shutdown(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001188 if result < 0:
Paul Aurichbff1d1a2015-01-08 08:36:53 -08001189 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001190 elif result > 0:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001191 return True
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001192 else:
1193 return False
1194
1195
1196 def get_cipher_list(self):
1197 """
1198 Get the session cipher list
1199
1200 :return: A list of cipher strings
1201 """
1202 ciphers = []
1203 for i in count():
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001204 result = _lib.SSL_get_cipher_list(self._ssl, i)
1205 if result == _ffi.NULL:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001206 break
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001207 ciphers.append(_native(_ffi.string(result)))
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001208 return ciphers
1209
1210
1211 def get_client_ca_list(self):
1212 """
1213 Get CAs whose certificates are suggested for client authentication.
1214
1215 :return: If this is a server connection, a list of X509Names representing
1216 the acceptable CAs as set by :py:meth:`OpenSSL.SSL.Context.set_client_ca_list` or
1217 :py:meth:`OpenSSL.SSL.Context.add_client_ca`. If this is a client connection,
1218 the list of such X509Names sent by the server, or an empty list if that
1219 has not yet happened.
1220 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001221 ca_names = _lib.SSL_get_client_CA_list(self._ssl)
1222 if ca_names == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001223 # TODO: This is untested.
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001224 return []
1225
1226 result = []
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001227 for i in range(_lib.sk_X509_NAME_num(ca_names)):
1228 name = _lib.sk_X509_NAME_value(ca_names, i)
1229 copy = _lib.X509_NAME_dup(name)
1230 if copy == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001231 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001232 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001233
1234 pyname = X509Name.__new__(X509Name)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001235 pyname._name = _ffi.gc(copy, _lib.X509_NAME_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001236 result.append(pyname)
1237 return result
1238
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001239
1240 def makefile(self):
1241 """
1242 The makefile() method is not implemented, since there is no dup semantics
1243 for SSL connections
1244
Jean-Paul Calderone6749ec22014-04-17 16:30:21 -04001245 :raise: NotImplementedError
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001246 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001247 raise NotImplementedError("Cannot make file object of OpenSSL.SSL.Connection")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001248
1249
1250 def get_app_data(self):
1251 """
1252 Get application data
1253
1254 :return: The application data
1255 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001256 return self._app_data
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001257
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001258
1259 def set_app_data(self, data):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001260 """
1261 Set application data
1262
1263 :param data - The application data
1264 :return: None
1265 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001266 self._app_data = data
1267
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001268
1269 def get_shutdown(self):
1270 """
1271 Get shutdown state
1272
1273 :return: The shutdown state, a bitvector of SENT_SHUTDOWN, RECEIVED_SHUTDOWN.
1274 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001275 return _lib.SSL_get_shutdown(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001276
1277
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001278 def set_shutdown(self, state):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001279 """
1280 Set shutdown state
1281
1282 :param state - bitvector of SENT_SHUTDOWN, RECEIVED_SHUTDOWN.
1283 :return: None
1284 """
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -05001285 if not isinstance(state, integer_types):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001286 raise TypeError("state must be an integer")
1287
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001288 _lib.SSL_set_shutdown(self._ssl, state)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001289
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001290
1291 def state_string(self):
1292 """
1293 Get a verbose state description
1294
1295 :return: A string representing the state
1296 """
1297
1298 def server_random(self):
1299 """
1300 Get a copy of the server hello nonce.
1301
1302 :return: A string representing the state
1303 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001304 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001305 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001306 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001307 self._ssl.s3.server_random,
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001308 _lib.SSL3_RANDOM_SIZE)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001309
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001310
1311 def client_random(self):
1312 """
1313 Get a copy of the client hello nonce.
1314
1315 :return: A string representing the state
1316 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001317 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001318 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001319 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001320 self._ssl.s3.client_random,
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001321 _lib.SSL3_RANDOM_SIZE)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001322
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001323
1324 def master_key(self):
1325 """
1326 Get a copy of the master key.
1327
1328 :return: A string representing the state
1329 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001330 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001331 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001332 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001333 self._ssl.session.master_key,
1334 self._ssl.session.master_key_length)[:]
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001335
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001336
1337 def sock_shutdown(self, *args, **kwargs):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001338 """
1339 See shutdown(2)
1340
1341 :return: What the socket's shutdown() method returns
1342 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001343 return self._socket.shutdown(*args, **kwargs)
1344
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001345
1346 def get_peer_certificate(self):
1347 """
1348 Retrieve the other side's certificate (if any)
1349
1350 :return: The peer's certificate
1351 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001352 cert = _lib.SSL_get_peer_certificate(self._ssl)
1353 if cert != _ffi.NULL:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001354 pycert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001355 pycert._x509 = _ffi.gc(cert, _lib.X509_free)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001356 return pycert
1357 return None
1358
1359
1360 def get_peer_cert_chain(self):
1361 """
1362 Retrieve the other side's certificate (if any)
1363
1364 :return: A list of X509 instances giving the peer's certificate chain,
1365 or None if it does not have one.
1366 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001367 cert_stack = _lib.SSL_get_peer_cert_chain(self._ssl)
1368 if cert_stack == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001369 return None
1370
1371 result = []
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001372 for i in range(_lib.sk_X509_num(cert_stack)):
Jean-Paul Calderone73b15c22013-03-05 18:30:39 -08001373 # TODO could incref instead of dup here
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001374 cert = _lib.X509_dup(_lib.sk_X509_value(cert_stack, i))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001375 pycert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001376 pycert._x509 = _ffi.gc(cert, _lib.X509_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001377 result.append(pycert)
1378 return result
1379
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001380
1381 def want_read(self):
1382 """
1383 Checks if more data has to be read from the transport layer to complete an
1384 operation.
1385
1386 :return: True iff more data has to be read
1387 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001388 return _lib.SSL_want_read(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001389
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001390
1391 def want_write(self):
1392 """
1393 Checks if there is data to write to the transport layer to complete an
1394 operation.
1395
1396 :return: True iff there is data to write
1397 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001398 return _lib.SSL_want_write(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001399
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001400
1401 def set_accept_state(self):
1402 """
1403 Set the connection to work in server mode. The handshake will be handled
1404 automatically by read/write.
1405
1406 :return: None
1407 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001408 _lib.SSL_set_accept_state(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001409
1410
1411 def set_connect_state(self):
1412 """
1413 Set the connection to work in client mode. The handshake will be handled
1414 automatically by read/write.
1415
1416 :return: None
1417 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001418 _lib.SSL_set_connect_state(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001419
1420
1421 def get_session(self):
1422 """
1423 Returns the Session currently used.
1424
1425 @return: An instance of :py:class:`OpenSSL.SSL.Session` or :py:obj:`None` if
1426 no session exists.
1427 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001428 session = _lib.SSL_get1_session(self._ssl)
1429 if session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001430 return None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001431
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001432 pysession = Session.__new__(Session)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001433 pysession._session = _ffi.gc(session, _lib.SSL_SESSION_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001434 return pysession
1435
1436
1437 def set_session(self, session):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001438 """
1439 Set the session to be used when the TLS/SSL connection is established.
1440
1441 :param session: A Session instance representing the session to use.
1442 :returns: None
1443 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001444 if not isinstance(session, Session):
1445 raise TypeError("session must be a Session instance")
1446
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001447 result = _lib.SSL_set_session(self._ssl, session._session)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001448 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001449 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001450
Jean-Paul Calderonedbd76272014-03-29 18:09:40 -04001451
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001452 def _get_finished_message(self, function):
1453 """
1454 Helper to implement :py:meth:`get_finished` and
1455 :py:meth:`get_peer_finished`.
1456
1457 :param function: Either :py:data:`SSL_get_finished`: or
1458 :py:data:`SSL_get_peer_finished`.
1459
1460 :return: :py:data:`None` if the desired message has not yet been
1461 received, otherwise the contents of the message.
1462 :rtype: :py:class:`bytes` or :py:class:`NoneType`
1463 """
Jean-Paul Calderone01af9042014-03-30 11:40:42 -04001464 # The OpenSSL documentation says nothing about what might happen if the
1465 # count argument given is zero. Specifically, it doesn't say whether
1466 # the output buffer may be NULL in that case or not. Inspection of the
1467 # implementation reveals that it calls memcpy() unconditionally.
1468 # Section 7.1.4, paragraph 1 of the C standard suggests that
1469 # memcpy(NULL, source, 0) is not guaranteed to produce defined (let
1470 # alone desirable) behavior (though it probably does on just about
1471 # every implementation...)
1472 #
1473 # Allocate a tiny buffer to pass in (instead of just passing NULL as
1474 # one might expect) for the initial call so as to be safe against this
1475 # potentially undefined behavior.
1476 empty = _ffi.new("char[]", 0)
1477 size = function(self._ssl, empty, 0)
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001478 if size == 0:
1479 # No Finished message so far.
1480 return None
1481
1482 buf = _ffi.new("char[]", size)
1483 function(self._ssl, buf, size)
1484 return _ffi.buffer(buf, size)[:]
1485
1486
Fedor Brunner5747b932014-03-05 14:22:34 +01001487 def get_finished(self):
1488 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001489 Obtain the latest `handshake finished` message sent to the peer.
Fedor Brunner5747b932014-03-05 14:22:34 +01001490
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001491 :return: The contents of the message or :py:obj:`None` if the TLS
1492 handshake has not yet completed.
1493 :rtype: :py:class:`bytes` or :py:class:`NoneType`
Fedor Brunner5747b932014-03-05 14:22:34 +01001494 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001495 return self._get_finished_message(_lib.SSL_get_finished)
1496
Fedor Brunner5747b932014-03-05 14:22:34 +01001497
1498 def get_peer_finished(self):
1499 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001500 Obtain the latest `handshake finished` message received from the peer.
Fedor Brunner5747b932014-03-05 14:22:34 +01001501
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001502 :return: The contents of the message or :py:obj:`None` if the TLS
1503 handshake has not yet completed.
1504 :rtype: :py:class:`bytes` or :py:class:`NoneType`
Fedor Brunner5747b932014-03-05 14:22:34 +01001505 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001506 return self._get_finished_message(_lib.SSL_get_peer_finished)
Fedor Brunner5747b932014-03-05 14:22:34 +01001507
Jean-Paul Calderone7c556ef2014-03-30 10:45:00 -04001508
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001509 def get_cipher_name(self):
1510 """
1511 Obtain the name of the currently used cipher.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001512
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001513 :returns: The name of the currently used cipher or :py:obj:`None`
1514 if no connection has been established.
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001515 :rtype: :py:class:`unicode` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001516 """
1517 cipher = _lib.SSL_get_current_cipher(self._ssl)
1518 if cipher == _ffi.NULL:
1519 return None
1520 else:
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001521 name = _ffi.string(_lib.SSL_CIPHER_get_name(cipher))
1522 return name.decode("utf-8")
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001523
Jean-Paul Calderonedbd76272014-03-29 18:09:40 -04001524
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001525 def get_cipher_bits(self):
1526 """
1527 Obtain the number of secret bits of the currently used cipher.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001528
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001529 :returns: The number of secret bits of the currently used cipher
1530 or :py:obj:`None` if no connection has been established.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001531 :rtype: :py:class:`int` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001532 """
1533 cipher = _lib.SSL_get_current_cipher(self._ssl)
1534 if cipher == _ffi.NULL:
1535 return None
1536 else:
1537 return _lib.SSL_CIPHER_get_bits(cipher, _ffi.NULL)
1538
Jean-Paul Calderonedbd76272014-03-29 18:09:40 -04001539
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001540 def get_cipher_version(self):
1541 """
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001542 Obtain the protocol version of the currently used cipher.
1543
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001544 :returns: The protocol name of the currently used cipher
1545 or :py:obj:`None` if no connection has been established.
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001546 :rtype: :py:class:`unicode` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001547 """
1548 cipher = _lib.SSL_get_current_cipher(self._ssl)
1549 if cipher == _ffi.NULL:
1550 return None
1551 else:
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001552 version =_ffi.string(_lib.SSL_CIPHER_get_version(cipher))
1553 return version.decode("utf-8")
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001554
1555
1556
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001557ConnectionType = Connection
Jean-Paul Calderone11ed8e82014-01-18 10:21:50 -05001558
Jean-Paul Calderonefab157b2014-01-18 11:21:38 -05001559# This is similar to the initialization calls at the end of OpenSSL/crypto.py
1560# but is exercised mostly by the Context initializer.
Jean-Paul Calderone11ed8e82014-01-18 10:21:50 -05001561_lib.SSL_library_init()