blob: 4e0f8a419d873f0df6e1ea9828ff67a43925129f [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
Cory Benfield63759dc2015-04-12 08:57:03 -04008from six import binary_type as _binary_type
Konstantinos Koukopoulosc8b13ea2014-01-28 00:21:50 -08009from six import integer_types as integer_types
Cory Benfieldcd010f62014-05-15 19:00:27 +010010from six import int2byte, indexbytes
Jean-Paul Calderone63eab692014-01-18 10:19:56 -050011
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -050012from OpenSSL._util import (
Hynek Schlawackaa861212016-03-13 13:53:48 +010013 UNSPECIFIED as _UNSPECIFIED,
14 exception_from_error_queue as _exception_from_error_queue,
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -050015 ffi as _ffi,
16 lib as _lib,
Hynek Schlawackf90e3682016-03-11 11:21:13 +010017 make_assert as _make_assert,
Hynek Schlawackaa861212016-03-13 13:53:48 +010018 native as _native,
Jean-Paul Calderone55f9e882015-04-12 09:31:03 -040019 path_string as _path_string,
Hynek Schlawackaa861212016-03-13 13:53:48 +010020 text_to_bytes_and_warn as _text_to_bytes_and_warn,
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
Alex Gaynorbf012872016-06-04 13:18:39 -070062MODE_RELEASE_BUFFERS = _lib.SSL_MODE_RELEASE_BUFFERS
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080063
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050064OP_SINGLE_DH_USE = _lib.SSL_OP_SINGLE_DH_USE
Akihiro Yamazakie64d80c2015-09-06 00:16:57 +090065OP_SINGLE_ECDH_USE = _lib.SSL_OP_SINGLE_ECDH_USE
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050066OP_EPHEMERAL_RSA = _lib.SSL_OP_EPHEMERAL_RSA
67OP_MICROSOFT_SESS_ID_BUG = _lib.SSL_OP_MICROSOFT_SESS_ID_BUG
68OP_NETSCAPE_CHALLENGE_BUG = _lib.SSL_OP_NETSCAPE_CHALLENGE_BUG
Alex Gaynor62da94d2015-09-05 14:37:34 -040069OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG = (
70 _lib.SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG
71)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050072OP_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 Gaynor62da94d2015-09-05 14:37:34 -040087OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG = (
88 _lib.SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG
89)
Alex Gaynorbf012872016-06-04 13:18:39 -070090OP_NO_COMPRESSION = _lib.SSL_OP_NO_COMPRESSION
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -080091
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050092OP_NO_QUERY_MTU = _lib.SSL_OP_NO_QUERY_MTU
93OP_COOKIE_EXCHANGE = _lib.SSL_OP_COOKIE_EXCHANGE
Arturo Filastò5f8c7a82014-03-09 20:01:25 +010094try:
95 OP_NO_TICKET = _lib.SSL_OP_NO_TICKET
96except AttributeError:
97 pass
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -080098
Alex Gaynorc4889812015-09-04 08:43:17 -040099OP_ALL = _lib.SSL_OP_ALL
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -0800100
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500101VERIFY_PEER = _lib.SSL_VERIFY_PEER
102VERIFY_FAIL_IF_NO_PEER_CERT = _lib.SSL_VERIFY_FAIL_IF_NO_PEER_CERT
103VERIFY_CLIENT_ONCE = _lib.SSL_VERIFY_CLIENT_ONCE
104VERIFY_NONE = _lib.SSL_VERIFY_NONE
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -0800105
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500106SESS_CACHE_OFF = _lib.SSL_SESS_CACHE_OFF
107SESS_CACHE_CLIENT = _lib.SSL_SESS_CACHE_CLIENT
108SESS_CACHE_SERVER = _lib.SSL_SESS_CACHE_SERVER
109SESS_CACHE_BOTH = _lib.SSL_SESS_CACHE_BOTH
110SESS_CACHE_NO_AUTO_CLEAR = _lib.SSL_SESS_CACHE_NO_AUTO_CLEAR
111SESS_CACHE_NO_INTERNAL_LOOKUP = _lib.SSL_SESS_CACHE_NO_INTERNAL_LOOKUP
112SESS_CACHE_NO_INTERNAL_STORE = _lib.SSL_SESS_CACHE_NO_INTERNAL_STORE
113SESS_CACHE_NO_INTERNAL = _lib.SSL_SESS_CACHE_NO_INTERNAL
Jean-Paul Calderoned39a3f62013-03-04 12:23:51 -0800114
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500115SSL_ST_CONNECT = _lib.SSL_ST_CONNECT
116SSL_ST_ACCEPT = _lib.SSL_ST_ACCEPT
117SSL_ST_MASK = _lib.SSL_ST_MASK
118SSL_ST_INIT = _lib.SSL_ST_INIT
119SSL_ST_BEFORE = _lib.SSL_ST_BEFORE
120SSL_ST_OK = _lib.SSL_ST_OK
121SSL_ST_RENEGOTIATE = _lib.SSL_ST_RENEGOTIATE
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800122
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500123SSL_CB_LOOP = _lib.SSL_CB_LOOP
124SSL_CB_EXIT = _lib.SSL_CB_EXIT
125SSL_CB_READ = _lib.SSL_CB_READ
126SSL_CB_WRITE = _lib.SSL_CB_WRITE
127SSL_CB_ALERT = _lib.SSL_CB_ALERT
128SSL_CB_READ_ALERT = _lib.SSL_CB_READ_ALERT
129SSL_CB_WRITE_ALERT = _lib.SSL_CB_WRITE_ALERT
130SSL_CB_ACCEPT_LOOP = _lib.SSL_CB_ACCEPT_LOOP
131SSL_CB_ACCEPT_EXIT = _lib.SSL_CB_ACCEPT_EXIT
132SSL_CB_CONNECT_LOOP = _lib.SSL_CB_CONNECT_LOOP
133SSL_CB_CONNECT_EXIT = _lib.SSL_CB_CONNECT_EXIT
134SSL_CB_HANDSHAKE_START = _lib.SSL_CB_HANDSHAKE_START
135SSL_CB_HANDSHAKE_DONE = _lib.SSL_CB_HANDSHAKE_DONE
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800136
Alex Gaynor83284952015-09-05 10:43:30 -0400137
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
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500144_raise_current_error = partial(_exception_from_error_queue, Error)
Hynek Schlawackf90e3682016-03-11 11:21:13 +0100145_openssl_assert = _make_assert(Error)
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500146
147
148class WantReadError(Error):
149 pass
150
151
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500152class WantWriteError(Error):
153 pass
154
155
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500156class WantX509LookupError(Error):
157 pass
158
159
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500160class ZeroReturnError(Error):
161 pass
162
163
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500164class SysCallError(Error):
165 pass
166
167
Cory Benfield0ea76e72015-03-22 09:05:28 +0000168class _CallbackExceptionHelper(object):
169 """
170 A base class for wrapper classes that allow for intelligent exception
171 handling in OpenSSL callbacks.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500172
Jean-Paul Calderone1b172982015-03-22 19:37:11 -0400173 :ivar list _problems: Any exceptions that occurred while executing in a
174 context where they could not be raised in the normal way. Typically
175 this is because OpenSSL has called into some Python code and requires a
176 return value. The exceptions are saved to be raised later when it is
177 possible to do so.
Cory Benfield0ea76e72015-03-22 09:05:28 +0000178 """
Alex Gaynor62da94d2015-09-05 14:37:34 -0400179
Jean-Paul Calderone09540d72015-03-22 19:37:20 -0400180 def __init__(self):
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800181 self._problems = []
182
Cory Benfield0ea76e72015-03-22 09:05:28 +0000183 def raise_if_problem(self):
Jean-Paul Calderone1b172982015-03-22 19:37:11 -0400184 """
185 Raise an exception from the OpenSSL error queue or that was previously
186 captured whe running a callback.
187 """
Cory Benfield0ea76e72015-03-22 09:05:28 +0000188 if self._problems:
189 try:
190 _raise_current_error()
191 except Error:
192 pass
193 raise self._problems.pop(0)
194
195
196class _VerifyHelper(_CallbackExceptionHelper):
Jean-Paul Calderone1b172982015-03-22 19:37:11 -0400197 """
198 Wrap a callback such that it can be used as a certificate verification
199 callback.
200 """
Alex Gaynor62da94d2015-09-05 14:37:34 -0400201
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800202 def __init__(self, callback):
Jean-Paul Calderone837f4032015-03-22 17:38:28 -0400203 _CallbackExceptionHelper.__init__(self)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800204
205 @wraps(callback)
206 def wrapper(ok, store_ctx):
207 cert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500208 cert._x509 = _lib.X509_STORE_CTX_get_current_cert(store_ctx)
209 error_number = _lib.X509_STORE_CTX_get_error(store_ctx)
210 error_depth = _lib.X509_STORE_CTX_get_error_depth(store_ctx)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800211
Jean-Paul Calderone6a8cd112014-04-02 21:09:08 -0400212 index = _lib.SSL_get_ex_data_X509_STORE_CTX_idx()
213 ssl = _lib.X509_STORE_CTX_get_ex_data(store_ctx, index)
214 connection = Connection._reverse_mapping[ssl]
215
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800216 try:
Alex Gaynor62da94d2015-09-05 14:37:34 -0400217 result = callback(
218 connection, cert, error_number, error_depth, ok
219 )
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800220 except Exception as e:
221 self._problems.append(e)
222 return 0
223 else:
224 if result:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500225 _lib.X509_STORE_CTX_set_error(store_ctx, _lib.X509_V_OK)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800226 return 1
227 else:
228 return 0
229
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500230 self.callback = _ffi.callback(
231 "int (*)(int, X509_STORE_CTX *)", wrapper)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800232
233
Cory Benfield0ea76e72015-03-22 09:05:28 +0000234class _NpnAdvertiseHelper(_CallbackExceptionHelper):
Jean-Paul Calderone1b172982015-03-22 19:37:11 -0400235 """
236 Wrap a callback such that it can be used as an NPN advertisement callback.
237 """
Alex Gaynor62da94d2015-09-05 14:37:34 -0400238
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 """
Alex Gaynor62da94d2015-09-05 14:37:34 -0400279
Cory Benfield0ea76e72015-03-22 09:05:28 +0000280 def __init__(self, callback):
Jean-Paul Calderone837f4032015-03-22 17:38:28 -0400281 _CallbackExceptionHelper.__init__(self)
Cory Benfield0ea76e72015-03-22 09:05:28 +0000282
283 @wraps(callback)
284 def wrapper(ssl, out, outlen, in_, inlen, arg):
285 try:
286 conn = Connection._reverse_mapping[ssl]
287
288 # The string passed to us is actually made up of multiple
289 # length-prefixed bytestrings. We need to split that into a
290 # list.
291 instr = _ffi.buffer(in_, inlen)[:]
292 protolist = []
293 while instr:
294 l = indexbytes(instr, 0)
Alex Gaynorca87ff62015-09-04 23:31:03 -0400295 proto = instr[1:l + 1]
Cory Benfield0ea76e72015-03-22 09:05:28 +0000296 protolist.append(proto)
Alex Gaynorca87ff62015-09-04 23:31:03 -0400297 instr = instr[l + 1:]
Cory Benfield0ea76e72015-03-22 09:05:28 +0000298
299 # Call the callback
300 outstr = callback(conn, protolist)
301
302 # Save our callback arguments on the connection object. This is
303 # done to make sure that they don't get freed before OpenSSL
304 # uses them. Then, return them appropriately in the output
305 # parameters.
306 conn._npn_select_callback_args = [
307 _ffi.new("unsigned char *", len(outstr)),
308 _ffi.new("unsigned char[]", outstr),
309 ]
310 outlen[0] = conn._npn_select_callback_args[0][0]
311 out[0] = conn._npn_select_callback_args[1]
312 return 0
313 except Exception as e:
314 self._problems.append(e)
315 return 2 # SSL_TLSEXT_ERR_ALERT_FATAL
316
317 self.callback = _ffi.callback(
Alex Gaynor62da94d2015-09-05 14:37:34 -0400318 ("int (*)(SSL *, unsigned char **, unsigned char *, "
319 "const unsigned char *, unsigned int, void *)"),
Cory Benfield0ea76e72015-03-22 09:05:28 +0000320 wrapper
321 )
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800322
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800323
Cory Benfield9da5ffb2015-04-13 17:20:14 -0400324class _ALPNSelectHelper(_CallbackExceptionHelper):
Cory Benfieldf1177e72015-04-12 09:11:49 -0400325 """
326 Wrap a callback such that it can be used as an ALPN selection callback.
327 """
Alex Gaynor62da94d2015-09-05 14:37:34 -0400328
Cory Benfieldf1177e72015-04-12 09:11:49 -0400329 def __init__(self, callback):
330 _CallbackExceptionHelper.__init__(self)
331
332 @wraps(callback)
333 def wrapper(ssl, out, outlen, in_, inlen, arg):
334 try:
335 conn = Connection._reverse_mapping[ssl]
336
337 # The string passed to us is made up of multiple
338 # length-prefixed bytestrings. We need to split that into a
339 # list.
340 instr = _ffi.buffer(in_, inlen)[:]
341 protolist = []
342 while instr:
Cory Benfield93134db2015-04-13 17:22:13 -0400343 encoded_len = indexbytes(instr, 0)
344 proto = instr[1:encoded_len + 1]
Cory Benfieldf1177e72015-04-12 09:11:49 -0400345 protolist.append(proto)
Cory Benfield93134db2015-04-13 17:22:13 -0400346 instr = instr[encoded_len + 1:]
Cory Benfieldf1177e72015-04-12 09:11:49 -0400347
348 # Call the callback
349 outstr = callback(conn, protolist)
350
351 if not isinstance(outstr, _binary_type):
352 raise TypeError("ALPN callback must return a bytestring.")
353
354 # Save our callback arguments on the connection object to make
355 # sure that they don't get freed before OpenSSL can use them.
356 # Then, return them in the appropriate output parameters.
357 conn._alpn_select_callback_args = [
358 _ffi.new("unsigned char *", len(outstr)),
359 _ffi.new("unsigned char[]", outstr),
360 ]
361 outlen[0] = conn._alpn_select_callback_args[0][0]
362 out[0] = conn._alpn_select_callback_args[1]
363 return 0
364 except Exception as e:
365 self._problems.append(e)
366 return 2 # SSL_TLSEXT_ERR_ALERT_FATAL
367
368 self.callback = _ffi.callback(
Alex Gaynor62da94d2015-09-05 14:37:34 -0400369 ("int (*)(SSL *, unsigned char **, unsigned char *, "
370 "const unsigned char *, unsigned int, void *)"),
Cory Benfieldf1177e72015-04-12 09:11:49 -0400371 wrapper
372 )
373
374
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800375def _asFileDescriptor(obj):
376 fd = None
Konstantinos Koukopoulosc8b13ea2014-01-28 00:21:50 -0800377 if not isinstance(obj, integer_types):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800378 meth = getattr(obj, "fileno", None)
379 if meth is not None:
380 obj = meth()
381
Konstantinos Koukopoulosc8b13ea2014-01-28 00:21:50 -0800382 if isinstance(obj, integer_types):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800383 fd = obj
384
Konstantinos Koukopoulosc8b13ea2014-01-28 00:21:50 -0800385 if not isinstance(fd, integer_types):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800386 raise TypeError("argument must be an int, or have a fileno() method.")
387 elif fd < 0:
388 raise ValueError(
389 "file descriptor cannot be a negative integer (%i)" % (fd,))
390
391 return fd
392
393
Jean-Paul Calderoned39a3f62013-03-04 12:23:51 -0800394def SSLeay_version(type):
395 """
396 Return a string describing the version of OpenSSL in use.
397
398 :param type: One of the SSLEAY_ constants defined in this module.
399 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500400 return _ffi.string(_lib.SSLeay_version(type))
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800401
402
Cory Benfieldef404df2016-03-29 15:32:48 +0100403def _make_requires(flag, error):
Cory Benfielda876cef2015-04-13 17:29:12 -0400404 """
Cory Benfieldef404df2016-03-29 15:32:48 +0100405 Builds a decorator that ensures that functions that rely on OpenSSL
406 functions that are not present in this build raise NotImplementedError,
407 rather than AttributeError coming out of cryptography.
408
409 :param flag: A cryptography flag that guards the functions, e.g.
410 ``Cryptography_HAS_NEXTPROTONEG``.
411 :param error: The string to be used in the exception if the flag is false.
Cory Benfielda876cef2015-04-13 17:29:12 -0400412 """
Cory Benfieldef404df2016-03-29 15:32:48 +0100413 def _requires_decorator(func):
414 if not flag:
415 @wraps(func)
416 def explode(*args, **kwargs):
417 raise NotImplementedError(error)
418 return explode
419 else:
420 return func
Cory Benfield10b277f2015-04-13 17:12:42 -0400421
Cory Benfieldef404df2016-03-29 15:32:48 +0100422 return _requires_decorator
Cory Benfield10b277f2015-04-13 17:12:42 -0400423
424
Cory Benfieldef404df2016-03-29 15:32:48 +0100425_requires_npn = _make_requires(
426 _lib.Cryptography_HAS_NEXTPROTONEG, "NPN not available"
427)
Cory Benfield7907e332015-04-13 17:18:25 -0400428
429
Cory Benfieldef404df2016-03-29 15:32:48 +0100430_requires_alpn = _make_requires(
431 _lib.Cryptography_HAS_ALPN, "ALPN not available"
432)
Cory Benfielde6f35882016-03-29 11:21:04 +0100433
Cory Benfielde6f35882016-03-29 11:21:04 +0100434
Cory Benfieldef404df2016-03-29 15:32:48 +0100435_requires_sni = _make_requires(
436 _lib.Cryptography_HAS_TLSEXT_HOSTNAME, "SNI not available"
437)
Cory Benfielde6f35882016-03-29 11:21:04 +0100438
439
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800440class Session(object):
441 pass
442
443
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800444class Context(object):
445 """
Hynek Schlawackf90e3682016-03-11 11:21:13 +0100446 :class:`OpenSSL.SSL.Context` instances define the parameters for setting
Alex Gaynor62da94d2015-09-05 14:37:34 -0400447 up new SSL connections.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800448 """
449 _methods = {
Andrew Dunhamec84a0a2014-02-24 12:41:37 -0800450 SSLv2_METHOD: "SSLv2_method",
Jean-Paul Calderonebe2bb422013-12-29 07:34:08 -0500451 SSLv3_METHOD: "SSLv3_method",
452 SSLv23_METHOD: "SSLv23_method",
453 TLSv1_METHOD: "TLSv1_method",
454 TLSv1_1_METHOD: "TLSv1_1_method",
455 TLSv1_2_METHOD: "TLSv1_2_method",
Alex Gaynorc4889812015-09-04 08:43:17 -0400456 }
Jean-Paul Calderonebe2bb422013-12-29 07:34:08 -0500457 _methods = dict(
458 (identifier, getattr(_lib, name))
459 for (identifier, name) in _methods.items()
460 if getattr(_lib, name, None) is not None)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800461
462 def __init__(self, method):
463 """
464 :param method: One of SSLv2_METHOD, SSLv3_METHOD, SSLv23_METHOD, or
465 TLSv1_METHOD.
466 """
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -0500467 if not isinstance(method, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800468 raise TypeError("method must be an integer")
469
470 try:
471 method_func = self._methods[method]
472 except KeyError:
473 raise ValueError("No such protocol")
474
475 method_obj = method_func()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500476 if method_obj == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500477 # TODO: This is untested.
478 _raise_current_error()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800479
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500480 context = _lib.SSL_CTX_new(method_obj)
481 if context == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500482 # TODO: This is untested.
483 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500484 context = _ffi.gc(context, _lib.SSL_CTX_free)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800485
486 self._context = context
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800487 self._passphrase_helper = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800488 self._passphrase_callback = None
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800489 self._passphrase_userdata = None
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800490 self._verify_helper = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800491 self._verify_callback = None
492 self._info_callback = None
493 self._tlsext_servername_callback = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800494 self._app_data = None
Cory Benfield0ea76e72015-03-22 09:05:28 +0000495 self._npn_advertise_helper = None
Cory Benfield84a121e2014-03-31 20:30:25 +0100496 self._npn_advertise_callback = None
Cory Benfield0ea76e72015-03-22 09:05:28 +0000497 self._npn_select_helper = None
Cory Benfield84a121e2014-03-31 20:30:25 +0100498 self._npn_select_callback = None
Cory Benfieldf1177e72015-04-12 09:11:49 -0400499 self._alpn_select_helper = None
Cory Benfield12eae892014-06-07 15:42:56 +0100500 self._alpn_select_callback = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800501
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -0800502 # SSL_CTX_set_app_data(self->ctx, self);
503 # SSL_CTX_set_mode(self->ctx, SSL_MODE_ENABLE_PARTIAL_WRITE |
504 # SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
505 # SSL_MODE_AUTO_RETRY);
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500506 self.set_mode(_lib.SSL_MODE_ENABLE_PARTIAL_WRITE)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800507
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800508 def load_verify_locations(self, cafile, capath=None):
509 """
510 Let SSL know where we can find trusted certificates for the certificate
511 chain
512
Jean-Paul Calderone55f9e882015-04-12 09:31:03 -0400513 :param cafile: In which file we can find the certificates (``bytes`` or
514 ``unicode``).
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800515 :param capath: In which directory we can find the certificates
Jean-Paul Calderone55f9e882015-04-12 09:31:03 -0400516 (``bytes`` or ``unicode``).
517
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800518 :return: None
519 """
520 if cafile is None:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500521 cafile = _ffi.NULL
Jean-Paul Calderone55f9e882015-04-12 09:31:03 -0400522 else:
523 cafile = _path_string(cafile)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800524
525 if capath is None:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500526 capath = _ffi.NULL
Jean-Paul Calderone55f9e882015-04-12 09:31:03 -0400527 else:
528 capath = _path_string(capath)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800529
Alex Gaynor62da94d2015-09-05 14:37:34 -0400530 load_result = _lib.SSL_CTX_load_verify_locations(
531 self._context, cafile, capath
532 )
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800533 if not load_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500534 _raise_current_error()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800535
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800536 def _wrap_callback(self, callback):
537 @wraps(callback)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800538 def wrapper(size, verify, userdata):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800539 return callback(size, verify, self._passphrase_userdata)
540 return _PassphraseHelper(
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800541 FILETYPE_PEM, wrapper, more_args=True, truncate=True)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800542
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800543 def set_passwd_cb(self, callback, userdata=None):
544 """
545 Set the passphrase callback
546
547 :param callback: The Python callback to use
548 :param userdata: (optional) A Python object which will be given as
549 argument to the callback
550 :return: None
551 """
552 if not callable(callback):
553 raise TypeError("callback must be callable")
554
555 self._passphrase_helper = self._wrap_callback(callback)
556 self._passphrase_callback = self._passphrase_helper.callback
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500557 _lib.SSL_CTX_set_default_passwd_cb(
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800558 self._context, self._passphrase_callback)
559 self._passphrase_userdata = userdata
560
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800561 def set_default_verify_paths(self):
562 """
563 Use the platform-specific CA certificate locations
564
565 :return: None
566 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500567 set_result = _lib.SSL_CTX_set_default_verify_paths(self._context)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800568 if not set_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500569 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500570 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800571
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800572 def use_certificate_chain_file(self, certfile):
573 """
574 Load a certificate chain from a file
575
Jean-Paul Calderoneb6f8a792015-04-13 10:10:06 -0400576 :param certfile: The name of the certificate chain file (``bytes`` or
577 ``unicode``).
578
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800579 :return: None
580 """
Jean-Paul Calderoneaac43a32015-04-12 09:51:21 -0400581 certfile = _path_string(certfile)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800582
Alex Gaynor62da94d2015-09-05 14:37:34 -0400583 result = _lib.SSL_CTX_use_certificate_chain_file(
584 self._context, certfile
585 )
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800586 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500587 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800588
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800589 def use_certificate_file(self, certfile, filetype=FILETYPE_PEM):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800590 """
591 Load a certificate from a file
592
Jean-Paul Calderoneb6f8a792015-04-13 10:10:06 -0400593 :param certfile: The name of the certificate file (``bytes`` or
594 ``unicode``).
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800595 :param filetype: (optional) The encoding of the file, default is PEM
Jean-Paul Calderoneb6f8a792015-04-13 10:10:06 -0400596
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800597 :return: None
598 """
Jean-Paul Calderoned57a7b62015-04-12 09:57:36 -0400599 certfile = _path_string(certfile)
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -0500600 if not isinstance(filetype, integer_types):
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800601 raise TypeError("filetype must be an integer")
602
Alex Gaynor62da94d2015-09-05 14:37:34 -0400603 use_result = _lib.SSL_CTX_use_certificate_file(
604 self._context, certfile, filetype
605 )
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800606 if not use_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500607 _raise_current_error()
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800608
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800609 def use_certificate(self, cert):
610 """
611 Load a certificate from a X509 object
612
613 :param cert: The X509 object
614 :return: None
615 """
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800616 if not isinstance(cert, X509):
617 raise TypeError("cert must be an X509 instance")
618
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500619 use_result = _lib.SSL_CTX_use_certificate(self._context, cert._x509)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800620 if not use_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500621 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800622
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800623 def add_extra_chain_cert(self, certobj):
624 """
625 Add certificate to chain
626
627 :param certobj: The X509 certificate object to add to the chain
628 :return: None
629 """
630 if not isinstance(certobj, X509):
631 raise TypeError("certobj must be an X509 instance")
632
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500633 copy = _lib.X509_dup(certobj._x509)
634 add_result = _lib.SSL_CTX_add_extra_chain_cert(self._context, copy)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800635 if not add_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500636 # TODO: This is untested.
637 _lib.X509_free(copy)
638 _raise_current_error()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800639
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800640 def _raise_passphrase_exception(self):
641 if self._passphrase_helper is None:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500642 _raise_current_error()
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800643 exception = self._passphrase_helper.raise_if_problem(Error)
644 if exception is not None:
645 raise exception
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
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800668 def use_privatekey(self, pkey):
669 """
670 Load a private key from a PKey object
671
672 :param pkey: The PKey object
673 :return: None
674 """
675 if not isinstance(pkey, PKey):
676 raise TypeError("pkey must be a PKey instance")
677
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500678 use_result = _lib.SSL_CTX_use_PrivateKey(self._context, pkey._pkey)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800679 if not use_result:
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800680 self._raise_passphrase_exception()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800681
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800682 def check_privatekey(self):
683 """
684 Check that the private key and certificate match up
685
686 :return: None (raises an exception if something's wrong)
687 """
Jean-Paul Calderonea0344922014-12-11 14:02:31 -0500688 if not _lib.SSL_CTX_check_private_key(self._context):
689 _raise_current_error()
690
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800691 def load_client_ca(self, cafile):
692 """
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +0100693 Load the trusted certificates that will be sent to the client. Does
694 not actually imply any of the certificates are trusted; that must be
Alex Gaynor62da94d2015-09-05 14:37:34 -0400695 configured separately.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800696
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +0100697 :param bytes cafile: The path to a certificates file in PEM format.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800698 :return: None
699 """
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +0100700 ca_list = _lib.SSL_load_client_CA_file(
701 _text_to_bytes_and_warn("cafile", cafile)
702 )
703 _openssl_assert(ca_list != _ffi.NULL)
704 # SSL_CTX_set_client_CA_list doesn't return anything.
705 _lib.SSL_CTX_set_client_CA_list(self._context, ca_list)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800706
707 def set_session_id(self, buf):
708 """
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +0100709 Set the session id to *buf* within which a session can be reused for
710 this Context object. This is needed when doing session resumption,
711 because there is no way for a stored session to know which Context
712 object it is associated with.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800713
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +0100714 :param bytes buf: The session id.
715
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800716 :returns: None
717 """
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +0100718 buf = _text_to_bytes_and_warn("buf", buf)
719 _openssl_assert(
720 _lib.SSL_CTX_set_session_id_context(
721 self._context,
722 buf,
723 len(buf),
724 ) == 1
725 )
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800726
727 def set_session_cache_mode(self, mode):
728 """
729 Enable/disable session caching and specify the mode used.
730
731 :param mode: One or more of the SESS_CACHE_* flags (combine using
732 bitwise or)
733 :returns: The previously set caching mode.
734 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500735 if not isinstance(mode, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800736 raise TypeError("mode must be an integer")
737
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500738 return _lib.SSL_CTX_set_session_cache_mode(self._context, mode)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800739
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800740 def get_session_cache_mode(self):
741 """
742 :returns: The currently used cache mode.
743 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500744 return _lib.SSL_CTX_get_session_cache_mode(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800745
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800746 def set_verify(self, mode, callback):
747 """
748 Set the verify mode and verify callback
749
750 :param mode: The verify mode, this is either VERIFY_NONE or
751 VERIFY_PEER combined with possible other flags
752 :param callback: The Python callback to use
753 :return: None
754
755 See SSL_CTX_set_verify(3SSL) for further details.
756 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500757 if not isinstance(mode, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800758 raise TypeError("mode must be an integer")
759
760 if not callable(callback):
761 raise TypeError("callback must be callable")
762
Jean-Paul Calderone6a8cd112014-04-02 21:09:08 -0400763 self._verify_helper = _VerifyHelper(callback)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800764 self._verify_callback = self._verify_helper.callback
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500765 _lib.SSL_CTX_set_verify(self._context, mode, self._verify_callback)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800766
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800767 def set_verify_depth(self, depth):
768 """
769 Set the verify depth
770
771 :param depth: An integer specifying the verify depth
772 :return: None
773 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500774 if not isinstance(depth, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800775 raise TypeError("depth must be an integer")
776
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500777 _lib.SSL_CTX_set_verify_depth(self._context, depth)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800778
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800779 def get_verify_mode(self):
780 """
781 Get the verify mode
782
783 :return: The verify mode
784 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500785 return _lib.SSL_CTX_get_verify_mode(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800786
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800787 def get_verify_depth(self):
788 """
789 Get the verify depth
790
791 :return: The verify depth
792 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500793 return _lib.SSL_CTX_get_verify_depth(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800794
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800795 def load_tmp_dh(self, dhfile):
796 """
797 Load parameters for Ephemeral Diffie-Hellman
798
Jean-Paul Calderone4e0c43f2015-04-13 10:15:17 -0400799 :param dhfile: The file to load EDH parameters from (``bytes`` or
800 ``unicode``).
801
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800802 :return: None
803 """
Jean-Paul Calderone9e1c1dd2015-04-12 10:13:13 -0400804 dhfile = _path_string(dhfile)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800805
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -0500806 bio = _lib.BIO_new_file(dhfile, b"r")
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500807 if bio == _ffi.NULL:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500808 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500809 bio = _ffi.gc(bio, _lib.BIO_free)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800810
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500811 dh = _lib.PEM_read_bio_DHparams(bio, _ffi.NULL, _ffi.NULL, _ffi.NULL)
812 dh = _ffi.gc(dh, _lib.DH_free)
813 _lib.SSL_CTX_set_tmp_dh(self._context, dh)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800814
Jean-Paul Calderone3e4e3352014-04-19 09:28:28 -0400815 def set_tmp_ecdh(self, curve):
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600816 """
Andy Lutomirski76a61332014-03-12 15:02:56 -0700817 Select a curve to use for ECDHE key exchange.
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600818
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -0400819 :param curve: A curve object to use as returned by either
820 :py:meth:`OpenSSL.crypto.get_elliptic_curve` or
821 :py:meth:`OpenSSL.crypto.get_elliptic_curves`.
Andy Lutomirskif05a2732014-03-13 17:22:25 -0700822
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600823 :return: None
824 """
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -0400825 _lib.SSL_CTX_set_tmp_ecdh(self._context, curve._to_EC_KEY())
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600826
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800827 def set_cipher_list(self, cipher_list):
828 """
Hynek Schlawackf90e3682016-03-11 11:21:13 +0100829 Set the list of ciphers to be used in this context.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800830
Hynek Schlawackf90e3682016-03-11 11:21:13 +0100831 See the OpenSSL manual for more information (e.g.
832 :manpage:`ciphers(1)`).
833
834 :param bytes cipher_list: An OpenSSL cipher string.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800835 :return: None
836 """
Hynek Schlawackf90e3682016-03-11 11:21:13 +0100837 cipher_list = _text_to_bytes_and_warn("cipher_list", cipher_list)
Jean-Paul Calderone63eab692014-01-18 10:19:56 -0500838
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800839 if not isinstance(cipher_list, bytes):
Hynek Schlawacka7a63af2016-03-11 12:05:26 +0100840 raise TypeError("cipher_list must be a byte string.")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800841
Hynek Schlawackf90e3682016-03-11 11:21:13 +0100842 _openssl_assert(
Hynek Schlawack22a4b662016-03-11 14:59:39 +0100843 _lib.SSL_CTX_set_cipher_list(self._context, cipher_list) == 1
Hynek Schlawackf90e3682016-03-11 11:21:13 +0100844 )
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800845
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800846 def set_client_ca_list(self, certificate_authorities):
847 """
Alex Gaynor62da94d2015-09-05 14:37:34 -0400848 Set the list of preferred client certificate signers for this server
849 context.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800850
Alex Gaynor62da94d2015-09-05 14:37:34 -0400851 This list of certificate authorities will be sent to the client when
852 the server requests a client certificate.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800853
854 :param certificate_authorities: a sequence of X509Names.
855 :return: None
856 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500857 name_stack = _lib.sk_X509_NAME_new_null()
858 if name_stack == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500859 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500860 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800861
862 try:
863 for ca_name in certificate_authorities:
864 if not isinstance(ca_name, X509Name):
865 raise TypeError(
Alex Gaynor62da94d2015-09-05 14:37:34 -0400866 "client CAs must be X509Name objects, not %s "
867 "objects" % (
868 type(ca_name).__name__,
869 )
870 )
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500871 copy = _lib.X509_NAME_dup(ca_name._name)
872 if copy == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500873 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500874 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500875 push_result = _lib.sk_X509_NAME_push(name_stack, copy)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800876 if not push_result:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500877 _lib.X509_NAME_free(copy)
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500878 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800879 except:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500880 _lib.sk_X509_NAME_free(name_stack)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800881 raise
882
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500883 _lib.SSL_CTX_set_client_CA_list(self._context, name_stack)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800884
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800885 def add_client_ca(self, certificate_authority):
886 """
Alex Gaynor62da94d2015-09-05 14:37:34 -0400887 Add the CA certificate to the list of preferred signers for this
888 context.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800889
890 The list of certificate authorities will be sent to the client when the
891 server requests a client certificate.
892
893 :param certificate_authority: certificate authority's X509 certificate.
894 :return: None
895 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800896 if not isinstance(certificate_authority, X509):
897 raise TypeError("certificate_authority must be an X509 instance")
898
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500899 add_result = _lib.SSL_CTX_add_client_CA(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800900 self._context, certificate_authority._x509)
901 if not add_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500902 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500903 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800904
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800905 def set_timeout(self, timeout):
906 """
907 Set session timeout
908
909 :param timeout: The timeout in seconds
910 :return: The previous session timeout
911 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500912 if not isinstance(timeout, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800913 raise TypeError("timeout must be an integer")
914
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500915 return _lib.SSL_CTX_set_timeout(self._context, timeout)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800916
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800917 def get_timeout(self):
918 """
919 Get the session timeout
920
921 :return: The session timeout
922 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500923 return _lib.SSL_CTX_get_timeout(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800924
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800925 def set_info_callback(self, callback):
926 """
927 Set the info callback
928
929 :param callback: The Python callback to use
930 :return: None
931 """
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800932 @wraps(callback)
933 def wrapper(ssl, where, return_code):
Jean-Paul Calderonef2bbc9c2014-02-02 10:59:14 -0500934 callback(Connection._reverse_mapping[ssl], where, return_code)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500935 self._info_callback = _ffi.callback(
936 "void (*)(const SSL *, int, int)", wrapper)
937 _lib.SSL_CTX_set_info_callback(self._context, self._info_callback)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800938
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800939 def get_app_data(self):
940 """
941 Get the application data (supplied via set_app_data())
942
943 :return: The application data
944 """
945 return self._app_data
946
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800947 def set_app_data(self, data):
948 """
949 Set the application data (will be returned from get_app_data())
950
951 :param data: Any Python object
952 :return: None
953 """
954 self._app_data = data
955
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800956 def get_cert_store(self):
957 """
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500958 Get the certificate store for the context.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800959
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500960 :return: A X509Store object or None if it does not have one.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800961 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500962 store = _lib.SSL_CTX_get_cert_store(self._context)
963 if store == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500964 # TODO: This is untested.
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800965 return None
966
967 pystore = X509Store.__new__(X509Store)
968 pystore._store = store
969 return pystore
970
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800971 def set_options(self, options):
972 """
973 Add options. Options set before are not cleared!
974
975 :param options: The options to add.
976 :return: The new option bitmask.
977 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500978 if not isinstance(options, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800979 raise TypeError("options must be an integer")
980
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500981 return _lib.SSL_CTX_set_options(self._context, options)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800982
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800983 def set_mode(self, mode):
984 """
985 Add modes via bitmask. Modes set before are not cleared!
986
987 :param mode: The mode to add.
988 :return: The new mode bitmask.
989 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500990 if not isinstance(mode, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800991 raise TypeError("mode must be an integer")
992
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500993 return _lib.SSL_CTX_set_mode(self._context, mode)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800994
Cory Benfielde6f35882016-03-29 11:21:04 +0100995 @_requires_sni
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800996 def set_tlsext_servername_callback(self, callback):
997 """
Alex Gaynor62da94d2015-09-05 14:37:34 -0400998 Specify a callback function to be called when clients specify a server
999 name.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -08001000
1001 :param callback: The callback function. It will be invoked with one
1002 argument, the Connection instance.
1003 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001004 @wraps(callback)
1005 def wrapper(ssl, alert, arg):
1006 callback(Connection._reverse_mapping[ssl])
1007 return 0
1008
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001009 self._tlsext_servername_callback = _ffi.callback(
1010 "int (*)(const SSL *, int *, void *)", wrapper)
1011 _lib.SSL_CTX_set_tlsext_servername_callback(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001012 self._context, self._tlsext_servername_callback)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -08001013
Cory Benfield10b277f2015-04-13 17:12:42 -04001014 @_requires_npn
Cory Benfield84a121e2014-03-31 20:30:25 +01001015 def set_npn_advertise_callback(self, callback):
1016 """
Cory Benfieldbe3e7b82014-05-10 09:48:55 +01001017 Specify a callback function that will be called when offering `Next
1018 Protocol Negotiation
1019 <https://technotes.googlecode.com/git/nextprotoneg.html>`_ as a server.
Cory Benfield84a121e2014-03-31 20:30:25 +01001020
1021 :param callback: The callback function. It will be invoked with one
Cory Benfieldbe3e7b82014-05-10 09:48:55 +01001022 argument, the Connection instance. It should return a list of
1023 bytestrings representing the advertised protocols, like
1024 ``[b'http/1.1', b'spdy/2']``.
Cory Benfield84a121e2014-03-31 20:30:25 +01001025 """
Cory Benfield0ea76e72015-03-22 09:05:28 +00001026 self._npn_advertise_helper = _NpnAdvertiseHelper(callback)
1027 self._npn_advertise_callback = self._npn_advertise_helper.callback
Cory Benfield84a121e2014-03-31 20:30:25 +01001028 _lib.SSL_CTX_set_next_protos_advertised_cb(
1029 self._context, self._npn_advertise_callback, _ffi.NULL)
1030
Cory Benfield10b277f2015-04-13 17:12:42 -04001031 @_requires_npn
Cory Benfield84a121e2014-03-31 20:30:25 +01001032 def set_npn_select_callback(self, callback):
1033 """
1034 Specify a callback function that will be called when a server offers
1035 Next Protocol Negotiation options.
1036
1037 :param callback: The callback function. It will be invoked with two
1038 arguments: the Connection, and a list of offered protocols as
Cory Benfieldbe3e7b82014-05-10 09:48:55 +01001039 bytestrings, e.g. ``[b'http/1.1', b'spdy/2']``. It should return
1040 one of those bytestrings, the chosen protocol.
Cory Benfield84a121e2014-03-31 20:30:25 +01001041 """
Cory Benfield0ea76e72015-03-22 09:05:28 +00001042 self._npn_select_helper = _NpnSelectHelper(callback)
1043 self._npn_select_callback = self._npn_select_helper.callback
Cory Benfield84a121e2014-03-31 20:30:25 +01001044 _lib.SSL_CTX_set_next_proto_select_cb(
1045 self._context, self._npn_select_callback, _ffi.NULL)
1046
Cory Benfield7907e332015-04-13 17:18:25 -04001047 @_requires_alpn
Cory Benfield12eae892014-06-07 15:42:56 +01001048 def set_alpn_protos(self, protos):
1049 """
Cory Benfielde8e9c382015-04-11 17:33:48 -04001050 Specify the clients ALPN protocol list.
1051
1052 These protocols are offered to the server during protocol negotiation.
Cory Benfield12eae892014-06-07 15:42:56 +01001053
1054 :param protos: A list of the protocols to be offered to the server.
1055 This list should be a Python list of bytestrings representing the
1056 protocols to offer, e.g. ``[b'http/1.1', b'spdy/2']``.
1057 """
1058 # Take the list of protocols and join them together, prefixing them
1059 # with their lengths.
1060 protostr = b''.join(
1061 chain.from_iterable((int2byte(len(p)), p) for p in protos)
1062 )
1063
1064 # Build a C string from the list. We don't need to save this off
1065 # because OpenSSL immediately copies the data out.
1066 input_str = _ffi.new("unsigned char[]", protostr)
Cory Benfielde871af52015-04-11 17:57:50 -04001067 input_str_len = _ffi.cast("unsigned", len(protostr))
1068 _lib.SSL_CTX_set_alpn_protos(self._context, input_str, input_str_len)
Cory Benfield12eae892014-06-07 15:42:56 +01001069
Cory Benfield7907e332015-04-13 17:18:25 -04001070 @_requires_alpn
Cory Benfield12eae892014-06-07 15:42:56 +01001071 def set_alpn_select_callback(self, callback):
1072 """
Cory Benfielde8e9c382015-04-11 17:33:48 -04001073 Set the callback to handle ALPN protocol choice.
Cory Benfield12eae892014-06-07 15:42:56 +01001074
1075 :param callback: The callback function. It will be invoked with two
1076 arguments: the Connection, and a list of offered protocols as
1077 bytestrings, e.g ``[b'http/1.1', b'spdy/2']``. It should return
Cory Benfielde8e9c382015-04-11 17:33:48 -04001078 one of those bytestrings, the chosen protocol.
Cory Benfield12eae892014-06-07 15:42:56 +01001079 """
Cory Benfield9da5ffb2015-04-13 17:20:14 -04001080 self._alpn_select_helper = _ALPNSelectHelper(callback)
Cory Benfieldf1177e72015-04-12 09:11:49 -04001081 self._alpn_select_callback = self._alpn_select_helper.callback
Cory Benfield12eae892014-06-07 15:42:56 +01001082 _lib.SSL_CTX_set_alpn_select_cb(
1083 self._context, self._alpn_select_callback, _ffi.NULL)
1084
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -08001085ContextType = Context
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001086
1087
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001088class 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
Todd Chapman4f73e4f2015-08-27 11:26:43 -04001107 self._app_data = None
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001108
Cory Benfieldbe3e7b82014-05-10 09:48:55 +01001109 # References to strings used for Next Protocol Negotiation. OpenSSL's
1110 # header files suggest that these might get copied at some point, but
1111 # doesn't specify when, so we store them here to make sure they don't
1112 # get freed before OpenSSL uses them.
1113 self._npn_advertise_callback_args = None
1114 self._npn_select_callback_args = None
1115
Cory Benfield12eae892014-06-07 15:42:56 +01001116 # References to strings used for Application Layer Protocol
1117 # Negotiation. These strings get copied at some point but it's well
1118 # after the callback returns, so we have to hang them somewhere to
1119 # avoid them getting freed.
1120 self._alpn_select_callback_args = None
1121
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001122 self._reverse_mapping[self._ssl] = self
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001123
1124 if socket is None:
1125 self._socket = None
Jean-Paul Calderone73b15c22013-03-05 18:30:39 -08001126 # Don't set up any gc for these, SSL_free will take care of them.
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001127 self._into_ssl = _lib.BIO_new(_lib.BIO_s_mem())
1128 self._from_ssl = _lib.BIO_new(_lib.BIO_s_mem())
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001129
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001130 if self._into_ssl == _ffi.NULL or self._from_ssl == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001131 # TODO: This is untested.
1132 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001133
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001134 _lib.SSL_set_bio(self._ssl, self._into_ssl, self._from_ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001135 else:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001136 self._into_ssl = None
1137 self._from_ssl = None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001138 self._socket = socket
Alex Gaynor62da94d2015-09-05 14:37:34 -04001139 set_result = _lib.SSL_set_fd(
1140 self._ssl, _asFileDescriptor(self._socket))
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001141 if not set_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001142 # TODO: This is untested.
1143 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001144
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001145 def __getattr__(self, name):
1146 """
Alex Gaynor62da94d2015-09-05 14:37:34 -04001147 Look up attributes on the wrapped socket object if they are not found
1148 on the Connection object.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001149 """
kjav0b66fa12015-09-02 11:51:26 +01001150 if self._socket is None:
Alex Gaynor62da94d2015-09-05 14:37:34 -04001151 raise AttributeError("'%s' object has no attribute '%s'" % (
1152 self.__class__.__name__, name
1153 ))
kjav0b66fa12015-09-02 11:51:26 +01001154 else:
1155 return getattr(self._socket, name)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001156
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001157 def _raise_ssl_error(self, ssl, result):
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -08001158 if self._context._verify_helper is not None:
1159 self._context._verify_helper.raise_if_problem()
Cory Benfield0ea76e72015-03-22 09:05:28 +00001160 if self._context._npn_advertise_helper is not None:
1161 self._context._npn_advertise_helper.raise_if_problem()
1162 if self._context._npn_select_helper is not None:
1163 self._context._npn_select_helper.raise_if_problem()
Cory Benfieldf1177e72015-04-12 09:11:49 -04001164 if self._context._alpn_select_helper is not None:
1165 self._context._alpn_select_helper.raise_if_problem()
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -08001166
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001167 error = _lib.SSL_get_error(ssl, result)
1168 if error == _lib.SSL_ERROR_WANT_READ:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001169 raise WantReadError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001170 elif error == _lib.SSL_ERROR_WANT_WRITE:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001171 raise WantWriteError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001172 elif error == _lib.SSL_ERROR_ZERO_RETURN:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001173 raise ZeroReturnError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001174 elif error == _lib.SSL_ERROR_WANT_X509_LOOKUP:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001175 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001176 raise WantX509LookupError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001177 elif error == _lib.SSL_ERROR_SYSCALL:
1178 if _lib.ERR_peek_error() == 0:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001179 if result < 0:
Konstantinos Koukopoulos541150d2014-01-31 01:00:19 +02001180 if platform == "win32":
1181 errno = _ffi.getwinerror()[0]
1182 else:
1183 errno = _ffi.errno
Glyph3afdba82015-04-14 17:30:53 -04001184 raise SysCallError(errno, errorcode.get(errno))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001185 else:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001186 raise SysCallError(-1, "Unexpected EOF")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001187 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001188 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001189 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001190 elif error == _lib.SSL_ERROR_NONE:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001191 pass
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001192 else:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001193 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001194
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001195 def get_context(self):
1196 """
1197 Get session context
1198 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001199 return self._context
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001200
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
Cory Benfielde6f35882016-03-29 11:21:04 +01001214 @_requires_sni
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001215 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 """
Alex Gaynor62da94d2015-09-05 14:37:34 -04001222 name = _lib.SSL_get_servername(
1223 self._ssl, _lib.TLSEXT_NAMETYPE_host_name
1224 )
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001225 if name == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001226 return None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001227
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001228 return _ffi.string(name)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001229
Cory Benfielde6f35882016-03-29 11:21:04 +01001230 @_requires_sni
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001231 def set_tlsext_host_name(self, name):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001232 """
1233 Set the value of the servername extension to send in the client hello.
1234
1235 :param name: A byte string giving the name.
1236 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001237 if not isinstance(name, bytes):
1238 raise TypeError("name must be a byte string")
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001239 elif b"\0" in name:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001240 raise TypeError("name must not contain NUL byte")
1241
1242 # XXX I guess this can fail sometimes?
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001243 _lib.SSL_set_tlsext_host_name(self._ssl, name)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001244
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001245 def pending(self):
1246 """
1247 Get the number of bytes that can be safely read from the connection
1248
1249 :return: The number of bytes available in the receive buffer.
1250 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001251 return _lib.SSL_pending(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001252
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
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001279 def sendall(self, buf, flags=0):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001280 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001281 Send "all" data on the connection. This calls send() repeatedly until
1282 all data is sent. If an error occurs, it's impossible to tell how much
1283 data has been sent.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001284
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001285 :param buf: The string, buffer or memoryview to send
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001286 :param flags: (optional) Included for compatibility with the socket
1287 API, the value is ignored
1288 :return: The number of bytes written
1289 """
Jean-Paul Calderone39a8d592015-04-13 20:49:50 -04001290 buf = _text_to_bytes_and_warn("buf", buf)
Abraham Martine82326c2015-02-04 10:18:10 +00001291
Jean-Paul Calderone8fb53182013-12-30 08:35:49 -05001292 if isinstance(buf, _memoryview):
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -08001293 buf = buf.tobytes()
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001294 if isinstance(buf, _buffer):
1295 buf = str(buf)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001296 if not isinstance(buf, bytes):
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001297 raise TypeError("buf must be a memoryview, buffer or byte string")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001298
1299 left_to_send = len(buf)
1300 total_sent = 0
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001301 data = _ffi.new("char[]", buf)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001302
1303 while left_to_send:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001304 result = _lib.SSL_write(self._ssl, data + total_sent, left_to_send)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001305 self._raise_ssl_error(self._ssl, result)
1306 total_sent += result
1307 left_to_send -= result
1308
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001309 def recv(self, bufsiz, flags=None):
1310 """
Alex Gaynor67fc8c92016-05-27 08:27:19 -04001311 Receive data on the connection.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001312
1313 :param bufsiz: The maximum number of bytes to read
Maximilian Hils1d95dea2015-08-17 19:27:20 +02001314 :param flags: (optional) The only supported flag is ``MSG_PEEK``,
1315 all other flags are ignored.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001316 :return: The string read from the Connection
1317 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001318 buf = _ffi.new("char[]", bufsiz)
Maximilian Hils1d95dea2015-08-17 19:27:20 +02001319 if flags is not None and flags & socket.MSG_PEEK:
1320 result = _lib.SSL_peek(self._ssl, buf, bufsiz)
1321 else:
1322 result = _lib.SSL_read(self._ssl, buf, bufsiz)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001323 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001324 return _ffi.buffer(buf, result)[:]
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001325 read = recv
1326
Cory Benfield62d10332014-06-15 10:03:41 +01001327 def recv_into(self, buffer, nbytes=None, flags=None):
1328 """
1329 Receive data on the connection and store the data into a buffer rather
1330 than creating a new string.
1331
1332 :param buffer: The buffer to copy into.
1333 :param nbytes: (optional) The maximum number of bytes to read into the
1334 buffer. If not present, defaults to the size of the buffer. If
1335 larger than the size of the buffer, is reduced to the size of the
1336 buffer.
Maximilian Hils1d95dea2015-08-17 19:27:20 +02001337 :param flags: (optional) The only supported flag is ``MSG_PEEK``,
1338 all other flags are ignored.
Cory Benfield62d10332014-06-15 10:03:41 +01001339 :return: The number of bytes read into the buffer.
1340 """
1341 if nbytes is None:
1342 nbytes = len(buffer)
1343 else:
1344 nbytes = min(nbytes, len(buffer))
1345
1346 # We need to create a temporary buffer. This is annoying, it would be
1347 # better if we could pass memoryviews straight into the SSL_read call,
1348 # but right now we can't. Revisit this if CFFI gets that ability.
1349 buf = _ffi.new("char[]", nbytes)
Maximilian Hils1d95dea2015-08-17 19:27:20 +02001350 if flags is not None and flags & socket.MSG_PEEK:
1351 result = _lib.SSL_peek(self._ssl, buf, nbytes)
1352 else:
1353 result = _lib.SSL_read(self._ssl, buf, nbytes)
Cory Benfield62d10332014-06-15 10:03:41 +01001354 self._raise_ssl_error(self._ssl, result)
1355
1356 # This strange line is all to avoid a memory copy. The buffer protocol
1357 # should allow us to assign a CFFI buffer to the LHS of this line, but
1358 # on CPython 3.3+ that segfaults. As a workaround, we can temporarily
1359 # wrap it in a memoryview, except on Python 2.6 which doesn't have a
1360 # memoryview type.
1361 try:
1362 buffer[:result] = memoryview(_ffi.buffer(buf, result))
1363 except NameError:
1364 buffer[:result] = _ffi.buffer(buf, result)
1365
1366 return result
1367
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001368 def _handle_bio_errors(self, bio, result):
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001369 if _lib.BIO_should_retry(bio):
1370 if _lib.BIO_should_read(bio):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001371 raise WantReadError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001372 elif _lib.BIO_should_write(bio):
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001373 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001374 raise WantWriteError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001375 elif _lib.BIO_should_io_special(bio):
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001376 # TODO: This is untested. I think io_special means the socket
1377 # BIO has a not-yet connected socket.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001378 raise ValueError("BIO_should_io_special")
1379 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001380 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001381 raise ValueError("unknown bio failure")
1382 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001383 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001384 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001385
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001386 def bio_read(self, bufsiz):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001387 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001388 When using non-socket connections this function reads the "dirty" data
1389 that would have traveled away on the network.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001390
1391 :param bufsiz: The maximum number of bytes to read
1392 :return: The string read.
1393 """
Jean-Paul Calderone97e041d2013-03-05 21:03:12 -08001394 if self._from_ssl is None:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001395 raise TypeError("Connection sock was not None")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001396
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -05001397 if not isinstance(bufsiz, integer_types):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001398 raise TypeError("bufsiz must be an integer")
1399
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001400 buf = _ffi.new("char[]", bufsiz)
1401 result = _lib.BIO_read(self._from_ssl, buf, bufsiz)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001402 if result <= 0:
1403 self._handle_bio_errors(self._from_ssl, result)
1404
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001405 return _ffi.buffer(buf, result)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001406
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001407 def bio_write(self, buf):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001408 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001409 When using non-socket connections this function sends "dirty" data that
1410 would have traveled in on the network.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001411
1412 :param buf: The string to put into the memory BIO.
1413 :return: The number of bytes written
1414 """
Jean-Paul Calderone39a8d592015-04-13 20:49:50 -04001415 buf = _text_to_bytes_and_warn("buf", buf)
Abraham Martine82326c2015-02-04 10:18:10 +00001416
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001417 if self._into_ssl is None:
1418 raise TypeError("Connection sock was not None")
1419
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001420 result = _lib.BIO_write(self._into_ssl, buf, len(buf))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001421 if result <= 0:
1422 self._handle_bio_errors(self._into_ssl, result)
1423 return result
1424
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001425 def renegotiate(self):
1426 """
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +01001427 Renegotiate the session.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001428
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +01001429 :return: True if the renegotiation can be started, False otherwise
1430 :rtype: bool
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001431 """
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +01001432 if not self.renegotiate_pending():
1433 _openssl_assert(_lib.SSL_renegotiate(self._ssl) == 1)
1434 return True
1435 return False
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001436
1437 def do_handshake(self):
1438 """
1439 Perform an SSL handshake (usually called after renegotiate() or one of
1440 set_*_state()). This can raise the same exceptions as send and recv.
1441
1442 :return: None.
1443 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001444 result = _lib.SSL_do_handshake(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001445 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001446
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001447 def renegotiate_pending(self):
1448 """
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +01001449 Check if there's a renegotiation in progress, it will return False once
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001450 a renegotiation is finished.
1451
1452 :return: Whether there's a renegotiation in progress
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +01001453 :rtype: bool
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001454 """
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +01001455 return _lib.SSL_renegotiate_pending(self._ssl) == 1
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001456
1457 def total_renegotiations(self):
1458 """
1459 Find out the total number of renegotiations.
1460
1461 :return: The number of renegotiations.
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +01001462 :rtype: int
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001463 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001464 return _lib.SSL_total_renegotiations(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001465
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001466 def connect(self, addr):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001467 """
1468 Connect to remote host and set up client-side SSL
1469
1470 :param addr: A remote address
1471 :return: What the socket's connect method returns
1472 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001473 _lib.SSL_set_connect_state(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001474 return self._socket.connect(addr)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001475
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001476 def connect_ex(self, addr):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001477 """
Alex Gaynor62da94d2015-09-05 14:37:34 -04001478 Connect to remote host and set up client-side SSL. Note that if the
1479 socket's connect_ex method doesn't return 0, SSL won't be initialized.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001480
1481 :param addr: A remove address
1482 :return: What the socket's connect_ex method returns
1483 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001484 connect_ex = self._socket.connect_ex
1485 self.set_connect_state()
1486 return connect_ex(addr)
1487
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001488 def accept(self):
1489 """
1490 Accept incoming connection and set up SSL on it
1491
1492 :return: A (conn,addr) pair where conn is a Connection and addr is an
1493 address
1494 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001495 client, addr = self._socket.accept()
1496 conn = Connection(self._context, client)
1497 conn.set_accept_state()
1498 return (conn, addr)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001499
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001500 def bio_shutdown(self):
1501 """
1502 When using non-socket connections this function signals end of
1503 data on the input for this connection.
1504
1505 :return: None
1506 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001507 if self._from_ssl is None:
1508 raise TypeError("Connection sock was not None")
1509
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001510 _lib.BIO_set_mem_eof_return(self._into_ssl, 0)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001511
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001512 def shutdown(self):
1513 """
1514 Send closure alert
1515
1516 :return: True if the shutdown completed successfully (i.e. both sides
1517 have sent closure alerts), false otherwise (i.e. you have to
1518 wait for a ZeroReturnError on a recv() method call
1519 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001520 result = _lib.SSL_shutdown(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001521 if result < 0:
Paul Aurichbff1d1a2015-01-08 08:36:53 -08001522 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001523 elif result > 0:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001524 return True
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001525 else:
1526 return False
1527
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001528 def get_cipher_list(self):
1529 """
Hynek Schlawackf90e3682016-03-11 11:21:13 +01001530 Retrieve the list of ciphers used by the Connection object.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001531
Hynek Schlawackf90e3682016-03-11 11:21:13 +01001532 :return: A list of native cipher strings.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001533 """
1534 ciphers = []
1535 for i in count():
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001536 result = _lib.SSL_get_cipher_list(self._ssl, i)
1537 if result == _ffi.NULL:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001538 break
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001539 ciphers.append(_native(_ffi.string(result)))
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001540 return ciphers
1541
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001542 def get_client_ca_list(self):
1543 """
1544 Get CAs whose certificates are suggested for client authentication.
1545
Alex Gaynor62da94d2015-09-05 14:37:34 -04001546 :return: If this is a server connection, a list of X509Names
1547 representing the acceptable CAs as set by
1548 :py:meth:`OpenSSL.SSL.Context.set_client_ca_list` or
1549 :py:meth:`OpenSSL.SSL.Context.add_client_ca`. If this is a client
1550 connection, the list of such X509Names sent by the server, or an
1551 empty list if that has not yet happened.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001552 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001553 ca_names = _lib.SSL_get_client_CA_list(self._ssl)
1554 if ca_names == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001555 # TODO: This is untested.
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001556 return []
1557
1558 result = []
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001559 for i in range(_lib.sk_X509_NAME_num(ca_names)):
1560 name = _lib.sk_X509_NAME_value(ca_names, i)
1561 copy = _lib.X509_NAME_dup(name)
1562 if copy == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001563 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001564 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001565
1566 pyname = X509Name.__new__(X509Name)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001567 pyname._name = _ffi.gc(copy, _lib.X509_NAME_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001568 result.append(pyname)
1569 return result
1570
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001571 def makefile(self):
1572 """
Alex Gaynor62da94d2015-09-05 14:37:34 -04001573 The makefile() method is not implemented, since there is no dup
1574 semantics for SSL connections
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001575
Jean-Paul Calderone6749ec22014-04-17 16:30:21 -04001576 :raise: NotImplementedError
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001577 """
Alex Gaynor83284952015-09-05 10:43:30 -04001578 raise NotImplementedError(
1579 "Cannot make file object of OpenSSL.SSL.Connection")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001580
1581 def get_app_data(self):
1582 """
1583 Get application data
1584
1585 :return: The application data
1586 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001587 return self._app_data
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001588
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001589 def set_app_data(self, data):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001590 """
1591 Set application data
1592
1593 :param data - The application data
1594 :return: None
1595 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001596 self._app_data = data
1597
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001598 def get_shutdown(self):
1599 """
1600 Get shutdown state
1601
Alex Gaynor62da94d2015-09-05 14:37:34 -04001602 :return: The shutdown state, a bitvector of SENT_SHUTDOWN,
1603 RECEIVED_SHUTDOWN.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001604 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001605 return _lib.SSL_get_shutdown(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001606
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001607 def set_shutdown(self, state):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001608 """
1609 Set shutdown state
1610
1611 :param state - bitvector of SENT_SHUTDOWN, RECEIVED_SHUTDOWN.
1612 :return: None
1613 """
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -05001614 if not isinstance(state, integer_types):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001615 raise TypeError("state must be an integer")
1616
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001617 _lib.SSL_set_shutdown(self._ssl, state)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001618
Hynek Schlawackea94f2b2016-03-13 16:17:53 +01001619 def get_state_string(self):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001620 """
Hynek Schlawackea94f2b2016-03-13 16:17:53 +01001621 Retrieve a verbose string detailing the state of the Connection.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001622
1623 :return: A string representing the state
Hynek Schlawackea94f2b2016-03-13 16:17:53 +01001624 :rtype: bytes
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001625 """
kjavc704a2e2015-09-07 12:12:27 +01001626 return _ffi.string(_lib.SSL_state_string_long(self._ssl))
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001627
1628 def server_random(self):
1629 """
1630 Get a copy of the server hello nonce.
1631
1632 :return: A string representing the state
1633 """
Alex Gaynor93603062016-06-01 20:13:09 -07001634 session = _lib.SSL_get_session(self._ssl)
1635 if session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001636 return None
Alex Gaynor93603062016-06-01 20:13:09 -07001637 length = _lib.SSL_get_server_random(self._ssl, _ffi.NULL, 0)
1638 assert length > 0
1639 outp = _ffi.new("char[]", length)
1640 _lib.SSL_get_server_random(self._ssl, outp, length)
1641 return _ffi.buffer(outp, length)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001642
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001643 def client_random(self):
1644 """
1645 Get a copy of the client hello nonce.
1646
1647 :return: A string representing the state
1648 """
Alex Gaynor93603062016-06-01 20:13:09 -07001649 session = _lib.SSL_get_session(self._ssl)
1650 if session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001651 return None
Alex Gaynor93603062016-06-01 20:13:09 -07001652
1653 length = _lib.SSL_get_client_random(self._ssl, _ffi.NULL, 0)
1654 assert length > 0
1655 outp = _ffi.new("char[]", length)
1656 _lib.SSL_get_client_random(self._ssl, outp, length)
1657 return _ffi.buffer(outp, length)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001658
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001659 def master_key(self):
1660 """
1661 Get a copy of the master key.
1662
1663 :return: A string representing the state
1664 """
Alex Gaynor93603062016-06-01 20:13:09 -07001665 session = _lib.SSL_get_session(self._ssl)
1666 if session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001667 return None
Alex Gaynor93603062016-06-01 20:13:09 -07001668
1669 length = _lib.SSL_SESSION_get_master_key(session, _ffi.NULL, 0)
1670 assert length > 0
1671 outp = _ffi.new("char[]", length)
1672 _lib.SSL_SESSION_get_master_key(session, outp, length)
1673 return _ffi.buffer(outp, length)[:]
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001674
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001675 def sock_shutdown(self, *args, **kwargs):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001676 """
1677 See shutdown(2)
1678
1679 :return: What the socket's shutdown() method returns
1680 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001681 return self._socket.shutdown(*args, **kwargs)
1682
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001683 def get_peer_certificate(self):
1684 """
1685 Retrieve the other side's certificate (if any)
1686
1687 :return: The peer's certificate
1688 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001689 cert = _lib.SSL_get_peer_certificate(self._ssl)
1690 if cert != _ffi.NULL:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001691 pycert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001692 pycert._x509 = _ffi.gc(cert, _lib.X509_free)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001693 return pycert
1694 return None
1695
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001696 def get_peer_cert_chain(self):
1697 """
1698 Retrieve the other side's certificate (if any)
1699
1700 :return: A list of X509 instances giving the peer's certificate chain,
1701 or None if it does not have one.
1702 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001703 cert_stack = _lib.SSL_get_peer_cert_chain(self._ssl)
1704 if cert_stack == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001705 return None
1706
1707 result = []
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001708 for i in range(_lib.sk_X509_num(cert_stack)):
Jean-Paul Calderone73b15c22013-03-05 18:30:39 -08001709 # TODO could incref instead of dup here
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001710 cert = _lib.X509_dup(_lib.sk_X509_value(cert_stack, i))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001711 pycert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001712 pycert._x509 = _ffi.gc(cert, _lib.X509_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001713 result.append(pycert)
1714 return result
1715
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001716 def want_read(self):
1717 """
Alex Gaynor62da94d2015-09-05 14:37:34 -04001718 Checks if more data has to be read from the transport layer to complete
1719 an operation.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001720
1721 :return: True iff more data has to be read
1722 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001723 return _lib.SSL_want_read(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001724
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001725 def want_write(self):
1726 """
1727 Checks if there is data to write to the transport layer to complete an
1728 operation.
1729
1730 :return: True iff there is data to write
1731 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001732 return _lib.SSL_want_write(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001733
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001734 def set_accept_state(self):
1735 """
Alex Gaynor62da94d2015-09-05 14:37:34 -04001736 Set the connection to work in server mode. The handshake will be
1737 handled automatically by read/write.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001738
1739 :return: None
1740 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001741 _lib.SSL_set_accept_state(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001742
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001743 def set_connect_state(self):
1744 """
Alex Gaynor62da94d2015-09-05 14:37:34 -04001745 Set the connection to work in client mode. The handshake will be
1746 handled automatically by read/write.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001747
1748 :return: None
1749 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001750 _lib.SSL_set_connect_state(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001751
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001752 def get_session(self):
1753 """
1754 Returns the Session currently used.
1755
Alex Gaynor62da94d2015-09-05 14:37:34 -04001756 @return: An instance of :py:class:`OpenSSL.SSL.Session` or
1757 :py:obj:`None` if no session exists.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001758 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001759 session = _lib.SSL_get1_session(self._ssl)
1760 if session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001761 return None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001762
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001763 pysession = Session.__new__(Session)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001764 pysession._session = _ffi.gc(session, _lib.SSL_SESSION_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001765 return pysession
1766
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001767 def set_session(self, session):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001768 """
1769 Set the session to be used when the TLS/SSL connection is established.
1770
1771 :param session: A Session instance representing the session to use.
1772 :returns: None
1773 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001774 if not isinstance(session, Session):
1775 raise TypeError("session must be a Session instance")
1776
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001777 result = _lib.SSL_set_session(self._ssl, session._session)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001778 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001779 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001780
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001781 def _get_finished_message(self, function):
1782 """
1783 Helper to implement :py:meth:`get_finished` and
1784 :py:meth:`get_peer_finished`.
1785
1786 :param function: Either :py:data:`SSL_get_finished`: or
1787 :py:data:`SSL_get_peer_finished`.
1788
1789 :return: :py:data:`None` if the desired message has not yet been
1790 received, otherwise the contents of the message.
1791 :rtype: :py:class:`bytes` or :py:class:`NoneType`
1792 """
Jean-Paul Calderone01af9042014-03-30 11:40:42 -04001793 # The OpenSSL documentation says nothing about what might happen if the
1794 # count argument given is zero. Specifically, it doesn't say whether
1795 # the output buffer may be NULL in that case or not. Inspection of the
1796 # implementation reveals that it calls memcpy() unconditionally.
1797 # Section 7.1.4, paragraph 1 of the C standard suggests that
1798 # memcpy(NULL, source, 0) is not guaranteed to produce defined (let
1799 # alone desirable) behavior (though it probably does on just about
1800 # every implementation...)
1801 #
1802 # Allocate a tiny buffer to pass in (instead of just passing NULL as
1803 # one might expect) for the initial call so as to be safe against this
1804 # potentially undefined behavior.
1805 empty = _ffi.new("char[]", 0)
1806 size = function(self._ssl, empty, 0)
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001807 if size == 0:
1808 # No Finished message so far.
1809 return None
1810
1811 buf = _ffi.new("char[]", size)
1812 function(self._ssl, buf, size)
1813 return _ffi.buffer(buf, size)[:]
1814
Fedor Brunner5747b932014-03-05 14:22:34 +01001815 def get_finished(self):
1816 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001817 Obtain the latest `handshake finished` message sent to the peer.
Fedor Brunner5747b932014-03-05 14:22:34 +01001818
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001819 :return: The contents of the message or :py:obj:`None` if the TLS
1820 handshake has not yet completed.
1821 :rtype: :py:class:`bytes` or :py:class:`NoneType`
Fedor Brunner5747b932014-03-05 14:22:34 +01001822 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001823 return self._get_finished_message(_lib.SSL_get_finished)
1824
Fedor Brunner5747b932014-03-05 14:22:34 +01001825 def get_peer_finished(self):
1826 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001827 Obtain the latest `handshake finished` message received from the peer.
Fedor Brunner5747b932014-03-05 14:22:34 +01001828
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001829 :return: The contents of the message or :py:obj:`None` if the TLS
1830 handshake has not yet completed.
1831 :rtype: :py:class:`bytes` or :py:class:`NoneType`
Fedor Brunner5747b932014-03-05 14:22:34 +01001832 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001833 return self._get_finished_message(_lib.SSL_get_peer_finished)
Fedor Brunner5747b932014-03-05 14:22:34 +01001834
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001835 def get_cipher_name(self):
1836 """
1837 Obtain the name of the currently used cipher.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001838
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001839 :returns: The name of the currently used cipher or :py:obj:`None`
1840 if no connection has been established.
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001841 :rtype: :py:class:`unicode` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001842 """
1843 cipher = _lib.SSL_get_current_cipher(self._ssl)
1844 if cipher == _ffi.NULL:
1845 return None
1846 else:
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001847 name = _ffi.string(_lib.SSL_CIPHER_get_name(cipher))
1848 return name.decode("utf-8")
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001849
1850 def get_cipher_bits(self):
1851 """
1852 Obtain the number of secret bits of the currently used cipher.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001853
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001854 :returns: The number of secret bits of the currently used cipher
1855 or :py:obj:`None` if no connection has been established.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001856 :rtype: :py:class:`int` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001857 """
1858 cipher = _lib.SSL_get_current_cipher(self._ssl)
1859 if cipher == _ffi.NULL:
1860 return None
1861 else:
1862 return _lib.SSL_CIPHER_get_bits(cipher, _ffi.NULL)
1863
1864 def get_cipher_version(self):
1865 """
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001866 Obtain the protocol version of the currently used cipher.
1867
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001868 :returns: The protocol name of the currently used cipher
1869 or :py:obj:`None` if no connection has been established.
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001870 :rtype: :py:class:`unicode` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001871 """
1872 cipher = _lib.SSL_get_current_cipher(self._ssl)
1873 if cipher == _ffi.NULL:
1874 return None
1875 else:
Alex Gaynorc4889812015-09-04 08:43:17 -04001876 version = _ffi.string(_lib.SSL_CIPHER_get_version(cipher))
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001877 return version.decode("utf-8")
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001878
Jim Shaverabff1882015-05-27 09:15:55 -04001879 def get_protocol_version_name(self):
Jim Shaverba65e662015-04-26 12:23:40 -04001880 """
1881 Obtain the protocol version of the current connection.
1882
1883 :returns: The TLS version of the current connection, for example
Jim Shaver58d25732015-05-28 11:52:32 -04001884 the value for TLS 1.2 would be ``TLSv1.2``or ``Unknown``
Jim Shaverb5b6b0e2015-05-28 16:47:36 -04001885 for connections that were not successfully established.
Jim Shaver58d25732015-05-28 11:52:32 -04001886 :rtype: :py:class:`unicode`
Jim Shaverba65e662015-04-26 12:23:40 -04001887 """
Jim Shaverd1c896e2015-05-27 17:50:21 -04001888 version = _ffi.string(_lib.SSL_get_version(self._ssl))
Jim Shaver58d25732015-05-28 11:52:32 -04001889 return version.decode("utf-8")
Jim Shaverb2967922015-04-26 23:58:52 -04001890
Jim Shaver208438c2015-05-28 09:52:38 -04001891 def get_protocol_version(self):
1892 """
1893 Obtain the protocol version of the current connection.
1894
1895 :returns: The TLS version of the current connection, for example
1896 the value for TLS 1 would be 0x769.
1897 :rtype: :py:class:`int`
1898 """
1899 version = _lib.SSL_version(self._ssl)
1900 return version
1901
Cory Benfield10b277f2015-04-13 17:12:42 -04001902 @_requires_npn
Cory Benfield84a121e2014-03-31 20:30:25 +01001903 def get_next_proto_negotiated(self):
1904 """
1905 Get the protocol that was negotiated by NPN.
1906 """
1907 data = _ffi.new("unsigned char **")
1908 data_len = _ffi.new("unsigned int *")
1909
1910 _lib.SSL_get0_next_proto_negotiated(self._ssl, data, data_len)
1911
Cory Benfieldcd010f62014-05-15 19:00:27 +01001912 return _ffi.buffer(data[0], data_len[0])[:]
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001913
Cory Benfield7907e332015-04-13 17:18:25 -04001914 @_requires_alpn
Cory Benfield12eae892014-06-07 15:42:56 +01001915 def set_alpn_protos(self, protos):
1916 """
Cory Benfielde8e9c382015-04-11 17:33:48 -04001917 Specify the client's ALPN protocol list.
1918
1919 These protocols are offered to the server during protocol negotiation.
Cory Benfield12eae892014-06-07 15:42:56 +01001920
1921 :param protos: A list of the protocols to be offered to the server.
1922 This list should be a Python list of bytestrings representing the
1923 protocols to offer, e.g. ``[b'http/1.1', b'spdy/2']``.
1924 """
1925 # Take the list of protocols and join them together, prefixing them
1926 # with their lengths.
1927 protostr = b''.join(
1928 chain.from_iterable((int2byte(len(p)), p) for p in protos)
1929 )
1930
1931 # Build a C string from the list. We don't need to save this off
1932 # because OpenSSL immediately copies the data out.
1933 input_str = _ffi.new("unsigned char[]", protostr)
Cory Benfield9c1979a2015-04-12 08:51:52 -04001934 input_str_len = _ffi.cast("unsigned", len(protostr))
1935 _lib.SSL_set_alpn_protos(self._ssl, input_str, input_str_len)
Cory Benfield12eae892014-06-07 15:42:56 +01001936
Maximilian Hils66ded6a2015-08-26 06:02:03 +02001937 @_requires_alpn
Cory Benfield12eae892014-06-07 15:42:56 +01001938 def get_alpn_proto_negotiated(self):
Cory Benfield222f30e2015-04-13 18:10:21 -04001939 """
1940 Get the protocol that was negotiated by ALPN.
1941 """
Cory Benfield12eae892014-06-07 15:42:56 +01001942 data = _ffi.new("unsigned char **")
1943 data_len = _ffi.new("unsigned int *")
1944
1945 _lib.SSL_get0_alpn_selected(self._ssl, data, data_len)
1946
Cory Benfielde8e9c382015-04-11 17:33:48 -04001947 if not data_len:
1948 return b''
1949
Cory Benfield12eae892014-06-07 15:42:56 +01001950 return _ffi.buffer(data[0], data_len[0])[:]
1951
1952
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001953ConnectionType = Connection
Jean-Paul Calderone11ed8e82014-01-18 10:21:50 -05001954
Jean-Paul Calderonefab157b2014-01-18 11:21:38 -05001955# This is similar to the initialization calls at the end of OpenSSL/crypto.py
1956# but is exercised mostly by the Context initializer.
Jean-Paul Calderone11ed8e82014-01-18 10:21:50 -05001957_lib.SSL_library_init()