blob: 800ae1ed4f47e6954b380800654f0d4d7fd1839a [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 Benfield10b277f2015-04-13 17:12:42 -0400409def _requires_npn(func):
Cory Benfielda876cef2015-04-13 17:29:12 -0400410 """
411 Wraps any function that requires NPN support in OpenSSL, ensuring that
412 NotImplementedError is raised if NPN is not present.
413 """
Cory Benfield10b277f2015-04-13 17:12:42 -0400414 @wraps(func)
415 def wrapper(*args, **kwargs):
416 if not _lib.Cryptography_HAS_NEXTPROTONEG:
417 raise NotImplementedError("NPN not available.")
418
419 return func(*args, **kwargs)
420
421 return wrapper
422
423
Cory Benfield7907e332015-04-13 17:18:25 -0400424def _requires_alpn(func):
Cory Benfield9d80a762015-04-13 17:47:33 -0400425 """
426 Wraps any function that requires ALPN support in OpenSSL, ensuring that
427 NotImplementedError is raised if ALPN support is not present.
428 """
Cory Benfield7907e332015-04-13 17:18:25 -0400429 @wraps(func)
430 def wrapper(*args, **kwargs):
431 if not _lib.Cryptography_HAS_ALPN:
432 raise NotImplementedError("ALPN not available.")
433
434 return func(*args, **kwargs)
435
436 return wrapper
437
438
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800439class Session(object):
440 pass
441
442
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800443class Context(object):
444 """
Hynek Schlawackf90e3682016-03-11 11:21:13 +0100445 :class:`OpenSSL.SSL.Context` instances define the parameters for setting
Alex Gaynor62da94d2015-09-05 14:37:34 -0400446 up new SSL connections.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800447 """
448 _methods = {
Andrew Dunhamec84a0a2014-02-24 12:41:37 -0800449 SSLv2_METHOD: "SSLv2_method",
Jean-Paul Calderonebe2bb422013-12-29 07:34:08 -0500450 SSLv3_METHOD: "SSLv3_method",
451 SSLv23_METHOD: "SSLv23_method",
452 TLSv1_METHOD: "TLSv1_method",
453 TLSv1_1_METHOD: "TLSv1_1_method",
454 TLSv1_2_METHOD: "TLSv1_2_method",
Alex Gaynorc4889812015-09-04 08:43:17 -0400455 }
Jean-Paul Calderonebe2bb422013-12-29 07:34:08 -0500456 _methods = dict(
457 (identifier, getattr(_lib, name))
458 for (identifier, name) in _methods.items()
459 if getattr(_lib, name, None) is not None)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800460
461 def __init__(self, method):
462 """
463 :param method: One of SSLv2_METHOD, SSLv3_METHOD, SSLv23_METHOD, or
464 TLSv1_METHOD.
465 """
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -0500466 if not isinstance(method, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800467 raise TypeError("method must be an integer")
468
469 try:
470 method_func = self._methods[method]
471 except KeyError:
472 raise ValueError("No such protocol")
473
474 method_obj = method_func()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500475 if method_obj == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500476 # TODO: This is untested.
477 _raise_current_error()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800478
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500479 context = _lib.SSL_CTX_new(method_obj)
480 if context == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500481 # TODO: This is untested.
482 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500483 context = _ffi.gc(context, _lib.SSL_CTX_free)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800484
485 self._context = context
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800486 self._passphrase_helper = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800487 self._passphrase_callback = None
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800488 self._passphrase_userdata = None
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800489 self._verify_helper = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800490 self._verify_callback = None
491 self._info_callback = None
492 self._tlsext_servername_callback = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800493 self._app_data = None
Cory Benfield0ea76e72015-03-22 09:05:28 +0000494 self._npn_advertise_helper = None
Cory Benfield84a121e2014-03-31 20:30:25 +0100495 self._npn_advertise_callback = None
Cory Benfield0ea76e72015-03-22 09:05:28 +0000496 self._npn_select_helper = None
Cory Benfield84a121e2014-03-31 20:30:25 +0100497 self._npn_select_callback = None
Cory Benfieldf1177e72015-04-12 09:11:49 -0400498 self._alpn_select_helper = None
Cory Benfield12eae892014-06-07 15:42:56 +0100499 self._alpn_select_callback = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800500
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -0800501 # SSL_CTX_set_app_data(self->ctx, self);
502 # SSL_CTX_set_mode(self->ctx, SSL_MODE_ENABLE_PARTIAL_WRITE |
503 # SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
504 # SSL_MODE_AUTO_RETRY);
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500505 self.set_mode(_lib.SSL_MODE_ENABLE_PARTIAL_WRITE)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800506
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800507 def load_verify_locations(self, cafile, capath=None):
508 """
509 Let SSL know where we can find trusted certificates for the certificate
510 chain
511
Jean-Paul Calderone55f9e882015-04-12 09:31:03 -0400512 :param cafile: In which file we can find the certificates (``bytes`` or
513 ``unicode``).
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800514 :param capath: In which directory we can find the certificates
Jean-Paul Calderone55f9e882015-04-12 09:31:03 -0400515 (``bytes`` or ``unicode``).
516
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800517 :return: None
518 """
519 if cafile is None:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500520 cafile = _ffi.NULL
Jean-Paul Calderone55f9e882015-04-12 09:31:03 -0400521 else:
522 cafile = _path_string(cafile)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800523
524 if capath is None:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500525 capath = _ffi.NULL
Jean-Paul Calderone55f9e882015-04-12 09:31:03 -0400526 else:
527 capath = _path_string(capath)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800528
Alex Gaynor62da94d2015-09-05 14:37:34 -0400529 load_result = _lib.SSL_CTX_load_verify_locations(
530 self._context, cafile, capath
531 )
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800532 if not load_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500533 _raise_current_error()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800534
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800535 def _wrap_callback(self, callback):
536 @wraps(callback)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800537 def wrapper(size, verify, userdata):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800538 return callback(size, verify, self._passphrase_userdata)
539 return _PassphraseHelper(
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800540 FILETYPE_PEM, wrapper, more_args=True, truncate=True)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800541
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800542 def set_passwd_cb(self, callback, userdata=None):
543 """
544 Set the passphrase callback
545
546 :param callback: The Python callback to use
547 :param userdata: (optional) A Python object which will be given as
548 argument to the callback
549 :return: None
550 """
551 if not callable(callback):
552 raise TypeError("callback must be callable")
553
554 self._passphrase_helper = self._wrap_callback(callback)
555 self._passphrase_callback = self._passphrase_helper.callback
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500556 _lib.SSL_CTX_set_default_passwd_cb(
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800557 self._context, self._passphrase_callback)
558 self._passphrase_userdata = userdata
559
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800560 def set_default_verify_paths(self):
561 """
562 Use the platform-specific CA certificate locations
563
564 :return: None
565 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500566 set_result = _lib.SSL_CTX_set_default_verify_paths(self._context)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800567 if not set_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500568 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500569 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800570
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800571 def use_certificate_chain_file(self, certfile):
572 """
573 Load a certificate chain from a file
574
Jean-Paul Calderoneb6f8a792015-04-13 10:10:06 -0400575 :param certfile: The name of the certificate chain file (``bytes`` or
576 ``unicode``).
577
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800578 :return: None
579 """
Jean-Paul Calderoneaac43a32015-04-12 09:51:21 -0400580 certfile = _path_string(certfile)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800581
Alex Gaynor62da94d2015-09-05 14:37:34 -0400582 result = _lib.SSL_CTX_use_certificate_chain_file(
583 self._context, certfile
584 )
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800585 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500586 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800587
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800588 def use_certificate_file(self, certfile, filetype=FILETYPE_PEM):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800589 """
590 Load a certificate from a file
591
Jean-Paul Calderoneb6f8a792015-04-13 10:10:06 -0400592 :param certfile: The name of the certificate file (``bytes`` or
593 ``unicode``).
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800594 :param filetype: (optional) The encoding of the file, default is PEM
Jean-Paul Calderoneb6f8a792015-04-13 10:10:06 -0400595
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800596 :return: None
597 """
Jean-Paul Calderoned57a7b62015-04-12 09:57:36 -0400598 certfile = _path_string(certfile)
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -0500599 if not isinstance(filetype, integer_types):
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800600 raise TypeError("filetype must be an integer")
601
Alex Gaynor62da94d2015-09-05 14:37:34 -0400602 use_result = _lib.SSL_CTX_use_certificate_file(
603 self._context, certfile, filetype
604 )
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800605 if not use_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500606 _raise_current_error()
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800607
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800608 def use_certificate(self, cert):
609 """
610 Load a certificate from a X509 object
611
612 :param cert: The X509 object
613 :return: None
614 """
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800615 if not isinstance(cert, X509):
616 raise TypeError("cert must be an X509 instance")
617
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500618 use_result = _lib.SSL_CTX_use_certificate(self._context, cert._x509)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800619 if not use_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500620 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800621
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800622 def add_extra_chain_cert(self, certobj):
623 """
624 Add certificate to chain
625
626 :param certobj: The X509 certificate object to add to the chain
627 :return: None
628 """
629 if not isinstance(certobj, X509):
630 raise TypeError("certobj must be an X509 instance")
631
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500632 copy = _lib.X509_dup(certobj._x509)
633 add_result = _lib.SSL_CTX_add_extra_chain_cert(self._context, copy)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800634 if not add_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500635 # TODO: This is untested.
636 _lib.X509_free(copy)
637 _raise_current_error()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800638
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800639 def _raise_passphrase_exception(self):
640 if self._passphrase_helper is None:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500641 _raise_current_error()
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800642 exception = self._passphrase_helper.raise_if_problem(Error)
643 if exception is not None:
644 raise exception
645
Jean-Paul Calderone00f84eb2015-04-13 12:47:21 -0400646 def use_privatekey_file(self, keyfile, filetype=_UNSPECIFIED):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800647 """
648 Load a private key from a file
649
Jean-Paul Calderoneb6f8a792015-04-13 10:10:06 -0400650 :param keyfile: The name of the key file (``bytes`` or ``unicode``)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800651 :param filetype: (optional) The encoding of the file, default is PEM
Jean-Paul Calderoneb6f8a792015-04-13 10:10:06 -0400652
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800653 :return: None
654 """
Jean-Paul Calderone69a4e5b2015-04-12 10:04:28 -0400655 keyfile = _path_string(keyfile)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800656
Jean-Paul Calderone00f84eb2015-04-13 12:47:21 -0400657 if filetype is _UNSPECIFIED:
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800658 filetype = FILETYPE_PEM
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -0500659 elif not isinstance(filetype, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800660 raise TypeError("filetype must be an integer")
661
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500662 use_result = _lib.SSL_CTX_use_PrivateKey_file(
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800663 self._context, keyfile, filetype)
664 if not use_result:
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800665 self._raise_passphrase_exception()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800666
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800667 def use_privatekey(self, pkey):
668 """
669 Load a private key from a PKey object
670
671 :param pkey: The PKey object
672 :return: None
673 """
674 if not isinstance(pkey, PKey):
675 raise TypeError("pkey must be a PKey instance")
676
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500677 use_result = _lib.SSL_CTX_use_PrivateKey(self._context, pkey._pkey)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800678 if not use_result:
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800679 self._raise_passphrase_exception()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800680
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800681 def check_privatekey(self):
682 """
683 Check that the private key and certificate match up
684
685 :return: None (raises an exception if something's wrong)
686 """
Jean-Paul Calderonea0344922014-12-11 14:02:31 -0500687 if not _lib.SSL_CTX_check_private_key(self._context):
688 _raise_current_error()
689
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800690 def load_client_ca(self, cafile):
691 """
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +0100692 Load the trusted certificates that will be sent to the client. Does
693 not actually imply any of the certificates are trusted; that must be
Alex Gaynor62da94d2015-09-05 14:37:34 -0400694 configured separately.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800695
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +0100696 :param bytes cafile: The path to a certificates file in PEM format.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800697 :return: None
698 """
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +0100699 ca_list = _lib.SSL_load_client_CA_file(
700 _text_to_bytes_and_warn("cafile", cafile)
701 )
702 _openssl_assert(ca_list != _ffi.NULL)
703 # SSL_CTX_set_client_CA_list doesn't return anything.
704 _lib.SSL_CTX_set_client_CA_list(self._context, ca_list)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800705
706 def set_session_id(self, buf):
707 """
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +0100708 Set the session id to *buf* within which a session can be reused for
709 this Context object. This is needed when doing session resumption,
710 because there is no way for a stored session to know which Context
711 object it is associated with.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800712
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +0100713 :param bytes buf: The session id.
714
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800715 :returns: None
716 """
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +0100717 buf = _text_to_bytes_and_warn("buf", buf)
718 _openssl_assert(
719 _lib.SSL_CTX_set_session_id_context(
720 self._context,
721 buf,
722 len(buf),
723 ) == 1
724 )
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800725
726 def set_session_cache_mode(self, mode):
727 """
728 Enable/disable session caching and specify the mode used.
729
730 :param mode: One or more of the SESS_CACHE_* flags (combine using
731 bitwise or)
732 :returns: The previously set caching mode.
733 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500734 if not isinstance(mode, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800735 raise TypeError("mode must be an integer")
736
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500737 return _lib.SSL_CTX_set_session_cache_mode(self._context, mode)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800738
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800739 def get_session_cache_mode(self):
740 """
741 :returns: The currently used cache mode.
742 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500743 return _lib.SSL_CTX_get_session_cache_mode(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800744
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800745 def set_verify(self, mode, callback):
746 """
747 Set the verify mode and verify callback
748
749 :param mode: The verify mode, this is either VERIFY_NONE or
750 VERIFY_PEER combined with possible other flags
751 :param callback: The Python callback to use
752 :return: None
753
754 See SSL_CTX_set_verify(3SSL) for further details.
755 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500756 if not isinstance(mode, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800757 raise TypeError("mode must be an integer")
758
759 if not callable(callback):
760 raise TypeError("callback must be callable")
761
Jean-Paul Calderone6a8cd112014-04-02 21:09:08 -0400762 self._verify_helper = _VerifyHelper(callback)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800763 self._verify_callback = self._verify_helper.callback
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500764 _lib.SSL_CTX_set_verify(self._context, mode, self._verify_callback)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800765
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800766 def set_verify_depth(self, depth):
767 """
768 Set the verify depth
769
770 :param depth: An integer specifying the verify depth
771 :return: None
772 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500773 if not isinstance(depth, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800774 raise TypeError("depth must be an integer")
775
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500776 _lib.SSL_CTX_set_verify_depth(self._context, depth)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800777
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800778 def get_verify_mode(self):
779 """
780 Get the verify mode
781
782 :return: The verify mode
783 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500784 return _lib.SSL_CTX_get_verify_mode(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800785
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800786 def get_verify_depth(self):
787 """
788 Get the verify depth
789
790 :return: The verify depth
791 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500792 return _lib.SSL_CTX_get_verify_depth(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800793
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800794 def load_tmp_dh(self, dhfile):
795 """
796 Load parameters for Ephemeral Diffie-Hellman
797
Jean-Paul Calderone4e0c43f2015-04-13 10:15:17 -0400798 :param dhfile: The file to load EDH parameters from (``bytes`` or
799 ``unicode``).
800
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800801 :return: None
802 """
Jean-Paul Calderone9e1c1dd2015-04-12 10:13:13 -0400803 dhfile = _path_string(dhfile)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800804
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -0500805 bio = _lib.BIO_new_file(dhfile, b"r")
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500806 if bio == _ffi.NULL:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500807 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500808 bio = _ffi.gc(bio, _lib.BIO_free)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800809
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500810 dh = _lib.PEM_read_bio_DHparams(bio, _ffi.NULL, _ffi.NULL, _ffi.NULL)
811 dh = _ffi.gc(dh, _lib.DH_free)
812 _lib.SSL_CTX_set_tmp_dh(self._context, dh)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800813
Jean-Paul Calderone3e4e3352014-04-19 09:28:28 -0400814 def set_tmp_ecdh(self, curve):
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600815 """
Andy Lutomirski76a61332014-03-12 15:02:56 -0700816 Select a curve to use for ECDHE key exchange.
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600817
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -0400818 :param curve: A curve object to use as returned by either
819 :py:meth:`OpenSSL.crypto.get_elliptic_curve` or
820 :py:meth:`OpenSSL.crypto.get_elliptic_curves`.
Andy Lutomirskif05a2732014-03-13 17:22:25 -0700821
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600822 :return: None
823 """
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -0400824 _lib.SSL_CTX_set_tmp_ecdh(self._context, curve._to_EC_KEY())
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600825
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800826 def set_cipher_list(self, cipher_list):
827 """
Hynek Schlawackf90e3682016-03-11 11:21:13 +0100828 Set the list of ciphers to be used in this context.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800829
Hynek Schlawackf90e3682016-03-11 11:21:13 +0100830 See the OpenSSL manual for more information (e.g.
831 :manpage:`ciphers(1)`).
832
833 :param bytes cipher_list: An OpenSSL cipher string.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800834 :return: None
835 """
Hynek Schlawackf90e3682016-03-11 11:21:13 +0100836 cipher_list = _text_to_bytes_and_warn("cipher_list", cipher_list)
Jean-Paul Calderone63eab692014-01-18 10:19:56 -0500837
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800838 if not isinstance(cipher_list, bytes):
Hynek Schlawacka7a63af2016-03-11 12:05:26 +0100839 raise TypeError("cipher_list must be a byte string.")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800840
Hynek Schlawackf90e3682016-03-11 11:21:13 +0100841 _openssl_assert(
Hynek Schlawack22a4b662016-03-11 14:59:39 +0100842 _lib.SSL_CTX_set_cipher_list(self._context, cipher_list) == 1
Hynek Schlawackf90e3682016-03-11 11:21:13 +0100843 )
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800844
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800845 def set_client_ca_list(self, certificate_authorities):
846 """
Alex Gaynor62da94d2015-09-05 14:37:34 -0400847 Set the list of preferred client certificate signers for this server
848 context.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800849
Alex Gaynor62da94d2015-09-05 14:37:34 -0400850 This list of certificate authorities will be sent to the client when
851 the server requests a client certificate.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800852
853 :param certificate_authorities: a sequence of X509Names.
854 :return: None
855 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500856 name_stack = _lib.sk_X509_NAME_new_null()
857 if name_stack == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500858 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500859 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800860
861 try:
862 for ca_name in certificate_authorities:
863 if not isinstance(ca_name, X509Name):
864 raise TypeError(
Alex Gaynor62da94d2015-09-05 14:37:34 -0400865 "client CAs must be X509Name objects, not %s "
866 "objects" % (
867 type(ca_name).__name__,
868 )
869 )
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500870 copy = _lib.X509_NAME_dup(ca_name._name)
871 if copy == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500872 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500873 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500874 push_result = _lib.sk_X509_NAME_push(name_stack, copy)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800875 if not push_result:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500876 _lib.X509_NAME_free(copy)
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500877 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800878 except:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500879 _lib.sk_X509_NAME_free(name_stack)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800880 raise
881
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500882 _lib.SSL_CTX_set_client_CA_list(self._context, name_stack)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800883
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800884 def add_client_ca(self, certificate_authority):
885 """
Alex Gaynor62da94d2015-09-05 14:37:34 -0400886 Add the CA certificate to the list of preferred signers for this
887 context.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800888
889 The list of certificate authorities will be sent to the client when the
890 server requests a client certificate.
891
892 :param certificate_authority: certificate authority's X509 certificate.
893 :return: None
894 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800895 if not isinstance(certificate_authority, X509):
896 raise TypeError("certificate_authority must be an X509 instance")
897
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500898 add_result = _lib.SSL_CTX_add_client_CA(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800899 self._context, certificate_authority._x509)
900 if not add_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500901 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500902 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800903
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800904 def set_timeout(self, timeout):
905 """
906 Set session timeout
907
908 :param timeout: The timeout in seconds
909 :return: The previous session timeout
910 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500911 if not isinstance(timeout, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800912 raise TypeError("timeout must be an integer")
913
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500914 return _lib.SSL_CTX_set_timeout(self._context, timeout)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800915
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800916 def get_timeout(self):
917 """
918 Get the session timeout
919
920 :return: The session timeout
921 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500922 return _lib.SSL_CTX_get_timeout(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800923
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800924 def set_info_callback(self, callback):
925 """
926 Set the info callback
927
928 :param callback: The Python callback to use
929 :return: None
930 """
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800931 @wraps(callback)
932 def wrapper(ssl, where, return_code):
Jean-Paul Calderonef2bbc9c2014-02-02 10:59:14 -0500933 callback(Connection._reverse_mapping[ssl], where, return_code)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500934 self._info_callback = _ffi.callback(
935 "void (*)(const SSL *, int, int)", wrapper)
936 _lib.SSL_CTX_set_info_callback(self._context, self._info_callback)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800937
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800938 def get_app_data(self):
939 """
940 Get the application data (supplied via set_app_data())
941
942 :return: The application data
943 """
944 return self._app_data
945
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800946 def set_app_data(self, data):
947 """
948 Set the application data (will be returned from get_app_data())
949
950 :param data: Any Python object
951 :return: None
952 """
953 self._app_data = data
954
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800955 def get_cert_store(self):
956 """
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500957 Get the certificate store for the context.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800958
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500959 :return: A X509Store object or None if it does not have one.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800960 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500961 store = _lib.SSL_CTX_get_cert_store(self._context)
962 if store == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500963 # TODO: This is untested.
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800964 return None
965
966 pystore = X509Store.__new__(X509Store)
967 pystore._store = store
968 return pystore
969
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800970 def set_options(self, options):
971 """
972 Add options. Options set before are not cleared!
973
974 :param options: The options to add.
975 :return: The new option bitmask.
976 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500977 if not isinstance(options, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800978 raise TypeError("options must be an integer")
979
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500980 return _lib.SSL_CTX_set_options(self._context, options)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800981
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800982 def set_mode(self, mode):
983 """
984 Add modes via bitmask. Modes set before are not cleared!
985
986 :param mode: The mode to add.
987 :return: The new mode bitmask.
988 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500989 if not isinstance(mode, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800990 raise TypeError("mode must be an integer")
991
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500992 return _lib.SSL_CTX_set_mode(self._context, mode)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800993
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800994 def set_tlsext_servername_callback(self, callback):
995 """
Alex Gaynor62da94d2015-09-05 14:37:34 -0400996 Specify a callback function to be called when clients specify a server
997 name.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800998
999 :param callback: The callback function. It will be invoked with one
1000 argument, the Connection instance.
1001 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001002 @wraps(callback)
1003 def wrapper(ssl, alert, arg):
1004 callback(Connection._reverse_mapping[ssl])
1005 return 0
1006
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001007 self._tlsext_servername_callback = _ffi.callback(
1008 "int (*)(const SSL *, int *, void *)", wrapper)
1009 _lib.SSL_CTX_set_tlsext_servername_callback(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001010 self._context, self._tlsext_servername_callback)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -08001011
Cory Benfield10b277f2015-04-13 17:12:42 -04001012 @_requires_npn
Cory Benfield84a121e2014-03-31 20:30:25 +01001013 def set_npn_advertise_callback(self, callback):
1014 """
Cory Benfieldbe3e7b82014-05-10 09:48:55 +01001015 Specify a callback function that will be called when offering `Next
1016 Protocol Negotiation
1017 <https://technotes.googlecode.com/git/nextprotoneg.html>`_ as a server.
Cory Benfield84a121e2014-03-31 20:30:25 +01001018
1019 :param callback: The callback function. It will be invoked with one
Cory Benfieldbe3e7b82014-05-10 09:48:55 +01001020 argument, the Connection instance. It should return a list of
1021 bytestrings representing the advertised protocols, like
1022 ``[b'http/1.1', b'spdy/2']``.
Cory Benfield84a121e2014-03-31 20:30:25 +01001023 """
Cory Benfield0ea76e72015-03-22 09:05:28 +00001024 self._npn_advertise_helper = _NpnAdvertiseHelper(callback)
1025 self._npn_advertise_callback = self._npn_advertise_helper.callback
Cory Benfield84a121e2014-03-31 20:30:25 +01001026 _lib.SSL_CTX_set_next_protos_advertised_cb(
1027 self._context, self._npn_advertise_callback, _ffi.NULL)
1028
Cory Benfield10b277f2015-04-13 17:12:42 -04001029 @_requires_npn
Cory Benfield84a121e2014-03-31 20:30:25 +01001030 def set_npn_select_callback(self, callback):
1031 """
1032 Specify a callback function that will be called when a server offers
1033 Next Protocol Negotiation options.
1034
1035 :param callback: The callback function. It will be invoked with two
1036 arguments: the Connection, and a list of offered protocols as
Cory Benfieldbe3e7b82014-05-10 09:48:55 +01001037 bytestrings, e.g. ``[b'http/1.1', b'spdy/2']``. It should return
1038 one of those bytestrings, the chosen protocol.
Cory Benfield84a121e2014-03-31 20:30:25 +01001039 """
Cory Benfield0ea76e72015-03-22 09:05:28 +00001040 self._npn_select_helper = _NpnSelectHelper(callback)
1041 self._npn_select_callback = self._npn_select_helper.callback
Cory Benfield84a121e2014-03-31 20:30:25 +01001042 _lib.SSL_CTX_set_next_proto_select_cb(
1043 self._context, self._npn_select_callback, _ffi.NULL)
1044
Cory Benfield7907e332015-04-13 17:18:25 -04001045 @_requires_alpn
Cory Benfield12eae892014-06-07 15:42:56 +01001046 def set_alpn_protos(self, protos):
1047 """
Cory Benfielde8e9c382015-04-11 17:33:48 -04001048 Specify the clients ALPN protocol list.
1049
1050 These protocols are offered to the server during protocol negotiation.
Cory Benfield12eae892014-06-07 15:42:56 +01001051
1052 :param protos: A list of the protocols to be offered to the server.
1053 This list should be a Python list of bytestrings representing the
1054 protocols to offer, e.g. ``[b'http/1.1', b'spdy/2']``.
1055 """
1056 # Take the list of protocols and join them together, prefixing them
1057 # with their lengths.
1058 protostr = b''.join(
1059 chain.from_iterable((int2byte(len(p)), p) for p in protos)
1060 )
1061
1062 # Build a C string from the list. We don't need to save this off
1063 # because OpenSSL immediately copies the data out.
1064 input_str = _ffi.new("unsigned char[]", protostr)
Cory Benfielde871af52015-04-11 17:57:50 -04001065 input_str_len = _ffi.cast("unsigned", len(protostr))
1066 _lib.SSL_CTX_set_alpn_protos(self._context, input_str, input_str_len)
Cory Benfield12eae892014-06-07 15:42:56 +01001067
Cory Benfield7907e332015-04-13 17:18:25 -04001068 @_requires_alpn
Cory Benfield12eae892014-06-07 15:42:56 +01001069 def set_alpn_select_callback(self, callback):
1070 """
Cory Benfielde8e9c382015-04-11 17:33:48 -04001071 Set the callback to handle ALPN protocol choice.
Cory Benfield12eae892014-06-07 15:42:56 +01001072
1073 :param callback: The callback function. It will be invoked with two
1074 arguments: the Connection, and a list of offered protocols as
1075 bytestrings, e.g ``[b'http/1.1', b'spdy/2']``. It should return
Cory Benfielde8e9c382015-04-11 17:33:48 -04001076 one of those bytestrings, the chosen protocol.
Cory Benfield12eae892014-06-07 15:42:56 +01001077 """
Cory Benfield9da5ffb2015-04-13 17:20:14 -04001078 self._alpn_select_helper = _ALPNSelectHelper(callback)
Cory Benfieldf1177e72015-04-12 09:11:49 -04001079 self._alpn_select_callback = self._alpn_select_helper.callback
Cory Benfield12eae892014-06-07 15:42:56 +01001080 _lib.SSL_CTX_set_alpn_select_cb(
1081 self._context, self._alpn_select_callback, _ffi.NULL)
1082
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -08001083ContextType = Context
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001084
1085
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001086class Connection(object):
1087 """
1088 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001089 _reverse_mapping = WeakValueDictionary()
1090
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001091 def __init__(self, context, socket=None):
1092 """
1093 Create a new Connection object, using the given OpenSSL.SSL.Context
1094 instance and socket.
1095
1096 :param context: An SSL Context to use for this connection
1097 :param socket: The socket to use for transport layer
1098 """
1099 if not isinstance(context, Context):
1100 raise TypeError("context must be a Context instance")
1101
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001102 ssl = _lib.SSL_new(context._context)
1103 self._ssl = _ffi.gc(ssl, _lib.SSL_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001104 self._context = context
Todd Chapman4f73e4f2015-08-27 11:26:43 -04001105 self._app_data = None
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001106
Cory Benfieldbe3e7b82014-05-10 09:48:55 +01001107 # References to strings used for Next Protocol Negotiation. OpenSSL's
1108 # header files suggest that these might get copied at some point, but
1109 # doesn't specify when, so we store them here to make sure they don't
1110 # get freed before OpenSSL uses them.
1111 self._npn_advertise_callback_args = None
1112 self._npn_select_callback_args = None
1113
Cory Benfield12eae892014-06-07 15:42:56 +01001114 # References to strings used for Application Layer Protocol
1115 # Negotiation. These strings get copied at some point but it's well
1116 # after the callback returns, so we have to hang them somewhere to
1117 # avoid them getting freed.
1118 self._alpn_select_callback_args = None
1119
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001120 self._reverse_mapping[self._ssl] = self
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001121
1122 if socket is None:
1123 self._socket = None
Jean-Paul Calderone73b15c22013-03-05 18:30:39 -08001124 # Don't set up any gc for these, SSL_free will take care of them.
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001125 self._into_ssl = _lib.BIO_new(_lib.BIO_s_mem())
1126 self._from_ssl = _lib.BIO_new(_lib.BIO_s_mem())
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001127
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001128 if self._into_ssl == _ffi.NULL or self._from_ssl == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001129 # TODO: This is untested.
1130 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001131
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001132 _lib.SSL_set_bio(self._ssl, self._into_ssl, self._from_ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001133 else:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001134 self._into_ssl = None
1135 self._from_ssl = None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001136 self._socket = socket
Alex Gaynor62da94d2015-09-05 14:37:34 -04001137 set_result = _lib.SSL_set_fd(
1138 self._ssl, _asFileDescriptor(self._socket))
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001139 if not set_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001140 # TODO: This is untested.
1141 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001142
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001143 def __getattr__(self, name):
1144 """
Alex Gaynor62da94d2015-09-05 14:37:34 -04001145 Look up attributes on the wrapped socket object if they are not found
1146 on the Connection object.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001147 """
kjav0b66fa12015-09-02 11:51:26 +01001148 if self._socket is None:
Alex Gaynor62da94d2015-09-05 14:37:34 -04001149 raise AttributeError("'%s' object has no attribute '%s'" % (
1150 self.__class__.__name__, name
1151 ))
kjav0b66fa12015-09-02 11:51:26 +01001152 else:
1153 return getattr(self._socket, name)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001154
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001155 def _raise_ssl_error(self, ssl, result):
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -08001156 if self._context._verify_helper is not None:
1157 self._context._verify_helper.raise_if_problem()
Cory Benfield0ea76e72015-03-22 09:05:28 +00001158 if self._context._npn_advertise_helper is not None:
1159 self._context._npn_advertise_helper.raise_if_problem()
1160 if self._context._npn_select_helper is not None:
1161 self._context._npn_select_helper.raise_if_problem()
Cory Benfieldf1177e72015-04-12 09:11:49 -04001162 if self._context._alpn_select_helper is not None:
1163 self._context._alpn_select_helper.raise_if_problem()
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -08001164
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001165 error = _lib.SSL_get_error(ssl, result)
1166 if error == _lib.SSL_ERROR_WANT_READ:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001167 raise WantReadError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001168 elif error == _lib.SSL_ERROR_WANT_WRITE:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001169 raise WantWriteError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001170 elif error == _lib.SSL_ERROR_ZERO_RETURN:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001171 raise ZeroReturnError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001172 elif error == _lib.SSL_ERROR_WANT_X509_LOOKUP:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001173 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001174 raise WantX509LookupError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001175 elif error == _lib.SSL_ERROR_SYSCALL:
1176 if _lib.ERR_peek_error() == 0:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001177 if result < 0:
Konstantinos Koukopoulos541150d2014-01-31 01:00:19 +02001178 if platform == "win32":
1179 errno = _ffi.getwinerror()[0]
1180 else:
1181 errno = _ffi.errno
Glyph3afdba82015-04-14 17:30:53 -04001182 raise SysCallError(errno, errorcode.get(errno))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001183 else:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001184 raise SysCallError(-1, "Unexpected EOF")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001185 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001186 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001187 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001188 elif error == _lib.SSL_ERROR_NONE:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001189 pass
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001190 else:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001191 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001192
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001193 def get_context(self):
1194 """
1195 Get session context
1196 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001197 return self._context
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001198
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001199 def set_context(self, context):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001200 """
1201 Switch this connection to a new session context
1202
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001203 :param context: A :py:class:`Context` instance giving the new session
1204 context to use.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001205 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001206 if not isinstance(context, Context):
1207 raise TypeError("context must be a Context instance")
1208
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001209 _lib.SSL_set_SSL_CTX(self._ssl, context._context)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001210 self._context = context
1211
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001212 def get_servername(self):
1213 """
1214 Retrieve the servername extension value if provided in the client hello
1215 message, or None if there wasn't one.
1216
1217 :return: A byte string giving the server name or :py:data:`None`.
1218 """
Alex Gaynor62da94d2015-09-05 14:37:34 -04001219 name = _lib.SSL_get_servername(
1220 self._ssl, _lib.TLSEXT_NAMETYPE_host_name
1221 )
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001222 if name == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001223 return None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001224
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001225 return _ffi.string(name)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001226
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001227 def set_tlsext_host_name(self, name):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001228 """
1229 Set the value of the servername extension to send in the client hello.
1230
1231 :param name: A byte string giving the name.
1232 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001233 if not isinstance(name, bytes):
1234 raise TypeError("name must be a byte string")
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001235 elif b"\0" in name:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001236 raise TypeError("name must not contain NUL byte")
1237
1238 # XXX I guess this can fail sometimes?
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001239 _lib.SSL_set_tlsext_host_name(self._ssl, name)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001240
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001241 def pending(self):
1242 """
1243 Get the number of bytes that can be safely read from the connection
1244
1245 :return: The number of bytes available in the receive buffer.
1246 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001247 return _lib.SSL_pending(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001248
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001249 def send(self, buf, flags=0):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001250 """
1251 Send data on the connection. NOTE: If you get one of the WantRead,
1252 WantWrite or WantX509Lookup exceptions on this, you have to call the
1253 method again with the SAME buffer.
1254
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001255 :param buf: The string, buffer or memoryview to send
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001256 :param flags: (optional) Included for compatibility with the socket
1257 API, the value is ignored
1258 :return: The number of bytes written
1259 """
Abraham Martine82326c2015-02-04 10:18:10 +00001260 # Backward compatibility
Jean-Paul Calderone39a8d592015-04-13 20:49:50 -04001261 buf = _text_to_bytes_and_warn("buf", buf)
Abraham Martine82326c2015-02-04 10:18:10 +00001262
Jean-Paul Calderone8fb53182013-12-30 08:35:49 -05001263 if isinstance(buf, _memoryview):
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -08001264 buf = buf.tobytes()
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001265 if isinstance(buf, _buffer):
1266 buf = str(buf)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001267 if not isinstance(buf, bytes):
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001268 raise TypeError("data must be a memoryview, buffer or byte string")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001269
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001270 result = _lib.SSL_write(self._ssl, buf, len(buf))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001271 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001272 return result
1273 write = send
1274
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001275 def sendall(self, buf, flags=0):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001276 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001277 Send "all" data on the connection. This calls send() repeatedly until
1278 all data is sent. If an error occurs, it's impossible to tell how much
1279 data has been sent.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001280
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001281 :param buf: The string, buffer or memoryview to send
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001282 :param flags: (optional) Included for compatibility with the socket
1283 API, the value is ignored
1284 :return: The number of bytes written
1285 """
Jean-Paul Calderone39a8d592015-04-13 20:49:50 -04001286 buf = _text_to_bytes_and_warn("buf", buf)
Abraham Martine82326c2015-02-04 10:18:10 +00001287
Jean-Paul Calderone8fb53182013-12-30 08:35:49 -05001288 if isinstance(buf, _memoryview):
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -08001289 buf = buf.tobytes()
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001290 if isinstance(buf, _buffer):
1291 buf = str(buf)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001292 if not isinstance(buf, bytes):
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001293 raise TypeError("buf must be a memoryview, buffer or byte string")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001294
1295 left_to_send = len(buf)
1296 total_sent = 0
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001297 data = _ffi.new("char[]", buf)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001298
1299 while left_to_send:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001300 result = _lib.SSL_write(self._ssl, data + total_sent, left_to_send)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001301 self._raise_ssl_error(self._ssl, result)
1302 total_sent += result
1303 left_to_send -= result
1304
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001305 def recv(self, bufsiz, flags=None):
1306 """
1307 Receive data on the connection. NOTE: If you get one of the WantRead,
1308 WantWrite or WantX509Lookup exceptions on this, you have to call the
1309 method again with the SAME buffer.
1310
1311 :param bufsiz: The maximum number of bytes to read
Maximilian Hils1d95dea2015-08-17 19:27:20 +02001312 :param flags: (optional) The only supported flag is ``MSG_PEEK``,
1313 all other flags are ignored.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001314 :return: The string read from the Connection
1315 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001316 buf = _ffi.new("char[]", bufsiz)
Maximilian Hils1d95dea2015-08-17 19:27:20 +02001317 if flags is not None and flags & socket.MSG_PEEK:
1318 result = _lib.SSL_peek(self._ssl, buf, bufsiz)
1319 else:
1320 result = _lib.SSL_read(self._ssl, buf, bufsiz)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001321 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001322 return _ffi.buffer(buf, result)[:]
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001323 read = recv
1324
Cory Benfield62d10332014-06-15 10:03:41 +01001325 def recv_into(self, buffer, nbytes=None, flags=None):
1326 """
1327 Receive data on the connection and store the data into a buffer rather
1328 than creating a new string.
1329
1330 :param buffer: The buffer to copy into.
1331 :param nbytes: (optional) The maximum number of bytes to read into the
1332 buffer. If not present, defaults to the size of the buffer. If
1333 larger than the size of the buffer, is reduced to the size of the
1334 buffer.
Maximilian Hils1d95dea2015-08-17 19:27:20 +02001335 :param flags: (optional) The only supported flag is ``MSG_PEEK``,
1336 all other flags are ignored.
Cory Benfield62d10332014-06-15 10:03:41 +01001337 :return: The number of bytes read into the buffer.
1338 """
1339 if nbytes is None:
1340 nbytes = len(buffer)
1341 else:
1342 nbytes = min(nbytes, len(buffer))
1343
1344 # We need to create a temporary buffer. This is annoying, it would be
1345 # better if we could pass memoryviews straight into the SSL_read call,
1346 # but right now we can't. Revisit this if CFFI gets that ability.
1347 buf = _ffi.new("char[]", nbytes)
Maximilian Hils1d95dea2015-08-17 19:27:20 +02001348 if flags is not None and flags & socket.MSG_PEEK:
1349 result = _lib.SSL_peek(self._ssl, buf, nbytes)
1350 else:
1351 result = _lib.SSL_read(self._ssl, buf, nbytes)
Cory Benfield62d10332014-06-15 10:03:41 +01001352 self._raise_ssl_error(self._ssl, result)
1353
1354 # This strange line is all to avoid a memory copy. The buffer protocol
1355 # should allow us to assign a CFFI buffer to the LHS of this line, but
1356 # on CPython 3.3+ that segfaults. As a workaround, we can temporarily
1357 # wrap it in a memoryview, except on Python 2.6 which doesn't have a
1358 # memoryview type.
1359 try:
1360 buffer[:result] = memoryview(_ffi.buffer(buf, result))
1361 except NameError:
1362 buffer[:result] = _ffi.buffer(buf, result)
1363
1364 return result
1365
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001366 def _handle_bio_errors(self, bio, result):
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001367 if _lib.BIO_should_retry(bio):
1368 if _lib.BIO_should_read(bio):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001369 raise WantReadError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001370 elif _lib.BIO_should_write(bio):
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001371 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001372 raise WantWriteError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001373 elif _lib.BIO_should_io_special(bio):
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001374 # TODO: This is untested. I think io_special means the socket
1375 # BIO has a not-yet connected socket.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001376 raise ValueError("BIO_should_io_special")
1377 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001378 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001379 raise ValueError("unknown bio failure")
1380 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001381 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001382 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001383
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001384 def bio_read(self, bufsiz):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001385 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001386 When using non-socket connections this function reads the "dirty" data
1387 that would have traveled away on the network.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001388
1389 :param bufsiz: The maximum number of bytes to read
1390 :return: The string read.
1391 """
Jean-Paul Calderone97e041d2013-03-05 21:03:12 -08001392 if self._from_ssl is None:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001393 raise TypeError("Connection sock was not None")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001394
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -05001395 if not isinstance(bufsiz, integer_types):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001396 raise TypeError("bufsiz must be an integer")
1397
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001398 buf = _ffi.new("char[]", bufsiz)
1399 result = _lib.BIO_read(self._from_ssl, buf, bufsiz)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001400 if result <= 0:
1401 self._handle_bio_errors(self._from_ssl, result)
1402
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001403 return _ffi.buffer(buf, result)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001404
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001405 def bio_write(self, buf):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001406 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001407 When using non-socket connections this function sends "dirty" data that
1408 would have traveled in on the network.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001409
1410 :param buf: The string to put into the memory BIO.
1411 :return: The number of bytes written
1412 """
Jean-Paul Calderone39a8d592015-04-13 20:49:50 -04001413 buf = _text_to_bytes_and_warn("buf", buf)
Abraham Martine82326c2015-02-04 10:18:10 +00001414
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001415 if self._into_ssl is None:
1416 raise TypeError("Connection sock was not None")
1417
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001418 result = _lib.BIO_write(self._into_ssl, buf, len(buf))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001419 if result <= 0:
1420 self._handle_bio_errors(self._into_ssl, result)
1421 return result
1422
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001423 def renegotiate(self):
1424 """
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +01001425 Renegotiate the session.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001426
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +01001427 :return: True if the renegotiation can be started, False otherwise
1428 :rtype: bool
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001429 """
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +01001430 if not self.renegotiate_pending():
1431 _openssl_assert(_lib.SSL_renegotiate(self._ssl) == 1)
1432 return True
1433 return False
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001434
1435 def do_handshake(self):
1436 """
1437 Perform an SSL handshake (usually called after renegotiate() or one of
1438 set_*_state()). This can raise the same exceptions as send and recv.
1439
1440 :return: None.
1441 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001442 result = _lib.SSL_do_handshake(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001443 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001444
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001445 def renegotiate_pending(self):
1446 """
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +01001447 Check if there's a renegotiation in progress, it will return False once
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001448 a renegotiation is finished.
1449
1450 :return: Whether there's a renegotiation in progress
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +01001451 :rtype: bool
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001452 """
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +01001453 return _lib.SSL_renegotiate_pending(self._ssl) == 1
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001454
1455 def total_renegotiations(self):
1456 """
1457 Find out the total number of renegotiations.
1458
1459 :return: The number of renegotiations.
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +01001460 :rtype: int
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001461 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001462 return _lib.SSL_total_renegotiations(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001463
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001464 def connect(self, addr):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001465 """
1466 Connect to remote host and set up client-side SSL
1467
1468 :param addr: A remote address
1469 :return: What the socket's connect method returns
1470 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001471 _lib.SSL_set_connect_state(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001472 return self._socket.connect(addr)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001473
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001474 def connect_ex(self, addr):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001475 """
Alex Gaynor62da94d2015-09-05 14:37:34 -04001476 Connect to remote host and set up client-side SSL. Note that if the
1477 socket's connect_ex method doesn't return 0, SSL won't be initialized.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001478
1479 :param addr: A remove address
1480 :return: What the socket's connect_ex method returns
1481 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001482 connect_ex = self._socket.connect_ex
1483 self.set_connect_state()
1484 return connect_ex(addr)
1485
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001486 def accept(self):
1487 """
1488 Accept incoming connection and set up SSL on it
1489
1490 :return: A (conn,addr) pair where conn is a Connection and addr is an
1491 address
1492 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001493 client, addr = self._socket.accept()
1494 conn = Connection(self._context, client)
1495 conn.set_accept_state()
1496 return (conn, addr)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001497
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001498 def bio_shutdown(self):
1499 """
1500 When using non-socket connections this function signals end of
1501 data on the input for this connection.
1502
1503 :return: None
1504 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001505 if self._from_ssl is None:
1506 raise TypeError("Connection sock was not None")
1507
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001508 _lib.BIO_set_mem_eof_return(self._into_ssl, 0)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001509
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001510 def shutdown(self):
1511 """
1512 Send closure alert
1513
1514 :return: True if the shutdown completed successfully (i.e. both sides
1515 have sent closure alerts), false otherwise (i.e. you have to
1516 wait for a ZeroReturnError on a recv() method call
1517 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001518 result = _lib.SSL_shutdown(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001519 if result < 0:
Paul Aurichbff1d1a2015-01-08 08:36:53 -08001520 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001521 elif result > 0:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001522 return True
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001523 else:
1524 return False
1525
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001526 def get_cipher_list(self):
1527 """
Hynek Schlawackf90e3682016-03-11 11:21:13 +01001528 Retrieve the list of ciphers used by the Connection object.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001529
Hynek Schlawackf90e3682016-03-11 11:21:13 +01001530 :return: A list of native cipher strings.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001531 """
1532 ciphers = []
1533 for i in count():
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001534 result = _lib.SSL_get_cipher_list(self._ssl, i)
1535 if result == _ffi.NULL:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001536 break
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001537 ciphers.append(_native(_ffi.string(result)))
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001538 return ciphers
1539
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001540 def get_client_ca_list(self):
1541 """
1542 Get CAs whose certificates are suggested for client authentication.
1543
Alex Gaynor62da94d2015-09-05 14:37:34 -04001544 :return: If this is a server connection, a list of X509Names
1545 representing the acceptable CAs as set by
1546 :py:meth:`OpenSSL.SSL.Context.set_client_ca_list` or
1547 :py:meth:`OpenSSL.SSL.Context.add_client_ca`. If this is a client
1548 connection, the list of such X509Names sent by the server, or an
1549 empty list if that has not yet happened.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001550 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001551 ca_names = _lib.SSL_get_client_CA_list(self._ssl)
1552 if ca_names == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001553 # TODO: This is untested.
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001554 return []
1555
1556 result = []
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001557 for i in range(_lib.sk_X509_NAME_num(ca_names)):
1558 name = _lib.sk_X509_NAME_value(ca_names, i)
1559 copy = _lib.X509_NAME_dup(name)
1560 if copy == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001561 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001562 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001563
1564 pyname = X509Name.__new__(X509Name)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001565 pyname._name = _ffi.gc(copy, _lib.X509_NAME_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001566 result.append(pyname)
1567 return result
1568
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001569 def makefile(self):
1570 """
Alex Gaynor62da94d2015-09-05 14:37:34 -04001571 The makefile() method is not implemented, since there is no dup
1572 semantics for SSL connections
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001573
Jean-Paul Calderone6749ec22014-04-17 16:30:21 -04001574 :raise: NotImplementedError
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001575 """
Alex Gaynor83284952015-09-05 10:43:30 -04001576 raise NotImplementedError(
1577 "Cannot make file object of OpenSSL.SSL.Connection")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001578
1579 def get_app_data(self):
1580 """
1581 Get application data
1582
1583 :return: The application data
1584 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001585 return self._app_data
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001586
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001587 def set_app_data(self, data):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001588 """
1589 Set application data
1590
1591 :param data - The application data
1592 :return: None
1593 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001594 self._app_data = data
1595
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001596 def get_shutdown(self):
1597 """
1598 Get shutdown state
1599
Alex Gaynor62da94d2015-09-05 14:37:34 -04001600 :return: The shutdown state, a bitvector of SENT_SHUTDOWN,
1601 RECEIVED_SHUTDOWN.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001602 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001603 return _lib.SSL_get_shutdown(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001604
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001605 def set_shutdown(self, state):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001606 """
1607 Set shutdown state
1608
1609 :param state - bitvector of SENT_SHUTDOWN, RECEIVED_SHUTDOWN.
1610 :return: None
1611 """
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -05001612 if not isinstance(state, integer_types):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001613 raise TypeError("state must be an integer")
1614
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001615 _lib.SSL_set_shutdown(self._ssl, state)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001616
Hynek Schlawackea94f2b2016-03-13 16:17:53 +01001617 def get_state_string(self):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001618 """
Hynek Schlawackea94f2b2016-03-13 16:17:53 +01001619 Retrieve a verbose string detailing the state of the Connection.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001620
1621 :return: A string representing the state
Hynek Schlawackea94f2b2016-03-13 16:17:53 +01001622 :rtype: bytes
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001623 """
kjavc704a2e2015-09-07 12:12:27 +01001624 return _ffi.string(_lib.SSL_state_string_long(self._ssl))
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001625
1626 def server_random(self):
1627 """
1628 Get a copy of the server hello nonce.
1629
1630 :return: A string representing the state
1631 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001632 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001633 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001634 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001635 self._ssl.s3.server_random,
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001636 _lib.SSL3_RANDOM_SIZE)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001637
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001638 def client_random(self):
1639 """
1640 Get a copy of the client hello nonce.
1641
1642 :return: A string representing the state
1643 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001644 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001645 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001646 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001647 self._ssl.s3.client_random,
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001648 _lib.SSL3_RANDOM_SIZE)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001649
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001650 def master_key(self):
1651 """
1652 Get a copy of the master key.
1653
1654 :return: A string representing the state
1655 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001656 if self._ssl.session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001657 return None
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001658 return _ffi.buffer(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001659 self._ssl.session.master_key,
1660 self._ssl.session.master_key_length)[:]
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001661
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001662 def sock_shutdown(self, *args, **kwargs):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001663 """
1664 See shutdown(2)
1665
1666 :return: What the socket's shutdown() method returns
1667 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001668 return self._socket.shutdown(*args, **kwargs)
1669
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001670 def get_peer_certificate(self):
1671 """
1672 Retrieve the other side's certificate (if any)
1673
1674 :return: The peer's certificate
1675 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001676 cert = _lib.SSL_get_peer_certificate(self._ssl)
1677 if cert != _ffi.NULL:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001678 pycert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001679 pycert._x509 = _ffi.gc(cert, _lib.X509_free)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001680 return pycert
1681 return None
1682
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001683 def get_peer_cert_chain(self):
1684 """
1685 Retrieve the other side's certificate (if any)
1686
1687 :return: A list of X509 instances giving the peer's certificate chain,
1688 or None if it does not have one.
1689 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001690 cert_stack = _lib.SSL_get_peer_cert_chain(self._ssl)
1691 if cert_stack == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001692 return None
1693
1694 result = []
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001695 for i in range(_lib.sk_X509_num(cert_stack)):
Jean-Paul Calderone73b15c22013-03-05 18:30:39 -08001696 # TODO could incref instead of dup here
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001697 cert = _lib.X509_dup(_lib.sk_X509_value(cert_stack, i))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001698 pycert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001699 pycert._x509 = _ffi.gc(cert, _lib.X509_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001700 result.append(pycert)
1701 return result
1702
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001703 def want_read(self):
1704 """
Alex Gaynor62da94d2015-09-05 14:37:34 -04001705 Checks if more data has to be read from the transport layer to complete
1706 an operation.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001707
1708 :return: True iff more data has to be read
1709 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001710 return _lib.SSL_want_read(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001711
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001712 def want_write(self):
1713 """
1714 Checks if there is data to write to the transport layer to complete an
1715 operation.
1716
1717 :return: True iff there is data to write
1718 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001719 return _lib.SSL_want_write(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001720
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001721 def set_accept_state(self):
1722 """
Alex Gaynor62da94d2015-09-05 14:37:34 -04001723 Set the connection to work in server mode. The handshake will be
1724 handled automatically by read/write.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001725
1726 :return: None
1727 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001728 _lib.SSL_set_accept_state(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001729
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001730 def set_connect_state(self):
1731 """
Alex Gaynor62da94d2015-09-05 14:37:34 -04001732 Set the connection to work in client mode. The handshake will be
1733 handled automatically by read/write.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001734
1735 :return: None
1736 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001737 _lib.SSL_set_connect_state(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001738
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001739 def get_session(self):
1740 """
1741 Returns the Session currently used.
1742
Alex Gaynor62da94d2015-09-05 14:37:34 -04001743 @return: An instance of :py:class:`OpenSSL.SSL.Session` or
1744 :py:obj:`None` if no session exists.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001745 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001746 session = _lib.SSL_get1_session(self._ssl)
1747 if session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001748 return None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001749
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001750 pysession = Session.__new__(Session)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001751 pysession._session = _ffi.gc(session, _lib.SSL_SESSION_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001752 return pysession
1753
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001754 def set_session(self, session):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001755 """
1756 Set the session to be used when the TLS/SSL connection is established.
1757
1758 :param session: A Session instance representing the session to use.
1759 :returns: None
1760 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001761 if not isinstance(session, Session):
1762 raise TypeError("session must be a Session instance")
1763
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001764 result = _lib.SSL_set_session(self._ssl, session._session)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001765 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001766 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001767
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001768 def _get_finished_message(self, function):
1769 """
1770 Helper to implement :py:meth:`get_finished` and
1771 :py:meth:`get_peer_finished`.
1772
1773 :param function: Either :py:data:`SSL_get_finished`: or
1774 :py:data:`SSL_get_peer_finished`.
1775
1776 :return: :py:data:`None` if the desired message has not yet been
1777 received, otherwise the contents of the message.
1778 :rtype: :py:class:`bytes` or :py:class:`NoneType`
1779 """
Jean-Paul Calderone01af9042014-03-30 11:40:42 -04001780 # The OpenSSL documentation says nothing about what might happen if the
1781 # count argument given is zero. Specifically, it doesn't say whether
1782 # the output buffer may be NULL in that case or not. Inspection of the
1783 # implementation reveals that it calls memcpy() unconditionally.
1784 # Section 7.1.4, paragraph 1 of the C standard suggests that
1785 # memcpy(NULL, source, 0) is not guaranteed to produce defined (let
1786 # alone desirable) behavior (though it probably does on just about
1787 # every implementation...)
1788 #
1789 # Allocate a tiny buffer to pass in (instead of just passing NULL as
1790 # one might expect) for the initial call so as to be safe against this
1791 # potentially undefined behavior.
1792 empty = _ffi.new("char[]", 0)
1793 size = function(self._ssl, empty, 0)
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001794 if size == 0:
1795 # No Finished message so far.
1796 return None
1797
1798 buf = _ffi.new("char[]", size)
1799 function(self._ssl, buf, size)
1800 return _ffi.buffer(buf, size)[:]
1801
Fedor Brunner5747b932014-03-05 14:22:34 +01001802 def get_finished(self):
1803 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001804 Obtain the latest `handshake finished` message sent to the peer.
Fedor Brunner5747b932014-03-05 14:22:34 +01001805
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001806 :return: The contents of the message or :py:obj:`None` if the TLS
1807 handshake has not yet completed.
1808 :rtype: :py:class:`bytes` or :py:class:`NoneType`
Fedor Brunner5747b932014-03-05 14:22:34 +01001809 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001810 return self._get_finished_message(_lib.SSL_get_finished)
1811
Fedor Brunner5747b932014-03-05 14:22:34 +01001812 def get_peer_finished(self):
1813 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001814 Obtain the latest `handshake finished` message received from 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_peer_finished)
Fedor Brunner5747b932014-03-05 14:22:34 +01001821
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001822 def get_cipher_name(self):
1823 """
1824 Obtain the name of the currently used cipher.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001825
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001826 :returns: The name of the currently used cipher or :py:obj:`None`
1827 if no connection has been established.
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001828 :rtype: :py:class:`unicode` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001829 """
1830 cipher = _lib.SSL_get_current_cipher(self._ssl)
1831 if cipher == _ffi.NULL:
1832 return None
1833 else:
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001834 name = _ffi.string(_lib.SSL_CIPHER_get_name(cipher))
1835 return name.decode("utf-8")
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001836
1837 def get_cipher_bits(self):
1838 """
1839 Obtain the number of secret bits of the currently used cipher.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001840
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001841 :returns: The number of secret bits of the currently used cipher
1842 or :py:obj:`None` if no connection has been established.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001843 :rtype: :py:class:`int` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001844 """
1845 cipher = _lib.SSL_get_current_cipher(self._ssl)
1846 if cipher == _ffi.NULL:
1847 return None
1848 else:
1849 return _lib.SSL_CIPHER_get_bits(cipher, _ffi.NULL)
1850
1851 def get_cipher_version(self):
1852 """
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001853 Obtain the protocol version of the currently used cipher.
1854
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001855 :returns: The protocol name of the currently used cipher
1856 or :py:obj:`None` if no connection has been established.
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001857 :rtype: :py:class:`unicode` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001858 """
1859 cipher = _lib.SSL_get_current_cipher(self._ssl)
1860 if cipher == _ffi.NULL:
1861 return None
1862 else:
Alex Gaynorc4889812015-09-04 08:43:17 -04001863 version = _ffi.string(_lib.SSL_CIPHER_get_version(cipher))
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001864 return version.decode("utf-8")
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001865
Jim Shaverabff1882015-05-27 09:15:55 -04001866 def get_protocol_version_name(self):
Jim Shaverba65e662015-04-26 12:23:40 -04001867 """
1868 Obtain the protocol version of the current connection.
1869
1870 :returns: The TLS version of the current connection, for example
Jim Shaver58d25732015-05-28 11:52:32 -04001871 the value for TLS 1.2 would be ``TLSv1.2``or ``Unknown``
Jim Shaverb5b6b0e2015-05-28 16:47:36 -04001872 for connections that were not successfully established.
Jim Shaver58d25732015-05-28 11:52:32 -04001873 :rtype: :py:class:`unicode`
Jim Shaverba65e662015-04-26 12:23:40 -04001874 """
Jim Shaverd1c896e2015-05-27 17:50:21 -04001875 version = _ffi.string(_lib.SSL_get_version(self._ssl))
Jim Shaver58d25732015-05-28 11:52:32 -04001876 return version.decode("utf-8")
Jim Shaverb2967922015-04-26 23:58:52 -04001877
Jim Shaver208438c2015-05-28 09:52:38 -04001878 def get_protocol_version(self):
1879 """
1880 Obtain the protocol version of the current connection.
1881
1882 :returns: The TLS version of the current connection, for example
1883 the value for TLS 1 would be 0x769.
1884 :rtype: :py:class:`int`
1885 """
1886 version = _lib.SSL_version(self._ssl)
1887 return version
1888
Cory Benfield10b277f2015-04-13 17:12:42 -04001889 @_requires_npn
Cory Benfield84a121e2014-03-31 20:30:25 +01001890 def get_next_proto_negotiated(self):
1891 """
1892 Get the protocol that was negotiated by NPN.
1893 """
1894 data = _ffi.new("unsigned char **")
1895 data_len = _ffi.new("unsigned int *")
1896
1897 _lib.SSL_get0_next_proto_negotiated(self._ssl, data, data_len)
1898
Cory Benfieldcd010f62014-05-15 19:00:27 +01001899 return _ffi.buffer(data[0], data_len[0])[:]
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001900
Cory Benfield7907e332015-04-13 17:18:25 -04001901 @_requires_alpn
Cory Benfield12eae892014-06-07 15:42:56 +01001902 def set_alpn_protos(self, protos):
1903 """
Cory Benfielde8e9c382015-04-11 17:33:48 -04001904 Specify the client's ALPN protocol list.
1905
1906 These protocols are offered to the server during protocol negotiation.
Cory Benfield12eae892014-06-07 15:42:56 +01001907
1908 :param protos: A list of the protocols to be offered to the server.
1909 This list should be a Python list of bytestrings representing the
1910 protocols to offer, e.g. ``[b'http/1.1', b'spdy/2']``.
1911 """
1912 # Take the list of protocols and join them together, prefixing them
1913 # with their lengths.
1914 protostr = b''.join(
1915 chain.from_iterable((int2byte(len(p)), p) for p in protos)
1916 )
1917
1918 # Build a C string from the list. We don't need to save this off
1919 # because OpenSSL immediately copies the data out.
1920 input_str = _ffi.new("unsigned char[]", protostr)
Cory Benfield9c1979a2015-04-12 08:51:52 -04001921 input_str_len = _ffi.cast("unsigned", len(protostr))
1922 _lib.SSL_set_alpn_protos(self._ssl, input_str, input_str_len)
Cory Benfield12eae892014-06-07 15:42:56 +01001923
Maximilian Hils66ded6a2015-08-26 06:02:03 +02001924 @_requires_alpn
Cory Benfield12eae892014-06-07 15:42:56 +01001925 def get_alpn_proto_negotiated(self):
Cory Benfield222f30e2015-04-13 18:10:21 -04001926 """
1927 Get the protocol that was negotiated by ALPN.
1928 """
Cory Benfield12eae892014-06-07 15:42:56 +01001929 data = _ffi.new("unsigned char **")
1930 data_len = _ffi.new("unsigned int *")
1931
1932 _lib.SSL_get0_alpn_selected(self._ssl, data, data_len)
1933
Cory Benfielde8e9c382015-04-11 17:33:48 -04001934 if not data_len:
1935 return b''
1936
Cory Benfield12eae892014-06-07 15:42:56 +01001937 return _ffi.buffer(data[0], data_len[0])[:]
1938
1939
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001940ConnectionType = Connection
Jean-Paul Calderone11ed8e82014-01-18 10:21:50 -05001941
Jean-Paul Calderonefab157b2014-01-18 11:21:38 -05001942# This is similar to the initialization calls at the end of OpenSSL/crypto.py
1943# but is exercised mostly by the Context initializer.
Jean-Paul Calderone11ed8e82014-01-18 10:21:50 -05001944_lib.SSL_library_init()