blob: 7b1cbc1b4ef55a3771f0d18cd0cd1a9849045aaa [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 """
495
496 def load_client_ca(self, cafile):
497 """
498 Load the trusted certificates that will be sent to the client (basically
499 telling the client "These are the guys I trust"). Does not actually
500 imply any of the certificates are trusted; that must be configured
501 separately.
502
503 :param cafile: The name of the certificates file
504 :return: None
505 """
506
507 def set_session_id(self, buf):
508 """
509 Set the session identifier. This is needed if you want to do session
510 resumption.
511
512 :param buf: A Python object that can be safely converted to a string
513 :returns: None
514 """
515
516 def set_session_cache_mode(self, mode):
517 """
518 Enable/disable session caching and specify the mode used.
519
520 :param mode: One or more of the SESS_CACHE_* flags (combine using
521 bitwise or)
522 :returns: The previously set caching mode.
523 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500524 if not isinstance(mode, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800525 raise TypeError("mode must be an integer")
526
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500527 return _lib.SSL_CTX_set_session_cache_mode(self._context, mode)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800528
529
530 def get_session_cache_mode(self):
531 """
532 :returns: The currently used cache mode.
533 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500534 return _lib.SSL_CTX_get_session_cache_mode(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800535
536
537 def set_verify(self, mode, callback):
538 """
539 Set the verify mode and verify callback
540
541 :param mode: The verify mode, this is either VERIFY_NONE or
542 VERIFY_PEER combined with possible other flags
543 :param callback: The Python callback to use
544 :return: None
545
546 See SSL_CTX_set_verify(3SSL) for further details.
547 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500548 if not isinstance(mode, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800549 raise TypeError("mode must be an integer")
550
551 if not callable(callback):
552 raise TypeError("callback must be callable")
553
Jean-Paul Calderone6a8cd112014-04-02 21:09:08 -0400554 self._verify_helper = _VerifyHelper(callback)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800555 self._verify_callback = self._verify_helper.callback
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500556 _lib.SSL_CTX_set_verify(self._context, mode, self._verify_callback)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800557
558
559 def set_verify_depth(self, depth):
560 """
561 Set the verify depth
562
563 :param depth: An integer specifying the verify depth
564 :return: None
565 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500566 if not isinstance(depth, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800567 raise TypeError("depth must be an integer")
568
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500569 _lib.SSL_CTX_set_verify_depth(self._context, depth)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800570
571
572 def get_verify_mode(self):
573 """
574 Get the verify mode
575
576 :return: The verify mode
577 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500578 return _lib.SSL_CTX_get_verify_mode(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800579
580
581 def get_verify_depth(self):
582 """
583 Get the verify depth
584
585 :return: The verify depth
586 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500587 return _lib.SSL_CTX_get_verify_depth(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800588
589
590 def load_tmp_dh(self, dhfile):
591 """
592 Load parameters for Ephemeral Diffie-Hellman
593
594 :param dhfile: The file to load EDH parameters from
595 :return: None
596 """
597 if not isinstance(dhfile, bytes):
598 raise TypeError("dhfile must be a byte string")
599
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -0500600 bio = _lib.BIO_new_file(dhfile, b"r")
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500601 if bio == _ffi.NULL:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500602 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500603 bio = _ffi.gc(bio, _lib.BIO_free)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800604
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500605 dh = _lib.PEM_read_bio_DHparams(bio, _ffi.NULL, _ffi.NULL, _ffi.NULL)
606 dh = _ffi.gc(dh, _lib.DH_free)
607 _lib.SSL_CTX_set_tmp_dh(self._context, dh)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800608
609
Jean-Paul Calderone3e4e3352014-04-19 09:28:28 -0400610 def set_tmp_ecdh(self, curve):
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600611 """
Andy Lutomirski76a61332014-03-12 15:02:56 -0700612 Select a curve to use for ECDHE key exchange.
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600613
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -0400614 :param curve: A curve object to use as returned by either
615 :py:meth:`OpenSSL.crypto.get_elliptic_curve` or
616 :py:meth:`OpenSSL.crypto.get_elliptic_curves`.
Andy Lutomirskif05a2732014-03-13 17:22:25 -0700617
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600618 :return: None
619 """
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -0400620 _lib.SSL_CTX_set_tmp_ecdh(self._context, curve._to_EC_KEY())
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600621
622
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800623 def set_cipher_list(self, cipher_list):
624 """
625 Change the cipher list
626
627 :param cipher_list: A cipher list, see ciphers(1)
628 :return: None
629 """
Jean-Paul Calderone63eab692014-01-18 10:19:56 -0500630 if isinstance(cipher_list, _text_type):
631 cipher_list = cipher_list.encode("ascii")
632
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800633 if not isinstance(cipher_list, bytes):
Jean-Paul Calderone63eab692014-01-18 10:19:56 -0500634 raise TypeError("cipher_list must be bytes or unicode")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800635
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500636 result = _lib.SSL_CTX_set_cipher_list(self._context, cipher_list)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800637 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500638 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800639
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800640
641 def set_client_ca_list(self, certificate_authorities):
642 """
643 Set the list of preferred client certificate signers for this server context.
644
645 This list of certificate authorities will be sent to the client when the
646 server requests a client certificate.
647
648 :param certificate_authorities: a sequence of X509Names.
649 :return: None
650 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500651 name_stack = _lib.sk_X509_NAME_new_null()
652 if name_stack == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500653 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500654 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800655
656 try:
657 for ca_name in certificate_authorities:
658 if not isinstance(ca_name, X509Name):
659 raise TypeError(
660 "client CAs must be X509Name objects, not %s objects" % (
661 type(ca_name).__name__,))
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500662 copy = _lib.X509_NAME_dup(ca_name._name)
663 if copy == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500664 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500665 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500666 push_result = _lib.sk_X509_NAME_push(name_stack, copy)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800667 if not push_result:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500668 _lib.X509_NAME_free(copy)
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500669 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800670 except:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500671 _lib.sk_X509_NAME_free(name_stack)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800672 raise
673
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500674 _lib.SSL_CTX_set_client_CA_list(self._context, name_stack)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800675
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800676
677 def add_client_ca(self, certificate_authority):
678 """
679 Add the CA certificate to the list of preferred signers for this context.
680
681 The list of certificate authorities will be sent to the client when the
682 server requests a client certificate.
683
684 :param certificate_authority: certificate authority's X509 certificate.
685 :return: None
686 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800687 if not isinstance(certificate_authority, X509):
688 raise TypeError("certificate_authority must be an X509 instance")
689
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500690 add_result = _lib.SSL_CTX_add_client_CA(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800691 self._context, certificate_authority._x509)
692 if not add_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500693 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500694 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800695
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800696
697 def set_timeout(self, timeout):
698 """
699 Set session timeout
700
701 :param timeout: The timeout in seconds
702 :return: The previous session timeout
703 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500704 if not isinstance(timeout, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800705 raise TypeError("timeout must be an integer")
706
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500707 return _lib.SSL_CTX_set_timeout(self._context, timeout)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800708
709
710 def get_timeout(self):
711 """
712 Get the session timeout
713
714 :return: The session timeout
715 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500716 return _lib.SSL_CTX_get_timeout(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800717
718
719 def set_info_callback(self, callback):
720 """
721 Set the info callback
722
723 :param callback: The Python callback to use
724 :return: None
725 """
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800726 @wraps(callback)
727 def wrapper(ssl, where, return_code):
Jean-Paul Calderonef2bbc9c2014-02-02 10:59:14 -0500728 callback(Connection._reverse_mapping[ssl], where, return_code)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500729 self._info_callback = _ffi.callback(
730 "void (*)(const SSL *, int, int)", wrapper)
731 _lib.SSL_CTX_set_info_callback(self._context, self._info_callback)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800732
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800733
734 def get_app_data(self):
735 """
736 Get the application data (supplied via set_app_data())
737
738 :return: The application data
739 """
740 return self._app_data
741
742
743 def set_app_data(self, data):
744 """
745 Set the application data (will be returned from get_app_data())
746
747 :param data: Any Python object
748 :return: None
749 """
750 self._app_data = data
751
752
753 def get_cert_store(self):
754 """
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500755 Get the certificate store for the context.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800756
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500757 :return: A X509Store object or None if it does not have one.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800758 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500759 store = _lib.SSL_CTX_get_cert_store(self._context)
760 if store == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500761 # TODO: This is untested.
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800762 return None
763
764 pystore = X509Store.__new__(X509Store)
765 pystore._store = store
766 return pystore
767
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800768
769 def set_options(self, options):
770 """
771 Add options. Options set before are not cleared!
772
773 :param options: The options to add.
774 :return: The new option bitmask.
775 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500776 if not isinstance(options, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800777 raise TypeError("options must be an integer")
778
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500779 return _lib.SSL_CTX_set_options(self._context, options)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800780
781
782 def set_mode(self, mode):
783 """
784 Add modes via bitmask. Modes set before are not cleared!
785
786 :param mode: The mode to add.
787 :return: The new mode bitmask.
788 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500789 if not isinstance(mode, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800790 raise TypeError("mode must be an integer")
791
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500792 return _lib.SSL_CTX_set_mode(self._context, mode)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800793
794
795 def set_tlsext_servername_callback(self, callback):
796 """
797 Specify a callback function to be called when clients specify a server name.
798
799 :param callback: The callback function. It will be invoked with one
800 argument, the Connection instance.
801 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800802 @wraps(callback)
803 def wrapper(ssl, alert, arg):
804 callback(Connection._reverse_mapping[ssl])
805 return 0
806
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500807 self._tlsext_servername_callback = _ffi.callback(
808 "int (*)(const SSL *, int *, void *)", wrapper)
809 _lib.SSL_CTX_set_tlsext_servername_callback(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800810 self._context, self._tlsext_servername_callback)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800811
812ContextType = Context
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800813
814
815
816class Connection(object):
817 """
818 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800819 _reverse_mapping = WeakValueDictionary()
820
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800821 def __init__(self, context, socket=None):
822 """
823 Create a new Connection object, using the given OpenSSL.SSL.Context
824 instance and socket.
825
826 :param context: An SSL Context to use for this connection
827 :param socket: The socket to use for transport layer
828 """
829 if not isinstance(context, Context):
830 raise TypeError("context must be a Context instance")
831
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500832 ssl = _lib.SSL_new(context._context)
833 self._ssl = _ffi.gc(ssl, _lib.SSL_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800834 self._context = context
835
836 self._reverse_mapping[self._ssl] = self
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800837
838 if socket is None:
839 self._socket = None
Jean-Paul Calderone73b15c22013-03-05 18:30:39 -0800840 # Don't set up any gc for these, SSL_free will take care of them.
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500841 self._into_ssl = _lib.BIO_new(_lib.BIO_s_mem())
842 self._from_ssl = _lib.BIO_new(_lib.BIO_s_mem())
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800843
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500844 if self._into_ssl == _ffi.NULL or self._from_ssl == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500845 # TODO: This is untested.
846 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800847
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500848 _lib.SSL_set_bio(self._ssl, self._into_ssl, self._from_ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800849 else:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800850 self._into_ssl = None
851 self._from_ssl = None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800852 self._socket = socket
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500853 set_result = _lib.SSL_set_fd(self._ssl, _asFileDescriptor(self._socket))
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800854 if not set_result:
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
858
859 def __getattr__(self, name):
860 """
861 Look up attributes on the wrapped socket object if they are not found on
862 the Connection object.
863 """
864 return getattr(self._socket, name)
865
866
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800867 def _raise_ssl_error(self, ssl, result):
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800868 if self._context._verify_helper is not None:
869 self._context._verify_helper.raise_if_problem()
870
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500871 error = _lib.SSL_get_error(ssl, result)
872 if error == _lib.SSL_ERROR_WANT_READ:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800873 raise WantReadError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500874 elif error == _lib.SSL_ERROR_WANT_WRITE:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -0700875 raise WantWriteError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500876 elif error == _lib.SSL_ERROR_ZERO_RETURN:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800877 raise ZeroReturnError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500878 elif error == _lib.SSL_ERROR_WANT_X509_LOOKUP:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500879 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -0700880 raise WantX509LookupError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500881 elif error == _lib.SSL_ERROR_SYSCALL:
882 if _lib.ERR_peek_error() == 0:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800883 if result < 0:
Konstantinos Koukopoulos541150d2014-01-31 01:00:19 +0200884 if platform == "win32":
885 errno = _ffi.getwinerror()[0]
886 else:
887 errno = _ffi.errno
888 raise SysCallError(errno, errorcode[errno])
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800889 else:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -0700890 raise SysCallError(-1, "Unexpected EOF")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800891 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500892 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500893 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500894 elif error == _lib.SSL_ERROR_NONE:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -0700895 pass
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800896 else:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500897 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800898
899
900 def get_context(self):
901 """
902 Get session context
903 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800904 return self._context
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800905
906
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800907 def set_context(self, context):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800908 """
909 Switch this connection to a new session context
910
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800911 :param context: A :py:class:`Context` instance giving the new session
912 context to use.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800913 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800914 if not isinstance(context, Context):
915 raise TypeError("context must be a Context instance")
916
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500917 _lib.SSL_set_SSL_CTX(self._ssl, context._context)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800918 self._context = context
919
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800920
921 def get_servername(self):
922 """
923 Retrieve the servername extension value if provided in the client hello
924 message, or None if there wasn't one.
925
926 :return: A byte string giving the server name or :py:data:`None`.
927 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500928 name = _lib.SSL_get_servername(self._ssl, _lib.TLSEXT_NAMETYPE_host_name)
929 if name == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800930 return None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800931
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500932 return _ffi.string(name)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800933
934
935 def set_tlsext_host_name(self, name):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800936 """
937 Set the value of the servername extension to send in the client hello.
938
939 :param name: A byte string giving the name.
940 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800941 if not isinstance(name, bytes):
942 raise TypeError("name must be a byte string")
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -0500943 elif b"\0" in name:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800944 raise TypeError("name must not contain NUL byte")
945
946 # XXX I guess this can fail sometimes?
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500947 _lib.SSL_set_tlsext_host_name(self._ssl, name)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800948
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800949
950 def pending(self):
951 """
952 Get the number of bytes that can be safely read from the connection
953
954 :return: The number of bytes available in the receive buffer.
955 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500956 return _lib.SSL_pending(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800957
958
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800959 def send(self, buf, flags=0):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800960 """
961 Send data on the connection. NOTE: If you get one of the WantRead,
962 WantWrite or WantX509Lookup exceptions on this, you have to call the
963 method again with the SAME buffer.
964
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +0200965 :param buf: The string, buffer or memoryview to send
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800966 :param flags: (optional) Included for compatibility with the socket
967 API, the value is ignored
968 :return: The number of bytes written
969 """
Jean-Paul Calderone8fb53182013-12-30 08:35:49 -0500970 if isinstance(buf, _memoryview):
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -0800971 buf = buf.tobytes()
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +0200972 if isinstance(buf, _buffer):
973 buf = str(buf)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800974 if not isinstance(buf, bytes):
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +0200975 raise TypeError("data must be a memoryview, buffer or byte string")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800976
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500977 result = _lib.SSL_write(self._ssl, buf, len(buf))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800978 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800979 return result
980 write = send
981
982
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800983 def sendall(self, buf, flags=0):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800984 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800985 Send "all" data on the connection. This calls send() repeatedly until
986 all data is sent. If an error occurs, it's impossible to tell how much
987 data has been sent.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800988
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +0200989 :param buf: The string, buffer or memoryview to send
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800990 :param flags: (optional) Included for compatibility with the socket
991 API, the value is ignored
992 :return: The number of bytes written
993 """
Jean-Paul Calderone8fb53182013-12-30 08:35:49 -0500994 if isinstance(buf, _memoryview):
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -0800995 buf = buf.tobytes()
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +0200996 if isinstance(buf, _buffer):
997 buf = str(buf)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800998 if not isinstance(buf, bytes):
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +0200999 raise TypeError("buf must be a memoryview, buffer or byte string")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001000
1001 left_to_send = len(buf)
1002 total_sent = 0
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001003 data = _ffi.new("char[]", buf)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001004
1005 while left_to_send:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001006 result = _lib.SSL_write(self._ssl, data + total_sent, left_to_send)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001007 self._raise_ssl_error(self._ssl, result)
1008 total_sent += result
1009 left_to_send -= result
1010
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001011
1012 def recv(self, bufsiz, flags=None):
1013 """
1014 Receive data on the connection. NOTE: If you get one of the WantRead,
1015 WantWrite or WantX509Lookup exceptions on this, you have to call the
1016 method again with the SAME buffer.
1017
1018 :param bufsiz: The maximum number of bytes to read
1019 :param flags: (optional) Included for compatibility with the socket
1020 API, the value is ignored
1021 :return: The string read from the Connection
1022 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001023 buf = _ffi.new("char[]", bufsiz)
1024 result = _lib.SSL_read(self._ssl, buf, bufsiz)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001025 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001026 return _ffi.buffer(buf, result)[:]
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001027 read = recv
1028
1029
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001030 def _handle_bio_errors(self, bio, result):
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001031 if _lib.BIO_should_retry(bio):
1032 if _lib.BIO_should_read(bio):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001033 raise WantReadError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001034 elif _lib.BIO_should_write(bio):
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001035 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001036 raise WantWriteError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001037 elif _lib.BIO_should_io_special(bio):
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001038 # TODO: This is untested. I think io_special means the socket
1039 # BIO has a not-yet connected socket.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001040 raise ValueError("BIO_should_io_special")
1041 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001042 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001043 raise ValueError("unknown bio failure")
1044 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001045 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001046 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001047
1048
1049 def bio_read(self, bufsiz):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001050 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001051 When using non-socket connections this function reads the "dirty" data
1052 that would have traveled away on the network.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001053
1054 :param bufsiz: The maximum number of bytes to read
1055 :return: The string read.
1056 """
Jean-Paul Calderone97e041d2013-03-05 21:03:12 -08001057 if self._from_ssl is None:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001058 raise TypeError("Connection sock was not None")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001059
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -05001060 if not isinstance(bufsiz, integer_types):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001061 raise TypeError("bufsiz must be an integer")
1062
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001063 buf = _ffi.new("char[]", bufsiz)
1064 result = _lib.BIO_read(self._from_ssl, buf, bufsiz)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001065 if result <= 0:
1066 self._handle_bio_errors(self._from_ssl, result)
1067
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001068 return _ffi.buffer(buf, result)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001069
1070
1071 def bio_write(self, buf):
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 sends "dirty" data that
1074 would have traveled in on the network.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001075
1076 :param buf: The string to put into the memory BIO.
1077 :return: The number of bytes written
1078 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001079 if self._into_ssl is None:
1080 raise TypeError("Connection sock was not None")
1081
1082 if not isinstance(buf, bytes):
1083 raise TypeError("buf must be a byte string")
1084
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001085 result = _lib.BIO_write(self._into_ssl, buf, len(buf))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001086 if result <= 0:
1087 self._handle_bio_errors(self._into_ssl, result)
1088 return result
1089
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001090
1091 def renegotiate(self):
1092 """
1093 Renegotiate the session
1094
1095 :return: True if the renegotiation can be started, false otherwise
1096 """
1097
1098 def do_handshake(self):
1099 """
1100 Perform an SSL handshake (usually called after renegotiate() or one of
1101 set_*_state()). This can raise the same exceptions as send and recv.
1102
1103 :return: None.
1104 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001105 result = _lib.SSL_do_handshake(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001106 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001107
1108
1109 def renegotiate_pending(self):
1110 """
1111 Check if there's a renegotiation in progress, it will return false once
1112 a renegotiation is finished.
1113
1114 :return: Whether there's a renegotiation in progress
1115 """
1116
1117 def total_renegotiations(self):
1118 """
1119 Find out the total number of renegotiations.
1120
1121 :return: The number of renegotiations.
1122 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001123 return _lib.SSL_total_renegotiations(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001124
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001125
1126 def connect(self, addr):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001127 """
1128 Connect to remote host and set up client-side SSL
1129
1130 :param addr: A remote address
1131 :return: What the socket's connect method returns
1132 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001133 _lib.SSL_set_connect_state(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001134 return self._socket.connect(addr)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001135
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001136
1137 def connect_ex(self, addr):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001138 """
1139 Connect to remote host and set up client-side SSL. Note that if the socket's
1140 connect_ex method doesn't return 0, SSL won't be initialized.
1141
1142 :param addr: A remove address
1143 :return: What the socket's connect_ex method returns
1144 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001145 connect_ex = self._socket.connect_ex
1146 self.set_connect_state()
1147 return connect_ex(addr)
1148
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001149
1150 def accept(self):
1151 """
1152 Accept incoming connection and set up SSL on it
1153
1154 :return: A (conn,addr) pair where conn is a Connection and addr is an
1155 address
1156 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001157 client, addr = self._socket.accept()
1158 conn = Connection(self._context, client)
1159 conn.set_accept_state()
1160 return (conn, addr)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001161
1162
1163 def bio_shutdown(self):
1164 """
1165 When using non-socket connections this function signals end of
1166 data on the input for this connection.
1167
1168 :return: None
1169 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001170 if self._from_ssl is None:
1171 raise TypeError("Connection sock was not None")
1172
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001173 _lib.BIO_set_mem_eof_return(self._into_ssl, 0)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001174
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001175
1176 def shutdown(self):
1177 """
1178 Send closure alert
1179
1180 :return: True if the shutdown completed successfully (i.e. both sides
1181 have sent closure alerts), false otherwise (i.e. you have to
1182 wait for a ZeroReturnError on a recv() method call
1183 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001184 result = _lib.SSL_shutdown(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001185 if result < 0:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001186 # TODO: This is untested.
1187 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001188 elif result > 0:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001189 return True
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001190 else:
1191 return False
1192
1193
1194 def get_cipher_list(self):
1195 """
1196 Get the session cipher list
1197
1198 :return: A list of cipher strings
1199 """
1200 ciphers = []
1201 for i in count():
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001202 result = _lib.SSL_get_cipher_list(self._ssl, i)
1203 if result == _ffi.NULL:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001204 break
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001205 ciphers.append(_native(_ffi.string(result)))
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001206 return ciphers
1207
1208
1209 def get_client_ca_list(self):
1210 """
1211 Get CAs whose certificates are suggested for client authentication.
1212
1213 :return: If this is a server connection, a list of X509Names representing
1214 the acceptable CAs as set by :py:meth:`OpenSSL.SSL.Context.set_client_ca_list` or
1215 :py:meth:`OpenSSL.SSL.Context.add_client_ca`. If this is a client connection,
1216 the list of such X509Names sent by the server, or an empty list if that
1217 has not yet happened.
1218 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001219 ca_names = _lib.SSL_get_client_CA_list(self._ssl)
1220 if ca_names == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001221 # TODO: This is untested.
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001222 return []
1223
1224 result = []
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001225 for i in range(_lib.sk_X509_NAME_num(ca_names)):
1226 name = _lib.sk_X509_NAME_value(ca_names, i)
1227 copy = _lib.X509_NAME_dup(name)
1228 if copy == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001229 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001230 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001231
1232 pyname = X509Name.__new__(X509Name)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001233 pyname._name = _ffi.gc(copy, _lib.X509_NAME_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001234 result.append(pyname)
1235 return result
1236
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001237
1238 def makefile(self):
1239 """
1240 The makefile() method is not implemented, since there is no dup semantics
1241 for SSL connections
1242
Jean-Paul Calderone6749ec22014-04-17 16:30:21 -04001243 :raise: NotImplementedError
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001244 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001245 raise NotImplementedError("Cannot make file object of OpenSSL.SSL.Connection")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001246
1247
1248 def get_app_data(self):
1249 """
1250 Get application data
1251
1252 :return: The application data
1253 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001254 return self._app_data
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001255
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001256
1257 def set_app_data(self, data):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001258 """
1259 Set application data
1260
1261 :param data - The application data
1262 :return: None
1263 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001264 self._app_data = data
1265
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001266
1267 def get_shutdown(self):
1268 """
1269 Get shutdown state
1270
1271 :return: The shutdown state, a bitvector of SENT_SHUTDOWN, RECEIVED_SHUTDOWN.
1272 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001273 return _lib.SSL_get_shutdown(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001274
1275
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001276 def set_shutdown(self, state):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001277 """
1278 Set shutdown state
1279
1280 :param state - bitvector of SENT_SHUTDOWN, RECEIVED_SHUTDOWN.
1281 :return: None
1282 """
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -05001283 if not isinstance(state, integer_types):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001284 raise TypeError("state must be an integer")
1285
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001286 _lib.SSL_set_shutdown(self._ssl, state)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001287
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001288
1289 def state_string(self):
1290 """
1291 Get a verbose state description
1292
1293 :return: A string representing the state
1294 """
1295
1296 def server_random(self):
1297 """
1298 Get a copy of the server hello nonce.
1299
1300 :return: A string representing the state
1301 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001302 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001303 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001304 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001305 self._ssl.s3.server_random,
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001306 _lib.SSL3_RANDOM_SIZE)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001307
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001308
1309 def client_random(self):
1310 """
1311 Get a copy of the client hello nonce.
1312
1313 :return: A string representing the state
1314 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001315 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001316 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001317 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001318 self._ssl.s3.client_random,
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001319 _lib.SSL3_RANDOM_SIZE)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001320
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001321
1322 def master_key(self):
1323 """
1324 Get a copy of the master key.
1325
1326 :return: A string representing the state
1327 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001328 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001329 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001330 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001331 self._ssl.session.master_key,
1332 self._ssl.session.master_key_length)[:]
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001333
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001334
1335 def sock_shutdown(self, *args, **kwargs):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001336 """
1337 See shutdown(2)
1338
1339 :return: What the socket's shutdown() method returns
1340 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001341 return self._socket.shutdown(*args, **kwargs)
1342
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001343
1344 def get_peer_certificate(self):
1345 """
1346 Retrieve the other side's certificate (if any)
1347
1348 :return: The peer's certificate
1349 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001350 cert = _lib.SSL_get_peer_certificate(self._ssl)
1351 if cert != _ffi.NULL:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001352 pycert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001353 pycert._x509 = _ffi.gc(cert, _lib.X509_free)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001354 return pycert
1355 return None
1356
1357
1358 def get_peer_cert_chain(self):
1359 """
1360 Retrieve the other side's certificate (if any)
1361
1362 :return: A list of X509 instances giving the peer's certificate chain,
1363 or None if it does not have one.
1364 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001365 cert_stack = _lib.SSL_get_peer_cert_chain(self._ssl)
1366 if cert_stack == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001367 return None
1368
1369 result = []
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001370 for i in range(_lib.sk_X509_num(cert_stack)):
Jean-Paul Calderone73b15c22013-03-05 18:30:39 -08001371 # TODO could incref instead of dup here
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001372 cert = _lib.X509_dup(_lib.sk_X509_value(cert_stack, i))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001373 pycert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001374 pycert._x509 = _ffi.gc(cert, _lib.X509_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001375 result.append(pycert)
1376 return result
1377
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001378
1379 def want_read(self):
1380 """
1381 Checks if more data has to be read from the transport layer to complete an
1382 operation.
1383
1384 :return: True iff more data has to be read
1385 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001386 return _lib.SSL_want_read(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001387
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001388
1389 def want_write(self):
1390 """
1391 Checks if there is data to write to the transport layer to complete an
1392 operation.
1393
1394 :return: True iff there is data to write
1395 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001396 return _lib.SSL_want_write(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001397
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001398
1399 def set_accept_state(self):
1400 """
1401 Set the connection to work in server mode. The handshake will be handled
1402 automatically by read/write.
1403
1404 :return: None
1405 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001406 _lib.SSL_set_accept_state(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001407
1408
1409 def set_connect_state(self):
1410 """
1411 Set the connection to work in client mode. The handshake will be handled
1412 automatically by read/write.
1413
1414 :return: None
1415 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001416 _lib.SSL_set_connect_state(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001417
1418
1419 def get_session(self):
1420 """
1421 Returns the Session currently used.
1422
1423 @return: An instance of :py:class:`OpenSSL.SSL.Session` or :py:obj:`None` if
1424 no session exists.
1425 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001426 session = _lib.SSL_get1_session(self._ssl)
1427 if session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001428 return None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001429
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001430 pysession = Session.__new__(Session)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001431 pysession._session = _ffi.gc(session, _lib.SSL_SESSION_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001432 return pysession
1433
1434
1435 def set_session(self, session):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001436 """
1437 Set the session to be used when the TLS/SSL connection is established.
1438
1439 :param session: A Session instance representing the session to use.
1440 :returns: None
1441 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001442 if not isinstance(session, Session):
1443 raise TypeError("session must be a Session instance")
1444
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001445 result = _lib.SSL_set_session(self._ssl, session._session)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001446 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001447 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001448
Jean-Paul Calderonedbd76272014-03-29 18:09:40 -04001449
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001450 def _get_finished_message(self, function):
1451 """
1452 Helper to implement :py:meth:`get_finished` and
1453 :py:meth:`get_peer_finished`.
1454
1455 :param function: Either :py:data:`SSL_get_finished`: or
1456 :py:data:`SSL_get_peer_finished`.
1457
1458 :return: :py:data:`None` if the desired message has not yet been
1459 received, otherwise the contents of the message.
1460 :rtype: :py:class:`bytes` or :py:class:`NoneType`
1461 """
Jean-Paul Calderone01af9042014-03-30 11:40:42 -04001462 # The OpenSSL documentation says nothing about what might happen if the
1463 # count argument given is zero. Specifically, it doesn't say whether
1464 # the output buffer may be NULL in that case or not. Inspection of the
1465 # implementation reveals that it calls memcpy() unconditionally.
1466 # Section 7.1.4, paragraph 1 of the C standard suggests that
1467 # memcpy(NULL, source, 0) is not guaranteed to produce defined (let
1468 # alone desirable) behavior (though it probably does on just about
1469 # every implementation...)
1470 #
1471 # Allocate a tiny buffer to pass in (instead of just passing NULL as
1472 # one might expect) for the initial call so as to be safe against this
1473 # potentially undefined behavior.
1474 empty = _ffi.new("char[]", 0)
1475 size = function(self._ssl, empty, 0)
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001476 if size == 0:
1477 # No Finished message so far.
1478 return None
1479
1480 buf = _ffi.new("char[]", size)
1481 function(self._ssl, buf, size)
1482 return _ffi.buffer(buf, size)[:]
1483
1484
Fedor Brunner5747b932014-03-05 14:22:34 +01001485 def get_finished(self):
1486 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001487 Obtain the latest `handshake finished` message sent to the peer.
Fedor Brunner5747b932014-03-05 14:22:34 +01001488
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001489 :return: The contents of the message or :py:obj:`None` if the TLS
1490 handshake has not yet completed.
1491 :rtype: :py:class:`bytes` or :py:class:`NoneType`
Fedor Brunner5747b932014-03-05 14:22:34 +01001492 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001493 return self._get_finished_message(_lib.SSL_get_finished)
1494
Fedor Brunner5747b932014-03-05 14:22:34 +01001495
1496 def get_peer_finished(self):
1497 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001498 Obtain the latest `handshake finished` message received from the peer.
Fedor Brunner5747b932014-03-05 14:22:34 +01001499
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001500 :return: The contents of the message or :py:obj:`None` if the TLS
1501 handshake has not yet completed.
1502 :rtype: :py:class:`bytes` or :py:class:`NoneType`
Fedor Brunner5747b932014-03-05 14:22:34 +01001503 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001504 return self._get_finished_message(_lib.SSL_get_peer_finished)
Fedor Brunner5747b932014-03-05 14:22:34 +01001505
Jean-Paul Calderone7c556ef2014-03-30 10:45:00 -04001506
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001507 def get_cipher_name(self):
1508 """
1509 Obtain the name of the currently used cipher.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001510
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001511 :returns: The name of the currently used cipher or :py:obj:`None`
1512 if no connection has been established.
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001513 :rtype: :py:class:`unicode` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001514 """
1515 cipher = _lib.SSL_get_current_cipher(self._ssl)
1516 if cipher == _ffi.NULL:
1517 return None
1518 else:
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001519 name = _ffi.string(_lib.SSL_CIPHER_get_name(cipher))
1520 return name.decode("utf-8")
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001521
Jean-Paul Calderonedbd76272014-03-29 18:09:40 -04001522
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001523 def get_cipher_bits(self):
1524 """
1525 Obtain the number of secret bits of the currently used cipher.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001526
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001527 :returns: The number of secret bits of the currently used cipher
1528 or :py:obj:`None` if no connection has been established.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001529 :rtype: :py:class:`int` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001530 """
1531 cipher = _lib.SSL_get_current_cipher(self._ssl)
1532 if cipher == _ffi.NULL:
1533 return None
1534 else:
1535 return _lib.SSL_CIPHER_get_bits(cipher, _ffi.NULL)
1536
Jean-Paul Calderonedbd76272014-03-29 18:09:40 -04001537
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001538 def get_cipher_version(self):
1539 """
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001540 Obtain the protocol version of the currently used cipher.
1541
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001542 :returns: The protocol name of the currently used cipher
1543 or :py:obj:`None` if no connection has been established.
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001544 :rtype: :py:class:`unicode` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001545 """
1546 cipher = _lib.SSL_get_current_cipher(self._ssl)
1547 if cipher == _ffi.NULL:
1548 return None
1549 else:
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001550 version =_ffi.string(_lib.SSL_CIPHER_get_version(cipher))
1551 return version.decode("utf-8")
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001552
1553
1554
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001555ConnectionType = Connection
Jean-Paul Calderone11ed8e82014-01-18 10:21:50 -05001556
Jean-Paul Calderonefab157b2014-01-18 11:21:38 -05001557# This is similar to the initialization calls at the end of OpenSSL/crypto.py
1558# but is exercised mostly by the Context initializer.
Jean-Paul Calderone11ed8e82014-01-18 10:21:50 -05001559_lib.SSL_library_init()