blob: aaee300f06371c8c85e85e908242ace01a90ab8e [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,
Jean-Paul Calderone55f9e882015-04-12 09:31:03 -040014 native as _native,
15 path_string as _path_string,
16)
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080017
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -080018from OpenSSL.crypto import (
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -050019 FILETYPE_PEM, _PassphraseHelper, PKey, X509Name, X509, X509Store)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -080020
21_unspecified = object()
22
Jean-Paul Calderone8fb53182013-12-30 08:35:49 -050023try:
24 _memoryview = memoryview
25except NameError:
26 class _memoryview(object):
27 pass
28
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +020029try:
30 _buffer = buffer
31except NameError:
32 class _buffer(object):
33 pass
34
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050035OPENSSL_VERSION_NUMBER = _lib.OPENSSL_VERSION_NUMBER
36SSLEAY_VERSION = _lib.SSLEAY_VERSION
37SSLEAY_CFLAGS = _lib.SSLEAY_CFLAGS
38SSLEAY_PLATFORM = _lib.SSLEAY_PLATFORM
39SSLEAY_DIR = _lib.SSLEAY_DIR
40SSLEAY_BUILT_ON = _lib.SSLEAY_BUILT_ON
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080041
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050042SENT_SHUTDOWN = _lib.SSL_SENT_SHUTDOWN
43RECEIVED_SHUTDOWN = _lib.SSL_RECEIVED_SHUTDOWN
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080044
45SSLv2_METHOD = 1
46SSLv3_METHOD = 2
47SSLv23_METHOD = 3
48TLSv1_METHOD = 4
Jean-Paul Calderone56bff942013-11-03 11:30:43 -050049TLSv1_1_METHOD = 5
50TLSv1_2_METHOD = 6
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080051
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050052OP_NO_SSLv2 = _lib.SSL_OP_NO_SSLv2
53OP_NO_SSLv3 = _lib.SSL_OP_NO_SSLv3
54OP_NO_TLSv1 = _lib.SSL_OP_NO_TLSv1
Jean-Paul Calderonebe2bb422013-12-29 07:34:08 -050055
56OP_NO_TLSv1_1 = getattr(_lib, "SSL_OP_NO_TLSv1_1", 0)
57OP_NO_TLSv1_2 = getattr(_lib, "SSL_OP_NO_TLSv1_2", 0)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -080058
Jean-Paul Calderone0d7e8a12014-01-08 16:54:13 -050059try:
60 MODE_RELEASE_BUFFERS = _lib.SSL_MODE_RELEASE_BUFFERS
61except AttributeError:
62 pass
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080063
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050064OP_SINGLE_DH_USE = _lib.SSL_OP_SINGLE_DH_USE
65OP_EPHEMERAL_RSA = _lib.SSL_OP_EPHEMERAL_RSA
66OP_MICROSOFT_SESS_ID_BUG = _lib.SSL_OP_MICROSOFT_SESS_ID_BUG
67OP_NETSCAPE_CHALLENGE_BUG = _lib.SSL_OP_NETSCAPE_CHALLENGE_BUG
68OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG = _lib.SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG
69OP_SSLREF2_REUSE_CERT_TYPE_BUG = _lib.SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG
70OP_MICROSOFT_BIG_SSLV3_BUFFER = _lib.SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER
Jean-Paul Calderone0d7e8a12014-01-08 16:54:13 -050071try:
72 OP_MSIE_SSLV2_RSA_PADDING = _lib.SSL_OP_MSIE_SSLV2_RSA_PADDING
73except AttributeError:
74 pass
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050075OP_SSLEAY_080_CLIENT_DH_BUG = _lib.SSL_OP_SSLEAY_080_CLIENT_DH_BUG
76OP_TLS_D5_BUG = _lib.SSL_OP_TLS_D5_BUG
77OP_TLS_BLOCK_PADDING_BUG = _lib.SSL_OP_TLS_BLOCK_PADDING_BUG
78OP_DONT_INSERT_EMPTY_FRAGMENTS = _lib.SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
79OP_CIPHER_SERVER_PREFERENCE = _lib.SSL_OP_CIPHER_SERVER_PREFERENCE
80OP_TLS_ROLLBACK_BUG = _lib.SSL_OP_TLS_ROLLBACK_BUG
81OP_PKCS1_CHECK_1 = _lib.SSL_OP_PKCS1_CHECK_1
82OP_PKCS1_CHECK_2 = _lib.SSL_OP_PKCS1_CHECK_2
83OP_NETSCAPE_CA_DN_BUG = _lib.SSL_OP_NETSCAPE_CA_DN_BUG
84OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG= _lib.SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG
Jean-Paul Calderonec1780342014-01-08 16:59:03 -050085try:
86 OP_NO_COMPRESSION = _lib.SSL_OP_NO_COMPRESSION
87except AttributeError:
88 pass
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -080089
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050090OP_NO_QUERY_MTU = _lib.SSL_OP_NO_QUERY_MTU
91OP_COOKIE_EXCHANGE = _lib.SSL_OP_COOKIE_EXCHANGE
Arturo Filastò5f8c7a82014-03-09 20:01:25 +010092try:
93 OP_NO_TICKET = _lib.SSL_OP_NO_TICKET
94except AttributeError:
95 pass
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -080096
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050097OP_ALL = _lib.SSL_OP_ALL
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080098
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050099VERIFY_PEER = _lib.SSL_VERIFY_PEER
100VERIFY_FAIL_IF_NO_PEER_CERT = _lib.SSL_VERIFY_FAIL_IF_NO_PEER_CERT
101VERIFY_CLIENT_ONCE = _lib.SSL_VERIFY_CLIENT_ONCE
102VERIFY_NONE = _lib.SSL_VERIFY_NONE
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -0800103
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500104SESS_CACHE_OFF = _lib.SSL_SESS_CACHE_OFF
105SESS_CACHE_CLIENT = _lib.SSL_SESS_CACHE_CLIENT
106SESS_CACHE_SERVER = _lib.SSL_SESS_CACHE_SERVER
107SESS_CACHE_BOTH = _lib.SSL_SESS_CACHE_BOTH
108SESS_CACHE_NO_AUTO_CLEAR = _lib.SSL_SESS_CACHE_NO_AUTO_CLEAR
109SESS_CACHE_NO_INTERNAL_LOOKUP = _lib.SSL_SESS_CACHE_NO_INTERNAL_LOOKUP
110SESS_CACHE_NO_INTERNAL_STORE = _lib.SSL_SESS_CACHE_NO_INTERNAL_STORE
111SESS_CACHE_NO_INTERNAL = _lib.SSL_SESS_CACHE_NO_INTERNAL
Jean-Paul Calderoned39a3f62013-03-04 12:23:51 -0800112
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500113SSL_ST_CONNECT = _lib.SSL_ST_CONNECT
114SSL_ST_ACCEPT = _lib.SSL_ST_ACCEPT
115SSL_ST_MASK = _lib.SSL_ST_MASK
116SSL_ST_INIT = _lib.SSL_ST_INIT
117SSL_ST_BEFORE = _lib.SSL_ST_BEFORE
118SSL_ST_OK = _lib.SSL_ST_OK
119SSL_ST_RENEGOTIATE = _lib.SSL_ST_RENEGOTIATE
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800120
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500121SSL_CB_LOOP = _lib.SSL_CB_LOOP
122SSL_CB_EXIT = _lib.SSL_CB_EXIT
123SSL_CB_READ = _lib.SSL_CB_READ
124SSL_CB_WRITE = _lib.SSL_CB_WRITE
125SSL_CB_ALERT = _lib.SSL_CB_ALERT
126SSL_CB_READ_ALERT = _lib.SSL_CB_READ_ALERT
127SSL_CB_WRITE_ALERT = _lib.SSL_CB_WRITE_ALERT
128SSL_CB_ACCEPT_LOOP = _lib.SSL_CB_ACCEPT_LOOP
129SSL_CB_ACCEPT_EXIT = _lib.SSL_CB_ACCEPT_EXIT
130SSL_CB_CONNECT_LOOP = _lib.SSL_CB_CONNECT_LOOP
131SSL_CB_CONNECT_EXIT = _lib.SSL_CB_CONNECT_EXIT
132SSL_CB_HANDSHAKE_START = _lib.SSL_CB_HANDSHAKE_START
133SSL_CB_HANDSHAKE_DONE = _lib.SSL_CB_HANDSHAKE_DONE
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800134
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500135class Error(Exception):
Jean-Paul Calderone511cde02013-12-29 10:31:13 -0500136 """
137 An error occurred in an `OpenSSL.SSL` API.
138 """
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500139
140
141
142_raise_current_error = partial(_exception_from_error_queue, Error)
143
144
145class WantReadError(Error):
146 pass
147
148
149
150class WantWriteError(Error):
151 pass
152
153
154
155class WantX509LookupError(Error):
156 pass
157
158
159
160class ZeroReturnError(Error):
161 pass
162
163
164
165class SysCallError(Error):
166 pass
167
168
169
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800170class _VerifyHelper(object):
Jean-Paul Calderone6a8cd112014-04-02 21:09:08 -0400171 def __init__(self, callback):
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800172 self._problems = []
173
174 @wraps(callback)
175 def wrapper(ok, store_ctx):
176 cert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500177 cert._x509 = _lib.X509_STORE_CTX_get_current_cert(store_ctx)
178 error_number = _lib.X509_STORE_CTX_get_error(store_ctx)
179 error_depth = _lib.X509_STORE_CTX_get_error_depth(store_ctx)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800180
Jean-Paul Calderone6a8cd112014-04-02 21:09:08 -0400181 index = _lib.SSL_get_ex_data_X509_STORE_CTX_idx()
182 ssl = _lib.X509_STORE_CTX_get_ex_data(store_ctx, index)
183 connection = Connection._reverse_mapping[ssl]
184
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800185 try:
186 result = callback(connection, cert, error_number, error_depth, ok)
187 except Exception as e:
188 self._problems.append(e)
189 return 0
190 else:
191 if result:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500192 _lib.X509_STORE_CTX_set_error(store_ctx, _lib.X509_V_OK)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800193 return 1
194 else:
195 return 0
196
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500197 self.callback = _ffi.callback(
198 "int (*)(int, X509_STORE_CTX *)", wrapper)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800199
200
201 def raise_if_problem(self):
202 if self._problems:
203 try:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500204 _raise_current_error()
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800205 except Error:
206 pass
207 raise self._problems.pop(0)
208
209
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800210
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800211def _asFileDescriptor(obj):
212 fd = None
Konstantinos Koukopoulosc8b13ea2014-01-28 00:21:50 -0800213 if not isinstance(obj, integer_types):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800214 meth = getattr(obj, "fileno", None)
215 if meth is not None:
216 obj = meth()
217
Konstantinos Koukopoulosc8b13ea2014-01-28 00:21:50 -0800218 if isinstance(obj, integer_types):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800219 fd = obj
220
Konstantinos Koukopoulosc8b13ea2014-01-28 00:21:50 -0800221 if not isinstance(fd, integer_types):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800222 raise TypeError("argument must be an int, or have a fileno() method.")
223 elif fd < 0:
224 raise ValueError(
225 "file descriptor cannot be a negative integer (%i)" % (fd,))
226
227 return fd
228
229
230
Jean-Paul Calderoned39a3f62013-03-04 12:23:51 -0800231def SSLeay_version(type):
232 """
233 Return a string describing the version of OpenSSL in use.
234
235 :param type: One of the SSLEAY_ constants defined in this module.
236 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500237 return _ffi.string(_lib.SSLeay_version(type))
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800238
239
240
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800241class Session(object):
242 pass
243
244
245
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800246class Context(object):
247 """
248 :py:obj:`OpenSSL.SSL.Context` instances define the parameters for setting up
249 new SSL connections.
250 """
251 _methods = {
Andrew Dunhamec84a0a2014-02-24 12:41:37 -0800252 SSLv2_METHOD: "SSLv2_method",
Jean-Paul Calderonebe2bb422013-12-29 07:34:08 -0500253 SSLv3_METHOD: "SSLv3_method",
254 SSLv23_METHOD: "SSLv23_method",
255 TLSv1_METHOD: "TLSv1_method",
256 TLSv1_1_METHOD: "TLSv1_1_method",
257 TLSv1_2_METHOD: "TLSv1_2_method",
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800258 }
Jean-Paul Calderonebe2bb422013-12-29 07:34:08 -0500259 _methods = dict(
260 (identifier, getattr(_lib, name))
261 for (identifier, name) in _methods.items()
262 if getattr(_lib, name, None) is not None)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800263
Jean-Paul Calderone63157872013-03-20 16:43:38 -0700264
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800265 def __init__(self, method):
266 """
267 :param method: One of SSLv2_METHOD, SSLv3_METHOD, SSLv23_METHOD, or
268 TLSv1_METHOD.
269 """
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -0500270 if not isinstance(method, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800271 raise TypeError("method must be an integer")
272
273 try:
274 method_func = self._methods[method]
275 except KeyError:
276 raise ValueError("No such protocol")
277
278 method_obj = method_func()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500279 if method_obj == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500280 # TODO: This is untested.
281 _raise_current_error()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800282
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500283 context = _lib.SSL_CTX_new(method_obj)
284 if context == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500285 # TODO: This is untested.
286 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500287 context = _ffi.gc(context, _lib.SSL_CTX_free)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800288
289 self._context = context
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800290 self._passphrase_helper = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800291 self._passphrase_callback = None
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800292 self._passphrase_userdata = None
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800293 self._verify_helper = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800294 self._verify_callback = None
295 self._info_callback = None
296 self._tlsext_servername_callback = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800297 self._app_data = None
298
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -0800299 # SSL_CTX_set_app_data(self->ctx, self);
300 # SSL_CTX_set_mode(self->ctx, SSL_MODE_ENABLE_PARTIAL_WRITE |
301 # SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
302 # SSL_MODE_AUTO_RETRY);
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500303 self.set_mode(_lib.SSL_MODE_ENABLE_PARTIAL_WRITE)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800304
305
306 def load_verify_locations(self, cafile, capath=None):
307 """
308 Let SSL know where we can find trusted certificates for the certificate
309 chain
310
Jean-Paul Calderone55f9e882015-04-12 09:31:03 -0400311 :param cafile: In which file we can find the certificates (``bytes`` or
312 ``unicode``).
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800313 :param capath: In which directory we can find the certificates
Jean-Paul Calderone55f9e882015-04-12 09:31:03 -0400314 (``bytes`` or ``unicode``).
315
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800316 :return: None
317 """
318 if cafile is None:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500319 cafile = _ffi.NULL
Jean-Paul Calderone55f9e882015-04-12 09:31:03 -0400320 else:
321 cafile = _path_string(cafile)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800322
323 if capath is None:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500324 capath = _ffi.NULL
Jean-Paul Calderone55f9e882015-04-12 09:31:03 -0400325 else:
326 capath = _path_string(capath)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800327
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500328 load_result = _lib.SSL_CTX_load_verify_locations(self._context, cafile, capath)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800329 if not load_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500330 _raise_current_error()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800331
332
333 def _wrap_callback(self, callback):
334 @wraps(callback)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800335 def wrapper(size, verify, userdata):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800336 return callback(size, verify, self._passphrase_userdata)
337 return _PassphraseHelper(
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800338 FILETYPE_PEM, wrapper, more_args=True, truncate=True)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800339
340
341 def set_passwd_cb(self, callback, userdata=None):
342 """
343 Set the passphrase callback
344
345 :param callback: The Python callback to use
346 :param userdata: (optional) A Python object which will be given as
347 argument to the callback
348 :return: None
349 """
350 if not callable(callback):
351 raise TypeError("callback must be callable")
352
353 self._passphrase_helper = self._wrap_callback(callback)
354 self._passphrase_callback = self._passphrase_helper.callback
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500355 _lib.SSL_CTX_set_default_passwd_cb(
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800356 self._context, self._passphrase_callback)
357 self._passphrase_userdata = userdata
358
359
360 def set_default_verify_paths(self):
361 """
362 Use the platform-specific CA certificate locations
363
364 :return: None
365 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500366 set_result = _lib.SSL_CTX_set_default_verify_paths(self._context)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800367 if not set_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500368 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500369 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800370
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800371
372 def use_certificate_chain_file(self, certfile):
373 """
374 Load a certificate chain from a file
375
376 :param certfile: The name of the certificate chain file
377 :return: None
378 """
Jean-Paul Calderoned8607982014-01-18 10:30:55 -0500379 if isinstance(certfile, _text_type):
380 # Perhaps sys.getfilesystemencoding() could be better?
381 certfile = certfile.encode("utf-8")
382
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800383 if not isinstance(certfile, bytes):
Jean-Paul Calderoned8607982014-01-18 10:30:55 -0500384 raise TypeError("certfile must be bytes or unicode")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800385
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500386 result = _lib.SSL_CTX_use_certificate_chain_file(self._context, certfile)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800387 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500388 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800389
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800390
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800391 def use_certificate_file(self, certfile, filetype=FILETYPE_PEM):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800392 """
393 Load a certificate from a file
394
395 :param certfile: The name of the certificate file
396 :param filetype: (optional) The encoding of the file, default is PEM
397 :return: None
398 """
Jean-Paul Calderone684baf52014-01-18 10:31:19 -0500399 if isinstance(certfile, _text_type):
400 # Perhaps sys.getfilesystemencoding() could be better?
401 certfile = certfile.encode("utf-8")
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800402 if not isinstance(certfile, bytes):
Jean-Paul Calderone684baf52014-01-18 10:31:19 -0500403 raise TypeError("certfile must be bytes or unicode")
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -0500404 if not isinstance(filetype, integer_types):
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800405 raise TypeError("filetype must be an integer")
406
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500407 use_result = _lib.SSL_CTX_use_certificate_file(self._context, certfile, filetype)
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800408 if not use_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500409 _raise_current_error()
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800410
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800411
412 def use_certificate(self, cert):
413 """
414 Load a certificate from a X509 object
415
416 :param cert: The X509 object
417 :return: None
418 """
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800419 if not isinstance(cert, X509):
420 raise TypeError("cert must be an X509 instance")
421
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500422 use_result = _lib.SSL_CTX_use_certificate(self._context, cert._x509)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800423 if not use_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500424 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800425
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800426
427 def add_extra_chain_cert(self, certobj):
428 """
429 Add certificate to chain
430
431 :param certobj: The X509 certificate object to add to the chain
432 :return: None
433 """
434 if not isinstance(certobj, X509):
435 raise TypeError("certobj must be an X509 instance")
436
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500437 copy = _lib.X509_dup(certobj._x509)
438 add_result = _lib.SSL_CTX_add_extra_chain_cert(self._context, copy)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800439 if not add_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500440 # TODO: This is untested.
441 _lib.X509_free(copy)
442 _raise_current_error()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800443
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800444
445 def _raise_passphrase_exception(self):
446 if self._passphrase_helper is None:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500447 _raise_current_error()
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800448 exception = self._passphrase_helper.raise_if_problem(Error)
449 if exception is not None:
450 raise exception
451
452
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800453 def use_privatekey_file(self, keyfile, filetype=_unspecified):
454 """
455 Load a private key from a file
456
457 :param keyfile: The name of the key file
458 :param filetype: (optional) The encoding of the file, default is PEM
459 :return: None
460 """
Jean-Paul Calderone87e525a2014-01-18 10:31:51 -0500461 if isinstance(keyfile, _text_type):
462 # Perhaps sys.getfilesystemencoding() could be better?
463 keyfile = keyfile.encode("utf-8")
464
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800465 if not isinstance(keyfile, bytes):
466 raise TypeError("keyfile must be a byte string")
467
468 if filetype is _unspecified:
469 filetype = FILETYPE_PEM
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -0500470 elif not isinstance(filetype, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800471 raise TypeError("filetype must be an integer")
472
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500473 use_result = _lib.SSL_CTX_use_PrivateKey_file(
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800474 self._context, keyfile, filetype)
475 if not use_result:
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800476 self._raise_passphrase_exception()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800477
478
479 def use_privatekey(self, pkey):
480 """
481 Load a private key from a PKey object
482
483 :param pkey: The PKey object
484 :return: None
485 """
486 if not isinstance(pkey, PKey):
487 raise TypeError("pkey must be a PKey instance")
488
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500489 use_result = _lib.SSL_CTX_use_PrivateKey(self._context, pkey._pkey)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800490 if not use_result:
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800491 self._raise_passphrase_exception()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800492
493
494 def check_privatekey(self):
495 """
496 Check that the private key and certificate match up
497
498 :return: None (raises an exception if something's wrong)
499 """
500
501 def load_client_ca(self, cafile):
502 """
503 Load the trusted certificates that will be sent to the client (basically
504 telling the client "These are the guys I trust"). Does not actually
505 imply any of the certificates are trusted; that must be configured
506 separately.
507
508 :param cafile: The name of the certificates file
509 :return: None
510 """
511
512 def set_session_id(self, buf):
513 """
514 Set the session identifier. This is needed if you want to do session
515 resumption.
516
517 :param buf: A Python object that can be safely converted to a string
518 :returns: None
519 """
520
521 def set_session_cache_mode(self, mode):
522 """
523 Enable/disable session caching and specify the mode used.
524
525 :param mode: One or more of the SESS_CACHE_* flags (combine using
526 bitwise or)
527 :returns: The previously set caching mode.
528 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500529 if not isinstance(mode, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800530 raise TypeError("mode must be an integer")
531
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500532 return _lib.SSL_CTX_set_session_cache_mode(self._context, mode)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800533
534
535 def get_session_cache_mode(self):
536 """
537 :returns: The currently used cache mode.
538 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500539 return _lib.SSL_CTX_get_session_cache_mode(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800540
541
542 def set_verify(self, mode, callback):
543 """
544 Set the verify mode and verify callback
545
546 :param mode: The verify mode, this is either VERIFY_NONE or
547 VERIFY_PEER combined with possible other flags
548 :param callback: The Python callback to use
549 :return: None
550
551 See SSL_CTX_set_verify(3SSL) for further details.
552 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500553 if not isinstance(mode, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800554 raise TypeError("mode must be an integer")
555
556 if not callable(callback):
557 raise TypeError("callback must be callable")
558
Jean-Paul Calderone6a8cd112014-04-02 21:09:08 -0400559 self._verify_helper = _VerifyHelper(callback)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800560 self._verify_callback = self._verify_helper.callback
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500561 _lib.SSL_CTX_set_verify(self._context, mode, self._verify_callback)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800562
563
564 def set_verify_depth(self, depth):
565 """
566 Set the verify depth
567
568 :param depth: An integer specifying the verify depth
569 :return: None
570 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500571 if not isinstance(depth, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800572 raise TypeError("depth must be an integer")
573
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500574 _lib.SSL_CTX_set_verify_depth(self._context, depth)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800575
576
577 def get_verify_mode(self):
578 """
579 Get the verify mode
580
581 :return: The verify mode
582 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500583 return _lib.SSL_CTX_get_verify_mode(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800584
585
586 def get_verify_depth(self):
587 """
588 Get the verify depth
589
590 :return: The verify depth
591 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500592 return _lib.SSL_CTX_get_verify_depth(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800593
594
595 def load_tmp_dh(self, dhfile):
596 """
597 Load parameters for Ephemeral Diffie-Hellman
598
599 :param dhfile: The file to load EDH parameters from
600 :return: None
601 """
602 if not isinstance(dhfile, bytes):
603 raise TypeError("dhfile must be a byte string")
604
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -0500605 bio = _lib.BIO_new_file(dhfile, b"r")
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500606 if bio == _ffi.NULL:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500607 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500608 bio = _ffi.gc(bio, _lib.BIO_free)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800609
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500610 dh = _lib.PEM_read_bio_DHparams(bio, _ffi.NULL, _ffi.NULL, _ffi.NULL)
611 dh = _ffi.gc(dh, _lib.DH_free)
612 _lib.SSL_CTX_set_tmp_dh(self._context, dh)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800613
614
Jean-Paul Calderone3e4e3352014-04-19 09:28:28 -0400615 def set_tmp_ecdh(self, curve):
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600616 """
Andy Lutomirski76a61332014-03-12 15:02:56 -0700617 Select a curve to use for ECDHE key exchange.
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600618
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -0400619 :param curve: A curve object to use as returned by either
620 :py:meth:`OpenSSL.crypto.get_elliptic_curve` or
621 :py:meth:`OpenSSL.crypto.get_elliptic_curves`.
Andy Lutomirskif05a2732014-03-13 17:22:25 -0700622
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600623 :return: None
624 """
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -0400625 _lib.SSL_CTX_set_tmp_ecdh(self._context, curve._to_EC_KEY())
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600626
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
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +0200970 :param buf: The string, buffer or memoryview to send
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800971 :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()
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +0200977 if isinstance(buf, _buffer):
978 buf = str(buf)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800979 if not isinstance(buf, bytes):
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +0200980 raise TypeError("data must be a memoryview, buffer or byte string")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800981
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500982 result = _lib.SSL_write(self._ssl, buf, len(buf))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800983 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800984 return result
985 write = send
986
987
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800988 def sendall(self, buf, flags=0):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800989 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800990 Send "all" data on the connection. This calls send() repeatedly until
991 all data is sent. If an error occurs, it's impossible to tell how much
992 data has been sent.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800993
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +0200994 :param buf: The string, buffer or memoryview to send
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800995 :param flags: (optional) Included for compatibility with the socket
996 API, the value is ignored
997 :return: The number of bytes written
998 """
Jean-Paul Calderone8fb53182013-12-30 08:35:49 -0500999 if isinstance(buf, _memoryview):
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -08001000 buf = buf.tobytes()
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001001 if isinstance(buf, _buffer):
1002 buf = str(buf)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001003 if not isinstance(buf, bytes):
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001004 raise TypeError("buf must be a memoryview, buffer or byte string")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001005
1006 left_to_send = len(buf)
1007 total_sent = 0
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001008 data = _ffi.new("char[]", buf)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001009
1010 while left_to_send:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001011 result = _lib.SSL_write(self._ssl, data + total_sent, left_to_send)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001012 self._raise_ssl_error(self._ssl, result)
1013 total_sent += result
1014 left_to_send -= result
1015
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001016
1017 def recv(self, bufsiz, flags=None):
1018 """
1019 Receive data on the connection. NOTE: If you get one of the WantRead,
1020 WantWrite or WantX509Lookup exceptions on this, you have to call the
1021 method again with the SAME buffer.
1022
1023 :param bufsiz: The maximum number of bytes to read
1024 :param flags: (optional) Included for compatibility with the socket
1025 API, the value is ignored
1026 :return: The string read from the Connection
1027 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001028 buf = _ffi.new("char[]", bufsiz)
1029 result = _lib.SSL_read(self._ssl, buf, bufsiz)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001030 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001031 return _ffi.buffer(buf, result)[:]
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001032 read = recv
1033
1034
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001035 def _handle_bio_errors(self, bio, result):
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001036 if _lib.BIO_should_retry(bio):
1037 if _lib.BIO_should_read(bio):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001038 raise WantReadError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001039 elif _lib.BIO_should_write(bio):
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001040 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001041 raise WantWriteError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001042 elif _lib.BIO_should_io_special(bio):
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001043 # TODO: This is untested. I think io_special means the socket
1044 # BIO has a not-yet connected socket.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001045 raise ValueError("BIO_should_io_special")
1046 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001047 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001048 raise ValueError("unknown bio failure")
1049 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001050 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001051 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001052
1053
1054 def bio_read(self, bufsiz):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001055 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001056 When using non-socket connections this function reads the "dirty" data
1057 that would have traveled away on the network.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001058
1059 :param bufsiz: The maximum number of bytes to read
1060 :return: The string read.
1061 """
Jean-Paul Calderone97e041d2013-03-05 21:03:12 -08001062 if self._from_ssl is None:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001063 raise TypeError("Connection sock was not None")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001064
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -05001065 if not isinstance(bufsiz, integer_types):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001066 raise TypeError("bufsiz must be an integer")
1067
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001068 buf = _ffi.new("char[]", bufsiz)
1069 result = _lib.BIO_read(self._from_ssl, buf, bufsiz)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001070 if result <= 0:
1071 self._handle_bio_errors(self._from_ssl, result)
1072
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001073 return _ffi.buffer(buf, result)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001074
1075
1076 def bio_write(self, buf):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001077 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001078 When using non-socket connections this function sends "dirty" data that
1079 would have traveled in on the network.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001080
1081 :param buf: The string to put into the memory BIO.
1082 :return: The number of bytes written
1083 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001084 if self._into_ssl is None:
1085 raise TypeError("Connection sock was not None")
1086
1087 if not isinstance(buf, bytes):
1088 raise TypeError("buf must be a byte string")
1089
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001090 result = _lib.BIO_write(self._into_ssl, buf, len(buf))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001091 if result <= 0:
1092 self._handle_bio_errors(self._into_ssl, result)
1093 return result
1094
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001095
1096 def renegotiate(self):
1097 """
1098 Renegotiate the session
1099
1100 :return: True if the renegotiation can be started, false otherwise
1101 """
1102
1103 def do_handshake(self):
1104 """
1105 Perform an SSL handshake (usually called after renegotiate() or one of
1106 set_*_state()). This can raise the same exceptions as send and recv.
1107
1108 :return: None.
1109 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001110 result = _lib.SSL_do_handshake(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001111 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001112
1113
1114 def renegotiate_pending(self):
1115 """
1116 Check if there's a renegotiation in progress, it will return false once
1117 a renegotiation is finished.
1118
1119 :return: Whether there's a renegotiation in progress
1120 """
1121
1122 def total_renegotiations(self):
1123 """
1124 Find out the total number of renegotiations.
1125
1126 :return: The number of renegotiations.
1127 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001128 return _lib.SSL_total_renegotiations(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001129
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001130
1131 def connect(self, addr):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001132 """
1133 Connect to remote host and set up client-side SSL
1134
1135 :param addr: A remote address
1136 :return: What the socket's connect method returns
1137 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001138 _lib.SSL_set_connect_state(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001139 return self._socket.connect(addr)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001140
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001141
1142 def connect_ex(self, addr):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001143 """
1144 Connect to remote host and set up client-side SSL. Note that if the socket's
1145 connect_ex method doesn't return 0, SSL won't be initialized.
1146
1147 :param addr: A remove address
1148 :return: What the socket's connect_ex method returns
1149 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001150 connect_ex = self._socket.connect_ex
1151 self.set_connect_state()
1152 return connect_ex(addr)
1153
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001154
1155 def accept(self):
1156 """
1157 Accept incoming connection and set up SSL on it
1158
1159 :return: A (conn,addr) pair where conn is a Connection and addr is an
1160 address
1161 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001162 client, addr = self._socket.accept()
1163 conn = Connection(self._context, client)
1164 conn.set_accept_state()
1165 return (conn, addr)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001166
1167
1168 def bio_shutdown(self):
1169 """
1170 When using non-socket connections this function signals end of
1171 data on the input for this connection.
1172
1173 :return: None
1174 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001175 if self._from_ssl is None:
1176 raise TypeError("Connection sock was not None")
1177
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001178 _lib.BIO_set_mem_eof_return(self._into_ssl, 0)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001179
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001180
1181 def shutdown(self):
1182 """
1183 Send closure alert
1184
1185 :return: True if the shutdown completed successfully (i.e. both sides
1186 have sent closure alerts), false otherwise (i.e. you have to
1187 wait for a ZeroReturnError on a recv() method call
1188 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001189 result = _lib.SSL_shutdown(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001190 if result < 0:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001191 # TODO: This is untested.
1192 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001193 elif result > 0:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001194 return True
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001195 else:
1196 return False
1197
1198
1199 def get_cipher_list(self):
1200 """
1201 Get the session cipher list
1202
1203 :return: A list of cipher strings
1204 """
1205 ciphers = []
1206 for i in count():
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001207 result = _lib.SSL_get_cipher_list(self._ssl, i)
1208 if result == _ffi.NULL:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001209 break
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001210 ciphers.append(_native(_ffi.string(result)))
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001211 return ciphers
1212
1213
1214 def get_client_ca_list(self):
1215 """
1216 Get CAs whose certificates are suggested for client authentication.
1217
1218 :return: If this is a server connection, a list of X509Names representing
1219 the acceptable CAs as set by :py:meth:`OpenSSL.SSL.Context.set_client_ca_list` or
1220 :py:meth:`OpenSSL.SSL.Context.add_client_ca`. If this is a client connection,
1221 the list of such X509Names sent by the server, or an empty list if that
1222 has not yet happened.
1223 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001224 ca_names = _lib.SSL_get_client_CA_list(self._ssl)
1225 if ca_names == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001226 # TODO: This is untested.
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001227 return []
1228
1229 result = []
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001230 for i in range(_lib.sk_X509_NAME_num(ca_names)):
1231 name = _lib.sk_X509_NAME_value(ca_names, i)
1232 copy = _lib.X509_NAME_dup(name)
1233 if copy == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001234 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001235 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001236
1237 pyname = X509Name.__new__(X509Name)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001238 pyname._name = _ffi.gc(copy, _lib.X509_NAME_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001239 result.append(pyname)
1240 return result
1241
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001242
1243 def makefile(self):
1244 """
1245 The makefile() method is not implemented, since there is no dup semantics
1246 for SSL connections
1247
Jean-Paul Calderone6749ec22014-04-17 16:30:21 -04001248 :raise: NotImplementedError
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001249 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001250 raise NotImplementedError("Cannot make file object of OpenSSL.SSL.Connection")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001251
1252
1253 def get_app_data(self):
1254 """
1255 Get application data
1256
1257 :return: The application data
1258 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001259 return self._app_data
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001260
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001261
1262 def set_app_data(self, data):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001263 """
1264 Set application data
1265
1266 :param data - The application data
1267 :return: None
1268 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001269 self._app_data = data
1270
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001271
1272 def get_shutdown(self):
1273 """
1274 Get shutdown state
1275
1276 :return: The shutdown state, a bitvector of SENT_SHUTDOWN, RECEIVED_SHUTDOWN.
1277 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001278 return _lib.SSL_get_shutdown(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001279
1280
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001281 def set_shutdown(self, state):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001282 """
1283 Set shutdown state
1284
1285 :param state - bitvector of SENT_SHUTDOWN, RECEIVED_SHUTDOWN.
1286 :return: None
1287 """
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -05001288 if not isinstance(state, integer_types):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001289 raise TypeError("state must be an integer")
1290
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001291 _lib.SSL_set_shutdown(self._ssl, state)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001292
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001293
1294 def state_string(self):
1295 """
1296 Get a verbose state description
1297
1298 :return: A string representing the state
1299 """
1300
1301 def server_random(self):
1302 """
1303 Get a copy of the server hello nonce.
1304
1305 :return: A string representing the state
1306 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001307 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001308 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001309 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001310 self._ssl.s3.server_random,
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001311 _lib.SSL3_RANDOM_SIZE)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001312
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001313
1314 def client_random(self):
1315 """
1316 Get a copy of the client hello nonce.
1317
1318 :return: A string representing the state
1319 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001320 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001321 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001322 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001323 self._ssl.s3.client_random,
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001324 _lib.SSL3_RANDOM_SIZE)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001325
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001326
1327 def master_key(self):
1328 """
1329 Get a copy of the master key.
1330
1331 :return: A string representing the state
1332 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001333 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001334 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001335 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001336 self._ssl.session.master_key,
1337 self._ssl.session.master_key_length)[:]
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001338
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001339
1340 def sock_shutdown(self, *args, **kwargs):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001341 """
1342 See shutdown(2)
1343
1344 :return: What the socket's shutdown() method returns
1345 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001346 return self._socket.shutdown(*args, **kwargs)
1347
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001348
1349 def get_peer_certificate(self):
1350 """
1351 Retrieve the other side's certificate (if any)
1352
1353 :return: The peer's certificate
1354 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001355 cert = _lib.SSL_get_peer_certificate(self._ssl)
1356 if cert != _ffi.NULL:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001357 pycert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001358 pycert._x509 = _ffi.gc(cert, _lib.X509_free)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001359 return pycert
1360 return None
1361
1362
1363 def get_peer_cert_chain(self):
1364 """
1365 Retrieve the other side's certificate (if any)
1366
1367 :return: A list of X509 instances giving the peer's certificate chain,
1368 or None if it does not have one.
1369 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001370 cert_stack = _lib.SSL_get_peer_cert_chain(self._ssl)
1371 if cert_stack == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001372 return None
1373
1374 result = []
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001375 for i in range(_lib.sk_X509_num(cert_stack)):
Jean-Paul Calderone73b15c22013-03-05 18:30:39 -08001376 # TODO could incref instead of dup here
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001377 cert = _lib.X509_dup(_lib.sk_X509_value(cert_stack, i))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001378 pycert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001379 pycert._x509 = _ffi.gc(cert, _lib.X509_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001380 result.append(pycert)
1381 return result
1382
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001383
1384 def want_read(self):
1385 """
1386 Checks if more data has to be read from the transport layer to complete an
1387 operation.
1388
1389 :return: True iff more data has to be read
1390 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001391 return _lib.SSL_want_read(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001392
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001393
1394 def want_write(self):
1395 """
1396 Checks if there is data to write to the transport layer to complete an
1397 operation.
1398
1399 :return: True iff there is data to write
1400 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001401 return _lib.SSL_want_write(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001402
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001403
1404 def set_accept_state(self):
1405 """
1406 Set the connection to work in server mode. The handshake will be handled
1407 automatically by read/write.
1408
1409 :return: None
1410 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001411 _lib.SSL_set_accept_state(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001412
1413
1414 def set_connect_state(self):
1415 """
1416 Set the connection to work in client mode. The handshake will be handled
1417 automatically by read/write.
1418
1419 :return: None
1420 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001421 _lib.SSL_set_connect_state(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001422
1423
1424 def get_session(self):
1425 """
1426 Returns the Session currently used.
1427
1428 @return: An instance of :py:class:`OpenSSL.SSL.Session` or :py:obj:`None` if
1429 no session exists.
1430 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001431 session = _lib.SSL_get1_session(self._ssl)
1432 if session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001433 return None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001434
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001435 pysession = Session.__new__(Session)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001436 pysession._session = _ffi.gc(session, _lib.SSL_SESSION_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001437 return pysession
1438
1439
1440 def set_session(self, session):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001441 """
1442 Set the session to be used when the TLS/SSL connection is established.
1443
1444 :param session: A Session instance representing the session to use.
1445 :returns: None
1446 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001447 if not isinstance(session, Session):
1448 raise TypeError("session must be a Session instance")
1449
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001450 result = _lib.SSL_set_session(self._ssl, session._session)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001451 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001452 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001453
Jean-Paul Calderonedbd76272014-03-29 18:09:40 -04001454
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001455 def _get_finished_message(self, function):
1456 """
1457 Helper to implement :py:meth:`get_finished` and
1458 :py:meth:`get_peer_finished`.
1459
1460 :param function: Either :py:data:`SSL_get_finished`: or
1461 :py:data:`SSL_get_peer_finished`.
1462
1463 :return: :py:data:`None` if the desired message has not yet been
1464 received, otherwise the contents of the message.
1465 :rtype: :py:class:`bytes` or :py:class:`NoneType`
1466 """
Jean-Paul Calderone01af9042014-03-30 11:40:42 -04001467 # The OpenSSL documentation says nothing about what might happen if the
1468 # count argument given is zero. Specifically, it doesn't say whether
1469 # the output buffer may be NULL in that case or not. Inspection of the
1470 # implementation reveals that it calls memcpy() unconditionally.
1471 # Section 7.1.4, paragraph 1 of the C standard suggests that
1472 # memcpy(NULL, source, 0) is not guaranteed to produce defined (let
1473 # alone desirable) behavior (though it probably does on just about
1474 # every implementation...)
1475 #
1476 # Allocate a tiny buffer to pass in (instead of just passing NULL as
1477 # one might expect) for the initial call so as to be safe against this
1478 # potentially undefined behavior.
1479 empty = _ffi.new("char[]", 0)
1480 size = function(self._ssl, empty, 0)
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001481 if size == 0:
1482 # No Finished message so far.
1483 return None
1484
1485 buf = _ffi.new("char[]", size)
1486 function(self._ssl, buf, size)
1487 return _ffi.buffer(buf, size)[:]
1488
1489
Fedor Brunner5747b932014-03-05 14:22:34 +01001490 def get_finished(self):
1491 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001492 Obtain the latest `handshake finished` message sent to the peer.
Fedor Brunner5747b932014-03-05 14:22:34 +01001493
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001494 :return: The contents of the message or :py:obj:`None` if the TLS
1495 handshake has not yet completed.
1496 :rtype: :py:class:`bytes` or :py:class:`NoneType`
Fedor Brunner5747b932014-03-05 14:22:34 +01001497 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001498 return self._get_finished_message(_lib.SSL_get_finished)
1499
Fedor Brunner5747b932014-03-05 14:22:34 +01001500
1501 def get_peer_finished(self):
1502 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001503 Obtain the latest `handshake finished` message received from the peer.
Fedor Brunner5747b932014-03-05 14:22:34 +01001504
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001505 :return: The contents of the message or :py:obj:`None` if the TLS
1506 handshake has not yet completed.
1507 :rtype: :py:class:`bytes` or :py:class:`NoneType`
Fedor Brunner5747b932014-03-05 14:22:34 +01001508 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001509 return self._get_finished_message(_lib.SSL_get_peer_finished)
Fedor Brunner5747b932014-03-05 14:22:34 +01001510
Jean-Paul Calderone7c556ef2014-03-30 10:45:00 -04001511
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001512 def get_cipher_name(self):
1513 """
1514 Obtain the name of the currently used cipher.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001515
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001516 :returns: The name of the currently used cipher or :py:obj:`None`
1517 if no connection has been established.
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001518 :rtype: :py:class:`unicode` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001519 """
1520 cipher = _lib.SSL_get_current_cipher(self._ssl)
1521 if cipher == _ffi.NULL:
1522 return None
1523 else:
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001524 name = _ffi.string(_lib.SSL_CIPHER_get_name(cipher))
1525 return name.decode("utf-8")
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001526
Jean-Paul Calderonedbd76272014-03-29 18:09:40 -04001527
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001528 def get_cipher_bits(self):
1529 """
1530 Obtain the number of secret bits of the currently used cipher.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001531
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001532 :returns: The number of secret bits of the currently used cipher
1533 or :py:obj:`None` if no connection has been established.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001534 :rtype: :py:class:`int` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001535 """
1536 cipher = _lib.SSL_get_current_cipher(self._ssl)
1537 if cipher == _ffi.NULL:
1538 return None
1539 else:
1540 return _lib.SSL_CIPHER_get_bits(cipher, _ffi.NULL)
1541
Jean-Paul Calderonedbd76272014-03-29 18:09:40 -04001542
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001543 def get_cipher_version(self):
1544 """
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001545 Obtain the protocol version of the currently used cipher.
1546
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001547 :returns: The protocol name of the currently used cipher
1548 or :py:obj:`None` if no connection has been established.
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001549 :rtype: :py:class:`unicode` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001550 """
1551 cipher = _lib.SSL_get_current_cipher(self._ssl)
1552 if cipher == _ffi.NULL:
1553 return None
1554 else:
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001555 version =_ffi.string(_lib.SSL_CIPHER_get_version(cipher))
1556 return version.decode("utf-8")
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001557
1558
1559
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001560ConnectionType = Connection
Jean-Paul Calderone11ed8e82014-01-18 10:21:50 -05001561
Jean-Paul Calderonefab157b2014-01-18 11:21:38 -05001562# This is similar to the initialization calls at the end of OpenSSL/crypto.py
1563# but is exercised mostly by the Context initializer.
Jean-Paul Calderone11ed8e82014-01-18 10:21:50 -05001564_lib.SSL_library_init()