blob: b83f4b82fe9bf5bbf53a20e6ceb2bf7cc9e41478 [file] [log] [blame]
Maximilian Hils1d95dea2015-08-17 19:27:20 +02001import socket
Konstantinos Koukopoulos541150d2014-01-31 01:00:19 +02002from sys import platform
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05003from functools import wraps, partial
Cory Benfieldbe3e7b82014-05-10 09:48:55 +01004from itertools import count, chain
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08005from weakref import WeakValueDictionary
6from errno import errorcode
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -08007
Jean-Paul Calderone63eab692014-01-18 10:19:56 -05008from six import text_type as _text_type
Cory Benfield63759dc2015-04-12 08:57:03 -04009from six import binary_type as _binary_type
Konstantinos Koukopoulosc8b13ea2014-01-28 00:21:50 -080010from six import integer_types as integer_types
Cory Benfieldcd010f62014-05-15 19:00:27 +010011from six import int2byte, indexbytes
Jean-Paul Calderone63eab692014-01-18 10:19:56 -050012
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -050013from OpenSSL._util import (
14 ffi as _ffi,
15 lib as _lib,
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -050016 exception_from_error_queue as _exception_from_error_queue,
Jean-Paul Calderone55f9e882015-04-12 09:31:03 -040017 native as _native,
Jean-Paul Calderone39a8d592015-04-13 20:49:50 -040018 text_to_bytes_and_warn as _text_to_bytes_and_warn,
Jean-Paul Calderone55f9e882015-04-12 09:31:03 -040019 path_string as _path_string,
Jean-Paul Calderone00f84eb2015-04-13 12:47:21 -040020 UNSPECIFIED as _UNSPECIFIED,
Jean-Paul Calderone55f9e882015-04-12 09:31:03 -040021)
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080022
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -080023from OpenSSL.crypto import (
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -050024 FILETYPE_PEM, _PassphraseHelper, PKey, X509Name, X509, X509Store)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -080025
Jean-Paul Calderone8fb53182013-12-30 08:35:49 -050026try:
27 _memoryview = memoryview
28except NameError:
29 class _memoryview(object):
30 pass
31
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +020032try:
33 _buffer = buffer
34except NameError:
35 class _buffer(object):
36 pass
37
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050038OPENSSL_VERSION_NUMBER = _lib.OPENSSL_VERSION_NUMBER
39SSLEAY_VERSION = _lib.SSLEAY_VERSION
40SSLEAY_CFLAGS = _lib.SSLEAY_CFLAGS
41SSLEAY_PLATFORM = _lib.SSLEAY_PLATFORM
42SSLEAY_DIR = _lib.SSLEAY_DIR
43SSLEAY_BUILT_ON = _lib.SSLEAY_BUILT_ON
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080044
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050045SENT_SHUTDOWN = _lib.SSL_SENT_SHUTDOWN
46RECEIVED_SHUTDOWN = _lib.SSL_RECEIVED_SHUTDOWN
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080047
48SSLv2_METHOD = 1
49SSLv3_METHOD = 2
50SSLv23_METHOD = 3
51TLSv1_METHOD = 4
Jean-Paul Calderone56bff942013-11-03 11:30:43 -050052TLSv1_1_METHOD = 5
53TLSv1_2_METHOD = 6
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080054
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050055OP_NO_SSLv2 = _lib.SSL_OP_NO_SSLv2
56OP_NO_SSLv3 = _lib.SSL_OP_NO_SSLv3
57OP_NO_TLSv1 = _lib.SSL_OP_NO_TLSv1
Jean-Paul Calderonebe2bb422013-12-29 07:34:08 -050058
59OP_NO_TLSv1_1 = getattr(_lib, "SSL_OP_NO_TLSv1_1", 0)
60OP_NO_TLSv1_2 = getattr(_lib, "SSL_OP_NO_TLSv1_2", 0)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -080061
Jean-Paul Calderone0d7e8a12014-01-08 16:54:13 -050062try:
63 MODE_RELEASE_BUFFERS = _lib.SSL_MODE_RELEASE_BUFFERS
64except AttributeError:
65 pass
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080066
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050067OP_SINGLE_DH_USE = _lib.SSL_OP_SINGLE_DH_USE
68OP_EPHEMERAL_RSA = _lib.SSL_OP_EPHEMERAL_RSA
69OP_MICROSOFT_SESS_ID_BUG = _lib.SSL_OP_MICROSOFT_SESS_ID_BUG
70OP_NETSCAPE_CHALLENGE_BUG = _lib.SSL_OP_NETSCAPE_CHALLENGE_BUG
71OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG = _lib.SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG
72OP_SSLREF2_REUSE_CERT_TYPE_BUG = _lib.SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG
73OP_MICROSOFT_BIG_SSLV3_BUFFER = _lib.SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER
Jean-Paul Calderone0d7e8a12014-01-08 16:54:13 -050074try:
75 OP_MSIE_SSLV2_RSA_PADDING = _lib.SSL_OP_MSIE_SSLV2_RSA_PADDING
76except AttributeError:
77 pass
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050078OP_SSLEAY_080_CLIENT_DH_BUG = _lib.SSL_OP_SSLEAY_080_CLIENT_DH_BUG
79OP_TLS_D5_BUG = _lib.SSL_OP_TLS_D5_BUG
80OP_TLS_BLOCK_PADDING_BUG = _lib.SSL_OP_TLS_BLOCK_PADDING_BUG
81OP_DONT_INSERT_EMPTY_FRAGMENTS = _lib.SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
82OP_CIPHER_SERVER_PREFERENCE = _lib.SSL_OP_CIPHER_SERVER_PREFERENCE
83OP_TLS_ROLLBACK_BUG = _lib.SSL_OP_TLS_ROLLBACK_BUG
84OP_PKCS1_CHECK_1 = _lib.SSL_OP_PKCS1_CHECK_1
85OP_PKCS1_CHECK_2 = _lib.SSL_OP_PKCS1_CHECK_2
86OP_NETSCAPE_CA_DN_BUG = _lib.SSL_OP_NETSCAPE_CA_DN_BUG
Alex Gaynorc4889812015-09-04 08:43:17 -040087OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG = _lib.SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG
Jean-Paul Calderonec1780342014-01-08 16:59:03 -050088try:
89 OP_NO_COMPRESSION = _lib.SSL_OP_NO_COMPRESSION
90except AttributeError:
91 pass
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -080092
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050093OP_NO_QUERY_MTU = _lib.SSL_OP_NO_QUERY_MTU
94OP_COOKIE_EXCHANGE = _lib.SSL_OP_COOKIE_EXCHANGE
Arturo Filastò5f8c7a82014-03-09 20:01:25 +010095try:
96 OP_NO_TICKET = _lib.SSL_OP_NO_TICKET
97except AttributeError:
98 pass
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -080099
Alex Gaynorc4889812015-09-04 08:43:17 -0400100OP_ALL = _lib.SSL_OP_ALL
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -0800101
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500102VERIFY_PEER = _lib.SSL_VERIFY_PEER
103VERIFY_FAIL_IF_NO_PEER_CERT = _lib.SSL_VERIFY_FAIL_IF_NO_PEER_CERT
104VERIFY_CLIENT_ONCE = _lib.SSL_VERIFY_CLIENT_ONCE
105VERIFY_NONE = _lib.SSL_VERIFY_NONE
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -0800106
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500107SESS_CACHE_OFF = _lib.SSL_SESS_CACHE_OFF
108SESS_CACHE_CLIENT = _lib.SSL_SESS_CACHE_CLIENT
109SESS_CACHE_SERVER = _lib.SSL_SESS_CACHE_SERVER
110SESS_CACHE_BOTH = _lib.SSL_SESS_CACHE_BOTH
111SESS_CACHE_NO_AUTO_CLEAR = _lib.SSL_SESS_CACHE_NO_AUTO_CLEAR
112SESS_CACHE_NO_INTERNAL_LOOKUP = _lib.SSL_SESS_CACHE_NO_INTERNAL_LOOKUP
113SESS_CACHE_NO_INTERNAL_STORE = _lib.SSL_SESS_CACHE_NO_INTERNAL_STORE
114SESS_CACHE_NO_INTERNAL = _lib.SSL_SESS_CACHE_NO_INTERNAL
Jean-Paul Calderoned39a3f62013-03-04 12:23:51 -0800115
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500116SSL_ST_CONNECT = _lib.SSL_ST_CONNECT
117SSL_ST_ACCEPT = _lib.SSL_ST_ACCEPT
118SSL_ST_MASK = _lib.SSL_ST_MASK
119SSL_ST_INIT = _lib.SSL_ST_INIT
120SSL_ST_BEFORE = _lib.SSL_ST_BEFORE
121SSL_ST_OK = _lib.SSL_ST_OK
122SSL_ST_RENEGOTIATE = _lib.SSL_ST_RENEGOTIATE
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800123
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500124SSL_CB_LOOP = _lib.SSL_CB_LOOP
125SSL_CB_EXIT = _lib.SSL_CB_EXIT
126SSL_CB_READ = _lib.SSL_CB_READ
127SSL_CB_WRITE = _lib.SSL_CB_WRITE
128SSL_CB_ALERT = _lib.SSL_CB_ALERT
129SSL_CB_READ_ALERT = _lib.SSL_CB_READ_ALERT
130SSL_CB_WRITE_ALERT = _lib.SSL_CB_WRITE_ALERT
131SSL_CB_ACCEPT_LOOP = _lib.SSL_CB_ACCEPT_LOOP
132SSL_CB_ACCEPT_EXIT = _lib.SSL_CB_ACCEPT_EXIT
133SSL_CB_CONNECT_LOOP = _lib.SSL_CB_CONNECT_LOOP
134SSL_CB_CONNECT_EXIT = _lib.SSL_CB_CONNECT_EXIT
135SSL_CB_HANDSHAKE_START = _lib.SSL_CB_HANDSHAKE_START
136SSL_CB_HANDSHAKE_DONE = _lib.SSL_CB_HANDSHAKE_DONE
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800137
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500138class Error(Exception):
Jean-Paul Calderone511cde02013-12-29 10:31:13 -0500139 """
140 An error occurred in an `OpenSSL.SSL` API.
141 """
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500142
143
144
145_raise_current_error = partial(_exception_from_error_queue, Error)
146
147
148class WantReadError(Error):
149 pass
150
151
152
153class WantWriteError(Error):
154 pass
155
156
157
158class WantX509LookupError(Error):
159 pass
160
161
162
163class ZeroReturnError(Error):
164 pass
165
166
167
168class SysCallError(Error):
169 pass
170
171
Cory Benfield0ea76e72015-03-22 09:05:28 +0000172class _CallbackExceptionHelper(object):
173 """
174 A base class for wrapper classes that allow for intelligent exception
175 handling in OpenSSL callbacks.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500176
Jean-Paul Calderone1b172982015-03-22 19:37:11 -0400177 :ivar list _problems: Any exceptions that occurred while executing in a
178 context where they could not be raised in the normal way. Typically
179 this is because OpenSSL has called into some Python code and requires a
180 return value. The exceptions are saved to be raised later when it is
181 possible to do so.
Cory Benfield0ea76e72015-03-22 09:05:28 +0000182 """
Jean-Paul Calderone09540d72015-03-22 19:37:20 -0400183 def __init__(self):
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800184 self._problems = []
185
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800186
Cory Benfield0ea76e72015-03-22 09:05:28 +0000187 def raise_if_problem(self):
Jean-Paul Calderone1b172982015-03-22 19:37:11 -0400188 """
189 Raise an exception from the OpenSSL error queue or that was previously
190 captured whe running a callback.
191 """
Cory Benfield0ea76e72015-03-22 09:05:28 +0000192 if self._problems:
193 try:
194 _raise_current_error()
195 except Error:
196 pass
197 raise self._problems.pop(0)
198
199
200class _VerifyHelper(_CallbackExceptionHelper):
Jean-Paul Calderone1b172982015-03-22 19:37:11 -0400201 """
202 Wrap a callback such that it can be used as a certificate verification
203 callback.
204 """
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800205 def __init__(self, callback):
Jean-Paul Calderone837f4032015-03-22 17:38:28 -0400206 _CallbackExceptionHelper.__init__(self)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800207
208 @wraps(callback)
209 def wrapper(ok, store_ctx):
210 cert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500211 cert._x509 = _lib.X509_STORE_CTX_get_current_cert(store_ctx)
212 error_number = _lib.X509_STORE_CTX_get_error(store_ctx)
213 error_depth = _lib.X509_STORE_CTX_get_error_depth(store_ctx)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800214
Jean-Paul Calderone6a8cd112014-04-02 21:09:08 -0400215 index = _lib.SSL_get_ex_data_X509_STORE_CTX_idx()
216 ssl = _lib.X509_STORE_CTX_get_ex_data(store_ctx, index)
217 connection = Connection._reverse_mapping[ssl]
218
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800219 try:
220 result = callback(connection, cert, error_number, error_depth, ok)
221 except Exception as e:
222 self._problems.append(e)
223 return 0
224 else:
225 if result:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500226 _lib.X509_STORE_CTX_set_error(store_ctx, _lib.X509_V_OK)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800227 return 1
228 else:
229 return 0
230
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500231 self.callback = _ffi.callback(
232 "int (*)(int, X509_STORE_CTX *)", wrapper)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800233
234
Cory Benfield0ea76e72015-03-22 09:05:28 +0000235class _NpnAdvertiseHelper(_CallbackExceptionHelper):
Jean-Paul Calderone1b172982015-03-22 19:37:11 -0400236 """
237 Wrap a callback such that it can be used as an NPN advertisement callback.
238 """
Cory Benfield0ea76e72015-03-22 09:05:28 +0000239 def __init__(self, callback):
Jean-Paul Calderone837f4032015-03-22 17:38:28 -0400240 _CallbackExceptionHelper.__init__(self)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800241
Cory Benfield0ea76e72015-03-22 09:05:28 +0000242 @wraps(callback)
243 def wrapper(ssl, out, outlen, arg):
244 try:
245 conn = Connection._reverse_mapping[ssl]
246 protos = callback(conn)
247
248 # Join the protocols into a Python bytestring, length-prefixing
249 # each element.
250 protostr = b''.join(
251 chain.from_iterable((int2byte(len(p)), p) for p in protos)
252 )
253
254 # Save our callback arguments on the connection object. This is
255 # done to make sure that they don't get freed before OpenSSL
256 # uses them. Then, return them appropriately in the output
257 # parameters.
258 conn._npn_advertise_callback_args = [
259 _ffi.new("unsigned int *", len(protostr)),
260 _ffi.new("unsigned char[]", protostr),
261 ]
262 outlen[0] = conn._npn_advertise_callback_args[0][0]
263 out[0] = conn._npn_advertise_callback_args[1]
264 return 0
265 except Exception as e:
266 self._problems.append(e)
267 return 2 # SSL_TLSEXT_ERR_ALERT_FATAL
268
269 self.callback = _ffi.callback(
270 "int (*)(SSL *, const unsigned char **, unsigned int *, void *)",
271 wrapper
272 )
273
274
275class _NpnSelectHelper(_CallbackExceptionHelper):
Jean-Paul Calderone1b172982015-03-22 19:37:11 -0400276 """
277 Wrap a callback such that it can be used as an NPN selection callback.
278 """
Cory Benfield0ea76e72015-03-22 09:05:28 +0000279 def __init__(self, callback):
Jean-Paul Calderone837f4032015-03-22 17:38:28 -0400280 _CallbackExceptionHelper.__init__(self)
Cory Benfield0ea76e72015-03-22 09:05:28 +0000281
282 @wraps(callback)
283 def wrapper(ssl, out, outlen, in_, inlen, arg):
284 try:
285 conn = Connection._reverse_mapping[ssl]
286
287 # The string passed to us is actually made up of multiple
288 # length-prefixed bytestrings. We need to split that into a
289 # list.
290 instr = _ffi.buffer(in_, inlen)[:]
291 protolist = []
292 while instr:
293 l = indexbytes(instr, 0)
294 proto = instr[1:l+1]
295 protolist.append(proto)
296 instr = instr[l+1:]
297
298 # Call the callback
299 outstr = callback(conn, protolist)
300
301 # Save our callback arguments on the connection object. This is
302 # done to make sure that they don't get freed before OpenSSL
303 # uses them. Then, return them appropriately in the output
304 # parameters.
305 conn._npn_select_callback_args = [
306 _ffi.new("unsigned char *", len(outstr)),
307 _ffi.new("unsigned char[]", outstr),
308 ]
309 outlen[0] = conn._npn_select_callback_args[0][0]
310 out[0] = conn._npn_select_callback_args[1]
311 return 0
312 except Exception as e:
313 self._problems.append(e)
314 return 2 # SSL_TLSEXT_ERR_ALERT_FATAL
315
316 self.callback = _ffi.callback(
317 "int (*)(SSL *, unsigned char **, unsigned char *, "
318 "const unsigned char *, unsigned int, void *)",
319 wrapper
320 )
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800321
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800322
Cory Benfield9da5ffb2015-04-13 17:20:14 -0400323class _ALPNSelectHelper(_CallbackExceptionHelper):
Cory Benfieldf1177e72015-04-12 09:11:49 -0400324 """
325 Wrap a callback such that it can be used as an ALPN selection callback.
326 """
327 def __init__(self, callback):
328 _CallbackExceptionHelper.__init__(self)
329
330 @wraps(callback)
331 def wrapper(ssl, out, outlen, in_, inlen, arg):
332 try:
333 conn = Connection._reverse_mapping[ssl]
334
335 # The string passed to us is made up of multiple
336 # length-prefixed bytestrings. We need to split that into a
337 # list.
338 instr = _ffi.buffer(in_, inlen)[:]
339 protolist = []
340 while instr:
Cory Benfield93134db2015-04-13 17:22:13 -0400341 encoded_len = indexbytes(instr, 0)
342 proto = instr[1:encoded_len + 1]
Cory Benfieldf1177e72015-04-12 09:11:49 -0400343 protolist.append(proto)
Cory Benfield93134db2015-04-13 17:22:13 -0400344 instr = instr[encoded_len + 1:]
Cory Benfieldf1177e72015-04-12 09:11:49 -0400345
346 # Call the callback
347 outstr = callback(conn, protolist)
348
349 if not isinstance(outstr, _binary_type):
350 raise TypeError("ALPN callback must return a bytestring.")
351
352 # Save our callback arguments on the connection object to make
353 # sure that they don't get freed before OpenSSL can use them.
354 # Then, return them in the appropriate output parameters.
355 conn._alpn_select_callback_args = [
356 _ffi.new("unsigned char *", len(outstr)),
357 _ffi.new("unsigned char[]", outstr),
358 ]
359 outlen[0] = conn._alpn_select_callback_args[0][0]
360 out[0] = conn._alpn_select_callback_args[1]
361 return 0
362 except Exception as e:
363 self._problems.append(e)
364 return 2 # SSL_TLSEXT_ERR_ALERT_FATAL
365
366 self.callback = _ffi.callback(
367 "int (*)(SSL *, unsigned char **, unsigned char *, "
368 "const unsigned char *, unsigned int, void *)",
369 wrapper
370 )
371
372
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800373def _asFileDescriptor(obj):
374 fd = None
Konstantinos Koukopoulosc8b13ea2014-01-28 00:21:50 -0800375 if not isinstance(obj, integer_types):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800376 meth = getattr(obj, "fileno", None)
377 if meth is not None:
378 obj = meth()
379
Konstantinos Koukopoulosc8b13ea2014-01-28 00:21:50 -0800380 if isinstance(obj, integer_types):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800381 fd = obj
382
Konstantinos Koukopoulosc8b13ea2014-01-28 00:21:50 -0800383 if not isinstance(fd, integer_types):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800384 raise TypeError("argument must be an int, or have a fileno() method.")
385 elif fd < 0:
386 raise ValueError(
387 "file descriptor cannot be a negative integer (%i)" % (fd,))
388
389 return fd
390
391
392
Jean-Paul Calderoned39a3f62013-03-04 12:23:51 -0800393def SSLeay_version(type):
394 """
395 Return a string describing the version of OpenSSL in use.
396
397 :param type: One of the SSLEAY_ constants defined in this module.
398 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500399 return _ffi.string(_lib.SSLeay_version(type))
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800400
401
Cory Benfield10b277f2015-04-13 17:12:42 -0400402def _requires_npn(func):
Cory Benfielda876cef2015-04-13 17:29:12 -0400403 """
404 Wraps any function that requires NPN support in OpenSSL, ensuring that
405 NotImplementedError is raised if NPN is not present.
406 """
Cory Benfield10b277f2015-04-13 17:12:42 -0400407 @wraps(func)
408 def wrapper(*args, **kwargs):
409 if not _lib.Cryptography_HAS_NEXTPROTONEG:
410 raise NotImplementedError("NPN not available.")
411
412 return func(*args, **kwargs)
413
414 return wrapper
415
416
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800417
Cory Benfield7907e332015-04-13 17:18:25 -0400418def _requires_alpn(func):
Cory Benfield9d80a762015-04-13 17:47:33 -0400419 """
420 Wraps any function that requires ALPN support in OpenSSL, ensuring that
421 NotImplementedError is raised if ALPN support is not present.
422 """
Cory Benfield7907e332015-04-13 17:18:25 -0400423 @wraps(func)
424 def wrapper(*args, **kwargs):
425 if not _lib.Cryptography_HAS_ALPN:
426 raise NotImplementedError("ALPN not available.")
427
428 return func(*args, **kwargs)
429
430 return wrapper
431
432
433
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800434class Session(object):
435 pass
436
437
438
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800439class Context(object):
440 """
441 :py:obj:`OpenSSL.SSL.Context` instances define the parameters for setting up
442 new SSL connections.
443 """
444 _methods = {
Andrew Dunhamec84a0a2014-02-24 12:41:37 -0800445 SSLv2_METHOD: "SSLv2_method",
Jean-Paul Calderonebe2bb422013-12-29 07:34:08 -0500446 SSLv3_METHOD: "SSLv3_method",
447 SSLv23_METHOD: "SSLv23_method",
448 TLSv1_METHOD: "TLSv1_method",
449 TLSv1_1_METHOD: "TLSv1_1_method",
450 TLSv1_2_METHOD: "TLSv1_2_method",
Alex Gaynorc4889812015-09-04 08:43:17 -0400451 }
Jean-Paul Calderonebe2bb422013-12-29 07:34:08 -0500452 _methods = dict(
453 (identifier, getattr(_lib, name))
454 for (identifier, name) in _methods.items()
455 if getattr(_lib, name, None) is not None)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800456
Jean-Paul Calderone63157872013-03-20 16:43:38 -0700457
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800458 def __init__(self, method):
459 """
460 :param method: One of SSLv2_METHOD, SSLv3_METHOD, SSLv23_METHOD, or
461 TLSv1_METHOD.
462 """
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -0500463 if not isinstance(method, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800464 raise TypeError("method must be an integer")
465
466 try:
467 method_func = self._methods[method]
468 except KeyError:
469 raise ValueError("No such protocol")
470
471 method_obj = method_func()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500472 if method_obj == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500473 # TODO: This is untested.
474 _raise_current_error()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800475
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500476 context = _lib.SSL_CTX_new(method_obj)
477 if context == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500478 # TODO: This is untested.
479 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500480 context = _ffi.gc(context, _lib.SSL_CTX_free)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800481
482 self._context = context
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800483 self._passphrase_helper = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800484 self._passphrase_callback = None
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800485 self._passphrase_userdata = None
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800486 self._verify_helper = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800487 self._verify_callback = None
488 self._info_callback = None
489 self._tlsext_servername_callback = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800490 self._app_data = None
Cory Benfield0ea76e72015-03-22 09:05:28 +0000491 self._npn_advertise_helper = None
Cory Benfield84a121e2014-03-31 20:30:25 +0100492 self._npn_advertise_callback = None
Cory Benfield0ea76e72015-03-22 09:05:28 +0000493 self._npn_select_helper = None
Cory Benfield84a121e2014-03-31 20:30:25 +0100494 self._npn_select_callback = None
Cory Benfieldf1177e72015-04-12 09:11:49 -0400495 self._alpn_select_helper = None
Cory Benfield12eae892014-06-07 15:42:56 +0100496 self._alpn_select_callback = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800497
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -0800498 # SSL_CTX_set_app_data(self->ctx, self);
499 # SSL_CTX_set_mode(self->ctx, SSL_MODE_ENABLE_PARTIAL_WRITE |
500 # SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
501 # SSL_MODE_AUTO_RETRY);
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500502 self.set_mode(_lib.SSL_MODE_ENABLE_PARTIAL_WRITE)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800503
504
505 def load_verify_locations(self, cafile, capath=None):
506 """
507 Let SSL know where we can find trusted certificates for the certificate
508 chain
509
Jean-Paul Calderone55f9e882015-04-12 09:31:03 -0400510 :param cafile: In which file we can find the certificates (``bytes`` or
511 ``unicode``).
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800512 :param capath: In which directory we can find the certificates
Jean-Paul Calderone55f9e882015-04-12 09:31:03 -0400513 (``bytes`` or ``unicode``).
514
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800515 :return: None
516 """
517 if cafile is None:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500518 cafile = _ffi.NULL
Jean-Paul Calderone55f9e882015-04-12 09:31:03 -0400519 else:
520 cafile = _path_string(cafile)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800521
522 if capath is None:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500523 capath = _ffi.NULL
Jean-Paul Calderone55f9e882015-04-12 09:31:03 -0400524 else:
525 capath = _path_string(capath)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800526
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500527 load_result = _lib.SSL_CTX_load_verify_locations(self._context, cafile, capath)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800528 if not load_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500529 _raise_current_error()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800530
531
532 def _wrap_callback(self, callback):
533 @wraps(callback)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800534 def wrapper(size, verify, userdata):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800535 return callback(size, verify, self._passphrase_userdata)
536 return _PassphraseHelper(
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800537 FILETYPE_PEM, wrapper, more_args=True, truncate=True)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800538
539
540 def set_passwd_cb(self, callback, userdata=None):
541 """
542 Set the passphrase callback
543
544 :param callback: The Python callback to use
545 :param userdata: (optional) A Python object which will be given as
546 argument to the callback
547 :return: None
548 """
549 if not callable(callback):
550 raise TypeError("callback must be callable")
551
552 self._passphrase_helper = self._wrap_callback(callback)
553 self._passphrase_callback = self._passphrase_helper.callback
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500554 _lib.SSL_CTX_set_default_passwd_cb(
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800555 self._context, self._passphrase_callback)
556 self._passphrase_userdata = userdata
557
558
559 def set_default_verify_paths(self):
560 """
561 Use the platform-specific CA certificate locations
562
563 :return: None
564 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500565 set_result = _lib.SSL_CTX_set_default_verify_paths(self._context)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800566 if not set_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500567 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500568 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800569
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800570
571 def use_certificate_chain_file(self, certfile):
572 """
573 Load a certificate chain from a file
574
Jean-Paul Calderoneb6f8a792015-04-13 10:10:06 -0400575 :param certfile: The name of the certificate chain file (``bytes`` or
576 ``unicode``).
577
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800578 :return: None
579 """
Jean-Paul Calderoneaac43a32015-04-12 09:51:21 -0400580 certfile = _path_string(certfile)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800581
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500582 result = _lib.SSL_CTX_use_certificate_chain_file(self._context, certfile)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800583 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500584 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800585
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800586
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800587 def use_certificate_file(self, certfile, filetype=FILETYPE_PEM):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800588 """
589 Load a certificate from a file
590
Jean-Paul Calderoneb6f8a792015-04-13 10:10:06 -0400591 :param certfile: The name of the certificate file (``bytes`` or
592 ``unicode``).
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800593 :param filetype: (optional) The encoding of the file, default is PEM
Jean-Paul Calderoneb6f8a792015-04-13 10:10:06 -0400594
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800595 :return: None
596 """
Jean-Paul Calderoned57a7b62015-04-12 09:57:36 -0400597 certfile = _path_string(certfile)
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -0500598 if not isinstance(filetype, integer_types):
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800599 raise TypeError("filetype must be an integer")
600
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500601 use_result = _lib.SSL_CTX_use_certificate_file(self._context, certfile, filetype)
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800602 if not use_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500603 _raise_current_error()
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800604
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800605
606 def use_certificate(self, cert):
607 """
608 Load a certificate from a X509 object
609
610 :param cert: The X509 object
611 :return: None
612 """
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800613 if not isinstance(cert, X509):
614 raise TypeError("cert must be an X509 instance")
615
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500616 use_result = _lib.SSL_CTX_use_certificate(self._context, cert._x509)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800617 if not use_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500618 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800619
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800620
621 def add_extra_chain_cert(self, certobj):
622 """
623 Add certificate to chain
624
625 :param certobj: The X509 certificate object to add to the chain
626 :return: None
627 """
628 if not isinstance(certobj, X509):
629 raise TypeError("certobj must be an X509 instance")
630
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500631 copy = _lib.X509_dup(certobj._x509)
632 add_result = _lib.SSL_CTX_add_extra_chain_cert(self._context, copy)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800633 if not add_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500634 # TODO: This is untested.
635 _lib.X509_free(copy)
636 _raise_current_error()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800637
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800638
639 def _raise_passphrase_exception(self):
640 if self._passphrase_helper is None:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500641 _raise_current_error()
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800642 exception = self._passphrase_helper.raise_if_problem(Error)
643 if exception is not None:
644 raise exception
645
646
Jean-Paul Calderone00f84eb2015-04-13 12:47:21 -0400647 def use_privatekey_file(self, keyfile, filetype=_UNSPECIFIED):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800648 """
649 Load a private key from a file
650
Jean-Paul Calderoneb6f8a792015-04-13 10:10:06 -0400651 :param keyfile: The name of the key file (``bytes`` or ``unicode``)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800652 :param filetype: (optional) The encoding of the file, default is PEM
Jean-Paul Calderoneb6f8a792015-04-13 10:10:06 -0400653
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800654 :return: None
655 """
Jean-Paul Calderone69a4e5b2015-04-12 10:04:28 -0400656 keyfile = _path_string(keyfile)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800657
Jean-Paul Calderone00f84eb2015-04-13 12:47:21 -0400658 if filetype is _UNSPECIFIED:
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800659 filetype = FILETYPE_PEM
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -0500660 elif not isinstance(filetype, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800661 raise TypeError("filetype must be an integer")
662
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500663 use_result = _lib.SSL_CTX_use_PrivateKey_file(
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800664 self._context, keyfile, filetype)
665 if not use_result:
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800666 self._raise_passphrase_exception()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800667
668
669 def use_privatekey(self, pkey):
670 """
671 Load a private key from a PKey object
672
673 :param pkey: The PKey object
674 :return: None
675 """
676 if not isinstance(pkey, PKey):
677 raise TypeError("pkey must be a PKey instance")
678
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500679 use_result = _lib.SSL_CTX_use_PrivateKey(self._context, pkey._pkey)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800680 if not use_result:
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800681 self._raise_passphrase_exception()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800682
683
684 def check_privatekey(self):
685 """
686 Check that the private key and certificate match up
687
688 :return: None (raises an exception if something's wrong)
689 """
Jean-Paul Calderonea0344922014-12-11 14:02:31 -0500690 if not _lib.SSL_CTX_check_private_key(self._context):
691 _raise_current_error()
692
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800693
694 def load_client_ca(self, cafile):
695 """
696 Load the trusted certificates that will be sent to the client (basically
697 telling the client "These are the guys I trust"). Does not actually
698 imply any of the certificates are trusted; that must be configured
699 separately.
700
701 :param cafile: The name of the certificates file
702 :return: None
703 """
704
705 def set_session_id(self, buf):
706 """
707 Set the session identifier. This is needed if you want to do session
708 resumption.
709
710 :param buf: A Python object that can be safely converted to a string
711 :returns: None
712 """
713
714 def set_session_cache_mode(self, mode):
715 """
716 Enable/disable session caching and specify the mode used.
717
718 :param mode: One or more of the SESS_CACHE_* flags (combine using
719 bitwise or)
720 :returns: The previously set caching mode.
721 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500722 if not isinstance(mode, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800723 raise TypeError("mode must be an integer")
724
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500725 return _lib.SSL_CTX_set_session_cache_mode(self._context, mode)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800726
727
728 def get_session_cache_mode(self):
729 """
730 :returns: The currently used cache mode.
731 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500732 return _lib.SSL_CTX_get_session_cache_mode(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800733
734
735 def set_verify(self, mode, callback):
736 """
737 Set the verify mode and verify callback
738
739 :param mode: The verify mode, this is either VERIFY_NONE or
740 VERIFY_PEER combined with possible other flags
741 :param callback: The Python callback to use
742 :return: None
743
744 See SSL_CTX_set_verify(3SSL) for further details.
745 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500746 if not isinstance(mode, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800747 raise TypeError("mode must be an integer")
748
749 if not callable(callback):
750 raise TypeError("callback must be callable")
751
Jean-Paul Calderone6a8cd112014-04-02 21:09:08 -0400752 self._verify_helper = _VerifyHelper(callback)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800753 self._verify_callback = self._verify_helper.callback
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500754 _lib.SSL_CTX_set_verify(self._context, mode, self._verify_callback)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800755
756
757 def set_verify_depth(self, depth):
758 """
759 Set the verify depth
760
761 :param depth: An integer specifying the verify depth
762 :return: None
763 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500764 if not isinstance(depth, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800765 raise TypeError("depth must be an integer")
766
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500767 _lib.SSL_CTX_set_verify_depth(self._context, depth)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800768
769
770 def get_verify_mode(self):
771 """
772 Get the verify mode
773
774 :return: The verify mode
775 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500776 return _lib.SSL_CTX_get_verify_mode(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800777
778
779 def get_verify_depth(self):
780 """
781 Get the verify depth
782
783 :return: The verify depth
784 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500785 return _lib.SSL_CTX_get_verify_depth(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800786
787
788 def load_tmp_dh(self, dhfile):
789 """
790 Load parameters for Ephemeral Diffie-Hellman
791
Jean-Paul Calderone4e0c43f2015-04-13 10:15:17 -0400792 :param dhfile: The file to load EDH parameters from (``bytes`` or
793 ``unicode``).
794
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800795 :return: None
796 """
Jean-Paul Calderone9e1c1dd2015-04-12 10:13:13 -0400797 dhfile = _path_string(dhfile)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800798
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -0500799 bio = _lib.BIO_new_file(dhfile, b"r")
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500800 if bio == _ffi.NULL:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500801 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500802 bio = _ffi.gc(bio, _lib.BIO_free)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800803
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500804 dh = _lib.PEM_read_bio_DHparams(bio, _ffi.NULL, _ffi.NULL, _ffi.NULL)
805 dh = _ffi.gc(dh, _lib.DH_free)
806 _lib.SSL_CTX_set_tmp_dh(self._context, dh)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800807
808
Jean-Paul Calderone3e4e3352014-04-19 09:28:28 -0400809 def set_tmp_ecdh(self, curve):
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600810 """
Andy Lutomirski76a61332014-03-12 15:02:56 -0700811 Select a curve to use for ECDHE key exchange.
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600812
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -0400813 :param curve: A curve object to use as returned by either
814 :py:meth:`OpenSSL.crypto.get_elliptic_curve` or
815 :py:meth:`OpenSSL.crypto.get_elliptic_curves`.
Andy Lutomirskif05a2732014-03-13 17:22:25 -0700816
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600817 :return: None
818 """
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -0400819 _lib.SSL_CTX_set_tmp_ecdh(self._context, curve._to_EC_KEY())
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600820
821
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800822 def set_cipher_list(self, cipher_list):
823 """
824 Change the cipher list
825
826 :param cipher_list: A cipher list, see ciphers(1)
827 :return: None
828 """
Jean-Paul Calderone63eab692014-01-18 10:19:56 -0500829 if isinstance(cipher_list, _text_type):
830 cipher_list = cipher_list.encode("ascii")
831
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800832 if not isinstance(cipher_list, bytes):
Jean-Paul Calderone63eab692014-01-18 10:19:56 -0500833 raise TypeError("cipher_list must be bytes or unicode")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800834
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500835 result = _lib.SSL_CTX_set_cipher_list(self._context, cipher_list)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800836 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500837 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800838
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800839
840 def set_client_ca_list(self, certificate_authorities):
841 """
842 Set the list of preferred client certificate signers for this server context.
843
844 This list of certificate authorities will be sent to the client when the
845 server requests a client certificate.
846
847 :param certificate_authorities: a sequence of X509Names.
848 :return: None
849 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500850 name_stack = _lib.sk_X509_NAME_new_null()
851 if name_stack == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500852 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500853 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800854
855 try:
856 for ca_name in certificate_authorities:
857 if not isinstance(ca_name, X509Name):
858 raise TypeError(
859 "client CAs must be X509Name objects, not %s objects" % (
860 type(ca_name).__name__,))
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500861 copy = _lib.X509_NAME_dup(ca_name._name)
862 if copy == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500863 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500864 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500865 push_result = _lib.sk_X509_NAME_push(name_stack, copy)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800866 if not push_result:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500867 _lib.X509_NAME_free(copy)
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500868 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800869 except:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500870 _lib.sk_X509_NAME_free(name_stack)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800871 raise
872
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500873 _lib.SSL_CTX_set_client_CA_list(self._context, name_stack)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800874
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800875
876 def add_client_ca(self, certificate_authority):
877 """
878 Add the CA certificate to the list of preferred signers for this context.
879
880 The list of certificate authorities will be sent to the client when the
881 server requests a client certificate.
882
883 :param certificate_authority: certificate authority's X509 certificate.
884 :return: None
885 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800886 if not isinstance(certificate_authority, X509):
887 raise TypeError("certificate_authority must be an X509 instance")
888
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500889 add_result = _lib.SSL_CTX_add_client_CA(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800890 self._context, certificate_authority._x509)
891 if not add_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500892 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500893 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800894
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800895
896 def set_timeout(self, timeout):
897 """
898 Set session timeout
899
900 :param timeout: The timeout in seconds
901 :return: The previous session timeout
902 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500903 if not isinstance(timeout, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800904 raise TypeError("timeout must be an integer")
905
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500906 return _lib.SSL_CTX_set_timeout(self._context, timeout)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800907
908
909 def get_timeout(self):
910 """
911 Get the session timeout
912
913 :return: The session timeout
914 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500915 return _lib.SSL_CTX_get_timeout(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800916
917
918 def set_info_callback(self, callback):
919 """
920 Set the info callback
921
922 :param callback: The Python callback to use
923 :return: None
924 """
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800925 @wraps(callback)
926 def wrapper(ssl, where, return_code):
Jean-Paul Calderonef2bbc9c2014-02-02 10:59:14 -0500927 callback(Connection._reverse_mapping[ssl], where, return_code)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500928 self._info_callback = _ffi.callback(
929 "void (*)(const SSL *, int, int)", wrapper)
930 _lib.SSL_CTX_set_info_callback(self._context, self._info_callback)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800931
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800932
933 def get_app_data(self):
934 """
935 Get the application data (supplied via set_app_data())
936
937 :return: The application data
938 """
939 return self._app_data
940
941
942 def set_app_data(self, data):
943 """
944 Set the application data (will be returned from get_app_data())
945
946 :param data: Any Python object
947 :return: None
948 """
949 self._app_data = data
950
951
952 def get_cert_store(self):
953 """
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500954 Get the certificate store for the context.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800955
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500956 :return: A X509Store object or None if it does not have one.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800957 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500958 store = _lib.SSL_CTX_get_cert_store(self._context)
959 if store == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500960 # TODO: This is untested.
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800961 return None
962
963 pystore = X509Store.__new__(X509Store)
964 pystore._store = store
965 return pystore
966
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800967
968 def set_options(self, options):
969 """
970 Add options. Options set before are not cleared!
971
972 :param options: The options to add.
973 :return: The new option bitmask.
974 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500975 if not isinstance(options, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800976 raise TypeError("options must be an integer")
977
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500978 return _lib.SSL_CTX_set_options(self._context, options)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800979
980
981 def set_mode(self, mode):
982 """
983 Add modes via bitmask. Modes set before are not cleared!
984
985 :param mode: The mode to add.
986 :return: The new mode bitmask.
987 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500988 if not isinstance(mode, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800989 raise TypeError("mode must be an integer")
990
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500991 return _lib.SSL_CTX_set_mode(self._context, mode)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800992
993
994 def set_tlsext_servername_callback(self, callback):
995 """
996 Specify a callback function to be called when clients specify a server name.
997
998 :param callback: The callback function. It will be invoked with one
999 argument, the Connection instance.
1000 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001001 @wraps(callback)
1002 def wrapper(ssl, alert, arg):
1003 callback(Connection._reverse_mapping[ssl])
1004 return 0
1005
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001006 self._tlsext_servername_callback = _ffi.callback(
1007 "int (*)(const SSL *, int *, void *)", wrapper)
1008 _lib.SSL_CTX_set_tlsext_servername_callback(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001009 self._context, self._tlsext_servername_callback)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -08001010
Cory Benfield84a121e2014-03-31 20:30:25 +01001011
Cory Benfield10b277f2015-04-13 17:12:42 -04001012 @_requires_npn
Cory Benfield84a121e2014-03-31 20:30:25 +01001013 def set_npn_advertise_callback(self, callback):
1014 """
Cory Benfieldbe3e7b82014-05-10 09:48:55 +01001015 Specify a callback function that will be called when offering `Next
1016 Protocol Negotiation
1017 <https://technotes.googlecode.com/git/nextprotoneg.html>`_ as a server.
Cory Benfield84a121e2014-03-31 20:30:25 +01001018
1019 :param callback: The callback function. It will be invoked with one
Cory Benfieldbe3e7b82014-05-10 09:48:55 +01001020 argument, the Connection instance. It should return a list of
1021 bytestrings representing the advertised protocols, like
1022 ``[b'http/1.1', b'spdy/2']``.
Cory Benfield84a121e2014-03-31 20:30:25 +01001023 """
Cory Benfield0ea76e72015-03-22 09:05:28 +00001024 self._npn_advertise_helper = _NpnAdvertiseHelper(callback)
1025 self._npn_advertise_callback = self._npn_advertise_helper.callback
Cory Benfield84a121e2014-03-31 20:30:25 +01001026 _lib.SSL_CTX_set_next_protos_advertised_cb(
1027 self._context, self._npn_advertise_callback, _ffi.NULL)
1028
1029
Cory Benfield10b277f2015-04-13 17:12:42 -04001030 @_requires_npn
Cory Benfield84a121e2014-03-31 20:30:25 +01001031 def set_npn_select_callback(self, callback):
1032 """
1033 Specify a callback function that will be called when a server offers
1034 Next Protocol Negotiation options.
1035
1036 :param callback: The callback function. It will be invoked with two
1037 arguments: the Connection, and a list of offered protocols as
Cory Benfieldbe3e7b82014-05-10 09:48:55 +01001038 bytestrings, e.g. ``[b'http/1.1', b'spdy/2']``. It should return
1039 one of those bytestrings, the chosen protocol.
Cory Benfield84a121e2014-03-31 20:30:25 +01001040 """
Cory Benfield0ea76e72015-03-22 09:05:28 +00001041 self._npn_select_helper = _NpnSelectHelper(callback)
1042 self._npn_select_callback = self._npn_select_helper.callback
Cory Benfield84a121e2014-03-31 20:30:25 +01001043 _lib.SSL_CTX_set_next_proto_select_cb(
1044 self._context, self._npn_select_callback, _ffi.NULL)
1045
Cory Benfield7907e332015-04-13 17:18:25 -04001046 @_requires_alpn
Cory Benfield12eae892014-06-07 15:42:56 +01001047 def set_alpn_protos(self, protos):
1048 """
Cory Benfielde8e9c382015-04-11 17:33:48 -04001049 Specify the clients ALPN protocol list.
1050
1051 These protocols are offered to the server during protocol negotiation.
Cory Benfield12eae892014-06-07 15:42:56 +01001052
1053 :param protos: A list of the protocols to be offered to the server.
1054 This list should be a Python list of bytestrings representing the
1055 protocols to offer, e.g. ``[b'http/1.1', b'spdy/2']``.
1056 """
1057 # Take the list of protocols and join them together, prefixing them
1058 # with their lengths.
1059 protostr = b''.join(
1060 chain.from_iterable((int2byte(len(p)), p) for p in protos)
1061 )
1062
1063 # Build a C string from the list. We don't need to save this off
1064 # because OpenSSL immediately copies the data out.
1065 input_str = _ffi.new("unsigned char[]", protostr)
Cory Benfielde871af52015-04-11 17:57:50 -04001066 input_str_len = _ffi.cast("unsigned", len(protostr))
1067 _lib.SSL_CTX_set_alpn_protos(self._context, input_str, input_str_len)
Cory Benfield12eae892014-06-07 15:42:56 +01001068
Cory Benfield7907e332015-04-13 17:18:25 -04001069 @_requires_alpn
Cory Benfield12eae892014-06-07 15:42:56 +01001070 def set_alpn_select_callback(self, callback):
1071 """
Cory Benfielde8e9c382015-04-11 17:33:48 -04001072 Set the callback to handle ALPN protocol choice.
Cory Benfield12eae892014-06-07 15:42:56 +01001073
1074 :param callback: The callback function. It will be invoked with two
1075 arguments: the Connection, and a list of offered protocols as
1076 bytestrings, e.g ``[b'http/1.1', b'spdy/2']``. It should return
Cory Benfielde8e9c382015-04-11 17:33:48 -04001077 one of those bytestrings, the chosen protocol.
Cory Benfield12eae892014-06-07 15:42:56 +01001078 """
Cory Benfield9da5ffb2015-04-13 17:20:14 -04001079 self._alpn_select_helper = _ALPNSelectHelper(callback)
Cory Benfieldf1177e72015-04-12 09:11:49 -04001080 self._alpn_select_callback = self._alpn_select_helper.callback
Cory Benfield12eae892014-06-07 15:42:56 +01001081 _lib.SSL_CTX_set_alpn_select_cb(
1082 self._context, self._alpn_select_callback, _ffi.NULL)
1083
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -08001084ContextType = Context
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001085
1086
1087
1088class Connection(object):
1089 """
1090 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001091 _reverse_mapping = WeakValueDictionary()
1092
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001093 def __init__(self, context, socket=None):
1094 """
1095 Create a new Connection object, using the given OpenSSL.SSL.Context
1096 instance and socket.
1097
1098 :param context: An SSL Context to use for this connection
1099 :param socket: The socket to use for transport layer
1100 """
1101 if not isinstance(context, Context):
1102 raise TypeError("context must be a Context instance")
1103
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001104 ssl = _lib.SSL_new(context._context)
1105 self._ssl = _ffi.gc(ssl, _lib.SSL_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001106 self._context = context
1107
Cory Benfieldbe3e7b82014-05-10 09:48:55 +01001108 # References to strings used for Next Protocol Negotiation. OpenSSL's
1109 # header files suggest that these might get copied at some point, but
1110 # doesn't specify when, so we store them here to make sure they don't
1111 # get freed before OpenSSL uses them.
1112 self._npn_advertise_callback_args = None
1113 self._npn_select_callback_args = None
1114
Cory Benfield12eae892014-06-07 15:42:56 +01001115 # References to strings used for Application Layer Protocol
1116 # Negotiation. These strings get copied at some point but it's well
1117 # after the callback returns, so we have to hang them somewhere to
1118 # avoid them getting freed.
1119 self._alpn_select_callback_args = None
1120
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001121 self._reverse_mapping[self._ssl] = self
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001122
1123 if socket is None:
1124 self._socket = None
Jean-Paul Calderone73b15c22013-03-05 18:30:39 -08001125 # Don't set up any gc for these, SSL_free will take care of them.
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001126 self._into_ssl = _lib.BIO_new(_lib.BIO_s_mem())
1127 self._from_ssl = _lib.BIO_new(_lib.BIO_s_mem())
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001128
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001129 if self._into_ssl == _ffi.NULL or self._from_ssl == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001130 # TODO: This is untested.
1131 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001132
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001133 _lib.SSL_set_bio(self._ssl, self._into_ssl, self._from_ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001134 else:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001135 self._into_ssl = None
1136 self._from_ssl = None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001137 self._socket = socket
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001138 set_result = _lib.SSL_set_fd(self._ssl, _asFileDescriptor(self._socket))
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001139 if not set_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001140 # TODO: This is untested.
1141 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001142
1143
1144 def __getattr__(self, name):
1145 """
1146 Look up attributes on the wrapped socket object if they are not found on
1147 the Connection object.
1148 """
kjav0b66fa12015-09-02 11:51:26 +01001149 if self._socket is None:
1150 raise AttributeError("'" + self.__class__.__name__ + "' object has no attribute '" + name + "'")
1151 else:
1152 return getattr(self._socket, name)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001153
1154
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001155 def _raise_ssl_error(self, ssl, result):
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -08001156 if self._context._verify_helper is not None:
1157 self._context._verify_helper.raise_if_problem()
Cory Benfield0ea76e72015-03-22 09:05:28 +00001158 if self._context._npn_advertise_helper is not None:
1159 self._context._npn_advertise_helper.raise_if_problem()
1160 if self._context._npn_select_helper is not None:
1161 self._context._npn_select_helper.raise_if_problem()
Cory Benfieldf1177e72015-04-12 09:11:49 -04001162 if self._context._alpn_select_helper is not None:
1163 self._context._alpn_select_helper.raise_if_problem()
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -08001164
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001165 error = _lib.SSL_get_error(ssl, result)
1166 if error == _lib.SSL_ERROR_WANT_READ:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001167 raise WantReadError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001168 elif error == _lib.SSL_ERROR_WANT_WRITE:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001169 raise WantWriteError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001170 elif error == _lib.SSL_ERROR_ZERO_RETURN:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001171 raise ZeroReturnError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001172 elif error == _lib.SSL_ERROR_WANT_X509_LOOKUP:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001173 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001174 raise WantX509LookupError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001175 elif error == _lib.SSL_ERROR_SYSCALL:
1176 if _lib.ERR_peek_error() == 0:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001177 if result < 0:
Konstantinos Koukopoulos541150d2014-01-31 01:00:19 +02001178 if platform == "win32":
1179 errno = _ffi.getwinerror()[0]
1180 else:
1181 errno = _ffi.errno
Glyph3afdba82015-04-14 17:30:53 -04001182 raise SysCallError(errno, errorcode.get(errno))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001183 else:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001184 raise SysCallError(-1, "Unexpected EOF")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001185 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001186 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001187 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001188 elif error == _lib.SSL_ERROR_NONE:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001189 pass
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001190 else:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001191 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001192
1193
1194 def get_context(self):
1195 """
1196 Get session context
1197 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001198 return self._context
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001199
1200
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001201 def set_context(self, context):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001202 """
1203 Switch this connection to a new session context
1204
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001205 :param context: A :py:class:`Context` instance giving the new session
1206 context to use.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001207 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001208 if not isinstance(context, Context):
1209 raise TypeError("context must be a Context instance")
1210
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001211 _lib.SSL_set_SSL_CTX(self._ssl, context._context)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001212 self._context = context
1213
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001214
1215 def get_servername(self):
1216 """
1217 Retrieve the servername extension value if provided in the client hello
1218 message, or None if there wasn't one.
1219
1220 :return: A byte string giving the server name or :py:data:`None`.
1221 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001222 name = _lib.SSL_get_servername(self._ssl, _lib.TLSEXT_NAMETYPE_host_name)
1223 if name == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001224 return None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001225
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001226 return _ffi.string(name)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001227
1228
1229 def set_tlsext_host_name(self, name):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001230 """
1231 Set the value of the servername extension to send in the client hello.
1232
1233 :param name: A byte string giving the name.
1234 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001235 if not isinstance(name, bytes):
1236 raise TypeError("name must be a byte string")
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001237 elif b"\0" in name:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001238 raise TypeError("name must not contain NUL byte")
1239
1240 # XXX I guess this can fail sometimes?
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001241 _lib.SSL_set_tlsext_host_name(self._ssl, name)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001242
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001243
1244 def pending(self):
1245 """
1246 Get the number of bytes that can be safely read from the connection
1247
1248 :return: The number of bytes available in the receive buffer.
1249 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001250 return _lib.SSL_pending(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001251
1252
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001253 def send(self, buf, flags=0):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001254 """
1255 Send data on the connection. NOTE: If you get one of the WantRead,
1256 WantWrite or WantX509Lookup exceptions on this, you have to call the
1257 method again with the SAME buffer.
1258
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001259 :param buf: The string, buffer or memoryview to send
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001260 :param flags: (optional) Included for compatibility with the socket
1261 API, the value is ignored
1262 :return: The number of bytes written
1263 """
Abraham Martine82326c2015-02-04 10:18:10 +00001264 # Backward compatibility
Jean-Paul Calderone39a8d592015-04-13 20:49:50 -04001265 buf = _text_to_bytes_and_warn("buf", buf)
Abraham Martine82326c2015-02-04 10:18:10 +00001266
Jean-Paul Calderone8fb53182013-12-30 08:35:49 -05001267 if isinstance(buf, _memoryview):
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -08001268 buf = buf.tobytes()
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001269 if isinstance(buf, _buffer):
1270 buf = str(buf)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001271 if not isinstance(buf, bytes):
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001272 raise TypeError("data must be a memoryview, buffer or byte string")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001273
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001274 result = _lib.SSL_write(self._ssl, buf, len(buf))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001275 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001276 return result
1277 write = send
1278
1279
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001280 def sendall(self, buf, flags=0):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001281 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001282 Send "all" data on the connection. This calls send() repeatedly until
1283 all data is sent. If an error occurs, it's impossible to tell how much
1284 data has been sent.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001285
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001286 :param buf: The string, buffer or memoryview to send
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001287 :param flags: (optional) Included for compatibility with the socket
1288 API, the value is ignored
1289 :return: The number of bytes written
1290 """
Jean-Paul Calderone39a8d592015-04-13 20:49:50 -04001291 buf = _text_to_bytes_and_warn("buf", buf)
Abraham Martine82326c2015-02-04 10:18:10 +00001292
Jean-Paul Calderone8fb53182013-12-30 08:35:49 -05001293 if isinstance(buf, _memoryview):
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -08001294 buf = buf.tobytes()
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001295 if isinstance(buf, _buffer):
1296 buf = str(buf)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001297 if not isinstance(buf, bytes):
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001298 raise TypeError("buf must be a memoryview, buffer or byte string")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001299
1300 left_to_send = len(buf)
1301 total_sent = 0
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001302 data = _ffi.new("char[]", buf)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001303
1304 while left_to_send:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001305 result = _lib.SSL_write(self._ssl, data + total_sent, left_to_send)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001306 self._raise_ssl_error(self._ssl, result)
1307 total_sent += result
1308 left_to_send -= result
1309
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001310
1311 def recv(self, bufsiz, flags=None):
1312 """
1313 Receive data on the connection. NOTE: If you get one of the WantRead,
1314 WantWrite or WantX509Lookup exceptions on this, you have to call the
1315 method again with the SAME buffer.
1316
1317 :param bufsiz: The maximum number of bytes to read
Maximilian Hils1d95dea2015-08-17 19:27:20 +02001318 :param flags: (optional) The only supported flag is ``MSG_PEEK``,
1319 all other flags are ignored.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001320 :return: The string read from the Connection
1321 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001322 buf = _ffi.new("char[]", bufsiz)
Maximilian Hils1d95dea2015-08-17 19:27:20 +02001323 if flags is not None and flags & socket.MSG_PEEK:
1324 result = _lib.SSL_peek(self._ssl, buf, bufsiz)
1325 else:
1326 result = _lib.SSL_read(self._ssl, buf, bufsiz)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001327 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001328 return _ffi.buffer(buf, result)[:]
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001329 read = recv
1330
1331
Cory Benfield62d10332014-06-15 10:03:41 +01001332 def recv_into(self, buffer, nbytes=None, flags=None):
1333 """
1334 Receive data on the connection and store the data into a buffer rather
1335 than creating a new string.
1336
1337 :param buffer: The buffer to copy into.
1338 :param nbytes: (optional) The maximum number of bytes to read into the
1339 buffer. If not present, defaults to the size of the buffer. If
1340 larger than the size of the buffer, is reduced to the size of the
1341 buffer.
Maximilian Hils1d95dea2015-08-17 19:27:20 +02001342 :param flags: (optional) The only supported flag is ``MSG_PEEK``,
1343 all other flags are ignored.
Cory Benfield62d10332014-06-15 10:03:41 +01001344 :return: The number of bytes read into the buffer.
1345 """
1346 if nbytes is None:
1347 nbytes = len(buffer)
1348 else:
1349 nbytes = min(nbytes, len(buffer))
1350
1351 # We need to create a temporary buffer. This is annoying, it would be
1352 # better if we could pass memoryviews straight into the SSL_read call,
1353 # but right now we can't. Revisit this if CFFI gets that ability.
1354 buf = _ffi.new("char[]", nbytes)
Maximilian Hils1d95dea2015-08-17 19:27:20 +02001355 if flags is not None and flags & socket.MSG_PEEK:
1356 result = _lib.SSL_peek(self._ssl, buf, nbytes)
1357 else:
1358 result = _lib.SSL_read(self._ssl, buf, nbytes)
Cory Benfield62d10332014-06-15 10:03:41 +01001359 self._raise_ssl_error(self._ssl, result)
1360
1361 # This strange line is all to avoid a memory copy. The buffer protocol
1362 # should allow us to assign a CFFI buffer to the LHS of this line, but
1363 # on CPython 3.3+ that segfaults. As a workaround, we can temporarily
1364 # wrap it in a memoryview, except on Python 2.6 which doesn't have a
1365 # memoryview type.
1366 try:
1367 buffer[:result] = memoryview(_ffi.buffer(buf, result))
1368 except NameError:
1369 buffer[:result] = _ffi.buffer(buf, result)
1370
1371 return result
1372
1373
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001374 def _handle_bio_errors(self, bio, result):
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001375 if _lib.BIO_should_retry(bio):
1376 if _lib.BIO_should_read(bio):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001377 raise WantReadError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001378 elif _lib.BIO_should_write(bio):
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001379 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001380 raise WantWriteError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001381 elif _lib.BIO_should_io_special(bio):
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001382 # TODO: This is untested. I think io_special means the socket
1383 # BIO has a not-yet connected socket.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001384 raise ValueError("BIO_should_io_special")
1385 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001386 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001387 raise ValueError("unknown bio failure")
1388 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001389 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001390 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001391
1392
1393 def bio_read(self, bufsiz):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001394 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001395 When using non-socket connections this function reads the "dirty" data
1396 that would have traveled away on the network.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001397
1398 :param bufsiz: The maximum number of bytes to read
1399 :return: The string read.
1400 """
Jean-Paul Calderone97e041d2013-03-05 21:03:12 -08001401 if self._from_ssl is None:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001402 raise TypeError("Connection sock was not None")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001403
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -05001404 if not isinstance(bufsiz, integer_types):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001405 raise TypeError("bufsiz must be an integer")
1406
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001407 buf = _ffi.new("char[]", bufsiz)
1408 result = _lib.BIO_read(self._from_ssl, buf, bufsiz)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001409 if result <= 0:
1410 self._handle_bio_errors(self._from_ssl, result)
1411
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001412 return _ffi.buffer(buf, result)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001413
1414
1415 def bio_write(self, buf):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001416 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001417 When using non-socket connections this function sends "dirty" data that
1418 would have traveled in on the network.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001419
1420 :param buf: The string to put into the memory BIO.
1421 :return: The number of bytes written
1422 """
Jean-Paul Calderone39a8d592015-04-13 20:49:50 -04001423 buf = _text_to_bytes_and_warn("buf", buf)
Abraham Martine82326c2015-02-04 10:18:10 +00001424
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001425 if self._into_ssl is None:
1426 raise TypeError("Connection sock was not None")
1427
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001428 result = _lib.BIO_write(self._into_ssl, buf, len(buf))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001429 if result <= 0:
1430 self._handle_bio_errors(self._into_ssl, result)
1431 return result
1432
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001433
1434 def renegotiate(self):
1435 """
1436 Renegotiate the session
1437
1438 :return: True if the renegotiation can be started, false otherwise
1439 """
1440
1441 def do_handshake(self):
1442 """
1443 Perform an SSL handshake (usually called after renegotiate() or one of
1444 set_*_state()). This can raise the same exceptions as send and recv.
1445
1446 :return: None.
1447 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001448 result = _lib.SSL_do_handshake(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001449 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001450
1451
1452 def renegotiate_pending(self):
1453 """
1454 Check if there's a renegotiation in progress, it will return false once
1455 a renegotiation is finished.
1456
1457 :return: Whether there's a renegotiation in progress
1458 """
1459
1460 def total_renegotiations(self):
1461 """
1462 Find out the total number of renegotiations.
1463
1464 :return: The number of renegotiations.
1465 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001466 return _lib.SSL_total_renegotiations(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001467
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001468
1469 def connect(self, addr):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001470 """
1471 Connect to remote host and set up client-side SSL
1472
1473 :param addr: A remote address
1474 :return: What the socket's connect method returns
1475 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001476 _lib.SSL_set_connect_state(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001477 return self._socket.connect(addr)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001478
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001479
1480 def connect_ex(self, addr):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001481 """
1482 Connect to remote host and set up client-side SSL. Note that if the socket's
1483 connect_ex method doesn't return 0, SSL won't be initialized.
1484
1485 :param addr: A remove address
1486 :return: What the socket's connect_ex method returns
1487 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001488 connect_ex = self._socket.connect_ex
1489 self.set_connect_state()
1490 return connect_ex(addr)
1491
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001492
1493 def accept(self):
1494 """
1495 Accept incoming connection and set up SSL on it
1496
1497 :return: A (conn,addr) pair where conn is a Connection and addr is an
1498 address
1499 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001500 client, addr = self._socket.accept()
1501 conn = Connection(self._context, client)
1502 conn.set_accept_state()
1503 return (conn, addr)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001504
1505
1506 def bio_shutdown(self):
1507 """
1508 When using non-socket connections this function signals end of
1509 data on the input for this connection.
1510
1511 :return: None
1512 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001513 if self._from_ssl is None:
1514 raise TypeError("Connection sock was not None")
1515
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001516 _lib.BIO_set_mem_eof_return(self._into_ssl, 0)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001517
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001518
1519 def shutdown(self):
1520 """
1521 Send closure alert
1522
1523 :return: True if the shutdown completed successfully (i.e. both sides
1524 have sent closure alerts), false otherwise (i.e. you have to
1525 wait for a ZeroReturnError on a recv() method call
1526 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001527 result = _lib.SSL_shutdown(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001528 if result < 0:
Paul Aurichbff1d1a2015-01-08 08:36:53 -08001529 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001530 elif result > 0:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001531 return True
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001532 else:
1533 return False
1534
1535
1536 def get_cipher_list(self):
1537 """
1538 Get the session cipher list
1539
1540 :return: A list of cipher strings
1541 """
1542 ciphers = []
1543 for i in count():
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001544 result = _lib.SSL_get_cipher_list(self._ssl, i)
1545 if result == _ffi.NULL:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001546 break
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001547 ciphers.append(_native(_ffi.string(result)))
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001548 return ciphers
1549
1550
1551 def get_client_ca_list(self):
1552 """
1553 Get CAs whose certificates are suggested for client authentication.
1554
1555 :return: If this is a server connection, a list of X509Names representing
1556 the acceptable CAs as set by :py:meth:`OpenSSL.SSL.Context.set_client_ca_list` or
1557 :py:meth:`OpenSSL.SSL.Context.add_client_ca`. If this is a client connection,
1558 the list of such X509Names sent by the server, or an empty list if that
1559 has not yet happened.
1560 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001561 ca_names = _lib.SSL_get_client_CA_list(self._ssl)
1562 if ca_names == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001563 # TODO: This is untested.
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001564 return []
1565
1566 result = []
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001567 for i in range(_lib.sk_X509_NAME_num(ca_names)):
1568 name = _lib.sk_X509_NAME_value(ca_names, i)
1569 copy = _lib.X509_NAME_dup(name)
1570 if copy == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001571 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001572 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001573
1574 pyname = X509Name.__new__(X509Name)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001575 pyname._name = _ffi.gc(copy, _lib.X509_NAME_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001576 result.append(pyname)
1577 return result
1578
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001579
1580 def makefile(self):
1581 """
1582 The makefile() method is not implemented, since there is no dup semantics
1583 for SSL connections
1584
Jean-Paul Calderone6749ec22014-04-17 16:30:21 -04001585 :raise: NotImplementedError
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001586 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001587 raise NotImplementedError("Cannot make file object of OpenSSL.SSL.Connection")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001588
1589
1590 def get_app_data(self):
1591 """
1592 Get application data
1593
1594 :return: The application data
1595 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001596 return self._app_data
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001597
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001598
1599 def set_app_data(self, data):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001600 """
1601 Set application data
1602
1603 :param data - The application data
1604 :return: None
1605 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001606 self._app_data = data
1607
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001608
1609 def get_shutdown(self):
1610 """
1611 Get shutdown state
1612
1613 :return: The shutdown state, a bitvector of SENT_SHUTDOWN, RECEIVED_SHUTDOWN.
1614 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001615 return _lib.SSL_get_shutdown(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001616
1617
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001618 def set_shutdown(self, state):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001619 """
1620 Set shutdown state
1621
1622 :param state - bitvector of SENT_SHUTDOWN, RECEIVED_SHUTDOWN.
1623 :return: None
1624 """
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -05001625 if not isinstance(state, integer_types):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001626 raise TypeError("state must be an integer")
1627
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001628 _lib.SSL_set_shutdown(self._ssl, state)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001629
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001630
1631 def state_string(self):
1632 """
1633 Get a verbose state description
1634
1635 :return: A string representing the state
1636 """
1637
1638 def server_random(self):
1639 """
1640 Get a copy of the server hello nonce.
1641
1642 :return: A string representing the state
1643 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001644 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001645 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001646 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001647 self._ssl.s3.server_random,
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001648 _lib.SSL3_RANDOM_SIZE)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001649
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001650
1651 def client_random(self):
1652 """
1653 Get a copy of the client hello nonce.
1654
1655 :return: A string representing the state
1656 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001657 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001658 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001659 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001660 self._ssl.s3.client_random,
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001661 _lib.SSL3_RANDOM_SIZE)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001662
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001663
1664 def master_key(self):
1665 """
1666 Get a copy of the master key.
1667
1668 :return: A string representing the state
1669 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001670 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001671 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001672 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001673 self._ssl.session.master_key,
1674 self._ssl.session.master_key_length)[:]
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001675
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001676
1677 def sock_shutdown(self, *args, **kwargs):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001678 """
1679 See shutdown(2)
1680
1681 :return: What the socket's shutdown() method returns
1682 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001683 return self._socket.shutdown(*args, **kwargs)
1684
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001685
1686 def get_peer_certificate(self):
1687 """
1688 Retrieve the other side's certificate (if any)
1689
1690 :return: The peer's certificate
1691 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001692 cert = _lib.SSL_get_peer_certificate(self._ssl)
1693 if cert != _ffi.NULL:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001694 pycert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001695 pycert._x509 = _ffi.gc(cert, _lib.X509_free)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001696 return pycert
1697 return None
1698
1699
1700 def get_peer_cert_chain(self):
1701 """
1702 Retrieve the other side's certificate (if any)
1703
1704 :return: A list of X509 instances giving the peer's certificate chain,
1705 or None if it does not have one.
1706 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001707 cert_stack = _lib.SSL_get_peer_cert_chain(self._ssl)
1708 if cert_stack == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001709 return None
1710
1711 result = []
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001712 for i in range(_lib.sk_X509_num(cert_stack)):
Jean-Paul Calderone73b15c22013-03-05 18:30:39 -08001713 # TODO could incref instead of dup here
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001714 cert = _lib.X509_dup(_lib.sk_X509_value(cert_stack, i))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001715 pycert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001716 pycert._x509 = _ffi.gc(cert, _lib.X509_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001717 result.append(pycert)
1718 return result
1719
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001720
1721 def want_read(self):
1722 """
1723 Checks if more data has to be read from the transport layer to complete an
1724 operation.
1725
1726 :return: True iff more data has to be read
1727 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001728 return _lib.SSL_want_read(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001729
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001730
1731 def want_write(self):
1732 """
1733 Checks if there is data to write to the transport layer to complete an
1734 operation.
1735
1736 :return: True iff there is data to write
1737 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001738 return _lib.SSL_want_write(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001739
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001740
1741 def set_accept_state(self):
1742 """
1743 Set the connection to work in server 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_accept_state(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001749
1750
1751 def set_connect_state(self):
1752 """
1753 Set the connection to work in client mode. The handshake will be handled
1754 automatically by read/write.
1755
1756 :return: None
1757 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001758 _lib.SSL_set_connect_state(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001759
1760
1761 def get_session(self):
1762 """
1763 Returns the Session currently used.
1764
1765 @return: An instance of :py:class:`OpenSSL.SSL.Session` or :py:obj:`None` if
1766 no session exists.
1767 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001768 session = _lib.SSL_get1_session(self._ssl)
1769 if session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001770 return None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001771
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001772 pysession = Session.__new__(Session)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001773 pysession._session = _ffi.gc(session, _lib.SSL_SESSION_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001774 return pysession
1775
1776
1777 def set_session(self, session):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001778 """
1779 Set the session to be used when the TLS/SSL connection is established.
1780
1781 :param session: A Session instance representing the session to use.
1782 :returns: None
1783 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001784 if not isinstance(session, Session):
1785 raise TypeError("session must be a Session instance")
1786
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001787 result = _lib.SSL_set_session(self._ssl, session._session)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001788 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001789 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001790
Jean-Paul Calderonedbd76272014-03-29 18:09:40 -04001791
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001792 def _get_finished_message(self, function):
1793 """
1794 Helper to implement :py:meth:`get_finished` and
1795 :py:meth:`get_peer_finished`.
1796
1797 :param function: Either :py:data:`SSL_get_finished`: or
1798 :py:data:`SSL_get_peer_finished`.
1799
1800 :return: :py:data:`None` if the desired message has not yet been
1801 received, otherwise the contents of the message.
1802 :rtype: :py:class:`bytes` or :py:class:`NoneType`
1803 """
Jean-Paul Calderone01af9042014-03-30 11:40:42 -04001804 # The OpenSSL documentation says nothing about what might happen if the
1805 # count argument given is zero. Specifically, it doesn't say whether
1806 # the output buffer may be NULL in that case or not. Inspection of the
1807 # implementation reveals that it calls memcpy() unconditionally.
1808 # Section 7.1.4, paragraph 1 of the C standard suggests that
1809 # memcpy(NULL, source, 0) is not guaranteed to produce defined (let
1810 # alone desirable) behavior (though it probably does on just about
1811 # every implementation...)
1812 #
1813 # Allocate a tiny buffer to pass in (instead of just passing NULL as
1814 # one might expect) for the initial call so as to be safe against this
1815 # potentially undefined behavior.
1816 empty = _ffi.new("char[]", 0)
1817 size = function(self._ssl, empty, 0)
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001818 if size == 0:
1819 # No Finished message so far.
1820 return None
1821
1822 buf = _ffi.new("char[]", size)
1823 function(self._ssl, buf, size)
1824 return _ffi.buffer(buf, size)[:]
1825
1826
Fedor Brunner5747b932014-03-05 14:22:34 +01001827 def get_finished(self):
1828 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001829 Obtain the latest `handshake finished` message sent to the peer.
Fedor Brunner5747b932014-03-05 14:22:34 +01001830
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001831 :return: The contents of the message or :py:obj:`None` if the TLS
1832 handshake has not yet completed.
1833 :rtype: :py:class:`bytes` or :py:class:`NoneType`
Fedor Brunner5747b932014-03-05 14:22:34 +01001834 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001835 return self._get_finished_message(_lib.SSL_get_finished)
1836
Fedor Brunner5747b932014-03-05 14:22:34 +01001837
1838 def get_peer_finished(self):
1839 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001840 Obtain the latest `handshake finished` message received from the peer.
Fedor Brunner5747b932014-03-05 14:22:34 +01001841
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001842 :return: The contents of the message or :py:obj:`None` if the TLS
1843 handshake has not yet completed.
1844 :rtype: :py:class:`bytes` or :py:class:`NoneType`
Fedor Brunner5747b932014-03-05 14:22:34 +01001845 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001846 return self._get_finished_message(_lib.SSL_get_peer_finished)
Fedor Brunner5747b932014-03-05 14:22:34 +01001847
Jean-Paul Calderone7c556ef2014-03-30 10:45:00 -04001848
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001849 def get_cipher_name(self):
1850 """
1851 Obtain the name of the currently used cipher.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001852
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001853 :returns: The name of the currently used cipher or :py:obj:`None`
1854 if no connection has been established.
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001855 :rtype: :py:class:`unicode` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001856 """
1857 cipher = _lib.SSL_get_current_cipher(self._ssl)
1858 if cipher == _ffi.NULL:
1859 return None
1860 else:
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001861 name = _ffi.string(_lib.SSL_CIPHER_get_name(cipher))
1862 return name.decode("utf-8")
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001863
Jean-Paul Calderonedbd76272014-03-29 18:09:40 -04001864
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001865 def get_cipher_bits(self):
1866 """
1867 Obtain the number of secret bits of the currently used cipher.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001868
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001869 :returns: The number of secret bits of the currently used cipher
1870 or :py:obj:`None` if no connection has been established.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001871 :rtype: :py:class:`int` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001872 """
1873 cipher = _lib.SSL_get_current_cipher(self._ssl)
1874 if cipher == _ffi.NULL:
1875 return None
1876 else:
1877 return _lib.SSL_CIPHER_get_bits(cipher, _ffi.NULL)
1878
Jean-Paul Calderonedbd76272014-03-29 18:09:40 -04001879
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001880 def get_cipher_version(self):
1881 """
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001882 Obtain the protocol version of the currently used cipher.
1883
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001884 :returns: The protocol name of the currently used cipher
1885 or :py:obj:`None` if no connection has been established.
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001886 :rtype: :py:class:`unicode` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001887 """
1888 cipher = _lib.SSL_get_current_cipher(self._ssl)
1889 if cipher == _ffi.NULL:
1890 return None
1891 else:
Alex Gaynorc4889812015-09-04 08:43:17 -04001892 version = _ffi.string(_lib.SSL_CIPHER_get_version(cipher))
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001893 return version.decode("utf-8")
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001894
Cory Benfield10b277f2015-04-13 17:12:42 -04001895
Jim Shaverabff1882015-05-27 09:15:55 -04001896 def get_protocol_version_name(self):
Jim Shaverba65e662015-04-26 12:23:40 -04001897 """
1898 Obtain the protocol version of the current connection.
1899
1900 :returns: The TLS version of the current connection, for example
Jim Shaver58d25732015-05-28 11:52:32 -04001901 the value for TLS 1.2 would be ``TLSv1.2``or ``Unknown``
Jim Shaverb5b6b0e2015-05-28 16:47:36 -04001902 for connections that were not successfully established.
Jim Shaver58d25732015-05-28 11:52:32 -04001903 :rtype: :py:class:`unicode`
Jim Shaverba65e662015-04-26 12:23:40 -04001904 """
Jim Shaverd1c896e2015-05-27 17:50:21 -04001905 version = _ffi.string(_lib.SSL_get_version(self._ssl))
Jim Shaver58d25732015-05-28 11:52:32 -04001906 return version.decode("utf-8")
Jim Shaverb2967922015-04-26 23:58:52 -04001907
Jim Shaverba65e662015-04-26 12:23:40 -04001908
Jim Shaver208438c2015-05-28 09:52:38 -04001909 def get_protocol_version(self):
1910 """
1911 Obtain the protocol version of the current connection.
1912
1913 :returns: The TLS version of the current connection, for example
1914 the value for TLS 1 would be 0x769.
1915 :rtype: :py:class:`int`
1916 """
1917 version = _lib.SSL_version(self._ssl)
1918 return version
1919
1920
Cory Benfield10b277f2015-04-13 17:12:42 -04001921 @_requires_npn
Cory Benfield84a121e2014-03-31 20:30:25 +01001922 def get_next_proto_negotiated(self):
1923 """
1924 Get the protocol that was negotiated by NPN.
1925 """
1926 data = _ffi.new("unsigned char **")
1927 data_len = _ffi.new("unsigned int *")
1928
1929 _lib.SSL_get0_next_proto_negotiated(self._ssl, data, data_len)
1930
Cory Benfieldcd010f62014-05-15 19:00:27 +01001931 return _ffi.buffer(data[0], data_len[0])[:]
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001932
Hynek Schlawackc3717b92015-04-18 12:13:16 +02001933
Cory Benfield7907e332015-04-13 17:18:25 -04001934 @_requires_alpn
Cory Benfield12eae892014-06-07 15:42:56 +01001935 def set_alpn_protos(self, protos):
1936 """
Cory Benfielde8e9c382015-04-11 17:33:48 -04001937 Specify the client's ALPN protocol list.
1938
1939 These protocols are offered to the server during protocol negotiation.
Cory Benfield12eae892014-06-07 15:42:56 +01001940
1941 :param protos: A list of the protocols to be offered to the server.
1942 This list should be a Python list of bytestrings representing the
1943 protocols to offer, e.g. ``[b'http/1.1', b'spdy/2']``.
1944 """
1945 # Take the list of protocols and join them together, prefixing them
1946 # with their lengths.
1947 protostr = b''.join(
1948 chain.from_iterable((int2byte(len(p)), p) for p in protos)
1949 )
1950
1951 # Build a C string from the list. We don't need to save this off
1952 # because OpenSSL immediately copies the data out.
1953 input_str = _ffi.new("unsigned char[]", protostr)
Cory Benfield9c1979a2015-04-12 08:51:52 -04001954 input_str_len = _ffi.cast("unsigned", len(protostr))
1955 _lib.SSL_set_alpn_protos(self._ssl, input_str, input_str_len)
Cory Benfield12eae892014-06-07 15:42:56 +01001956
1957
Maximilian Hils66ded6a2015-08-26 06:02:03 +02001958 @_requires_alpn
Cory Benfield12eae892014-06-07 15:42:56 +01001959 def get_alpn_proto_negotiated(self):
Cory Benfield222f30e2015-04-13 18:10:21 -04001960 """
1961 Get the protocol that was negotiated by ALPN.
1962 """
Cory Benfield12eae892014-06-07 15:42:56 +01001963 data = _ffi.new("unsigned char **")
1964 data_len = _ffi.new("unsigned int *")
1965
1966 _lib.SSL_get0_alpn_selected(self._ssl, data, data_len)
1967
Cory Benfielde8e9c382015-04-11 17:33:48 -04001968 if not data_len:
1969 return b''
1970
Cory Benfield12eae892014-06-07 15:42:56 +01001971 return _ffi.buffer(data[0], data_len[0])[:]
1972
1973
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001974
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001975ConnectionType = Connection
Jean-Paul Calderone11ed8e82014-01-18 10:21:50 -05001976
Jean-Paul Calderonefab157b2014-01-18 11:21:38 -05001977# This is similar to the initialization calls at the end of OpenSSL/crypto.py
1978# but is exercised mostly by the Context initializer.
Jean-Paul Calderone11ed8e82014-01-18 10:21:50 -05001979_lib.SSL_library_init()