blob: f92c064288e70c3ecf3741b26dccebcb0209d219 [file] [log] [blame]
Maximilian Hils1d95dea2015-08-17 19:27:20 +02001import socket
Konstantinos Koukopoulos541150d2014-01-31 01:00:19 +02002from sys import platform
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05003from functools import wraps, partial
Cory Benfieldbe3e7b82014-05-10 09:48:55 +01004from itertools import count, chain
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08005from weakref import WeakValueDictionary
6from errno import errorcode
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -08007
Cory Benfield63759dc2015-04-12 08:57:03 -04008from six import binary_type as _binary_type
Konstantinos Koukopoulosc8b13ea2014-01-28 00:21:50 -08009from six import integer_types as integer_types
Cory Benfieldcd010f62014-05-15 19:00:27 +010010from six import int2byte, indexbytes
Jean-Paul Calderone63eab692014-01-18 10:19:56 -050011
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -050012from OpenSSL._util import (
Hynek Schlawackaa861212016-03-13 13:53:48 +010013 UNSPECIFIED as _UNSPECIFIED,
14 exception_from_error_queue as _exception_from_error_queue,
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -050015 ffi as _ffi,
16 lib as _lib,
Hynek Schlawackf90e3682016-03-11 11:21:13 +010017 make_assert as _make_assert,
Hynek Schlawackaa861212016-03-13 13:53:48 +010018 native as _native,
Jean-Paul Calderone55f9e882015-04-12 09:31:03 -040019 path_string as _path_string,
Hynek Schlawackaa861212016-03-13 13:53:48 +010020 text_to_bytes_and_warn as _text_to_bytes_and_warn,
Jean-Paul Calderone55f9e882015-04-12 09:31:03 -040021)
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080022
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -080023from OpenSSL.crypto import (
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -050024 FILETYPE_PEM, _PassphraseHelper, PKey, X509Name, X509, X509Store)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -080025
Jean-Paul Calderone8fb53182013-12-30 08:35:49 -050026try:
27 _memoryview = memoryview
28except NameError:
29 class _memoryview(object):
30 pass
31
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +020032try:
33 _buffer = buffer
34except NameError:
35 class _buffer(object):
36 pass
37
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050038OPENSSL_VERSION_NUMBER = _lib.OPENSSL_VERSION_NUMBER
39SSLEAY_VERSION = _lib.SSLEAY_VERSION
40SSLEAY_CFLAGS = _lib.SSLEAY_CFLAGS
41SSLEAY_PLATFORM = _lib.SSLEAY_PLATFORM
42SSLEAY_DIR = _lib.SSLEAY_DIR
43SSLEAY_BUILT_ON = _lib.SSLEAY_BUILT_ON
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080044
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050045SENT_SHUTDOWN = _lib.SSL_SENT_SHUTDOWN
46RECEIVED_SHUTDOWN = _lib.SSL_RECEIVED_SHUTDOWN
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080047
48SSLv2_METHOD = 1
49SSLv3_METHOD = 2
50SSLv23_METHOD = 3
51TLSv1_METHOD = 4
Jean-Paul Calderone56bff942013-11-03 11:30:43 -050052TLSv1_1_METHOD = 5
53TLSv1_2_METHOD = 6
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080054
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050055OP_NO_SSLv2 = _lib.SSL_OP_NO_SSLv2
56OP_NO_SSLv3 = _lib.SSL_OP_NO_SSLv3
57OP_NO_TLSv1 = _lib.SSL_OP_NO_TLSv1
Jean-Paul Calderonebe2bb422013-12-29 07:34:08 -050058
59OP_NO_TLSv1_1 = getattr(_lib, "SSL_OP_NO_TLSv1_1", 0)
60OP_NO_TLSv1_2 = getattr(_lib, "SSL_OP_NO_TLSv1_2", 0)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -080061
Alex Gaynorbf012872016-06-04 13:18:39 -070062MODE_RELEASE_BUFFERS = _lib.SSL_MODE_RELEASE_BUFFERS
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080063
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050064OP_SINGLE_DH_USE = _lib.SSL_OP_SINGLE_DH_USE
Akihiro Yamazakie64d80c2015-09-06 00:16:57 +090065OP_SINGLE_ECDH_USE = _lib.SSL_OP_SINGLE_ECDH_USE
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050066OP_EPHEMERAL_RSA = _lib.SSL_OP_EPHEMERAL_RSA
67OP_MICROSOFT_SESS_ID_BUG = _lib.SSL_OP_MICROSOFT_SESS_ID_BUG
68OP_NETSCAPE_CHALLENGE_BUG = _lib.SSL_OP_NETSCAPE_CHALLENGE_BUG
Alex Gaynor62da94d2015-09-05 14:37:34 -040069OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG = (
70 _lib.SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG
71)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050072OP_SSLREF2_REUSE_CERT_TYPE_BUG = _lib.SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG
73OP_MICROSOFT_BIG_SSLV3_BUFFER = _lib.SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER
Alex Gaynor5bb2bd12016-07-03 10:48:32 -040074OP_MSIE_SSLV2_RSA_PADDING = _lib.SSL_OP_MSIE_SSLV2_RSA_PADDING
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050075OP_SSLEAY_080_CLIENT_DH_BUG = _lib.SSL_OP_SSLEAY_080_CLIENT_DH_BUG
76OP_TLS_D5_BUG = _lib.SSL_OP_TLS_D5_BUG
77OP_TLS_BLOCK_PADDING_BUG = _lib.SSL_OP_TLS_BLOCK_PADDING_BUG
78OP_DONT_INSERT_EMPTY_FRAGMENTS = _lib.SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
79OP_CIPHER_SERVER_PREFERENCE = _lib.SSL_OP_CIPHER_SERVER_PREFERENCE
80OP_TLS_ROLLBACK_BUG = _lib.SSL_OP_TLS_ROLLBACK_BUG
81OP_PKCS1_CHECK_1 = _lib.SSL_OP_PKCS1_CHECK_1
82OP_PKCS1_CHECK_2 = _lib.SSL_OP_PKCS1_CHECK_2
83OP_NETSCAPE_CA_DN_BUG = _lib.SSL_OP_NETSCAPE_CA_DN_BUG
Alex Gaynor62da94d2015-09-05 14:37:34 -040084OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG = (
85 _lib.SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG
86)
Alex Gaynorbf012872016-06-04 13:18:39 -070087OP_NO_COMPRESSION = _lib.SSL_OP_NO_COMPRESSION
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -080088
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050089OP_NO_QUERY_MTU = _lib.SSL_OP_NO_QUERY_MTU
90OP_COOKIE_EXCHANGE = _lib.SSL_OP_COOKIE_EXCHANGE
Alex Gaynor5bb2bd12016-07-03 10:48:32 -040091OP_NO_TICKET = _lib.SSL_OP_NO_TICKET
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -080092
Alex Gaynorc4889812015-09-04 08:43:17 -040093OP_ALL = _lib.SSL_OP_ALL
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080094
Jean-Paul Calderone6037d072013-12-28 18:04:00 -050095VERIFY_PEER = _lib.SSL_VERIFY_PEER
96VERIFY_FAIL_IF_NO_PEER_CERT = _lib.SSL_VERIFY_FAIL_IF_NO_PEER_CERT
97VERIFY_CLIENT_ONCE = _lib.SSL_VERIFY_CLIENT_ONCE
98VERIFY_NONE = _lib.SSL_VERIFY_NONE
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080099
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500100SESS_CACHE_OFF = _lib.SSL_SESS_CACHE_OFF
101SESS_CACHE_CLIENT = _lib.SSL_SESS_CACHE_CLIENT
102SESS_CACHE_SERVER = _lib.SSL_SESS_CACHE_SERVER
103SESS_CACHE_BOTH = _lib.SSL_SESS_CACHE_BOTH
104SESS_CACHE_NO_AUTO_CLEAR = _lib.SSL_SESS_CACHE_NO_AUTO_CLEAR
105SESS_CACHE_NO_INTERNAL_LOOKUP = _lib.SSL_SESS_CACHE_NO_INTERNAL_LOOKUP
106SESS_CACHE_NO_INTERNAL_STORE = _lib.SSL_SESS_CACHE_NO_INTERNAL_STORE
107SESS_CACHE_NO_INTERNAL = _lib.SSL_SESS_CACHE_NO_INTERNAL
Jean-Paul Calderoned39a3f62013-03-04 12:23:51 -0800108
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500109SSL_ST_CONNECT = _lib.SSL_ST_CONNECT
110SSL_ST_ACCEPT = _lib.SSL_ST_ACCEPT
111SSL_ST_MASK = _lib.SSL_ST_MASK
Alex Gaynor5af32d02016-09-24 01:52:21 -0400112if _lib.Cryptography_HAS_SSL_ST:
113 SSL_ST_INIT = _lib.SSL_ST_INIT
114 SSL_ST_BEFORE = _lib.SSL_ST_BEFORE
115 SSL_ST_OK = _lib.SSL_ST_OK
116 SSL_ST_RENEGOTIATE = _lib.SSL_ST_RENEGOTIATE
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800117
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500118SSL_CB_LOOP = _lib.SSL_CB_LOOP
119SSL_CB_EXIT = _lib.SSL_CB_EXIT
120SSL_CB_READ = _lib.SSL_CB_READ
121SSL_CB_WRITE = _lib.SSL_CB_WRITE
122SSL_CB_ALERT = _lib.SSL_CB_ALERT
123SSL_CB_READ_ALERT = _lib.SSL_CB_READ_ALERT
124SSL_CB_WRITE_ALERT = _lib.SSL_CB_WRITE_ALERT
125SSL_CB_ACCEPT_LOOP = _lib.SSL_CB_ACCEPT_LOOP
126SSL_CB_ACCEPT_EXIT = _lib.SSL_CB_ACCEPT_EXIT
127SSL_CB_CONNECT_LOOP = _lib.SSL_CB_CONNECT_LOOP
128SSL_CB_CONNECT_EXIT = _lib.SSL_CB_CONNECT_EXIT
129SSL_CB_HANDSHAKE_START = _lib.SSL_CB_HANDSHAKE_START
130SSL_CB_HANDSHAKE_DONE = _lib.SSL_CB_HANDSHAKE_DONE
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800131
Alex Gaynor83284952015-09-05 10:43:30 -0400132
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500133class Error(Exception):
Jean-Paul Calderone511cde02013-12-29 10:31:13 -0500134 """
135 An error occurred in an `OpenSSL.SSL` API.
136 """
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500137
138
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500139_raise_current_error = partial(_exception_from_error_queue, Error)
Hynek Schlawackf90e3682016-03-11 11:21:13 +0100140_openssl_assert = _make_assert(Error)
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500141
142
143class WantReadError(Error):
144 pass
145
146
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500147class WantWriteError(Error):
148 pass
149
150
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500151class WantX509LookupError(Error):
152 pass
153
154
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500155class ZeroReturnError(Error):
156 pass
157
158
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500159class SysCallError(Error):
160 pass
161
162
Cory Benfield0ea76e72015-03-22 09:05:28 +0000163class _CallbackExceptionHelper(object):
164 """
165 A base class for wrapper classes that allow for intelligent exception
166 handling in OpenSSL callbacks.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500167
Jean-Paul Calderone1b172982015-03-22 19:37:11 -0400168 :ivar list _problems: Any exceptions that occurred while executing in a
169 context where they could not be raised in the normal way. Typically
170 this is because OpenSSL has called into some Python code and requires a
171 return value. The exceptions are saved to be raised later when it is
172 possible to do so.
Cory Benfield0ea76e72015-03-22 09:05:28 +0000173 """
Alex Gaynor62da94d2015-09-05 14:37:34 -0400174
Jean-Paul Calderone09540d72015-03-22 19:37:20 -0400175 def __init__(self):
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800176 self._problems = []
177
Cory Benfield0ea76e72015-03-22 09:05:28 +0000178 def raise_if_problem(self):
Jean-Paul Calderone1b172982015-03-22 19:37:11 -0400179 """
180 Raise an exception from the OpenSSL error queue or that was previously
181 captured whe running a callback.
182 """
Cory Benfield0ea76e72015-03-22 09:05:28 +0000183 if self._problems:
184 try:
185 _raise_current_error()
186 except Error:
187 pass
188 raise self._problems.pop(0)
189
190
191class _VerifyHelper(_CallbackExceptionHelper):
Jean-Paul Calderone1b172982015-03-22 19:37:11 -0400192 """
193 Wrap a callback such that it can be used as a certificate verification
194 callback.
195 """
Alex Gaynor62da94d2015-09-05 14:37:34 -0400196
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800197 def __init__(self, callback):
Jean-Paul Calderone837f4032015-03-22 17:38:28 -0400198 _CallbackExceptionHelper.__init__(self)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800199
200 @wraps(callback)
201 def wrapper(ok, store_ctx):
202 cert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500203 cert._x509 = _lib.X509_STORE_CTX_get_current_cert(store_ctx)
204 error_number = _lib.X509_STORE_CTX_get_error(store_ctx)
205 error_depth = _lib.X509_STORE_CTX_get_error_depth(store_ctx)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800206
Jean-Paul Calderone6a8cd112014-04-02 21:09:08 -0400207 index = _lib.SSL_get_ex_data_X509_STORE_CTX_idx()
208 ssl = _lib.X509_STORE_CTX_get_ex_data(store_ctx, index)
209 connection = Connection._reverse_mapping[ssl]
210
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800211 try:
Alex Gaynor62da94d2015-09-05 14:37:34 -0400212 result = callback(
213 connection, cert, error_number, error_depth, ok
214 )
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800215 except Exception as e:
216 self._problems.append(e)
217 return 0
218 else:
219 if result:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500220 _lib.X509_STORE_CTX_set_error(store_ctx, _lib.X509_V_OK)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800221 return 1
222 else:
223 return 0
224
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500225 self.callback = _ffi.callback(
226 "int (*)(int, X509_STORE_CTX *)", wrapper)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800227
228
Cory Benfield0ea76e72015-03-22 09:05:28 +0000229class _NpnAdvertiseHelper(_CallbackExceptionHelper):
Jean-Paul Calderone1b172982015-03-22 19:37:11 -0400230 """
231 Wrap a callback such that it can be used as an NPN advertisement callback.
232 """
Alex Gaynor62da94d2015-09-05 14:37:34 -0400233
Cory Benfield0ea76e72015-03-22 09:05:28 +0000234 def __init__(self, callback):
Jean-Paul Calderone837f4032015-03-22 17:38:28 -0400235 _CallbackExceptionHelper.__init__(self)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800236
Cory Benfield0ea76e72015-03-22 09:05:28 +0000237 @wraps(callback)
238 def wrapper(ssl, out, outlen, arg):
239 try:
240 conn = Connection._reverse_mapping[ssl]
241 protos = callback(conn)
242
243 # Join the protocols into a Python bytestring, length-prefixing
244 # each element.
245 protostr = b''.join(
246 chain.from_iterable((int2byte(len(p)), p) for p in protos)
247 )
248
249 # Save our callback arguments on the connection object. This is
250 # done to make sure that they don't get freed before OpenSSL
251 # uses them. Then, return them appropriately in the output
252 # parameters.
253 conn._npn_advertise_callback_args = [
254 _ffi.new("unsigned int *", len(protostr)),
255 _ffi.new("unsigned char[]", protostr),
256 ]
257 outlen[0] = conn._npn_advertise_callback_args[0][0]
258 out[0] = conn._npn_advertise_callback_args[1]
259 return 0
260 except Exception as e:
261 self._problems.append(e)
262 return 2 # SSL_TLSEXT_ERR_ALERT_FATAL
263
264 self.callback = _ffi.callback(
265 "int (*)(SSL *, const unsigned char **, unsigned int *, void *)",
266 wrapper
267 )
268
269
270class _NpnSelectHelper(_CallbackExceptionHelper):
Jean-Paul Calderone1b172982015-03-22 19:37:11 -0400271 """
272 Wrap a callback such that it can be used as an NPN selection callback.
273 """
Alex Gaynor62da94d2015-09-05 14:37:34 -0400274
Cory Benfield0ea76e72015-03-22 09:05:28 +0000275 def __init__(self, callback):
Jean-Paul Calderone837f4032015-03-22 17:38:28 -0400276 _CallbackExceptionHelper.__init__(self)
Cory Benfield0ea76e72015-03-22 09:05:28 +0000277
278 @wraps(callback)
279 def wrapper(ssl, out, outlen, in_, inlen, arg):
280 try:
281 conn = Connection._reverse_mapping[ssl]
282
283 # The string passed to us is actually made up of multiple
284 # length-prefixed bytestrings. We need to split that into a
285 # list.
286 instr = _ffi.buffer(in_, inlen)[:]
287 protolist = []
288 while instr:
289 l = indexbytes(instr, 0)
Alex Gaynorca87ff62015-09-04 23:31:03 -0400290 proto = instr[1:l + 1]
Cory Benfield0ea76e72015-03-22 09:05:28 +0000291 protolist.append(proto)
Alex Gaynorca87ff62015-09-04 23:31:03 -0400292 instr = instr[l + 1:]
Cory Benfield0ea76e72015-03-22 09:05:28 +0000293
294 # Call the callback
295 outstr = callback(conn, protolist)
296
297 # Save our callback arguments on the connection object. This is
298 # done to make sure that they don't get freed before OpenSSL
299 # uses them. Then, return them appropriately in the output
300 # parameters.
301 conn._npn_select_callback_args = [
302 _ffi.new("unsigned char *", len(outstr)),
303 _ffi.new("unsigned char[]", outstr),
304 ]
305 outlen[0] = conn._npn_select_callback_args[0][0]
306 out[0] = conn._npn_select_callback_args[1]
307 return 0
308 except Exception as e:
309 self._problems.append(e)
310 return 2 # SSL_TLSEXT_ERR_ALERT_FATAL
311
312 self.callback = _ffi.callback(
Alex Gaynor62da94d2015-09-05 14:37:34 -0400313 ("int (*)(SSL *, unsigned char **, unsigned char *, "
314 "const unsigned char *, unsigned int, void *)"),
Cory Benfield0ea76e72015-03-22 09:05:28 +0000315 wrapper
316 )
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800317
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800318
Cory Benfield9da5ffb2015-04-13 17:20:14 -0400319class _ALPNSelectHelper(_CallbackExceptionHelper):
Cory Benfieldf1177e72015-04-12 09:11:49 -0400320 """
321 Wrap a callback such that it can be used as an ALPN selection callback.
322 """
Alex Gaynor62da94d2015-09-05 14:37:34 -0400323
Cory Benfieldf1177e72015-04-12 09:11:49 -0400324 def __init__(self, callback):
325 _CallbackExceptionHelper.__init__(self)
326
327 @wraps(callback)
328 def wrapper(ssl, out, outlen, in_, inlen, arg):
329 try:
330 conn = Connection._reverse_mapping[ssl]
331
332 # The string passed to us is made up of multiple
333 # length-prefixed bytestrings. We need to split that into a
334 # list.
335 instr = _ffi.buffer(in_, inlen)[:]
336 protolist = []
337 while instr:
Cory Benfield93134db2015-04-13 17:22:13 -0400338 encoded_len = indexbytes(instr, 0)
339 proto = instr[1:encoded_len + 1]
Cory Benfieldf1177e72015-04-12 09:11:49 -0400340 protolist.append(proto)
Cory Benfield93134db2015-04-13 17:22:13 -0400341 instr = instr[encoded_len + 1:]
Cory Benfieldf1177e72015-04-12 09:11:49 -0400342
343 # Call the callback
344 outstr = callback(conn, protolist)
345
346 if not isinstance(outstr, _binary_type):
347 raise TypeError("ALPN callback must return a bytestring.")
348
349 # Save our callback arguments on the connection object to make
350 # sure that they don't get freed before OpenSSL can use them.
351 # Then, return them in the appropriate output parameters.
352 conn._alpn_select_callback_args = [
353 _ffi.new("unsigned char *", len(outstr)),
354 _ffi.new("unsigned char[]", outstr),
355 ]
356 outlen[0] = conn._alpn_select_callback_args[0][0]
357 out[0] = conn._alpn_select_callback_args[1]
358 return 0
359 except Exception as e:
360 self._problems.append(e)
361 return 2 # SSL_TLSEXT_ERR_ALERT_FATAL
362
363 self.callback = _ffi.callback(
Alex Gaynor62da94d2015-09-05 14:37:34 -0400364 ("int (*)(SSL *, unsigned char **, unsigned char *, "
365 "const unsigned char *, unsigned int, void *)"),
Cory Benfieldf1177e72015-04-12 09:11:49 -0400366 wrapper
367 )
368
369
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800370def _asFileDescriptor(obj):
371 fd = None
Konstantinos Koukopoulosc8b13ea2014-01-28 00:21:50 -0800372 if not isinstance(obj, integer_types):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800373 meth = getattr(obj, "fileno", None)
374 if meth is not None:
375 obj = meth()
376
Konstantinos Koukopoulosc8b13ea2014-01-28 00:21:50 -0800377 if isinstance(obj, integer_types):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800378 fd = obj
379
Konstantinos Koukopoulosc8b13ea2014-01-28 00:21:50 -0800380 if not isinstance(fd, integer_types):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800381 raise TypeError("argument must be an int, or have a fileno() method.")
382 elif fd < 0:
383 raise ValueError(
384 "file descriptor cannot be a negative integer (%i)" % (fd,))
385
386 return fd
387
388
Jean-Paul Calderoned39a3f62013-03-04 12:23:51 -0800389def SSLeay_version(type):
390 """
391 Return a string describing the version of OpenSSL in use.
392
393 :param type: One of the SSLEAY_ constants defined in this module.
394 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500395 return _ffi.string(_lib.SSLeay_version(type))
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800396
397
Cory Benfieldef404df2016-03-29 15:32:48 +0100398def _make_requires(flag, error):
Cory Benfielda876cef2015-04-13 17:29:12 -0400399 """
Cory Benfieldef404df2016-03-29 15:32:48 +0100400 Builds a decorator that ensures that functions that rely on OpenSSL
401 functions that are not present in this build raise NotImplementedError,
402 rather than AttributeError coming out of cryptography.
403
404 :param flag: A cryptography flag that guards the functions, e.g.
405 ``Cryptography_HAS_NEXTPROTONEG``.
406 :param error: The string to be used in the exception if the flag is false.
Cory Benfielda876cef2015-04-13 17:29:12 -0400407 """
Cory Benfieldef404df2016-03-29 15:32:48 +0100408 def _requires_decorator(func):
409 if not flag:
410 @wraps(func)
411 def explode(*args, **kwargs):
412 raise NotImplementedError(error)
413 return explode
414 else:
415 return func
Cory Benfield10b277f2015-04-13 17:12:42 -0400416
Cory Benfieldef404df2016-03-29 15:32:48 +0100417 return _requires_decorator
Cory Benfield10b277f2015-04-13 17:12:42 -0400418
419
Cory Benfieldef404df2016-03-29 15:32:48 +0100420_requires_npn = _make_requires(
421 _lib.Cryptography_HAS_NEXTPROTONEG, "NPN not available"
422)
Cory Benfield7907e332015-04-13 17:18:25 -0400423
424
Cory Benfieldef404df2016-03-29 15:32:48 +0100425_requires_alpn = _make_requires(
426 _lib.Cryptography_HAS_ALPN, "ALPN not available"
427)
Cory Benfielde6f35882016-03-29 11:21:04 +0100428
Cory Benfielde6f35882016-03-29 11:21:04 +0100429
Cory Benfieldef404df2016-03-29 15:32:48 +0100430_requires_sni = _make_requires(
431 _lib.Cryptography_HAS_TLSEXT_HOSTNAME, "SNI not available"
432)
Cory Benfielde6f35882016-03-29 11:21:04 +0100433
434
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800435class Session(object):
436 pass
437
438
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800439class Context(object):
440 """
Hynek Schlawackf90e3682016-03-11 11:21:13 +0100441 :class:`OpenSSL.SSL.Context` instances define the parameters for setting
Alex Gaynor62da94d2015-09-05 14:37:34 -0400442 up new SSL connections.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800443 """
444 _methods = {
Andrew Dunhamec84a0a2014-02-24 12:41:37 -0800445 SSLv2_METHOD: "SSLv2_method",
Jean-Paul Calderonebe2bb422013-12-29 07:34:08 -0500446 SSLv3_METHOD: "SSLv3_method",
447 SSLv23_METHOD: "SSLv23_method",
448 TLSv1_METHOD: "TLSv1_method",
449 TLSv1_1_METHOD: "TLSv1_1_method",
450 TLSv1_2_METHOD: "TLSv1_2_method",
Alex Gaynorc4889812015-09-04 08:43:17 -0400451 }
Jean-Paul Calderonebe2bb422013-12-29 07:34:08 -0500452 _methods = dict(
453 (identifier, getattr(_lib, name))
454 for (identifier, name) in _methods.items()
455 if getattr(_lib, name, None) is not None)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800456
457 def __init__(self, method):
458 """
459 :param method: One of SSLv2_METHOD, SSLv3_METHOD, SSLv23_METHOD, or
460 TLSv1_METHOD.
461 """
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -0500462 if not isinstance(method, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800463 raise TypeError("method must be an integer")
464
465 try:
466 method_func = self._methods[method]
467 except KeyError:
468 raise ValueError("No such protocol")
469
470 method_obj = method_func()
Alex Gaynora829e902016-06-04 18:16:01 -0700471 _openssl_assert(method_obj != _ffi.NULL)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800472
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500473 context = _lib.SSL_CTX_new(method_obj)
Alex Gaynora829e902016-06-04 18:16:01 -0700474 _openssl_assert(context != _ffi.NULL)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500475 context = _ffi.gc(context, _lib.SSL_CTX_free)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800476
477 self._context = context
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800478 self._passphrase_helper = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800479 self._passphrase_callback = None
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800480 self._passphrase_userdata = None
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800481 self._verify_helper = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800482 self._verify_callback = None
483 self._info_callback = None
484 self._tlsext_servername_callback = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800485 self._app_data = None
Cory Benfield0ea76e72015-03-22 09:05:28 +0000486 self._npn_advertise_helper = None
Cory Benfield84a121e2014-03-31 20:30:25 +0100487 self._npn_advertise_callback = None
Cory Benfield0ea76e72015-03-22 09:05:28 +0000488 self._npn_select_helper = None
Cory Benfield84a121e2014-03-31 20:30:25 +0100489 self._npn_select_callback = None
Cory Benfieldf1177e72015-04-12 09:11:49 -0400490 self._alpn_select_helper = None
Cory Benfield12eae892014-06-07 15:42:56 +0100491 self._alpn_select_callback = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800492
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -0800493 # SSL_CTX_set_app_data(self->ctx, self);
494 # SSL_CTX_set_mode(self->ctx, SSL_MODE_ENABLE_PARTIAL_WRITE |
495 # SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
496 # SSL_MODE_AUTO_RETRY);
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500497 self.set_mode(_lib.SSL_MODE_ENABLE_PARTIAL_WRITE)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800498
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800499 def load_verify_locations(self, cafile, capath=None):
500 """
501 Let SSL know where we can find trusted certificates for the certificate
502 chain
503
Jean-Paul Calderone55f9e882015-04-12 09:31:03 -0400504 :param cafile: In which file we can find the certificates (``bytes`` or
505 ``unicode``).
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800506 :param capath: In which directory we can find the certificates
Jean-Paul Calderone55f9e882015-04-12 09:31:03 -0400507 (``bytes`` or ``unicode``).
508
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800509 :return: None
510 """
511 if cafile is None:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500512 cafile = _ffi.NULL
Jean-Paul Calderone55f9e882015-04-12 09:31:03 -0400513 else:
514 cafile = _path_string(cafile)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800515
516 if capath is None:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500517 capath = _ffi.NULL
Jean-Paul Calderone55f9e882015-04-12 09:31:03 -0400518 else:
519 capath = _path_string(capath)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800520
Alex Gaynor62da94d2015-09-05 14:37:34 -0400521 load_result = _lib.SSL_CTX_load_verify_locations(
522 self._context, cafile, capath
523 )
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800524 if not load_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500525 _raise_current_error()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800526
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800527 def _wrap_callback(self, callback):
528 @wraps(callback)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800529 def wrapper(size, verify, userdata):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800530 return callback(size, verify, self._passphrase_userdata)
531 return _PassphraseHelper(
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800532 FILETYPE_PEM, wrapper, more_args=True, truncate=True)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800533
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800534 def set_passwd_cb(self, callback, userdata=None):
535 """
536 Set the passphrase callback
537
538 :param callback: The Python callback to use
539 :param userdata: (optional) A Python object which will be given as
540 argument to the callback
541 :return: None
542 """
543 if not callable(callback):
544 raise TypeError("callback must be callable")
545
546 self._passphrase_helper = self._wrap_callback(callback)
547 self._passphrase_callback = self._passphrase_helper.callback
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500548 _lib.SSL_CTX_set_default_passwd_cb(
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800549 self._context, self._passphrase_callback)
550 self._passphrase_userdata = userdata
551
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800552 def set_default_verify_paths(self):
553 """
554 Use the platform-specific CA certificate locations
555
556 :return: None
557 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500558 set_result = _lib.SSL_CTX_set_default_verify_paths(self._context)
Alex Gaynor09f19f52016-07-03 09:54:09 -0400559 _openssl_assert(set_result == 1)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800560
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800561 def use_certificate_chain_file(self, certfile):
562 """
563 Load a certificate chain from a file
564
Jean-Paul Calderoneb6f8a792015-04-13 10:10:06 -0400565 :param certfile: The name of the certificate chain file (``bytes`` or
566 ``unicode``).
567
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800568 :return: None
569 """
Jean-Paul Calderoneaac43a32015-04-12 09:51:21 -0400570 certfile = _path_string(certfile)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800571
Alex Gaynor62da94d2015-09-05 14:37:34 -0400572 result = _lib.SSL_CTX_use_certificate_chain_file(
573 self._context, certfile
574 )
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800575 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500576 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800577
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800578 def use_certificate_file(self, certfile, filetype=FILETYPE_PEM):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800579 """
580 Load a certificate from a file
581
Jean-Paul Calderoneb6f8a792015-04-13 10:10:06 -0400582 :param certfile: The name of the certificate file (``bytes`` or
583 ``unicode``).
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800584 :param filetype: (optional) The encoding of the file, default is PEM
Jean-Paul Calderoneb6f8a792015-04-13 10:10:06 -0400585
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800586 :return: None
587 """
Jean-Paul Calderoned57a7b62015-04-12 09:57:36 -0400588 certfile = _path_string(certfile)
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -0500589 if not isinstance(filetype, integer_types):
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800590 raise TypeError("filetype must be an integer")
591
Alex Gaynor62da94d2015-09-05 14:37:34 -0400592 use_result = _lib.SSL_CTX_use_certificate_file(
593 self._context, certfile, filetype
594 )
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800595 if not use_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500596 _raise_current_error()
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800597
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800598 def use_certificate(self, cert):
599 """
600 Load a certificate from a X509 object
601
602 :param cert: The X509 object
603 :return: None
604 """
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800605 if not isinstance(cert, X509):
606 raise TypeError("cert must be an X509 instance")
607
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500608 use_result = _lib.SSL_CTX_use_certificate(self._context, cert._x509)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800609 if not use_result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500610 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800611
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800612 def add_extra_chain_cert(self, certobj):
613 """
614 Add certificate to chain
615
616 :param certobj: The X509 certificate object to add to the chain
617 :return: None
618 """
619 if not isinstance(certobj, X509):
620 raise TypeError("certobj must be an X509 instance")
621
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500622 copy = _lib.X509_dup(certobj._x509)
623 add_result = _lib.SSL_CTX_add_extra_chain_cert(self._context, copy)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800624 if not add_result:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500625 # TODO: This is untested.
626 _lib.X509_free(copy)
627 _raise_current_error()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800628
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800629 def _raise_passphrase_exception(self):
630 if self._passphrase_helper is None:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500631 _raise_current_error()
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800632 exception = self._passphrase_helper.raise_if_problem(Error)
633 if exception is not None:
634 raise exception
635
Jean-Paul Calderone00f84eb2015-04-13 12:47:21 -0400636 def use_privatekey_file(self, keyfile, filetype=_UNSPECIFIED):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800637 """
638 Load a private key from a file
639
Jean-Paul Calderoneb6f8a792015-04-13 10:10:06 -0400640 :param keyfile: The name of the key file (``bytes`` or ``unicode``)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800641 :param filetype: (optional) The encoding of the file, default is PEM
Jean-Paul Calderoneb6f8a792015-04-13 10:10:06 -0400642
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800643 :return: None
644 """
Jean-Paul Calderone69a4e5b2015-04-12 10:04:28 -0400645 keyfile = _path_string(keyfile)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800646
Jean-Paul Calderone00f84eb2015-04-13 12:47:21 -0400647 if filetype is _UNSPECIFIED:
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800648 filetype = FILETYPE_PEM
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -0500649 elif not isinstance(filetype, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800650 raise TypeError("filetype must be an integer")
651
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500652 use_result = _lib.SSL_CTX_use_PrivateKey_file(
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800653 self._context, keyfile, filetype)
654 if not use_result:
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800655 self._raise_passphrase_exception()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800656
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800657 def use_privatekey(self, pkey):
658 """
659 Load a private key from a PKey object
660
661 :param pkey: The PKey object
662 :return: None
663 """
664 if not isinstance(pkey, PKey):
665 raise TypeError("pkey must be a PKey instance")
666
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500667 use_result = _lib.SSL_CTX_use_PrivateKey(self._context, pkey._pkey)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800668 if not use_result:
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800669 self._raise_passphrase_exception()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800670
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800671 def check_privatekey(self):
672 """
673 Check that the private key and certificate match up
674
675 :return: None (raises an exception if something's wrong)
676 """
Jean-Paul Calderonea0344922014-12-11 14:02:31 -0500677 if not _lib.SSL_CTX_check_private_key(self._context):
678 _raise_current_error()
679
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800680 def load_client_ca(self, cafile):
681 """
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +0100682 Load the trusted certificates that will be sent to the client. Does
683 not actually imply any of the certificates are trusted; that must be
Alex Gaynor62da94d2015-09-05 14:37:34 -0400684 configured separately.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800685
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +0100686 :param bytes cafile: The path to a certificates file in PEM format.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800687 :return: None
688 """
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +0100689 ca_list = _lib.SSL_load_client_CA_file(
690 _text_to_bytes_and_warn("cafile", cafile)
691 )
692 _openssl_assert(ca_list != _ffi.NULL)
693 # SSL_CTX_set_client_CA_list doesn't return anything.
694 _lib.SSL_CTX_set_client_CA_list(self._context, ca_list)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800695
696 def set_session_id(self, buf):
697 """
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +0100698 Set the session id to *buf* within which a session can be reused for
699 this Context object. This is needed when doing session resumption,
700 because there is no way for a stored session to know which Context
701 object it is associated with.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800702
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +0100703 :param bytes buf: The session id.
704
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800705 :returns: None
706 """
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +0100707 buf = _text_to_bytes_and_warn("buf", buf)
708 _openssl_assert(
709 _lib.SSL_CTX_set_session_id_context(
710 self._context,
711 buf,
712 len(buf),
713 ) == 1
714 )
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800715
716 def set_session_cache_mode(self, mode):
717 """
718 Enable/disable session caching and specify the mode used.
719
720 :param mode: One or more of the SESS_CACHE_* flags (combine using
721 bitwise or)
722 :returns: The previously set caching mode.
723 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500724 if not isinstance(mode, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800725 raise TypeError("mode must be an integer")
726
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500727 return _lib.SSL_CTX_set_session_cache_mode(self._context, mode)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800728
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800729 def get_session_cache_mode(self):
730 """
731 :returns: The currently used cache mode.
732 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500733 return _lib.SSL_CTX_get_session_cache_mode(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800734
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800735 def set_verify(self, mode, callback):
736 """
737 Set the verify mode and verify callback
738
739 :param mode: The verify mode, this is either VERIFY_NONE or
740 VERIFY_PEER combined with possible other flags
741 :param callback: The Python callback to use
742 :return: None
743
744 See SSL_CTX_set_verify(3SSL) for further details.
745 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500746 if not isinstance(mode, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800747 raise TypeError("mode must be an integer")
748
749 if not callable(callback):
750 raise TypeError("callback must be callable")
751
Jean-Paul Calderone6a8cd112014-04-02 21:09:08 -0400752 self._verify_helper = _VerifyHelper(callback)
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800753 self._verify_callback = self._verify_helper.callback
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500754 _lib.SSL_CTX_set_verify(self._context, mode, self._verify_callback)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800755
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800756 def set_verify_depth(self, depth):
757 """
758 Set the verify depth
759
760 :param depth: An integer specifying the verify depth
761 :return: None
762 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500763 if not isinstance(depth, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800764 raise TypeError("depth must be an integer")
765
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500766 _lib.SSL_CTX_set_verify_depth(self._context, depth)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800767
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800768 def get_verify_mode(self):
769 """
770 Get the verify mode
771
772 :return: The verify mode
773 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500774 return _lib.SSL_CTX_get_verify_mode(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800775
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800776 def get_verify_depth(self):
777 """
778 Get the verify depth
779
780 :return: The verify depth
781 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500782 return _lib.SSL_CTX_get_verify_depth(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800783
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800784 def load_tmp_dh(self, dhfile):
785 """
786 Load parameters for Ephemeral Diffie-Hellman
787
Jean-Paul Calderone4e0c43f2015-04-13 10:15:17 -0400788 :param dhfile: The file to load EDH parameters from (``bytes`` or
789 ``unicode``).
790
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800791 :return: None
792 """
Jean-Paul Calderone9e1c1dd2015-04-12 10:13:13 -0400793 dhfile = _path_string(dhfile)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800794
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -0500795 bio = _lib.BIO_new_file(dhfile, b"r")
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500796 if bio == _ffi.NULL:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500797 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500798 bio = _ffi.gc(bio, _lib.BIO_free)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800799
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500800 dh = _lib.PEM_read_bio_DHparams(bio, _ffi.NULL, _ffi.NULL, _ffi.NULL)
801 dh = _ffi.gc(dh, _lib.DH_free)
802 _lib.SSL_CTX_set_tmp_dh(self._context, dh)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800803
Jean-Paul Calderone3e4e3352014-04-19 09:28:28 -0400804 def set_tmp_ecdh(self, curve):
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600805 """
Andy Lutomirski76a61332014-03-12 15:02:56 -0700806 Select a curve to use for ECDHE key exchange.
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600807
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -0400808 :param curve: A curve object to use as returned by either
809 :py:meth:`OpenSSL.crypto.get_elliptic_curve` or
810 :py:meth:`OpenSSL.crypto.get_elliptic_curves`.
Andy Lutomirskif05a2732014-03-13 17:22:25 -0700811
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600812 :return: None
813 """
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -0400814 _lib.SSL_CTX_set_tmp_ecdh(self._context, curve._to_EC_KEY())
Alex Gaynor7b8d57a2014-01-17 12:08:54 -0600815
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800816 def set_cipher_list(self, cipher_list):
817 """
Hynek Schlawackf90e3682016-03-11 11:21:13 +0100818 Set the list of ciphers to be used in this context.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800819
Hynek Schlawackf90e3682016-03-11 11:21:13 +0100820 See the OpenSSL manual for more information (e.g.
821 :manpage:`ciphers(1)`).
822
823 :param bytes cipher_list: An OpenSSL cipher string.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800824 :return: None
825 """
Hynek Schlawackf90e3682016-03-11 11:21:13 +0100826 cipher_list = _text_to_bytes_and_warn("cipher_list", cipher_list)
Jean-Paul Calderone63eab692014-01-18 10:19:56 -0500827
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800828 if not isinstance(cipher_list, bytes):
Hynek Schlawacka7a63af2016-03-11 12:05:26 +0100829 raise TypeError("cipher_list must be a byte string.")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800830
Hynek Schlawackf90e3682016-03-11 11:21:13 +0100831 _openssl_assert(
Hynek Schlawack22a4b662016-03-11 14:59:39 +0100832 _lib.SSL_CTX_set_cipher_list(self._context, cipher_list) == 1
Hynek Schlawackf90e3682016-03-11 11:21:13 +0100833 )
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800834
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800835 def set_client_ca_list(self, certificate_authorities):
836 """
Alex Gaynor62da94d2015-09-05 14:37:34 -0400837 Set the list of preferred client certificate signers for this server
838 context.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800839
Alex Gaynor62da94d2015-09-05 14:37:34 -0400840 This list of certificate authorities will be sent to the client when
841 the server requests a client certificate.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800842
843 :param certificate_authorities: a sequence of X509Names.
844 :return: None
845 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500846 name_stack = _lib.sk_X509_NAME_new_null()
Alex Gaynora829e902016-06-04 18:16:01 -0700847 _openssl_assert(name_stack != _ffi.NULL)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800848
849 try:
850 for ca_name in certificate_authorities:
851 if not isinstance(ca_name, X509Name):
852 raise TypeError(
Alex Gaynor62da94d2015-09-05 14:37:34 -0400853 "client CAs must be X509Name objects, not %s "
854 "objects" % (
855 type(ca_name).__name__,
856 )
857 )
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500858 copy = _lib.X509_NAME_dup(ca_name._name)
Alex Gaynora829e902016-06-04 18:16:01 -0700859 _openssl_assert(copy != _ffi.NULL)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500860 push_result = _lib.sk_X509_NAME_push(name_stack, copy)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800861 if not push_result:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500862 _lib.X509_NAME_free(copy)
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -0500863 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800864 except:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500865 _lib.sk_X509_NAME_free(name_stack)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800866 raise
867
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500868 _lib.SSL_CTX_set_client_CA_list(self._context, name_stack)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800869
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800870 def add_client_ca(self, certificate_authority):
871 """
Alex Gaynor62da94d2015-09-05 14:37:34 -0400872 Add the CA certificate to the list of preferred signers for this
873 context.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800874
875 The list of certificate authorities will be sent to the client when the
876 server requests a client certificate.
877
878 :param certificate_authority: certificate authority's X509 certificate.
879 :return: None
880 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800881 if not isinstance(certificate_authority, X509):
882 raise TypeError("certificate_authority must be an X509 instance")
883
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500884 add_result = _lib.SSL_CTX_add_client_CA(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800885 self._context, certificate_authority._x509)
Alex Gaynor09f19f52016-07-03 09:54:09 -0400886 _openssl_assert(add_result == 1)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800887
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800888 def set_timeout(self, timeout):
889 """
890 Set session timeout
891
892 :param timeout: The timeout in seconds
893 :return: The previous session timeout
894 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500895 if not isinstance(timeout, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800896 raise TypeError("timeout must be an integer")
897
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500898 return _lib.SSL_CTX_set_timeout(self._context, timeout)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800899
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800900 def get_timeout(self):
901 """
902 Get the session timeout
903
904 :return: The session timeout
905 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500906 return _lib.SSL_CTX_get_timeout(self._context)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800907
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800908 def set_info_callback(self, callback):
909 """
910 Set the info callback
911
912 :param callback: The Python callback to use
913 :return: None
914 """
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800915 @wraps(callback)
916 def wrapper(ssl, where, return_code):
Jean-Paul Calderonef2bbc9c2014-02-02 10:59:14 -0500917 callback(Connection._reverse_mapping[ssl], where, return_code)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500918 self._info_callback = _ffi.callback(
919 "void (*)(const SSL *, int, int)", wrapper)
920 _lib.SSL_CTX_set_info_callback(self._context, self._info_callback)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800921
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800922 def get_app_data(self):
923 """
924 Get the application data (supplied via set_app_data())
925
926 :return: The application data
927 """
928 return self._app_data
929
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800930 def set_app_data(self, data):
931 """
932 Set the application data (will be returned from get_app_data())
933
934 :param data: Any Python object
935 :return: None
936 """
937 self._app_data = data
938
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800939 def get_cert_store(self):
940 """
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500941 Get the certificate store for the context.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800942
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500943 :return: A X509Store object or None if it does not have one.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800944 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500945 store = _lib.SSL_CTX_get_cert_store(self._context)
946 if store == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -0500947 # TODO: This is untested.
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800948 return None
949
950 pystore = X509Store.__new__(X509Store)
951 pystore._store = store
952 return pystore
953
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800954 def set_options(self, options):
955 """
956 Add options. Options set before are not cleared!
957
958 :param options: The options to add.
959 :return: The new option bitmask.
960 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500961 if not isinstance(options, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800962 raise TypeError("options must be an integer")
963
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500964 return _lib.SSL_CTX_set_options(self._context, options)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800965
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800966 def set_mode(self, mode):
967 """
968 Add modes via bitmask. Modes set before are not cleared!
969
970 :param mode: The mode to add.
971 :return: The new mode bitmask.
972 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500973 if not isinstance(mode, integer_types):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800974 raise TypeError("mode must be an integer")
975
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500976 return _lib.SSL_CTX_set_mode(self._context, mode)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800977
Cory Benfielde6f35882016-03-29 11:21:04 +0100978 @_requires_sni
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800979 def set_tlsext_servername_callback(self, callback):
980 """
Alex Gaynor62da94d2015-09-05 14:37:34 -0400981 Specify a callback function to be called when clients specify a server
982 name.
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800983
984 :param callback: The callback function. It will be invoked with one
985 argument, the Connection instance.
986 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800987 @wraps(callback)
988 def wrapper(ssl, alert, arg):
989 callback(Connection._reverse_mapping[ssl])
990 return 0
991
Jean-Paul Calderone6037d072013-12-28 18:04:00 -0500992 self._tlsext_servername_callback = _ffi.callback(
993 "int (*)(const SSL *, int *, void *)", wrapper)
994 _lib.SSL_CTX_set_tlsext_servername_callback(
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800995 self._context, self._tlsext_servername_callback)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800996
Cory Benfield10b277f2015-04-13 17:12:42 -0400997 @_requires_npn
Cory Benfield84a121e2014-03-31 20:30:25 +0100998 def set_npn_advertise_callback(self, callback):
999 """
Cory Benfieldbe3e7b82014-05-10 09:48:55 +01001000 Specify a callback function that will be called when offering `Next
1001 Protocol Negotiation
1002 <https://technotes.googlecode.com/git/nextprotoneg.html>`_ as a server.
Cory Benfield84a121e2014-03-31 20:30:25 +01001003
1004 :param callback: The callback function. It will be invoked with one
Cory Benfieldbe3e7b82014-05-10 09:48:55 +01001005 argument, the Connection instance. It should return a list of
1006 bytestrings representing the advertised protocols, like
1007 ``[b'http/1.1', b'spdy/2']``.
Cory Benfield84a121e2014-03-31 20:30:25 +01001008 """
Cory Benfield0ea76e72015-03-22 09:05:28 +00001009 self._npn_advertise_helper = _NpnAdvertiseHelper(callback)
1010 self._npn_advertise_callback = self._npn_advertise_helper.callback
Cory Benfield84a121e2014-03-31 20:30:25 +01001011 _lib.SSL_CTX_set_next_protos_advertised_cb(
1012 self._context, self._npn_advertise_callback, _ffi.NULL)
1013
Cory Benfield10b277f2015-04-13 17:12:42 -04001014 @_requires_npn
Cory Benfield84a121e2014-03-31 20:30:25 +01001015 def set_npn_select_callback(self, callback):
1016 """
1017 Specify a callback function that will be called when a server offers
1018 Next Protocol Negotiation options.
1019
1020 :param callback: The callback function. It will be invoked with two
1021 arguments: the Connection, and a list of offered protocols as
Cory Benfieldbe3e7b82014-05-10 09:48:55 +01001022 bytestrings, e.g. ``[b'http/1.1', b'spdy/2']``. It should return
1023 one of those bytestrings, the chosen protocol.
Cory Benfield84a121e2014-03-31 20:30:25 +01001024 """
Cory Benfield0ea76e72015-03-22 09:05:28 +00001025 self._npn_select_helper = _NpnSelectHelper(callback)
1026 self._npn_select_callback = self._npn_select_helper.callback
Cory Benfield84a121e2014-03-31 20:30:25 +01001027 _lib.SSL_CTX_set_next_proto_select_cb(
1028 self._context, self._npn_select_callback, _ffi.NULL)
1029
Cory Benfield7907e332015-04-13 17:18:25 -04001030 @_requires_alpn
Cory Benfield12eae892014-06-07 15:42:56 +01001031 def set_alpn_protos(self, protos):
1032 """
Cory Benfielde8e9c382015-04-11 17:33:48 -04001033 Specify the clients ALPN protocol list.
1034
1035 These protocols are offered to the server during protocol negotiation.
Cory Benfield12eae892014-06-07 15:42:56 +01001036
1037 :param protos: A list of the protocols to be offered to the server.
1038 This list should be a Python list of bytestrings representing the
1039 protocols to offer, e.g. ``[b'http/1.1', b'spdy/2']``.
1040 """
1041 # Take the list of protocols and join them together, prefixing them
1042 # with their lengths.
1043 protostr = b''.join(
1044 chain.from_iterable((int2byte(len(p)), p) for p in protos)
1045 )
1046
1047 # Build a C string from the list. We don't need to save this off
1048 # because OpenSSL immediately copies the data out.
1049 input_str = _ffi.new("unsigned char[]", protostr)
Cory Benfielde871af52015-04-11 17:57:50 -04001050 input_str_len = _ffi.cast("unsigned", len(protostr))
1051 _lib.SSL_CTX_set_alpn_protos(self._context, input_str, input_str_len)
Cory Benfield12eae892014-06-07 15:42:56 +01001052
Cory Benfield7907e332015-04-13 17:18:25 -04001053 @_requires_alpn
Cory Benfield12eae892014-06-07 15:42:56 +01001054 def set_alpn_select_callback(self, callback):
1055 """
Cory Benfielde8e9c382015-04-11 17:33:48 -04001056 Set the callback to handle ALPN protocol choice.
Cory Benfield12eae892014-06-07 15:42:56 +01001057
1058 :param callback: The callback function. It will be invoked with two
1059 arguments: the Connection, and a list of offered protocols as
1060 bytestrings, e.g ``[b'http/1.1', b'spdy/2']``. It should return
Cory Benfielde8e9c382015-04-11 17:33:48 -04001061 one of those bytestrings, the chosen protocol.
Cory Benfield12eae892014-06-07 15:42:56 +01001062 """
Cory Benfield9da5ffb2015-04-13 17:20:14 -04001063 self._alpn_select_helper = _ALPNSelectHelper(callback)
Cory Benfieldf1177e72015-04-12 09:11:49 -04001064 self._alpn_select_callback = self._alpn_select_helper.callback
Cory Benfield12eae892014-06-07 15:42:56 +01001065 _lib.SSL_CTX_set_alpn_select_cb(
1066 self._context, self._alpn_select_callback, _ffi.NULL)
1067
Alex Chanc6077062016-11-18 13:53:39 +00001068
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -08001069ContextType = Context
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001070
1071
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001072class Connection(object):
1073 """
1074 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001075 _reverse_mapping = WeakValueDictionary()
1076
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001077 def __init__(self, context, socket=None):
1078 """
1079 Create a new Connection object, using the given OpenSSL.SSL.Context
1080 instance and socket.
1081
1082 :param context: An SSL Context to use for this connection
1083 :param socket: The socket to use for transport layer
1084 """
1085 if not isinstance(context, Context):
1086 raise TypeError("context must be a Context instance")
1087
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001088 ssl = _lib.SSL_new(context._context)
1089 self._ssl = _ffi.gc(ssl, _lib.SSL_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001090 self._context = context
Todd Chapman4f73e4f2015-08-27 11:26:43 -04001091 self._app_data = None
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001092
Cory Benfieldbe3e7b82014-05-10 09:48:55 +01001093 # References to strings used for Next Protocol Negotiation. OpenSSL's
1094 # header files suggest that these might get copied at some point, but
1095 # doesn't specify when, so we store them here to make sure they don't
1096 # get freed before OpenSSL uses them.
1097 self._npn_advertise_callback_args = None
1098 self._npn_select_callback_args = None
1099
Cory Benfield12eae892014-06-07 15:42:56 +01001100 # References to strings used for Application Layer Protocol
1101 # Negotiation. These strings get copied at some point but it's well
1102 # after the callback returns, so we have to hang them somewhere to
1103 # avoid them getting freed.
1104 self._alpn_select_callback_args = None
1105
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001106 self._reverse_mapping[self._ssl] = self
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001107
1108 if socket is None:
1109 self._socket = None
Jean-Paul Calderone73b15c22013-03-05 18:30:39 -08001110 # Don't set up any gc for these, SSL_free will take care of them.
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001111 self._into_ssl = _lib.BIO_new(_lib.BIO_s_mem())
Alex Gaynora829e902016-06-04 18:16:01 -07001112 _openssl_assert(self._into_ssl != _ffi.NULL)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001113
Alex Gaynora829e902016-06-04 18:16:01 -07001114 self._from_ssl = _lib.BIO_new(_lib.BIO_s_mem())
1115 _openssl_assert(self._from_ssl != _ffi.NULL)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001116
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001117 _lib.SSL_set_bio(self._ssl, self._into_ssl, self._from_ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001118 else:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001119 self._into_ssl = None
1120 self._from_ssl = None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001121 self._socket = socket
Alex Gaynor62da94d2015-09-05 14:37:34 -04001122 set_result = _lib.SSL_set_fd(
1123 self._ssl, _asFileDescriptor(self._socket))
Alex Gaynor09f19f52016-07-03 09:54:09 -04001124 _openssl_assert(set_result == 1)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001125
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001126 def __getattr__(self, name):
1127 """
Alex Gaynor62da94d2015-09-05 14:37:34 -04001128 Look up attributes on the wrapped socket object if they are not found
1129 on the Connection object.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001130 """
kjav0b66fa12015-09-02 11:51:26 +01001131 if self._socket is None:
Alex Gaynor62da94d2015-09-05 14:37:34 -04001132 raise AttributeError("'%s' object has no attribute '%s'" % (
1133 self.__class__.__name__, name
1134 ))
kjav0b66fa12015-09-02 11:51:26 +01001135 else:
1136 return getattr(self._socket, name)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001137
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001138 def _raise_ssl_error(self, ssl, result):
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -08001139 if self._context._verify_helper is not None:
1140 self._context._verify_helper.raise_if_problem()
Cory Benfield0ea76e72015-03-22 09:05:28 +00001141 if self._context._npn_advertise_helper is not None:
1142 self._context._npn_advertise_helper.raise_if_problem()
1143 if self._context._npn_select_helper is not None:
1144 self._context._npn_select_helper.raise_if_problem()
Cory Benfieldf1177e72015-04-12 09:11:49 -04001145 if self._context._alpn_select_helper is not None:
1146 self._context._alpn_select_helper.raise_if_problem()
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -08001147
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001148 error = _lib.SSL_get_error(ssl, result)
1149 if error == _lib.SSL_ERROR_WANT_READ:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001150 raise WantReadError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001151 elif error == _lib.SSL_ERROR_WANT_WRITE:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001152 raise WantWriteError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001153 elif error == _lib.SSL_ERROR_ZERO_RETURN:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001154 raise ZeroReturnError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001155 elif error == _lib.SSL_ERROR_WANT_X509_LOOKUP:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001156 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001157 raise WantX509LookupError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001158 elif error == _lib.SSL_ERROR_SYSCALL:
1159 if _lib.ERR_peek_error() == 0:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001160 if result < 0:
Konstantinos Koukopoulos541150d2014-01-31 01:00:19 +02001161 if platform == "win32":
1162 errno = _ffi.getwinerror()[0]
1163 else:
1164 errno = _ffi.errno
Alex Gaynor5af32d02016-09-24 01:52:21 -04001165
1166 if errno != 0:
1167 raise SysCallError(errno, errorcode.get(errno))
1168 raise SysCallError(-1, "Unexpected EOF")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001169 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001170 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001171 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001172 elif error == _lib.SSL_ERROR_NONE:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001173 pass
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001174 else:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001175 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001176
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001177 def get_context(self):
1178 """
1179 Get session context
1180 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001181 return self._context
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001182
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001183 def set_context(self, context):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001184 """
1185 Switch this connection to a new session context
1186
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001187 :param context: A :py:class:`Context` instance giving the new session
1188 context to use.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001189 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001190 if not isinstance(context, Context):
1191 raise TypeError("context must be a Context instance")
1192
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001193 _lib.SSL_set_SSL_CTX(self._ssl, context._context)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001194 self._context = context
1195
Cory Benfielde6f35882016-03-29 11:21:04 +01001196 @_requires_sni
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001197 def get_servername(self):
1198 """
1199 Retrieve the servername extension value if provided in the client hello
1200 message, or None if there wasn't one.
1201
1202 :return: A byte string giving the server name or :py:data:`None`.
1203 """
Alex Gaynor62da94d2015-09-05 14:37:34 -04001204 name = _lib.SSL_get_servername(
1205 self._ssl, _lib.TLSEXT_NAMETYPE_host_name
1206 )
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001207 if name == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001208 return None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001209
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001210 return _ffi.string(name)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001211
Cory Benfielde6f35882016-03-29 11:21:04 +01001212 @_requires_sni
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001213 def set_tlsext_host_name(self, name):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001214 """
1215 Set the value of the servername extension to send in the client hello.
1216
1217 :param name: A byte string giving the name.
1218 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001219 if not isinstance(name, bytes):
1220 raise TypeError("name must be a byte string")
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001221 elif b"\0" in name:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001222 raise TypeError("name must not contain NUL byte")
1223
1224 # XXX I guess this can fail sometimes?
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001225 _lib.SSL_set_tlsext_host_name(self._ssl, name)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001226
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001227 def pending(self):
1228 """
1229 Get the number of bytes that can be safely read from the connection
1230
1231 :return: The number of bytes available in the receive buffer.
1232 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001233 return _lib.SSL_pending(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001234
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001235 def send(self, buf, flags=0):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001236 """
1237 Send data on the connection. NOTE: If you get one of the WantRead,
1238 WantWrite or WantX509Lookup exceptions on this, you have to call the
1239 method again with the SAME buffer.
1240
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001241 :param buf: The string, buffer or memoryview to send
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001242 :param flags: (optional) Included for compatibility with the socket
1243 API, the value is ignored
1244 :return: The number of bytes written
1245 """
Abraham Martine82326c2015-02-04 10:18:10 +00001246 # Backward compatibility
Jean-Paul Calderone39a8d592015-04-13 20:49:50 -04001247 buf = _text_to_bytes_and_warn("buf", buf)
Abraham Martine82326c2015-02-04 10:18:10 +00001248
Jean-Paul Calderone8fb53182013-12-30 08:35:49 -05001249 if isinstance(buf, _memoryview):
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -08001250 buf = buf.tobytes()
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001251 if isinstance(buf, _buffer):
1252 buf = str(buf)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001253 if not isinstance(buf, bytes):
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001254 raise TypeError("data must be a memoryview, buffer or byte string")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001255
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001256 result = _lib.SSL_write(self._ssl, buf, len(buf))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001257 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001258 return result
1259 write = send
1260
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001261 def sendall(self, buf, flags=0):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001262 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001263 Send "all" data on the connection. This calls send() repeatedly until
1264 all data is sent. If an error occurs, it's impossible to tell how much
1265 data has been sent.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001266
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001267 :param buf: The string, buffer or memoryview to send
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001268 :param flags: (optional) Included for compatibility with the socket
1269 API, the value is ignored
1270 :return: The number of bytes written
1271 """
Jean-Paul Calderone39a8d592015-04-13 20:49:50 -04001272 buf = _text_to_bytes_and_warn("buf", buf)
Abraham Martine82326c2015-02-04 10:18:10 +00001273
Jean-Paul Calderone8fb53182013-12-30 08:35:49 -05001274 if isinstance(buf, _memoryview):
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -08001275 buf = buf.tobytes()
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001276 if isinstance(buf, _buffer):
1277 buf = str(buf)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001278 if not isinstance(buf, bytes):
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001279 raise TypeError("buf must be a memoryview, buffer or byte string")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001280
1281 left_to_send = len(buf)
1282 total_sent = 0
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001283 data = _ffi.new("char[]", buf)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001284
1285 while left_to_send:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001286 result = _lib.SSL_write(self._ssl, data + total_sent, left_to_send)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001287 self._raise_ssl_error(self._ssl, result)
1288 total_sent += result
1289 left_to_send -= result
1290
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001291 def recv(self, bufsiz, flags=None):
1292 """
Alex Gaynor67fc8c92016-05-27 08:27:19 -04001293 Receive data on the connection.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001294
1295 :param bufsiz: The maximum number of bytes to read
Maximilian Hils1d95dea2015-08-17 19:27:20 +02001296 :param flags: (optional) The only supported flag is ``MSG_PEEK``,
1297 all other flags are ignored.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001298 :return: The string read from the Connection
1299 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001300 buf = _ffi.new("char[]", bufsiz)
Maximilian Hils1d95dea2015-08-17 19:27:20 +02001301 if flags is not None and flags & socket.MSG_PEEK:
1302 result = _lib.SSL_peek(self._ssl, buf, bufsiz)
1303 else:
1304 result = _lib.SSL_read(self._ssl, buf, bufsiz)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001305 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001306 return _ffi.buffer(buf, result)[:]
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001307 read = recv
1308
Cory Benfield62d10332014-06-15 10:03:41 +01001309 def recv_into(self, buffer, nbytes=None, flags=None):
1310 """
1311 Receive data on the connection and store the data into a buffer rather
1312 than creating a new string.
1313
1314 :param buffer: The buffer to copy into.
1315 :param nbytes: (optional) The maximum number of bytes to read into the
1316 buffer. If not present, defaults to the size of the buffer. If
1317 larger than the size of the buffer, is reduced to the size of the
1318 buffer.
Maximilian Hils1d95dea2015-08-17 19:27:20 +02001319 :param flags: (optional) The only supported flag is ``MSG_PEEK``,
1320 all other flags are ignored.
Cory Benfield62d10332014-06-15 10:03:41 +01001321 :return: The number of bytes read into the buffer.
1322 """
1323 if nbytes is None:
1324 nbytes = len(buffer)
1325 else:
1326 nbytes = min(nbytes, len(buffer))
1327
1328 # We need to create a temporary buffer. This is annoying, it would be
1329 # better if we could pass memoryviews straight into the SSL_read call,
1330 # but right now we can't. Revisit this if CFFI gets that ability.
1331 buf = _ffi.new("char[]", nbytes)
Maximilian Hils1d95dea2015-08-17 19:27:20 +02001332 if flags is not None and flags & socket.MSG_PEEK:
1333 result = _lib.SSL_peek(self._ssl, buf, nbytes)
1334 else:
1335 result = _lib.SSL_read(self._ssl, buf, nbytes)
Cory Benfield62d10332014-06-15 10:03:41 +01001336 self._raise_ssl_error(self._ssl, result)
1337
1338 # This strange line is all to avoid a memory copy. The buffer protocol
1339 # should allow us to assign a CFFI buffer to the LHS of this line, but
1340 # on CPython 3.3+ that segfaults. As a workaround, we can temporarily
1341 # wrap it in a memoryview, except on Python 2.6 which doesn't have a
1342 # memoryview type.
1343 try:
1344 buffer[:result] = memoryview(_ffi.buffer(buf, result))
1345 except NameError:
1346 buffer[:result] = _ffi.buffer(buf, result)
1347
1348 return result
1349
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001350 def _handle_bio_errors(self, bio, result):
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001351 if _lib.BIO_should_retry(bio):
1352 if _lib.BIO_should_read(bio):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001353 raise WantReadError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001354 elif _lib.BIO_should_write(bio):
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001355 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001356 raise WantWriteError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001357 elif _lib.BIO_should_io_special(bio):
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001358 # TODO: This is untested. I think io_special means the socket
1359 # BIO has a not-yet connected socket.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001360 raise ValueError("BIO_should_io_special")
1361 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001362 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001363 raise ValueError("unknown bio failure")
1364 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001365 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001366 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001367
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001368 def bio_read(self, bufsiz):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001369 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001370 When using non-socket connections this function reads the "dirty" data
1371 that would have traveled away on the network.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001372
1373 :param bufsiz: The maximum number of bytes to read
1374 :return: The string read.
1375 """
Jean-Paul Calderone97e041d2013-03-05 21:03:12 -08001376 if self._from_ssl is None:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001377 raise TypeError("Connection sock was not None")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001378
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -05001379 if not isinstance(bufsiz, integer_types):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001380 raise TypeError("bufsiz must be an integer")
1381
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001382 buf = _ffi.new("char[]", bufsiz)
1383 result = _lib.BIO_read(self._from_ssl, buf, bufsiz)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001384 if result <= 0:
1385 self._handle_bio_errors(self._from_ssl, result)
1386
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001387 return _ffi.buffer(buf, result)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001388
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001389 def bio_write(self, buf):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001390 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001391 When using non-socket connections this function sends "dirty" data that
1392 would have traveled in on the network.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001393
1394 :param buf: The string to put into the memory BIO.
1395 :return: The number of bytes written
1396 """
Jean-Paul Calderone39a8d592015-04-13 20:49:50 -04001397 buf = _text_to_bytes_and_warn("buf", buf)
Abraham Martine82326c2015-02-04 10:18:10 +00001398
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001399 if self._into_ssl is None:
1400 raise TypeError("Connection sock was not None")
1401
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001402 result = _lib.BIO_write(self._into_ssl, buf, len(buf))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001403 if result <= 0:
1404 self._handle_bio_errors(self._into_ssl, result)
1405 return result
1406
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001407 def renegotiate(self):
1408 """
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +01001409 Renegotiate the session.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001410
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +01001411 :return: True if the renegotiation can be started, False otherwise
1412 :rtype: bool
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001413 """
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +01001414 if not self.renegotiate_pending():
1415 _openssl_assert(_lib.SSL_renegotiate(self._ssl) == 1)
1416 return True
1417 return False
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001418
1419 def do_handshake(self):
1420 """
1421 Perform an SSL handshake (usually called after renegotiate() or one of
1422 set_*_state()). This can raise the same exceptions as send and recv.
1423
1424 :return: None.
1425 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001426 result = _lib.SSL_do_handshake(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001427 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001428
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001429 def renegotiate_pending(self):
1430 """
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +01001431 Check if there's a renegotiation in progress, it will return False once
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001432 a renegotiation is finished.
1433
1434 :return: Whether there's a renegotiation in progress
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +01001435 :rtype: bool
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001436 """
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +01001437 return _lib.SSL_renegotiate_pending(self._ssl) == 1
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001438
1439 def total_renegotiations(self):
1440 """
1441 Find out the total number of renegotiations.
1442
1443 :return: The number of renegotiations.
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +01001444 :rtype: int
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001445 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001446 return _lib.SSL_total_renegotiations(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001447
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001448 def connect(self, addr):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001449 """
1450 Connect to remote host and set up client-side SSL
1451
1452 :param addr: A remote address
1453 :return: What the socket's connect method returns
1454 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001455 _lib.SSL_set_connect_state(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001456 return self._socket.connect(addr)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001457
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001458 def connect_ex(self, addr):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001459 """
Alex Gaynor62da94d2015-09-05 14:37:34 -04001460 Connect to remote host and set up client-side SSL. Note that if the
1461 socket's connect_ex method doesn't return 0, SSL won't be initialized.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001462
1463 :param addr: A remove address
1464 :return: What the socket's connect_ex method returns
1465 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001466 connect_ex = self._socket.connect_ex
1467 self.set_connect_state()
1468 return connect_ex(addr)
1469
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001470 def accept(self):
1471 """
1472 Accept incoming connection and set up SSL on it
1473
1474 :return: A (conn,addr) pair where conn is a Connection and addr is an
1475 address
1476 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001477 client, addr = self._socket.accept()
1478 conn = Connection(self._context, client)
1479 conn.set_accept_state()
1480 return (conn, addr)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001481
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001482 def bio_shutdown(self):
1483 """
1484 When using non-socket connections this function signals end of
1485 data on the input for this connection.
1486
1487 :return: None
1488 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001489 if self._from_ssl is None:
1490 raise TypeError("Connection sock was not None")
1491
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001492 _lib.BIO_set_mem_eof_return(self._into_ssl, 0)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001493
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001494 def shutdown(self):
1495 """
1496 Send closure alert
1497
1498 :return: True if the shutdown completed successfully (i.e. both sides
1499 have sent closure alerts), false otherwise (i.e. you have to
1500 wait for a ZeroReturnError on a recv() method call
1501 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001502 result = _lib.SSL_shutdown(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001503 if result < 0:
Paul Aurichbff1d1a2015-01-08 08:36:53 -08001504 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001505 elif result > 0:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001506 return True
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001507 else:
1508 return False
1509
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001510 def get_cipher_list(self):
1511 """
Hynek Schlawackf90e3682016-03-11 11:21:13 +01001512 Retrieve the list of ciphers used by the Connection object.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001513
Hynek Schlawackf90e3682016-03-11 11:21:13 +01001514 :return: A list of native cipher strings.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001515 """
1516 ciphers = []
1517 for i in count():
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001518 result = _lib.SSL_get_cipher_list(self._ssl, i)
1519 if result == _ffi.NULL:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001520 break
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001521 ciphers.append(_native(_ffi.string(result)))
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001522 return ciphers
1523
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001524 def get_client_ca_list(self):
1525 """
1526 Get CAs whose certificates are suggested for client authentication.
1527
Alex Gaynor62da94d2015-09-05 14:37:34 -04001528 :return: If this is a server connection, a list of X509Names
1529 representing the acceptable CAs as set by
1530 :py:meth:`OpenSSL.SSL.Context.set_client_ca_list` or
1531 :py:meth:`OpenSSL.SSL.Context.add_client_ca`. If this is a client
1532 connection, the list of such X509Names sent by the server, or an
1533 empty list if that has not yet happened.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001534 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001535 ca_names = _lib.SSL_get_client_CA_list(self._ssl)
1536 if ca_names == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001537 # TODO: This is untested.
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001538 return []
1539
1540 result = []
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001541 for i in range(_lib.sk_X509_NAME_num(ca_names)):
1542 name = _lib.sk_X509_NAME_value(ca_names, i)
1543 copy = _lib.X509_NAME_dup(name)
Alex Gaynora829e902016-06-04 18:16:01 -07001544 _openssl_assert(copy != _ffi.NULL)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001545
1546 pyname = X509Name.__new__(X509Name)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001547 pyname._name = _ffi.gc(copy, _lib.X509_NAME_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001548 result.append(pyname)
1549 return result
1550
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001551 def makefile(self):
1552 """
Alex Gaynor62da94d2015-09-05 14:37:34 -04001553 The makefile() method is not implemented, since there is no dup
1554 semantics for SSL connections
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001555
Jean-Paul Calderone6749ec22014-04-17 16:30:21 -04001556 :raise: NotImplementedError
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001557 """
Alex Gaynor83284952015-09-05 10:43:30 -04001558 raise NotImplementedError(
1559 "Cannot make file object of OpenSSL.SSL.Connection")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001560
1561 def get_app_data(self):
1562 """
1563 Get application data
1564
1565 :return: The application data
1566 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001567 return self._app_data
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001568
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001569 def set_app_data(self, data):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001570 """
1571 Set application data
1572
1573 :param data - The application data
1574 :return: None
1575 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001576 self._app_data = data
1577
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001578 def get_shutdown(self):
1579 """
1580 Get shutdown state
1581
Alex Gaynor62da94d2015-09-05 14:37:34 -04001582 :return: The shutdown state, a bitvector of SENT_SHUTDOWN,
1583 RECEIVED_SHUTDOWN.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001584 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001585 return _lib.SSL_get_shutdown(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001586
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001587 def set_shutdown(self, state):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001588 """
1589 Set shutdown state
1590
1591 :param state - bitvector of SENT_SHUTDOWN, RECEIVED_SHUTDOWN.
1592 :return: None
1593 """
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -05001594 if not isinstance(state, integer_types):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001595 raise TypeError("state must be an integer")
1596
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001597 _lib.SSL_set_shutdown(self._ssl, state)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001598
Hynek Schlawackea94f2b2016-03-13 16:17:53 +01001599 def get_state_string(self):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001600 """
Hynek Schlawackea94f2b2016-03-13 16:17:53 +01001601 Retrieve a verbose string detailing the state of the Connection.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001602
1603 :return: A string representing the state
Hynek Schlawackea94f2b2016-03-13 16:17:53 +01001604 :rtype: bytes
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001605 """
kjavc704a2e2015-09-07 12:12:27 +01001606 return _ffi.string(_lib.SSL_state_string_long(self._ssl))
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001607
1608 def server_random(self):
1609 """
1610 Get a copy of the server hello nonce.
1611
1612 :return: A string representing the state
1613 """
Alex Gaynor93603062016-06-01 20:13:09 -07001614 session = _lib.SSL_get_session(self._ssl)
1615 if session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001616 return None
Alex Gaynor93603062016-06-01 20:13:09 -07001617 length = _lib.SSL_get_server_random(self._ssl, _ffi.NULL, 0)
1618 assert length > 0
Paul Kehrer9f9113a2016-09-20 20:10:25 -05001619 outp = _ffi.new("unsigned char[]", length)
Alex Gaynor93603062016-06-01 20:13:09 -07001620 _lib.SSL_get_server_random(self._ssl, outp, length)
1621 return _ffi.buffer(outp, length)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001622
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001623 def client_random(self):
1624 """
1625 Get a copy of the client hello nonce.
1626
1627 :return: A string representing the state
1628 """
Alex Gaynor93603062016-06-01 20:13:09 -07001629 session = _lib.SSL_get_session(self._ssl)
1630 if session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001631 return None
Alex Gaynor93603062016-06-01 20:13:09 -07001632
1633 length = _lib.SSL_get_client_random(self._ssl, _ffi.NULL, 0)
1634 assert length > 0
Paul Kehrer9f9113a2016-09-20 20:10:25 -05001635 outp = _ffi.new("unsigned char[]", length)
Alex Gaynor93603062016-06-01 20:13:09 -07001636 _lib.SSL_get_client_random(self._ssl, outp, length)
1637 return _ffi.buffer(outp, length)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001638
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001639 def master_key(self):
1640 """
1641 Get a copy of the master key.
1642
1643 :return: A string representing the state
1644 """
Alex Gaynor93603062016-06-01 20:13:09 -07001645 session = _lib.SSL_get_session(self._ssl)
1646 if session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001647 return None
Alex Gaynor93603062016-06-01 20:13:09 -07001648
1649 length = _lib.SSL_SESSION_get_master_key(session, _ffi.NULL, 0)
1650 assert length > 0
Paul Kehrer9f9113a2016-09-20 20:10:25 -05001651 outp = _ffi.new("unsigned char[]", length)
Alex Gaynor93603062016-06-01 20:13:09 -07001652 _lib.SSL_SESSION_get_master_key(session, outp, length)
1653 return _ffi.buffer(outp, length)[:]
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001654
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001655 def sock_shutdown(self, *args, **kwargs):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001656 """
1657 See shutdown(2)
1658
1659 :return: What the socket's shutdown() method returns
1660 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001661 return self._socket.shutdown(*args, **kwargs)
1662
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001663 def get_peer_certificate(self):
1664 """
1665 Retrieve the other side's certificate (if any)
1666
1667 :return: The peer's certificate
1668 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001669 cert = _lib.SSL_get_peer_certificate(self._ssl)
1670 if cert != _ffi.NULL:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001671 pycert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001672 pycert._x509 = _ffi.gc(cert, _lib.X509_free)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001673 return pycert
1674 return None
1675
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001676 def get_peer_cert_chain(self):
1677 """
1678 Retrieve the other side's certificate (if any)
1679
1680 :return: A list of X509 instances giving the peer's certificate chain,
1681 or None if it does not have one.
1682 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001683 cert_stack = _lib.SSL_get_peer_cert_chain(self._ssl)
1684 if cert_stack == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001685 return None
1686
1687 result = []
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001688 for i in range(_lib.sk_X509_num(cert_stack)):
Jean-Paul Calderone73b15c22013-03-05 18:30:39 -08001689 # TODO could incref instead of dup here
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001690 cert = _lib.X509_dup(_lib.sk_X509_value(cert_stack, i))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001691 pycert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001692 pycert._x509 = _ffi.gc(cert, _lib.X509_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001693 result.append(pycert)
1694 return result
1695
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001696 def want_read(self):
1697 """
Alex Gaynor62da94d2015-09-05 14:37:34 -04001698 Checks if more data has to be read from the transport layer to complete
1699 an operation.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001700
1701 :return: True iff more data has to be read
1702 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001703 return _lib.SSL_want_read(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001704
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001705 def want_write(self):
1706 """
1707 Checks if there is data to write to the transport layer to complete an
1708 operation.
1709
1710 :return: True iff there is data to write
1711 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001712 return _lib.SSL_want_write(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001713
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001714 def set_accept_state(self):
1715 """
Alex Gaynor62da94d2015-09-05 14:37:34 -04001716 Set the connection to work in server mode. The handshake will be
1717 handled automatically by read/write.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001718
1719 :return: None
1720 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001721 _lib.SSL_set_accept_state(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001722
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001723 def set_connect_state(self):
1724 """
Alex Gaynor62da94d2015-09-05 14:37:34 -04001725 Set the connection to work in client mode. The handshake will be
1726 handled automatically by read/write.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001727
1728 :return: None
1729 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001730 _lib.SSL_set_connect_state(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001731
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001732 def get_session(self):
1733 """
1734 Returns the Session currently used.
1735
Alex Gaynor62da94d2015-09-05 14:37:34 -04001736 @return: An instance of :py:class:`OpenSSL.SSL.Session` or
1737 :py:obj:`None` if no session exists.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001738 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001739 session = _lib.SSL_get1_session(self._ssl)
1740 if session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001741 return None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001742
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001743 pysession = Session.__new__(Session)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001744 pysession._session = _ffi.gc(session, _lib.SSL_SESSION_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001745 return pysession
1746
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001747 def set_session(self, session):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001748 """
1749 Set the session to be used when the TLS/SSL connection is established.
1750
1751 :param session: A Session instance representing the session to use.
1752 :returns: None
1753 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001754 if not isinstance(session, Session):
1755 raise TypeError("session must be a Session instance")
1756
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001757 result = _lib.SSL_set_session(self._ssl, session._session)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001758 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001759 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001760
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001761 def _get_finished_message(self, function):
1762 """
1763 Helper to implement :py:meth:`get_finished` and
1764 :py:meth:`get_peer_finished`.
1765
1766 :param function: Either :py:data:`SSL_get_finished`: or
1767 :py:data:`SSL_get_peer_finished`.
1768
1769 :return: :py:data:`None` if the desired message has not yet been
1770 received, otherwise the contents of the message.
1771 :rtype: :py:class:`bytes` or :py:class:`NoneType`
1772 """
Jean-Paul Calderone01af9042014-03-30 11:40:42 -04001773 # The OpenSSL documentation says nothing about what might happen if the
1774 # count argument given is zero. Specifically, it doesn't say whether
1775 # the output buffer may be NULL in that case or not. Inspection of the
1776 # implementation reveals that it calls memcpy() unconditionally.
1777 # Section 7.1.4, paragraph 1 of the C standard suggests that
1778 # memcpy(NULL, source, 0) is not guaranteed to produce defined (let
1779 # alone desirable) behavior (though it probably does on just about
1780 # every implementation...)
1781 #
1782 # Allocate a tiny buffer to pass in (instead of just passing NULL as
1783 # one might expect) for the initial call so as to be safe against this
1784 # potentially undefined behavior.
1785 empty = _ffi.new("char[]", 0)
1786 size = function(self._ssl, empty, 0)
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001787 if size == 0:
1788 # No Finished message so far.
1789 return None
1790
1791 buf = _ffi.new("char[]", size)
1792 function(self._ssl, buf, size)
1793 return _ffi.buffer(buf, size)[:]
1794
Fedor Brunner5747b932014-03-05 14:22:34 +01001795 def get_finished(self):
1796 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001797 Obtain the latest `handshake finished` message sent to the peer.
Fedor Brunner5747b932014-03-05 14:22:34 +01001798
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001799 :return: The contents of the message or :py:obj:`None` if the TLS
1800 handshake has not yet completed.
1801 :rtype: :py:class:`bytes` or :py:class:`NoneType`
Fedor Brunner5747b932014-03-05 14:22:34 +01001802 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001803 return self._get_finished_message(_lib.SSL_get_finished)
1804
Fedor Brunner5747b932014-03-05 14:22:34 +01001805 def get_peer_finished(self):
1806 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001807 Obtain the latest `handshake finished` message received from the peer.
Fedor Brunner5747b932014-03-05 14:22:34 +01001808
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001809 :return: The contents of the message or :py:obj:`None` if the TLS
1810 handshake has not yet completed.
1811 :rtype: :py:class:`bytes` or :py:class:`NoneType`
Fedor Brunner5747b932014-03-05 14:22:34 +01001812 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001813 return self._get_finished_message(_lib.SSL_get_peer_finished)
Fedor Brunner5747b932014-03-05 14:22:34 +01001814
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001815 def get_cipher_name(self):
1816 """
1817 Obtain the name of the currently used cipher.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001818
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001819 :returns: The name of the currently used cipher or :py:obj:`None`
1820 if no connection has been established.
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001821 :rtype: :py:class:`unicode` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001822 """
1823 cipher = _lib.SSL_get_current_cipher(self._ssl)
1824 if cipher == _ffi.NULL:
1825 return None
1826 else:
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001827 name = _ffi.string(_lib.SSL_CIPHER_get_name(cipher))
1828 return name.decode("utf-8")
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001829
1830 def get_cipher_bits(self):
1831 """
1832 Obtain the number of secret bits of the currently used cipher.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001833
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001834 :returns: The number of secret bits of the currently used cipher
1835 or :py:obj:`None` if no connection has been established.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001836 :rtype: :py:class:`int` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001837 """
1838 cipher = _lib.SSL_get_current_cipher(self._ssl)
1839 if cipher == _ffi.NULL:
1840 return None
1841 else:
1842 return _lib.SSL_CIPHER_get_bits(cipher, _ffi.NULL)
1843
1844 def get_cipher_version(self):
1845 """
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001846 Obtain the protocol version of the currently used cipher.
1847
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001848 :returns: The protocol name of the currently used cipher
1849 or :py:obj:`None` if no connection has been established.
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001850 :rtype: :py:class:`unicode` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001851 """
1852 cipher = _lib.SSL_get_current_cipher(self._ssl)
1853 if cipher == _ffi.NULL:
1854 return None
1855 else:
Alex Gaynorc4889812015-09-04 08:43:17 -04001856 version = _ffi.string(_lib.SSL_CIPHER_get_version(cipher))
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001857 return version.decode("utf-8")
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001858
Jim Shaverabff1882015-05-27 09:15:55 -04001859 def get_protocol_version_name(self):
Jim Shaverba65e662015-04-26 12:23:40 -04001860 """
1861 Obtain the protocol version of the current connection.
1862
1863 :returns: The TLS version of the current connection, for example
Jim Shaver58d25732015-05-28 11:52:32 -04001864 the value for TLS 1.2 would be ``TLSv1.2``or ``Unknown``
Jim Shaverb5b6b0e2015-05-28 16:47:36 -04001865 for connections that were not successfully established.
Jim Shaver58d25732015-05-28 11:52:32 -04001866 :rtype: :py:class:`unicode`
Jim Shaverba65e662015-04-26 12:23:40 -04001867 """
Jim Shaverd1c896e2015-05-27 17:50:21 -04001868 version = _ffi.string(_lib.SSL_get_version(self._ssl))
Jim Shaver58d25732015-05-28 11:52:32 -04001869 return version.decode("utf-8")
Jim Shaverb2967922015-04-26 23:58:52 -04001870
Jim Shaver208438c2015-05-28 09:52:38 -04001871 def get_protocol_version(self):
1872 """
1873 Obtain the protocol version of the current connection.
1874
1875 :returns: The TLS version of the current connection, for example
1876 the value for TLS 1 would be 0x769.
1877 :rtype: :py:class:`int`
1878 """
1879 version = _lib.SSL_version(self._ssl)
1880 return version
1881
Cory Benfield10b277f2015-04-13 17:12:42 -04001882 @_requires_npn
Cory Benfield84a121e2014-03-31 20:30:25 +01001883 def get_next_proto_negotiated(self):
1884 """
1885 Get the protocol that was negotiated by NPN.
1886 """
1887 data = _ffi.new("unsigned char **")
1888 data_len = _ffi.new("unsigned int *")
1889
1890 _lib.SSL_get0_next_proto_negotiated(self._ssl, data, data_len)
1891
Cory Benfieldcd010f62014-05-15 19:00:27 +01001892 return _ffi.buffer(data[0], data_len[0])[:]
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001893
Cory Benfield7907e332015-04-13 17:18:25 -04001894 @_requires_alpn
Cory Benfield12eae892014-06-07 15:42:56 +01001895 def set_alpn_protos(self, protos):
1896 """
Cory Benfielde8e9c382015-04-11 17:33:48 -04001897 Specify the client's ALPN protocol list.
1898
1899 These protocols are offered to the server during protocol negotiation.
Cory Benfield12eae892014-06-07 15:42:56 +01001900
1901 :param protos: A list of the protocols to be offered to the server.
1902 This list should be a Python list of bytestrings representing the
1903 protocols to offer, e.g. ``[b'http/1.1', b'spdy/2']``.
1904 """
1905 # Take the list of protocols and join them together, prefixing them
1906 # with their lengths.
1907 protostr = b''.join(
1908 chain.from_iterable((int2byte(len(p)), p) for p in protos)
1909 )
1910
1911 # Build a C string from the list. We don't need to save this off
1912 # because OpenSSL immediately copies the data out.
1913 input_str = _ffi.new("unsigned char[]", protostr)
Cory Benfield9c1979a2015-04-12 08:51:52 -04001914 input_str_len = _ffi.cast("unsigned", len(protostr))
1915 _lib.SSL_set_alpn_protos(self._ssl, input_str, input_str_len)
Cory Benfield12eae892014-06-07 15:42:56 +01001916
Maximilian Hils66ded6a2015-08-26 06:02:03 +02001917 @_requires_alpn
Cory Benfield12eae892014-06-07 15:42:56 +01001918 def get_alpn_proto_negotiated(self):
Cory Benfield222f30e2015-04-13 18:10:21 -04001919 """
1920 Get the protocol that was negotiated by ALPN.
1921 """
Cory Benfield12eae892014-06-07 15:42:56 +01001922 data = _ffi.new("unsigned char **")
1923 data_len = _ffi.new("unsigned int *")
1924
1925 _lib.SSL_get0_alpn_selected(self._ssl, data, data_len)
1926
Cory Benfielde8e9c382015-04-11 17:33:48 -04001927 if not data_len:
1928 return b''
1929
Cory Benfield12eae892014-06-07 15:42:56 +01001930 return _ffi.buffer(data[0], data_len[0])[:]
1931
1932
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001933ConnectionType = Connection
Jean-Paul Calderone11ed8e82014-01-18 10:21:50 -05001934
Jean-Paul Calderonefab157b2014-01-18 11:21:38 -05001935# This is similar to the initialization calls at the end of OpenSSL/crypto.py
1936# but is exercised mostly by the Context initializer.
Jean-Paul Calderone11ed8e82014-01-18 10:21:50 -05001937_lib.SSL_library_init()