blob: e80ea3c49de3d75b0671f815b89dcfa9800e2e20 [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
Alex Gaynor12dc0842014-01-17 12:51:31 -0600130OPENSSL_NO_EC = not _lib.Cryptography_HAS_EC
131
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600132
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500133class Error(Exception):
Jean-Paul Calderone511cde02013-12-29 10:31:13 -0500134 """
135 An error occurred in an `OpenSSL.SSL` API.
136 """
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500137
138
139
140_raise_current_error = partial(_exception_from_error_queue, Error)
141
142
143class WantReadError(Error):
144 pass
145
146
147
148class WantWriteError(Error):
149 pass
150
151
152
153class WantX509LookupError(Error):
154 pass
155
156
157
158class ZeroReturnError(Error):
159 pass
160
161
162
163class SysCallError(Error):
164 pass
165
166
167
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800168class _VerifyHelper(object):
169 def __init__(self, connection, callback):
170 self._problems = []
171
172 @wraps(callback)
173 def wrapper(ok, store_ctx):
174 cert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500175 cert._x509 = _lib.X509_STORE_CTX_get_current_cert(store_ctx)
176 error_number = _lib.X509_STORE_CTX_get_error(store_ctx)
177 error_depth = _lib.X509_STORE_CTX_get_error_depth(store_ctx)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800178
179 try:
180 result = callback(connection, cert, error_number, error_depth, ok)
181 except Exception as e:
182 self._problems.append(e)
183 return 0
184 else:
185 if result:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500186 _lib.X509_STORE_CTX_set_error(store_ctx, _lib.X509_V_OK)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800187 return 1
188 else:
189 return 0
190
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500191 self.callback = _ffi.callback(
192 "int (*)(int, X509_STORE_CTX *)", wrapper)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800193
194
195 def raise_if_problem(self):
196 if self._problems:
197 try:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500198 _raise_current_error()
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800199 except Error:
200 pass
201 raise self._problems.pop(0)
202
203
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800204
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800205def _asFileDescriptor(obj):
206 fd = None
207
208 if not isinstance(obj, int):
209 meth = getattr(obj, "fileno", None)
210 if meth is not None:
211 obj = meth()
212
213 if isinstance(obj, int):
214 fd = obj
215
216 if not isinstance(fd, int):
217 raise TypeError("argument must be an int, or have a fileno() method.")
218 elif fd < 0:
219 raise ValueError(
220 "file descriptor cannot be a negative integer (%i)" % (fd,))
221
222 return fd
223
224
225
Jean-Paul Calderoned39a3f62013-03-04 12:23:51 -0800226def SSLeay_version(type):
227 """
228 Return a string describing the version of OpenSSL in use.
229
230 :param type: One of the SSLEAY_ constants defined in this module.
231 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500232 return _ffi.string(_lib.SSLeay_version(type))
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800233
234
235
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800236class Session(object):
237 pass
238
239
240
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800241class Context(object):
242 """
243 :py:obj:`OpenSSL.SSL.Context` instances define the parameters for setting up
244 new SSL connections.
245 """
246 _methods = {
Jean-Paul Calderonebe2bb422013-12-29 07:34:08 -0500247 SSLv3_METHOD: "SSLv3_method",
248 SSLv23_METHOD: "SSLv23_method",
249 TLSv1_METHOD: "TLSv1_method",
250 TLSv1_1_METHOD: "TLSv1_1_method",
251 TLSv1_2_METHOD: "TLSv1_2_method",
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800252 }
Jean-Paul Calderonebe2bb422013-12-29 07:34:08 -0500253 _methods = dict(
254 (identifier, getattr(_lib, name))
255 for (identifier, name) in _methods.items()
256 if getattr(_lib, name, None) is not None)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800257
Jean-Paul Calderone63157872013-03-20 16:43:38 -0700258
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800259 def __init__(self, method):
260 """
261 :param method: One of SSLv2_METHOD, SSLv3_METHOD, SSLv23_METHOD, or
262 TLSv1_METHOD.
263 """
264 if not isinstance(method, int):
265 raise TypeError("method must be an integer")
266
267 try:
268 method_func = self._methods[method]
269 except KeyError:
270 raise ValueError("No such protocol")
271
272 method_obj = method_func()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500273 if method_obj == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500274 # TODO: This is untested.
275 _raise_current_error()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800276
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500277 context = _lib.SSL_CTX_new(method_obj)
278 if context == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500279 # TODO: This is untested.
280 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500281 context = _ffi.gc(context, _lib.SSL_CTX_free)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800282
283 self._context = context
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800284 self._passphrase_helper = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800285 self._passphrase_callback = None
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800286 self._passphrase_userdata = None
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800287 self._verify_helper = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800288 self._verify_callback = None
289 self._info_callback = None
290 self._tlsext_servername_callback = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800291 self._app_data = None
292
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -0800293 # SSL_CTX_set_app_data(self->ctx, self);
294 # SSL_CTX_set_mode(self->ctx, SSL_MODE_ENABLE_PARTIAL_WRITE |
295 # SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
296 # SSL_MODE_AUTO_RETRY);
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500297 self.set_mode(_lib.SSL_MODE_ENABLE_PARTIAL_WRITE)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800298
299
300 def load_verify_locations(self, cafile, capath=None):
301 """
302 Let SSL know where we can find trusted certificates for the certificate
303 chain
304
305 :param cafile: In which file we can find the certificates
306 :param capath: In which directory we can find the certificates
307 :return: None
308 """
309 if cafile is None:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500310 cafile = _ffi.NULL
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800311 elif not isinstance(cafile, bytes):
312 raise TypeError("cafile must be None or a byte string")
313
314 if capath is None:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500315 capath = _ffi.NULL
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800316 elif not isinstance(capath, bytes):
317 raise TypeError("capath must be None or a byte string")
318
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500319 load_result = _lib.SSL_CTX_load_verify_locations(self._context, cafile, capath)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800320 if not load_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500321 _raise_current_error()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800322
323
324 def _wrap_callback(self, callback):
325 @wraps(callback)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800326 def wrapper(size, verify, userdata):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800327 return callback(size, verify, self._passphrase_userdata)
328 return _PassphraseHelper(
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800329 FILETYPE_PEM, wrapper, more_args=True, truncate=True)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800330
331
332 def set_passwd_cb(self, callback, userdata=None):
333 """
334 Set the passphrase callback
335
336 :param callback: The Python callback to use
337 :param userdata: (optional) A Python object which will be given as
338 argument to the callback
339 :return: None
340 """
341 if not callable(callback):
342 raise TypeError("callback must be callable")
343
344 self._passphrase_helper = self._wrap_callback(callback)
345 self._passphrase_callback = self._passphrase_helper.callback
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500346 _lib.SSL_CTX_set_default_passwd_cb(
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800347 self._context, self._passphrase_callback)
348 self._passphrase_userdata = userdata
349
350
351 def set_default_verify_paths(self):
352 """
353 Use the platform-specific CA certificate locations
354
355 :return: None
356 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500357 set_result = _lib.SSL_CTX_set_default_verify_paths(self._context)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800358 if not set_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500359 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500360 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800361
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800362
363 def use_certificate_chain_file(self, certfile):
364 """
365 Load a certificate chain from a file
366
367 :param certfile: The name of the certificate chain file
368 :return: None
369 """
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800370 if not isinstance(certfile, bytes):
371 raise TypeError("certfile must be a byte string")
372
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500373 result = _lib.SSL_CTX_use_certificate_chain_file(self._context, certfile)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800374 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500375 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800376
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800377
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800378 def use_certificate_file(self, certfile, filetype=FILETYPE_PEM):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800379 """
380 Load a certificate from a file
381
382 :param certfile: The name of the certificate file
383 :param filetype: (optional) The encoding of the file, default is PEM
384 :return: None
385 """
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800386 if not isinstance(certfile, bytes):
387 raise TypeError("certfile must be a byte string")
388 if not isinstance(filetype, int):
389 raise TypeError("filetype must be an integer")
390
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500391 use_result = _lib.SSL_CTX_use_certificate_file(self._context, certfile, filetype)
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800392 if not use_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500393 _raise_current_error()
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800394
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800395
396 def use_certificate(self, cert):
397 """
398 Load a certificate from a X509 object
399
400 :param cert: The X509 object
401 :return: None
402 """
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800403 if not isinstance(cert, X509):
404 raise TypeError("cert must be an X509 instance")
405
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500406 use_result = _lib.SSL_CTX_use_certificate(self._context, cert._x509)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800407 if not use_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500408 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800409
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800410
411 def add_extra_chain_cert(self, certobj):
412 """
413 Add certificate to chain
414
415 :param certobj: The X509 certificate object to add to the chain
416 :return: None
417 """
418 if not isinstance(certobj, X509):
419 raise TypeError("certobj must be an X509 instance")
420
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500421 copy = _lib.X509_dup(certobj._x509)
422 add_result = _lib.SSL_CTX_add_extra_chain_cert(self._context, copy)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800423 if not add_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500424 # TODO: This is untested.
425 _lib.X509_free(copy)
426 _raise_current_error()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800427
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800428
429 def _raise_passphrase_exception(self):
430 if self._passphrase_helper is None:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500431 _raise_current_error()
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800432 exception = self._passphrase_helper.raise_if_problem(Error)
433 if exception is not None:
434 raise exception
435
436
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800437 def use_privatekey_file(self, keyfile, filetype=_unspecified):
438 """
439 Load a private key from a file
440
441 :param keyfile: The name of the key file
442 :param filetype: (optional) The encoding of the file, default is PEM
443 :return: None
444 """
445 if not isinstance(keyfile, bytes):
446 raise TypeError("keyfile must be a byte string")
447
448 if filetype is _unspecified:
449 filetype = FILETYPE_PEM
450 elif not isinstance(filetype, int):
451 raise TypeError("filetype must be an integer")
452
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500453 use_result = _lib.SSL_CTX_use_PrivateKey_file(
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800454 self._context, keyfile, filetype)
455 if not use_result:
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800456 self._raise_passphrase_exception()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800457
458
459 def use_privatekey(self, pkey):
460 """
461 Load a private key from a PKey object
462
463 :param pkey: The PKey object
464 :return: None
465 """
466 if not isinstance(pkey, PKey):
467 raise TypeError("pkey must be a PKey instance")
468
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500469 use_result = _lib.SSL_CTX_use_PrivateKey(self._context, pkey._pkey)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800470 if not use_result:
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800471 self._raise_passphrase_exception()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800472
473
474 def check_privatekey(self):
475 """
476 Check that the private key and certificate match up
477
478 :return: None (raises an exception if something's wrong)
479 """
480
481 def load_client_ca(self, cafile):
482 """
483 Load the trusted certificates that will be sent to the client (basically
484 telling the client "These are the guys I trust"). Does not actually
485 imply any of the certificates are trusted; that must be configured
486 separately.
487
488 :param cafile: The name of the certificates file
489 :return: None
490 """
491
492 def set_session_id(self, buf):
493 """
494 Set the session identifier. This is needed if you want to do session
495 resumption.
496
497 :param buf: A Python object that can be safely converted to a string
498 :returns: None
499 """
500
501 def set_session_cache_mode(self, mode):
502 """
503 Enable/disable session caching and specify the mode used.
504
505 :param mode: One or more of the SESS_CACHE_* flags (combine using
506 bitwise or)
507 :returns: The previously set caching mode.
508 """
509 if not isinstance(mode, int):
510 raise TypeError("mode must be an integer")
511
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500512 return _lib.SSL_CTX_set_session_cache_mode(self._context, mode)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800513
514
515 def get_session_cache_mode(self):
516 """
517 :returns: The currently used cache mode.
518 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500519 return _lib.SSL_CTX_get_session_cache_mode(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800520
521
522 def set_verify(self, mode, callback):
523 """
524 Set the verify mode and verify callback
525
526 :param mode: The verify mode, this is either VERIFY_NONE or
527 VERIFY_PEER combined with possible other flags
528 :param callback: The Python callback to use
529 :return: None
530
531 See SSL_CTX_set_verify(3SSL) for further details.
532 """
533 if not isinstance(mode, int):
534 raise TypeError("mode must be an integer")
535
536 if not callable(callback):
537 raise TypeError("callback must be callable")
538
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800539 self._verify_helper = _VerifyHelper(self, callback)
540 self._verify_callback = self._verify_helper.callback
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500541 _lib.SSL_CTX_set_verify(self._context, mode, self._verify_callback)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800542
543
544 def set_verify_depth(self, depth):
545 """
546 Set the verify depth
547
548 :param depth: An integer specifying the verify depth
549 :return: None
550 """
551 if not isinstance(depth, int):
552 raise TypeError("depth must be an integer")
553
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500554 _lib.SSL_CTX_set_verify_depth(self._context, depth)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800555
556
557 def get_verify_mode(self):
558 """
559 Get the verify mode
560
561 :return: The verify mode
562 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500563 return _lib.SSL_CTX_get_verify_mode(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800564
565
566 def get_verify_depth(self):
567 """
568 Get the verify depth
569
570 :return: The verify depth
571 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500572 return _lib.SSL_CTX_get_verify_depth(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800573
574
575 def load_tmp_dh(self, dhfile):
576 """
577 Load parameters for Ephemeral Diffie-Hellman
578
579 :param dhfile: The file to load EDH parameters from
580 :return: None
581 """
582 if not isinstance(dhfile, bytes):
583 raise TypeError("dhfile must be a byte string")
584
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -0500585 bio = _lib.BIO_new_file(dhfile, b"r")
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500586 if bio == _ffi.NULL:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500587 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500588 bio = _ffi.gc(bio, _lib.BIO_free)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800589
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500590 dh = _lib.PEM_read_bio_DHparams(bio, _ffi.NULL, _ffi.NULL, _ffi.NULL)
591 dh = _ffi.gc(dh, _lib.DH_free)
592 _lib.SSL_CTX_set_tmp_dh(self._context, dh)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800593
594
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600595 def set_tmp_ecdh_by_curve_name(self, curve_name):
596 """
597 Configure this connection to people to use Elliptical Curve
598 Diffie-Hellman key exchanges.
599
Alex Gaynora683fc02014-01-17 12:45:56 -0600600 :param curve_name: One of the named curve constants.
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600601 :return: None
602 """
603 if _lib.Cryptography_HAS_EC:
604 ecdh = _lib.EC_KEY_new_by_curve_name(curve_name)
605 if ecdh == _ffi.NULL:
606 raise ValueError(
607 "OpenSSL could not load the requested elliptic curve"
608 )
609 _lib.SSL_CTX_set_tmp_ecdh(self._context, ecdh)
610 _lib.EC_KEY_free(ecdh)
611 else:
612 raise ValueError("OpenSSL is compiled without ECDH support")
613
614
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800615 def set_cipher_list(self, cipher_list):
616 """
617 Change the cipher list
618
619 :param cipher_list: A cipher list, see ciphers(1)
620 :return: None
621 """
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800622 if not isinstance(cipher_list, bytes):
623 raise TypeError("cipher_list must be a byte string")
624
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500625 result = _lib.SSL_CTX_set_cipher_list(self._context, cipher_list)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800626 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500627 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800628
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800629
630 def set_client_ca_list(self, certificate_authorities):
631 """
632 Set the list of preferred client certificate signers for this server context.
633
634 This list of certificate authorities will be sent to the client when the
635 server requests a client certificate.
636
637 :param certificate_authorities: a sequence of X509Names.
638 :return: None
639 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500640 name_stack = _lib.sk_X509_NAME_new_null()
641 if name_stack == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500642 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500643 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800644
645 try:
646 for ca_name in certificate_authorities:
647 if not isinstance(ca_name, X509Name):
648 raise TypeError(
649 "client CAs must be X509Name objects, not %s objects" % (
650 type(ca_name).__name__,))
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500651 copy = _lib.X509_NAME_dup(ca_name._name)
652 if copy == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500653 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500654 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500655 push_result = _lib.sk_X509_NAME_push(name_stack, copy)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800656 if not push_result:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500657 _lib.X509_NAME_free(copy)
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500658 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800659 except:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500660 _lib.sk_X509_NAME_free(name_stack)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800661 raise
662
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500663 _lib.SSL_CTX_set_client_CA_list(self._context, name_stack)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800664
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800665
666 def add_client_ca(self, certificate_authority):
667 """
668 Add the CA certificate to the list of preferred signers for this context.
669
670 The list of certificate authorities will be sent to the client when the
671 server requests a client certificate.
672
673 :param certificate_authority: certificate authority's X509 certificate.
674 :return: None
675 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800676 if not isinstance(certificate_authority, X509):
677 raise TypeError("certificate_authority must be an X509 instance")
678
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500679 add_result = _lib.SSL_CTX_add_client_CA(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800680 self._context, certificate_authority._x509)
681 if not add_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500682 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500683 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800684
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800685
686 def set_timeout(self, timeout):
687 """
688 Set session timeout
689
690 :param timeout: The timeout in seconds
691 :return: The previous session timeout
692 """
693 if not isinstance(timeout, int):
694 raise TypeError("timeout must be an integer")
695
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500696 return _lib.SSL_CTX_set_timeout(self._context, timeout)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800697
698
699 def get_timeout(self):
700 """
701 Get the session timeout
702
703 :return: The session timeout
704 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500705 return _lib.SSL_CTX_get_timeout(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800706
707
708 def set_info_callback(self, callback):
709 """
710 Set the info callback
711
712 :param callback: The Python callback to use
713 :return: None
714 """
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800715 @wraps(callback)
716 def wrapper(ssl, where, return_code):
717 callback(self, where, return_code)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500718 self._info_callback = _ffi.callback(
719 "void (*)(const SSL *, int, int)", wrapper)
720 _lib.SSL_CTX_set_info_callback(self._context, self._info_callback)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800721
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800722
723 def get_app_data(self):
724 """
725 Get the application data (supplied via set_app_data())
726
727 :return: The application data
728 """
729 return self._app_data
730
731
732 def set_app_data(self, data):
733 """
734 Set the application data (will be returned from get_app_data())
735
736 :param data: Any Python object
737 :return: None
738 """
739 self._app_data = data
740
741
742 def get_cert_store(self):
743 """
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500744 Get the certificate store for the context.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800745
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500746 :return: A X509Store object or None if it does not have one.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800747 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500748 store = _lib.SSL_CTX_get_cert_store(self._context)
749 if store == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500750 # TODO: This is untested.
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800751 return None
752
753 pystore = X509Store.__new__(X509Store)
754 pystore._store = store
755 return pystore
756
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800757
758 def set_options(self, options):
759 """
760 Add options. Options set before are not cleared!
761
762 :param options: The options to add.
763 :return: The new option bitmask.
764 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800765 if not isinstance(options, int):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800766 raise TypeError("options must be an integer")
767
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500768 return _lib.SSL_CTX_set_options(self._context, options)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800769
770
771 def set_mode(self, mode):
772 """
773 Add modes via bitmask. Modes set before are not cleared!
774
775 :param mode: The mode to add.
776 :return: The new mode bitmask.
777 """
778 if not isinstance(mode, int):
779 raise TypeError("mode must be an integer")
780
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500781 return _lib.SSL_CTX_set_mode(self._context, mode)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800782
783
784 def set_tlsext_servername_callback(self, callback):
785 """
786 Specify a callback function to be called when clients specify a server name.
787
788 :param callback: The callback function. It will be invoked with one
789 argument, the Connection instance.
790 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800791 @wraps(callback)
792 def wrapper(ssl, alert, arg):
793 callback(Connection._reverse_mapping[ssl])
794 return 0
795
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500796 self._tlsext_servername_callback = _ffi.callback(
797 "int (*)(const SSL *, int *, void *)", wrapper)
798 _lib.SSL_CTX_set_tlsext_servername_callback(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800799 self._context, self._tlsext_servername_callback)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800800
801ContextType = Context
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800802
803
804
805class Connection(object):
806 """
807 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800808 _reverse_mapping = WeakValueDictionary()
809
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800810 def __init__(self, context, socket=None):
811 """
812 Create a new Connection object, using the given OpenSSL.SSL.Context
813 instance and socket.
814
815 :param context: An SSL Context to use for this connection
816 :param socket: The socket to use for transport layer
817 """
818 if not isinstance(context, Context):
819 raise TypeError("context must be a Context instance")
820
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500821 ssl = _lib.SSL_new(context._context)
822 self._ssl = _ffi.gc(ssl, _lib.SSL_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800823 self._context = context
824
825 self._reverse_mapping[self._ssl] = self
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800826
827 if socket is None:
828 self._socket = None
Jean-Paul Calderone73b15c22013-03-05 18:30:39 -0800829 # Don't set up any gc for these, SSL_free will take care of them.
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500830 self._into_ssl = _lib.BIO_new(_lib.BIO_s_mem())
831 self._from_ssl = _lib.BIO_new(_lib.BIO_s_mem())
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800832
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500833 if self._into_ssl == _ffi.NULL or self._from_ssl == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500834 # TODO: This is untested.
835 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800836
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500837 _lib.SSL_set_bio(self._ssl, self._into_ssl, self._from_ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800838 else:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800839 self._into_ssl = None
840 self._from_ssl = None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800841 self._socket = socket
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500842 set_result = _lib.SSL_set_fd(self._ssl, _asFileDescriptor(self._socket))
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800843 if not set_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500844 # TODO: This is untested.
845 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800846
847
848 def __getattr__(self, name):
849 """
850 Look up attributes on the wrapped socket object if they are not found on
851 the Connection object.
852 """
853 return getattr(self._socket, name)
854
855
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800856 def _raise_ssl_error(self, ssl, result):
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800857 if self._context._verify_helper is not None:
858 self._context._verify_helper.raise_if_problem()
859
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500860 error = _lib.SSL_get_error(ssl, result)
861 if error == _lib.SSL_ERROR_WANT_READ:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800862 raise WantReadError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500863 elif error == _lib.SSL_ERROR_WANT_WRITE:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -0700864 raise WantWriteError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500865 elif error == _lib.SSL_ERROR_ZERO_RETURN:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800866 raise ZeroReturnError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500867 elif error == _lib.SSL_ERROR_WANT_X509_LOOKUP:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500868 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -0700869 raise WantX509LookupError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500870 elif error == _lib.SSL_ERROR_SYSCALL:
871 if _lib.ERR_peek_error() == 0:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800872 if result < 0:
873 raise SysCallError(
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500874 _ffi.errno, errorcode[_ffi.errno])
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800875 else:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -0700876 raise SysCallError(-1, "Unexpected EOF")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800877 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500878 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500879 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500880 elif error == _lib.SSL_ERROR_NONE:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -0700881 pass
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800882 else:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500883 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800884
885
886 def get_context(self):
887 """
888 Get session context
889 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800890 return self._context
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800891
892
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800893 def set_context(self, context):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800894 """
895 Switch this connection to a new session context
896
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800897 :param context: A :py:class:`Context` instance giving the new session
898 context to use.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800899 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800900 if not isinstance(context, Context):
901 raise TypeError("context must be a Context instance")
902
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500903 _lib.SSL_set_SSL_CTX(self._ssl, context._context)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800904 self._context = context
905
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800906
907 def get_servername(self):
908 """
909 Retrieve the servername extension value if provided in the client hello
910 message, or None if there wasn't one.
911
912 :return: A byte string giving the server name or :py:data:`None`.
913 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500914 name = _lib.SSL_get_servername(self._ssl, _lib.TLSEXT_NAMETYPE_host_name)
915 if name == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800916 return None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800917
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500918 return _ffi.string(name)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800919
920
921 def set_tlsext_host_name(self, name):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800922 """
923 Set the value of the servername extension to send in the client hello.
924
925 :param name: A byte string giving the name.
926 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800927 if not isinstance(name, bytes):
928 raise TypeError("name must be a byte string")
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -0500929 elif b"\0" in name:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800930 raise TypeError("name must not contain NUL byte")
931
932 # XXX I guess this can fail sometimes?
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500933 _lib.SSL_set_tlsext_host_name(self._ssl, name)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800934
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800935
936 def pending(self):
937 """
938 Get the number of bytes that can be safely read from the connection
939
940 :return: The number of bytes available in the receive buffer.
941 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500942 return _lib.SSL_pending(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800943
944
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800945 def send(self, buf, flags=0):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800946 """
947 Send data on the connection. NOTE: If you get one of the WantRead,
948 WantWrite or WantX509Lookup exceptions on this, you have to call the
949 method again with the SAME buffer.
950
951 :param buf: The string to send
952 :param flags: (optional) Included for compatibility with the socket
953 API, the value is ignored
954 :return: The number of bytes written
955 """
Jean-Paul Calderone8fb53182013-12-30 08:35:49 -0500956 if isinstance(buf, _memoryview):
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -0800957 buf = buf.tobytes()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800958 if not isinstance(buf, bytes):
959 raise TypeError("data must be a byte string")
960 if not isinstance(flags, int):
961 raise TypeError("flags must be an integer")
962
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500963 result = _lib.SSL_write(self._ssl, buf, len(buf))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800964 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800965 return result
966 write = send
967
968
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800969 def sendall(self, buf, flags=0):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800970 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800971 Send "all" data on the connection. This calls send() repeatedly until
972 all data is sent. If an error occurs, it's impossible to tell how much
973 data has been sent.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800974
975 :param buf: The string to send
976 :param flags: (optional) Included for compatibility with the socket
977 API, the value is ignored
978 :return: The number of bytes written
979 """
Jean-Paul Calderone8fb53182013-12-30 08:35:49 -0500980 if isinstance(buf, _memoryview):
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -0800981 buf = buf.tobytes()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800982 if not isinstance(buf, bytes):
983 raise TypeError("buf must be a byte string")
984 if not isinstance(flags, int):
985 raise TypeError("flags must be an integer")
986
987 left_to_send = len(buf)
988 total_sent = 0
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500989 data = _ffi.new("char[]", buf)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800990
991 while left_to_send:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500992 result = _lib.SSL_write(self._ssl, data + total_sent, left_to_send)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800993 self._raise_ssl_error(self._ssl, result)
994 total_sent += result
995 left_to_send -= result
996
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800997
998 def recv(self, bufsiz, flags=None):
999 """
1000 Receive data on the connection. NOTE: If you get one of the WantRead,
1001 WantWrite or WantX509Lookup exceptions on this, you have to call the
1002 method again with the SAME buffer.
1003
1004 :param bufsiz: The maximum number of bytes to read
1005 :param flags: (optional) Included for compatibility with the socket
1006 API, the value is ignored
1007 :return: The string read from the Connection
1008 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001009 buf = _ffi.new("char[]", bufsiz)
1010 result = _lib.SSL_read(self._ssl, buf, bufsiz)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001011 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001012 return _ffi.buffer(buf, result)[:]
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001013 read = recv
1014
1015
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001016 def _handle_bio_errors(self, bio, result):
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001017 if _lib.BIO_should_retry(bio):
1018 if _lib.BIO_should_read(bio):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001019 raise WantReadError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001020 elif _lib.BIO_should_write(bio):
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001021 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001022 raise WantWriteError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001023 elif _lib.BIO_should_io_special(bio):
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001024 # TODO: This is untested. I think io_special means the socket
1025 # BIO has a not-yet connected socket.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001026 raise ValueError("BIO_should_io_special")
1027 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001028 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001029 raise ValueError("unknown bio failure")
1030 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001031 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001032 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001033
1034
1035 def bio_read(self, bufsiz):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001036 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001037 When using non-socket connections this function reads the "dirty" data
1038 that would have traveled away on the network.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001039
1040 :param bufsiz: The maximum number of bytes to read
1041 :return: The string read.
1042 """
Jean-Paul Calderone97e041d2013-03-05 21:03:12 -08001043 if self._from_ssl is None:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001044 raise TypeError("Connection sock was not None")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001045
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001046 if not isinstance(bufsiz, int):
1047 raise TypeError("bufsiz must be an integer")
1048
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001049 buf = _ffi.new("char[]", bufsiz)
1050 result = _lib.BIO_read(self._from_ssl, buf, bufsiz)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001051 if result <= 0:
1052 self._handle_bio_errors(self._from_ssl, result)
1053
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001054 return _ffi.buffer(buf, result)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001055
1056
1057 def bio_write(self, buf):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001058 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001059 When using non-socket connections this function sends "dirty" data that
1060 would have traveled in on the network.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001061
1062 :param buf: The string to put into the memory BIO.
1063 :return: The number of bytes written
1064 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001065 if self._into_ssl is None:
1066 raise TypeError("Connection sock was not None")
1067
1068 if not isinstance(buf, bytes):
1069 raise TypeError("buf must be a byte string")
1070
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001071 result = _lib.BIO_write(self._into_ssl, buf, len(buf))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001072 if result <= 0:
1073 self._handle_bio_errors(self._into_ssl, result)
1074 return result
1075
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001076
1077 def renegotiate(self):
1078 """
1079 Renegotiate the session
1080
1081 :return: True if the renegotiation can be started, false otherwise
1082 """
1083
1084 def do_handshake(self):
1085 """
1086 Perform an SSL handshake (usually called after renegotiate() or one of
1087 set_*_state()). This can raise the same exceptions as send and recv.
1088
1089 :return: None.
1090 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001091 result = _lib.SSL_do_handshake(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001092 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001093
1094
1095 def renegotiate_pending(self):
1096 """
1097 Check if there's a renegotiation in progress, it will return false once
1098 a renegotiation is finished.
1099
1100 :return: Whether there's a renegotiation in progress
1101 """
1102
1103 def total_renegotiations(self):
1104 """
1105 Find out the total number of renegotiations.
1106
1107 :return: The number of renegotiations.
1108 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001109 return _lib.SSL_total_renegotiations(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001110
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001111
1112 def connect(self, addr):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001113 """
1114 Connect to remote host and set up client-side SSL
1115
1116 :param addr: A remote address
1117 :return: What the socket's connect method returns
1118 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001119 _lib.SSL_set_connect_state(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001120 return self._socket.connect(addr)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001121
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001122
1123 def connect_ex(self, addr):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001124 """
1125 Connect to remote host and set up client-side SSL. Note that if the socket's
1126 connect_ex method doesn't return 0, SSL won't be initialized.
1127
1128 :param addr: A remove address
1129 :return: What the socket's connect_ex method returns
1130 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001131 connect_ex = self._socket.connect_ex
1132 self.set_connect_state()
1133 return connect_ex(addr)
1134
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001135
1136 def accept(self):
1137 """
1138 Accept incoming connection and set up SSL on it
1139
1140 :return: A (conn,addr) pair where conn is a Connection and addr is an
1141 address
1142 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001143 client, addr = self._socket.accept()
1144 conn = Connection(self._context, client)
1145 conn.set_accept_state()
1146 return (conn, addr)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001147
1148
1149 def bio_shutdown(self):
1150 """
1151 When using non-socket connections this function signals end of
1152 data on the input for this connection.
1153
1154 :return: None
1155 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001156 if self._from_ssl is None:
1157 raise TypeError("Connection sock was not None")
1158
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001159 _lib.BIO_set_mem_eof_return(self._into_ssl, 0)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001160
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001161
1162 def shutdown(self):
1163 """
1164 Send closure alert
1165
1166 :return: True if the shutdown completed successfully (i.e. both sides
1167 have sent closure alerts), false otherwise (i.e. you have to
1168 wait for a ZeroReturnError on a recv() method call
1169 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001170 result = _lib.SSL_shutdown(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001171 if result < 0:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001172 # TODO: This is untested.
1173 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001174 elif result > 0:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001175 return True
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001176 else:
1177 return False
1178
1179
1180 def get_cipher_list(self):
1181 """
1182 Get the session cipher list
1183
1184 :return: A list of cipher strings
1185 """
1186 ciphers = []
1187 for i in count():
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001188 result = _lib.SSL_get_cipher_list(self._ssl, i)
1189 if result == _ffi.NULL:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001190 break
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001191 ciphers.append(_native(_ffi.string(result)))
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001192 return ciphers
1193
1194
1195 def get_client_ca_list(self):
1196 """
1197 Get CAs whose certificates are suggested for client authentication.
1198
1199 :return: If this is a server connection, a list of X509Names representing
1200 the acceptable CAs as set by :py:meth:`OpenSSL.SSL.Context.set_client_ca_list` or
1201 :py:meth:`OpenSSL.SSL.Context.add_client_ca`. If this is a client connection,
1202 the list of such X509Names sent by the server, or an empty list if that
1203 has not yet happened.
1204 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001205 ca_names = _lib.SSL_get_client_CA_list(self._ssl)
1206 if ca_names == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001207 # TODO: This is untested.
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001208 return []
1209
1210 result = []
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001211 for i in range(_lib.sk_X509_NAME_num(ca_names)):
1212 name = _lib.sk_X509_NAME_value(ca_names, i)
1213 copy = _lib.X509_NAME_dup(name)
1214 if copy == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001215 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001216 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001217
1218 pyname = X509Name.__new__(X509Name)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001219 pyname._name = _ffi.gc(copy, _lib.X509_NAME_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001220 result.append(pyname)
1221 return result
1222
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001223
1224 def makefile(self):
1225 """
1226 The makefile() method is not implemented, since there is no dup semantics
1227 for SSL connections
1228
1229 :raise NotImplementedError
1230 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001231 raise NotImplementedError("Cannot make file object of OpenSSL.SSL.Connection")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001232
1233
1234 def get_app_data(self):
1235 """
1236 Get application data
1237
1238 :return: The application data
1239 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001240 return self._app_data
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001241
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001242
1243 def set_app_data(self, data):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001244 """
1245 Set application data
1246
1247 :param data - The application data
1248 :return: None
1249 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001250 self._app_data = data
1251
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001252
1253 def get_shutdown(self):
1254 """
1255 Get shutdown state
1256
1257 :return: The shutdown state, a bitvector of SENT_SHUTDOWN, RECEIVED_SHUTDOWN.
1258 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001259 return _lib.SSL_get_shutdown(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001260
1261
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001262 def set_shutdown(self, state):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001263 """
1264 Set shutdown state
1265
1266 :param state - bitvector of SENT_SHUTDOWN, RECEIVED_SHUTDOWN.
1267 :return: None
1268 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001269 if not isinstance(state, int):
1270 raise TypeError("state must be an integer")
1271
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001272 _lib.SSL_set_shutdown(self._ssl, state)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001273
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001274
1275 def state_string(self):
1276 """
1277 Get a verbose state description
1278
1279 :return: A string representing the state
1280 """
1281
1282 def server_random(self):
1283 """
1284 Get a copy of the server hello nonce.
1285
1286 :return: A string representing the state
1287 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001288 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001289 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001290 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001291 self._ssl.s3.server_random,
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001292 _lib.SSL3_RANDOM_SIZE)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001293
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001294
1295 def client_random(self):
1296 """
1297 Get a copy of the client hello nonce.
1298
1299 :return: A string representing the state
1300 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001301 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001302 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001303 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001304 self._ssl.s3.client_random,
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001305 _lib.SSL3_RANDOM_SIZE)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001306
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001307
1308 def master_key(self):
1309 """
1310 Get a copy of the master key.
1311
1312 :return: A string representing the state
1313 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001314 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001315 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001316 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001317 self._ssl.session.master_key,
1318 self._ssl.session.master_key_length)[:]
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001319
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001320
1321 def sock_shutdown(self, *args, **kwargs):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001322 """
1323 See shutdown(2)
1324
1325 :return: What the socket's shutdown() method returns
1326 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001327 return self._socket.shutdown(*args, **kwargs)
1328
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001329
1330 def get_peer_certificate(self):
1331 """
1332 Retrieve the other side's certificate (if any)
1333
1334 :return: The peer's certificate
1335 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001336 cert = _lib.SSL_get_peer_certificate(self._ssl)
1337 if cert != _ffi.NULL:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001338 pycert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001339 pycert._x509 = _ffi.gc(cert, _lib.X509_free)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001340 return pycert
1341 return None
1342
1343
1344 def get_peer_cert_chain(self):
1345 """
1346 Retrieve the other side's certificate (if any)
1347
1348 :return: A list of X509 instances giving the peer's certificate chain,
1349 or None if it does not have one.
1350 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001351 cert_stack = _lib.SSL_get_peer_cert_chain(self._ssl)
1352 if cert_stack == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001353 return None
1354
1355 result = []
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001356 for i in range(_lib.sk_X509_num(cert_stack)):
Jean-Paul Calderone73b15c22013-03-05 18:30:39 -08001357 # TODO could incref instead of dup here
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001358 cert = _lib.X509_dup(_lib.sk_X509_value(cert_stack, i))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001359 pycert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001360 pycert._x509 = _ffi.gc(cert, _lib.X509_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001361 result.append(pycert)
1362 return result
1363
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001364
1365 def want_read(self):
1366 """
1367 Checks if more data has to be read from the transport layer to complete an
1368 operation.
1369
1370 :return: True iff more data has to be read
1371 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001372 return _lib.SSL_want_read(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001373
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001374
1375 def want_write(self):
1376 """
1377 Checks if there is data to write to the transport layer to complete an
1378 operation.
1379
1380 :return: True iff there is data to write
1381 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001382 return _lib.SSL_want_write(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001383
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001384
1385 def set_accept_state(self):
1386 """
1387 Set the connection to work in server mode. The handshake will be handled
1388 automatically by read/write.
1389
1390 :return: None
1391 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001392 _lib.SSL_set_accept_state(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001393
1394
1395 def set_connect_state(self):
1396 """
1397 Set the connection to work in client mode. The handshake will be handled
1398 automatically by read/write.
1399
1400 :return: None
1401 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001402 _lib.SSL_set_connect_state(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001403
1404
1405 def get_session(self):
1406 """
1407 Returns the Session currently used.
1408
1409 @return: An instance of :py:class:`OpenSSL.SSL.Session` or :py:obj:`None` if
1410 no session exists.
1411 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001412 session = _lib.SSL_get1_session(self._ssl)
1413 if session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001414 return None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001415
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001416 pysession = Session.__new__(Session)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001417 pysession._session = _ffi.gc(session, _lib.SSL_SESSION_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001418 return pysession
1419
1420
1421 def set_session(self, session):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001422 """
1423 Set the session to be used when the TLS/SSL connection is established.
1424
1425 :param session: A Session instance representing the session to use.
1426 :returns: None
1427 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001428 if not isinstance(session, Session):
1429 raise TypeError("session must be a Session instance")
1430
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001431 result = _lib.SSL_set_session(self._ssl, session._session)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001432 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001433 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001434
1435ConnectionType = Connection