blob: 7ebf7e021724c2565ff0c169c91fa1343ea7acd2 [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
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -08001068ContextType = Context
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001069
1070
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001071class Connection(object):
1072 """
1073 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001074 _reverse_mapping = WeakValueDictionary()
1075
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001076 def __init__(self, context, socket=None):
1077 """
1078 Create a new Connection object, using the given OpenSSL.SSL.Context
1079 instance and socket.
1080
1081 :param context: An SSL Context to use for this connection
1082 :param socket: The socket to use for transport layer
1083 """
1084 if not isinstance(context, Context):
1085 raise TypeError("context must be a Context instance")
1086
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001087 ssl = _lib.SSL_new(context._context)
1088 self._ssl = _ffi.gc(ssl, _lib.SSL_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001089 self._context = context
Todd Chapman4f73e4f2015-08-27 11:26:43 -04001090 self._app_data = None
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001091
Cory Benfieldbe3e7b82014-05-10 09:48:55 +01001092 # References to strings used for Next Protocol Negotiation. OpenSSL's
1093 # header files suggest that these might get copied at some point, but
1094 # doesn't specify when, so we store them here to make sure they don't
1095 # get freed before OpenSSL uses them.
1096 self._npn_advertise_callback_args = None
1097 self._npn_select_callback_args = None
1098
Cory Benfield12eae892014-06-07 15:42:56 +01001099 # References to strings used for Application Layer Protocol
1100 # Negotiation. These strings get copied at some point but it's well
1101 # after the callback returns, so we have to hang them somewhere to
1102 # avoid them getting freed.
1103 self._alpn_select_callback_args = None
1104
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001105 self._reverse_mapping[self._ssl] = self
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001106
1107 if socket is None:
1108 self._socket = None
Jean-Paul Calderone73b15c22013-03-05 18:30:39 -08001109 # Don't set up any gc for these, SSL_free will take care of them.
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001110 self._into_ssl = _lib.BIO_new(_lib.BIO_s_mem())
Alex Gaynora829e902016-06-04 18:16:01 -07001111 _openssl_assert(self._into_ssl != _ffi.NULL)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001112
Alex Gaynora829e902016-06-04 18:16:01 -07001113 self._from_ssl = _lib.BIO_new(_lib.BIO_s_mem())
1114 _openssl_assert(self._from_ssl != _ffi.NULL)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001115
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001116 _lib.SSL_set_bio(self._ssl, self._into_ssl, self._from_ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001117 else:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001118 self._into_ssl = None
1119 self._from_ssl = None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001120 self._socket = socket
Alex Gaynor62da94d2015-09-05 14:37:34 -04001121 set_result = _lib.SSL_set_fd(
1122 self._ssl, _asFileDescriptor(self._socket))
Alex Gaynor09f19f52016-07-03 09:54:09 -04001123 _openssl_assert(set_result == 1)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001124
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001125 def __getattr__(self, name):
1126 """
Alex Gaynor62da94d2015-09-05 14:37:34 -04001127 Look up attributes on the wrapped socket object if they are not found
1128 on the Connection object.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001129 """
kjav0b66fa12015-09-02 11:51:26 +01001130 if self._socket is None:
Alex Gaynor62da94d2015-09-05 14:37:34 -04001131 raise AttributeError("'%s' object has no attribute '%s'" % (
1132 self.__class__.__name__, name
1133 ))
kjav0b66fa12015-09-02 11:51:26 +01001134 else:
1135 return getattr(self._socket, name)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001136
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001137 def _raise_ssl_error(self, ssl, result):
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -08001138 if self._context._verify_helper is not None:
1139 self._context._verify_helper.raise_if_problem()
Cory Benfield0ea76e72015-03-22 09:05:28 +00001140 if self._context._npn_advertise_helper is not None:
1141 self._context._npn_advertise_helper.raise_if_problem()
1142 if self._context._npn_select_helper is not None:
1143 self._context._npn_select_helper.raise_if_problem()
Cory Benfieldf1177e72015-04-12 09:11:49 -04001144 if self._context._alpn_select_helper is not None:
1145 self._context._alpn_select_helper.raise_if_problem()
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -08001146
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001147 error = _lib.SSL_get_error(ssl, result)
1148 if error == _lib.SSL_ERROR_WANT_READ:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001149 raise WantReadError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001150 elif error == _lib.SSL_ERROR_WANT_WRITE:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001151 raise WantWriteError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001152 elif error == _lib.SSL_ERROR_ZERO_RETURN:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001153 raise ZeroReturnError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001154 elif error == _lib.SSL_ERROR_WANT_X509_LOOKUP:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001155 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001156 raise WantX509LookupError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001157 elif error == _lib.SSL_ERROR_SYSCALL:
1158 if _lib.ERR_peek_error() == 0:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001159 if result < 0:
Konstantinos Koukopoulos541150d2014-01-31 01:00:19 +02001160 if platform == "win32":
1161 errno = _ffi.getwinerror()[0]
1162 else:
1163 errno = _ffi.errno
Alex Gaynor5af32d02016-09-24 01:52:21 -04001164
1165 if errno != 0:
1166 raise SysCallError(errno, errorcode.get(errno))
1167 raise SysCallError(-1, "Unexpected EOF")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001168 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001169 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001170 _raise_current_error()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001171 elif error == _lib.SSL_ERROR_NONE:
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001172 pass
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001173 else:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001174 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001175
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001176 def get_context(self):
1177 """
1178 Get session context
1179 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001180 return self._context
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001181
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001182 def set_context(self, context):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001183 """
1184 Switch this connection to a new session context
1185
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001186 :param context: A :py:class:`Context` instance giving the new session
1187 context to use.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001188 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001189 if not isinstance(context, Context):
1190 raise TypeError("context must be a Context instance")
1191
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001192 _lib.SSL_set_SSL_CTX(self._ssl, context._context)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001193 self._context = context
1194
Cory Benfielde6f35882016-03-29 11:21:04 +01001195 @_requires_sni
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001196 def get_servername(self):
1197 """
1198 Retrieve the servername extension value if provided in the client hello
1199 message, or None if there wasn't one.
1200
1201 :return: A byte string giving the server name or :py:data:`None`.
1202 """
Alex Gaynor62da94d2015-09-05 14:37:34 -04001203 name = _lib.SSL_get_servername(
1204 self._ssl, _lib.TLSEXT_NAMETYPE_host_name
1205 )
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001206 if name == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001207 return None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001208
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001209 return _ffi.string(name)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001210
Cory Benfielde6f35882016-03-29 11:21:04 +01001211 @_requires_sni
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001212 def set_tlsext_host_name(self, name):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001213 """
1214 Set the value of the servername extension to send in the client hello.
1215
1216 :param name: A byte string giving the name.
1217 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001218 if not isinstance(name, bytes):
1219 raise TypeError("name must be a byte string")
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001220 elif b"\0" in name:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001221 raise TypeError("name must not contain NUL byte")
1222
1223 # XXX I guess this can fail sometimes?
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001224 _lib.SSL_set_tlsext_host_name(self._ssl, name)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001225
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001226 def pending(self):
1227 """
1228 Get the number of bytes that can be safely read from the connection
1229
1230 :return: The number of bytes available in the receive buffer.
1231 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001232 return _lib.SSL_pending(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001233
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001234 def send(self, buf, flags=0):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001235 """
1236 Send data on the connection. NOTE: If you get one of the WantRead,
1237 WantWrite or WantX509Lookup exceptions on this, you have to call the
1238 method again with the SAME buffer.
1239
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001240 :param buf: The string, buffer or memoryview to send
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001241 :param flags: (optional) Included for compatibility with the socket
1242 API, the value is ignored
1243 :return: The number of bytes written
1244 """
Abraham Martine82326c2015-02-04 10:18:10 +00001245 # Backward compatibility
Jean-Paul Calderone39a8d592015-04-13 20:49:50 -04001246 buf = _text_to_bytes_and_warn("buf", buf)
Abraham Martine82326c2015-02-04 10:18:10 +00001247
Jean-Paul Calderone8fb53182013-12-30 08:35:49 -05001248 if isinstance(buf, _memoryview):
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -08001249 buf = buf.tobytes()
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001250 if isinstance(buf, _buffer):
1251 buf = str(buf)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001252 if not isinstance(buf, bytes):
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001253 raise TypeError("data must be a memoryview, buffer or byte string")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001254
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001255 result = _lib.SSL_write(self._ssl, buf, len(buf))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001256 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001257 return result
1258 write = send
1259
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001260 def sendall(self, buf, flags=0):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001261 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001262 Send "all" data on the connection. This calls send() repeatedly until
1263 all data is sent. If an error occurs, it's impossible to tell how much
1264 data has been sent.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001265
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001266 :param buf: The string, buffer or memoryview to send
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001267 :param flags: (optional) Included for compatibility with the socket
1268 API, the value is ignored
1269 :return: The number of bytes written
1270 """
Jean-Paul Calderone39a8d592015-04-13 20:49:50 -04001271 buf = _text_to_bytes_and_warn("buf", buf)
Abraham Martine82326c2015-02-04 10:18:10 +00001272
Jean-Paul Calderone8fb53182013-12-30 08:35:49 -05001273 if isinstance(buf, _memoryview):
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -08001274 buf = buf.tobytes()
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001275 if isinstance(buf, _buffer):
1276 buf = str(buf)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001277 if not isinstance(buf, bytes):
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02001278 raise TypeError("buf must be a memoryview, buffer or byte string")
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001279
1280 left_to_send = len(buf)
1281 total_sent = 0
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001282 data = _ffi.new("char[]", buf)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001283
1284 while left_to_send:
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001285 result = _lib.SSL_write(self._ssl, data + total_sent, left_to_send)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001286 self._raise_ssl_error(self._ssl, result)
1287 total_sent += result
1288 left_to_send -= result
1289
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001290 def recv(self, bufsiz, flags=None):
1291 """
Alex Gaynor67fc8c92016-05-27 08:27:19 -04001292 Receive data on the connection.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001293
1294 :param bufsiz: The maximum number of bytes to read
Maximilian Hils1d95dea2015-08-17 19:27:20 +02001295 :param flags: (optional) The only supported flag is ``MSG_PEEK``,
1296 all other flags are ignored.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001297 :return: The string read from the Connection
1298 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001299 buf = _ffi.new("char[]", bufsiz)
Maximilian Hils1d95dea2015-08-17 19:27:20 +02001300 if flags is not None and flags & socket.MSG_PEEK:
1301 result = _lib.SSL_peek(self._ssl, buf, bufsiz)
1302 else:
1303 result = _lib.SSL_read(self._ssl, buf, bufsiz)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001304 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001305 return _ffi.buffer(buf, result)[:]
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001306 read = recv
1307
Cory Benfield62d10332014-06-15 10:03:41 +01001308 def recv_into(self, buffer, nbytes=None, flags=None):
1309 """
1310 Receive data on the connection and store the data into a buffer rather
1311 than creating a new string.
1312
1313 :param buffer: The buffer to copy into.
1314 :param nbytes: (optional) The maximum number of bytes to read into the
1315 buffer. If not present, defaults to the size of the buffer. If
1316 larger than the size of the buffer, is reduced to the size of the
1317 buffer.
Maximilian Hils1d95dea2015-08-17 19:27:20 +02001318 :param flags: (optional) The only supported flag is ``MSG_PEEK``,
1319 all other flags are ignored.
Cory Benfield62d10332014-06-15 10:03:41 +01001320 :return: The number of bytes read into the buffer.
1321 """
1322 if nbytes is None:
1323 nbytes = len(buffer)
1324 else:
1325 nbytes = min(nbytes, len(buffer))
1326
1327 # We need to create a temporary buffer. This is annoying, it would be
1328 # better if we could pass memoryviews straight into the SSL_read call,
1329 # but right now we can't. Revisit this if CFFI gets that ability.
1330 buf = _ffi.new("char[]", nbytes)
Maximilian Hils1d95dea2015-08-17 19:27:20 +02001331 if flags is not None and flags & socket.MSG_PEEK:
1332 result = _lib.SSL_peek(self._ssl, buf, nbytes)
1333 else:
1334 result = _lib.SSL_read(self._ssl, buf, nbytes)
Cory Benfield62d10332014-06-15 10:03:41 +01001335 self._raise_ssl_error(self._ssl, result)
1336
1337 # This strange line is all to avoid a memory copy. The buffer protocol
1338 # should allow us to assign a CFFI buffer to the LHS of this line, but
1339 # on CPython 3.3+ that segfaults. As a workaround, we can temporarily
1340 # wrap it in a memoryview, except on Python 2.6 which doesn't have a
1341 # memoryview type.
1342 try:
1343 buffer[:result] = memoryview(_ffi.buffer(buf, result))
1344 except NameError:
1345 buffer[:result] = _ffi.buffer(buf, result)
1346
1347 return result
1348
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001349 def _handle_bio_errors(self, bio, result):
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001350 if _lib.BIO_should_retry(bio):
1351 if _lib.BIO_should_read(bio):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001352 raise WantReadError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001353 elif _lib.BIO_should_write(bio):
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001354 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001355 raise WantWriteError()
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001356 elif _lib.BIO_should_io_special(bio):
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001357 # TODO: This is untested. I think io_special means the socket
1358 # BIO has a not-yet connected socket.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001359 raise ValueError("BIO_should_io_special")
1360 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001361 # TODO: This is untested.
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001362 raise ValueError("unknown bio failure")
1363 else:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001364 # TODO: This is untested.
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001365 _raise_current_error()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001366
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001367 def bio_read(self, bufsiz):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001368 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001369 When using non-socket connections this function reads the "dirty" data
1370 that would have traveled away on the network.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001371
1372 :param bufsiz: The maximum number of bytes to read
1373 :return: The string read.
1374 """
Jean-Paul Calderone97e041d2013-03-05 21:03:12 -08001375 if self._from_ssl is None:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001376 raise TypeError("Connection sock was not None")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001377
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -05001378 if not isinstance(bufsiz, integer_types):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001379 raise TypeError("bufsiz must be an integer")
1380
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001381 buf = _ffi.new("char[]", bufsiz)
1382 result = _lib.BIO_read(self._from_ssl, buf, bufsiz)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001383 if result <= 0:
1384 self._handle_bio_errors(self._from_ssl, result)
1385
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001386 return _ffi.buffer(buf, result)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001387
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001388 def bio_write(self, buf):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001389 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001390 When using non-socket connections this function sends "dirty" data that
1391 would have traveled in on the network.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001392
1393 :param buf: The string to put into the memory BIO.
1394 :return: The number of bytes written
1395 """
Jean-Paul Calderone39a8d592015-04-13 20:49:50 -04001396 buf = _text_to_bytes_and_warn("buf", buf)
Abraham Martine82326c2015-02-04 10:18:10 +00001397
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001398 if self._into_ssl is None:
1399 raise TypeError("Connection sock was not None")
1400
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001401 result = _lib.BIO_write(self._into_ssl, buf, len(buf))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001402 if result <= 0:
1403 self._handle_bio_errors(self._into_ssl, result)
1404 return result
1405
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001406 def renegotiate(self):
1407 """
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +01001408 Renegotiate the session.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001409
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +01001410 :return: True if the renegotiation can be started, False otherwise
1411 :rtype: bool
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001412 """
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +01001413 if not self.renegotiate_pending():
1414 _openssl_assert(_lib.SSL_renegotiate(self._ssl) == 1)
1415 return True
1416 return False
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001417
1418 def do_handshake(self):
1419 """
1420 Perform an SSL handshake (usually called after renegotiate() or one of
1421 set_*_state()). This can raise the same exceptions as send and recv.
1422
1423 :return: None.
1424 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001425 result = _lib.SSL_do_handshake(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001426 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001427
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001428 def renegotiate_pending(self):
1429 """
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +01001430 Check if there's a renegotiation in progress, it will return False once
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001431 a renegotiation is finished.
1432
1433 :return: Whether there's a renegotiation in progress
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +01001434 :rtype: bool
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001435 """
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +01001436 return _lib.SSL_renegotiate_pending(self._ssl) == 1
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001437
1438 def total_renegotiations(self):
1439 """
1440 Find out the total number of renegotiations.
1441
1442 :return: The number of renegotiations.
Hynek Schlawackb1f3ca82016-02-13 09:10:04 +01001443 :rtype: int
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001444 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001445 return _lib.SSL_total_renegotiations(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001446
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001447 def connect(self, addr):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001448 """
1449 Connect to remote host and set up client-side SSL
1450
1451 :param addr: A remote address
1452 :return: What the socket's connect method returns
1453 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001454 _lib.SSL_set_connect_state(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001455 return self._socket.connect(addr)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001456
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001457 def connect_ex(self, addr):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001458 """
Alex Gaynor62da94d2015-09-05 14:37:34 -04001459 Connect to remote host and set up client-side SSL. Note that if the
1460 socket's connect_ex method doesn't return 0, SSL won't be initialized.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001461
1462 :param addr: A remove address
1463 :return: What the socket's connect_ex method returns
1464 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001465 connect_ex = self._socket.connect_ex
1466 self.set_connect_state()
1467 return connect_ex(addr)
1468
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001469 def accept(self):
1470 """
1471 Accept incoming connection and set up SSL on it
1472
1473 :return: A (conn,addr) pair where conn is a Connection and addr is an
1474 address
1475 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001476 client, addr = self._socket.accept()
1477 conn = Connection(self._context, client)
1478 conn.set_accept_state()
1479 return (conn, addr)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001480
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001481 def bio_shutdown(self):
1482 """
1483 When using non-socket connections this function signals end of
1484 data on the input for this connection.
1485
1486 :return: None
1487 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001488 if self._from_ssl is None:
1489 raise TypeError("Connection sock was not None")
1490
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001491 _lib.BIO_set_mem_eof_return(self._into_ssl, 0)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001492
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001493 def shutdown(self):
1494 """
1495 Send closure alert
1496
1497 :return: True if the shutdown completed successfully (i.e. both sides
1498 have sent closure alerts), false otherwise (i.e. you have to
1499 wait for a ZeroReturnError on a recv() method call
1500 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001501 result = _lib.SSL_shutdown(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001502 if result < 0:
Paul Aurichbff1d1a2015-01-08 08:36:53 -08001503 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001504 elif result > 0:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001505 return True
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001506 else:
1507 return False
1508
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001509 def get_cipher_list(self):
1510 """
Hynek Schlawackf90e3682016-03-11 11:21:13 +01001511 Retrieve the list of ciphers used by the Connection object.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001512
Hynek Schlawackf90e3682016-03-11 11:21:13 +01001513 :return: A list of native cipher strings.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001514 """
1515 ciphers = []
1516 for i in count():
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001517 result = _lib.SSL_get_cipher_list(self._ssl, i)
1518 if result == _ffi.NULL:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001519 break
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001520 ciphers.append(_native(_ffi.string(result)))
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001521 return ciphers
1522
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001523 def get_client_ca_list(self):
1524 """
1525 Get CAs whose certificates are suggested for client authentication.
1526
Alex Gaynor62da94d2015-09-05 14:37:34 -04001527 :return: If this is a server connection, a list of X509Names
1528 representing the acceptable CAs as set by
1529 :py:meth:`OpenSSL.SSL.Context.set_client_ca_list` or
1530 :py:meth:`OpenSSL.SSL.Context.add_client_ca`. If this is a client
1531 connection, the list of such X509Names sent by the server, or an
1532 empty list if that has not yet happened.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001533 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001534 ca_names = _lib.SSL_get_client_CA_list(self._ssl)
1535 if ca_names == _ffi.NULL:
Jean-Paul Calderonea9f84ad2013-12-29 17:06:11 -05001536 # TODO: This is untested.
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001537 return []
1538
1539 result = []
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001540 for i in range(_lib.sk_X509_NAME_num(ca_names)):
1541 name = _lib.sk_X509_NAME_value(ca_names, i)
1542 copy = _lib.X509_NAME_dup(name)
Alex Gaynora829e902016-06-04 18:16:01 -07001543 _openssl_assert(copy != _ffi.NULL)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001544
1545 pyname = X509Name.__new__(X509Name)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001546 pyname._name = _ffi.gc(copy, _lib.X509_NAME_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001547 result.append(pyname)
1548 return result
1549
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001550 def makefile(self):
1551 """
Alex Gaynor62da94d2015-09-05 14:37:34 -04001552 The makefile() method is not implemented, since there is no dup
1553 semantics for SSL connections
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001554
Jean-Paul Calderone6749ec22014-04-17 16:30:21 -04001555 :raise: NotImplementedError
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001556 """
Alex Gaynor83284952015-09-05 10:43:30 -04001557 raise NotImplementedError(
1558 "Cannot make file object of OpenSSL.SSL.Connection")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001559
1560 def get_app_data(self):
1561 """
1562 Get application data
1563
1564 :return: The application data
1565 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001566 return self._app_data
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001567
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001568 def set_app_data(self, data):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001569 """
1570 Set application data
1571
1572 :param data - The application data
1573 :return: None
1574 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001575 self._app_data = data
1576
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001577 def get_shutdown(self):
1578 """
1579 Get shutdown state
1580
Alex Gaynor62da94d2015-09-05 14:37:34 -04001581 :return: The shutdown state, a bitvector of SENT_SHUTDOWN,
1582 RECEIVED_SHUTDOWN.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001583 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001584 return _lib.SSL_get_shutdown(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001585
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001586 def set_shutdown(self, state):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001587 """
1588 Set shutdown state
1589
1590 :param state - bitvector of SENT_SHUTDOWN, RECEIVED_SHUTDOWN.
1591 :return: None
1592 """
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -05001593 if not isinstance(state, integer_types):
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001594 raise TypeError("state must be an integer")
1595
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001596 _lib.SSL_set_shutdown(self._ssl, state)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001597
Hynek Schlawackea94f2b2016-03-13 16:17:53 +01001598 def get_state_string(self):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001599 """
Hynek Schlawackea94f2b2016-03-13 16:17:53 +01001600 Retrieve a verbose string detailing the state of the Connection.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001601
1602 :return: A string representing the state
Hynek Schlawackea94f2b2016-03-13 16:17:53 +01001603 :rtype: bytes
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001604 """
kjavc704a2e2015-09-07 12:12:27 +01001605 return _ffi.string(_lib.SSL_state_string_long(self._ssl))
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001606
1607 def server_random(self):
1608 """
1609 Get a copy of the server hello nonce.
1610
1611 :return: A string representing the state
1612 """
Alex Gaynor93603062016-06-01 20:13:09 -07001613 session = _lib.SSL_get_session(self._ssl)
1614 if session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001615 return None
Alex Gaynor93603062016-06-01 20:13:09 -07001616 length = _lib.SSL_get_server_random(self._ssl, _ffi.NULL, 0)
1617 assert length > 0
Paul Kehrer9f9113a2016-09-20 20:10:25 -05001618 outp = _ffi.new("unsigned char[]", length)
Alex Gaynor93603062016-06-01 20:13:09 -07001619 _lib.SSL_get_server_random(self._ssl, outp, length)
1620 return _ffi.buffer(outp, length)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001621
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001622 def client_random(self):
1623 """
1624 Get a copy of the client hello nonce.
1625
1626 :return: A string representing the state
1627 """
Alex Gaynor93603062016-06-01 20:13:09 -07001628 session = _lib.SSL_get_session(self._ssl)
1629 if session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001630 return None
Alex Gaynor93603062016-06-01 20:13:09 -07001631
1632 length = _lib.SSL_get_client_random(self._ssl, _ffi.NULL, 0)
1633 assert length > 0
Paul Kehrer9f9113a2016-09-20 20:10:25 -05001634 outp = _ffi.new("unsigned char[]", length)
Alex Gaynor93603062016-06-01 20:13:09 -07001635 _lib.SSL_get_client_random(self._ssl, outp, length)
1636 return _ffi.buffer(outp, length)[:]
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001637
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001638 def master_key(self):
1639 """
1640 Get a copy of the master key.
1641
1642 :return: A string representing the state
1643 """
Alex Gaynor93603062016-06-01 20:13:09 -07001644 session = _lib.SSL_get_session(self._ssl)
1645 if session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001646 return None
Alex Gaynor93603062016-06-01 20:13:09 -07001647
1648 length = _lib.SSL_SESSION_get_master_key(session, _ffi.NULL, 0)
1649 assert length > 0
Paul Kehrer9f9113a2016-09-20 20:10:25 -05001650 outp = _ffi.new("unsigned char[]", length)
Alex Gaynor93603062016-06-01 20:13:09 -07001651 _lib.SSL_SESSION_get_master_key(session, outp, length)
1652 return _ffi.buffer(outp, length)[:]
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001653
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001654 def sock_shutdown(self, *args, **kwargs):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001655 """
1656 See shutdown(2)
1657
1658 :return: What the socket's shutdown() method returns
1659 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001660 return self._socket.shutdown(*args, **kwargs)
1661
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001662 def get_peer_certificate(self):
1663 """
1664 Retrieve the other side's certificate (if any)
1665
1666 :return: The peer's certificate
1667 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001668 cert = _lib.SSL_get_peer_certificate(self._ssl)
1669 if cert != _ffi.NULL:
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001670 pycert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001671 pycert._x509 = _ffi.gc(cert, _lib.X509_free)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001672 return pycert
1673 return None
1674
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001675 def get_peer_cert_chain(self):
1676 """
1677 Retrieve the other side's certificate (if any)
1678
1679 :return: A list of X509 instances giving the peer's certificate chain,
1680 or None if it does not have one.
1681 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001682 cert_stack = _lib.SSL_get_peer_cert_chain(self._ssl)
1683 if cert_stack == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001684 return None
1685
1686 result = []
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001687 for i in range(_lib.sk_X509_num(cert_stack)):
Jean-Paul Calderone73b15c22013-03-05 18:30:39 -08001688 # TODO could incref instead of dup here
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001689 cert = _lib.X509_dup(_lib.sk_X509_value(cert_stack, i))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001690 pycert = X509.__new__(X509)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001691 pycert._x509 = _ffi.gc(cert, _lib.X509_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001692 result.append(pycert)
1693 return result
1694
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001695 def want_read(self):
1696 """
Alex Gaynor62da94d2015-09-05 14:37:34 -04001697 Checks if more data has to be read from the transport layer to complete
1698 an operation.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001699
1700 :return: True iff more data has to be read
1701 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001702 return _lib.SSL_want_read(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001703
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001704 def want_write(self):
1705 """
1706 Checks if there is data to write to the transport layer to complete an
1707 operation.
1708
1709 :return: True iff there is data to write
1710 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001711 return _lib.SSL_want_write(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001712
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001713 def set_accept_state(self):
1714 """
Alex Gaynor62da94d2015-09-05 14:37:34 -04001715 Set the connection to work in server mode. The handshake will be
1716 handled automatically by read/write.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001717
1718 :return: None
1719 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001720 _lib.SSL_set_accept_state(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001721
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001722 def set_connect_state(self):
1723 """
Alex Gaynor62da94d2015-09-05 14:37:34 -04001724 Set the connection to work in client mode. The handshake will be
1725 handled automatically by read/write.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001726
1727 :return: None
1728 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001729 _lib.SSL_set_connect_state(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001730
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001731 def get_session(self):
1732 """
1733 Returns the Session currently used.
1734
Alex Gaynor62da94d2015-09-05 14:37:34 -04001735 @return: An instance of :py:class:`OpenSSL.SSL.Session` or
1736 :py:obj:`None` if no session exists.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001737 """
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001738 session = _lib.SSL_get1_session(self._ssl)
1739 if session == _ffi.NULL:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001740 return None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001741
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001742 pysession = Session.__new__(Session)
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001743 pysession._session = _ffi.gc(session, _lib.SSL_SESSION_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001744 return pysession
1745
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001746 def set_session(self, session):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001747 """
1748 Set the session to be used when the TLS/SSL connection is established.
1749
1750 :param session: A Session instance representing the session to use.
1751 :returns: None
1752 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001753 if not isinstance(session, Session):
1754 raise TypeError("session must be a Session instance")
1755
Jean-Paul Calderone6037d072013-12-28 18:04:00 -05001756 result = _lib.SSL_set_session(self._ssl, session._session)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001757 if not result:
Jean-Paul Calderonec86bb7d2013-12-29 10:25:59 -05001758 _raise_current_error()
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001759
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001760 def _get_finished_message(self, function):
1761 """
1762 Helper to implement :py:meth:`get_finished` and
1763 :py:meth:`get_peer_finished`.
1764
1765 :param function: Either :py:data:`SSL_get_finished`: or
1766 :py:data:`SSL_get_peer_finished`.
1767
1768 :return: :py:data:`None` if the desired message has not yet been
1769 received, otherwise the contents of the message.
1770 :rtype: :py:class:`bytes` or :py:class:`NoneType`
1771 """
Jean-Paul Calderone01af9042014-03-30 11:40:42 -04001772 # The OpenSSL documentation says nothing about what might happen if the
1773 # count argument given is zero. Specifically, it doesn't say whether
1774 # the output buffer may be NULL in that case or not. Inspection of the
1775 # implementation reveals that it calls memcpy() unconditionally.
1776 # Section 7.1.4, paragraph 1 of the C standard suggests that
1777 # memcpy(NULL, source, 0) is not guaranteed to produce defined (let
1778 # alone desirable) behavior (though it probably does on just about
1779 # every implementation...)
1780 #
1781 # Allocate a tiny buffer to pass in (instead of just passing NULL as
1782 # one might expect) for the initial call so as to be safe against this
1783 # potentially undefined behavior.
1784 empty = _ffi.new("char[]", 0)
1785 size = function(self._ssl, empty, 0)
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001786 if size == 0:
1787 # No Finished message so far.
1788 return None
1789
1790 buf = _ffi.new("char[]", size)
1791 function(self._ssl, buf, size)
1792 return _ffi.buffer(buf, size)[:]
1793
Fedor Brunner5747b932014-03-05 14:22:34 +01001794 def get_finished(self):
1795 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001796 Obtain the latest `handshake finished` message sent to the peer.
Fedor Brunner5747b932014-03-05 14:22:34 +01001797
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001798 :return: The contents of the message or :py:obj:`None` if the TLS
1799 handshake has not yet completed.
1800 :rtype: :py:class:`bytes` or :py:class:`NoneType`
Fedor Brunner5747b932014-03-05 14:22:34 +01001801 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001802 return self._get_finished_message(_lib.SSL_get_finished)
1803
Fedor Brunner5747b932014-03-05 14:22:34 +01001804 def get_peer_finished(self):
1805 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001806 Obtain the latest `handshake finished` message received from the peer.
Fedor Brunner5747b932014-03-05 14:22:34 +01001807
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001808 :return: The contents of the message or :py:obj:`None` if the TLS
1809 handshake has not yet completed.
1810 :rtype: :py:class:`bytes` or :py:class:`NoneType`
Fedor Brunner5747b932014-03-05 14:22:34 +01001811 """
Jean-Paul Calderoneac209562014-03-30 11:26:32 -04001812 return self._get_finished_message(_lib.SSL_get_peer_finished)
Fedor Brunner5747b932014-03-05 14:22:34 +01001813
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001814 def get_cipher_name(self):
1815 """
1816 Obtain the name of the currently used cipher.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001817
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001818 :returns: The name of the currently used cipher or :py:obj:`None`
1819 if no connection has been established.
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001820 :rtype: :py:class:`unicode` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001821 """
1822 cipher = _lib.SSL_get_current_cipher(self._ssl)
1823 if cipher == _ffi.NULL:
1824 return None
1825 else:
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001826 name = _ffi.string(_lib.SSL_CIPHER_get_name(cipher))
1827 return name.decode("utf-8")
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001828
1829 def get_cipher_bits(self):
1830 """
1831 Obtain the number of secret bits of the currently used cipher.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001832
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001833 :returns: The number of secret bits of the currently used cipher
1834 or :py:obj:`None` if no connection has been established.
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001835 :rtype: :py:class:`int` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001836 """
1837 cipher = _lib.SSL_get_current_cipher(self._ssl)
1838 if cipher == _ffi.NULL:
1839 return None
1840 else:
1841 return _lib.SSL_CIPHER_get_bits(cipher, _ffi.NULL)
1842
1843 def get_cipher_version(self):
1844 """
Jean-Paul Calderone9e3ccd42014-03-29 18:13:36 -04001845 Obtain the protocol version of the currently used cipher.
1846
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001847 :returns: The protocol name of the currently used cipher
1848 or :py:obj:`None` if no connection has been established.
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001849 :rtype: :py:class:`unicode` or :py:class:`NoneType`
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001850 """
1851 cipher = _lib.SSL_get_current_cipher(self._ssl)
1852 if cipher == _ffi.NULL:
1853 return None
1854 else:
Alex Gaynorc4889812015-09-04 08:43:17 -04001855 version = _ffi.string(_lib.SSL_CIPHER_get_version(cipher))
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04001856 return version.decode("utf-8")
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001857
Jim Shaverabff1882015-05-27 09:15:55 -04001858 def get_protocol_version_name(self):
Jim Shaverba65e662015-04-26 12:23:40 -04001859 """
1860 Obtain the protocol version of the current connection.
1861
1862 :returns: The TLS version of the current connection, for example
Jim Shaver58d25732015-05-28 11:52:32 -04001863 the value for TLS 1.2 would be ``TLSv1.2``or ``Unknown``
Jim Shaverb5b6b0e2015-05-28 16:47:36 -04001864 for connections that were not successfully established.
Jim Shaver58d25732015-05-28 11:52:32 -04001865 :rtype: :py:class:`unicode`
Jim Shaverba65e662015-04-26 12:23:40 -04001866 """
Jim Shaverd1c896e2015-05-27 17:50:21 -04001867 version = _ffi.string(_lib.SSL_get_version(self._ssl))
Jim Shaver58d25732015-05-28 11:52:32 -04001868 return version.decode("utf-8")
Jim Shaverb2967922015-04-26 23:58:52 -04001869
Jim Shaver208438c2015-05-28 09:52:38 -04001870 def get_protocol_version(self):
1871 """
1872 Obtain the protocol version of the current connection.
1873
1874 :returns: The TLS version of the current connection, for example
1875 the value for TLS 1 would be 0x769.
1876 :rtype: :py:class:`int`
1877 """
1878 version = _lib.SSL_version(self._ssl)
1879 return version
1880
Cory Benfield10b277f2015-04-13 17:12:42 -04001881 @_requires_npn
Cory Benfield84a121e2014-03-31 20:30:25 +01001882 def get_next_proto_negotiated(self):
1883 """
1884 Get the protocol that was negotiated by NPN.
1885 """
1886 data = _ffi.new("unsigned char **")
1887 data_len = _ffi.new("unsigned int *")
1888
1889 _lib.SSL_get0_next_proto_negotiated(self._ssl, data, data_len)
1890
Cory Benfieldcd010f62014-05-15 19:00:27 +01001891 return _ffi.buffer(data[0], data_len[0])[:]
Fedor Brunnerd95014a2014-03-03 17:34:41 +01001892
Cory Benfield7907e332015-04-13 17:18:25 -04001893 @_requires_alpn
Cory Benfield12eae892014-06-07 15:42:56 +01001894 def set_alpn_protos(self, protos):
1895 """
Cory Benfielde8e9c382015-04-11 17:33:48 -04001896 Specify the client's ALPN protocol list.
1897
1898 These protocols are offered to the server during protocol negotiation.
Cory Benfield12eae892014-06-07 15:42:56 +01001899
1900 :param protos: A list of the protocols to be offered to the server.
1901 This list should be a Python list of bytestrings representing the
1902 protocols to offer, e.g. ``[b'http/1.1', b'spdy/2']``.
1903 """
1904 # Take the list of protocols and join them together, prefixing them
1905 # with their lengths.
1906 protostr = b''.join(
1907 chain.from_iterable((int2byte(len(p)), p) for p in protos)
1908 )
1909
1910 # Build a C string from the list. We don't need to save this off
1911 # because OpenSSL immediately copies the data out.
1912 input_str = _ffi.new("unsigned char[]", protostr)
Cory Benfield9c1979a2015-04-12 08:51:52 -04001913 input_str_len = _ffi.cast("unsigned", len(protostr))
1914 _lib.SSL_set_alpn_protos(self._ssl, input_str, input_str_len)
Cory Benfield12eae892014-06-07 15:42:56 +01001915
Maximilian Hils66ded6a2015-08-26 06:02:03 +02001916 @_requires_alpn
Cory Benfield12eae892014-06-07 15:42:56 +01001917 def get_alpn_proto_negotiated(self):
Cory Benfield222f30e2015-04-13 18:10:21 -04001918 """
1919 Get the protocol that was negotiated by ALPN.
1920 """
Cory Benfield12eae892014-06-07 15:42:56 +01001921 data = _ffi.new("unsigned char **")
1922 data_len = _ffi.new("unsigned int *")
1923
1924 _lib.SSL_get0_alpn_selected(self._ssl, data, data_len)
1925
Cory Benfielde8e9c382015-04-11 17:33:48 -04001926 if not data_len:
1927 return b''
1928
Cory Benfield12eae892014-06-07 15:42:56 +01001929 return _ffi.buffer(data[0], data_len[0])[:]
1930
1931
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001932ConnectionType = Connection
Jean-Paul Calderone11ed8e82014-01-18 10:21:50 -05001933
Jean-Paul Calderonefab157b2014-01-18 11:21:38 -05001934# This is similar to the initialization calls at the end of OpenSSL/crypto.py
1935# but is exercised mostly by the Context initializer.
Jean-Paul Calderone11ed8e82014-01-18 10:21:50 -05001936_lib.SSL_library_init()