blob: 98c34b4c1784f4fbaa1317719e7e4860c6d14da9 [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
Jean-Paul Calderone0d7e8a12014-01-08 16:54:13 -050062try:
63 MODE_RELEASE_BUFFERS = _lib.SSL_MODE_RELEASE_BUFFERS
64except AttributeError:
65 pass
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080066
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050067OP_SINGLE_DH_USE = _lib.SSL_OP_SINGLE_DH_USE
Akihiro Yamazakie64d80c2015-09-06 00:16:57 +090068OP_SINGLE_ECDH_USE = _lib.SSL_OP_SINGLE_ECDH_USE
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050069OP_EPHEMERAL_RSA = _lib.SSL_OP_EPHEMERAL_RSA
70OP_MICROSOFT_SESS_ID_BUG = _lib.SSL_OP_MICROSOFT_SESS_ID_BUG
71OP_NETSCAPE_CHALLENGE_BUG = _lib.SSL_OP_NETSCAPE_CHALLENGE_BUG
Alex Gaynor62da94d2015-09-05 14:37:34 -040072OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG = (
73 _lib.SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG
74)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050075OP_SSLREF2_REUSE_CERT_TYPE_BUG = _lib.SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG
76OP_MICROSOFT_BIG_SSLV3_BUFFER = _lib.SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER
Jean-Paul Calderone0d7e8a12014-01-08 16:54:13 -050077try:
78 OP_MSIE_SSLV2_RSA_PADDING = _lib.SSL_OP_MSIE_SSLV2_RSA_PADDING
79except AttributeError:
80 pass
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050081OP_SSLEAY_080_CLIENT_DH_BUG = _lib.SSL_OP_SSLEAY_080_CLIENT_DH_BUG
82OP_TLS_D5_BUG = _lib.SSL_OP_TLS_D5_BUG
83OP_TLS_BLOCK_PADDING_BUG = _lib.SSL_OP_TLS_BLOCK_PADDING_BUG
84OP_DONT_INSERT_EMPTY_FRAGMENTS = _lib.SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
85OP_CIPHER_SERVER_PREFERENCE = _lib.SSL_OP_CIPHER_SERVER_PREFERENCE
86OP_TLS_ROLLBACK_BUG = _lib.SSL_OP_TLS_ROLLBACK_BUG
87OP_PKCS1_CHECK_1 = _lib.SSL_OP_PKCS1_CHECK_1
88OP_PKCS1_CHECK_2 = _lib.SSL_OP_PKCS1_CHECK_2
89OP_NETSCAPE_CA_DN_BUG = _lib.SSL_OP_NETSCAPE_CA_DN_BUG
Alex Gaynor62da94d2015-09-05 14:37:34 -040090OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG = (
91 _lib.SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG
92)
Jean-Paul Calderonec1780342014-01-08 16:59:03 -050093try:
94 OP_NO_COMPRESSION = _lib.SSL_OP_NO_COMPRESSION
95except AttributeError:
96 pass
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -080097
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050098OP_NO_QUERY_MTU = _lib.SSL_OP_NO_QUERY_MTU
99OP_COOKIE_EXCHANGE = _lib.SSL_OP_COOKIE_EXCHANGE
Arturo Filastò5f8c7a82014-03-09 20:01:25 +0100100try:
101 OP_NO_TICKET = _lib.SSL_OP_NO_TICKET
102except AttributeError:
103 pass
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800104
Alex Gaynorc4889812015-09-04 08:43:17 -0400105OP_ALL = _lib.SSL_OP_ALL
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -0800106
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500107VERIFY_PEER = _lib.SSL_VERIFY_PEER
108VERIFY_FAIL_IF_NO_PEER_CERT = _lib.SSL_VERIFY_FAIL_IF_NO_PEER_CERT
109VERIFY_CLIENT_ONCE = _lib.SSL_VERIFY_CLIENT_ONCE
110VERIFY_NONE = _lib.SSL_VERIFY_NONE
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -0800111
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500112SESS_CACHE_OFF = _lib.SSL_SESS_CACHE_OFF
113SESS_CACHE_CLIENT = _lib.SSL_SESS_CACHE_CLIENT
114SESS_CACHE_SERVER = _lib.SSL_SESS_CACHE_SERVER
115SESS_CACHE_BOTH = _lib.SSL_SESS_CACHE_BOTH
116SESS_CACHE_NO_AUTO_CLEAR = _lib.SSL_SESS_CACHE_NO_AUTO_CLEAR
117SESS_CACHE_NO_INTERNAL_LOOKUP = _lib.SSL_SESS_CACHE_NO_INTERNAL_LOOKUP
118SESS_CACHE_NO_INTERNAL_STORE = _lib.SSL_SESS_CACHE_NO_INTERNAL_STORE
119SESS_CACHE_NO_INTERNAL = _lib.SSL_SESS_CACHE_NO_INTERNAL
Jean-Paul Calderoned39a3f62013-03-04 12:23:51 -0800120
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500121SSL_ST_CONNECT = _lib.SSL_ST_CONNECT
122SSL_ST_ACCEPT = _lib.SSL_ST_ACCEPT
123SSL_ST_MASK = _lib.SSL_ST_MASK
124SSL_ST_INIT = _lib.SSL_ST_INIT
125SSL_ST_BEFORE = _lib.SSL_ST_BEFORE
126SSL_ST_OK = _lib.SSL_ST_OK
127SSL_ST_RENEGOTIATE = _lib.SSL_ST_RENEGOTIATE
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800128
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500129SSL_CB_LOOP = _lib.SSL_CB_LOOP
130SSL_CB_EXIT = _lib.SSL_CB_EXIT
131SSL_CB_READ = _lib.SSL_CB_READ
132SSL_CB_WRITE = _lib.SSL_CB_WRITE
133SSL_CB_ALERT = _lib.SSL_CB_ALERT
134SSL_CB_READ_ALERT = _lib.SSL_CB_READ_ALERT
135SSL_CB_WRITE_ALERT = _lib.SSL_CB_WRITE_ALERT
136SSL_CB_ACCEPT_LOOP = _lib.SSL_CB_ACCEPT_LOOP
137SSL_CB_ACCEPT_EXIT = _lib.SSL_CB_ACCEPT_EXIT
138SSL_CB_CONNECT_LOOP = _lib.SSL_CB_CONNECT_LOOP
139SSL_CB_CONNECT_EXIT = _lib.SSL_CB_CONNECT_EXIT
140SSL_CB_HANDSHAKE_START = _lib.SSL_CB_HANDSHAKE_START
141SSL_CB_HANDSHAKE_DONE = _lib.SSL_CB_HANDSHAKE_DONE
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800142
Alex Gaynor83284952015-09-05 10:43:30 -0400143
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500144class Error(Exception):
Jean-Paul Calderone511cde02013-12-29 10:31:13 -0500145 """
146 An error occurred in an `OpenSSL.SSL` API.
147 """
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500148
149
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500150_raise_current_error = partial(_exception_from_error_queue, Error)
Hynek Schlawackf90e3682016-03-11 11:21:13 +0100151_openssl_assert = _make_assert(Error)
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500152
153
154class WantReadError(Error):
155 pass
156
157
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500158class WantWriteError(Error):
159 pass
160
161
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500162class WantX509LookupError(Error):
163 pass
164
165
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500166class ZeroReturnError(Error):
167 pass
168
169
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500170class SysCallError(Error):
171 pass
172
173
Cory Benfield0ea76e72015-03-22 09:05:28 +0000174class _CallbackExceptionHelper(object):
175 """
176 A base class for wrapper classes that allow for intelligent exception
177 handling in OpenSSL callbacks.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500178
Jean-Paul Calderone1b172982015-03-22 19:37:11 -0400179 :ivar list _problems: Any exceptions that occurred while executing in a
180 context where they could not be raised in the normal way. Typically
181 this is because OpenSSL has called into some Python code and requires a
182 return value. The exceptions are saved to be raised later when it is
183 possible to do so.
Cory Benfield0ea76e72015-03-22 09:05:28 +0000184 """
Alex Gaynor62da94d2015-09-05 14:37:34 -0400185
Jean-Paul Calderone09540d72015-03-22 19:37:20 -0400186 def __init__(self):
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800187 self._problems = []
188
Cory Benfield0ea76e72015-03-22 09:05:28 +0000189 def raise_if_problem(self):
Jean-Paul Calderone1b172982015-03-22 19:37:11 -0400190 """
191 Raise an exception from the OpenSSL error queue or that was previously
192 captured whe running a callback.
193 """
Cory Benfield0ea76e72015-03-22 09:05:28 +0000194 if self._problems:
195 try:
196 _raise_current_error()
197 except Error:
198 pass
199 raise self._problems.pop(0)
200
201
202class _VerifyHelper(_CallbackExceptionHelper):
Jean-Paul Calderone1b172982015-03-22 19:37:11 -0400203 """
204 Wrap a callback such that it can be used as a certificate verification
205 callback.
206 """
Alex Gaynor62da94d2015-09-05 14:37:34 -0400207
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800208 def __init__(self, callback):
Jean-Paul Calderone837f4032015-03-22 17:38:28 -0400209 _CallbackExceptionHelper.__init__(self)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800210
211 @wraps(callback)
212 def wrapper(ok, store_ctx):
213 cert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500214 cert._x509 = _lib.X509_STORE_CTX_get_current_cert(store_ctx)
215 error_number = _lib.X509_STORE_CTX_get_error(store_ctx)
216 error_depth = _lib.X509_STORE_CTX_get_error_depth(store_ctx)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800217
Jean-Paul Calderone6a8cd112014-04-02 21:09:08 -0400218 index = _lib.SSL_get_ex_data_X509_STORE_CTX_idx()
219 ssl = _lib.X509_STORE_CTX_get_ex_data(store_ctx, index)
220 connection = Connection._reverse_mapping[ssl]
221
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800222 try:
Alex Gaynor62da94d2015-09-05 14:37:34 -0400223 result = callback(
224 connection, cert, error_number, error_depth, ok
225 )
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800226 except Exception as e:
227 self._problems.append(e)
228 return 0
229 else:
230 if result:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500231 _lib.X509_STORE_CTX_set_error(store_ctx, _lib.X509_V_OK)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800232 return 1
233 else:
234 return 0
235
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500236 self.callback = _ffi.callback(
237 "int (*)(int, X509_STORE_CTX *)", wrapper)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800238
239
Cory Benfield0ea76e72015-03-22 09:05:28 +0000240class _NpnAdvertiseHelper(_CallbackExceptionHelper):
Jean-Paul Calderone1b172982015-03-22 19:37:11 -0400241 """
242 Wrap a callback such that it can be used as an NPN advertisement callback.
243 """
Alex Gaynor62da94d2015-09-05 14:37:34 -0400244
Cory Benfield0ea76e72015-03-22 09:05:28 +0000245 def __init__(self, callback):
Jean-Paul Calderone837f4032015-03-22 17:38:28 -0400246 _CallbackExceptionHelper.__init__(self)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800247
Cory Benfield0ea76e72015-03-22 09:05:28 +0000248 @wraps(callback)
249 def wrapper(ssl, out, outlen, arg):
250 try:
251 conn = Connection._reverse_mapping[ssl]
252 protos = callback(conn)
253
254 # Join the protocols into a Python bytestring, length-prefixing
255 # each element.
256 protostr = b''.join(
257 chain.from_iterable((int2byte(len(p)), p) for p in protos)
258 )
259
260 # Save our callback arguments on the connection object. This is
261 # done to make sure that they don't get freed before OpenSSL
262 # uses them. Then, return them appropriately in the output
263 # parameters.
264 conn._npn_advertise_callback_args = [
265 _ffi.new("unsigned int *", len(protostr)),
266 _ffi.new("unsigned char[]", protostr),
267 ]
268 outlen[0] = conn._npn_advertise_callback_args[0][0]
269 out[0] = conn._npn_advertise_callback_args[1]
270 return 0
271 except Exception as e:
272 self._problems.append(e)
273 return 2 # SSL_TLSEXT_ERR_ALERT_FATAL
274
275 self.callback = _ffi.callback(
276 "int (*)(SSL *, const unsigned char **, unsigned int *, void *)",
277 wrapper
278 )
279
280
281class _NpnSelectHelper(_CallbackExceptionHelper):
Jean-Paul Calderone1b172982015-03-22 19:37:11 -0400282 """
283 Wrap a callback such that it can be used as an NPN selection callback.
284 """
Alex Gaynor62da94d2015-09-05 14:37:34 -0400285
Cory Benfield0ea76e72015-03-22 09:05:28 +0000286 def __init__(self, callback):
Jean-Paul Calderone837f4032015-03-22 17:38:28 -0400287 _CallbackExceptionHelper.__init__(self)
Cory Benfield0ea76e72015-03-22 09:05:28 +0000288
289 @wraps(callback)
290 def wrapper(ssl, out, outlen, in_, inlen, arg):
291 try:
292 conn = Connection._reverse_mapping[ssl]
293
294 # The string passed to us is actually made up of multiple
295 # length-prefixed bytestrings. We need to split that into a
296 # list.
297 instr = _ffi.buffer(in_, inlen)[:]
298 protolist = []
299 while instr:
300 l = indexbytes(instr, 0)
Alex Gaynorca87ff62015-09-04 23:31:03 -0400301 proto = instr[1:l + 1]
Cory Benfield0ea76e72015-03-22 09:05:28 +0000302 protolist.append(proto)
Alex Gaynorca87ff62015-09-04 23:31:03 -0400303 instr = instr[l + 1:]
Cory Benfield0ea76e72015-03-22 09:05:28 +0000304
305 # Call the callback
306 outstr = callback(conn, protolist)
307
308 # Save our callback arguments on the connection object. This is
309 # done to make sure that they don't get freed before OpenSSL
310 # uses them. Then, return them appropriately in the output
311 # parameters.
312 conn._npn_select_callback_args = [
313 _ffi.new("unsigned char *", len(outstr)),
314 _ffi.new("unsigned char[]", outstr),
315 ]
316 outlen[0] = conn._npn_select_callback_args[0][0]
317 out[0] = conn._npn_select_callback_args[1]
318 return 0
319 except Exception as e:
320 self._problems.append(e)
321 return 2 # SSL_TLSEXT_ERR_ALERT_FATAL
322
323 self.callback = _ffi.callback(
Alex Gaynor62da94d2015-09-05 14:37:34 -0400324 ("int (*)(SSL *, unsigned char **, unsigned char *, "
325 "const unsigned char *, unsigned int, void *)"),
Cory Benfield0ea76e72015-03-22 09:05:28 +0000326 wrapper
327 )
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800328
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800329
Cory Benfield9da5ffb2015-04-13 17:20:14 -0400330class _ALPNSelectHelper(_CallbackExceptionHelper):
Cory Benfieldf1177e72015-04-12 09:11:49 -0400331 """
332 Wrap a callback such that it can be used as an ALPN selection callback.
333 """
Alex Gaynor62da94d2015-09-05 14:37:34 -0400334
Cory Benfieldf1177e72015-04-12 09:11:49 -0400335 def __init__(self, callback):
336 _CallbackExceptionHelper.__init__(self)
337
338 @wraps(callback)
339 def wrapper(ssl, out, outlen, in_, inlen, arg):
340 try:
341 conn = Connection._reverse_mapping[ssl]
342
343 # The string passed to us is made up of multiple
344 # length-prefixed bytestrings. We need to split that into a
345 # list.
346 instr = _ffi.buffer(in_, inlen)[:]
347 protolist = []
348 while instr:
Cory Benfield93134db2015-04-13 17:22:13 -0400349 encoded_len = indexbytes(instr, 0)
350 proto = instr[1:encoded_len + 1]
Cory Benfieldf1177e72015-04-12 09:11:49 -0400351 protolist.append(proto)
Cory Benfield93134db2015-04-13 17:22:13 -0400352 instr = instr[encoded_len + 1:]
Cory Benfieldf1177e72015-04-12 09:11:49 -0400353
354 # Call the callback
355 outstr = callback(conn, protolist)
356
357 if not isinstance(outstr, _binary_type):
358 raise TypeError("ALPN callback must return a bytestring.")
359
360 # Save our callback arguments on the connection object to make
361 # sure that they don't get freed before OpenSSL can use them.
362 # Then, return them in the appropriate output parameters.
363 conn._alpn_select_callback_args = [
364 _ffi.new("unsigned char *", len(outstr)),
365 _ffi.new("unsigned char[]", outstr),
366 ]
367 outlen[0] = conn._alpn_select_callback_args[0][0]
368 out[0] = conn._alpn_select_callback_args[1]
369 return 0
370 except Exception as e:
371 self._problems.append(e)
372 return 2 # SSL_TLSEXT_ERR_ALERT_FATAL
373
374 self.callback = _ffi.callback(
Alex Gaynor62da94d2015-09-05 14:37:34 -0400375 ("int (*)(SSL *, unsigned char **, unsigned char *, "
376 "const unsigned char *, unsigned int, void *)"),
Cory Benfieldf1177e72015-04-12 09:11:49 -0400377 wrapper
378 )
379
380
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800381def _asFileDescriptor(obj):
382 fd = None
Konstantinos Koukopoulosc8b13ea2014-01-28 00:21:50 -0800383 if not isinstance(obj, integer_types):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800384 meth = getattr(obj, "fileno", None)
385 if meth is not None:
386 obj = meth()
387
Konstantinos Koukopoulosc8b13ea2014-01-28 00:21:50 -0800388 if isinstance(obj, integer_types):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800389 fd = obj
390
Konstantinos Koukopoulosc8b13ea2014-01-28 00:21:50 -0800391 if not isinstance(fd, integer_types):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800392 raise TypeError("argument must be an int, or have a fileno() method.")
393 elif fd < 0:
394 raise ValueError(
395 "file descriptor cannot be a negative integer (%i)" % (fd,))
396
397 return fd
398
399
Jean-Paul Calderoned39a3f62013-03-04 12:23:51 -0800400def SSLeay_version(type):
401 """
402 Return a string describing the version of OpenSSL in use.
403
404 :param type: One of the SSLEAY_ constants defined in this module.
405 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500406 return _ffi.string(_lib.SSLeay_version(type))
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800407
408
Cory Benfieldef404df2016-03-29 15:32:48 +0100409def _make_requires(flag, error):
Cory Benfielda876cef2015-04-13 17:29:12 -0400410 """
Cory Benfieldef404df2016-03-29 15:32:48 +0100411 Builds a decorator that ensures that functions that rely on OpenSSL
412 functions that are not present in this build raise NotImplementedError,
413 rather than AttributeError coming out of cryptography.
414
415 :param flag: A cryptography flag that guards the functions, e.g.
416 ``Cryptography_HAS_NEXTPROTONEG``.
417 :param error: The string to be used in the exception if the flag is false.
Cory Benfielda876cef2015-04-13 17:29:12 -0400418 """
Cory Benfieldef404df2016-03-29 15:32:48 +0100419 def _requires_decorator(func):
420 if not flag:
421 @wraps(func)
422 def explode(*args, **kwargs):
423 raise NotImplementedError(error)
424 return explode
425 else:
426 return func
Cory Benfield10b277f2015-04-13 17:12:42 -0400427
Cory Benfieldef404df2016-03-29 15:32:48 +0100428 return _requires_decorator
Cory Benfield10b277f2015-04-13 17:12:42 -0400429
430
Cory Benfieldef404df2016-03-29 15:32:48 +0100431_requires_npn = _make_requires(
432 _lib.Cryptography_HAS_NEXTPROTONEG, "NPN not available"
433)
Cory Benfield7907e332015-04-13 17:18:25 -0400434
435
Cory Benfieldef404df2016-03-29 15:32:48 +0100436_requires_alpn = _make_requires(
437 _lib.Cryptography_HAS_ALPN, "ALPN not available"
438)
Cory Benfielde6f35882016-03-29 11:21:04 +0100439
Cory Benfielde6f35882016-03-29 11:21:04 +0100440
Cory Benfieldef404df2016-03-29 15:32:48 +0100441_requires_sni = _make_requires(
442 _lib.Cryptography_HAS_TLSEXT_HOSTNAME, "SNI not available"
443)
Cory Benfielde6f35882016-03-29 11:21:04 +0100444
445
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800446class Session(object):
447 pass
448
449
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800450class Context(object):
451 """
Hynek Schlawackf90e3682016-03-11 11:21:13 +0100452 :class:`OpenSSL.SSL.Context` instances define the parameters for setting
Alex Gaynor62da94d2015-09-05 14:37:34 -0400453 up new SSL connections.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800454 """
455 _methods = {
Andrew Dunhamec84a0a2014-02-24 12:41:37 -0800456 SSLv2_METHOD: "SSLv2_method",
Jean-Paul Calderonebe2bb422013-12-29 07:34:08 -0500457 SSLv3_METHOD: "SSLv3_method",
458 SSLv23_METHOD: "SSLv23_method",
459 TLSv1_METHOD: "TLSv1_method",
460 TLSv1_1_METHOD: "TLSv1_1_method",
461 TLSv1_2_METHOD: "TLSv1_2_method",
Alex Gaynorc4889812015-09-04 08:43:17 -0400462 }
Jean-Paul Calderonebe2bb422013-12-29 07:34:08 -0500463 _methods = dict(
464 (identifier, getattr(_lib, name))
465 for (identifier, name) in _methods.items()
466 if getattr(_lib, name, None) is not None)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800467
468 def __init__(self, method):
469 """
470 :param method: One of SSLv2_METHOD, SSLv3_METHOD, SSLv23_METHOD, or
471 TLSv1_METHOD.
472 """
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -0500473 if not isinstance(method, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800474 raise TypeError("method must be an integer")
475
476 try:
477 method_func = self._methods[method]
478 except KeyError:
479 raise ValueError("No such protocol")
480
481 method_obj = method_func()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500482 if method_obj == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500483 # TODO: This is untested.
484 _raise_current_error()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800485
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500486 context = _lib.SSL_CTX_new(method_obj)
487 if context == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500488 # TODO: This is untested.
489 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500490 context = _ffi.gc(context, _lib.SSL_CTX_free)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800491
492 self._context = context
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800493 self._passphrase_helper = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800494 self._passphrase_callback = None
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800495 self._passphrase_userdata = None
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800496 self._verify_helper = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800497 self._verify_callback = None
498 self._info_callback = None
499 self._tlsext_servername_callback = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800500 self._app_data = None
Cory Benfield0ea76e72015-03-22 09:05:28 +0000501 self._npn_advertise_helper = None
Cory Benfield84a121e2014-03-31 20:30:25 +0100502 self._npn_advertise_callback = None
Cory Benfield0ea76e72015-03-22 09:05:28 +0000503 self._npn_select_helper = None
Cory Benfield84a121e2014-03-31 20:30:25 +0100504 self._npn_select_callback = None
Cory Benfieldf1177e72015-04-12 09:11:49 -0400505 self._alpn_select_helper = None
Cory Benfield12eae892014-06-07 15:42:56 +0100506 self._alpn_select_callback = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800507
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -0800508 # SSL_CTX_set_app_data(self->ctx, self);
509 # SSL_CTX_set_mode(self->ctx, SSL_MODE_ENABLE_PARTIAL_WRITE |
510 # SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
511 # SSL_MODE_AUTO_RETRY);
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500512 self.set_mode(_lib.SSL_MODE_ENABLE_PARTIAL_WRITE)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800513
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800514 def load_verify_locations(self, cafile, capath=None):
515 """
516 Let SSL know where we can find trusted certificates for the certificate
517 chain
518
Jean-Paul Calderone55f9e882015-04-12 09:31:03 -0400519 :param cafile: In which file we can find the certificates (``bytes`` or
520 ``unicode``).
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800521 :param capath: In which directory we can find the certificates
Jean-Paul Calderone55f9e882015-04-12 09:31:03 -0400522 (``bytes`` or ``unicode``).
523
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800524 :return: None
525 """
526 if cafile is None:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500527 cafile = _ffi.NULL
Jean-Paul Calderone55f9e882015-04-12 09:31:03 -0400528 else:
529 cafile = _path_string(cafile)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800530
531 if capath is None:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500532 capath = _ffi.NULL
Jean-Paul Calderone55f9e882015-04-12 09:31:03 -0400533 else:
534 capath = _path_string(capath)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800535
Alex Gaynor62da94d2015-09-05 14:37:34 -0400536 load_result = _lib.SSL_CTX_load_verify_locations(
537 self._context, cafile, capath
538 )
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800539 if not load_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500540 _raise_current_error()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800541
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800542 def _wrap_callback(self, callback):
543 @wraps(callback)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800544 def wrapper(size, verify, userdata):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800545 return callback(size, verify, self._passphrase_userdata)
546 return _PassphraseHelper(
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800547 FILETYPE_PEM, wrapper, more_args=True, truncate=True)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800548
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800549 def set_passwd_cb(self, callback, userdata=None):
550 """
551 Set the passphrase callback
552
553 :param callback: The Python callback to use
554 :param userdata: (optional) A Python object which will be given as
555 argument to the callback
556 :return: None
557 """
558 if not callable(callback):
559 raise TypeError("callback must be callable")
560
561 self._passphrase_helper = self._wrap_callback(callback)
562 self._passphrase_callback = self._passphrase_helper.callback
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500563 _lib.SSL_CTX_set_default_passwd_cb(
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800564 self._context, self._passphrase_callback)
565 self._passphrase_userdata = userdata
566
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800567 def set_default_verify_paths(self):
568 """
569 Use the platform-specific CA certificate locations
570
571 :return: None
572 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500573 set_result = _lib.SSL_CTX_set_default_verify_paths(self._context)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800574 if not set_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500575 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500576 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800577
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800578 def use_certificate_chain_file(self, certfile):
579 """
580 Load a certificate chain from a file
581
Jean-Paul Calderoneb6f8a792015-04-13 10:10:06 -0400582 :param certfile: The name of the certificate chain file (``bytes`` or
583 ``unicode``).
584
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800585 :return: None
586 """
Jean-Paul Calderoneaac43a32015-04-12 09:51:21 -0400587 certfile = _path_string(certfile)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800588
Alex Gaynor62da94d2015-09-05 14:37:34 -0400589 result = _lib.SSL_CTX_use_certificate_chain_file(
590 self._context, certfile
591 )
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800592 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500593 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800594
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800595 def use_certificate_file(self, certfile, filetype=FILETYPE_PEM):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800596 """
597 Load a certificate from a file
598
Jean-Paul Calderoneb6f8a792015-04-13 10:10:06 -0400599 :param certfile: The name of the certificate file (``bytes`` or
600 ``unicode``).
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800601 :param filetype: (optional) The encoding of the file, default is PEM
Jean-Paul Calderoneb6f8a792015-04-13 10:10:06 -0400602
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800603 :return: None
604 """
Jean-Paul Calderoned57a7b62015-04-12 09:57:36 -0400605 certfile = _path_string(certfile)
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -0500606 if not isinstance(filetype, integer_types):
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800607 raise TypeError("filetype must be an integer")
608
Alex Gaynor62da94d2015-09-05 14:37:34 -0400609 use_result = _lib.SSL_CTX_use_certificate_file(
610 self._context, certfile, filetype
611 )
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800612 if not use_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500613 _raise_current_error()
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800614
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800615 def use_certificate(self, cert):
616 """
617 Load a certificate from a X509 object
618
619 :param cert: The X509 object
620 :return: None
621 """
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800622 if not isinstance(cert, X509):
623 raise TypeError("cert must be an X509 instance")
624
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500625 use_result = _lib.SSL_CTX_use_certificate(self._context, cert._x509)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800626 if not use_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500627 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800628
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800629 def add_extra_chain_cert(self, certobj):
630 """
631 Add certificate to chain
632
633 :param certobj: The X509 certificate object to add to the chain
634 :return: None
635 """
636 if not isinstance(certobj, X509):
637 raise TypeError("certobj must be an X509 instance")
638
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500639 copy = _lib.X509_dup(certobj._x509)
640 add_result = _lib.SSL_CTX_add_extra_chain_cert(self._context, copy)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800641 if not add_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500642 # TODO: This is untested.
643 _lib.X509_free(copy)
644 _raise_current_error()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800645
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800646 def _raise_passphrase_exception(self):
647 if self._passphrase_helper is None:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500648 _raise_current_error()
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800649 exception = self._passphrase_helper.raise_if_problem(Error)
650 if exception is not None:
651 raise exception
652
Jean-Paul Calderone00f84eb2015-04-13 12:47:21 -0400653 def use_privatekey_file(self, keyfile, filetype=_UNSPECIFIED):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800654 """
655 Load a private key from a file
656
Jean-Paul Calderoneb6f8a792015-04-13 10:10:06 -0400657 :param keyfile: The name of the key file (``bytes`` or ``unicode``)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800658 :param filetype: (optional) The encoding of the file, default is PEM
Jean-Paul Calderoneb6f8a792015-04-13 10:10:06 -0400659
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800660 :return: None
661 """
Jean-Paul Calderone69a4e5b2015-04-12 10:04:28 -0400662 keyfile = _path_string(keyfile)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800663
Jean-Paul Calderone00f84eb2015-04-13 12:47:21 -0400664 if filetype is _UNSPECIFIED:
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800665 filetype = FILETYPE_PEM
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -0500666 elif not isinstance(filetype, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800667 raise TypeError("filetype must be an integer")
668
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500669 use_result = _lib.SSL_CTX_use_PrivateKey_file(
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800670 self._context, keyfile, filetype)
671 if not use_result:
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800672 self._raise_passphrase_exception()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800673
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800674 def use_privatekey(self, pkey):
675 """
676 Load a private key from a PKey object
677
678 :param pkey: The PKey object
679 :return: None
680 """
681 if not isinstance(pkey, PKey):
682 raise TypeError("pkey must be a PKey instance")
683
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500684 use_result = _lib.SSL_CTX_use_PrivateKey(self._context, pkey._pkey)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800685 if not use_result:
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800686 self._raise_passphrase_exception()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800687
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800688 def check_privatekey(self):
689 """
690 Check that the private key and certificate match up
691
692 :return: None (raises an exception if something's wrong)
693 """
Jean-Paul Calderonea0344922014-12-11 14:02:31 -0500694 if not _lib.SSL_CTX_check_private_key(self._context):
695 _raise_current_error()
696
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800697 def load_client_ca(self, cafile):
698 """
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +0100699 Load the trusted certificates that will be sent to the client. Does
700 not actually imply any of the certificates are trusted; that must be
Alex Gaynor62da94d2015-09-05 14:37:34 -0400701 configured separately.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800702
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +0100703 :param bytes cafile: The path to a certificates file in PEM format.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800704 :return: None
705 """
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +0100706 ca_list = _lib.SSL_load_client_CA_file(
707 _text_to_bytes_and_warn("cafile", cafile)
708 )
709 _openssl_assert(ca_list != _ffi.NULL)
710 # SSL_CTX_set_client_CA_list doesn't return anything.
711 _lib.SSL_CTX_set_client_CA_list(self._context, ca_list)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800712
713 def set_session_id(self, buf):
714 """
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +0100715 Set the session id to *buf* within which a session can be reused for
716 this Context object. This is needed when doing session resumption,
717 because there is no way for a stored session to know which Context
718 object it is associated with.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800719
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +0100720 :param bytes buf: The session id.
721
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800722 :returns: None
723 """
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +0100724 buf = _text_to_bytes_and_warn("buf", buf)
725 _openssl_assert(
726 _lib.SSL_CTX_set_session_id_context(
727 self._context,
728 buf,
729 len(buf),
730 ) == 1
731 )
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800732
733 def set_session_cache_mode(self, mode):
734 """
735 Enable/disable session caching and specify the mode used.
736
737 :param mode: One or more of the SESS_CACHE_* flags (combine using
738 bitwise or)
739 :returns: The previously set caching mode.
740 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500741 if not isinstance(mode, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800742 raise TypeError("mode must be an integer")
743
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500744 return _lib.SSL_CTX_set_session_cache_mode(self._context, mode)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800745
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800746 def get_session_cache_mode(self):
747 """
748 :returns: The currently used cache mode.
749 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500750 return _lib.SSL_CTX_get_session_cache_mode(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800751
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800752 def set_verify(self, mode, callback):
753 """
754 Set the verify mode and verify callback
755
756 :param mode: The verify mode, this is either VERIFY_NONE or
757 VERIFY_PEER combined with possible other flags
758 :param callback: The Python callback to use
759 :return: None
760
761 See SSL_CTX_set_verify(3SSL) for further details.
762 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500763 if not isinstance(mode, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800764 raise TypeError("mode must be an integer")
765
766 if not callable(callback):
767 raise TypeError("callback must be callable")
768
Jean-Paul Calderone6a8cd112014-04-02 21:09:08 -0400769 self._verify_helper = _VerifyHelper(callback)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800770 self._verify_callback = self._verify_helper.callback
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500771 _lib.SSL_CTX_set_verify(self._context, mode, self._verify_callback)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800772
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800773 def set_verify_depth(self, depth):
774 """
775 Set the verify depth
776
777 :param depth: An integer specifying the verify depth
778 :return: None
779 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500780 if not isinstance(depth, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800781 raise TypeError("depth must be an integer")
782
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500783 _lib.SSL_CTX_set_verify_depth(self._context, depth)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800784
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800785 def get_verify_mode(self):
786 """
787 Get the verify mode
788
789 :return: The verify mode
790 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500791 return _lib.SSL_CTX_get_verify_mode(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800792
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800793 def get_verify_depth(self):
794 """
795 Get the verify depth
796
797 :return: The verify depth
798 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500799 return _lib.SSL_CTX_get_verify_depth(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800800
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800801 def load_tmp_dh(self, dhfile):
802 """
803 Load parameters for Ephemeral Diffie-Hellman
804
Jean-Paul Calderone4e0c43f2015-04-13 10:15:17 -0400805 :param dhfile: The file to load EDH parameters from (``bytes`` or
806 ``unicode``).
807
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800808 :return: None
809 """
Jean-Paul Calderone9e1c1dd2015-04-12 10:13:13 -0400810 dhfile = _path_string(dhfile)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800811
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -0500812 bio = _lib.BIO_new_file(dhfile, b"r")
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500813 if bio == _ffi.NULL:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500814 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500815 bio = _ffi.gc(bio, _lib.BIO_free)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800816
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500817 dh = _lib.PEM_read_bio_DHparams(bio, _ffi.NULL, _ffi.NULL, _ffi.NULL)
818 dh = _ffi.gc(dh, _lib.DH_free)
819 _lib.SSL_CTX_set_tmp_dh(self._context, dh)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800820
Jean-Paul Calderone3e4e3352014-04-19 09:28:28 -0400821 def set_tmp_ecdh(self, curve):
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600822 """
Andy Lutomirski76a61332014-03-12 15:02:56 -0700823 Select a curve to use for ECDHE key exchange.
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600824
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -0400825 :param curve: A curve object to use as returned by either
826 :py:meth:`OpenSSL.crypto.get_elliptic_curve` or
827 :py:meth:`OpenSSL.crypto.get_elliptic_curves`.
Andy Lutomirskif05a2732014-03-13 17:22:25 -0700828
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600829 :return: None
830 """
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -0400831 _lib.SSL_CTX_set_tmp_ecdh(self._context, curve._to_EC_KEY())
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600832
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800833 def set_cipher_list(self, cipher_list):
834 """
Hynek Schlawackf90e3682016-03-11 11:21:13 +0100835 Set the list of ciphers to be used in this context.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800836
Hynek Schlawackf90e3682016-03-11 11:21:13 +0100837 See the OpenSSL manual for more information (e.g.
838 :manpage:`ciphers(1)`).
839
840 :param bytes cipher_list: An OpenSSL cipher string.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800841 :return: None
842 """
Hynek Schlawackf90e3682016-03-11 11:21:13 +0100843 cipher_list = _text_to_bytes_and_warn("cipher_list", cipher_list)
Jean-Paul Calderone63eab692014-01-18 10:19:56 -0500844
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800845 if not isinstance(cipher_list, bytes):
Hynek Schlawacka7a63af2016-03-11 12:05:26 +0100846 raise TypeError("cipher_list must be a byte string.")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800847
Hynek Schlawackf90e3682016-03-11 11:21:13 +0100848 _openssl_assert(
Hynek Schlawack22a4b662016-03-11 14:59:39 +0100849 _lib.SSL_CTX_set_cipher_list(self._context, cipher_list) == 1
Hynek Schlawackf90e3682016-03-11 11:21:13 +0100850 )
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800851
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800852 def set_client_ca_list(self, certificate_authorities):
853 """
Alex Gaynor62da94d2015-09-05 14:37:34 -0400854 Set the list of preferred client certificate signers for this server
855 context.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800856
Alex Gaynor62da94d2015-09-05 14:37:34 -0400857 This list of certificate authorities will be sent to the client when
858 the server requests a client certificate.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800859
860 :param certificate_authorities: a sequence of X509Names.
861 :return: None
862 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500863 name_stack = _lib.sk_X509_NAME_new_null()
864 if name_stack == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500865 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500866 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800867
868 try:
869 for ca_name in certificate_authorities:
870 if not isinstance(ca_name, X509Name):
871 raise TypeError(
Alex Gaynor62da94d2015-09-05 14:37:34 -0400872 "client CAs must be X509Name objects, not %s "
873 "objects" % (
874 type(ca_name).__name__,
875 )
876 )
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500877 copy = _lib.X509_NAME_dup(ca_name._name)
878 if copy == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500879 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500880 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500881 push_result = _lib.sk_X509_NAME_push(name_stack, copy)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800882 if not push_result:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500883 _lib.X509_NAME_free(copy)
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500884 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800885 except:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500886 _lib.sk_X509_NAME_free(name_stack)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800887 raise
888
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500889 _lib.SSL_CTX_set_client_CA_list(self._context, name_stack)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800890
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800891 def add_client_ca(self, certificate_authority):
892 """
Alex Gaynor62da94d2015-09-05 14:37:34 -0400893 Add the CA certificate to the list of preferred signers for this
894 context.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800895
896 The list of certificate authorities will be sent to the client when the
897 server requests a client certificate.
898
899 :param certificate_authority: certificate authority's X509 certificate.
900 :return: None
901 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800902 if not isinstance(certificate_authority, X509):
903 raise TypeError("certificate_authority must be an X509 instance")
904
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500905 add_result = _lib.SSL_CTX_add_client_CA(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800906 self._context, certificate_authority._x509)
907 if not add_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500908 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500909 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800910
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800911 def set_timeout(self, timeout):
912 """
913 Set session timeout
914
915 :param timeout: The timeout in seconds
916 :return: The previous session timeout
917 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500918 if not isinstance(timeout, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800919 raise TypeError("timeout must be an integer")
920
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500921 return _lib.SSL_CTX_set_timeout(self._context, timeout)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800922
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800923 def get_timeout(self):
924 """
925 Get the session timeout
926
927 :return: The session timeout
928 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500929 return _lib.SSL_CTX_get_timeout(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800930
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800931 def set_info_callback(self, callback):
932 """
933 Set the info callback
934
935 :param callback: The Python callback to use
936 :return: None
937 """
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800938 @wraps(callback)
939 def wrapper(ssl, where, return_code):
Jean-Paul Calderonef2bbc9c2014-02-02 10:59:14 -0500940 callback(Connection._reverse_mapping[ssl], where, return_code)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500941 self._info_callback = _ffi.callback(
942 "void (*)(const SSL *, int, int)", wrapper)
943 _lib.SSL_CTX_set_info_callback(self._context, self._info_callback)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800944
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800945 def get_app_data(self):
946 """
947 Get the application data (supplied via set_app_data())
948
949 :return: The application data
950 """
951 return self._app_data
952
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800953 def set_app_data(self, data):
954 """
955 Set the application data (will be returned from get_app_data())
956
957 :param data: Any Python object
958 :return: None
959 """
960 self._app_data = data
961
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800962 def get_cert_store(self):
963 """
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500964 Get the certificate store for the context.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800965
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500966 :return: A X509Store object or None if it does not have one.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800967 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500968 store = _lib.SSL_CTX_get_cert_store(self._context)
969 if store == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500970 # TODO: This is untested.
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800971 return None
972
973 pystore = X509Store.__new__(X509Store)
974 pystore._store = store
975 return pystore
976
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800977 def set_options(self, options):
978 """
979 Add options. Options set before are not cleared!
980
981 :param options: The options to add.
982 :return: The new option bitmask.
983 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500984 if not isinstance(options, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800985 raise TypeError("options must be an integer")
986
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500987 return _lib.SSL_CTX_set_options(self._context, options)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800988
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800989 def set_mode(self, mode):
990 """
991 Add modes via bitmask. Modes set before are not cleared!
992
993 :param mode: The mode to add.
994 :return: The new mode bitmask.
995 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500996 if not isinstance(mode, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800997 raise TypeError("mode must be an integer")
998
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500999 return _lib.SSL_CTX_set_mode(self._context, mode)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -08001000
Cory Benfielde6f35882016-03-29 11:21:04 +01001001 @_requires_sni
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -08001002 def set_tlsext_servername_callback(self, callback):
1003 """
Alex Gaynor62da94d2015-09-05 14:37:34 -04001004 Specify a callback function to be called when clients specify a server
1005 name.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -08001006
1007 :param callback: The callback function. It will be invoked with one
1008 argument, the Connection instance.
1009 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001010 @wraps(callback)
1011 def wrapper(ssl, alert, arg):
1012 callback(Connection._reverse_mapping[ssl])
1013 return 0
1014
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001015 self._tlsext_servername_callback = _ffi.callback(
1016 "int (*)(const SSL *, int *, void *)", wrapper)
1017 _lib.SSL_CTX_set_tlsext_servername_callback(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001018 self._context, self._tlsext_servername_callback)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -08001019
Cory Benfield10b277f2015-04-13 17:12:42 -04001020 @_requires_npn
Cory Benfield84a121e2014-03-31 20:30:25 +01001021 def set_npn_advertise_callback(self, callback):
1022 """
Cory Benfieldbe3e7b82014-05-10 09:48:55 +01001023 Specify a callback function that will be called when offering `Next
1024 Protocol Negotiation
1025 <https://technotes.googlecode.com/git/nextprotoneg.html>`_ as a server.
Cory Benfield84a121e2014-03-31 20:30:25 +01001026
1027 :param callback: The callback function. It will be invoked with one
Cory Benfieldbe3e7b82014-05-10 09:48:55 +01001028 argument, the Connection instance. It should return a list of
1029 bytestrings representing the advertised protocols, like
1030 ``[b'http/1.1', b'spdy/2']``.
Cory Benfield84a121e2014-03-31 20:30:25 +01001031 """
Cory Benfield0ea76e72015-03-22 09:05:28 +00001032 self._npn_advertise_helper = _NpnAdvertiseHelper(callback)
1033 self._npn_advertise_callback = self._npn_advertise_helper.callback
Cory Benfield84a121e2014-03-31 20:30:25 +01001034 _lib.SSL_CTX_set_next_protos_advertised_cb(
1035 self._context, self._npn_advertise_callback, _ffi.NULL)
1036
Cory Benfield10b277f2015-04-13 17:12:42 -04001037 @_requires_npn
Cory Benfield84a121e2014-03-31 20:30:25 +01001038 def set_npn_select_callback(self, callback):
1039 """
1040 Specify a callback function that will be called when a server offers
1041 Next Protocol Negotiation options.
1042
1043 :param callback: The callback function. It will be invoked with two
1044 arguments: the Connection, and a list of offered protocols as
Cory Benfieldbe3e7b82014-05-10 09:48:55 +01001045 bytestrings, e.g. ``[b'http/1.1', b'spdy/2']``. It should return
1046 one of those bytestrings, the chosen protocol.
Cory Benfield84a121e2014-03-31 20:30:25 +01001047 """
Cory Benfield0ea76e72015-03-22 09:05:28 +00001048 self._npn_select_helper = _NpnSelectHelper(callback)
1049 self._npn_select_callback = self._npn_select_helper.callback
Cory Benfield84a121e2014-03-31 20:30:25 +01001050 _lib.SSL_CTX_set_next_proto_select_cb(
1051 self._context, self._npn_select_callback, _ffi.NULL)
1052
Cory Benfield7907e332015-04-13 17:18:25 -04001053 @_requires_alpn
Cory Benfield12eae892014-06-07 15:42:56 +01001054 def set_alpn_protos(self, protos):
1055 """
Cory Benfielde8e9c382015-04-11 17:33:48 -04001056 Specify the clients ALPN protocol list.
1057
1058 These protocols are offered to the server during protocol negotiation.
Cory Benfield12eae892014-06-07 15:42:56 +01001059
1060 :param protos: A list of the protocols to be offered to the server.
1061 This list should be a Python list of bytestrings representing the
1062 protocols to offer, e.g. ``[b'http/1.1', b'spdy/2']``.
1063 """
1064 # Take the list of protocols and join them together, prefixing them
1065 # with their lengths.
1066 protostr = b''.join(
1067 chain.from_iterable((int2byte(len(p)), p) for p in protos)
1068 )
1069
1070 # Build a C string from the list. We don't need to save this off
1071 # because OpenSSL immediately copies the data out.
1072 input_str = _ffi.new("unsigned char[]", protostr)
Cory Benfielde871af52015-04-11 17:57:50 -04001073 input_str_len = _ffi.cast("unsigned", len(protostr))
1074 _lib.SSL_CTX_set_alpn_protos(self._context, input_str, input_str_len)
Cory Benfield12eae892014-06-07 15:42:56 +01001075
Cory Benfield7907e332015-04-13 17:18:25 -04001076 @_requires_alpn
Cory Benfield12eae892014-06-07 15:42:56 +01001077 def set_alpn_select_callback(self, callback):
1078 """
Cory Benfielde8e9c382015-04-11 17:33:48 -04001079 Set the callback to handle ALPN protocol choice.
Cory Benfield12eae892014-06-07 15:42:56 +01001080
1081 :param callback: The callback function. It will be invoked with two
1082 arguments: the Connection, and a list of offered protocols as
1083 bytestrings, e.g ``[b'http/1.1', b'spdy/2']``. It should return
Cory Benfielde8e9c382015-04-11 17:33:48 -04001084 one of those bytestrings, the chosen protocol.
Cory Benfield12eae892014-06-07 15:42:56 +01001085 """
Cory Benfield9da5ffb2015-04-13 17:20:14 -04001086 self._alpn_select_helper = _ALPNSelectHelper(callback)
Cory Benfieldf1177e72015-04-12 09:11:49 -04001087 self._alpn_select_callback = self._alpn_select_helper.callback
Cory Benfield12eae892014-06-07 15:42:56 +01001088 _lib.SSL_CTX_set_alpn_select_cb(
1089 self._context, self._alpn_select_callback, _ffi.NULL)
1090
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -08001091ContextType = Context
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001092
1093
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001094class Connection(object):
1095 """
1096 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001097 _reverse_mapping = WeakValueDictionary()
1098
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001099 def __init__(self, context, socket=None):
1100 """
1101 Create a new Connection object, using the given OpenSSL.SSL.Context
1102 instance and socket.
1103
1104 :param context: An SSL Context to use for this connection
1105 :param socket: The socket to use for transport layer
1106 """
1107 if not isinstance(context, Context):
1108 raise TypeError("context must be a Context instance")
1109
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001110 ssl = _lib.SSL_new(context._context)
1111 self._ssl = _ffi.gc(ssl, _lib.SSL_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001112 self._context = context
Todd Chapman4f73e4f2015-08-27 11:26:43 -04001113 self._app_data = None
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001114
Cory Benfieldbe3e7b82014-05-10 09:48:55 +01001115 # References to strings used for Next Protocol Negotiation. OpenSSL's
1116 # header files suggest that these might get copied at some point, but
1117 # doesn't specify when, so we store them here to make sure they don't
1118 # get freed before OpenSSL uses them.
1119 self._npn_advertise_callback_args = None
1120 self._npn_select_callback_args = None
1121
Cory Benfield12eae892014-06-07 15:42:56 +01001122 # References to strings used for Application Layer Protocol
1123 # Negotiation. These strings get copied at some point but it's well
1124 # after the callback returns, so we have to hang them somewhere to
1125 # avoid them getting freed.
1126 self._alpn_select_callback_args = None
1127
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001128 self._reverse_mapping[self._ssl] = self
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001129
1130 if socket is None:
1131 self._socket = None
Jean-Paul Calderone73b15c22013-03-05 18:30:39 -08001132 # Don't set up any gc for these, SSL_free will take care of them.
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001133 self._into_ssl = _lib.BIO_new(_lib.BIO_s_mem())
1134 self._from_ssl = _lib.BIO_new(_lib.BIO_s_mem())
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001135
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001136 if self._into_ssl == _ffi.NULL or self._from_ssl == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001137 # TODO: This is untested.
1138 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001139
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001140 _lib.SSL_set_bio(self._ssl, self._into_ssl, self._from_ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001141 else:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001142 self._into_ssl = None
1143 self._from_ssl = None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001144 self._socket = socket
Alex Gaynor62da94d2015-09-05 14:37:34 -04001145 set_result = _lib.SSL_set_fd(
1146 self._ssl, _asFileDescriptor(self._socket))
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001147 if not set_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001148 # TODO: This is untested.
1149 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001150
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001151 def __getattr__(self, name):
1152 """
Alex Gaynor62da94d2015-09-05 14:37:34 -04001153 Look up attributes on the wrapped socket object if they are not found
1154 on the Connection object.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001155 """
kjav0b66fa12015-09-02 11:51:26 +01001156 if self._socket is None:
Alex Gaynor62da94d2015-09-05 14:37:34 -04001157 raise AttributeError("'%s' object has no attribute '%s'" % (
1158 self.__class__.__name__, name
1159 ))
kjav0b66fa12015-09-02 11:51:26 +01001160 else:
1161 return getattr(self._socket, name)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001162
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001163 def _raise_ssl_error(self, ssl, result):
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -08001164 if self._context._verify_helper is not None:
1165 self._context._verify_helper.raise_if_problem()
Cory Benfield0ea76e72015-03-22 09:05:28 +00001166 if self._context._npn_advertise_helper is not None:
1167 self._context._npn_advertise_helper.raise_if_problem()
1168 if self._context._npn_select_helper is not None:
1169 self._context._npn_select_helper.raise_if_problem()
Cory Benfieldf1177e72015-04-12 09:11:49 -04001170 if self._context._alpn_select_helper is not None:
1171 self._context._alpn_select_helper.raise_if_problem()
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -08001172
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001173 error = _lib.SSL_get_error(ssl, result)
1174 if error == _lib.SSL_ERROR_WANT_READ:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001175 raise WantReadError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001176 elif error == _lib.SSL_ERROR_WANT_WRITE:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001177 raise WantWriteError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001178 elif error == _lib.SSL_ERROR_ZERO_RETURN:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001179 raise ZeroReturnError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001180 elif error == _lib.SSL_ERROR_WANT_X509_LOOKUP:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001181 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001182 raise WantX509LookupError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001183 elif error == _lib.SSL_ERROR_SYSCALL:
1184 if _lib.ERR_peek_error() == 0:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001185 if result < 0:
Konstantinos Koukopoulos541150d2014-01-31 01:00:19 +02001186 if platform == "win32":
1187 errno = _ffi.getwinerror()[0]
1188 else:
1189 errno = _ffi.errno
Glyph3afdba82015-04-14 17:30:53 -04001190 raise SysCallError(errno, errorcode.get(errno))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001191 else:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001192 raise SysCallError(-1, "Unexpected EOF")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001193 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001194 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001195 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001196 elif error == _lib.SSL_ERROR_NONE:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001197 pass
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001198 else:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001199 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001200
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001201 def get_context(self):
1202 """
1203 Get session context
1204 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001205 return self._context
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001206
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001207 def set_context(self, context):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001208 """
1209 Switch this connection to a new session context
1210
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001211 :param context: A :py:class:`Context` instance giving the new session
1212 context to use.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001213 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001214 if not isinstance(context, Context):
1215 raise TypeError("context must be a Context instance")
1216
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001217 _lib.SSL_set_SSL_CTX(self._ssl, context._context)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001218 self._context = context
1219
Cory Benfielde6f35882016-03-29 11:21:04 +01001220 @_requires_sni
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001221 def get_servername(self):
1222 """
1223 Retrieve the servername extension value if provided in the client hello
1224 message, or None if there wasn't one.
1225
1226 :return: A byte string giving the server name or :py:data:`None`.
1227 """
Alex Gaynor62da94d2015-09-05 14:37:34 -04001228 name = _lib.SSL_get_servername(
1229 self._ssl, _lib.TLSEXT_NAMETYPE_host_name
1230 )
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001231 if name == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001232 return None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001233
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001234 return _ffi.string(name)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001235
Cory Benfielde6f35882016-03-29 11:21:04 +01001236 @_requires_sni
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001237 def set_tlsext_host_name(self, name):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001238 """
1239 Set the value of the servername extension to send in the client hello.
1240
1241 :param name: A byte string giving the name.
1242 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001243 if not isinstance(name, bytes):
1244 raise TypeError("name must be a byte string")
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001245 elif b"\0" in name:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001246 raise TypeError("name must not contain NUL byte")
1247
1248 # XXX I guess this can fail sometimes?
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001249 _lib.SSL_set_tlsext_host_name(self._ssl, name)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001250
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001251 def pending(self):
1252 """
1253 Get the number of bytes that can be safely read from the connection
1254
1255 :return: The number of bytes available in the receive buffer.
1256 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001257 return _lib.SSL_pending(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001258
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001259 def send(self, buf, flags=0):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001260 """
1261 Send data on the connection. NOTE: If you get one of the WantRead,
1262 WantWrite or WantX509Lookup exceptions on this, you have to call the
1263 method again with the SAME buffer.
1264
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001265 :param buf: The string, buffer or memoryview to send
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001266 :param flags: (optional) Included for compatibility with the socket
1267 API, the value is ignored
1268 :return: The number of bytes written
1269 """
Abraham Martine82326c2015-02-04 10:18:10 +00001270 # Backward compatibility
Jean-Paul Calderone39a8d592015-04-13 20:49:50 -04001271 buf = _text_to_bytes_and_warn("buf", buf)
Abraham Martine82326c2015-02-04 10:18:10 +00001272
Jean-Paul Calderone8fb53182013-12-30 08:35:49 -05001273 if isinstance(buf, _memoryview):
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -08001274 buf = buf.tobytes()
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001275 if isinstance(buf, _buffer):
1276 buf = str(buf)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001277 if not isinstance(buf, bytes):
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001278 raise TypeError("data must be a memoryview, buffer or byte string")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001279
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001280 result = _lib.SSL_write(self._ssl, buf, len(buf))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001281 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001282 return result
1283 write = send
1284
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001285 def sendall(self, buf, flags=0):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001286 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001287 Send "all" data on the connection. This calls send() repeatedly until
1288 all data is sent. If an error occurs, it's impossible to tell how much
1289 data has been sent.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001290
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001291 :param buf: The string, buffer or memoryview to send
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001292 :param flags: (optional) Included for compatibility with the socket
1293 API, the value is ignored
1294 :return: The number of bytes written
1295 """
Jean-Paul Calderone39a8d592015-04-13 20:49:50 -04001296 buf = _text_to_bytes_and_warn("buf", buf)
Abraham Martine82326c2015-02-04 10:18:10 +00001297
Jean-Paul Calderone8fb53182013-12-30 08:35:49 -05001298 if isinstance(buf, _memoryview):
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -08001299 buf = buf.tobytes()
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001300 if isinstance(buf, _buffer):
1301 buf = str(buf)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001302 if not isinstance(buf, bytes):
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001303 raise TypeError("buf must be a memoryview, buffer or byte string")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001304
1305 left_to_send = len(buf)
1306 total_sent = 0
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001307 data = _ffi.new("char[]", buf)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001308
1309 while left_to_send:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001310 result = _lib.SSL_write(self._ssl, data + total_sent, left_to_send)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001311 self._raise_ssl_error(self._ssl, result)
1312 total_sent += result
1313 left_to_send -= result
1314
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001315 def recv(self, bufsiz, flags=None):
1316 """
Alex Gaynor67fc8c92016-05-27 08:27:19 -04001317 Receive data on the connection.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001318
1319 :param bufsiz: The maximum number of bytes to read
Maximilian Hils1d95dea2015-08-17 19:27:20 +02001320 :param flags: (optional) The only supported flag is ``MSG_PEEK``,
1321 all other flags are ignored.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001322 :return: The string read from the Connection
1323 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001324 buf = _ffi.new("char[]", bufsiz)
Maximilian Hils1d95dea2015-08-17 19:27:20 +02001325 if flags is not None and flags & socket.MSG_PEEK:
1326 result = _lib.SSL_peek(self._ssl, buf, bufsiz)
1327 else:
1328 result = _lib.SSL_read(self._ssl, buf, bufsiz)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001329 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001330 return _ffi.buffer(buf, result)[:]
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001331 read = recv
1332
Cory Benfield62d10332014-06-15 10:03:41 +01001333 def recv_into(self, buffer, nbytes=None, flags=None):
1334 """
1335 Receive data on the connection and store the data into a buffer rather
1336 than creating a new string.
1337
1338 :param buffer: The buffer to copy into.
1339 :param nbytes: (optional) The maximum number of bytes to read into the
1340 buffer. If not present, defaults to the size of the buffer. If
1341 larger than the size of the buffer, is reduced to the size of the
1342 buffer.
Maximilian Hils1d95dea2015-08-17 19:27:20 +02001343 :param flags: (optional) The only supported flag is ``MSG_PEEK``,
1344 all other flags are ignored.
Cory Benfield62d10332014-06-15 10:03:41 +01001345 :return: The number of bytes read into the buffer.
1346 """
1347 if nbytes is None:
1348 nbytes = len(buffer)
1349 else:
1350 nbytes = min(nbytes, len(buffer))
1351
1352 # We need to create a temporary buffer. This is annoying, it would be
1353 # better if we could pass memoryviews straight into the SSL_read call,
1354 # but right now we can't. Revisit this if CFFI gets that ability.
1355 buf = _ffi.new("char[]", nbytes)
Maximilian Hils1d95dea2015-08-17 19:27:20 +02001356 if flags is not None and flags & socket.MSG_PEEK:
1357 result = _lib.SSL_peek(self._ssl, buf, nbytes)
1358 else:
1359 result = _lib.SSL_read(self._ssl, buf, nbytes)
Cory Benfield62d10332014-06-15 10:03:41 +01001360 self._raise_ssl_error(self._ssl, result)
1361
1362 # This strange line is all to avoid a memory copy. The buffer protocol
1363 # should allow us to assign a CFFI buffer to the LHS of this line, but
1364 # on CPython 3.3+ that segfaults. As a workaround, we can temporarily
1365 # wrap it in a memoryview, except on Python 2.6 which doesn't have a
1366 # memoryview type.
1367 try:
1368 buffer[:result] = memoryview(_ffi.buffer(buf, result))
1369 except NameError:
1370 buffer[:result] = _ffi.buffer(buf, result)
1371
1372 return result
1373
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001374 def _handle_bio_errors(self, bio, result):
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001375 if _lib.BIO_should_retry(bio):
1376 if _lib.BIO_should_read(bio):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001377 raise WantReadError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001378 elif _lib.BIO_should_write(bio):
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001379 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001380 raise WantWriteError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001381 elif _lib.BIO_should_io_special(bio):
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001382 # TODO: This is untested. I think io_special means the socket
1383 # BIO has a not-yet connected socket.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001384 raise ValueError("BIO_should_io_special")
1385 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001386 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001387 raise ValueError("unknown bio failure")
1388 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001389 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001390 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001391
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001392 def bio_read(self, bufsiz):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001393 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001394 When using non-socket connections this function reads the "dirty" data
1395 that would have traveled away on the network.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001396
1397 :param bufsiz: The maximum number of bytes to read
1398 :return: The string read.
1399 """
Jean-Paul Calderone97e041d2013-03-05 21:03:12 -08001400 if self._from_ssl is None:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001401 raise TypeError("Connection sock was not None")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001402
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -05001403 if not isinstance(bufsiz, integer_types):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001404 raise TypeError("bufsiz must be an integer")
1405
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001406 buf = _ffi.new("char[]", bufsiz)
1407 result = _lib.BIO_read(self._from_ssl, buf, bufsiz)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001408 if result <= 0:
1409 self._handle_bio_errors(self._from_ssl, result)
1410
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001411 return _ffi.buffer(buf, result)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001412
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001413 def bio_write(self, buf):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001414 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001415 When using non-socket connections this function sends "dirty" data that
1416 would have traveled in on the network.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001417
1418 :param buf: The string to put into the memory BIO.
1419 :return: The number of bytes written
1420 """
Jean-Paul Calderone39a8d592015-04-13 20:49:50 -04001421 buf = _text_to_bytes_and_warn("buf", buf)
Abraham Martine82326c2015-02-04 10:18:10 +00001422
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001423 if self._into_ssl is None:
1424 raise TypeError("Connection sock was not None")
1425
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001426 result = _lib.BIO_write(self._into_ssl, buf, len(buf))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001427 if result <= 0:
1428 self._handle_bio_errors(self._into_ssl, result)
1429 return result
1430
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001431 def renegotiate(self):
1432 """
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +01001433 Renegotiate the session.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001434
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +01001435 :return: True if the renegotiation can be started, False otherwise
1436 :rtype: bool
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001437 """
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +01001438 if not self.renegotiate_pending():
1439 _openssl_assert(_lib.SSL_renegotiate(self._ssl) == 1)
1440 return True
1441 return False
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001442
1443 def do_handshake(self):
1444 """
1445 Perform an SSL handshake (usually called after renegotiate() or one of
1446 set_*_state()). This can raise the same exceptions as send and recv.
1447
1448 :return: None.
1449 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001450 result = _lib.SSL_do_handshake(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001451 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001452
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001453 def renegotiate_pending(self):
1454 """
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +01001455 Check if there's a renegotiation in progress, it will return False once
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001456 a renegotiation is finished.
1457
1458 :return: Whether there's a renegotiation in progress
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +01001459 :rtype: bool
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001460 """
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +01001461 return _lib.SSL_renegotiate_pending(self._ssl) == 1
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001462
1463 def total_renegotiations(self):
1464 """
1465 Find out the total number of renegotiations.
1466
1467 :return: The number of renegotiations.
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +01001468 :rtype: int
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001469 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001470 return _lib.SSL_total_renegotiations(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001471
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001472 def connect(self, addr):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001473 """
1474 Connect to remote host and set up client-side SSL
1475
1476 :param addr: A remote address
1477 :return: What the socket's connect method returns
1478 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001479 _lib.SSL_set_connect_state(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001480 return self._socket.connect(addr)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001481
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001482 def connect_ex(self, addr):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001483 """
Alex Gaynor62da94d2015-09-05 14:37:34 -04001484 Connect to remote host and set up client-side SSL. Note that if the
1485 socket's connect_ex method doesn't return 0, SSL won't be initialized.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001486
1487 :param addr: A remove address
1488 :return: What the socket's connect_ex method returns
1489 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001490 connect_ex = self._socket.connect_ex
1491 self.set_connect_state()
1492 return connect_ex(addr)
1493
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001494 def accept(self):
1495 """
1496 Accept incoming connection and set up SSL on it
1497
1498 :return: A (conn,addr) pair where conn is a Connection and addr is an
1499 address
1500 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001501 client, addr = self._socket.accept()
1502 conn = Connection(self._context, client)
1503 conn.set_accept_state()
1504 return (conn, addr)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001505
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001506 def bio_shutdown(self):
1507 """
1508 When using non-socket connections this function signals end of
1509 data on the input for this connection.
1510
1511 :return: None
1512 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001513 if self._from_ssl is None:
1514 raise TypeError("Connection sock was not None")
1515
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001516 _lib.BIO_set_mem_eof_return(self._into_ssl, 0)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001517
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001518 def shutdown(self):
1519 """
1520 Send closure alert
1521
1522 :return: True if the shutdown completed successfully (i.e. both sides
1523 have sent closure alerts), false otherwise (i.e. you have to
1524 wait for a ZeroReturnError on a recv() method call
1525 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001526 result = _lib.SSL_shutdown(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001527 if result < 0:
Paul Aurichbff1d1a2015-01-08 08:36:53 -08001528 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001529 elif result > 0:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001530 return True
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001531 else:
1532 return False
1533
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001534 def get_cipher_list(self):
1535 """
Hynek Schlawackf90e3682016-03-11 11:21:13 +01001536 Retrieve the list of ciphers used by the Connection object.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001537
Hynek Schlawackf90e3682016-03-11 11:21:13 +01001538 :return: A list of native cipher strings.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001539 """
1540 ciphers = []
1541 for i in count():
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001542 result = _lib.SSL_get_cipher_list(self._ssl, i)
1543 if result == _ffi.NULL:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001544 break
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001545 ciphers.append(_native(_ffi.string(result)))
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001546 return ciphers
1547
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001548 def get_client_ca_list(self):
1549 """
1550 Get CAs whose certificates are suggested for client authentication.
1551
Alex Gaynor62da94d2015-09-05 14:37:34 -04001552 :return: If this is a server connection, a list of X509Names
1553 representing the acceptable CAs as set by
1554 :py:meth:`OpenSSL.SSL.Context.set_client_ca_list` or
1555 :py:meth:`OpenSSL.SSL.Context.add_client_ca`. If this is a client
1556 connection, the list of such X509Names sent by the server, or an
1557 empty list if that has not yet happened.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001558 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001559 ca_names = _lib.SSL_get_client_CA_list(self._ssl)
1560 if ca_names == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001561 # TODO: This is untested.
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001562 return []
1563
1564 result = []
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001565 for i in range(_lib.sk_X509_NAME_num(ca_names)):
1566 name = _lib.sk_X509_NAME_value(ca_names, i)
1567 copy = _lib.X509_NAME_dup(name)
1568 if copy == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001569 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001570 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001571
1572 pyname = X509Name.__new__(X509Name)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001573 pyname._name = _ffi.gc(copy, _lib.X509_NAME_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001574 result.append(pyname)
1575 return result
1576
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001577 def makefile(self):
1578 """
Alex Gaynor62da94d2015-09-05 14:37:34 -04001579 The makefile() method is not implemented, since there is no dup
1580 semantics for SSL connections
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001581
Jean-Paul Calderone6749ec22014-04-17 16:30:21 -04001582 :raise: NotImplementedError
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001583 """
Alex Gaynor83284952015-09-05 10:43:30 -04001584 raise NotImplementedError(
1585 "Cannot make file object of OpenSSL.SSL.Connection")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001586
1587 def get_app_data(self):
1588 """
1589 Get application data
1590
1591 :return: The application data
1592 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001593 return self._app_data
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001594
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001595 def set_app_data(self, data):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001596 """
1597 Set application data
1598
1599 :param data - The application data
1600 :return: None
1601 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001602 self._app_data = data
1603
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001604 def get_shutdown(self):
1605 """
1606 Get shutdown state
1607
Alex Gaynor62da94d2015-09-05 14:37:34 -04001608 :return: The shutdown state, a bitvector of SENT_SHUTDOWN,
1609 RECEIVED_SHUTDOWN.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001610 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001611 return _lib.SSL_get_shutdown(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001612
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001613 def set_shutdown(self, state):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001614 """
1615 Set shutdown state
1616
1617 :param state - bitvector of SENT_SHUTDOWN, RECEIVED_SHUTDOWN.
1618 :return: None
1619 """
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -05001620 if not isinstance(state, integer_types):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001621 raise TypeError("state must be an integer")
1622
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001623 _lib.SSL_set_shutdown(self._ssl, state)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001624
Hynek Schlawackea94f2b2016-03-13 16:17:53 +01001625 def get_state_string(self):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001626 """
Hynek Schlawackea94f2b2016-03-13 16:17:53 +01001627 Retrieve a verbose string detailing the state of the Connection.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001628
1629 :return: A string representing the state
Hynek Schlawackea94f2b2016-03-13 16:17:53 +01001630 :rtype: bytes
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001631 """
kjavc704a2e2015-09-07 12:12:27 +01001632 return _ffi.string(_lib.SSL_state_string_long(self._ssl))
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001633
1634 def server_random(self):
1635 """
1636 Get a copy of the server hello nonce.
1637
1638 :return: A string representing the state
1639 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001640 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001641 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001642 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001643 self._ssl.s3.server_random,
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001644 _lib.SSL3_RANDOM_SIZE)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001645
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001646 def client_random(self):
1647 """
1648 Get a copy of the client hello nonce.
1649
1650 :return: A string representing the state
1651 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001652 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001653 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001654 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001655 self._ssl.s3.client_random,
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001656 _lib.SSL3_RANDOM_SIZE)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001657
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001658 def master_key(self):
1659 """
1660 Get a copy of the master key.
1661
1662 :return: A string representing the state
1663 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001664 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001665 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001666 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001667 self._ssl.session.master_key,
1668 self._ssl.session.master_key_length)[:]
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001669
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001670 def sock_shutdown(self, *args, **kwargs):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001671 """
1672 See shutdown(2)
1673
1674 :return: What the socket's shutdown() method returns
1675 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001676 return self._socket.shutdown(*args, **kwargs)
1677
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001678 def get_peer_certificate(self):
1679 """
1680 Retrieve the other side's certificate (if any)
1681
1682 :return: The peer's certificate
1683 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001684 cert = _lib.SSL_get_peer_certificate(self._ssl)
1685 if cert != _ffi.NULL:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001686 pycert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001687 pycert._x509 = _ffi.gc(cert, _lib.X509_free)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001688 return pycert
1689 return None
1690
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001691 def get_peer_cert_chain(self):
1692 """
1693 Retrieve the other side's certificate (if any)
1694
1695 :return: A list of X509 instances giving the peer's certificate chain,
1696 or None if it does not have one.
1697 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001698 cert_stack = _lib.SSL_get_peer_cert_chain(self._ssl)
1699 if cert_stack == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001700 return None
1701
1702 result = []
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001703 for i in range(_lib.sk_X509_num(cert_stack)):
Jean-Paul Calderone73b15c22013-03-05 18:30:39 -08001704 # TODO could incref instead of dup here
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001705 cert = _lib.X509_dup(_lib.sk_X509_value(cert_stack, i))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001706 pycert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001707 pycert._x509 = _ffi.gc(cert, _lib.X509_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001708 result.append(pycert)
1709 return result
1710
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001711 def want_read(self):
1712 """
Alex Gaynor62da94d2015-09-05 14:37:34 -04001713 Checks if more data has to be read from the transport layer to complete
1714 an operation.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001715
1716 :return: True iff more data has to be read
1717 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001718 return _lib.SSL_want_read(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001719
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001720 def want_write(self):
1721 """
1722 Checks if there is data to write to the transport layer to complete an
1723 operation.
1724
1725 :return: True iff there is data to write
1726 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001727 return _lib.SSL_want_write(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001728
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001729 def set_accept_state(self):
1730 """
Alex Gaynor62da94d2015-09-05 14:37:34 -04001731 Set the connection to work in server mode. The handshake will be
1732 handled automatically by read/write.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001733
1734 :return: None
1735 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001736 _lib.SSL_set_accept_state(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001737
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001738 def set_connect_state(self):
1739 """
Alex Gaynor62da94d2015-09-05 14:37:34 -04001740 Set the connection to work in client mode. The handshake will be
1741 handled automatically by read/write.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001742
1743 :return: None
1744 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001745 _lib.SSL_set_connect_state(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001746
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001747 def get_session(self):
1748 """
1749 Returns the Session currently used.
1750
Alex Gaynor62da94d2015-09-05 14:37:34 -04001751 @return: An instance of :py:class:`OpenSSL.SSL.Session` or
1752 :py:obj:`None` if no session exists.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001753 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001754 session = _lib.SSL_get1_session(self._ssl)
1755 if session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001756 return None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001757
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001758 pysession = Session.__new__(Session)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001759 pysession._session = _ffi.gc(session, _lib.SSL_SESSION_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001760 return pysession
1761
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001762 def set_session(self, session):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001763 """
1764 Set the session to be used when the TLS/SSL connection is established.
1765
1766 :param session: A Session instance representing the session to use.
1767 :returns: None
1768 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001769 if not isinstance(session, Session):
1770 raise TypeError("session must be a Session instance")
1771
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001772 result = _lib.SSL_set_session(self._ssl, session._session)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001773 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001774 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001775
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001776 def _get_finished_message(self, function):
1777 """
1778 Helper to implement :py:meth:`get_finished` and
1779 :py:meth:`get_peer_finished`.
1780
1781 :param function: Either :py:data:`SSL_get_finished`: or
1782 :py:data:`SSL_get_peer_finished`.
1783
1784 :return: :py:data:`None` if the desired message has not yet been
1785 received, otherwise the contents of the message.
1786 :rtype: :py:class:`bytes` or :py:class:`NoneType`
1787 """
Jean-Paul Calderone01af9042014-03-30 11:40:42 -04001788 # The OpenSSL documentation says nothing about what might happen if the
1789 # count argument given is zero. Specifically, it doesn't say whether
1790 # the output buffer may be NULL in that case or not. Inspection of the
1791 # implementation reveals that it calls memcpy() unconditionally.
1792 # Section 7.1.4, paragraph 1 of the C standard suggests that
1793 # memcpy(NULL, source, 0) is not guaranteed to produce defined (let
1794 # alone desirable) behavior (though it probably does on just about
1795 # every implementation...)
1796 #
1797 # Allocate a tiny buffer to pass in (instead of just passing NULL as
1798 # one might expect) for the initial call so as to be safe against this
1799 # potentially undefined behavior.
1800 empty = _ffi.new("char[]", 0)
1801 size = function(self._ssl, empty, 0)
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001802 if size == 0:
1803 # No Finished message so far.
1804 return None
1805
1806 buf = _ffi.new("char[]", size)
1807 function(self._ssl, buf, size)
1808 return _ffi.buffer(buf, size)[:]
1809
Fedor Brunner5747b932014-03-05 14:22:34 +01001810 def get_finished(self):
1811 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001812 Obtain the latest `handshake finished` message sent to the peer.
Fedor Brunner5747b932014-03-05 14:22:34 +01001813
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001814 :return: The contents of the message or :py:obj:`None` if the TLS
1815 handshake has not yet completed.
1816 :rtype: :py:class:`bytes` or :py:class:`NoneType`
Fedor Brunner5747b932014-03-05 14:22:34 +01001817 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001818 return self._get_finished_message(_lib.SSL_get_finished)
1819
Fedor Brunner5747b932014-03-05 14:22:34 +01001820 def get_peer_finished(self):
1821 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001822 Obtain the latest `handshake finished` message received from the peer.
Fedor Brunner5747b932014-03-05 14:22:34 +01001823
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001824 :return: The contents of the message or :py:obj:`None` if the TLS
1825 handshake has not yet completed.
1826 :rtype: :py:class:`bytes` or :py:class:`NoneType`
Fedor Brunner5747b932014-03-05 14:22:34 +01001827 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001828 return self._get_finished_message(_lib.SSL_get_peer_finished)
Fedor Brunner5747b932014-03-05 14:22:34 +01001829
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001830 def get_cipher_name(self):
1831 """
1832 Obtain the name of the currently used cipher.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001833
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001834 :returns: The name of the currently used cipher or :py:obj:`None`
1835 if no connection has been established.
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001836 :rtype: :py:class:`unicode` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001837 """
1838 cipher = _lib.SSL_get_current_cipher(self._ssl)
1839 if cipher == _ffi.NULL:
1840 return None
1841 else:
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001842 name = _ffi.string(_lib.SSL_CIPHER_get_name(cipher))
1843 return name.decode("utf-8")
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001844
1845 def get_cipher_bits(self):
1846 """
1847 Obtain the number of secret bits of the currently used cipher.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001848
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001849 :returns: The number of secret bits of the currently used cipher
1850 or :py:obj:`None` if no connection has been established.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001851 :rtype: :py:class:`int` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001852 """
1853 cipher = _lib.SSL_get_current_cipher(self._ssl)
1854 if cipher == _ffi.NULL:
1855 return None
1856 else:
1857 return _lib.SSL_CIPHER_get_bits(cipher, _ffi.NULL)
1858
1859 def get_cipher_version(self):
1860 """
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001861 Obtain the protocol version of the currently used cipher.
1862
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001863 :returns: The protocol name of the currently used cipher
1864 or :py:obj:`None` if no connection has been established.
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001865 :rtype: :py:class:`unicode` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001866 """
1867 cipher = _lib.SSL_get_current_cipher(self._ssl)
1868 if cipher == _ffi.NULL:
1869 return None
1870 else:
Alex Gaynorc4889812015-09-04 08:43:17 -04001871 version = _ffi.string(_lib.SSL_CIPHER_get_version(cipher))
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001872 return version.decode("utf-8")
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001873
Jim Shaverabff1882015-05-27 09:15:55 -04001874 def get_protocol_version_name(self):
Jim Shaverba65e662015-04-26 12:23:40 -04001875 """
1876 Obtain the protocol version of the current connection.
1877
1878 :returns: The TLS version of the current connection, for example
Jim Shaver58d25732015-05-28 11:52:32 -04001879 the value for TLS 1.2 would be ``TLSv1.2``or ``Unknown``
Jim Shaverb5b6b0e2015-05-28 16:47:36 -04001880 for connections that were not successfully established.
Jim Shaver58d25732015-05-28 11:52:32 -04001881 :rtype: :py:class:`unicode`
Jim Shaverba65e662015-04-26 12:23:40 -04001882 """
Jim Shaverd1c896e2015-05-27 17:50:21 -04001883 version = _ffi.string(_lib.SSL_get_version(self._ssl))
Jim Shaver58d25732015-05-28 11:52:32 -04001884 return version.decode("utf-8")
Jim Shaverb2967922015-04-26 23:58:52 -04001885
Jim Shaver208438c2015-05-28 09:52:38 -04001886 def get_protocol_version(self):
1887 """
1888 Obtain the protocol version of the current connection.
1889
1890 :returns: The TLS version of the current connection, for example
1891 the value for TLS 1 would be 0x769.
1892 :rtype: :py:class:`int`
1893 """
1894 version = _lib.SSL_version(self._ssl)
1895 return version
1896
Cory Benfield10b277f2015-04-13 17:12:42 -04001897 @_requires_npn
Cory Benfield84a121e2014-03-31 20:30:25 +01001898 def get_next_proto_negotiated(self):
1899 """
1900 Get the protocol that was negotiated by NPN.
1901 """
1902 data = _ffi.new("unsigned char **")
1903 data_len = _ffi.new("unsigned int *")
1904
1905 _lib.SSL_get0_next_proto_negotiated(self._ssl, data, data_len)
1906
Cory Benfieldcd010f62014-05-15 19:00:27 +01001907 return _ffi.buffer(data[0], data_len[0])[:]
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001908
Cory Benfield7907e332015-04-13 17:18:25 -04001909 @_requires_alpn
Cory Benfield12eae892014-06-07 15:42:56 +01001910 def set_alpn_protos(self, protos):
1911 """
Cory Benfielde8e9c382015-04-11 17:33:48 -04001912 Specify the client's ALPN protocol list.
1913
1914 These protocols are offered to the server during protocol negotiation.
Cory Benfield12eae892014-06-07 15:42:56 +01001915
1916 :param protos: A list of the protocols to be offered to the server.
1917 This list should be a Python list of bytestrings representing the
1918 protocols to offer, e.g. ``[b'http/1.1', b'spdy/2']``.
1919 """
1920 # Take the list of protocols and join them together, prefixing them
1921 # with their lengths.
1922 protostr = b''.join(
1923 chain.from_iterable((int2byte(len(p)), p) for p in protos)
1924 )
1925
1926 # Build a C string from the list. We don't need to save this off
1927 # because OpenSSL immediately copies the data out.
1928 input_str = _ffi.new("unsigned char[]", protostr)
Cory Benfield9c1979a2015-04-12 08:51:52 -04001929 input_str_len = _ffi.cast("unsigned", len(protostr))
1930 _lib.SSL_set_alpn_protos(self._ssl, input_str, input_str_len)
Cory Benfield12eae892014-06-07 15:42:56 +01001931
Maximilian Hils66ded6a2015-08-26 06:02:03 +02001932 @_requires_alpn
Cory Benfield12eae892014-06-07 15:42:56 +01001933 def get_alpn_proto_negotiated(self):
Cory Benfield222f30e2015-04-13 18:10:21 -04001934 """
1935 Get the protocol that was negotiated by ALPN.
1936 """
Cory Benfield12eae892014-06-07 15:42:56 +01001937 data = _ffi.new("unsigned char **")
1938 data_len = _ffi.new("unsigned int *")
1939
1940 _lib.SSL_get0_alpn_selected(self._ssl, data, data_len)
1941
Cory Benfielde8e9c382015-04-11 17:33:48 -04001942 if not data_len:
1943 return b''
1944
Cory Benfield12eae892014-06-07 15:42:56 +01001945 return _ffi.buffer(data[0], data_len[0])[:]
1946
1947
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001948ConnectionType = Connection
Jean-Paul Calderone11ed8e82014-01-18 10:21:50 -05001949
Jean-Paul Calderonefab157b2014-01-18 11:21:38 -05001950# This is similar to the initialization calls at the end of OpenSSL/crypto.py
1951# but is exercised mostly by the Context initializer.
Jean-Paul Calderone11ed8e82014-01-18 10:21:50 -05001952_lib.SSL_library_init()