blob: ff0259a70ff1e136d0f3d6c644cc33139ce666d5 [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 """
Abraham Martine82326c2015-02-04 10:18:10 +0000313
314 # Backward compatibility
315 if isinstance(cafile, _text_type):
316 DeprecationWarning("str object in cafile is no longer accepted, use bytes")
317 cafile = cafile.encode('utf-8')
318
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800319 if cafile is None:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500320 cafile = _ffi.NULL
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800321 elif not isinstance(cafile, bytes):
322 raise TypeError("cafile must be None or a byte string")
323
324 if capath is None:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500325 capath = _ffi.NULL
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800326 elif not isinstance(capath, bytes):
327 raise TypeError("capath must be None or a byte string")
328
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500329 load_result = _lib.SSL_CTX_load_verify_locations(self._context, cafile, capath)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800330 if not load_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500331 _raise_current_error()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800332
333
334 def _wrap_callback(self, callback):
335 @wraps(callback)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800336 def wrapper(size, verify, userdata):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800337 return callback(size, verify, self._passphrase_userdata)
338 return _PassphraseHelper(
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800339 FILETYPE_PEM, wrapper, more_args=True, truncate=True)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800340
341
342 def set_passwd_cb(self, callback, userdata=None):
343 """
344 Set the passphrase callback
345
346 :param callback: The Python callback to use
347 :param userdata: (optional) A Python object which will be given as
348 argument to the callback
349 :return: None
350 """
351 if not callable(callback):
352 raise TypeError("callback must be callable")
353
354 self._passphrase_helper = self._wrap_callback(callback)
355 self._passphrase_callback = self._passphrase_helper.callback
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500356 _lib.SSL_CTX_set_default_passwd_cb(
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800357 self._context, self._passphrase_callback)
358 self._passphrase_userdata = userdata
359
360
361 def set_default_verify_paths(self):
362 """
363 Use the platform-specific CA certificate locations
364
365 :return: None
366 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500367 set_result = _lib.SSL_CTX_set_default_verify_paths(self._context)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800368 if not set_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500369 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500370 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800371
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800372
373 def use_certificate_chain_file(self, certfile):
374 """
375 Load a certificate chain from a file
376
377 :param certfile: The name of the certificate chain file
378 :return: None
379 """
Jean-Paul Calderoned8607982014-01-18 10:30:55 -0500380 if isinstance(certfile, _text_type):
381 # Perhaps sys.getfilesystemencoding() could be better?
382 certfile = certfile.encode("utf-8")
383
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800384 if not isinstance(certfile, bytes):
Jean-Paul Calderoned8607982014-01-18 10:30:55 -0500385 raise TypeError("certfile must be bytes or unicode")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800386
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500387 result = _lib.SSL_CTX_use_certificate_chain_file(self._context, certfile)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800388 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500389 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800390
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800391
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800392 def use_certificate_file(self, certfile, filetype=FILETYPE_PEM):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800393 """
394 Load a certificate from a file
395
396 :param certfile: The name of the certificate file
397 :param filetype: (optional) The encoding of the file, default is PEM
398 :return: None
399 """
Jean-Paul Calderone684baf52014-01-18 10:31:19 -0500400 if isinstance(certfile, _text_type):
401 # Perhaps sys.getfilesystemencoding() could be better?
402 certfile = certfile.encode("utf-8")
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800403 if not isinstance(certfile, bytes):
Jean-Paul Calderone684baf52014-01-18 10:31:19 -0500404 raise TypeError("certfile must be bytes or unicode")
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -0500405 if not isinstance(filetype, integer_types):
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800406 raise TypeError("filetype must be an integer")
407
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500408 use_result = _lib.SSL_CTX_use_certificate_file(self._context, certfile, filetype)
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800409 if not use_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500410 _raise_current_error()
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800411
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800412
413 def use_certificate(self, cert):
414 """
415 Load a certificate from a X509 object
416
417 :param cert: The X509 object
418 :return: None
419 """
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800420 if not isinstance(cert, X509):
421 raise TypeError("cert must be an X509 instance")
422
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500423 use_result = _lib.SSL_CTX_use_certificate(self._context, cert._x509)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800424 if not use_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500425 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800426
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800427
428 def add_extra_chain_cert(self, certobj):
429 """
430 Add certificate to chain
431
432 :param certobj: The X509 certificate object to add to the chain
433 :return: None
434 """
435 if not isinstance(certobj, X509):
436 raise TypeError("certobj must be an X509 instance")
437
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500438 copy = _lib.X509_dup(certobj._x509)
439 add_result = _lib.SSL_CTX_add_extra_chain_cert(self._context, copy)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800440 if not add_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500441 # TODO: This is untested.
442 _lib.X509_free(copy)
443 _raise_current_error()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800444
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800445
446 def _raise_passphrase_exception(self):
447 if self._passphrase_helper is None:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500448 _raise_current_error()
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800449 exception = self._passphrase_helper.raise_if_problem(Error)
450 if exception is not None:
451 raise exception
452
453
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800454 def use_privatekey_file(self, keyfile, filetype=_unspecified):
455 """
456 Load a private key from a file
457
458 :param keyfile: The name of the key file
459 :param filetype: (optional) The encoding of the file, default is PEM
460 :return: None
461 """
Jean-Paul Calderone87e525a2014-01-18 10:31:51 -0500462 if isinstance(keyfile, _text_type):
463 # Perhaps sys.getfilesystemencoding() could be better?
464 keyfile = keyfile.encode("utf-8")
465
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800466 if not isinstance(keyfile, bytes):
467 raise TypeError("keyfile must be a byte string")
468
469 if filetype is _unspecified:
470 filetype = FILETYPE_PEM
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -0500471 elif not isinstance(filetype, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800472 raise TypeError("filetype must be an integer")
473
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500474 use_result = _lib.SSL_CTX_use_PrivateKey_file(
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800475 self._context, keyfile, filetype)
476 if not use_result:
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800477 self._raise_passphrase_exception()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800478
479
480 def use_privatekey(self, pkey):
481 """
482 Load a private key from a PKey object
483
484 :param pkey: The PKey object
485 :return: None
486 """
487 if not isinstance(pkey, PKey):
488 raise TypeError("pkey must be a PKey instance")
489
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500490 use_result = _lib.SSL_CTX_use_PrivateKey(self._context, pkey._pkey)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800491 if not use_result:
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800492 self._raise_passphrase_exception()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800493
494
495 def check_privatekey(self):
496 """
497 Check that the private key and certificate match up
498
499 :return: None (raises an exception if something's wrong)
500 """
Jean-Paul Calderonea0344922014-12-11 14:02:31 -0500501 if not _lib.SSL_CTX_check_private_key(self._context):
502 _raise_current_error()
503
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800504
505 def load_client_ca(self, cafile):
506 """
507 Load the trusted certificates that will be sent to the client (basically
508 telling the client "These are the guys I trust"). Does not actually
509 imply any of the certificates are trusted; that must be configured
510 separately.
511
512 :param cafile: The name of the certificates file
513 :return: None
514 """
515
516 def set_session_id(self, buf):
517 """
518 Set the session identifier. This is needed if you want to do session
519 resumption.
520
521 :param buf: A Python object that can be safely converted to a string
522 :returns: None
523 """
524
525 def set_session_cache_mode(self, mode):
526 """
527 Enable/disable session caching and specify the mode used.
528
529 :param mode: One or more of the SESS_CACHE_* flags (combine using
530 bitwise or)
531 :returns: The previously set caching mode.
532 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500533 if not isinstance(mode, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800534 raise TypeError("mode must be an integer")
535
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500536 return _lib.SSL_CTX_set_session_cache_mode(self._context, mode)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800537
538
539 def get_session_cache_mode(self):
540 """
541 :returns: The currently used cache mode.
542 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500543 return _lib.SSL_CTX_get_session_cache_mode(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800544
545
546 def set_verify(self, mode, callback):
547 """
548 Set the verify mode and verify callback
549
550 :param mode: The verify mode, this is either VERIFY_NONE or
551 VERIFY_PEER combined with possible other flags
552 :param callback: The Python callback to use
553 :return: None
554
555 See SSL_CTX_set_verify(3SSL) for further details.
556 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500557 if not isinstance(mode, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800558 raise TypeError("mode must be an integer")
559
560 if not callable(callback):
561 raise TypeError("callback must be callable")
562
Jean-Paul Calderone6a8cd112014-04-02 21:09:08 -0400563 self._verify_helper = _VerifyHelper(callback)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800564 self._verify_callback = self._verify_helper.callback
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500565 _lib.SSL_CTX_set_verify(self._context, mode, self._verify_callback)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800566
567
568 def set_verify_depth(self, depth):
569 """
570 Set the verify depth
571
572 :param depth: An integer specifying the verify depth
573 :return: None
574 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500575 if not isinstance(depth, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800576 raise TypeError("depth must be an integer")
577
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500578 _lib.SSL_CTX_set_verify_depth(self._context, depth)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800579
580
581 def get_verify_mode(self):
582 """
583 Get the verify mode
584
585 :return: The verify mode
586 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500587 return _lib.SSL_CTX_get_verify_mode(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800588
589
590 def get_verify_depth(self):
591 """
592 Get the verify depth
593
594 :return: The verify depth
595 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500596 return _lib.SSL_CTX_get_verify_depth(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800597
598
599 def load_tmp_dh(self, dhfile):
600 """
601 Load parameters for Ephemeral Diffie-Hellman
602
603 :param dhfile: The file to load EDH parameters from
604 :return: None
605 """
606 if not isinstance(dhfile, bytes):
607 raise TypeError("dhfile must be a byte string")
608
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -0500609 bio = _lib.BIO_new_file(dhfile, b"r")
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500610 if bio == _ffi.NULL:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500611 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500612 bio = _ffi.gc(bio, _lib.BIO_free)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800613
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500614 dh = _lib.PEM_read_bio_DHparams(bio, _ffi.NULL, _ffi.NULL, _ffi.NULL)
615 dh = _ffi.gc(dh, _lib.DH_free)
616 _lib.SSL_CTX_set_tmp_dh(self._context, dh)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800617
618
Jean-Paul Calderone3e4e3352014-04-19 09:28:28 -0400619 def set_tmp_ecdh(self, curve):
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600620 """
Andy Lutomirski76a61332014-03-12 15:02:56 -0700621 Select a curve to use for ECDHE key exchange.
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600622
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -0400623 :param curve: A curve object to use as returned by either
624 :py:meth:`OpenSSL.crypto.get_elliptic_curve` or
625 :py:meth:`OpenSSL.crypto.get_elliptic_curves`.
Andy Lutomirskif05a2732014-03-13 17:22:25 -0700626
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600627 :return: None
628 """
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -0400629 _lib.SSL_CTX_set_tmp_ecdh(self._context, curve._to_EC_KEY())
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600630
631
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800632 def set_cipher_list(self, cipher_list):
633 """
634 Change the cipher list
635
636 :param cipher_list: A cipher list, see ciphers(1)
637 :return: None
638 """
Jean-Paul Calderone63eab692014-01-18 10:19:56 -0500639 if isinstance(cipher_list, _text_type):
640 cipher_list = cipher_list.encode("ascii")
641
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800642 if not isinstance(cipher_list, bytes):
Jean-Paul Calderone63eab692014-01-18 10:19:56 -0500643 raise TypeError("cipher_list must be bytes or unicode")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800644
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500645 result = _lib.SSL_CTX_set_cipher_list(self._context, cipher_list)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800646 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500647 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800648
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800649
650 def set_client_ca_list(self, certificate_authorities):
651 """
652 Set the list of preferred client certificate signers for this server context.
653
654 This list of certificate authorities will be sent to the client when the
655 server requests a client certificate.
656
657 :param certificate_authorities: a sequence of X509Names.
658 :return: None
659 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500660 name_stack = _lib.sk_X509_NAME_new_null()
661 if name_stack == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500662 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500663 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800664
665 try:
666 for ca_name in certificate_authorities:
667 if not isinstance(ca_name, X509Name):
668 raise TypeError(
669 "client CAs must be X509Name objects, not %s objects" % (
670 type(ca_name).__name__,))
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500671 copy = _lib.X509_NAME_dup(ca_name._name)
672 if copy == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500673 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500674 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500675 push_result = _lib.sk_X509_NAME_push(name_stack, copy)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800676 if not push_result:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500677 _lib.X509_NAME_free(copy)
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500678 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800679 except:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500680 _lib.sk_X509_NAME_free(name_stack)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800681 raise
682
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500683 _lib.SSL_CTX_set_client_CA_list(self._context, name_stack)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800684
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800685
686 def add_client_ca(self, certificate_authority):
687 """
688 Add the CA certificate to the list of preferred signers for this context.
689
690 The list of certificate authorities will be sent to the client when the
691 server requests a client certificate.
692
693 :param certificate_authority: certificate authority's X509 certificate.
694 :return: None
695 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800696 if not isinstance(certificate_authority, X509):
697 raise TypeError("certificate_authority must be an X509 instance")
698
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500699 add_result = _lib.SSL_CTX_add_client_CA(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800700 self._context, certificate_authority._x509)
701 if not add_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500702 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500703 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800704
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800705
706 def set_timeout(self, timeout):
707 """
708 Set session timeout
709
710 :param timeout: The timeout in seconds
711 :return: The previous session timeout
712 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500713 if not isinstance(timeout, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800714 raise TypeError("timeout must be an integer")
715
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500716 return _lib.SSL_CTX_set_timeout(self._context, timeout)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800717
718
719 def get_timeout(self):
720 """
721 Get the session timeout
722
723 :return: The session timeout
724 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500725 return _lib.SSL_CTX_get_timeout(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800726
727
728 def set_info_callback(self, callback):
729 """
730 Set the info callback
731
732 :param callback: The Python callback to use
733 :return: None
734 """
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800735 @wraps(callback)
736 def wrapper(ssl, where, return_code):
Jean-Paul Calderonef2bbc9c2014-02-02 10:59:14 -0500737 callback(Connection._reverse_mapping[ssl], where, return_code)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500738 self._info_callback = _ffi.callback(
739 "void (*)(const SSL *, int, int)", wrapper)
740 _lib.SSL_CTX_set_info_callback(self._context, self._info_callback)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800741
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800742
743 def get_app_data(self):
744 """
745 Get the application data (supplied via set_app_data())
746
747 :return: The application data
748 """
749 return self._app_data
750
751
752 def set_app_data(self, data):
753 """
754 Set the application data (will be returned from get_app_data())
755
756 :param data: Any Python object
757 :return: None
758 """
759 self._app_data = data
760
761
762 def get_cert_store(self):
763 """
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500764 Get the certificate store for the context.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800765
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500766 :return: A X509Store object or None if it does not have one.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800767 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500768 store = _lib.SSL_CTX_get_cert_store(self._context)
769 if store == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500770 # TODO: This is untested.
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800771 return None
772
773 pystore = X509Store.__new__(X509Store)
774 pystore._store = store
775 return pystore
776
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800777
778 def set_options(self, options):
779 """
780 Add options. Options set before are not cleared!
781
782 :param options: The options to add.
783 :return: The new option bitmask.
784 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500785 if not isinstance(options, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800786 raise TypeError("options must be an integer")
787
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500788 return _lib.SSL_CTX_set_options(self._context, options)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800789
790
791 def set_mode(self, mode):
792 """
793 Add modes via bitmask. Modes set before are not cleared!
794
795 :param mode: The mode to add.
796 :return: The new mode bitmask.
797 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500798 if not isinstance(mode, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800799 raise TypeError("mode must be an integer")
800
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500801 return _lib.SSL_CTX_set_mode(self._context, mode)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800802
803
804 def set_tlsext_servername_callback(self, callback):
805 """
806 Specify a callback function to be called when clients specify a server name.
807
808 :param callback: The callback function. It will be invoked with one
809 argument, the Connection instance.
810 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800811 @wraps(callback)
812 def wrapper(ssl, alert, arg):
813 callback(Connection._reverse_mapping[ssl])
814 return 0
815
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500816 self._tlsext_servername_callback = _ffi.callback(
817 "int (*)(const SSL *, int *, void *)", wrapper)
818 _lib.SSL_CTX_set_tlsext_servername_callback(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800819 self._context, self._tlsext_servername_callback)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800820
821ContextType = Context
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800822
823
824
825class Connection(object):
826 """
827 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800828 _reverse_mapping = WeakValueDictionary()
829
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800830 def __init__(self, context, socket=None):
831 """
832 Create a new Connection object, using the given OpenSSL.SSL.Context
833 instance and socket.
834
835 :param context: An SSL Context to use for this connection
836 :param socket: The socket to use for transport layer
837 """
838 if not isinstance(context, Context):
839 raise TypeError("context must be a Context instance")
840
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500841 ssl = _lib.SSL_new(context._context)
842 self._ssl = _ffi.gc(ssl, _lib.SSL_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800843 self._context = context
844
845 self._reverse_mapping[self._ssl] = self
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800846
847 if socket is None:
848 self._socket = None
Jean-Paul Calderone73b15c22013-03-05 18:30:39 -0800849 # Don't set up any gc for these, SSL_free will take care of them.
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500850 self._into_ssl = _lib.BIO_new(_lib.BIO_s_mem())
851 self._from_ssl = _lib.BIO_new(_lib.BIO_s_mem())
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800852
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500853 if self._into_ssl == _ffi.NULL or self._from_ssl == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500854 # TODO: This is untested.
855 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800856
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500857 _lib.SSL_set_bio(self._ssl, self._into_ssl, self._from_ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800858 else:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800859 self._into_ssl = None
860 self._from_ssl = None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800861 self._socket = socket
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500862 set_result = _lib.SSL_set_fd(self._ssl, _asFileDescriptor(self._socket))
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800863 if not set_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500864 # TODO: This is untested.
865 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800866
867
868 def __getattr__(self, name):
869 """
870 Look up attributes on the wrapped socket object if they are not found on
871 the Connection object.
872 """
873 return getattr(self._socket, name)
874
875
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800876 def _raise_ssl_error(self, ssl, result):
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800877 if self._context._verify_helper is not None:
878 self._context._verify_helper.raise_if_problem()
879
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500880 error = _lib.SSL_get_error(ssl, result)
881 if error == _lib.SSL_ERROR_WANT_READ:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800882 raise WantReadError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500883 elif error == _lib.SSL_ERROR_WANT_WRITE:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -0700884 raise WantWriteError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500885 elif error == _lib.SSL_ERROR_ZERO_RETURN:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800886 raise ZeroReturnError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500887 elif error == _lib.SSL_ERROR_WANT_X509_LOOKUP:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500888 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -0700889 raise WantX509LookupError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500890 elif error == _lib.SSL_ERROR_SYSCALL:
891 if _lib.ERR_peek_error() == 0:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800892 if result < 0:
Konstantinos Koukopoulos541150d2014-01-31 01:00:19 +0200893 if platform == "win32":
894 errno = _ffi.getwinerror()[0]
895 else:
896 errno = _ffi.errno
897 raise SysCallError(errno, errorcode[errno])
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800898 else:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -0700899 raise SysCallError(-1, "Unexpected EOF")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800900 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500901 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500902 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500903 elif error == _lib.SSL_ERROR_NONE:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -0700904 pass
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800905 else:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500906 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800907
908
909 def get_context(self):
910 """
911 Get session context
912 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800913 return self._context
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800914
915
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800916 def set_context(self, context):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800917 """
918 Switch this connection to a new session context
919
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800920 :param context: A :py:class:`Context` instance giving the new session
921 context to use.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800922 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800923 if not isinstance(context, Context):
924 raise TypeError("context must be a Context instance")
925
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500926 _lib.SSL_set_SSL_CTX(self._ssl, context._context)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800927 self._context = context
928
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800929
930 def get_servername(self):
931 """
932 Retrieve the servername extension value if provided in the client hello
933 message, or None if there wasn't one.
934
935 :return: A byte string giving the server name or :py:data:`None`.
936 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500937 name = _lib.SSL_get_servername(self._ssl, _lib.TLSEXT_NAMETYPE_host_name)
938 if name == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800939 return None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800940
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500941 return _ffi.string(name)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800942
943
944 def set_tlsext_host_name(self, name):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800945 """
946 Set the value of the servername extension to send in the client hello.
947
948 :param name: A byte string giving the name.
949 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800950 if not isinstance(name, bytes):
951 raise TypeError("name must be a byte string")
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -0500952 elif b"\0" in name:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800953 raise TypeError("name must not contain NUL byte")
954
955 # XXX I guess this can fail sometimes?
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500956 _lib.SSL_set_tlsext_host_name(self._ssl, name)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800957
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800958
959 def pending(self):
960 """
961 Get the number of bytes that can be safely read from the connection
962
963 :return: The number of bytes available in the receive buffer.
964 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500965 return _lib.SSL_pending(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800966
967
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800968 def send(self, buf, flags=0):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800969 """
970 Send data on the connection. NOTE: If you get one of the WantRead,
971 WantWrite or WantX509Lookup exceptions on this, you have to call the
972 method again with the SAME buffer.
973
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +0200974 :param buf: The string, buffer or memoryview to send
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800975 :param flags: (optional) Included for compatibility with the socket
976 API, the value is ignored
977 :return: The number of bytes written
978 """
Abraham Martine82326c2015-02-04 10:18:10 +0000979
980 # Backward compatibility
981 if isinstance(buf, _text_type):
982 DeprecationWarning("str object in buf is no longer accepted, use bytes")
983 buf = buf.encode('utf-8')
984
Jean-Paul Calderone8fb53182013-12-30 08:35:49 -0500985 if isinstance(buf, _memoryview):
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -0800986 buf = buf.tobytes()
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +0200987 if isinstance(buf, _buffer):
988 buf = str(buf)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800989 if not isinstance(buf, bytes):
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +0200990 raise TypeError("data must be a memoryview, buffer or byte string")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800991
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500992 result = _lib.SSL_write(self._ssl, buf, len(buf))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800993 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800994 return result
995 write = send
996
997
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800998 def sendall(self, buf, flags=0):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800999 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001000 Send "all" data on the connection. This calls send() repeatedly until
1001 all data is sent. If an error occurs, it's impossible to tell how much
1002 data has been sent.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001003
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001004 :param buf: The string, buffer or memoryview to send
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001005 :param flags: (optional) Included for compatibility with the socket
1006 API, the value is ignored
1007 :return: The number of bytes written
1008 """
Abraham Martine82326c2015-02-04 10:18:10 +00001009
1010 # Backward compatibility
1011 if isinstance(buf, _text_type):
1012 DeprecationWarning("str object in buf is no longer accepted, use bytes")
1013 buf = buf.encode('utf-8')
1014
Jean-Paul Calderone8fb53182013-12-30 08:35:49 -05001015 if isinstance(buf, _memoryview):
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -08001016 buf = buf.tobytes()
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001017 if isinstance(buf, _buffer):
1018 buf = str(buf)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001019 if not isinstance(buf, bytes):
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001020 raise TypeError("buf must be a memoryview, buffer or byte string")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001021
1022 left_to_send = len(buf)
1023 total_sent = 0
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001024 data = _ffi.new("char[]", buf)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001025
1026 while left_to_send:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001027 result = _lib.SSL_write(self._ssl, data + total_sent, left_to_send)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001028 self._raise_ssl_error(self._ssl, result)
1029 total_sent += result
1030 left_to_send -= result
1031
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001032
1033 def recv(self, bufsiz, flags=None):
1034 """
1035 Receive data on the connection. NOTE: If you get one of the WantRead,
1036 WantWrite or WantX509Lookup exceptions on this, you have to call the
1037 method again with the SAME buffer.
1038
1039 :param bufsiz: The maximum number of bytes to read
1040 :param flags: (optional) Included for compatibility with the socket
1041 API, the value is ignored
1042 :return: The string read from the Connection
1043 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001044 buf = _ffi.new("char[]", bufsiz)
1045 result = _lib.SSL_read(self._ssl, buf, bufsiz)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001046 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001047 return _ffi.buffer(buf, result)[:]
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001048 read = recv
1049
1050
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001051 def _handle_bio_errors(self, bio, result):
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001052 if _lib.BIO_should_retry(bio):
1053 if _lib.BIO_should_read(bio):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001054 raise WantReadError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001055 elif _lib.BIO_should_write(bio):
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001056 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001057 raise WantWriteError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001058 elif _lib.BIO_should_io_special(bio):
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001059 # TODO: This is untested. I think io_special means the socket
1060 # BIO has a not-yet connected socket.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001061 raise ValueError("BIO_should_io_special")
1062 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001063 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001064 raise ValueError("unknown bio failure")
1065 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001066 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001067 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001068
1069
1070 def bio_read(self, bufsiz):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001071 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001072 When using non-socket connections this function reads the "dirty" data
1073 that would have traveled away on the network.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001074
1075 :param bufsiz: The maximum number of bytes to read
1076 :return: The string read.
1077 """
Jean-Paul Calderone97e041d2013-03-05 21:03:12 -08001078 if self._from_ssl is None:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001079 raise TypeError("Connection sock was not None")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001080
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -05001081 if not isinstance(bufsiz, integer_types):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001082 raise TypeError("bufsiz must be an integer")
1083
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001084 buf = _ffi.new("char[]", bufsiz)
1085 result = _lib.BIO_read(self._from_ssl, buf, bufsiz)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001086 if result <= 0:
1087 self._handle_bio_errors(self._from_ssl, result)
1088
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001089 return _ffi.buffer(buf, result)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001090
1091
1092 def bio_write(self, buf):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001093 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001094 When using non-socket connections this function sends "dirty" data that
1095 would have traveled in on the network.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001096
1097 :param buf: The string to put into the memory BIO.
1098 :return: The number of bytes written
1099 """
Abraham Martine82326c2015-02-04 10:18:10 +00001100
1101 # Backward compatibility
1102 if isinstance(buf, _text_type):
1103 DeprecationWarning("str object in buf is no longer accepted, use bytes")
1104 buf = buf.encode("ascii")
1105
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001106 if self._into_ssl is None:
1107 raise TypeError("Connection sock was not None")
1108
1109 if not isinstance(buf, bytes):
1110 raise TypeError("buf must be a byte string")
1111
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001112 result = _lib.BIO_write(self._into_ssl, buf, len(buf))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001113 if result <= 0:
1114 self._handle_bio_errors(self._into_ssl, result)
1115 return result
1116
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001117
1118 def renegotiate(self):
1119 """
1120 Renegotiate the session
1121
1122 :return: True if the renegotiation can be started, false otherwise
1123 """
1124
1125 def do_handshake(self):
1126 """
1127 Perform an SSL handshake (usually called after renegotiate() or one of
1128 set_*_state()). This can raise the same exceptions as send and recv.
1129
1130 :return: None.
1131 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001132 result = _lib.SSL_do_handshake(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001133 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001134
1135
1136 def renegotiate_pending(self):
1137 """
1138 Check if there's a renegotiation in progress, it will return false once
1139 a renegotiation is finished.
1140
1141 :return: Whether there's a renegotiation in progress
1142 """
1143
1144 def total_renegotiations(self):
1145 """
1146 Find out the total number of renegotiations.
1147
1148 :return: The number of renegotiations.
1149 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001150 return _lib.SSL_total_renegotiations(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001151
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001152
1153 def connect(self, addr):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001154 """
1155 Connect to remote host and set up client-side SSL
1156
1157 :param addr: A remote address
1158 :return: What the socket's connect method returns
1159 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001160 _lib.SSL_set_connect_state(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001161 return self._socket.connect(addr)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001162
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001163
1164 def connect_ex(self, addr):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001165 """
1166 Connect to remote host and set up client-side SSL. Note that if the socket's
1167 connect_ex method doesn't return 0, SSL won't be initialized.
1168
1169 :param addr: A remove address
1170 :return: What the socket's connect_ex method returns
1171 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001172 connect_ex = self._socket.connect_ex
1173 self.set_connect_state()
1174 return connect_ex(addr)
1175
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001176
1177 def accept(self):
1178 """
1179 Accept incoming connection and set up SSL on it
1180
1181 :return: A (conn,addr) pair where conn is a Connection and addr is an
1182 address
1183 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001184 client, addr = self._socket.accept()
1185 conn = Connection(self._context, client)
1186 conn.set_accept_state()
1187 return (conn, addr)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001188
1189
1190 def bio_shutdown(self):
1191 """
1192 When using non-socket connections this function signals end of
1193 data on the input for this connection.
1194
1195 :return: None
1196 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001197 if self._from_ssl is None:
1198 raise TypeError("Connection sock was not None")
1199
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001200 _lib.BIO_set_mem_eof_return(self._into_ssl, 0)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001201
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001202
1203 def shutdown(self):
1204 """
1205 Send closure alert
1206
1207 :return: True if the shutdown completed successfully (i.e. both sides
1208 have sent closure alerts), false otherwise (i.e. you have to
1209 wait for a ZeroReturnError on a recv() method call
1210 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001211 result = _lib.SSL_shutdown(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001212 if result < 0:
Paul Aurichbff1d1a2015-01-08 08:36:53 -08001213 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001214 elif result > 0:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001215 return True
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001216 else:
1217 return False
1218
1219
1220 def get_cipher_list(self):
1221 """
1222 Get the session cipher list
1223
1224 :return: A list of cipher strings
1225 """
1226 ciphers = []
1227 for i in count():
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001228 result = _lib.SSL_get_cipher_list(self._ssl, i)
1229 if result == _ffi.NULL:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001230 break
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001231 ciphers.append(_native(_ffi.string(result)))
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001232 return ciphers
1233
1234
1235 def get_client_ca_list(self):
1236 """
1237 Get CAs whose certificates are suggested for client authentication.
1238
1239 :return: If this is a server connection, a list of X509Names representing
1240 the acceptable CAs as set by :py:meth:`OpenSSL.SSL.Context.set_client_ca_list` or
1241 :py:meth:`OpenSSL.SSL.Context.add_client_ca`. If this is a client connection,
1242 the list of such X509Names sent by the server, or an empty list if that
1243 has not yet happened.
1244 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001245 ca_names = _lib.SSL_get_client_CA_list(self._ssl)
1246 if ca_names == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001247 # TODO: This is untested.
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001248 return []
1249
1250 result = []
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001251 for i in range(_lib.sk_X509_NAME_num(ca_names)):
1252 name = _lib.sk_X509_NAME_value(ca_names, i)
1253 copy = _lib.X509_NAME_dup(name)
1254 if copy == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001255 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001256 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001257
1258 pyname = X509Name.__new__(X509Name)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001259 pyname._name = _ffi.gc(copy, _lib.X509_NAME_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001260 result.append(pyname)
1261 return result
1262
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001263
1264 def makefile(self):
1265 """
1266 The makefile() method is not implemented, since there is no dup semantics
1267 for SSL connections
1268
Jean-Paul Calderone6749ec22014-04-17 16:30:21 -04001269 :raise: NotImplementedError
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001270 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001271 raise NotImplementedError("Cannot make file object of OpenSSL.SSL.Connection")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001272
1273
1274 def get_app_data(self):
1275 """
1276 Get application data
1277
1278 :return: The application data
1279 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001280 return self._app_data
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001281
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001282
1283 def set_app_data(self, data):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001284 """
1285 Set application data
1286
1287 :param data - The application data
1288 :return: None
1289 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001290 self._app_data = data
1291
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001292
1293 def get_shutdown(self):
1294 """
1295 Get shutdown state
1296
1297 :return: The shutdown state, a bitvector of SENT_SHUTDOWN, RECEIVED_SHUTDOWN.
1298 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001299 return _lib.SSL_get_shutdown(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001300
1301
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001302 def set_shutdown(self, state):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001303 """
1304 Set shutdown state
1305
1306 :param state - bitvector of SENT_SHUTDOWN, RECEIVED_SHUTDOWN.
1307 :return: None
1308 """
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -05001309 if not isinstance(state, integer_types):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001310 raise TypeError("state must be an integer")
1311
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001312 _lib.SSL_set_shutdown(self._ssl, state)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001313
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001314
1315 def state_string(self):
1316 """
1317 Get a verbose state description
1318
1319 :return: A string representing the state
1320 """
1321
1322 def server_random(self):
1323 """
1324 Get a copy of the server hello nonce.
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.s3.server_random,
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001332 _lib.SSL3_RANDOM_SIZE)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001333
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001334
1335 def client_random(self):
1336 """
1337 Get a copy of the client hello nonce.
1338
1339 :return: A string representing the state
1340 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001341 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001342 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001343 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001344 self._ssl.s3.client_random,
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001345 _lib.SSL3_RANDOM_SIZE)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001346
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001347
1348 def master_key(self):
1349 """
1350 Get a copy of the master key.
1351
1352 :return: A string representing the state
1353 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001354 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001355 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001356 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001357 self._ssl.session.master_key,
1358 self._ssl.session.master_key_length)[:]
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001359
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001360
1361 def sock_shutdown(self, *args, **kwargs):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001362 """
1363 See shutdown(2)
1364
1365 :return: What the socket's shutdown() method returns
1366 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001367 return self._socket.shutdown(*args, **kwargs)
1368
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001369
1370 def get_peer_certificate(self):
1371 """
1372 Retrieve the other side's certificate (if any)
1373
1374 :return: The peer's certificate
1375 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001376 cert = _lib.SSL_get_peer_certificate(self._ssl)
1377 if cert != _ffi.NULL:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001378 pycert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001379 pycert._x509 = _ffi.gc(cert, _lib.X509_free)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001380 return pycert
1381 return None
1382
1383
1384 def get_peer_cert_chain(self):
1385 """
1386 Retrieve the other side's certificate (if any)
1387
1388 :return: A list of X509 instances giving the peer's certificate chain,
1389 or None if it does not have one.
1390 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001391 cert_stack = _lib.SSL_get_peer_cert_chain(self._ssl)
1392 if cert_stack == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001393 return None
1394
1395 result = []
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001396 for i in range(_lib.sk_X509_num(cert_stack)):
Jean-Paul Calderone73b15c22013-03-05 18:30:39 -08001397 # TODO could incref instead of dup here
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001398 cert = _lib.X509_dup(_lib.sk_X509_value(cert_stack, i))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001399 pycert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001400 pycert._x509 = _ffi.gc(cert, _lib.X509_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001401 result.append(pycert)
1402 return result
1403
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001404
1405 def want_read(self):
1406 """
1407 Checks if more data has to be read from the transport layer to complete an
1408 operation.
1409
1410 :return: True iff more data has to be read
1411 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001412 return _lib.SSL_want_read(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001413
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001414
1415 def want_write(self):
1416 """
1417 Checks if there is data to write to the transport layer to complete an
1418 operation.
1419
1420 :return: True iff there is data to write
1421 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001422 return _lib.SSL_want_write(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001423
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001424
1425 def set_accept_state(self):
1426 """
1427 Set the connection to work in server mode. The handshake will be handled
1428 automatically by read/write.
1429
1430 :return: None
1431 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001432 _lib.SSL_set_accept_state(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001433
1434
1435 def set_connect_state(self):
1436 """
1437 Set the connection to work in client mode. The handshake will be handled
1438 automatically by read/write.
1439
1440 :return: None
1441 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001442 _lib.SSL_set_connect_state(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001443
1444
1445 def get_session(self):
1446 """
1447 Returns the Session currently used.
1448
1449 @return: An instance of :py:class:`OpenSSL.SSL.Session` or :py:obj:`None` if
1450 no session exists.
1451 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001452 session = _lib.SSL_get1_session(self._ssl)
1453 if session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001454 return None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001455
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001456 pysession = Session.__new__(Session)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001457 pysession._session = _ffi.gc(session, _lib.SSL_SESSION_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001458 return pysession
1459
1460
1461 def set_session(self, session):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001462 """
1463 Set the session to be used when the TLS/SSL connection is established.
1464
1465 :param session: A Session instance representing the session to use.
1466 :returns: None
1467 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001468 if not isinstance(session, Session):
1469 raise TypeError("session must be a Session instance")
1470
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001471 result = _lib.SSL_set_session(self._ssl, session._session)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001472 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001473 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001474
Jean-Paul Calderonedbd76272014-03-29 18:09:40 -04001475
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001476 def _get_finished_message(self, function):
1477 """
1478 Helper to implement :py:meth:`get_finished` and
1479 :py:meth:`get_peer_finished`.
1480
1481 :param function: Either :py:data:`SSL_get_finished`: or
1482 :py:data:`SSL_get_peer_finished`.
1483
1484 :return: :py:data:`None` if the desired message has not yet been
1485 received, otherwise the contents of the message.
1486 :rtype: :py:class:`bytes` or :py:class:`NoneType`
1487 """
Jean-Paul Calderone01af9042014-03-30 11:40:42 -04001488 # The OpenSSL documentation says nothing about what might happen if the
1489 # count argument given is zero. Specifically, it doesn't say whether
1490 # the output buffer may be NULL in that case or not. Inspection of the
1491 # implementation reveals that it calls memcpy() unconditionally.
1492 # Section 7.1.4, paragraph 1 of the C standard suggests that
1493 # memcpy(NULL, source, 0) is not guaranteed to produce defined (let
1494 # alone desirable) behavior (though it probably does on just about
1495 # every implementation...)
1496 #
1497 # Allocate a tiny buffer to pass in (instead of just passing NULL as
1498 # one might expect) for the initial call so as to be safe against this
1499 # potentially undefined behavior.
1500 empty = _ffi.new("char[]", 0)
1501 size = function(self._ssl, empty, 0)
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001502 if size == 0:
1503 # No Finished message so far.
1504 return None
1505
1506 buf = _ffi.new("char[]", size)
1507 function(self._ssl, buf, size)
1508 return _ffi.buffer(buf, size)[:]
1509
1510
Fedor Brunner5747b932014-03-05 14:22:34 +01001511 def get_finished(self):
1512 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001513 Obtain the latest `handshake finished` message sent to the peer.
Fedor Brunner5747b932014-03-05 14:22:34 +01001514
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001515 :return: The contents of the message or :py:obj:`None` if the TLS
1516 handshake has not yet completed.
1517 :rtype: :py:class:`bytes` or :py:class:`NoneType`
Fedor Brunner5747b932014-03-05 14:22:34 +01001518 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001519 return self._get_finished_message(_lib.SSL_get_finished)
1520
Fedor Brunner5747b932014-03-05 14:22:34 +01001521
1522 def get_peer_finished(self):
1523 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001524 Obtain the latest `handshake finished` message received from the peer.
Fedor Brunner5747b932014-03-05 14:22:34 +01001525
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001526 :return: The contents of the message or :py:obj:`None` if the TLS
1527 handshake has not yet completed.
1528 :rtype: :py:class:`bytes` or :py:class:`NoneType`
Fedor Brunner5747b932014-03-05 14:22:34 +01001529 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001530 return self._get_finished_message(_lib.SSL_get_peer_finished)
Fedor Brunner5747b932014-03-05 14:22:34 +01001531
Jean-Paul Calderone7c556ef2014-03-30 10:45:00 -04001532
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001533 def get_cipher_name(self):
1534 """
1535 Obtain the name of the currently used cipher.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001536
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001537 :returns: The name of the currently used cipher or :py:obj:`None`
1538 if no connection has been established.
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001539 :rtype: :py:class:`unicode` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001540 """
1541 cipher = _lib.SSL_get_current_cipher(self._ssl)
1542 if cipher == _ffi.NULL:
1543 return None
1544 else:
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001545 name = _ffi.string(_lib.SSL_CIPHER_get_name(cipher))
1546 return name.decode("utf-8")
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001547
Jean-Paul Calderonedbd76272014-03-29 18:09:40 -04001548
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001549 def get_cipher_bits(self):
1550 """
1551 Obtain the number of secret bits of the currently used cipher.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001552
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001553 :returns: The number of secret bits of the currently used cipher
1554 or :py:obj:`None` if no connection has been established.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001555 :rtype: :py:class:`int` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001556 """
1557 cipher = _lib.SSL_get_current_cipher(self._ssl)
1558 if cipher == _ffi.NULL:
1559 return None
1560 else:
1561 return _lib.SSL_CIPHER_get_bits(cipher, _ffi.NULL)
1562
Jean-Paul Calderonedbd76272014-03-29 18:09:40 -04001563
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001564 def get_cipher_version(self):
1565 """
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001566 Obtain the protocol version of the currently used cipher.
1567
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001568 :returns: The protocol name of the currently used cipher
1569 or :py:obj:`None` if no connection has been established.
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001570 :rtype: :py:class:`unicode` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001571 """
1572 cipher = _lib.SSL_get_current_cipher(self._ssl)
1573 if cipher == _ffi.NULL:
1574 return None
1575 else:
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001576 version =_ffi.string(_lib.SSL_CIPHER_get_version(cipher))
1577 return version.decode("utf-8")
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001578
1579
1580
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001581ConnectionType = Connection
Jean-Paul Calderone11ed8e82014-01-18 10:21:50 -05001582
Jean-Paul Calderonefab157b2014-01-18 11:21:38 -05001583# This is similar to the initialization calls at the end of OpenSSL/crypto.py
1584# but is exercised mostly by the Context initializer.
Jean-Paul Calderone11ed8e82014-01-18 10:21:50 -05001585_lib.SSL_library_init()