blob: d3572dd720318b458c5e06f8c0cbb1db1ef5ffef [file] [log] [blame]
Konstantinos Koukopoulos541150d2014-01-31 01:00:19 +02001from sys import platform
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05002from functools import wraps, partial
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08003from itertools import count
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08004from weakref import WeakValueDictionary
5from errno import errorcode
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -08006
Jean-Paul Calderone63eab692014-01-18 10:19:56 -05007from six import text_type as _text_type
Konstantinos Koukopoulosc8b13ea2014-01-28 00:21:50 -08008from six import integer_types as integer_types
Jean-Paul Calderone63eab692014-01-18 10:19:56 -05009
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -050010from OpenSSL._util import (
11 ffi as _ffi,
12 lib as _lib,
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -050013 exception_from_error_queue as _exception_from_error_queue,
14 native as _native)
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080015
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -080016from OpenSSL.crypto import (
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -050017 FILETYPE_PEM, _PassphraseHelper, PKey, X509Name, X509, X509Store)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -080018
19_unspecified = object()
20
Jean-Paul Calderone8fb53182013-12-30 08:35:49 -050021try:
22 _memoryview = memoryview
23except NameError:
24 class _memoryview(object):
25 pass
26
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050027OPENSSL_VERSION_NUMBER = _lib.OPENSSL_VERSION_NUMBER
28SSLEAY_VERSION = _lib.SSLEAY_VERSION
29SSLEAY_CFLAGS = _lib.SSLEAY_CFLAGS
30SSLEAY_PLATFORM = _lib.SSLEAY_PLATFORM
31SSLEAY_DIR = _lib.SSLEAY_DIR
32SSLEAY_BUILT_ON = _lib.SSLEAY_BUILT_ON
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080033
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050034SENT_SHUTDOWN = _lib.SSL_SENT_SHUTDOWN
35RECEIVED_SHUTDOWN = _lib.SSL_RECEIVED_SHUTDOWN
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080036
37SSLv2_METHOD = 1
38SSLv3_METHOD = 2
39SSLv23_METHOD = 3
40TLSv1_METHOD = 4
Jean-Paul Calderone56bff942013-11-03 11:30:43 -050041TLSv1_1_METHOD = 5
42TLSv1_2_METHOD = 6
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080043
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050044OP_NO_SSLv2 = _lib.SSL_OP_NO_SSLv2
45OP_NO_SSLv3 = _lib.SSL_OP_NO_SSLv3
46OP_NO_TLSv1 = _lib.SSL_OP_NO_TLSv1
Jean-Paul Calderonebe2bb422013-12-29 07:34:08 -050047
48OP_NO_TLSv1_1 = getattr(_lib, "SSL_OP_NO_TLSv1_1", 0)
49OP_NO_TLSv1_2 = getattr(_lib, "SSL_OP_NO_TLSv1_2", 0)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -080050
Jean-Paul Calderone0d7e8a12014-01-08 16:54:13 -050051try:
52 MODE_RELEASE_BUFFERS = _lib.SSL_MODE_RELEASE_BUFFERS
53except AttributeError:
54 pass
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080055
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050056OP_SINGLE_DH_USE = _lib.SSL_OP_SINGLE_DH_USE
57OP_EPHEMERAL_RSA = _lib.SSL_OP_EPHEMERAL_RSA
58OP_MICROSOFT_SESS_ID_BUG = _lib.SSL_OP_MICROSOFT_SESS_ID_BUG
59OP_NETSCAPE_CHALLENGE_BUG = _lib.SSL_OP_NETSCAPE_CHALLENGE_BUG
60OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG = _lib.SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG
61OP_SSLREF2_REUSE_CERT_TYPE_BUG = _lib.SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG
62OP_MICROSOFT_BIG_SSLV3_BUFFER = _lib.SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER
Jean-Paul Calderone0d7e8a12014-01-08 16:54:13 -050063try:
64 OP_MSIE_SSLV2_RSA_PADDING = _lib.SSL_OP_MSIE_SSLV2_RSA_PADDING
65except AttributeError:
66 pass
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050067OP_SSLEAY_080_CLIENT_DH_BUG = _lib.SSL_OP_SSLEAY_080_CLIENT_DH_BUG
68OP_TLS_D5_BUG = _lib.SSL_OP_TLS_D5_BUG
69OP_TLS_BLOCK_PADDING_BUG = _lib.SSL_OP_TLS_BLOCK_PADDING_BUG
70OP_DONT_INSERT_EMPTY_FRAGMENTS = _lib.SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
71OP_CIPHER_SERVER_PREFERENCE = _lib.SSL_OP_CIPHER_SERVER_PREFERENCE
72OP_TLS_ROLLBACK_BUG = _lib.SSL_OP_TLS_ROLLBACK_BUG
73OP_PKCS1_CHECK_1 = _lib.SSL_OP_PKCS1_CHECK_1
74OP_PKCS1_CHECK_2 = _lib.SSL_OP_PKCS1_CHECK_2
75OP_NETSCAPE_CA_DN_BUG = _lib.SSL_OP_NETSCAPE_CA_DN_BUG
76OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG= _lib.SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG
Jean-Paul Calderonec1780342014-01-08 16:59:03 -050077try:
78 OP_NO_COMPRESSION = _lib.SSL_OP_NO_COMPRESSION
79except AttributeError:
80 pass
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -080081
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050082OP_NO_QUERY_MTU = _lib.SSL_OP_NO_QUERY_MTU
83OP_COOKIE_EXCHANGE = _lib.SSL_OP_COOKIE_EXCHANGE
Arturo Filastò5f8c7a82014-03-09 20:01:25 +010084try:
85 OP_NO_TICKET = _lib.SSL_OP_NO_TICKET
86except AttributeError:
87 pass
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -080088
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050089OP_ALL = _lib.SSL_OP_ALL
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080090
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050091VERIFY_PEER = _lib.SSL_VERIFY_PEER
92VERIFY_FAIL_IF_NO_PEER_CERT = _lib.SSL_VERIFY_FAIL_IF_NO_PEER_CERT
93VERIFY_CLIENT_ONCE = _lib.SSL_VERIFY_CLIENT_ONCE
94VERIFY_NONE = _lib.SSL_VERIFY_NONE
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080095
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050096SESS_CACHE_OFF = _lib.SSL_SESS_CACHE_OFF
97SESS_CACHE_CLIENT = _lib.SSL_SESS_CACHE_CLIENT
98SESS_CACHE_SERVER = _lib.SSL_SESS_CACHE_SERVER
99SESS_CACHE_BOTH = _lib.SSL_SESS_CACHE_BOTH
100SESS_CACHE_NO_AUTO_CLEAR = _lib.SSL_SESS_CACHE_NO_AUTO_CLEAR
101SESS_CACHE_NO_INTERNAL_LOOKUP = _lib.SSL_SESS_CACHE_NO_INTERNAL_LOOKUP
102SESS_CACHE_NO_INTERNAL_STORE = _lib.SSL_SESS_CACHE_NO_INTERNAL_STORE
103SESS_CACHE_NO_INTERNAL = _lib.SSL_SESS_CACHE_NO_INTERNAL
Jean-Paul Calderoned39a3f62013-03-04 12:23:51 -0800104
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500105SSL_ST_CONNECT = _lib.SSL_ST_CONNECT
106SSL_ST_ACCEPT = _lib.SSL_ST_ACCEPT
107SSL_ST_MASK = _lib.SSL_ST_MASK
108SSL_ST_INIT = _lib.SSL_ST_INIT
109SSL_ST_BEFORE = _lib.SSL_ST_BEFORE
110SSL_ST_OK = _lib.SSL_ST_OK
111SSL_ST_RENEGOTIATE = _lib.SSL_ST_RENEGOTIATE
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800112
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500113SSL_CB_LOOP = _lib.SSL_CB_LOOP
114SSL_CB_EXIT = _lib.SSL_CB_EXIT
115SSL_CB_READ = _lib.SSL_CB_READ
116SSL_CB_WRITE = _lib.SSL_CB_WRITE
117SSL_CB_ALERT = _lib.SSL_CB_ALERT
118SSL_CB_READ_ALERT = _lib.SSL_CB_READ_ALERT
119SSL_CB_WRITE_ALERT = _lib.SSL_CB_WRITE_ALERT
120SSL_CB_ACCEPT_LOOP = _lib.SSL_CB_ACCEPT_LOOP
121SSL_CB_ACCEPT_EXIT = _lib.SSL_CB_ACCEPT_EXIT
122SSL_CB_CONNECT_LOOP = _lib.SSL_CB_CONNECT_LOOP
123SSL_CB_CONNECT_EXIT = _lib.SSL_CB_CONNECT_EXIT
124SSL_CB_HANDSHAKE_START = _lib.SSL_CB_HANDSHAKE_START
125SSL_CB_HANDSHAKE_DONE = _lib.SSL_CB_HANDSHAKE_DONE
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800126
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800127
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500128class Error(Exception):
Jean-Paul Calderone511cde02013-12-29 10:31:13 -0500129 """
130 An error occurred in an `OpenSSL.SSL` API.
131 """
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500132
133
134
135_raise_current_error = partial(_exception_from_error_queue, Error)
136
137
138class WantReadError(Error):
139 pass
140
141
142
143class WantWriteError(Error):
144 pass
145
146
147
148class WantX509LookupError(Error):
149 pass
150
151
152
153class ZeroReturnError(Error):
154 pass
155
156
157
158class SysCallError(Error):
159 pass
160
161
162
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800163class _VerifyHelper(object):
164 def __init__(self, connection, callback):
165 self._problems = []
166
167 @wraps(callback)
168 def wrapper(ok, store_ctx):
169 cert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500170 cert._x509 = _lib.X509_STORE_CTX_get_current_cert(store_ctx)
171 error_number = _lib.X509_STORE_CTX_get_error(store_ctx)
172 error_depth = _lib.X509_STORE_CTX_get_error_depth(store_ctx)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800173
174 try:
175 result = callback(connection, cert, error_number, error_depth, ok)
176 except Exception as e:
177 self._problems.append(e)
178 return 0
179 else:
180 if result:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500181 _lib.X509_STORE_CTX_set_error(store_ctx, _lib.X509_V_OK)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800182 return 1
183 else:
184 return 0
185
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500186 self.callback = _ffi.callback(
187 "int (*)(int, X509_STORE_CTX *)", wrapper)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800188
189
190 def raise_if_problem(self):
191 if self._problems:
192 try:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500193 _raise_current_error()
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800194 except Error:
195 pass
196 raise self._problems.pop(0)
197
198
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800199
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800200def _asFileDescriptor(obj):
201 fd = None
Konstantinos Koukopoulosc8b13ea2014-01-28 00:21:50 -0800202 if not isinstance(obj, integer_types):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800203 meth = getattr(obj, "fileno", None)
204 if meth is not None:
205 obj = meth()
206
Konstantinos Koukopoulosc8b13ea2014-01-28 00:21:50 -0800207 if isinstance(obj, integer_types):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800208 fd = obj
209
Konstantinos Koukopoulosc8b13ea2014-01-28 00:21:50 -0800210 if not isinstance(fd, integer_types):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800211 raise TypeError("argument must be an int, or have a fileno() method.")
212 elif fd < 0:
213 raise ValueError(
214 "file descriptor cannot be a negative integer (%i)" % (fd,))
215
216 return fd
217
218
219
Jean-Paul Calderoned39a3f62013-03-04 12:23:51 -0800220def SSLeay_version(type):
221 """
222 Return a string describing the version of OpenSSL in use.
223
224 :param type: One of the SSLEAY_ constants defined in this module.
225 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500226 return _ffi.string(_lib.SSLeay_version(type))
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800227
228
229
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800230class Session(object):
231 pass
232
233
234
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800235class Context(object):
236 """
237 :py:obj:`OpenSSL.SSL.Context` instances define the parameters for setting up
238 new SSL connections.
239 """
240 _methods = {
Andrew Dunhamec84a0a2014-02-24 12:41:37 -0800241 SSLv2_METHOD: "SSLv2_method",
Jean-Paul Calderonebe2bb422013-12-29 07:34:08 -0500242 SSLv3_METHOD: "SSLv3_method",
243 SSLv23_METHOD: "SSLv23_method",
244 TLSv1_METHOD: "TLSv1_method",
245 TLSv1_1_METHOD: "TLSv1_1_method",
246 TLSv1_2_METHOD: "TLSv1_2_method",
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800247 }
Jean-Paul Calderonebe2bb422013-12-29 07:34:08 -0500248 _methods = dict(
249 (identifier, getattr(_lib, name))
250 for (identifier, name) in _methods.items()
251 if getattr(_lib, name, None) is not None)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800252
Jean-Paul Calderone63157872013-03-20 16:43:38 -0700253
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800254 def __init__(self, method):
255 """
256 :param method: One of SSLv2_METHOD, SSLv3_METHOD, SSLv23_METHOD, or
257 TLSv1_METHOD.
258 """
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -0500259 if not isinstance(method, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800260 raise TypeError("method must be an integer")
261
262 try:
263 method_func = self._methods[method]
264 except KeyError:
265 raise ValueError("No such protocol")
266
267 method_obj = method_func()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500268 if method_obj == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500269 # TODO: This is untested.
270 _raise_current_error()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800271
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500272 context = _lib.SSL_CTX_new(method_obj)
273 if context == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500274 # TODO: This is untested.
275 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500276 context = _ffi.gc(context, _lib.SSL_CTX_free)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800277
278 self._context = context
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800279 self._passphrase_helper = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800280 self._passphrase_callback = None
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800281 self._passphrase_userdata = None
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800282 self._verify_helper = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800283 self._verify_callback = None
284 self._info_callback = None
285 self._tlsext_servername_callback = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800286 self._app_data = None
287
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -0800288 # SSL_CTX_set_app_data(self->ctx, self);
289 # SSL_CTX_set_mode(self->ctx, SSL_MODE_ENABLE_PARTIAL_WRITE |
290 # SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
291 # SSL_MODE_AUTO_RETRY);
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500292 self.set_mode(_lib.SSL_MODE_ENABLE_PARTIAL_WRITE)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800293
294
295 def load_verify_locations(self, cafile, capath=None):
296 """
297 Let SSL know where we can find trusted certificates for the certificate
298 chain
299
300 :param cafile: In which file we can find the certificates
301 :param capath: In which directory we can find the certificates
302 :return: None
303 """
304 if cafile is None:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500305 cafile = _ffi.NULL
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800306 elif not isinstance(cafile, bytes):
307 raise TypeError("cafile must be None or a byte string")
308
309 if capath is None:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500310 capath = _ffi.NULL
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800311 elif not isinstance(capath, bytes):
312 raise TypeError("capath must be None or a byte string")
313
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500314 load_result = _lib.SSL_CTX_load_verify_locations(self._context, cafile, capath)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800315 if not load_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500316 _raise_current_error()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800317
318
319 def _wrap_callback(self, callback):
320 @wraps(callback)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800321 def wrapper(size, verify, userdata):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800322 return callback(size, verify, self._passphrase_userdata)
323 return _PassphraseHelper(
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800324 FILETYPE_PEM, wrapper, more_args=True, truncate=True)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800325
326
327 def set_passwd_cb(self, callback, userdata=None):
328 """
329 Set the passphrase callback
330
331 :param callback: The Python callback to use
332 :param userdata: (optional) A Python object which will be given as
333 argument to the callback
334 :return: None
335 """
336 if not callable(callback):
337 raise TypeError("callback must be callable")
338
339 self._passphrase_helper = self._wrap_callback(callback)
340 self._passphrase_callback = self._passphrase_helper.callback
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500341 _lib.SSL_CTX_set_default_passwd_cb(
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800342 self._context, self._passphrase_callback)
343 self._passphrase_userdata = userdata
344
345
346 def set_default_verify_paths(self):
347 """
348 Use the platform-specific CA certificate locations
349
350 :return: None
351 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500352 set_result = _lib.SSL_CTX_set_default_verify_paths(self._context)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800353 if not set_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500354 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500355 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800356
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800357
358 def use_certificate_chain_file(self, certfile):
359 """
360 Load a certificate chain from a file
361
362 :param certfile: The name of the certificate chain file
363 :return: None
364 """
Jean-Paul Calderoned8607982014-01-18 10:30:55 -0500365 if isinstance(certfile, _text_type):
366 # Perhaps sys.getfilesystemencoding() could be better?
367 certfile = certfile.encode("utf-8")
368
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800369 if not isinstance(certfile, bytes):
Jean-Paul Calderoned8607982014-01-18 10:30:55 -0500370 raise TypeError("certfile must be bytes or unicode")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800371
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500372 result = _lib.SSL_CTX_use_certificate_chain_file(self._context, certfile)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800373 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500374 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800375
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800376
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800377 def use_certificate_file(self, certfile, filetype=FILETYPE_PEM):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800378 """
379 Load a certificate from a file
380
381 :param certfile: The name of the certificate file
382 :param filetype: (optional) The encoding of the file, default is PEM
383 :return: None
384 """
Jean-Paul Calderone684baf52014-01-18 10:31:19 -0500385 if isinstance(certfile, _text_type):
386 # Perhaps sys.getfilesystemencoding() could be better?
387 certfile = certfile.encode("utf-8")
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800388 if not isinstance(certfile, bytes):
Jean-Paul Calderone684baf52014-01-18 10:31:19 -0500389 raise TypeError("certfile must be bytes or unicode")
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -0500390 if not isinstance(filetype, integer_types):
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800391 raise TypeError("filetype must be an integer")
392
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500393 use_result = _lib.SSL_CTX_use_certificate_file(self._context, certfile, filetype)
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800394 if not use_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500395 _raise_current_error()
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800396
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800397
398 def use_certificate(self, cert):
399 """
400 Load a certificate from a X509 object
401
402 :param cert: The X509 object
403 :return: None
404 """
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800405 if not isinstance(cert, X509):
406 raise TypeError("cert must be an X509 instance")
407
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500408 use_result = _lib.SSL_CTX_use_certificate(self._context, cert._x509)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800409 if not use_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500410 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800411
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800412
413 def add_extra_chain_cert(self, certobj):
414 """
415 Add certificate to chain
416
417 :param certobj: The X509 certificate object to add to the chain
418 :return: None
419 """
420 if not isinstance(certobj, X509):
421 raise TypeError("certobj must be an X509 instance")
422
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500423 copy = _lib.X509_dup(certobj._x509)
424 add_result = _lib.SSL_CTX_add_extra_chain_cert(self._context, copy)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800425 if not add_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500426 # TODO: This is untested.
427 _lib.X509_free(copy)
428 _raise_current_error()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800429
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800430
431 def _raise_passphrase_exception(self):
432 if self._passphrase_helper is None:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500433 _raise_current_error()
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800434 exception = self._passphrase_helper.raise_if_problem(Error)
435 if exception is not None:
436 raise exception
437
438
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800439 def use_privatekey_file(self, keyfile, filetype=_unspecified):
440 """
441 Load a private key from a file
442
443 :param keyfile: The name of the key file
444 :param filetype: (optional) The encoding of the file, default is PEM
445 :return: None
446 """
Jean-Paul Calderone87e525a2014-01-18 10:31:51 -0500447 if isinstance(keyfile, _text_type):
448 # Perhaps sys.getfilesystemencoding() could be better?
449 keyfile = keyfile.encode("utf-8")
450
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800451 if not isinstance(keyfile, bytes):
452 raise TypeError("keyfile must be a byte string")
453
454 if filetype is _unspecified:
455 filetype = FILETYPE_PEM
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -0500456 elif not isinstance(filetype, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800457 raise TypeError("filetype must be an integer")
458
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500459 use_result = _lib.SSL_CTX_use_PrivateKey_file(
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800460 self._context, keyfile, filetype)
461 if not use_result:
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800462 self._raise_passphrase_exception()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800463
464
465 def use_privatekey(self, pkey):
466 """
467 Load a private key from a PKey object
468
469 :param pkey: The PKey object
470 :return: None
471 """
472 if not isinstance(pkey, PKey):
473 raise TypeError("pkey must be a PKey instance")
474
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500475 use_result = _lib.SSL_CTX_use_PrivateKey(self._context, pkey._pkey)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800476 if not use_result:
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800477 self._raise_passphrase_exception()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800478
479
480 def check_privatekey(self):
481 """
482 Check that the private key and certificate match up
483
484 :return: None (raises an exception if something's wrong)
485 """
486
487 def load_client_ca(self, cafile):
488 """
489 Load the trusted certificates that will be sent to the client (basically
490 telling the client "These are the guys I trust"). Does not actually
491 imply any of the certificates are trusted; that must be configured
492 separately.
493
494 :param cafile: The name of the certificates file
495 :return: None
496 """
497
498 def set_session_id(self, buf):
499 """
500 Set the session identifier. This is needed if you want to do session
501 resumption.
502
503 :param buf: A Python object that can be safely converted to a string
504 :returns: None
505 """
506
507 def set_session_cache_mode(self, mode):
508 """
509 Enable/disable session caching and specify the mode used.
510
511 :param mode: One or more of the SESS_CACHE_* flags (combine using
512 bitwise or)
513 :returns: The previously set caching mode.
514 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500515 if not isinstance(mode, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800516 raise TypeError("mode must be an integer")
517
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500518 return _lib.SSL_CTX_set_session_cache_mode(self._context, mode)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800519
520
521 def get_session_cache_mode(self):
522 """
523 :returns: The currently used cache mode.
524 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500525 return _lib.SSL_CTX_get_session_cache_mode(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800526
527
528 def set_verify(self, mode, callback):
529 """
530 Set the verify mode and verify callback
531
532 :param mode: The verify mode, this is either VERIFY_NONE or
533 VERIFY_PEER combined with possible other flags
534 :param callback: The Python callback to use
535 :return: None
536
537 See SSL_CTX_set_verify(3SSL) for further details.
538 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500539 if not isinstance(mode, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800540 raise TypeError("mode must be an integer")
541
542 if not callable(callback):
543 raise TypeError("callback must be callable")
544
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800545 self._verify_helper = _VerifyHelper(self, callback)
546 self._verify_callback = self._verify_helper.callback
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500547 _lib.SSL_CTX_set_verify(self._context, mode, self._verify_callback)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800548
549
550 def set_verify_depth(self, depth):
551 """
552 Set the verify depth
553
554 :param depth: An integer specifying the verify depth
555 :return: None
556 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500557 if not isinstance(depth, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800558 raise TypeError("depth must be an integer")
559
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500560 _lib.SSL_CTX_set_verify_depth(self._context, depth)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800561
562
563 def get_verify_mode(self):
564 """
565 Get the verify mode
566
567 :return: The verify mode
568 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500569 return _lib.SSL_CTX_get_verify_mode(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800570
571
572 def get_verify_depth(self):
573 """
574 Get the verify depth
575
576 :return: The verify depth
577 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500578 return _lib.SSL_CTX_get_verify_depth(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800579
580
581 def load_tmp_dh(self, dhfile):
582 """
583 Load parameters for Ephemeral Diffie-Hellman
584
585 :param dhfile: The file to load EDH parameters from
586 :return: None
587 """
588 if not isinstance(dhfile, bytes):
589 raise TypeError("dhfile must be a byte string")
590
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -0500591 bio = _lib.BIO_new_file(dhfile, b"r")
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500592 if bio == _ffi.NULL:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500593 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500594 bio = _ffi.gc(bio, _lib.BIO_free)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800595
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500596 dh = _lib.PEM_read_bio_DHparams(bio, _ffi.NULL, _ffi.NULL, _ffi.NULL)
597 dh = _ffi.gc(dh, _lib.DH_free)
598 _lib.SSL_CTX_set_tmp_dh(self._context, dh)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800599
600
601 def set_cipher_list(self, cipher_list):
602 """
603 Change the cipher list
604
605 :param cipher_list: A cipher list, see ciphers(1)
606 :return: None
607 """
Jean-Paul Calderone63eab692014-01-18 10:19:56 -0500608 if isinstance(cipher_list, _text_type):
609 cipher_list = cipher_list.encode("ascii")
610
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800611 if not isinstance(cipher_list, bytes):
Jean-Paul Calderone63eab692014-01-18 10:19:56 -0500612 raise TypeError("cipher_list must be bytes or unicode")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800613
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500614 result = _lib.SSL_CTX_set_cipher_list(self._context, cipher_list)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800615 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500616 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800617
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800618
619 def set_client_ca_list(self, certificate_authorities):
620 """
621 Set the list of preferred client certificate signers for this server context.
622
623 This list of certificate authorities will be sent to the client when the
624 server requests a client certificate.
625
626 :param certificate_authorities: a sequence of X509Names.
627 :return: None
628 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500629 name_stack = _lib.sk_X509_NAME_new_null()
630 if name_stack == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500631 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500632 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800633
634 try:
635 for ca_name in certificate_authorities:
636 if not isinstance(ca_name, X509Name):
637 raise TypeError(
638 "client CAs must be X509Name objects, not %s objects" % (
639 type(ca_name).__name__,))
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500640 copy = _lib.X509_NAME_dup(ca_name._name)
641 if copy == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500642 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500643 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500644 push_result = _lib.sk_X509_NAME_push(name_stack, copy)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800645 if not push_result:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500646 _lib.X509_NAME_free(copy)
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500647 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800648 except:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500649 _lib.sk_X509_NAME_free(name_stack)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800650 raise
651
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500652 _lib.SSL_CTX_set_client_CA_list(self._context, name_stack)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800653
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800654
655 def add_client_ca(self, certificate_authority):
656 """
657 Add the CA certificate to the list of preferred signers for this context.
658
659 The list of certificate authorities will be sent to the client when the
660 server requests a client certificate.
661
662 :param certificate_authority: certificate authority's X509 certificate.
663 :return: None
664 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800665 if not isinstance(certificate_authority, X509):
666 raise TypeError("certificate_authority must be an X509 instance")
667
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500668 add_result = _lib.SSL_CTX_add_client_CA(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800669 self._context, certificate_authority._x509)
670 if not add_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500671 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500672 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800673
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800674
675 def set_timeout(self, timeout):
676 """
677 Set session timeout
678
679 :param timeout: The timeout in seconds
680 :return: The previous session timeout
681 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500682 if not isinstance(timeout, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800683 raise TypeError("timeout must be an integer")
684
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500685 return _lib.SSL_CTX_set_timeout(self._context, timeout)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800686
687
688 def get_timeout(self):
689 """
690 Get the session timeout
691
692 :return: The session timeout
693 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500694 return _lib.SSL_CTX_get_timeout(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800695
696
697 def set_info_callback(self, callback):
698 """
699 Set the info callback
700
701 :param callback: The Python callback to use
702 :return: None
703 """
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800704 @wraps(callback)
705 def wrapper(ssl, where, return_code):
Jean-Paul Calderonef2bbc9c2014-02-02 10:59:14 -0500706 callback(Connection._reverse_mapping[ssl], where, return_code)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500707 self._info_callback = _ffi.callback(
708 "void (*)(const SSL *, int, int)", wrapper)
709 _lib.SSL_CTX_set_info_callback(self._context, self._info_callback)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800710
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800711
712 def get_app_data(self):
713 """
714 Get the application data (supplied via set_app_data())
715
716 :return: The application data
717 """
718 return self._app_data
719
720
721 def set_app_data(self, data):
722 """
723 Set the application data (will be returned from get_app_data())
724
725 :param data: Any Python object
726 :return: None
727 """
728 self._app_data = data
729
730
731 def get_cert_store(self):
732 """
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500733 Get the certificate store for the context.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800734
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500735 :return: A X509Store object or None if it does not have one.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800736 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500737 store = _lib.SSL_CTX_get_cert_store(self._context)
738 if store == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500739 # TODO: This is untested.
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800740 return None
741
742 pystore = X509Store.__new__(X509Store)
743 pystore._store = store
744 return pystore
745
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800746
747 def set_options(self, options):
748 """
749 Add options. Options set before are not cleared!
750
751 :param options: The options to add.
752 :return: The new option bitmask.
753 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500754 if not isinstance(options, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800755 raise TypeError("options must be an integer")
756
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500757 return _lib.SSL_CTX_set_options(self._context, options)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800758
759
760 def set_mode(self, mode):
761 """
762 Add modes via bitmask. Modes set before are not cleared!
763
764 :param mode: The mode to add.
765 :return: The new mode bitmask.
766 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500767 if not isinstance(mode, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800768 raise TypeError("mode must be an integer")
769
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500770 return _lib.SSL_CTX_set_mode(self._context, mode)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800771
772
773 def set_tlsext_servername_callback(self, callback):
774 """
775 Specify a callback function to be called when clients specify a server name.
776
777 :param callback: The callback function. It will be invoked with one
778 argument, the Connection instance.
779 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800780 @wraps(callback)
781 def wrapper(ssl, alert, arg):
782 callback(Connection._reverse_mapping[ssl])
783 return 0
784
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500785 self._tlsext_servername_callback = _ffi.callback(
786 "int (*)(const SSL *, int *, void *)", wrapper)
787 _lib.SSL_CTX_set_tlsext_servername_callback(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800788 self._context, self._tlsext_servername_callback)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800789
790ContextType = Context
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800791
792
793
794class Connection(object):
795 """
796 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800797 _reverse_mapping = WeakValueDictionary()
798
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800799 def __init__(self, context, socket=None):
800 """
801 Create a new Connection object, using the given OpenSSL.SSL.Context
802 instance and socket.
803
804 :param context: An SSL Context to use for this connection
805 :param socket: The socket to use for transport layer
806 """
807 if not isinstance(context, Context):
808 raise TypeError("context must be a Context instance")
809
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500810 ssl = _lib.SSL_new(context._context)
811 self._ssl = _ffi.gc(ssl, _lib.SSL_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800812 self._context = context
813
814 self._reverse_mapping[self._ssl] = self
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800815
816 if socket is None:
817 self._socket = None
Jean-Paul Calderone73b15c22013-03-05 18:30:39 -0800818 # Don't set up any gc for these, SSL_free will take care of them.
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500819 self._into_ssl = _lib.BIO_new(_lib.BIO_s_mem())
820 self._from_ssl = _lib.BIO_new(_lib.BIO_s_mem())
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800821
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500822 if self._into_ssl == _ffi.NULL or self._from_ssl == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500823 # TODO: This is untested.
824 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800825
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500826 _lib.SSL_set_bio(self._ssl, self._into_ssl, self._from_ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800827 else:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800828 self._into_ssl = None
829 self._from_ssl = None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800830 self._socket = socket
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500831 set_result = _lib.SSL_set_fd(self._ssl, _asFileDescriptor(self._socket))
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800832 if not set_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500833 # TODO: This is untested.
834 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800835
836
837 def __getattr__(self, name):
838 """
839 Look up attributes on the wrapped socket object if they are not found on
840 the Connection object.
841 """
842 return getattr(self._socket, name)
843
844
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800845 def _raise_ssl_error(self, ssl, result):
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800846 if self._context._verify_helper is not None:
847 self._context._verify_helper.raise_if_problem()
848
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500849 error = _lib.SSL_get_error(ssl, result)
850 if error == _lib.SSL_ERROR_WANT_READ:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800851 raise WantReadError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500852 elif error == _lib.SSL_ERROR_WANT_WRITE:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -0700853 raise WantWriteError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500854 elif error == _lib.SSL_ERROR_ZERO_RETURN:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800855 raise ZeroReturnError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500856 elif error == _lib.SSL_ERROR_WANT_X509_LOOKUP:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500857 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -0700858 raise WantX509LookupError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500859 elif error == _lib.SSL_ERROR_SYSCALL:
860 if _lib.ERR_peek_error() == 0:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800861 if result < 0:
Konstantinos Koukopoulos541150d2014-01-31 01:00:19 +0200862 if platform == "win32":
863 errno = _ffi.getwinerror()[0]
864 else:
865 errno = _ffi.errno
866 raise SysCallError(errno, errorcode[errno])
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800867 else:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -0700868 raise SysCallError(-1, "Unexpected EOF")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800869 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500870 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500871 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500872 elif error == _lib.SSL_ERROR_NONE:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -0700873 pass
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800874 else:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500875 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800876
877
878 def get_context(self):
879 """
880 Get session context
881 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800882 return self._context
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800883
884
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800885 def set_context(self, context):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800886 """
887 Switch this connection to a new session context
888
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800889 :param context: A :py:class:`Context` instance giving the new session
890 context to use.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800891 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800892 if not isinstance(context, Context):
893 raise TypeError("context must be a Context instance")
894
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500895 _lib.SSL_set_SSL_CTX(self._ssl, context._context)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800896 self._context = context
897
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800898
899 def get_servername(self):
900 """
901 Retrieve the servername extension value if provided in the client hello
902 message, or None if there wasn't one.
903
904 :return: A byte string giving the server name or :py:data:`None`.
905 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500906 name = _lib.SSL_get_servername(self._ssl, _lib.TLSEXT_NAMETYPE_host_name)
907 if name == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800908 return None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800909
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500910 return _ffi.string(name)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800911
912
913 def set_tlsext_host_name(self, name):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800914 """
915 Set the value of the servername extension to send in the client hello.
916
917 :param name: A byte string giving the name.
918 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800919 if not isinstance(name, bytes):
920 raise TypeError("name must be a byte string")
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -0500921 elif b"\0" in name:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800922 raise TypeError("name must not contain NUL byte")
923
924 # XXX I guess this can fail sometimes?
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500925 _lib.SSL_set_tlsext_host_name(self._ssl, name)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800926
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800927
928 def pending(self):
929 """
930 Get the number of bytes that can be safely read from the connection
931
932 :return: The number of bytes available in the receive buffer.
933 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500934 return _lib.SSL_pending(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800935
936
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800937 def send(self, buf, flags=0):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800938 """
939 Send data on the connection. NOTE: If you get one of the WantRead,
940 WantWrite or WantX509Lookup exceptions on this, you have to call the
941 method again with the SAME buffer.
942
943 :param buf: The string to send
944 :param flags: (optional) Included for compatibility with the socket
945 API, the value is ignored
946 :return: The number of bytes written
947 """
Jean-Paul Calderone8fb53182013-12-30 08:35:49 -0500948 if isinstance(buf, _memoryview):
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -0800949 buf = buf.tobytes()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800950 if not isinstance(buf, bytes):
951 raise TypeError("data must be a byte string")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800952
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500953 result = _lib.SSL_write(self._ssl, buf, len(buf))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800954 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800955 return result
956 write = send
957
958
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800959 def sendall(self, buf, flags=0):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800960 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800961 Send "all" data on the connection. This calls send() repeatedly until
962 all data is sent. If an error occurs, it's impossible to tell how much
963 data has been sent.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800964
965 :param buf: The string to send
966 :param flags: (optional) Included for compatibility with the socket
967 API, the value is ignored
968 :return: The number of bytes written
969 """
Jean-Paul Calderone8fb53182013-12-30 08:35:49 -0500970 if isinstance(buf, _memoryview):
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -0800971 buf = buf.tobytes()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800972 if not isinstance(buf, bytes):
973 raise TypeError("buf must be a byte string")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800974
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 Calderonebef4f4c2014-02-02 18:13:31 -05001034 if not isinstance(bufsiz, integer_types):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001035 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 Calderonef73a3cb2014-02-09 08:49:06 -05001257 if not isinstance(state, integer_types):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001258 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
Jean-Paul Calderonedbd76272014-03-29 18:09:40 -04001423
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001424 def get_cipher_name(self):
1425 """
1426 Obtain the name of the currently used cipher.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001427
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001428 :returns: The name of the currently used cipher or :py:obj:`None`
1429 if no connection has been established.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001430 :rtype: :py:class:`str` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001431 """
1432 cipher = _lib.SSL_get_current_cipher(self._ssl)
1433 if cipher == _ffi.NULL:
1434 return None
1435 else:
1436 return _native(_ffi.string(_lib.SSL_CIPHER_get_name(cipher)))
1437
Jean-Paul Calderonedbd76272014-03-29 18:09:40 -04001438
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001439 def get_cipher_bits(self):
1440 """
1441 Obtain the number of secret bits of the currently used cipher.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001442
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001443 :returns: The number of secret bits of the currently used cipher
1444 or :py:obj:`None` if no connection has been established.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001445 :rtype: :py:class:`int` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001446 """
1447 cipher = _lib.SSL_get_current_cipher(self._ssl)
1448 if cipher == _ffi.NULL:
1449 return None
1450 else:
1451 return _lib.SSL_CIPHER_get_bits(cipher, _ffi.NULL)
1452
Jean-Paul Calderonedbd76272014-03-29 18:09:40 -04001453
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001454 def get_cipher_version(self):
1455 """
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001456 Obtain the protocol version of the currently used cipher.
1457
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001458 :returns: The protocol name of the currently used cipher
1459 or :py:obj:`None` if no connection has been established.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001460 :rtype: :py:class:`str` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001461 """
1462 cipher = _lib.SSL_get_current_cipher(self._ssl)
1463 if cipher == _ffi.NULL:
1464 return None
1465 else:
1466 return _native(_ffi.string(_lib.SSL_CIPHER_get_version(cipher)))
1467
1468
1469
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001470ConnectionType = Connection
Jean-Paul Calderone11ed8e82014-01-18 10:21:50 -05001471
Jean-Paul Calderonefab157b2014-01-18 11:21:38 -05001472# This is similar to the initialization calls at the end of OpenSSL/crypto.py
1473# but is exercised mostly by the Context initializer.
Jean-Paul Calderone11ed8e82014-01-18 10:21:50 -05001474_lib.SSL_library_init()