blob: 85cf976dff1589d359d6eee8cd669441bfea4fc6 [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,
Jean-Paul Calderone39a8d592015-04-13 20:49:50 -040017 text_to_bytes_and_warn as _text_to_bytes_and_warn,
Jean-Paul Calderone55f9e882015-04-12 09:31:03 -040018 path_string as _path_string,
Jean-Paul Calderone00f84eb2015-04-13 12:47:21 -040019 UNSPECIFIED as _UNSPECIFIED,
Jean-Paul Calderone55f9e882015-04-12 09:31:03 -040020)
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080021
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -080022from OpenSSL.crypto import (
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -050023 FILETYPE_PEM, _PassphraseHelper, PKey, X509Name, X509, X509Store)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -080024
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 Benfield9da5ffb2015-04-13 17:20:14 -0400322class _ALPNSelectHelper(_CallbackExceptionHelper):
Cory Benfieldf1177e72015-04-12 09:11:49 -0400323 """
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:
Cory Benfield93134db2015-04-13 17:22:13 -0400340 encoded_len = indexbytes(instr, 0)
341 proto = instr[1:encoded_len + 1]
Cory Benfieldf1177e72015-04-12 09:11:49 -0400342 protolist.append(proto)
Cory Benfield93134db2015-04-13 17:22:13 -0400343 instr = instr[encoded_len + 1:]
Cory Benfieldf1177e72015-04-12 09:11:49 -0400344
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
Cory Benfield10b277f2015-04-13 17:12:42 -0400401def _requires_npn(func):
Cory Benfielda876cef2015-04-13 17:29:12 -0400402 """
403 Wraps any function that requires NPN support in OpenSSL, ensuring that
404 NotImplementedError is raised if NPN is not present.
405 """
Cory Benfield10b277f2015-04-13 17:12:42 -0400406 @wraps(func)
407 def wrapper(*args, **kwargs):
408 if not _lib.Cryptography_HAS_NEXTPROTONEG:
409 raise NotImplementedError("NPN not available.")
410
411 return func(*args, **kwargs)
412
413 return wrapper
414
415
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800416
Cory Benfield7907e332015-04-13 17:18:25 -0400417def _requires_alpn(func):
Cory Benfield9d80a762015-04-13 17:47:33 -0400418 """
419 Wraps any function that requires ALPN support in OpenSSL, ensuring that
420 NotImplementedError is raised if ALPN support is not present.
421 """
Cory Benfield7907e332015-04-13 17:18:25 -0400422 @wraps(func)
423 def wrapper(*args, **kwargs):
424 if not _lib.Cryptography_HAS_ALPN:
425 raise NotImplementedError("ALPN not available.")
426
427 return func(*args, **kwargs)
428
429 return wrapper
430
431
432
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800433class Session(object):
434 pass
435
436
437
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800438class Context(object):
439 """
440 :py:obj:`OpenSSL.SSL.Context` instances define the parameters for setting up
441 new SSL connections.
442 """
443 _methods = {
Andrew Dunhamec84a0a2014-02-24 12:41:37 -0800444 SSLv2_METHOD: "SSLv2_method",
Jean-Paul Calderonebe2bb422013-12-29 07:34:08 -0500445 SSLv3_METHOD: "SSLv3_method",
446 SSLv23_METHOD: "SSLv23_method",
447 TLSv1_METHOD: "TLSv1_method",
448 TLSv1_1_METHOD: "TLSv1_1_method",
449 TLSv1_2_METHOD: "TLSv1_2_method",
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800450 }
Jean-Paul Calderonebe2bb422013-12-29 07:34:08 -0500451 _methods = dict(
452 (identifier, getattr(_lib, name))
453 for (identifier, name) in _methods.items()
454 if getattr(_lib, name, None) is not None)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800455
Jean-Paul Calderone63157872013-03-20 16:43:38 -0700456
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800457 def __init__(self, method):
458 """
459 :param method: One of SSLv2_METHOD, SSLv3_METHOD, SSLv23_METHOD, or
460 TLSv1_METHOD.
461 """
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -0500462 if not isinstance(method, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800463 raise TypeError("method must be an integer")
464
465 try:
466 method_func = self._methods[method]
467 except KeyError:
468 raise ValueError("No such protocol")
469
470 method_obj = method_func()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500471 if method_obj == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500472 # TODO: This is untested.
473 _raise_current_error()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800474
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500475 context = _lib.SSL_CTX_new(method_obj)
476 if context == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500477 # TODO: This is untested.
478 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500479 context = _ffi.gc(context, _lib.SSL_CTX_free)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800480
481 self._context = context
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800482 self._passphrase_helper = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800483 self._passphrase_callback = None
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800484 self._passphrase_userdata = None
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800485 self._verify_helper = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800486 self._verify_callback = None
487 self._info_callback = None
488 self._tlsext_servername_callback = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800489 self._app_data = None
Cory Benfield0ea76e72015-03-22 09:05:28 +0000490 self._npn_advertise_helper = None
Cory Benfield84a121e2014-03-31 20:30:25 +0100491 self._npn_advertise_callback = None
Cory Benfield0ea76e72015-03-22 09:05:28 +0000492 self._npn_select_helper = None
Cory Benfield84a121e2014-03-31 20:30:25 +0100493 self._npn_select_callback = None
Cory Benfieldf1177e72015-04-12 09:11:49 -0400494 self._alpn_select_helper = None
Cory Benfield12eae892014-06-07 15:42:56 +0100495 self._alpn_select_callback = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800496
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -0800497 # SSL_CTX_set_app_data(self->ctx, self);
498 # SSL_CTX_set_mode(self->ctx, SSL_MODE_ENABLE_PARTIAL_WRITE |
499 # SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
500 # SSL_MODE_AUTO_RETRY);
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500501 self.set_mode(_lib.SSL_MODE_ENABLE_PARTIAL_WRITE)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800502
503
504 def load_verify_locations(self, cafile, capath=None):
505 """
506 Let SSL know where we can find trusted certificates for the certificate
507 chain
508
Jean-Paul Calderone55f9e882015-04-12 09:31:03 -0400509 :param cafile: In which file we can find the certificates (``bytes`` or
510 ``unicode``).
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800511 :param capath: In which directory we can find the certificates
Jean-Paul Calderone55f9e882015-04-12 09:31:03 -0400512 (``bytes`` or ``unicode``).
513
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800514 :return: None
515 """
516 if cafile is None:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500517 cafile = _ffi.NULL
Jean-Paul Calderone55f9e882015-04-12 09:31:03 -0400518 else:
519 cafile = _path_string(cafile)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800520
521 if capath is None:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500522 capath = _ffi.NULL
Jean-Paul Calderone55f9e882015-04-12 09:31:03 -0400523 else:
524 capath = _path_string(capath)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800525
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500526 load_result = _lib.SSL_CTX_load_verify_locations(self._context, cafile, capath)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800527 if not load_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500528 _raise_current_error()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800529
530
531 def _wrap_callback(self, callback):
532 @wraps(callback)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800533 def wrapper(size, verify, userdata):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800534 return callback(size, verify, self._passphrase_userdata)
535 return _PassphraseHelper(
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800536 FILETYPE_PEM, wrapper, more_args=True, truncate=True)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800537
538
539 def set_passwd_cb(self, callback, userdata=None):
540 """
541 Set the passphrase callback
542
543 :param callback: The Python callback to use
544 :param userdata: (optional) A Python object which will be given as
545 argument to the callback
546 :return: None
547 """
548 if not callable(callback):
549 raise TypeError("callback must be callable")
550
551 self._passphrase_helper = self._wrap_callback(callback)
552 self._passphrase_callback = self._passphrase_helper.callback
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500553 _lib.SSL_CTX_set_default_passwd_cb(
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800554 self._context, self._passphrase_callback)
555 self._passphrase_userdata = userdata
556
557
558 def set_default_verify_paths(self):
559 """
560 Use the platform-specific CA certificate locations
561
562 :return: None
563 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500564 set_result = _lib.SSL_CTX_set_default_verify_paths(self._context)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800565 if not set_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500566 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500567 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800568
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800569
570 def use_certificate_chain_file(self, certfile):
571 """
572 Load a certificate chain from a file
573
Jean-Paul Calderoneb6f8a792015-04-13 10:10:06 -0400574 :param certfile: The name of the certificate chain file (``bytes`` or
575 ``unicode``).
576
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800577 :return: None
578 """
Jean-Paul Calderoneaac43a32015-04-12 09:51:21 -0400579 certfile = _path_string(certfile)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800580
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500581 result = _lib.SSL_CTX_use_certificate_chain_file(self._context, certfile)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800582 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500583 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800584
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800585
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800586 def use_certificate_file(self, certfile, filetype=FILETYPE_PEM):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800587 """
588 Load a certificate from a file
589
Jean-Paul Calderoneb6f8a792015-04-13 10:10:06 -0400590 :param certfile: The name of the certificate file (``bytes`` or
591 ``unicode``).
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800592 :param filetype: (optional) The encoding of the file, default is PEM
Jean-Paul Calderoneb6f8a792015-04-13 10:10:06 -0400593
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800594 :return: None
595 """
Jean-Paul Calderoned57a7b62015-04-12 09:57:36 -0400596 certfile = _path_string(certfile)
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -0500597 if not isinstance(filetype, integer_types):
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800598 raise TypeError("filetype must be an integer")
599
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500600 use_result = _lib.SSL_CTX_use_certificate_file(self._context, certfile, filetype)
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800601 if not use_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500602 _raise_current_error()
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800603
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800604
605 def use_certificate(self, cert):
606 """
607 Load a certificate from a X509 object
608
609 :param cert: The X509 object
610 :return: None
611 """
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800612 if not isinstance(cert, X509):
613 raise TypeError("cert must be an X509 instance")
614
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500615 use_result = _lib.SSL_CTX_use_certificate(self._context, cert._x509)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800616 if not use_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500617 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800618
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800619
620 def add_extra_chain_cert(self, certobj):
621 """
622 Add certificate to chain
623
624 :param certobj: The X509 certificate object to add to the chain
625 :return: None
626 """
627 if not isinstance(certobj, X509):
628 raise TypeError("certobj must be an X509 instance")
629
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500630 copy = _lib.X509_dup(certobj._x509)
631 add_result = _lib.SSL_CTX_add_extra_chain_cert(self._context, copy)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800632 if not add_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500633 # TODO: This is untested.
634 _lib.X509_free(copy)
635 _raise_current_error()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800636
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800637
638 def _raise_passphrase_exception(self):
639 if self._passphrase_helper is None:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500640 _raise_current_error()
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800641 exception = self._passphrase_helper.raise_if_problem(Error)
642 if exception is not None:
643 raise exception
644
645
Jean-Paul Calderone00f84eb2015-04-13 12:47:21 -0400646 def use_privatekey_file(self, keyfile, filetype=_UNSPECIFIED):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800647 """
648 Load a private key from a file
649
Jean-Paul Calderoneb6f8a792015-04-13 10:10:06 -0400650 :param keyfile: The name of the key file (``bytes`` or ``unicode``)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800651 :param filetype: (optional) The encoding of the file, default is PEM
Jean-Paul Calderoneb6f8a792015-04-13 10:10:06 -0400652
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800653 :return: None
654 """
Jean-Paul Calderone69a4e5b2015-04-12 10:04:28 -0400655 keyfile = _path_string(keyfile)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800656
Jean-Paul Calderone00f84eb2015-04-13 12:47:21 -0400657 if filetype is _UNSPECIFIED:
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800658 filetype = FILETYPE_PEM
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -0500659 elif not isinstance(filetype, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800660 raise TypeError("filetype must be an integer")
661
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500662 use_result = _lib.SSL_CTX_use_PrivateKey_file(
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800663 self._context, keyfile, filetype)
664 if not use_result:
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800665 self._raise_passphrase_exception()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800666
667
668 def use_privatekey(self, pkey):
669 """
670 Load a private key from a PKey object
671
672 :param pkey: The PKey object
673 :return: None
674 """
675 if not isinstance(pkey, PKey):
676 raise TypeError("pkey must be a PKey instance")
677
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500678 use_result = _lib.SSL_CTX_use_PrivateKey(self._context, pkey._pkey)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800679 if not use_result:
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800680 self._raise_passphrase_exception()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800681
682
683 def check_privatekey(self):
684 """
685 Check that the private key and certificate match up
686
687 :return: None (raises an exception if something's wrong)
688 """
Jean-Paul Calderonea0344922014-12-11 14:02:31 -0500689 if not _lib.SSL_CTX_check_private_key(self._context):
690 _raise_current_error()
691
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800692
693 def load_client_ca(self, cafile):
694 """
695 Load the trusted certificates that will be sent to the client (basically
696 telling the client "These are the guys I trust"). Does not actually
697 imply any of the certificates are trusted; that must be configured
698 separately.
699
700 :param cafile: The name of the certificates file
701 :return: None
702 """
703
704 def set_session_id(self, buf):
705 """
706 Set the session identifier. This is needed if you want to do session
707 resumption.
708
709 :param buf: A Python object that can be safely converted to a string
710 :returns: None
711 """
712
713 def set_session_cache_mode(self, mode):
714 """
715 Enable/disable session caching and specify the mode used.
716
717 :param mode: One or more of the SESS_CACHE_* flags (combine using
718 bitwise or)
719 :returns: The previously set caching mode.
720 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500721 if not isinstance(mode, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800722 raise TypeError("mode must be an integer")
723
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500724 return _lib.SSL_CTX_set_session_cache_mode(self._context, mode)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800725
726
727 def get_session_cache_mode(self):
728 """
729 :returns: The currently used cache mode.
730 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500731 return _lib.SSL_CTX_get_session_cache_mode(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800732
733
734 def set_verify(self, mode, callback):
735 """
736 Set the verify mode and verify callback
737
738 :param mode: The verify mode, this is either VERIFY_NONE or
739 VERIFY_PEER combined with possible other flags
740 :param callback: The Python callback to use
741 :return: None
742
743 See SSL_CTX_set_verify(3SSL) for further details.
744 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500745 if not isinstance(mode, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800746 raise TypeError("mode must be an integer")
747
748 if not callable(callback):
749 raise TypeError("callback must be callable")
750
Jean-Paul Calderone6a8cd112014-04-02 21:09:08 -0400751 self._verify_helper = _VerifyHelper(callback)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800752 self._verify_callback = self._verify_helper.callback
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500753 _lib.SSL_CTX_set_verify(self._context, mode, self._verify_callback)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800754
755
756 def set_verify_depth(self, depth):
757 """
758 Set the verify depth
759
760 :param depth: An integer specifying the verify depth
761 :return: None
762 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500763 if not isinstance(depth, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800764 raise TypeError("depth must be an integer")
765
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500766 _lib.SSL_CTX_set_verify_depth(self._context, depth)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800767
768
769 def get_verify_mode(self):
770 """
771 Get the verify mode
772
773 :return: The verify mode
774 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500775 return _lib.SSL_CTX_get_verify_mode(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800776
777
778 def get_verify_depth(self):
779 """
780 Get the verify depth
781
782 :return: The verify depth
783 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500784 return _lib.SSL_CTX_get_verify_depth(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800785
786
787 def load_tmp_dh(self, dhfile):
788 """
789 Load parameters for Ephemeral Diffie-Hellman
790
Jean-Paul Calderone4e0c43f2015-04-13 10:15:17 -0400791 :param dhfile: The file to load EDH parameters from (``bytes`` or
792 ``unicode``).
793
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800794 :return: None
795 """
Jean-Paul Calderone9e1c1dd2015-04-12 10:13:13 -0400796 dhfile = _path_string(dhfile)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800797
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -0500798 bio = _lib.BIO_new_file(dhfile, b"r")
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500799 if bio == _ffi.NULL:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500800 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500801 bio = _ffi.gc(bio, _lib.BIO_free)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800802
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500803 dh = _lib.PEM_read_bio_DHparams(bio, _ffi.NULL, _ffi.NULL, _ffi.NULL)
804 dh = _ffi.gc(dh, _lib.DH_free)
805 _lib.SSL_CTX_set_tmp_dh(self._context, dh)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800806
807
Jean-Paul Calderone3e4e3352014-04-19 09:28:28 -0400808 def set_tmp_ecdh(self, curve):
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600809 """
Andy Lutomirski76a61332014-03-12 15:02:56 -0700810 Select a curve to use for ECDHE key exchange.
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600811
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -0400812 :param curve: A curve object to use as returned by either
813 :py:meth:`OpenSSL.crypto.get_elliptic_curve` or
814 :py:meth:`OpenSSL.crypto.get_elliptic_curves`.
Andy Lutomirskif05a2732014-03-13 17:22:25 -0700815
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600816 :return: None
817 """
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -0400818 _lib.SSL_CTX_set_tmp_ecdh(self._context, curve._to_EC_KEY())
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600819
820
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800821 def set_cipher_list(self, cipher_list):
822 """
823 Change the cipher list
824
825 :param cipher_list: A cipher list, see ciphers(1)
826 :return: None
827 """
Jean-Paul Calderone63eab692014-01-18 10:19:56 -0500828 if isinstance(cipher_list, _text_type):
829 cipher_list = cipher_list.encode("ascii")
830
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800831 if not isinstance(cipher_list, bytes):
Jean-Paul Calderone63eab692014-01-18 10:19:56 -0500832 raise TypeError("cipher_list must be bytes or unicode")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800833
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500834 result = _lib.SSL_CTX_set_cipher_list(self._context, cipher_list)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800835 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500836 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800837
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800838
839 def set_client_ca_list(self, certificate_authorities):
840 """
841 Set the list of preferred client certificate signers for this server context.
842
843 This list of certificate authorities will be sent to the client when the
844 server requests a client certificate.
845
846 :param certificate_authorities: a sequence of X509Names.
847 :return: None
848 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500849 name_stack = _lib.sk_X509_NAME_new_null()
850 if name_stack == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500851 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500852 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800853
854 try:
855 for ca_name in certificate_authorities:
856 if not isinstance(ca_name, X509Name):
857 raise TypeError(
858 "client CAs must be X509Name objects, not %s objects" % (
859 type(ca_name).__name__,))
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500860 copy = _lib.X509_NAME_dup(ca_name._name)
861 if copy == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500862 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500863 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500864 push_result = _lib.sk_X509_NAME_push(name_stack, copy)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800865 if not push_result:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500866 _lib.X509_NAME_free(copy)
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500867 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800868 except:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500869 _lib.sk_X509_NAME_free(name_stack)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800870 raise
871
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500872 _lib.SSL_CTX_set_client_CA_list(self._context, name_stack)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800873
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800874
875 def add_client_ca(self, certificate_authority):
876 """
877 Add the CA certificate to the list of preferred signers for this context.
878
879 The list of certificate authorities will be sent to the client when the
880 server requests a client certificate.
881
882 :param certificate_authority: certificate authority's X509 certificate.
883 :return: None
884 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800885 if not isinstance(certificate_authority, X509):
886 raise TypeError("certificate_authority must be an X509 instance")
887
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500888 add_result = _lib.SSL_CTX_add_client_CA(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800889 self._context, certificate_authority._x509)
890 if not add_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500891 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500892 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800893
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800894
895 def set_timeout(self, timeout):
896 """
897 Set session timeout
898
899 :param timeout: The timeout in seconds
900 :return: The previous session timeout
901 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500902 if not isinstance(timeout, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800903 raise TypeError("timeout must be an integer")
904
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500905 return _lib.SSL_CTX_set_timeout(self._context, timeout)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800906
907
908 def get_timeout(self):
909 """
910 Get the session timeout
911
912 :return: The session timeout
913 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500914 return _lib.SSL_CTX_get_timeout(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800915
916
917 def set_info_callback(self, callback):
918 """
919 Set the info callback
920
921 :param callback: The Python callback to use
922 :return: None
923 """
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800924 @wraps(callback)
925 def wrapper(ssl, where, return_code):
Jean-Paul Calderonef2bbc9c2014-02-02 10:59:14 -0500926 callback(Connection._reverse_mapping[ssl], where, return_code)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500927 self._info_callback = _ffi.callback(
928 "void (*)(const SSL *, int, int)", wrapper)
929 _lib.SSL_CTX_set_info_callback(self._context, self._info_callback)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800930
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800931
932 def get_app_data(self):
933 """
934 Get the application data (supplied via set_app_data())
935
936 :return: The application data
937 """
938 return self._app_data
939
940
941 def set_app_data(self, data):
942 """
943 Set the application data (will be returned from get_app_data())
944
945 :param data: Any Python object
946 :return: None
947 """
948 self._app_data = data
949
950
951 def get_cert_store(self):
952 """
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500953 Get the certificate store for the context.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800954
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500955 :return: A X509Store object or None if it does not have one.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800956 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500957 store = _lib.SSL_CTX_get_cert_store(self._context)
958 if store == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500959 # TODO: This is untested.
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800960 return None
961
962 pystore = X509Store.__new__(X509Store)
963 pystore._store = store
964 return pystore
965
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800966
967 def set_options(self, options):
968 """
969 Add options. Options set before are not cleared!
970
971 :param options: The options to add.
972 :return: The new option bitmask.
973 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500974 if not isinstance(options, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800975 raise TypeError("options must be an integer")
976
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500977 return _lib.SSL_CTX_set_options(self._context, options)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800978
979
980 def set_mode(self, mode):
981 """
982 Add modes via bitmask. Modes set before are not cleared!
983
984 :param mode: The mode to add.
985 :return: The new mode bitmask.
986 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500987 if not isinstance(mode, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800988 raise TypeError("mode must be an integer")
989
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500990 return _lib.SSL_CTX_set_mode(self._context, mode)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800991
992
993 def set_tlsext_servername_callback(self, callback):
994 """
995 Specify a callback function to be called when clients specify a server name.
996
997 :param callback: The callback function. It will be invoked with one
998 argument, the Connection instance.
999 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001000 @wraps(callback)
1001 def wrapper(ssl, alert, arg):
1002 callback(Connection._reverse_mapping[ssl])
1003 return 0
1004
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001005 self._tlsext_servername_callback = _ffi.callback(
1006 "int (*)(const SSL *, int *, void *)", wrapper)
1007 _lib.SSL_CTX_set_tlsext_servername_callback(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001008 self._context, self._tlsext_servername_callback)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -08001009
Cory Benfield84a121e2014-03-31 20:30:25 +01001010
Cory Benfield10b277f2015-04-13 17:12:42 -04001011 @_requires_npn
Cory Benfield84a121e2014-03-31 20:30:25 +01001012 def set_npn_advertise_callback(self, callback):
1013 """
Cory Benfieldbe3e7b82014-05-10 09:48:55 +01001014 Specify a callback function that will be called when offering `Next
1015 Protocol Negotiation
1016 <https://technotes.googlecode.com/git/nextprotoneg.html>`_ as a server.
Cory Benfield84a121e2014-03-31 20:30:25 +01001017
1018 :param callback: The callback function. It will be invoked with one
Cory Benfieldbe3e7b82014-05-10 09:48:55 +01001019 argument, the Connection instance. It should return a list of
1020 bytestrings representing the advertised protocols, like
1021 ``[b'http/1.1', b'spdy/2']``.
Cory Benfield84a121e2014-03-31 20:30:25 +01001022 """
Cory Benfield0ea76e72015-03-22 09:05:28 +00001023 self._npn_advertise_helper = _NpnAdvertiseHelper(callback)
1024 self._npn_advertise_callback = self._npn_advertise_helper.callback
Cory Benfield84a121e2014-03-31 20:30:25 +01001025 _lib.SSL_CTX_set_next_protos_advertised_cb(
1026 self._context, self._npn_advertise_callback, _ffi.NULL)
1027
1028
Cory Benfield10b277f2015-04-13 17:12:42 -04001029 @_requires_npn
Cory Benfield84a121e2014-03-31 20:30:25 +01001030 def set_npn_select_callback(self, callback):
1031 """
1032 Specify a callback function that will be called when a server offers
1033 Next Protocol Negotiation options.
1034
1035 :param callback: The callback function. It will be invoked with two
1036 arguments: the Connection, and a list of offered protocols as
Cory Benfieldbe3e7b82014-05-10 09:48:55 +01001037 bytestrings, e.g. ``[b'http/1.1', b'spdy/2']``. It should return
1038 one of those bytestrings, the chosen protocol.
Cory Benfield84a121e2014-03-31 20:30:25 +01001039 """
Cory Benfield0ea76e72015-03-22 09:05:28 +00001040 self._npn_select_helper = _NpnSelectHelper(callback)
1041 self._npn_select_callback = self._npn_select_helper.callback
Cory Benfield84a121e2014-03-31 20:30:25 +01001042 _lib.SSL_CTX_set_next_proto_select_cb(
1043 self._context, self._npn_select_callback, _ffi.NULL)
1044
Cory Benfield7907e332015-04-13 17:18:25 -04001045 @_requires_alpn
Cory Benfield12eae892014-06-07 15:42:56 +01001046 def set_alpn_protos(self, protos):
1047 """
Cory Benfielde8e9c382015-04-11 17:33:48 -04001048 Specify the clients ALPN protocol list.
1049
1050 These protocols are offered to the server during protocol negotiation.
Cory Benfield12eae892014-06-07 15:42:56 +01001051
1052 :param protos: A list of the protocols to be offered to the server.
1053 This list should be a Python list of bytestrings representing the
1054 protocols to offer, e.g. ``[b'http/1.1', b'spdy/2']``.
1055 """
1056 # Take the list of protocols and join them together, prefixing them
1057 # with their lengths.
1058 protostr = b''.join(
1059 chain.from_iterable((int2byte(len(p)), p) for p in protos)
1060 )
1061
1062 # Build a C string from the list. We don't need to save this off
1063 # because OpenSSL immediately copies the data out.
1064 input_str = _ffi.new("unsigned char[]", protostr)
Cory Benfielde871af52015-04-11 17:57:50 -04001065 input_str_len = _ffi.cast("unsigned", len(protostr))
1066 _lib.SSL_CTX_set_alpn_protos(self._context, input_str, input_str_len)
Cory Benfield12eae892014-06-07 15:42:56 +01001067
Cory Benfield7907e332015-04-13 17:18:25 -04001068 @_requires_alpn
Cory Benfield12eae892014-06-07 15:42:56 +01001069 def set_alpn_select_callback(self, callback):
1070 """
Cory Benfielde8e9c382015-04-11 17:33:48 -04001071 Set the callback to handle ALPN protocol choice.
Cory Benfield12eae892014-06-07 15:42:56 +01001072
1073 :param callback: The callback function. It will be invoked with two
1074 arguments: the Connection, and a list of offered protocols as
1075 bytestrings, e.g ``[b'http/1.1', b'spdy/2']``. It should return
Cory Benfielde8e9c382015-04-11 17:33:48 -04001076 one of those bytestrings, the chosen protocol.
Cory Benfield12eae892014-06-07 15:42:56 +01001077 """
Cory Benfield9da5ffb2015-04-13 17:20:14 -04001078 self._alpn_select_helper = _ALPNSelectHelper(callback)
Cory Benfieldf1177e72015-04-12 09:11:49 -04001079 self._alpn_select_callback = self._alpn_select_helper.callback
Cory Benfield12eae892014-06-07 15:42:56 +01001080 _lib.SSL_CTX_set_alpn_select_cb(
1081 self._context, self._alpn_select_callback, _ffi.NULL)
1082
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -08001083ContextType = Context
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001084
1085
1086
1087class Connection(object):
1088 """
1089 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001090 _reverse_mapping = WeakValueDictionary()
1091
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001092 def __init__(self, context, socket=None):
1093 """
1094 Create a new Connection object, using the given OpenSSL.SSL.Context
1095 instance and socket.
1096
1097 :param context: An SSL Context to use for this connection
1098 :param socket: The socket to use for transport layer
1099 """
1100 if not isinstance(context, Context):
1101 raise TypeError("context must be a Context instance")
1102
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001103 ssl = _lib.SSL_new(context._context)
1104 self._ssl = _ffi.gc(ssl, _lib.SSL_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001105 self._context = context
1106
Cory Benfieldbe3e7b82014-05-10 09:48:55 +01001107 # References to strings used for Next Protocol Negotiation. OpenSSL's
1108 # header files suggest that these might get copied at some point, but
1109 # doesn't specify when, so we store them here to make sure they don't
1110 # get freed before OpenSSL uses them.
1111 self._npn_advertise_callback_args = None
1112 self._npn_select_callback_args = None
1113
Cory Benfield12eae892014-06-07 15:42:56 +01001114 # References to strings used for Application Layer Protocol
1115 # Negotiation. These strings get copied at some point but it's well
1116 # after the callback returns, so we have to hang them somewhere to
1117 # avoid them getting freed.
1118 self._alpn_select_callback_args = None
1119
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001120 self._reverse_mapping[self._ssl] = self
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001121
1122 if socket is None:
1123 self._socket = None
Jean-Paul Calderone73b15c22013-03-05 18:30:39 -08001124 # Don't set up any gc for these, SSL_free will take care of them.
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001125 self._into_ssl = _lib.BIO_new(_lib.BIO_s_mem())
1126 self._from_ssl = _lib.BIO_new(_lib.BIO_s_mem())
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001127
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001128 if self._into_ssl == _ffi.NULL or self._from_ssl == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001129 # TODO: This is untested.
1130 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001131
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001132 _lib.SSL_set_bio(self._ssl, self._into_ssl, self._from_ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001133 else:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001134 self._into_ssl = None
1135 self._from_ssl = None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001136 self._socket = socket
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001137 set_result = _lib.SSL_set_fd(self._ssl, _asFileDescriptor(self._socket))
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001138 if not set_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001139 # TODO: This is untested.
1140 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001141
1142
1143 def __getattr__(self, name):
1144 """
1145 Look up attributes on the wrapped socket object if they are not found on
1146 the Connection object.
1147 """
1148 return getattr(self._socket, name)
1149
1150
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001151 def _raise_ssl_error(self, ssl, result):
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -08001152 if self._context._verify_helper is not None:
1153 self._context._verify_helper.raise_if_problem()
Cory Benfield0ea76e72015-03-22 09:05:28 +00001154 if self._context._npn_advertise_helper is not None:
1155 self._context._npn_advertise_helper.raise_if_problem()
1156 if self._context._npn_select_helper is not None:
1157 self._context._npn_select_helper.raise_if_problem()
Cory Benfieldf1177e72015-04-12 09:11:49 -04001158 if self._context._alpn_select_helper is not None:
1159 self._context._alpn_select_helper.raise_if_problem()
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -08001160
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001161 error = _lib.SSL_get_error(ssl, result)
1162 if error == _lib.SSL_ERROR_WANT_READ:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001163 raise WantReadError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001164 elif error == _lib.SSL_ERROR_WANT_WRITE:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001165 raise WantWriteError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001166 elif error == _lib.SSL_ERROR_ZERO_RETURN:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001167 raise ZeroReturnError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001168 elif error == _lib.SSL_ERROR_WANT_X509_LOOKUP:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001169 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001170 raise WantX509LookupError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001171 elif error == _lib.SSL_ERROR_SYSCALL:
1172 if _lib.ERR_peek_error() == 0:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001173 if result < 0:
Konstantinos Koukopoulos541150d2014-01-31 01:00:19 +02001174 if platform == "win32":
1175 errno = _ffi.getwinerror()[0]
1176 else:
1177 errno = _ffi.errno
Glyph3afdba82015-04-14 17:30:53 -04001178 raise SysCallError(errno, errorcode.get(errno))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001179 else:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001180 raise SysCallError(-1, "Unexpected EOF")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001181 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001182 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001183 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001184 elif error == _lib.SSL_ERROR_NONE:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001185 pass
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001186 else:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001187 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001188
1189
1190 def get_context(self):
1191 """
1192 Get session context
1193 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001194 return self._context
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001195
1196
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001197 def set_context(self, context):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001198 """
1199 Switch this connection to a new session context
1200
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001201 :param context: A :py:class:`Context` instance giving the new session
1202 context to use.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001203 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001204 if not isinstance(context, Context):
1205 raise TypeError("context must be a Context instance")
1206
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001207 _lib.SSL_set_SSL_CTX(self._ssl, context._context)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001208 self._context = context
1209
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001210
1211 def get_servername(self):
1212 """
1213 Retrieve the servername extension value if provided in the client hello
1214 message, or None if there wasn't one.
1215
1216 :return: A byte string giving the server name or :py:data:`None`.
1217 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001218 name = _lib.SSL_get_servername(self._ssl, _lib.TLSEXT_NAMETYPE_host_name)
1219 if name == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001220 return None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001221
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001222 return _ffi.string(name)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001223
1224
1225 def set_tlsext_host_name(self, name):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001226 """
1227 Set the value of the servername extension to send in the client hello.
1228
1229 :param name: A byte string giving the name.
1230 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001231 if not isinstance(name, bytes):
1232 raise TypeError("name must be a byte string")
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001233 elif b"\0" in name:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001234 raise TypeError("name must not contain NUL byte")
1235
1236 # XXX I guess this can fail sometimes?
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001237 _lib.SSL_set_tlsext_host_name(self._ssl, name)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001238
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001239
1240 def pending(self):
1241 """
1242 Get the number of bytes that can be safely read from the connection
1243
1244 :return: The number of bytes available in the receive buffer.
1245 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001246 return _lib.SSL_pending(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001247
1248
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001249 def send(self, buf, flags=0):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001250 """
1251 Send data on the connection. NOTE: If you get one of the WantRead,
1252 WantWrite or WantX509Lookup exceptions on this, you have to call the
1253 method again with the SAME buffer.
1254
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001255 :param buf: The string, buffer or memoryview to send
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001256 :param flags: (optional) Included for compatibility with the socket
1257 API, the value is ignored
1258 :return: The number of bytes written
1259 """
Abraham Martine82326c2015-02-04 10:18:10 +00001260 # Backward compatibility
Jean-Paul Calderone39a8d592015-04-13 20:49:50 -04001261 buf = _text_to_bytes_and_warn("buf", buf)
Abraham Martine82326c2015-02-04 10:18:10 +00001262
Jean-Paul Calderone8fb53182013-12-30 08:35:49 -05001263 if isinstance(buf, _memoryview):
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -08001264 buf = buf.tobytes()
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001265 if isinstance(buf, _buffer):
1266 buf = str(buf)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001267 if not isinstance(buf, bytes):
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001268 raise TypeError("data must be a memoryview, buffer or byte string")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001269
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001270 result = _lib.SSL_write(self._ssl, buf, len(buf))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001271 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001272 return result
1273 write = send
1274
1275
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001276 def sendall(self, buf, flags=0):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001277 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001278 Send "all" data on the connection. This calls send() repeatedly until
1279 all data is sent. If an error occurs, it's impossible to tell how much
1280 data has been sent.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001281
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001282 :param buf: The string, buffer or memoryview to send
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001283 :param flags: (optional) Included for compatibility with the socket
1284 API, the value is ignored
1285 :return: The number of bytes written
1286 """
Jean-Paul Calderone39a8d592015-04-13 20:49:50 -04001287 buf = _text_to_bytes_and_warn("buf", buf)
Abraham Martine82326c2015-02-04 10:18:10 +00001288
Jean-Paul Calderone8fb53182013-12-30 08:35:49 -05001289 if isinstance(buf, _memoryview):
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -08001290 buf = buf.tobytes()
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001291 if isinstance(buf, _buffer):
1292 buf = str(buf)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001293 if not isinstance(buf, bytes):
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001294 raise TypeError("buf must be a memoryview, buffer or byte string")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001295
1296 left_to_send = len(buf)
1297 total_sent = 0
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001298 data = _ffi.new("char[]", buf)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001299
1300 while left_to_send:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001301 result = _lib.SSL_write(self._ssl, data + total_sent, left_to_send)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001302 self._raise_ssl_error(self._ssl, result)
1303 total_sent += result
1304 left_to_send -= result
1305
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001306
1307 def recv(self, bufsiz, flags=None):
1308 """
1309 Receive data on the connection. NOTE: If you get one of the WantRead,
1310 WantWrite or WantX509Lookup exceptions on this, you have to call the
1311 method again with the SAME buffer.
1312
1313 :param bufsiz: The maximum number of bytes to read
1314 :param flags: (optional) Included for compatibility with the socket
1315 API, the value is ignored
1316 :return: The string read from the Connection
1317 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001318 buf = _ffi.new("char[]", bufsiz)
1319 result = _lib.SSL_read(self._ssl, buf, bufsiz)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001320 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001321 return _ffi.buffer(buf, result)[:]
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001322 read = recv
1323
1324
Cory Benfield62d10332014-06-15 10:03:41 +01001325 def recv_into(self, buffer, nbytes=None, flags=None):
1326 """
1327 Receive data on the connection and store the data into a buffer rather
1328 than creating a new string.
1329
1330 :param buffer: The buffer to copy into.
1331 :param nbytes: (optional) The maximum number of bytes to read into the
1332 buffer. If not present, defaults to the size of the buffer. If
1333 larger than the size of the buffer, is reduced to the size of the
1334 buffer.
1335 :param flags: (optional) Included for compatibility with the socket
1336 API, the value is ignored.
1337 :return: The number of bytes read into the buffer.
1338 """
1339 if nbytes is None:
1340 nbytes = len(buffer)
1341 else:
1342 nbytes = min(nbytes, len(buffer))
1343
1344 # We need to create a temporary buffer. This is annoying, it would be
1345 # better if we could pass memoryviews straight into the SSL_read call,
1346 # but right now we can't. Revisit this if CFFI gets that ability.
1347 buf = _ffi.new("char[]", nbytes)
1348 result = _lib.SSL_read(self._ssl, buf, nbytes)
1349 self._raise_ssl_error(self._ssl, result)
1350
1351 # This strange line is all to avoid a memory copy. The buffer protocol
1352 # should allow us to assign a CFFI buffer to the LHS of this line, but
1353 # on CPython 3.3+ that segfaults. As a workaround, we can temporarily
1354 # wrap it in a memoryview, except on Python 2.6 which doesn't have a
1355 # memoryview type.
1356 try:
1357 buffer[:result] = memoryview(_ffi.buffer(buf, result))
1358 except NameError:
1359 buffer[:result] = _ffi.buffer(buf, result)
1360
1361 return result
1362
1363
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001364 def _handle_bio_errors(self, bio, result):
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001365 if _lib.BIO_should_retry(bio):
1366 if _lib.BIO_should_read(bio):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001367 raise WantReadError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001368 elif _lib.BIO_should_write(bio):
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001369 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001370 raise WantWriteError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001371 elif _lib.BIO_should_io_special(bio):
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001372 # TODO: This is untested. I think io_special means the socket
1373 # BIO has a not-yet connected socket.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001374 raise ValueError("BIO_should_io_special")
1375 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001376 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001377 raise ValueError("unknown bio failure")
1378 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001379 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001380 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001381
1382
1383 def bio_read(self, bufsiz):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001384 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001385 When using non-socket connections this function reads the "dirty" data
1386 that would have traveled away on the network.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001387
1388 :param bufsiz: The maximum number of bytes to read
1389 :return: The string read.
1390 """
Jean-Paul Calderone97e041d2013-03-05 21:03:12 -08001391 if self._from_ssl is None:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001392 raise TypeError("Connection sock was not None")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001393
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -05001394 if not isinstance(bufsiz, integer_types):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001395 raise TypeError("bufsiz must be an integer")
1396
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001397 buf = _ffi.new("char[]", bufsiz)
1398 result = _lib.BIO_read(self._from_ssl, buf, bufsiz)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001399 if result <= 0:
1400 self._handle_bio_errors(self._from_ssl, result)
1401
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001402 return _ffi.buffer(buf, result)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001403
1404
1405 def bio_write(self, buf):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001406 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001407 When using non-socket connections this function sends "dirty" data that
1408 would have traveled in on the network.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001409
1410 :param buf: The string to put into the memory BIO.
1411 :return: The number of bytes written
1412 """
Jean-Paul Calderone39a8d592015-04-13 20:49:50 -04001413 buf = _text_to_bytes_and_warn("buf", buf)
Abraham Martine82326c2015-02-04 10:18:10 +00001414
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001415 if self._into_ssl is None:
1416 raise TypeError("Connection sock was not None")
1417
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001418 result = _lib.BIO_write(self._into_ssl, buf, len(buf))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001419 if result <= 0:
1420 self._handle_bio_errors(self._into_ssl, result)
1421 return result
1422
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001423
1424 def renegotiate(self):
1425 """
1426 Renegotiate the session
1427
1428 :return: True if the renegotiation can be started, false otherwise
1429 """
1430
1431 def do_handshake(self):
1432 """
1433 Perform an SSL handshake (usually called after renegotiate() or one of
1434 set_*_state()). This can raise the same exceptions as send and recv.
1435
1436 :return: None.
1437 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001438 result = _lib.SSL_do_handshake(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001439 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001440
1441
1442 def renegotiate_pending(self):
1443 """
1444 Check if there's a renegotiation in progress, it will return false once
1445 a renegotiation is finished.
1446
1447 :return: Whether there's a renegotiation in progress
1448 """
1449
1450 def total_renegotiations(self):
1451 """
1452 Find out the total number of renegotiations.
1453
1454 :return: The number of renegotiations.
1455 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001456 return _lib.SSL_total_renegotiations(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001457
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001458
1459 def connect(self, addr):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001460 """
1461 Connect to remote host and set up client-side SSL
1462
1463 :param addr: A remote address
1464 :return: What the socket's connect method returns
1465 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001466 _lib.SSL_set_connect_state(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001467 return self._socket.connect(addr)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001468
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001469
1470 def connect_ex(self, addr):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001471 """
1472 Connect to remote host and set up client-side SSL. Note that if the socket's
1473 connect_ex method doesn't return 0, SSL won't be initialized.
1474
1475 :param addr: A remove address
1476 :return: What the socket's connect_ex method returns
1477 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001478 connect_ex = self._socket.connect_ex
1479 self.set_connect_state()
1480 return connect_ex(addr)
1481
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001482
1483 def accept(self):
1484 """
1485 Accept incoming connection and set up SSL on it
1486
1487 :return: A (conn,addr) pair where conn is a Connection and addr is an
1488 address
1489 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001490 client, addr = self._socket.accept()
1491 conn = Connection(self._context, client)
1492 conn.set_accept_state()
1493 return (conn, addr)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001494
1495
1496 def bio_shutdown(self):
1497 """
1498 When using non-socket connections this function signals end of
1499 data on the input for this connection.
1500
1501 :return: None
1502 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001503 if self._from_ssl is None:
1504 raise TypeError("Connection sock was not None")
1505
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001506 _lib.BIO_set_mem_eof_return(self._into_ssl, 0)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001507
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001508
1509 def shutdown(self):
1510 """
1511 Send closure alert
1512
1513 :return: True if the shutdown completed successfully (i.e. both sides
1514 have sent closure alerts), false otherwise (i.e. you have to
1515 wait for a ZeroReturnError on a recv() method call
1516 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001517 result = _lib.SSL_shutdown(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001518 if result < 0:
Paul Aurichbff1d1a2015-01-08 08:36:53 -08001519 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001520 elif result > 0:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001521 return True
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001522 else:
1523 return False
1524
1525
1526 def get_cipher_list(self):
1527 """
1528 Get the session cipher list
1529
1530 :return: A list of cipher strings
1531 """
1532 ciphers = []
1533 for i in count():
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001534 result = _lib.SSL_get_cipher_list(self._ssl, i)
1535 if result == _ffi.NULL:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001536 break
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001537 ciphers.append(_native(_ffi.string(result)))
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001538 return ciphers
1539
1540
1541 def get_client_ca_list(self):
1542 """
1543 Get CAs whose certificates are suggested for client authentication.
1544
1545 :return: If this is a server connection, a list of X509Names representing
1546 the acceptable CAs as set by :py:meth:`OpenSSL.SSL.Context.set_client_ca_list` or
1547 :py:meth:`OpenSSL.SSL.Context.add_client_ca`. If this is a client connection,
1548 the list of such X509Names sent by the server, or an empty list if that
1549 has not yet happened.
1550 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001551 ca_names = _lib.SSL_get_client_CA_list(self._ssl)
1552 if ca_names == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001553 # TODO: This is untested.
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001554 return []
1555
1556 result = []
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001557 for i in range(_lib.sk_X509_NAME_num(ca_names)):
1558 name = _lib.sk_X509_NAME_value(ca_names, i)
1559 copy = _lib.X509_NAME_dup(name)
1560 if copy == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001561 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001562 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001563
1564 pyname = X509Name.__new__(X509Name)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001565 pyname._name = _ffi.gc(copy, _lib.X509_NAME_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001566 result.append(pyname)
1567 return result
1568
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001569
1570 def makefile(self):
1571 """
1572 The makefile() method is not implemented, since there is no dup semantics
1573 for SSL connections
1574
Jean-Paul Calderone6749ec22014-04-17 16:30:21 -04001575 :raise: NotImplementedError
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001576 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001577 raise NotImplementedError("Cannot make file object of OpenSSL.SSL.Connection")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001578
1579
1580 def get_app_data(self):
1581 """
1582 Get application data
1583
1584 :return: The application data
1585 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001586 return self._app_data
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001587
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001588
1589 def set_app_data(self, data):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001590 """
1591 Set application data
1592
1593 :param data - The application data
1594 :return: None
1595 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001596 self._app_data = data
1597
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001598
1599 def get_shutdown(self):
1600 """
1601 Get shutdown state
1602
1603 :return: The shutdown state, a bitvector of SENT_SHUTDOWN, RECEIVED_SHUTDOWN.
1604 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001605 return _lib.SSL_get_shutdown(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001606
1607
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001608 def set_shutdown(self, state):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001609 """
1610 Set shutdown state
1611
1612 :param state - bitvector of SENT_SHUTDOWN, RECEIVED_SHUTDOWN.
1613 :return: None
1614 """
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -05001615 if not isinstance(state, integer_types):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001616 raise TypeError("state must be an integer")
1617
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001618 _lib.SSL_set_shutdown(self._ssl, state)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001619
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001620
1621 def state_string(self):
1622 """
1623 Get a verbose state description
1624
1625 :return: A string representing the state
1626 """
1627
1628 def server_random(self):
1629 """
1630 Get a copy of the server hello nonce.
1631
1632 :return: A string representing the state
1633 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001634 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001635 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001636 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001637 self._ssl.s3.server_random,
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001638 _lib.SSL3_RANDOM_SIZE)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001639
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001640
1641 def client_random(self):
1642 """
1643 Get a copy of the client hello nonce.
1644
1645 :return: A string representing the state
1646 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001647 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001648 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001649 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001650 self._ssl.s3.client_random,
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001651 _lib.SSL3_RANDOM_SIZE)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001652
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001653
1654 def master_key(self):
1655 """
1656 Get a copy of the master key.
1657
1658 :return: A string representing the state
1659 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001660 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001661 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001662 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001663 self._ssl.session.master_key,
1664 self._ssl.session.master_key_length)[:]
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001665
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001666
1667 def sock_shutdown(self, *args, **kwargs):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001668 """
1669 See shutdown(2)
1670
1671 :return: What the socket's shutdown() method returns
1672 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001673 return self._socket.shutdown(*args, **kwargs)
1674
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001675
1676 def get_peer_certificate(self):
1677 """
1678 Retrieve the other side's certificate (if any)
1679
1680 :return: The peer's certificate
1681 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001682 cert = _lib.SSL_get_peer_certificate(self._ssl)
1683 if cert != _ffi.NULL:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001684 pycert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001685 pycert._x509 = _ffi.gc(cert, _lib.X509_free)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001686 return pycert
1687 return None
1688
1689
1690 def get_peer_cert_chain(self):
1691 """
1692 Retrieve the other side's certificate (if any)
1693
1694 :return: A list of X509 instances giving the peer's certificate chain,
1695 or None if it does not have one.
1696 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001697 cert_stack = _lib.SSL_get_peer_cert_chain(self._ssl)
1698 if cert_stack == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001699 return None
1700
1701 result = []
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001702 for i in range(_lib.sk_X509_num(cert_stack)):
Jean-Paul Calderone73b15c22013-03-05 18:30:39 -08001703 # TODO could incref instead of dup here
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001704 cert = _lib.X509_dup(_lib.sk_X509_value(cert_stack, i))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001705 pycert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001706 pycert._x509 = _ffi.gc(cert, _lib.X509_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001707 result.append(pycert)
1708 return result
1709
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001710
1711 def want_read(self):
1712 """
1713 Checks if more data has to be read from the transport layer to complete an
1714 operation.
1715
1716 :return: True iff more data has to be read
1717 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001718 return _lib.SSL_want_read(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001719
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001720
1721 def want_write(self):
1722 """
1723 Checks if there is data to write to the transport layer to complete an
1724 operation.
1725
1726 :return: True iff there is data to write
1727 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001728 return _lib.SSL_want_write(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001729
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001730
1731 def set_accept_state(self):
1732 """
1733 Set the connection to work in server mode. The handshake will be handled
1734 automatically by read/write.
1735
1736 :return: None
1737 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001738 _lib.SSL_set_accept_state(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001739
1740
1741 def set_connect_state(self):
1742 """
1743 Set the connection to work in client mode. The handshake will be handled
1744 automatically by read/write.
1745
1746 :return: None
1747 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001748 _lib.SSL_set_connect_state(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001749
1750
1751 def get_session(self):
1752 """
1753 Returns the Session currently used.
1754
1755 @return: An instance of :py:class:`OpenSSL.SSL.Session` or :py:obj:`None` if
1756 no session exists.
1757 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001758 session = _lib.SSL_get1_session(self._ssl)
1759 if session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001760 return None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001761
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001762 pysession = Session.__new__(Session)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001763 pysession._session = _ffi.gc(session, _lib.SSL_SESSION_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001764 return pysession
1765
1766
1767 def set_session(self, session):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001768 """
1769 Set the session to be used when the TLS/SSL connection is established.
1770
1771 :param session: A Session instance representing the session to use.
1772 :returns: None
1773 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001774 if not isinstance(session, Session):
1775 raise TypeError("session must be a Session instance")
1776
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001777 result = _lib.SSL_set_session(self._ssl, session._session)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001778 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001779 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001780
Jean-Paul Calderonedbd76272014-03-29 18:09:40 -04001781
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001782 def _get_finished_message(self, function):
1783 """
1784 Helper to implement :py:meth:`get_finished` and
1785 :py:meth:`get_peer_finished`.
1786
1787 :param function: Either :py:data:`SSL_get_finished`: or
1788 :py:data:`SSL_get_peer_finished`.
1789
1790 :return: :py:data:`None` if the desired message has not yet been
1791 received, otherwise the contents of the message.
1792 :rtype: :py:class:`bytes` or :py:class:`NoneType`
1793 """
Jean-Paul Calderone01af9042014-03-30 11:40:42 -04001794 # The OpenSSL documentation says nothing about what might happen if the
1795 # count argument given is zero. Specifically, it doesn't say whether
1796 # the output buffer may be NULL in that case or not. Inspection of the
1797 # implementation reveals that it calls memcpy() unconditionally.
1798 # Section 7.1.4, paragraph 1 of the C standard suggests that
1799 # memcpy(NULL, source, 0) is not guaranteed to produce defined (let
1800 # alone desirable) behavior (though it probably does on just about
1801 # every implementation...)
1802 #
1803 # Allocate a tiny buffer to pass in (instead of just passing NULL as
1804 # one might expect) for the initial call so as to be safe against this
1805 # potentially undefined behavior.
1806 empty = _ffi.new("char[]", 0)
1807 size = function(self._ssl, empty, 0)
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001808 if size == 0:
1809 # No Finished message so far.
1810 return None
1811
1812 buf = _ffi.new("char[]", size)
1813 function(self._ssl, buf, size)
1814 return _ffi.buffer(buf, size)[:]
1815
1816
Fedor Brunner5747b932014-03-05 14:22:34 +01001817 def get_finished(self):
1818 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001819 Obtain the latest `handshake finished` message sent to the peer.
Fedor Brunner5747b932014-03-05 14:22:34 +01001820
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001821 :return: The contents of the message or :py:obj:`None` if the TLS
1822 handshake has not yet completed.
1823 :rtype: :py:class:`bytes` or :py:class:`NoneType`
Fedor Brunner5747b932014-03-05 14:22:34 +01001824 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001825 return self._get_finished_message(_lib.SSL_get_finished)
1826
Fedor Brunner5747b932014-03-05 14:22:34 +01001827
1828 def get_peer_finished(self):
1829 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001830 Obtain the latest `handshake finished` message received from the peer.
Fedor Brunner5747b932014-03-05 14:22:34 +01001831
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001832 :return: The contents of the message or :py:obj:`None` if the TLS
1833 handshake has not yet completed.
1834 :rtype: :py:class:`bytes` or :py:class:`NoneType`
Fedor Brunner5747b932014-03-05 14:22:34 +01001835 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001836 return self._get_finished_message(_lib.SSL_get_peer_finished)
Fedor Brunner5747b932014-03-05 14:22:34 +01001837
Jean-Paul Calderone7c556ef2014-03-30 10:45:00 -04001838
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001839 def get_cipher_name(self):
1840 """
1841 Obtain the name of the currently used cipher.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001842
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001843 :returns: The name of the currently used cipher or :py:obj:`None`
1844 if no connection has been established.
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001845 :rtype: :py:class:`unicode` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001846 """
1847 cipher = _lib.SSL_get_current_cipher(self._ssl)
1848 if cipher == _ffi.NULL:
1849 return None
1850 else:
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001851 name = _ffi.string(_lib.SSL_CIPHER_get_name(cipher))
1852 return name.decode("utf-8")
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001853
Jean-Paul Calderonedbd76272014-03-29 18:09:40 -04001854
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001855 def get_cipher_bits(self):
1856 """
1857 Obtain the number of secret bits of the currently used cipher.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001858
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001859 :returns: The number of secret bits of the currently used cipher
1860 or :py:obj:`None` if no connection has been established.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001861 :rtype: :py:class:`int` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001862 """
1863 cipher = _lib.SSL_get_current_cipher(self._ssl)
1864 if cipher == _ffi.NULL:
1865 return None
1866 else:
1867 return _lib.SSL_CIPHER_get_bits(cipher, _ffi.NULL)
1868
Jean-Paul Calderonedbd76272014-03-29 18:09:40 -04001869
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001870 def get_cipher_version(self):
1871 """
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001872 Obtain the protocol version of the currently used cipher.
1873
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001874 :returns: The protocol name of the currently used cipher
1875 or :py:obj:`None` if no connection has been established.
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001876 :rtype: :py:class:`unicode` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001877 """
1878 cipher = _lib.SSL_get_current_cipher(self._ssl)
1879 if cipher == _ffi.NULL:
1880 return None
1881 else:
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001882 version =_ffi.string(_lib.SSL_CIPHER_get_version(cipher))
1883 return version.decode("utf-8")
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001884
Cory Benfield10b277f2015-04-13 17:12:42 -04001885
Jim Shaverabff1882015-05-27 09:15:55 -04001886 def get_protocol_version_name(self):
Jim Shaverba65e662015-04-26 12:23:40 -04001887 """
1888 Obtain the protocol version of the current connection.
1889
1890 :returns: The TLS version of the current connection, for example
Jim Shaverabff1882015-05-27 09:15:55 -04001891 the value for TLS 1.2 would be ``b'TLSv1.2'``.
Jim Shaverb2967922015-04-26 23:58:52 -04001892 :rtype: :py:class:`unicode`
Jim Shaverba65e662015-04-26 12:23:40 -04001893 """
Jim Shaverabff1882015-05-27 09:15:55 -04001894 version = _lib.SSL_get_version(self._ssl)
1895 return version
Jim Shaverb2967922015-04-26 23:58:52 -04001896
Jim Shaverba65e662015-04-26 12:23:40 -04001897
Cory Benfield10b277f2015-04-13 17:12:42 -04001898 @_requires_npn
Cory Benfield84a121e2014-03-31 20:30:25 +01001899 def get_next_proto_negotiated(self):
1900 """
1901 Get the protocol that was negotiated by NPN.
1902 """
1903 data = _ffi.new("unsigned char **")
1904 data_len = _ffi.new("unsigned int *")
1905
1906 _lib.SSL_get0_next_proto_negotiated(self._ssl, data, data_len)
1907
Cory Benfieldcd010f62014-05-15 19:00:27 +01001908 return _ffi.buffer(data[0], data_len[0])[:]
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001909
Hynek Schlawackc3717b92015-04-18 12:13:16 +02001910
Cory Benfield7907e332015-04-13 17:18:25 -04001911 @_requires_alpn
Cory Benfield12eae892014-06-07 15:42:56 +01001912 def set_alpn_protos(self, protos):
1913 """
Cory Benfielde8e9c382015-04-11 17:33:48 -04001914 Specify the client's ALPN protocol list.
1915
1916 These protocols are offered to the server during protocol negotiation.
Cory Benfield12eae892014-06-07 15:42:56 +01001917
1918 :param protos: A list of the protocols to be offered to the server.
1919 This list should be a Python list of bytestrings representing the
1920 protocols to offer, e.g. ``[b'http/1.1', b'spdy/2']``.
1921 """
1922 # Take the list of protocols and join them together, prefixing them
1923 # with their lengths.
1924 protostr = b''.join(
1925 chain.from_iterable((int2byte(len(p)), p) for p in protos)
1926 )
1927
1928 # Build a C string from the list. We don't need to save this off
1929 # because OpenSSL immediately copies the data out.
1930 input_str = _ffi.new("unsigned char[]", protostr)
Cory Benfield9c1979a2015-04-12 08:51:52 -04001931 input_str_len = _ffi.cast("unsigned", len(protostr))
1932 _lib.SSL_set_alpn_protos(self._ssl, input_str, input_str_len)
Cory Benfield12eae892014-06-07 15:42:56 +01001933
1934
1935 def get_alpn_proto_negotiated(self):
Cory Benfield222f30e2015-04-13 18:10:21 -04001936 """
1937 Get the protocol that was negotiated by ALPN.
1938 """
Cory Benfield3e619292015-04-13 12:34:51 -04001939 if not _lib.Cryptography_HAS_ALPN:
1940 raise NotImplementedError("ALPN not available")
1941
Cory Benfield12eae892014-06-07 15:42:56 +01001942 data = _ffi.new("unsigned char **")
1943 data_len = _ffi.new("unsigned int *")
1944
1945 _lib.SSL_get0_alpn_selected(self._ssl, data, data_len)
1946
Cory Benfielde8e9c382015-04-11 17:33:48 -04001947 if not data_len:
1948 return b''
1949
Cory Benfield12eae892014-06-07 15:42:56 +01001950 return _ffi.buffer(data[0], data_len[0])[:]
1951
1952
Richard J. Moore5d85fca2015-01-11 17:04:43 +00001953 def get_protocol_version(self):
1954 """
1955 Obtain the protocol version of the current connection.
1956
1957 :returns: The TLS version of the current connection, for example
1958 the value for TLS 1.2 would be 0x303.
1959 :rtype: :py:class:`int`
1960 """
1961 version = _lib.SSL_version(self._ssl)
1962 return version
1963
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001964
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001965ConnectionType = Connection
Jean-Paul Calderone11ed8e82014-01-18 10:21:50 -05001966
Jean-Paul Calderonefab157b2014-01-18 11:21:38 -05001967# This is similar to the initialization calls at the end of OpenSSL/crypto.py
1968# but is exercised mostly by the Context initializer.
Jean-Paul Calderone11ed8e82014-01-18 10:21:50 -05001969_lib.SSL_library_init()