blob: e6a629b153989b27a44fee2ddfb055cfcdf869f9 [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
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050027OPENSSL_VERSION_NUMBER = _lib.OPENSSL_VERSION_NUMBER
28SSLEAY_VERSION = _lib.SSLEAY_VERSION
29SSLEAY_CFLAGS = _lib.SSLEAY_CFLAGS
30SSLEAY_PLATFORM = _lib.SSLEAY_PLATFORM
31SSLEAY_DIR = _lib.SSLEAY_DIR
32SSLEAY_BUILT_ON = _lib.SSLEAY_BUILT_ON
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080033
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050034SENT_SHUTDOWN = _lib.SSL_SENT_SHUTDOWN
35RECEIVED_SHUTDOWN = _lib.SSL_RECEIVED_SHUTDOWN
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080036
37SSLv2_METHOD = 1
38SSLv3_METHOD = 2
39SSLv23_METHOD = 3
40TLSv1_METHOD = 4
Jean-Paul Calderone56bff942013-11-03 11:30:43 -050041TLSv1_1_METHOD = 5
42TLSv1_2_METHOD = 6
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080043
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050044OP_NO_SSLv2 = _lib.SSL_OP_NO_SSLv2
45OP_NO_SSLv3 = _lib.SSL_OP_NO_SSLv3
46OP_NO_TLSv1 = _lib.SSL_OP_NO_TLSv1
Jean-Paul Calderonebe2bb422013-12-29 07:34:08 -050047
48OP_NO_TLSv1_1 = getattr(_lib, "SSL_OP_NO_TLSv1_1", 0)
49OP_NO_TLSv1_2 = getattr(_lib, "SSL_OP_NO_TLSv1_2", 0)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -080050
Jean-Paul Calderone0d7e8a12014-01-08 16:54:13 -050051try:
52 MODE_RELEASE_BUFFERS = _lib.SSL_MODE_RELEASE_BUFFERS
53except AttributeError:
54 pass
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080055
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050056OP_SINGLE_DH_USE = _lib.SSL_OP_SINGLE_DH_USE
57OP_EPHEMERAL_RSA = _lib.SSL_OP_EPHEMERAL_RSA
58OP_MICROSOFT_SESS_ID_BUG = _lib.SSL_OP_MICROSOFT_SESS_ID_BUG
59OP_NETSCAPE_CHALLENGE_BUG = _lib.SSL_OP_NETSCAPE_CHALLENGE_BUG
60OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG = _lib.SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG
61OP_SSLREF2_REUSE_CERT_TYPE_BUG = _lib.SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG
62OP_MICROSOFT_BIG_SSLV3_BUFFER = _lib.SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER
Jean-Paul Calderone0d7e8a12014-01-08 16:54:13 -050063try:
64 OP_MSIE_SSLV2_RSA_PADDING = _lib.SSL_OP_MSIE_SSLV2_RSA_PADDING
65except AttributeError:
66 pass
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050067OP_SSLEAY_080_CLIENT_DH_BUG = _lib.SSL_OP_SSLEAY_080_CLIENT_DH_BUG
68OP_TLS_D5_BUG = _lib.SSL_OP_TLS_D5_BUG
69OP_TLS_BLOCK_PADDING_BUG = _lib.SSL_OP_TLS_BLOCK_PADDING_BUG
70OP_DONT_INSERT_EMPTY_FRAGMENTS = _lib.SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
71OP_CIPHER_SERVER_PREFERENCE = _lib.SSL_OP_CIPHER_SERVER_PREFERENCE
72OP_TLS_ROLLBACK_BUG = _lib.SSL_OP_TLS_ROLLBACK_BUG
73OP_PKCS1_CHECK_1 = _lib.SSL_OP_PKCS1_CHECK_1
74OP_PKCS1_CHECK_2 = _lib.SSL_OP_PKCS1_CHECK_2
75OP_NETSCAPE_CA_DN_BUG = _lib.SSL_OP_NETSCAPE_CA_DN_BUG
76OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG= _lib.SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG
Jean-Paul Calderonec1780342014-01-08 16:59:03 -050077try:
78 OP_NO_COMPRESSION = _lib.SSL_OP_NO_COMPRESSION
79except AttributeError:
80 pass
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -080081
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050082OP_NO_QUERY_MTU = _lib.SSL_OP_NO_QUERY_MTU
83OP_COOKIE_EXCHANGE = _lib.SSL_OP_COOKIE_EXCHANGE
Arturo Filastò5f8c7a82014-03-09 20:01:25 +010084try:
85 OP_NO_TICKET = _lib.SSL_OP_NO_TICKET
86except AttributeError:
87 pass
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -080088
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050089OP_ALL = _lib.SSL_OP_ALL
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080090
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050091VERIFY_PEER = _lib.SSL_VERIFY_PEER
92VERIFY_FAIL_IF_NO_PEER_CERT = _lib.SSL_VERIFY_FAIL_IF_NO_PEER_CERT
93VERIFY_CLIENT_ONCE = _lib.SSL_VERIFY_CLIENT_ONCE
94VERIFY_NONE = _lib.SSL_VERIFY_NONE
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080095
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050096SESS_CACHE_OFF = _lib.SSL_SESS_CACHE_OFF
97SESS_CACHE_CLIENT = _lib.SSL_SESS_CACHE_CLIENT
98SESS_CACHE_SERVER = _lib.SSL_SESS_CACHE_SERVER
99SESS_CACHE_BOTH = _lib.SSL_SESS_CACHE_BOTH
100SESS_CACHE_NO_AUTO_CLEAR = _lib.SSL_SESS_CACHE_NO_AUTO_CLEAR
101SESS_CACHE_NO_INTERNAL_LOOKUP = _lib.SSL_SESS_CACHE_NO_INTERNAL_LOOKUP
102SESS_CACHE_NO_INTERNAL_STORE = _lib.SSL_SESS_CACHE_NO_INTERNAL_STORE
103SESS_CACHE_NO_INTERNAL = _lib.SSL_SESS_CACHE_NO_INTERNAL
Jean-Paul Calderoned39a3f62013-03-04 12:23:51 -0800104
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500105SSL_ST_CONNECT = _lib.SSL_ST_CONNECT
106SSL_ST_ACCEPT = _lib.SSL_ST_ACCEPT
107SSL_ST_MASK = _lib.SSL_ST_MASK
108SSL_ST_INIT = _lib.SSL_ST_INIT
109SSL_ST_BEFORE = _lib.SSL_ST_BEFORE
110SSL_ST_OK = _lib.SSL_ST_OK
111SSL_ST_RENEGOTIATE = _lib.SSL_ST_RENEGOTIATE
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800112
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500113SSL_CB_LOOP = _lib.SSL_CB_LOOP
114SSL_CB_EXIT = _lib.SSL_CB_EXIT
115SSL_CB_READ = _lib.SSL_CB_READ
116SSL_CB_WRITE = _lib.SSL_CB_WRITE
117SSL_CB_ALERT = _lib.SSL_CB_ALERT
118SSL_CB_READ_ALERT = _lib.SSL_CB_READ_ALERT
119SSL_CB_WRITE_ALERT = _lib.SSL_CB_WRITE_ALERT
120SSL_CB_ACCEPT_LOOP = _lib.SSL_CB_ACCEPT_LOOP
121SSL_CB_ACCEPT_EXIT = _lib.SSL_CB_ACCEPT_EXIT
122SSL_CB_CONNECT_LOOP = _lib.SSL_CB_CONNECT_LOOP
123SSL_CB_CONNECT_EXIT = _lib.SSL_CB_CONNECT_EXIT
124SSL_CB_HANDSHAKE_START = _lib.SSL_CB_HANDSHAKE_START
125SSL_CB_HANDSHAKE_DONE = _lib.SSL_CB_HANDSHAKE_DONE
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800126
Alex Gaynor807853c2014-01-17 13:03:27 -0600127_Cryptography_HAS_EC = _lib.Cryptography_HAS_EC
Andy Lutomirski9bca0ed2014-03-05 14:41:41 -0800128ELLIPTIC_CURVE_DESCRIPTIONS = {} # In case there's no EC support
129if _Cryptography_HAS_EC:
130 _num_curves = _lib.EC_get_builtin_curves(_ffi.NULL, 0)
131 _curves = _ffi.new('EC_builtin_curve[]', _num_curves)
132 if _lib.EC_get_builtin_curves(_curves, _num_curves) == _num_curves:
Andy Lutomirskif05a2732014-03-13 17:22:25 -0700133 ELLIPTIC_CURVE_DESCRIPTIONS = dict((_ffi.string(_lib.OBJ_nid2sn(c.nid)),
134 _ffi.string(c.comment))
Andy Lutomirski76a61332014-03-12 15:02:56 -0700135 for c in _curves)
Andy Lutomirski9bca0ed2014-03-05 14:41:41 -0800136 del _num_curves
137 del _curves
Alex Gaynor12dc0842014-01-17 12:51:31 -0600138
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800139
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500140class Error(Exception):
Jean-Paul Calderone511cde02013-12-29 10:31:13 -0500141 """
142 An error occurred in an `OpenSSL.SSL` API.
143 """
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500144
145
146
147_raise_current_error = partial(_exception_from_error_queue, Error)
148
149
150class WantReadError(Error):
151 pass
152
153
154
155class WantWriteError(Error):
156 pass
157
158
159
160class WantX509LookupError(Error):
161 pass
162
163
164
165class ZeroReturnError(Error):
166 pass
167
168
169
170class SysCallError(Error):
171 pass
172
173
174
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800175class _VerifyHelper(object):
176 def __init__(self, connection, callback):
177 self._problems = []
178
179 @wraps(callback)
180 def wrapper(ok, store_ctx):
181 cert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500182 cert._x509 = _lib.X509_STORE_CTX_get_current_cert(store_ctx)
183 error_number = _lib.X509_STORE_CTX_get_error(store_ctx)
184 error_depth = _lib.X509_STORE_CTX_get_error_depth(store_ctx)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800185
186 try:
187 result = callback(connection, cert, error_number, error_depth, ok)
188 except Exception as e:
189 self._problems.append(e)
190 return 0
191 else:
192 if result:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500193 _lib.X509_STORE_CTX_set_error(store_ctx, _lib.X509_V_OK)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800194 return 1
195 else:
196 return 0
197
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500198 self.callback = _ffi.callback(
199 "int (*)(int, X509_STORE_CTX *)", wrapper)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800200
201
202 def raise_if_problem(self):
203 if self._problems:
204 try:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500205 _raise_current_error()
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800206 except Error:
207 pass
208 raise self._problems.pop(0)
209
210
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800211
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800212def _asFileDescriptor(obj):
213 fd = None
Konstantinos Koukopoulosc8b13ea2014-01-28 00:21:50 -0800214 if not isinstance(obj, integer_types):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800215 meth = getattr(obj, "fileno", None)
216 if meth is not None:
217 obj = meth()
218
Konstantinos Koukopoulosc8b13ea2014-01-28 00:21:50 -0800219 if isinstance(obj, integer_types):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800220 fd = obj
221
Konstantinos Koukopoulosc8b13ea2014-01-28 00:21:50 -0800222 if not isinstance(fd, integer_types):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800223 raise TypeError("argument must be an int, or have a fileno() method.")
224 elif fd < 0:
225 raise ValueError(
226 "file descriptor cannot be a negative integer (%i)" % (fd,))
227
228 return fd
229
230
231
Jean-Paul Calderoned39a3f62013-03-04 12:23:51 -0800232def SSLeay_version(type):
233 """
234 Return a string describing the version of OpenSSL in use.
235
236 :param type: One of the SSLEAY_ constants defined in this module.
237 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500238 return _ffi.string(_lib.SSLeay_version(type))
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800239
240
241
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800242class Session(object):
243 pass
244
245
246
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800247class Context(object):
248 """
249 :py:obj:`OpenSSL.SSL.Context` instances define the parameters for setting up
250 new SSL connections.
251 """
252 _methods = {
Andrew Dunhamec84a0a2014-02-24 12:41:37 -0800253 SSLv2_METHOD: "SSLv2_method",
Jean-Paul Calderonebe2bb422013-12-29 07:34:08 -0500254 SSLv3_METHOD: "SSLv3_method",
255 SSLv23_METHOD: "SSLv23_method",
256 TLSv1_METHOD: "TLSv1_method",
257 TLSv1_1_METHOD: "TLSv1_1_method",
258 TLSv1_2_METHOD: "TLSv1_2_method",
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800259 }
Jean-Paul Calderonebe2bb422013-12-29 07:34:08 -0500260 _methods = dict(
261 (identifier, getattr(_lib, name))
262 for (identifier, name) in _methods.items()
263 if getattr(_lib, name, None) is not None)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800264
Jean-Paul Calderone63157872013-03-20 16:43:38 -0700265
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800266 def __init__(self, method):
267 """
268 :param method: One of SSLv2_METHOD, SSLv3_METHOD, SSLv23_METHOD, or
269 TLSv1_METHOD.
270 """
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -0500271 if not isinstance(method, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800272 raise TypeError("method must be an integer")
273
274 try:
275 method_func = self._methods[method]
276 except KeyError:
277 raise ValueError("No such protocol")
278
279 method_obj = method_func()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500280 if method_obj == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500281 # TODO: This is untested.
282 _raise_current_error()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800283
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500284 context = _lib.SSL_CTX_new(method_obj)
285 if context == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500286 # TODO: This is untested.
287 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500288 context = _ffi.gc(context, _lib.SSL_CTX_free)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800289
290 self._context = context
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800291 self._passphrase_helper = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800292 self._passphrase_callback = None
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800293 self._passphrase_userdata = None
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800294 self._verify_helper = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800295 self._verify_callback = None
296 self._info_callback = None
297 self._tlsext_servername_callback = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800298 self._app_data = None
299
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -0800300 # SSL_CTX_set_app_data(self->ctx, self);
301 # SSL_CTX_set_mode(self->ctx, SSL_MODE_ENABLE_PARTIAL_WRITE |
302 # SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
303 # SSL_MODE_AUTO_RETRY);
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500304 self.set_mode(_lib.SSL_MODE_ENABLE_PARTIAL_WRITE)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800305
306
307 def load_verify_locations(self, cafile, capath=None):
308 """
309 Let SSL know where we can find trusted certificates for the certificate
310 chain
311
312 :param cafile: In which file we can find the certificates
313 :param capath: In which directory we can find the certificates
314 :return: None
315 """
316 if cafile is None:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500317 cafile = _ffi.NULL
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800318 elif not isinstance(cafile, bytes):
319 raise TypeError("cafile must be None or a byte string")
320
321 if capath is None:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500322 capath = _ffi.NULL
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800323 elif not isinstance(capath, bytes):
324 raise TypeError("capath must be None or a byte string")
325
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500326 load_result = _lib.SSL_CTX_load_verify_locations(self._context, cafile, capath)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800327 if not load_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500328 _raise_current_error()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800329
330
331 def _wrap_callback(self, callback):
332 @wraps(callback)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800333 def wrapper(size, verify, userdata):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800334 return callback(size, verify, self._passphrase_userdata)
335 return _PassphraseHelper(
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800336 FILETYPE_PEM, wrapper, more_args=True, truncate=True)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800337
338
339 def set_passwd_cb(self, callback, userdata=None):
340 """
341 Set the passphrase callback
342
343 :param callback: The Python callback to use
344 :param userdata: (optional) A Python object which will be given as
345 argument to the callback
346 :return: None
347 """
348 if not callable(callback):
349 raise TypeError("callback must be callable")
350
351 self._passphrase_helper = self._wrap_callback(callback)
352 self._passphrase_callback = self._passphrase_helper.callback
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500353 _lib.SSL_CTX_set_default_passwd_cb(
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800354 self._context, self._passphrase_callback)
355 self._passphrase_userdata = userdata
356
357
358 def set_default_verify_paths(self):
359 """
360 Use the platform-specific CA certificate locations
361
362 :return: None
363 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500364 set_result = _lib.SSL_CTX_set_default_verify_paths(self._context)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800365 if not set_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500366 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500367 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800368
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800369
370 def use_certificate_chain_file(self, certfile):
371 """
372 Load a certificate chain from a file
373
374 :param certfile: The name of the certificate chain file
375 :return: None
376 """
Jean-Paul Calderoned8607982014-01-18 10:30:55 -0500377 if isinstance(certfile, _text_type):
378 # Perhaps sys.getfilesystemencoding() could be better?
379 certfile = certfile.encode("utf-8")
380
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800381 if not isinstance(certfile, bytes):
Jean-Paul Calderoned8607982014-01-18 10:30:55 -0500382 raise TypeError("certfile must be bytes or unicode")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800383
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500384 result = _lib.SSL_CTX_use_certificate_chain_file(self._context, certfile)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800385 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500386 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800387
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800388
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800389 def use_certificate_file(self, certfile, filetype=FILETYPE_PEM):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800390 """
391 Load a certificate from a file
392
393 :param certfile: The name of the certificate file
394 :param filetype: (optional) The encoding of the file, default is PEM
395 :return: None
396 """
Jean-Paul Calderone684baf52014-01-18 10:31:19 -0500397 if isinstance(certfile, _text_type):
398 # Perhaps sys.getfilesystemencoding() could be better?
399 certfile = certfile.encode("utf-8")
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800400 if not isinstance(certfile, bytes):
Jean-Paul Calderone684baf52014-01-18 10:31:19 -0500401 raise TypeError("certfile must be bytes or unicode")
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -0500402 if not isinstance(filetype, integer_types):
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800403 raise TypeError("filetype must be an integer")
404
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500405 use_result = _lib.SSL_CTX_use_certificate_file(self._context, certfile, filetype)
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800406 if not use_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500407 _raise_current_error()
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800408
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800409
410 def use_certificate(self, cert):
411 """
412 Load a certificate from a X509 object
413
414 :param cert: The X509 object
415 :return: None
416 """
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800417 if not isinstance(cert, X509):
418 raise TypeError("cert must be an X509 instance")
419
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500420 use_result = _lib.SSL_CTX_use_certificate(self._context, cert._x509)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800421 if not use_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500422 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800423
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800424
425 def add_extra_chain_cert(self, certobj):
426 """
427 Add certificate to chain
428
429 :param certobj: The X509 certificate object to add to the chain
430 :return: None
431 """
432 if not isinstance(certobj, X509):
433 raise TypeError("certobj must be an X509 instance")
434
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500435 copy = _lib.X509_dup(certobj._x509)
436 add_result = _lib.SSL_CTX_add_extra_chain_cert(self._context, copy)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800437 if not add_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500438 # TODO: This is untested.
439 _lib.X509_free(copy)
440 _raise_current_error()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800441
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800442
443 def _raise_passphrase_exception(self):
444 if self._passphrase_helper is None:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500445 _raise_current_error()
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800446 exception = self._passphrase_helper.raise_if_problem(Error)
447 if exception is not None:
448 raise exception
449
450
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800451 def use_privatekey_file(self, keyfile, filetype=_unspecified):
452 """
453 Load a private key from a file
454
455 :param keyfile: The name of the key file
456 :param filetype: (optional) The encoding of the file, default is PEM
457 :return: None
458 """
Jean-Paul Calderone87e525a2014-01-18 10:31:51 -0500459 if isinstance(keyfile, _text_type):
460 # Perhaps sys.getfilesystemencoding() could be better?
461 keyfile = keyfile.encode("utf-8")
462
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800463 if not isinstance(keyfile, bytes):
464 raise TypeError("keyfile must be a byte string")
465
466 if filetype is _unspecified:
467 filetype = FILETYPE_PEM
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -0500468 elif not isinstance(filetype, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800469 raise TypeError("filetype must be an integer")
470
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500471 use_result = _lib.SSL_CTX_use_PrivateKey_file(
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800472 self._context, keyfile, filetype)
473 if not use_result:
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800474 self._raise_passphrase_exception()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800475
476
477 def use_privatekey(self, pkey):
478 """
479 Load a private key from a PKey object
480
481 :param pkey: The PKey object
482 :return: None
483 """
484 if not isinstance(pkey, PKey):
485 raise TypeError("pkey must be a PKey instance")
486
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500487 use_result = _lib.SSL_CTX_use_PrivateKey(self._context, pkey._pkey)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800488 if not use_result:
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800489 self._raise_passphrase_exception()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800490
491
492 def check_privatekey(self):
493 """
494 Check that the private key and certificate match up
495
496 :return: None (raises an exception if something's wrong)
497 """
498
499 def load_client_ca(self, cafile):
500 """
501 Load the trusted certificates that will be sent to the client (basically
502 telling the client "These are the guys I trust"). Does not actually
503 imply any of the certificates are trusted; that must be configured
504 separately.
505
506 :param cafile: The name of the certificates file
507 :return: None
508 """
509
510 def set_session_id(self, buf):
511 """
512 Set the session identifier. This is needed if you want to do session
513 resumption.
514
515 :param buf: A Python object that can be safely converted to a string
516 :returns: None
517 """
518
519 def set_session_cache_mode(self, mode):
520 """
521 Enable/disable session caching and specify the mode used.
522
523 :param mode: One or more of the SESS_CACHE_* flags (combine using
524 bitwise or)
525 :returns: The previously set caching mode.
526 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500527 if not isinstance(mode, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800528 raise TypeError("mode must be an integer")
529
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500530 return _lib.SSL_CTX_set_session_cache_mode(self._context, mode)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800531
532
533 def get_session_cache_mode(self):
534 """
535 :returns: The currently used cache mode.
536 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500537 return _lib.SSL_CTX_get_session_cache_mode(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800538
539
540 def set_verify(self, mode, callback):
541 """
542 Set the verify mode and verify callback
543
544 :param mode: The verify mode, this is either VERIFY_NONE or
545 VERIFY_PEER combined with possible other flags
546 :param callback: The Python callback to use
547 :return: None
548
549 See SSL_CTX_set_verify(3SSL) for further details.
550 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500551 if not isinstance(mode, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800552 raise TypeError("mode must be an integer")
553
554 if not callable(callback):
555 raise TypeError("callback must be callable")
556
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800557 self._verify_helper = _VerifyHelper(self, callback)
558 self._verify_callback = self._verify_helper.callback
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500559 _lib.SSL_CTX_set_verify(self._context, mode, self._verify_callback)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800560
561
562 def set_verify_depth(self, depth):
563 """
564 Set the verify depth
565
566 :param depth: An integer specifying the verify depth
567 :return: None
568 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500569 if not isinstance(depth, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800570 raise TypeError("depth must be an integer")
571
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500572 _lib.SSL_CTX_set_verify_depth(self._context, depth)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800573
574
575 def get_verify_mode(self):
576 """
577 Get the verify mode
578
579 :return: The verify mode
580 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500581 return _lib.SSL_CTX_get_verify_mode(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800582
583
584 def get_verify_depth(self):
585 """
586 Get the verify depth
587
588 :return: The verify depth
589 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500590 return _lib.SSL_CTX_get_verify_depth(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800591
592
593 def load_tmp_dh(self, dhfile):
594 """
595 Load parameters for Ephemeral Diffie-Hellman
596
597 :param dhfile: The file to load EDH parameters from
598 :return: None
599 """
600 if not isinstance(dhfile, bytes):
601 raise TypeError("dhfile must be a byte string")
602
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -0500603 bio = _lib.BIO_new_file(dhfile, b"r")
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500604 if bio == _ffi.NULL:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500605 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500606 bio = _ffi.gc(bio, _lib.BIO_free)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800607
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500608 dh = _lib.PEM_read_bio_DHparams(bio, _ffi.NULL, _ffi.NULL, _ffi.NULL)
609 dh = _ffi.gc(dh, _lib.DH_free)
610 _lib.SSL_CTX_set_tmp_dh(self._context, dh)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800611
612
Andy Lutomirskif05a2732014-03-13 17:22:25 -0700613 def set_tmp_ecdh_curve(self, curve_name):
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600614 """
Andy Lutomirski76a61332014-03-12 15:02:56 -0700615 Select a curve to use for ECDHE key exchange.
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600616
Andy Lutomirskif05a2732014-03-13 17:22:25 -0700617 The valid values of *curve_name* are the keys in
618 :py:data:OpenSSL.SSL.ELLIPTIC_CURVE_DESCRIPTIONS.
619
620 Raises a ``ValueError`` if the linked OpenSSL was not compiled with
621 elliptical curve support, or the specified curve is not available.
622
623 :param curve_name: The 'short name' of a curve, e.g. 'prime256v1'
624 :type curve_name: str
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600625 :return: None
626 """
627 if _lib.Cryptography_HAS_EC:
Andy Lutomirskif05a2732014-03-13 17:22:25 -0700628 nid = _lib.OBJ_sn2nid(curve_name)
629 if nid == _lib.NID_undef:
630 raise ValueError("No such OpenSSL object '%s'" % curve_name)
631 ecdh = _lib.EC_KEY_new_by_curve_name(nid)
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600632 if ecdh == _ffi.NULL:
633 raise ValueError(
634 "OpenSSL could not load the requested elliptic curve"
635 )
636 _lib.SSL_CTX_set_tmp_ecdh(self._context, ecdh)
637 _lib.EC_KEY_free(ecdh)
638 else:
639 raise ValueError("OpenSSL is compiled without ECDH support")
640
641
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800642 def set_cipher_list(self, cipher_list):
643 """
644 Change the cipher list
645
646 :param cipher_list: A cipher list, see ciphers(1)
647 :return: None
648 """
Jean-Paul Calderone63eab692014-01-18 10:19:56 -0500649 if isinstance(cipher_list, _text_type):
650 cipher_list = cipher_list.encode("ascii")
651
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800652 if not isinstance(cipher_list, bytes):
Jean-Paul Calderone63eab692014-01-18 10:19:56 -0500653 raise TypeError("cipher_list must be bytes or unicode")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800654
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500655 result = _lib.SSL_CTX_set_cipher_list(self._context, cipher_list)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800656 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500657 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800658
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800659
660 def set_client_ca_list(self, certificate_authorities):
661 """
662 Set the list of preferred client certificate signers for this server context.
663
664 This list of certificate authorities will be sent to the client when the
665 server requests a client certificate.
666
667 :param certificate_authorities: a sequence of X509Names.
668 :return: None
669 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500670 name_stack = _lib.sk_X509_NAME_new_null()
671 if name_stack == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500672 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500673 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800674
675 try:
676 for ca_name in certificate_authorities:
677 if not isinstance(ca_name, X509Name):
678 raise TypeError(
679 "client CAs must be X509Name objects, not %s objects" % (
680 type(ca_name).__name__,))
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500681 copy = _lib.X509_NAME_dup(ca_name._name)
682 if copy == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500683 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500684 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500685 push_result = _lib.sk_X509_NAME_push(name_stack, copy)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800686 if not push_result:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500687 _lib.X509_NAME_free(copy)
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500688 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800689 except:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500690 _lib.sk_X509_NAME_free(name_stack)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800691 raise
692
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500693 _lib.SSL_CTX_set_client_CA_list(self._context, name_stack)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800694
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800695
696 def add_client_ca(self, certificate_authority):
697 """
698 Add the CA certificate to the list of preferred signers for this context.
699
700 The list of certificate authorities will be sent to the client when the
701 server requests a client certificate.
702
703 :param certificate_authority: certificate authority's X509 certificate.
704 :return: None
705 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800706 if not isinstance(certificate_authority, X509):
707 raise TypeError("certificate_authority must be an X509 instance")
708
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500709 add_result = _lib.SSL_CTX_add_client_CA(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800710 self._context, certificate_authority._x509)
711 if not add_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500712 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500713 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800714
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800715
716 def set_timeout(self, timeout):
717 """
718 Set session timeout
719
720 :param timeout: The timeout in seconds
721 :return: The previous session timeout
722 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500723 if not isinstance(timeout, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800724 raise TypeError("timeout must be an integer")
725
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500726 return _lib.SSL_CTX_set_timeout(self._context, timeout)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800727
728
729 def get_timeout(self):
730 """
731 Get the session timeout
732
733 :return: The session timeout
734 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500735 return _lib.SSL_CTX_get_timeout(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800736
737
738 def set_info_callback(self, callback):
739 """
740 Set the info callback
741
742 :param callback: The Python callback to use
743 :return: None
744 """
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800745 @wraps(callback)
746 def wrapper(ssl, where, return_code):
Jean-Paul Calderonef2bbc9c2014-02-02 10:59:14 -0500747 callback(Connection._reverse_mapping[ssl], where, return_code)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500748 self._info_callback = _ffi.callback(
749 "void (*)(const SSL *, int, int)", wrapper)
750 _lib.SSL_CTX_set_info_callback(self._context, self._info_callback)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800751
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800752
753 def get_app_data(self):
754 """
755 Get the application data (supplied via set_app_data())
756
757 :return: The application data
758 """
759 return self._app_data
760
761
762 def set_app_data(self, data):
763 """
764 Set the application data (will be returned from get_app_data())
765
766 :param data: Any Python object
767 :return: None
768 """
769 self._app_data = data
770
771
772 def get_cert_store(self):
773 """
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500774 Get the certificate store for the context.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800775
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500776 :return: A X509Store object or None if it does not have one.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800777 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500778 store = _lib.SSL_CTX_get_cert_store(self._context)
779 if store == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500780 # TODO: This is untested.
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800781 return None
782
783 pystore = X509Store.__new__(X509Store)
784 pystore._store = store
785 return pystore
786
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800787
788 def set_options(self, options):
789 """
790 Add options. Options set before are not cleared!
791
792 :param options: The options to add.
793 :return: The new option bitmask.
794 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500795 if not isinstance(options, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800796 raise TypeError("options must be an integer")
797
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500798 return _lib.SSL_CTX_set_options(self._context, options)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800799
800
801 def set_mode(self, mode):
802 """
803 Add modes via bitmask. Modes set before are not cleared!
804
805 :param mode: The mode to add.
806 :return: The new mode bitmask.
807 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500808 if not isinstance(mode, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800809 raise TypeError("mode must be an integer")
810
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500811 return _lib.SSL_CTX_set_mode(self._context, mode)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800812
813
814 def set_tlsext_servername_callback(self, callback):
815 """
816 Specify a callback function to be called when clients specify a server name.
817
818 :param callback: The callback function. It will be invoked with one
819 argument, the Connection instance.
820 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800821 @wraps(callback)
822 def wrapper(ssl, alert, arg):
823 callback(Connection._reverse_mapping[ssl])
824 return 0
825
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500826 self._tlsext_servername_callback = _ffi.callback(
827 "int (*)(const SSL *, int *, void *)", wrapper)
828 _lib.SSL_CTX_set_tlsext_servername_callback(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800829 self._context, self._tlsext_servername_callback)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800830
831ContextType = Context
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800832
833
834
835class Connection(object):
836 """
837 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800838 _reverse_mapping = WeakValueDictionary()
839
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800840 def __init__(self, context, socket=None):
841 """
842 Create a new Connection object, using the given OpenSSL.SSL.Context
843 instance and socket.
844
845 :param context: An SSL Context to use for this connection
846 :param socket: The socket to use for transport layer
847 """
848 if not isinstance(context, Context):
849 raise TypeError("context must be a Context instance")
850
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500851 ssl = _lib.SSL_new(context._context)
852 self._ssl = _ffi.gc(ssl, _lib.SSL_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800853 self._context = context
854
855 self._reverse_mapping[self._ssl] = self
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800856
857 if socket is None:
858 self._socket = None
Jean-Paul Calderone73b15c22013-03-05 18:30:39 -0800859 # Don't set up any gc for these, SSL_free will take care of them.
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500860 self._into_ssl = _lib.BIO_new(_lib.BIO_s_mem())
861 self._from_ssl = _lib.BIO_new(_lib.BIO_s_mem())
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800862
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500863 if self._into_ssl == _ffi.NULL or self._from_ssl == _ffi.NULL:
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
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500867 _lib.SSL_set_bio(self._ssl, self._into_ssl, self._from_ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800868 else:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800869 self._into_ssl = None
870 self._from_ssl = None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800871 self._socket = socket
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500872 set_result = _lib.SSL_set_fd(self._ssl, _asFileDescriptor(self._socket))
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800873 if not set_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500874 # TODO: This is untested.
875 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800876
877
878 def __getattr__(self, name):
879 """
880 Look up attributes on the wrapped socket object if they are not found on
881 the Connection object.
882 """
883 return getattr(self._socket, name)
884
885
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800886 def _raise_ssl_error(self, ssl, result):
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800887 if self._context._verify_helper is not None:
888 self._context._verify_helper.raise_if_problem()
889
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500890 error = _lib.SSL_get_error(ssl, result)
891 if error == _lib.SSL_ERROR_WANT_READ:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800892 raise WantReadError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500893 elif error == _lib.SSL_ERROR_WANT_WRITE:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -0700894 raise WantWriteError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500895 elif error == _lib.SSL_ERROR_ZERO_RETURN:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800896 raise ZeroReturnError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500897 elif error == _lib.SSL_ERROR_WANT_X509_LOOKUP:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500898 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -0700899 raise WantX509LookupError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500900 elif error == _lib.SSL_ERROR_SYSCALL:
901 if _lib.ERR_peek_error() == 0:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800902 if result < 0:
Konstantinos Koukopoulos541150d2014-01-31 01:00:19 +0200903 if platform == "win32":
904 errno = _ffi.getwinerror()[0]
905 else:
906 errno = _ffi.errno
907 raise SysCallError(errno, errorcode[errno])
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800908 else:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -0700909 raise SysCallError(-1, "Unexpected EOF")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800910 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500911 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500912 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500913 elif error == _lib.SSL_ERROR_NONE:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -0700914 pass
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800915 else:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500916 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800917
918
919 def get_context(self):
920 """
921 Get session context
922 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800923 return self._context
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800924
925
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800926 def set_context(self, context):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800927 """
928 Switch this connection to a new session context
929
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800930 :param context: A :py:class:`Context` instance giving the new session
931 context to use.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800932 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800933 if not isinstance(context, Context):
934 raise TypeError("context must be a Context instance")
935
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500936 _lib.SSL_set_SSL_CTX(self._ssl, context._context)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800937 self._context = context
938
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800939
940 def get_servername(self):
941 """
942 Retrieve the servername extension value if provided in the client hello
943 message, or None if there wasn't one.
944
945 :return: A byte string giving the server name or :py:data:`None`.
946 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500947 name = _lib.SSL_get_servername(self._ssl, _lib.TLSEXT_NAMETYPE_host_name)
948 if name == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800949 return None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800950
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500951 return _ffi.string(name)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800952
953
954 def set_tlsext_host_name(self, name):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800955 """
956 Set the value of the servername extension to send in the client hello.
957
958 :param name: A byte string giving the name.
959 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800960 if not isinstance(name, bytes):
961 raise TypeError("name must be a byte string")
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -0500962 elif b"\0" in name:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800963 raise TypeError("name must not contain NUL byte")
964
965 # XXX I guess this can fail sometimes?
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500966 _lib.SSL_set_tlsext_host_name(self._ssl, name)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800967
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800968
969 def pending(self):
970 """
971 Get the number of bytes that can be safely read from the connection
972
973 :return: The number of bytes available in the receive buffer.
974 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500975 return _lib.SSL_pending(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800976
977
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800978 def send(self, buf, flags=0):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800979 """
980 Send data on the connection. NOTE: If you get one of the WantRead,
981 WantWrite or WantX509Lookup exceptions on this, you have to call the
982 method again with the SAME buffer.
983
984 :param buf: The string to send
985 :param flags: (optional) Included for compatibility with the socket
986 API, the value is ignored
987 :return: The number of bytes written
988 """
Jean-Paul Calderone8fb53182013-12-30 08:35:49 -0500989 if isinstance(buf, _memoryview):
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -0800990 buf = buf.tobytes()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800991 if not isinstance(buf, bytes):
992 raise TypeError("data must be a byte string")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800993
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500994 result = _lib.SSL_write(self._ssl, buf, len(buf))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800995 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800996 return result
997 write = send
998
999
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001000 def sendall(self, buf, flags=0):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001001 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001002 Send "all" data on the connection. This calls send() repeatedly until
1003 all data is sent. If an error occurs, it's impossible to tell how much
1004 data has been sent.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001005
1006 :param buf: The string to send
1007 :param flags: (optional) Included for compatibility with the socket
1008 API, the value is ignored
1009 :return: The number of bytes written
1010 """
Jean-Paul Calderone8fb53182013-12-30 08:35:49 -05001011 if isinstance(buf, _memoryview):
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -08001012 buf = buf.tobytes()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001013 if not isinstance(buf, bytes):
1014 raise TypeError("buf must be a byte string")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001015
1016 left_to_send = len(buf)
1017 total_sent = 0
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001018 data = _ffi.new("char[]", buf)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001019
1020 while left_to_send:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001021 result = _lib.SSL_write(self._ssl, data + total_sent, left_to_send)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001022 self._raise_ssl_error(self._ssl, result)
1023 total_sent += result
1024 left_to_send -= result
1025
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001026
1027 def recv(self, bufsiz, flags=None):
1028 """
1029 Receive data on the connection. NOTE: If you get one of the WantRead,
1030 WantWrite or WantX509Lookup exceptions on this, you have to call the
1031 method again with the SAME buffer.
1032
1033 :param bufsiz: The maximum number of bytes to read
1034 :param flags: (optional) Included for compatibility with the socket
1035 API, the value is ignored
1036 :return: The string read from the Connection
1037 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001038 buf = _ffi.new("char[]", bufsiz)
1039 result = _lib.SSL_read(self._ssl, buf, bufsiz)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001040 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001041 return _ffi.buffer(buf, result)[:]
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001042 read = recv
1043
1044
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001045 def _handle_bio_errors(self, bio, result):
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001046 if _lib.BIO_should_retry(bio):
1047 if _lib.BIO_should_read(bio):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001048 raise WantReadError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001049 elif _lib.BIO_should_write(bio):
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001050 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001051 raise WantWriteError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001052 elif _lib.BIO_should_io_special(bio):
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001053 # TODO: This is untested. I think io_special means the socket
1054 # BIO has a not-yet connected socket.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001055 raise ValueError("BIO_should_io_special")
1056 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001057 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001058 raise ValueError("unknown bio failure")
1059 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001060 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001061 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001062
1063
1064 def bio_read(self, bufsiz):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001065 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001066 When using non-socket connections this function reads the "dirty" data
1067 that would have traveled away on the network.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001068
1069 :param bufsiz: The maximum number of bytes to read
1070 :return: The string read.
1071 """
Jean-Paul Calderone97e041d2013-03-05 21:03:12 -08001072 if self._from_ssl is None:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001073 raise TypeError("Connection sock was not None")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001074
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -05001075 if not isinstance(bufsiz, integer_types):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001076 raise TypeError("bufsiz must be an integer")
1077
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001078 buf = _ffi.new("char[]", bufsiz)
1079 result = _lib.BIO_read(self._from_ssl, buf, bufsiz)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001080 if result <= 0:
1081 self._handle_bio_errors(self._from_ssl, result)
1082
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001083 return _ffi.buffer(buf, result)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001084
1085
1086 def bio_write(self, buf):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001087 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001088 When using non-socket connections this function sends "dirty" data that
1089 would have traveled in on the network.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001090
1091 :param buf: The string to put into the memory BIO.
1092 :return: The number of bytes written
1093 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001094 if self._into_ssl is None:
1095 raise TypeError("Connection sock was not None")
1096
1097 if not isinstance(buf, bytes):
1098 raise TypeError("buf must be a byte string")
1099
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001100 result = _lib.BIO_write(self._into_ssl, buf, len(buf))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001101 if result <= 0:
1102 self._handle_bio_errors(self._into_ssl, result)
1103 return result
1104
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001105
1106 def renegotiate(self):
1107 """
1108 Renegotiate the session
1109
1110 :return: True if the renegotiation can be started, false otherwise
1111 """
1112
1113 def do_handshake(self):
1114 """
1115 Perform an SSL handshake (usually called after renegotiate() or one of
1116 set_*_state()). This can raise the same exceptions as send and recv.
1117
1118 :return: None.
1119 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001120 result = _lib.SSL_do_handshake(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001121 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001122
1123
1124 def renegotiate_pending(self):
1125 """
1126 Check if there's a renegotiation in progress, it will return false once
1127 a renegotiation is finished.
1128
1129 :return: Whether there's a renegotiation in progress
1130 """
1131
1132 def total_renegotiations(self):
1133 """
1134 Find out the total number of renegotiations.
1135
1136 :return: The number of renegotiations.
1137 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001138 return _lib.SSL_total_renegotiations(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001139
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001140
1141 def connect(self, addr):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001142 """
1143 Connect to remote host and set up client-side SSL
1144
1145 :param addr: A remote address
1146 :return: What the socket's connect method returns
1147 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001148 _lib.SSL_set_connect_state(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001149 return self._socket.connect(addr)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001150
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001151
1152 def connect_ex(self, addr):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001153 """
1154 Connect to remote host and set up client-side SSL. Note that if the socket's
1155 connect_ex method doesn't return 0, SSL won't be initialized.
1156
1157 :param addr: A remove address
1158 :return: What the socket's connect_ex method returns
1159 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001160 connect_ex = self._socket.connect_ex
1161 self.set_connect_state()
1162 return connect_ex(addr)
1163
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001164
1165 def accept(self):
1166 """
1167 Accept incoming connection and set up SSL on it
1168
1169 :return: A (conn,addr) pair where conn is a Connection and addr is an
1170 address
1171 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001172 client, addr = self._socket.accept()
1173 conn = Connection(self._context, client)
1174 conn.set_accept_state()
1175 return (conn, addr)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001176
1177
1178 def bio_shutdown(self):
1179 """
1180 When using non-socket connections this function signals end of
1181 data on the input for this connection.
1182
1183 :return: None
1184 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001185 if self._from_ssl is None:
1186 raise TypeError("Connection sock was not None")
1187
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001188 _lib.BIO_set_mem_eof_return(self._into_ssl, 0)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001189
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001190
1191 def shutdown(self):
1192 """
1193 Send closure alert
1194
1195 :return: True if the shutdown completed successfully (i.e. both sides
1196 have sent closure alerts), false otherwise (i.e. you have to
1197 wait for a ZeroReturnError on a recv() method call
1198 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001199 result = _lib.SSL_shutdown(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001200 if result < 0:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001201 # TODO: This is untested.
1202 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001203 elif result > 0:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001204 return True
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001205 else:
1206 return False
1207
1208
1209 def get_cipher_list(self):
1210 """
1211 Get the session cipher list
1212
1213 :return: A list of cipher strings
1214 """
1215 ciphers = []
1216 for i in count():
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001217 result = _lib.SSL_get_cipher_list(self._ssl, i)
1218 if result == _ffi.NULL:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001219 break
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001220 ciphers.append(_native(_ffi.string(result)))
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001221 return ciphers
1222
1223
1224 def get_client_ca_list(self):
1225 """
1226 Get CAs whose certificates are suggested for client authentication.
1227
1228 :return: If this is a server connection, a list of X509Names representing
1229 the acceptable CAs as set by :py:meth:`OpenSSL.SSL.Context.set_client_ca_list` or
1230 :py:meth:`OpenSSL.SSL.Context.add_client_ca`. If this is a client connection,
1231 the list of such X509Names sent by the server, or an empty list if that
1232 has not yet happened.
1233 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001234 ca_names = _lib.SSL_get_client_CA_list(self._ssl)
1235 if ca_names == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001236 # TODO: This is untested.
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001237 return []
1238
1239 result = []
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001240 for i in range(_lib.sk_X509_NAME_num(ca_names)):
1241 name = _lib.sk_X509_NAME_value(ca_names, i)
1242 copy = _lib.X509_NAME_dup(name)
1243 if copy == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001244 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001245 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001246
1247 pyname = X509Name.__new__(X509Name)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001248 pyname._name = _ffi.gc(copy, _lib.X509_NAME_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001249 result.append(pyname)
1250 return result
1251
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001252
1253 def makefile(self):
1254 """
1255 The makefile() method is not implemented, since there is no dup semantics
1256 for SSL connections
1257
1258 :raise NotImplementedError
1259 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001260 raise NotImplementedError("Cannot make file object of OpenSSL.SSL.Connection")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001261
1262
1263 def get_app_data(self):
1264 """
1265 Get application data
1266
1267 :return: The application data
1268 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001269 return self._app_data
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001270
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001271
1272 def set_app_data(self, data):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001273 """
1274 Set application data
1275
1276 :param data - The application data
1277 :return: None
1278 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001279 self._app_data = data
1280
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001281
1282 def get_shutdown(self):
1283 """
1284 Get shutdown state
1285
1286 :return: The shutdown state, a bitvector of SENT_SHUTDOWN, RECEIVED_SHUTDOWN.
1287 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001288 return _lib.SSL_get_shutdown(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001289
1290
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001291 def set_shutdown(self, state):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001292 """
1293 Set shutdown state
1294
1295 :param state - bitvector of SENT_SHUTDOWN, RECEIVED_SHUTDOWN.
1296 :return: None
1297 """
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -05001298 if not isinstance(state, integer_types):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001299 raise TypeError("state must be an integer")
1300
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001301 _lib.SSL_set_shutdown(self._ssl, state)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001302
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001303
1304 def state_string(self):
1305 """
1306 Get a verbose state description
1307
1308 :return: A string representing the state
1309 """
1310
1311 def server_random(self):
1312 """
1313 Get a copy of the server hello nonce.
1314
1315 :return: A string representing the state
1316 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001317 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001318 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001319 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001320 self._ssl.s3.server_random,
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001321 _lib.SSL3_RANDOM_SIZE)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001322
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001323
1324 def client_random(self):
1325 """
1326 Get a copy of the client hello nonce.
1327
1328 :return: A string representing the state
1329 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001330 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001331 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001332 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001333 self._ssl.s3.client_random,
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001334 _lib.SSL3_RANDOM_SIZE)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001335
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001336
1337 def master_key(self):
1338 """
1339 Get a copy of the master key.
1340
1341 :return: A string representing the state
1342 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001343 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001344 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001345 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001346 self._ssl.session.master_key,
1347 self._ssl.session.master_key_length)[:]
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001348
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001349
1350 def sock_shutdown(self, *args, **kwargs):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001351 """
1352 See shutdown(2)
1353
1354 :return: What the socket's shutdown() method returns
1355 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001356 return self._socket.shutdown(*args, **kwargs)
1357
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001358
1359 def get_peer_certificate(self):
1360 """
1361 Retrieve the other side's certificate (if any)
1362
1363 :return: The peer's certificate
1364 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001365 cert = _lib.SSL_get_peer_certificate(self._ssl)
1366 if cert != _ffi.NULL:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001367 pycert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001368 pycert._x509 = _ffi.gc(cert, _lib.X509_free)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001369 return pycert
1370 return None
1371
1372
1373 def get_peer_cert_chain(self):
1374 """
1375 Retrieve the other side's certificate (if any)
1376
1377 :return: A list of X509 instances giving the peer's certificate chain,
1378 or None if it does not have one.
1379 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001380 cert_stack = _lib.SSL_get_peer_cert_chain(self._ssl)
1381 if cert_stack == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001382 return None
1383
1384 result = []
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001385 for i in range(_lib.sk_X509_num(cert_stack)):
Jean-Paul Calderone73b15c22013-03-05 18:30:39 -08001386 # TODO could incref instead of dup here
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001387 cert = _lib.X509_dup(_lib.sk_X509_value(cert_stack, i))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001388 pycert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001389 pycert._x509 = _ffi.gc(cert, _lib.X509_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001390 result.append(pycert)
1391 return result
1392
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001393
1394 def want_read(self):
1395 """
1396 Checks if more data has to be read from the transport layer to complete an
1397 operation.
1398
1399 :return: True iff more data has to be read
1400 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001401 return _lib.SSL_want_read(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001402
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001403
1404 def want_write(self):
1405 """
1406 Checks if there is data to write to the transport layer to complete an
1407 operation.
1408
1409 :return: True iff there is data to write
1410 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001411 return _lib.SSL_want_write(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001412
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001413
1414 def set_accept_state(self):
1415 """
1416 Set the connection to work in server mode. The handshake will be handled
1417 automatically by read/write.
1418
1419 :return: None
1420 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001421 _lib.SSL_set_accept_state(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001422
1423
1424 def set_connect_state(self):
1425 """
1426 Set the connection to work in client mode. The handshake will be handled
1427 automatically by read/write.
1428
1429 :return: None
1430 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001431 _lib.SSL_set_connect_state(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001432
1433
1434 def get_session(self):
1435 """
1436 Returns the Session currently used.
1437
1438 @return: An instance of :py:class:`OpenSSL.SSL.Session` or :py:obj:`None` if
1439 no session exists.
1440 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001441 session = _lib.SSL_get1_session(self._ssl)
1442 if session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001443 return None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001444
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001445 pysession = Session.__new__(Session)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001446 pysession._session = _ffi.gc(session, _lib.SSL_SESSION_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001447 return pysession
1448
1449
1450 def set_session(self, session):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001451 """
1452 Set the session to be used when the TLS/SSL connection is established.
1453
1454 :param session: A Session instance representing the session to use.
1455 :returns: None
1456 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001457 if not isinstance(session, Session):
1458 raise TypeError("session must be a Session instance")
1459
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001460 result = _lib.SSL_set_session(self._ssl, session._session)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001461 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001462 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001463
1464ConnectionType = Connection
Jean-Paul Calderone11ed8e82014-01-18 10:21:50 -05001465
Jean-Paul Calderonefab157b2014-01-18 11:21:38 -05001466# This is similar to the initialization calls at the end of OpenSSL/crypto.py
1467# but is exercised mostly by the Context initializer.
Jean-Paul Calderone11ed8e82014-01-18 10:21:50 -05001468_lib.SSL_library_init()