blob: d960eb36e7aaaaf3c0e30b8e37774786f9b41694 [file] [log] [blame]
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -08001
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 Calderonec86bb7d2013-12-29 10:25:59 -05007from OpenSSL._util import (
8 ffi as _ffi,
9 lib as _lib,
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -050010 exception_from_error_queue as _exception_from_error_queue,
11 native as _native)
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080012
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -080013from OpenSSL.crypto import (
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -050014 FILETYPE_PEM, _PassphraseHelper, PKey, X509Name, X509, X509Store)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -080015
16_unspecified = object()
17
Jean-Paul Calderone8fb53182013-12-30 08:35:49 -050018try:
19 _memoryview = memoryview
20except NameError:
21 class _memoryview(object):
22 pass
23
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050024OPENSSL_VERSION_NUMBER = _lib.OPENSSL_VERSION_NUMBER
25SSLEAY_VERSION = _lib.SSLEAY_VERSION
26SSLEAY_CFLAGS = _lib.SSLEAY_CFLAGS
27SSLEAY_PLATFORM = _lib.SSLEAY_PLATFORM
28SSLEAY_DIR = _lib.SSLEAY_DIR
29SSLEAY_BUILT_ON = _lib.SSLEAY_BUILT_ON
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080030
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050031SENT_SHUTDOWN = _lib.SSL_SENT_SHUTDOWN
32RECEIVED_SHUTDOWN = _lib.SSL_RECEIVED_SHUTDOWN
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080033
34SSLv2_METHOD = 1
35SSLv3_METHOD = 2
36SSLv23_METHOD = 3
37TLSv1_METHOD = 4
Jean-Paul Calderone56bff942013-11-03 11:30:43 -050038TLSv1_1_METHOD = 5
39TLSv1_2_METHOD = 6
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080040
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050041OP_NO_SSLv2 = _lib.SSL_OP_NO_SSLv2
42OP_NO_SSLv3 = _lib.SSL_OP_NO_SSLv3
43OP_NO_TLSv1 = _lib.SSL_OP_NO_TLSv1
Jean-Paul Calderonebe2bb422013-12-29 07:34:08 -050044
45OP_NO_TLSv1_1 = getattr(_lib, "SSL_OP_NO_TLSv1_1", 0)
46OP_NO_TLSv1_2 = getattr(_lib, "SSL_OP_NO_TLSv1_2", 0)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -080047
Jean-Paul Calderone0d7e8a12014-01-08 16:54:13 -050048try:
49 MODE_RELEASE_BUFFERS = _lib.SSL_MODE_RELEASE_BUFFERS
50except AttributeError:
51 pass
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080052
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050053OP_SINGLE_DH_USE = _lib.SSL_OP_SINGLE_DH_USE
54OP_EPHEMERAL_RSA = _lib.SSL_OP_EPHEMERAL_RSA
55OP_MICROSOFT_SESS_ID_BUG = _lib.SSL_OP_MICROSOFT_SESS_ID_BUG
56OP_NETSCAPE_CHALLENGE_BUG = _lib.SSL_OP_NETSCAPE_CHALLENGE_BUG
57OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG = _lib.SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG
58OP_SSLREF2_REUSE_CERT_TYPE_BUG = _lib.SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG
59OP_MICROSOFT_BIG_SSLV3_BUFFER = _lib.SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER
Jean-Paul Calderone0d7e8a12014-01-08 16:54:13 -050060try:
61 OP_MSIE_SSLV2_RSA_PADDING = _lib.SSL_OP_MSIE_SSLV2_RSA_PADDING
62except AttributeError:
63 pass
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050064OP_SSLEAY_080_CLIENT_DH_BUG = _lib.SSL_OP_SSLEAY_080_CLIENT_DH_BUG
65OP_TLS_D5_BUG = _lib.SSL_OP_TLS_D5_BUG
66OP_TLS_BLOCK_PADDING_BUG = _lib.SSL_OP_TLS_BLOCK_PADDING_BUG
67OP_DONT_INSERT_EMPTY_FRAGMENTS = _lib.SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
68OP_CIPHER_SERVER_PREFERENCE = _lib.SSL_OP_CIPHER_SERVER_PREFERENCE
69OP_TLS_ROLLBACK_BUG = _lib.SSL_OP_TLS_ROLLBACK_BUG
70OP_PKCS1_CHECK_1 = _lib.SSL_OP_PKCS1_CHECK_1
71OP_PKCS1_CHECK_2 = _lib.SSL_OP_PKCS1_CHECK_2
72OP_NETSCAPE_CA_DN_BUG = _lib.SSL_OP_NETSCAPE_CA_DN_BUG
73OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG= _lib.SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG
Jean-Paul Calderonec1780342014-01-08 16:59:03 -050074try:
75 OP_NO_COMPRESSION = _lib.SSL_OP_NO_COMPRESSION
76except AttributeError:
77 pass
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -080078
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050079OP_NO_QUERY_MTU = _lib.SSL_OP_NO_QUERY_MTU
80OP_COOKIE_EXCHANGE = _lib.SSL_OP_COOKIE_EXCHANGE
81OP_NO_TICKET = _lib.SSL_OP_NO_TICKET
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -080082
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050083OP_ALL = _lib.SSL_OP_ALL
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080084
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050085VERIFY_PEER = _lib.SSL_VERIFY_PEER
86VERIFY_FAIL_IF_NO_PEER_CERT = _lib.SSL_VERIFY_FAIL_IF_NO_PEER_CERT
87VERIFY_CLIENT_ONCE = _lib.SSL_VERIFY_CLIENT_ONCE
88VERIFY_NONE = _lib.SSL_VERIFY_NONE
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080089
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050090SESS_CACHE_OFF = _lib.SSL_SESS_CACHE_OFF
91SESS_CACHE_CLIENT = _lib.SSL_SESS_CACHE_CLIENT
92SESS_CACHE_SERVER = _lib.SSL_SESS_CACHE_SERVER
93SESS_CACHE_BOTH = _lib.SSL_SESS_CACHE_BOTH
94SESS_CACHE_NO_AUTO_CLEAR = _lib.SSL_SESS_CACHE_NO_AUTO_CLEAR
95SESS_CACHE_NO_INTERNAL_LOOKUP = _lib.SSL_SESS_CACHE_NO_INTERNAL_LOOKUP
96SESS_CACHE_NO_INTERNAL_STORE = _lib.SSL_SESS_CACHE_NO_INTERNAL_STORE
97SESS_CACHE_NO_INTERNAL = _lib.SSL_SESS_CACHE_NO_INTERNAL
Jean-Paul Calderoned39a3f62013-03-04 12:23:51 -080098
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050099SSL_ST_CONNECT = _lib.SSL_ST_CONNECT
100SSL_ST_ACCEPT = _lib.SSL_ST_ACCEPT
101SSL_ST_MASK = _lib.SSL_ST_MASK
102SSL_ST_INIT = _lib.SSL_ST_INIT
103SSL_ST_BEFORE = _lib.SSL_ST_BEFORE
104SSL_ST_OK = _lib.SSL_ST_OK
105SSL_ST_RENEGOTIATE = _lib.SSL_ST_RENEGOTIATE
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800106
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500107SSL_CB_LOOP = _lib.SSL_CB_LOOP
108SSL_CB_EXIT = _lib.SSL_CB_EXIT
109SSL_CB_READ = _lib.SSL_CB_READ
110SSL_CB_WRITE = _lib.SSL_CB_WRITE
111SSL_CB_ALERT = _lib.SSL_CB_ALERT
112SSL_CB_READ_ALERT = _lib.SSL_CB_READ_ALERT
113SSL_CB_WRITE_ALERT = _lib.SSL_CB_WRITE_ALERT
114SSL_CB_ACCEPT_LOOP = _lib.SSL_CB_ACCEPT_LOOP
115SSL_CB_ACCEPT_EXIT = _lib.SSL_CB_ACCEPT_EXIT
116SSL_CB_CONNECT_LOOP = _lib.SSL_CB_CONNECT_LOOP
117SSL_CB_CONNECT_EXIT = _lib.SSL_CB_CONNECT_EXIT
118SSL_CB_HANDSHAKE_START = _lib.SSL_CB_HANDSHAKE_START
119SSL_CB_HANDSHAKE_DONE = _lib.SSL_CB_HANDSHAKE_DONE
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800120
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800121
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600122NID_X9_62_prime192v1 = _lib.NID_X9_62_prime192v1
123NID_X9_62_prime192v2 = _lib.NID_X9_62_prime192v2
124NID_X9_62_prime192v3 = _lib.NID_X9_62_prime192v3
125NID_X9_62_prime239v1 = _lib.NID_X9_62_prime239v1
126NID_X9_62_prime239v2 = _lib.NID_X9_62_prime239v2
127NID_X9_62_prime239v3 = _lib.NID_X9_62_prime239v3
128NID_X9_62_prime256v1 = _lib.NID_X9_62_prime256v1
129
130
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500131class Error(Exception):
Jean-Paul Calderone511cde02013-12-29 10:31:13 -0500132 """
133 An error occurred in an `OpenSSL.SSL` API.
134 """
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500135
136
137
138_raise_current_error = partial(_exception_from_error_queue, Error)
139
140
141class WantReadError(Error):
142 pass
143
144
145
146class WantWriteError(Error):
147 pass
148
149
150
151class WantX509LookupError(Error):
152 pass
153
154
155
156class ZeroReturnError(Error):
157 pass
158
159
160
161class SysCallError(Error):
162 pass
163
164
165
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800166class _VerifyHelper(object):
167 def __init__(self, connection, callback):
168 self._problems = []
169
170 @wraps(callback)
171 def wrapper(ok, store_ctx):
172 cert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500173 cert._x509 = _lib.X509_STORE_CTX_get_current_cert(store_ctx)
174 error_number = _lib.X509_STORE_CTX_get_error(store_ctx)
175 error_depth = _lib.X509_STORE_CTX_get_error_depth(store_ctx)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800176
177 try:
178 result = callback(connection, cert, error_number, error_depth, ok)
179 except Exception as e:
180 self._problems.append(e)
181 return 0
182 else:
183 if result:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500184 _lib.X509_STORE_CTX_set_error(store_ctx, _lib.X509_V_OK)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800185 return 1
186 else:
187 return 0
188
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500189 self.callback = _ffi.callback(
190 "int (*)(int, X509_STORE_CTX *)", wrapper)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800191
192
193 def raise_if_problem(self):
194 if self._problems:
195 try:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500196 _raise_current_error()
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800197 except Error:
198 pass
199 raise self._problems.pop(0)
200
201
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800202
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800203def _asFileDescriptor(obj):
204 fd = None
205
206 if not isinstance(obj, int):
207 meth = getattr(obj, "fileno", None)
208 if meth is not None:
209 obj = meth()
210
211 if isinstance(obj, int):
212 fd = obj
213
214 if not isinstance(fd, int):
215 raise TypeError("argument must be an int, or have a fileno() method.")
216 elif fd < 0:
217 raise ValueError(
218 "file descriptor cannot be a negative integer (%i)" % (fd,))
219
220 return fd
221
222
223
Jean-Paul Calderoned39a3f62013-03-04 12:23:51 -0800224def SSLeay_version(type):
225 """
226 Return a string describing the version of OpenSSL in use.
227
228 :param type: One of the SSLEAY_ constants defined in this module.
229 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500230 return _ffi.string(_lib.SSLeay_version(type))
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800231
232
233
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800234class Session(object):
235 pass
236
237
238
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800239class Context(object):
240 """
241 :py:obj:`OpenSSL.SSL.Context` instances define the parameters for setting up
242 new SSL connections.
243 """
244 _methods = {
Jean-Paul Calderonebe2bb422013-12-29 07:34:08 -0500245 SSLv3_METHOD: "SSLv3_method",
246 SSLv23_METHOD: "SSLv23_method",
247 TLSv1_METHOD: "TLSv1_method",
248 TLSv1_1_METHOD: "TLSv1_1_method",
249 TLSv1_2_METHOD: "TLSv1_2_method",
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800250 }
Jean-Paul Calderonebe2bb422013-12-29 07:34:08 -0500251 _methods = dict(
252 (identifier, getattr(_lib, name))
253 for (identifier, name) in _methods.items()
254 if getattr(_lib, name, None) is not None)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800255
Jean-Paul Calderone63157872013-03-20 16:43:38 -0700256
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800257 def __init__(self, method):
258 """
259 :param method: One of SSLv2_METHOD, SSLv3_METHOD, SSLv23_METHOD, or
260 TLSv1_METHOD.
261 """
262 if not isinstance(method, int):
263 raise TypeError("method must be an integer")
264
265 try:
266 method_func = self._methods[method]
267 except KeyError:
268 raise ValueError("No such protocol")
269
270 method_obj = method_func()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500271 if method_obj == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500272 # TODO: This is untested.
273 _raise_current_error()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800274
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500275 context = _lib.SSL_CTX_new(method_obj)
276 if context == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500277 # TODO: This is untested.
278 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500279 context = _ffi.gc(context, _lib.SSL_CTX_free)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800280
281 self._context = context
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800282 self._passphrase_helper = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800283 self._passphrase_callback = None
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800284 self._passphrase_userdata = None
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800285 self._verify_helper = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800286 self._verify_callback = None
287 self._info_callback = None
288 self._tlsext_servername_callback = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800289 self._app_data = None
290
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -0800291 # SSL_CTX_set_app_data(self->ctx, self);
292 # SSL_CTX_set_mode(self->ctx, SSL_MODE_ENABLE_PARTIAL_WRITE |
293 # SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
294 # SSL_MODE_AUTO_RETRY);
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500295 self.set_mode(_lib.SSL_MODE_ENABLE_PARTIAL_WRITE)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800296
297
298 def load_verify_locations(self, cafile, capath=None):
299 """
300 Let SSL know where we can find trusted certificates for the certificate
301 chain
302
303 :param cafile: In which file we can find the certificates
304 :param capath: In which directory we can find the certificates
305 :return: None
306 """
307 if cafile is None:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500308 cafile = _ffi.NULL
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800309 elif not isinstance(cafile, bytes):
310 raise TypeError("cafile must be None or a byte string")
311
312 if capath is None:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500313 capath = _ffi.NULL
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800314 elif not isinstance(capath, bytes):
315 raise TypeError("capath must be None or a byte string")
316
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500317 load_result = _lib.SSL_CTX_load_verify_locations(self._context, cafile, capath)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800318 if not load_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500319 _raise_current_error()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800320
321
322 def _wrap_callback(self, callback):
323 @wraps(callback)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800324 def wrapper(size, verify, userdata):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800325 return callback(size, verify, self._passphrase_userdata)
326 return _PassphraseHelper(
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800327 FILETYPE_PEM, wrapper, more_args=True, truncate=True)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800328
329
330 def set_passwd_cb(self, callback, userdata=None):
331 """
332 Set the passphrase callback
333
334 :param callback: The Python callback to use
335 :param userdata: (optional) A Python object which will be given as
336 argument to the callback
337 :return: None
338 """
339 if not callable(callback):
340 raise TypeError("callback must be callable")
341
342 self._passphrase_helper = self._wrap_callback(callback)
343 self._passphrase_callback = self._passphrase_helper.callback
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500344 _lib.SSL_CTX_set_default_passwd_cb(
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800345 self._context, self._passphrase_callback)
346 self._passphrase_userdata = userdata
347
348
349 def set_default_verify_paths(self):
350 """
351 Use the platform-specific CA certificate locations
352
353 :return: None
354 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500355 set_result = _lib.SSL_CTX_set_default_verify_paths(self._context)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800356 if not set_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500357 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500358 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800359
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800360
361 def use_certificate_chain_file(self, certfile):
362 """
363 Load a certificate chain from a file
364
365 :param certfile: The name of the certificate chain file
366 :return: None
367 """
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800368 if not isinstance(certfile, bytes):
369 raise TypeError("certfile must be a byte string")
370
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500371 result = _lib.SSL_CTX_use_certificate_chain_file(self._context, certfile)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800372 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500373 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800374
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800375
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800376 def use_certificate_file(self, certfile, filetype=FILETYPE_PEM):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800377 """
378 Load a certificate from a file
379
380 :param certfile: The name of the certificate file
381 :param filetype: (optional) The encoding of the file, default is PEM
382 :return: None
383 """
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800384 if not isinstance(certfile, bytes):
385 raise TypeError("certfile must be a byte string")
386 if not isinstance(filetype, int):
387 raise TypeError("filetype must be an integer")
388
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500389 use_result = _lib.SSL_CTX_use_certificate_file(self._context, certfile, filetype)
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800390 if not use_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500391 _raise_current_error()
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800392
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800393
394 def use_certificate(self, cert):
395 """
396 Load a certificate from a X509 object
397
398 :param cert: The X509 object
399 :return: None
400 """
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800401 if not isinstance(cert, X509):
402 raise TypeError("cert must be an X509 instance")
403
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500404 use_result = _lib.SSL_CTX_use_certificate(self._context, cert._x509)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800405 if not use_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500406 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800407
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800408
409 def add_extra_chain_cert(self, certobj):
410 """
411 Add certificate to chain
412
413 :param certobj: The X509 certificate object to add to the chain
414 :return: None
415 """
416 if not isinstance(certobj, X509):
417 raise TypeError("certobj must be an X509 instance")
418
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500419 copy = _lib.X509_dup(certobj._x509)
420 add_result = _lib.SSL_CTX_add_extra_chain_cert(self._context, copy)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800421 if not add_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500422 # TODO: This is untested.
423 _lib.X509_free(copy)
424 _raise_current_error()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800425
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800426
427 def _raise_passphrase_exception(self):
428 if self._passphrase_helper is None:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500429 _raise_current_error()
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800430 exception = self._passphrase_helper.raise_if_problem(Error)
431 if exception is not None:
432 raise exception
433
434
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800435 def use_privatekey_file(self, keyfile, filetype=_unspecified):
436 """
437 Load a private key from a file
438
439 :param keyfile: The name of the key file
440 :param filetype: (optional) The encoding of the file, default is PEM
441 :return: None
442 """
443 if not isinstance(keyfile, bytes):
444 raise TypeError("keyfile must be a byte string")
445
446 if filetype is _unspecified:
447 filetype = FILETYPE_PEM
448 elif not isinstance(filetype, int):
449 raise TypeError("filetype must be an integer")
450
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500451 use_result = _lib.SSL_CTX_use_PrivateKey_file(
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800452 self._context, keyfile, filetype)
453 if not use_result:
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800454 self._raise_passphrase_exception()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800455
456
457 def use_privatekey(self, pkey):
458 """
459 Load a private key from a PKey object
460
461 :param pkey: The PKey object
462 :return: None
463 """
464 if not isinstance(pkey, PKey):
465 raise TypeError("pkey must be a PKey instance")
466
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500467 use_result = _lib.SSL_CTX_use_PrivateKey(self._context, pkey._pkey)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800468 if not use_result:
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800469 self._raise_passphrase_exception()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800470
471
472 def check_privatekey(self):
473 """
474 Check that the private key and certificate match up
475
476 :return: None (raises an exception if something's wrong)
477 """
478
479 def load_client_ca(self, cafile):
480 """
481 Load the trusted certificates that will be sent to the client (basically
482 telling the client "These are the guys I trust"). Does not actually
483 imply any of the certificates are trusted; that must be configured
484 separately.
485
486 :param cafile: The name of the certificates file
487 :return: None
488 """
489
490 def set_session_id(self, buf):
491 """
492 Set the session identifier. This is needed if you want to do session
493 resumption.
494
495 :param buf: A Python object that can be safely converted to a string
496 :returns: None
497 """
498
499 def set_session_cache_mode(self, mode):
500 """
501 Enable/disable session caching and specify the mode used.
502
503 :param mode: One or more of the SESS_CACHE_* flags (combine using
504 bitwise or)
505 :returns: The previously set caching mode.
506 """
507 if not isinstance(mode, int):
508 raise TypeError("mode must be an integer")
509
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500510 return _lib.SSL_CTX_set_session_cache_mode(self._context, mode)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800511
512
513 def get_session_cache_mode(self):
514 """
515 :returns: The currently used cache mode.
516 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500517 return _lib.SSL_CTX_get_session_cache_mode(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800518
519
520 def set_verify(self, mode, callback):
521 """
522 Set the verify mode and verify callback
523
524 :param mode: The verify mode, this is either VERIFY_NONE or
525 VERIFY_PEER combined with possible other flags
526 :param callback: The Python callback to use
527 :return: None
528
529 See SSL_CTX_set_verify(3SSL) for further details.
530 """
531 if not isinstance(mode, int):
532 raise TypeError("mode must be an integer")
533
534 if not callable(callback):
535 raise TypeError("callback must be callable")
536
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800537 self._verify_helper = _VerifyHelper(self, callback)
538 self._verify_callback = self._verify_helper.callback
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500539 _lib.SSL_CTX_set_verify(self._context, mode, self._verify_callback)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800540
541
542 def set_verify_depth(self, depth):
543 """
544 Set the verify depth
545
546 :param depth: An integer specifying the verify depth
547 :return: None
548 """
549 if not isinstance(depth, int):
550 raise TypeError("depth must be an integer")
551
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500552 _lib.SSL_CTX_set_verify_depth(self._context, depth)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800553
554
555 def get_verify_mode(self):
556 """
557 Get the verify mode
558
559 :return: The verify mode
560 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500561 return _lib.SSL_CTX_get_verify_mode(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800562
563
564 def get_verify_depth(self):
565 """
566 Get the verify depth
567
568 :return: The verify depth
569 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500570 return _lib.SSL_CTX_get_verify_depth(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800571
572
573 def load_tmp_dh(self, dhfile):
574 """
575 Load parameters for Ephemeral Diffie-Hellman
576
577 :param dhfile: The file to load EDH parameters from
578 :return: None
579 """
580 if not isinstance(dhfile, bytes):
581 raise TypeError("dhfile must be a byte string")
582
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -0500583 bio = _lib.BIO_new_file(dhfile, b"r")
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500584 if bio == _ffi.NULL:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500585 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500586 bio = _ffi.gc(bio, _lib.BIO_free)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800587
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500588 dh = _lib.PEM_read_bio_DHparams(bio, _ffi.NULL, _ffi.NULL, _ffi.NULL)
589 dh = _ffi.gc(dh, _lib.DH_free)
590 _lib.SSL_CTX_set_tmp_dh(self._context, dh)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800591
592
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600593 def set_tmp_ecdh_by_curve_name(self, curve_name):
594 """
595 Configure this connection to people to use Elliptical Curve
596 Diffie-Hellman key exchanges.
597
598 :param curve_name: One of the named curve constsants.
599 :return: None
600 """
601 if _lib.Cryptography_HAS_EC:
602 ecdh = _lib.EC_KEY_new_by_curve_name(curve_name)
603 if ecdh == _ffi.NULL:
604 raise ValueError(
605 "OpenSSL could not load the requested elliptic curve"
606 )
607 _lib.SSL_CTX_set_tmp_ecdh(self._context, ecdh)
608 _lib.EC_KEY_free(ecdh)
609 else:
610 raise ValueError("OpenSSL is compiled without ECDH support")
611
612
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800613 def set_cipher_list(self, cipher_list):
614 """
615 Change the cipher list
616
617 :param cipher_list: A cipher list, see ciphers(1)
618 :return: None
619 """
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800620 if not isinstance(cipher_list, bytes):
621 raise TypeError("cipher_list must be a byte string")
622
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500623 result = _lib.SSL_CTX_set_cipher_list(self._context, cipher_list)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800624 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500625 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800626
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800627
628 def set_client_ca_list(self, certificate_authorities):
629 """
630 Set the list of preferred client certificate signers for this server context.
631
632 This list of certificate authorities will be sent to the client when the
633 server requests a client certificate.
634
635 :param certificate_authorities: a sequence of X509Names.
636 :return: None
637 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500638 name_stack = _lib.sk_X509_NAME_new_null()
639 if name_stack == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500640 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500641 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800642
643 try:
644 for ca_name in certificate_authorities:
645 if not isinstance(ca_name, X509Name):
646 raise TypeError(
647 "client CAs must be X509Name objects, not %s objects" % (
648 type(ca_name).__name__,))
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500649 copy = _lib.X509_NAME_dup(ca_name._name)
650 if copy == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500651 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500652 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500653 push_result = _lib.sk_X509_NAME_push(name_stack, copy)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800654 if not push_result:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500655 _lib.X509_NAME_free(copy)
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500656 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800657 except:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500658 _lib.sk_X509_NAME_free(name_stack)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800659 raise
660
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500661 _lib.SSL_CTX_set_client_CA_list(self._context, name_stack)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800662
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800663
664 def add_client_ca(self, certificate_authority):
665 """
666 Add the CA certificate to the list of preferred signers for this context.
667
668 The list of certificate authorities will be sent to the client when the
669 server requests a client certificate.
670
671 :param certificate_authority: certificate authority's X509 certificate.
672 :return: None
673 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800674 if not isinstance(certificate_authority, X509):
675 raise TypeError("certificate_authority must be an X509 instance")
676
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500677 add_result = _lib.SSL_CTX_add_client_CA(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800678 self._context, certificate_authority._x509)
679 if not add_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500680 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500681 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800682
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800683
684 def set_timeout(self, timeout):
685 """
686 Set session timeout
687
688 :param timeout: The timeout in seconds
689 :return: The previous session timeout
690 """
691 if not isinstance(timeout, int):
692 raise TypeError("timeout must be an integer")
693
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500694 return _lib.SSL_CTX_set_timeout(self._context, timeout)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800695
696
697 def get_timeout(self):
698 """
699 Get the session timeout
700
701 :return: The session timeout
702 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500703 return _lib.SSL_CTX_get_timeout(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800704
705
706 def set_info_callback(self, callback):
707 """
708 Set the info callback
709
710 :param callback: The Python callback to use
711 :return: None
712 """
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800713 @wraps(callback)
714 def wrapper(ssl, where, return_code):
715 callback(self, where, return_code)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500716 self._info_callback = _ffi.callback(
717 "void (*)(const SSL *, int, int)", wrapper)
718 _lib.SSL_CTX_set_info_callback(self._context, self._info_callback)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800719
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800720
721 def get_app_data(self):
722 """
723 Get the application data (supplied via set_app_data())
724
725 :return: The application data
726 """
727 return self._app_data
728
729
730 def set_app_data(self, data):
731 """
732 Set the application data (will be returned from get_app_data())
733
734 :param data: Any Python object
735 :return: None
736 """
737 self._app_data = data
738
739
740 def get_cert_store(self):
741 """
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500742 Get the certificate store for the context.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800743
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500744 :return: A X509Store object or None if it does not have one.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800745 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500746 store = _lib.SSL_CTX_get_cert_store(self._context)
747 if store == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500748 # TODO: This is untested.
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800749 return None
750
751 pystore = X509Store.__new__(X509Store)
752 pystore._store = store
753 return pystore
754
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800755
756 def set_options(self, options):
757 """
758 Add options. Options set before are not cleared!
759
760 :param options: The options to add.
761 :return: The new option bitmask.
762 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800763 if not isinstance(options, int):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800764 raise TypeError("options must be an integer")
765
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500766 return _lib.SSL_CTX_set_options(self._context, options)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800767
768
769 def set_mode(self, mode):
770 """
771 Add modes via bitmask. Modes set before are not cleared!
772
773 :param mode: The mode to add.
774 :return: The new mode bitmask.
775 """
776 if not isinstance(mode, int):
777 raise TypeError("mode must be an integer")
778
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500779 return _lib.SSL_CTX_set_mode(self._context, mode)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800780
781
782 def set_tlsext_servername_callback(self, callback):
783 """
784 Specify a callback function to be called when clients specify a server name.
785
786 :param callback: The callback function. It will be invoked with one
787 argument, the Connection instance.
788 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800789 @wraps(callback)
790 def wrapper(ssl, alert, arg):
791 callback(Connection._reverse_mapping[ssl])
792 return 0
793
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500794 self._tlsext_servername_callback = _ffi.callback(
795 "int (*)(const SSL *, int *, void *)", wrapper)
796 _lib.SSL_CTX_set_tlsext_servername_callback(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800797 self._context, self._tlsext_servername_callback)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800798
799ContextType = Context
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800800
801
802
803class Connection(object):
804 """
805 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800806 _reverse_mapping = WeakValueDictionary()
807
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800808 def __init__(self, context, socket=None):
809 """
810 Create a new Connection object, using the given OpenSSL.SSL.Context
811 instance and socket.
812
813 :param context: An SSL Context to use for this connection
814 :param socket: The socket to use for transport layer
815 """
816 if not isinstance(context, Context):
817 raise TypeError("context must be a Context instance")
818
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500819 ssl = _lib.SSL_new(context._context)
820 self._ssl = _ffi.gc(ssl, _lib.SSL_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800821 self._context = context
822
823 self._reverse_mapping[self._ssl] = self
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800824
825 if socket is None:
826 self._socket = None
Jean-Paul Calderone73b15c22013-03-05 18:30:39 -0800827 # Don't set up any gc for these, SSL_free will take care of them.
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500828 self._into_ssl = _lib.BIO_new(_lib.BIO_s_mem())
829 self._from_ssl = _lib.BIO_new(_lib.BIO_s_mem())
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800830
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500831 if self._into_ssl == _ffi.NULL or self._from_ssl == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500832 # TODO: This is untested.
833 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800834
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500835 _lib.SSL_set_bio(self._ssl, self._into_ssl, self._from_ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800836 else:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800837 self._into_ssl = None
838 self._from_ssl = None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800839 self._socket = socket
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500840 set_result = _lib.SSL_set_fd(self._ssl, _asFileDescriptor(self._socket))
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800841 if not set_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500842 # TODO: This is untested.
843 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800844
845
846 def __getattr__(self, name):
847 """
848 Look up attributes on the wrapped socket object if they are not found on
849 the Connection object.
850 """
851 return getattr(self._socket, name)
852
853
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800854 def _raise_ssl_error(self, ssl, result):
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800855 if self._context._verify_helper is not None:
856 self._context._verify_helper.raise_if_problem()
857
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500858 error = _lib.SSL_get_error(ssl, result)
859 if error == _lib.SSL_ERROR_WANT_READ:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800860 raise WantReadError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500861 elif error == _lib.SSL_ERROR_WANT_WRITE:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -0700862 raise WantWriteError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500863 elif error == _lib.SSL_ERROR_ZERO_RETURN:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800864 raise ZeroReturnError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500865 elif error == _lib.SSL_ERROR_WANT_X509_LOOKUP:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500866 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -0700867 raise WantX509LookupError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500868 elif error == _lib.SSL_ERROR_SYSCALL:
869 if _lib.ERR_peek_error() == 0:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800870 if result < 0:
871 raise SysCallError(
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500872 _ffi.errno, errorcode[_ffi.errno])
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800873 else:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -0700874 raise SysCallError(-1, "Unexpected EOF")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800875 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500876 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500877 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500878 elif error == _lib.SSL_ERROR_NONE:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -0700879 pass
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800880 else:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500881 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800882
883
884 def get_context(self):
885 """
886 Get session context
887 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800888 return self._context
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800889
890
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800891 def set_context(self, context):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800892 """
893 Switch this connection to a new session context
894
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800895 :param context: A :py:class:`Context` instance giving the new session
896 context to use.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800897 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800898 if not isinstance(context, Context):
899 raise TypeError("context must be a Context instance")
900
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500901 _lib.SSL_set_SSL_CTX(self._ssl, context._context)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800902 self._context = context
903
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800904
905 def get_servername(self):
906 """
907 Retrieve the servername extension value if provided in the client hello
908 message, or None if there wasn't one.
909
910 :return: A byte string giving the server name or :py:data:`None`.
911 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500912 name = _lib.SSL_get_servername(self._ssl, _lib.TLSEXT_NAMETYPE_host_name)
913 if name == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800914 return None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800915
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500916 return _ffi.string(name)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800917
918
919 def set_tlsext_host_name(self, name):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800920 """
921 Set the value of the servername extension to send in the client hello.
922
923 :param name: A byte string giving the name.
924 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800925 if not isinstance(name, bytes):
926 raise TypeError("name must be a byte string")
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -0500927 elif b"\0" in name:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800928 raise TypeError("name must not contain NUL byte")
929
930 # XXX I guess this can fail sometimes?
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500931 _lib.SSL_set_tlsext_host_name(self._ssl, name)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800932
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800933
934 def pending(self):
935 """
936 Get the number of bytes that can be safely read from the connection
937
938 :return: The number of bytes available in the receive buffer.
939 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500940 return _lib.SSL_pending(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800941
942
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800943 def send(self, buf, flags=0):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800944 """
945 Send data on the connection. NOTE: If you get one of the WantRead,
946 WantWrite or WantX509Lookup exceptions on this, you have to call the
947 method again with the SAME buffer.
948
949 :param buf: The string to send
950 :param flags: (optional) Included for compatibility with the socket
951 API, the value is ignored
952 :return: The number of bytes written
953 """
Jean-Paul Calderone8fb53182013-12-30 08:35:49 -0500954 if isinstance(buf, _memoryview):
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -0800955 buf = buf.tobytes()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800956 if not isinstance(buf, bytes):
957 raise TypeError("data must be a byte string")
958 if not isinstance(flags, int):
959 raise TypeError("flags must be an integer")
960
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500961 result = _lib.SSL_write(self._ssl, buf, len(buf))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800962 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800963 return result
964 write = send
965
966
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800967 def sendall(self, buf, flags=0):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800968 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800969 Send "all" data on the connection. This calls send() repeatedly until
970 all data is sent. If an error occurs, it's impossible to tell how much
971 data has been sent.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800972
973 :param buf: The string to send
974 :param flags: (optional) Included for compatibility with the socket
975 API, the value is ignored
976 :return: The number of bytes written
977 """
Jean-Paul Calderone8fb53182013-12-30 08:35:49 -0500978 if isinstance(buf, _memoryview):
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -0800979 buf = buf.tobytes()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800980 if not isinstance(buf, bytes):
981 raise TypeError("buf must be a byte string")
982 if not isinstance(flags, int):
983 raise TypeError("flags must be an integer")
984
985 left_to_send = len(buf)
986 total_sent = 0
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500987 data = _ffi.new("char[]", buf)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800988
989 while left_to_send:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500990 result = _lib.SSL_write(self._ssl, data + total_sent, left_to_send)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800991 self._raise_ssl_error(self._ssl, result)
992 total_sent += result
993 left_to_send -= result
994
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800995
996 def recv(self, bufsiz, flags=None):
997 """
998 Receive data on the connection. NOTE: If you get one of the WantRead,
999 WantWrite or WantX509Lookup exceptions on this, you have to call the
1000 method again with the SAME buffer.
1001
1002 :param bufsiz: The maximum number of bytes to read
1003 :param flags: (optional) Included for compatibility with the socket
1004 API, the value is ignored
1005 :return: The string read from the Connection
1006 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001007 buf = _ffi.new("char[]", bufsiz)
1008 result = _lib.SSL_read(self._ssl, buf, bufsiz)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001009 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001010 return _ffi.buffer(buf, result)[:]
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001011 read = recv
1012
1013
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001014 def _handle_bio_errors(self, bio, result):
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001015 if _lib.BIO_should_retry(bio):
1016 if _lib.BIO_should_read(bio):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001017 raise WantReadError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001018 elif _lib.BIO_should_write(bio):
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001019 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001020 raise WantWriteError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001021 elif _lib.BIO_should_io_special(bio):
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001022 # TODO: This is untested. I think io_special means the socket
1023 # BIO has a not-yet connected socket.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001024 raise ValueError("BIO_should_io_special")
1025 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001026 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001027 raise ValueError("unknown bio failure")
1028 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001029 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001030 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001031
1032
1033 def bio_read(self, bufsiz):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001034 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001035 When using non-socket connections this function reads the "dirty" data
1036 that would have traveled away on the network.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001037
1038 :param bufsiz: The maximum number of bytes to read
1039 :return: The string read.
1040 """
Jean-Paul Calderone97e041d2013-03-05 21:03:12 -08001041 if self._from_ssl is None:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001042 raise TypeError("Connection sock was not None")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001043
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001044 if not isinstance(bufsiz, int):
1045 raise TypeError("bufsiz must be an integer")
1046
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001047 buf = _ffi.new("char[]", bufsiz)
1048 result = _lib.BIO_read(self._from_ssl, buf, bufsiz)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001049 if result <= 0:
1050 self._handle_bio_errors(self._from_ssl, result)
1051
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001052 return _ffi.buffer(buf, result)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001053
1054
1055 def bio_write(self, buf):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001056 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001057 When using non-socket connections this function sends "dirty" data that
1058 would have traveled in on the network.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001059
1060 :param buf: The string to put into the memory BIO.
1061 :return: The number of bytes written
1062 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001063 if self._into_ssl is None:
1064 raise TypeError("Connection sock was not None")
1065
1066 if not isinstance(buf, bytes):
1067 raise TypeError("buf must be a byte string")
1068
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001069 result = _lib.BIO_write(self._into_ssl, buf, len(buf))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001070 if result <= 0:
1071 self._handle_bio_errors(self._into_ssl, result)
1072 return result
1073
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001074
1075 def renegotiate(self):
1076 """
1077 Renegotiate the session
1078
1079 :return: True if the renegotiation can be started, false otherwise
1080 """
1081
1082 def do_handshake(self):
1083 """
1084 Perform an SSL handshake (usually called after renegotiate() or one of
1085 set_*_state()). This can raise the same exceptions as send and recv.
1086
1087 :return: None.
1088 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001089 result = _lib.SSL_do_handshake(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001090 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001091
1092
1093 def renegotiate_pending(self):
1094 """
1095 Check if there's a renegotiation in progress, it will return false once
1096 a renegotiation is finished.
1097
1098 :return: Whether there's a renegotiation in progress
1099 """
1100
1101 def total_renegotiations(self):
1102 """
1103 Find out the total number of renegotiations.
1104
1105 :return: The number of renegotiations.
1106 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001107 return _lib.SSL_total_renegotiations(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001108
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001109
1110 def connect(self, addr):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001111 """
1112 Connect to remote host and set up client-side SSL
1113
1114 :param addr: A remote address
1115 :return: What the socket's connect method returns
1116 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001117 _lib.SSL_set_connect_state(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001118 return self._socket.connect(addr)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001119
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001120
1121 def connect_ex(self, addr):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001122 """
1123 Connect to remote host and set up client-side SSL. Note that if the socket's
1124 connect_ex method doesn't return 0, SSL won't be initialized.
1125
1126 :param addr: A remove address
1127 :return: What the socket's connect_ex method returns
1128 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001129 connect_ex = self._socket.connect_ex
1130 self.set_connect_state()
1131 return connect_ex(addr)
1132
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001133
1134 def accept(self):
1135 """
1136 Accept incoming connection and set up SSL on it
1137
1138 :return: A (conn,addr) pair where conn is a Connection and addr is an
1139 address
1140 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001141 client, addr = self._socket.accept()
1142 conn = Connection(self._context, client)
1143 conn.set_accept_state()
1144 return (conn, addr)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001145
1146
1147 def bio_shutdown(self):
1148 """
1149 When using non-socket connections this function signals end of
1150 data on the input for this connection.
1151
1152 :return: None
1153 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001154 if self._from_ssl is None:
1155 raise TypeError("Connection sock was not None")
1156
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001157 _lib.BIO_set_mem_eof_return(self._into_ssl, 0)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001158
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001159
1160 def shutdown(self):
1161 """
1162 Send closure alert
1163
1164 :return: True if the shutdown completed successfully (i.e. both sides
1165 have sent closure alerts), false otherwise (i.e. you have to
1166 wait for a ZeroReturnError on a recv() method call
1167 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001168 result = _lib.SSL_shutdown(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001169 if result < 0:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001170 # TODO: This is untested.
1171 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001172 elif result > 0:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001173 return True
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001174 else:
1175 return False
1176
1177
1178 def get_cipher_list(self):
1179 """
1180 Get the session cipher list
1181
1182 :return: A list of cipher strings
1183 """
1184 ciphers = []
1185 for i in count():
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001186 result = _lib.SSL_get_cipher_list(self._ssl, i)
1187 if result == _ffi.NULL:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001188 break
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001189 ciphers.append(_native(_ffi.string(result)))
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001190 return ciphers
1191
1192
1193 def get_client_ca_list(self):
1194 """
1195 Get CAs whose certificates are suggested for client authentication.
1196
1197 :return: If this is a server connection, a list of X509Names representing
1198 the acceptable CAs as set by :py:meth:`OpenSSL.SSL.Context.set_client_ca_list` or
1199 :py:meth:`OpenSSL.SSL.Context.add_client_ca`. If this is a client connection,
1200 the list of such X509Names sent by the server, or an empty list if that
1201 has not yet happened.
1202 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001203 ca_names = _lib.SSL_get_client_CA_list(self._ssl)
1204 if ca_names == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001205 # TODO: This is untested.
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001206 return []
1207
1208 result = []
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001209 for i in range(_lib.sk_X509_NAME_num(ca_names)):
1210 name = _lib.sk_X509_NAME_value(ca_names, i)
1211 copy = _lib.X509_NAME_dup(name)
1212 if copy == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001213 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001214 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001215
1216 pyname = X509Name.__new__(X509Name)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001217 pyname._name = _ffi.gc(copy, _lib.X509_NAME_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001218 result.append(pyname)
1219 return result
1220
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001221
1222 def makefile(self):
1223 """
1224 The makefile() method is not implemented, since there is no dup semantics
1225 for SSL connections
1226
1227 :raise NotImplementedError
1228 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001229 raise NotImplementedError("Cannot make file object of OpenSSL.SSL.Connection")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001230
1231
1232 def get_app_data(self):
1233 """
1234 Get application data
1235
1236 :return: The application data
1237 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001238 return self._app_data
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001239
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001240
1241 def set_app_data(self, data):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001242 """
1243 Set application data
1244
1245 :param data - The application data
1246 :return: None
1247 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001248 self._app_data = data
1249
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001250
1251 def get_shutdown(self):
1252 """
1253 Get shutdown state
1254
1255 :return: The shutdown state, a bitvector of SENT_SHUTDOWN, RECEIVED_SHUTDOWN.
1256 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001257 return _lib.SSL_get_shutdown(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001258
1259
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001260 def set_shutdown(self, state):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001261 """
1262 Set shutdown state
1263
1264 :param state - bitvector of SENT_SHUTDOWN, RECEIVED_SHUTDOWN.
1265 :return: None
1266 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001267 if not isinstance(state, int):
1268 raise TypeError("state must be an integer")
1269
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001270 _lib.SSL_set_shutdown(self._ssl, state)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001271
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001272
1273 def state_string(self):
1274 """
1275 Get a verbose state description
1276
1277 :return: A string representing the state
1278 """
1279
1280 def server_random(self):
1281 """
1282 Get a copy of the server hello nonce.
1283
1284 :return: A string representing the state
1285 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001286 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001287 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001288 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001289 self._ssl.s3.server_random,
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001290 _lib.SSL3_RANDOM_SIZE)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001291
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001292
1293 def client_random(self):
1294 """
1295 Get a copy of the client hello nonce.
1296
1297 :return: A string representing the state
1298 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001299 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001300 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001301 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001302 self._ssl.s3.client_random,
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001303 _lib.SSL3_RANDOM_SIZE)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001304
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001305
1306 def master_key(self):
1307 """
1308 Get a copy of the master key.
1309
1310 :return: A string representing the state
1311 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001312 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001313 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001314 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001315 self._ssl.session.master_key,
1316 self._ssl.session.master_key_length)[:]
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001317
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001318
1319 def sock_shutdown(self, *args, **kwargs):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001320 """
1321 See shutdown(2)
1322
1323 :return: What the socket's shutdown() method returns
1324 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001325 return self._socket.shutdown(*args, **kwargs)
1326
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001327
1328 def get_peer_certificate(self):
1329 """
1330 Retrieve the other side's certificate (if any)
1331
1332 :return: The peer's certificate
1333 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001334 cert = _lib.SSL_get_peer_certificate(self._ssl)
1335 if cert != _ffi.NULL:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001336 pycert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001337 pycert._x509 = _ffi.gc(cert, _lib.X509_free)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001338 return pycert
1339 return None
1340
1341
1342 def get_peer_cert_chain(self):
1343 """
1344 Retrieve the other side's certificate (if any)
1345
1346 :return: A list of X509 instances giving the peer's certificate chain,
1347 or None if it does not have one.
1348 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001349 cert_stack = _lib.SSL_get_peer_cert_chain(self._ssl)
1350 if cert_stack == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001351 return None
1352
1353 result = []
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001354 for i in range(_lib.sk_X509_num(cert_stack)):
Jean-Paul Calderone73b15c22013-03-05 18:30:39 -08001355 # TODO could incref instead of dup here
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001356 cert = _lib.X509_dup(_lib.sk_X509_value(cert_stack, i))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001357 pycert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001358 pycert._x509 = _ffi.gc(cert, _lib.X509_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001359 result.append(pycert)
1360 return result
1361
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001362
1363 def want_read(self):
1364 """
1365 Checks if more data has to be read from the transport layer to complete an
1366 operation.
1367
1368 :return: True iff more data has to be read
1369 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001370 return _lib.SSL_want_read(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001371
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001372
1373 def want_write(self):
1374 """
1375 Checks if there is data to write to the transport layer to complete an
1376 operation.
1377
1378 :return: True iff there is data to write
1379 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001380 return _lib.SSL_want_write(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001381
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001382
1383 def set_accept_state(self):
1384 """
1385 Set the connection to work in server mode. The handshake will be handled
1386 automatically by read/write.
1387
1388 :return: None
1389 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001390 _lib.SSL_set_accept_state(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001391
1392
1393 def set_connect_state(self):
1394 """
1395 Set the connection to work in client mode. The handshake will be handled
1396 automatically by read/write.
1397
1398 :return: None
1399 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001400 _lib.SSL_set_connect_state(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001401
1402
1403 def get_session(self):
1404 """
1405 Returns the Session currently used.
1406
1407 @return: An instance of :py:class:`OpenSSL.SSL.Session` or :py:obj:`None` if
1408 no session exists.
1409 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001410 session = _lib.SSL_get1_session(self._ssl)
1411 if session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001412 return None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001413
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001414 pysession = Session.__new__(Session)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001415 pysession._session = _ffi.gc(session, _lib.SSL_SESSION_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001416 return pysession
1417
1418
1419 def set_session(self, session):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001420 """
1421 Set the session to be used when the TLS/SSL connection is established.
1422
1423 :param session: A Session instance representing the session to use.
1424 :returns: None
1425 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001426 if not isinstance(session, Session):
1427 raise TypeError("session must be a Session instance")
1428
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001429 result = _lib.SSL_set_session(self._ssl, session._session)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001430 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001431 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001432
1433ConnectionType = Connection