blob: 5451e1386820b952d824415a83a7e75e58b7fbe8 [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
Cory Benfieldbe3e7b82014-05-10 09:48:55 +01003from itertools import count, chain
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
Cory Benfield63759dc2015-04-12 08:57:03 -04008from six import binary_type as _binary_type
Konstantinos Koukopoulosc8b13ea2014-01-28 00:21:50 -08009from six import integer_types as integer_types
Cory Benfieldcd010f62014-05-15 19:00:27 +010010from six import int2byte, indexbytes
Jean-Paul Calderone63eab692014-01-18 10:19:56 -050011
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -050012from OpenSSL._util import (
13 ffi as _ffi,
14 lib as _lib,
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -050015 exception_from_error_queue as _exception_from_error_queue,
Jean-Paul Calderone55f9e882015-04-12 09:31:03 -040016 native as _native,
17 path_string as _path_string,
18)
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080019
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -080020from OpenSSL.crypto import (
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -050021 FILETYPE_PEM, _PassphraseHelper, PKey, X509Name, X509, X509Store)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -080022
23_unspecified = object()
24
Jean-Paul Calderone8fb53182013-12-30 08:35:49 -050025try:
26 _memoryview = memoryview
27except NameError:
28 class _memoryview(object):
29 pass
30
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +020031try:
32 _buffer = buffer
33except NameError:
34 class _buffer(object):
35 pass
36
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050037OPENSSL_VERSION_NUMBER = _lib.OPENSSL_VERSION_NUMBER
38SSLEAY_VERSION = _lib.SSLEAY_VERSION
39SSLEAY_CFLAGS = _lib.SSLEAY_CFLAGS
40SSLEAY_PLATFORM = _lib.SSLEAY_PLATFORM
41SSLEAY_DIR = _lib.SSLEAY_DIR
42SSLEAY_BUILT_ON = _lib.SSLEAY_BUILT_ON
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080043
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050044SENT_SHUTDOWN = _lib.SSL_SENT_SHUTDOWN
45RECEIVED_SHUTDOWN = _lib.SSL_RECEIVED_SHUTDOWN
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080046
47SSLv2_METHOD = 1
48SSLv3_METHOD = 2
49SSLv23_METHOD = 3
50TLSv1_METHOD = 4
Jean-Paul Calderone56bff942013-11-03 11:30:43 -050051TLSv1_1_METHOD = 5
52TLSv1_2_METHOD = 6
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080053
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050054OP_NO_SSLv2 = _lib.SSL_OP_NO_SSLv2
55OP_NO_SSLv3 = _lib.SSL_OP_NO_SSLv3
56OP_NO_TLSv1 = _lib.SSL_OP_NO_TLSv1
Jean-Paul Calderonebe2bb422013-12-29 07:34:08 -050057
58OP_NO_TLSv1_1 = getattr(_lib, "SSL_OP_NO_TLSv1_1", 0)
59OP_NO_TLSv1_2 = getattr(_lib, "SSL_OP_NO_TLSv1_2", 0)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -080060
Jean-Paul Calderone0d7e8a12014-01-08 16:54:13 -050061try:
62 MODE_RELEASE_BUFFERS = _lib.SSL_MODE_RELEASE_BUFFERS
63except AttributeError:
64 pass
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080065
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050066OP_SINGLE_DH_USE = _lib.SSL_OP_SINGLE_DH_USE
67OP_EPHEMERAL_RSA = _lib.SSL_OP_EPHEMERAL_RSA
68OP_MICROSOFT_SESS_ID_BUG = _lib.SSL_OP_MICROSOFT_SESS_ID_BUG
69OP_NETSCAPE_CHALLENGE_BUG = _lib.SSL_OP_NETSCAPE_CHALLENGE_BUG
70OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG = _lib.SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG
71OP_SSLREF2_REUSE_CERT_TYPE_BUG = _lib.SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG
72OP_MICROSOFT_BIG_SSLV3_BUFFER = _lib.SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER
Jean-Paul Calderone0d7e8a12014-01-08 16:54:13 -050073try:
74 OP_MSIE_SSLV2_RSA_PADDING = _lib.SSL_OP_MSIE_SSLV2_RSA_PADDING
75except AttributeError:
76 pass
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050077OP_SSLEAY_080_CLIENT_DH_BUG = _lib.SSL_OP_SSLEAY_080_CLIENT_DH_BUG
78OP_TLS_D5_BUG = _lib.SSL_OP_TLS_D5_BUG
79OP_TLS_BLOCK_PADDING_BUG = _lib.SSL_OP_TLS_BLOCK_PADDING_BUG
80OP_DONT_INSERT_EMPTY_FRAGMENTS = _lib.SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
81OP_CIPHER_SERVER_PREFERENCE = _lib.SSL_OP_CIPHER_SERVER_PREFERENCE
82OP_TLS_ROLLBACK_BUG = _lib.SSL_OP_TLS_ROLLBACK_BUG
83OP_PKCS1_CHECK_1 = _lib.SSL_OP_PKCS1_CHECK_1
84OP_PKCS1_CHECK_2 = _lib.SSL_OP_PKCS1_CHECK_2
85OP_NETSCAPE_CA_DN_BUG = _lib.SSL_OP_NETSCAPE_CA_DN_BUG
86OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG= _lib.SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG
Jean-Paul Calderonec1780342014-01-08 16:59:03 -050087try:
88 OP_NO_COMPRESSION = _lib.SSL_OP_NO_COMPRESSION
89except AttributeError:
90 pass
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -080091
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050092OP_NO_QUERY_MTU = _lib.SSL_OP_NO_QUERY_MTU
93OP_COOKIE_EXCHANGE = _lib.SSL_OP_COOKIE_EXCHANGE
Arturo Filastò5f8c7a82014-03-09 20:01:25 +010094try:
95 OP_NO_TICKET = _lib.SSL_OP_NO_TICKET
96except AttributeError:
97 pass
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -080098
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050099OP_ALL = _lib.SSL_OP_ALL
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -0800100
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500101VERIFY_PEER = _lib.SSL_VERIFY_PEER
102VERIFY_FAIL_IF_NO_PEER_CERT = _lib.SSL_VERIFY_FAIL_IF_NO_PEER_CERT
103VERIFY_CLIENT_ONCE = _lib.SSL_VERIFY_CLIENT_ONCE
104VERIFY_NONE = _lib.SSL_VERIFY_NONE
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -0800105
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500106SESS_CACHE_OFF = _lib.SSL_SESS_CACHE_OFF
107SESS_CACHE_CLIENT = _lib.SSL_SESS_CACHE_CLIENT
108SESS_CACHE_SERVER = _lib.SSL_SESS_CACHE_SERVER
109SESS_CACHE_BOTH = _lib.SSL_SESS_CACHE_BOTH
110SESS_CACHE_NO_AUTO_CLEAR = _lib.SSL_SESS_CACHE_NO_AUTO_CLEAR
111SESS_CACHE_NO_INTERNAL_LOOKUP = _lib.SSL_SESS_CACHE_NO_INTERNAL_LOOKUP
112SESS_CACHE_NO_INTERNAL_STORE = _lib.SSL_SESS_CACHE_NO_INTERNAL_STORE
113SESS_CACHE_NO_INTERNAL = _lib.SSL_SESS_CACHE_NO_INTERNAL
Jean-Paul Calderoned39a3f62013-03-04 12:23:51 -0800114
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500115SSL_ST_CONNECT = _lib.SSL_ST_CONNECT
116SSL_ST_ACCEPT = _lib.SSL_ST_ACCEPT
117SSL_ST_MASK = _lib.SSL_ST_MASK
118SSL_ST_INIT = _lib.SSL_ST_INIT
119SSL_ST_BEFORE = _lib.SSL_ST_BEFORE
120SSL_ST_OK = _lib.SSL_ST_OK
121SSL_ST_RENEGOTIATE = _lib.SSL_ST_RENEGOTIATE
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800122
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500123SSL_CB_LOOP = _lib.SSL_CB_LOOP
124SSL_CB_EXIT = _lib.SSL_CB_EXIT
125SSL_CB_READ = _lib.SSL_CB_READ
126SSL_CB_WRITE = _lib.SSL_CB_WRITE
127SSL_CB_ALERT = _lib.SSL_CB_ALERT
128SSL_CB_READ_ALERT = _lib.SSL_CB_READ_ALERT
129SSL_CB_WRITE_ALERT = _lib.SSL_CB_WRITE_ALERT
130SSL_CB_ACCEPT_LOOP = _lib.SSL_CB_ACCEPT_LOOP
131SSL_CB_ACCEPT_EXIT = _lib.SSL_CB_ACCEPT_EXIT
132SSL_CB_CONNECT_LOOP = _lib.SSL_CB_CONNECT_LOOP
133SSL_CB_CONNECT_EXIT = _lib.SSL_CB_CONNECT_EXIT
134SSL_CB_HANDSHAKE_START = _lib.SSL_CB_HANDSHAKE_START
135SSL_CB_HANDSHAKE_DONE = _lib.SSL_CB_HANDSHAKE_DONE
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800136
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500137class Error(Exception):
Jean-Paul Calderone511cde02013-12-29 10:31:13 -0500138 """
139 An error occurred in an `OpenSSL.SSL` API.
140 """
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500141
142
143
144_raise_current_error = partial(_exception_from_error_queue, Error)
145
146
147class WantReadError(Error):
148 pass
149
150
151
152class WantWriteError(Error):
153 pass
154
155
156
157class WantX509LookupError(Error):
158 pass
159
160
161
162class ZeroReturnError(Error):
163 pass
164
165
166
167class SysCallError(Error):
168 pass
169
170
Cory Benfield0ea76e72015-03-22 09:05:28 +0000171class _CallbackExceptionHelper(object):
172 """
173 A base class for wrapper classes that allow for intelligent exception
174 handling in OpenSSL callbacks.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500175
Jean-Paul Calderone1b172982015-03-22 19:37:11 -0400176 :ivar list _problems: Any exceptions that occurred while executing in a
177 context where they could not be raised in the normal way. Typically
178 this is because OpenSSL has called into some Python code and requires a
179 return value. The exceptions are saved to be raised later when it is
180 possible to do so.
Cory Benfield0ea76e72015-03-22 09:05:28 +0000181 """
Jean-Paul Calderone09540d72015-03-22 19:37:20 -0400182 def __init__(self):
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800183 self._problems = []
184
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800185
Cory Benfield0ea76e72015-03-22 09:05:28 +0000186 def raise_if_problem(self):
Jean-Paul Calderone1b172982015-03-22 19:37:11 -0400187 """
188 Raise an exception from the OpenSSL error queue or that was previously
189 captured whe running a callback.
190 """
Cory Benfield0ea76e72015-03-22 09:05:28 +0000191 if self._problems:
192 try:
193 _raise_current_error()
194 except Error:
195 pass
196 raise self._problems.pop(0)
197
198
199class _VerifyHelper(_CallbackExceptionHelper):
Jean-Paul Calderone1b172982015-03-22 19:37:11 -0400200 """
201 Wrap a callback such that it can be used as a certificate verification
202 callback.
203 """
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800204 def __init__(self, callback):
Jean-Paul Calderone837f4032015-03-22 17:38:28 -0400205 _CallbackExceptionHelper.__init__(self)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800206
207 @wraps(callback)
208 def wrapper(ok, store_ctx):
209 cert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500210 cert._x509 = _lib.X509_STORE_CTX_get_current_cert(store_ctx)
211 error_number = _lib.X509_STORE_CTX_get_error(store_ctx)
212 error_depth = _lib.X509_STORE_CTX_get_error_depth(store_ctx)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800213
Jean-Paul Calderone6a8cd112014-04-02 21:09:08 -0400214 index = _lib.SSL_get_ex_data_X509_STORE_CTX_idx()
215 ssl = _lib.X509_STORE_CTX_get_ex_data(store_ctx, index)
216 connection = Connection._reverse_mapping[ssl]
217
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800218 try:
219 result = callback(connection, cert, error_number, error_depth, ok)
220 except Exception as e:
221 self._problems.append(e)
222 return 0
223 else:
224 if result:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500225 _lib.X509_STORE_CTX_set_error(store_ctx, _lib.X509_V_OK)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800226 return 1
227 else:
228 return 0
229
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500230 self.callback = _ffi.callback(
231 "int (*)(int, X509_STORE_CTX *)", wrapper)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800232
233
Cory Benfield0ea76e72015-03-22 09:05:28 +0000234class _NpnAdvertiseHelper(_CallbackExceptionHelper):
Jean-Paul Calderone1b172982015-03-22 19:37:11 -0400235 """
236 Wrap a callback such that it can be used as an NPN advertisement callback.
237 """
Cory Benfield0ea76e72015-03-22 09:05:28 +0000238 def __init__(self, callback):
Jean-Paul Calderone837f4032015-03-22 17:38:28 -0400239 _CallbackExceptionHelper.__init__(self)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800240
Cory Benfield0ea76e72015-03-22 09:05:28 +0000241 @wraps(callback)
242 def wrapper(ssl, out, outlen, arg):
243 try:
244 conn = Connection._reverse_mapping[ssl]
245 protos = callback(conn)
246
247 # Join the protocols into a Python bytestring, length-prefixing
248 # each element.
249 protostr = b''.join(
250 chain.from_iterable((int2byte(len(p)), p) for p in protos)
251 )
252
253 # Save our callback arguments on the connection object. This is
254 # done to make sure that they don't get freed before OpenSSL
255 # uses them. Then, return them appropriately in the output
256 # parameters.
257 conn._npn_advertise_callback_args = [
258 _ffi.new("unsigned int *", len(protostr)),
259 _ffi.new("unsigned char[]", protostr),
260 ]
261 outlen[0] = conn._npn_advertise_callback_args[0][0]
262 out[0] = conn._npn_advertise_callback_args[1]
263 return 0
264 except Exception as e:
265 self._problems.append(e)
266 return 2 # SSL_TLSEXT_ERR_ALERT_FATAL
267
268 self.callback = _ffi.callback(
269 "int (*)(SSL *, const unsigned char **, unsigned int *, void *)",
270 wrapper
271 )
272
273
274class _NpnSelectHelper(_CallbackExceptionHelper):
Jean-Paul Calderone1b172982015-03-22 19:37:11 -0400275 """
276 Wrap a callback such that it can be used as an NPN selection callback.
277 """
Cory Benfield0ea76e72015-03-22 09:05:28 +0000278 def __init__(self, callback):
Jean-Paul Calderone837f4032015-03-22 17:38:28 -0400279 _CallbackExceptionHelper.__init__(self)
Cory Benfield0ea76e72015-03-22 09:05:28 +0000280
281 @wraps(callback)
282 def wrapper(ssl, out, outlen, in_, inlen, arg):
283 try:
284 conn = Connection._reverse_mapping[ssl]
285
286 # The string passed to us is actually made up of multiple
287 # length-prefixed bytestrings. We need to split that into a
288 # list.
289 instr = _ffi.buffer(in_, inlen)[:]
290 protolist = []
291 while instr:
292 l = indexbytes(instr, 0)
293 proto = instr[1:l+1]
294 protolist.append(proto)
295 instr = instr[l+1:]
296
297 # Call the callback
298 outstr = callback(conn, protolist)
299
300 # Save our callback arguments on the connection object. This is
301 # done to make sure that they don't get freed before OpenSSL
302 # uses them. Then, return them appropriately in the output
303 # parameters.
304 conn._npn_select_callback_args = [
305 _ffi.new("unsigned char *", len(outstr)),
306 _ffi.new("unsigned char[]", outstr),
307 ]
308 outlen[0] = conn._npn_select_callback_args[0][0]
309 out[0] = conn._npn_select_callback_args[1]
310 return 0
311 except Exception as e:
312 self._problems.append(e)
313 return 2 # SSL_TLSEXT_ERR_ALERT_FATAL
314
315 self.callback = _ffi.callback(
316 "int (*)(SSL *, unsigned char **, unsigned char *, "
317 "const unsigned char *, unsigned int, void *)",
318 wrapper
319 )
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800320
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800321
Cory Benfieldf1177e72015-04-12 09:11:49 -0400322class _AlpnSelectHelper(_CallbackExceptionHelper):
323 """
324 Wrap a callback such that it can be used as an ALPN selection callback.
325 """
326 def __init__(self, callback):
327 _CallbackExceptionHelper.__init__(self)
328
329 @wraps(callback)
330 def wrapper(ssl, out, outlen, in_, inlen, arg):
331 try:
332 conn = Connection._reverse_mapping[ssl]
333
334 # The string passed to us is made up of multiple
335 # length-prefixed bytestrings. We need to split that into a
336 # list.
337 instr = _ffi.buffer(in_, inlen)[:]
338 protolist = []
339 while instr:
340 l = indexbytes(instr, 0)
341 proto = instr[1:l+1]
342 protolist.append(proto)
343 instr = instr[l+1:]
344
345 # Call the callback
346 outstr = callback(conn, protolist)
347
348 if not isinstance(outstr, _binary_type):
349 raise TypeError("ALPN callback must return a bytestring.")
350
351 # Save our callback arguments on the connection object to make
352 # sure that they don't get freed before OpenSSL can use them.
353 # Then, return them in the appropriate output parameters.
354 conn._alpn_select_callback_args = [
355 _ffi.new("unsigned char *", len(outstr)),
356 _ffi.new("unsigned char[]", outstr),
357 ]
358 outlen[0] = conn._alpn_select_callback_args[0][0]
359 out[0] = conn._alpn_select_callback_args[1]
360 return 0
361 except Exception as e:
362 self._problems.append(e)
363 return 2 # SSL_TLSEXT_ERR_ALERT_FATAL
364
365 self.callback = _ffi.callback(
366 "int (*)(SSL *, unsigned char **, unsigned char *, "
367 "const unsigned char *, unsigned int, void *)",
368 wrapper
369 )
370
371
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800372def _asFileDescriptor(obj):
373 fd = None
Konstantinos Koukopoulosc8b13ea2014-01-28 00:21:50 -0800374 if not isinstance(obj, integer_types):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800375 meth = getattr(obj, "fileno", None)
376 if meth is not None:
377 obj = meth()
378
Konstantinos Koukopoulosc8b13ea2014-01-28 00:21:50 -0800379 if isinstance(obj, integer_types):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800380 fd = obj
381
Konstantinos Koukopoulosc8b13ea2014-01-28 00:21:50 -0800382 if not isinstance(fd, integer_types):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800383 raise TypeError("argument must be an int, or have a fileno() method.")
384 elif fd < 0:
385 raise ValueError(
386 "file descriptor cannot be a negative integer (%i)" % (fd,))
387
388 return fd
389
390
391
Jean-Paul Calderoned39a3f62013-03-04 12:23:51 -0800392def SSLeay_version(type):
393 """
394 Return a string describing the version of OpenSSL in use.
395
396 :param type: One of the SSLEAY_ constants defined in this module.
397 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500398 return _ffi.string(_lib.SSLeay_version(type))
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800399
400
401
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800402class Session(object):
403 pass
404
405
406
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800407class Context(object):
408 """
409 :py:obj:`OpenSSL.SSL.Context` instances define the parameters for setting up
410 new SSL connections.
411 """
412 _methods = {
Andrew Dunhamec84a0a2014-02-24 12:41:37 -0800413 SSLv2_METHOD: "SSLv2_method",
Jean-Paul Calderonebe2bb422013-12-29 07:34:08 -0500414 SSLv3_METHOD: "SSLv3_method",
415 SSLv23_METHOD: "SSLv23_method",
416 TLSv1_METHOD: "TLSv1_method",
417 TLSv1_1_METHOD: "TLSv1_1_method",
418 TLSv1_2_METHOD: "TLSv1_2_method",
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800419 }
Jean-Paul Calderonebe2bb422013-12-29 07:34:08 -0500420 _methods = dict(
421 (identifier, getattr(_lib, name))
422 for (identifier, name) in _methods.items()
423 if getattr(_lib, name, None) is not None)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800424
Jean-Paul Calderone63157872013-03-20 16:43:38 -0700425
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800426 def __init__(self, method):
427 """
428 :param method: One of SSLv2_METHOD, SSLv3_METHOD, SSLv23_METHOD, or
429 TLSv1_METHOD.
430 """
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -0500431 if not isinstance(method, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800432 raise TypeError("method must be an integer")
433
434 try:
435 method_func = self._methods[method]
436 except KeyError:
437 raise ValueError("No such protocol")
438
439 method_obj = method_func()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500440 if method_obj == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500441 # TODO: This is untested.
442 _raise_current_error()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800443
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500444 context = _lib.SSL_CTX_new(method_obj)
445 if context == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500446 # TODO: This is untested.
447 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500448 context = _ffi.gc(context, _lib.SSL_CTX_free)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800449
450 self._context = context
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800451 self._passphrase_helper = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800452 self._passphrase_callback = None
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800453 self._passphrase_userdata = None
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800454 self._verify_helper = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800455 self._verify_callback = None
456 self._info_callback = None
457 self._tlsext_servername_callback = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800458 self._app_data = None
Cory Benfield0ea76e72015-03-22 09:05:28 +0000459 self._npn_advertise_helper = None
Cory Benfield84a121e2014-03-31 20:30:25 +0100460 self._npn_advertise_callback = None
Cory Benfield0ea76e72015-03-22 09:05:28 +0000461 self._npn_select_helper = None
Cory Benfield84a121e2014-03-31 20:30:25 +0100462 self._npn_select_callback = None
Cory Benfieldf1177e72015-04-12 09:11:49 -0400463 self._alpn_select_helper = None
Cory Benfield12eae892014-06-07 15:42:56 +0100464 self._alpn_select_callback = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800465
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -0800466 # SSL_CTX_set_app_data(self->ctx, self);
467 # SSL_CTX_set_mode(self->ctx, SSL_MODE_ENABLE_PARTIAL_WRITE |
468 # SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
469 # SSL_MODE_AUTO_RETRY);
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500470 self.set_mode(_lib.SSL_MODE_ENABLE_PARTIAL_WRITE)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800471
472
473 def load_verify_locations(self, cafile, capath=None):
474 """
475 Let SSL know where we can find trusted certificates for the certificate
476 chain
477
Jean-Paul Calderone55f9e882015-04-12 09:31:03 -0400478 :param cafile: In which file we can find the certificates (``bytes`` or
479 ``unicode``).
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800480 :param capath: In which directory we can find the certificates
Jean-Paul Calderone55f9e882015-04-12 09:31:03 -0400481 (``bytes`` or ``unicode``).
482
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800483 :return: None
484 """
485 if cafile is None:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500486 cafile = _ffi.NULL
Jean-Paul Calderone55f9e882015-04-12 09:31:03 -0400487 else:
488 cafile = _path_string(cafile)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800489
490 if capath is None:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500491 capath = _ffi.NULL
Jean-Paul Calderone55f9e882015-04-12 09:31:03 -0400492 else:
493 capath = _path_string(capath)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800494
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500495 load_result = _lib.SSL_CTX_load_verify_locations(self._context, cafile, capath)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800496 if not load_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500497 _raise_current_error()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800498
499
500 def _wrap_callback(self, callback):
501 @wraps(callback)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800502 def wrapper(size, verify, userdata):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800503 return callback(size, verify, self._passphrase_userdata)
504 return _PassphraseHelper(
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800505 FILETYPE_PEM, wrapper, more_args=True, truncate=True)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800506
507
508 def set_passwd_cb(self, callback, userdata=None):
509 """
510 Set the passphrase callback
511
512 :param callback: The Python callback to use
513 :param userdata: (optional) A Python object which will be given as
514 argument to the callback
515 :return: None
516 """
517 if not callable(callback):
518 raise TypeError("callback must be callable")
519
520 self._passphrase_helper = self._wrap_callback(callback)
521 self._passphrase_callback = self._passphrase_helper.callback
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500522 _lib.SSL_CTX_set_default_passwd_cb(
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800523 self._context, self._passphrase_callback)
524 self._passphrase_userdata = userdata
525
526
527 def set_default_verify_paths(self):
528 """
529 Use the platform-specific CA certificate locations
530
531 :return: None
532 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500533 set_result = _lib.SSL_CTX_set_default_verify_paths(self._context)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800534 if not set_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500535 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500536 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800537
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800538
539 def use_certificate_chain_file(self, certfile):
540 """
541 Load a certificate chain from a file
542
Jean-Paul Calderoneb6f8a792015-04-13 10:10:06 -0400543 :param certfile: The name of the certificate chain file (``bytes`` or
544 ``unicode``).
545
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800546 :return: None
547 """
Jean-Paul Calderoneaac43a32015-04-12 09:51:21 -0400548 certfile = _path_string(certfile)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800549
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500550 result = _lib.SSL_CTX_use_certificate_chain_file(self._context, certfile)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800551 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500552 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800553
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800554
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800555 def use_certificate_file(self, certfile, filetype=FILETYPE_PEM):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800556 """
557 Load a certificate from a file
558
Jean-Paul Calderoneb6f8a792015-04-13 10:10:06 -0400559 :param certfile: The name of the certificate file (``bytes`` or
560 ``unicode``).
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800561 :param filetype: (optional) The encoding of the file, default is PEM
Jean-Paul Calderoneb6f8a792015-04-13 10:10:06 -0400562
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800563 :return: None
564 """
Jean-Paul Calderoned57a7b62015-04-12 09:57:36 -0400565 certfile = _path_string(certfile)
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -0500566 if not isinstance(filetype, integer_types):
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800567 raise TypeError("filetype must be an integer")
568
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500569 use_result = _lib.SSL_CTX_use_certificate_file(self._context, certfile, filetype)
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800570 if not use_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500571 _raise_current_error()
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800572
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800573
574 def use_certificate(self, cert):
575 """
576 Load a certificate from a X509 object
577
578 :param cert: The X509 object
579 :return: None
580 """
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800581 if not isinstance(cert, X509):
582 raise TypeError("cert must be an X509 instance")
583
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500584 use_result = _lib.SSL_CTX_use_certificate(self._context, cert._x509)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800585 if not use_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500586 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800587
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800588
589 def add_extra_chain_cert(self, certobj):
590 """
591 Add certificate to chain
592
593 :param certobj: The X509 certificate object to add to the chain
594 :return: None
595 """
596 if not isinstance(certobj, X509):
597 raise TypeError("certobj must be an X509 instance")
598
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500599 copy = _lib.X509_dup(certobj._x509)
600 add_result = _lib.SSL_CTX_add_extra_chain_cert(self._context, copy)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800601 if not add_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500602 # TODO: This is untested.
603 _lib.X509_free(copy)
604 _raise_current_error()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800605
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800606
607 def _raise_passphrase_exception(self):
608 if self._passphrase_helper is None:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500609 _raise_current_error()
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800610 exception = self._passphrase_helper.raise_if_problem(Error)
611 if exception is not None:
612 raise exception
613
614
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800615 def use_privatekey_file(self, keyfile, filetype=_unspecified):
616 """
617 Load a private key from a file
618
Jean-Paul Calderoneb6f8a792015-04-13 10:10:06 -0400619 :param keyfile: The name of the key file (``bytes`` or ``unicode``)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800620 :param filetype: (optional) The encoding of the file, default is PEM
Jean-Paul Calderoneb6f8a792015-04-13 10:10:06 -0400621
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800622 :return: None
623 """
Jean-Paul Calderone69a4e5b2015-04-12 10:04:28 -0400624 keyfile = _path_string(keyfile)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800625
626 if filetype is _unspecified:
627 filetype = FILETYPE_PEM
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -0500628 elif not isinstance(filetype, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800629 raise TypeError("filetype must be an integer")
630
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500631 use_result = _lib.SSL_CTX_use_PrivateKey_file(
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800632 self._context, keyfile, filetype)
633 if not use_result:
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800634 self._raise_passphrase_exception()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800635
636
637 def use_privatekey(self, pkey):
638 """
639 Load a private key from a PKey object
640
641 :param pkey: The PKey object
642 :return: None
643 """
644 if not isinstance(pkey, PKey):
645 raise TypeError("pkey must be a PKey instance")
646
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500647 use_result = _lib.SSL_CTX_use_PrivateKey(self._context, pkey._pkey)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800648 if not use_result:
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800649 self._raise_passphrase_exception()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800650
651
652 def check_privatekey(self):
653 """
654 Check that the private key and certificate match up
655
656 :return: None (raises an exception if something's wrong)
657 """
Jean-Paul Calderonea0344922014-12-11 14:02:31 -0500658 if not _lib.SSL_CTX_check_private_key(self._context):
659 _raise_current_error()
660
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800661
662 def load_client_ca(self, cafile):
663 """
664 Load the trusted certificates that will be sent to the client (basically
665 telling the client "These are the guys I trust"). Does not actually
666 imply any of the certificates are trusted; that must be configured
667 separately.
668
669 :param cafile: The name of the certificates file
670 :return: None
671 """
672
673 def set_session_id(self, buf):
674 """
675 Set the session identifier. This is needed if you want to do session
676 resumption.
677
678 :param buf: A Python object that can be safely converted to a string
679 :returns: None
680 """
681
682 def set_session_cache_mode(self, mode):
683 """
684 Enable/disable session caching and specify the mode used.
685
686 :param mode: One or more of the SESS_CACHE_* flags (combine using
687 bitwise or)
688 :returns: The previously set caching mode.
689 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500690 if not isinstance(mode, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800691 raise TypeError("mode must be an integer")
692
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500693 return _lib.SSL_CTX_set_session_cache_mode(self._context, mode)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800694
695
696 def get_session_cache_mode(self):
697 """
698 :returns: The currently used cache mode.
699 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500700 return _lib.SSL_CTX_get_session_cache_mode(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800701
702
703 def set_verify(self, mode, callback):
704 """
705 Set the verify mode and verify callback
706
707 :param mode: The verify mode, this is either VERIFY_NONE or
708 VERIFY_PEER combined with possible other flags
709 :param callback: The Python callback to use
710 :return: None
711
712 See SSL_CTX_set_verify(3SSL) for further details.
713 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500714 if not isinstance(mode, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800715 raise TypeError("mode must be an integer")
716
717 if not callable(callback):
718 raise TypeError("callback must be callable")
719
Jean-Paul Calderone6a8cd112014-04-02 21:09:08 -0400720 self._verify_helper = _VerifyHelper(callback)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800721 self._verify_callback = self._verify_helper.callback
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500722 _lib.SSL_CTX_set_verify(self._context, mode, self._verify_callback)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800723
724
725 def set_verify_depth(self, depth):
726 """
727 Set the verify depth
728
729 :param depth: An integer specifying the verify depth
730 :return: None
731 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500732 if not isinstance(depth, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800733 raise TypeError("depth must be an integer")
734
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500735 _lib.SSL_CTX_set_verify_depth(self._context, depth)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800736
737
738 def get_verify_mode(self):
739 """
740 Get the verify mode
741
742 :return: The verify mode
743 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500744 return _lib.SSL_CTX_get_verify_mode(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800745
746
747 def get_verify_depth(self):
748 """
749 Get the verify depth
750
751 :return: The verify depth
752 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500753 return _lib.SSL_CTX_get_verify_depth(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800754
755
756 def load_tmp_dh(self, dhfile):
757 """
758 Load parameters for Ephemeral Diffie-Hellman
759
Jean-Paul Calderone4e0c43f2015-04-13 10:15:17 -0400760 :param dhfile: The file to load EDH parameters from (``bytes`` or
761 ``unicode``).
762
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800763 :return: None
764 """
Jean-Paul Calderone9e1c1dd2015-04-12 10:13:13 -0400765 dhfile = _path_string(dhfile)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800766
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -0500767 bio = _lib.BIO_new_file(dhfile, b"r")
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500768 if bio == _ffi.NULL:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500769 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500770 bio = _ffi.gc(bio, _lib.BIO_free)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800771
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500772 dh = _lib.PEM_read_bio_DHparams(bio, _ffi.NULL, _ffi.NULL, _ffi.NULL)
773 dh = _ffi.gc(dh, _lib.DH_free)
774 _lib.SSL_CTX_set_tmp_dh(self._context, dh)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800775
776
Jean-Paul Calderone3e4e3352014-04-19 09:28:28 -0400777 def set_tmp_ecdh(self, curve):
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600778 """
Andy Lutomirski76a61332014-03-12 15:02:56 -0700779 Select a curve to use for ECDHE key exchange.
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600780
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -0400781 :param curve: A curve object to use as returned by either
782 :py:meth:`OpenSSL.crypto.get_elliptic_curve` or
783 :py:meth:`OpenSSL.crypto.get_elliptic_curves`.
Andy Lutomirskif05a2732014-03-13 17:22:25 -0700784
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600785 :return: None
786 """
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -0400787 _lib.SSL_CTX_set_tmp_ecdh(self._context, curve._to_EC_KEY())
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600788
789
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800790 def set_cipher_list(self, cipher_list):
791 """
792 Change the cipher list
793
794 :param cipher_list: A cipher list, see ciphers(1)
795 :return: None
796 """
Jean-Paul Calderone63eab692014-01-18 10:19:56 -0500797 if isinstance(cipher_list, _text_type):
798 cipher_list = cipher_list.encode("ascii")
799
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800800 if not isinstance(cipher_list, bytes):
Jean-Paul Calderone63eab692014-01-18 10:19:56 -0500801 raise TypeError("cipher_list must be bytes or unicode")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800802
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500803 result = _lib.SSL_CTX_set_cipher_list(self._context, cipher_list)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800804 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500805 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800806
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800807
808 def set_client_ca_list(self, certificate_authorities):
809 """
810 Set the list of preferred client certificate signers for this server context.
811
812 This list of certificate authorities will be sent to the client when the
813 server requests a client certificate.
814
815 :param certificate_authorities: a sequence of X509Names.
816 :return: None
817 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500818 name_stack = _lib.sk_X509_NAME_new_null()
819 if name_stack == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500820 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500821 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800822
823 try:
824 for ca_name in certificate_authorities:
825 if not isinstance(ca_name, X509Name):
826 raise TypeError(
827 "client CAs must be X509Name objects, not %s objects" % (
828 type(ca_name).__name__,))
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500829 copy = _lib.X509_NAME_dup(ca_name._name)
830 if copy == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500831 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500832 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500833 push_result = _lib.sk_X509_NAME_push(name_stack, copy)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800834 if not push_result:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500835 _lib.X509_NAME_free(copy)
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500836 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800837 except:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500838 _lib.sk_X509_NAME_free(name_stack)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800839 raise
840
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500841 _lib.SSL_CTX_set_client_CA_list(self._context, name_stack)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800842
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800843
844 def add_client_ca(self, certificate_authority):
845 """
846 Add the CA certificate to the list of preferred signers for this context.
847
848 The list of certificate authorities will be sent to the client when the
849 server requests a client certificate.
850
851 :param certificate_authority: certificate authority's X509 certificate.
852 :return: None
853 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800854 if not isinstance(certificate_authority, X509):
855 raise TypeError("certificate_authority must be an X509 instance")
856
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500857 add_result = _lib.SSL_CTX_add_client_CA(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800858 self._context, certificate_authority._x509)
859 if not add_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500860 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500861 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800862
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800863
864 def set_timeout(self, timeout):
865 """
866 Set session timeout
867
868 :param timeout: The timeout in seconds
869 :return: The previous session timeout
870 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500871 if not isinstance(timeout, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800872 raise TypeError("timeout must be an integer")
873
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500874 return _lib.SSL_CTX_set_timeout(self._context, timeout)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800875
876
877 def get_timeout(self):
878 """
879 Get the session timeout
880
881 :return: The session timeout
882 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500883 return _lib.SSL_CTX_get_timeout(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800884
885
886 def set_info_callback(self, callback):
887 """
888 Set the info callback
889
890 :param callback: The Python callback to use
891 :return: None
892 """
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800893 @wraps(callback)
894 def wrapper(ssl, where, return_code):
Jean-Paul Calderonef2bbc9c2014-02-02 10:59:14 -0500895 callback(Connection._reverse_mapping[ssl], where, return_code)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500896 self._info_callback = _ffi.callback(
897 "void (*)(const SSL *, int, int)", wrapper)
898 _lib.SSL_CTX_set_info_callback(self._context, self._info_callback)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800899
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800900
901 def get_app_data(self):
902 """
903 Get the application data (supplied via set_app_data())
904
905 :return: The application data
906 """
907 return self._app_data
908
909
910 def set_app_data(self, data):
911 """
912 Set the application data (will be returned from get_app_data())
913
914 :param data: Any Python object
915 :return: None
916 """
917 self._app_data = data
918
919
920 def get_cert_store(self):
921 """
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500922 Get the certificate store for the context.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800923
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500924 :return: A X509Store object or None if it does not have one.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800925 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500926 store = _lib.SSL_CTX_get_cert_store(self._context)
927 if store == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500928 # TODO: This is untested.
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800929 return None
930
931 pystore = X509Store.__new__(X509Store)
932 pystore._store = store
933 return pystore
934
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800935
936 def set_options(self, options):
937 """
938 Add options. Options set before are not cleared!
939
940 :param options: The options to add.
941 :return: The new option bitmask.
942 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500943 if not isinstance(options, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800944 raise TypeError("options must be an integer")
945
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500946 return _lib.SSL_CTX_set_options(self._context, options)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800947
948
949 def set_mode(self, mode):
950 """
951 Add modes via bitmask. Modes set before are not cleared!
952
953 :param mode: The mode to add.
954 :return: The new mode bitmask.
955 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500956 if not isinstance(mode, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800957 raise TypeError("mode must be an integer")
958
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500959 return _lib.SSL_CTX_set_mode(self._context, mode)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800960
961
962 def set_tlsext_servername_callback(self, callback):
963 """
964 Specify a callback function to be called when clients specify a server name.
965
966 :param callback: The callback function. It will be invoked with one
967 argument, the Connection instance.
968 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800969 @wraps(callback)
970 def wrapper(ssl, alert, arg):
971 callback(Connection._reverse_mapping[ssl])
972 return 0
973
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500974 self._tlsext_servername_callback = _ffi.callback(
975 "int (*)(const SSL *, int *, void *)", wrapper)
976 _lib.SSL_CTX_set_tlsext_servername_callback(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800977 self._context, self._tlsext_servername_callback)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800978
Cory Benfield84a121e2014-03-31 20:30:25 +0100979 def set_npn_advertise_callback(self, callback):
980 """
Cory Benfieldbe3e7b82014-05-10 09:48:55 +0100981 Specify a callback function that will be called when offering `Next
982 Protocol Negotiation
983 <https://technotes.googlecode.com/git/nextprotoneg.html>`_ as a server.
Cory Benfield84a121e2014-03-31 20:30:25 +0100984
985 :param callback: The callback function. It will be invoked with one
Cory Benfieldbe3e7b82014-05-10 09:48:55 +0100986 argument, the Connection instance. It should return a list of
987 bytestrings representing the advertised protocols, like
988 ``[b'http/1.1', b'spdy/2']``.
Cory Benfield84a121e2014-03-31 20:30:25 +0100989 """
Cory Benfield0ea76e72015-03-22 09:05:28 +0000990 self._npn_advertise_helper = _NpnAdvertiseHelper(callback)
991 self._npn_advertise_callback = self._npn_advertise_helper.callback
Cory Benfield84a121e2014-03-31 20:30:25 +0100992 _lib.SSL_CTX_set_next_protos_advertised_cb(
993 self._context, self._npn_advertise_callback, _ffi.NULL)
994
995
996 def set_npn_select_callback(self, callback):
997 """
998 Specify a callback function that will be called when a server offers
999 Next Protocol Negotiation options.
1000
1001 :param callback: The callback function. It will be invoked with two
1002 arguments: the Connection, and a list of offered protocols as
Cory Benfieldbe3e7b82014-05-10 09:48:55 +01001003 bytestrings, e.g. ``[b'http/1.1', b'spdy/2']``. It should return
1004 one of those bytestrings, the chosen protocol.
Cory Benfield84a121e2014-03-31 20:30:25 +01001005 """
Cory Benfield0ea76e72015-03-22 09:05:28 +00001006 self._npn_select_helper = _NpnSelectHelper(callback)
1007 self._npn_select_callback = self._npn_select_helper.callback
Cory Benfield84a121e2014-03-31 20:30:25 +01001008 _lib.SSL_CTX_set_next_proto_select_cb(
1009 self._context, self._npn_select_callback, _ffi.NULL)
1010
Cory Benfield12eae892014-06-07 15:42:56 +01001011 def set_alpn_protos(self, protos):
1012 """
Cory Benfielde8e9c382015-04-11 17:33:48 -04001013 Specify the clients ALPN protocol list.
1014
1015 These protocols are offered to the server during protocol negotiation.
Cory Benfield12eae892014-06-07 15:42:56 +01001016
1017 :param protos: A list of the protocols to be offered to the server.
1018 This list should be a Python list of bytestrings representing the
1019 protocols to offer, e.g. ``[b'http/1.1', b'spdy/2']``.
1020 """
Cory Benfield3e619292015-04-13 12:34:51 -04001021 if not _lib.Cryptography_HAS_ALPN:
1022 raise NotImplementedError("ALPN not available")
1023
Cory Benfield12eae892014-06-07 15:42:56 +01001024 # Take the list of protocols and join them together, prefixing them
1025 # with their lengths.
1026 protostr = b''.join(
1027 chain.from_iterable((int2byte(len(p)), p) for p in protos)
1028 )
1029
1030 # Build a C string from the list. We don't need to save this off
1031 # because OpenSSL immediately copies the data out.
1032 input_str = _ffi.new("unsigned char[]", protostr)
Cory Benfielde871af52015-04-11 17:57:50 -04001033 input_str_len = _ffi.cast("unsigned", len(protostr))
1034 _lib.SSL_CTX_set_alpn_protos(self._context, input_str, input_str_len)
Cory Benfield12eae892014-06-07 15:42:56 +01001035
1036 def set_alpn_select_callback(self, callback):
1037 """
Cory Benfielde8e9c382015-04-11 17:33:48 -04001038 Set the callback to handle ALPN protocol choice.
Cory Benfield12eae892014-06-07 15:42:56 +01001039
1040 :param callback: The callback function. It will be invoked with two
1041 arguments: the Connection, and a list of offered protocols as
1042 bytestrings, e.g ``[b'http/1.1', b'spdy/2']``. It should return
Cory Benfielde8e9c382015-04-11 17:33:48 -04001043 one of those bytestrings, the chosen protocol.
Cory Benfield12eae892014-06-07 15:42:56 +01001044 """
Cory Benfield3e619292015-04-13 12:34:51 -04001045 if not _lib.Cryptography_HAS_ALPN:
1046 raise NotImplementedError("ALPN not available")
1047
Cory Benfieldf1177e72015-04-12 09:11:49 -04001048 self._alpn_select_helper = _AlpnSelectHelper(callback)
1049 self._alpn_select_callback = self._alpn_select_helper.callback
Cory Benfield12eae892014-06-07 15:42:56 +01001050 _lib.SSL_CTX_set_alpn_select_cb(
1051 self._context, self._alpn_select_callback, _ffi.NULL)
1052
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -08001053ContextType = Context
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001054
1055
1056
1057class Connection(object):
1058 """
1059 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001060 _reverse_mapping = WeakValueDictionary()
1061
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001062 def __init__(self, context, socket=None):
1063 """
1064 Create a new Connection object, using the given OpenSSL.SSL.Context
1065 instance and socket.
1066
1067 :param context: An SSL Context to use for this connection
1068 :param socket: The socket to use for transport layer
1069 """
1070 if not isinstance(context, Context):
1071 raise TypeError("context must be a Context instance")
1072
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001073 ssl = _lib.SSL_new(context._context)
1074 self._ssl = _ffi.gc(ssl, _lib.SSL_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001075 self._context = context
1076
Cory Benfieldbe3e7b82014-05-10 09:48:55 +01001077 # References to strings used for Next Protocol Negotiation. OpenSSL's
1078 # header files suggest that these might get copied at some point, but
1079 # doesn't specify when, so we store them here to make sure they don't
1080 # get freed before OpenSSL uses them.
1081 self._npn_advertise_callback_args = None
1082 self._npn_select_callback_args = None
1083
Cory Benfield12eae892014-06-07 15:42:56 +01001084 # References to strings used for Application Layer Protocol
1085 # Negotiation. These strings get copied at some point but it's well
1086 # after the callback returns, so we have to hang them somewhere to
1087 # avoid them getting freed.
1088 self._alpn_select_callback_args = None
1089
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001090 self._reverse_mapping[self._ssl] = self
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001091
1092 if socket is None:
1093 self._socket = None
Jean-Paul Calderone73b15c22013-03-05 18:30:39 -08001094 # Don't set up any gc for these, SSL_free will take care of them.
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001095 self._into_ssl = _lib.BIO_new(_lib.BIO_s_mem())
1096 self._from_ssl = _lib.BIO_new(_lib.BIO_s_mem())
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001097
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001098 if self._into_ssl == _ffi.NULL or self._from_ssl == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001099 # TODO: This is untested.
1100 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001101
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001102 _lib.SSL_set_bio(self._ssl, self._into_ssl, self._from_ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001103 else:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001104 self._into_ssl = None
1105 self._from_ssl = None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001106 self._socket = socket
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001107 set_result = _lib.SSL_set_fd(self._ssl, _asFileDescriptor(self._socket))
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001108 if not set_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001109 # TODO: This is untested.
1110 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001111
1112
1113 def __getattr__(self, name):
1114 """
1115 Look up attributes on the wrapped socket object if they are not found on
1116 the Connection object.
1117 """
1118 return getattr(self._socket, name)
1119
1120
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001121 def _raise_ssl_error(self, ssl, result):
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -08001122 if self._context._verify_helper is not None:
1123 self._context._verify_helper.raise_if_problem()
Cory Benfield0ea76e72015-03-22 09:05:28 +00001124 if self._context._npn_advertise_helper is not None:
1125 self._context._npn_advertise_helper.raise_if_problem()
1126 if self._context._npn_select_helper is not None:
1127 self._context._npn_select_helper.raise_if_problem()
Cory Benfieldf1177e72015-04-12 09:11:49 -04001128 if self._context._alpn_select_helper is not None:
1129 self._context._alpn_select_helper.raise_if_problem()
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -08001130
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001131 error = _lib.SSL_get_error(ssl, result)
1132 if error == _lib.SSL_ERROR_WANT_READ:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001133 raise WantReadError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001134 elif error == _lib.SSL_ERROR_WANT_WRITE:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001135 raise WantWriteError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001136 elif error == _lib.SSL_ERROR_ZERO_RETURN:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001137 raise ZeroReturnError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001138 elif error == _lib.SSL_ERROR_WANT_X509_LOOKUP:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001139 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001140 raise WantX509LookupError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001141 elif error == _lib.SSL_ERROR_SYSCALL:
1142 if _lib.ERR_peek_error() == 0:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001143 if result < 0:
Konstantinos Koukopoulos541150d2014-01-31 01:00:19 +02001144 if platform == "win32":
1145 errno = _ffi.getwinerror()[0]
1146 else:
1147 errno = _ffi.errno
1148 raise SysCallError(errno, errorcode[errno])
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001149 else:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001150 raise SysCallError(-1, "Unexpected EOF")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001151 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001152 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001153 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001154 elif error == _lib.SSL_ERROR_NONE:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001155 pass
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001156 else:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001157 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001158
1159
1160 def get_context(self):
1161 """
1162 Get session context
1163 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001164 return self._context
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001165
1166
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001167 def set_context(self, context):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001168 """
1169 Switch this connection to a new session context
1170
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001171 :param context: A :py:class:`Context` instance giving the new session
1172 context to use.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001173 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001174 if not isinstance(context, Context):
1175 raise TypeError("context must be a Context instance")
1176
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001177 _lib.SSL_set_SSL_CTX(self._ssl, context._context)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001178 self._context = context
1179
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001180
1181 def get_servername(self):
1182 """
1183 Retrieve the servername extension value if provided in the client hello
1184 message, or None if there wasn't one.
1185
1186 :return: A byte string giving the server name or :py:data:`None`.
1187 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001188 name = _lib.SSL_get_servername(self._ssl, _lib.TLSEXT_NAMETYPE_host_name)
1189 if name == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001190 return None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001191
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001192 return _ffi.string(name)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001193
1194
1195 def set_tlsext_host_name(self, name):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001196 """
1197 Set the value of the servername extension to send in the client hello.
1198
1199 :param name: A byte string giving the name.
1200 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001201 if not isinstance(name, bytes):
1202 raise TypeError("name must be a byte string")
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001203 elif b"\0" in name:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001204 raise TypeError("name must not contain NUL byte")
1205
1206 # XXX I guess this can fail sometimes?
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001207 _lib.SSL_set_tlsext_host_name(self._ssl, name)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001208
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001209
1210 def pending(self):
1211 """
1212 Get the number of bytes that can be safely read from the connection
1213
1214 :return: The number of bytes available in the receive buffer.
1215 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001216 return _lib.SSL_pending(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001217
1218
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001219 def send(self, buf, flags=0):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001220 """
1221 Send data on the connection. NOTE: If you get one of the WantRead,
1222 WantWrite or WantX509Lookup exceptions on this, you have to call the
1223 method again with the SAME buffer.
1224
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001225 :param buf: The string, buffer or memoryview to send
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001226 :param flags: (optional) Included for compatibility with the socket
1227 API, the value is ignored
1228 :return: The number of bytes written
1229 """
Jean-Paul Calderone8fb53182013-12-30 08:35:49 -05001230 if isinstance(buf, _memoryview):
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -08001231 buf = buf.tobytes()
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001232 if isinstance(buf, _buffer):
1233 buf = str(buf)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001234 if not isinstance(buf, bytes):
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001235 raise TypeError("data must be a memoryview, buffer or byte string")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001236
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001237 result = _lib.SSL_write(self._ssl, buf, len(buf))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001238 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001239 return result
1240 write = send
1241
1242
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001243 def sendall(self, buf, flags=0):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001244 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001245 Send "all" data on the connection. This calls send() repeatedly until
1246 all data is sent. If an error occurs, it's impossible to tell how much
1247 data has been sent.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001248
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001249 :param buf: The string, buffer or memoryview to send
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001250 :param flags: (optional) Included for compatibility with the socket
1251 API, the value is ignored
1252 :return: The number of bytes written
1253 """
Jean-Paul Calderone8fb53182013-12-30 08:35:49 -05001254 if isinstance(buf, _memoryview):
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -08001255 buf = buf.tobytes()
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001256 if isinstance(buf, _buffer):
1257 buf = str(buf)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001258 if not isinstance(buf, bytes):
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001259 raise TypeError("buf must be a memoryview, buffer or byte string")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001260
1261 left_to_send = len(buf)
1262 total_sent = 0
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001263 data = _ffi.new("char[]", buf)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001264
1265 while left_to_send:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001266 result = _lib.SSL_write(self._ssl, data + total_sent, left_to_send)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001267 self._raise_ssl_error(self._ssl, result)
1268 total_sent += result
1269 left_to_send -= result
1270
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001271
1272 def recv(self, bufsiz, flags=None):
1273 """
1274 Receive data on the connection. NOTE: If you get one of the WantRead,
1275 WantWrite or WantX509Lookup exceptions on this, you have to call the
1276 method again with the SAME buffer.
1277
1278 :param bufsiz: The maximum number of bytes to read
1279 :param flags: (optional) Included for compatibility with the socket
1280 API, the value is ignored
1281 :return: The string read from the Connection
1282 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001283 buf = _ffi.new("char[]", bufsiz)
1284 result = _lib.SSL_read(self._ssl, buf, bufsiz)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001285 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001286 return _ffi.buffer(buf, result)[:]
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001287 read = recv
1288
1289
Cory Benfield62d10332014-06-15 10:03:41 +01001290 def recv_into(self, buffer, nbytes=None, flags=None):
1291 """
1292 Receive data on the connection and store the data into a buffer rather
1293 than creating a new string.
1294
1295 :param buffer: The buffer to copy into.
1296 :param nbytes: (optional) The maximum number of bytes to read into the
1297 buffer. If not present, defaults to the size of the buffer. If
1298 larger than the size of the buffer, is reduced to the size of the
1299 buffer.
1300 :param flags: (optional) Included for compatibility with the socket
1301 API, the value is ignored.
1302 :return: The number of bytes read into the buffer.
1303 """
1304 if nbytes is None:
1305 nbytes = len(buffer)
1306 else:
1307 nbytes = min(nbytes, len(buffer))
1308
1309 # We need to create a temporary buffer. This is annoying, it would be
1310 # better if we could pass memoryviews straight into the SSL_read call,
1311 # but right now we can't. Revisit this if CFFI gets that ability.
1312 buf = _ffi.new("char[]", nbytes)
1313 result = _lib.SSL_read(self._ssl, buf, nbytes)
1314 self._raise_ssl_error(self._ssl, result)
1315
1316 # This strange line is all to avoid a memory copy. The buffer protocol
1317 # should allow us to assign a CFFI buffer to the LHS of this line, but
1318 # on CPython 3.3+ that segfaults. As a workaround, we can temporarily
1319 # wrap it in a memoryview, except on Python 2.6 which doesn't have a
1320 # memoryview type.
1321 try:
1322 buffer[:result] = memoryview(_ffi.buffer(buf, result))
1323 except NameError:
1324 buffer[:result] = _ffi.buffer(buf, result)
1325
1326 return result
1327
1328
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001329 def _handle_bio_errors(self, bio, result):
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001330 if _lib.BIO_should_retry(bio):
1331 if _lib.BIO_should_read(bio):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001332 raise WantReadError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001333 elif _lib.BIO_should_write(bio):
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001334 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001335 raise WantWriteError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001336 elif _lib.BIO_should_io_special(bio):
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001337 # TODO: This is untested. I think io_special means the socket
1338 # BIO has a not-yet connected socket.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001339 raise ValueError("BIO_should_io_special")
1340 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001341 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001342 raise ValueError("unknown bio failure")
1343 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001344 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001345 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001346
1347
1348 def bio_read(self, bufsiz):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001349 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001350 When using non-socket connections this function reads the "dirty" data
1351 that would have traveled away on the network.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001352
1353 :param bufsiz: The maximum number of bytes to read
1354 :return: The string read.
1355 """
Jean-Paul Calderone97e041d2013-03-05 21:03:12 -08001356 if self._from_ssl is None:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001357 raise TypeError("Connection sock was not None")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001358
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -05001359 if not isinstance(bufsiz, integer_types):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001360 raise TypeError("bufsiz must be an integer")
1361
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001362 buf = _ffi.new("char[]", bufsiz)
1363 result = _lib.BIO_read(self._from_ssl, buf, bufsiz)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001364 if result <= 0:
1365 self._handle_bio_errors(self._from_ssl, result)
1366
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001367 return _ffi.buffer(buf, result)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001368
1369
1370 def bio_write(self, buf):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001371 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001372 When using non-socket connections this function sends "dirty" data that
1373 would have traveled in on the network.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001374
1375 :param buf: The string to put into the memory BIO.
1376 :return: The number of bytes written
1377 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001378 if self._into_ssl is None:
1379 raise TypeError("Connection sock was not None")
1380
1381 if not isinstance(buf, bytes):
1382 raise TypeError("buf must be a byte string")
1383
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001384 result = _lib.BIO_write(self._into_ssl, buf, len(buf))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001385 if result <= 0:
1386 self._handle_bio_errors(self._into_ssl, result)
1387 return result
1388
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001389
1390 def renegotiate(self):
1391 """
1392 Renegotiate the session
1393
1394 :return: True if the renegotiation can be started, false otherwise
1395 """
1396
1397 def do_handshake(self):
1398 """
1399 Perform an SSL handshake (usually called after renegotiate() or one of
1400 set_*_state()). This can raise the same exceptions as send and recv.
1401
1402 :return: None.
1403 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001404 result = _lib.SSL_do_handshake(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001405 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001406
1407
1408 def renegotiate_pending(self):
1409 """
1410 Check if there's a renegotiation in progress, it will return false once
1411 a renegotiation is finished.
1412
1413 :return: Whether there's a renegotiation in progress
1414 """
1415
1416 def total_renegotiations(self):
1417 """
1418 Find out the total number of renegotiations.
1419
1420 :return: The number of renegotiations.
1421 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001422 return _lib.SSL_total_renegotiations(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001423
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001424
1425 def connect(self, addr):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001426 """
1427 Connect to remote host and set up client-side SSL
1428
1429 :param addr: A remote address
1430 :return: What the socket's connect method returns
1431 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001432 _lib.SSL_set_connect_state(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001433 return self._socket.connect(addr)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001434
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001435
1436 def connect_ex(self, addr):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001437 """
1438 Connect to remote host and set up client-side SSL. Note that if the socket's
1439 connect_ex method doesn't return 0, SSL won't be initialized.
1440
1441 :param addr: A remove address
1442 :return: What the socket's connect_ex method returns
1443 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001444 connect_ex = self._socket.connect_ex
1445 self.set_connect_state()
1446 return connect_ex(addr)
1447
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001448
1449 def accept(self):
1450 """
1451 Accept incoming connection and set up SSL on it
1452
1453 :return: A (conn,addr) pair where conn is a Connection and addr is an
1454 address
1455 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001456 client, addr = self._socket.accept()
1457 conn = Connection(self._context, client)
1458 conn.set_accept_state()
1459 return (conn, addr)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001460
1461
1462 def bio_shutdown(self):
1463 """
1464 When using non-socket connections this function signals end of
1465 data on the input for this connection.
1466
1467 :return: None
1468 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001469 if self._from_ssl is None:
1470 raise TypeError("Connection sock was not None")
1471
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001472 _lib.BIO_set_mem_eof_return(self._into_ssl, 0)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001473
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001474
1475 def shutdown(self):
1476 """
1477 Send closure alert
1478
1479 :return: True if the shutdown completed successfully (i.e. both sides
1480 have sent closure alerts), false otherwise (i.e. you have to
1481 wait for a ZeroReturnError on a recv() method call
1482 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001483 result = _lib.SSL_shutdown(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001484 if result < 0:
Paul Aurichbff1d1a2015-01-08 08:36:53 -08001485 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001486 elif result > 0:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001487 return True
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001488 else:
1489 return False
1490
1491
1492 def get_cipher_list(self):
1493 """
1494 Get the session cipher list
1495
1496 :return: A list of cipher strings
1497 """
1498 ciphers = []
1499 for i in count():
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001500 result = _lib.SSL_get_cipher_list(self._ssl, i)
1501 if result == _ffi.NULL:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001502 break
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001503 ciphers.append(_native(_ffi.string(result)))
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001504 return ciphers
1505
1506
1507 def get_client_ca_list(self):
1508 """
1509 Get CAs whose certificates are suggested for client authentication.
1510
1511 :return: If this is a server connection, a list of X509Names representing
1512 the acceptable CAs as set by :py:meth:`OpenSSL.SSL.Context.set_client_ca_list` or
1513 :py:meth:`OpenSSL.SSL.Context.add_client_ca`. If this is a client connection,
1514 the list of such X509Names sent by the server, or an empty list if that
1515 has not yet happened.
1516 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001517 ca_names = _lib.SSL_get_client_CA_list(self._ssl)
1518 if ca_names == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001519 # TODO: This is untested.
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001520 return []
1521
1522 result = []
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001523 for i in range(_lib.sk_X509_NAME_num(ca_names)):
1524 name = _lib.sk_X509_NAME_value(ca_names, i)
1525 copy = _lib.X509_NAME_dup(name)
1526 if copy == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001527 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001528 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001529
1530 pyname = X509Name.__new__(X509Name)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001531 pyname._name = _ffi.gc(copy, _lib.X509_NAME_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001532 result.append(pyname)
1533 return result
1534
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001535
1536 def makefile(self):
1537 """
1538 The makefile() method is not implemented, since there is no dup semantics
1539 for SSL connections
1540
Jean-Paul Calderone6749ec22014-04-17 16:30:21 -04001541 :raise: NotImplementedError
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001542 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001543 raise NotImplementedError("Cannot make file object of OpenSSL.SSL.Connection")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001544
1545
1546 def get_app_data(self):
1547 """
1548 Get application data
1549
1550 :return: The application data
1551 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001552 return self._app_data
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001553
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001554
1555 def set_app_data(self, data):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001556 """
1557 Set application data
1558
1559 :param data - The application data
1560 :return: None
1561 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001562 self._app_data = data
1563
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001564
1565 def get_shutdown(self):
1566 """
1567 Get shutdown state
1568
1569 :return: The shutdown state, a bitvector of SENT_SHUTDOWN, RECEIVED_SHUTDOWN.
1570 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001571 return _lib.SSL_get_shutdown(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001572
1573
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001574 def set_shutdown(self, state):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001575 """
1576 Set shutdown state
1577
1578 :param state - bitvector of SENT_SHUTDOWN, RECEIVED_SHUTDOWN.
1579 :return: None
1580 """
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -05001581 if not isinstance(state, integer_types):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001582 raise TypeError("state must be an integer")
1583
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001584 _lib.SSL_set_shutdown(self._ssl, state)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001585
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001586
1587 def state_string(self):
1588 """
1589 Get a verbose state description
1590
1591 :return: A string representing the state
1592 """
1593
1594 def server_random(self):
1595 """
1596 Get a copy of the server hello nonce.
1597
1598 :return: A string representing the state
1599 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001600 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001601 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001602 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001603 self._ssl.s3.server_random,
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001604 _lib.SSL3_RANDOM_SIZE)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001605
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001606
1607 def client_random(self):
1608 """
1609 Get a copy of the client hello nonce.
1610
1611 :return: A string representing the state
1612 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001613 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001614 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001615 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001616 self._ssl.s3.client_random,
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001617 _lib.SSL3_RANDOM_SIZE)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001618
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001619
1620 def master_key(self):
1621 """
1622 Get a copy of the master key.
1623
1624 :return: A string representing the state
1625 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001626 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001627 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001628 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001629 self._ssl.session.master_key,
1630 self._ssl.session.master_key_length)[:]
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001631
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001632
1633 def sock_shutdown(self, *args, **kwargs):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001634 """
1635 See shutdown(2)
1636
1637 :return: What the socket's shutdown() method returns
1638 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001639 return self._socket.shutdown(*args, **kwargs)
1640
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001641
1642 def get_peer_certificate(self):
1643 """
1644 Retrieve the other side's certificate (if any)
1645
1646 :return: The peer's certificate
1647 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001648 cert = _lib.SSL_get_peer_certificate(self._ssl)
1649 if cert != _ffi.NULL:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001650 pycert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001651 pycert._x509 = _ffi.gc(cert, _lib.X509_free)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001652 return pycert
1653 return None
1654
1655
1656 def get_peer_cert_chain(self):
1657 """
1658 Retrieve the other side's certificate (if any)
1659
1660 :return: A list of X509 instances giving the peer's certificate chain,
1661 or None if it does not have one.
1662 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001663 cert_stack = _lib.SSL_get_peer_cert_chain(self._ssl)
1664 if cert_stack == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001665 return None
1666
1667 result = []
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001668 for i in range(_lib.sk_X509_num(cert_stack)):
Jean-Paul Calderone73b15c22013-03-05 18:30:39 -08001669 # TODO could incref instead of dup here
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001670 cert = _lib.X509_dup(_lib.sk_X509_value(cert_stack, i))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001671 pycert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001672 pycert._x509 = _ffi.gc(cert, _lib.X509_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001673 result.append(pycert)
1674 return result
1675
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001676
1677 def want_read(self):
1678 """
1679 Checks if more data has to be read from the transport layer to complete an
1680 operation.
1681
1682 :return: True iff more data has to be read
1683 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001684 return _lib.SSL_want_read(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001685
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001686
1687 def want_write(self):
1688 """
1689 Checks if there is data to write to the transport layer to complete an
1690 operation.
1691
1692 :return: True iff there is data to write
1693 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001694 return _lib.SSL_want_write(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001695
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001696
1697 def set_accept_state(self):
1698 """
1699 Set the connection to work in server mode. The handshake will be handled
1700 automatically by read/write.
1701
1702 :return: None
1703 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001704 _lib.SSL_set_accept_state(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001705
1706
1707 def set_connect_state(self):
1708 """
1709 Set the connection to work in client mode. The handshake will be handled
1710 automatically by read/write.
1711
1712 :return: None
1713 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001714 _lib.SSL_set_connect_state(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001715
1716
1717 def get_session(self):
1718 """
1719 Returns the Session currently used.
1720
1721 @return: An instance of :py:class:`OpenSSL.SSL.Session` or :py:obj:`None` if
1722 no session exists.
1723 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001724 session = _lib.SSL_get1_session(self._ssl)
1725 if session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001726 return None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001727
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001728 pysession = Session.__new__(Session)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001729 pysession._session = _ffi.gc(session, _lib.SSL_SESSION_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001730 return pysession
1731
1732
1733 def set_session(self, session):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001734 """
1735 Set the session to be used when the TLS/SSL connection is established.
1736
1737 :param session: A Session instance representing the session to use.
1738 :returns: None
1739 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001740 if not isinstance(session, Session):
1741 raise TypeError("session must be a Session instance")
1742
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001743 result = _lib.SSL_set_session(self._ssl, session._session)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001744 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001745 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001746
Jean-Paul Calderonedbd76272014-03-29 18:09:40 -04001747
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001748 def _get_finished_message(self, function):
1749 """
1750 Helper to implement :py:meth:`get_finished` and
1751 :py:meth:`get_peer_finished`.
1752
1753 :param function: Either :py:data:`SSL_get_finished`: or
1754 :py:data:`SSL_get_peer_finished`.
1755
1756 :return: :py:data:`None` if the desired message has not yet been
1757 received, otherwise the contents of the message.
1758 :rtype: :py:class:`bytes` or :py:class:`NoneType`
1759 """
Jean-Paul Calderone01af9042014-03-30 11:40:42 -04001760 # The OpenSSL documentation says nothing about what might happen if the
1761 # count argument given is zero. Specifically, it doesn't say whether
1762 # the output buffer may be NULL in that case or not. Inspection of the
1763 # implementation reveals that it calls memcpy() unconditionally.
1764 # Section 7.1.4, paragraph 1 of the C standard suggests that
1765 # memcpy(NULL, source, 0) is not guaranteed to produce defined (let
1766 # alone desirable) behavior (though it probably does on just about
1767 # every implementation...)
1768 #
1769 # Allocate a tiny buffer to pass in (instead of just passing NULL as
1770 # one might expect) for the initial call so as to be safe against this
1771 # potentially undefined behavior.
1772 empty = _ffi.new("char[]", 0)
1773 size = function(self._ssl, empty, 0)
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001774 if size == 0:
1775 # No Finished message so far.
1776 return None
1777
1778 buf = _ffi.new("char[]", size)
1779 function(self._ssl, buf, size)
1780 return _ffi.buffer(buf, size)[:]
1781
1782
Fedor Brunner5747b932014-03-05 14:22:34 +01001783 def get_finished(self):
1784 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001785 Obtain the latest `handshake finished` message sent to the peer.
Fedor Brunner5747b932014-03-05 14:22:34 +01001786
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001787 :return: The contents of the message or :py:obj:`None` if the TLS
1788 handshake has not yet completed.
1789 :rtype: :py:class:`bytes` or :py:class:`NoneType`
Fedor Brunner5747b932014-03-05 14:22:34 +01001790 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001791 return self._get_finished_message(_lib.SSL_get_finished)
1792
Fedor Brunner5747b932014-03-05 14:22:34 +01001793
1794 def get_peer_finished(self):
1795 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001796 Obtain the latest `handshake finished` message received from the peer.
Fedor Brunner5747b932014-03-05 14:22:34 +01001797
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001798 :return: The contents of the message or :py:obj:`None` if the TLS
1799 handshake has not yet completed.
1800 :rtype: :py:class:`bytes` or :py:class:`NoneType`
Fedor Brunner5747b932014-03-05 14:22:34 +01001801 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001802 return self._get_finished_message(_lib.SSL_get_peer_finished)
Fedor Brunner5747b932014-03-05 14:22:34 +01001803
Jean-Paul Calderone7c556ef2014-03-30 10:45:00 -04001804
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001805 def get_cipher_name(self):
1806 """
1807 Obtain the name of the currently used cipher.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001808
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001809 :returns: The name of the currently used cipher or :py:obj:`None`
1810 if no connection has been established.
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001811 :rtype: :py:class:`unicode` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001812 """
1813 cipher = _lib.SSL_get_current_cipher(self._ssl)
1814 if cipher == _ffi.NULL:
1815 return None
1816 else:
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001817 name = _ffi.string(_lib.SSL_CIPHER_get_name(cipher))
1818 return name.decode("utf-8")
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001819
Jean-Paul Calderonedbd76272014-03-29 18:09:40 -04001820
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001821 def get_cipher_bits(self):
1822 """
1823 Obtain the number of secret bits of the currently used cipher.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001824
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001825 :returns: The number of secret bits of the currently used cipher
1826 or :py:obj:`None` if no connection has been established.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001827 :rtype: :py:class:`int` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001828 """
1829 cipher = _lib.SSL_get_current_cipher(self._ssl)
1830 if cipher == _ffi.NULL:
1831 return None
1832 else:
1833 return _lib.SSL_CIPHER_get_bits(cipher, _ffi.NULL)
1834
Jean-Paul Calderonedbd76272014-03-29 18:09:40 -04001835
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001836 def get_cipher_version(self):
1837 """
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001838 Obtain the protocol version of the currently used cipher.
1839
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001840 :returns: The protocol name of the currently used cipher
1841 or :py:obj:`None` if no connection has been established.
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001842 :rtype: :py:class:`unicode` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001843 """
1844 cipher = _lib.SSL_get_current_cipher(self._ssl)
1845 if cipher == _ffi.NULL:
1846 return None
1847 else:
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001848 version =_ffi.string(_lib.SSL_CIPHER_get_version(cipher))
1849 return version.decode("utf-8")
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001850
Cory Benfield84a121e2014-03-31 20:30:25 +01001851 def get_next_proto_negotiated(self):
1852 """
1853 Get the protocol that was negotiated by NPN.
1854 """
1855 data = _ffi.new("unsigned char **")
1856 data_len = _ffi.new("unsigned int *")
1857
1858 _lib.SSL_get0_next_proto_negotiated(self._ssl, data, data_len)
1859
Cory Benfieldcd010f62014-05-15 19:00:27 +01001860 return _ffi.buffer(data[0], data_len[0])[:]
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001861
Cory Benfield12eae892014-06-07 15:42:56 +01001862 def set_alpn_protos(self, protos):
1863 """
Cory Benfielde8e9c382015-04-11 17:33:48 -04001864 Specify the client's ALPN protocol list.
1865
1866 These protocols are offered to the server during protocol negotiation.
Cory Benfield12eae892014-06-07 15:42:56 +01001867
1868 :param protos: A list of the protocols to be offered to the server.
1869 This list should be a Python list of bytestrings representing the
1870 protocols to offer, e.g. ``[b'http/1.1', b'spdy/2']``.
1871 """
Cory Benfield3e619292015-04-13 12:34:51 -04001872 if not _lib.Cryptography_HAS_ALPN:
1873 raise NotImplementedError("ALPN not available")
1874
Cory Benfield12eae892014-06-07 15:42:56 +01001875 # Take the list of protocols and join them together, prefixing them
1876 # with their lengths.
1877 protostr = b''.join(
1878 chain.from_iterable((int2byte(len(p)), p) for p in protos)
1879 )
1880
1881 # Build a C string from the list. We don't need to save this off
1882 # because OpenSSL immediately copies the data out.
1883 input_str = _ffi.new("unsigned char[]", protostr)
Cory Benfield9c1979a2015-04-12 08:51:52 -04001884 input_str_len = _ffi.cast("unsigned", len(protostr))
1885 _lib.SSL_set_alpn_protos(self._ssl, input_str, input_str_len)
Cory Benfield12eae892014-06-07 15:42:56 +01001886
1887
1888 def get_alpn_proto_negotiated(self):
Cory Benfielde8e9c382015-04-11 17:33:48 -04001889 """Get the protocol that was negotiated by ALPN."""
Cory Benfield3e619292015-04-13 12:34:51 -04001890 if not _lib.Cryptography_HAS_ALPN:
1891 raise NotImplementedError("ALPN not available")
1892
Cory Benfield12eae892014-06-07 15:42:56 +01001893 data = _ffi.new("unsigned char **")
1894 data_len = _ffi.new("unsigned int *")
1895
1896 _lib.SSL_get0_alpn_selected(self._ssl, data, data_len)
1897
Cory Benfielde8e9c382015-04-11 17:33:48 -04001898 if not data_len:
1899 return b''
1900
Cory Benfield12eae892014-06-07 15:42:56 +01001901 return _ffi.buffer(data[0], data_len[0])[:]
1902
1903
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001904
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001905ConnectionType = Connection
Jean-Paul Calderone11ed8e82014-01-18 10:21:50 -05001906
Jean-Paul Calderonefab157b2014-01-18 11:21:38 -05001907# This is similar to the initialization calls at the end of OpenSSL/crypto.py
1908# but is exercised mostly by the Context initializer.
Jean-Paul Calderone11ed8e82014-01-18 10:21:50 -05001909_lib.SSL_library_init()