blob: 0e645efa6a9bb59c1db67b054320e1678887586f [file] [log] [blame]
Abraham Martind2f0b072015-03-25 13:56:25 +00001from 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,
Jean-Paul Calderone6462b072015-03-29 07:03:11 -040014 native as _native,
15 warn_text as _warn_text)
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080016
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -080017from OpenSSL.crypto import (
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -050018 FILETYPE_PEM, _PassphraseHelper, PKey, X509Name, X509, X509Store)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -080019
20_unspecified = object()
21
Jean-Paul Calderone8fb53182013-12-30 08:35:49 -050022try:
23 _memoryview = memoryview
24except NameError:
25 class _memoryview(object):
26 pass
27
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +020028try:
29 _buffer = buffer
30except NameError:
31 class _buffer(object):
32 pass
33
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050034OPENSSL_VERSION_NUMBER = _lib.OPENSSL_VERSION_NUMBER
35SSLEAY_VERSION = _lib.SSLEAY_VERSION
36SSLEAY_CFLAGS = _lib.SSLEAY_CFLAGS
37SSLEAY_PLATFORM = _lib.SSLEAY_PLATFORM
38SSLEAY_DIR = _lib.SSLEAY_DIR
39SSLEAY_BUILT_ON = _lib.SSLEAY_BUILT_ON
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080040
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050041SENT_SHUTDOWN = _lib.SSL_SENT_SHUTDOWN
42RECEIVED_SHUTDOWN = _lib.SSL_RECEIVED_SHUTDOWN
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080043
44SSLv2_METHOD = 1
45SSLv3_METHOD = 2
46SSLv23_METHOD = 3
47TLSv1_METHOD = 4
Jean-Paul Calderone56bff942013-11-03 11:30:43 -050048TLSv1_1_METHOD = 5
49TLSv1_2_METHOD = 6
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080050
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050051OP_NO_SSLv2 = _lib.SSL_OP_NO_SSLv2
52OP_NO_SSLv3 = _lib.SSL_OP_NO_SSLv3
53OP_NO_TLSv1 = _lib.SSL_OP_NO_TLSv1
Jean-Paul Calderonebe2bb422013-12-29 07:34:08 -050054
55OP_NO_TLSv1_1 = getattr(_lib, "SSL_OP_NO_TLSv1_1", 0)
56OP_NO_TLSv1_2 = getattr(_lib, "SSL_OP_NO_TLSv1_2", 0)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -080057
Jean-Paul Calderone0d7e8a12014-01-08 16:54:13 -050058try:
59 MODE_RELEASE_BUFFERS = _lib.SSL_MODE_RELEASE_BUFFERS
60except AttributeError:
61 pass
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080062
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050063OP_SINGLE_DH_USE = _lib.SSL_OP_SINGLE_DH_USE
64OP_EPHEMERAL_RSA = _lib.SSL_OP_EPHEMERAL_RSA
65OP_MICROSOFT_SESS_ID_BUG = _lib.SSL_OP_MICROSOFT_SESS_ID_BUG
66OP_NETSCAPE_CHALLENGE_BUG = _lib.SSL_OP_NETSCAPE_CHALLENGE_BUG
67OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG = _lib.SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG
68OP_SSLREF2_REUSE_CERT_TYPE_BUG = _lib.SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG
69OP_MICROSOFT_BIG_SSLV3_BUFFER = _lib.SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER
Jean-Paul Calderone0d7e8a12014-01-08 16:54:13 -050070try:
71 OP_MSIE_SSLV2_RSA_PADDING = _lib.SSL_OP_MSIE_SSLV2_RSA_PADDING
72except AttributeError:
73 pass
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050074OP_SSLEAY_080_CLIENT_DH_BUG = _lib.SSL_OP_SSLEAY_080_CLIENT_DH_BUG
75OP_TLS_D5_BUG = _lib.SSL_OP_TLS_D5_BUG
76OP_TLS_BLOCK_PADDING_BUG = _lib.SSL_OP_TLS_BLOCK_PADDING_BUG
77OP_DONT_INSERT_EMPTY_FRAGMENTS = _lib.SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
78OP_CIPHER_SERVER_PREFERENCE = _lib.SSL_OP_CIPHER_SERVER_PREFERENCE
79OP_TLS_ROLLBACK_BUG = _lib.SSL_OP_TLS_ROLLBACK_BUG
80OP_PKCS1_CHECK_1 = _lib.SSL_OP_PKCS1_CHECK_1
81OP_PKCS1_CHECK_2 = _lib.SSL_OP_PKCS1_CHECK_2
82OP_NETSCAPE_CA_DN_BUG = _lib.SSL_OP_NETSCAPE_CA_DN_BUG
83OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG= _lib.SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG
Jean-Paul Calderonec1780342014-01-08 16:59:03 -050084try:
85 OP_NO_COMPRESSION = _lib.SSL_OP_NO_COMPRESSION
86except AttributeError:
87 pass
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -080088
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050089OP_NO_QUERY_MTU = _lib.SSL_OP_NO_QUERY_MTU
90OP_COOKIE_EXCHANGE = _lib.SSL_OP_COOKIE_EXCHANGE
Arturo Filastò5f8c7a82014-03-09 20:01:25 +010091try:
92 OP_NO_TICKET = _lib.SSL_OP_NO_TICKET
93except AttributeError:
94 pass
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -080095
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050096OP_ALL = _lib.SSL_OP_ALL
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080097
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050098VERIFY_PEER = _lib.SSL_VERIFY_PEER
99VERIFY_FAIL_IF_NO_PEER_CERT = _lib.SSL_VERIFY_FAIL_IF_NO_PEER_CERT
100VERIFY_CLIENT_ONCE = _lib.SSL_VERIFY_CLIENT_ONCE
101VERIFY_NONE = _lib.SSL_VERIFY_NONE
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -0800102
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500103SESS_CACHE_OFF = _lib.SSL_SESS_CACHE_OFF
104SESS_CACHE_CLIENT = _lib.SSL_SESS_CACHE_CLIENT
105SESS_CACHE_SERVER = _lib.SSL_SESS_CACHE_SERVER
106SESS_CACHE_BOTH = _lib.SSL_SESS_CACHE_BOTH
107SESS_CACHE_NO_AUTO_CLEAR = _lib.SSL_SESS_CACHE_NO_AUTO_CLEAR
108SESS_CACHE_NO_INTERNAL_LOOKUP = _lib.SSL_SESS_CACHE_NO_INTERNAL_LOOKUP
109SESS_CACHE_NO_INTERNAL_STORE = _lib.SSL_SESS_CACHE_NO_INTERNAL_STORE
110SESS_CACHE_NO_INTERNAL = _lib.SSL_SESS_CACHE_NO_INTERNAL
Jean-Paul Calderoned39a3f62013-03-04 12:23:51 -0800111
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500112SSL_ST_CONNECT = _lib.SSL_ST_CONNECT
113SSL_ST_ACCEPT = _lib.SSL_ST_ACCEPT
114SSL_ST_MASK = _lib.SSL_ST_MASK
115SSL_ST_INIT = _lib.SSL_ST_INIT
116SSL_ST_BEFORE = _lib.SSL_ST_BEFORE
117SSL_ST_OK = _lib.SSL_ST_OK
118SSL_ST_RENEGOTIATE = _lib.SSL_ST_RENEGOTIATE
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800119
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500120SSL_CB_LOOP = _lib.SSL_CB_LOOP
121SSL_CB_EXIT = _lib.SSL_CB_EXIT
122SSL_CB_READ = _lib.SSL_CB_READ
123SSL_CB_WRITE = _lib.SSL_CB_WRITE
124SSL_CB_ALERT = _lib.SSL_CB_ALERT
125SSL_CB_READ_ALERT = _lib.SSL_CB_READ_ALERT
126SSL_CB_WRITE_ALERT = _lib.SSL_CB_WRITE_ALERT
127SSL_CB_ACCEPT_LOOP = _lib.SSL_CB_ACCEPT_LOOP
128SSL_CB_ACCEPT_EXIT = _lib.SSL_CB_ACCEPT_EXIT
129SSL_CB_CONNECT_LOOP = _lib.SSL_CB_CONNECT_LOOP
130SSL_CB_CONNECT_EXIT = _lib.SSL_CB_CONNECT_EXIT
131SSL_CB_HANDSHAKE_START = _lib.SSL_CB_HANDSHAKE_START
132SSL_CB_HANDSHAKE_DONE = _lib.SSL_CB_HANDSHAKE_DONE
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800133
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500134class Error(Exception):
Jean-Paul Calderone511cde02013-12-29 10:31:13 -0500135 """
136 An error occurred in an `OpenSSL.SSL` API.
137 """
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500138
139
140
141_raise_current_error = partial(_exception_from_error_queue, Error)
142
143
144class WantReadError(Error):
145 pass
146
147
148
149class WantWriteError(Error):
150 pass
151
152
153
154class WantX509LookupError(Error):
155 pass
156
157
158
159class ZeroReturnError(Error):
160 pass
161
162
163
164class SysCallError(Error):
165 pass
166
167
168
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800169class _VerifyHelper(object):
Jean-Paul Calderone6a8cd112014-04-02 21:09:08 -0400170 def __init__(self, callback):
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800171 self._problems = []
172
173 @wraps(callback)
174 def wrapper(ok, store_ctx):
175 cert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500176 cert._x509 = _lib.X509_STORE_CTX_get_current_cert(store_ctx)
177 error_number = _lib.X509_STORE_CTX_get_error(store_ctx)
178 error_depth = _lib.X509_STORE_CTX_get_error_depth(store_ctx)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800179
Jean-Paul Calderone6a8cd112014-04-02 21:09:08 -0400180 index = _lib.SSL_get_ex_data_X509_STORE_CTX_idx()
181 ssl = _lib.X509_STORE_CTX_get_ex_data(store_ctx, index)
182 connection = Connection._reverse_mapping[ssl]
183
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800184 try:
185 result = callback(connection, cert, error_number, error_depth, ok)
186 except Exception as e:
187 self._problems.append(e)
188 return 0
189 else:
190 if result:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500191 _lib.X509_STORE_CTX_set_error(store_ctx, _lib.X509_V_OK)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800192 return 1
193 else:
194 return 0
195
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500196 self.callback = _ffi.callback(
197 "int (*)(int, X509_STORE_CTX *)", wrapper)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800198
199
200 def raise_if_problem(self):
201 if self._problems:
202 try:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500203 _raise_current_error()
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800204 except Error:
205 pass
206 raise self._problems.pop(0)
207
208
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800209
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800210def _asFileDescriptor(obj):
211 fd = None
Konstantinos Koukopoulosc8b13ea2014-01-28 00:21:50 -0800212 if not isinstance(obj, integer_types):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800213 meth = getattr(obj, "fileno", None)
214 if meth is not None:
215 obj = meth()
216
Konstantinos Koukopoulosc8b13ea2014-01-28 00:21:50 -0800217 if isinstance(obj, integer_types):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800218 fd = obj
219
Konstantinos Koukopoulosc8b13ea2014-01-28 00:21:50 -0800220 if not isinstance(fd, integer_types):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800221 raise TypeError("argument must be an int, or have a fileno() method.")
222 elif fd < 0:
223 raise ValueError(
224 "file descriptor cannot be a negative integer (%i)" % (fd,))
225
226 return fd
227
228
229
Jean-Paul Calderoned39a3f62013-03-04 12:23:51 -0800230def SSLeay_version(type):
231 """
232 Return a string describing the version of OpenSSL in use.
233
234 :param type: One of the SSLEAY_ constants defined in this module.
235 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500236 return _ffi.string(_lib.SSLeay_version(type))
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800237
238
239
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800240class Session(object):
241 pass
242
243
244
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800245class Context(object):
246 """
247 :py:obj:`OpenSSL.SSL.Context` instances define the parameters for setting up
248 new SSL connections.
249 """
250 _methods = {
Andrew Dunhamec84a0a2014-02-24 12:41:37 -0800251 SSLv2_METHOD: "SSLv2_method",
Jean-Paul Calderonebe2bb422013-12-29 07:34:08 -0500252 SSLv3_METHOD: "SSLv3_method",
253 SSLv23_METHOD: "SSLv23_method",
254 TLSv1_METHOD: "TLSv1_method",
255 TLSv1_1_METHOD: "TLSv1_1_method",
256 TLSv1_2_METHOD: "TLSv1_2_method",
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800257 }
Jean-Paul Calderonebe2bb422013-12-29 07:34:08 -0500258 _methods = dict(
259 (identifier, getattr(_lib, name))
260 for (identifier, name) in _methods.items()
261 if getattr(_lib, name, None) is not None)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800262
Jean-Paul Calderone63157872013-03-20 16:43:38 -0700263
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800264 def __init__(self, method):
265 """
266 :param method: One of SSLv2_METHOD, SSLv3_METHOD, SSLv23_METHOD, or
267 TLSv1_METHOD.
268 """
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -0500269 if not isinstance(method, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800270 raise TypeError("method must be an integer")
271
272 try:
273 method_func = self._methods[method]
274 except KeyError:
275 raise ValueError("No such protocol")
276
277 method_obj = method_func()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500278 if method_obj == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500279 # TODO: This is untested.
280 _raise_current_error()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800281
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500282 context = _lib.SSL_CTX_new(method_obj)
283 if context == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500284 # TODO: This is untested.
285 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500286 context = _ffi.gc(context, _lib.SSL_CTX_free)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800287
288 self._context = context
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800289 self._passphrase_helper = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800290 self._passphrase_callback = None
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800291 self._passphrase_userdata = None
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800292 self._verify_helper = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800293 self._verify_callback = None
294 self._info_callback = None
295 self._tlsext_servername_callback = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800296 self._app_data = None
297
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -0800298 # SSL_CTX_set_app_data(self->ctx, self);
299 # SSL_CTX_set_mode(self->ctx, SSL_MODE_ENABLE_PARTIAL_WRITE |
300 # SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
301 # SSL_MODE_AUTO_RETRY);
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500302 self.set_mode(_lib.SSL_MODE_ENABLE_PARTIAL_WRITE)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800303
304
305 def load_verify_locations(self, cafile, capath=None):
306 """
307 Let SSL know where we can find trusted certificates for the certificate
308 chain
309
310 :param cafile: In which file we can find the certificates
311 :param capath: In which directory we can find the certificates
312 :return: None
313 """
314 if cafile is None:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500315 cafile = _ffi.NULL
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800316 elif not isinstance(cafile, bytes):
317 raise TypeError("cafile must be None or a byte string")
318
319 if capath is None:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500320 capath = _ffi.NULL
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800321 elif not isinstance(capath, bytes):
322 raise TypeError("capath must be None or a byte string")
323
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500324 load_result = _lib.SSL_CTX_load_verify_locations(self._context, cafile, capath)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800325 if not load_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500326 _raise_current_error()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800327
328
329 def _wrap_callback(self, callback):
330 @wraps(callback)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800331 def wrapper(size, verify, userdata):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800332 return callback(size, verify, self._passphrase_userdata)
333 return _PassphraseHelper(
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800334 FILETYPE_PEM, wrapper, more_args=True, truncate=True)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800335
336
337 def set_passwd_cb(self, callback, userdata=None):
338 """
339 Set the passphrase callback
340
341 :param callback: The Python callback to use
342 :param userdata: (optional) A Python object which will be given as
343 argument to the callback
344 :return: None
345 """
346 if not callable(callback):
347 raise TypeError("callback must be callable")
348
349 self._passphrase_helper = self._wrap_callback(callback)
350 self._passphrase_callback = self._passphrase_helper.callback
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500351 _lib.SSL_CTX_set_default_passwd_cb(
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800352 self._context, self._passphrase_callback)
353 self._passphrase_userdata = userdata
354
355
356 def set_default_verify_paths(self):
357 """
358 Use the platform-specific CA certificate locations
359
360 :return: None
361 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500362 set_result = _lib.SSL_CTX_set_default_verify_paths(self._context)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800363 if not set_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500364 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500365 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800366
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800367
368 def use_certificate_chain_file(self, certfile):
369 """
370 Load a certificate chain from a file
371
372 :param certfile: The name of the certificate chain file
373 :return: None
374 """
Jean-Paul Calderoned8607982014-01-18 10:30:55 -0500375 if isinstance(certfile, _text_type):
376 # Perhaps sys.getfilesystemencoding() could be better?
377 certfile = certfile.encode("utf-8")
378
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800379 if not isinstance(certfile, bytes):
Jean-Paul Calderoned8607982014-01-18 10:30:55 -0500380 raise TypeError("certfile must be bytes or unicode")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800381
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500382 result = _lib.SSL_CTX_use_certificate_chain_file(self._context, certfile)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800383 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500384 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800385
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800386
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800387 def use_certificate_file(self, certfile, filetype=FILETYPE_PEM):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800388 """
389 Load a certificate from a file
390
391 :param certfile: The name of the certificate file
392 :param filetype: (optional) The encoding of the file, default is PEM
393 :return: None
394 """
Jean-Paul Calderone684baf52014-01-18 10:31:19 -0500395 if isinstance(certfile, _text_type):
396 # Perhaps sys.getfilesystemencoding() could be better?
397 certfile = certfile.encode("utf-8")
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800398 if not isinstance(certfile, bytes):
Jean-Paul Calderone684baf52014-01-18 10:31:19 -0500399 raise TypeError("certfile must be bytes or unicode")
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -0500400 if not isinstance(filetype, integer_types):
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800401 raise TypeError("filetype must be an integer")
402
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500403 use_result = _lib.SSL_CTX_use_certificate_file(self._context, certfile, filetype)
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800404 if not use_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500405 _raise_current_error()
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800406
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800407
408 def use_certificate(self, cert):
409 """
410 Load a certificate from a X509 object
411
412 :param cert: The X509 object
413 :return: None
414 """
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800415 if not isinstance(cert, X509):
416 raise TypeError("cert must be an X509 instance")
417
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500418 use_result = _lib.SSL_CTX_use_certificate(self._context, cert._x509)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800419 if not use_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500420 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800421
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800422
423 def add_extra_chain_cert(self, certobj):
424 """
425 Add certificate to chain
426
427 :param certobj: The X509 certificate object to add to the chain
428 :return: None
429 """
430 if not isinstance(certobj, X509):
431 raise TypeError("certobj must be an X509 instance")
432
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500433 copy = _lib.X509_dup(certobj._x509)
434 add_result = _lib.SSL_CTX_add_extra_chain_cert(self._context, copy)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800435 if not add_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500436 # TODO: This is untested.
437 _lib.X509_free(copy)
438 _raise_current_error()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800439
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800440
441 def _raise_passphrase_exception(self):
442 if self._passphrase_helper is None:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500443 _raise_current_error()
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800444 exception = self._passphrase_helper.raise_if_problem(Error)
445 if exception is not None:
446 raise exception
447
448
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800449 def use_privatekey_file(self, keyfile, filetype=_unspecified):
450 """
451 Load a private key from a file
452
453 :param keyfile: The name of the key file
454 :param filetype: (optional) The encoding of the file, default is PEM
455 :return: None
456 """
Jean-Paul Calderone87e525a2014-01-18 10:31:51 -0500457 if isinstance(keyfile, _text_type):
458 # Perhaps sys.getfilesystemencoding() could be better?
459 keyfile = keyfile.encode("utf-8")
460
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800461 if not isinstance(keyfile, bytes):
462 raise TypeError("keyfile must be a byte string")
463
464 if filetype is _unspecified:
465 filetype = FILETYPE_PEM
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -0500466 elif not isinstance(filetype, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800467 raise TypeError("filetype must be an integer")
468
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500469 use_result = _lib.SSL_CTX_use_PrivateKey_file(
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800470 self._context, keyfile, filetype)
471 if not use_result:
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800472 self._raise_passphrase_exception()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800473
474
475 def use_privatekey(self, pkey):
476 """
477 Load a private key from a PKey object
478
479 :param pkey: The PKey object
480 :return: None
481 """
482 if not isinstance(pkey, PKey):
483 raise TypeError("pkey must be a PKey instance")
484
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500485 use_result = _lib.SSL_CTX_use_PrivateKey(self._context, pkey._pkey)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800486 if not use_result:
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800487 self._raise_passphrase_exception()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800488
489
490 def check_privatekey(self):
491 """
492 Check that the private key and certificate match up
493
494 :return: None (raises an exception if something's wrong)
495 """
Jean-Paul Calderonea0344922014-12-11 14:02:31 -0500496 if not _lib.SSL_CTX_check_private_key(self._context):
497 _raise_current_error()
498
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800499
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 Calderone6a8cd112014-04-02 21:09:08 -0400558 self._verify_helper = _VerifyHelper(callback)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800559 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
Jean-Paul Calderone3e4e3352014-04-19 09:28:28 -0400614 def set_tmp_ecdh(self, curve):
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
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -0400618 :param curve: A curve object to use as returned by either
619 :py:meth:`OpenSSL.crypto.get_elliptic_curve` or
620 :py:meth:`OpenSSL.crypto.get_elliptic_curves`.
Andy Lutomirskif05a2732014-03-13 17:22:25 -0700621
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600622 :return: None
623 """
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -0400624 _lib.SSL_CTX_set_tmp_ecdh(self._context, curve._to_EC_KEY())
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600625
626
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800627 def set_cipher_list(self, cipher_list):
628 """
629 Change the cipher list
630
631 :param cipher_list: A cipher list, see ciphers(1)
632 :return: None
633 """
Jean-Paul Calderone63eab692014-01-18 10:19:56 -0500634 if isinstance(cipher_list, _text_type):
635 cipher_list = cipher_list.encode("ascii")
636
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800637 if not isinstance(cipher_list, bytes):
Jean-Paul Calderone63eab692014-01-18 10:19:56 -0500638 raise TypeError("cipher_list must be bytes or unicode")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800639
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500640 result = _lib.SSL_CTX_set_cipher_list(self._context, cipher_list)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800641 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500642 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800643
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800644
645 def set_client_ca_list(self, certificate_authorities):
646 """
647 Set the list of preferred client certificate signers for this server context.
648
649 This list of certificate authorities will be sent to the client when the
650 server requests a client certificate.
651
652 :param certificate_authorities: a sequence of X509Names.
653 :return: None
654 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500655 name_stack = _lib.sk_X509_NAME_new_null()
656 if name_stack == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500657 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500658 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800659
660 try:
661 for ca_name in certificate_authorities:
662 if not isinstance(ca_name, X509Name):
663 raise TypeError(
664 "client CAs must be X509Name objects, not %s objects" % (
665 type(ca_name).__name__,))
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500666 copy = _lib.X509_NAME_dup(ca_name._name)
667 if copy == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500668 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500669 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500670 push_result = _lib.sk_X509_NAME_push(name_stack, copy)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800671 if not push_result:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500672 _lib.X509_NAME_free(copy)
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500673 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800674 except:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500675 _lib.sk_X509_NAME_free(name_stack)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800676 raise
677
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500678 _lib.SSL_CTX_set_client_CA_list(self._context, name_stack)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800679
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800680
681 def add_client_ca(self, certificate_authority):
682 """
683 Add the CA certificate to the list of preferred signers for this context.
684
685 The list of certificate authorities will be sent to the client when the
686 server requests a client certificate.
687
688 :param certificate_authority: certificate authority's X509 certificate.
689 :return: None
690 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800691 if not isinstance(certificate_authority, X509):
692 raise TypeError("certificate_authority must be an X509 instance")
693
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500694 add_result = _lib.SSL_CTX_add_client_CA(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800695 self._context, certificate_authority._x509)
696 if not add_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500697 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500698 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800699
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800700
701 def set_timeout(self, timeout):
702 """
703 Set session timeout
704
705 :param timeout: The timeout in seconds
706 :return: The previous session timeout
707 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500708 if not isinstance(timeout, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800709 raise TypeError("timeout must be an integer")
710
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500711 return _lib.SSL_CTX_set_timeout(self._context, timeout)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800712
713
714 def get_timeout(self):
715 """
716 Get the session timeout
717
718 :return: The session timeout
719 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500720 return _lib.SSL_CTX_get_timeout(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800721
722
723 def set_info_callback(self, callback):
724 """
725 Set the info callback
726
727 :param callback: The Python callback to use
728 :return: None
729 """
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800730 @wraps(callback)
731 def wrapper(ssl, where, return_code):
Jean-Paul Calderonef2bbc9c2014-02-02 10:59:14 -0500732 callback(Connection._reverse_mapping[ssl], where, return_code)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500733 self._info_callback = _ffi.callback(
734 "void (*)(const SSL *, int, int)", wrapper)
735 _lib.SSL_CTX_set_info_callback(self._context, self._info_callback)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800736
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800737
738 def get_app_data(self):
739 """
740 Get the application data (supplied via set_app_data())
741
742 :return: The application data
743 """
744 return self._app_data
745
746
747 def set_app_data(self, data):
748 """
749 Set the application data (will be returned from get_app_data())
750
751 :param data: Any Python object
752 :return: None
753 """
754 self._app_data = data
755
756
757 def get_cert_store(self):
758 """
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500759 Get the certificate store for the context.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800760
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500761 :return: A X509Store object or None if it does not have one.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800762 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500763 store = _lib.SSL_CTX_get_cert_store(self._context)
764 if store == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500765 # TODO: This is untested.
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800766 return None
767
768 pystore = X509Store.__new__(X509Store)
769 pystore._store = store
770 return pystore
771
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800772
773 def set_options(self, options):
774 """
775 Add options. Options set before are not cleared!
776
777 :param options: The options to add.
778 :return: The new option bitmask.
779 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500780 if not isinstance(options, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800781 raise TypeError("options must be an integer")
782
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500783 return _lib.SSL_CTX_set_options(self._context, options)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800784
785
786 def set_mode(self, mode):
787 """
788 Add modes via bitmask. Modes set before are not cleared!
789
790 :param mode: The mode to add.
791 :return: The new mode bitmask.
792 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500793 if not isinstance(mode, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800794 raise TypeError("mode must be an integer")
795
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500796 return _lib.SSL_CTX_set_mode(self._context, mode)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800797
798
799 def set_tlsext_servername_callback(self, callback):
800 """
801 Specify a callback function to be called when clients specify a server name.
802
803 :param callback: The callback function. It will be invoked with one
804 argument, the Connection instance.
805 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800806 @wraps(callback)
807 def wrapper(ssl, alert, arg):
808 callback(Connection._reverse_mapping[ssl])
809 return 0
810
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500811 self._tlsext_servername_callback = _ffi.callback(
812 "int (*)(const SSL *, int *, void *)", wrapper)
813 _lib.SSL_CTX_set_tlsext_servername_callback(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800814 self._context, self._tlsext_servername_callback)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800815
816ContextType = Context
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800817
818
819
820class Connection(object):
821 """
822 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800823 _reverse_mapping = WeakValueDictionary()
824
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800825 def __init__(self, context, socket=None):
826 """
827 Create a new Connection object, using the given OpenSSL.SSL.Context
828 instance and socket.
829
830 :param context: An SSL Context to use for this connection
831 :param socket: The socket to use for transport layer
832 """
833 if not isinstance(context, Context):
834 raise TypeError("context must be a Context instance")
835
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500836 ssl = _lib.SSL_new(context._context)
837 self._ssl = _ffi.gc(ssl, _lib.SSL_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800838 self._context = context
839
840 self._reverse_mapping[self._ssl] = self
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800841
842 if socket is None:
843 self._socket = None
Jean-Paul Calderone73b15c22013-03-05 18:30:39 -0800844 # Don't set up any gc for these, SSL_free will take care of them.
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500845 self._into_ssl = _lib.BIO_new(_lib.BIO_s_mem())
846 self._from_ssl = _lib.BIO_new(_lib.BIO_s_mem())
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800847
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500848 if self._into_ssl == _ffi.NULL or self._from_ssl == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500849 # TODO: This is untested.
850 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800851
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500852 _lib.SSL_set_bio(self._ssl, self._into_ssl, self._from_ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800853 else:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800854 self._into_ssl = None
855 self._from_ssl = None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800856 self._socket = socket
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500857 set_result = _lib.SSL_set_fd(self._ssl, _asFileDescriptor(self._socket))
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800858 if not set_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500859 # TODO: This is untested.
860 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800861
862
863 def __getattr__(self, name):
864 """
865 Look up attributes on the wrapped socket object if they are not found on
866 the Connection object.
867 """
868 return getattr(self._socket, name)
869
870
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800871 def _raise_ssl_error(self, ssl, result):
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800872 if self._context._verify_helper is not None:
873 self._context._verify_helper.raise_if_problem()
874
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500875 error = _lib.SSL_get_error(ssl, result)
876 if error == _lib.SSL_ERROR_WANT_READ:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800877 raise WantReadError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500878 elif error == _lib.SSL_ERROR_WANT_WRITE:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -0700879 raise WantWriteError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500880 elif error == _lib.SSL_ERROR_ZERO_RETURN:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800881 raise ZeroReturnError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500882 elif error == _lib.SSL_ERROR_WANT_X509_LOOKUP:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500883 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -0700884 raise WantX509LookupError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500885 elif error == _lib.SSL_ERROR_SYSCALL:
886 if _lib.ERR_peek_error() == 0:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800887 if result < 0:
Konstantinos Koukopoulos541150d2014-01-31 01:00:19 +0200888 if platform == "win32":
889 errno = _ffi.getwinerror()[0]
890 else:
891 errno = _ffi.errno
892 raise SysCallError(errno, errorcode[errno])
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800893 else:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -0700894 raise SysCallError(-1, "Unexpected EOF")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800895 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500896 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500897 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500898 elif error == _lib.SSL_ERROR_NONE:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -0700899 pass
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800900 else:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500901 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800902
903
904 def get_context(self):
905 """
906 Get session context
907 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800908 return self._context
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800909
910
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800911 def set_context(self, context):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800912 """
913 Switch this connection to a new session context
914
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800915 :param context: A :py:class:`Context` instance giving the new session
916 context to use.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800917 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800918 if not isinstance(context, Context):
919 raise TypeError("context must be a Context instance")
920
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500921 _lib.SSL_set_SSL_CTX(self._ssl, context._context)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800922 self._context = context
923
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800924
925 def get_servername(self):
926 """
927 Retrieve the servername extension value if provided in the client hello
928 message, or None if there wasn't one.
929
930 :return: A byte string giving the server name or :py:data:`None`.
931 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500932 name = _lib.SSL_get_servername(self._ssl, _lib.TLSEXT_NAMETYPE_host_name)
933 if name == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800934 return None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800935
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500936 return _ffi.string(name)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800937
938
939 def set_tlsext_host_name(self, name):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800940 """
941 Set the value of the servername extension to send in the client hello.
942
943 :param name: A byte string giving the name.
944 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800945 if not isinstance(name, bytes):
946 raise TypeError("name must be a byte string")
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -0500947 elif b"\0" in name:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800948 raise TypeError("name must not contain NUL byte")
949
950 # XXX I guess this can fail sometimes?
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500951 _lib.SSL_set_tlsext_host_name(self._ssl, name)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800952
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800953
954 def pending(self):
955 """
956 Get the number of bytes that can be safely read from the connection
957
958 :return: The number of bytes available in the receive buffer.
959 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500960 return _lib.SSL_pending(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800961
962
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800963 def send(self, buf, flags=0):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800964 """
965 Send data on the connection. NOTE: If you get one of the WantRead,
966 WantWrite or WantX509Lookup exceptions on this, you have to call the
967 method again with the SAME buffer.
968
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +0200969 :param buf: The string, buffer or memoryview to send
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800970 :param flags: (optional) Included for compatibility with the socket
971 API, the value is ignored
972 :return: The number of bytes written
973 """
Abraham Martine82326c2015-02-04 10:18:10 +0000974 # Backward compatibility
Jean-Paul Calderone6462b072015-03-29 07:03:11 -0400975 buf = _warn_text("buf", buf)
Abraham Martine82326c2015-02-04 10:18:10 +0000976
Jean-Paul Calderone8fb53182013-12-30 08:35:49 -0500977 if isinstance(buf, _memoryview):
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -0800978 buf = buf.tobytes()
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +0200979 if isinstance(buf, _buffer):
980 buf = str(buf)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800981 if not isinstance(buf, bytes):
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +0200982 raise TypeError("data must be a memoryview, buffer or byte string")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800983
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500984 result = _lib.SSL_write(self._ssl, buf, len(buf))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800985 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800986 return result
987 write = send
988
989
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800990 def sendall(self, buf, flags=0):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800991 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800992 Send "all" data on the connection. This calls send() repeatedly until
993 all data is sent. If an error occurs, it's impossible to tell how much
994 data has been sent.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800995
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +0200996 :param buf: The string, buffer or memoryview to send
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800997 :param flags: (optional) Included for compatibility with the socket
998 API, the value is ignored
999 :return: The number of bytes written
1000 """
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04001001 buf = _warn_text("buf", buf)
Abraham Martine82326c2015-02-04 10:18:10 +00001002
Jean-Paul Calderone8fb53182013-12-30 08:35:49 -05001003 if isinstance(buf, _memoryview):
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -08001004 buf = buf.tobytes()
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001005 if isinstance(buf, _buffer):
1006 buf = str(buf)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001007 if not isinstance(buf, bytes):
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001008 raise TypeError("buf must be a memoryview, buffer or byte string")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001009
1010 left_to_send = len(buf)
1011 total_sent = 0
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001012 data = _ffi.new("char[]", buf)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001013
1014 while left_to_send:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001015 result = _lib.SSL_write(self._ssl, data + total_sent, left_to_send)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001016 self._raise_ssl_error(self._ssl, result)
1017 total_sent += result
1018 left_to_send -= result
1019
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001020
1021 def recv(self, bufsiz, flags=None):
1022 """
1023 Receive data on the connection. NOTE: If you get one of the WantRead,
1024 WantWrite or WantX509Lookup exceptions on this, you have to call the
1025 method again with the SAME buffer.
1026
1027 :param bufsiz: The maximum number of bytes to read
1028 :param flags: (optional) Included for compatibility with the socket
1029 API, the value is ignored
1030 :return: The string read from the Connection
1031 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001032 buf = _ffi.new("char[]", bufsiz)
1033 result = _lib.SSL_read(self._ssl, buf, bufsiz)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001034 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001035 return _ffi.buffer(buf, result)[:]
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001036 read = recv
1037
1038
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001039 def _handle_bio_errors(self, bio, result):
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001040 if _lib.BIO_should_retry(bio):
1041 if _lib.BIO_should_read(bio):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001042 raise WantReadError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001043 elif _lib.BIO_should_write(bio):
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001044 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001045 raise WantWriteError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001046 elif _lib.BIO_should_io_special(bio):
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001047 # TODO: This is untested. I think io_special means the socket
1048 # BIO has a not-yet connected socket.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001049 raise ValueError("BIO_should_io_special")
1050 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001051 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001052 raise ValueError("unknown bio failure")
1053 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001054 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001055 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001056
1057
1058 def bio_read(self, bufsiz):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001059 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001060 When using non-socket connections this function reads the "dirty" data
1061 that would have traveled away on the network.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001062
1063 :param bufsiz: The maximum number of bytes to read
1064 :return: The string read.
1065 """
Jean-Paul Calderone97e041d2013-03-05 21:03:12 -08001066 if self._from_ssl is None:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001067 raise TypeError("Connection sock was not None")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001068
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -05001069 if not isinstance(bufsiz, integer_types):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001070 raise TypeError("bufsiz must be an integer")
1071
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001072 buf = _ffi.new("char[]", bufsiz)
1073 result = _lib.BIO_read(self._from_ssl, buf, bufsiz)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001074 if result <= 0:
1075 self._handle_bio_errors(self._from_ssl, result)
1076
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001077 return _ffi.buffer(buf, result)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001078
1079
1080 def bio_write(self, buf):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001081 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001082 When using non-socket connections this function sends "dirty" data that
1083 would have traveled in on the network.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001084
1085 :param buf: The string to put into the memory BIO.
1086 :return: The number of bytes written
1087 """
Jean-Paul Calderone6462b072015-03-29 07:03:11 -04001088 buf = _warn_text("buf", buf)
Abraham Martine82326c2015-02-04 10:18:10 +00001089
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001090 if self._into_ssl is None:
1091 raise TypeError("Connection sock was not None")
1092
1093 if not isinstance(buf, bytes):
1094 raise TypeError("buf must be a byte string")
1095
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001096 result = _lib.BIO_write(self._into_ssl, buf, len(buf))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001097 if result <= 0:
1098 self._handle_bio_errors(self._into_ssl, result)
1099 return result
1100
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001101
1102 def renegotiate(self):
1103 """
1104 Renegotiate the session
1105
1106 :return: True if the renegotiation can be started, false otherwise
1107 """
1108
1109 def do_handshake(self):
1110 """
1111 Perform an SSL handshake (usually called after renegotiate() or one of
1112 set_*_state()). This can raise the same exceptions as send and recv.
1113
1114 :return: None.
1115 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001116 result = _lib.SSL_do_handshake(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001117 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001118
1119
1120 def renegotiate_pending(self):
1121 """
1122 Check if there's a renegotiation in progress, it will return false once
1123 a renegotiation is finished.
1124
1125 :return: Whether there's a renegotiation in progress
1126 """
1127
1128 def total_renegotiations(self):
1129 """
1130 Find out the total number of renegotiations.
1131
1132 :return: The number of renegotiations.
1133 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001134 return _lib.SSL_total_renegotiations(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001135
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001136
1137 def connect(self, addr):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001138 """
1139 Connect to remote host and set up client-side SSL
1140
1141 :param addr: A remote address
1142 :return: What the socket's connect method returns
1143 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001144 _lib.SSL_set_connect_state(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001145 return self._socket.connect(addr)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001146
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001147
1148 def connect_ex(self, addr):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001149 """
1150 Connect to remote host and set up client-side SSL. Note that if the socket's
1151 connect_ex method doesn't return 0, SSL won't be initialized.
1152
1153 :param addr: A remove address
1154 :return: What the socket's connect_ex method returns
1155 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001156 connect_ex = self._socket.connect_ex
1157 self.set_connect_state()
1158 return connect_ex(addr)
1159
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001160
1161 def accept(self):
1162 """
1163 Accept incoming connection and set up SSL on it
1164
1165 :return: A (conn,addr) pair where conn is a Connection and addr is an
1166 address
1167 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001168 client, addr = self._socket.accept()
1169 conn = Connection(self._context, client)
1170 conn.set_accept_state()
1171 return (conn, addr)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001172
1173
1174 def bio_shutdown(self):
1175 """
1176 When using non-socket connections this function signals end of
1177 data on the input for this connection.
1178
1179 :return: None
1180 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001181 if self._from_ssl is None:
1182 raise TypeError("Connection sock was not None")
1183
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001184 _lib.BIO_set_mem_eof_return(self._into_ssl, 0)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001185
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001186
1187 def shutdown(self):
1188 """
1189 Send closure alert
1190
1191 :return: True if the shutdown completed successfully (i.e. both sides
1192 have sent closure alerts), false otherwise (i.e. you have to
1193 wait for a ZeroReturnError on a recv() method call
1194 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001195 result = _lib.SSL_shutdown(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001196 if result < 0:
Paul Aurichbff1d1a2015-01-08 08:36:53 -08001197 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001198 elif result > 0:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001199 return True
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001200 else:
1201 return False
1202
1203
1204 def get_cipher_list(self):
1205 """
1206 Get the session cipher list
1207
1208 :return: A list of cipher strings
1209 """
1210 ciphers = []
1211 for i in count():
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001212 result = _lib.SSL_get_cipher_list(self._ssl, i)
1213 if result == _ffi.NULL:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001214 break
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001215 ciphers.append(_native(_ffi.string(result)))
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001216 return ciphers
1217
1218
1219 def get_client_ca_list(self):
1220 """
1221 Get CAs whose certificates are suggested for client authentication.
1222
1223 :return: If this is a server connection, a list of X509Names representing
1224 the acceptable CAs as set by :py:meth:`OpenSSL.SSL.Context.set_client_ca_list` or
1225 :py:meth:`OpenSSL.SSL.Context.add_client_ca`. If this is a client connection,
1226 the list of such X509Names sent by the server, or an empty list if that
1227 has not yet happened.
1228 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001229 ca_names = _lib.SSL_get_client_CA_list(self._ssl)
1230 if ca_names == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001231 # TODO: This is untested.
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001232 return []
1233
1234 result = []
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001235 for i in range(_lib.sk_X509_NAME_num(ca_names)):
1236 name = _lib.sk_X509_NAME_value(ca_names, i)
1237 copy = _lib.X509_NAME_dup(name)
1238 if copy == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001239 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001240 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001241
1242 pyname = X509Name.__new__(X509Name)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001243 pyname._name = _ffi.gc(copy, _lib.X509_NAME_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001244 result.append(pyname)
1245 return result
1246
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001247
1248 def makefile(self):
1249 """
1250 The makefile() method is not implemented, since there is no dup semantics
1251 for SSL connections
1252
Jean-Paul Calderone6749ec22014-04-17 16:30:21 -04001253 :raise: NotImplementedError
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001254 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001255 raise NotImplementedError("Cannot make file object of OpenSSL.SSL.Connection")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001256
1257
1258 def get_app_data(self):
1259 """
1260 Get application data
1261
1262 :return: The application data
1263 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001264 return self._app_data
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001265
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001266
1267 def set_app_data(self, data):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001268 """
1269 Set application data
1270
1271 :param data - The application data
1272 :return: None
1273 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001274 self._app_data = data
1275
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001276
1277 def get_shutdown(self):
1278 """
1279 Get shutdown state
1280
1281 :return: The shutdown state, a bitvector of SENT_SHUTDOWN, RECEIVED_SHUTDOWN.
1282 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001283 return _lib.SSL_get_shutdown(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001284
1285
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001286 def set_shutdown(self, state):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001287 """
1288 Set shutdown state
1289
1290 :param state - bitvector of SENT_SHUTDOWN, RECEIVED_SHUTDOWN.
1291 :return: None
1292 """
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -05001293 if not isinstance(state, integer_types):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001294 raise TypeError("state must be an integer")
1295
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001296 _lib.SSL_set_shutdown(self._ssl, state)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001297
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001298
1299 def state_string(self):
1300 """
1301 Get a verbose state description
1302
1303 :return: A string representing the state
1304 """
1305
1306 def server_random(self):
1307 """
1308 Get a copy of the server hello nonce.
1309
1310 :return: A string representing the state
1311 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001312 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001313 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001314 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001315 self._ssl.s3.server_random,
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001316 _lib.SSL3_RANDOM_SIZE)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001317
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001318
1319 def client_random(self):
1320 """
1321 Get a copy of the client hello nonce.
1322
1323 :return: A string representing the state
1324 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001325 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001326 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001327 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001328 self._ssl.s3.client_random,
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001329 _lib.SSL3_RANDOM_SIZE)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001330
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001331
1332 def master_key(self):
1333 """
1334 Get a copy of the master key.
1335
1336 :return: A string representing the state
1337 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001338 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001339 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001340 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001341 self._ssl.session.master_key,
1342 self._ssl.session.master_key_length)[:]
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001343
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001344
1345 def sock_shutdown(self, *args, **kwargs):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001346 """
1347 See shutdown(2)
1348
1349 :return: What the socket's shutdown() method returns
1350 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001351 return self._socket.shutdown(*args, **kwargs)
1352
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001353
1354 def get_peer_certificate(self):
1355 """
1356 Retrieve the other side's certificate (if any)
1357
1358 :return: The peer's certificate
1359 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001360 cert = _lib.SSL_get_peer_certificate(self._ssl)
1361 if cert != _ffi.NULL:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001362 pycert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001363 pycert._x509 = _ffi.gc(cert, _lib.X509_free)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001364 return pycert
1365 return None
1366
1367
1368 def get_peer_cert_chain(self):
1369 """
1370 Retrieve the other side's certificate (if any)
1371
1372 :return: A list of X509 instances giving the peer's certificate chain,
1373 or None if it does not have one.
1374 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001375 cert_stack = _lib.SSL_get_peer_cert_chain(self._ssl)
1376 if cert_stack == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001377 return None
1378
1379 result = []
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001380 for i in range(_lib.sk_X509_num(cert_stack)):
Jean-Paul Calderone73b15c22013-03-05 18:30:39 -08001381 # TODO could incref instead of dup here
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001382 cert = _lib.X509_dup(_lib.sk_X509_value(cert_stack, i))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001383 pycert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001384 pycert._x509 = _ffi.gc(cert, _lib.X509_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001385 result.append(pycert)
1386 return result
1387
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001388
1389 def want_read(self):
1390 """
1391 Checks if more data has to be read from the transport layer to complete an
1392 operation.
1393
1394 :return: True iff more data has to be read
1395 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001396 return _lib.SSL_want_read(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001397
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001398
1399 def want_write(self):
1400 """
1401 Checks if there is data to write to the transport layer to complete an
1402 operation.
1403
1404 :return: True iff there is data to write
1405 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001406 return _lib.SSL_want_write(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001407
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001408
1409 def set_accept_state(self):
1410 """
1411 Set the connection to work in server mode. The handshake will be handled
1412 automatically by read/write.
1413
1414 :return: None
1415 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001416 _lib.SSL_set_accept_state(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001417
1418
1419 def set_connect_state(self):
1420 """
1421 Set the connection to work in client mode. The handshake will be handled
1422 automatically by read/write.
1423
1424 :return: None
1425 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001426 _lib.SSL_set_connect_state(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001427
1428
1429 def get_session(self):
1430 """
1431 Returns the Session currently used.
1432
1433 @return: An instance of :py:class:`OpenSSL.SSL.Session` or :py:obj:`None` if
1434 no session exists.
1435 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001436 session = _lib.SSL_get1_session(self._ssl)
1437 if session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001438 return None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001439
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001440 pysession = Session.__new__(Session)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001441 pysession._session = _ffi.gc(session, _lib.SSL_SESSION_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001442 return pysession
1443
1444
1445 def set_session(self, session):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001446 """
1447 Set the session to be used when the TLS/SSL connection is established.
1448
1449 :param session: A Session instance representing the session to use.
1450 :returns: None
1451 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001452 if not isinstance(session, Session):
1453 raise TypeError("session must be a Session instance")
1454
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001455 result = _lib.SSL_set_session(self._ssl, session._session)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001456 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001457 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001458
Jean-Paul Calderonedbd76272014-03-29 18:09:40 -04001459
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001460 def _get_finished_message(self, function):
1461 """
1462 Helper to implement :py:meth:`get_finished` and
1463 :py:meth:`get_peer_finished`.
1464
1465 :param function: Either :py:data:`SSL_get_finished`: or
1466 :py:data:`SSL_get_peer_finished`.
1467
1468 :return: :py:data:`None` if the desired message has not yet been
1469 received, otherwise the contents of the message.
1470 :rtype: :py:class:`bytes` or :py:class:`NoneType`
1471 """
Jean-Paul Calderone01af9042014-03-30 11:40:42 -04001472 # The OpenSSL documentation says nothing about what might happen if the
1473 # count argument given is zero. Specifically, it doesn't say whether
1474 # the output buffer may be NULL in that case or not. Inspection of the
1475 # implementation reveals that it calls memcpy() unconditionally.
1476 # Section 7.1.4, paragraph 1 of the C standard suggests that
1477 # memcpy(NULL, source, 0) is not guaranteed to produce defined (let
1478 # alone desirable) behavior (though it probably does on just about
1479 # every implementation...)
1480 #
1481 # Allocate a tiny buffer to pass in (instead of just passing NULL as
1482 # one might expect) for the initial call so as to be safe against this
1483 # potentially undefined behavior.
1484 empty = _ffi.new("char[]", 0)
1485 size = function(self._ssl, empty, 0)
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001486 if size == 0:
1487 # No Finished message so far.
1488 return None
1489
1490 buf = _ffi.new("char[]", size)
1491 function(self._ssl, buf, size)
1492 return _ffi.buffer(buf, size)[:]
1493
1494
Fedor Brunner5747b932014-03-05 14:22:34 +01001495 def get_finished(self):
1496 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001497 Obtain the latest `handshake finished` message sent to the peer.
Fedor Brunner5747b932014-03-05 14:22:34 +01001498
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001499 :return: The contents of the message or :py:obj:`None` if the TLS
1500 handshake has not yet completed.
1501 :rtype: :py:class:`bytes` or :py:class:`NoneType`
Fedor Brunner5747b932014-03-05 14:22:34 +01001502 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001503 return self._get_finished_message(_lib.SSL_get_finished)
1504
Fedor Brunner5747b932014-03-05 14:22:34 +01001505
1506 def get_peer_finished(self):
1507 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001508 Obtain the latest `handshake finished` message received from the peer.
Fedor Brunner5747b932014-03-05 14:22:34 +01001509
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001510 :return: The contents of the message or :py:obj:`None` if the TLS
1511 handshake has not yet completed.
1512 :rtype: :py:class:`bytes` or :py:class:`NoneType`
Fedor Brunner5747b932014-03-05 14:22:34 +01001513 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001514 return self._get_finished_message(_lib.SSL_get_peer_finished)
Fedor Brunner5747b932014-03-05 14:22:34 +01001515
Jean-Paul Calderone7c556ef2014-03-30 10:45:00 -04001516
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001517 def get_cipher_name(self):
1518 """
1519 Obtain the name of the currently used cipher.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001520
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001521 :returns: The name of the currently used cipher or :py:obj:`None`
1522 if no connection has been established.
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001523 :rtype: :py:class:`unicode` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001524 """
1525 cipher = _lib.SSL_get_current_cipher(self._ssl)
1526 if cipher == _ffi.NULL:
1527 return None
1528 else:
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001529 name = _ffi.string(_lib.SSL_CIPHER_get_name(cipher))
1530 return name.decode("utf-8")
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001531
Jean-Paul Calderonedbd76272014-03-29 18:09:40 -04001532
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001533 def get_cipher_bits(self):
1534 """
1535 Obtain the number of secret bits of the currently used cipher.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001536
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001537 :returns: The number of secret bits of the currently used cipher
1538 or :py:obj:`None` if no connection has been established.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001539 :rtype: :py:class:`int` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001540 """
1541 cipher = _lib.SSL_get_current_cipher(self._ssl)
1542 if cipher == _ffi.NULL:
1543 return None
1544 else:
1545 return _lib.SSL_CIPHER_get_bits(cipher, _ffi.NULL)
1546
Jean-Paul Calderonedbd76272014-03-29 18:09:40 -04001547
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001548 def get_cipher_version(self):
1549 """
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001550 Obtain the protocol version of the currently used cipher.
1551
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001552 :returns: The protocol name of the currently used cipher
1553 or :py:obj:`None` if no connection has been established.
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001554 :rtype: :py:class:`unicode` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001555 """
1556 cipher = _lib.SSL_get_current_cipher(self._ssl)
1557 if cipher == _ffi.NULL:
1558 return None
1559 else:
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001560 version =_ffi.string(_lib.SSL_CIPHER_get_version(cipher))
1561 return version.decode("utf-8")
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001562
1563
1564
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001565ConnectionType = Connection
Jean-Paul Calderone11ed8e82014-01-18 10:21:50 -05001566
Jean-Paul Calderonefab157b2014-01-18 11:21:38 -05001567# This is similar to the initialization calls at the end of OpenSSL/crypto.py
1568# but is exercised mostly by the Context initializer.
Jean-Paul Calderone11ed8e82014-01-18 10:21:50 -05001569_lib.SSL_library_init()