blob: 5eea271e840ce13f67ed6944ede60e3b7f4a4c57 [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()
Alex Gaynora829e902016-06-04 18:16:01 -0700476 _openssl_assert(method_obj != _ffi.NULL)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800477
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500478 context = _lib.SSL_CTX_new(method_obj)
Alex Gaynora829e902016-06-04 18:16:01 -0700479 _openssl_assert(context != _ffi.NULL)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500480 context = _ffi.gc(context, _lib.SSL_CTX_free)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800481
482 self._context = context
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800483 self._passphrase_helper = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800484 self._passphrase_callback = None
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800485 self._passphrase_userdata = None
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800486 self._verify_helper = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800487 self._verify_callback = None
488 self._info_callback = None
489 self._tlsext_servername_callback = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800490 self._app_data = None
Cory Benfield0ea76e72015-03-22 09:05:28 +0000491 self._npn_advertise_helper = None
Cory Benfield84a121e2014-03-31 20:30:25 +0100492 self._npn_advertise_callback = None
Cory Benfield0ea76e72015-03-22 09:05:28 +0000493 self._npn_select_helper = None
Cory Benfield84a121e2014-03-31 20:30:25 +0100494 self._npn_select_callback = None
Cory Benfieldf1177e72015-04-12 09:11:49 -0400495 self._alpn_select_helper = None
Cory Benfield12eae892014-06-07 15:42:56 +0100496 self._alpn_select_callback = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800497
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -0800498 # SSL_CTX_set_app_data(self->ctx, self);
499 # SSL_CTX_set_mode(self->ctx, SSL_MODE_ENABLE_PARTIAL_WRITE |
500 # SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
501 # SSL_MODE_AUTO_RETRY);
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500502 self.set_mode(_lib.SSL_MODE_ENABLE_PARTIAL_WRITE)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800503
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800504 def load_verify_locations(self, cafile, capath=None):
505 """
506 Let SSL know where we can find trusted certificates for the certificate
507 chain
508
Jean-Paul Calderone55f9e882015-04-12 09:31:03 -0400509 :param cafile: In which file we can find the certificates (``bytes`` or
510 ``unicode``).
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800511 :param capath: In which directory we can find the certificates
Jean-Paul Calderone55f9e882015-04-12 09:31:03 -0400512 (``bytes`` or ``unicode``).
513
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800514 :return: None
515 """
516 if cafile is None:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500517 cafile = _ffi.NULL
Jean-Paul Calderone55f9e882015-04-12 09:31:03 -0400518 else:
519 cafile = _path_string(cafile)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800520
521 if capath is None:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500522 capath = _ffi.NULL
Jean-Paul Calderone55f9e882015-04-12 09:31:03 -0400523 else:
524 capath = _path_string(capath)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800525
Alex Gaynor62da94d2015-09-05 14:37:34 -0400526 load_result = _lib.SSL_CTX_load_verify_locations(
527 self._context, cafile, capath
528 )
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800529 if not load_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500530 _raise_current_error()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800531
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800532 def _wrap_callback(self, callback):
533 @wraps(callback)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800534 def wrapper(size, verify, userdata):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800535 return callback(size, verify, self._passphrase_userdata)
536 return _PassphraseHelper(
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800537 FILETYPE_PEM, wrapper, more_args=True, truncate=True)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800538
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800539 def set_passwd_cb(self, callback, userdata=None):
540 """
541 Set the passphrase callback
542
543 :param callback: The Python callback to use
544 :param userdata: (optional) A Python object which will be given as
545 argument to the callback
546 :return: None
547 """
548 if not callable(callback):
549 raise TypeError("callback must be callable")
550
551 self._passphrase_helper = self._wrap_callback(callback)
552 self._passphrase_callback = self._passphrase_helper.callback
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500553 _lib.SSL_CTX_set_default_passwd_cb(
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800554 self._context, self._passphrase_callback)
555 self._passphrase_userdata = userdata
556
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800557 def set_default_verify_paths(self):
558 """
559 Use the platform-specific CA certificate locations
560
561 :return: None
562 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500563 set_result = _lib.SSL_CTX_set_default_verify_paths(self._context)
Alex Gaynor09f19f52016-07-03 09:54:09 -0400564 _openssl_assert(set_result == 1)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800565
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800566 def use_certificate_chain_file(self, certfile):
567 """
568 Load a certificate chain from a file
569
Jean-Paul Calderoneb6f8a792015-04-13 10:10:06 -0400570 :param certfile: The name of the certificate chain file (``bytes`` or
571 ``unicode``).
572
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800573 :return: None
574 """
Jean-Paul Calderoneaac43a32015-04-12 09:51:21 -0400575 certfile = _path_string(certfile)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800576
Alex Gaynor62da94d2015-09-05 14:37:34 -0400577 result = _lib.SSL_CTX_use_certificate_chain_file(
578 self._context, certfile
579 )
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800580 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500581 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800582
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800583 def use_certificate_file(self, certfile, filetype=FILETYPE_PEM):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800584 """
585 Load a certificate from a file
586
Jean-Paul Calderoneb6f8a792015-04-13 10:10:06 -0400587 :param certfile: The name of the certificate file (``bytes`` or
588 ``unicode``).
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800589 :param filetype: (optional) The encoding of the file, default is PEM
Jean-Paul Calderoneb6f8a792015-04-13 10:10:06 -0400590
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800591 :return: None
592 """
Jean-Paul Calderoned57a7b62015-04-12 09:57:36 -0400593 certfile = _path_string(certfile)
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -0500594 if not isinstance(filetype, integer_types):
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800595 raise TypeError("filetype must be an integer")
596
Alex Gaynor62da94d2015-09-05 14:37:34 -0400597 use_result = _lib.SSL_CTX_use_certificate_file(
598 self._context, certfile, filetype
599 )
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800600 if not use_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500601 _raise_current_error()
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800602
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800603 def use_certificate(self, cert):
604 """
605 Load a certificate from a X509 object
606
607 :param cert: The X509 object
608 :return: None
609 """
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800610 if not isinstance(cert, X509):
611 raise TypeError("cert must be an X509 instance")
612
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500613 use_result = _lib.SSL_CTX_use_certificate(self._context, cert._x509)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800614 if not use_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500615 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800616
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800617 def add_extra_chain_cert(self, certobj):
618 """
619 Add certificate to chain
620
621 :param certobj: The X509 certificate object to add to the chain
622 :return: None
623 """
624 if not isinstance(certobj, X509):
625 raise TypeError("certobj must be an X509 instance")
626
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500627 copy = _lib.X509_dup(certobj._x509)
628 add_result = _lib.SSL_CTX_add_extra_chain_cert(self._context, copy)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800629 if not add_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500630 # TODO: This is untested.
631 _lib.X509_free(copy)
632 _raise_current_error()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800633
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800634 def _raise_passphrase_exception(self):
635 if self._passphrase_helper is None:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500636 _raise_current_error()
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800637 exception = self._passphrase_helper.raise_if_problem(Error)
638 if exception is not None:
639 raise exception
640
Jean-Paul Calderone00f84eb2015-04-13 12:47:21 -0400641 def use_privatekey_file(self, keyfile, filetype=_UNSPECIFIED):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800642 """
643 Load a private key from a file
644
Jean-Paul Calderoneb6f8a792015-04-13 10:10:06 -0400645 :param keyfile: The name of the key file (``bytes`` or ``unicode``)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800646 :param filetype: (optional) The encoding of the file, default is PEM
Jean-Paul Calderoneb6f8a792015-04-13 10:10:06 -0400647
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800648 :return: None
649 """
Jean-Paul Calderone69a4e5b2015-04-12 10:04:28 -0400650 keyfile = _path_string(keyfile)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800651
Jean-Paul Calderone00f84eb2015-04-13 12:47:21 -0400652 if filetype is _UNSPECIFIED:
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800653 filetype = FILETYPE_PEM
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -0500654 elif not isinstance(filetype, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800655 raise TypeError("filetype must be an integer")
656
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500657 use_result = _lib.SSL_CTX_use_PrivateKey_file(
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800658 self._context, keyfile, filetype)
659 if not use_result:
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800660 self._raise_passphrase_exception()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800661
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800662 def use_privatekey(self, pkey):
663 """
664 Load a private key from a PKey object
665
666 :param pkey: The PKey object
667 :return: None
668 """
669 if not isinstance(pkey, PKey):
670 raise TypeError("pkey must be a PKey instance")
671
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500672 use_result = _lib.SSL_CTX_use_PrivateKey(self._context, pkey._pkey)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800673 if not use_result:
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800674 self._raise_passphrase_exception()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800675
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800676 def check_privatekey(self):
677 """
678 Check that the private key and certificate match up
679
680 :return: None (raises an exception if something's wrong)
681 """
Jean-Paul Calderonea0344922014-12-11 14:02:31 -0500682 if not _lib.SSL_CTX_check_private_key(self._context):
683 _raise_current_error()
684
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800685 def load_client_ca(self, cafile):
686 """
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +0100687 Load the trusted certificates that will be sent to the client. Does
688 not actually imply any of the certificates are trusted; that must be
Alex Gaynor62da94d2015-09-05 14:37:34 -0400689 configured separately.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800690
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +0100691 :param bytes cafile: The path to a certificates file in PEM format.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800692 :return: None
693 """
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +0100694 ca_list = _lib.SSL_load_client_CA_file(
695 _text_to_bytes_and_warn("cafile", cafile)
696 )
697 _openssl_assert(ca_list != _ffi.NULL)
698 # SSL_CTX_set_client_CA_list doesn't return anything.
699 _lib.SSL_CTX_set_client_CA_list(self._context, ca_list)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800700
701 def set_session_id(self, buf):
702 """
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +0100703 Set the session id to *buf* within which a session can be reused for
704 this Context object. This is needed when doing session resumption,
705 because there is no way for a stored session to know which Context
706 object it is associated with.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800707
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +0100708 :param bytes buf: The session id.
709
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800710 :returns: None
711 """
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +0100712 buf = _text_to_bytes_and_warn("buf", buf)
713 _openssl_assert(
714 _lib.SSL_CTX_set_session_id_context(
715 self._context,
716 buf,
717 len(buf),
718 ) == 1
719 )
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800720
721 def set_session_cache_mode(self, mode):
722 """
723 Enable/disable session caching and specify the mode used.
724
725 :param mode: One or more of the SESS_CACHE_* flags (combine using
726 bitwise or)
727 :returns: The previously set caching mode.
728 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500729 if not isinstance(mode, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800730 raise TypeError("mode must be an integer")
731
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500732 return _lib.SSL_CTX_set_session_cache_mode(self._context, mode)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800733
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800734 def get_session_cache_mode(self):
735 """
736 :returns: The currently used cache mode.
737 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500738 return _lib.SSL_CTX_get_session_cache_mode(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800739
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800740 def set_verify(self, mode, callback):
741 """
742 Set the verify mode and verify callback
743
744 :param mode: The verify mode, this is either VERIFY_NONE or
745 VERIFY_PEER combined with possible other flags
746 :param callback: The Python callback to use
747 :return: None
748
749 See SSL_CTX_set_verify(3SSL) for further details.
750 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500751 if not isinstance(mode, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800752 raise TypeError("mode must be an integer")
753
754 if not callable(callback):
755 raise TypeError("callback must be callable")
756
Jean-Paul Calderone6a8cd112014-04-02 21:09:08 -0400757 self._verify_helper = _VerifyHelper(callback)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800758 self._verify_callback = self._verify_helper.callback
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500759 _lib.SSL_CTX_set_verify(self._context, mode, self._verify_callback)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800760
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800761 def set_verify_depth(self, depth):
762 """
763 Set the verify depth
764
765 :param depth: An integer specifying the verify depth
766 :return: None
767 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500768 if not isinstance(depth, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800769 raise TypeError("depth must be an integer")
770
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500771 _lib.SSL_CTX_set_verify_depth(self._context, depth)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800772
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800773 def get_verify_mode(self):
774 """
775 Get the verify mode
776
777 :return: The verify mode
778 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500779 return _lib.SSL_CTX_get_verify_mode(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800780
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800781 def get_verify_depth(self):
782 """
783 Get the verify depth
784
785 :return: The verify depth
786 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500787 return _lib.SSL_CTX_get_verify_depth(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800788
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800789 def load_tmp_dh(self, dhfile):
790 """
791 Load parameters for Ephemeral Diffie-Hellman
792
Jean-Paul Calderone4e0c43f2015-04-13 10:15:17 -0400793 :param dhfile: The file to load EDH parameters from (``bytes`` or
794 ``unicode``).
795
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800796 :return: None
797 """
Jean-Paul Calderone9e1c1dd2015-04-12 10:13:13 -0400798 dhfile = _path_string(dhfile)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800799
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -0500800 bio = _lib.BIO_new_file(dhfile, b"r")
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500801 if bio == _ffi.NULL:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500802 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500803 bio = _ffi.gc(bio, _lib.BIO_free)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800804
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500805 dh = _lib.PEM_read_bio_DHparams(bio, _ffi.NULL, _ffi.NULL, _ffi.NULL)
806 dh = _ffi.gc(dh, _lib.DH_free)
807 _lib.SSL_CTX_set_tmp_dh(self._context, dh)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800808
Jean-Paul Calderone3e4e3352014-04-19 09:28:28 -0400809 def set_tmp_ecdh(self, curve):
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600810 """
Andy Lutomirski76a61332014-03-12 15:02:56 -0700811 Select a curve to use for ECDHE key exchange.
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600812
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -0400813 :param curve: A curve object to use as returned by either
814 :py:meth:`OpenSSL.crypto.get_elliptic_curve` or
815 :py:meth:`OpenSSL.crypto.get_elliptic_curves`.
Andy Lutomirskif05a2732014-03-13 17:22:25 -0700816
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600817 :return: None
818 """
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -0400819 _lib.SSL_CTX_set_tmp_ecdh(self._context, curve._to_EC_KEY())
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600820
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800821 def set_cipher_list(self, cipher_list):
822 """
Hynek Schlawackf90e3682016-03-11 11:21:13 +0100823 Set the list of ciphers to be used in this context.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800824
Hynek Schlawackf90e3682016-03-11 11:21:13 +0100825 See the OpenSSL manual for more information (e.g.
826 :manpage:`ciphers(1)`).
827
828 :param bytes cipher_list: An OpenSSL cipher string.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800829 :return: None
830 """
Hynek Schlawackf90e3682016-03-11 11:21:13 +0100831 cipher_list = _text_to_bytes_and_warn("cipher_list", cipher_list)
Jean-Paul Calderone63eab692014-01-18 10:19:56 -0500832
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800833 if not isinstance(cipher_list, bytes):
Hynek Schlawacka7a63af2016-03-11 12:05:26 +0100834 raise TypeError("cipher_list must be a byte string.")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800835
Hynek Schlawackf90e3682016-03-11 11:21:13 +0100836 _openssl_assert(
Hynek Schlawack22a4b662016-03-11 14:59:39 +0100837 _lib.SSL_CTX_set_cipher_list(self._context, cipher_list) == 1
Hynek Schlawackf90e3682016-03-11 11:21:13 +0100838 )
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800839
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800840 def set_client_ca_list(self, certificate_authorities):
841 """
Alex Gaynor62da94d2015-09-05 14:37:34 -0400842 Set the list of preferred client certificate signers for this server
843 context.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800844
Alex Gaynor62da94d2015-09-05 14:37:34 -0400845 This list of certificate authorities will be sent to the client when
846 the server requests a client certificate.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800847
848 :param certificate_authorities: a sequence of X509Names.
849 :return: None
850 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500851 name_stack = _lib.sk_X509_NAME_new_null()
Alex Gaynora829e902016-06-04 18:16:01 -0700852 _openssl_assert(name_stack != _ffi.NULL)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800853
854 try:
855 for ca_name in certificate_authorities:
856 if not isinstance(ca_name, X509Name):
857 raise TypeError(
Alex Gaynor62da94d2015-09-05 14:37:34 -0400858 "client CAs must be X509Name objects, not %s "
859 "objects" % (
860 type(ca_name).__name__,
861 )
862 )
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500863 copy = _lib.X509_NAME_dup(ca_name._name)
Alex Gaynora829e902016-06-04 18:16:01 -0700864 _openssl_assert(copy != _ffi.NULL)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500865 push_result = _lib.sk_X509_NAME_push(name_stack, copy)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800866 if not push_result:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500867 _lib.X509_NAME_free(copy)
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500868 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800869 except:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500870 _lib.sk_X509_NAME_free(name_stack)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800871 raise
872
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500873 _lib.SSL_CTX_set_client_CA_list(self._context, name_stack)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800874
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800875 def add_client_ca(self, certificate_authority):
876 """
Alex Gaynor62da94d2015-09-05 14:37:34 -0400877 Add the CA certificate to the list of preferred signers for this
878 context.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800879
880 The list of certificate authorities will be sent to the client when the
881 server requests a client certificate.
882
883 :param certificate_authority: certificate authority's X509 certificate.
884 :return: None
885 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800886 if not isinstance(certificate_authority, X509):
887 raise TypeError("certificate_authority must be an X509 instance")
888
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500889 add_result = _lib.SSL_CTX_add_client_CA(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800890 self._context, certificate_authority._x509)
Alex Gaynor09f19f52016-07-03 09:54:09 -0400891 _openssl_assert(add_result == 1)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800892
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800893 def set_timeout(self, timeout):
894 """
895 Set session timeout
896
897 :param timeout: The timeout in seconds
898 :return: The previous session timeout
899 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500900 if not isinstance(timeout, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800901 raise TypeError("timeout must be an integer")
902
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500903 return _lib.SSL_CTX_set_timeout(self._context, timeout)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800904
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800905 def get_timeout(self):
906 """
907 Get the session timeout
908
909 :return: The session timeout
910 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500911 return _lib.SSL_CTX_get_timeout(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800912
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800913 def set_info_callback(self, callback):
914 """
915 Set the info callback
916
917 :param callback: The Python callback to use
918 :return: None
919 """
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800920 @wraps(callback)
921 def wrapper(ssl, where, return_code):
Jean-Paul Calderonef2bbc9c2014-02-02 10:59:14 -0500922 callback(Connection._reverse_mapping[ssl], where, return_code)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500923 self._info_callback = _ffi.callback(
924 "void (*)(const SSL *, int, int)", wrapper)
925 _lib.SSL_CTX_set_info_callback(self._context, self._info_callback)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800926
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800927 def get_app_data(self):
928 """
929 Get the application data (supplied via set_app_data())
930
931 :return: The application data
932 """
933 return self._app_data
934
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800935 def set_app_data(self, data):
936 """
937 Set the application data (will be returned from get_app_data())
938
939 :param data: Any Python object
940 :return: None
941 """
942 self._app_data = data
943
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800944 def get_cert_store(self):
945 """
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500946 Get the certificate store for the context.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800947
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500948 :return: A X509Store object or None if it does not have one.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800949 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500950 store = _lib.SSL_CTX_get_cert_store(self._context)
951 if store == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500952 # TODO: This is untested.
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800953 return None
954
955 pystore = X509Store.__new__(X509Store)
956 pystore._store = store
957 return pystore
958
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800959 def set_options(self, options):
960 """
961 Add options. Options set before are not cleared!
962
963 :param options: The options to add.
964 :return: The new option bitmask.
965 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500966 if not isinstance(options, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800967 raise TypeError("options must be an integer")
968
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500969 return _lib.SSL_CTX_set_options(self._context, options)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800970
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800971 def set_mode(self, mode):
972 """
973 Add modes via bitmask. Modes set before are not cleared!
974
975 :param mode: The mode to add.
976 :return: The new mode bitmask.
977 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500978 if not isinstance(mode, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800979 raise TypeError("mode must be an integer")
980
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500981 return _lib.SSL_CTX_set_mode(self._context, mode)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800982
Cory Benfielde6f35882016-03-29 11:21:04 +0100983 @_requires_sni
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800984 def set_tlsext_servername_callback(self, callback):
985 """
Alex Gaynor62da94d2015-09-05 14:37:34 -0400986 Specify a callback function to be called when clients specify a server
987 name.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800988
989 :param callback: The callback function. It will be invoked with one
990 argument, the Connection instance.
991 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800992 @wraps(callback)
993 def wrapper(ssl, alert, arg):
994 callback(Connection._reverse_mapping[ssl])
995 return 0
996
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500997 self._tlsext_servername_callback = _ffi.callback(
998 "int (*)(const SSL *, int *, void *)", wrapper)
999 _lib.SSL_CTX_set_tlsext_servername_callback(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001000 self._context, self._tlsext_servername_callback)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -08001001
Cory Benfield10b277f2015-04-13 17:12:42 -04001002 @_requires_npn
Cory Benfield84a121e2014-03-31 20:30:25 +01001003 def set_npn_advertise_callback(self, callback):
1004 """
Cory Benfieldbe3e7b82014-05-10 09:48:55 +01001005 Specify a callback function that will be called when offering `Next
1006 Protocol Negotiation
1007 <https://technotes.googlecode.com/git/nextprotoneg.html>`_ as a server.
Cory Benfield84a121e2014-03-31 20:30:25 +01001008
1009 :param callback: The callback function. It will be invoked with one
Cory Benfieldbe3e7b82014-05-10 09:48:55 +01001010 argument, the Connection instance. It should return a list of
1011 bytestrings representing the advertised protocols, like
1012 ``[b'http/1.1', b'spdy/2']``.
Cory Benfield84a121e2014-03-31 20:30:25 +01001013 """
Cory Benfield0ea76e72015-03-22 09:05:28 +00001014 self._npn_advertise_helper = _NpnAdvertiseHelper(callback)
1015 self._npn_advertise_callback = self._npn_advertise_helper.callback
Cory Benfield84a121e2014-03-31 20:30:25 +01001016 _lib.SSL_CTX_set_next_protos_advertised_cb(
1017 self._context, self._npn_advertise_callback, _ffi.NULL)
1018
Cory Benfield10b277f2015-04-13 17:12:42 -04001019 @_requires_npn
Cory Benfield84a121e2014-03-31 20:30:25 +01001020 def set_npn_select_callback(self, callback):
1021 """
1022 Specify a callback function that will be called when a server offers
1023 Next Protocol Negotiation options.
1024
1025 :param callback: The callback function. It will be invoked with two
1026 arguments: the Connection, and a list of offered protocols as
Cory Benfieldbe3e7b82014-05-10 09:48:55 +01001027 bytestrings, e.g. ``[b'http/1.1', b'spdy/2']``. It should return
1028 one of those bytestrings, the chosen protocol.
Cory Benfield84a121e2014-03-31 20:30:25 +01001029 """
Cory Benfield0ea76e72015-03-22 09:05:28 +00001030 self._npn_select_helper = _NpnSelectHelper(callback)
1031 self._npn_select_callback = self._npn_select_helper.callback
Cory Benfield84a121e2014-03-31 20:30:25 +01001032 _lib.SSL_CTX_set_next_proto_select_cb(
1033 self._context, self._npn_select_callback, _ffi.NULL)
1034
Cory Benfield7907e332015-04-13 17:18:25 -04001035 @_requires_alpn
Cory Benfield12eae892014-06-07 15:42:56 +01001036 def set_alpn_protos(self, protos):
1037 """
Cory Benfielde8e9c382015-04-11 17:33:48 -04001038 Specify the clients ALPN protocol list.
1039
1040 These protocols are offered to the server during protocol negotiation.
Cory Benfield12eae892014-06-07 15:42:56 +01001041
1042 :param protos: A list of the protocols to be offered to the server.
1043 This list should be a Python list of bytestrings representing the
1044 protocols to offer, e.g. ``[b'http/1.1', b'spdy/2']``.
1045 """
1046 # Take the list of protocols and join them together, prefixing them
1047 # with their lengths.
1048 protostr = b''.join(
1049 chain.from_iterable((int2byte(len(p)), p) for p in protos)
1050 )
1051
1052 # Build a C string from the list. We don't need to save this off
1053 # because OpenSSL immediately copies the data out.
1054 input_str = _ffi.new("unsigned char[]", protostr)
Cory Benfielde871af52015-04-11 17:57:50 -04001055 input_str_len = _ffi.cast("unsigned", len(protostr))
1056 _lib.SSL_CTX_set_alpn_protos(self._context, input_str, input_str_len)
Cory Benfield12eae892014-06-07 15:42:56 +01001057
Cory Benfield7907e332015-04-13 17:18:25 -04001058 @_requires_alpn
Cory Benfield12eae892014-06-07 15:42:56 +01001059 def set_alpn_select_callback(self, callback):
1060 """
Cory Benfielde8e9c382015-04-11 17:33:48 -04001061 Set the callback to handle ALPN protocol choice.
Cory Benfield12eae892014-06-07 15:42:56 +01001062
1063 :param callback: The callback function. It will be invoked with two
1064 arguments: the Connection, and a list of offered protocols as
1065 bytestrings, e.g ``[b'http/1.1', b'spdy/2']``. It should return
Cory Benfielde8e9c382015-04-11 17:33:48 -04001066 one of those bytestrings, the chosen protocol.
Cory Benfield12eae892014-06-07 15:42:56 +01001067 """
Cory Benfield9da5ffb2015-04-13 17:20:14 -04001068 self._alpn_select_helper = _ALPNSelectHelper(callback)
Cory Benfieldf1177e72015-04-12 09:11:49 -04001069 self._alpn_select_callback = self._alpn_select_helper.callback
Cory Benfield12eae892014-06-07 15:42:56 +01001070 _lib.SSL_CTX_set_alpn_select_cb(
1071 self._context, self._alpn_select_callback, _ffi.NULL)
1072
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -08001073ContextType = Context
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001074
1075
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001076class Connection(object):
1077 """
1078 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001079 _reverse_mapping = WeakValueDictionary()
1080
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001081 def __init__(self, context, socket=None):
1082 """
1083 Create a new Connection object, using the given OpenSSL.SSL.Context
1084 instance and socket.
1085
1086 :param context: An SSL Context to use for this connection
1087 :param socket: The socket to use for transport layer
1088 """
1089 if not isinstance(context, Context):
1090 raise TypeError("context must be a Context instance")
1091
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001092 ssl = _lib.SSL_new(context._context)
1093 self._ssl = _ffi.gc(ssl, _lib.SSL_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001094 self._context = context
Todd Chapman4f73e4f2015-08-27 11:26:43 -04001095 self._app_data = None
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001096
Cory Benfieldbe3e7b82014-05-10 09:48:55 +01001097 # References to strings used for Next Protocol Negotiation. OpenSSL's
1098 # header files suggest that these might get copied at some point, but
1099 # doesn't specify when, so we store them here to make sure they don't
1100 # get freed before OpenSSL uses them.
1101 self._npn_advertise_callback_args = None
1102 self._npn_select_callback_args = None
1103
Cory Benfield12eae892014-06-07 15:42:56 +01001104 # References to strings used for Application Layer Protocol
1105 # Negotiation. These strings get copied at some point but it's well
1106 # after the callback returns, so we have to hang them somewhere to
1107 # avoid them getting freed.
1108 self._alpn_select_callback_args = None
1109
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001110 self._reverse_mapping[self._ssl] = self
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001111
1112 if socket is None:
1113 self._socket = None
Jean-Paul Calderone73b15c22013-03-05 18:30:39 -08001114 # Don't set up any gc for these, SSL_free will take care of them.
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001115 self._into_ssl = _lib.BIO_new(_lib.BIO_s_mem())
Alex Gaynora829e902016-06-04 18:16:01 -07001116 _openssl_assert(self._into_ssl != _ffi.NULL)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001117
Alex Gaynora829e902016-06-04 18:16:01 -07001118 self._from_ssl = _lib.BIO_new(_lib.BIO_s_mem())
1119 _openssl_assert(self._from_ssl != _ffi.NULL)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001120
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001121 _lib.SSL_set_bio(self._ssl, self._into_ssl, self._from_ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001122 else:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001123 self._into_ssl = None
1124 self._from_ssl = None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001125 self._socket = socket
Alex Gaynor62da94d2015-09-05 14:37:34 -04001126 set_result = _lib.SSL_set_fd(
1127 self._ssl, _asFileDescriptor(self._socket))
Alex Gaynor09f19f52016-07-03 09:54:09 -04001128 _openssl_assert(set_result == 1)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001129
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001130 def __getattr__(self, name):
1131 """
Alex Gaynor62da94d2015-09-05 14:37:34 -04001132 Look up attributes on the wrapped socket object if they are not found
1133 on the Connection object.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001134 """
kjav0b66fa12015-09-02 11:51:26 +01001135 if self._socket is None:
Alex Gaynor62da94d2015-09-05 14:37:34 -04001136 raise AttributeError("'%s' object has no attribute '%s'" % (
1137 self.__class__.__name__, name
1138 ))
kjav0b66fa12015-09-02 11:51:26 +01001139 else:
1140 return getattr(self._socket, name)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001141
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001142 def _raise_ssl_error(self, ssl, result):
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -08001143 if self._context._verify_helper is not None:
1144 self._context._verify_helper.raise_if_problem()
Cory Benfield0ea76e72015-03-22 09:05:28 +00001145 if self._context._npn_advertise_helper is not None:
1146 self._context._npn_advertise_helper.raise_if_problem()
1147 if self._context._npn_select_helper is not None:
1148 self._context._npn_select_helper.raise_if_problem()
Cory Benfieldf1177e72015-04-12 09:11:49 -04001149 if self._context._alpn_select_helper is not None:
1150 self._context._alpn_select_helper.raise_if_problem()
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -08001151
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001152 error = _lib.SSL_get_error(ssl, result)
1153 if error == _lib.SSL_ERROR_WANT_READ:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001154 raise WantReadError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001155 elif error == _lib.SSL_ERROR_WANT_WRITE:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001156 raise WantWriteError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001157 elif error == _lib.SSL_ERROR_ZERO_RETURN:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001158 raise ZeroReturnError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001159 elif error == _lib.SSL_ERROR_WANT_X509_LOOKUP:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001160 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001161 raise WantX509LookupError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001162 elif error == _lib.SSL_ERROR_SYSCALL:
1163 if _lib.ERR_peek_error() == 0:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001164 if result < 0:
Konstantinos Koukopoulos541150d2014-01-31 01:00:19 +02001165 if platform == "win32":
1166 errno = _ffi.getwinerror()[0]
1167 else:
1168 errno = _ffi.errno
Glyph3afdba82015-04-14 17:30:53 -04001169 raise SysCallError(errno, errorcode.get(errno))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001170 else:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001171 raise SysCallError(-1, "Unexpected EOF")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001172 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001173 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001174 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001175 elif error == _lib.SSL_ERROR_NONE:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001176 pass
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001177 else:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001178 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001179
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001180 def get_context(self):
1181 """
1182 Get session context
1183 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001184 return self._context
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001185
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001186 def set_context(self, context):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001187 """
1188 Switch this connection to a new session context
1189
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001190 :param context: A :py:class:`Context` instance giving the new session
1191 context to use.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001192 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001193 if not isinstance(context, Context):
1194 raise TypeError("context must be a Context instance")
1195
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001196 _lib.SSL_set_SSL_CTX(self._ssl, context._context)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001197 self._context = context
1198
Cory Benfielde6f35882016-03-29 11:21:04 +01001199 @_requires_sni
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001200 def get_servername(self):
1201 """
1202 Retrieve the servername extension value if provided in the client hello
1203 message, or None if there wasn't one.
1204
1205 :return: A byte string giving the server name or :py:data:`None`.
1206 """
Alex Gaynor62da94d2015-09-05 14:37:34 -04001207 name = _lib.SSL_get_servername(
1208 self._ssl, _lib.TLSEXT_NAMETYPE_host_name
1209 )
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001210 if name == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001211 return None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001212
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001213 return _ffi.string(name)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001214
Cory Benfielde6f35882016-03-29 11:21:04 +01001215 @_requires_sni
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001216 def set_tlsext_host_name(self, name):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001217 """
1218 Set the value of the servername extension to send in the client hello.
1219
1220 :param name: A byte string giving the name.
1221 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001222 if not isinstance(name, bytes):
1223 raise TypeError("name must be a byte string")
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001224 elif b"\0" in name:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001225 raise TypeError("name must not contain NUL byte")
1226
1227 # XXX I guess this can fail sometimes?
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001228 _lib.SSL_set_tlsext_host_name(self._ssl, name)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001229
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001230 def pending(self):
1231 """
1232 Get the number of bytes that can be safely read from the connection
1233
1234 :return: The number of bytes available in the receive buffer.
1235 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001236 return _lib.SSL_pending(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001237
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001238 def send(self, buf, flags=0):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001239 """
1240 Send data on the connection. NOTE: If you get one of the WantRead,
1241 WantWrite or WantX509Lookup exceptions on this, you have to call the
1242 method again with the SAME buffer.
1243
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001244 :param buf: The string, buffer or memoryview to send
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001245 :param flags: (optional) Included for compatibility with the socket
1246 API, the value is ignored
1247 :return: The number of bytes written
1248 """
Abraham Martine82326c2015-02-04 10:18:10 +00001249 # Backward compatibility
Jean-Paul Calderone39a8d592015-04-13 20:49:50 -04001250 buf = _text_to_bytes_and_warn("buf", buf)
Abraham Martine82326c2015-02-04 10:18:10 +00001251
Jean-Paul Calderone8fb53182013-12-30 08:35:49 -05001252 if isinstance(buf, _memoryview):
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -08001253 buf = buf.tobytes()
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001254 if isinstance(buf, _buffer):
1255 buf = str(buf)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001256 if not isinstance(buf, bytes):
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001257 raise TypeError("data must be a memoryview, buffer or byte string")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001258
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001259 result = _lib.SSL_write(self._ssl, buf, len(buf))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001260 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001261 return result
1262 write = send
1263
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001264 def sendall(self, buf, flags=0):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001265 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001266 Send "all" data on the connection. This calls send() repeatedly until
1267 all data is sent. If an error occurs, it's impossible to tell how much
1268 data has been sent.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001269
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001270 :param buf: The string, buffer or memoryview to send
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001271 :param flags: (optional) Included for compatibility with the socket
1272 API, the value is ignored
1273 :return: The number of bytes written
1274 """
Jean-Paul Calderone39a8d592015-04-13 20:49:50 -04001275 buf = _text_to_bytes_and_warn("buf", buf)
Abraham Martine82326c2015-02-04 10:18:10 +00001276
Jean-Paul Calderone8fb53182013-12-30 08:35:49 -05001277 if isinstance(buf, _memoryview):
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -08001278 buf = buf.tobytes()
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001279 if isinstance(buf, _buffer):
1280 buf = str(buf)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001281 if not isinstance(buf, bytes):
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001282 raise TypeError("buf must be a memoryview, buffer or byte string")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001283
1284 left_to_send = len(buf)
1285 total_sent = 0
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001286 data = _ffi.new("char[]", buf)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001287
1288 while left_to_send:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001289 result = _lib.SSL_write(self._ssl, data + total_sent, left_to_send)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001290 self._raise_ssl_error(self._ssl, result)
1291 total_sent += result
1292 left_to_send -= result
1293
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001294 def recv(self, bufsiz, flags=None):
1295 """
Alex Gaynor67fc8c92016-05-27 08:27:19 -04001296 Receive data on the connection.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001297
1298 :param bufsiz: The maximum number of bytes to read
Maximilian Hils1d95dea2015-08-17 19:27:20 +02001299 :param flags: (optional) The only supported flag is ``MSG_PEEK``,
1300 all other flags are ignored.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001301 :return: The string read from the Connection
1302 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001303 buf = _ffi.new("char[]", bufsiz)
Maximilian Hils1d95dea2015-08-17 19:27:20 +02001304 if flags is not None and flags & socket.MSG_PEEK:
1305 result = _lib.SSL_peek(self._ssl, buf, bufsiz)
1306 else:
1307 result = _lib.SSL_read(self._ssl, buf, bufsiz)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001308 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001309 return _ffi.buffer(buf, result)[:]
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001310 read = recv
1311
Cory Benfield62d10332014-06-15 10:03:41 +01001312 def recv_into(self, buffer, nbytes=None, flags=None):
1313 """
1314 Receive data on the connection and store the data into a buffer rather
1315 than creating a new string.
1316
1317 :param buffer: The buffer to copy into.
1318 :param nbytes: (optional) The maximum number of bytes to read into the
1319 buffer. If not present, defaults to the size of the buffer. If
1320 larger than the size of the buffer, is reduced to the size of the
1321 buffer.
Maximilian Hils1d95dea2015-08-17 19:27:20 +02001322 :param flags: (optional) The only supported flag is ``MSG_PEEK``,
1323 all other flags are ignored.
Cory Benfield62d10332014-06-15 10:03:41 +01001324 :return: The number of bytes read into the buffer.
1325 """
1326 if nbytes is None:
1327 nbytes = len(buffer)
1328 else:
1329 nbytes = min(nbytes, len(buffer))
1330
1331 # We need to create a temporary buffer. This is annoying, it would be
1332 # better if we could pass memoryviews straight into the SSL_read call,
1333 # but right now we can't. Revisit this if CFFI gets that ability.
1334 buf = _ffi.new("char[]", nbytes)
Maximilian Hils1d95dea2015-08-17 19:27:20 +02001335 if flags is not None and flags & socket.MSG_PEEK:
1336 result = _lib.SSL_peek(self._ssl, buf, nbytes)
1337 else:
1338 result = _lib.SSL_read(self._ssl, buf, nbytes)
Cory Benfield62d10332014-06-15 10:03:41 +01001339 self._raise_ssl_error(self._ssl, result)
1340
1341 # This strange line is all to avoid a memory copy. The buffer protocol
1342 # should allow us to assign a CFFI buffer to the LHS of this line, but
1343 # on CPython 3.3+ that segfaults. As a workaround, we can temporarily
1344 # wrap it in a memoryview, except on Python 2.6 which doesn't have a
1345 # memoryview type.
1346 try:
1347 buffer[:result] = memoryview(_ffi.buffer(buf, result))
1348 except NameError:
1349 buffer[:result] = _ffi.buffer(buf, result)
1350
1351 return result
1352
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001353 def _handle_bio_errors(self, bio, result):
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001354 if _lib.BIO_should_retry(bio):
1355 if _lib.BIO_should_read(bio):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001356 raise WantReadError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001357 elif _lib.BIO_should_write(bio):
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001358 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001359 raise WantWriteError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001360 elif _lib.BIO_should_io_special(bio):
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001361 # TODO: This is untested. I think io_special means the socket
1362 # BIO has a not-yet connected socket.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001363 raise ValueError("BIO_should_io_special")
1364 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001365 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001366 raise ValueError("unknown bio failure")
1367 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001368 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001369 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001370
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001371 def bio_read(self, bufsiz):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001372 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001373 When using non-socket connections this function reads the "dirty" data
1374 that would have traveled away on the network.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001375
1376 :param bufsiz: The maximum number of bytes to read
1377 :return: The string read.
1378 """
Jean-Paul Calderone97e041d2013-03-05 21:03:12 -08001379 if self._from_ssl is None:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001380 raise TypeError("Connection sock was not None")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001381
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -05001382 if not isinstance(bufsiz, integer_types):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001383 raise TypeError("bufsiz must be an integer")
1384
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001385 buf = _ffi.new("char[]", bufsiz)
1386 result = _lib.BIO_read(self._from_ssl, buf, bufsiz)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001387 if result <= 0:
1388 self._handle_bio_errors(self._from_ssl, result)
1389
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001390 return _ffi.buffer(buf, result)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001391
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001392 def bio_write(self, buf):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001393 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001394 When using non-socket connections this function sends "dirty" data that
1395 would have traveled in on the network.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001396
1397 :param buf: The string to put into the memory BIO.
1398 :return: The number of bytes written
1399 """
Jean-Paul Calderone39a8d592015-04-13 20:49:50 -04001400 buf = _text_to_bytes_and_warn("buf", buf)
Abraham Martine82326c2015-02-04 10:18:10 +00001401
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001402 if self._into_ssl is None:
1403 raise TypeError("Connection sock was not None")
1404
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001405 result = _lib.BIO_write(self._into_ssl, buf, len(buf))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001406 if result <= 0:
1407 self._handle_bio_errors(self._into_ssl, result)
1408 return result
1409
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001410 def renegotiate(self):
1411 """
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +01001412 Renegotiate the session.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001413
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +01001414 :return: True if the renegotiation can be started, False otherwise
1415 :rtype: bool
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001416 """
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +01001417 if not self.renegotiate_pending():
1418 _openssl_assert(_lib.SSL_renegotiate(self._ssl) == 1)
1419 return True
1420 return False
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001421
1422 def do_handshake(self):
1423 """
1424 Perform an SSL handshake (usually called after renegotiate() or one of
1425 set_*_state()). This can raise the same exceptions as send and recv.
1426
1427 :return: None.
1428 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001429 result = _lib.SSL_do_handshake(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001430 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001431
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001432 def renegotiate_pending(self):
1433 """
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +01001434 Check if there's a renegotiation in progress, it will return False once
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001435 a renegotiation is finished.
1436
1437 :return: Whether there's a renegotiation in progress
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +01001438 :rtype: bool
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001439 """
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +01001440 return _lib.SSL_renegotiate_pending(self._ssl) == 1
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001441
1442 def total_renegotiations(self):
1443 """
1444 Find out the total number of renegotiations.
1445
1446 :return: The number of renegotiations.
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +01001447 :rtype: int
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001448 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001449 return _lib.SSL_total_renegotiations(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001450
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001451 def connect(self, addr):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001452 """
1453 Connect to remote host and set up client-side SSL
1454
1455 :param addr: A remote address
1456 :return: What the socket's connect method returns
1457 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001458 _lib.SSL_set_connect_state(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001459 return self._socket.connect(addr)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001460
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001461 def connect_ex(self, addr):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001462 """
Alex Gaynor62da94d2015-09-05 14:37:34 -04001463 Connect to remote host and set up client-side SSL. Note that if the
1464 socket's connect_ex method doesn't return 0, SSL won't be initialized.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001465
1466 :param addr: A remove address
1467 :return: What the socket's connect_ex method returns
1468 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001469 connect_ex = self._socket.connect_ex
1470 self.set_connect_state()
1471 return connect_ex(addr)
1472
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001473 def accept(self):
1474 """
1475 Accept incoming connection and set up SSL on it
1476
1477 :return: A (conn,addr) pair where conn is a Connection and addr is an
1478 address
1479 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001480 client, addr = self._socket.accept()
1481 conn = Connection(self._context, client)
1482 conn.set_accept_state()
1483 return (conn, addr)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001484
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001485 def bio_shutdown(self):
1486 """
1487 When using non-socket connections this function signals end of
1488 data on the input for this connection.
1489
1490 :return: None
1491 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001492 if self._from_ssl is None:
1493 raise TypeError("Connection sock was not None")
1494
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001495 _lib.BIO_set_mem_eof_return(self._into_ssl, 0)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001496
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001497 def shutdown(self):
1498 """
1499 Send closure alert
1500
1501 :return: True if the shutdown completed successfully (i.e. both sides
1502 have sent closure alerts), false otherwise (i.e. you have to
1503 wait for a ZeroReturnError on a recv() method call
1504 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001505 result = _lib.SSL_shutdown(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001506 if result < 0:
Paul Aurichbff1d1a2015-01-08 08:36:53 -08001507 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001508 elif result > 0:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001509 return True
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001510 else:
1511 return False
1512
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001513 def get_cipher_list(self):
1514 """
Hynek Schlawackf90e3682016-03-11 11:21:13 +01001515 Retrieve the list of ciphers used by the Connection object.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001516
Hynek Schlawackf90e3682016-03-11 11:21:13 +01001517 :return: A list of native cipher strings.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001518 """
1519 ciphers = []
1520 for i in count():
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001521 result = _lib.SSL_get_cipher_list(self._ssl, i)
1522 if result == _ffi.NULL:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001523 break
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001524 ciphers.append(_native(_ffi.string(result)))
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001525 return ciphers
1526
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001527 def get_client_ca_list(self):
1528 """
1529 Get CAs whose certificates are suggested for client authentication.
1530
Alex Gaynor62da94d2015-09-05 14:37:34 -04001531 :return: If this is a server connection, a list of X509Names
1532 representing the acceptable CAs as set by
1533 :py:meth:`OpenSSL.SSL.Context.set_client_ca_list` or
1534 :py:meth:`OpenSSL.SSL.Context.add_client_ca`. If this is a client
1535 connection, the list of such X509Names sent by the server, or an
1536 empty list if that has not yet happened.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001537 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001538 ca_names = _lib.SSL_get_client_CA_list(self._ssl)
1539 if ca_names == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001540 # TODO: This is untested.
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001541 return []
1542
1543 result = []
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001544 for i in range(_lib.sk_X509_NAME_num(ca_names)):
1545 name = _lib.sk_X509_NAME_value(ca_names, i)
1546 copy = _lib.X509_NAME_dup(name)
Alex Gaynora829e902016-06-04 18:16:01 -07001547 _openssl_assert(copy != _ffi.NULL)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001548
1549 pyname = X509Name.__new__(X509Name)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001550 pyname._name = _ffi.gc(copy, _lib.X509_NAME_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001551 result.append(pyname)
1552 return result
1553
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001554 def makefile(self):
1555 """
Alex Gaynor62da94d2015-09-05 14:37:34 -04001556 The makefile() method is not implemented, since there is no dup
1557 semantics for SSL connections
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001558
Jean-Paul Calderone6749ec22014-04-17 16:30:21 -04001559 :raise: NotImplementedError
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001560 """
Alex Gaynor83284952015-09-05 10:43:30 -04001561 raise NotImplementedError(
1562 "Cannot make file object of OpenSSL.SSL.Connection")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001563
1564 def get_app_data(self):
1565 """
1566 Get application data
1567
1568 :return: The application data
1569 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001570 return self._app_data
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001571
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001572 def set_app_data(self, data):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001573 """
1574 Set application data
1575
1576 :param data - The application data
1577 :return: None
1578 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001579 self._app_data = data
1580
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001581 def get_shutdown(self):
1582 """
1583 Get shutdown state
1584
Alex Gaynor62da94d2015-09-05 14:37:34 -04001585 :return: The shutdown state, a bitvector of SENT_SHUTDOWN,
1586 RECEIVED_SHUTDOWN.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001587 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001588 return _lib.SSL_get_shutdown(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001589
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001590 def set_shutdown(self, state):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001591 """
1592 Set shutdown state
1593
1594 :param state - bitvector of SENT_SHUTDOWN, RECEIVED_SHUTDOWN.
1595 :return: None
1596 """
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -05001597 if not isinstance(state, integer_types):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001598 raise TypeError("state must be an integer")
1599
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001600 _lib.SSL_set_shutdown(self._ssl, state)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001601
Hynek Schlawackea94f2b2016-03-13 16:17:53 +01001602 def get_state_string(self):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001603 """
Hynek Schlawackea94f2b2016-03-13 16:17:53 +01001604 Retrieve a verbose string detailing the state of the Connection.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001605
1606 :return: A string representing the state
Hynek Schlawackea94f2b2016-03-13 16:17:53 +01001607 :rtype: bytes
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001608 """
kjavc704a2e2015-09-07 12:12:27 +01001609 return _ffi.string(_lib.SSL_state_string_long(self._ssl))
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001610
1611 def server_random(self):
1612 """
1613 Get a copy of the server hello nonce.
1614
1615 :return: A string representing the state
1616 """
Alex Gaynor93603062016-06-01 20:13:09 -07001617 session = _lib.SSL_get_session(self._ssl)
1618 if session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001619 return None
Alex Gaynor93603062016-06-01 20:13:09 -07001620 length = _lib.SSL_get_server_random(self._ssl, _ffi.NULL, 0)
1621 assert length > 0
1622 outp = _ffi.new("char[]", length)
1623 _lib.SSL_get_server_random(self._ssl, outp, length)
1624 return _ffi.buffer(outp, length)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001625
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001626 def client_random(self):
1627 """
1628 Get a copy of the client hello nonce.
1629
1630 :return: A string representing the state
1631 """
Alex Gaynor93603062016-06-01 20:13:09 -07001632 session = _lib.SSL_get_session(self._ssl)
1633 if session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001634 return None
Alex Gaynor93603062016-06-01 20:13:09 -07001635
1636 length = _lib.SSL_get_client_random(self._ssl, _ffi.NULL, 0)
1637 assert length > 0
1638 outp = _ffi.new("char[]", length)
1639 _lib.SSL_get_client_random(self._ssl, outp, length)
1640 return _ffi.buffer(outp, length)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001641
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001642 def master_key(self):
1643 """
1644 Get a copy of the master key.
1645
1646 :return: A string representing the state
1647 """
Alex Gaynor93603062016-06-01 20:13:09 -07001648 session = _lib.SSL_get_session(self._ssl)
1649 if session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001650 return None
Alex Gaynor93603062016-06-01 20:13:09 -07001651
1652 length = _lib.SSL_SESSION_get_master_key(session, _ffi.NULL, 0)
1653 assert length > 0
1654 outp = _ffi.new("char[]", length)
1655 _lib.SSL_SESSION_get_master_key(session, outp, length)
1656 return _ffi.buffer(outp, length)[:]
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001657
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001658 def sock_shutdown(self, *args, **kwargs):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001659 """
1660 See shutdown(2)
1661
1662 :return: What the socket's shutdown() method returns
1663 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001664 return self._socket.shutdown(*args, **kwargs)
1665
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001666 def get_peer_certificate(self):
1667 """
1668 Retrieve the other side's certificate (if any)
1669
1670 :return: The peer's certificate
1671 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001672 cert = _lib.SSL_get_peer_certificate(self._ssl)
1673 if cert != _ffi.NULL:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001674 pycert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001675 pycert._x509 = _ffi.gc(cert, _lib.X509_free)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001676 return pycert
1677 return None
1678
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001679 def get_peer_cert_chain(self):
1680 """
1681 Retrieve the other side's certificate (if any)
1682
1683 :return: A list of X509 instances giving the peer's certificate chain,
1684 or None if it does not have one.
1685 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001686 cert_stack = _lib.SSL_get_peer_cert_chain(self._ssl)
1687 if cert_stack == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001688 return None
1689
1690 result = []
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001691 for i in range(_lib.sk_X509_num(cert_stack)):
Jean-Paul Calderone73b15c22013-03-05 18:30:39 -08001692 # TODO could incref instead of dup here
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001693 cert = _lib.X509_dup(_lib.sk_X509_value(cert_stack, i))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001694 pycert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001695 pycert._x509 = _ffi.gc(cert, _lib.X509_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001696 result.append(pycert)
1697 return result
1698
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001699 def want_read(self):
1700 """
Alex Gaynor62da94d2015-09-05 14:37:34 -04001701 Checks if more data has to be read from the transport layer to complete
1702 an operation.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001703
1704 :return: True iff more data has to be read
1705 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001706 return _lib.SSL_want_read(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001707
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001708 def want_write(self):
1709 """
1710 Checks if there is data to write to the transport layer to complete an
1711 operation.
1712
1713 :return: True iff there is data to write
1714 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001715 return _lib.SSL_want_write(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001716
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001717 def set_accept_state(self):
1718 """
Alex Gaynor62da94d2015-09-05 14:37:34 -04001719 Set the connection to work in server mode. The handshake will be
1720 handled automatically by read/write.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001721
1722 :return: None
1723 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001724 _lib.SSL_set_accept_state(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001725
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001726 def set_connect_state(self):
1727 """
Alex Gaynor62da94d2015-09-05 14:37:34 -04001728 Set the connection to work in client mode. The handshake will be
1729 handled automatically by read/write.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001730
1731 :return: None
1732 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001733 _lib.SSL_set_connect_state(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001734
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001735 def get_session(self):
1736 """
1737 Returns the Session currently used.
1738
Alex Gaynor62da94d2015-09-05 14:37:34 -04001739 @return: An instance of :py:class:`OpenSSL.SSL.Session` or
1740 :py:obj:`None` if no session exists.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001741 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001742 session = _lib.SSL_get1_session(self._ssl)
1743 if session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001744 return None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001745
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001746 pysession = Session.__new__(Session)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001747 pysession._session = _ffi.gc(session, _lib.SSL_SESSION_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001748 return pysession
1749
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001750 def set_session(self, session):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001751 """
1752 Set the session to be used when the TLS/SSL connection is established.
1753
1754 :param session: A Session instance representing the session to use.
1755 :returns: None
1756 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001757 if not isinstance(session, Session):
1758 raise TypeError("session must be a Session instance")
1759
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001760 result = _lib.SSL_set_session(self._ssl, session._session)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001761 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001762 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001763
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001764 def _get_finished_message(self, function):
1765 """
1766 Helper to implement :py:meth:`get_finished` and
1767 :py:meth:`get_peer_finished`.
1768
1769 :param function: Either :py:data:`SSL_get_finished`: or
1770 :py:data:`SSL_get_peer_finished`.
1771
1772 :return: :py:data:`None` if the desired message has not yet been
1773 received, otherwise the contents of the message.
1774 :rtype: :py:class:`bytes` or :py:class:`NoneType`
1775 """
Jean-Paul Calderone01af9042014-03-30 11:40:42 -04001776 # The OpenSSL documentation says nothing about what might happen if the
1777 # count argument given is zero. Specifically, it doesn't say whether
1778 # the output buffer may be NULL in that case or not. Inspection of the
1779 # implementation reveals that it calls memcpy() unconditionally.
1780 # Section 7.1.4, paragraph 1 of the C standard suggests that
1781 # memcpy(NULL, source, 0) is not guaranteed to produce defined (let
1782 # alone desirable) behavior (though it probably does on just about
1783 # every implementation...)
1784 #
1785 # Allocate a tiny buffer to pass in (instead of just passing NULL as
1786 # one might expect) for the initial call so as to be safe against this
1787 # potentially undefined behavior.
1788 empty = _ffi.new("char[]", 0)
1789 size = function(self._ssl, empty, 0)
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001790 if size == 0:
1791 # No Finished message so far.
1792 return None
1793
1794 buf = _ffi.new("char[]", size)
1795 function(self._ssl, buf, size)
1796 return _ffi.buffer(buf, size)[:]
1797
Fedor Brunner5747b932014-03-05 14:22:34 +01001798 def get_finished(self):
1799 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001800 Obtain the latest `handshake finished` message sent to the peer.
Fedor Brunner5747b932014-03-05 14:22:34 +01001801
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001802 :return: The contents of the message or :py:obj:`None` if the TLS
1803 handshake has not yet completed.
1804 :rtype: :py:class:`bytes` or :py:class:`NoneType`
Fedor Brunner5747b932014-03-05 14:22:34 +01001805 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001806 return self._get_finished_message(_lib.SSL_get_finished)
1807
Fedor Brunner5747b932014-03-05 14:22:34 +01001808 def get_peer_finished(self):
1809 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001810 Obtain the latest `handshake finished` message received from the peer.
Fedor Brunner5747b932014-03-05 14:22:34 +01001811
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001812 :return: The contents of the message or :py:obj:`None` if the TLS
1813 handshake has not yet completed.
1814 :rtype: :py:class:`bytes` or :py:class:`NoneType`
Fedor Brunner5747b932014-03-05 14:22:34 +01001815 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001816 return self._get_finished_message(_lib.SSL_get_peer_finished)
Fedor Brunner5747b932014-03-05 14:22:34 +01001817
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001818 def get_cipher_name(self):
1819 """
1820 Obtain the name of the currently used cipher.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001821
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001822 :returns: The name of the currently used cipher or :py:obj:`None`
1823 if no connection has been established.
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001824 :rtype: :py:class:`unicode` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001825 """
1826 cipher = _lib.SSL_get_current_cipher(self._ssl)
1827 if cipher == _ffi.NULL:
1828 return None
1829 else:
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001830 name = _ffi.string(_lib.SSL_CIPHER_get_name(cipher))
1831 return name.decode("utf-8")
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001832
1833 def get_cipher_bits(self):
1834 """
1835 Obtain the number of secret bits of the currently used cipher.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001836
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001837 :returns: The number of secret bits of the currently used cipher
1838 or :py:obj:`None` if no connection has been established.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001839 :rtype: :py:class:`int` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001840 """
1841 cipher = _lib.SSL_get_current_cipher(self._ssl)
1842 if cipher == _ffi.NULL:
1843 return None
1844 else:
1845 return _lib.SSL_CIPHER_get_bits(cipher, _ffi.NULL)
1846
1847 def get_cipher_version(self):
1848 """
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001849 Obtain the protocol version of the currently used cipher.
1850
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001851 :returns: The protocol name of the currently used cipher
1852 or :py:obj:`None` if no connection has been established.
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001853 :rtype: :py:class:`unicode` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001854 """
1855 cipher = _lib.SSL_get_current_cipher(self._ssl)
1856 if cipher == _ffi.NULL:
1857 return None
1858 else:
Alex Gaynorc4889812015-09-04 08:43:17 -04001859 version = _ffi.string(_lib.SSL_CIPHER_get_version(cipher))
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001860 return version.decode("utf-8")
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001861
Jim Shaverabff1882015-05-27 09:15:55 -04001862 def get_protocol_version_name(self):
Jim Shaverba65e662015-04-26 12:23:40 -04001863 """
1864 Obtain the protocol version of the current connection.
1865
1866 :returns: The TLS version of the current connection, for example
Jim Shaver58d25732015-05-28 11:52:32 -04001867 the value for TLS 1.2 would be ``TLSv1.2``or ``Unknown``
Jim Shaverb5b6b0e2015-05-28 16:47:36 -04001868 for connections that were not successfully established.
Jim Shaver58d25732015-05-28 11:52:32 -04001869 :rtype: :py:class:`unicode`
Jim Shaverba65e662015-04-26 12:23:40 -04001870 """
Jim Shaverd1c896e2015-05-27 17:50:21 -04001871 version = _ffi.string(_lib.SSL_get_version(self._ssl))
Jim Shaver58d25732015-05-28 11:52:32 -04001872 return version.decode("utf-8")
Jim Shaverb2967922015-04-26 23:58:52 -04001873
Jim Shaver208438c2015-05-28 09:52:38 -04001874 def get_protocol_version(self):
1875 """
1876 Obtain the protocol version of the current connection.
1877
1878 :returns: The TLS version of the current connection, for example
1879 the value for TLS 1 would be 0x769.
1880 :rtype: :py:class:`int`
1881 """
1882 version = _lib.SSL_version(self._ssl)
1883 return version
1884
Cory Benfield10b277f2015-04-13 17:12:42 -04001885 @_requires_npn
Cory Benfield84a121e2014-03-31 20:30:25 +01001886 def get_next_proto_negotiated(self):
1887 """
1888 Get the protocol that was negotiated by NPN.
1889 """
1890 data = _ffi.new("unsigned char **")
1891 data_len = _ffi.new("unsigned int *")
1892
1893 _lib.SSL_get0_next_proto_negotiated(self._ssl, data, data_len)
1894
Cory Benfieldcd010f62014-05-15 19:00:27 +01001895 return _ffi.buffer(data[0], data_len[0])[:]
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001896
Cory Benfield7907e332015-04-13 17:18:25 -04001897 @_requires_alpn
Cory Benfield12eae892014-06-07 15:42:56 +01001898 def set_alpn_protos(self, protos):
1899 """
Cory Benfielde8e9c382015-04-11 17:33:48 -04001900 Specify the client's ALPN protocol list.
1901
1902 These protocols are offered to the server during protocol negotiation.
Cory Benfield12eae892014-06-07 15:42:56 +01001903
1904 :param protos: A list of the protocols to be offered to the server.
1905 This list should be a Python list of bytestrings representing the
1906 protocols to offer, e.g. ``[b'http/1.1', b'spdy/2']``.
1907 """
1908 # Take the list of protocols and join them together, prefixing them
1909 # with their lengths.
1910 protostr = b''.join(
1911 chain.from_iterable((int2byte(len(p)), p) for p in protos)
1912 )
1913
1914 # Build a C string from the list. We don't need to save this off
1915 # because OpenSSL immediately copies the data out.
1916 input_str = _ffi.new("unsigned char[]", protostr)
Cory Benfield9c1979a2015-04-12 08:51:52 -04001917 input_str_len = _ffi.cast("unsigned", len(protostr))
1918 _lib.SSL_set_alpn_protos(self._ssl, input_str, input_str_len)
Cory Benfield12eae892014-06-07 15:42:56 +01001919
Maximilian Hils66ded6a2015-08-26 06:02:03 +02001920 @_requires_alpn
Cory Benfield12eae892014-06-07 15:42:56 +01001921 def get_alpn_proto_negotiated(self):
Cory Benfield222f30e2015-04-13 18:10:21 -04001922 """
1923 Get the protocol that was negotiated by ALPN.
1924 """
Cory Benfield12eae892014-06-07 15:42:56 +01001925 data = _ffi.new("unsigned char **")
1926 data_len = _ffi.new("unsigned int *")
1927
1928 _lib.SSL_get0_alpn_selected(self._ssl, data, data_len)
1929
Cory Benfielde8e9c382015-04-11 17:33:48 -04001930 if not data_len:
1931 return b''
1932
Cory Benfield12eae892014-06-07 15:42:56 +01001933 return _ffi.buffer(data[0], data_len[0])[:]
1934
1935
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001936ConnectionType = Connection
Jean-Paul Calderone11ed8e82014-01-18 10:21:50 -05001937
Jean-Paul Calderonefab157b2014-01-18 11:21:38 -05001938# This is similar to the initialization calls at the end of OpenSSL/crypto.py
1939# but is exercised mostly by the Context initializer.
Jean-Paul Calderone11ed8e82014-01-18 10:21:50 -05001940_lib.SSL_library_init()