blob: f21ad9d43db2b7cb7e1e3c91037b6a675cd58e70 [file] [log] [blame]
Konstantinos Koukopoulos541150d2014-01-31 01:00:19 +02001from sys import platform
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05002from functools import wraps, partial
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08003from itertools import count
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08004from weakref import WeakValueDictionary
5from errno import errorcode
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -08006
Jean-Paul Calderone63eab692014-01-18 10:19:56 -05007from six import text_type as _text_type
Konstantinos Koukopoulosc8b13ea2014-01-28 00:21:50 -08008from six import integer_types as integer_types
Jean-Paul Calderone63eab692014-01-18 10:19:56 -05009
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -050010from OpenSSL._util import (
11 ffi as _ffi,
12 lib as _lib,
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -050013 exception_from_error_queue as _exception_from_error_queue,
14 native as _native)
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080015
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -080016from OpenSSL.crypto import (
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -050017 FILETYPE_PEM, _PassphraseHelper, PKey, X509Name, X509, X509Store)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -080018
19_unspecified = object()
20
Jean-Paul Calderone8fb53182013-12-30 08:35:49 -050021try:
22 _memoryview = memoryview
23except NameError:
24 class _memoryview(object):
25 pass
26
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050027OPENSSL_VERSION_NUMBER = _lib.OPENSSL_VERSION_NUMBER
28SSLEAY_VERSION = _lib.SSLEAY_VERSION
29SSLEAY_CFLAGS = _lib.SSLEAY_CFLAGS
30SSLEAY_PLATFORM = _lib.SSLEAY_PLATFORM
31SSLEAY_DIR = _lib.SSLEAY_DIR
32SSLEAY_BUILT_ON = _lib.SSLEAY_BUILT_ON
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080033
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050034SENT_SHUTDOWN = _lib.SSL_SENT_SHUTDOWN
35RECEIVED_SHUTDOWN = _lib.SSL_RECEIVED_SHUTDOWN
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080036
37SSLv2_METHOD = 1
38SSLv3_METHOD = 2
39SSLv23_METHOD = 3
40TLSv1_METHOD = 4
Jean-Paul Calderone56bff942013-11-03 11:30:43 -050041TLSv1_1_METHOD = 5
42TLSv1_2_METHOD = 6
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080043
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050044OP_NO_SSLv2 = _lib.SSL_OP_NO_SSLv2
45OP_NO_SSLv3 = _lib.SSL_OP_NO_SSLv3
46OP_NO_TLSv1 = _lib.SSL_OP_NO_TLSv1
Jean-Paul Calderonebe2bb422013-12-29 07:34:08 -050047
48OP_NO_TLSv1_1 = getattr(_lib, "SSL_OP_NO_TLSv1_1", 0)
49OP_NO_TLSv1_2 = getattr(_lib, "SSL_OP_NO_TLSv1_2", 0)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -080050
Jean-Paul Calderone0d7e8a12014-01-08 16:54:13 -050051try:
52 MODE_RELEASE_BUFFERS = _lib.SSL_MODE_RELEASE_BUFFERS
53except AttributeError:
54 pass
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080055
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050056OP_SINGLE_DH_USE = _lib.SSL_OP_SINGLE_DH_USE
57OP_EPHEMERAL_RSA = _lib.SSL_OP_EPHEMERAL_RSA
58OP_MICROSOFT_SESS_ID_BUG = _lib.SSL_OP_MICROSOFT_SESS_ID_BUG
59OP_NETSCAPE_CHALLENGE_BUG = _lib.SSL_OP_NETSCAPE_CHALLENGE_BUG
60OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG = _lib.SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG
61OP_SSLREF2_REUSE_CERT_TYPE_BUG = _lib.SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG
62OP_MICROSOFT_BIG_SSLV3_BUFFER = _lib.SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER
Jean-Paul Calderone0d7e8a12014-01-08 16:54:13 -050063try:
64 OP_MSIE_SSLV2_RSA_PADDING = _lib.SSL_OP_MSIE_SSLV2_RSA_PADDING
65except AttributeError:
66 pass
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050067OP_SSLEAY_080_CLIENT_DH_BUG = _lib.SSL_OP_SSLEAY_080_CLIENT_DH_BUG
68OP_TLS_D5_BUG = _lib.SSL_OP_TLS_D5_BUG
69OP_TLS_BLOCK_PADDING_BUG = _lib.SSL_OP_TLS_BLOCK_PADDING_BUG
70OP_DONT_INSERT_EMPTY_FRAGMENTS = _lib.SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
71OP_CIPHER_SERVER_PREFERENCE = _lib.SSL_OP_CIPHER_SERVER_PREFERENCE
72OP_TLS_ROLLBACK_BUG = _lib.SSL_OP_TLS_ROLLBACK_BUG
73OP_PKCS1_CHECK_1 = _lib.SSL_OP_PKCS1_CHECK_1
74OP_PKCS1_CHECK_2 = _lib.SSL_OP_PKCS1_CHECK_2
75OP_NETSCAPE_CA_DN_BUG = _lib.SSL_OP_NETSCAPE_CA_DN_BUG
76OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG= _lib.SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG
Jean-Paul Calderonec1780342014-01-08 16:59:03 -050077try:
78 OP_NO_COMPRESSION = _lib.SSL_OP_NO_COMPRESSION
79except AttributeError:
80 pass
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -080081
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050082OP_NO_QUERY_MTU = _lib.SSL_OP_NO_QUERY_MTU
83OP_COOKIE_EXCHANGE = _lib.SSL_OP_COOKIE_EXCHANGE
84OP_NO_TICKET = _lib.SSL_OP_NO_TICKET
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -080085
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050086OP_ALL = _lib.SSL_OP_ALL
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080087
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050088VERIFY_PEER = _lib.SSL_VERIFY_PEER
89VERIFY_FAIL_IF_NO_PEER_CERT = _lib.SSL_VERIFY_FAIL_IF_NO_PEER_CERT
90VERIFY_CLIENT_ONCE = _lib.SSL_VERIFY_CLIENT_ONCE
91VERIFY_NONE = _lib.SSL_VERIFY_NONE
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080092
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050093SESS_CACHE_OFF = _lib.SSL_SESS_CACHE_OFF
94SESS_CACHE_CLIENT = _lib.SSL_SESS_CACHE_CLIENT
95SESS_CACHE_SERVER = _lib.SSL_SESS_CACHE_SERVER
96SESS_CACHE_BOTH = _lib.SSL_SESS_CACHE_BOTH
97SESS_CACHE_NO_AUTO_CLEAR = _lib.SSL_SESS_CACHE_NO_AUTO_CLEAR
98SESS_CACHE_NO_INTERNAL_LOOKUP = _lib.SSL_SESS_CACHE_NO_INTERNAL_LOOKUP
99SESS_CACHE_NO_INTERNAL_STORE = _lib.SSL_SESS_CACHE_NO_INTERNAL_STORE
100SESS_CACHE_NO_INTERNAL = _lib.SSL_SESS_CACHE_NO_INTERNAL
Jean-Paul Calderoned39a3f62013-03-04 12:23:51 -0800101
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500102SSL_ST_CONNECT = _lib.SSL_ST_CONNECT
103SSL_ST_ACCEPT = _lib.SSL_ST_ACCEPT
104SSL_ST_MASK = _lib.SSL_ST_MASK
105SSL_ST_INIT = _lib.SSL_ST_INIT
106SSL_ST_BEFORE = _lib.SSL_ST_BEFORE
107SSL_ST_OK = _lib.SSL_ST_OK
108SSL_ST_RENEGOTIATE = _lib.SSL_ST_RENEGOTIATE
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800109
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500110SSL_CB_LOOP = _lib.SSL_CB_LOOP
111SSL_CB_EXIT = _lib.SSL_CB_EXIT
112SSL_CB_READ = _lib.SSL_CB_READ
113SSL_CB_WRITE = _lib.SSL_CB_WRITE
114SSL_CB_ALERT = _lib.SSL_CB_ALERT
115SSL_CB_READ_ALERT = _lib.SSL_CB_READ_ALERT
116SSL_CB_WRITE_ALERT = _lib.SSL_CB_WRITE_ALERT
117SSL_CB_ACCEPT_LOOP = _lib.SSL_CB_ACCEPT_LOOP
118SSL_CB_ACCEPT_EXIT = _lib.SSL_CB_ACCEPT_EXIT
119SSL_CB_CONNECT_LOOP = _lib.SSL_CB_CONNECT_LOOP
120SSL_CB_CONNECT_EXIT = _lib.SSL_CB_CONNECT_EXIT
121SSL_CB_HANDSHAKE_START = _lib.SSL_CB_HANDSHAKE_START
122SSL_CB_HANDSHAKE_DONE = _lib.SSL_CB_HANDSHAKE_DONE
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800123
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800124
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500125class Error(Exception):
Jean-Paul Calderone511cde02013-12-29 10:31:13 -0500126 """
127 An error occurred in an `OpenSSL.SSL` API.
128 """
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500129
130
131
132_raise_current_error = partial(_exception_from_error_queue, Error)
133
134
135class WantReadError(Error):
136 pass
137
138
139
140class WantWriteError(Error):
141 pass
142
143
144
145class WantX509LookupError(Error):
146 pass
147
148
149
150class ZeroReturnError(Error):
151 pass
152
153
154
155class SysCallError(Error):
156 pass
157
158
159
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800160class _VerifyHelper(object):
161 def __init__(self, connection, callback):
162 self._problems = []
163
164 @wraps(callback)
165 def wrapper(ok, store_ctx):
166 cert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500167 cert._x509 = _lib.X509_STORE_CTX_get_current_cert(store_ctx)
168 error_number = _lib.X509_STORE_CTX_get_error(store_ctx)
169 error_depth = _lib.X509_STORE_CTX_get_error_depth(store_ctx)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800170
171 try:
172 result = callback(connection, cert, error_number, error_depth, ok)
173 except Exception as e:
174 self._problems.append(e)
175 return 0
176 else:
177 if result:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500178 _lib.X509_STORE_CTX_set_error(store_ctx, _lib.X509_V_OK)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800179 return 1
180 else:
181 return 0
182
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500183 self.callback = _ffi.callback(
184 "int (*)(int, X509_STORE_CTX *)", wrapper)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800185
186
187 def raise_if_problem(self):
188 if self._problems:
189 try:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500190 _raise_current_error()
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800191 except Error:
192 pass
193 raise self._problems.pop(0)
194
195
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800196
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800197def _asFileDescriptor(obj):
198 fd = None
Konstantinos Koukopoulosc8b13ea2014-01-28 00:21:50 -0800199 if not isinstance(obj, integer_types):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800200 meth = getattr(obj, "fileno", None)
201 if meth is not None:
202 obj = meth()
203
Konstantinos Koukopoulosc8b13ea2014-01-28 00:21:50 -0800204 if isinstance(obj, integer_types):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800205 fd = obj
206
Konstantinos Koukopoulosc8b13ea2014-01-28 00:21:50 -0800207 if not isinstance(fd, integer_types):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800208 raise TypeError("argument must be an int, or have a fileno() method.")
209 elif fd < 0:
210 raise ValueError(
211 "file descriptor cannot be a negative integer (%i)" % (fd,))
212
213 return fd
214
215
216
Jean-Paul Calderoned39a3f62013-03-04 12:23:51 -0800217def SSLeay_version(type):
218 """
219 Return a string describing the version of OpenSSL in use.
220
221 :param type: One of the SSLEAY_ constants defined in this module.
222 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500223 return _ffi.string(_lib.SSLeay_version(type))
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800224
225
226
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800227class Session(object):
228 pass
229
230
231
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800232class Context(object):
233 """
234 :py:obj:`OpenSSL.SSL.Context` instances define the parameters for setting up
235 new SSL connections.
236 """
237 _methods = {
Jean-Paul Calderonebe2bb422013-12-29 07:34:08 -0500238 SSLv3_METHOD: "SSLv3_method",
239 SSLv23_METHOD: "SSLv23_method",
240 TLSv1_METHOD: "TLSv1_method",
241 TLSv1_1_METHOD: "TLSv1_1_method",
242 TLSv1_2_METHOD: "TLSv1_2_method",
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800243 }
Jean-Paul Calderonebe2bb422013-12-29 07:34:08 -0500244 _methods = dict(
245 (identifier, getattr(_lib, name))
246 for (identifier, name) in _methods.items()
247 if getattr(_lib, name, None) is not None)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800248
Jean-Paul Calderone63157872013-03-20 16:43:38 -0700249
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800250 def __init__(self, method):
251 """
252 :param method: One of SSLv2_METHOD, SSLv3_METHOD, SSLv23_METHOD, or
253 TLSv1_METHOD.
254 """
255 if not isinstance(method, int):
256 raise TypeError("method must be an integer")
257
258 try:
259 method_func = self._methods[method]
260 except KeyError:
261 raise ValueError("No such protocol")
262
263 method_obj = method_func()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500264 if method_obj == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500265 # TODO: This is untested.
266 _raise_current_error()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800267
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500268 context = _lib.SSL_CTX_new(method_obj)
269 if context == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500270 # TODO: This is untested.
271 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500272 context = _ffi.gc(context, _lib.SSL_CTX_free)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800273
274 self._context = context
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800275 self._passphrase_helper = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800276 self._passphrase_callback = None
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800277 self._passphrase_userdata = None
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800278 self._verify_helper = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800279 self._verify_callback = None
280 self._info_callback = None
281 self._tlsext_servername_callback = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800282 self._app_data = None
283
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -0800284 # SSL_CTX_set_app_data(self->ctx, self);
285 # SSL_CTX_set_mode(self->ctx, SSL_MODE_ENABLE_PARTIAL_WRITE |
286 # SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
287 # SSL_MODE_AUTO_RETRY);
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500288 self.set_mode(_lib.SSL_MODE_ENABLE_PARTIAL_WRITE)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800289
290
291 def load_verify_locations(self, cafile, capath=None):
292 """
293 Let SSL know where we can find trusted certificates for the certificate
294 chain
295
296 :param cafile: In which file we can find the certificates
297 :param capath: In which directory we can find the certificates
298 :return: None
299 """
300 if cafile is None:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500301 cafile = _ffi.NULL
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800302 elif not isinstance(cafile, bytes):
303 raise TypeError("cafile must be None or a byte string")
304
305 if capath is None:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500306 capath = _ffi.NULL
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800307 elif not isinstance(capath, bytes):
308 raise TypeError("capath must be None or a byte string")
309
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500310 load_result = _lib.SSL_CTX_load_verify_locations(self._context, cafile, capath)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800311 if not load_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500312 _raise_current_error()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800313
314
315 def _wrap_callback(self, callback):
316 @wraps(callback)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800317 def wrapper(size, verify, userdata):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800318 return callback(size, verify, self._passphrase_userdata)
319 return _PassphraseHelper(
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800320 FILETYPE_PEM, wrapper, more_args=True, truncate=True)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800321
322
323 def set_passwd_cb(self, callback, userdata=None):
324 """
325 Set the passphrase callback
326
327 :param callback: The Python callback to use
328 :param userdata: (optional) A Python object which will be given as
329 argument to the callback
330 :return: None
331 """
332 if not callable(callback):
333 raise TypeError("callback must be callable")
334
335 self._passphrase_helper = self._wrap_callback(callback)
336 self._passphrase_callback = self._passphrase_helper.callback
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500337 _lib.SSL_CTX_set_default_passwd_cb(
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800338 self._context, self._passphrase_callback)
339 self._passphrase_userdata = userdata
340
341
342 def set_default_verify_paths(self):
343 """
344 Use the platform-specific CA certificate locations
345
346 :return: None
347 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500348 set_result = _lib.SSL_CTX_set_default_verify_paths(self._context)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800349 if not set_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500350 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500351 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800352
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800353
354 def use_certificate_chain_file(self, certfile):
355 """
356 Load a certificate chain from a file
357
358 :param certfile: The name of the certificate chain file
359 :return: None
360 """
Jean-Paul Calderoned8607982014-01-18 10:30:55 -0500361 if isinstance(certfile, _text_type):
362 # Perhaps sys.getfilesystemencoding() could be better?
363 certfile = certfile.encode("utf-8")
364
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800365 if not isinstance(certfile, bytes):
Jean-Paul Calderoned8607982014-01-18 10:30:55 -0500366 raise TypeError("certfile must be bytes or unicode")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800367
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500368 result = _lib.SSL_CTX_use_certificate_chain_file(self._context, certfile)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800369 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500370 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800371
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800372
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800373 def use_certificate_file(self, certfile, filetype=FILETYPE_PEM):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800374 """
375 Load a certificate from a file
376
377 :param certfile: The name of the certificate file
378 :param filetype: (optional) The encoding of the file, default is PEM
379 :return: None
380 """
Jean-Paul Calderone684baf52014-01-18 10:31:19 -0500381 if isinstance(certfile, _text_type):
382 # Perhaps sys.getfilesystemencoding() could be better?
383 certfile = certfile.encode("utf-8")
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800384 if not isinstance(certfile, bytes):
Jean-Paul Calderone684baf52014-01-18 10:31:19 -0500385 raise TypeError("certfile must be bytes or unicode")
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800386 if not isinstance(filetype, int):
387 raise TypeError("filetype must be an integer")
388
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500389 use_result = _lib.SSL_CTX_use_certificate_file(self._context, certfile, filetype)
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800390 if not use_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500391 _raise_current_error()
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800392
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800393
394 def use_certificate(self, cert):
395 """
396 Load a certificate from a X509 object
397
398 :param cert: The X509 object
399 :return: None
400 """
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800401 if not isinstance(cert, X509):
402 raise TypeError("cert must be an X509 instance")
403
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500404 use_result = _lib.SSL_CTX_use_certificate(self._context, cert._x509)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800405 if not use_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500406 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800407
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800408
409 def add_extra_chain_cert(self, certobj):
410 """
411 Add certificate to chain
412
413 :param certobj: The X509 certificate object to add to the chain
414 :return: None
415 """
416 if not isinstance(certobj, X509):
417 raise TypeError("certobj must be an X509 instance")
418
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500419 copy = _lib.X509_dup(certobj._x509)
420 add_result = _lib.SSL_CTX_add_extra_chain_cert(self._context, copy)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800421 if not add_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500422 # TODO: This is untested.
423 _lib.X509_free(copy)
424 _raise_current_error()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800425
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800426
427 def _raise_passphrase_exception(self):
428 if self._passphrase_helper is None:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500429 _raise_current_error()
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800430 exception = self._passphrase_helper.raise_if_problem(Error)
431 if exception is not None:
432 raise exception
433
434
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800435 def use_privatekey_file(self, keyfile, filetype=_unspecified):
436 """
437 Load a private key from a file
438
439 :param keyfile: The name of the key file
440 :param filetype: (optional) The encoding of the file, default is PEM
441 :return: None
442 """
Jean-Paul Calderone87e525a2014-01-18 10:31:51 -0500443 if isinstance(keyfile, _text_type):
444 # Perhaps sys.getfilesystemencoding() could be better?
445 keyfile = keyfile.encode("utf-8")
446
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800447 if not isinstance(keyfile, bytes):
448 raise TypeError("keyfile must be a byte string")
449
450 if filetype is _unspecified:
451 filetype = FILETYPE_PEM
452 elif not isinstance(filetype, int):
453 raise TypeError("filetype must be an integer")
454
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500455 use_result = _lib.SSL_CTX_use_PrivateKey_file(
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800456 self._context, keyfile, filetype)
457 if not use_result:
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800458 self._raise_passphrase_exception()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800459
460
461 def use_privatekey(self, pkey):
462 """
463 Load a private key from a PKey object
464
465 :param pkey: The PKey object
466 :return: None
467 """
468 if not isinstance(pkey, PKey):
469 raise TypeError("pkey must be a PKey instance")
470
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500471 use_result = _lib.SSL_CTX_use_PrivateKey(self._context, pkey._pkey)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800472 if not use_result:
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800473 self._raise_passphrase_exception()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800474
475
476 def check_privatekey(self):
477 """
478 Check that the private key and certificate match up
479
480 :return: None (raises an exception if something's wrong)
481 """
482
483 def load_client_ca(self, cafile):
484 """
485 Load the trusted certificates that will be sent to the client (basically
486 telling the client "These are the guys I trust"). Does not actually
487 imply any of the certificates are trusted; that must be configured
488 separately.
489
490 :param cafile: The name of the certificates file
491 :return: None
492 """
493
494 def set_session_id(self, buf):
495 """
496 Set the session identifier. This is needed if you want to do session
497 resumption.
498
499 :param buf: A Python object that can be safely converted to a string
500 :returns: None
501 """
502
503 def set_session_cache_mode(self, mode):
504 """
505 Enable/disable session caching and specify the mode used.
506
507 :param mode: One or more of the SESS_CACHE_* flags (combine using
508 bitwise or)
509 :returns: The previously set caching mode.
510 """
511 if not isinstance(mode, int):
512 raise TypeError("mode must be an integer")
513
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500514 return _lib.SSL_CTX_set_session_cache_mode(self._context, mode)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800515
516
517 def get_session_cache_mode(self):
518 """
519 :returns: The currently used cache mode.
520 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500521 return _lib.SSL_CTX_get_session_cache_mode(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800522
523
524 def set_verify(self, mode, callback):
525 """
526 Set the verify mode and verify callback
527
528 :param mode: The verify mode, this is either VERIFY_NONE or
529 VERIFY_PEER combined with possible other flags
530 :param callback: The Python callback to use
531 :return: None
532
533 See SSL_CTX_set_verify(3SSL) for further details.
534 """
535 if not isinstance(mode, int):
536 raise TypeError("mode must be an integer")
537
538 if not callable(callback):
539 raise TypeError("callback must be callable")
540
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800541 self._verify_helper = _VerifyHelper(self, callback)
542 self._verify_callback = self._verify_helper.callback
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500543 _lib.SSL_CTX_set_verify(self._context, mode, self._verify_callback)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800544
545
546 def set_verify_depth(self, depth):
547 """
548 Set the verify depth
549
550 :param depth: An integer specifying the verify depth
551 :return: None
552 """
553 if not isinstance(depth, int):
554 raise TypeError("depth must be an integer")
555
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500556 _lib.SSL_CTX_set_verify_depth(self._context, depth)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800557
558
559 def get_verify_mode(self):
560 """
561 Get the verify mode
562
563 :return: The verify mode
564 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500565 return _lib.SSL_CTX_get_verify_mode(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800566
567
568 def get_verify_depth(self):
569 """
570 Get the verify depth
571
572 :return: The verify depth
573 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500574 return _lib.SSL_CTX_get_verify_depth(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800575
576
577 def load_tmp_dh(self, dhfile):
578 """
579 Load parameters for Ephemeral Diffie-Hellman
580
581 :param dhfile: The file to load EDH parameters from
582 :return: None
583 """
584 if not isinstance(dhfile, bytes):
585 raise TypeError("dhfile must be a byte string")
586
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -0500587 bio = _lib.BIO_new_file(dhfile, b"r")
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500588 if bio == _ffi.NULL:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500589 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500590 bio = _ffi.gc(bio, _lib.BIO_free)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800591
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500592 dh = _lib.PEM_read_bio_DHparams(bio, _ffi.NULL, _ffi.NULL, _ffi.NULL)
593 dh = _ffi.gc(dh, _lib.DH_free)
594 _lib.SSL_CTX_set_tmp_dh(self._context, dh)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800595
596
597 def set_cipher_list(self, cipher_list):
598 """
599 Change the cipher list
600
601 :param cipher_list: A cipher list, see ciphers(1)
602 :return: None
603 """
Jean-Paul Calderone63eab692014-01-18 10:19:56 -0500604 if isinstance(cipher_list, _text_type):
605 cipher_list = cipher_list.encode("ascii")
606
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800607 if not isinstance(cipher_list, bytes):
Jean-Paul Calderone63eab692014-01-18 10:19:56 -0500608 raise TypeError("cipher_list must be bytes or unicode")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800609
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500610 result = _lib.SSL_CTX_set_cipher_list(self._context, cipher_list)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800611 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500612 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800613
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800614
615 def set_client_ca_list(self, certificate_authorities):
616 """
617 Set the list of preferred client certificate signers for this server context.
618
619 This list of certificate authorities will be sent to the client when the
620 server requests a client certificate.
621
622 :param certificate_authorities: a sequence of X509Names.
623 :return: None
624 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500625 name_stack = _lib.sk_X509_NAME_new_null()
626 if name_stack == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500627 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500628 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800629
630 try:
631 for ca_name in certificate_authorities:
632 if not isinstance(ca_name, X509Name):
633 raise TypeError(
634 "client CAs must be X509Name objects, not %s objects" % (
635 type(ca_name).__name__,))
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500636 copy = _lib.X509_NAME_dup(ca_name._name)
637 if copy == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500638 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500639 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500640 push_result = _lib.sk_X509_NAME_push(name_stack, copy)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800641 if not push_result:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500642 _lib.X509_NAME_free(copy)
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500643 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800644 except:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500645 _lib.sk_X509_NAME_free(name_stack)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800646 raise
647
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500648 _lib.SSL_CTX_set_client_CA_list(self._context, name_stack)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800649
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800650
651 def add_client_ca(self, certificate_authority):
652 """
653 Add the CA certificate to the list of preferred signers for this context.
654
655 The list of certificate authorities will be sent to the client when the
656 server requests a client certificate.
657
658 :param certificate_authority: certificate authority's X509 certificate.
659 :return: None
660 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800661 if not isinstance(certificate_authority, X509):
662 raise TypeError("certificate_authority must be an X509 instance")
663
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500664 add_result = _lib.SSL_CTX_add_client_CA(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800665 self._context, certificate_authority._x509)
666 if not add_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500667 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500668 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800669
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800670
671 def set_timeout(self, timeout):
672 """
673 Set session timeout
674
675 :param timeout: The timeout in seconds
676 :return: The previous session timeout
677 """
678 if not isinstance(timeout, int):
679 raise TypeError("timeout must be an integer")
680
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500681 return _lib.SSL_CTX_set_timeout(self._context, timeout)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800682
683
684 def get_timeout(self):
685 """
686 Get the session timeout
687
688 :return: The session timeout
689 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500690 return _lib.SSL_CTX_get_timeout(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800691
692
693 def set_info_callback(self, callback):
694 """
695 Set the info callback
696
697 :param callback: The Python callback to use
698 :return: None
699 """
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800700 @wraps(callback)
701 def wrapper(ssl, where, return_code):
Jean-Paul Calderonef2bbc9c2014-02-02 10:59:14 -0500702 callback(Connection._reverse_mapping[ssl], where, return_code)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500703 self._info_callback = _ffi.callback(
704 "void (*)(const SSL *, int, int)", wrapper)
705 _lib.SSL_CTX_set_info_callback(self._context, self._info_callback)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800706
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800707
708 def get_app_data(self):
709 """
710 Get the application data (supplied via set_app_data())
711
712 :return: The application data
713 """
714 return self._app_data
715
716
717 def set_app_data(self, data):
718 """
719 Set the application data (will be returned from get_app_data())
720
721 :param data: Any Python object
722 :return: None
723 """
724 self._app_data = data
725
726
727 def get_cert_store(self):
728 """
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500729 Get the certificate store for the context.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800730
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500731 :return: A X509Store object or None if it does not have one.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800732 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500733 store = _lib.SSL_CTX_get_cert_store(self._context)
734 if store == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500735 # TODO: This is untested.
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800736 return None
737
738 pystore = X509Store.__new__(X509Store)
739 pystore._store = store
740 return pystore
741
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800742
743 def set_options(self, options):
744 """
745 Add options. Options set before are not cleared!
746
747 :param options: The options to add.
748 :return: The new option bitmask.
749 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800750 if not isinstance(options, int):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800751 raise TypeError("options must be an integer")
752
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500753 return _lib.SSL_CTX_set_options(self._context, options)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800754
755
756 def set_mode(self, mode):
757 """
758 Add modes via bitmask. Modes set before are not cleared!
759
760 :param mode: The mode to add.
761 :return: The new mode bitmask.
762 """
763 if not isinstance(mode, int):
764 raise TypeError("mode must be an integer")
765
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500766 return _lib.SSL_CTX_set_mode(self._context, mode)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800767
768
769 def set_tlsext_servername_callback(self, callback):
770 """
771 Specify a callback function to be called when clients specify a server name.
772
773 :param callback: The callback function. It will be invoked with one
774 argument, the Connection instance.
775 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800776 @wraps(callback)
777 def wrapper(ssl, alert, arg):
778 callback(Connection._reverse_mapping[ssl])
779 return 0
780
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500781 self._tlsext_servername_callback = _ffi.callback(
782 "int (*)(const SSL *, int *, void *)", wrapper)
783 _lib.SSL_CTX_set_tlsext_servername_callback(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800784 self._context, self._tlsext_servername_callback)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800785
786ContextType = Context
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800787
788
789
790class Connection(object):
791 """
792 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800793 _reverse_mapping = WeakValueDictionary()
794
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800795 def __init__(self, context, socket=None):
796 """
797 Create a new Connection object, using the given OpenSSL.SSL.Context
798 instance and socket.
799
800 :param context: An SSL Context to use for this connection
801 :param socket: The socket to use for transport layer
802 """
803 if not isinstance(context, Context):
804 raise TypeError("context must be a Context instance")
805
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500806 ssl = _lib.SSL_new(context._context)
807 self._ssl = _ffi.gc(ssl, _lib.SSL_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800808 self._context = context
809
810 self._reverse_mapping[self._ssl] = self
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800811
812 if socket is None:
813 self._socket = None
Jean-Paul Calderone73b15c22013-03-05 18:30:39 -0800814 # Don't set up any gc for these, SSL_free will take care of them.
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500815 self._into_ssl = _lib.BIO_new(_lib.BIO_s_mem())
816 self._from_ssl = _lib.BIO_new(_lib.BIO_s_mem())
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800817
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500818 if self._into_ssl == _ffi.NULL or self._from_ssl == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500819 # TODO: This is untested.
820 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800821
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500822 _lib.SSL_set_bio(self._ssl, self._into_ssl, self._from_ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800823 else:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800824 self._into_ssl = None
825 self._from_ssl = None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800826 self._socket = socket
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500827 set_result = _lib.SSL_set_fd(self._ssl, _asFileDescriptor(self._socket))
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800828 if not set_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500829 # TODO: This is untested.
830 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800831
832
833 def __getattr__(self, name):
834 """
835 Look up attributes on the wrapped socket object if they are not found on
836 the Connection object.
837 """
838 return getattr(self._socket, name)
839
840
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800841 def _raise_ssl_error(self, ssl, result):
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800842 if self._context._verify_helper is not None:
843 self._context._verify_helper.raise_if_problem()
844
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500845 error = _lib.SSL_get_error(ssl, result)
846 if error == _lib.SSL_ERROR_WANT_READ:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800847 raise WantReadError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500848 elif error == _lib.SSL_ERROR_WANT_WRITE:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -0700849 raise WantWriteError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500850 elif error == _lib.SSL_ERROR_ZERO_RETURN:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800851 raise ZeroReturnError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500852 elif error == _lib.SSL_ERROR_WANT_X509_LOOKUP:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500853 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -0700854 raise WantX509LookupError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500855 elif error == _lib.SSL_ERROR_SYSCALL:
856 if _lib.ERR_peek_error() == 0:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800857 if result < 0:
Konstantinos Koukopoulos541150d2014-01-31 01:00:19 +0200858 if platform == "win32":
859 errno = _ffi.getwinerror()[0]
860 else:
861 errno = _ffi.errno
862 raise SysCallError(errno, errorcode[errno])
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800863 else:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -0700864 raise SysCallError(-1, "Unexpected EOF")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800865 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500866 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500867 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500868 elif error == _lib.SSL_ERROR_NONE:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -0700869 pass
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800870 else:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500871 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800872
873
874 def get_context(self):
875 """
876 Get session context
877 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800878 return self._context
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800879
880
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800881 def set_context(self, context):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800882 """
883 Switch this connection to a new session context
884
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800885 :param context: A :py:class:`Context` instance giving the new session
886 context to use.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800887 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800888 if not isinstance(context, Context):
889 raise TypeError("context must be a Context instance")
890
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500891 _lib.SSL_set_SSL_CTX(self._ssl, context._context)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800892 self._context = context
893
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800894
895 def get_servername(self):
896 """
897 Retrieve the servername extension value if provided in the client hello
898 message, or None if there wasn't one.
899
900 :return: A byte string giving the server name or :py:data:`None`.
901 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500902 name = _lib.SSL_get_servername(self._ssl, _lib.TLSEXT_NAMETYPE_host_name)
903 if name == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800904 return None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800905
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500906 return _ffi.string(name)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800907
908
909 def set_tlsext_host_name(self, name):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800910 """
911 Set the value of the servername extension to send in the client hello.
912
913 :param name: A byte string giving the name.
914 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800915 if not isinstance(name, bytes):
916 raise TypeError("name must be a byte string")
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -0500917 elif b"\0" in name:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800918 raise TypeError("name must not contain NUL byte")
919
920 # XXX I guess this can fail sometimes?
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500921 _lib.SSL_set_tlsext_host_name(self._ssl, name)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800922
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800923
924 def pending(self):
925 """
926 Get the number of bytes that can be safely read from the connection
927
928 :return: The number of bytes available in the receive buffer.
929 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500930 return _lib.SSL_pending(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800931
932
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800933 def send(self, buf, flags=0):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800934 """
935 Send data on the connection. NOTE: If you get one of the WantRead,
936 WantWrite or WantX509Lookup exceptions on this, you have to call the
937 method again with the SAME buffer.
938
939 :param buf: The string to send
940 :param flags: (optional) Included for compatibility with the socket
941 API, the value is ignored
942 :return: The number of bytes written
943 """
Jean-Paul Calderone8fb53182013-12-30 08:35:49 -0500944 if isinstance(buf, _memoryview):
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -0800945 buf = buf.tobytes()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800946 if not isinstance(buf, bytes):
947 raise TypeError("data must be a byte string")
948 if not isinstance(flags, int):
949 raise TypeError("flags must be an integer")
950
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500951 result = _lib.SSL_write(self._ssl, buf, len(buf))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800952 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800953 return result
954 write = send
955
956
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800957 def sendall(self, buf, flags=0):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800958 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800959 Send "all" data on the connection. This calls send() repeatedly until
960 all data is sent. If an error occurs, it's impossible to tell how much
961 data has been sent.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800962
963 :param buf: The string to send
964 :param flags: (optional) Included for compatibility with the socket
965 API, the value is ignored
966 :return: The number of bytes written
967 """
Jean-Paul Calderone8fb53182013-12-30 08:35:49 -0500968 if isinstance(buf, _memoryview):
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -0800969 buf = buf.tobytes()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800970 if not isinstance(buf, bytes):
971 raise TypeError("buf must be a byte string")
972 if not isinstance(flags, int):
973 raise TypeError("flags must be an integer")
974
975 left_to_send = len(buf)
976 total_sent = 0
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500977 data = _ffi.new("char[]", buf)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800978
979 while left_to_send:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500980 result = _lib.SSL_write(self._ssl, data + total_sent, left_to_send)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800981 self._raise_ssl_error(self._ssl, result)
982 total_sent += result
983 left_to_send -= result
984
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800985
986 def recv(self, bufsiz, flags=None):
987 """
988 Receive data on the connection. NOTE: If you get one of the WantRead,
989 WantWrite or WantX509Lookup exceptions on this, you have to call the
990 method again with the SAME buffer.
991
992 :param bufsiz: The maximum number of bytes to read
993 :param flags: (optional) Included for compatibility with the socket
994 API, the value is ignored
995 :return: The string read from the Connection
996 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500997 buf = _ffi.new("char[]", bufsiz)
998 result = _lib.SSL_read(self._ssl, buf, bufsiz)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800999 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001000 return _ffi.buffer(buf, result)[:]
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001001 read = recv
1002
1003
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001004 def _handle_bio_errors(self, bio, result):
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001005 if _lib.BIO_should_retry(bio):
1006 if _lib.BIO_should_read(bio):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001007 raise WantReadError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001008 elif _lib.BIO_should_write(bio):
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001009 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001010 raise WantWriteError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001011 elif _lib.BIO_should_io_special(bio):
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001012 # TODO: This is untested. I think io_special means the socket
1013 # BIO has a not-yet connected socket.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001014 raise ValueError("BIO_should_io_special")
1015 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001016 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001017 raise ValueError("unknown bio failure")
1018 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001019 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001020 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001021
1022
1023 def bio_read(self, bufsiz):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001024 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001025 When using non-socket connections this function reads the "dirty" data
1026 that would have traveled away on the network.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001027
1028 :param bufsiz: The maximum number of bytes to read
1029 :return: The string read.
1030 """
Jean-Paul Calderone97e041d2013-03-05 21:03:12 -08001031 if self._from_ssl is None:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001032 raise TypeError("Connection sock was not None")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001033
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001034 if not isinstance(bufsiz, int):
1035 raise TypeError("bufsiz must be an integer")
1036
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001037 buf = _ffi.new("char[]", bufsiz)
1038 result = _lib.BIO_read(self._from_ssl, buf, bufsiz)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001039 if result <= 0:
1040 self._handle_bio_errors(self._from_ssl, result)
1041
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001042 return _ffi.buffer(buf, result)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001043
1044
1045 def bio_write(self, buf):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001046 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001047 When using non-socket connections this function sends "dirty" data that
1048 would have traveled in on the network.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001049
1050 :param buf: The string to put into the memory BIO.
1051 :return: The number of bytes written
1052 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001053 if self._into_ssl is None:
1054 raise TypeError("Connection sock was not None")
1055
1056 if not isinstance(buf, bytes):
1057 raise TypeError("buf must be a byte string")
1058
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001059 result = _lib.BIO_write(self._into_ssl, buf, len(buf))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001060 if result <= 0:
1061 self._handle_bio_errors(self._into_ssl, result)
1062 return result
1063
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001064
1065 def renegotiate(self):
1066 """
1067 Renegotiate the session
1068
1069 :return: True if the renegotiation can be started, false otherwise
1070 """
1071
1072 def do_handshake(self):
1073 """
1074 Perform an SSL handshake (usually called after renegotiate() or one of
1075 set_*_state()). This can raise the same exceptions as send and recv.
1076
1077 :return: None.
1078 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001079 result = _lib.SSL_do_handshake(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001080 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001081
1082
1083 def renegotiate_pending(self):
1084 """
1085 Check if there's a renegotiation in progress, it will return false once
1086 a renegotiation is finished.
1087
1088 :return: Whether there's a renegotiation in progress
1089 """
1090
1091 def total_renegotiations(self):
1092 """
1093 Find out the total number of renegotiations.
1094
1095 :return: The number of renegotiations.
1096 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001097 return _lib.SSL_total_renegotiations(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001098
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001099
1100 def connect(self, addr):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001101 """
1102 Connect to remote host and set up client-side SSL
1103
1104 :param addr: A remote address
1105 :return: What the socket's connect method returns
1106 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001107 _lib.SSL_set_connect_state(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001108 return self._socket.connect(addr)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001109
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001110
1111 def connect_ex(self, addr):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001112 """
1113 Connect to remote host and set up client-side SSL. Note that if the socket's
1114 connect_ex method doesn't return 0, SSL won't be initialized.
1115
1116 :param addr: A remove address
1117 :return: What the socket's connect_ex method returns
1118 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001119 connect_ex = self._socket.connect_ex
1120 self.set_connect_state()
1121 return connect_ex(addr)
1122
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001123
1124 def accept(self):
1125 """
1126 Accept incoming connection and set up SSL on it
1127
1128 :return: A (conn,addr) pair where conn is a Connection and addr is an
1129 address
1130 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001131 client, addr = self._socket.accept()
1132 conn = Connection(self._context, client)
1133 conn.set_accept_state()
1134 return (conn, addr)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001135
1136
1137 def bio_shutdown(self):
1138 """
1139 When using non-socket connections this function signals end of
1140 data on the input for this connection.
1141
1142 :return: None
1143 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001144 if self._from_ssl is None:
1145 raise TypeError("Connection sock was not None")
1146
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001147 _lib.BIO_set_mem_eof_return(self._into_ssl, 0)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001148
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001149
1150 def shutdown(self):
1151 """
1152 Send closure alert
1153
1154 :return: True if the shutdown completed successfully (i.e. both sides
1155 have sent closure alerts), false otherwise (i.e. you have to
1156 wait for a ZeroReturnError on a recv() method call
1157 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001158 result = _lib.SSL_shutdown(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001159 if result < 0:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001160 # TODO: This is untested.
1161 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001162 elif result > 0:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001163 return True
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001164 else:
1165 return False
1166
1167
1168 def get_cipher_list(self):
1169 """
1170 Get the session cipher list
1171
1172 :return: A list of cipher strings
1173 """
1174 ciphers = []
1175 for i in count():
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001176 result = _lib.SSL_get_cipher_list(self._ssl, i)
1177 if result == _ffi.NULL:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001178 break
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001179 ciphers.append(_native(_ffi.string(result)))
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001180 return ciphers
1181
1182
1183 def get_client_ca_list(self):
1184 """
1185 Get CAs whose certificates are suggested for client authentication.
1186
1187 :return: If this is a server connection, a list of X509Names representing
1188 the acceptable CAs as set by :py:meth:`OpenSSL.SSL.Context.set_client_ca_list` or
1189 :py:meth:`OpenSSL.SSL.Context.add_client_ca`. If this is a client connection,
1190 the list of such X509Names sent by the server, or an empty list if that
1191 has not yet happened.
1192 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001193 ca_names = _lib.SSL_get_client_CA_list(self._ssl)
1194 if ca_names == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001195 # TODO: This is untested.
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001196 return []
1197
1198 result = []
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001199 for i in range(_lib.sk_X509_NAME_num(ca_names)):
1200 name = _lib.sk_X509_NAME_value(ca_names, i)
1201 copy = _lib.X509_NAME_dup(name)
1202 if copy == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001203 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001204 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001205
1206 pyname = X509Name.__new__(X509Name)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001207 pyname._name = _ffi.gc(copy, _lib.X509_NAME_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001208 result.append(pyname)
1209 return result
1210
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001211
1212 def makefile(self):
1213 """
1214 The makefile() method is not implemented, since there is no dup semantics
1215 for SSL connections
1216
1217 :raise NotImplementedError
1218 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001219 raise NotImplementedError("Cannot make file object of OpenSSL.SSL.Connection")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001220
1221
1222 def get_app_data(self):
1223 """
1224 Get application data
1225
1226 :return: The application data
1227 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001228 return self._app_data
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001229
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001230
1231 def set_app_data(self, data):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001232 """
1233 Set application data
1234
1235 :param data - The application data
1236 :return: None
1237 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001238 self._app_data = data
1239
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001240
1241 def get_shutdown(self):
1242 """
1243 Get shutdown state
1244
1245 :return: The shutdown state, a bitvector of SENT_SHUTDOWN, RECEIVED_SHUTDOWN.
1246 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001247 return _lib.SSL_get_shutdown(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001248
1249
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001250 def set_shutdown(self, state):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001251 """
1252 Set shutdown state
1253
1254 :param state - bitvector of SENT_SHUTDOWN, RECEIVED_SHUTDOWN.
1255 :return: None
1256 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001257 if not isinstance(state, int):
1258 raise TypeError("state must be an integer")
1259
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001260 _lib.SSL_set_shutdown(self._ssl, state)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001261
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001262
1263 def state_string(self):
1264 """
1265 Get a verbose state description
1266
1267 :return: A string representing the state
1268 """
1269
1270 def server_random(self):
1271 """
1272 Get a copy of the server hello nonce.
1273
1274 :return: A string representing the state
1275 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001276 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001277 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001278 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001279 self._ssl.s3.server_random,
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001280 _lib.SSL3_RANDOM_SIZE)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001281
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001282
1283 def client_random(self):
1284 """
1285 Get a copy of the client hello nonce.
1286
1287 :return: A string representing the state
1288 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001289 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001290 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001291 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001292 self._ssl.s3.client_random,
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001293 _lib.SSL3_RANDOM_SIZE)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001294
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001295
1296 def master_key(self):
1297 """
1298 Get a copy of the master key.
1299
1300 :return: A string representing the state
1301 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001302 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001303 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001304 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001305 self._ssl.session.master_key,
1306 self._ssl.session.master_key_length)[:]
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001307
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001308
1309 def sock_shutdown(self, *args, **kwargs):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001310 """
1311 See shutdown(2)
1312
1313 :return: What the socket's shutdown() method returns
1314 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001315 return self._socket.shutdown(*args, **kwargs)
1316
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001317
1318 def get_peer_certificate(self):
1319 """
1320 Retrieve the other side's certificate (if any)
1321
1322 :return: The peer's certificate
1323 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001324 cert = _lib.SSL_get_peer_certificate(self._ssl)
1325 if cert != _ffi.NULL:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001326 pycert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001327 pycert._x509 = _ffi.gc(cert, _lib.X509_free)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001328 return pycert
1329 return None
1330
1331
1332 def get_peer_cert_chain(self):
1333 """
1334 Retrieve the other side's certificate (if any)
1335
1336 :return: A list of X509 instances giving the peer's certificate chain,
1337 or None if it does not have one.
1338 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001339 cert_stack = _lib.SSL_get_peer_cert_chain(self._ssl)
1340 if cert_stack == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001341 return None
1342
1343 result = []
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001344 for i in range(_lib.sk_X509_num(cert_stack)):
Jean-Paul Calderone73b15c22013-03-05 18:30:39 -08001345 # TODO could incref instead of dup here
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001346 cert = _lib.X509_dup(_lib.sk_X509_value(cert_stack, i))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001347 pycert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001348 pycert._x509 = _ffi.gc(cert, _lib.X509_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001349 result.append(pycert)
1350 return result
1351
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001352
1353 def want_read(self):
1354 """
1355 Checks if more data has to be read from the transport layer to complete an
1356 operation.
1357
1358 :return: True iff more data has to be read
1359 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001360 return _lib.SSL_want_read(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001361
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001362
1363 def want_write(self):
1364 """
1365 Checks if there is data to write to the transport layer to complete an
1366 operation.
1367
1368 :return: True iff there is data to write
1369 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001370 return _lib.SSL_want_write(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001371
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001372
1373 def set_accept_state(self):
1374 """
1375 Set the connection to work in server mode. The handshake will be handled
1376 automatically by read/write.
1377
1378 :return: None
1379 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001380 _lib.SSL_set_accept_state(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001381
1382
1383 def set_connect_state(self):
1384 """
1385 Set the connection to work in client mode. The handshake will be handled
1386 automatically by read/write.
1387
1388 :return: None
1389 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001390 _lib.SSL_set_connect_state(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001391
1392
1393 def get_session(self):
1394 """
1395 Returns the Session currently used.
1396
1397 @return: An instance of :py:class:`OpenSSL.SSL.Session` or :py:obj:`None` if
1398 no session exists.
1399 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001400 session = _lib.SSL_get1_session(self._ssl)
1401 if session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001402 return None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001403
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001404 pysession = Session.__new__(Session)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001405 pysession._session = _ffi.gc(session, _lib.SSL_SESSION_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001406 return pysession
1407
1408
1409 def set_session(self, session):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001410 """
1411 Set the session to be used when the TLS/SSL connection is established.
1412
1413 :param session: A Session instance representing the session to use.
1414 :returns: None
1415 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001416 if not isinstance(session, Session):
1417 raise TypeError("session must be a Session instance")
1418
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001419 result = _lib.SSL_set_session(self._ssl, session._session)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001420 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001421 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001422
1423ConnectionType = Connection
Jean-Paul Calderone11ed8e82014-01-18 10:21:50 -05001424
Jean-Paul Calderonefab157b2014-01-18 11:21:38 -05001425# This is similar to the initialization calls at the end of OpenSSL/crypto.py
1426# but is exercised mostly by the Context initializer.
Jean-Paul Calderone11ed8e82014-01-18 10:21:50 -05001427_lib.SSL_library_init()