blob: 03aa47beefa92c30f5831f1a36d1e330046cc7f5 [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
84OP_NO_TICKET = _lib.SSL_OP_NO_TICKET
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -080085
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050086OP_ALL = _lib.SSL_OP_ALL
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080087
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050088VERIFY_PEER = _lib.SSL_VERIFY_PEER
89VERIFY_FAIL_IF_NO_PEER_CERT = _lib.SSL_VERIFY_FAIL_IF_NO_PEER_CERT
90VERIFY_CLIENT_ONCE = _lib.SSL_VERIFY_CLIENT_ONCE
91VERIFY_NONE = _lib.SSL_VERIFY_NONE
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080092
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050093SESS_CACHE_OFF = _lib.SSL_SESS_CACHE_OFF
94SESS_CACHE_CLIENT = _lib.SSL_SESS_CACHE_CLIENT
95SESS_CACHE_SERVER = _lib.SSL_SESS_CACHE_SERVER
96SESS_CACHE_BOTH = _lib.SSL_SESS_CACHE_BOTH
97SESS_CACHE_NO_AUTO_CLEAR = _lib.SSL_SESS_CACHE_NO_AUTO_CLEAR
98SESS_CACHE_NO_INTERNAL_LOOKUP = _lib.SSL_SESS_CACHE_NO_INTERNAL_LOOKUP
99SESS_CACHE_NO_INTERNAL_STORE = _lib.SSL_SESS_CACHE_NO_INTERNAL_STORE
100SESS_CACHE_NO_INTERNAL = _lib.SSL_SESS_CACHE_NO_INTERNAL
Jean-Paul Calderoned39a3f62013-03-04 12:23:51 -0800101
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500102SSL_ST_CONNECT = _lib.SSL_ST_CONNECT
103SSL_ST_ACCEPT = _lib.SSL_ST_ACCEPT
104SSL_ST_MASK = _lib.SSL_ST_MASK
105SSL_ST_INIT = _lib.SSL_ST_INIT
106SSL_ST_BEFORE = _lib.SSL_ST_BEFORE
107SSL_ST_OK = _lib.SSL_ST_OK
108SSL_ST_RENEGOTIATE = _lib.SSL_ST_RENEGOTIATE
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800109
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500110SSL_CB_LOOP = _lib.SSL_CB_LOOP
111SSL_CB_EXIT = _lib.SSL_CB_EXIT
112SSL_CB_READ = _lib.SSL_CB_READ
113SSL_CB_WRITE = _lib.SSL_CB_WRITE
114SSL_CB_ALERT = _lib.SSL_CB_ALERT
115SSL_CB_READ_ALERT = _lib.SSL_CB_READ_ALERT
116SSL_CB_WRITE_ALERT = _lib.SSL_CB_WRITE_ALERT
117SSL_CB_ACCEPT_LOOP = _lib.SSL_CB_ACCEPT_LOOP
118SSL_CB_ACCEPT_EXIT = _lib.SSL_CB_ACCEPT_EXIT
119SSL_CB_CONNECT_LOOP = _lib.SSL_CB_CONNECT_LOOP
120SSL_CB_CONNECT_EXIT = _lib.SSL_CB_CONNECT_EXIT
121SSL_CB_HANDSHAKE_START = _lib.SSL_CB_HANDSHAKE_START
122SSL_CB_HANDSHAKE_DONE = _lib.SSL_CB_HANDSHAKE_DONE
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800123
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800124
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600125NID_X9_62_prime192v1 = _lib.NID_X9_62_prime192v1
126NID_X9_62_prime192v2 = _lib.NID_X9_62_prime192v2
127NID_X9_62_prime192v3 = _lib.NID_X9_62_prime192v3
128NID_X9_62_prime239v1 = _lib.NID_X9_62_prime239v1
129NID_X9_62_prime239v2 = _lib.NID_X9_62_prime239v2
130NID_X9_62_prime239v3 = _lib.NID_X9_62_prime239v3
131NID_X9_62_prime256v1 = _lib.NID_X9_62_prime256v1
132
Alex Gaynor807853c2014-01-17 13:03:27 -0600133_Cryptography_HAS_EC = _lib.Cryptography_HAS_EC
Alex Gaynor12dc0842014-01-17 12:51:31 -0600134
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600135
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500136class Error(Exception):
Jean-Paul Calderone511cde02013-12-29 10:31:13 -0500137 """
138 An error occurred in an `OpenSSL.SSL` API.
139 """
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500140
141
142
143_raise_current_error = partial(_exception_from_error_queue, Error)
144
145
146class WantReadError(Error):
147 pass
148
149
150
151class WantWriteError(Error):
152 pass
153
154
155
156class WantX509LookupError(Error):
157 pass
158
159
160
161class ZeroReturnError(Error):
162 pass
163
164
165
166class SysCallError(Error):
167 pass
168
169
170
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800171class _VerifyHelper(object):
172 def __init__(self, connection, callback):
173 self._problems = []
174
175 @wraps(callback)
176 def wrapper(ok, store_ctx):
177 cert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500178 cert._x509 = _lib.X509_STORE_CTX_get_current_cert(store_ctx)
179 error_number = _lib.X509_STORE_CTX_get_error(store_ctx)
180 error_depth = _lib.X509_STORE_CTX_get_error_depth(store_ctx)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800181
182 try:
183 result = callback(connection, cert, error_number, error_depth, ok)
184 except Exception as e:
185 self._problems.append(e)
186 return 0
187 else:
188 if result:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500189 _lib.X509_STORE_CTX_set_error(store_ctx, _lib.X509_V_OK)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800190 return 1
191 else:
192 return 0
193
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500194 self.callback = _ffi.callback(
195 "int (*)(int, X509_STORE_CTX *)", wrapper)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800196
197
198 def raise_if_problem(self):
199 if self._problems:
200 try:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500201 _raise_current_error()
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800202 except Error:
203 pass
204 raise self._problems.pop(0)
205
206
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800207
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800208def _asFileDescriptor(obj):
209 fd = None
Konstantinos Koukopoulosc8b13ea2014-01-28 00:21:50 -0800210 if not isinstance(obj, integer_types):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800211 meth = getattr(obj, "fileno", None)
212 if meth is not None:
213 obj = meth()
214
Konstantinos Koukopoulosc8b13ea2014-01-28 00:21:50 -0800215 if isinstance(obj, integer_types):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800216 fd = obj
217
Konstantinos Koukopoulosc8b13ea2014-01-28 00:21:50 -0800218 if not isinstance(fd, integer_types):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800219 raise TypeError("argument must be an int, or have a fileno() method.")
220 elif fd < 0:
221 raise ValueError(
222 "file descriptor cannot be a negative integer (%i)" % (fd,))
223
224 return fd
225
226
227
Jean-Paul Calderoned39a3f62013-03-04 12:23:51 -0800228def SSLeay_version(type):
229 """
230 Return a string describing the version of OpenSSL in use.
231
232 :param type: One of the SSLEAY_ constants defined in this module.
233 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500234 return _ffi.string(_lib.SSLeay_version(type))
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800235
236
237
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800238class Session(object):
239 pass
240
241
242
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800243class Context(object):
244 """
245 :py:obj:`OpenSSL.SSL.Context` instances define the parameters for setting up
246 new SSL connections.
247 """
248 _methods = {
Jean-Paul Calderonebe2bb422013-12-29 07:34:08 -0500249 SSLv3_METHOD: "SSLv3_method",
250 SSLv23_METHOD: "SSLv23_method",
251 TLSv1_METHOD: "TLSv1_method",
252 TLSv1_1_METHOD: "TLSv1_1_method",
253 TLSv1_2_METHOD: "TLSv1_2_method",
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800254 }
Jean-Paul Calderonebe2bb422013-12-29 07:34:08 -0500255 _methods = dict(
256 (identifier, getattr(_lib, name))
257 for (identifier, name) in _methods.items()
258 if getattr(_lib, name, None) is not None)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800259
Jean-Paul Calderone63157872013-03-20 16:43:38 -0700260
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800261 def __init__(self, method):
262 """
263 :param method: One of SSLv2_METHOD, SSLv3_METHOD, SSLv23_METHOD, or
264 TLSv1_METHOD.
265 """
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -0500266 if not isinstance(method, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800267 raise TypeError("method must be an integer")
268
269 try:
270 method_func = self._methods[method]
271 except KeyError:
272 raise ValueError("No such protocol")
273
274 method_obj = method_func()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500275 if method_obj == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500276 # TODO: This is untested.
277 _raise_current_error()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800278
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500279 context = _lib.SSL_CTX_new(method_obj)
280 if context == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500281 # TODO: This is untested.
282 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500283 context = _ffi.gc(context, _lib.SSL_CTX_free)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800284
285 self._context = context
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800286 self._passphrase_helper = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800287 self._passphrase_callback = None
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800288 self._passphrase_userdata = None
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800289 self._verify_helper = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800290 self._verify_callback = None
291 self._info_callback = None
292 self._tlsext_servername_callback = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800293 self._app_data = None
294
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -0800295 # SSL_CTX_set_app_data(self->ctx, self);
296 # SSL_CTX_set_mode(self->ctx, SSL_MODE_ENABLE_PARTIAL_WRITE |
297 # SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
298 # SSL_MODE_AUTO_RETRY);
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500299 self.set_mode(_lib.SSL_MODE_ENABLE_PARTIAL_WRITE)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800300
301
302 def load_verify_locations(self, cafile, capath=None):
303 """
304 Let SSL know where we can find trusted certificates for the certificate
305 chain
306
307 :param cafile: In which file we can find the certificates
308 :param capath: In which directory we can find the certificates
309 :return: None
310 """
311 if cafile is None:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500312 cafile = _ffi.NULL
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800313 elif not isinstance(cafile, bytes):
314 raise TypeError("cafile must be None or a byte string")
315
316 if capath is None:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500317 capath = _ffi.NULL
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800318 elif not isinstance(capath, bytes):
319 raise TypeError("capath must be None or a byte string")
320
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500321 load_result = _lib.SSL_CTX_load_verify_locations(self._context, cafile, capath)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800322 if not load_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500323 _raise_current_error()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800324
325
326 def _wrap_callback(self, callback):
327 @wraps(callback)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800328 def wrapper(size, verify, userdata):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800329 return callback(size, verify, self._passphrase_userdata)
330 return _PassphraseHelper(
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800331 FILETYPE_PEM, wrapper, more_args=True, truncate=True)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800332
333
334 def set_passwd_cb(self, callback, userdata=None):
335 """
336 Set the passphrase callback
337
338 :param callback: The Python callback to use
339 :param userdata: (optional) A Python object which will be given as
340 argument to the callback
341 :return: None
342 """
343 if not callable(callback):
344 raise TypeError("callback must be callable")
345
346 self._passphrase_helper = self._wrap_callback(callback)
347 self._passphrase_callback = self._passphrase_helper.callback
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500348 _lib.SSL_CTX_set_default_passwd_cb(
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800349 self._context, self._passphrase_callback)
350 self._passphrase_userdata = userdata
351
352
353 def set_default_verify_paths(self):
354 """
355 Use the platform-specific CA certificate locations
356
357 :return: None
358 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500359 set_result = _lib.SSL_CTX_set_default_verify_paths(self._context)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800360 if not set_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500361 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500362 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800363
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800364
365 def use_certificate_chain_file(self, certfile):
366 """
367 Load a certificate chain from a file
368
369 :param certfile: The name of the certificate chain file
370 :return: None
371 """
Jean-Paul Calderoned8607982014-01-18 10:30:55 -0500372 if isinstance(certfile, _text_type):
373 # Perhaps sys.getfilesystemencoding() could be better?
374 certfile = certfile.encode("utf-8")
375
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800376 if not isinstance(certfile, bytes):
Jean-Paul Calderoned8607982014-01-18 10:30:55 -0500377 raise TypeError("certfile must be bytes or unicode")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800378
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500379 result = _lib.SSL_CTX_use_certificate_chain_file(self._context, certfile)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800380 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500381 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800382
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800383
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800384 def use_certificate_file(self, certfile, filetype=FILETYPE_PEM):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800385 """
386 Load a certificate from a file
387
388 :param certfile: The name of the certificate file
389 :param filetype: (optional) The encoding of the file, default is PEM
390 :return: None
391 """
Jean-Paul Calderone684baf52014-01-18 10:31:19 -0500392 if isinstance(certfile, _text_type):
393 # Perhaps sys.getfilesystemencoding() could be better?
394 certfile = certfile.encode("utf-8")
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800395 if not isinstance(certfile, bytes):
Jean-Paul Calderone684baf52014-01-18 10:31:19 -0500396 raise TypeError("certfile must be bytes or unicode")
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -0500397 if not isinstance(filetype, integer_types):
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800398 raise TypeError("filetype must be an integer")
399
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500400 use_result = _lib.SSL_CTX_use_certificate_file(self._context, certfile, filetype)
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800401 if not use_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500402 _raise_current_error()
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800403
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800404
405 def use_certificate(self, cert):
406 """
407 Load a certificate from a X509 object
408
409 :param cert: The X509 object
410 :return: None
411 """
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800412 if not isinstance(cert, X509):
413 raise TypeError("cert must be an X509 instance")
414
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500415 use_result = _lib.SSL_CTX_use_certificate(self._context, cert._x509)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800416 if not use_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500417 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800418
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800419
420 def add_extra_chain_cert(self, certobj):
421 """
422 Add certificate to chain
423
424 :param certobj: The X509 certificate object to add to the chain
425 :return: None
426 """
427 if not isinstance(certobj, X509):
428 raise TypeError("certobj must be an X509 instance")
429
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500430 copy = _lib.X509_dup(certobj._x509)
431 add_result = _lib.SSL_CTX_add_extra_chain_cert(self._context, copy)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800432 if not add_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500433 # TODO: This is untested.
434 _lib.X509_free(copy)
435 _raise_current_error()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800436
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800437
438 def _raise_passphrase_exception(self):
439 if self._passphrase_helper is None:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500440 _raise_current_error()
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800441 exception = self._passphrase_helper.raise_if_problem(Error)
442 if exception is not None:
443 raise exception
444
445
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800446 def use_privatekey_file(self, keyfile, filetype=_unspecified):
447 """
448 Load a private key from a file
449
450 :param keyfile: The name of the key file
451 :param filetype: (optional) The encoding of the file, default is PEM
452 :return: None
453 """
Jean-Paul Calderone87e525a2014-01-18 10:31:51 -0500454 if isinstance(keyfile, _text_type):
455 # Perhaps sys.getfilesystemencoding() could be better?
456 keyfile = keyfile.encode("utf-8")
457
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800458 if not isinstance(keyfile, bytes):
459 raise TypeError("keyfile must be a byte string")
460
461 if filetype is _unspecified:
462 filetype = FILETYPE_PEM
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -0500463 elif not isinstance(filetype, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800464 raise TypeError("filetype must be an integer")
465
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500466 use_result = _lib.SSL_CTX_use_PrivateKey_file(
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800467 self._context, keyfile, filetype)
468 if not use_result:
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800469 self._raise_passphrase_exception()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800470
471
472 def use_privatekey(self, pkey):
473 """
474 Load a private key from a PKey object
475
476 :param pkey: The PKey object
477 :return: None
478 """
479 if not isinstance(pkey, PKey):
480 raise TypeError("pkey must be a PKey instance")
481
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500482 use_result = _lib.SSL_CTX_use_PrivateKey(self._context, pkey._pkey)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800483 if not use_result:
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800484 self._raise_passphrase_exception()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800485
486
487 def check_privatekey(self):
488 """
489 Check that the private key and certificate match up
490
491 :return: None (raises an exception if something's wrong)
492 """
493
494 def load_client_ca(self, cafile):
495 """
496 Load the trusted certificates that will be sent to the client (basically
497 telling the client "These are the guys I trust"). Does not actually
498 imply any of the certificates are trusted; that must be configured
499 separately.
500
501 :param cafile: The name of the certificates file
502 :return: None
503 """
504
505 def set_session_id(self, buf):
506 """
507 Set the session identifier. This is needed if you want to do session
508 resumption.
509
510 :param buf: A Python object that can be safely converted to a string
511 :returns: None
512 """
513
514 def set_session_cache_mode(self, mode):
515 """
516 Enable/disable session caching and specify the mode used.
517
518 :param mode: One or more of the SESS_CACHE_* flags (combine using
519 bitwise or)
520 :returns: The previously set caching mode.
521 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500522 if not isinstance(mode, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800523 raise TypeError("mode must be an integer")
524
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500525 return _lib.SSL_CTX_set_session_cache_mode(self._context, mode)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800526
527
528 def get_session_cache_mode(self):
529 """
530 :returns: The currently used cache mode.
531 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500532 return _lib.SSL_CTX_get_session_cache_mode(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800533
534
535 def set_verify(self, mode, callback):
536 """
537 Set the verify mode and verify callback
538
539 :param mode: The verify mode, this is either VERIFY_NONE or
540 VERIFY_PEER combined with possible other flags
541 :param callback: The Python callback to use
542 :return: None
543
544 See SSL_CTX_set_verify(3SSL) for further details.
545 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500546 if not isinstance(mode, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800547 raise TypeError("mode must be an integer")
548
549 if not callable(callback):
550 raise TypeError("callback must be callable")
551
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800552 self._verify_helper = _VerifyHelper(self, callback)
553 self._verify_callback = self._verify_helper.callback
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500554 _lib.SSL_CTX_set_verify(self._context, mode, self._verify_callback)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800555
556
557 def set_verify_depth(self, depth):
558 """
559 Set the verify depth
560
561 :param depth: An integer specifying the verify depth
562 :return: None
563 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500564 if not isinstance(depth, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800565 raise TypeError("depth must be an integer")
566
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500567 _lib.SSL_CTX_set_verify_depth(self._context, depth)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800568
569
570 def get_verify_mode(self):
571 """
572 Get the verify mode
573
574 :return: The verify mode
575 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500576 return _lib.SSL_CTX_get_verify_mode(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800577
578
579 def get_verify_depth(self):
580 """
581 Get the verify depth
582
583 :return: The verify depth
584 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500585 return _lib.SSL_CTX_get_verify_depth(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800586
587
588 def load_tmp_dh(self, dhfile):
589 """
590 Load parameters for Ephemeral Diffie-Hellman
591
592 :param dhfile: The file to load EDH parameters from
593 :return: None
594 """
595 if not isinstance(dhfile, bytes):
596 raise TypeError("dhfile must be a byte string")
597
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -0500598 bio = _lib.BIO_new_file(dhfile, b"r")
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500599 if bio == _ffi.NULL:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500600 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500601 bio = _ffi.gc(bio, _lib.BIO_free)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800602
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500603 dh = _lib.PEM_read_bio_DHparams(bio, _ffi.NULL, _ffi.NULL, _ffi.NULL)
604 dh = _ffi.gc(dh, _lib.DH_free)
605 _lib.SSL_CTX_set_tmp_dh(self._context, dh)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800606
607
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600608 def set_tmp_ecdh_by_curve_name(self, curve_name):
609 """
610 Configure this connection to people to use Elliptical Curve
611 Diffie-Hellman key exchanges.
612
Alex Gaynora683fc02014-01-17 12:45:56 -0600613 :param curve_name: One of the named curve constants.
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600614 :return: None
615 """
616 if _lib.Cryptography_HAS_EC:
617 ecdh = _lib.EC_KEY_new_by_curve_name(curve_name)
618 if ecdh == _ffi.NULL:
619 raise ValueError(
620 "OpenSSL could not load the requested elliptic curve"
621 )
622 _lib.SSL_CTX_set_tmp_ecdh(self._context, ecdh)
623 _lib.EC_KEY_free(ecdh)
624 else:
625 raise ValueError("OpenSSL is compiled without ECDH support")
626
627
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800628 def set_cipher_list(self, cipher_list):
629 """
630 Change the cipher list
631
632 :param cipher_list: A cipher list, see ciphers(1)
633 :return: None
634 """
Jean-Paul Calderone63eab692014-01-18 10:19:56 -0500635 if isinstance(cipher_list, _text_type):
636 cipher_list = cipher_list.encode("ascii")
637
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800638 if not isinstance(cipher_list, bytes):
Jean-Paul Calderone63eab692014-01-18 10:19:56 -0500639 raise TypeError("cipher_list must be bytes or unicode")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800640
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500641 result = _lib.SSL_CTX_set_cipher_list(self._context, cipher_list)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800642 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500643 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800644
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800645
646 def set_client_ca_list(self, certificate_authorities):
647 """
648 Set the list of preferred client certificate signers for this server context.
649
650 This list of certificate authorities will be sent to the client when the
651 server requests a client certificate.
652
653 :param certificate_authorities: a sequence of X509Names.
654 :return: None
655 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500656 name_stack = _lib.sk_X509_NAME_new_null()
657 if name_stack == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500658 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500659 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800660
661 try:
662 for ca_name in certificate_authorities:
663 if not isinstance(ca_name, X509Name):
664 raise TypeError(
665 "client CAs must be X509Name objects, not %s objects" % (
666 type(ca_name).__name__,))
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500667 copy = _lib.X509_NAME_dup(ca_name._name)
668 if copy == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500669 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500670 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500671 push_result = _lib.sk_X509_NAME_push(name_stack, copy)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800672 if not push_result:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500673 _lib.X509_NAME_free(copy)
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500674 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800675 except:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500676 _lib.sk_X509_NAME_free(name_stack)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800677 raise
678
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500679 _lib.SSL_CTX_set_client_CA_list(self._context, name_stack)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800680
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800681
682 def add_client_ca(self, certificate_authority):
683 """
684 Add the CA certificate to the list of preferred signers for this context.
685
686 The list of certificate authorities will be sent to the client when the
687 server requests a client certificate.
688
689 :param certificate_authority: certificate authority's X509 certificate.
690 :return: None
691 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800692 if not isinstance(certificate_authority, X509):
693 raise TypeError("certificate_authority must be an X509 instance")
694
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500695 add_result = _lib.SSL_CTX_add_client_CA(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800696 self._context, certificate_authority._x509)
697 if not add_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500698 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500699 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800700
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800701
702 def set_timeout(self, timeout):
703 """
704 Set session timeout
705
706 :param timeout: The timeout in seconds
707 :return: The previous session timeout
708 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500709 if not isinstance(timeout, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800710 raise TypeError("timeout must be an integer")
711
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500712 return _lib.SSL_CTX_set_timeout(self._context, timeout)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800713
714
715 def get_timeout(self):
716 """
717 Get the session timeout
718
719 :return: The session timeout
720 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500721 return _lib.SSL_CTX_get_timeout(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800722
723
724 def set_info_callback(self, callback):
725 """
726 Set the info callback
727
728 :param callback: The Python callback to use
729 :return: None
730 """
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800731 @wraps(callback)
732 def wrapper(ssl, where, return_code):
Jean-Paul Calderonef2bbc9c2014-02-02 10:59:14 -0500733 callback(Connection._reverse_mapping[ssl], where, return_code)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500734 self._info_callback = _ffi.callback(
735 "void (*)(const SSL *, int, int)", wrapper)
736 _lib.SSL_CTX_set_info_callback(self._context, self._info_callback)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800737
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800738
739 def get_app_data(self):
740 """
741 Get the application data (supplied via set_app_data())
742
743 :return: The application data
744 """
745 return self._app_data
746
747
748 def set_app_data(self, data):
749 """
750 Set the application data (will be returned from get_app_data())
751
752 :param data: Any Python object
753 :return: None
754 """
755 self._app_data = data
756
757
758 def get_cert_store(self):
759 """
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500760 Get the certificate store for the context.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800761
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500762 :return: A X509Store object or None if it does not have one.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800763 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500764 store = _lib.SSL_CTX_get_cert_store(self._context)
765 if store == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500766 # TODO: This is untested.
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800767 return None
768
769 pystore = X509Store.__new__(X509Store)
770 pystore._store = store
771 return pystore
772
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800773
774 def set_options(self, options):
775 """
776 Add options. Options set before are not cleared!
777
778 :param options: The options to add.
779 :return: The new option bitmask.
780 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500781 if not isinstance(options, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800782 raise TypeError("options must be an integer")
783
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500784 return _lib.SSL_CTX_set_options(self._context, options)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800785
786
787 def set_mode(self, mode):
788 """
789 Add modes via bitmask. Modes set before are not cleared!
790
791 :param mode: The mode to add.
792 :return: The new mode bitmask.
793 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500794 if not isinstance(mode, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800795 raise TypeError("mode must be an integer")
796
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500797 return _lib.SSL_CTX_set_mode(self._context, mode)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800798
799
800 def set_tlsext_servername_callback(self, callback):
801 """
802 Specify a callback function to be called when clients specify a server name.
803
804 :param callback: The callback function. It will be invoked with one
805 argument, the Connection instance.
806 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800807 @wraps(callback)
808 def wrapper(ssl, alert, arg):
809 callback(Connection._reverse_mapping[ssl])
810 return 0
811
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500812 self._tlsext_servername_callback = _ffi.callback(
813 "int (*)(const SSL *, int *, void *)", wrapper)
814 _lib.SSL_CTX_set_tlsext_servername_callback(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800815 self._context, self._tlsext_servername_callback)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800816
817ContextType = Context
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800818
819
820
821class Connection(object):
822 """
823 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800824 _reverse_mapping = WeakValueDictionary()
825
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800826 def __init__(self, context, socket=None):
827 """
828 Create a new Connection object, using the given OpenSSL.SSL.Context
829 instance and socket.
830
831 :param context: An SSL Context to use for this connection
832 :param socket: The socket to use for transport layer
833 """
834 if not isinstance(context, Context):
835 raise TypeError("context must be a Context instance")
836
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500837 ssl = _lib.SSL_new(context._context)
838 self._ssl = _ffi.gc(ssl, _lib.SSL_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800839 self._context = context
840
841 self._reverse_mapping[self._ssl] = self
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800842
843 if socket is None:
844 self._socket = None
Jean-Paul Calderone73b15c22013-03-05 18:30:39 -0800845 # Don't set up any gc for these, SSL_free will take care of them.
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500846 self._into_ssl = _lib.BIO_new(_lib.BIO_s_mem())
847 self._from_ssl = _lib.BIO_new(_lib.BIO_s_mem())
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800848
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500849 if self._into_ssl == _ffi.NULL or self._from_ssl == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500850 # TODO: This is untested.
851 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800852
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500853 _lib.SSL_set_bio(self._ssl, self._into_ssl, self._from_ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800854 else:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800855 self._into_ssl = None
856 self._from_ssl = None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800857 self._socket = socket
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500858 set_result = _lib.SSL_set_fd(self._ssl, _asFileDescriptor(self._socket))
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800859 if not set_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500860 # TODO: This is untested.
861 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800862
863
864 def __getattr__(self, name):
865 """
866 Look up attributes on the wrapped socket object if they are not found on
867 the Connection object.
868 """
869 return getattr(self._socket, name)
870
871
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800872 def _raise_ssl_error(self, ssl, result):
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800873 if self._context._verify_helper is not None:
874 self._context._verify_helper.raise_if_problem()
875
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500876 error = _lib.SSL_get_error(ssl, result)
877 if error == _lib.SSL_ERROR_WANT_READ:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800878 raise WantReadError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500879 elif error == _lib.SSL_ERROR_WANT_WRITE:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -0700880 raise WantWriteError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500881 elif error == _lib.SSL_ERROR_ZERO_RETURN:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800882 raise ZeroReturnError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500883 elif error == _lib.SSL_ERROR_WANT_X509_LOOKUP:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500884 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -0700885 raise WantX509LookupError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500886 elif error == _lib.SSL_ERROR_SYSCALL:
887 if _lib.ERR_peek_error() == 0:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800888 if result < 0:
Konstantinos Koukopoulos541150d2014-01-31 01:00:19 +0200889 if platform == "win32":
890 errno = _ffi.getwinerror()[0]
891 else:
892 errno = _ffi.errno
893 raise SysCallError(errno, errorcode[errno])
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800894 else:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -0700895 raise SysCallError(-1, "Unexpected EOF")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800896 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500897 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500898 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500899 elif error == _lib.SSL_ERROR_NONE:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -0700900 pass
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800901 else:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500902 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800903
904
905 def get_context(self):
906 """
907 Get session context
908 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800909 return self._context
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800910
911
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800912 def set_context(self, context):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800913 """
914 Switch this connection to a new session context
915
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800916 :param context: A :py:class:`Context` instance giving the new session
917 context to use.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800918 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800919 if not isinstance(context, Context):
920 raise TypeError("context must be a Context instance")
921
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500922 _lib.SSL_set_SSL_CTX(self._ssl, context._context)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800923 self._context = context
924
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800925
926 def get_servername(self):
927 """
928 Retrieve the servername extension value if provided in the client hello
929 message, or None if there wasn't one.
930
931 :return: A byte string giving the server name or :py:data:`None`.
932 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500933 name = _lib.SSL_get_servername(self._ssl, _lib.TLSEXT_NAMETYPE_host_name)
934 if name == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800935 return None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800936
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500937 return _ffi.string(name)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800938
939
940 def set_tlsext_host_name(self, name):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800941 """
942 Set the value of the servername extension to send in the client hello.
943
944 :param name: A byte string giving the name.
945 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800946 if not isinstance(name, bytes):
947 raise TypeError("name must be a byte string")
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -0500948 elif b"\0" in name:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800949 raise TypeError("name must not contain NUL byte")
950
951 # XXX I guess this can fail sometimes?
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500952 _lib.SSL_set_tlsext_host_name(self._ssl, name)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800953
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800954
955 def pending(self):
956 """
957 Get the number of bytes that can be safely read from the connection
958
959 :return: The number of bytes available in the receive buffer.
960 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500961 return _lib.SSL_pending(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800962
963
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800964 def send(self, buf, flags=0):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800965 """
966 Send data on the connection. NOTE: If you get one of the WantRead,
967 WantWrite or WantX509Lookup exceptions on this, you have to call the
968 method again with the SAME buffer.
969
970 :param buf: The string to send
971 :param flags: (optional) Included for compatibility with the socket
972 API, the value is ignored
973 :return: The number of bytes written
974 """
Jean-Paul Calderone8fb53182013-12-30 08:35:49 -0500975 if isinstance(buf, _memoryview):
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -0800976 buf = buf.tobytes()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800977 if not isinstance(buf, bytes):
978 raise TypeError("data must be a byte string")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800979
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500980 result = _lib.SSL_write(self._ssl, buf, len(buf))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800981 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800982 return result
983 write = send
984
985
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800986 def sendall(self, buf, flags=0):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800987 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800988 Send "all" data on the connection. This calls send() repeatedly until
989 all data is sent. If an error occurs, it's impossible to tell how much
990 data has been sent.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800991
992 :param buf: The string to send
993 :param flags: (optional) Included for compatibility with the socket
994 API, the value is ignored
995 :return: The number of bytes written
996 """
Jean-Paul Calderone8fb53182013-12-30 08:35:49 -0500997 if isinstance(buf, _memoryview):
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -0800998 buf = buf.tobytes()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800999 if not isinstance(buf, bytes):
1000 raise TypeError("buf must be a byte string")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001001
1002 left_to_send = len(buf)
1003 total_sent = 0
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001004 data = _ffi.new("char[]", buf)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001005
1006 while left_to_send:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001007 result = _lib.SSL_write(self._ssl, data + total_sent, left_to_send)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001008 self._raise_ssl_error(self._ssl, result)
1009 total_sent += result
1010 left_to_send -= result
1011
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001012
1013 def recv(self, bufsiz, flags=None):
1014 """
1015 Receive data on the connection. NOTE: If you get one of the WantRead,
1016 WantWrite or WantX509Lookup exceptions on this, you have to call the
1017 method again with the SAME buffer.
1018
1019 :param bufsiz: The maximum number of bytes to read
1020 :param flags: (optional) Included for compatibility with the socket
1021 API, the value is ignored
1022 :return: The string read from the Connection
1023 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001024 buf = _ffi.new("char[]", bufsiz)
1025 result = _lib.SSL_read(self._ssl, buf, bufsiz)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001026 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001027 return _ffi.buffer(buf, result)[:]
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001028 read = recv
1029
1030
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001031 def _handle_bio_errors(self, bio, result):
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001032 if _lib.BIO_should_retry(bio):
1033 if _lib.BIO_should_read(bio):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001034 raise WantReadError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001035 elif _lib.BIO_should_write(bio):
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001036 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001037 raise WantWriteError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001038 elif _lib.BIO_should_io_special(bio):
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001039 # TODO: This is untested. I think io_special means the socket
1040 # BIO has a not-yet connected socket.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001041 raise ValueError("BIO_should_io_special")
1042 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001043 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001044 raise ValueError("unknown bio failure")
1045 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001046 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001047 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001048
1049
1050 def bio_read(self, bufsiz):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001051 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001052 When using non-socket connections this function reads the "dirty" data
1053 that would have traveled away on the network.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001054
1055 :param bufsiz: The maximum number of bytes to read
1056 :return: The string read.
1057 """
Jean-Paul Calderone97e041d2013-03-05 21:03:12 -08001058 if self._from_ssl is None:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001059 raise TypeError("Connection sock was not None")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001060
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -05001061 if not isinstance(bufsiz, integer_types):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001062 raise TypeError("bufsiz must be an integer")
1063
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001064 buf = _ffi.new("char[]", bufsiz)
1065 result = _lib.BIO_read(self._from_ssl, buf, bufsiz)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001066 if result <= 0:
1067 self._handle_bio_errors(self._from_ssl, result)
1068
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001069 return _ffi.buffer(buf, result)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001070
1071
1072 def bio_write(self, buf):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001073 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001074 When using non-socket connections this function sends "dirty" data that
1075 would have traveled in on the network.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001076
1077 :param buf: The string to put into the memory BIO.
1078 :return: The number of bytes written
1079 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001080 if self._into_ssl is None:
1081 raise TypeError("Connection sock was not None")
1082
1083 if not isinstance(buf, bytes):
1084 raise TypeError("buf must be a byte string")
1085
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001086 result = _lib.BIO_write(self._into_ssl, buf, len(buf))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001087 if result <= 0:
1088 self._handle_bio_errors(self._into_ssl, result)
1089 return result
1090
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001091
1092 def renegotiate(self):
1093 """
1094 Renegotiate the session
1095
1096 :return: True if the renegotiation can be started, false otherwise
1097 """
1098
1099 def do_handshake(self):
1100 """
1101 Perform an SSL handshake (usually called after renegotiate() or one of
1102 set_*_state()). This can raise the same exceptions as send and recv.
1103
1104 :return: None.
1105 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001106 result = _lib.SSL_do_handshake(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001107 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001108
1109
1110 def renegotiate_pending(self):
1111 """
1112 Check if there's a renegotiation in progress, it will return false once
1113 a renegotiation is finished.
1114
1115 :return: Whether there's a renegotiation in progress
1116 """
1117
1118 def total_renegotiations(self):
1119 """
1120 Find out the total number of renegotiations.
1121
1122 :return: The number of renegotiations.
1123 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001124 return _lib.SSL_total_renegotiations(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001125
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001126
1127 def connect(self, addr):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001128 """
1129 Connect to remote host and set up client-side SSL
1130
1131 :param addr: A remote address
1132 :return: What the socket's connect method returns
1133 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001134 _lib.SSL_set_connect_state(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001135 return self._socket.connect(addr)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001136
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001137
1138 def connect_ex(self, addr):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001139 """
1140 Connect to remote host and set up client-side SSL. Note that if the socket's
1141 connect_ex method doesn't return 0, SSL won't be initialized.
1142
1143 :param addr: A remove address
1144 :return: What the socket's connect_ex method returns
1145 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001146 connect_ex = self._socket.connect_ex
1147 self.set_connect_state()
1148 return connect_ex(addr)
1149
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001150
1151 def accept(self):
1152 """
1153 Accept incoming connection and set up SSL on it
1154
1155 :return: A (conn,addr) pair where conn is a Connection and addr is an
1156 address
1157 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001158 client, addr = self._socket.accept()
1159 conn = Connection(self._context, client)
1160 conn.set_accept_state()
1161 return (conn, addr)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001162
1163
1164 def bio_shutdown(self):
1165 """
1166 When using non-socket connections this function signals end of
1167 data on the input for this connection.
1168
1169 :return: None
1170 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001171 if self._from_ssl is None:
1172 raise TypeError("Connection sock was not None")
1173
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001174 _lib.BIO_set_mem_eof_return(self._into_ssl, 0)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001175
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001176
1177 def shutdown(self):
1178 """
1179 Send closure alert
1180
1181 :return: True if the shutdown completed successfully (i.e. both sides
1182 have sent closure alerts), false otherwise (i.e. you have to
1183 wait for a ZeroReturnError on a recv() method call
1184 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001185 result = _lib.SSL_shutdown(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001186 if result < 0:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001187 # TODO: This is untested.
1188 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001189 elif result > 0:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001190 return True
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001191 else:
1192 return False
1193
1194
1195 def get_cipher_list(self):
1196 """
1197 Get the session cipher list
1198
1199 :return: A list of cipher strings
1200 """
1201 ciphers = []
1202 for i in count():
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001203 result = _lib.SSL_get_cipher_list(self._ssl, i)
1204 if result == _ffi.NULL:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001205 break
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001206 ciphers.append(_native(_ffi.string(result)))
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001207 return ciphers
1208
1209
1210 def get_client_ca_list(self):
1211 """
1212 Get CAs whose certificates are suggested for client authentication.
1213
1214 :return: If this is a server connection, a list of X509Names representing
1215 the acceptable CAs as set by :py:meth:`OpenSSL.SSL.Context.set_client_ca_list` or
1216 :py:meth:`OpenSSL.SSL.Context.add_client_ca`. If this is a client connection,
1217 the list of such X509Names sent by the server, or an empty list if that
1218 has not yet happened.
1219 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001220 ca_names = _lib.SSL_get_client_CA_list(self._ssl)
1221 if ca_names == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001222 # TODO: This is untested.
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001223 return []
1224
1225 result = []
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001226 for i in range(_lib.sk_X509_NAME_num(ca_names)):
1227 name = _lib.sk_X509_NAME_value(ca_names, i)
1228 copy = _lib.X509_NAME_dup(name)
1229 if copy == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001230 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001231 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001232
1233 pyname = X509Name.__new__(X509Name)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001234 pyname._name = _ffi.gc(copy, _lib.X509_NAME_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001235 result.append(pyname)
1236 return result
1237
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001238
1239 def makefile(self):
1240 """
1241 The makefile() method is not implemented, since there is no dup semantics
1242 for SSL connections
1243
1244 :raise NotImplementedError
1245 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001246 raise NotImplementedError("Cannot make file object of OpenSSL.SSL.Connection")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001247
1248
1249 def get_app_data(self):
1250 """
1251 Get application data
1252
1253 :return: The application data
1254 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001255 return self._app_data
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001256
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001257
1258 def set_app_data(self, data):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001259 """
1260 Set application data
1261
1262 :param data - The application data
1263 :return: None
1264 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001265 self._app_data = data
1266
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001267
1268 def get_shutdown(self):
1269 """
1270 Get shutdown state
1271
1272 :return: The shutdown state, a bitvector of SENT_SHUTDOWN, RECEIVED_SHUTDOWN.
1273 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001274 return _lib.SSL_get_shutdown(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001275
1276
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001277 def set_shutdown(self, state):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001278 """
1279 Set shutdown state
1280
1281 :param state - bitvector of SENT_SHUTDOWN, RECEIVED_SHUTDOWN.
1282 :return: None
1283 """
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -05001284 if not isinstance(state, integer_types):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001285 raise TypeError("state must be an integer")
1286
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001287 _lib.SSL_set_shutdown(self._ssl, state)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001288
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001289
1290 def state_string(self):
1291 """
1292 Get a verbose state description
1293
1294 :return: A string representing the state
1295 """
1296
1297 def server_random(self):
1298 """
1299 Get a copy of the server hello nonce.
1300
1301 :return: A string representing the state
1302 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001303 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001304 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001305 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001306 self._ssl.s3.server_random,
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001307 _lib.SSL3_RANDOM_SIZE)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001308
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001309
1310 def client_random(self):
1311 """
1312 Get a copy of the client hello nonce.
1313
1314 :return: A string representing the state
1315 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001316 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001317 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001318 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001319 self._ssl.s3.client_random,
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001320 _lib.SSL3_RANDOM_SIZE)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001321
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001322
1323 def master_key(self):
1324 """
1325 Get a copy of the master key.
1326
1327 :return: A string representing the state
1328 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001329 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001330 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001331 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001332 self._ssl.session.master_key,
1333 self._ssl.session.master_key_length)[:]
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001334
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001335
1336 def sock_shutdown(self, *args, **kwargs):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001337 """
1338 See shutdown(2)
1339
1340 :return: What the socket's shutdown() method returns
1341 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001342 return self._socket.shutdown(*args, **kwargs)
1343
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001344
1345 def get_peer_certificate(self):
1346 """
1347 Retrieve the other side's certificate (if any)
1348
1349 :return: The peer's certificate
1350 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001351 cert = _lib.SSL_get_peer_certificate(self._ssl)
1352 if cert != _ffi.NULL:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001353 pycert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001354 pycert._x509 = _ffi.gc(cert, _lib.X509_free)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001355 return pycert
1356 return None
1357
1358
1359 def get_peer_cert_chain(self):
1360 """
1361 Retrieve the other side's certificate (if any)
1362
1363 :return: A list of X509 instances giving the peer's certificate chain,
1364 or None if it does not have one.
1365 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001366 cert_stack = _lib.SSL_get_peer_cert_chain(self._ssl)
1367 if cert_stack == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001368 return None
1369
1370 result = []
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001371 for i in range(_lib.sk_X509_num(cert_stack)):
Jean-Paul Calderone73b15c22013-03-05 18:30:39 -08001372 # TODO could incref instead of dup here
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001373 cert = _lib.X509_dup(_lib.sk_X509_value(cert_stack, i))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001374 pycert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001375 pycert._x509 = _ffi.gc(cert, _lib.X509_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001376 result.append(pycert)
1377 return result
1378
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001379
1380 def want_read(self):
1381 """
1382 Checks if more data has to be read from the transport layer to complete an
1383 operation.
1384
1385 :return: True iff more data has to be read
1386 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001387 return _lib.SSL_want_read(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001388
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001389
1390 def want_write(self):
1391 """
1392 Checks if there is data to write to the transport layer to complete an
1393 operation.
1394
1395 :return: True iff there is data to write
1396 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001397 return _lib.SSL_want_write(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001398
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001399
1400 def set_accept_state(self):
1401 """
1402 Set the connection to work in server mode. The handshake will be handled
1403 automatically by read/write.
1404
1405 :return: None
1406 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001407 _lib.SSL_set_accept_state(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001408
1409
1410 def set_connect_state(self):
1411 """
1412 Set the connection to work in client mode. The handshake will be handled
1413 automatically by read/write.
1414
1415 :return: None
1416 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001417 _lib.SSL_set_connect_state(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001418
1419
1420 def get_session(self):
1421 """
1422 Returns the Session currently used.
1423
1424 @return: An instance of :py:class:`OpenSSL.SSL.Session` or :py:obj:`None` if
1425 no session exists.
1426 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001427 session = _lib.SSL_get1_session(self._ssl)
1428 if session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001429 return None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001430
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001431 pysession = Session.__new__(Session)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001432 pysession._session = _ffi.gc(session, _lib.SSL_SESSION_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001433 return pysession
1434
1435
1436 def set_session(self, session):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001437 """
1438 Set the session to be used when the TLS/SSL connection is established.
1439
1440 :param session: A Session instance representing the session to use.
1441 :returns: None
1442 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001443 if not isinstance(session, Session):
1444 raise TypeError("session must be a Session instance")
1445
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001446 result = _lib.SSL_set_session(self._ssl, session._session)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001447 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001448 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001449
1450ConnectionType = Connection
Jean-Paul Calderone11ed8e82014-01-18 10:21:50 -05001451
Jean-Paul Calderonefab157b2014-01-18 11:21:38 -05001452# This is similar to the initialization calls at the end of OpenSSL/crypto.py
1453# but is exercised mostly by the Context initializer.
Jean-Paul Calderone11ed8e82014-01-18 10:21:50 -05001454_lib.SSL_library_init()