blob: 794199c5f97c26831047d8df3f8432cac5d20166 [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 """
1317 Receive data on the connection. NOTE: If you get one of the WantRead,
1318 WantWrite or WantX509Lookup exceptions on this, you have to call the
1319 method again with the SAME buffer.
1320
1321 :param bufsiz: The maximum number of bytes to read
Maximilian Hils1d95dea2015-08-17 19:27:20 +02001322 :param flags: (optional) The only supported flag is ``MSG_PEEK``,
1323 all other flags are ignored.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001324 :return: The string read from the Connection
1325 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001326 buf = _ffi.new("char[]", bufsiz)
Maximilian Hils1d95dea2015-08-17 19:27:20 +02001327 if flags is not None and flags & socket.MSG_PEEK:
1328 result = _lib.SSL_peek(self._ssl, buf, bufsiz)
1329 else:
1330 result = _lib.SSL_read(self._ssl, buf, bufsiz)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001331 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001332 return _ffi.buffer(buf, result)[:]
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001333 read = recv
1334
Cory Benfield62d10332014-06-15 10:03:41 +01001335 def recv_into(self, buffer, nbytes=None, flags=None):
1336 """
1337 Receive data on the connection and store the data into a buffer rather
1338 than creating a new string.
1339
1340 :param buffer: The buffer to copy into.
1341 :param nbytes: (optional) The maximum number of bytes to read into the
1342 buffer. If not present, defaults to the size of the buffer. If
1343 larger than the size of the buffer, is reduced to the size of the
1344 buffer.
Maximilian Hils1d95dea2015-08-17 19:27:20 +02001345 :param flags: (optional) The only supported flag is ``MSG_PEEK``,
1346 all other flags are ignored.
Cory Benfield62d10332014-06-15 10:03:41 +01001347 :return: The number of bytes read into the buffer.
1348 """
1349 if nbytes is None:
1350 nbytes = len(buffer)
1351 else:
1352 nbytes = min(nbytes, len(buffer))
1353
1354 # We need to create a temporary buffer. This is annoying, it would be
1355 # better if we could pass memoryviews straight into the SSL_read call,
1356 # but right now we can't. Revisit this if CFFI gets that ability.
1357 buf = _ffi.new("char[]", nbytes)
Maximilian Hils1d95dea2015-08-17 19:27:20 +02001358 if flags is not None and flags & socket.MSG_PEEK:
1359 result = _lib.SSL_peek(self._ssl, buf, nbytes)
1360 else:
1361 result = _lib.SSL_read(self._ssl, buf, nbytes)
Cory Benfield62d10332014-06-15 10:03:41 +01001362 self._raise_ssl_error(self._ssl, result)
1363
1364 # This strange line is all to avoid a memory copy. The buffer protocol
1365 # should allow us to assign a CFFI buffer to the LHS of this line, but
1366 # on CPython 3.3+ that segfaults. As a workaround, we can temporarily
1367 # wrap it in a memoryview, except on Python 2.6 which doesn't have a
1368 # memoryview type.
1369 try:
1370 buffer[:result] = memoryview(_ffi.buffer(buf, result))
1371 except NameError:
1372 buffer[:result] = _ffi.buffer(buf, result)
1373
1374 return result
1375
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001376 def _handle_bio_errors(self, bio, result):
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001377 if _lib.BIO_should_retry(bio):
1378 if _lib.BIO_should_read(bio):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001379 raise WantReadError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001380 elif _lib.BIO_should_write(bio):
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001381 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001382 raise WantWriteError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001383 elif _lib.BIO_should_io_special(bio):
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001384 # TODO: This is untested. I think io_special means the socket
1385 # BIO has a not-yet connected socket.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001386 raise ValueError("BIO_should_io_special")
1387 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001388 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001389 raise ValueError("unknown bio failure")
1390 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001391 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001392 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001393
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001394 def bio_read(self, bufsiz):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001395 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001396 When using non-socket connections this function reads the "dirty" data
1397 that would have traveled away on the network.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001398
1399 :param bufsiz: The maximum number of bytes to read
1400 :return: The string read.
1401 """
Jean-Paul Calderone97e041d2013-03-05 21:03:12 -08001402 if self._from_ssl is None:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001403 raise TypeError("Connection sock was not None")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001404
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -05001405 if not isinstance(bufsiz, integer_types):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001406 raise TypeError("bufsiz must be an integer")
1407
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001408 buf = _ffi.new("char[]", bufsiz)
1409 result = _lib.BIO_read(self._from_ssl, buf, bufsiz)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001410 if result <= 0:
1411 self._handle_bio_errors(self._from_ssl, result)
1412
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001413 return _ffi.buffer(buf, result)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001414
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001415 def bio_write(self, buf):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001416 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001417 When using non-socket connections this function sends "dirty" data that
1418 would have traveled in on the network.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001419
1420 :param buf: The string to put into the memory BIO.
1421 :return: The number of bytes written
1422 """
Jean-Paul Calderone39a8d592015-04-13 20:49:50 -04001423 buf = _text_to_bytes_and_warn("buf", buf)
Abraham Martine82326c2015-02-04 10:18:10 +00001424
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001425 if self._into_ssl is None:
1426 raise TypeError("Connection sock was not None")
1427
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001428 result = _lib.BIO_write(self._into_ssl, buf, len(buf))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001429 if result <= 0:
1430 self._handle_bio_errors(self._into_ssl, result)
1431 return result
1432
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001433 def renegotiate(self):
1434 """
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +01001435 Renegotiate the session.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001436
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +01001437 :return: True if the renegotiation can be started, False otherwise
1438 :rtype: bool
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001439 """
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +01001440 if not self.renegotiate_pending():
1441 _openssl_assert(_lib.SSL_renegotiate(self._ssl) == 1)
1442 return True
1443 return False
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001444
1445 def do_handshake(self):
1446 """
1447 Perform an SSL handshake (usually called after renegotiate() or one of
1448 set_*_state()). This can raise the same exceptions as send and recv.
1449
1450 :return: None.
1451 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001452 result = _lib.SSL_do_handshake(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001453 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001454
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001455 def renegotiate_pending(self):
1456 """
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +01001457 Check if there's a renegotiation in progress, it will return False once
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001458 a renegotiation is finished.
1459
1460 :return: Whether there's a renegotiation in progress
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +01001461 :rtype: bool
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001462 """
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +01001463 return _lib.SSL_renegotiate_pending(self._ssl) == 1
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001464
1465 def total_renegotiations(self):
1466 """
1467 Find out the total number of renegotiations.
1468
1469 :return: The number of renegotiations.
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +01001470 :rtype: int
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001471 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001472 return _lib.SSL_total_renegotiations(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001473
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001474 def connect(self, addr):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001475 """
1476 Connect to remote host and set up client-side SSL
1477
1478 :param addr: A remote address
1479 :return: What the socket's connect method returns
1480 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001481 _lib.SSL_set_connect_state(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001482 return self._socket.connect(addr)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001483
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001484 def connect_ex(self, addr):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001485 """
Alex Gaynor62da94d2015-09-05 14:37:34 -04001486 Connect to remote host and set up client-side SSL. Note that if the
1487 socket's connect_ex method doesn't return 0, SSL won't be initialized.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001488
1489 :param addr: A remove address
1490 :return: What the socket's connect_ex method returns
1491 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001492 connect_ex = self._socket.connect_ex
1493 self.set_connect_state()
1494 return connect_ex(addr)
1495
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001496 def accept(self):
1497 """
1498 Accept incoming connection and set up SSL on it
1499
1500 :return: A (conn,addr) pair where conn is a Connection and addr is an
1501 address
1502 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001503 client, addr = self._socket.accept()
1504 conn = Connection(self._context, client)
1505 conn.set_accept_state()
1506 return (conn, addr)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001507
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001508 def bio_shutdown(self):
1509 """
1510 When using non-socket connections this function signals end of
1511 data on the input for this connection.
1512
1513 :return: None
1514 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001515 if self._from_ssl is None:
1516 raise TypeError("Connection sock was not None")
1517
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001518 _lib.BIO_set_mem_eof_return(self._into_ssl, 0)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001519
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001520 def shutdown(self):
1521 """
1522 Send closure alert
1523
1524 :return: True if the shutdown completed successfully (i.e. both sides
1525 have sent closure alerts), false otherwise (i.e. you have to
1526 wait for a ZeroReturnError on a recv() method call
1527 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001528 result = _lib.SSL_shutdown(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001529 if result < 0:
Paul Aurichbff1d1a2015-01-08 08:36:53 -08001530 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001531 elif result > 0:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001532 return True
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001533 else:
1534 return False
1535
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001536 def get_cipher_list(self):
1537 """
Hynek Schlawackf90e3682016-03-11 11:21:13 +01001538 Retrieve the list of ciphers used by the Connection object.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001539
Hynek Schlawackf90e3682016-03-11 11:21:13 +01001540 :return: A list of native cipher strings.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001541 """
1542 ciphers = []
1543 for i in count():
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001544 result = _lib.SSL_get_cipher_list(self._ssl, i)
1545 if result == _ffi.NULL:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001546 break
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001547 ciphers.append(_native(_ffi.string(result)))
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001548 return ciphers
1549
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001550 def get_client_ca_list(self):
1551 """
1552 Get CAs whose certificates are suggested for client authentication.
1553
Alex Gaynor62da94d2015-09-05 14:37:34 -04001554 :return: If this is a server connection, a list of X509Names
1555 representing the acceptable CAs as set by
1556 :py:meth:`OpenSSL.SSL.Context.set_client_ca_list` or
1557 :py:meth:`OpenSSL.SSL.Context.add_client_ca`. If this is a client
1558 connection, the list of such X509Names sent by the server, or an
1559 empty list if that has not yet happened.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001560 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001561 ca_names = _lib.SSL_get_client_CA_list(self._ssl)
1562 if ca_names == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001563 # TODO: This is untested.
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001564 return []
1565
1566 result = []
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001567 for i in range(_lib.sk_X509_NAME_num(ca_names)):
1568 name = _lib.sk_X509_NAME_value(ca_names, i)
1569 copy = _lib.X509_NAME_dup(name)
1570 if copy == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001571 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001572 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001573
1574 pyname = X509Name.__new__(X509Name)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001575 pyname._name = _ffi.gc(copy, _lib.X509_NAME_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001576 result.append(pyname)
1577 return result
1578
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001579 def makefile(self):
1580 """
Alex Gaynor62da94d2015-09-05 14:37:34 -04001581 The makefile() method is not implemented, since there is no dup
1582 semantics for SSL connections
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001583
Jean-Paul Calderone6749ec22014-04-17 16:30:21 -04001584 :raise: NotImplementedError
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001585 """
Alex Gaynor83284952015-09-05 10:43:30 -04001586 raise NotImplementedError(
1587 "Cannot make file object of OpenSSL.SSL.Connection")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001588
1589 def get_app_data(self):
1590 """
1591 Get application data
1592
1593 :return: The application data
1594 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001595 return self._app_data
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001596
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001597 def set_app_data(self, data):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001598 """
1599 Set application data
1600
1601 :param data - The application data
1602 :return: None
1603 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001604 self._app_data = data
1605
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001606 def get_shutdown(self):
1607 """
1608 Get shutdown state
1609
Alex Gaynor62da94d2015-09-05 14:37:34 -04001610 :return: The shutdown state, a bitvector of SENT_SHUTDOWN,
1611 RECEIVED_SHUTDOWN.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001612 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001613 return _lib.SSL_get_shutdown(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001614
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001615 def set_shutdown(self, state):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001616 """
1617 Set shutdown state
1618
1619 :param state - bitvector of SENT_SHUTDOWN, RECEIVED_SHUTDOWN.
1620 :return: None
1621 """
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -05001622 if not isinstance(state, integer_types):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001623 raise TypeError("state must be an integer")
1624
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001625 _lib.SSL_set_shutdown(self._ssl, state)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001626
Hynek Schlawackea94f2b2016-03-13 16:17:53 +01001627 def get_state_string(self):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001628 """
Hynek Schlawackea94f2b2016-03-13 16:17:53 +01001629 Retrieve a verbose string detailing the state of the Connection.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001630
1631 :return: A string representing the state
Hynek Schlawackea94f2b2016-03-13 16:17:53 +01001632 :rtype: bytes
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001633 """
kjavc704a2e2015-09-07 12:12:27 +01001634 return _ffi.string(_lib.SSL_state_string_long(self._ssl))
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001635
1636 def server_random(self):
1637 """
1638 Get a copy of the server hello nonce.
1639
1640 :return: A string representing the state
1641 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001642 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001643 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001644 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001645 self._ssl.s3.server_random,
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001646 _lib.SSL3_RANDOM_SIZE)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001647
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001648 def client_random(self):
1649 """
1650 Get a copy of the client hello nonce.
1651
1652 :return: A string representing the state
1653 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001654 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001655 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001656 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001657 self._ssl.s3.client_random,
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001658 _lib.SSL3_RANDOM_SIZE)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001659
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001660 def master_key(self):
1661 """
1662 Get a copy of the master key.
1663
1664 :return: A string representing the state
1665 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001666 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001667 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001668 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001669 self._ssl.session.master_key,
1670 self._ssl.session.master_key_length)[:]
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001671
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001672 def sock_shutdown(self, *args, **kwargs):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001673 """
1674 See shutdown(2)
1675
1676 :return: What the socket's shutdown() method returns
1677 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001678 return self._socket.shutdown(*args, **kwargs)
1679
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001680 def get_peer_certificate(self):
1681 """
1682 Retrieve the other side's certificate (if any)
1683
1684 :return: The peer's certificate
1685 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001686 cert = _lib.SSL_get_peer_certificate(self._ssl)
1687 if cert != _ffi.NULL:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001688 pycert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001689 pycert._x509 = _ffi.gc(cert, _lib.X509_free)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001690 return pycert
1691 return None
1692
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001693 def get_peer_cert_chain(self):
1694 """
1695 Retrieve the other side's certificate (if any)
1696
1697 :return: A list of X509 instances giving the peer's certificate chain,
1698 or None if it does not have one.
1699 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001700 cert_stack = _lib.SSL_get_peer_cert_chain(self._ssl)
1701 if cert_stack == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001702 return None
1703
1704 result = []
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001705 for i in range(_lib.sk_X509_num(cert_stack)):
Jean-Paul Calderone73b15c22013-03-05 18:30:39 -08001706 # TODO could incref instead of dup here
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001707 cert = _lib.X509_dup(_lib.sk_X509_value(cert_stack, i))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001708 pycert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001709 pycert._x509 = _ffi.gc(cert, _lib.X509_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001710 result.append(pycert)
1711 return result
1712
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001713 def want_read(self):
1714 """
Alex Gaynor62da94d2015-09-05 14:37:34 -04001715 Checks if more data has to be read from the transport layer to complete
1716 an operation.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001717
1718 :return: True iff more data has to be read
1719 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001720 return _lib.SSL_want_read(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001721
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001722 def want_write(self):
1723 """
1724 Checks if there is data to write to the transport layer to complete an
1725 operation.
1726
1727 :return: True iff there is data to write
1728 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001729 return _lib.SSL_want_write(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001730
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001731 def set_accept_state(self):
1732 """
Alex Gaynor62da94d2015-09-05 14:37:34 -04001733 Set the connection to work in server mode. The handshake will be
1734 handled automatically by read/write.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001735
1736 :return: None
1737 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001738 _lib.SSL_set_accept_state(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001739
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001740 def set_connect_state(self):
1741 """
Alex Gaynor62da94d2015-09-05 14:37:34 -04001742 Set the connection to work in client mode. The handshake will be
1743 handled automatically by read/write.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001744
1745 :return: None
1746 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001747 _lib.SSL_set_connect_state(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001748
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001749 def get_session(self):
1750 """
1751 Returns the Session currently used.
1752
Alex Gaynor62da94d2015-09-05 14:37:34 -04001753 @return: An instance of :py:class:`OpenSSL.SSL.Session` or
1754 :py:obj:`None` if no session exists.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001755 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001756 session = _lib.SSL_get1_session(self._ssl)
1757 if session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001758 return None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001759
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001760 pysession = Session.__new__(Session)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001761 pysession._session = _ffi.gc(session, _lib.SSL_SESSION_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001762 return pysession
1763
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001764 def set_session(self, session):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001765 """
1766 Set the session to be used when the TLS/SSL connection is established.
1767
1768 :param session: A Session instance representing the session to use.
1769 :returns: None
1770 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001771 if not isinstance(session, Session):
1772 raise TypeError("session must be a Session instance")
1773
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001774 result = _lib.SSL_set_session(self._ssl, session._session)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001775 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001776 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001777
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001778 def _get_finished_message(self, function):
1779 """
1780 Helper to implement :py:meth:`get_finished` and
1781 :py:meth:`get_peer_finished`.
1782
1783 :param function: Either :py:data:`SSL_get_finished`: or
1784 :py:data:`SSL_get_peer_finished`.
1785
1786 :return: :py:data:`None` if the desired message has not yet been
1787 received, otherwise the contents of the message.
1788 :rtype: :py:class:`bytes` or :py:class:`NoneType`
1789 """
Jean-Paul Calderone01af9042014-03-30 11:40:42 -04001790 # The OpenSSL documentation says nothing about what might happen if the
1791 # count argument given is zero. Specifically, it doesn't say whether
1792 # the output buffer may be NULL in that case or not. Inspection of the
1793 # implementation reveals that it calls memcpy() unconditionally.
1794 # Section 7.1.4, paragraph 1 of the C standard suggests that
1795 # memcpy(NULL, source, 0) is not guaranteed to produce defined (let
1796 # alone desirable) behavior (though it probably does on just about
1797 # every implementation...)
1798 #
1799 # Allocate a tiny buffer to pass in (instead of just passing NULL as
1800 # one might expect) for the initial call so as to be safe against this
1801 # potentially undefined behavior.
1802 empty = _ffi.new("char[]", 0)
1803 size = function(self._ssl, empty, 0)
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001804 if size == 0:
1805 # No Finished message so far.
1806 return None
1807
1808 buf = _ffi.new("char[]", size)
1809 function(self._ssl, buf, size)
1810 return _ffi.buffer(buf, size)[:]
1811
Fedor Brunner5747b932014-03-05 14:22:34 +01001812 def get_finished(self):
1813 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001814 Obtain the latest `handshake finished` message sent to the peer.
Fedor Brunner5747b932014-03-05 14:22:34 +01001815
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001816 :return: The contents of the message or :py:obj:`None` if the TLS
1817 handshake has not yet completed.
1818 :rtype: :py:class:`bytes` or :py:class:`NoneType`
Fedor Brunner5747b932014-03-05 14:22:34 +01001819 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001820 return self._get_finished_message(_lib.SSL_get_finished)
1821
Fedor Brunner5747b932014-03-05 14:22:34 +01001822 def get_peer_finished(self):
1823 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001824 Obtain the latest `handshake finished` message received from the peer.
Fedor Brunner5747b932014-03-05 14:22:34 +01001825
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001826 :return: The contents of the message or :py:obj:`None` if the TLS
1827 handshake has not yet completed.
1828 :rtype: :py:class:`bytes` or :py:class:`NoneType`
Fedor Brunner5747b932014-03-05 14:22:34 +01001829 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001830 return self._get_finished_message(_lib.SSL_get_peer_finished)
Fedor Brunner5747b932014-03-05 14:22:34 +01001831
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001832 def get_cipher_name(self):
1833 """
1834 Obtain the name of the currently used cipher.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001835
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001836 :returns: The name of the currently used cipher or :py:obj:`None`
1837 if no connection has been established.
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001838 :rtype: :py:class:`unicode` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001839 """
1840 cipher = _lib.SSL_get_current_cipher(self._ssl)
1841 if cipher == _ffi.NULL:
1842 return None
1843 else:
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001844 name = _ffi.string(_lib.SSL_CIPHER_get_name(cipher))
1845 return name.decode("utf-8")
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001846
1847 def get_cipher_bits(self):
1848 """
1849 Obtain the number of secret bits of the currently used cipher.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001850
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001851 :returns: The number of secret bits of the currently used cipher
1852 or :py:obj:`None` if no connection has been established.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001853 :rtype: :py:class:`int` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001854 """
1855 cipher = _lib.SSL_get_current_cipher(self._ssl)
1856 if cipher == _ffi.NULL:
1857 return None
1858 else:
1859 return _lib.SSL_CIPHER_get_bits(cipher, _ffi.NULL)
1860
1861 def get_cipher_version(self):
1862 """
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001863 Obtain the protocol version of the currently used cipher.
1864
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001865 :returns: The protocol name of the currently used cipher
1866 or :py:obj:`None` if no connection has been established.
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001867 :rtype: :py:class:`unicode` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001868 """
1869 cipher = _lib.SSL_get_current_cipher(self._ssl)
1870 if cipher == _ffi.NULL:
1871 return None
1872 else:
Alex Gaynorc4889812015-09-04 08:43:17 -04001873 version = _ffi.string(_lib.SSL_CIPHER_get_version(cipher))
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001874 return version.decode("utf-8")
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001875
Jim Shaverabff1882015-05-27 09:15:55 -04001876 def get_protocol_version_name(self):
Jim Shaverba65e662015-04-26 12:23:40 -04001877 """
1878 Obtain the protocol version of the current connection.
1879
1880 :returns: The TLS version of the current connection, for example
Jim Shaver58d25732015-05-28 11:52:32 -04001881 the value for TLS 1.2 would be ``TLSv1.2``or ``Unknown``
Jim Shaverb5b6b0e2015-05-28 16:47:36 -04001882 for connections that were not successfully established.
Jim Shaver58d25732015-05-28 11:52:32 -04001883 :rtype: :py:class:`unicode`
Jim Shaverba65e662015-04-26 12:23:40 -04001884 """
Jim Shaverd1c896e2015-05-27 17:50:21 -04001885 version = _ffi.string(_lib.SSL_get_version(self._ssl))
Jim Shaver58d25732015-05-28 11:52:32 -04001886 return version.decode("utf-8")
Jim Shaverb2967922015-04-26 23:58:52 -04001887
Jim Shaver208438c2015-05-28 09:52:38 -04001888 def get_protocol_version(self):
1889 """
1890 Obtain the protocol version of the current connection.
1891
1892 :returns: The TLS version of the current connection, for example
1893 the value for TLS 1 would be 0x769.
1894 :rtype: :py:class:`int`
1895 """
1896 version = _lib.SSL_version(self._ssl)
1897 return version
1898
Cory Benfield10b277f2015-04-13 17:12:42 -04001899 @_requires_npn
Cory Benfield84a121e2014-03-31 20:30:25 +01001900 def get_next_proto_negotiated(self):
1901 """
1902 Get the protocol that was negotiated by NPN.
1903 """
1904 data = _ffi.new("unsigned char **")
1905 data_len = _ffi.new("unsigned int *")
1906
1907 _lib.SSL_get0_next_proto_negotiated(self._ssl, data, data_len)
1908
Cory Benfieldcd010f62014-05-15 19:00:27 +01001909 return _ffi.buffer(data[0], data_len[0])[:]
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001910
Cory Benfield7907e332015-04-13 17:18:25 -04001911 @_requires_alpn
Cory Benfield12eae892014-06-07 15:42:56 +01001912 def set_alpn_protos(self, protos):
1913 """
Cory Benfielde8e9c382015-04-11 17:33:48 -04001914 Specify the client's ALPN protocol list.
1915
1916 These protocols are offered to the server during protocol negotiation.
Cory Benfield12eae892014-06-07 15:42:56 +01001917
1918 :param protos: A list of the protocols to be offered to the server.
1919 This list should be a Python list of bytestrings representing the
1920 protocols to offer, e.g. ``[b'http/1.1', b'spdy/2']``.
1921 """
1922 # Take the list of protocols and join them together, prefixing them
1923 # with their lengths.
1924 protostr = b''.join(
1925 chain.from_iterable((int2byte(len(p)), p) for p in protos)
1926 )
1927
1928 # Build a C string from the list. We don't need to save this off
1929 # because OpenSSL immediately copies the data out.
1930 input_str = _ffi.new("unsigned char[]", protostr)
Cory Benfield9c1979a2015-04-12 08:51:52 -04001931 input_str_len = _ffi.cast("unsigned", len(protostr))
1932 _lib.SSL_set_alpn_protos(self._ssl, input_str, input_str_len)
Cory Benfield12eae892014-06-07 15:42:56 +01001933
Maximilian Hils66ded6a2015-08-26 06:02:03 +02001934 @_requires_alpn
Cory Benfield12eae892014-06-07 15:42:56 +01001935 def get_alpn_proto_negotiated(self):
Cory Benfield222f30e2015-04-13 18:10:21 -04001936 """
1937 Get the protocol that was negotiated by ALPN.
1938 """
Cory Benfield12eae892014-06-07 15:42:56 +01001939 data = _ffi.new("unsigned char **")
1940 data_len = _ffi.new("unsigned int *")
1941
1942 _lib.SSL_get0_alpn_selected(self._ssl, data, data_len)
1943
Cory Benfielde8e9c382015-04-11 17:33:48 -04001944 if not data_len:
1945 return b''
1946
Cory Benfield12eae892014-06-07 15:42:56 +01001947 return _ffi.buffer(data[0], data_len[0])[:]
1948
1949
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001950ConnectionType = Connection
Jean-Paul Calderone11ed8e82014-01-18 10:21:50 -05001951
Jean-Paul Calderonefab157b2014-01-18 11:21:38 -05001952# This is similar to the initialization calls at the end of OpenSSL/crypto.py
1953# but is exercised mostly by the Context initializer.
Jean-Paul Calderone11ed8e82014-01-18 10:21:50 -05001954_lib.SSL_library_init()