blob: b30bed48fb0ec2c7423c29e76f4a15565bc55b98 [file] [log] [blame]
Jean-Paul Calderone8671c852011-03-02 19:26:20 -05001# Copyright (C) Jean-Paul Calderone
2# See LICENSE for details.
Jean-Paul Calderone8b63d452008-03-21 18:31:12 -04003
Jean-Paul Calderone30c09ea2008-03-21 17:04:05 -04004"""
Jonathan Ballet648875f2011-07-16 14:14:58 +09005Unit tests for :py:obj:`OpenSSL.SSL`.
Jean-Paul Calderone30c09ea2008-03-21 17:04:05 -04006"""
7
Jean-Paul Calderone4c1aacd2014-01-11 08:15:17 -05008from gc import collect, get_referrers
Konstantinos Koukopoulos541150d2014-01-31 01:00:19 +02009from errno import ECONNREFUSED, EINPROGRESS, EWOULDBLOCK, EPIPE, ESHUTDOWN
Jean-Paul Calderonec4cb6582011-05-26 18:47:00 -040010from sys import platform, version_info
Jean-Paul Calderoned899af02013-03-19 22:10:37 -070011from socket import SHUT_RDWR, error, socket
Jean-Paul Calderonea65cf6c2009-07-19 10:26:52 -040012from os import makedirs
Jean-Paul Calderone1461c492013-10-03 16:05:00 -040013from os.path import join
Jean-Paul Calderone0b88b6a2009-07-05 12:44:41 -040014from unittest import main
Jean-Paul Calderonec4cb6582011-05-26 18:47:00 -040015from weakref import ref
Jean-Paul Calderone460cc1f2009-03-07 11:31:12 -050016
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -040017from six import PY3, text_type, u
Jean-Paul Calderonec76c61c2014-01-18 13:21:52 -050018
Jean-Paul Calderone20222ae2011-05-19 21:43:46 -040019from OpenSSL.crypto import TYPE_RSA, FILETYPE_PEM
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -080020from OpenSSL.crypto import PKey, X509, X509Extension, X509Store
Jean-Paul Calderone7526d172010-09-09 17:55:31 -040021from OpenSSL.crypto import dump_privatekey, load_privatekey
22from OpenSSL.crypto import dump_certificate, load_certificate
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -040023from OpenSSL.crypto import get_elliptic_curves
Jean-Paul Calderone7526d172010-09-09 17:55:31 -040024
Jean-Paul Calderoneb41d1f42014-04-17 16:02:04 -040025from OpenSSL.SSL import _lib
Jean-Paul Calderone9f2e38e2011-04-14 09:36:55 -040026from OpenSSL.SSL import OPENSSL_VERSION_NUMBER, SSLEAY_VERSION, SSLEAY_CFLAGS
27from OpenSSL.SSL import SSLEAY_PLATFORM, SSLEAY_DIR, SSLEAY_BUILT_ON
Jean-Paul Calderonee4f6b472010-07-29 22:50:58 -040028from OpenSSL.SSL import SENT_SHUTDOWN, RECEIVED_SHUTDOWN
Jean-Paul Calderone1461c492013-10-03 16:05:00 -040029from OpenSSL.SSL import (
30 SSLv2_METHOD, SSLv3_METHOD, SSLv23_METHOD, TLSv1_METHOD,
31 TLSv1_1_METHOD, TLSv1_2_METHOD)
32from OpenSSL.SSL import OP_SINGLE_DH_USE, OP_NO_SSLv2, OP_NO_SSLv3
Jean-Paul Calderone20222ae2011-05-19 21:43:46 -040033from OpenSSL.SSL import (
34 VERIFY_PEER, VERIFY_FAIL_IF_NO_PEER_CERT, VERIFY_CLIENT_ONCE, VERIFY_NONE)
Jean-Paul Calderone0222a492011-09-08 18:26:03 -040035
Jean-Paul Calderone20222ae2011-05-19 21:43:46 -040036from OpenSSL.SSL import (
Jean-Paul Calderone313bf012012-02-08 13:02:49 -050037 SESS_CACHE_OFF, SESS_CACHE_CLIENT, SESS_CACHE_SERVER, SESS_CACHE_BOTH,
38 SESS_CACHE_NO_AUTO_CLEAR, SESS_CACHE_NO_INTERNAL_LOOKUP,
39 SESS_CACHE_NO_INTERNAL_STORE, SESS_CACHE_NO_INTERNAL)
40
41from OpenSSL.SSL import (
Jean-Paul Calderoned899af02013-03-19 22:10:37 -070042 Error, SysCallError, WantReadError, WantWriteError, ZeroReturnError)
Jean-Paul Calderonee0fcf512012-02-13 09:10:15 -050043from OpenSSL.SSL import (
Jean-Paul Calderoned899af02013-03-19 22:10:37 -070044 Context, ContextType, Session, Connection, ConnectionType, SSLeay_version)
Jean-Paul Calderone7526d172010-09-09 17:55:31 -040045
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -050046from OpenSSL.test.util import TestCase, b
Jean-Paul Calderone20222ae2011-05-19 21:43:46 -040047from OpenSSL.test.test_crypto import (
48 cleartextCertificatePEM, cleartextPrivateKeyPEM)
49from OpenSSL.test.test_crypto import (
50 client_cert_pem, client_key_pem, server_cert_pem, server_key_pem,
51 root_cert_pem)
52
Jean-Paul Calderone4bccf5e2008-12-28 22:50:42 -050053try:
54 from OpenSSL.SSL import OP_NO_QUERY_MTU
55except ImportError:
56 OP_NO_QUERY_MTU = None
57try:
58 from OpenSSL.SSL import OP_COOKIE_EXCHANGE
59except ImportError:
60 OP_COOKIE_EXCHANGE = None
61try:
62 from OpenSSL.SSL import OP_NO_TICKET
63except ImportError:
64 OP_NO_TICKET = None
Jean-Paul Calderone5ef86512008-04-26 19:06:28 -040065
Jean-Paul Calderone0222a492011-09-08 18:26:03 -040066try:
Jean-Paul Calderonec62d4c12011-09-08 18:29:32 -040067 from OpenSSL.SSL import OP_NO_COMPRESSION
68except ImportError:
69 OP_NO_COMPRESSION = None
70
71try:
Jean-Paul Calderone0222a492011-09-08 18:26:03 -040072 from OpenSSL.SSL import MODE_RELEASE_BUFFERS
73except ImportError:
74 MODE_RELEASE_BUFFERS = None
75
Jean-Paul Calderone1461c492013-10-03 16:05:00 -040076try:
77 from OpenSSL.SSL import OP_NO_TLSv1, OP_NO_TLSv1_1, OP_NO_TLSv1_2
78except ImportError:
79 OP_NO_TLSv1 = OP_NO_TLSv1_1 = OP_NO_TLSv1_2 = None
80
Jean-Paul Calderone31e85a82011-03-21 19:13:35 -040081from OpenSSL.SSL import (
82 SSL_ST_CONNECT, SSL_ST_ACCEPT, SSL_ST_MASK, SSL_ST_INIT, SSL_ST_BEFORE,
83 SSL_ST_OK, SSL_ST_RENEGOTIATE,
84 SSL_CB_LOOP, SSL_CB_EXIT, SSL_CB_READ, SSL_CB_WRITE, SSL_CB_ALERT,
85 SSL_CB_READ_ALERT, SSL_CB_WRITE_ALERT, SSL_CB_ACCEPT_LOOP,
86 SSL_CB_ACCEPT_EXIT, SSL_CB_CONNECT_LOOP, SSL_CB_CONNECT_EXIT,
87 SSL_CB_HANDSHAKE_START, SSL_CB_HANDSHAKE_DONE)
Jean-Paul Calderone30c09ea2008-03-21 17:04:05 -040088
Jean-Paul Calderone6ace4782010-09-09 18:43:40 -040089# openssl dhparam 128 -out dh-128.pem (note that 128 is a small number of bits
90# to use)
91dhparam = """\
92-----BEGIN DH PARAMETERS-----
93MBYCEQCobsg29c9WZP/54oAPcwiDAgEC
94-----END DH PARAMETERS-----
95"""
96
97
Jean-Paul Calderonebf37f0f2010-07-31 14:56:20 -040098def verify_cb(conn, cert, errnum, depth, ok):
Jean-Paul Calderonebf37f0f2010-07-31 14:56:20 -040099 return ok
100
Jean-Paul Calderone20222ae2011-05-19 21:43:46 -0400101
Rick Deanb1ccd562009-07-09 23:52:39 -0500102def socket_pair():
Jean-Paul Calderone1a9613b2009-07-16 12:13:36 -0400103 """
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400104 Establish and return a pair of network sockets connected to each other.
Jean-Paul Calderone1a9613b2009-07-16 12:13:36 -0400105 """
106 # Connect a pair of sockets
Rick Deanb1ccd562009-07-09 23:52:39 -0500107 port = socket()
108 port.bind(('', 0))
109 port.listen(1)
110 client = socket()
111 client.setblocking(False)
Jean-Paul Calderonef23c5d92009-07-23 17:58:15 -0400112 client.connect_ex(("127.0.0.1", port.getsockname()[1]))
Jean-Paul Calderone94b24a82009-07-16 19:11:38 -0400113 client.setblocking(True)
Rick Deanb1ccd562009-07-09 23:52:39 -0500114 server = port.accept()[0]
Rick Deanb1ccd562009-07-09 23:52:39 -0500115
Jean-Paul Calderone1a9613b2009-07-16 12:13:36 -0400116 # Let's pass some unencrypted data to make sure our socket connection is
117 # fine. Just one byte, so we don't have to worry about buffers getting
118 # filled up or fragmentation.
Jean-Paul Calderone9e4eeae2010-08-22 21:32:52 -0400119 server.send(b("x"))
120 assert client.recv(1024) == b("x")
121 client.send(b("y"))
122 assert server.recv(1024) == b("y")
Rick Deanb1ccd562009-07-09 23:52:39 -0500123
Jean-Paul Calderone7ca48b52010-07-28 18:57:21 -0400124 # Most of our callers want non-blocking sockets, make it easy for them.
Jean-Paul Calderone94b24a82009-07-16 19:11:38 -0400125 server.setblocking(False)
126 client.setblocking(False)
127
Rick Deanb1ccd562009-07-09 23:52:39 -0500128 return (server, client)
129
130
Jean-Paul Calderone94b24a82009-07-16 19:11:38 -0400131
Jean-Paul Calderonef8742032010-09-25 00:00:32 -0400132def handshake(client, server):
133 conns = [client, server]
134 while conns:
135 for conn in conns:
136 try:
137 conn.do_handshake()
138 except WantReadError:
139 pass
140 else:
141 conns.remove(conn)
142
143
Jean-Paul Calderone20222ae2011-05-19 21:43:46 -0400144def _create_certificate_chain():
145 """
146 Construct and return a chain of certificates.
147
148 1. A new self-signed certificate authority certificate (cacert)
149 2. A new intermediate certificate signed by cacert (icert)
150 3. A new server certificate signed by icert (scert)
151 """
152 caext = X509Extension(b('basicConstraints'), False, b('CA:true'))
153
154 # Step 1
155 cakey = PKey()
156 cakey.generate_key(TYPE_RSA, 512)
157 cacert = X509()
158 cacert.get_subject().commonName = "Authority Certificate"
159 cacert.set_issuer(cacert.get_subject())
160 cacert.set_pubkey(cakey)
161 cacert.set_notBefore(b("20000101000000Z"))
162 cacert.set_notAfter(b("20200101000000Z"))
163 cacert.add_extensions([caext])
164 cacert.set_serial_number(0)
165 cacert.sign(cakey, "sha1")
166
167 # Step 2
168 ikey = PKey()
169 ikey.generate_key(TYPE_RSA, 512)
170 icert = X509()
171 icert.get_subject().commonName = "Intermediate Certificate"
172 icert.set_issuer(cacert.get_subject())
173 icert.set_pubkey(ikey)
174 icert.set_notBefore(b("20000101000000Z"))
175 icert.set_notAfter(b("20200101000000Z"))
176 icert.add_extensions([caext])
177 icert.set_serial_number(0)
178 icert.sign(cakey, "sha1")
179
180 # Step 3
181 skey = PKey()
182 skey.generate_key(TYPE_RSA, 512)
183 scert = X509()
184 scert.get_subject().commonName = "Server Certificate"
185 scert.set_issuer(icert.get_subject())
186 scert.set_pubkey(skey)
187 scert.set_notBefore(b("20000101000000Z"))
188 scert.set_notAfter(b("20200101000000Z"))
189 scert.add_extensions([
190 X509Extension(b('basicConstraints'), True, b('CA:false'))])
191 scert.set_serial_number(0)
192 scert.sign(ikey, "sha1")
193
194 return [(cakey, cacert), (ikey, icert), (skey, scert)]
195
196
197
Jean-Paul Calderonebf37f0f2010-07-31 14:56:20 -0400198class _LoopbackMixin:
Jean-Paul Calderonea8fb0c82010-09-09 18:04:56 -0400199 """
200 Helper mixin which defines methods for creating a connected socket pair and
201 for forcing two connected SSL sockets to talk to each other via memory BIOs.
202 """
Jean-Paul Calderonefef5c4b2012-02-14 16:31:52 -0500203 def _loopbackClientFactory(self, socket):
204 client = Connection(Context(TLSv1_METHOD), socket)
205 client.set_connect_state()
206 return client
Jean-Paul Calderonebf37f0f2010-07-31 14:56:20 -0400207
Jean-Paul Calderonefef5c4b2012-02-14 16:31:52 -0500208
209 def _loopbackServerFactory(self, socket):
Jean-Paul Calderonebf37f0f2010-07-31 14:56:20 -0400210 ctx = Context(TLSv1_METHOD)
211 ctx.use_privatekey(load_privatekey(FILETYPE_PEM, server_key_pem))
212 ctx.use_certificate(load_certificate(FILETYPE_PEM, server_cert_pem))
Jean-Paul Calderonefef5c4b2012-02-14 16:31:52 -0500213 server = Connection(ctx, socket)
Jean-Paul Calderonebf37f0f2010-07-31 14:56:20 -0400214 server.set_accept_state()
Jean-Paul Calderonefef5c4b2012-02-14 16:31:52 -0500215 return server
216
217
218 def _loopback(self, serverFactory=None, clientFactory=None):
219 if serverFactory is None:
220 serverFactory = self._loopbackServerFactory
221 if clientFactory is None:
222 clientFactory = self._loopbackClientFactory
223
224 (server, client) = socket_pair()
225 server = serverFactory(server)
226 client = clientFactory(client)
Jean-Paul Calderonebf37f0f2010-07-31 14:56:20 -0400227
Jean-Paul Calderonef8742032010-09-25 00:00:32 -0400228 handshake(client, server)
Jean-Paul Calderonebf37f0f2010-07-31 14:56:20 -0400229
230 server.setblocking(True)
231 client.setblocking(True)
232 return server, client
233
234
235 def _interactInMemory(self, client_conn, server_conn):
236 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900237 Try to read application bytes from each of the two :py:obj:`Connection`
Jean-Paul Calderonebf37f0f2010-07-31 14:56:20 -0400238 objects. Copy bytes back and forth between their send/receive buffers
239 for as long as there is anything to copy. When there is nothing more
Jonathan Ballet648875f2011-07-16 14:14:58 +0900240 to copy, return :py:obj:`None`. If one of them actually manages to deliver
Jean-Paul Calderonebf37f0f2010-07-31 14:56:20 -0400241 some application bytes, return a two-tuple of the connection from which
242 the bytes were read and the bytes themselves.
243 """
244 wrote = True
245 while wrote:
246 # Loop until neither side has anything to say
247 wrote = False
248
249 # Copy stuff from each side's send buffer to the other side's
250 # receive buffer.
251 for (read, write) in [(client_conn, server_conn),
252 (server_conn, client_conn)]:
253
254 # Give the side a chance to generate some more bytes, or
255 # succeed.
256 try:
Jean-Paul Calderone20222ae2011-05-19 21:43:46 -0400257 data = read.recv(2 ** 16)
Jean-Paul Calderonebf37f0f2010-07-31 14:56:20 -0400258 except WantReadError:
259 # It didn't succeed, so we'll hope it generated some
260 # output.
261 pass
262 else:
263 # It did succeed, so we'll stop now and let the caller deal
264 # with it.
Jean-Paul Calderone20222ae2011-05-19 21:43:46 -0400265 return (read, data)
Jean-Paul Calderonebf37f0f2010-07-31 14:56:20 -0400266
267 while True:
268 # Keep copying as long as there's more stuff there.
269 try:
270 dirty = read.bio_read(4096)
271 except WantReadError:
272 # Okay, nothing more waiting to be sent. Stop
273 # processing this send buffer.
274 break
275 else:
276 # Keep track of the fact that someone generated some
277 # output.
278 wrote = True
279 write.bio_write(dirty)
280
281
Jean-Paul Calderone6a8cd112014-04-02 21:09:08 -0400282 def _handshakeInMemory(self, client_conn, server_conn):
283 client_conn.set_connect_state()
284 server_conn.set_accept_state()
285
286 for conn in [client_conn, server_conn]:
287 try:
288 conn.do_handshake()
289 except WantReadError:
290 pass
291
292 self._interactInMemory(client_conn, server_conn)
293
294
Jean-Paul Calderone20222ae2011-05-19 21:43:46 -0400295
Jean-Paul Calderone9f2e38e2011-04-14 09:36:55 -0400296class VersionTests(TestCase):
297 """
298 Tests for version information exposed by
Jonathan Ballet648875f2011-07-16 14:14:58 +0900299 :py:obj:`OpenSSL.SSL.SSLeay_version` and
300 :py:obj:`OpenSSL.SSL.OPENSSL_VERSION_NUMBER`.
Jean-Paul Calderone9f2e38e2011-04-14 09:36:55 -0400301 """
302 def test_OPENSSL_VERSION_NUMBER(self):
303 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900304 :py:obj:`OPENSSL_VERSION_NUMBER` is an integer with status in the low
Jean-Paul Calderone9f2e38e2011-04-14 09:36:55 -0400305 byte and the patch, fix, minor, and major versions in the
306 nibbles above that.
307 """
308 self.assertTrue(isinstance(OPENSSL_VERSION_NUMBER, int))
309
310
311 def test_SSLeay_version(self):
312 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900313 :py:obj:`SSLeay_version` takes a version type indicator and returns
Jean-Paul Calderone9f2e38e2011-04-14 09:36:55 -0400314 one of a number of version strings based on that indicator.
315 """
316 versions = {}
317 for t in [SSLEAY_VERSION, SSLEAY_CFLAGS, SSLEAY_BUILT_ON,
318 SSLEAY_PLATFORM, SSLEAY_DIR]:
319 version = SSLeay_version(t)
320 versions[version] = t
321 self.assertTrue(isinstance(version, bytes))
322 self.assertEqual(len(versions), 5)
323
324
Jean-Paul Calderonebf37f0f2010-07-31 14:56:20 -0400325
326class ContextTests(TestCase, _LoopbackMixin):
Jean-Paul Calderone30c09ea2008-03-21 17:04:05 -0400327 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900328 Unit tests for :py:obj:`OpenSSL.SSL.Context`.
Jean-Paul Calderone30c09ea2008-03-21 17:04:05 -0400329 """
330 def test_method(self):
331 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900332 :py:obj:`Context` can be instantiated with one of :py:obj:`SSLv2_METHOD`,
Jean-Paul Calderone1461c492013-10-03 16:05:00 -0400333 :py:obj:`SSLv3_METHOD`, :py:obj:`SSLv23_METHOD`, :py:obj:`TLSv1_METHOD`,
334 :py:obj:`TLSv1_1_METHOD`, or :py:obj:`TLSv1_2_METHOD`.
Jean-Paul Calderone30c09ea2008-03-21 17:04:05 -0400335 """
Jean-Paul Calderone1461c492013-10-03 16:05:00 -0400336 methods = [
337 SSLv3_METHOD, SSLv23_METHOD, TLSv1_METHOD]
338 for meth in methods:
Jean-Paul Calderone30c09ea2008-03-21 17:04:05 -0400339 Context(meth)
Jean-Paul Calderone9f2e38e2011-04-14 09:36:55 -0400340
Jean-Paul Calderone1461c492013-10-03 16:05:00 -0400341
342 maybe = [SSLv2_METHOD, TLSv1_1_METHOD, TLSv1_2_METHOD]
343 for meth in maybe:
344 try:
345 Context(meth)
346 except (Error, ValueError):
347 # Some versions of OpenSSL have SSLv2 / TLSv1.1 / TLSv1.2, some
348 # don't. Difficult to say in advance.
349 pass
Jean-Paul Calderone9f2e38e2011-04-14 09:36:55 -0400350
Jean-Paul Calderone30c09ea2008-03-21 17:04:05 -0400351 self.assertRaises(TypeError, Context, "")
352 self.assertRaises(ValueError, Context, 10)
353
354
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -0500355 if not PY3:
356 def test_method_long(self):
357 """
358 On Python 2 :py:class:`Context` accepts values of type
359 :py:obj:`long` as well as :py:obj:`int`.
360 """
361 Context(long(TLSv1_METHOD))
362
363
364
Rick Deane15b1472009-07-09 15:53:42 -0500365 def test_type(self):
366 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900367 :py:obj:`Context` and :py:obj:`ContextType` refer to the same type object and can be
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400368 used to create instances of that type.
Rick Deane15b1472009-07-09 15:53:42 -0500369 """
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400370 self.assertIdentical(Context, ContextType)
371 self.assertConsistentType(Context, 'Context', TLSv1_METHOD)
Rick Deane15b1472009-07-09 15:53:42 -0500372
373
Jean-Paul Calderone30c09ea2008-03-21 17:04:05 -0400374 def test_use_privatekey(self):
375 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900376 :py:obj:`Context.use_privatekey` takes an :py:obj:`OpenSSL.crypto.PKey` instance.
Jean-Paul Calderone30c09ea2008-03-21 17:04:05 -0400377 """
378 key = PKey()
379 key.generate_key(TYPE_RSA, 128)
380 ctx = Context(TLSv1_METHOD)
381 ctx.use_privatekey(key)
382 self.assertRaises(TypeError, ctx.use_privatekey, "")
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -0400383
384
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800385 def test_use_privatekey_file_missing(self):
386 """
387 :py:obj:`Context.use_privatekey_file` raises :py:obj:`OpenSSL.SSL.Error`
388 when passed the name of a file which does not exist.
389 """
390 ctx = Context(TLSv1_METHOD)
391 self.assertRaises(Error, ctx.use_privatekey_file, self.mktemp())
392
393
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -0500394 if not PY3:
395 def test_use_privatekey_file_long(self):
396 """
397 On Python 2 :py:obj:`Context.use_privatekey_file` accepts a
398 filetype of type :py:obj:`long` as well as :py:obj:`int`.
399 """
400 pemfile = self.mktemp()
401
402 key = PKey()
403 key.generate_key(TYPE_RSA, 128)
404
405 with open(pemfile, "wt") as pem:
406 pem.write(
407 dump_privatekey(FILETYPE_PEM, key).decode("ascii"))
408
409 ctx = Context(TLSv1_METHOD)
410 ctx.use_privatekey_file(pemfile, long(FILETYPE_PEM))
411
412
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800413 def test_use_certificate_wrong_args(self):
414 """
415 :py:obj:`Context.use_certificate_wrong_args` raises :py:obj:`TypeError`
416 when not passed exactly one :py:obj:`OpenSSL.crypto.X509` instance as an
417 argument.
418 """
419 ctx = Context(TLSv1_METHOD)
420 self.assertRaises(TypeError, ctx.use_certificate)
421 self.assertRaises(TypeError, ctx.use_certificate, "hello, world")
422 self.assertRaises(TypeError, ctx.use_certificate, X509(), "hello, world")
423
424
425 def test_use_certificate_uninitialized(self):
426 """
427 :py:obj:`Context.use_certificate` raises :py:obj:`OpenSSL.SSL.Error`
428 when passed a :py:obj:`OpenSSL.crypto.X509` instance which has not been
429 initialized (ie, which does not actually have any certificate data).
430 """
431 ctx = Context(TLSv1_METHOD)
432 self.assertRaises(Error, ctx.use_certificate, X509())
433
434
435 def test_use_certificate(self):
436 """
437 :py:obj:`Context.use_certificate` sets the certificate which will be
438 used to identify connections created using the context.
439 """
440 # TODO
441 # Hard to assert anything. But we could set a privatekey then ask
442 # OpenSSL if the cert and key agree using check_privatekey. Then as
443 # long as check_privatekey works right we're good...
444 ctx = Context(TLSv1_METHOD)
445 ctx.use_certificate(load_certificate(FILETYPE_PEM, cleartextCertificatePEM))
446
447
448 def test_use_certificate_file_wrong_args(self):
449 """
450 :py:obj:`Context.use_certificate_file` raises :py:obj:`TypeError` if
451 called with zero arguments or more than two arguments, or if the first
452 argument is not a byte string or the second argumnent is not an integer.
453 """
454 ctx = Context(TLSv1_METHOD)
455 self.assertRaises(TypeError, ctx.use_certificate_file)
456 self.assertRaises(TypeError, ctx.use_certificate_file, b"somefile", object())
457 self.assertRaises(
458 TypeError, ctx.use_certificate_file, b"somefile", FILETYPE_PEM, object())
459 self.assertRaises(
460 TypeError, ctx.use_certificate_file, object(), FILETYPE_PEM)
461 self.assertRaises(
462 TypeError, ctx.use_certificate_file, b"somefile", object())
463
464
465 def test_use_certificate_file_missing(self):
466 """
467 :py:obj:`Context.use_certificate_file` raises
468 `:py:obj:`OpenSSL.SSL.Error` if passed the name of a file which does not
469 exist.
470 """
471 ctx = Context(TLSv1_METHOD)
472 self.assertRaises(Error, ctx.use_certificate_file, self.mktemp())
473
474
475 def test_use_certificate_file(self):
476 """
477 :py:obj:`Context.use_certificate` sets the certificate which will be
478 used to identify connections created using the context.
479 """
480 # TODO
481 # Hard to assert anything. But we could set a privatekey then ask
482 # OpenSSL if the cert and key agree using check_privatekey. Then as
483 # long as check_privatekey works right we're good...
484 pem_filename = self.mktemp()
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -0500485 with open(pem_filename, "wb") as pem_file:
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800486 pem_file.write(cleartextCertificatePEM)
487
488 ctx = Context(TLSv1_METHOD)
489 ctx.use_certificate_file(pem_filename)
490
491
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -0500492 if not PY3:
493 def test_use_certificate_file_long(self):
494 """
495 On Python 2 :py:obj:`Context.use_certificate_file` accepts a
496 filetype of type :py:obj:`long` as well as :py:obj:`int`.
497 """
498 pem_filename = self.mktemp()
499 with open(pem_filename, "wb") as pem_file:
500 pem_file.write(cleartextCertificatePEM)
501
502 ctx = Context(TLSv1_METHOD)
503 ctx.use_certificate_file(pem_filename, long(FILETYPE_PEM))
504
505
Jean-Paul Calderonebd479162010-07-30 18:03:25 -0400506 def test_set_app_data_wrong_args(self):
507 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900508 :py:obj:`Context.set_app_data` raises :py:obj:`TypeError` if called with other than
Jean-Paul Calderonebd479162010-07-30 18:03:25 -0400509 one argument.
510 """
511 context = Context(TLSv1_METHOD)
512 self.assertRaises(TypeError, context.set_app_data)
513 self.assertRaises(TypeError, context.set_app_data, None, None)
514
515
516 def test_get_app_data_wrong_args(self):
517 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900518 :py:obj:`Context.get_app_data` raises :py:obj:`TypeError` if called with any
Jean-Paul Calderonebd479162010-07-30 18:03:25 -0400519 arguments.
520 """
521 context = Context(TLSv1_METHOD)
522 self.assertRaises(TypeError, context.get_app_data, None)
523
524
525 def test_app_data(self):
526 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900527 :py:obj:`Context.set_app_data` stores an object for later retrieval using
528 :py:obj:`Context.get_app_data`.
Jean-Paul Calderonebd479162010-07-30 18:03:25 -0400529 """
530 app_data = object()
531 context = Context(TLSv1_METHOD)
532 context.set_app_data(app_data)
533 self.assertIdentical(context.get_app_data(), app_data)
534
535
Jean-Paul Calderone40569ca2010-07-30 18:04:58 -0400536 def test_set_options_wrong_args(self):
537 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900538 :py:obj:`Context.set_options` raises :py:obj:`TypeError` if called with the wrong
539 number of arguments or a non-:py:obj:`int` argument.
Jean-Paul Calderone40569ca2010-07-30 18:04:58 -0400540 """
541 context = Context(TLSv1_METHOD)
542 self.assertRaises(TypeError, context.set_options)
543 self.assertRaises(TypeError, context.set_options, None)
544 self.assertRaises(TypeError, context.set_options, 1, None)
545
546
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500547 def test_set_options(self):
548 """
549 :py:obj:`Context.set_options` returns the new options value.
550 """
551 context = Context(TLSv1_METHOD)
552 options = context.set_options(OP_NO_SSLv2)
553 self.assertTrue(OP_NO_SSLv2 & options)
554
555
556 if not PY3:
557 def test_set_options_long(self):
558 """
559 On Python 2 :py:obj:`Context.set_options` accepts values of type
560 :py:obj:`long` as well as :py:obj:`int`.
561 """
562 context = Context(TLSv1_METHOD)
563 options = context.set_options(long(OP_NO_SSLv2))
564 self.assertTrue(OP_NO_SSLv2 & options)
565
566
Guillermo Gonzalez74a2c292011-08-29 16:16:58 -0300567 def test_set_mode_wrong_args(self):
568 """
Jean-Paul Calderone64efa2c2011-09-11 10:00:09 -0400569 :py:obj:`Context.set`mode} raises :py:obj:`TypeError` if called with the wrong
570 number of arguments or a non-:py:obj:`int` argument.
Guillermo Gonzalez74a2c292011-08-29 16:16:58 -0300571 """
572 context = Context(TLSv1_METHOD)
573 self.assertRaises(TypeError, context.set_mode)
574 self.assertRaises(TypeError, context.set_mode, None)
575 self.assertRaises(TypeError, context.set_mode, 1, None)
576
577
Jean-Paul Calderone0222a492011-09-08 18:26:03 -0400578 if MODE_RELEASE_BUFFERS is not None:
579 def test_set_mode(self):
580 """
Jean-Paul Calderone64efa2c2011-09-11 10:00:09 -0400581 :py:obj:`Context.set_mode` accepts a mode bitvector and returns the newly
Jean-Paul Calderone0222a492011-09-08 18:26:03 -0400582 set mode.
583 """
584 context = Context(TLSv1_METHOD)
585 self.assertTrue(
586 MODE_RELEASE_BUFFERS & context.set_mode(MODE_RELEASE_BUFFERS))
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500587
588 if not PY3:
589 def test_set_mode_long(self):
590 """
591 On Python 2 :py:obj:`Context.set_mode` accepts values of type
592 :py:obj:`long` as well as :py:obj:`int`.
593 """
594 context = Context(TLSv1_METHOD)
595 mode = context.set_mode(long(MODE_RELEASE_BUFFERS))
596 self.assertTrue(MODE_RELEASE_BUFFERS & mode)
Jean-Paul Calderone0222a492011-09-08 18:26:03 -0400597 else:
598 "MODE_RELEASE_BUFFERS unavailable - OpenSSL version may be too old"
599
600
Jean-Paul Calderone5ebb44a2010-07-30 18:09:41 -0400601 def test_set_timeout_wrong_args(self):
602 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900603 :py:obj:`Context.set_timeout` raises :py:obj:`TypeError` if called with the wrong
604 number of arguments or a non-:py:obj:`int` argument.
Jean-Paul Calderone5ebb44a2010-07-30 18:09:41 -0400605 """
606 context = Context(TLSv1_METHOD)
607 self.assertRaises(TypeError, context.set_timeout)
608 self.assertRaises(TypeError, context.set_timeout, None)
609 self.assertRaises(TypeError, context.set_timeout, 1, None)
610
611
612 def test_get_timeout_wrong_args(self):
613 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900614 :py:obj:`Context.get_timeout` raises :py:obj:`TypeError` if called with any arguments.
Jean-Paul Calderone5ebb44a2010-07-30 18:09:41 -0400615 """
616 context = Context(TLSv1_METHOD)
617 self.assertRaises(TypeError, context.get_timeout, None)
618
619
620 def test_timeout(self):
621 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900622 :py:obj:`Context.set_timeout` sets the session timeout for all connections
623 created using the context object. :py:obj:`Context.get_timeout` retrieves this
Jean-Paul Calderone5ebb44a2010-07-30 18:09:41 -0400624 value.
625 """
626 context = Context(TLSv1_METHOD)
627 context.set_timeout(1234)
628 self.assertEquals(context.get_timeout(), 1234)
629
630
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500631 if not PY3:
632 def test_timeout_long(self):
633 """
634 On Python 2 :py:obj:`Context.set_timeout` accepts values of type
635 `long` as well as int.
636 """
637 context = Context(TLSv1_METHOD)
638 context.set_timeout(long(1234))
639 self.assertEquals(context.get_timeout(), 1234)
640
641
Jean-Paul Calderonee2b69512010-07-30 18:22:06 -0400642 def test_set_verify_depth_wrong_args(self):
643 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900644 :py:obj:`Context.set_verify_depth` raises :py:obj:`TypeError` if called with the wrong
645 number of arguments or a non-:py:obj:`int` argument.
Jean-Paul Calderonee2b69512010-07-30 18:22:06 -0400646 """
647 context = Context(TLSv1_METHOD)
648 self.assertRaises(TypeError, context.set_verify_depth)
649 self.assertRaises(TypeError, context.set_verify_depth, None)
650 self.assertRaises(TypeError, context.set_verify_depth, 1, None)
651
652
653 def test_get_verify_depth_wrong_args(self):
654 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900655 :py:obj:`Context.get_verify_depth` raises :py:obj:`TypeError` if called with any arguments.
Jean-Paul Calderonee2b69512010-07-30 18:22:06 -0400656 """
657 context = Context(TLSv1_METHOD)
658 self.assertRaises(TypeError, context.get_verify_depth, None)
659
660
661 def test_verify_depth(self):
662 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900663 :py:obj:`Context.set_verify_depth` sets the number of certificates in a chain
Jean-Paul Calderonee2b69512010-07-30 18:22:06 -0400664 to follow before giving up. The value can be retrieved with
Jonathan Ballet648875f2011-07-16 14:14:58 +0900665 :py:obj:`Context.get_verify_depth`.
Jean-Paul Calderonee2b69512010-07-30 18:22:06 -0400666 """
667 context = Context(TLSv1_METHOD)
668 context.set_verify_depth(11)
669 self.assertEquals(context.get_verify_depth(), 11)
670
671
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500672 if not PY3:
673 def test_verify_depth_long(self):
674 """
675 On Python 2 :py:obj:`Context.set_verify_depth` accepts values of
676 type `long` as well as int.
677 """
678 context = Context(TLSv1_METHOD)
679 context.set_verify_depth(long(11))
680 self.assertEquals(context.get_verify_depth(), 11)
681
682
Jean-Paul Calderone389d76d2010-07-30 17:57:53 -0400683 def _write_encrypted_pem(self, passphrase):
Jean-Paul Calderonea8fb0c82010-09-09 18:04:56 -0400684 """
685 Write a new private key out to a new file, encrypted using the given
686 passphrase. Return the path to the new file.
687 """
Jean-Paul Calderone389d76d2010-07-30 17:57:53 -0400688 key = PKey()
689 key.generate_key(TYPE_RSA, 128)
690 pemFile = self.mktemp()
Jean-Paul Calderonea9868832010-08-22 21:38:34 -0400691 fObj = open(pemFile, 'w')
692 pem = dump_privatekey(FILETYPE_PEM, key, "blowfish", passphrase)
693 fObj.write(pem.decode('ascii'))
Jean-Paul Calderone389d76d2010-07-30 17:57:53 -0400694 fObj.close()
695 return pemFile
696
697
Jean-Paul Calderonef4480622010-08-02 18:25:03 -0400698 def test_set_passwd_cb_wrong_args(self):
699 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900700 :py:obj:`Context.set_passwd_cb` raises :py:obj:`TypeError` if called with the
Jean-Paul Calderonef4480622010-08-02 18:25:03 -0400701 wrong arguments or with a non-callable first argument.
702 """
703 context = Context(TLSv1_METHOD)
704 self.assertRaises(TypeError, context.set_passwd_cb)
705 self.assertRaises(TypeError, context.set_passwd_cb, None)
706 self.assertRaises(TypeError, context.set_passwd_cb, lambda: None, None, None)
707
708
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -0400709 def test_set_passwd_cb(self):
710 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900711 :py:obj:`Context.set_passwd_cb` accepts a callable which will be invoked when
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -0400712 a private key is loaded from an encrypted PEM.
713 """
Jean-Paul Calderonea9868832010-08-22 21:38:34 -0400714 passphrase = b("foobar")
Jean-Paul Calderone389d76d2010-07-30 17:57:53 -0400715 pemFile = self._write_encrypted_pem(passphrase)
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -0400716 calledWith = []
717 def passphraseCallback(maxlen, verify, extra):
718 calledWith.append((maxlen, verify, extra))
719 return passphrase
720 context = Context(TLSv1_METHOD)
721 context.set_passwd_cb(passphraseCallback)
722 context.use_privatekey_file(pemFile)
723 self.assertTrue(len(calledWith), 1)
724 self.assertTrue(isinstance(calledWith[0][0], int))
725 self.assertTrue(isinstance(calledWith[0][1], int))
726 self.assertEqual(calledWith[0][2], None)
Jean-Paul Calderone5ef86512008-04-26 19:06:28 -0400727
728
Jean-Paul Calderone389d76d2010-07-30 17:57:53 -0400729 def test_passwd_callback_exception(self):
730 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900731 :py:obj:`Context.use_privatekey_file` propagates any exception raised by the
Jean-Paul Calderone389d76d2010-07-30 17:57:53 -0400732 passphrase callback.
733 """
Jean-Paul Calderonea9868832010-08-22 21:38:34 -0400734 pemFile = self._write_encrypted_pem(b("monkeys are nice"))
Jean-Paul Calderone389d76d2010-07-30 17:57:53 -0400735 def passphraseCallback(maxlen, verify, extra):
736 raise RuntimeError("Sorry, I am a fail.")
737
738 context = Context(TLSv1_METHOD)
739 context.set_passwd_cb(passphraseCallback)
740 self.assertRaises(RuntimeError, context.use_privatekey_file, pemFile)
741
742
743 def test_passwd_callback_false(self):
744 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900745 :py:obj:`Context.use_privatekey_file` raises :py:obj:`OpenSSL.SSL.Error` if the
Jean-Paul Calderone389d76d2010-07-30 17:57:53 -0400746 passphrase callback returns a false value.
747 """
Jean-Paul Calderonea9868832010-08-22 21:38:34 -0400748 pemFile = self._write_encrypted_pem(b("monkeys are nice"))
Jean-Paul Calderone389d76d2010-07-30 17:57:53 -0400749 def passphraseCallback(maxlen, verify, extra):
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -0500750 return b""
Jean-Paul Calderone389d76d2010-07-30 17:57:53 -0400751
752 context = Context(TLSv1_METHOD)
753 context.set_passwd_cb(passphraseCallback)
754 self.assertRaises(Error, context.use_privatekey_file, pemFile)
755
756
757 def test_passwd_callback_non_string(self):
758 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900759 :py:obj:`Context.use_privatekey_file` raises :py:obj:`OpenSSL.SSL.Error` if the
Jean-Paul Calderone389d76d2010-07-30 17:57:53 -0400760 passphrase callback returns a true non-string value.
761 """
Jean-Paul Calderonea9868832010-08-22 21:38:34 -0400762 pemFile = self._write_encrypted_pem(b("monkeys are nice"))
Jean-Paul Calderone389d76d2010-07-30 17:57:53 -0400763 def passphraseCallback(maxlen, verify, extra):
764 return 10
765
766 context = Context(TLSv1_METHOD)
767 context.set_passwd_cb(passphraseCallback)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800768 self.assertRaises(ValueError, context.use_privatekey_file, pemFile)
Jean-Paul Calderone389d76d2010-07-30 17:57:53 -0400769
770
771 def test_passwd_callback_too_long(self):
772 """
773 If the passphrase returned by the passphrase callback returns a string
774 longer than the indicated maximum length, it is truncated.
775 """
776 # A priori knowledge!
Jean-Paul Calderonea9868832010-08-22 21:38:34 -0400777 passphrase = b("x") * 1024
Jean-Paul Calderone389d76d2010-07-30 17:57:53 -0400778 pemFile = self._write_encrypted_pem(passphrase)
779 def passphraseCallback(maxlen, verify, extra):
780 assert maxlen == 1024
Jean-Paul Calderoneb1f7f5f2010-08-22 21:40:52 -0400781 return passphrase + b("y")
Jean-Paul Calderone389d76d2010-07-30 17:57:53 -0400782
783 context = Context(TLSv1_METHOD)
784 context.set_passwd_cb(passphraseCallback)
785 # This shall succeed because the truncated result is the correct
786 # passphrase.
787 context.use_privatekey_file(pemFile)
788
789
Jean-Paul Calderone5ef86512008-04-26 19:06:28 -0400790 def test_set_info_callback(self):
791 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900792 :py:obj:`Context.set_info_callback` accepts a callable which will be invoked
Jean-Paul Calderone5ef86512008-04-26 19:06:28 -0400793 when certain information about an SSL connection is available.
794 """
Rick Deanb1ccd562009-07-09 23:52:39 -0500795 (server, client) = socket_pair()
Jean-Paul Calderone5ef86512008-04-26 19:06:28 -0400796
797 clientSSL = Connection(Context(TLSv1_METHOD), client)
798 clientSSL.set_connect_state()
799
800 called = []
801 def info(conn, where, ret):
802 called.append((conn, where, ret))
803 context = Context(TLSv1_METHOD)
804 context.set_info_callback(info)
805 context.use_certificate(
806 load_certificate(FILETYPE_PEM, cleartextCertificatePEM))
807 context.use_privatekey(
808 load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM))
809
Jean-Paul Calderone5ef86512008-04-26 19:06:28 -0400810 serverSSL = Connection(context, server)
811 serverSSL.set_accept_state()
812
Jean-Paul Calderonef2bbc9c2014-02-02 10:59:14 -0500813 handshake(clientSSL, serverSSL)
Jean-Paul Calderone5ef86512008-04-26 19:06:28 -0400814
Jean-Paul Calderone3835e522014-02-02 11:12:30 -0500815 # The callback must always be called with a Connection instance as the
816 # first argument. It would probably be better to split this into
817 # separate tests for client and server side info callbacks so we could
818 # assert it is called with the right Connection instance. It would
819 # also be good to assert *something* about `where` and `ret`.
Jean-Paul Calderonef2bbc9c2014-02-02 10:59:14 -0500820 notConnections = [
821 conn for (conn, where, ret) in called
822 if not isinstance(conn, Connection)]
823 self.assertEqual(
824 [], notConnections,
825 "Some info callback arguments were not Connection instaces.")
Jean-Paul Calderonee1bd4322008-09-07 20:17:17 -0400826
827
Jean-Paul Calderone1cb5d022008-09-07 20:58:50 -0400828 def _load_verify_locations_test(self, *args):
Jean-Paul Calderonea8fb0c82010-09-09 18:04:56 -0400829 """
830 Create a client context which will verify the peer certificate and call
Jean-Paul Calderone64efa2c2011-09-11 10:00:09 -0400831 its :py:obj:`load_verify_locations` method with the given arguments.
832 Then connect it to a server and ensure that the handshake succeeds.
Jean-Paul Calderonea8fb0c82010-09-09 18:04:56 -0400833 """
Rick Deanb1ccd562009-07-09 23:52:39 -0500834 (server, client) = socket_pair()
Jean-Paul Calderonee1bd4322008-09-07 20:17:17 -0400835
Jean-Paul Calderonee1bd4322008-09-07 20:17:17 -0400836 clientContext = Context(TLSv1_METHOD)
Jean-Paul Calderone1cb5d022008-09-07 20:58:50 -0400837 clientContext.load_verify_locations(*args)
Jean-Paul Calderonee1bd4322008-09-07 20:17:17 -0400838 # Require that the server certificate verify properly or the
839 # connection will fail.
840 clientContext.set_verify(
841 VERIFY_PEER,
842 lambda conn, cert, errno, depth, preverify_ok: preverify_ok)
843
844 clientSSL = Connection(clientContext, client)
845 clientSSL.set_connect_state()
846
Jean-Paul Calderonee1bd4322008-09-07 20:17:17 -0400847 serverContext = Context(TLSv1_METHOD)
848 serverContext.use_certificate(
849 load_certificate(FILETYPE_PEM, cleartextCertificatePEM))
850 serverContext.use_privatekey(
851 load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM))
852
853 serverSSL = Connection(serverContext, server)
854 serverSSL.set_accept_state()
855
Jean-Paul Calderonef8742032010-09-25 00:00:32 -0400856 # Without load_verify_locations above, the handshake
857 # will fail:
858 # Error: [('SSL routines', 'SSL3_GET_SERVER_CERTIFICATE',
859 # 'certificate verify failed')]
860 handshake(clientSSL, serverSSL)
Jean-Paul Calderonee1bd4322008-09-07 20:17:17 -0400861
862 cert = clientSSL.get_peer_certificate()
Jean-Paul Calderone20131f52009-04-01 12:05:45 -0400863 self.assertEqual(cert.get_subject().CN, 'Testing Root CA')
Jean-Paul Calderone5075fce2008-09-07 20:18:55 -0400864
Jean-Paul Calderone12608a82009-11-07 10:35:15 -0500865
Jean-Paul Calderone1cb5d022008-09-07 20:58:50 -0400866 def test_load_verify_file(self):
867 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900868 :py:obj:`Context.load_verify_locations` accepts a file name and uses the
Jean-Paul Calderone1cb5d022008-09-07 20:58:50 -0400869 certificates within for verification purposes.
870 """
871 cafile = self.mktemp()
Jean-Paul Calderonea9868832010-08-22 21:38:34 -0400872 fObj = open(cafile, 'w')
Jean-Paul Calderoneb1f7f5f2010-08-22 21:40:52 -0400873 fObj.write(cleartextCertificatePEM.decode('ascii'))
Jean-Paul Calderone1cb5d022008-09-07 20:58:50 -0400874 fObj.close()
875
876 self._load_verify_locations_test(cafile)
877
Jean-Paul Calderone5075fce2008-09-07 20:18:55 -0400878
879 def test_load_verify_invalid_file(self):
880 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900881 :py:obj:`Context.load_verify_locations` raises :py:obj:`Error` when passed a
Jean-Paul Calderone5075fce2008-09-07 20:18:55 -0400882 non-existent cafile.
883 """
884 clientContext = Context(TLSv1_METHOD)
885 self.assertRaises(
886 Error, clientContext.load_verify_locations, self.mktemp())
Jean-Paul Calderone1cb5d022008-09-07 20:58:50 -0400887
888
889 def test_load_verify_directory(self):
890 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900891 :py:obj:`Context.load_verify_locations` accepts a directory name and uses
Jean-Paul Calderone1cb5d022008-09-07 20:58:50 -0400892 the certificates within for verification purposes.
893 """
894 capath = self.mktemp()
895 makedirs(capath)
Jean-Paul Calderone24dfb332011-05-04 18:10:26 -0400896 # Hash values computed manually with c_rehash to avoid depending on
897 # c_rehash in the test suite. One is from OpenSSL 0.9.8, the other
898 # from OpenSSL 1.0.0.
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -0500899 for name in [b'c7adac82.0', b'c3705638.0']:
Jean-Paul Calderone24dfb332011-05-04 18:10:26 -0400900 cafile = join(capath, name)
901 fObj = open(cafile, 'w')
902 fObj.write(cleartextCertificatePEM.decode('ascii'))
903 fObj.close()
Jean-Paul Calderone1cb5d022008-09-07 20:58:50 -0400904
Jean-Paul Calderone1cb5d022008-09-07 20:58:50 -0400905 self._load_verify_locations_test(None, capath)
906
907
Jean-Paul Calderonef4480622010-08-02 18:25:03 -0400908 def test_load_verify_locations_wrong_args(self):
909 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900910 :py:obj:`Context.load_verify_locations` raises :py:obj:`TypeError` if called with
911 the wrong number of arguments or with non-:py:obj:`str` arguments.
Jean-Paul Calderonef4480622010-08-02 18:25:03 -0400912 """
913 context = Context(TLSv1_METHOD)
914 self.assertRaises(TypeError, context.load_verify_locations)
915 self.assertRaises(TypeError, context.load_verify_locations, object())
916 self.assertRaises(TypeError, context.load_verify_locations, object(), object())
917 self.assertRaises(TypeError, context.load_verify_locations, None, None, None)
918
919
Jean-Paul Calderone7ca48b52010-07-28 18:57:21 -0400920 if platform == "win32":
921 "set_default_verify_paths appears not to work on Windows. "
Jean-Paul Calderone28fb8f02009-07-24 18:01:31 -0400922 "See LP#404343 and LP#404344."
923 else:
924 def test_set_default_verify_paths(self):
925 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900926 :py:obj:`Context.set_default_verify_paths` causes the platform-specific CA
Jean-Paul Calderone28fb8f02009-07-24 18:01:31 -0400927 certificate locations to be used for verification purposes.
928 """
929 # Testing this requires a server with a certificate signed by one of
930 # the CAs in the platform CA location. Getting one of those costs
931 # money. Fortunately (or unfortunately, depending on your
932 # perspective), it's easy to think of a public server on the
933 # internet which has such a certificate. Connecting to the network
934 # in a unit test is bad, but it's the only way I can think of to
935 # really test this. -exarkun
Jean-Paul Calderone1cb5d022008-09-07 20:58:50 -0400936
Jean-Paul Calderone28fb8f02009-07-24 18:01:31 -0400937 # Arg, verisign.com doesn't speak TLSv1
938 context = Context(SSLv3_METHOD)
939 context.set_default_verify_paths()
940 context.set_verify(
Ziga Seilnacht44611bf2009-08-31 20:49:30 +0200941 VERIFY_PEER,
Jean-Paul Calderone28fb8f02009-07-24 18:01:31 -0400942 lambda conn, cert, errno, depth, preverify_ok: preverify_ok)
Jean-Paul Calderone1cb5d022008-09-07 20:58:50 -0400943
Jean-Paul Calderone28fb8f02009-07-24 18:01:31 -0400944 client = socket()
945 client.connect(('verisign.com', 443))
946 clientSSL = Connection(context, client)
947 clientSSL.set_connect_state()
948 clientSSL.do_handshake()
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -0500949 clientSSL.send(b"GET / HTTP/1.0\r\n\r\n")
Jean-Paul Calderone28fb8f02009-07-24 18:01:31 -0400950 self.assertTrue(clientSSL.recv(1024))
Jean-Paul Calderone9eadb962008-09-07 21:20:44 -0400951
952
953 def test_set_default_verify_paths_signature(self):
954 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900955 :py:obj:`Context.set_default_verify_paths` takes no arguments and raises
956 :py:obj:`TypeError` if given any.
Jean-Paul Calderone9eadb962008-09-07 21:20:44 -0400957 """
958 context = Context(TLSv1_METHOD)
959 self.assertRaises(TypeError, context.set_default_verify_paths, None)
960 self.assertRaises(TypeError, context.set_default_verify_paths, 1)
961 self.assertRaises(TypeError, context.set_default_verify_paths, "")
Jean-Paul Calderone327d8f92008-12-28 21:55:56 -0500962
Jean-Paul Calderonef4480622010-08-02 18:25:03 -0400963
Jean-Paul Calderone12608a82009-11-07 10:35:15 -0500964 def test_add_extra_chain_cert_invalid_cert(self):
965 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900966 :py:obj:`Context.add_extra_chain_cert` raises :py:obj:`TypeError` if called with
Jean-Paul Calderone12608a82009-11-07 10:35:15 -0500967 other than one argument or if called with an object which is not an
Jonathan Ballet648875f2011-07-16 14:14:58 +0900968 instance of :py:obj:`X509`.
Jean-Paul Calderone12608a82009-11-07 10:35:15 -0500969 """
970 context = Context(TLSv1_METHOD)
971 self.assertRaises(TypeError, context.add_extra_chain_cert)
972 self.assertRaises(TypeError, context.add_extra_chain_cert, object())
973 self.assertRaises(TypeError, context.add_extra_chain_cert, object(), object())
974
975
Jean-Paul Calderonef4480622010-08-02 18:25:03 -0400976 def _handshake_test(self, serverContext, clientContext):
977 """
978 Verify that a client and server created with the given contexts can
979 successfully handshake and communicate.
980 """
981 serverSocket, clientSocket = socket_pair()
982
Jean-Paul Calderonebf37f0f2010-07-31 14:56:20 -0400983 server = Connection(serverContext, serverSocket)
Jean-Paul Calderone9485f2c2010-07-29 22:38:42 -0400984 server.set_accept_state()
Jean-Paul Calderonebf37f0f2010-07-31 14:56:20 -0400985
Jean-Paul Calderonef4480622010-08-02 18:25:03 -0400986 client = Connection(clientContext, clientSocket)
987 client.set_connect_state()
988
989 # Make them talk to each other.
990 # self._interactInMemory(client, server)
991 for i in range(3):
992 for s in [client, server]:
993 try:
994 s.do_handshake()
995 except WantReadError:
996 pass
997
998
Jean-Paul Calderone6a8cd112014-04-02 21:09:08 -0400999 def test_set_verify_callback_connection_argument(self):
1000 """
1001 The first argument passed to the verify callback is the
1002 :py:class:`Connection` instance for which verification is taking place.
1003 """
1004 serverContext = Context(TLSv1_METHOD)
1005 serverContext.use_privatekey(
1006 load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM))
1007 serverContext.use_certificate(
1008 load_certificate(FILETYPE_PEM, cleartextCertificatePEM))
1009 serverConnection = Connection(serverContext, None)
1010
1011 class VerifyCallback(object):
1012 def callback(self, connection, *args):
1013 self.connection = connection
1014 return 1
1015
1016 verify = VerifyCallback()
1017 clientContext = Context(TLSv1_METHOD)
1018 clientContext.set_verify(VERIFY_PEER, verify.callback)
1019 clientConnection = Connection(clientContext, None)
1020 clientConnection.set_connect_state()
1021
1022 self._handshakeInMemory(clientConnection, serverConnection)
1023
1024 self.assertIdentical(verify.connection, clientConnection)
1025
1026
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -08001027 def test_set_verify_callback_exception(self):
1028 """
1029 If the verify callback passed to :py:obj:`Context.set_verify` raises an
1030 exception, verification fails and the exception is propagated to the
1031 caller of :py:obj:`Connection.do_handshake`.
1032 """
1033 serverContext = Context(TLSv1_METHOD)
1034 serverContext.use_privatekey(
1035 load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM))
1036 serverContext.use_certificate(
1037 load_certificate(FILETYPE_PEM, cleartextCertificatePEM))
1038
1039 clientContext = Context(TLSv1_METHOD)
1040 def verify_callback(*args):
1041 raise Exception("silly verify failure")
1042 clientContext.set_verify(VERIFY_PEER, verify_callback)
1043
1044 exc = self.assertRaises(
1045 Exception, self._handshake_test, serverContext, clientContext)
1046 self.assertEqual("silly verify failure", str(exc))
1047
1048
Jean-Paul Calderonef4480622010-08-02 18:25:03 -04001049 def test_add_extra_chain_cert(self):
1050 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001051 :py:obj:`Context.add_extra_chain_cert` accepts an :py:obj:`X509` instance to add to
Jean-Paul Calderonef4480622010-08-02 18:25:03 -04001052 the certificate chain.
1053
Jonathan Ballet648875f2011-07-16 14:14:58 +09001054 See :py:obj:`_create_certificate_chain` for the details of the certificate
Jean-Paul Calderonef4480622010-08-02 18:25:03 -04001055 chain tested.
1056
1057 The chain is tested by starting a server with scert and connecting
1058 to it with a client which trusts cacert and requires verification to
1059 succeed.
1060 """
Jean-Paul Calderone20222ae2011-05-19 21:43:46 -04001061 chain = _create_certificate_chain()
Jean-Paul Calderonef4480622010-08-02 18:25:03 -04001062 [(cakey, cacert), (ikey, icert), (skey, scert)] = chain
1063
Jean-Paul Calderonebf37f0f2010-07-31 14:56:20 -04001064 # Dump the CA certificate to a file because that's the only way to load
1065 # it as a trusted CA in the client context.
1066 for cert, name in [(cacert, 'ca.pem'), (icert, 'i.pem'), (scert, 's.pem')]:
Jean-Paul Calderonea9868832010-08-22 21:38:34 -04001067 fObj = open(name, 'w')
Jean-Paul Calderoneb1f7f5f2010-08-22 21:40:52 -04001068 fObj.write(dump_certificate(FILETYPE_PEM, cert).decode('ascii'))
Jean-Paul Calderonebf37f0f2010-07-31 14:56:20 -04001069 fObj.close()
1070
1071 for key, name in [(cakey, 'ca.key'), (ikey, 'i.key'), (skey, 's.key')]:
Jean-Paul Calderonea9868832010-08-22 21:38:34 -04001072 fObj = open(name, 'w')
Jean-Paul Calderoneb1f7f5f2010-08-22 21:40:52 -04001073 fObj.write(dump_privatekey(FILETYPE_PEM, key).decode('ascii'))
Jean-Paul Calderonebf37f0f2010-07-31 14:56:20 -04001074 fObj.close()
1075
Jean-Paul Calderonef4480622010-08-02 18:25:03 -04001076 # Create the server context
1077 serverContext = Context(TLSv1_METHOD)
1078 serverContext.use_privatekey(skey)
1079 serverContext.use_certificate(scert)
Jean-Paul Calderone16cf03d2010-09-08 18:53:39 -04001080 # The client already has cacert, we only need to give them icert.
Jean-Paul Calderonef4480622010-08-02 18:25:03 -04001081 serverContext.add_extra_chain_cert(icert)
1082
Jean-Paul Calderonebf37f0f2010-07-31 14:56:20 -04001083 # Create the client
1084 clientContext = Context(TLSv1_METHOD)
1085 clientContext.set_verify(
1086 VERIFY_PEER | VERIFY_FAIL_IF_NO_PEER_CERT, verify_cb)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001087 clientContext.load_verify_locations(b"ca.pem")
Jean-Paul Calderone9485f2c2010-07-29 22:38:42 -04001088
Jean-Paul Calderonef4480622010-08-02 18:25:03 -04001089 # Try it out.
1090 self._handshake_test(serverContext, clientContext)
1091
1092
Jean-Paul Calderonef4480622010-08-02 18:25:03 -04001093 def test_use_certificate_chain_file(self):
1094 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001095 :py:obj:`Context.use_certificate_chain_file` reads a certificate chain from
Jean-Paul Calderonef4480622010-08-02 18:25:03 -04001096 the specified file.
1097
1098 The chain is tested by starting a server with scert and connecting
1099 to it with a client which trusts cacert and requires verification to
1100 succeed.
1101 """
Jean-Paul Calderone20222ae2011-05-19 21:43:46 -04001102 chain = _create_certificate_chain()
Jean-Paul Calderonef4480622010-08-02 18:25:03 -04001103 [(cakey, cacert), (ikey, icert), (skey, scert)] = chain
1104
1105 # Write out the chain file.
1106 chainFile = self.mktemp()
Jean-Paul Calderoned8607982014-01-18 10:30:55 -05001107 fObj = open(chainFile, 'wb')
Jean-Paul Calderonef4480622010-08-02 18:25:03 -04001108 # Most specific to least general.
Jean-Paul Calderoned8607982014-01-18 10:30:55 -05001109 fObj.write(dump_certificate(FILETYPE_PEM, scert))
1110 fObj.write(dump_certificate(FILETYPE_PEM, icert))
1111 fObj.write(dump_certificate(FILETYPE_PEM, cacert))
Jean-Paul Calderonef4480622010-08-02 18:25:03 -04001112 fObj.close()
1113
1114 serverContext = Context(TLSv1_METHOD)
1115 serverContext.use_certificate_chain_file(chainFile)
1116 serverContext.use_privatekey(skey)
1117
Jean-Paul Calderonea9868832010-08-22 21:38:34 -04001118 fObj = open('ca.pem', 'w')
1119 fObj.write(dump_certificate(FILETYPE_PEM, cacert).decode('ascii'))
Jean-Paul Calderonef4480622010-08-02 18:25:03 -04001120 fObj.close()
1121
1122 clientContext = Context(TLSv1_METHOD)
1123 clientContext.set_verify(
1124 VERIFY_PEER | VERIFY_FAIL_IF_NO_PEER_CERT, verify_cb)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001125 clientContext.load_verify_locations(b"ca.pem")
Jean-Paul Calderonef4480622010-08-02 18:25:03 -04001126
1127 self._handshake_test(serverContext, clientContext)
1128
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001129
1130 def test_use_certificate_chain_file_wrong_args(self):
1131 """
1132 :py:obj:`Context.use_certificate_chain_file` raises :py:obj:`TypeError`
1133 if passed zero or more than one argument or when passed a non-byte
1134 string single argument. It also raises :py:obj:`OpenSSL.SSL.Error` when
1135 passed a bad chain file name (for example, the name of a file which does
1136 not exist).
1137 """
1138 context = Context(TLSv1_METHOD)
1139 self.assertRaises(TypeError, context.use_certificate_chain_file)
1140 self.assertRaises(TypeError, context.use_certificate_chain_file, object())
1141 self.assertRaises(TypeError, context.use_certificate_chain_file, b"foo", object())
1142
1143 self.assertRaises(Error, context.use_certificate_chain_file, self.mktemp())
1144
Jean-Paul Calderonee0d79362010-08-03 18:46:46 -04001145 # XXX load_client_ca
1146 # XXX set_session_id
Jean-Paul Calderone0294e3d2010-09-09 18:17:48 -04001147
1148 def test_get_verify_mode_wrong_args(self):
1149 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001150 :py:obj:`Context.get_verify_mode` raises :py:obj:`TypeError` if called with any
Jean-Paul Calderone0294e3d2010-09-09 18:17:48 -04001151 arguments.
1152 """
1153 context = Context(TLSv1_METHOD)
1154 self.assertRaises(TypeError, context.get_verify_mode, None)
1155
1156
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -05001157 def test_set_verify_mode(self):
Jean-Paul Calderone0294e3d2010-09-09 18:17:48 -04001158 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001159 :py:obj:`Context.get_verify_mode` returns the verify mode flags previously
1160 passed to :py:obj:`Context.set_verify`.
Jean-Paul Calderone0294e3d2010-09-09 18:17:48 -04001161 """
1162 context = Context(TLSv1_METHOD)
1163 self.assertEquals(context.get_verify_mode(), 0)
1164 context.set_verify(
1165 VERIFY_PEER | VERIFY_CLIENT_ONCE, lambda *args: None)
1166 self.assertEquals(
1167 context.get_verify_mode(), VERIFY_PEER | VERIFY_CLIENT_ONCE)
1168
Jean-Paul Calderone6ace4782010-09-09 18:43:40 -04001169
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -05001170 if not PY3:
1171 def test_set_verify_mode_long(self):
1172 """
1173 On Python 2 :py:obj:`Context.set_verify_mode` accepts values of
1174 type :py:obj:`long` as well as :py:obj:`int`.
1175 """
1176 context = Context(TLSv1_METHOD)
1177 self.assertEquals(context.get_verify_mode(), 0)
1178 context.set_verify(
1179 long(VERIFY_PEER | VERIFY_CLIENT_ONCE), lambda *args: None)
1180 self.assertEquals(
1181 context.get_verify_mode(), VERIFY_PEER | VERIFY_CLIENT_ONCE)
1182
1183
Jean-Paul Calderone6ace4782010-09-09 18:43:40 -04001184 def test_load_tmp_dh_wrong_args(self):
1185 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001186 :py:obj:`Context.load_tmp_dh` raises :py:obj:`TypeError` if called with the wrong
1187 number of arguments or with a non-:py:obj:`str` argument.
Jean-Paul Calderone6ace4782010-09-09 18:43:40 -04001188 """
1189 context = Context(TLSv1_METHOD)
1190 self.assertRaises(TypeError, context.load_tmp_dh)
1191 self.assertRaises(TypeError, context.load_tmp_dh, "foo", None)
1192 self.assertRaises(TypeError, context.load_tmp_dh, object())
1193
1194
1195 def test_load_tmp_dh_missing_file(self):
1196 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001197 :py:obj:`Context.load_tmp_dh` raises :py:obj:`OpenSSL.SSL.Error` if the specified file
Jean-Paul Calderone6ace4782010-09-09 18:43:40 -04001198 does not exist.
1199 """
1200 context = Context(TLSv1_METHOD)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001201 self.assertRaises(Error, context.load_tmp_dh, b"hello")
Jean-Paul Calderone6ace4782010-09-09 18:43:40 -04001202
1203
1204 def test_load_tmp_dh(self):
1205 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001206 :py:obj:`Context.load_tmp_dh` loads Diffie-Hellman parameters from the
Jean-Paul Calderone6ace4782010-09-09 18:43:40 -04001207 specified file.
1208 """
1209 context = Context(TLSv1_METHOD)
1210 dhfilename = self.mktemp()
1211 dhfile = open(dhfilename, "w")
1212 dhfile.write(dhparam)
1213 dhfile.close()
1214 context.load_tmp_dh(dhfilename)
1215 # XXX What should I assert here? -exarkun
1216
1217
Jean-Paul Calderone3e4e3352014-04-19 09:28:28 -04001218 def test_set_tmp_ecdh(self):
Andy Lutomirskif05a2732014-03-13 17:22:25 -07001219 """
Jean-Paul Calderone3e4e3352014-04-19 09:28:28 -04001220 :py:obj:`Context.set_tmp_ecdh` sets the elliptic curve for
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04001221 Diffie-Hellman to the specified curve.
Andy Lutomirskif05a2732014-03-13 17:22:25 -07001222 """
1223 context = Context(TLSv1_METHOD)
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04001224 for curve in get_elliptic_curves():
1225 # The only easily "assertable" thing is that it does not raise an
1226 # exception.
Jean-Paul Calderone3e4e3352014-04-19 09:28:28 -04001227 context.set_tmp_ecdh(curve)
Alex Gaynor12dc0842014-01-17 12:51:31 -06001228
1229
Jean-Paul Calderone63eab692014-01-18 10:19:56 -05001230 def test_set_cipher_list_bytes(self):
Jean-Paul Calderone6ace4782010-09-09 18:43:40 -04001231 """
Jean-Paul Calderone63eab692014-01-18 10:19:56 -05001232 :py:obj:`Context.set_cipher_list` accepts a :py:obj:`bytes` naming the
1233 ciphers which connections created with the context object will be able
1234 to choose from.
Jean-Paul Calderone6ace4782010-09-09 18:43:40 -04001235 """
1236 context = Context(TLSv1_METHOD)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001237 context.set_cipher_list(b"hello world:EXP-RC4-MD5")
Jean-Paul Calderone6ace4782010-09-09 18:43:40 -04001238 conn = Connection(context, None)
1239 self.assertEquals(conn.get_cipher_list(), ["EXP-RC4-MD5"])
Jean-Paul Calderone9485f2c2010-07-29 22:38:42 -04001240
Jean-Paul Calderone9485f2c2010-07-29 22:38:42 -04001241
Jean-Paul Calderone63eab692014-01-18 10:19:56 -05001242 def test_set_cipher_list_text(self):
1243 """
1244 :py:obj:`Context.set_cipher_list` accepts a :py:obj:`unicode` naming
1245 the ciphers which connections created with the context object will be
1246 able to choose from.
1247 """
1248 context = Context(TLSv1_METHOD)
Jean-Paul Calderonec76c61c2014-01-18 13:21:52 -05001249 context.set_cipher_list(u("hello world:EXP-RC4-MD5"))
Jean-Paul Calderone63eab692014-01-18 10:19:56 -05001250 conn = Connection(context, None)
1251 self.assertEquals(conn.get_cipher_list(), ["EXP-RC4-MD5"])
1252
1253
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001254 def test_set_cipher_list_wrong_args(self):
1255 """
Jean-Paul Calderone17044832014-01-18 10:20:11 -05001256 :py:obj:`Context.set_cipher_list` raises :py:obj:`TypeError` when
1257 passed zero arguments or more than one argument or when passed a
1258 non-string single argument and raises :py:obj:`OpenSSL.SSL.Error` when
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001259 passed an incorrect cipher list string.
1260 """
1261 context = Context(TLSv1_METHOD)
1262 self.assertRaises(TypeError, context.set_cipher_list)
1263 self.assertRaises(TypeError, context.set_cipher_list, object())
1264 self.assertRaises(TypeError, context.set_cipher_list, b"EXP-RC4-MD5", object())
1265
Jean-Paul Calderone63eab692014-01-18 10:19:56 -05001266 self.assertRaises(Error, context.set_cipher_list, "imaginary-cipher")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001267
1268
Jean-Paul Calderone313bf012012-02-08 13:02:49 -05001269 def test_set_session_cache_mode_wrong_args(self):
1270 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -05001271 :py:obj:`Context.set_session_cache_mode` raises :py:obj:`TypeError` if
1272 called with other than one integer argument.
Jean-Paul Calderone313bf012012-02-08 13:02:49 -05001273 """
1274 context = Context(TLSv1_METHOD)
1275 self.assertRaises(TypeError, context.set_session_cache_mode)
1276 self.assertRaises(TypeError, context.set_session_cache_mode, object())
1277
1278
1279 def test_get_session_cache_mode_wrong_args(self):
1280 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -05001281 :py:obj:`Context.get_session_cache_mode` raises :py:obj:`TypeError` if
1282 called with any arguments.
Jean-Paul Calderone313bf012012-02-08 13:02:49 -05001283 """
1284 context = Context(TLSv1_METHOD)
1285 self.assertRaises(TypeError, context.get_session_cache_mode, 1)
1286
1287
1288 def test_session_cache_mode(self):
1289 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -05001290 :py:obj:`Context.set_session_cache_mode` specifies how sessions are
1291 cached. The setting can be retrieved via
1292 :py:obj:`Context.get_session_cache_mode`.
Jean-Paul Calderone313bf012012-02-08 13:02:49 -05001293 """
1294 context = Context(TLSv1_METHOD)
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -05001295 context.set_session_cache_mode(SESS_CACHE_OFF)
Jean-Paul Calderone313bf012012-02-08 13:02:49 -05001296 off = context.set_session_cache_mode(SESS_CACHE_BOTH)
1297 self.assertEqual(SESS_CACHE_OFF, off)
1298 self.assertEqual(SESS_CACHE_BOTH, context.get_session_cache_mode())
1299
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -05001300 if not PY3:
1301 def test_session_cache_mode_long(self):
1302 """
1303 On Python 2 :py:obj:`Context.set_session_cache_mode` accepts values
1304 of type :py:obj:`long` as well as :py:obj:`int`.
1305 """
1306 context = Context(TLSv1_METHOD)
1307 context.set_session_cache_mode(long(SESS_CACHE_BOTH))
1308 self.assertEqual(
1309 SESS_CACHE_BOTH, context.get_session_cache_mode())
1310
Jean-Paul Calderone313bf012012-02-08 13:02:49 -05001311
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001312 def test_get_cert_store(self):
1313 """
1314 :py:obj:`Context.get_cert_store` returns a :py:obj:`X509Store` instance.
1315 """
1316 context = Context(TLSv1_METHOD)
1317 store = context.get_cert_store()
1318 self.assertIsInstance(store, X509Store)
1319
1320
Jean-Paul Calderone9485f2c2010-07-29 22:38:42 -04001321
Jean-Paul Calderonec4cb6582011-05-26 18:47:00 -04001322class ServerNameCallbackTests(TestCase, _LoopbackMixin):
1323 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001324 Tests for :py:obj:`Context.set_tlsext_servername_callback` and its interaction with
1325 :py:obj:`Connection`.
Jean-Paul Calderonec4cb6582011-05-26 18:47:00 -04001326 """
1327 def test_wrong_args(self):
1328 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001329 :py:obj:`Context.set_tlsext_servername_callback` raises :py:obj:`TypeError` if called
Jean-Paul Calderonec4cb6582011-05-26 18:47:00 -04001330 with other than one argument.
1331 """
1332 context = Context(TLSv1_METHOD)
1333 self.assertRaises(TypeError, context.set_tlsext_servername_callback)
1334 self.assertRaises(
1335 TypeError, context.set_tlsext_servername_callback, 1, 2)
1336
Jean-Paul Calderone4c1aacd2014-01-11 08:15:17 -05001337
Jean-Paul Calderonec4cb6582011-05-26 18:47:00 -04001338 def test_old_callback_forgotten(self):
1339 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001340 If :py:obj:`Context.set_tlsext_servername_callback` is used to specify a new
Jean-Paul Calderonec4cb6582011-05-26 18:47:00 -04001341 callback, the one it replaces is dereferenced.
1342 """
1343 def callback(connection):
1344 pass
1345
1346 def replacement(connection):
1347 pass
1348
1349 context = Context(TLSv1_METHOD)
1350 context.set_tlsext_servername_callback(callback)
1351
1352 tracker = ref(callback)
1353 del callback
1354
1355 context.set_tlsext_servername_callback(replacement)
Jean-Paul Calderoned4033eb2014-01-11 08:21:46 -05001356
1357 # One run of the garbage collector happens to work on CPython. PyPy
1358 # doesn't collect the underlying object until a second run for whatever
1359 # reason. That's fine, it still demonstrates our code has properly
1360 # dropped the reference.
1361 collect()
Jean-Paul Calderonec4cb6582011-05-26 18:47:00 -04001362 collect()
Jean-Paul Calderone4c1aacd2014-01-11 08:15:17 -05001363
1364 callback = tracker()
1365 if callback is not None:
1366 referrers = get_referrers(callback)
Jean-Paul Calderone7de39562014-01-11 08:17:59 -05001367 if len(referrers) > 1:
Jean-Paul Calderone4c1aacd2014-01-11 08:15:17 -05001368 self.fail("Some references remain: %r" % (referrers,))
Jean-Paul Calderonec4cb6582011-05-26 18:47:00 -04001369
1370
1371 def test_no_servername(self):
1372 """
1373 When a client specifies no server name, the callback passed to
Jonathan Ballet648875f2011-07-16 14:14:58 +09001374 :py:obj:`Context.set_tlsext_servername_callback` is invoked and the result of
1375 :py:obj:`Connection.get_servername` is :py:obj:`None`.
Jean-Paul Calderonec4cb6582011-05-26 18:47:00 -04001376 """
1377 args = []
1378 def servername(conn):
1379 args.append((conn, conn.get_servername()))
1380 context = Context(TLSv1_METHOD)
1381 context.set_tlsext_servername_callback(servername)
1382
1383 # Lose our reference to it. The Context is responsible for keeping it
1384 # alive now.
1385 del servername
1386 collect()
1387
1388 # Necessary to actually accept the connection
1389 context.use_privatekey(load_privatekey(FILETYPE_PEM, server_key_pem))
1390 context.use_certificate(load_certificate(FILETYPE_PEM, server_cert_pem))
1391
1392 # Do a little connection to trigger the logic
1393 server = Connection(context, None)
1394 server.set_accept_state()
1395
1396 client = Connection(Context(TLSv1_METHOD), None)
1397 client.set_connect_state()
1398
1399 self._interactInMemory(server, client)
1400
1401 self.assertEqual([(server, None)], args)
1402
1403
1404 def test_servername(self):
1405 """
1406 When a client specifies a server name in its hello message, the callback
Jonathan Ballet648875f2011-07-16 14:14:58 +09001407 passed to :py:obj:`Contexts.set_tlsext_servername_callback` is invoked and the
1408 result of :py:obj:`Connection.get_servername` is that server name.
Jean-Paul Calderonec4cb6582011-05-26 18:47:00 -04001409 """
1410 args = []
1411 def servername(conn):
1412 args.append((conn, conn.get_servername()))
1413 context = Context(TLSv1_METHOD)
1414 context.set_tlsext_servername_callback(servername)
1415
1416 # Necessary to actually accept the connection
1417 context.use_privatekey(load_privatekey(FILETYPE_PEM, server_key_pem))
1418 context.use_certificate(load_certificate(FILETYPE_PEM, server_cert_pem))
1419
1420 # Do a little connection to trigger the logic
1421 server = Connection(context, None)
1422 server.set_accept_state()
1423
1424 client = Connection(Context(TLSv1_METHOD), None)
1425 client.set_connect_state()
1426 client.set_tlsext_host_name(b("foo1.example.com"))
1427
1428 self._interactInMemory(server, client)
1429
1430 self.assertEqual([(server, b("foo1.example.com"))], args)
1431
1432
1433
Jean-Paul Calderonee0fcf512012-02-13 09:10:15 -05001434class SessionTests(TestCase):
1435 """
1436 Unit tests for :py:obj:`OpenSSL.SSL.Session`.
1437 """
1438 def test_construction(self):
1439 """
1440 :py:class:`Session` can be constructed with no arguments, creating a new
1441 instance of that type.
1442 """
1443 new_session = Session()
1444 self.assertTrue(isinstance(new_session, Session))
1445
1446
1447 def test_construction_wrong_args(self):
1448 """
1449 If any arguments are passed to :py:class:`Session`, :py:obj:`TypeError`
1450 is raised.
1451 """
1452 self.assertRaises(TypeError, Session, 123)
1453 self.assertRaises(TypeError, Session, "hello")
1454 self.assertRaises(TypeError, Session, object())
1455
1456
1457
Jean-Paul Calderone9485f2c2010-07-29 22:38:42 -04001458class ConnectionTests(TestCase, _LoopbackMixin):
Rick Deane15b1472009-07-09 15:53:42 -05001459 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001460 Unit tests for :py:obj:`OpenSSL.SSL.Connection`.
Rick Deane15b1472009-07-09 15:53:42 -05001461 """
Jean-Paul Calderone541eaf22010-09-09 18:55:08 -04001462 # XXX get_peer_certificate -> None
1463 # XXX sock_shutdown
1464 # XXX master_key -> TypeError
1465 # XXX server_random -> TypeError
1466 # XXX state_string
1467 # XXX connect -> TypeError
1468 # XXX connect_ex -> TypeError
1469 # XXX set_connect_state -> TypeError
1470 # XXX set_accept_state -> TypeError
1471 # XXX renegotiate_pending
1472 # XXX do_handshake -> TypeError
1473 # XXX bio_read -> TypeError
1474 # XXX recv -> TypeError
1475 # XXX send -> TypeError
1476 # XXX bio_write -> TypeError
1477
Rick Deane15b1472009-07-09 15:53:42 -05001478 def test_type(self):
1479 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001480 :py:obj:`Connection` and :py:obj:`ConnectionType` refer to the same type object and
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001481 can be used to create instances of that type.
Rick Deane15b1472009-07-09 15:53:42 -05001482 """
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001483 self.assertIdentical(Connection, ConnectionType)
Rick Deane15b1472009-07-09 15:53:42 -05001484 ctx = Context(TLSv1_METHOD)
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001485 self.assertConsistentType(Connection, 'Connection', ctx, None)
Rick Deane15b1472009-07-09 15:53:42 -05001486
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001487
Jean-Paul Calderone4fd058a2009-11-22 11:46:42 -05001488 def test_get_context(self):
1489 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001490 :py:obj:`Connection.get_context` returns the :py:obj:`Context` instance used to
1491 construct the :py:obj:`Connection` instance.
Jean-Paul Calderone4fd058a2009-11-22 11:46:42 -05001492 """
1493 context = Context(TLSv1_METHOD)
1494 connection = Connection(context, None)
1495 self.assertIdentical(connection.get_context(), context)
1496
1497
1498 def test_get_context_wrong_args(self):
1499 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001500 :py:obj:`Connection.get_context` raises :py:obj:`TypeError` if called with any
Jean-Paul Calderone4fd058a2009-11-22 11:46:42 -05001501 arguments.
1502 """
1503 connection = Connection(Context(TLSv1_METHOD), None)
1504 self.assertRaises(TypeError, connection.get_context, None)
1505
1506
Jean-Paul Calderone95613b72011-05-25 22:30:21 -04001507 def test_set_context_wrong_args(self):
1508 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001509 :py:obj:`Connection.set_context` raises :py:obj:`TypeError` if called with a
1510 non-:py:obj:`Context` instance argument or with any number of arguments other
Jean-Paul Calderone95613b72011-05-25 22:30:21 -04001511 than 1.
1512 """
1513 ctx = Context(TLSv1_METHOD)
1514 connection = Connection(ctx, None)
1515 self.assertRaises(TypeError, connection.set_context)
1516 self.assertRaises(TypeError, connection.set_context, object())
1517 self.assertRaises(TypeError, connection.set_context, "hello")
1518 self.assertRaises(TypeError, connection.set_context, 1)
1519 self.assertRaises(TypeError, connection.set_context, 1, 2)
1520 self.assertRaises(
1521 TypeError, connection.set_context, Context(TLSv1_METHOD), 2)
1522 self.assertIdentical(ctx, connection.get_context())
1523
1524
1525 def test_set_context(self):
1526 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001527 :py:obj:`Connection.set_context` specifies a new :py:obj:`Context` instance to be used
Jean-Paul Calderone95613b72011-05-25 22:30:21 -04001528 for the connection.
1529 """
1530 original = Context(SSLv23_METHOD)
1531 replacement = Context(TLSv1_METHOD)
1532 connection = Connection(original, None)
1533 connection.set_context(replacement)
1534 self.assertIdentical(replacement, connection.get_context())
1535 # Lose our references to the contexts, just in case the Connection isn't
1536 # properly managing its own contributions to their reference counts.
1537 del original, replacement
Jean-Paul Calderonec4cb6582011-05-26 18:47:00 -04001538 collect()
1539
1540
1541 def test_set_tlsext_host_name_wrong_args(self):
1542 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001543 If :py:obj:`Connection.set_tlsext_host_name` is called with a non-byte string
Jean-Paul Calderonec4cb6582011-05-26 18:47:00 -04001544 argument or a byte string with an embedded NUL or other than one
Jonathan Ballet648875f2011-07-16 14:14:58 +09001545 argument, :py:obj:`TypeError` is raised.
Jean-Paul Calderonec4cb6582011-05-26 18:47:00 -04001546 """
1547 conn = Connection(Context(TLSv1_METHOD), None)
1548 self.assertRaises(TypeError, conn.set_tlsext_host_name)
1549 self.assertRaises(TypeError, conn.set_tlsext_host_name, object())
1550 self.assertRaises(TypeError, conn.set_tlsext_host_name, 123, 456)
1551 self.assertRaises(
1552 TypeError, conn.set_tlsext_host_name, b("with\0null"))
1553
1554 if version_info >= (3,):
1555 # On Python 3.x, don't accidentally implicitly convert from text.
1556 self.assertRaises(
1557 TypeError,
1558 conn.set_tlsext_host_name, b("example.com").decode("ascii"))
Jean-Paul Calderone95613b72011-05-25 22:30:21 -04001559
1560
Jean-Paul Calderone871a4d82011-05-26 19:24:02 -04001561 def test_get_servername_wrong_args(self):
1562 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001563 :py:obj:`Connection.get_servername` raises :py:obj:`TypeError` if called with any
Jean-Paul Calderone871a4d82011-05-26 19:24:02 -04001564 arguments.
1565 """
1566 connection = Connection(Context(TLSv1_METHOD), None)
1567 self.assertRaises(TypeError, connection.get_servername, object())
1568 self.assertRaises(TypeError, connection.get_servername, 1)
1569 self.assertRaises(TypeError, connection.get_servername, "hello")
1570
1571
Jean-Paul Calderone1d69a722010-07-29 09:05:53 -04001572 def test_pending(self):
Jean-Paul Calderone93dba222010-09-08 22:59:37 -04001573 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001574 :py:obj:`Connection.pending` returns the number of bytes available for
Jean-Paul Calderone93dba222010-09-08 22:59:37 -04001575 immediate read.
1576 """
Jean-Paul Calderone1d69a722010-07-29 09:05:53 -04001577 connection = Connection(Context(TLSv1_METHOD), None)
1578 self.assertEquals(connection.pending(), 0)
1579
1580
1581 def test_pending_wrong_args(self):
Jean-Paul Calderone93dba222010-09-08 22:59:37 -04001582 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001583 :py:obj:`Connection.pending` raises :py:obj:`TypeError` if called with any arguments.
Jean-Paul Calderone93dba222010-09-08 22:59:37 -04001584 """
Jean-Paul Calderone1d69a722010-07-29 09:05:53 -04001585 connection = Connection(Context(TLSv1_METHOD), None)
1586 self.assertRaises(TypeError, connection.pending, None)
1587
1588
Jean-Paul Calderonecfecc242010-07-29 22:47:06 -04001589 def test_connect_wrong_args(self):
Jean-Paul Calderone93dba222010-09-08 22:59:37 -04001590 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001591 :py:obj:`Connection.connect` raises :py:obj:`TypeError` if called with a non-address
Jean-Paul Calderone93dba222010-09-08 22:59:37 -04001592 argument or with the wrong number of arguments.
1593 """
Jean-Paul Calderonecfecc242010-07-29 22:47:06 -04001594 connection = Connection(Context(TLSv1_METHOD), socket())
1595 self.assertRaises(TypeError, connection.connect, None)
Jean-Paul Calderone93dba222010-09-08 22:59:37 -04001596 self.assertRaises(TypeError, connection.connect)
1597 self.assertRaises(TypeError, connection.connect, ("127.0.0.1", 1), None)
Jean-Paul Calderonecfecc242010-07-29 22:47:06 -04001598
1599
Jean-Paul Calderone8bdeba22010-07-29 09:45:07 -04001600 def test_connect_refused(self):
Jean-Paul Calderone93dba222010-09-08 22:59:37 -04001601 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001602 :py:obj:`Connection.connect` raises :py:obj:`socket.error` if the underlying socket
Jean-Paul Calderone93dba222010-09-08 22:59:37 -04001603 connect method raises it.
1604 """
Jean-Paul Calderone8bdeba22010-07-29 09:45:07 -04001605 client = socket()
1606 context = Context(TLSv1_METHOD)
1607 clientSSL = Connection(context, client)
1608 exc = self.assertRaises(error, clientSSL.connect, ("127.0.0.1", 1))
Jean-Paul Calderone35adf9d2010-07-29 18:40:44 -04001609 self.assertEquals(exc.args[0], ECONNREFUSED)
Jean-Paul Calderone8bdeba22010-07-29 09:45:07 -04001610
1611
1612 def test_connect(self):
Jean-Paul Calderone93dba222010-09-08 22:59:37 -04001613 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001614 :py:obj:`Connection.connect` establishes a connection to the specified address.
Jean-Paul Calderone93dba222010-09-08 22:59:37 -04001615 """
Jean-Paul Calderone0bcb0e02010-07-29 09:49:59 -04001616 port = socket()
1617 port.bind(('', 0))
1618 port.listen(3)
1619
1620 clientSSL = Connection(Context(TLSv1_METHOD), socket())
Jean-Paul Calderoneb6e0fd92010-09-19 09:22:13 -04001621 clientSSL.connect(('127.0.0.1', port.getsockname()[1]))
1622 # XXX An assertion? Or something?
Jean-Paul Calderone0bcb0e02010-07-29 09:49:59 -04001623
1624
Jean-Paul Calderone7b614872010-09-24 17:43:44 -04001625 if platform == "darwin":
1626 "connect_ex sometimes causes a kernel panic on OS X 10.6.4"
1627 else:
1628 def test_connect_ex(self):
1629 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001630 If there is a connection error, :py:obj:`Connection.connect_ex` returns the
Jean-Paul Calderone7b614872010-09-24 17:43:44 -04001631 errno instead of raising an exception.
1632 """
1633 port = socket()
1634 port.bind(('', 0))
1635 port.listen(3)
Jean-Paul Calderone55d91f42010-07-29 19:22:17 -04001636
Jean-Paul Calderone7b614872010-09-24 17:43:44 -04001637 clientSSL = Connection(Context(TLSv1_METHOD), socket())
1638 clientSSL.setblocking(False)
1639 result = clientSSL.connect_ex(port.getsockname())
1640 expected = (EINPROGRESS, EWOULDBLOCK)
1641 self.assertTrue(
1642 result in expected, "%r not in %r" % (result, expected))
Jean-Paul Calderone55d91f42010-07-29 19:22:17 -04001643
1644
Jean-Paul Calderonecfecc242010-07-29 22:47:06 -04001645 def test_accept_wrong_args(self):
Jean-Paul Calderone93dba222010-09-08 22:59:37 -04001646 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001647 :py:obj:`Connection.accept` raises :py:obj:`TypeError` if called with any arguments.
Jean-Paul Calderone93dba222010-09-08 22:59:37 -04001648 """
Jean-Paul Calderonecfecc242010-07-29 22:47:06 -04001649 connection = Connection(Context(TLSv1_METHOD), socket())
1650 self.assertRaises(TypeError, connection.accept, None)
1651
1652
Jean-Paul Calderone0bcb0e02010-07-29 09:49:59 -04001653 def test_accept(self):
Jean-Paul Calderone93dba222010-09-08 22:59:37 -04001654 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001655 :py:obj:`Connection.accept` accepts a pending connection attempt and returns a
1656 tuple of a new :py:obj:`Connection` (the accepted client) and the address the
Jean-Paul Calderone93dba222010-09-08 22:59:37 -04001657 connection originated from.
1658 """
Jean-Paul Calderone8bdeba22010-07-29 09:45:07 -04001659 ctx = Context(TLSv1_METHOD)
1660 ctx.use_privatekey(load_privatekey(FILETYPE_PEM, server_key_pem))
1661 ctx.use_certificate(load_certificate(FILETYPE_PEM, server_cert_pem))
Jean-Paul Calderone0bcb0e02010-07-29 09:49:59 -04001662 port = socket()
1663 portSSL = Connection(ctx, port)
1664 portSSL.bind(('', 0))
1665 portSSL.listen(3)
Jean-Paul Calderone8bdeba22010-07-29 09:45:07 -04001666
Jean-Paul Calderone0bcb0e02010-07-29 09:49:59 -04001667 clientSSL = Connection(Context(TLSv1_METHOD), socket())
Jean-Paul Calderoneb6e0fd92010-09-19 09:22:13 -04001668
1669 # Calling portSSL.getsockname() here to get the server IP address sounds
1670 # great, but frequently fails on Windows.
1671 clientSSL.connect(('127.0.0.1', portSSL.getsockname()[1]))
Jean-Paul Calderone8bdeba22010-07-29 09:45:07 -04001672
Jean-Paul Calderone0bcb0e02010-07-29 09:49:59 -04001673 serverSSL, address = portSSL.accept()
1674
1675 self.assertTrue(isinstance(serverSSL, Connection))
1676 self.assertIdentical(serverSSL.get_context(), ctx)
1677 self.assertEquals(address, clientSSL.getsockname())
Jean-Paul Calderone8bdeba22010-07-29 09:45:07 -04001678
1679
Jean-Paul Calderonecfecc242010-07-29 22:47:06 -04001680 def test_shutdown_wrong_args(self):
Jean-Paul Calderone93dba222010-09-08 22:59:37 -04001681 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001682 :py:obj:`Connection.shutdown` raises :py:obj:`TypeError` if called with the wrong
Jean-Paul Calderone93dba222010-09-08 22:59:37 -04001683 number of arguments or with arguments other than integers.
1684 """
Jean-Paul Calderonecfecc242010-07-29 22:47:06 -04001685 connection = Connection(Context(TLSv1_METHOD), None)
1686 self.assertRaises(TypeError, connection.shutdown, None)
Jean-Paul Calderone1d3e0222010-07-29 22:52:45 -04001687 self.assertRaises(TypeError, connection.get_shutdown, None)
1688 self.assertRaises(TypeError, connection.set_shutdown)
1689 self.assertRaises(TypeError, connection.set_shutdown, None)
1690 self.assertRaises(TypeError, connection.set_shutdown, 0, 1)
Jean-Paul Calderonecfecc242010-07-29 22:47:06 -04001691
1692
Jean-Paul Calderone9485f2c2010-07-29 22:38:42 -04001693 def test_shutdown(self):
Jean-Paul Calderone93dba222010-09-08 22:59:37 -04001694 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001695 :py:obj:`Connection.shutdown` performs an SSL-level connection shutdown.
Jean-Paul Calderone93dba222010-09-08 22:59:37 -04001696 """
Jean-Paul Calderone9485f2c2010-07-29 22:38:42 -04001697 server, client = self._loopback()
Jean-Paul Calderonee4f6b472010-07-29 22:50:58 -04001698 self.assertFalse(server.shutdown())
1699 self.assertEquals(server.get_shutdown(), SENT_SHUTDOWN)
Jean-Paul Calderone9485f2c2010-07-29 22:38:42 -04001700 self.assertRaises(ZeroReturnError, client.recv, 1024)
Jean-Paul Calderonee4f6b472010-07-29 22:50:58 -04001701 self.assertEquals(client.get_shutdown(), RECEIVED_SHUTDOWN)
1702 client.shutdown()
1703 self.assertEquals(client.get_shutdown(), SENT_SHUTDOWN|RECEIVED_SHUTDOWN)
1704 self.assertRaises(ZeroReturnError, server.recv, 1024)
1705 self.assertEquals(server.get_shutdown(), SENT_SHUTDOWN|RECEIVED_SHUTDOWN)
Jean-Paul Calderone9485f2c2010-07-29 22:38:42 -04001706
1707
Jean-Paul Calderonec89eef22010-07-29 22:51:58 -04001708 def test_set_shutdown(self):
Jean-Paul Calderone93dba222010-09-08 22:59:37 -04001709 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001710 :py:obj:`Connection.set_shutdown` sets the state of the SSL connection shutdown
Jean-Paul Calderone93dba222010-09-08 22:59:37 -04001711 process.
1712 """
Jean-Paul Calderonec89eef22010-07-29 22:51:58 -04001713 connection = Connection(Context(TLSv1_METHOD), socket())
1714 connection.set_shutdown(RECEIVED_SHUTDOWN)
1715 self.assertEquals(connection.get_shutdown(), RECEIVED_SHUTDOWN)
1716
1717
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -05001718 if not PY3:
1719 def test_set_shutdown_long(self):
1720 """
1721 On Python 2 :py:obj:`Connection.set_shutdown` accepts an argument
1722 of type :py:obj:`long` as well as :py:obj:`int`.
1723 """
1724 connection = Connection(Context(TLSv1_METHOD), socket())
1725 connection.set_shutdown(long(RECEIVED_SHUTDOWN))
1726 self.assertEquals(connection.get_shutdown(), RECEIVED_SHUTDOWN)
1727
1728
Jean-Paul Calderonecfecc242010-07-29 22:47:06 -04001729 def test_app_data_wrong_args(self):
Jean-Paul Calderone93dba222010-09-08 22:59:37 -04001730 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001731 :py:obj:`Connection.set_app_data` raises :py:obj:`TypeError` if called with other than
1732 one argument. :py:obj:`Connection.get_app_data` raises :py:obj:`TypeError` if called
Jean-Paul Calderone93dba222010-09-08 22:59:37 -04001733 with any arguments.
1734 """
Jean-Paul Calderonecfecc242010-07-29 22:47:06 -04001735 conn = Connection(Context(TLSv1_METHOD), None)
1736 self.assertRaises(TypeError, conn.get_app_data, None)
1737 self.assertRaises(TypeError, conn.set_app_data)
1738 self.assertRaises(TypeError, conn.set_app_data, None, None)
1739
1740
Jean-Paul Calderone1bd8c792010-07-29 09:51:06 -04001741 def test_app_data(self):
Jean-Paul Calderone93dba222010-09-08 22:59:37 -04001742 """
1743 Any object can be set as app data by passing it to
Jonathan Ballet648875f2011-07-16 14:14:58 +09001744 :py:obj:`Connection.set_app_data` and later retrieved with
1745 :py:obj:`Connection.get_app_data`.
Jean-Paul Calderone93dba222010-09-08 22:59:37 -04001746 """
Jean-Paul Calderone1bd8c792010-07-29 09:51:06 -04001747 conn = Connection(Context(TLSv1_METHOD), None)
1748 app_data = object()
1749 conn.set_app_data(app_data)
1750 self.assertIdentical(conn.get_app_data(), app_data)
1751
1752
Jean-Paul Calderonecfecc242010-07-29 22:47:06 -04001753 def test_makefile(self):
Jean-Paul Calderone93dba222010-09-08 22:59:37 -04001754 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001755 :py:obj:`Connection.makefile` is not implemented and calling that method raises
1756 :py:obj:`NotImplementedError`.
Jean-Paul Calderone93dba222010-09-08 22:59:37 -04001757 """
Jean-Paul Calderonecfecc242010-07-29 22:47:06 -04001758 conn = Connection(Context(TLSv1_METHOD), None)
1759 self.assertRaises(NotImplementedError, conn.makefile)
1760
1761
Jean-Paul Calderone20222ae2011-05-19 21:43:46 -04001762 def test_get_peer_cert_chain_wrong_args(self):
1763 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001764 :py:obj:`Connection.get_peer_cert_chain` raises :py:obj:`TypeError` if called with any
Jean-Paul Calderone20222ae2011-05-19 21:43:46 -04001765 arguments.
1766 """
1767 conn = Connection(Context(TLSv1_METHOD), None)
1768 self.assertRaises(TypeError, conn.get_peer_cert_chain, 1)
1769 self.assertRaises(TypeError, conn.get_peer_cert_chain, "foo")
1770 self.assertRaises(TypeError, conn.get_peer_cert_chain, object())
1771 self.assertRaises(TypeError, conn.get_peer_cert_chain, [])
1772
1773
1774 def test_get_peer_cert_chain(self):
1775 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001776 :py:obj:`Connection.get_peer_cert_chain` returns a list of certificates which
Jean-Paul Calderone20222ae2011-05-19 21:43:46 -04001777 the connected server returned for the certification verification.
1778 """
1779 chain = _create_certificate_chain()
1780 [(cakey, cacert), (ikey, icert), (skey, scert)] = chain
1781
1782 serverContext = Context(TLSv1_METHOD)
1783 serverContext.use_privatekey(skey)
1784 serverContext.use_certificate(scert)
1785 serverContext.add_extra_chain_cert(icert)
1786 serverContext.add_extra_chain_cert(cacert)
1787 server = Connection(serverContext, None)
1788 server.set_accept_state()
1789
1790 # Create the client
1791 clientContext = Context(TLSv1_METHOD)
1792 clientContext.set_verify(VERIFY_NONE, verify_cb)
1793 client = Connection(clientContext, None)
1794 client.set_connect_state()
1795
1796 self._interactInMemory(client, server)
1797
1798 chain = client.get_peer_cert_chain()
1799 self.assertEqual(len(chain), 3)
Jean-Paul Calderonee33300c2011-05-19 21:44:38 -04001800 self.assertEqual(
Jean-Paul Calderone24a42432011-05-19 22:21:18 -04001801 "Server Certificate", chain[0].get_subject().CN)
Jean-Paul Calderonee33300c2011-05-19 21:44:38 -04001802 self.assertEqual(
Jean-Paul Calderone24a42432011-05-19 22:21:18 -04001803 "Intermediate Certificate", chain[1].get_subject().CN)
Jean-Paul Calderonee33300c2011-05-19 21:44:38 -04001804 self.assertEqual(
Jean-Paul Calderone24a42432011-05-19 22:21:18 -04001805 "Authority Certificate", chain[2].get_subject().CN)
1806
1807
1808 def test_get_peer_cert_chain_none(self):
1809 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001810 :py:obj:`Connection.get_peer_cert_chain` returns :py:obj:`None` if the peer sends no
Jean-Paul Calderone24a42432011-05-19 22:21:18 -04001811 certificate chain.
1812 """
1813 ctx = Context(TLSv1_METHOD)
1814 ctx.use_privatekey(load_privatekey(FILETYPE_PEM, server_key_pem))
1815 ctx.use_certificate(load_certificate(FILETYPE_PEM, server_cert_pem))
1816 server = Connection(ctx, None)
1817 server.set_accept_state()
1818 client = Connection(Context(TLSv1_METHOD), None)
1819 client.set_connect_state()
1820 self._interactInMemory(client, server)
1821 self.assertIdentical(None, server.get_peer_cert_chain())
Jean-Paul Calderone20222ae2011-05-19 21:43:46 -04001822
1823
Jean-Paul Calderone64eaffc2012-02-13 11:53:49 -05001824 def test_get_session_wrong_args(self):
1825 """
1826 :py:obj:`Connection.get_session` raises :py:obj:`TypeError` if called
1827 with any arguments.
1828 """
1829 ctx = Context(TLSv1_METHOD)
1830 server = Connection(ctx, None)
1831 self.assertRaises(TypeError, server.get_session, 123)
1832 self.assertRaises(TypeError, server.get_session, "hello")
1833 self.assertRaises(TypeError, server.get_session, object())
1834
1835
1836 def test_get_session_unconnected(self):
1837 """
1838 :py:obj:`Connection.get_session` returns :py:obj:`None` when used with
1839 an object which has not been connected.
1840 """
1841 ctx = Context(TLSv1_METHOD)
1842 server = Connection(ctx, None)
1843 session = server.get_session()
1844 self.assertIdentical(None, session)
1845
1846
1847 def test_server_get_session(self):
1848 """
1849 On the server side of a connection, :py:obj:`Connection.get_session`
1850 returns a :py:class:`Session` instance representing the SSL session for
1851 that connection.
1852 """
1853 server, client = self._loopback()
1854 session = server.get_session()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001855 self.assertIsInstance(session, Session)
Jean-Paul Calderone64eaffc2012-02-13 11:53:49 -05001856
1857
1858 def test_client_get_session(self):
1859 """
1860 On the client side of a connection, :py:obj:`Connection.get_session`
1861 returns a :py:class:`Session` instance representing the SSL session for
1862 that connection.
1863 """
1864 server, client = self._loopback()
1865 session = client.get_session()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001866 self.assertIsInstance(session, Session)
Jean-Paul Calderone64eaffc2012-02-13 11:53:49 -05001867
1868
Jean-Paul Calderonefef5c4b2012-02-14 16:31:52 -05001869 def test_set_session_wrong_args(self):
1870 """
1871 If called with an object that is not an instance of :py:class:`Session`,
1872 or with other than one argument, :py:obj:`Connection.set_session` raises
1873 :py:obj:`TypeError`.
1874 """
1875 ctx = Context(TLSv1_METHOD)
1876 connection = Connection(ctx, None)
1877 self.assertRaises(TypeError, connection.set_session)
1878 self.assertRaises(TypeError, connection.set_session, 123)
1879 self.assertRaises(TypeError, connection.set_session, "hello")
1880 self.assertRaises(TypeError, connection.set_session, object())
1881 self.assertRaises(
1882 TypeError, connection.set_session, Session(), Session())
1883
1884
1885 def test_client_set_session(self):
1886 """
1887 :py:obj:`Connection.set_session`, when used prior to a connection being
1888 established, accepts a :py:class:`Session` instance and causes an
1889 attempt to re-use the session it represents when the SSL handshake is
1890 performed.
1891 """
1892 key = load_privatekey(FILETYPE_PEM, server_key_pem)
1893 cert = load_certificate(FILETYPE_PEM, server_cert_pem)
1894 ctx = Context(TLSv1_METHOD)
1895 ctx.use_privatekey(key)
1896 ctx.use_certificate(cert)
1897 ctx.set_session_id("unity-test")
1898
1899 def makeServer(socket):
1900 server = Connection(ctx, socket)
1901 server.set_accept_state()
1902 return server
1903
1904 originalServer, originalClient = self._loopback(
1905 serverFactory=makeServer)
1906 originalSession = originalClient.get_session()
1907
1908 def makeClient(socket):
1909 client = self._loopbackClientFactory(socket)
1910 client.set_session(originalSession)
1911 return client
1912 resumedServer, resumedClient = self._loopback(
1913 serverFactory=makeServer,
1914 clientFactory=makeClient)
1915
1916 # This is a proxy: in general, we have no access to any unique
1917 # identifier for the session (new enough versions of OpenSSL expose a
1918 # hash which could be usable, but "new enough" is very, very new).
1919 # Instead, exploit the fact that the master key is re-used if the
1920 # session is re-used. As long as the master key for the two connections
1921 # is the same, the session was re-used!
1922 self.assertEqual(
1923 originalServer.master_key(), resumedServer.master_key())
1924
1925
Jean-Paul Calderone5ea41492012-02-14 16:51:35 -05001926 def test_set_session_wrong_method(self):
1927 """
Jean-Paul Calderone068cb592012-02-14 16:52:43 -05001928 If :py:obj:`Connection.set_session` is passed a :py:class:`Session`
1929 instance associated with a context using a different SSL method than the
1930 :py:obj:`Connection` is using, a :py:class:`OpenSSL.SSL.Error` is
1931 raised.
Jean-Paul Calderone5ea41492012-02-14 16:51:35 -05001932 """
1933 key = load_privatekey(FILETYPE_PEM, server_key_pem)
1934 cert = load_certificate(FILETYPE_PEM, server_cert_pem)
1935 ctx = Context(TLSv1_METHOD)
1936 ctx.use_privatekey(key)
1937 ctx.use_certificate(cert)
1938 ctx.set_session_id("unity-test")
1939
1940 def makeServer(socket):
1941 server = Connection(ctx, socket)
1942 server.set_accept_state()
1943 return server
1944
1945 originalServer, originalClient = self._loopback(
1946 serverFactory=makeServer)
1947 originalSession = originalClient.get_session()
1948
1949 def makeClient(socket):
1950 # Intentionally use a different, incompatible method here.
1951 client = Connection(Context(SSLv3_METHOD), socket)
1952 client.set_connect_state()
1953 client.set_session(originalSession)
1954 return client
1955
1956 self.assertRaises(
1957 Error,
1958 self._loopback, clientFactory=makeClient, serverFactory=makeServer)
1959
1960
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001961 def test_wantWriteError(self):
1962 """
1963 :py:obj:`Connection` methods which generate output raise
1964 :py:obj:`OpenSSL.SSL.WantWriteError` if writing to the connection's BIO
1965 fail indicating a should-write state.
1966 """
1967 client_socket, server_socket = socket_pair()
1968 # Fill up the client's send buffer so Connection won't be able to write
Jean-Paul Calderonebbff8b92014-03-22 14:20:30 -04001969 # anything. Only write a single byte at a time so we can be sure we
1970 # completely fill the buffer. Even though the socket API is allowed to
1971 # signal a short write via its return value it seems this doesn't
1972 # always happen on all platforms (FreeBSD and OS X particular) for the
1973 # very last bit of available buffer space.
1974 msg = b"x"
1975 for i in range(1024 * 1024 * 4):
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001976 try:
1977 client_socket.send(msg)
1978 except error as e:
1979 if e.errno == EWOULDBLOCK:
1980 break
1981 raise
1982 else:
1983 self.fail(
1984 "Failed to fill socket buffer, cannot test BIO want write")
1985
1986 ctx = Context(TLSv1_METHOD)
1987 conn = Connection(ctx, client_socket)
1988 # Client's speak first, so make it an SSL client
1989 conn.set_connect_state()
1990 self.assertRaises(WantWriteError, conn.do_handshake)
1991
1992 # XXX want_read
1993
Fedor Brunner416f4a12014-03-28 13:18:38 +01001994 def test_get_finished_before_connect(self):
Fedor Brunner5747b932014-03-05 14:22:34 +01001995 """
Jean-Paul Calderone5b05b482014-03-30 11:28:54 -04001996 :py:obj:`Connection.get_finished` returns :py:obj:`None` before TLS
1997 handshake is completed.
Fedor Brunner5747b932014-03-05 14:22:34 +01001998 """
Fedor Brunner5747b932014-03-05 14:22:34 +01001999 ctx = Context(TLSv1_METHOD)
2000 connection = Connection(ctx, None)
2001 self.assertEqual(connection.get_finished(), None)
Fedor Brunner416f4a12014-03-28 13:18:38 +01002002
Jean-Paul Calderone5b05b482014-03-30 11:28:54 -04002003
Fedor Brunner416f4a12014-03-28 13:18:38 +01002004 def test_get_peer_finished_before_connect(self):
2005 """
Jean-Paul Calderone5b05b482014-03-30 11:28:54 -04002006 :py:obj:`Connection.get_peer_finished` returns :py:obj:`None` before
2007 TLS handshake is completed.
Fedor Brunner416f4a12014-03-28 13:18:38 +01002008 """
Fedor Brunner416f4a12014-03-28 13:18:38 +01002009 ctx = Context(TLSv1_METHOD)
2010 connection = Connection(ctx, None)
Fedor Brunner5747b932014-03-05 14:22:34 +01002011 self.assertEqual(connection.get_peer_finished(), None)
2012
Jean-Paul Calderone5b05b482014-03-30 11:28:54 -04002013
Fedor Brunner416f4a12014-03-28 13:18:38 +01002014 def test_get_finished(self):
2015 """
2016 :py:obj:`Connection.get_finished` method returns the TLS Finished
Jean-Paul Calderone5b05b482014-03-30 11:28:54 -04002017 message send from client, or server. Finished messages are send during
2018 TLS handshake.
Fedor Brunner416f4a12014-03-28 13:18:38 +01002019 """
2020
Fedor Brunner5747b932014-03-05 14:22:34 +01002021 server, client = self._loopback()
2022
2023 self.assertNotEqual(server.get_finished(), None)
2024 self.assertTrue(len(server.get_finished()) > 0)
Fedor Brunner416f4a12014-03-28 13:18:38 +01002025
Jean-Paul Calderoned979f232014-03-30 11:58:00 -04002026
Fedor Brunner416f4a12014-03-28 13:18:38 +01002027 def test_get_peer_finished(self):
2028 """
2029 :py:obj:`Connection.get_peer_finished` method returns the TLS Finished
Jean-Paul Calderone5b05b482014-03-30 11:28:54 -04002030 message received from client, or server. Finished messages are send
2031 during TLS handshake.
Fedor Brunner416f4a12014-03-28 13:18:38 +01002032 """
Fedor Brunner416f4a12014-03-28 13:18:38 +01002033 server, client = self._loopback()
2034
2035 self.assertNotEqual(server.get_peer_finished(), None)
Fedor Brunner5747b932014-03-05 14:22:34 +01002036 self.assertTrue(len(server.get_peer_finished()) > 0)
2037
Jean-Paul Calderone5b05b482014-03-30 11:28:54 -04002038
Fedor Brunner416f4a12014-03-28 13:18:38 +01002039 def test_tls_finished_message_symmetry(self):
2040 """
Jean-Paul Calderone5b05b482014-03-30 11:28:54 -04002041 The TLS Finished message send by server must be the TLS Finished message
Fedor Brunner416f4a12014-03-28 13:18:38 +01002042 received by client.
2043
Jean-Paul Calderone5b05b482014-03-30 11:28:54 -04002044 The TLS Finished message send by client must be the TLS Finished message
Fedor Brunner416f4a12014-03-28 13:18:38 +01002045 received by server.
2046 """
Fedor Brunner416f4a12014-03-28 13:18:38 +01002047 server, client = self._loopback()
2048
Fedor Brunner5747b932014-03-05 14:22:34 +01002049 self.assertEqual(server.get_finished(), client.get_peer_finished())
2050 self.assertEqual(client.get_finished(), server.get_peer_finished())
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002051
Jean-Paul Calderone5b05b482014-03-30 11:28:54 -04002052
Fedor Brunner2cffdbc2014-03-10 10:35:23 +01002053 def test_get_cipher_name_before_connect(self):
2054 """
Jean-Paul Calderone5b05b482014-03-30 11:28:54 -04002055 :py:obj:`Connection.get_cipher_name` returns :py:obj:`None` if no
2056 connection has been established.
Fedor Brunner2cffdbc2014-03-10 10:35:23 +01002057 """
2058 ctx = Context(TLSv1_METHOD)
2059 conn = Connection(ctx, None)
Jean-Paul Calderone069e2bf2014-03-29 18:21:58 -04002060 self.assertIdentical(conn.get_cipher_name(), None)
Fedor Brunner2cffdbc2014-03-10 10:35:23 +01002061
Jean-Paul Calderonedbd76272014-03-29 18:09:40 -04002062
Fedor Brunnerd95014a2014-03-03 17:34:41 +01002063 def test_get_cipher_name(self):
2064 """
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04002065 :py:obj:`Connection.get_cipher_name` returns a :py:class:`unicode`
2066 string giving the name of the currently used cipher.
Fedor Brunnerd95014a2014-03-03 17:34:41 +01002067 """
Fedor Brunnerd95014a2014-03-03 17:34:41 +01002068 server, client = self._loopback()
2069 server_cipher_name, client_cipher_name = \
2070 server.get_cipher_name(), client.get_cipher_name()
2071
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04002072 self.assertIsInstance(server_cipher_name, text_type)
2073 self.assertIsInstance(client_cipher_name, text_type)
Fedor Brunnerd95014a2014-03-03 17:34:41 +01002074
2075 self.assertEqual(server_cipher_name, client_cipher_name)
2076
Jean-Paul Calderonedbd76272014-03-29 18:09:40 -04002077
Fedor Brunner2cffdbc2014-03-10 10:35:23 +01002078 def test_get_cipher_version_before_connect(self):
2079 """
Jean-Paul Calderone5b05b482014-03-30 11:28:54 -04002080 :py:obj:`Connection.get_cipher_version` returns :py:obj:`None` if no
2081 connection has been established.
Fedor Brunner2cffdbc2014-03-10 10:35:23 +01002082 """
2083 ctx = Context(TLSv1_METHOD)
2084 conn = Connection(ctx, None)
Jean-Paul Calderone069e2bf2014-03-29 18:21:58 -04002085 self.assertIdentical(conn.get_cipher_version(), None)
Fedor Brunner2cffdbc2014-03-10 10:35:23 +01002086
Jean-Paul Calderonedbd76272014-03-29 18:09:40 -04002087
Fedor Brunnerd95014a2014-03-03 17:34:41 +01002088 def test_get_cipher_version(self):
2089 """
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04002090 :py:obj:`Connection.get_cipher_version` returns a :py:class:`unicode`
2091 string giving the protocol name of the currently used cipher.
Fedor Brunnerd95014a2014-03-03 17:34:41 +01002092 """
Fedor Brunnerd95014a2014-03-03 17:34:41 +01002093 server, client = self._loopback()
2094 server_cipher_version, client_cipher_version = \
2095 server.get_cipher_version(), client.get_cipher_version()
2096
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04002097 self.assertIsInstance(server_cipher_version, text_type)
2098 self.assertIsInstance(client_cipher_version, text_type)
Fedor Brunnerd95014a2014-03-03 17:34:41 +01002099
2100 self.assertEqual(server_cipher_version, client_cipher_version)
2101
Jean-Paul Calderonedbd76272014-03-29 18:09:40 -04002102
Fedor Brunner2cffdbc2014-03-10 10:35:23 +01002103 def test_get_cipher_bits_before_connect(self):
2104 """
Jean-Paul Calderone5b05b482014-03-30 11:28:54 -04002105 :py:obj:`Connection.get_cipher_bits` returns :py:obj:`None` if no
2106 connection has been established.
Fedor Brunner2cffdbc2014-03-10 10:35:23 +01002107 """
2108 ctx = Context(TLSv1_METHOD)
2109 conn = Connection(ctx, None)
Jean-Paul Calderone069e2bf2014-03-29 18:21:58 -04002110 self.assertIdentical(conn.get_cipher_bits(), None)
Fedor Brunner2cffdbc2014-03-10 10:35:23 +01002111
Jean-Paul Calderonedbd76272014-03-29 18:09:40 -04002112
Fedor Brunnerd95014a2014-03-03 17:34:41 +01002113 def test_get_cipher_bits(self):
2114 """
Jean-Paul Calderone5b05b482014-03-30 11:28:54 -04002115 :py:obj:`Connection.get_cipher_bits` returns the number of secret bits
2116 of the currently used cipher.
Fedor Brunnerd95014a2014-03-03 17:34:41 +01002117 """
Fedor Brunnerd95014a2014-03-03 17:34:41 +01002118 server, client = self._loopback()
2119 server_cipher_bits, client_cipher_bits = \
2120 server.get_cipher_bits(), client.get_cipher_bits()
2121
Fedor Brunner2cffdbc2014-03-10 10:35:23 +01002122 self.assertIsInstance(server_cipher_bits, int)
2123 self.assertIsInstance(client_cipher_bits, int)
Fedor Brunnerd95014a2014-03-03 17:34:41 +01002124
2125 self.assertEqual(server_cipher_bits, client_cipher_bits)
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002126
Jean-Paul Calderonedbd76272014-03-29 18:09:40 -04002127
2128
Jean-Paul Calderonef135e622010-07-28 19:14:16 -04002129class ConnectionGetCipherListTests(TestCase):
Jean-Paul Calderonea8fb0c82010-09-09 18:04:56 -04002130 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002131 Tests for :py:obj:`Connection.get_cipher_list`.
Jean-Paul Calderonea8fb0c82010-09-09 18:04:56 -04002132 """
Jean-Paul Calderone54a2bc02010-09-09 17:52:38 -04002133 def test_wrong_args(self):
Jean-Paul Calderonea8fb0c82010-09-09 18:04:56 -04002134 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002135 :py:obj:`Connection.get_cipher_list` raises :py:obj:`TypeError` if called with any
Jean-Paul Calderonea8fb0c82010-09-09 18:04:56 -04002136 arguments.
2137 """
Jean-Paul Calderonef135e622010-07-28 19:14:16 -04002138 connection = Connection(Context(TLSv1_METHOD), None)
2139 self.assertRaises(TypeError, connection.get_cipher_list, None)
2140
2141
2142 def test_result(self):
Jean-Paul Calderonea8fb0c82010-09-09 18:04:56 -04002143 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002144 :py:obj:`Connection.get_cipher_list` returns a :py:obj:`list` of
2145 :py:obj:`bytes` giving the names of the ciphers which might be used.
Jean-Paul Calderonea8fb0c82010-09-09 18:04:56 -04002146 """
Jean-Paul Calderonef135e622010-07-28 19:14:16 -04002147 connection = Connection(Context(TLSv1_METHOD), None)
2148 ciphers = connection.get_cipher_list()
2149 self.assertTrue(isinstance(ciphers, list))
2150 for cipher in ciphers:
2151 self.assertTrue(isinstance(cipher, str))
2152
2153
2154
Jean-Paul Calderone9cbbe262011-01-05 14:53:43 -05002155class ConnectionSendTests(TestCase, _LoopbackMixin):
2156 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002157 Tests for :py:obj:`Connection.send`
Jean-Paul Calderone9cbbe262011-01-05 14:53:43 -05002158 """
2159 def test_wrong_args(self):
2160 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -05002161 When called with arguments other than string argument for its first
2162 parameter or more than two arguments, :py:obj:`Connection.send` raises
2163 :py:obj:`TypeError`.
Jean-Paul Calderone9cbbe262011-01-05 14:53:43 -05002164 """
2165 connection = Connection(Context(TLSv1_METHOD), None)
Jean-Paul Calderone77fa2602011-01-05 18:23:39 -05002166 self.assertRaises(TypeError, connection.send)
2167 self.assertRaises(TypeError, connection.send, object())
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -05002168 self.assertRaises(TypeError, connection.send, "foo", object(), "bar")
Jean-Paul Calderone9cbbe262011-01-05 14:53:43 -05002169
2170
2171 def test_short_bytes(self):
2172 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002173 When passed a short byte string, :py:obj:`Connection.send` transmits all of it
Jean-Paul Calderone9cbbe262011-01-05 14:53:43 -05002174 and returns the number of bytes sent.
2175 """
2176 server, client = self._loopback()
2177 count = server.send(b('xy'))
2178 self.assertEquals(count, 2)
2179 self.assertEquals(client.recv(2), b('xy'))
2180
2181 try:
2182 memoryview
2183 except NameError:
2184 "cannot test sending memoryview without memoryview"
2185 else:
2186 def test_short_memoryview(self):
2187 """
2188 When passed a memoryview onto a small number of bytes,
Jonathan Ballet648875f2011-07-16 14:14:58 +09002189 :py:obj:`Connection.send` transmits all of them and returns the number of
Jean-Paul Calderone9cbbe262011-01-05 14:53:43 -05002190 bytes sent.
2191 """
2192 server, client = self._loopback()
2193 count = server.send(memoryview(b('xy')))
2194 self.assertEquals(count, 2)
2195 self.assertEquals(client.recv(2), b('xy'))
2196
2197
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02002198 try:
2199 buffer
2200 except NameError:
2201 "cannot test sending buffer without buffer"
2202 else:
2203 def test_short_buffer(self):
2204 """
2205 When passed a buffer containing a small number of bytes,
2206 :py:obj:`Connection.send` transmits all of them and returns the number of
2207 bytes sent.
2208 """
2209 server, client = self._loopback()
2210 count = server.send(buffer(b('xy')))
2211 self.assertEquals(count, 2)
2212 self.assertEquals(client.recv(2), b('xy'))
2213
2214
Jean-Paul Calderone691e6c92011-01-21 22:04:35 -05002215
Jean-Paul Calderone8ea22522010-07-29 09:39:39 -04002216class ConnectionSendallTests(TestCase, _LoopbackMixin):
2217 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002218 Tests for :py:obj:`Connection.sendall`.
Jean-Paul Calderone8ea22522010-07-29 09:39:39 -04002219 """
Jean-Paul Calderonea8fb0c82010-09-09 18:04:56 -04002220 def test_wrong_args(self):
Jean-Paul Calderone8ea22522010-07-29 09:39:39 -04002221 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -05002222 When called with arguments other than a string argument for its first
2223 parameter or with more than two arguments, :py:obj:`Connection.sendall`
2224 raises :py:obj:`TypeError`.
Jean-Paul Calderone8ea22522010-07-29 09:39:39 -04002225 """
2226 connection = Connection(Context(TLSv1_METHOD), None)
2227 self.assertRaises(TypeError, connection.sendall)
2228 self.assertRaises(TypeError, connection.sendall, object())
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -05002229 self.assertRaises(
2230 TypeError, connection.sendall, "foo", object(), "bar")
Jean-Paul Calderone8ea22522010-07-29 09:39:39 -04002231
2232
Jean-Paul Calderone7ca48b52010-07-28 18:57:21 -04002233 def test_short(self):
2234 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002235 :py:obj:`Connection.sendall` transmits all of the bytes in the string passed to
Jean-Paul Calderone7ca48b52010-07-28 18:57:21 -04002236 it.
2237 """
2238 server, client = self._loopback()
Jean-Paul Calderonea9868832010-08-22 21:38:34 -04002239 server.sendall(b('x'))
2240 self.assertEquals(client.recv(1), b('x'))
Jean-Paul Calderone7ca48b52010-07-28 18:57:21 -04002241
2242
Jean-Paul Calderone691e6c92011-01-21 22:04:35 -05002243 try:
2244 memoryview
2245 except NameError:
2246 "cannot test sending memoryview without memoryview"
2247 else:
2248 def test_short_memoryview(self):
2249 """
2250 When passed a memoryview onto a small number of bytes,
Jonathan Ballet648875f2011-07-16 14:14:58 +09002251 :py:obj:`Connection.sendall` transmits all of them.
Jean-Paul Calderone691e6c92011-01-21 22:04:35 -05002252 """
2253 server, client = self._loopback()
2254 server.sendall(memoryview(b('x')))
2255 self.assertEquals(client.recv(1), b('x'))
2256
2257
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02002258 try:
2259 buffer
2260 except NameError:
2261 "cannot test sending buffers without buffers"
2262 else:
2263 def test_short_buffers(self):
2264 """
2265 When passed a buffer containing a small number of bytes,
2266 :py:obj:`Connection.sendall` transmits all of them.
2267 """
2268 server, client = self._loopback()
2269 server.sendall(buffer(b('x')))
2270 self.assertEquals(client.recv(1), b('x'))
2271
2272
Jean-Paul Calderone7ca48b52010-07-28 18:57:21 -04002273 def test_long(self):
Jean-Paul Calderonea8fb0c82010-09-09 18:04:56 -04002274 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002275 :py:obj:`Connection.sendall` transmits all of the bytes in the string passed to
Jean-Paul Calderonea8fb0c82010-09-09 18:04:56 -04002276 it even if this requires multiple calls of an underlying write function.
2277 """
Jean-Paul Calderone7ca48b52010-07-28 18:57:21 -04002278 server, client = self._loopback()
Jean-Paul Calderone6241c702010-09-16 19:59:24 -04002279 # Should be enough, underlying SSL_write should only do 16k at a time.
2280 # On Windows, after 32k of bytes the write will block (forever - because
2281 # no one is yet reading).
Jean-Paul Calderone9e4c1352010-09-19 09:34:43 -04002282 message = b('x') * (1024 * 32 - 1) + b('y')
Jean-Paul Calderone7ca48b52010-07-28 18:57:21 -04002283 server.sendall(message)
2284 accum = []
2285 received = 0
2286 while received < len(message):
Jean-Paul Calderoneb1f7f5f2010-08-22 21:40:52 -04002287 data = client.recv(1024)
2288 accum.append(data)
2289 received += len(data)
Jean-Paul Calderonef4047852010-09-19 09:45:57 -04002290 self.assertEquals(message, b('').join(accum))
Jean-Paul Calderone7ca48b52010-07-28 18:57:21 -04002291
2292
Jean-Paul Calderone974bdc02010-07-28 19:06:10 -04002293 def test_closed(self):
2294 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002295 If the underlying socket is closed, :py:obj:`Connection.sendall` propagates the
Jean-Paul Calderone974bdc02010-07-28 19:06:10 -04002296 write error from the low level write call.
2297 """
2298 server, client = self._loopback()
Jean-Paul Calderone05d43e82010-09-24 18:01:36 -04002299 server.sock_shutdown(2)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002300 exc = self.assertRaises(SysCallError, server.sendall, b"hello, world")
Konstantinos Koukopoulos541150d2014-01-31 01:00:19 +02002301 if platform == "win32":
2302 self.assertEqual(exc.args[0], ESHUTDOWN)
2303 else:
2304 self.assertEqual(exc.args[0], EPIPE)
Jean-Paul Calderone974bdc02010-07-28 19:06:10 -04002305
Jean-Paul Calderone7ca48b52010-07-28 18:57:21 -04002306
Jean-Paul Calderone1d69a722010-07-29 09:05:53 -04002307
Jean-Paul Calderone8ea22522010-07-29 09:39:39 -04002308class ConnectionRenegotiateTests(TestCase, _LoopbackMixin):
2309 """
2310 Tests for SSL renegotiation APIs.
2311 """
2312 def test_renegotiate_wrong_args(self):
Jean-Paul Calderonea8fb0c82010-09-09 18:04:56 -04002313 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002314 :py:obj:`Connection.renegotiate` raises :py:obj:`TypeError` if called with any
Jean-Paul Calderonea8fb0c82010-09-09 18:04:56 -04002315 arguments.
2316 """
Jean-Paul Calderone8ea22522010-07-29 09:39:39 -04002317 connection = Connection(Context(TLSv1_METHOD), None)
2318 self.assertRaises(TypeError, connection.renegotiate, None)
2319
2320
Jean-Paul Calderonecfecc242010-07-29 22:47:06 -04002321 def test_total_renegotiations_wrong_args(self):
Jean-Paul Calderonea8fb0c82010-09-09 18:04:56 -04002322 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002323 :py:obj:`Connection.total_renegotiations` raises :py:obj:`TypeError` if called with
Jean-Paul Calderonea8fb0c82010-09-09 18:04:56 -04002324 any arguments.
2325 """
Jean-Paul Calderonecfecc242010-07-29 22:47:06 -04002326 connection = Connection(Context(TLSv1_METHOD), None)
2327 self.assertRaises(TypeError, connection.total_renegotiations, None)
2328
2329
2330 def test_total_renegotiations(self):
Jean-Paul Calderonea8fb0c82010-09-09 18:04:56 -04002331 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002332 :py:obj:`Connection.total_renegotiations` returns :py:obj:`0` before any
Jean-Paul Calderonea8fb0c82010-09-09 18:04:56 -04002333 renegotiations have happened.
2334 """
Jean-Paul Calderonecfecc242010-07-29 22:47:06 -04002335 connection = Connection(Context(TLSv1_METHOD), None)
2336 self.assertEquals(connection.total_renegotiations(), 0)
2337
2338
Jean-Paul Calderone8ea22522010-07-29 09:39:39 -04002339# def test_renegotiate(self):
2340# """
2341# """
2342# server, client = self._loopback()
2343
2344# server.send("hello world")
2345# self.assertEquals(client.recv(len("hello world")), "hello world")
2346
2347# self.assertEquals(server.total_renegotiations(), 0)
2348# self.assertTrue(server.renegotiate())
2349
2350# server.setblocking(False)
2351# client.setblocking(False)
2352# while server.renegotiate_pending():
2353# client.do_handshake()
2354# server.do_handshake()
2355
2356# self.assertEquals(server.total_renegotiations(), 1)
2357
2358
2359
2360
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002361class ErrorTests(TestCase):
2362 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002363 Unit tests for :py:obj:`OpenSSL.SSL.Error`.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002364 """
2365 def test_type(self):
2366 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002367 :py:obj:`Error` is an exception type.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002368 """
2369 self.assertTrue(issubclass(Error, Exception))
Rick Deane15b1472009-07-09 15:53:42 -05002370 self.assertEqual(Error.__name__, 'Error')
Rick Deane15b1472009-07-09 15:53:42 -05002371
2372
2373
Jean-Paul Calderone327d8f92008-12-28 21:55:56 -05002374class ConstantsTests(TestCase):
2375 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002376 Tests for the values of constants exposed in :py:obj:`OpenSSL.SSL`.
Jean-Paul Calderone327d8f92008-12-28 21:55:56 -05002377
2378 These are values defined by OpenSSL intended only to be used as flags to
2379 OpenSSL APIs. The only assertions it seems can be made about them is
2380 their values.
2381 """
Jean-Paul Calderoned811b682008-12-28 22:59:15 -05002382 # unittest.TestCase has no skip mechanism
2383 if OP_NO_QUERY_MTU is not None:
2384 def test_op_no_query_mtu(self):
2385 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002386 The value of :py:obj:`OpenSSL.SSL.OP_NO_QUERY_MTU` is 0x1000, the value of
Jean-Paul Calderone64efa2c2011-09-11 10:00:09 -04002387 :py:const:`SSL_OP_NO_QUERY_MTU` defined by :file:`openssl/ssl.h`.
Jean-Paul Calderoned811b682008-12-28 22:59:15 -05002388 """
2389 self.assertEqual(OP_NO_QUERY_MTU, 0x1000)
2390 else:
2391 "OP_NO_QUERY_MTU unavailable - OpenSSL version may be too old"
Jean-Paul Calderone327d8f92008-12-28 21:55:56 -05002392
2393
Jean-Paul Calderoned811b682008-12-28 22:59:15 -05002394 if OP_COOKIE_EXCHANGE is not None:
2395 def test_op_cookie_exchange(self):
2396 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002397 The value of :py:obj:`OpenSSL.SSL.OP_COOKIE_EXCHANGE` is 0x2000, the value
Jean-Paul Calderone64efa2c2011-09-11 10:00:09 -04002398 of :py:const:`SSL_OP_COOKIE_EXCHANGE` defined by :file:`openssl/ssl.h`.
Jean-Paul Calderoned811b682008-12-28 22:59:15 -05002399 """
2400 self.assertEqual(OP_COOKIE_EXCHANGE, 0x2000)
2401 else:
2402 "OP_COOKIE_EXCHANGE unavailable - OpenSSL version may be too old"
Jean-Paul Calderone327d8f92008-12-28 21:55:56 -05002403
2404
Jean-Paul Calderoned811b682008-12-28 22:59:15 -05002405 if OP_NO_TICKET is not None:
2406 def test_op_no_ticket(self):
2407 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002408 The value of :py:obj:`OpenSSL.SSL.OP_NO_TICKET` is 0x4000, the value of
Jean-Paul Calderone64efa2c2011-09-11 10:00:09 -04002409 :py:const:`SSL_OP_NO_TICKET` defined by :file:`openssl/ssl.h`.
Jean-Paul Calderoned811b682008-12-28 22:59:15 -05002410 """
2411 self.assertEqual(OP_NO_TICKET, 0x4000)
Jean-Paul Calderonecebd1782011-09-11 10:01:31 -04002412 else:
Jean-Paul Calderoned811b682008-12-28 22:59:15 -05002413 "OP_NO_TICKET unavailable - OpenSSL version may be too old"
Rick Dean5b7b6372009-04-01 11:34:06 -05002414
2415
Jean-Paul Calderonec62d4c12011-09-08 18:29:32 -04002416 if OP_NO_COMPRESSION is not None:
2417 def test_op_no_compression(self):
2418 """
Jean-Paul Calderone64efa2c2011-09-11 10:00:09 -04002419 The value of :py:obj:`OpenSSL.SSL.OP_NO_COMPRESSION` is 0x20000, the value
2420 of :py:const:`SSL_OP_NO_COMPRESSION` defined by :file:`openssl/ssl.h`.
Jean-Paul Calderonec62d4c12011-09-08 18:29:32 -04002421 """
2422 self.assertEqual(OP_NO_COMPRESSION, 0x20000)
2423 else:
2424 "OP_NO_COMPRESSION unavailable - OpenSSL version may be too old"
2425
2426
Jean-Paul Calderone313bf012012-02-08 13:02:49 -05002427 def test_sess_cache_off(self):
2428 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -05002429 The value of :py:obj:`OpenSSL.SSL.SESS_CACHE_OFF` 0x0, the value of
2430 :py:obj:`SSL_SESS_CACHE_OFF` defined by ``openssl/ssl.h``.
Jean-Paul Calderone313bf012012-02-08 13:02:49 -05002431 """
2432 self.assertEqual(0x0, SESS_CACHE_OFF)
2433
2434
2435 def test_sess_cache_client(self):
2436 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -05002437 The value of :py:obj:`OpenSSL.SSL.SESS_CACHE_CLIENT` 0x1, the value of
2438 :py:obj:`SSL_SESS_CACHE_CLIENT` defined by ``openssl/ssl.h``.
Jean-Paul Calderone313bf012012-02-08 13:02:49 -05002439 """
2440 self.assertEqual(0x1, SESS_CACHE_CLIENT)
2441
2442
2443 def test_sess_cache_server(self):
2444 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -05002445 The value of :py:obj:`OpenSSL.SSL.SESS_CACHE_SERVER` 0x2, the value of
2446 :py:obj:`SSL_SESS_CACHE_SERVER` defined by ``openssl/ssl.h``.
Jean-Paul Calderone313bf012012-02-08 13:02:49 -05002447 """
2448 self.assertEqual(0x2, SESS_CACHE_SERVER)
2449
2450
2451 def test_sess_cache_both(self):
2452 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -05002453 The value of :py:obj:`OpenSSL.SSL.SESS_CACHE_BOTH` 0x3, the value of
2454 :py:obj:`SSL_SESS_CACHE_BOTH` defined by ``openssl/ssl.h``.
Jean-Paul Calderone313bf012012-02-08 13:02:49 -05002455 """
2456 self.assertEqual(0x3, SESS_CACHE_BOTH)
2457
2458
2459 def test_sess_cache_no_auto_clear(self):
2460 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -05002461 The value of :py:obj:`OpenSSL.SSL.SESS_CACHE_NO_AUTO_CLEAR` 0x80, the
2462 value of :py:obj:`SSL_SESS_CACHE_NO_AUTO_CLEAR` defined by
2463 ``openssl/ssl.h``.
Jean-Paul Calderone313bf012012-02-08 13:02:49 -05002464 """
2465 self.assertEqual(0x80, SESS_CACHE_NO_AUTO_CLEAR)
2466
2467
2468 def test_sess_cache_no_internal_lookup(self):
2469 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -05002470 The value of :py:obj:`OpenSSL.SSL.SESS_CACHE_NO_INTERNAL_LOOKUP` 0x100,
2471 the value of :py:obj:`SSL_SESS_CACHE_NO_INTERNAL_LOOKUP` defined by
2472 ``openssl/ssl.h``.
Jean-Paul Calderone313bf012012-02-08 13:02:49 -05002473 """
2474 self.assertEqual(0x100, SESS_CACHE_NO_INTERNAL_LOOKUP)
2475
2476
2477 def test_sess_cache_no_internal_store(self):
2478 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -05002479 The value of :py:obj:`OpenSSL.SSL.SESS_CACHE_NO_INTERNAL_STORE` 0x200,
2480 the value of :py:obj:`SSL_SESS_CACHE_NO_INTERNAL_STORE` defined by
2481 ``openssl/ssl.h``.
Jean-Paul Calderone313bf012012-02-08 13:02:49 -05002482 """
2483 self.assertEqual(0x200, SESS_CACHE_NO_INTERNAL_STORE)
2484
2485
2486 def test_sess_cache_no_internal(self):
2487 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -05002488 The value of :py:obj:`OpenSSL.SSL.SESS_CACHE_NO_INTERNAL` 0x300, the
2489 value of :py:obj:`SSL_SESS_CACHE_NO_INTERNAL` defined by
2490 ``openssl/ssl.h``.
Jean-Paul Calderone313bf012012-02-08 13:02:49 -05002491 """
2492 self.assertEqual(0x300, SESS_CACHE_NO_INTERNAL)
2493
2494
Jean-Paul Calderoneeeee26a2009-04-27 11:24:30 -04002495
Jean-Paul Calderonebf37f0f2010-07-31 14:56:20 -04002496class MemoryBIOTests(TestCase, _LoopbackMixin):
Rick Deanb71c0d22009-04-01 14:09:23 -05002497 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002498 Tests for :py:obj:`OpenSSL.SSL.Connection` using a memory BIO.
Rick Deanb71c0d22009-04-01 14:09:23 -05002499 """
Jean-Paul Calderonece8324d2009-07-16 12:22:52 -04002500 def _server(self, sock):
2501 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002502 Create a new server-side SSL :py:obj:`Connection` object wrapped around
2503 :py:obj:`sock`.
Jean-Paul Calderonece8324d2009-07-16 12:22:52 -04002504 """
Jean-Paul Calderoneaff0fc42009-04-27 17:13:34 -04002505 # Create the server side Connection. This is mostly setup boilerplate
2506 # - use TLSv1, use a particular certificate, etc.
2507 server_ctx = Context(TLSv1_METHOD)
2508 server_ctx.set_options(OP_NO_SSLv2 | OP_NO_SSLv3 | OP_SINGLE_DH_USE )
2509 server_ctx.set_verify(VERIFY_PEER|VERIFY_FAIL_IF_NO_PEER_CERT|VERIFY_CLIENT_ONCE, verify_cb)
2510 server_store = server_ctx.get_cert_store()
2511 server_ctx.use_privatekey(load_privatekey(FILETYPE_PEM, server_key_pem))
2512 server_ctx.use_certificate(load_certificate(FILETYPE_PEM, server_cert_pem))
2513 server_ctx.check_privatekey()
2514 server_store.add_cert(load_certificate(FILETYPE_PEM, root_cert_pem))
Rick Deanb1ccd562009-07-09 23:52:39 -05002515 # Here the Connection is actually created. If None is passed as the 2nd
2516 # parameter, it indicates a memory BIO should be created.
2517 server_conn = Connection(server_ctx, sock)
Jean-Paul Calderoneaff0fc42009-04-27 17:13:34 -04002518 server_conn.set_accept_state()
2519 return server_conn
2520
2521
Jean-Paul Calderonece8324d2009-07-16 12:22:52 -04002522 def _client(self, sock):
2523 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002524 Create a new client-side SSL :py:obj:`Connection` object wrapped around
2525 :py:obj:`sock`.
Jean-Paul Calderonece8324d2009-07-16 12:22:52 -04002526 """
2527 # Now create the client side Connection. Similar boilerplate to the
2528 # above.
Jean-Paul Calderoneaff0fc42009-04-27 17:13:34 -04002529 client_ctx = Context(TLSv1_METHOD)
2530 client_ctx.set_options(OP_NO_SSLv2 | OP_NO_SSLv3 | OP_SINGLE_DH_USE )
2531 client_ctx.set_verify(VERIFY_PEER|VERIFY_FAIL_IF_NO_PEER_CERT|VERIFY_CLIENT_ONCE, verify_cb)
2532 client_store = client_ctx.get_cert_store()
2533 client_ctx.use_privatekey(load_privatekey(FILETYPE_PEM, client_key_pem))
2534 client_ctx.use_certificate(load_certificate(FILETYPE_PEM, client_cert_pem))
2535 client_ctx.check_privatekey()
2536 client_store.add_cert(load_certificate(FILETYPE_PEM, root_cert_pem))
Rick Deanb1ccd562009-07-09 23:52:39 -05002537 client_conn = Connection(client_ctx, sock)
Jean-Paul Calderoneaff0fc42009-04-27 17:13:34 -04002538 client_conn.set_connect_state()
2539 return client_conn
2540
2541
Jean-Paul Calderonece8324d2009-07-16 12:22:52 -04002542 def test_memoryConnect(self):
Jean-Paul Calderone958299e2009-04-27 12:59:12 -04002543 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002544 Two :py:obj:`Connection`s which use memory BIOs can be manually connected by
Jean-Paul Calderone958299e2009-04-27 12:59:12 -04002545 reading from the output of each and writing those bytes to the input of
2546 the other and in this way establish a connection and exchange
2547 application-level bytes with each other.
2548 """
Jean-Paul Calderonece8324d2009-07-16 12:22:52 -04002549 server_conn = self._server(None)
2550 client_conn = self._client(None)
Rick Deanb71c0d22009-04-01 14:09:23 -05002551
Jean-Paul Calderone958299e2009-04-27 12:59:12 -04002552 # There should be no key or nonces yet.
2553 self.assertIdentical(server_conn.master_key(), None)
2554 self.assertIdentical(server_conn.client_random(), None)
2555 self.assertIdentical(server_conn.server_random(), None)
Rick Deanb71c0d22009-04-01 14:09:23 -05002556
Jean-Paul Calderone958299e2009-04-27 12:59:12 -04002557 # First, the handshake needs to happen. We'll deliver bytes back and
2558 # forth between the client and server until neither of them feels like
2559 # speaking any more.
Jean-Paul Calderonebf37f0f2010-07-31 14:56:20 -04002560 self.assertIdentical(
2561 self._interactInMemory(client_conn, server_conn), None)
Jean-Paul Calderone958299e2009-04-27 12:59:12 -04002562
2563 # Now that the handshake is done, there should be a key and nonces.
2564 self.assertNotIdentical(server_conn.master_key(), None)
2565 self.assertNotIdentical(server_conn.client_random(), None)
2566 self.assertNotIdentical(server_conn.server_random(), None)
Jean-Paul Calderone6c051e62009-07-05 13:50:34 -04002567 self.assertEquals(server_conn.client_random(), client_conn.client_random())
2568 self.assertEquals(server_conn.server_random(), client_conn.server_random())
2569 self.assertNotEquals(server_conn.client_random(), server_conn.server_random())
2570 self.assertNotEquals(client_conn.client_random(), client_conn.server_random())
Jean-Paul Calderone958299e2009-04-27 12:59:12 -04002571
2572 # Here are the bytes we'll try to send.
Jean-Paul Calderonea441fdc2010-08-22 21:33:57 -04002573 important_message = b('One if by land, two if by sea.')
Rick Deanb71c0d22009-04-01 14:09:23 -05002574
Jean-Paul Calderone958299e2009-04-27 12:59:12 -04002575 server_conn.write(important_message)
2576 self.assertEquals(
Jean-Paul Calderonebf37f0f2010-07-31 14:56:20 -04002577 self._interactInMemory(client_conn, server_conn),
Jean-Paul Calderone958299e2009-04-27 12:59:12 -04002578 (client_conn, important_message))
2579
2580 client_conn.write(important_message[::-1])
2581 self.assertEquals(
Jean-Paul Calderonebf37f0f2010-07-31 14:56:20 -04002582 self._interactInMemory(client_conn, server_conn),
Jean-Paul Calderone958299e2009-04-27 12:59:12 -04002583 (server_conn, important_message[::-1]))
Rick Deanb71c0d22009-04-01 14:09:23 -05002584
2585
Jean-Paul Calderonece8324d2009-07-16 12:22:52 -04002586 def test_socketConnect(self):
Rick Deanb1ccd562009-07-09 23:52:39 -05002587 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002588 Just like :py:obj:`test_memoryConnect` but with an actual socket.
Jean-Paul Calderonece8324d2009-07-16 12:22:52 -04002589
2590 This is primarily to rule out the memory BIO code as the source of
Jonathan Ballet648875f2011-07-16 14:14:58 +09002591 any problems encountered while passing data over a :py:obj:`Connection` (if
Jean-Paul Calderonece8324d2009-07-16 12:22:52 -04002592 this test fails, there must be a problem outside the memory BIO
2593 code, as no memory BIO is involved here). Even though this isn't a
2594 memory BIO test, it's convenient to have it here.
Rick Deanb1ccd562009-07-09 23:52:39 -05002595 """
Jean-Paul Calderone06c7cc92010-09-24 23:52:00 -04002596 server_conn, client_conn = self._loopback()
Rick Deanb1ccd562009-07-09 23:52:39 -05002597
Jean-Paul Calderonea441fdc2010-08-22 21:33:57 -04002598 important_message = b("Help me Obi Wan Kenobi, you're my only hope.")
Rick Deanb1ccd562009-07-09 23:52:39 -05002599 client_conn.send(important_message)
2600 msg = server_conn.recv(1024)
2601 self.assertEqual(msg, important_message)
2602
2603 # Again in the other direction, just for fun.
2604 important_message = important_message[::-1]
2605 server_conn.send(important_message)
2606 msg = client_conn.recv(1024)
2607 self.assertEqual(msg, important_message)
2608
2609
Jean-Paul Calderonefc4ed0f2009-04-27 11:51:27 -04002610 def test_socketOverridesMemory(self):
Rick Deanb71c0d22009-04-01 14:09:23 -05002611 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002612 Test that :py:obj:`OpenSSL.SSL.bio_read` and :py:obj:`OpenSSL.SSL.bio_write` don't
2613 work on :py:obj:`OpenSSL.SSL.Connection`() that use sockets.
Rick Deanb71c0d22009-04-01 14:09:23 -05002614 """
2615 context = Context(SSLv3_METHOD)
2616 client = socket()
2617 clientSSL = Connection(context, client)
2618 self.assertRaises( TypeError, clientSSL.bio_read, 100)
2619 self.assertRaises( TypeError, clientSSL.bio_write, "foo")
Jean-Paul Calderone07acf3f2009-05-05 13:23:28 -04002620 self.assertRaises( TypeError, clientSSL.bio_shutdown )
Jean-Paul Calderoneaff0fc42009-04-27 17:13:34 -04002621
2622
2623 def test_outgoingOverflow(self):
2624 """
2625 If more bytes than can be written to the memory BIO are passed to
Jonathan Ballet648875f2011-07-16 14:14:58 +09002626 :py:obj:`Connection.send` at once, the number of bytes which were written is
Jean-Paul Calderoneaff0fc42009-04-27 17:13:34 -04002627 returned and that many bytes from the beginning of the input can be
2628 read from the other end of the connection.
2629 """
Jean-Paul Calderonece8324d2009-07-16 12:22:52 -04002630 server = self._server(None)
2631 client = self._client(None)
Jean-Paul Calderoneaff0fc42009-04-27 17:13:34 -04002632
Jean-Paul Calderonebf37f0f2010-07-31 14:56:20 -04002633 self._interactInMemory(client, server)
Jean-Paul Calderoneaff0fc42009-04-27 17:13:34 -04002634
2635 size = 2 ** 15
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002636 sent = client.send(b"x" * size)
Jean-Paul Calderoneaff0fc42009-04-27 17:13:34 -04002637 # Sanity check. We're trying to test what happens when the entire
2638 # input can't be sent. If the entire input was sent, this test is
2639 # meaningless.
2640 self.assertTrue(sent < size)
2641
Jean-Paul Calderonebf37f0f2010-07-31 14:56:20 -04002642 receiver, received = self._interactInMemory(client, server)
Jean-Paul Calderoneaff0fc42009-04-27 17:13:34 -04002643 self.assertIdentical(receiver, server)
2644
2645 # We can rely on all of these bytes being received at once because
2646 # _loopback passes 2 ** 16 to recv - more than 2 ** 15.
2647 self.assertEquals(len(received), sent)
Jean-Paul Calderone3ad85d42009-04-30 20:24:35 -04002648
2649
2650 def test_shutdown(self):
2651 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002652 :py:obj:`Connection.bio_shutdown` signals the end of the data stream from
2653 which the :py:obj:`Connection` reads.
Jean-Paul Calderone3ad85d42009-04-30 20:24:35 -04002654 """
Jean-Paul Calderonece8324d2009-07-16 12:22:52 -04002655 server = self._server(None)
Jean-Paul Calderone3ad85d42009-04-30 20:24:35 -04002656 server.bio_shutdown()
2657 e = self.assertRaises(Error, server.recv, 1024)
2658 # We don't want WantReadError or ZeroReturnError or anything - it's a
2659 # handshake failure.
2660 self.assertEquals(e.__class__, Error)
Jean-Paul Calderone0b88b6a2009-07-05 12:44:41 -04002661
2662
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07002663 def test_unexpectedEndOfFile(self):
2664 """
2665 If the connection is lost before an orderly SSL shutdown occurs,
2666 :py:obj:`OpenSSL.SSL.SysCallError` is raised with a message of
2667 "Unexpected EOF".
2668 """
2669 server_conn, client_conn = self._loopback()
2670 client_conn.sock_shutdown(SHUT_RDWR)
2671 exc = self.assertRaises(SysCallError, server_conn.recv, 1024)
2672 self.assertEqual(exc.args, (-1, "Unexpected EOF"))
2673
2674
Ziga Seilnachtf93bf102009-10-23 09:51:07 +02002675 def _check_client_ca_list(self, func):
Jean-Paul Calderone911c9112009-10-24 11:12:00 -04002676 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002677 Verify the return value of the :py:obj:`get_client_ca_list` method for server and client connections.
Jean-Paul Calderone911c9112009-10-24 11:12:00 -04002678
Jonathan Ballet78b92a22011-07-16 08:07:26 +09002679 :param func: A function which will be called with the server context
Jean-Paul Calderone911c9112009-10-24 11:12:00 -04002680 before the client and server are connected to each other. This
2681 function should specify a list of CAs for the server to send to the
2682 client and return that same list. The list will be used to verify
Jonathan Ballet648875f2011-07-16 14:14:58 +09002683 that :py:obj:`get_client_ca_list` returns the proper value at various
Jean-Paul Calderone911c9112009-10-24 11:12:00 -04002684 times.
2685 """
Ziga Seilnacht679c4262009-09-01 01:32:29 +02002686 server = self._server(None)
2687 client = self._client(None)
Ziga Seilnachtf93bf102009-10-23 09:51:07 +02002688 self.assertEqual(client.get_client_ca_list(), [])
2689 self.assertEqual(server.get_client_ca_list(), [])
Ziga Seilnacht679c4262009-09-01 01:32:29 +02002690 ctx = server.get_context()
2691 expected = func(ctx)
Ziga Seilnachtf93bf102009-10-23 09:51:07 +02002692 self.assertEqual(client.get_client_ca_list(), [])
2693 self.assertEqual(server.get_client_ca_list(), expected)
Jean-Paul Calderonebf37f0f2010-07-31 14:56:20 -04002694 self._interactInMemory(client, server)
Ziga Seilnachtf93bf102009-10-23 09:51:07 +02002695 self.assertEqual(client.get_client_ca_list(), expected)
2696 self.assertEqual(server.get_client_ca_list(), expected)
Ziga Seilnacht679c4262009-09-01 01:32:29 +02002697
2698
Jean-Paul Calderone911c9112009-10-24 11:12:00 -04002699 def test_set_client_ca_list_errors(self):
Ziga Seilnacht679c4262009-09-01 01:32:29 +02002700 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002701 :py:obj:`Context.set_client_ca_list` raises a :py:obj:`TypeError` if called with a
Jean-Paul Calderone911c9112009-10-24 11:12:00 -04002702 non-list or a list that contains objects other than X509Names.
Ziga Seilnacht679c4262009-09-01 01:32:29 +02002703 """
2704 ctx = Context(TLSv1_METHOD)
Ziga Seilnachtf93bf102009-10-23 09:51:07 +02002705 self.assertRaises(TypeError, ctx.set_client_ca_list, "spam")
2706 self.assertRaises(TypeError, ctx.set_client_ca_list, ["spam"])
2707 self.assertIdentical(ctx.set_client_ca_list([]), None)
Ziga Seilnacht679c4262009-09-01 01:32:29 +02002708
2709
Jean-Paul Calderone911c9112009-10-24 11:12:00 -04002710 def test_set_empty_ca_list(self):
Ziga Seilnacht679c4262009-09-01 01:32:29 +02002711 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002712 If passed an empty list, :py:obj:`Context.set_client_ca_list` configures the
Jean-Paul Calderone911c9112009-10-24 11:12:00 -04002713 context to send no CA names to the client and, on both the server and
Jonathan Ballet648875f2011-07-16 14:14:58 +09002714 client sides, :py:obj:`Connection.get_client_ca_list` returns an empty list
Jean-Paul Calderone911c9112009-10-24 11:12:00 -04002715 after the connection is set up.
2716 """
2717 def no_ca(ctx):
2718 ctx.set_client_ca_list([])
2719 return []
2720 self._check_client_ca_list(no_ca)
2721
2722
2723 def test_set_one_ca_list(self):
2724 """
2725 If passed a list containing a single X509Name,
Jonathan Ballet648875f2011-07-16 14:14:58 +09002726 :py:obj:`Context.set_client_ca_list` configures the context to send that CA
Jean-Paul Calderone911c9112009-10-24 11:12:00 -04002727 name to the client and, on both the server and client sides,
Jonathan Ballet648875f2011-07-16 14:14:58 +09002728 :py:obj:`Connection.get_client_ca_list` returns a list containing that
Jean-Paul Calderone911c9112009-10-24 11:12:00 -04002729 X509Name after the connection is set up.
2730 """
2731 cacert = load_certificate(FILETYPE_PEM, root_cert_pem)
2732 cadesc = cacert.get_subject()
2733 def single_ca(ctx):
2734 ctx.set_client_ca_list([cadesc])
2735 return [cadesc]
2736 self._check_client_ca_list(single_ca)
2737
2738
2739 def test_set_multiple_ca_list(self):
2740 """
2741 If passed a list containing multiple X509Name objects,
Jonathan Ballet648875f2011-07-16 14:14:58 +09002742 :py:obj:`Context.set_client_ca_list` configures the context to send those CA
Jean-Paul Calderone911c9112009-10-24 11:12:00 -04002743 names to the client and, on both the server and client sides,
Jonathan Ballet648875f2011-07-16 14:14:58 +09002744 :py:obj:`Connection.get_client_ca_list` returns a list containing those
Jean-Paul Calderone911c9112009-10-24 11:12:00 -04002745 X509Names after the connection is set up.
2746 """
2747 secert = load_certificate(FILETYPE_PEM, server_cert_pem)
2748 clcert = load_certificate(FILETYPE_PEM, server_cert_pem)
2749
2750 sedesc = secert.get_subject()
2751 cldesc = clcert.get_subject()
2752
2753 def multiple_ca(ctx):
2754 L = [sedesc, cldesc]
2755 ctx.set_client_ca_list(L)
2756 return L
2757 self._check_client_ca_list(multiple_ca)
2758
2759
2760 def test_reset_ca_list(self):
2761 """
2762 If called multiple times, only the X509Names passed to the final call
Jonathan Ballet648875f2011-07-16 14:14:58 +09002763 of :py:obj:`Context.set_client_ca_list` are used to configure the CA names
Jean-Paul Calderone911c9112009-10-24 11:12:00 -04002764 sent to the client.
Ziga Seilnacht679c4262009-09-01 01:32:29 +02002765 """
2766 cacert = load_certificate(FILETYPE_PEM, root_cert_pem)
2767 secert = load_certificate(FILETYPE_PEM, server_cert_pem)
2768 clcert = load_certificate(FILETYPE_PEM, server_cert_pem)
2769
2770 cadesc = cacert.get_subject()
2771 sedesc = secert.get_subject()
2772 cldesc = clcert.get_subject()
2773
Ziga Seilnachtf93bf102009-10-23 09:51:07 +02002774 def changed_ca(ctx):
2775 ctx.set_client_ca_list([sedesc, cldesc])
2776 ctx.set_client_ca_list([cadesc])
Ziga Seilnacht679c4262009-09-01 01:32:29 +02002777 return [cadesc]
Ziga Seilnachtf93bf102009-10-23 09:51:07 +02002778 self._check_client_ca_list(changed_ca)
Ziga Seilnacht679c4262009-09-01 01:32:29 +02002779
Jean-Paul Calderone911c9112009-10-24 11:12:00 -04002780
2781 def test_mutated_ca_list(self):
2782 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002783 If the list passed to :py:obj:`Context.set_client_ca_list` is mutated
Jean-Paul Calderone911c9112009-10-24 11:12:00 -04002784 afterwards, this does not affect the list of CA names sent to the
2785 client.
2786 """
2787 cacert = load_certificate(FILETYPE_PEM, root_cert_pem)
2788 secert = load_certificate(FILETYPE_PEM, server_cert_pem)
2789
2790 cadesc = cacert.get_subject()
2791 sedesc = secert.get_subject()
2792
Ziga Seilnachtf93bf102009-10-23 09:51:07 +02002793 def mutated_ca(ctx):
Ziga Seilnacht679c4262009-09-01 01:32:29 +02002794 L = [cadesc]
Ziga Seilnachtf93bf102009-10-23 09:51:07 +02002795 ctx.set_client_ca_list([cadesc])
Ziga Seilnacht679c4262009-09-01 01:32:29 +02002796 L.append(sedesc)
2797 return [cadesc]
Ziga Seilnachtf93bf102009-10-23 09:51:07 +02002798 self._check_client_ca_list(mutated_ca)
Ziga Seilnacht679c4262009-09-01 01:32:29 +02002799
2800
Jean-Paul Calderone911c9112009-10-24 11:12:00 -04002801 def test_add_client_ca_errors(self):
Ziga Seilnacht679c4262009-09-01 01:32:29 +02002802 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002803 :py:obj:`Context.add_client_ca` raises :py:obj:`TypeError` if called with a non-X509
Jean-Paul Calderone911c9112009-10-24 11:12:00 -04002804 object or with a number of arguments other than one.
Ziga Seilnacht679c4262009-09-01 01:32:29 +02002805 """
2806 ctx = Context(TLSv1_METHOD)
2807 cacert = load_certificate(FILETYPE_PEM, root_cert_pem)
Jean-Paul Calderone911c9112009-10-24 11:12:00 -04002808 self.assertRaises(TypeError, ctx.add_client_ca)
Ziga Seilnachtf93bf102009-10-23 09:51:07 +02002809 self.assertRaises(TypeError, ctx.add_client_ca, "spam")
Jean-Paul Calderone911c9112009-10-24 11:12:00 -04002810 self.assertRaises(TypeError, ctx.add_client_ca, cacert, cacert)
Ziga Seilnacht679c4262009-09-01 01:32:29 +02002811
2812
Jean-Paul Calderone055a9172009-10-24 13:45:11 -04002813 def test_one_add_client_ca(self):
Ziga Seilnacht679c4262009-09-01 01:32:29 +02002814 """
Jean-Paul Calderone055a9172009-10-24 13:45:11 -04002815 A certificate's subject can be added as a CA to be sent to the client
Jonathan Ballet648875f2011-07-16 14:14:58 +09002816 with :py:obj:`Context.add_client_ca`.
Jean-Paul Calderone055a9172009-10-24 13:45:11 -04002817 """
2818 cacert = load_certificate(FILETYPE_PEM, root_cert_pem)
2819 cadesc = cacert.get_subject()
2820 def single_ca(ctx):
2821 ctx.add_client_ca(cacert)
2822 return [cadesc]
2823 self._check_client_ca_list(single_ca)
2824
2825
2826 def test_multiple_add_client_ca(self):
2827 """
2828 Multiple CA names can be sent to the client by calling
Jonathan Ballet648875f2011-07-16 14:14:58 +09002829 :py:obj:`Context.add_client_ca` with multiple X509 objects.
Jean-Paul Calderone055a9172009-10-24 13:45:11 -04002830 """
2831 cacert = load_certificate(FILETYPE_PEM, root_cert_pem)
2832 secert = load_certificate(FILETYPE_PEM, server_cert_pem)
2833
2834 cadesc = cacert.get_subject()
2835 sedesc = secert.get_subject()
2836
2837 def multiple_ca(ctx):
2838 ctx.add_client_ca(cacert)
2839 ctx.add_client_ca(secert)
2840 return [cadesc, sedesc]
2841 self._check_client_ca_list(multiple_ca)
2842
2843
2844 def test_set_and_add_client_ca(self):
2845 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002846 A call to :py:obj:`Context.set_client_ca_list` followed by a call to
2847 :py:obj:`Context.add_client_ca` results in using the CA names from the first
Jean-Paul Calderone055a9172009-10-24 13:45:11 -04002848 call and the CA name from the second call.
Ziga Seilnacht679c4262009-09-01 01:32:29 +02002849 """
2850 cacert = load_certificate(FILETYPE_PEM, root_cert_pem)
2851 secert = load_certificate(FILETYPE_PEM, server_cert_pem)
2852 clcert = load_certificate(FILETYPE_PEM, server_cert_pem)
2853
2854 cadesc = cacert.get_subject()
2855 sedesc = secert.get_subject()
2856 cldesc = clcert.get_subject()
2857
Ziga Seilnachtf93bf102009-10-23 09:51:07 +02002858 def mixed_set_add_ca(ctx):
2859 ctx.set_client_ca_list([cadesc, sedesc])
2860 ctx.add_client_ca(clcert)
Ziga Seilnacht679c4262009-09-01 01:32:29 +02002861 return [cadesc, sedesc, cldesc]
Ziga Seilnachtf93bf102009-10-23 09:51:07 +02002862 self._check_client_ca_list(mixed_set_add_ca)
Ziga Seilnacht679c4262009-09-01 01:32:29 +02002863
Jean-Paul Calderone055a9172009-10-24 13:45:11 -04002864
2865 def test_set_after_add_client_ca(self):
2866 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002867 A call to :py:obj:`Context.set_client_ca_list` after a call to
2868 :py:obj:`Context.add_client_ca` replaces the CA name specified by the former
Jean-Paul Calderone055a9172009-10-24 13:45:11 -04002869 call with the names specified by the latter cal.
2870 """
2871 cacert = load_certificate(FILETYPE_PEM, root_cert_pem)
2872 secert = load_certificate(FILETYPE_PEM, server_cert_pem)
2873 clcert = load_certificate(FILETYPE_PEM, server_cert_pem)
2874
2875 cadesc = cacert.get_subject()
2876 sedesc = secert.get_subject()
Jean-Paul Calderone055a9172009-10-24 13:45:11 -04002877
Ziga Seilnachtf93bf102009-10-23 09:51:07 +02002878 def set_replaces_add_ca(ctx):
2879 ctx.add_client_ca(clcert)
2880 ctx.set_client_ca_list([cadesc])
2881 ctx.add_client_ca(secert)
Ziga Seilnacht679c4262009-09-01 01:32:29 +02002882 return [cadesc, sedesc]
Ziga Seilnachtf93bf102009-10-23 09:51:07 +02002883 self._check_client_ca_list(set_replaces_add_ca)
Ziga Seilnacht679c4262009-09-01 01:32:29 +02002884
Jean-Paul Calderone0b88b6a2009-07-05 12:44:41 -04002885
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07002886
2887class ConnectionBIOTests(TestCase):
2888 """
2889 Tests for :py:obj:`Connection.bio_read` and :py:obj:`Connection.bio_write`.
2890 """
2891 def test_wantReadError(self):
2892 """
2893 :py:obj:`Connection.bio_read` raises :py:obj:`OpenSSL.SSL.WantReadError`
2894 if there are no bytes available to be read from the BIO.
2895 """
2896 ctx = Context(TLSv1_METHOD)
2897 conn = Connection(ctx, None)
2898 self.assertRaises(WantReadError, conn.bio_read, 1024)
2899
2900
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -05002901 def test_buffer_size(self):
2902 """
2903 :py:obj:`Connection.bio_read` accepts an integer giving the maximum
2904 number of bytes to read and return.
2905 """
2906 ctx = Context(TLSv1_METHOD)
2907 conn = Connection(ctx, None)
2908 conn.set_connect_state()
2909 try:
2910 conn.do_handshake()
2911 except WantReadError:
2912 pass
2913 data = conn.bio_read(2)
2914 self.assertEqual(2, len(data))
2915
2916
2917 if not PY3:
2918 def test_buffer_size_long(self):
2919 """
2920 On Python 2 :py:obj:`Connection.bio_read` accepts values of type
2921 :py:obj:`long` as well as :py:obj:`int`.
2922 """
2923 ctx = Context(TLSv1_METHOD)
2924 conn = Connection(ctx, None)
2925 conn.set_connect_state()
2926 try:
2927 conn.do_handshake()
2928 except WantReadError:
2929 pass
2930 data = conn.bio_read(long(2))
2931 self.assertEqual(2, len(data))
2932
2933
2934
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07002935
Jean-Paul Calderone31e85a82011-03-21 19:13:35 -04002936class InfoConstantTests(TestCase):
2937 """
2938 Tests for assorted constants exposed for use in info callbacks.
2939 """
2940 def test_integers(self):
2941 """
2942 All of the info constants are integers.
2943
2944 This is a very weak test. It would be nice to have one that actually
2945 verifies that as certain info events happen, the value passed to the
2946 info callback matches up with the constant exposed by OpenSSL.SSL.
2947 """
2948 for const in [
2949 SSL_ST_CONNECT, SSL_ST_ACCEPT, SSL_ST_MASK, SSL_ST_INIT,
2950 SSL_ST_BEFORE, SSL_ST_OK, SSL_ST_RENEGOTIATE,
2951 SSL_CB_LOOP, SSL_CB_EXIT, SSL_CB_READ, SSL_CB_WRITE, SSL_CB_ALERT,
2952 SSL_CB_READ_ALERT, SSL_CB_WRITE_ALERT, SSL_CB_ACCEPT_LOOP,
2953 SSL_CB_ACCEPT_EXIT, SSL_CB_CONNECT_LOOP, SSL_CB_CONNECT_EXIT,
2954 SSL_CB_HANDSHAKE_START, SSL_CB_HANDSHAKE_DONE]:
2955
2956 self.assertTrue(isinstance(const, int))
2957
Ziga Seilnacht44611bf2009-08-31 20:49:30 +02002958
Jean-Paul Calderone0b88b6a2009-07-05 12:44:41 -04002959if __name__ == '__main__':
2960 main()