blob: 8dfa0edd08a0126855e7ce84dec598324326a4c8 [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)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800564 if not set_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500565 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500566 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800567
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800568 def use_certificate_chain_file(self, certfile):
569 """
570 Load a certificate chain from a file
571
Jean-Paul Calderoneb6f8a792015-04-13 10:10:06 -0400572 :param certfile: The name of the certificate chain file (``bytes`` or
573 ``unicode``).
574
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800575 :return: None
576 """
Jean-Paul Calderoneaac43a32015-04-12 09:51:21 -0400577 certfile = _path_string(certfile)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800578
Alex Gaynor62da94d2015-09-05 14:37:34 -0400579 result = _lib.SSL_CTX_use_certificate_chain_file(
580 self._context, certfile
581 )
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800582 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500583 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800584
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800585 def use_certificate_file(self, certfile, filetype=FILETYPE_PEM):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800586 """
587 Load a certificate from a file
588
Jean-Paul Calderoneb6f8a792015-04-13 10:10:06 -0400589 :param certfile: The name of the certificate file (``bytes`` or
590 ``unicode``).
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800591 :param filetype: (optional) The encoding of the file, default is PEM
Jean-Paul Calderoneb6f8a792015-04-13 10:10:06 -0400592
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800593 :return: None
594 """
Jean-Paul Calderoned57a7b62015-04-12 09:57:36 -0400595 certfile = _path_string(certfile)
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -0500596 if not isinstance(filetype, integer_types):
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800597 raise TypeError("filetype must be an integer")
598
Alex Gaynor62da94d2015-09-05 14:37:34 -0400599 use_result = _lib.SSL_CTX_use_certificate_file(
600 self._context, certfile, filetype
601 )
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800602 if not use_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500603 _raise_current_error()
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800604
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800605 def use_certificate(self, cert):
606 """
607 Load a certificate from a X509 object
608
609 :param cert: The X509 object
610 :return: None
611 """
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800612 if not isinstance(cert, X509):
613 raise TypeError("cert must be an X509 instance")
614
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500615 use_result = _lib.SSL_CTX_use_certificate(self._context, cert._x509)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800616 if not use_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500617 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800618
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800619 def add_extra_chain_cert(self, certobj):
620 """
621 Add certificate to chain
622
623 :param certobj: The X509 certificate object to add to the chain
624 :return: None
625 """
626 if not isinstance(certobj, X509):
627 raise TypeError("certobj must be an X509 instance")
628
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500629 copy = _lib.X509_dup(certobj._x509)
630 add_result = _lib.SSL_CTX_add_extra_chain_cert(self._context, copy)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800631 if not add_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500632 # TODO: This is untested.
633 _lib.X509_free(copy)
634 _raise_current_error()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800635
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800636 def _raise_passphrase_exception(self):
637 if self._passphrase_helper is None:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500638 _raise_current_error()
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800639 exception = self._passphrase_helper.raise_if_problem(Error)
640 if exception is not None:
641 raise exception
642
Jean-Paul Calderone00f84eb2015-04-13 12:47:21 -0400643 def use_privatekey_file(self, keyfile, filetype=_UNSPECIFIED):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800644 """
645 Load a private key from a file
646
Jean-Paul Calderoneb6f8a792015-04-13 10:10:06 -0400647 :param keyfile: The name of the key file (``bytes`` or ``unicode``)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800648 :param filetype: (optional) The encoding of the file, default is PEM
Jean-Paul Calderoneb6f8a792015-04-13 10:10:06 -0400649
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800650 :return: None
651 """
Jean-Paul Calderone69a4e5b2015-04-12 10:04:28 -0400652 keyfile = _path_string(keyfile)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800653
Jean-Paul Calderone00f84eb2015-04-13 12:47:21 -0400654 if filetype is _UNSPECIFIED:
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800655 filetype = FILETYPE_PEM
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -0500656 elif not isinstance(filetype, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800657 raise TypeError("filetype must be an integer")
658
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500659 use_result = _lib.SSL_CTX_use_PrivateKey_file(
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800660 self._context, keyfile, filetype)
661 if not use_result:
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800662 self._raise_passphrase_exception()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800663
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800664 def use_privatekey(self, pkey):
665 """
666 Load a private key from a PKey object
667
668 :param pkey: The PKey object
669 :return: None
670 """
671 if not isinstance(pkey, PKey):
672 raise TypeError("pkey must be a PKey instance")
673
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500674 use_result = _lib.SSL_CTX_use_PrivateKey(self._context, pkey._pkey)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800675 if not use_result:
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800676 self._raise_passphrase_exception()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800677
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800678 def check_privatekey(self):
679 """
680 Check that the private key and certificate match up
681
682 :return: None (raises an exception if something's wrong)
683 """
Jean-Paul Calderonea0344922014-12-11 14:02:31 -0500684 if not _lib.SSL_CTX_check_private_key(self._context):
685 _raise_current_error()
686
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800687 def load_client_ca(self, cafile):
688 """
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +0100689 Load the trusted certificates that will be sent to the client. Does
690 not actually imply any of the certificates are trusted; that must be
Alex Gaynor62da94d2015-09-05 14:37:34 -0400691 configured separately.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800692
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +0100693 :param bytes cafile: The path to a certificates file in PEM format.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800694 :return: None
695 """
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +0100696 ca_list = _lib.SSL_load_client_CA_file(
697 _text_to_bytes_and_warn("cafile", cafile)
698 )
699 _openssl_assert(ca_list != _ffi.NULL)
700 # SSL_CTX_set_client_CA_list doesn't return anything.
701 _lib.SSL_CTX_set_client_CA_list(self._context, ca_list)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800702
703 def set_session_id(self, buf):
704 """
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +0100705 Set the session id to *buf* within which a session can be reused for
706 this Context object. This is needed when doing session resumption,
707 because there is no way for a stored session to know which Context
708 object it is associated with.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800709
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +0100710 :param bytes buf: The session id.
711
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800712 :returns: None
713 """
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +0100714 buf = _text_to_bytes_and_warn("buf", buf)
715 _openssl_assert(
716 _lib.SSL_CTX_set_session_id_context(
717 self._context,
718 buf,
719 len(buf),
720 ) == 1
721 )
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800722
723 def set_session_cache_mode(self, mode):
724 """
725 Enable/disable session caching and specify the mode used.
726
727 :param mode: One or more of the SESS_CACHE_* flags (combine using
728 bitwise or)
729 :returns: The previously set caching mode.
730 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500731 if not isinstance(mode, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800732 raise TypeError("mode must be an integer")
733
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500734 return _lib.SSL_CTX_set_session_cache_mode(self._context, mode)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800735
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800736 def get_session_cache_mode(self):
737 """
738 :returns: The currently used cache mode.
739 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500740 return _lib.SSL_CTX_get_session_cache_mode(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800741
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800742 def set_verify(self, mode, callback):
743 """
744 Set the verify mode and verify callback
745
746 :param mode: The verify mode, this is either VERIFY_NONE or
747 VERIFY_PEER combined with possible other flags
748 :param callback: The Python callback to use
749 :return: None
750
751 See SSL_CTX_set_verify(3SSL) for further details.
752 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500753 if not isinstance(mode, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800754 raise TypeError("mode must be an integer")
755
756 if not callable(callback):
757 raise TypeError("callback must be callable")
758
Jean-Paul Calderone6a8cd112014-04-02 21:09:08 -0400759 self._verify_helper = _VerifyHelper(callback)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800760 self._verify_callback = self._verify_helper.callback
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500761 _lib.SSL_CTX_set_verify(self._context, mode, self._verify_callback)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800762
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800763 def set_verify_depth(self, depth):
764 """
765 Set the verify depth
766
767 :param depth: An integer specifying the verify depth
768 :return: None
769 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500770 if not isinstance(depth, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800771 raise TypeError("depth must be an integer")
772
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500773 _lib.SSL_CTX_set_verify_depth(self._context, depth)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800774
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800775 def get_verify_mode(self):
776 """
777 Get the verify mode
778
779 :return: The verify mode
780 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500781 return _lib.SSL_CTX_get_verify_mode(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800782
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800783 def get_verify_depth(self):
784 """
785 Get the verify depth
786
787 :return: The verify depth
788 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500789 return _lib.SSL_CTX_get_verify_depth(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800790
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800791 def load_tmp_dh(self, dhfile):
792 """
793 Load parameters for Ephemeral Diffie-Hellman
794
Jean-Paul Calderone4e0c43f2015-04-13 10:15:17 -0400795 :param dhfile: The file to load EDH parameters from (``bytes`` or
796 ``unicode``).
797
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800798 :return: None
799 """
Jean-Paul Calderone9e1c1dd2015-04-12 10:13:13 -0400800 dhfile = _path_string(dhfile)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800801
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -0500802 bio = _lib.BIO_new_file(dhfile, b"r")
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500803 if bio == _ffi.NULL:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500804 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500805 bio = _ffi.gc(bio, _lib.BIO_free)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800806
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500807 dh = _lib.PEM_read_bio_DHparams(bio, _ffi.NULL, _ffi.NULL, _ffi.NULL)
808 dh = _ffi.gc(dh, _lib.DH_free)
809 _lib.SSL_CTX_set_tmp_dh(self._context, dh)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800810
Jean-Paul Calderone3e4e3352014-04-19 09:28:28 -0400811 def set_tmp_ecdh(self, curve):
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600812 """
Andy Lutomirski76a61332014-03-12 15:02:56 -0700813 Select a curve to use for ECDHE key exchange.
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600814
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -0400815 :param curve: A curve object to use as returned by either
816 :py:meth:`OpenSSL.crypto.get_elliptic_curve` or
817 :py:meth:`OpenSSL.crypto.get_elliptic_curves`.
Andy Lutomirskif05a2732014-03-13 17:22:25 -0700818
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600819 :return: None
820 """
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -0400821 _lib.SSL_CTX_set_tmp_ecdh(self._context, curve._to_EC_KEY())
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600822
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800823 def set_cipher_list(self, cipher_list):
824 """
Hynek Schlawackf90e3682016-03-11 11:21:13 +0100825 Set the list of ciphers to be used in this context.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800826
Hynek Schlawackf90e3682016-03-11 11:21:13 +0100827 See the OpenSSL manual for more information (e.g.
828 :manpage:`ciphers(1)`).
829
830 :param bytes cipher_list: An OpenSSL cipher string.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800831 :return: None
832 """
Hynek Schlawackf90e3682016-03-11 11:21:13 +0100833 cipher_list = _text_to_bytes_and_warn("cipher_list", cipher_list)
Jean-Paul Calderone63eab692014-01-18 10:19:56 -0500834
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800835 if not isinstance(cipher_list, bytes):
Hynek Schlawacka7a63af2016-03-11 12:05:26 +0100836 raise TypeError("cipher_list must be a byte string.")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800837
Hynek Schlawackf90e3682016-03-11 11:21:13 +0100838 _openssl_assert(
Hynek Schlawack22a4b662016-03-11 14:59:39 +0100839 _lib.SSL_CTX_set_cipher_list(self._context, cipher_list) == 1
Hynek Schlawackf90e3682016-03-11 11:21:13 +0100840 )
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800841
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800842 def set_client_ca_list(self, certificate_authorities):
843 """
Alex Gaynor62da94d2015-09-05 14:37:34 -0400844 Set the list of preferred client certificate signers for this server
845 context.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800846
Alex Gaynor62da94d2015-09-05 14:37:34 -0400847 This list of certificate authorities will be sent to the client when
848 the server requests a client certificate.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800849
850 :param certificate_authorities: a sequence of X509Names.
851 :return: None
852 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500853 name_stack = _lib.sk_X509_NAME_new_null()
Alex Gaynora829e902016-06-04 18:16:01 -0700854 _openssl_assert(name_stack != _ffi.NULL)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800855
856 try:
857 for ca_name in certificate_authorities:
858 if not isinstance(ca_name, X509Name):
859 raise TypeError(
Alex Gaynor62da94d2015-09-05 14:37:34 -0400860 "client CAs must be X509Name objects, not %s "
861 "objects" % (
862 type(ca_name).__name__,
863 )
864 )
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500865 copy = _lib.X509_NAME_dup(ca_name._name)
Alex Gaynora829e902016-06-04 18:16:01 -0700866 _openssl_assert(copy != _ffi.NULL)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500867 push_result = _lib.sk_X509_NAME_push(name_stack, copy)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800868 if not push_result:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500869 _lib.X509_NAME_free(copy)
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500870 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800871 except:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500872 _lib.sk_X509_NAME_free(name_stack)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800873 raise
874
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500875 _lib.SSL_CTX_set_client_CA_list(self._context, name_stack)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800876
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800877 def add_client_ca(self, certificate_authority):
878 """
Alex Gaynor62da94d2015-09-05 14:37:34 -0400879 Add the CA certificate to the list of preferred signers for this
880 context.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800881
882 The list of certificate authorities will be sent to the client when the
883 server requests a client certificate.
884
885 :param certificate_authority: certificate authority's X509 certificate.
886 :return: None
887 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800888 if not isinstance(certificate_authority, X509):
889 raise TypeError("certificate_authority must be an X509 instance")
890
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500891 add_result = _lib.SSL_CTX_add_client_CA(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800892 self._context, certificate_authority._x509)
893 if not add_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500894 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500895 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800896
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800897 def set_timeout(self, timeout):
898 """
899 Set session timeout
900
901 :param timeout: The timeout in seconds
902 :return: The previous session timeout
903 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500904 if not isinstance(timeout, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800905 raise TypeError("timeout must be an integer")
906
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500907 return _lib.SSL_CTX_set_timeout(self._context, timeout)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800908
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800909 def get_timeout(self):
910 """
911 Get the session timeout
912
913 :return: The session timeout
914 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500915 return _lib.SSL_CTX_get_timeout(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800916
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800917 def set_info_callback(self, callback):
918 """
919 Set the info callback
920
921 :param callback: The Python callback to use
922 :return: None
923 """
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800924 @wraps(callback)
925 def wrapper(ssl, where, return_code):
Jean-Paul Calderonef2bbc9c2014-02-02 10:59:14 -0500926 callback(Connection._reverse_mapping[ssl], where, return_code)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500927 self._info_callback = _ffi.callback(
928 "void (*)(const SSL *, int, int)", wrapper)
929 _lib.SSL_CTX_set_info_callback(self._context, self._info_callback)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800930
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800931 def get_app_data(self):
932 """
933 Get the application data (supplied via set_app_data())
934
935 :return: The application data
936 """
937 return self._app_data
938
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800939 def set_app_data(self, data):
940 """
941 Set the application data (will be returned from get_app_data())
942
943 :param data: Any Python object
944 :return: None
945 """
946 self._app_data = data
947
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800948 def get_cert_store(self):
949 """
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500950 Get the certificate store for the context.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800951
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500952 :return: A X509Store object or None if it does not have one.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800953 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500954 store = _lib.SSL_CTX_get_cert_store(self._context)
955 if store == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500956 # TODO: This is untested.
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800957 return None
958
959 pystore = X509Store.__new__(X509Store)
960 pystore._store = store
961 return pystore
962
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800963 def set_options(self, options):
964 """
965 Add options. Options set before are not cleared!
966
967 :param options: The options to add.
968 :return: The new option bitmask.
969 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500970 if not isinstance(options, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800971 raise TypeError("options must be an integer")
972
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500973 return _lib.SSL_CTX_set_options(self._context, options)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800974
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800975 def set_mode(self, mode):
976 """
977 Add modes via bitmask. Modes set before are not cleared!
978
979 :param mode: The mode to add.
980 :return: The new mode bitmask.
981 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500982 if not isinstance(mode, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800983 raise TypeError("mode must be an integer")
984
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500985 return _lib.SSL_CTX_set_mode(self._context, mode)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800986
Cory Benfielde6f35882016-03-29 11:21:04 +0100987 @_requires_sni
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800988 def set_tlsext_servername_callback(self, callback):
989 """
Alex Gaynor62da94d2015-09-05 14:37:34 -0400990 Specify a callback function to be called when clients specify a server
991 name.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800992
993 :param callback: The callback function. It will be invoked with one
994 argument, the Connection instance.
995 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800996 @wraps(callback)
997 def wrapper(ssl, alert, arg):
998 callback(Connection._reverse_mapping[ssl])
999 return 0
1000
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001001 self._tlsext_servername_callback = _ffi.callback(
1002 "int (*)(const SSL *, int *, void *)", wrapper)
1003 _lib.SSL_CTX_set_tlsext_servername_callback(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001004 self._context, self._tlsext_servername_callback)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -08001005
Cory Benfield10b277f2015-04-13 17:12:42 -04001006 @_requires_npn
Cory Benfield84a121e2014-03-31 20:30:25 +01001007 def set_npn_advertise_callback(self, callback):
1008 """
Cory Benfieldbe3e7b82014-05-10 09:48:55 +01001009 Specify a callback function that will be called when offering `Next
1010 Protocol Negotiation
1011 <https://technotes.googlecode.com/git/nextprotoneg.html>`_ as a server.
Cory Benfield84a121e2014-03-31 20:30:25 +01001012
1013 :param callback: The callback function. It will be invoked with one
Cory Benfieldbe3e7b82014-05-10 09:48:55 +01001014 argument, the Connection instance. It should return a list of
1015 bytestrings representing the advertised protocols, like
1016 ``[b'http/1.1', b'spdy/2']``.
Cory Benfield84a121e2014-03-31 20:30:25 +01001017 """
Cory Benfield0ea76e72015-03-22 09:05:28 +00001018 self._npn_advertise_helper = _NpnAdvertiseHelper(callback)
1019 self._npn_advertise_callback = self._npn_advertise_helper.callback
Cory Benfield84a121e2014-03-31 20:30:25 +01001020 _lib.SSL_CTX_set_next_protos_advertised_cb(
1021 self._context, self._npn_advertise_callback, _ffi.NULL)
1022
Cory Benfield10b277f2015-04-13 17:12:42 -04001023 @_requires_npn
Cory Benfield84a121e2014-03-31 20:30:25 +01001024 def set_npn_select_callback(self, callback):
1025 """
1026 Specify a callback function that will be called when a server offers
1027 Next Protocol Negotiation options.
1028
1029 :param callback: The callback function. It will be invoked with two
1030 arguments: the Connection, and a list of offered protocols as
Cory Benfieldbe3e7b82014-05-10 09:48:55 +01001031 bytestrings, e.g. ``[b'http/1.1', b'spdy/2']``. It should return
1032 one of those bytestrings, the chosen protocol.
Cory Benfield84a121e2014-03-31 20:30:25 +01001033 """
Cory Benfield0ea76e72015-03-22 09:05:28 +00001034 self._npn_select_helper = _NpnSelectHelper(callback)
1035 self._npn_select_callback = self._npn_select_helper.callback
Cory Benfield84a121e2014-03-31 20:30:25 +01001036 _lib.SSL_CTX_set_next_proto_select_cb(
1037 self._context, self._npn_select_callback, _ffi.NULL)
1038
Cory Benfield7907e332015-04-13 17:18:25 -04001039 @_requires_alpn
Cory Benfield12eae892014-06-07 15:42:56 +01001040 def set_alpn_protos(self, protos):
1041 """
Cory Benfielde8e9c382015-04-11 17:33:48 -04001042 Specify the clients ALPN protocol list.
1043
1044 These protocols are offered to the server during protocol negotiation.
Cory Benfield12eae892014-06-07 15:42:56 +01001045
1046 :param protos: A list of the protocols to be offered to the server.
1047 This list should be a Python list of bytestrings representing the
1048 protocols to offer, e.g. ``[b'http/1.1', b'spdy/2']``.
1049 """
1050 # Take the list of protocols and join them together, prefixing them
1051 # with their lengths.
1052 protostr = b''.join(
1053 chain.from_iterable((int2byte(len(p)), p) for p in protos)
1054 )
1055
1056 # Build a C string from the list. We don't need to save this off
1057 # because OpenSSL immediately copies the data out.
1058 input_str = _ffi.new("unsigned char[]", protostr)
Cory Benfielde871af52015-04-11 17:57:50 -04001059 input_str_len = _ffi.cast("unsigned", len(protostr))
1060 _lib.SSL_CTX_set_alpn_protos(self._context, input_str, input_str_len)
Cory Benfield12eae892014-06-07 15:42:56 +01001061
Cory Benfield7907e332015-04-13 17:18:25 -04001062 @_requires_alpn
Cory Benfield12eae892014-06-07 15:42:56 +01001063 def set_alpn_select_callback(self, callback):
1064 """
Cory Benfielde8e9c382015-04-11 17:33:48 -04001065 Set the callback to handle ALPN protocol choice.
Cory Benfield12eae892014-06-07 15:42:56 +01001066
1067 :param callback: The callback function. It will be invoked with two
1068 arguments: the Connection, and a list of offered protocols as
1069 bytestrings, e.g ``[b'http/1.1', b'spdy/2']``. It should return
Cory Benfielde8e9c382015-04-11 17:33:48 -04001070 one of those bytestrings, the chosen protocol.
Cory Benfield12eae892014-06-07 15:42:56 +01001071 """
Cory Benfield9da5ffb2015-04-13 17:20:14 -04001072 self._alpn_select_helper = _ALPNSelectHelper(callback)
Cory Benfieldf1177e72015-04-12 09:11:49 -04001073 self._alpn_select_callback = self._alpn_select_helper.callback
Cory Benfield12eae892014-06-07 15:42:56 +01001074 _lib.SSL_CTX_set_alpn_select_cb(
1075 self._context, self._alpn_select_callback, _ffi.NULL)
1076
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -08001077ContextType = Context
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001078
1079
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001080class Connection(object):
1081 """
1082 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001083 _reverse_mapping = WeakValueDictionary()
1084
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001085 def __init__(self, context, socket=None):
1086 """
1087 Create a new Connection object, using the given OpenSSL.SSL.Context
1088 instance and socket.
1089
1090 :param context: An SSL Context to use for this connection
1091 :param socket: The socket to use for transport layer
1092 """
1093 if not isinstance(context, Context):
1094 raise TypeError("context must be a Context instance")
1095
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001096 ssl = _lib.SSL_new(context._context)
1097 self._ssl = _ffi.gc(ssl, _lib.SSL_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001098 self._context = context
Todd Chapman4f73e4f2015-08-27 11:26:43 -04001099 self._app_data = None
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001100
Cory Benfieldbe3e7b82014-05-10 09:48:55 +01001101 # References to strings used for Next Protocol Negotiation. OpenSSL's
1102 # header files suggest that these might get copied at some point, but
1103 # doesn't specify when, so we store them here to make sure they don't
1104 # get freed before OpenSSL uses them.
1105 self._npn_advertise_callback_args = None
1106 self._npn_select_callback_args = None
1107
Cory Benfield12eae892014-06-07 15:42:56 +01001108 # References to strings used for Application Layer Protocol
1109 # Negotiation. These strings get copied at some point but it's well
1110 # after the callback returns, so we have to hang them somewhere to
1111 # avoid them getting freed.
1112 self._alpn_select_callback_args = None
1113
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001114 self._reverse_mapping[self._ssl] = self
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001115
1116 if socket is None:
1117 self._socket = None
Jean-Paul Calderone73b15c22013-03-05 18:30:39 -08001118 # Don't set up any gc for these, SSL_free will take care of them.
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001119 self._into_ssl = _lib.BIO_new(_lib.BIO_s_mem())
Alex Gaynora829e902016-06-04 18:16:01 -07001120 _openssl_assert(self._into_ssl != _ffi.NULL)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001121
Alex Gaynora829e902016-06-04 18:16:01 -07001122 self._from_ssl = _lib.BIO_new(_lib.BIO_s_mem())
1123 _openssl_assert(self._from_ssl != _ffi.NULL)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001124
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001125 _lib.SSL_set_bio(self._ssl, self._into_ssl, self._from_ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001126 else:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001127 self._into_ssl = None
1128 self._from_ssl = None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001129 self._socket = socket
Alex Gaynor62da94d2015-09-05 14:37:34 -04001130 set_result = _lib.SSL_set_fd(
1131 self._ssl, _asFileDescriptor(self._socket))
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001132 if not set_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001133 # TODO: This is untested.
1134 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001135
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001136 def __getattr__(self, name):
1137 """
Alex Gaynor62da94d2015-09-05 14:37:34 -04001138 Look up attributes on the wrapped socket object if they are not found
1139 on the Connection object.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001140 """
kjav0b66fa12015-09-02 11:51:26 +01001141 if self._socket is None:
Alex Gaynor62da94d2015-09-05 14:37:34 -04001142 raise AttributeError("'%s' object has no attribute '%s'" % (
1143 self.__class__.__name__, name
1144 ))
kjav0b66fa12015-09-02 11:51:26 +01001145 else:
1146 return getattr(self._socket, name)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001147
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001148 def _raise_ssl_error(self, ssl, result):
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -08001149 if self._context._verify_helper is not None:
1150 self._context._verify_helper.raise_if_problem()
Cory Benfield0ea76e72015-03-22 09:05:28 +00001151 if self._context._npn_advertise_helper is not None:
1152 self._context._npn_advertise_helper.raise_if_problem()
1153 if self._context._npn_select_helper is not None:
1154 self._context._npn_select_helper.raise_if_problem()
Cory Benfieldf1177e72015-04-12 09:11:49 -04001155 if self._context._alpn_select_helper is not None:
1156 self._context._alpn_select_helper.raise_if_problem()
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -08001157
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001158 error = _lib.SSL_get_error(ssl, result)
1159 if error == _lib.SSL_ERROR_WANT_READ:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001160 raise WantReadError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001161 elif error == _lib.SSL_ERROR_WANT_WRITE:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001162 raise WantWriteError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001163 elif error == _lib.SSL_ERROR_ZERO_RETURN:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001164 raise ZeroReturnError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001165 elif error == _lib.SSL_ERROR_WANT_X509_LOOKUP:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001166 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001167 raise WantX509LookupError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001168 elif error == _lib.SSL_ERROR_SYSCALL:
1169 if _lib.ERR_peek_error() == 0:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001170 if result < 0:
Konstantinos Koukopoulos541150d2014-01-31 01:00:19 +02001171 if platform == "win32":
1172 errno = _ffi.getwinerror()[0]
1173 else:
1174 errno = _ffi.errno
Glyph3afdba82015-04-14 17:30:53 -04001175 raise SysCallError(errno, errorcode.get(errno))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001176 else:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001177 raise SysCallError(-1, "Unexpected EOF")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001178 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001179 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001180 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001181 elif error == _lib.SSL_ERROR_NONE:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001182 pass
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001183 else:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001184 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001185
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001186 def get_context(self):
1187 """
1188 Get session context
1189 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001190 return self._context
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001191
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001192 def set_context(self, context):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001193 """
1194 Switch this connection to a new session context
1195
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001196 :param context: A :py:class:`Context` instance giving the new session
1197 context to use.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001198 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001199 if not isinstance(context, Context):
1200 raise TypeError("context must be a Context instance")
1201
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001202 _lib.SSL_set_SSL_CTX(self._ssl, context._context)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001203 self._context = context
1204
Cory Benfielde6f35882016-03-29 11:21:04 +01001205 @_requires_sni
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001206 def get_servername(self):
1207 """
1208 Retrieve the servername extension value if provided in the client hello
1209 message, or None if there wasn't one.
1210
1211 :return: A byte string giving the server name or :py:data:`None`.
1212 """
Alex Gaynor62da94d2015-09-05 14:37:34 -04001213 name = _lib.SSL_get_servername(
1214 self._ssl, _lib.TLSEXT_NAMETYPE_host_name
1215 )
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001216 if name == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001217 return None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001218
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001219 return _ffi.string(name)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001220
Cory Benfielde6f35882016-03-29 11:21:04 +01001221 @_requires_sni
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001222 def set_tlsext_host_name(self, name):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001223 """
1224 Set the value of the servername extension to send in the client hello.
1225
1226 :param name: A byte string giving the name.
1227 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001228 if not isinstance(name, bytes):
1229 raise TypeError("name must be a byte string")
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001230 elif b"\0" in name:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001231 raise TypeError("name must not contain NUL byte")
1232
1233 # XXX I guess this can fail sometimes?
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001234 _lib.SSL_set_tlsext_host_name(self._ssl, name)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001235
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001236 def pending(self):
1237 """
1238 Get the number of bytes that can be safely read from the connection
1239
1240 :return: The number of bytes available in the receive buffer.
1241 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001242 return _lib.SSL_pending(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001243
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001244 def send(self, buf, flags=0):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001245 """
1246 Send data on the connection. NOTE: If you get one of the WantRead,
1247 WantWrite or WantX509Lookup exceptions on this, you have to call the
1248 method again with the SAME buffer.
1249
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001250 :param buf: The string, buffer or memoryview to send
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001251 :param flags: (optional) Included for compatibility with the socket
1252 API, the value is ignored
1253 :return: The number of bytes written
1254 """
Abraham Martine82326c2015-02-04 10:18:10 +00001255 # Backward compatibility
Jean-Paul Calderone39a8d592015-04-13 20:49:50 -04001256 buf = _text_to_bytes_and_warn("buf", buf)
Abraham Martine82326c2015-02-04 10:18:10 +00001257
Jean-Paul Calderone8fb53182013-12-30 08:35:49 -05001258 if isinstance(buf, _memoryview):
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -08001259 buf = buf.tobytes()
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001260 if isinstance(buf, _buffer):
1261 buf = str(buf)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001262 if not isinstance(buf, bytes):
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001263 raise TypeError("data must be a memoryview, buffer or byte string")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001264
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001265 result = _lib.SSL_write(self._ssl, buf, len(buf))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001266 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001267 return result
1268 write = send
1269
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001270 def sendall(self, buf, flags=0):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001271 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001272 Send "all" data on the connection. This calls send() repeatedly until
1273 all data is sent. If an error occurs, it's impossible to tell how much
1274 data has been sent.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001275
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001276 :param buf: The string, buffer or memoryview to send
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001277 :param flags: (optional) Included for compatibility with the socket
1278 API, the value is ignored
1279 :return: The number of bytes written
1280 """
Jean-Paul Calderone39a8d592015-04-13 20:49:50 -04001281 buf = _text_to_bytes_and_warn("buf", buf)
Abraham Martine82326c2015-02-04 10:18:10 +00001282
Jean-Paul Calderone8fb53182013-12-30 08:35:49 -05001283 if isinstance(buf, _memoryview):
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -08001284 buf = buf.tobytes()
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001285 if isinstance(buf, _buffer):
1286 buf = str(buf)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001287 if not isinstance(buf, bytes):
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001288 raise TypeError("buf must be a memoryview, buffer or byte string")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001289
1290 left_to_send = len(buf)
1291 total_sent = 0
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001292 data = _ffi.new("char[]", buf)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001293
1294 while left_to_send:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001295 result = _lib.SSL_write(self._ssl, data + total_sent, left_to_send)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001296 self._raise_ssl_error(self._ssl, result)
1297 total_sent += result
1298 left_to_send -= result
1299
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001300 def recv(self, bufsiz, flags=None):
1301 """
Alex Gaynor67fc8c92016-05-27 08:27:19 -04001302 Receive data on the connection.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001303
1304 :param bufsiz: The maximum number of bytes to read
Maximilian Hils1d95dea2015-08-17 19:27:20 +02001305 :param flags: (optional) The only supported flag is ``MSG_PEEK``,
1306 all other flags are ignored.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001307 :return: The string read from the Connection
1308 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001309 buf = _ffi.new("char[]", bufsiz)
Maximilian Hils1d95dea2015-08-17 19:27:20 +02001310 if flags is not None and flags & socket.MSG_PEEK:
1311 result = _lib.SSL_peek(self._ssl, buf, bufsiz)
1312 else:
1313 result = _lib.SSL_read(self._ssl, buf, bufsiz)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001314 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001315 return _ffi.buffer(buf, result)[:]
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001316 read = recv
1317
Cory Benfield62d10332014-06-15 10:03:41 +01001318 def recv_into(self, buffer, nbytes=None, flags=None):
1319 """
1320 Receive data on the connection and store the data into a buffer rather
1321 than creating a new string.
1322
1323 :param buffer: The buffer to copy into.
1324 :param nbytes: (optional) The maximum number of bytes to read into the
1325 buffer. If not present, defaults to the size of the buffer. If
1326 larger than the size of the buffer, is reduced to the size of the
1327 buffer.
Maximilian Hils1d95dea2015-08-17 19:27:20 +02001328 :param flags: (optional) The only supported flag is ``MSG_PEEK``,
1329 all other flags are ignored.
Cory Benfield62d10332014-06-15 10:03:41 +01001330 :return: The number of bytes read into the buffer.
1331 """
1332 if nbytes is None:
1333 nbytes = len(buffer)
1334 else:
1335 nbytes = min(nbytes, len(buffer))
1336
1337 # We need to create a temporary buffer. This is annoying, it would be
1338 # better if we could pass memoryviews straight into the SSL_read call,
1339 # but right now we can't. Revisit this if CFFI gets that ability.
1340 buf = _ffi.new("char[]", nbytes)
Maximilian Hils1d95dea2015-08-17 19:27:20 +02001341 if flags is not None and flags & socket.MSG_PEEK:
1342 result = _lib.SSL_peek(self._ssl, buf, nbytes)
1343 else:
1344 result = _lib.SSL_read(self._ssl, buf, nbytes)
Cory Benfield62d10332014-06-15 10:03:41 +01001345 self._raise_ssl_error(self._ssl, result)
1346
1347 # This strange line is all to avoid a memory copy. The buffer protocol
1348 # should allow us to assign a CFFI buffer to the LHS of this line, but
1349 # on CPython 3.3+ that segfaults. As a workaround, we can temporarily
1350 # wrap it in a memoryview, except on Python 2.6 which doesn't have a
1351 # memoryview type.
1352 try:
1353 buffer[:result] = memoryview(_ffi.buffer(buf, result))
1354 except NameError:
1355 buffer[:result] = _ffi.buffer(buf, result)
1356
1357 return result
1358
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001359 def _handle_bio_errors(self, bio, result):
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001360 if _lib.BIO_should_retry(bio):
1361 if _lib.BIO_should_read(bio):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001362 raise WantReadError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001363 elif _lib.BIO_should_write(bio):
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001364 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001365 raise WantWriteError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001366 elif _lib.BIO_should_io_special(bio):
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001367 # TODO: This is untested. I think io_special means the socket
1368 # BIO has a not-yet connected socket.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001369 raise ValueError("BIO_should_io_special")
1370 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001371 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001372 raise ValueError("unknown bio failure")
1373 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001374 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001375 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001376
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001377 def bio_read(self, bufsiz):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001378 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001379 When using non-socket connections this function reads the "dirty" data
1380 that would have traveled away on the network.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001381
1382 :param bufsiz: The maximum number of bytes to read
1383 :return: The string read.
1384 """
Jean-Paul Calderone97e041d2013-03-05 21:03:12 -08001385 if self._from_ssl is None:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001386 raise TypeError("Connection sock was not None")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001387
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -05001388 if not isinstance(bufsiz, integer_types):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001389 raise TypeError("bufsiz must be an integer")
1390
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001391 buf = _ffi.new("char[]", bufsiz)
1392 result = _lib.BIO_read(self._from_ssl, buf, bufsiz)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001393 if result <= 0:
1394 self._handle_bio_errors(self._from_ssl, result)
1395
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001396 return _ffi.buffer(buf, result)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001397
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001398 def bio_write(self, buf):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001399 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001400 When using non-socket connections this function sends "dirty" data that
1401 would have traveled in on the network.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001402
1403 :param buf: The string to put into the memory BIO.
1404 :return: The number of bytes written
1405 """
Jean-Paul Calderone39a8d592015-04-13 20:49:50 -04001406 buf = _text_to_bytes_and_warn("buf", buf)
Abraham Martine82326c2015-02-04 10:18:10 +00001407
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001408 if self._into_ssl is None:
1409 raise TypeError("Connection sock was not None")
1410
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001411 result = _lib.BIO_write(self._into_ssl, buf, len(buf))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001412 if result <= 0:
1413 self._handle_bio_errors(self._into_ssl, result)
1414 return result
1415
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001416 def renegotiate(self):
1417 """
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +01001418 Renegotiate the session.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001419
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +01001420 :return: True if the renegotiation can be started, False otherwise
1421 :rtype: bool
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001422 """
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +01001423 if not self.renegotiate_pending():
1424 _openssl_assert(_lib.SSL_renegotiate(self._ssl) == 1)
1425 return True
1426 return False
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001427
1428 def do_handshake(self):
1429 """
1430 Perform an SSL handshake (usually called after renegotiate() or one of
1431 set_*_state()). This can raise the same exceptions as send and recv.
1432
1433 :return: None.
1434 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001435 result = _lib.SSL_do_handshake(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001436 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001437
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001438 def renegotiate_pending(self):
1439 """
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +01001440 Check if there's a renegotiation in progress, it will return False once
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001441 a renegotiation is finished.
1442
1443 :return: Whether there's a renegotiation in progress
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +01001444 :rtype: bool
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001445 """
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +01001446 return _lib.SSL_renegotiate_pending(self._ssl) == 1
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001447
1448 def total_renegotiations(self):
1449 """
1450 Find out the total number of renegotiations.
1451
1452 :return: The number of renegotiations.
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +01001453 :rtype: int
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001454 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001455 return _lib.SSL_total_renegotiations(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001456
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001457 def connect(self, addr):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001458 """
1459 Connect to remote host and set up client-side SSL
1460
1461 :param addr: A remote address
1462 :return: What the socket's connect method returns
1463 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001464 _lib.SSL_set_connect_state(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001465 return self._socket.connect(addr)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001466
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001467 def connect_ex(self, addr):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001468 """
Alex Gaynor62da94d2015-09-05 14:37:34 -04001469 Connect to remote host and set up client-side SSL. Note that if the
1470 socket's connect_ex method doesn't return 0, SSL won't be initialized.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001471
1472 :param addr: A remove address
1473 :return: What the socket's connect_ex method returns
1474 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001475 connect_ex = self._socket.connect_ex
1476 self.set_connect_state()
1477 return connect_ex(addr)
1478
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001479 def accept(self):
1480 """
1481 Accept incoming connection and set up SSL on it
1482
1483 :return: A (conn,addr) pair where conn is a Connection and addr is an
1484 address
1485 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001486 client, addr = self._socket.accept()
1487 conn = Connection(self._context, client)
1488 conn.set_accept_state()
1489 return (conn, addr)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001490
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001491 def bio_shutdown(self):
1492 """
1493 When using non-socket connections this function signals end of
1494 data on the input for this connection.
1495
1496 :return: None
1497 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001498 if self._from_ssl is None:
1499 raise TypeError("Connection sock was not None")
1500
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001501 _lib.BIO_set_mem_eof_return(self._into_ssl, 0)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001502
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001503 def shutdown(self):
1504 """
1505 Send closure alert
1506
1507 :return: True if the shutdown completed successfully (i.e. both sides
1508 have sent closure alerts), false otherwise (i.e. you have to
1509 wait for a ZeroReturnError on a recv() method call
1510 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001511 result = _lib.SSL_shutdown(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001512 if result < 0:
Paul Aurichbff1d1a2015-01-08 08:36:53 -08001513 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001514 elif result > 0:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001515 return True
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001516 else:
1517 return False
1518
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001519 def get_cipher_list(self):
1520 """
Hynek Schlawackf90e3682016-03-11 11:21:13 +01001521 Retrieve the list of ciphers used by the Connection object.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001522
Hynek Schlawackf90e3682016-03-11 11:21:13 +01001523 :return: A list of native cipher strings.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001524 """
1525 ciphers = []
1526 for i in count():
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001527 result = _lib.SSL_get_cipher_list(self._ssl, i)
1528 if result == _ffi.NULL:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001529 break
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001530 ciphers.append(_native(_ffi.string(result)))
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001531 return ciphers
1532
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001533 def get_client_ca_list(self):
1534 """
1535 Get CAs whose certificates are suggested for client authentication.
1536
Alex Gaynor62da94d2015-09-05 14:37:34 -04001537 :return: If this is a server connection, a list of X509Names
1538 representing the acceptable CAs as set by
1539 :py:meth:`OpenSSL.SSL.Context.set_client_ca_list` or
1540 :py:meth:`OpenSSL.SSL.Context.add_client_ca`. If this is a client
1541 connection, the list of such X509Names sent by the server, or an
1542 empty list if that has not yet happened.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001543 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001544 ca_names = _lib.SSL_get_client_CA_list(self._ssl)
1545 if ca_names == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001546 # TODO: This is untested.
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001547 return []
1548
1549 result = []
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001550 for i in range(_lib.sk_X509_NAME_num(ca_names)):
1551 name = _lib.sk_X509_NAME_value(ca_names, i)
1552 copy = _lib.X509_NAME_dup(name)
Alex Gaynora829e902016-06-04 18:16:01 -07001553 _openssl_assert(copy != _ffi.NULL)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001554
1555 pyname = X509Name.__new__(X509Name)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001556 pyname._name = _ffi.gc(copy, _lib.X509_NAME_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001557 result.append(pyname)
1558 return result
1559
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001560 def makefile(self):
1561 """
Alex Gaynor62da94d2015-09-05 14:37:34 -04001562 The makefile() method is not implemented, since there is no dup
1563 semantics for SSL connections
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001564
Jean-Paul Calderone6749ec22014-04-17 16:30:21 -04001565 :raise: NotImplementedError
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001566 """
Alex Gaynor83284952015-09-05 10:43:30 -04001567 raise NotImplementedError(
1568 "Cannot make file object of OpenSSL.SSL.Connection")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001569
1570 def get_app_data(self):
1571 """
1572 Get application data
1573
1574 :return: The application data
1575 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001576 return self._app_data
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001577
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001578 def set_app_data(self, data):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001579 """
1580 Set application data
1581
1582 :param data - The application data
1583 :return: None
1584 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001585 self._app_data = data
1586
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001587 def get_shutdown(self):
1588 """
1589 Get shutdown state
1590
Alex Gaynor62da94d2015-09-05 14:37:34 -04001591 :return: The shutdown state, a bitvector of SENT_SHUTDOWN,
1592 RECEIVED_SHUTDOWN.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001593 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001594 return _lib.SSL_get_shutdown(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001595
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001596 def set_shutdown(self, state):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001597 """
1598 Set shutdown state
1599
1600 :param state - bitvector of SENT_SHUTDOWN, RECEIVED_SHUTDOWN.
1601 :return: None
1602 """
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -05001603 if not isinstance(state, integer_types):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001604 raise TypeError("state must be an integer")
1605
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001606 _lib.SSL_set_shutdown(self._ssl, state)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001607
Hynek Schlawackea94f2b2016-03-13 16:17:53 +01001608 def get_state_string(self):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001609 """
Hynek Schlawackea94f2b2016-03-13 16:17:53 +01001610 Retrieve a verbose string detailing the state of the Connection.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001611
1612 :return: A string representing the state
Hynek Schlawackea94f2b2016-03-13 16:17:53 +01001613 :rtype: bytes
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001614 """
kjavc704a2e2015-09-07 12:12:27 +01001615 return _ffi.string(_lib.SSL_state_string_long(self._ssl))
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001616
1617 def server_random(self):
1618 """
1619 Get a copy of the server hello nonce.
1620
1621 :return: A string representing the state
1622 """
Alex Gaynor93603062016-06-01 20:13:09 -07001623 session = _lib.SSL_get_session(self._ssl)
1624 if session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001625 return None
Alex Gaynor93603062016-06-01 20:13:09 -07001626 length = _lib.SSL_get_server_random(self._ssl, _ffi.NULL, 0)
1627 assert length > 0
1628 outp = _ffi.new("char[]", length)
1629 _lib.SSL_get_server_random(self._ssl, outp, length)
1630 return _ffi.buffer(outp, length)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001631
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001632 def client_random(self):
1633 """
1634 Get a copy of the client hello nonce.
1635
1636 :return: A string representing the state
1637 """
Alex Gaynor93603062016-06-01 20:13:09 -07001638 session = _lib.SSL_get_session(self._ssl)
1639 if session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001640 return None
Alex Gaynor93603062016-06-01 20:13:09 -07001641
1642 length = _lib.SSL_get_client_random(self._ssl, _ffi.NULL, 0)
1643 assert length > 0
1644 outp = _ffi.new("char[]", length)
1645 _lib.SSL_get_client_random(self._ssl, outp, length)
1646 return _ffi.buffer(outp, length)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001647
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001648 def master_key(self):
1649 """
1650 Get a copy of the master key.
1651
1652 :return: A string representing the state
1653 """
Alex Gaynor93603062016-06-01 20:13:09 -07001654 session = _lib.SSL_get_session(self._ssl)
1655 if session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001656 return None
Alex Gaynor93603062016-06-01 20:13:09 -07001657
1658 length = _lib.SSL_SESSION_get_master_key(session, _ffi.NULL, 0)
1659 assert length > 0
1660 outp = _ffi.new("char[]", length)
1661 _lib.SSL_SESSION_get_master_key(session, outp, length)
1662 return _ffi.buffer(outp, length)[:]
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001663
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001664 def sock_shutdown(self, *args, **kwargs):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001665 """
1666 See shutdown(2)
1667
1668 :return: What the socket's shutdown() method returns
1669 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001670 return self._socket.shutdown(*args, **kwargs)
1671
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001672 def get_peer_certificate(self):
1673 """
1674 Retrieve the other side's certificate (if any)
1675
1676 :return: The peer's certificate
1677 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001678 cert = _lib.SSL_get_peer_certificate(self._ssl)
1679 if cert != _ffi.NULL:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001680 pycert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001681 pycert._x509 = _ffi.gc(cert, _lib.X509_free)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001682 return pycert
1683 return None
1684
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001685 def get_peer_cert_chain(self):
1686 """
1687 Retrieve the other side's certificate (if any)
1688
1689 :return: A list of X509 instances giving the peer's certificate chain,
1690 or None if it does not have one.
1691 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001692 cert_stack = _lib.SSL_get_peer_cert_chain(self._ssl)
1693 if cert_stack == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001694 return None
1695
1696 result = []
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001697 for i in range(_lib.sk_X509_num(cert_stack)):
Jean-Paul Calderone73b15c22013-03-05 18:30:39 -08001698 # TODO could incref instead of dup here
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001699 cert = _lib.X509_dup(_lib.sk_X509_value(cert_stack, i))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001700 pycert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001701 pycert._x509 = _ffi.gc(cert, _lib.X509_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001702 result.append(pycert)
1703 return result
1704
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001705 def want_read(self):
1706 """
Alex Gaynor62da94d2015-09-05 14:37:34 -04001707 Checks if more data has to be read from the transport layer to complete
1708 an operation.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001709
1710 :return: True iff more data has to be read
1711 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001712 return _lib.SSL_want_read(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001713
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001714 def want_write(self):
1715 """
1716 Checks if there is data to write to the transport layer to complete an
1717 operation.
1718
1719 :return: True iff there is data to write
1720 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001721 return _lib.SSL_want_write(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001722
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001723 def set_accept_state(self):
1724 """
Alex Gaynor62da94d2015-09-05 14:37:34 -04001725 Set the connection to work in server mode. The handshake will be
1726 handled automatically by read/write.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001727
1728 :return: None
1729 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001730 _lib.SSL_set_accept_state(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001731
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001732 def set_connect_state(self):
1733 """
Alex Gaynor62da94d2015-09-05 14:37:34 -04001734 Set the connection to work in client mode. The handshake will be
1735 handled automatically by read/write.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001736
1737 :return: None
1738 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001739 _lib.SSL_set_connect_state(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001740
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001741 def get_session(self):
1742 """
1743 Returns the Session currently used.
1744
Alex Gaynor62da94d2015-09-05 14:37:34 -04001745 @return: An instance of :py:class:`OpenSSL.SSL.Session` or
1746 :py:obj:`None` if no session exists.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001747 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001748 session = _lib.SSL_get1_session(self._ssl)
1749 if session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001750 return None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001751
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001752 pysession = Session.__new__(Session)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001753 pysession._session = _ffi.gc(session, _lib.SSL_SESSION_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001754 return pysession
1755
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001756 def set_session(self, session):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001757 """
1758 Set the session to be used when the TLS/SSL connection is established.
1759
1760 :param session: A Session instance representing the session to use.
1761 :returns: None
1762 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001763 if not isinstance(session, Session):
1764 raise TypeError("session must be a Session instance")
1765
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001766 result = _lib.SSL_set_session(self._ssl, session._session)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001767 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001768 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001769
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001770 def _get_finished_message(self, function):
1771 """
1772 Helper to implement :py:meth:`get_finished` and
1773 :py:meth:`get_peer_finished`.
1774
1775 :param function: Either :py:data:`SSL_get_finished`: or
1776 :py:data:`SSL_get_peer_finished`.
1777
1778 :return: :py:data:`None` if the desired message has not yet been
1779 received, otherwise the contents of the message.
1780 :rtype: :py:class:`bytes` or :py:class:`NoneType`
1781 """
Jean-Paul Calderone01af9042014-03-30 11:40:42 -04001782 # The OpenSSL documentation says nothing about what might happen if the
1783 # count argument given is zero. Specifically, it doesn't say whether
1784 # the output buffer may be NULL in that case or not. Inspection of the
1785 # implementation reveals that it calls memcpy() unconditionally.
1786 # Section 7.1.4, paragraph 1 of the C standard suggests that
1787 # memcpy(NULL, source, 0) is not guaranteed to produce defined (let
1788 # alone desirable) behavior (though it probably does on just about
1789 # every implementation...)
1790 #
1791 # Allocate a tiny buffer to pass in (instead of just passing NULL as
1792 # one might expect) for the initial call so as to be safe against this
1793 # potentially undefined behavior.
1794 empty = _ffi.new("char[]", 0)
1795 size = function(self._ssl, empty, 0)
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001796 if size == 0:
1797 # No Finished message so far.
1798 return None
1799
1800 buf = _ffi.new("char[]", size)
1801 function(self._ssl, buf, size)
1802 return _ffi.buffer(buf, size)[:]
1803
Fedor Brunner5747b932014-03-05 14:22:34 +01001804 def get_finished(self):
1805 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001806 Obtain the latest `handshake finished` message sent to the peer.
Fedor Brunner5747b932014-03-05 14:22:34 +01001807
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001808 :return: The contents of the message or :py:obj:`None` if the TLS
1809 handshake has not yet completed.
1810 :rtype: :py:class:`bytes` or :py:class:`NoneType`
Fedor Brunner5747b932014-03-05 14:22:34 +01001811 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001812 return self._get_finished_message(_lib.SSL_get_finished)
1813
Fedor Brunner5747b932014-03-05 14:22:34 +01001814 def get_peer_finished(self):
1815 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001816 Obtain the latest `handshake finished` message received from the peer.
Fedor Brunner5747b932014-03-05 14:22:34 +01001817
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001818 :return: The contents of the message or :py:obj:`None` if the TLS
1819 handshake has not yet completed.
1820 :rtype: :py:class:`bytes` or :py:class:`NoneType`
Fedor Brunner5747b932014-03-05 14:22:34 +01001821 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001822 return self._get_finished_message(_lib.SSL_get_peer_finished)
Fedor Brunner5747b932014-03-05 14:22:34 +01001823
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001824 def get_cipher_name(self):
1825 """
1826 Obtain the name of the currently used cipher.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001827
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001828 :returns: The name of the currently used cipher or :py:obj:`None`
1829 if no connection has been established.
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001830 :rtype: :py:class:`unicode` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001831 """
1832 cipher = _lib.SSL_get_current_cipher(self._ssl)
1833 if cipher == _ffi.NULL:
1834 return None
1835 else:
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001836 name = _ffi.string(_lib.SSL_CIPHER_get_name(cipher))
1837 return name.decode("utf-8")
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001838
1839 def get_cipher_bits(self):
1840 """
1841 Obtain the number of secret bits of the currently used cipher.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001842
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001843 :returns: The number of secret bits of the currently used cipher
1844 or :py:obj:`None` if no connection has been established.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001845 :rtype: :py:class:`int` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001846 """
1847 cipher = _lib.SSL_get_current_cipher(self._ssl)
1848 if cipher == _ffi.NULL:
1849 return None
1850 else:
1851 return _lib.SSL_CIPHER_get_bits(cipher, _ffi.NULL)
1852
1853 def get_cipher_version(self):
1854 """
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001855 Obtain the protocol version of the currently used cipher.
1856
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001857 :returns: The protocol name of the currently used cipher
1858 or :py:obj:`None` if no connection has been established.
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001859 :rtype: :py:class:`unicode` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001860 """
1861 cipher = _lib.SSL_get_current_cipher(self._ssl)
1862 if cipher == _ffi.NULL:
1863 return None
1864 else:
Alex Gaynorc4889812015-09-04 08:43:17 -04001865 version = _ffi.string(_lib.SSL_CIPHER_get_version(cipher))
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001866 return version.decode("utf-8")
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001867
Jim Shaverabff1882015-05-27 09:15:55 -04001868 def get_protocol_version_name(self):
Jim Shaverba65e662015-04-26 12:23:40 -04001869 """
1870 Obtain the protocol version of the current connection.
1871
1872 :returns: The TLS version of the current connection, for example
Jim Shaver58d25732015-05-28 11:52:32 -04001873 the value for TLS 1.2 would be ``TLSv1.2``or ``Unknown``
Jim Shaverb5b6b0e2015-05-28 16:47:36 -04001874 for connections that were not successfully established.
Jim Shaver58d25732015-05-28 11:52:32 -04001875 :rtype: :py:class:`unicode`
Jim Shaverba65e662015-04-26 12:23:40 -04001876 """
Jim Shaverd1c896e2015-05-27 17:50:21 -04001877 version = _ffi.string(_lib.SSL_get_version(self._ssl))
Jim Shaver58d25732015-05-28 11:52:32 -04001878 return version.decode("utf-8")
Jim Shaverb2967922015-04-26 23:58:52 -04001879
Jim Shaver208438c2015-05-28 09:52:38 -04001880 def get_protocol_version(self):
1881 """
1882 Obtain the protocol version of the current connection.
1883
1884 :returns: The TLS version of the current connection, for example
1885 the value for TLS 1 would be 0x769.
1886 :rtype: :py:class:`int`
1887 """
1888 version = _lib.SSL_version(self._ssl)
1889 return version
1890
Cory Benfield10b277f2015-04-13 17:12:42 -04001891 @_requires_npn
Cory Benfield84a121e2014-03-31 20:30:25 +01001892 def get_next_proto_negotiated(self):
1893 """
1894 Get the protocol that was negotiated by NPN.
1895 """
1896 data = _ffi.new("unsigned char **")
1897 data_len = _ffi.new("unsigned int *")
1898
1899 _lib.SSL_get0_next_proto_negotiated(self._ssl, data, data_len)
1900
Cory Benfieldcd010f62014-05-15 19:00:27 +01001901 return _ffi.buffer(data[0], data_len[0])[:]
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001902
Cory Benfield7907e332015-04-13 17:18:25 -04001903 @_requires_alpn
Cory Benfield12eae892014-06-07 15:42:56 +01001904 def set_alpn_protos(self, protos):
1905 """
Cory Benfielde8e9c382015-04-11 17:33:48 -04001906 Specify the client's ALPN protocol list.
1907
1908 These protocols are offered to the server during protocol negotiation.
Cory Benfield12eae892014-06-07 15:42:56 +01001909
1910 :param protos: A list of the protocols to be offered to the server.
1911 This list should be a Python list of bytestrings representing the
1912 protocols to offer, e.g. ``[b'http/1.1', b'spdy/2']``.
1913 """
1914 # Take the list of protocols and join them together, prefixing them
1915 # with their lengths.
1916 protostr = b''.join(
1917 chain.from_iterable((int2byte(len(p)), p) for p in protos)
1918 )
1919
1920 # Build a C string from the list. We don't need to save this off
1921 # because OpenSSL immediately copies the data out.
1922 input_str = _ffi.new("unsigned char[]", protostr)
Cory Benfield9c1979a2015-04-12 08:51:52 -04001923 input_str_len = _ffi.cast("unsigned", len(protostr))
1924 _lib.SSL_set_alpn_protos(self._ssl, input_str, input_str_len)
Cory Benfield12eae892014-06-07 15:42:56 +01001925
Maximilian Hils66ded6a2015-08-26 06:02:03 +02001926 @_requires_alpn
Cory Benfield12eae892014-06-07 15:42:56 +01001927 def get_alpn_proto_negotiated(self):
Cory Benfield222f30e2015-04-13 18:10:21 -04001928 """
1929 Get the protocol that was negotiated by ALPN.
1930 """
Cory Benfield12eae892014-06-07 15:42:56 +01001931 data = _ffi.new("unsigned char **")
1932 data_len = _ffi.new("unsigned int *")
1933
1934 _lib.SSL_get0_alpn_selected(self._ssl, data, data_len)
1935
Cory Benfielde8e9c382015-04-11 17:33:48 -04001936 if not data_len:
1937 return b''
1938
Cory Benfield12eae892014-06-07 15:42:56 +01001939 return _ffi.buffer(data[0], data_len[0])[:]
1940
1941
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001942ConnectionType = Connection
Jean-Paul Calderone11ed8e82014-01-18 10:21:50 -05001943
Jean-Paul Calderonefab157b2014-01-18 11:21:38 -05001944# This is similar to the initialization calls at the end of OpenSSL/crypto.py
1945# but is exercised mostly by the Context initializer.
Jean-Paul Calderone11ed8e82014-01-18 10:21:50 -05001946_lib.SSL_library_init()