blob: 5b748ee8c99e0b5c698030e13130ed80136843a5 [file] [log] [blame]
Konstantinos Koukopoulos541150d2014-01-31 01:00:19 +02001from sys import platform
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05002from functools import wraps, partial
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08003from itertools import count
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08004from weakref import WeakValueDictionary
5from errno import errorcode
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -08006
Jean-Paul Calderone63eab692014-01-18 10:19:56 -05007from six import text_type as _text_type
Konstantinos Koukopoulosc8b13ea2014-01-28 00:21:50 -08008from six import integer_types as integer_types
Jean-Paul Calderone63eab692014-01-18 10:19:56 -05009
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -050010from OpenSSL._util import (
11 ffi as _ffi,
12 lib as _lib,
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -050013 exception_from_error_queue as _exception_from_error_queue,
14 native as _native)
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080015
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -080016from OpenSSL.crypto import (
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -050017 FILETYPE_PEM, _PassphraseHelper, PKey, X509Name, X509, X509Store)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -080018
19_unspecified = object()
20
Jean-Paul Calderone8fb53182013-12-30 08:35:49 -050021try:
22 _memoryview = memoryview
23except NameError:
24 class _memoryview(object):
25 pass
26
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050027OPENSSL_VERSION_NUMBER = _lib.OPENSSL_VERSION_NUMBER
28SSLEAY_VERSION = _lib.SSLEAY_VERSION
29SSLEAY_CFLAGS = _lib.SSLEAY_CFLAGS
30SSLEAY_PLATFORM = _lib.SSLEAY_PLATFORM
31SSLEAY_DIR = _lib.SSLEAY_DIR
32SSLEAY_BUILT_ON = _lib.SSLEAY_BUILT_ON
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080033
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050034SENT_SHUTDOWN = _lib.SSL_SENT_SHUTDOWN
35RECEIVED_SHUTDOWN = _lib.SSL_RECEIVED_SHUTDOWN
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080036
37SSLv2_METHOD = 1
38SSLv3_METHOD = 2
39SSLv23_METHOD = 3
40TLSv1_METHOD = 4
Jean-Paul Calderone56bff942013-11-03 11:30:43 -050041TLSv1_1_METHOD = 5
42TLSv1_2_METHOD = 6
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080043
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050044OP_NO_SSLv2 = _lib.SSL_OP_NO_SSLv2
45OP_NO_SSLv3 = _lib.SSL_OP_NO_SSLv3
46OP_NO_TLSv1 = _lib.SSL_OP_NO_TLSv1
Jean-Paul Calderonebe2bb422013-12-29 07:34:08 -050047
48OP_NO_TLSv1_1 = getattr(_lib, "SSL_OP_NO_TLSv1_1", 0)
49OP_NO_TLSv1_2 = getattr(_lib, "SSL_OP_NO_TLSv1_2", 0)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -080050
Jean-Paul Calderone0d7e8a12014-01-08 16:54:13 -050051try:
52 MODE_RELEASE_BUFFERS = _lib.SSL_MODE_RELEASE_BUFFERS
53except AttributeError:
54 pass
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080055
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050056OP_SINGLE_DH_USE = _lib.SSL_OP_SINGLE_DH_USE
57OP_EPHEMERAL_RSA = _lib.SSL_OP_EPHEMERAL_RSA
58OP_MICROSOFT_SESS_ID_BUG = _lib.SSL_OP_MICROSOFT_SESS_ID_BUG
59OP_NETSCAPE_CHALLENGE_BUG = _lib.SSL_OP_NETSCAPE_CHALLENGE_BUG
60OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG = _lib.SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG
61OP_SSLREF2_REUSE_CERT_TYPE_BUG = _lib.SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG
62OP_MICROSOFT_BIG_SSLV3_BUFFER = _lib.SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER
Jean-Paul Calderone0d7e8a12014-01-08 16:54:13 -050063try:
64 OP_MSIE_SSLV2_RSA_PADDING = _lib.SSL_OP_MSIE_SSLV2_RSA_PADDING
65except AttributeError:
66 pass
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050067OP_SSLEAY_080_CLIENT_DH_BUG = _lib.SSL_OP_SSLEAY_080_CLIENT_DH_BUG
68OP_TLS_D5_BUG = _lib.SSL_OP_TLS_D5_BUG
69OP_TLS_BLOCK_PADDING_BUG = _lib.SSL_OP_TLS_BLOCK_PADDING_BUG
70OP_DONT_INSERT_EMPTY_FRAGMENTS = _lib.SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
71OP_CIPHER_SERVER_PREFERENCE = _lib.SSL_OP_CIPHER_SERVER_PREFERENCE
72OP_TLS_ROLLBACK_BUG = _lib.SSL_OP_TLS_ROLLBACK_BUG
73OP_PKCS1_CHECK_1 = _lib.SSL_OP_PKCS1_CHECK_1
74OP_PKCS1_CHECK_2 = _lib.SSL_OP_PKCS1_CHECK_2
75OP_NETSCAPE_CA_DN_BUG = _lib.SSL_OP_NETSCAPE_CA_DN_BUG
76OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG= _lib.SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG
Jean-Paul Calderonec1780342014-01-08 16:59:03 -050077try:
78 OP_NO_COMPRESSION = _lib.SSL_OP_NO_COMPRESSION
79except AttributeError:
80 pass
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -080081
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050082OP_NO_QUERY_MTU = _lib.SSL_OP_NO_QUERY_MTU
83OP_COOKIE_EXCHANGE = _lib.SSL_OP_COOKIE_EXCHANGE
Arturo Filastò5f8c7a82014-03-09 20:01:25 +010084try:
85 OP_NO_TICKET = _lib.SSL_OP_NO_TICKET
86except AttributeError:
87 pass
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -080088
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050089OP_ALL = _lib.SSL_OP_ALL
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080090
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050091VERIFY_PEER = _lib.SSL_VERIFY_PEER
92VERIFY_FAIL_IF_NO_PEER_CERT = _lib.SSL_VERIFY_FAIL_IF_NO_PEER_CERT
93VERIFY_CLIENT_ONCE = _lib.SSL_VERIFY_CLIENT_ONCE
94VERIFY_NONE = _lib.SSL_VERIFY_NONE
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080095
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050096SESS_CACHE_OFF = _lib.SSL_SESS_CACHE_OFF
97SESS_CACHE_CLIENT = _lib.SSL_SESS_CACHE_CLIENT
98SESS_CACHE_SERVER = _lib.SSL_SESS_CACHE_SERVER
99SESS_CACHE_BOTH = _lib.SSL_SESS_CACHE_BOTH
100SESS_CACHE_NO_AUTO_CLEAR = _lib.SSL_SESS_CACHE_NO_AUTO_CLEAR
101SESS_CACHE_NO_INTERNAL_LOOKUP = _lib.SSL_SESS_CACHE_NO_INTERNAL_LOOKUP
102SESS_CACHE_NO_INTERNAL_STORE = _lib.SSL_SESS_CACHE_NO_INTERNAL_STORE
103SESS_CACHE_NO_INTERNAL = _lib.SSL_SESS_CACHE_NO_INTERNAL
Jean-Paul Calderoned39a3f62013-03-04 12:23:51 -0800104
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500105SSL_ST_CONNECT = _lib.SSL_ST_CONNECT
106SSL_ST_ACCEPT = _lib.SSL_ST_ACCEPT
107SSL_ST_MASK = _lib.SSL_ST_MASK
108SSL_ST_INIT = _lib.SSL_ST_INIT
109SSL_ST_BEFORE = _lib.SSL_ST_BEFORE
110SSL_ST_OK = _lib.SSL_ST_OK
111SSL_ST_RENEGOTIATE = _lib.SSL_ST_RENEGOTIATE
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800112
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500113SSL_CB_LOOP = _lib.SSL_CB_LOOP
114SSL_CB_EXIT = _lib.SSL_CB_EXIT
115SSL_CB_READ = _lib.SSL_CB_READ
116SSL_CB_WRITE = _lib.SSL_CB_WRITE
117SSL_CB_ALERT = _lib.SSL_CB_ALERT
118SSL_CB_READ_ALERT = _lib.SSL_CB_READ_ALERT
119SSL_CB_WRITE_ALERT = _lib.SSL_CB_WRITE_ALERT
120SSL_CB_ACCEPT_LOOP = _lib.SSL_CB_ACCEPT_LOOP
121SSL_CB_ACCEPT_EXIT = _lib.SSL_CB_ACCEPT_EXIT
122SSL_CB_CONNECT_LOOP = _lib.SSL_CB_CONNECT_LOOP
123SSL_CB_CONNECT_EXIT = _lib.SSL_CB_CONNECT_EXIT
124SSL_CB_HANDSHAKE_START = _lib.SSL_CB_HANDSHAKE_START
125SSL_CB_HANDSHAKE_DONE = _lib.SSL_CB_HANDSHAKE_DONE
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800126
Alex Gaynor807853c2014-01-17 13:03:27 -0600127_Cryptography_HAS_EC = _lib.Cryptography_HAS_EC
Andy Lutomirski9bca0ed2014-03-05 14:41:41 -0800128ELLIPTIC_CURVE_DESCRIPTIONS = {} # In case there's no EC support
129if _Cryptography_HAS_EC:
130 _num_curves = _lib.EC_get_builtin_curves(_ffi.NULL, 0)
131 _curves = _ffi.new('EC_builtin_curve[]', _num_curves)
132 if _lib.EC_get_builtin_curves(_curves, _num_curves) == _num_curves:
Andy Lutomirski5fb416a2014-04-04 12:19:52 -0700133 ELLIPTIC_CURVE_DESCRIPTIONS = dict(
134 (_ffi.string(_lib.OBJ_nid2sn(c.nid)).decode('ascii'),
135 _ffi.string(c.comment).decode('utf-8'))
136 for c in _curves)
Andy Lutomirski9bca0ed2014-03-05 14:41:41 -0800137 del _num_curves
138 del _curves
Alex Gaynor12dc0842014-01-17 12:51:31 -0600139
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800140
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500141class Error(Exception):
Jean-Paul Calderone511cde02013-12-29 10:31:13 -0500142 """
143 An error occurred in an `OpenSSL.SSL` API.
144 """
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500145
146
147
148_raise_current_error = partial(_exception_from_error_queue, Error)
149
150
151class WantReadError(Error):
152 pass
153
154
155
156class WantWriteError(Error):
157 pass
158
159
160
161class WantX509LookupError(Error):
162 pass
163
164
165
166class ZeroReturnError(Error):
167 pass
168
169
170
171class SysCallError(Error):
172 pass
173
174
175
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800176class _VerifyHelper(object):
177 def __init__(self, connection, callback):
178 self._problems = []
179
180 @wraps(callback)
181 def wrapper(ok, store_ctx):
182 cert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500183 cert._x509 = _lib.X509_STORE_CTX_get_current_cert(store_ctx)
184 error_number = _lib.X509_STORE_CTX_get_error(store_ctx)
185 error_depth = _lib.X509_STORE_CTX_get_error_depth(store_ctx)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800186
187 try:
188 result = callback(connection, cert, error_number, error_depth, ok)
189 except Exception as e:
190 self._problems.append(e)
191 return 0
192 else:
193 if result:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500194 _lib.X509_STORE_CTX_set_error(store_ctx, _lib.X509_V_OK)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800195 return 1
196 else:
197 return 0
198
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500199 self.callback = _ffi.callback(
200 "int (*)(int, X509_STORE_CTX *)", wrapper)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800201
202
203 def raise_if_problem(self):
204 if self._problems:
205 try:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500206 _raise_current_error()
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800207 except Error:
208 pass
209 raise self._problems.pop(0)
210
211
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800212
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800213def _asFileDescriptor(obj):
214 fd = None
Konstantinos Koukopoulosc8b13ea2014-01-28 00:21:50 -0800215 if not isinstance(obj, integer_types):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800216 meth = getattr(obj, "fileno", None)
217 if meth is not None:
218 obj = meth()
219
Konstantinos Koukopoulosc8b13ea2014-01-28 00:21:50 -0800220 if isinstance(obj, integer_types):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800221 fd = obj
222
Konstantinos Koukopoulosc8b13ea2014-01-28 00:21:50 -0800223 if not isinstance(fd, integer_types):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800224 raise TypeError("argument must be an int, or have a fileno() method.")
225 elif fd < 0:
226 raise ValueError(
227 "file descriptor cannot be a negative integer (%i)" % (fd,))
228
229 return fd
230
231
232
Jean-Paul Calderoned39a3f62013-03-04 12:23:51 -0800233def SSLeay_version(type):
234 """
235 Return a string describing the version of OpenSSL in use.
236
237 :param type: One of the SSLEAY_ constants defined in this module.
238 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500239 return _ffi.string(_lib.SSLeay_version(type))
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800240
241
242
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800243class Session(object):
244 pass
245
246
247
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800248class Context(object):
249 """
250 :py:obj:`OpenSSL.SSL.Context` instances define the parameters for setting up
251 new SSL connections.
252 """
253 _methods = {
Andrew Dunhamec84a0a2014-02-24 12:41:37 -0800254 SSLv2_METHOD: "SSLv2_method",
Jean-Paul Calderonebe2bb422013-12-29 07:34:08 -0500255 SSLv3_METHOD: "SSLv3_method",
256 SSLv23_METHOD: "SSLv23_method",
257 TLSv1_METHOD: "TLSv1_method",
258 TLSv1_1_METHOD: "TLSv1_1_method",
259 TLSv1_2_METHOD: "TLSv1_2_method",
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800260 }
Jean-Paul Calderonebe2bb422013-12-29 07:34:08 -0500261 _methods = dict(
262 (identifier, getattr(_lib, name))
263 for (identifier, name) in _methods.items()
264 if getattr(_lib, name, None) is not None)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800265
Jean-Paul Calderone63157872013-03-20 16:43:38 -0700266
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800267 def __init__(self, method):
268 """
269 :param method: One of SSLv2_METHOD, SSLv3_METHOD, SSLv23_METHOD, or
270 TLSv1_METHOD.
271 """
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -0500272 if not isinstance(method, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800273 raise TypeError("method must be an integer")
274
275 try:
276 method_func = self._methods[method]
277 except KeyError:
278 raise ValueError("No such protocol")
279
280 method_obj = method_func()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500281 if method_obj == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500282 # TODO: This is untested.
283 _raise_current_error()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800284
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500285 context = _lib.SSL_CTX_new(method_obj)
286 if context == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500287 # TODO: This is untested.
288 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500289 context = _ffi.gc(context, _lib.SSL_CTX_free)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800290
291 self._context = context
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800292 self._passphrase_helper = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800293 self._passphrase_callback = None
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800294 self._passphrase_userdata = None
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800295 self._verify_helper = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800296 self._verify_callback = None
297 self._info_callback = None
298 self._tlsext_servername_callback = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800299 self._app_data = None
300
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -0800301 # SSL_CTX_set_app_data(self->ctx, self);
302 # SSL_CTX_set_mode(self->ctx, SSL_MODE_ENABLE_PARTIAL_WRITE |
303 # SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
304 # SSL_MODE_AUTO_RETRY);
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500305 self.set_mode(_lib.SSL_MODE_ENABLE_PARTIAL_WRITE)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800306
307
308 def load_verify_locations(self, cafile, capath=None):
309 """
310 Let SSL know where we can find trusted certificates for the certificate
311 chain
312
313 :param cafile: In which file we can find the certificates
314 :param capath: In which directory we can find the certificates
315 :return: None
316 """
317 if cafile is None:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500318 cafile = _ffi.NULL
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800319 elif not isinstance(cafile, bytes):
320 raise TypeError("cafile must be None or a byte string")
321
322 if capath is None:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500323 capath = _ffi.NULL
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800324 elif not isinstance(capath, bytes):
325 raise TypeError("capath must be None or a byte string")
326
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500327 load_result = _lib.SSL_CTX_load_verify_locations(self._context, cafile, capath)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800328 if not load_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500329 _raise_current_error()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800330
331
332 def _wrap_callback(self, callback):
333 @wraps(callback)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800334 def wrapper(size, verify, userdata):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800335 return callback(size, verify, self._passphrase_userdata)
336 return _PassphraseHelper(
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800337 FILETYPE_PEM, wrapper, more_args=True, truncate=True)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800338
339
340 def set_passwd_cb(self, callback, userdata=None):
341 """
342 Set the passphrase callback
343
344 :param callback: The Python callback to use
345 :param userdata: (optional) A Python object which will be given as
346 argument to the callback
347 :return: None
348 """
349 if not callable(callback):
350 raise TypeError("callback must be callable")
351
352 self._passphrase_helper = self._wrap_callback(callback)
353 self._passphrase_callback = self._passphrase_helper.callback
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500354 _lib.SSL_CTX_set_default_passwd_cb(
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800355 self._context, self._passphrase_callback)
356 self._passphrase_userdata = userdata
357
358
359 def set_default_verify_paths(self):
360 """
361 Use the platform-specific CA certificate locations
362
363 :return: None
364 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500365 set_result = _lib.SSL_CTX_set_default_verify_paths(self._context)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800366 if not set_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500367 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500368 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800369
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800370
371 def use_certificate_chain_file(self, certfile):
372 """
373 Load a certificate chain from a file
374
375 :param certfile: The name of the certificate chain file
376 :return: None
377 """
Jean-Paul Calderoned8607982014-01-18 10:30:55 -0500378 if isinstance(certfile, _text_type):
379 # Perhaps sys.getfilesystemencoding() could be better?
380 certfile = certfile.encode("utf-8")
381
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800382 if not isinstance(certfile, bytes):
Jean-Paul Calderoned8607982014-01-18 10:30:55 -0500383 raise TypeError("certfile must be bytes or unicode")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800384
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500385 result = _lib.SSL_CTX_use_certificate_chain_file(self._context, certfile)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800386 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500387 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800388
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800389
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800390 def use_certificate_file(self, certfile, filetype=FILETYPE_PEM):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800391 """
392 Load a certificate from a file
393
394 :param certfile: The name of the certificate file
395 :param filetype: (optional) The encoding of the file, default is PEM
396 :return: None
397 """
Jean-Paul Calderone684baf52014-01-18 10:31:19 -0500398 if isinstance(certfile, _text_type):
399 # Perhaps sys.getfilesystemencoding() could be better?
400 certfile = certfile.encode("utf-8")
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800401 if not isinstance(certfile, bytes):
Jean-Paul Calderone684baf52014-01-18 10:31:19 -0500402 raise TypeError("certfile must be bytes or unicode")
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -0500403 if not isinstance(filetype, integer_types):
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800404 raise TypeError("filetype must be an integer")
405
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500406 use_result = _lib.SSL_CTX_use_certificate_file(self._context, certfile, filetype)
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800407 if not use_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500408 _raise_current_error()
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800409
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800410
411 def use_certificate(self, cert):
412 """
413 Load a certificate from a X509 object
414
415 :param cert: The X509 object
416 :return: None
417 """
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800418 if not isinstance(cert, X509):
419 raise TypeError("cert must be an X509 instance")
420
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500421 use_result = _lib.SSL_CTX_use_certificate(self._context, cert._x509)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800422 if not use_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500423 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800424
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800425
426 def add_extra_chain_cert(self, certobj):
427 """
428 Add certificate to chain
429
430 :param certobj: The X509 certificate object to add to the chain
431 :return: None
432 """
433 if not isinstance(certobj, X509):
434 raise TypeError("certobj must be an X509 instance")
435
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500436 copy = _lib.X509_dup(certobj._x509)
437 add_result = _lib.SSL_CTX_add_extra_chain_cert(self._context, copy)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800438 if not add_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500439 # TODO: This is untested.
440 _lib.X509_free(copy)
441 _raise_current_error()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800442
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800443
444 def _raise_passphrase_exception(self):
445 if self._passphrase_helper is None:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500446 _raise_current_error()
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800447 exception = self._passphrase_helper.raise_if_problem(Error)
448 if exception is not None:
449 raise exception
450
451
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800452 def use_privatekey_file(self, keyfile, filetype=_unspecified):
453 """
454 Load a private key from a file
455
456 :param keyfile: The name of the key file
457 :param filetype: (optional) The encoding of the file, default is PEM
458 :return: None
459 """
Jean-Paul Calderone87e525a2014-01-18 10:31:51 -0500460 if isinstance(keyfile, _text_type):
461 # Perhaps sys.getfilesystemencoding() could be better?
462 keyfile = keyfile.encode("utf-8")
463
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800464 if not isinstance(keyfile, bytes):
465 raise TypeError("keyfile must be a byte string")
466
467 if filetype is _unspecified:
468 filetype = FILETYPE_PEM
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -0500469 elif not isinstance(filetype, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800470 raise TypeError("filetype must be an integer")
471
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500472 use_result = _lib.SSL_CTX_use_PrivateKey_file(
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800473 self._context, keyfile, filetype)
474 if not use_result:
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800475 self._raise_passphrase_exception()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800476
477
478 def use_privatekey(self, pkey):
479 """
480 Load a private key from a PKey object
481
482 :param pkey: The PKey object
483 :return: None
484 """
485 if not isinstance(pkey, PKey):
486 raise TypeError("pkey must be a PKey instance")
487
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500488 use_result = _lib.SSL_CTX_use_PrivateKey(self._context, pkey._pkey)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800489 if not use_result:
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800490 self._raise_passphrase_exception()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800491
492
493 def check_privatekey(self):
494 """
495 Check that the private key and certificate match up
496
497 :return: None (raises an exception if something's wrong)
498 """
499
500 def load_client_ca(self, cafile):
501 """
502 Load the trusted certificates that will be sent to the client (basically
503 telling the client "These are the guys I trust"). Does not actually
504 imply any of the certificates are trusted; that must be configured
505 separately.
506
507 :param cafile: The name of the certificates file
508 :return: None
509 """
510
511 def set_session_id(self, buf):
512 """
513 Set the session identifier. This is needed if you want to do session
514 resumption.
515
516 :param buf: A Python object that can be safely converted to a string
517 :returns: None
518 """
519
520 def set_session_cache_mode(self, mode):
521 """
522 Enable/disable session caching and specify the mode used.
523
524 :param mode: One or more of the SESS_CACHE_* flags (combine using
525 bitwise or)
526 :returns: The previously set caching mode.
527 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500528 if not isinstance(mode, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800529 raise TypeError("mode must be an integer")
530
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500531 return _lib.SSL_CTX_set_session_cache_mode(self._context, mode)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800532
533
534 def get_session_cache_mode(self):
535 """
536 :returns: The currently used cache mode.
537 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500538 return _lib.SSL_CTX_get_session_cache_mode(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800539
540
541 def set_verify(self, mode, callback):
542 """
543 Set the verify mode and verify callback
544
545 :param mode: The verify mode, this is either VERIFY_NONE or
546 VERIFY_PEER combined with possible other flags
547 :param callback: The Python callback to use
548 :return: None
549
550 See SSL_CTX_set_verify(3SSL) for further details.
551 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500552 if not isinstance(mode, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800553 raise TypeError("mode must be an integer")
554
555 if not callable(callback):
556 raise TypeError("callback must be callable")
557
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800558 self._verify_helper = _VerifyHelper(self, callback)
559 self._verify_callback = self._verify_helper.callback
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500560 _lib.SSL_CTX_set_verify(self._context, mode, self._verify_callback)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800561
562
563 def set_verify_depth(self, depth):
564 """
565 Set the verify depth
566
567 :param depth: An integer specifying the verify depth
568 :return: None
569 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500570 if not isinstance(depth, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800571 raise TypeError("depth must be an integer")
572
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500573 _lib.SSL_CTX_set_verify_depth(self._context, depth)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800574
575
576 def get_verify_mode(self):
577 """
578 Get the verify mode
579
580 :return: The verify mode
581 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500582 return _lib.SSL_CTX_get_verify_mode(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800583
584
585 def get_verify_depth(self):
586 """
587 Get the verify depth
588
589 :return: The verify depth
590 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500591 return _lib.SSL_CTX_get_verify_depth(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800592
593
594 def load_tmp_dh(self, dhfile):
595 """
596 Load parameters for Ephemeral Diffie-Hellman
597
598 :param dhfile: The file to load EDH parameters from
599 :return: None
600 """
601 if not isinstance(dhfile, bytes):
602 raise TypeError("dhfile must be a byte string")
603
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -0500604 bio = _lib.BIO_new_file(dhfile, b"r")
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500605 if bio == _ffi.NULL:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500606 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500607 bio = _ffi.gc(bio, _lib.BIO_free)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800608
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500609 dh = _lib.PEM_read_bio_DHparams(bio, _ffi.NULL, _ffi.NULL, _ffi.NULL)
610 dh = _ffi.gc(dh, _lib.DH_free)
611 _lib.SSL_CTX_set_tmp_dh(self._context, dh)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800612
613
Andy Lutomirskif05a2732014-03-13 17:22:25 -0700614 def set_tmp_ecdh_curve(self, curve_name):
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600615 """
Andy Lutomirski76a61332014-03-12 15:02:56 -0700616 Select a curve to use for ECDHE key exchange.
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600617
Andy Lutomirskif05a2732014-03-13 17:22:25 -0700618 The valid values of *curve_name* are the keys in
619 :py:data:OpenSSL.SSL.ELLIPTIC_CURVE_DESCRIPTIONS.
620
621 Raises a ``ValueError`` if the linked OpenSSL was not compiled with
622 elliptical curve support, or the specified curve is not available.
623
624 :param curve_name: The 'short name' of a curve, e.g. 'prime256v1'
625 :type curve_name: str
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600626 :return: None
627 """
628 if _lib.Cryptography_HAS_EC:
Andy Lutomirski5fb416a2014-04-04 12:19:52 -0700629 nid = _lib.OBJ_sn2nid(curve_name.encode('ascii'))
Andy Lutomirskif05a2732014-03-13 17:22:25 -0700630 if nid == _lib.NID_undef:
631 raise ValueError("No such OpenSSL object '%s'" % curve_name)
632 ecdh = _lib.EC_KEY_new_by_curve_name(nid)
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600633 if ecdh == _ffi.NULL:
634 raise ValueError(
635 "OpenSSL could not load the requested elliptic curve"
636 )
637 _lib.SSL_CTX_set_tmp_ecdh(self._context, ecdh)
638 _lib.EC_KEY_free(ecdh)
639 else:
640 raise ValueError("OpenSSL is compiled without ECDH support")
641
642
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800643 def set_cipher_list(self, cipher_list):
644 """
645 Change the cipher list
646
647 :param cipher_list: A cipher list, see ciphers(1)
648 :return: None
649 """
Jean-Paul Calderone63eab692014-01-18 10:19:56 -0500650 if isinstance(cipher_list, _text_type):
651 cipher_list = cipher_list.encode("ascii")
652
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800653 if not isinstance(cipher_list, bytes):
Jean-Paul Calderone63eab692014-01-18 10:19:56 -0500654 raise TypeError("cipher_list must be bytes or unicode")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800655
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500656 result = _lib.SSL_CTX_set_cipher_list(self._context, cipher_list)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800657 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500658 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800659
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800660
661 def set_client_ca_list(self, certificate_authorities):
662 """
663 Set the list of preferred client certificate signers for this server context.
664
665 This list of certificate authorities will be sent to the client when the
666 server requests a client certificate.
667
668 :param certificate_authorities: a sequence of X509Names.
669 :return: None
670 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500671 name_stack = _lib.sk_X509_NAME_new_null()
672 if name_stack == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500673 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500674 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800675
676 try:
677 for ca_name in certificate_authorities:
678 if not isinstance(ca_name, X509Name):
679 raise TypeError(
680 "client CAs must be X509Name objects, not %s objects" % (
681 type(ca_name).__name__,))
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500682 copy = _lib.X509_NAME_dup(ca_name._name)
683 if copy == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500684 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500685 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500686 push_result = _lib.sk_X509_NAME_push(name_stack, copy)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800687 if not push_result:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500688 _lib.X509_NAME_free(copy)
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500689 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800690 except:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500691 _lib.sk_X509_NAME_free(name_stack)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800692 raise
693
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500694 _lib.SSL_CTX_set_client_CA_list(self._context, name_stack)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800695
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800696
697 def add_client_ca(self, certificate_authority):
698 """
699 Add the CA certificate to the list of preferred signers for this context.
700
701 The list of certificate authorities will be sent to the client when the
702 server requests a client certificate.
703
704 :param certificate_authority: certificate authority's X509 certificate.
705 :return: None
706 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800707 if not isinstance(certificate_authority, X509):
708 raise TypeError("certificate_authority must be an X509 instance")
709
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500710 add_result = _lib.SSL_CTX_add_client_CA(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800711 self._context, certificate_authority._x509)
712 if not add_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500713 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500714 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800715
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800716
717 def set_timeout(self, timeout):
718 """
719 Set session timeout
720
721 :param timeout: The timeout in seconds
722 :return: The previous session timeout
723 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500724 if not isinstance(timeout, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800725 raise TypeError("timeout must be an integer")
726
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500727 return _lib.SSL_CTX_set_timeout(self._context, timeout)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800728
729
730 def get_timeout(self):
731 """
732 Get the session timeout
733
734 :return: The session timeout
735 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500736 return _lib.SSL_CTX_get_timeout(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800737
738
739 def set_info_callback(self, callback):
740 """
741 Set the info callback
742
743 :param callback: The Python callback to use
744 :return: None
745 """
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800746 @wraps(callback)
747 def wrapper(ssl, where, return_code):
Jean-Paul Calderonef2bbc9c2014-02-02 10:59:14 -0500748 callback(Connection._reverse_mapping[ssl], where, return_code)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500749 self._info_callback = _ffi.callback(
750 "void (*)(const SSL *, int, int)", wrapper)
751 _lib.SSL_CTX_set_info_callback(self._context, self._info_callback)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800752
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800753
754 def get_app_data(self):
755 """
756 Get the application data (supplied via set_app_data())
757
758 :return: The application data
759 """
760 return self._app_data
761
762
763 def set_app_data(self, data):
764 """
765 Set the application data (will be returned from get_app_data())
766
767 :param data: Any Python object
768 :return: None
769 """
770 self._app_data = data
771
772
773 def get_cert_store(self):
774 """
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500775 Get the certificate store for the context.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800776
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500777 :return: A X509Store object or None if it does not have one.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800778 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500779 store = _lib.SSL_CTX_get_cert_store(self._context)
780 if store == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500781 # TODO: This is untested.
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800782 return None
783
784 pystore = X509Store.__new__(X509Store)
785 pystore._store = store
786 return pystore
787
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800788
789 def set_options(self, options):
790 """
791 Add options. Options set before are not cleared!
792
793 :param options: The options to add.
794 :return: The new option bitmask.
795 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500796 if not isinstance(options, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800797 raise TypeError("options must be an integer")
798
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500799 return _lib.SSL_CTX_set_options(self._context, options)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800800
801
802 def set_mode(self, mode):
803 """
804 Add modes via bitmask. Modes set before are not cleared!
805
806 :param mode: The mode to add.
807 :return: The new mode bitmask.
808 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500809 if not isinstance(mode, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800810 raise TypeError("mode must be an integer")
811
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500812 return _lib.SSL_CTX_set_mode(self._context, mode)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800813
814
815 def set_tlsext_servername_callback(self, callback):
816 """
817 Specify a callback function to be called when clients specify a server name.
818
819 :param callback: The callback function. It will be invoked with one
820 argument, the Connection instance.
821 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800822 @wraps(callback)
823 def wrapper(ssl, alert, arg):
824 callback(Connection._reverse_mapping[ssl])
825 return 0
826
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500827 self._tlsext_servername_callback = _ffi.callback(
828 "int (*)(const SSL *, int *, void *)", wrapper)
829 _lib.SSL_CTX_set_tlsext_servername_callback(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800830 self._context, self._tlsext_servername_callback)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800831
832ContextType = Context
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800833
834
835
836class Connection(object):
837 """
838 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800839 _reverse_mapping = WeakValueDictionary()
840
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800841 def __init__(self, context, socket=None):
842 """
843 Create a new Connection object, using the given OpenSSL.SSL.Context
844 instance and socket.
845
846 :param context: An SSL Context to use for this connection
847 :param socket: The socket to use for transport layer
848 """
849 if not isinstance(context, Context):
850 raise TypeError("context must be a Context instance")
851
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500852 ssl = _lib.SSL_new(context._context)
853 self._ssl = _ffi.gc(ssl, _lib.SSL_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800854 self._context = context
855
856 self._reverse_mapping[self._ssl] = self
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800857
858 if socket is None:
859 self._socket = None
Jean-Paul Calderone73b15c22013-03-05 18:30:39 -0800860 # Don't set up any gc for these, SSL_free will take care of them.
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500861 self._into_ssl = _lib.BIO_new(_lib.BIO_s_mem())
862 self._from_ssl = _lib.BIO_new(_lib.BIO_s_mem())
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800863
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500864 if self._into_ssl == _ffi.NULL or self._from_ssl == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500865 # TODO: This is untested.
866 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800867
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500868 _lib.SSL_set_bio(self._ssl, self._into_ssl, self._from_ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800869 else:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800870 self._into_ssl = None
871 self._from_ssl = None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800872 self._socket = socket
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500873 set_result = _lib.SSL_set_fd(self._ssl, _asFileDescriptor(self._socket))
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800874 if not set_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500875 # TODO: This is untested.
876 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800877
878
879 def __getattr__(self, name):
880 """
881 Look up attributes on the wrapped socket object if they are not found on
882 the Connection object.
883 """
884 return getattr(self._socket, name)
885
886
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800887 def _raise_ssl_error(self, ssl, result):
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800888 if self._context._verify_helper is not None:
889 self._context._verify_helper.raise_if_problem()
890
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500891 error = _lib.SSL_get_error(ssl, result)
892 if error == _lib.SSL_ERROR_WANT_READ:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800893 raise WantReadError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500894 elif error == _lib.SSL_ERROR_WANT_WRITE:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -0700895 raise WantWriteError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500896 elif error == _lib.SSL_ERROR_ZERO_RETURN:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800897 raise ZeroReturnError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500898 elif error == _lib.SSL_ERROR_WANT_X509_LOOKUP:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500899 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -0700900 raise WantX509LookupError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500901 elif error == _lib.SSL_ERROR_SYSCALL:
902 if _lib.ERR_peek_error() == 0:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800903 if result < 0:
Konstantinos Koukopoulos541150d2014-01-31 01:00:19 +0200904 if platform == "win32":
905 errno = _ffi.getwinerror()[0]
906 else:
907 errno = _ffi.errno
908 raise SysCallError(errno, errorcode[errno])
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800909 else:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -0700910 raise SysCallError(-1, "Unexpected EOF")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800911 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500912 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500913 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500914 elif error == _lib.SSL_ERROR_NONE:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -0700915 pass
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800916 else:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500917 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800918
919
920 def get_context(self):
921 """
922 Get session context
923 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800924 return self._context
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800925
926
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800927 def set_context(self, context):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800928 """
929 Switch this connection to a new session context
930
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800931 :param context: A :py:class:`Context` instance giving the new session
932 context to use.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800933 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800934 if not isinstance(context, Context):
935 raise TypeError("context must be a Context instance")
936
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500937 _lib.SSL_set_SSL_CTX(self._ssl, context._context)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800938 self._context = context
939
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800940
941 def get_servername(self):
942 """
943 Retrieve the servername extension value if provided in the client hello
944 message, or None if there wasn't one.
945
946 :return: A byte string giving the server name or :py:data:`None`.
947 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500948 name = _lib.SSL_get_servername(self._ssl, _lib.TLSEXT_NAMETYPE_host_name)
949 if name == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800950 return None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800951
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500952 return _ffi.string(name)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800953
954
955 def set_tlsext_host_name(self, name):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800956 """
957 Set the value of the servername extension to send in the client hello.
958
959 :param name: A byte string giving the name.
960 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800961 if not isinstance(name, bytes):
962 raise TypeError("name must be a byte string")
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -0500963 elif b"\0" in name:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800964 raise TypeError("name must not contain NUL byte")
965
966 # XXX I guess this can fail sometimes?
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500967 _lib.SSL_set_tlsext_host_name(self._ssl, name)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800968
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800969
970 def pending(self):
971 """
972 Get the number of bytes that can be safely read from the connection
973
974 :return: The number of bytes available in the receive buffer.
975 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500976 return _lib.SSL_pending(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800977
978
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800979 def send(self, buf, flags=0):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800980 """
981 Send data on the connection. NOTE: If you get one of the WantRead,
982 WantWrite or WantX509Lookup exceptions on this, you have to call the
983 method again with the SAME buffer.
984
985 :param buf: The string to send
986 :param flags: (optional) Included for compatibility with the socket
987 API, the value is ignored
988 :return: The number of bytes written
989 """
Jean-Paul Calderone8fb53182013-12-30 08:35:49 -0500990 if isinstance(buf, _memoryview):
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -0800991 buf = buf.tobytes()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800992 if not isinstance(buf, bytes):
993 raise TypeError("data must be a byte string")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800994
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500995 result = _lib.SSL_write(self._ssl, buf, len(buf))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800996 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800997 return result
998 write = send
999
1000
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001001 def sendall(self, buf, flags=0):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001002 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001003 Send "all" data on the connection. This calls send() repeatedly until
1004 all data is sent. If an error occurs, it's impossible to tell how much
1005 data has been sent.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001006
1007 :param buf: The string to send
1008 :param flags: (optional) Included for compatibility with the socket
1009 API, the value is ignored
1010 :return: The number of bytes written
1011 """
Jean-Paul Calderone8fb53182013-12-30 08:35:49 -05001012 if isinstance(buf, _memoryview):
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -08001013 buf = buf.tobytes()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001014 if not isinstance(buf, bytes):
1015 raise TypeError("buf must be a byte string")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001016
1017 left_to_send = len(buf)
1018 total_sent = 0
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001019 data = _ffi.new("char[]", buf)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001020
1021 while left_to_send:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001022 result = _lib.SSL_write(self._ssl, data + total_sent, left_to_send)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001023 self._raise_ssl_error(self._ssl, result)
1024 total_sent += result
1025 left_to_send -= result
1026
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001027
1028 def recv(self, bufsiz, flags=None):
1029 """
1030 Receive data on the connection. NOTE: If you get one of the WantRead,
1031 WantWrite or WantX509Lookup exceptions on this, you have to call the
1032 method again with the SAME buffer.
1033
1034 :param bufsiz: The maximum number of bytes to read
1035 :param flags: (optional) Included for compatibility with the socket
1036 API, the value is ignored
1037 :return: The string read from the Connection
1038 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001039 buf = _ffi.new("char[]", bufsiz)
1040 result = _lib.SSL_read(self._ssl, buf, bufsiz)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001041 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001042 return _ffi.buffer(buf, result)[:]
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001043 read = recv
1044
1045
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001046 def _handle_bio_errors(self, bio, result):
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001047 if _lib.BIO_should_retry(bio):
1048 if _lib.BIO_should_read(bio):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001049 raise WantReadError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001050 elif _lib.BIO_should_write(bio):
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001051 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001052 raise WantWriteError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001053 elif _lib.BIO_should_io_special(bio):
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001054 # TODO: This is untested. I think io_special means the socket
1055 # BIO has a not-yet connected socket.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001056 raise ValueError("BIO_should_io_special")
1057 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001058 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001059 raise ValueError("unknown bio failure")
1060 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001061 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001062 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001063
1064
1065 def bio_read(self, bufsiz):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001066 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001067 When using non-socket connections this function reads the "dirty" data
1068 that would have traveled away on the network.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001069
1070 :param bufsiz: The maximum number of bytes to read
1071 :return: The string read.
1072 """
Jean-Paul Calderone97e041d2013-03-05 21:03:12 -08001073 if self._from_ssl is None:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001074 raise TypeError("Connection sock was not None")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001075
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -05001076 if not isinstance(bufsiz, integer_types):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001077 raise TypeError("bufsiz must be an integer")
1078
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001079 buf = _ffi.new("char[]", bufsiz)
1080 result = _lib.BIO_read(self._from_ssl, buf, bufsiz)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001081 if result <= 0:
1082 self._handle_bio_errors(self._from_ssl, result)
1083
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001084 return _ffi.buffer(buf, result)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001085
1086
1087 def bio_write(self, buf):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001088 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001089 When using non-socket connections this function sends "dirty" data that
1090 would have traveled in on the network.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001091
1092 :param buf: The string to put into the memory BIO.
1093 :return: The number of bytes written
1094 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001095 if self._into_ssl is None:
1096 raise TypeError("Connection sock was not None")
1097
1098 if not isinstance(buf, bytes):
1099 raise TypeError("buf must be a byte string")
1100
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001101 result = _lib.BIO_write(self._into_ssl, buf, len(buf))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001102 if result <= 0:
1103 self._handle_bio_errors(self._into_ssl, result)
1104 return result
1105
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001106
1107 def renegotiate(self):
1108 """
1109 Renegotiate the session
1110
1111 :return: True if the renegotiation can be started, false otherwise
1112 """
1113
1114 def do_handshake(self):
1115 """
1116 Perform an SSL handshake (usually called after renegotiate() or one of
1117 set_*_state()). This can raise the same exceptions as send and recv.
1118
1119 :return: None.
1120 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001121 result = _lib.SSL_do_handshake(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001122 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001123
1124
1125 def renegotiate_pending(self):
1126 """
1127 Check if there's a renegotiation in progress, it will return false once
1128 a renegotiation is finished.
1129
1130 :return: Whether there's a renegotiation in progress
1131 """
1132
1133 def total_renegotiations(self):
1134 """
1135 Find out the total number of renegotiations.
1136
1137 :return: The number of renegotiations.
1138 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001139 return _lib.SSL_total_renegotiations(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001140
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001141
1142 def connect(self, addr):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001143 """
1144 Connect to remote host and set up client-side SSL
1145
1146 :param addr: A remote address
1147 :return: What the socket's connect method returns
1148 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001149 _lib.SSL_set_connect_state(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001150 return self._socket.connect(addr)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001151
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001152
1153 def connect_ex(self, addr):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001154 """
1155 Connect to remote host and set up client-side SSL. Note that if the socket's
1156 connect_ex method doesn't return 0, SSL won't be initialized.
1157
1158 :param addr: A remove address
1159 :return: What the socket's connect_ex method returns
1160 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001161 connect_ex = self._socket.connect_ex
1162 self.set_connect_state()
1163 return connect_ex(addr)
1164
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001165
1166 def accept(self):
1167 """
1168 Accept incoming connection and set up SSL on it
1169
1170 :return: A (conn,addr) pair where conn is a Connection and addr is an
1171 address
1172 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001173 client, addr = self._socket.accept()
1174 conn = Connection(self._context, client)
1175 conn.set_accept_state()
1176 return (conn, addr)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001177
1178
1179 def bio_shutdown(self):
1180 """
1181 When using non-socket connections this function signals end of
1182 data on the input for this connection.
1183
1184 :return: None
1185 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001186 if self._from_ssl is None:
1187 raise TypeError("Connection sock was not None")
1188
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001189 _lib.BIO_set_mem_eof_return(self._into_ssl, 0)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001190
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001191
1192 def shutdown(self):
1193 """
1194 Send closure alert
1195
1196 :return: True if the shutdown completed successfully (i.e. both sides
1197 have sent closure alerts), false otherwise (i.e. you have to
1198 wait for a ZeroReturnError on a recv() method call
1199 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001200 result = _lib.SSL_shutdown(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001201 if result < 0:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001202 # TODO: This is untested.
1203 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001204 elif result > 0:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001205 return True
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001206 else:
1207 return False
1208
1209
1210 def get_cipher_list(self):
1211 """
1212 Get the session cipher list
1213
1214 :return: A list of cipher strings
1215 """
1216 ciphers = []
1217 for i in count():
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001218 result = _lib.SSL_get_cipher_list(self._ssl, i)
1219 if result == _ffi.NULL:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001220 break
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001221 ciphers.append(_native(_ffi.string(result)))
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001222 return ciphers
1223
1224
1225 def get_client_ca_list(self):
1226 """
1227 Get CAs whose certificates are suggested for client authentication.
1228
1229 :return: If this is a server connection, a list of X509Names representing
1230 the acceptable CAs as set by :py:meth:`OpenSSL.SSL.Context.set_client_ca_list` or
1231 :py:meth:`OpenSSL.SSL.Context.add_client_ca`. If this is a client connection,
1232 the list of such X509Names sent by the server, or an empty list if that
1233 has not yet happened.
1234 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001235 ca_names = _lib.SSL_get_client_CA_list(self._ssl)
1236 if ca_names == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001237 # TODO: This is untested.
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001238 return []
1239
1240 result = []
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001241 for i in range(_lib.sk_X509_NAME_num(ca_names)):
1242 name = _lib.sk_X509_NAME_value(ca_names, i)
1243 copy = _lib.X509_NAME_dup(name)
1244 if copy == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001245 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001246 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001247
1248 pyname = X509Name.__new__(X509Name)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001249 pyname._name = _ffi.gc(copy, _lib.X509_NAME_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001250 result.append(pyname)
1251 return result
1252
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001253
1254 def makefile(self):
1255 """
1256 The makefile() method is not implemented, since there is no dup semantics
1257 for SSL connections
1258
1259 :raise NotImplementedError
1260 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001261 raise NotImplementedError("Cannot make file object of OpenSSL.SSL.Connection")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001262
1263
1264 def get_app_data(self):
1265 """
1266 Get application data
1267
1268 :return: The application data
1269 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001270 return self._app_data
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001271
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001272
1273 def set_app_data(self, data):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001274 """
1275 Set application data
1276
1277 :param data - The application data
1278 :return: None
1279 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001280 self._app_data = data
1281
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001282
1283 def get_shutdown(self):
1284 """
1285 Get shutdown state
1286
1287 :return: The shutdown state, a bitvector of SENT_SHUTDOWN, RECEIVED_SHUTDOWN.
1288 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001289 return _lib.SSL_get_shutdown(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001290
1291
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001292 def set_shutdown(self, state):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001293 """
1294 Set shutdown state
1295
1296 :param state - bitvector of SENT_SHUTDOWN, RECEIVED_SHUTDOWN.
1297 :return: None
1298 """
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -05001299 if not isinstance(state, integer_types):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001300 raise TypeError("state must be an integer")
1301
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001302 _lib.SSL_set_shutdown(self._ssl, state)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001303
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001304
1305 def state_string(self):
1306 """
1307 Get a verbose state description
1308
1309 :return: A string representing the state
1310 """
1311
1312 def server_random(self):
1313 """
1314 Get a copy of the server hello nonce.
1315
1316 :return: A string representing the state
1317 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001318 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001319 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001320 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001321 self._ssl.s3.server_random,
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001322 _lib.SSL3_RANDOM_SIZE)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001323
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001324
1325 def client_random(self):
1326 """
1327 Get a copy of the client hello nonce.
1328
1329 :return: A string representing the state
1330 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001331 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001332 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001333 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001334 self._ssl.s3.client_random,
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001335 _lib.SSL3_RANDOM_SIZE)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001336
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001337
1338 def master_key(self):
1339 """
1340 Get a copy of the master key.
1341
1342 :return: A string representing the state
1343 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001344 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001345 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001346 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001347 self._ssl.session.master_key,
1348 self._ssl.session.master_key_length)[:]
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001349
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001350
1351 def sock_shutdown(self, *args, **kwargs):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001352 """
1353 See shutdown(2)
1354
1355 :return: What the socket's shutdown() method returns
1356 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001357 return self._socket.shutdown(*args, **kwargs)
1358
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001359
1360 def get_peer_certificate(self):
1361 """
1362 Retrieve the other side's certificate (if any)
1363
1364 :return: The peer's certificate
1365 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001366 cert = _lib.SSL_get_peer_certificate(self._ssl)
1367 if cert != _ffi.NULL:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001368 pycert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001369 pycert._x509 = _ffi.gc(cert, _lib.X509_free)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001370 return pycert
1371 return None
1372
1373
1374 def get_peer_cert_chain(self):
1375 """
1376 Retrieve the other side's certificate (if any)
1377
1378 :return: A list of X509 instances giving the peer's certificate chain,
1379 or None if it does not have one.
1380 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001381 cert_stack = _lib.SSL_get_peer_cert_chain(self._ssl)
1382 if cert_stack == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001383 return None
1384
1385 result = []
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001386 for i in range(_lib.sk_X509_num(cert_stack)):
Jean-Paul Calderone73b15c22013-03-05 18:30:39 -08001387 # TODO could incref instead of dup here
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001388 cert = _lib.X509_dup(_lib.sk_X509_value(cert_stack, i))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001389 pycert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001390 pycert._x509 = _ffi.gc(cert, _lib.X509_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001391 result.append(pycert)
1392 return result
1393
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001394
1395 def want_read(self):
1396 """
1397 Checks if more data has to be read from the transport layer to complete an
1398 operation.
1399
1400 :return: True iff more data has to be read
1401 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001402 return _lib.SSL_want_read(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001403
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001404
1405 def want_write(self):
1406 """
1407 Checks if there is data to write to the transport layer to complete an
1408 operation.
1409
1410 :return: True iff there is data to write
1411 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001412 return _lib.SSL_want_write(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001413
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001414
1415 def set_accept_state(self):
1416 """
1417 Set the connection to work in server mode. The handshake will be handled
1418 automatically by read/write.
1419
1420 :return: None
1421 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001422 _lib.SSL_set_accept_state(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001423
1424
1425 def set_connect_state(self):
1426 """
1427 Set the connection to work in client mode. The handshake will be handled
1428 automatically by read/write.
1429
1430 :return: None
1431 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001432 _lib.SSL_set_connect_state(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001433
1434
1435 def get_session(self):
1436 """
1437 Returns the Session currently used.
1438
1439 @return: An instance of :py:class:`OpenSSL.SSL.Session` or :py:obj:`None` if
1440 no session exists.
1441 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001442 session = _lib.SSL_get1_session(self._ssl)
1443 if session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001444 return None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001445
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001446 pysession = Session.__new__(Session)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001447 pysession._session = _ffi.gc(session, _lib.SSL_SESSION_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001448 return pysession
1449
1450
1451 def set_session(self, session):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001452 """
1453 Set the session to be used when the TLS/SSL connection is established.
1454
1455 :param session: A Session instance representing the session to use.
1456 :returns: None
1457 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001458 if not isinstance(session, Session):
1459 raise TypeError("session must be a Session instance")
1460
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001461 result = _lib.SSL_set_session(self._ssl, session._session)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001462 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001463 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001464
1465ConnectionType = Connection
Jean-Paul Calderone11ed8e82014-01-18 10:21:50 -05001466
Jean-Paul Calderonefab157b2014-01-18 11:21:38 -05001467# This is similar to the initialization calls at the end of OpenSSL/crypto.py
1468# but is exercised mostly by the Context initializer.
Jean-Paul Calderone11ed8e82014-01-18 10:21:50 -05001469_lib.SSL_library_init()