blob: 5373510d6557855ad8dba9bbe6e97f96bfb2e6d7 [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 Calderone20222ae2011-05-19 21:43:46 -0400282
Jean-Paul Calderone9f2e38e2011-04-14 09:36:55 -0400283class VersionTests(TestCase):
284 """
285 Tests for version information exposed by
Jonathan Ballet648875f2011-07-16 14:14:58 +0900286 :py:obj:`OpenSSL.SSL.SSLeay_version` and
287 :py:obj:`OpenSSL.SSL.OPENSSL_VERSION_NUMBER`.
Jean-Paul Calderone9f2e38e2011-04-14 09:36:55 -0400288 """
289 def test_OPENSSL_VERSION_NUMBER(self):
290 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900291 :py:obj:`OPENSSL_VERSION_NUMBER` is an integer with status in the low
Jean-Paul Calderone9f2e38e2011-04-14 09:36:55 -0400292 byte and the patch, fix, minor, and major versions in the
293 nibbles above that.
294 """
295 self.assertTrue(isinstance(OPENSSL_VERSION_NUMBER, int))
296
297
298 def test_SSLeay_version(self):
299 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900300 :py:obj:`SSLeay_version` takes a version type indicator and returns
Jean-Paul Calderone9f2e38e2011-04-14 09:36:55 -0400301 one of a number of version strings based on that indicator.
302 """
303 versions = {}
304 for t in [SSLEAY_VERSION, SSLEAY_CFLAGS, SSLEAY_BUILT_ON,
305 SSLEAY_PLATFORM, SSLEAY_DIR]:
306 version = SSLeay_version(t)
307 versions[version] = t
308 self.assertTrue(isinstance(version, bytes))
309 self.assertEqual(len(versions), 5)
310
311
Jean-Paul Calderonebf37f0f2010-07-31 14:56:20 -0400312
313class ContextTests(TestCase, _LoopbackMixin):
Jean-Paul Calderone30c09ea2008-03-21 17:04:05 -0400314 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900315 Unit tests for :py:obj:`OpenSSL.SSL.Context`.
Jean-Paul Calderone30c09ea2008-03-21 17:04:05 -0400316 """
317 def test_method(self):
318 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900319 :py:obj:`Context` can be instantiated with one of :py:obj:`SSLv2_METHOD`,
Jean-Paul Calderone1461c492013-10-03 16:05:00 -0400320 :py:obj:`SSLv3_METHOD`, :py:obj:`SSLv23_METHOD`, :py:obj:`TLSv1_METHOD`,
321 :py:obj:`TLSv1_1_METHOD`, or :py:obj:`TLSv1_2_METHOD`.
Jean-Paul Calderone30c09ea2008-03-21 17:04:05 -0400322 """
Jean-Paul Calderone1461c492013-10-03 16:05:00 -0400323 methods = [
324 SSLv3_METHOD, SSLv23_METHOD, TLSv1_METHOD]
325 for meth in methods:
Jean-Paul Calderone30c09ea2008-03-21 17:04:05 -0400326 Context(meth)
Jean-Paul Calderone9f2e38e2011-04-14 09:36:55 -0400327
Jean-Paul Calderone1461c492013-10-03 16:05:00 -0400328
329 maybe = [SSLv2_METHOD, TLSv1_1_METHOD, TLSv1_2_METHOD]
330 for meth in maybe:
331 try:
332 Context(meth)
333 except (Error, ValueError):
334 # Some versions of OpenSSL have SSLv2 / TLSv1.1 / TLSv1.2, some
335 # don't. Difficult to say in advance.
336 pass
Jean-Paul Calderone9f2e38e2011-04-14 09:36:55 -0400337
Jean-Paul Calderone30c09ea2008-03-21 17:04:05 -0400338 self.assertRaises(TypeError, Context, "")
339 self.assertRaises(ValueError, Context, 10)
340
341
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -0500342 if not PY3:
343 def test_method_long(self):
344 """
345 On Python 2 :py:class:`Context` accepts values of type
346 :py:obj:`long` as well as :py:obj:`int`.
347 """
348 Context(long(TLSv1_METHOD))
349
350
351
Rick Deane15b1472009-07-09 15:53:42 -0500352 def test_type(self):
353 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900354 :py:obj:`Context` and :py:obj:`ContextType` refer to the same type object and can be
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400355 used to create instances of that type.
Rick Deane15b1472009-07-09 15:53:42 -0500356 """
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400357 self.assertIdentical(Context, ContextType)
358 self.assertConsistentType(Context, 'Context', TLSv1_METHOD)
Rick Deane15b1472009-07-09 15:53:42 -0500359
360
Jean-Paul Calderone30c09ea2008-03-21 17:04:05 -0400361 def test_use_privatekey(self):
362 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900363 :py:obj:`Context.use_privatekey` takes an :py:obj:`OpenSSL.crypto.PKey` instance.
Jean-Paul Calderone30c09ea2008-03-21 17:04:05 -0400364 """
365 key = PKey()
366 key.generate_key(TYPE_RSA, 128)
367 ctx = Context(TLSv1_METHOD)
368 ctx.use_privatekey(key)
369 self.assertRaises(TypeError, ctx.use_privatekey, "")
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -0400370
371
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800372 def test_use_privatekey_file_missing(self):
373 """
374 :py:obj:`Context.use_privatekey_file` raises :py:obj:`OpenSSL.SSL.Error`
375 when passed the name of a file which does not exist.
376 """
377 ctx = Context(TLSv1_METHOD)
378 self.assertRaises(Error, ctx.use_privatekey_file, self.mktemp())
379
380
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -0500381 if not PY3:
382 def test_use_privatekey_file_long(self):
383 """
384 On Python 2 :py:obj:`Context.use_privatekey_file` accepts a
385 filetype of type :py:obj:`long` as well as :py:obj:`int`.
386 """
387 pemfile = self.mktemp()
388
389 key = PKey()
390 key.generate_key(TYPE_RSA, 128)
391
392 with open(pemfile, "wt") as pem:
393 pem.write(
394 dump_privatekey(FILETYPE_PEM, key).decode("ascii"))
395
396 ctx = Context(TLSv1_METHOD)
397 ctx.use_privatekey_file(pemfile, long(FILETYPE_PEM))
398
399
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800400 def test_use_certificate_wrong_args(self):
401 """
402 :py:obj:`Context.use_certificate_wrong_args` raises :py:obj:`TypeError`
403 when not passed exactly one :py:obj:`OpenSSL.crypto.X509` instance as an
404 argument.
405 """
406 ctx = Context(TLSv1_METHOD)
407 self.assertRaises(TypeError, ctx.use_certificate)
408 self.assertRaises(TypeError, ctx.use_certificate, "hello, world")
409 self.assertRaises(TypeError, ctx.use_certificate, X509(), "hello, world")
410
411
412 def test_use_certificate_uninitialized(self):
413 """
414 :py:obj:`Context.use_certificate` raises :py:obj:`OpenSSL.SSL.Error`
415 when passed a :py:obj:`OpenSSL.crypto.X509` instance which has not been
416 initialized (ie, which does not actually have any certificate data).
417 """
418 ctx = Context(TLSv1_METHOD)
419 self.assertRaises(Error, ctx.use_certificate, X509())
420
421
422 def test_use_certificate(self):
423 """
424 :py:obj:`Context.use_certificate` sets the certificate which will be
425 used to identify connections created using the context.
426 """
427 # TODO
428 # Hard to assert anything. But we could set a privatekey then ask
429 # OpenSSL if the cert and key agree using check_privatekey. Then as
430 # long as check_privatekey works right we're good...
431 ctx = Context(TLSv1_METHOD)
432 ctx.use_certificate(load_certificate(FILETYPE_PEM, cleartextCertificatePEM))
433
434
435 def test_use_certificate_file_wrong_args(self):
436 """
437 :py:obj:`Context.use_certificate_file` raises :py:obj:`TypeError` if
438 called with zero arguments or more than two arguments, or if the first
439 argument is not a byte string or the second argumnent is not an integer.
440 """
441 ctx = Context(TLSv1_METHOD)
442 self.assertRaises(TypeError, ctx.use_certificate_file)
443 self.assertRaises(TypeError, ctx.use_certificate_file, b"somefile", object())
444 self.assertRaises(
445 TypeError, ctx.use_certificate_file, b"somefile", FILETYPE_PEM, object())
446 self.assertRaises(
447 TypeError, ctx.use_certificate_file, object(), FILETYPE_PEM)
448 self.assertRaises(
449 TypeError, ctx.use_certificate_file, b"somefile", object())
450
451
452 def test_use_certificate_file_missing(self):
453 """
454 :py:obj:`Context.use_certificate_file` raises
455 `:py:obj:`OpenSSL.SSL.Error` if passed the name of a file which does not
456 exist.
457 """
458 ctx = Context(TLSv1_METHOD)
459 self.assertRaises(Error, ctx.use_certificate_file, self.mktemp())
460
461
462 def test_use_certificate_file(self):
463 """
464 :py:obj:`Context.use_certificate` sets the certificate which will be
465 used to identify connections created using the context.
466 """
467 # TODO
468 # Hard to assert anything. But we could set a privatekey then ask
469 # OpenSSL if the cert and key agree using check_privatekey. Then as
470 # long as check_privatekey works right we're good...
471 pem_filename = self.mktemp()
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -0500472 with open(pem_filename, "wb") as pem_file:
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800473 pem_file.write(cleartextCertificatePEM)
474
475 ctx = Context(TLSv1_METHOD)
476 ctx.use_certificate_file(pem_filename)
477
478
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -0500479 if not PY3:
480 def test_use_certificate_file_long(self):
481 """
482 On Python 2 :py:obj:`Context.use_certificate_file` accepts a
483 filetype of type :py:obj:`long` as well as :py:obj:`int`.
484 """
485 pem_filename = self.mktemp()
486 with open(pem_filename, "wb") as pem_file:
487 pem_file.write(cleartextCertificatePEM)
488
489 ctx = Context(TLSv1_METHOD)
490 ctx.use_certificate_file(pem_filename, long(FILETYPE_PEM))
491
492
Jean-Paul Calderonebd479162010-07-30 18:03:25 -0400493 def test_set_app_data_wrong_args(self):
494 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900495 :py:obj:`Context.set_app_data` raises :py:obj:`TypeError` if called with other than
Jean-Paul Calderonebd479162010-07-30 18:03:25 -0400496 one argument.
497 """
498 context = Context(TLSv1_METHOD)
499 self.assertRaises(TypeError, context.set_app_data)
500 self.assertRaises(TypeError, context.set_app_data, None, None)
501
502
503 def test_get_app_data_wrong_args(self):
504 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900505 :py:obj:`Context.get_app_data` raises :py:obj:`TypeError` if called with any
Jean-Paul Calderonebd479162010-07-30 18:03:25 -0400506 arguments.
507 """
508 context = Context(TLSv1_METHOD)
509 self.assertRaises(TypeError, context.get_app_data, None)
510
511
512 def test_app_data(self):
513 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900514 :py:obj:`Context.set_app_data` stores an object for later retrieval using
515 :py:obj:`Context.get_app_data`.
Jean-Paul Calderonebd479162010-07-30 18:03:25 -0400516 """
517 app_data = object()
518 context = Context(TLSv1_METHOD)
519 context.set_app_data(app_data)
520 self.assertIdentical(context.get_app_data(), app_data)
521
522
Jean-Paul Calderone40569ca2010-07-30 18:04:58 -0400523 def test_set_options_wrong_args(self):
524 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900525 :py:obj:`Context.set_options` raises :py:obj:`TypeError` if called with the wrong
526 number of arguments or a non-:py:obj:`int` argument.
Jean-Paul Calderone40569ca2010-07-30 18:04:58 -0400527 """
528 context = Context(TLSv1_METHOD)
529 self.assertRaises(TypeError, context.set_options)
530 self.assertRaises(TypeError, context.set_options, None)
531 self.assertRaises(TypeError, context.set_options, 1, None)
532
533
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500534 def test_set_options(self):
535 """
536 :py:obj:`Context.set_options` returns the new options value.
537 """
538 context = Context(TLSv1_METHOD)
539 options = context.set_options(OP_NO_SSLv2)
540 self.assertTrue(OP_NO_SSLv2 & options)
541
542
543 if not PY3:
544 def test_set_options_long(self):
545 """
546 On Python 2 :py:obj:`Context.set_options` accepts values of type
547 :py:obj:`long` as well as :py:obj:`int`.
548 """
549 context = Context(TLSv1_METHOD)
550 options = context.set_options(long(OP_NO_SSLv2))
551 self.assertTrue(OP_NO_SSLv2 & options)
552
553
Guillermo Gonzalez74a2c292011-08-29 16:16:58 -0300554 def test_set_mode_wrong_args(self):
555 """
Jean-Paul Calderone64efa2c2011-09-11 10:00:09 -0400556 :py:obj:`Context.set`mode} raises :py:obj:`TypeError` if called with the wrong
557 number of arguments or a non-:py:obj:`int` argument.
Guillermo Gonzalez74a2c292011-08-29 16:16:58 -0300558 """
559 context = Context(TLSv1_METHOD)
560 self.assertRaises(TypeError, context.set_mode)
561 self.assertRaises(TypeError, context.set_mode, None)
562 self.assertRaises(TypeError, context.set_mode, 1, None)
563
564
Jean-Paul Calderone0222a492011-09-08 18:26:03 -0400565 if MODE_RELEASE_BUFFERS is not None:
566 def test_set_mode(self):
567 """
Jean-Paul Calderone64efa2c2011-09-11 10:00:09 -0400568 :py:obj:`Context.set_mode` accepts a mode bitvector and returns the newly
Jean-Paul Calderone0222a492011-09-08 18:26:03 -0400569 set mode.
570 """
571 context = Context(TLSv1_METHOD)
572 self.assertTrue(
573 MODE_RELEASE_BUFFERS & context.set_mode(MODE_RELEASE_BUFFERS))
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500574
575 if not PY3:
576 def test_set_mode_long(self):
577 """
578 On Python 2 :py:obj:`Context.set_mode` accepts values of type
579 :py:obj:`long` as well as :py:obj:`int`.
580 """
581 context = Context(TLSv1_METHOD)
582 mode = context.set_mode(long(MODE_RELEASE_BUFFERS))
583 self.assertTrue(MODE_RELEASE_BUFFERS & mode)
Jean-Paul Calderone0222a492011-09-08 18:26:03 -0400584 else:
585 "MODE_RELEASE_BUFFERS unavailable - OpenSSL version may be too old"
586
587
Jean-Paul Calderone5ebb44a2010-07-30 18:09:41 -0400588 def test_set_timeout_wrong_args(self):
589 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900590 :py:obj:`Context.set_timeout` raises :py:obj:`TypeError` if called with the wrong
591 number of arguments or a non-:py:obj:`int` argument.
Jean-Paul Calderone5ebb44a2010-07-30 18:09:41 -0400592 """
593 context = Context(TLSv1_METHOD)
594 self.assertRaises(TypeError, context.set_timeout)
595 self.assertRaises(TypeError, context.set_timeout, None)
596 self.assertRaises(TypeError, context.set_timeout, 1, None)
597
598
599 def test_get_timeout_wrong_args(self):
600 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900601 :py:obj:`Context.get_timeout` raises :py:obj:`TypeError` if called with any arguments.
Jean-Paul Calderone5ebb44a2010-07-30 18:09:41 -0400602 """
603 context = Context(TLSv1_METHOD)
604 self.assertRaises(TypeError, context.get_timeout, None)
605
606
607 def test_timeout(self):
608 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900609 :py:obj:`Context.set_timeout` sets the session timeout for all connections
610 created using the context object. :py:obj:`Context.get_timeout` retrieves this
Jean-Paul Calderone5ebb44a2010-07-30 18:09:41 -0400611 value.
612 """
613 context = Context(TLSv1_METHOD)
614 context.set_timeout(1234)
615 self.assertEquals(context.get_timeout(), 1234)
616
617
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500618 if not PY3:
619 def test_timeout_long(self):
620 """
621 On Python 2 :py:obj:`Context.set_timeout` accepts values of type
622 `long` as well as int.
623 """
624 context = Context(TLSv1_METHOD)
625 context.set_timeout(long(1234))
626 self.assertEquals(context.get_timeout(), 1234)
627
628
Jean-Paul Calderonee2b69512010-07-30 18:22:06 -0400629 def test_set_verify_depth_wrong_args(self):
630 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900631 :py:obj:`Context.set_verify_depth` raises :py:obj:`TypeError` if called with the wrong
632 number of arguments or a non-:py:obj:`int` argument.
Jean-Paul Calderonee2b69512010-07-30 18:22:06 -0400633 """
634 context = Context(TLSv1_METHOD)
635 self.assertRaises(TypeError, context.set_verify_depth)
636 self.assertRaises(TypeError, context.set_verify_depth, None)
637 self.assertRaises(TypeError, context.set_verify_depth, 1, None)
638
639
640 def test_get_verify_depth_wrong_args(self):
641 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900642 :py:obj:`Context.get_verify_depth` raises :py:obj:`TypeError` if called with any arguments.
Jean-Paul Calderonee2b69512010-07-30 18:22:06 -0400643 """
644 context = Context(TLSv1_METHOD)
645 self.assertRaises(TypeError, context.get_verify_depth, None)
646
647
648 def test_verify_depth(self):
649 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900650 :py:obj:`Context.set_verify_depth` sets the number of certificates in a chain
Jean-Paul Calderonee2b69512010-07-30 18:22:06 -0400651 to follow before giving up. The value can be retrieved with
Jonathan Ballet648875f2011-07-16 14:14:58 +0900652 :py:obj:`Context.get_verify_depth`.
Jean-Paul Calderonee2b69512010-07-30 18:22:06 -0400653 """
654 context = Context(TLSv1_METHOD)
655 context.set_verify_depth(11)
656 self.assertEquals(context.get_verify_depth(), 11)
657
658
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -0500659 if not PY3:
660 def test_verify_depth_long(self):
661 """
662 On Python 2 :py:obj:`Context.set_verify_depth` accepts values of
663 type `long` as well as int.
664 """
665 context = Context(TLSv1_METHOD)
666 context.set_verify_depth(long(11))
667 self.assertEquals(context.get_verify_depth(), 11)
668
669
Jean-Paul Calderone389d76d2010-07-30 17:57:53 -0400670 def _write_encrypted_pem(self, passphrase):
Jean-Paul Calderonea8fb0c82010-09-09 18:04:56 -0400671 """
672 Write a new private key out to a new file, encrypted using the given
673 passphrase. Return the path to the new file.
674 """
Jean-Paul Calderone389d76d2010-07-30 17:57:53 -0400675 key = PKey()
676 key.generate_key(TYPE_RSA, 128)
677 pemFile = self.mktemp()
Jean-Paul Calderonea9868832010-08-22 21:38:34 -0400678 fObj = open(pemFile, 'w')
679 pem = dump_privatekey(FILETYPE_PEM, key, "blowfish", passphrase)
680 fObj.write(pem.decode('ascii'))
Jean-Paul Calderone389d76d2010-07-30 17:57:53 -0400681 fObj.close()
682 return pemFile
683
684
Jean-Paul Calderonef4480622010-08-02 18:25:03 -0400685 def test_set_passwd_cb_wrong_args(self):
686 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900687 :py:obj:`Context.set_passwd_cb` raises :py:obj:`TypeError` if called with the
Jean-Paul Calderonef4480622010-08-02 18:25:03 -0400688 wrong arguments or with a non-callable first argument.
689 """
690 context = Context(TLSv1_METHOD)
691 self.assertRaises(TypeError, context.set_passwd_cb)
692 self.assertRaises(TypeError, context.set_passwd_cb, None)
693 self.assertRaises(TypeError, context.set_passwd_cb, lambda: None, None, None)
694
695
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -0400696 def test_set_passwd_cb(self):
697 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900698 :py:obj:`Context.set_passwd_cb` accepts a callable which will be invoked when
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -0400699 a private key is loaded from an encrypted PEM.
700 """
Jean-Paul Calderonea9868832010-08-22 21:38:34 -0400701 passphrase = b("foobar")
Jean-Paul Calderone389d76d2010-07-30 17:57:53 -0400702 pemFile = self._write_encrypted_pem(passphrase)
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -0400703 calledWith = []
704 def passphraseCallback(maxlen, verify, extra):
705 calledWith.append((maxlen, verify, extra))
706 return passphrase
707 context = Context(TLSv1_METHOD)
708 context.set_passwd_cb(passphraseCallback)
709 context.use_privatekey_file(pemFile)
710 self.assertTrue(len(calledWith), 1)
711 self.assertTrue(isinstance(calledWith[0][0], int))
712 self.assertTrue(isinstance(calledWith[0][1], int))
713 self.assertEqual(calledWith[0][2], None)
Jean-Paul Calderone5ef86512008-04-26 19:06:28 -0400714
715
Jean-Paul Calderone389d76d2010-07-30 17:57:53 -0400716 def test_passwd_callback_exception(self):
717 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900718 :py:obj:`Context.use_privatekey_file` propagates any exception raised by the
Jean-Paul Calderone389d76d2010-07-30 17:57:53 -0400719 passphrase callback.
720 """
Jean-Paul Calderonea9868832010-08-22 21:38:34 -0400721 pemFile = self._write_encrypted_pem(b("monkeys are nice"))
Jean-Paul Calderone389d76d2010-07-30 17:57:53 -0400722 def passphraseCallback(maxlen, verify, extra):
723 raise RuntimeError("Sorry, I am a fail.")
724
725 context = Context(TLSv1_METHOD)
726 context.set_passwd_cb(passphraseCallback)
727 self.assertRaises(RuntimeError, context.use_privatekey_file, pemFile)
728
729
730 def test_passwd_callback_false(self):
731 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900732 :py:obj:`Context.use_privatekey_file` raises :py:obj:`OpenSSL.SSL.Error` if the
Jean-Paul Calderone389d76d2010-07-30 17:57:53 -0400733 passphrase callback returns a false value.
734 """
Jean-Paul Calderonea9868832010-08-22 21:38:34 -0400735 pemFile = self._write_encrypted_pem(b("monkeys are nice"))
Jean-Paul Calderone389d76d2010-07-30 17:57:53 -0400736 def passphraseCallback(maxlen, verify, extra):
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -0500737 return b""
Jean-Paul Calderone389d76d2010-07-30 17:57:53 -0400738
739 context = Context(TLSv1_METHOD)
740 context.set_passwd_cb(passphraseCallback)
741 self.assertRaises(Error, context.use_privatekey_file, pemFile)
742
743
744 def test_passwd_callback_non_string(self):
745 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900746 :py:obj:`Context.use_privatekey_file` raises :py:obj:`OpenSSL.SSL.Error` if the
Jean-Paul Calderone389d76d2010-07-30 17:57:53 -0400747 passphrase callback returns a true non-string value.
748 """
Jean-Paul Calderonea9868832010-08-22 21:38:34 -0400749 pemFile = self._write_encrypted_pem(b("monkeys are nice"))
Jean-Paul Calderone389d76d2010-07-30 17:57:53 -0400750 def passphraseCallback(maxlen, verify, extra):
751 return 10
752
753 context = Context(TLSv1_METHOD)
754 context.set_passwd_cb(passphraseCallback)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800755 self.assertRaises(ValueError, context.use_privatekey_file, pemFile)
Jean-Paul Calderone389d76d2010-07-30 17:57:53 -0400756
757
758 def test_passwd_callback_too_long(self):
759 """
760 If the passphrase returned by the passphrase callback returns a string
761 longer than the indicated maximum length, it is truncated.
762 """
763 # A priori knowledge!
Jean-Paul Calderonea9868832010-08-22 21:38:34 -0400764 passphrase = b("x") * 1024
Jean-Paul Calderone389d76d2010-07-30 17:57:53 -0400765 pemFile = self._write_encrypted_pem(passphrase)
766 def passphraseCallback(maxlen, verify, extra):
767 assert maxlen == 1024
Jean-Paul Calderoneb1f7f5f2010-08-22 21:40:52 -0400768 return passphrase + b("y")
Jean-Paul Calderone389d76d2010-07-30 17:57:53 -0400769
770 context = Context(TLSv1_METHOD)
771 context.set_passwd_cb(passphraseCallback)
772 # This shall succeed because the truncated result is the correct
773 # passphrase.
774 context.use_privatekey_file(pemFile)
775
776
Jean-Paul Calderone5ef86512008-04-26 19:06:28 -0400777 def test_set_info_callback(self):
778 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900779 :py:obj:`Context.set_info_callback` accepts a callable which will be invoked
Jean-Paul Calderone5ef86512008-04-26 19:06:28 -0400780 when certain information about an SSL connection is available.
781 """
Rick Deanb1ccd562009-07-09 23:52:39 -0500782 (server, client) = socket_pair()
Jean-Paul Calderone5ef86512008-04-26 19:06:28 -0400783
784 clientSSL = Connection(Context(TLSv1_METHOD), client)
785 clientSSL.set_connect_state()
786
787 called = []
788 def info(conn, where, ret):
789 called.append((conn, where, ret))
790 context = Context(TLSv1_METHOD)
791 context.set_info_callback(info)
792 context.use_certificate(
793 load_certificate(FILETYPE_PEM, cleartextCertificatePEM))
794 context.use_privatekey(
795 load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM))
796
Jean-Paul Calderone5ef86512008-04-26 19:06:28 -0400797 serverSSL = Connection(context, server)
798 serverSSL.set_accept_state()
799
Jean-Paul Calderonef2bbc9c2014-02-02 10:59:14 -0500800 handshake(clientSSL, serverSSL)
Jean-Paul Calderone5ef86512008-04-26 19:06:28 -0400801
Jean-Paul Calderone3835e522014-02-02 11:12:30 -0500802 # The callback must always be called with a Connection instance as the
803 # first argument. It would probably be better to split this into
804 # separate tests for client and server side info callbacks so we could
805 # assert it is called with the right Connection instance. It would
806 # also be good to assert *something* about `where` and `ret`.
Jean-Paul Calderonef2bbc9c2014-02-02 10:59:14 -0500807 notConnections = [
808 conn for (conn, where, ret) in called
809 if not isinstance(conn, Connection)]
810 self.assertEqual(
811 [], notConnections,
812 "Some info callback arguments were not Connection instaces.")
Jean-Paul Calderonee1bd4322008-09-07 20:17:17 -0400813
814
Jean-Paul Calderone1cb5d022008-09-07 20:58:50 -0400815 def _load_verify_locations_test(self, *args):
Jean-Paul Calderonea8fb0c82010-09-09 18:04:56 -0400816 """
817 Create a client context which will verify the peer certificate and call
Jean-Paul Calderone64efa2c2011-09-11 10:00:09 -0400818 its :py:obj:`load_verify_locations` method with the given arguments.
819 Then connect it to a server and ensure that the handshake succeeds.
Jean-Paul Calderonea8fb0c82010-09-09 18:04:56 -0400820 """
Rick Deanb1ccd562009-07-09 23:52:39 -0500821 (server, client) = socket_pair()
Jean-Paul Calderonee1bd4322008-09-07 20:17:17 -0400822
Jean-Paul Calderonee1bd4322008-09-07 20:17:17 -0400823 clientContext = Context(TLSv1_METHOD)
Jean-Paul Calderone1cb5d022008-09-07 20:58:50 -0400824 clientContext.load_verify_locations(*args)
Jean-Paul Calderonee1bd4322008-09-07 20:17:17 -0400825 # Require that the server certificate verify properly or the
826 # connection will fail.
827 clientContext.set_verify(
828 VERIFY_PEER,
829 lambda conn, cert, errno, depth, preverify_ok: preverify_ok)
830
831 clientSSL = Connection(clientContext, client)
832 clientSSL.set_connect_state()
833
Jean-Paul Calderonee1bd4322008-09-07 20:17:17 -0400834 serverContext = Context(TLSv1_METHOD)
835 serverContext.use_certificate(
836 load_certificate(FILETYPE_PEM, cleartextCertificatePEM))
837 serverContext.use_privatekey(
838 load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM))
839
840 serverSSL = Connection(serverContext, server)
841 serverSSL.set_accept_state()
842
Jean-Paul Calderonef8742032010-09-25 00:00:32 -0400843 # Without load_verify_locations above, the handshake
844 # will fail:
845 # Error: [('SSL routines', 'SSL3_GET_SERVER_CERTIFICATE',
846 # 'certificate verify failed')]
847 handshake(clientSSL, serverSSL)
Jean-Paul Calderonee1bd4322008-09-07 20:17:17 -0400848
849 cert = clientSSL.get_peer_certificate()
Jean-Paul Calderone20131f52009-04-01 12:05:45 -0400850 self.assertEqual(cert.get_subject().CN, 'Testing Root CA')
Jean-Paul Calderone5075fce2008-09-07 20:18:55 -0400851
Jean-Paul Calderone12608a82009-11-07 10:35:15 -0500852
Jean-Paul Calderone1cb5d022008-09-07 20:58:50 -0400853 def test_load_verify_file(self):
854 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900855 :py:obj:`Context.load_verify_locations` accepts a file name and uses the
Jean-Paul Calderone1cb5d022008-09-07 20:58:50 -0400856 certificates within for verification purposes.
857 """
858 cafile = self.mktemp()
Jean-Paul Calderonea9868832010-08-22 21:38:34 -0400859 fObj = open(cafile, 'w')
Jean-Paul Calderoneb1f7f5f2010-08-22 21:40:52 -0400860 fObj.write(cleartextCertificatePEM.decode('ascii'))
Jean-Paul Calderone1cb5d022008-09-07 20:58:50 -0400861 fObj.close()
862
863 self._load_verify_locations_test(cafile)
864
Jean-Paul Calderone5075fce2008-09-07 20:18:55 -0400865
866 def test_load_verify_invalid_file(self):
867 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900868 :py:obj:`Context.load_verify_locations` raises :py:obj:`Error` when passed a
Jean-Paul Calderone5075fce2008-09-07 20:18:55 -0400869 non-existent cafile.
870 """
871 clientContext = Context(TLSv1_METHOD)
872 self.assertRaises(
873 Error, clientContext.load_verify_locations, self.mktemp())
Jean-Paul Calderone1cb5d022008-09-07 20:58:50 -0400874
875
876 def test_load_verify_directory(self):
877 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900878 :py:obj:`Context.load_verify_locations` accepts a directory name and uses
Jean-Paul Calderone1cb5d022008-09-07 20:58:50 -0400879 the certificates within for verification purposes.
880 """
881 capath = self.mktemp()
882 makedirs(capath)
Jean-Paul Calderone24dfb332011-05-04 18:10:26 -0400883 # Hash values computed manually with c_rehash to avoid depending on
884 # c_rehash in the test suite. One is from OpenSSL 0.9.8, the other
885 # from OpenSSL 1.0.0.
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -0500886 for name in [b'c7adac82.0', b'c3705638.0']:
Jean-Paul Calderone24dfb332011-05-04 18:10:26 -0400887 cafile = join(capath, name)
888 fObj = open(cafile, 'w')
889 fObj.write(cleartextCertificatePEM.decode('ascii'))
890 fObj.close()
Jean-Paul Calderone1cb5d022008-09-07 20:58:50 -0400891
Jean-Paul Calderone1cb5d022008-09-07 20:58:50 -0400892 self._load_verify_locations_test(None, capath)
893
894
Jean-Paul Calderonef4480622010-08-02 18:25:03 -0400895 def test_load_verify_locations_wrong_args(self):
896 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900897 :py:obj:`Context.load_verify_locations` raises :py:obj:`TypeError` if called with
898 the wrong number of arguments or with non-:py:obj:`str` arguments.
Jean-Paul Calderonef4480622010-08-02 18:25:03 -0400899 """
900 context = Context(TLSv1_METHOD)
901 self.assertRaises(TypeError, context.load_verify_locations)
902 self.assertRaises(TypeError, context.load_verify_locations, object())
903 self.assertRaises(TypeError, context.load_verify_locations, object(), object())
904 self.assertRaises(TypeError, context.load_verify_locations, None, None, None)
905
906
Jean-Paul Calderone7ca48b52010-07-28 18:57:21 -0400907 if platform == "win32":
908 "set_default_verify_paths appears not to work on Windows. "
Jean-Paul Calderone28fb8f02009-07-24 18:01:31 -0400909 "See LP#404343 and LP#404344."
910 else:
911 def test_set_default_verify_paths(self):
912 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900913 :py:obj:`Context.set_default_verify_paths` causes the platform-specific CA
Jean-Paul Calderone28fb8f02009-07-24 18:01:31 -0400914 certificate locations to be used for verification purposes.
915 """
916 # Testing this requires a server with a certificate signed by one of
917 # the CAs in the platform CA location. Getting one of those costs
918 # money. Fortunately (or unfortunately, depending on your
919 # perspective), it's easy to think of a public server on the
920 # internet which has such a certificate. Connecting to the network
921 # in a unit test is bad, but it's the only way I can think of to
922 # really test this. -exarkun
Jean-Paul Calderone1cb5d022008-09-07 20:58:50 -0400923
Jean-Paul Calderone28fb8f02009-07-24 18:01:31 -0400924 # Arg, verisign.com doesn't speak TLSv1
925 context = Context(SSLv3_METHOD)
926 context.set_default_verify_paths()
927 context.set_verify(
Ziga Seilnacht44611bf2009-08-31 20:49:30 +0200928 VERIFY_PEER,
Jean-Paul Calderone28fb8f02009-07-24 18:01:31 -0400929 lambda conn, cert, errno, depth, preverify_ok: preverify_ok)
Jean-Paul Calderone1cb5d022008-09-07 20:58:50 -0400930
Jean-Paul Calderone28fb8f02009-07-24 18:01:31 -0400931 client = socket()
932 client.connect(('verisign.com', 443))
933 clientSSL = Connection(context, client)
934 clientSSL.set_connect_state()
935 clientSSL.do_handshake()
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -0500936 clientSSL.send(b"GET / HTTP/1.0\r\n\r\n")
Jean-Paul Calderone28fb8f02009-07-24 18:01:31 -0400937 self.assertTrue(clientSSL.recv(1024))
Jean-Paul Calderone9eadb962008-09-07 21:20:44 -0400938
939
940 def test_set_default_verify_paths_signature(self):
941 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900942 :py:obj:`Context.set_default_verify_paths` takes no arguments and raises
943 :py:obj:`TypeError` if given any.
Jean-Paul Calderone9eadb962008-09-07 21:20:44 -0400944 """
945 context = Context(TLSv1_METHOD)
946 self.assertRaises(TypeError, context.set_default_verify_paths, None)
947 self.assertRaises(TypeError, context.set_default_verify_paths, 1)
948 self.assertRaises(TypeError, context.set_default_verify_paths, "")
Jean-Paul Calderone327d8f92008-12-28 21:55:56 -0500949
Jean-Paul Calderonef4480622010-08-02 18:25:03 -0400950
Jean-Paul Calderone12608a82009-11-07 10:35:15 -0500951 def test_add_extra_chain_cert_invalid_cert(self):
952 """
Jonathan Ballet648875f2011-07-16 14:14:58 +0900953 :py:obj:`Context.add_extra_chain_cert` raises :py:obj:`TypeError` if called with
Jean-Paul Calderone12608a82009-11-07 10:35:15 -0500954 other than one argument or if called with an object which is not an
Jonathan Ballet648875f2011-07-16 14:14:58 +0900955 instance of :py:obj:`X509`.
Jean-Paul Calderone12608a82009-11-07 10:35:15 -0500956 """
957 context = Context(TLSv1_METHOD)
958 self.assertRaises(TypeError, context.add_extra_chain_cert)
959 self.assertRaises(TypeError, context.add_extra_chain_cert, object())
960 self.assertRaises(TypeError, context.add_extra_chain_cert, object(), object())
961
962
Jean-Paul Calderonef4480622010-08-02 18:25:03 -0400963 def _handshake_test(self, serverContext, clientContext):
964 """
965 Verify that a client and server created with the given contexts can
966 successfully handshake and communicate.
967 """
968 serverSocket, clientSocket = socket_pair()
969
Jean-Paul Calderonebf37f0f2010-07-31 14:56:20 -0400970 server = Connection(serverContext, serverSocket)
Jean-Paul Calderone9485f2c2010-07-29 22:38:42 -0400971 server.set_accept_state()
Jean-Paul Calderonebf37f0f2010-07-31 14:56:20 -0400972
Jean-Paul Calderonef4480622010-08-02 18:25:03 -0400973 client = Connection(clientContext, clientSocket)
974 client.set_connect_state()
975
976 # Make them talk to each other.
977 # self._interactInMemory(client, server)
978 for i in range(3):
979 for s in [client, server]:
980 try:
981 s.do_handshake()
982 except WantReadError:
983 pass
984
985
Jean-Paul Calderone7e166fe2013-03-06 20:54:38 -0800986 def test_set_verify_callback_exception(self):
987 """
988 If the verify callback passed to :py:obj:`Context.set_verify` raises an
989 exception, verification fails and the exception is propagated to the
990 caller of :py:obj:`Connection.do_handshake`.
991 """
992 serverContext = Context(TLSv1_METHOD)
993 serverContext.use_privatekey(
994 load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM))
995 serverContext.use_certificate(
996 load_certificate(FILETYPE_PEM, cleartextCertificatePEM))
997
998 clientContext = Context(TLSv1_METHOD)
999 def verify_callback(*args):
1000 raise Exception("silly verify failure")
1001 clientContext.set_verify(VERIFY_PEER, verify_callback)
1002
1003 exc = self.assertRaises(
1004 Exception, self._handshake_test, serverContext, clientContext)
1005 self.assertEqual("silly verify failure", str(exc))
1006
1007
Jean-Paul Calderonef4480622010-08-02 18:25:03 -04001008 def test_add_extra_chain_cert(self):
1009 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001010 :py:obj:`Context.add_extra_chain_cert` accepts an :py:obj:`X509` instance to add to
Jean-Paul Calderonef4480622010-08-02 18:25:03 -04001011 the certificate chain.
1012
Jonathan Ballet648875f2011-07-16 14:14:58 +09001013 See :py:obj:`_create_certificate_chain` for the details of the certificate
Jean-Paul Calderonef4480622010-08-02 18:25:03 -04001014 chain tested.
1015
1016 The chain is tested by starting a server with scert and connecting
1017 to it with a client which trusts cacert and requires verification to
1018 succeed.
1019 """
Jean-Paul Calderone20222ae2011-05-19 21:43:46 -04001020 chain = _create_certificate_chain()
Jean-Paul Calderonef4480622010-08-02 18:25:03 -04001021 [(cakey, cacert), (ikey, icert), (skey, scert)] = chain
1022
Jean-Paul Calderonebf37f0f2010-07-31 14:56:20 -04001023 # Dump the CA certificate to a file because that's the only way to load
1024 # it as a trusted CA in the client context.
1025 for cert, name in [(cacert, 'ca.pem'), (icert, 'i.pem'), (scert, 's.pem')]:
Jean-Paul Calderonea9868832010-08-22 21:38:34 -04001026 fObj = open(name, 'w')
Jean-Paul Calderoneb1f7f5f2010-08-22 21:40:52 -04001027 fObj.write(dump_certificate(FILETYPE_PEM, cert).decode('ascii'))
Jean-Paul Calderonebf37f0f2010-07-31 14:56:20 -04001028 fObj.close()
1029
1030 for key, name in [(cakey, 'ca.key'), (ikey, 'i.key'), (skey, 's.key')]:
Jean-Paul Calderonea9868832010-08-22 21:38:34 -04001031 fObj = open(name, 'w')
Jean-Paul Calderoneb1f7f5f2010-08-22 21:40:52 -04001032 fObj.write(dump_privatekey(FILETYPE_PEM, key).decode('ascii'))
Jean-Paul Calderonebf37f0f2010-07-31 14:56:20 -04001033 fObj.close()
1034
Jean-Paul Calderonef4480622010-08-02 18:25:03 -04001035 # Create the server context
1036 serverContext = Context(TLSv1_METHOD)
1037 serverContext.use_privatekey(skey)
1038 serverContext.use_certificate(scert)
Jean-Paul Calderone16cf03d2010-09-08 18:53:39 -04001039 # The client already has cacert, we only need to give them icert.
Jean-Paul Calderonef4480622010-08-02 18:25:03 -04001040 serverContext.add_extra_chain_cert(icert)
1041
Jean-Paul Calderonebf37f0f2010-07-31 14:56:20 -04001042 # Create the client
1043 clientContext = Context(TLSv1_METHOD)
1044 clientContext.set_verify(
1045 VERIFY_PEER | VERIFY_FAIL_IF_NO_PEER_CERT, verify_cb)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001046 clientContext.load_verify_locations(b"ca.pem")
Jean-Paul Calderone9485f2c2010-07-29 22:38:42 -04001047
Jean-Paul Calderonef4480622010-08-02 18:25:03 -04001048 # Try it out.
1049 self._handshake_test(serverContext, clientContext)
1050
1051
Jean-Paul Calderonef4480622010-08-02 18:25:03 -04001052 def test_use_certificate_chain_file(self):
1053 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001054 :py:obj:`Context.use_certificate_chain_file` reads a certificate chain from
Jean-Paul Calderonef4480622010-08-02 18:25:03 -04001055 the specified file.
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
1064 # Write out the chain file.
1065 chainFile = self.mktemp()
Jean-Paul Calderoned8607982014-01-18 10:30:55 -05001066 fObj = open(chainFile, 'wb')
Jean-Paul Calderonef4480622010-08-02 18:25:03 -04001067 # Most specific to least general.
Jean-Paul Calderoned8607982014-01-18 10:30:55 -05001068 fObj.write(dump_certificate(FILETYPE_PEM, scert))
1069 fObj.write(dump_certificate(FILETYPE_PEM, icert))
1070 fObj.write(dump_certificate(FILETYPE_PEM, cacert))
Jean-Paul Calderonef4480622010-08-02 18:25:03 -04001071 fObj.close()
1072
1073 serverContext = Context(TLSv1_METHOD)
1074 serverContext.use_certificate_chain_file(chainFile)
1075 serverContext.use_privatekey(skey)
1076
Jean-Paul Calderonea9868832010-08-22 21:38:34 -04001077 fObj = open('ca.pem', 'w')
1078 fObj.write(dump_certificate(FILETYPE_PEM, cacert).decode('ascii'))
Jean-Paul Calderonef4480622010-08-02 18:25:03 -04001079 fObj.close()
1080
1081 clientContext = Context(TLSv1_METHOD)
1082 clientContext.set_verify(
1083 VERIFY_PEER | VERIFY_FAIL_IF_NO_PEER_CERT, verify_cb)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001084 clientContext.load_verify_locations(b"ca.pem")
Jean-Paul Calderonef4480622010-08-02 18:25:03 -04001085
1086 self._handshake_test(serverContext, clientContext)
1087
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001088
1089 def test_use_certificate_chain_file_wrong_args(self):
1090 """
1091 :py:obj:`Context.use_certificate_chain_file` raises :py:obj:`TypeError`
1092 if passed zero or more than one argument or when passed a non-byte
1093 string single argument. It also raises :py:obj:`OpenSSL.SSL.Error` when
1094 passed a bad chain file name (for example, the name of a file which does
1095 not exist).
1096 """
1097 context = Context(TLSv1_METHOD)
1098 self.assertRaises(TypeError, context.use_certificate_chain_file)
1099 self.assertRaises(TypeError, context.use_certificate_chain_file, object())
1100 self.assertRaises(TypeError, context.use_certificate_chain_file, b"foo", object())
1101
1102 self.assertRaises(Error, context.use_certificate_chain_file, self.mktemp())
1103
Jean-Paul Calderonee0d79362010-08-03 18:46:46 -04001104 # XXX load_client_ca
1105 # XXX set_session_id
Jean-Paul Calderone0294e3d2010-09-09 18:17:48 -04001106
1107 def test_get_verify_mode_wrong_args(self):
1108 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001109 :py:obj:`Context.get_verify_mode` raises :py:obj:`TypeError` if called with any
Jean-Paul Calderone0294e3d2010-09-09 18:17:48 -04001110 arguments.
1111 """
1112 context = Context(TLSv1_METHOD)
1113 self.assertRaises(TypeError, context.get_verify_mode, None)
1114
1115
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -05001116 def test_set_verify_mode(self):
Jean-Paul Calderone0294e3d2010-09-09 18:17:48 -04001117 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001118 :py:obj:`Context.get_verify_mode` returns the verify mode flags previously
1119 passed to :py:obj:`Context.set_verify`.
Jean-Paul Calderone0294e3d2010-09-09 18:17:48 -04001120 """
1121 context = Context(TLSv1_METHOD)
1122 self.assertEquals(context.get_verify_mode(), 0)
1123 context.set_verify(
1124 VERIFY_PEER | VERIFY_CLIENT_ONCE, lambda *args: None)
1125 self.assertEquals(
1126 context.get_verify_mode(), VERIFY_PEER | VERIFY_CLIENT_ONCE)
1127
Jean-Paul Calderone6ace4782010-09-09 18:43:40 -04001128
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -05001129 if not PY3:
1130 def test_set_verify_mode_long(self):
1131 """
1132 On Python 2 :py:obj:`Context.set_verify_mode` accepts values of
1133 type :py:obj:`long` as well as :py:obj:`int`.
1134 """
1135 context = Context(TLSv1_METHOD)
1136 self.assertEquals(context.get_verify_mode(), 0)
1137 context.set_verify(
1138 long(VERIFY_PEER | VERIFY_CLIENT_ONCE), lambda *args: None)
1139 self.assertEquals(
1140 context.get_verify_mode(), VERIFY_PEER | VERIFY_CLIENT_ONCE)
1141
1142
Jean-Paul Calderone6ace4782010-09-09 18:43:40 -04001143 def test_load_tmp_dh_wrong_args(self):
1144 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001145 :py:obj:`Context.load_tmp_dh` raises :py:obj:`TypeError` if called with the wrong
1146 number of arguments or with a non-:py:obj:`str` argument.
Jean-Paul Calderone6ace4782010-09-09 18:43:40 -04001147 """
1148 context = Context(TLSv1_METHOD)
1149 self.assertRaises(TypeError, context.load_tmp_dh)
1150 self.assertRaises(TypeError, context.load_tmp_dh, "foo", None)
1151 self.assertRaises(TypeError, context.load_tmp_dh, object())
1152
1153
1154 def test_load_tmp_dh_missing_file(self):
1155 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001156 :py:obj:`Context.load_tmp_dh` raises :py:obj:`OpenSSL.SSL.Error` if the specified file
Jean-Paul Calderone6ace4782010-09-09 18:43:40 -04001157 does not exist.
1158 """
1159 context = Context(TLSv1_METHOD)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001160 self.assertRaises(Error, context.load_tmp_dh, b"hello")
Jean-Paul Calderone6ace4782010-09-09 18:43:40 -04001161
1162
1163 def test_load_tmp_dh(self):
1164 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001165 :py:obj:`Context.load_tmp_dh` loads Diffie-Hellman parameters from the
Jean-Paul Calderone6ace4782010-09-09 18:43:40 -04001166 specified file.
1167 """
1168 context = Context(TLSv1_METHOD)
1169 dhfilename = self.mktemp()
1170 dhfile = open(dhfilename, "w")
1171 dhfile.write(dhparam)
1172 dhfile.close()
1173 context.load_tmp_dh(dhfilename)
1174 # XXX What should I assert here? -exarkun
1175
1176
Jean-Paul Calderone3e4e3352014-04-19 09:28:28 -04001177 def test_set_tmp_ecdh(self):
Andy Lutomirskif05a2732014-03-13 17:22:25 -07001178 """
Jean-Paul Calderone3e4e3352014-04-19 09:28:28 -04001179 :py:obj:`Context.set_tmp_ecdh` sets the elliptic curve for
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04001180 Diffie-Hellman to the specified curve.
Andy Lutomirskif05a2732014-03-13 17:22:25 -07001181 """
1182 context = Context(TLSv1_METHOD)
Jean-Paul Calderonec09fd582014-04-18 22:00:10 -04001183 for curve in get_elliptic_curves():
1184 # The only easily "assertable" thing is that it does not raise an
1185 # exception.
Jean-Paul Calderone3e4e3352014-04-19 09:28:28 -04001186 context.set_tmp_ecdh(curve)
Alex Gaynor12dc0842014-01-17 12:51:31 -06001187
1188
Jean-Paul Calderone63eab692014-01-18 10:19:56 -05001189 def test_set_cipher_list_bytes(self):
Jean-Paul Calderone6ace4782010-09-09 18:43:40 -04001190 """
Jean-Paul Calderone63eab692014-01-18 10:19:56 -05001191 :py:obj:`Context.set_cipher_list` accepts a :py:obj:`bytes` naming the
1192 ciphers which connections created with the context object will be able
1193 to choose from.
Jean-Paul Calderone6ace4782010-09-09 18:43:40 -04001194 """
1195 context = Context(TLSv1_METHOD)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05001196 context.set_cipher_list(b"hello world:EXP-RC4-MD5")
Jean-Paul Calderone6ace4782010-09-09 18:43:40 -04001197 conn = Connection(context, None)
1198 self.assertEquals(conn.get_cipher_list(), ["EXP-RC4-MD5"])
Jean-Paul Calderone9485f2c2010-07-29 22:38:42 -04001199
Jean-Paul Calderone9485f2c2010-07-29 22:38:42 -04001200
Jean-Paul Calderone63eab692014-01-18 10:19:56 -05001201 def test_set_cipher_list_text(self):
1202 """
1203 :py:obj:`Context.set_cipher_list` accepts a :py:obj:`unicode` naming
1204 the ciphers which connections created with the context object will be
1205 able to choose from.
1206 """
1207 context = Context(TLSv1_METHOD)
Jean-Paul Calderonec76c61c2014-01-18 13:21:52 -05001208 context.set_cipher_list(u("hello world:EXP-RC4-MD5"))
Jean-Paul Calderone63eab692014-01-18 10:19:56 -05001209 conn = Connection(context, None)
1210 self.assertEquals(conn.get_cipher_list(), ["EXP-RC4-MD5"])
1211
1212
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001213 def test_set_cipher_list_wrong_args(self):
1214 """
Jean-Paul Calderone17044832014-01-18 10:20:11 -05001215 :py:obj:`Context.set_cipher_list` raises :py:obj:`TypeError` when
1216 passed zero arguments or more than one argument or when passed a
1217 non-string single argument and raises :py:obj:`OpenSSL.SSL.Error` when
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001218 passed an incorrect cipher list string.
1219 """
1220 context = Context(TLSv1_METHOD)
1221 self.assertRaises(TypeError, context.set_cipher_list)
1222 self.assertRaises(TypeError, context.set_cipher_list, object())
1223 self.assertRaises(TypeError, context.set_cipher_list, b"EXP-RC4-MD5", object())
1224
Jean-Paul Calderone63eab692014-01-18 10:19:56 -05001225 self.assertRaises(Error, context.set_cipher_list, "imaginary-cipher")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001226
1227
Jean-Paul Calderone313bf012012-02-08 13:02:49 -05001228 def test_set_session_cache_mode_wrong_args(self):
1229 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -05001230 :py:obj:`Context.set_session_cache_mode` raises :py:obj:`TypeError` if
1231 called with other than one integer argument.
Jean-Paul Calderone313bf012012-02-08 13:02:49 -05001232 """
1233 context = Context(TLSv1_METHOD)
1234 self.assertRaises(TypeError, context.set_session_cache_mode)
1235 self.assertRaises(TypeError, context.set_session_cache_mode, object())
1236
1237
1238 def test_get_session_cache_mode_wrong_args(self):
1239 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -05001240 :py:obj:`Context.get_session_cache_mode` raises :py:obj:`TypeError` if
1241 called with any arguments.
Jean-Paul Calderone313bf012012-02-08 13:02:49 -05001242 """
1243 context = Context(TLSv1_METHOD)
1244 self.assertRaises(TypeError, context.get_session_cache_mode, 1)
1245
1246
1247 def test_session_cache_mode(self):
1248 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -05001249 :py:obj:`Context.set_session_cache_mode` specifies how sessions are
1250 cached. The setting can be retrieved via
1251 :py:obj:`Context.get_session_cache_mode`.
Jean-Paul Calderone313bf012012-02-08 13:02:49 -05001252 """
1253 context = Context(TLSv1_METHOD)
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -05001254 context.set_session_cache_mode(SESS_CACHE_OFF)
Jean-Paul Calderone313bf012012-02-08 13:02:49 -05001255 off = context.set_session_cache_mode(SESS_CACHE_BOTH)
1256 self.assertEqual(SESS_CACHE_OFF, off)
1257 self.assertEqual(SESS_CACHE_BOTH, context.get_session_cache_mode())
1258
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -05001259 if not PY3:
1260 def test_session_cache_mode_long(self):
1261 """
1262 On Python 2 :py:obj:`Context.set_session_cache_mode` accepts values
1263 of type :py:obj:`long` as well as :py:obj:`int`.
1264 """
1265 context = Context(TLSv1_METHOD)
1266 context.set_session_cache_mode(long(SESS_CACHE_BOTH))
1267 self.assertEqual(
1268 SESS_CACHE_BOTH, context.get_session_cache_mode())
1269
Jean-Paul Calderone313bf012012-02-08 13:02:49 -05001270
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001271 def test_get_cert_store(self):
1272 """
1273 :py:obj:`Context.get_cert_store` returns a :py:obj:`X509Store` instance.
1274 """
1275 context = Context(TLSv1_METHOD)
1276 store = context.get_cert_store()
1277 self.assertIsInstance(store, X509Store)
1278
1279
Jean-Paul Calderone9485f2c2010-07-29 22:38:42 -04001280
Jean-Paul Calderonec4cb6582011-05-26 18:47:00 -04001281class ServerNameCallbackTests(TestCase, _LoopbackMixin):
1282 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001283 Tests for :py:obj:`Context.set_tlsext_servername_callback` and its interaction with
1284 :py:obj:`Connection`.
Jean-Paul Calderonec4cb6582011-05-26 18:47:00 -04001285 """
1286 def test_wrong_args(self):
1287 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001288 :py:obj:`Context.set_tlsext_servername_callback` raises :py:obj:`TypeError` if called
Jean-Paul Calderonec4cb6582011-05-26 18:47:00 -04001289 with other than one argument.
1290 """
1291 context = Context(TLSv1_METHOD)
1292 self.assertRaises(TypeError, context.set_tlsext_servername_callback)
1293 self.assertRaises(
1294 TypeError, context.set_tlsext_servername_callback, 1, 2)
1295
Jean-Paul Calderone4c1aacd2014-01-11 08:15:17 -05001296
Jean-Paul Calderonec4cb6582011-05-26 18:47:00 -04001297 def test_old_callback_forgotten(self):
1298 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001299 If :py:obj:`Context.set_tlsext_servername_callback` is used to specify a new
Jean-Paul Calderonec4cb6582011-05-26 18:47:00 -04001300 callback, the one it replaces is dereferenced.
1301 """
1302 def callback(connection):
1303 pass
1304
1305 def replacement(connection):
1306 pass
1307
1308 context = Context(TLSv1_METHOD)
1309 context.set_tlsext_servername_callback(callback)
1310
1311 tracker = ref(callback)
1312 del callback
1313
1314 context.set_tlsext_servername_callback(replacement)
Jean-Paul Calderoned4033eb2014-01-11 08:21:46 -05001315
1316 # One run of the garbage collector happens to work on CPython. PyPy
1317 # doesn't collect the underlying object until a second run for whatever
1318 # reason. That's fine, it still demonstrates our code has properly
1319 # dropped the reference.
1320 collect()
Jean-Paul Calderonec4cb6582011-05-26 18:47:00 -04001321 collect()
Jean-Paul Calderone4c1aacd2014-01-11 08:15:17 -05001322
1323 callback = tracker()
1324 if callback is not None:
1325 referrers = get_referrers(callback)
Jean-Paul Calderone7de39562014-01-11 08:17:59 -05001326 if len(referrers) > 1:
Jean-Paul Calderone4c1aacd2014-01-11 08:15:17 -05001327 self.fail("Some references remain: %r" % (referrers,))
Jean-Paul Calderonec4cb6582011-05-26 18:47:00 -04001328
1329
1330 def test_no_servername(self):
1331 """
1332 When a client specifies no server name, the callback passed to
Jonathan Ballet648875f2011-07-16 14:14:58 +09001333 :py:obj:`Context.set_tlsext_servername_callback` is invoked and the result of
1334 :py:obj:`Connection.get_servername` is :py:obj:`None`.
Jean-Paul Calderonec4cb6582011-05-26 18:47:00 -04001335 """
1336 args = []
1337 def servername(conn):
1338 args.append((conn, conn.get_servername()))
1339 context = Context(TLSv1_METHOD)
1340 context.set_tlsext_servername_callback(servername)
1341
1342 # Lose our reference to it. The Context is responsible for keeping it
1343 # alive now.
1344 del servername
1345 collect()
1346
1347 # Necessary to actually accept the connection
1348 context.use_privatekey(load_privatekey(FILETYPE_PEM, server_key_pem))
1349 context.use_certificate(load_certificate(FILETYPE_PEM, server_cert_pem))
1350
1351 # Do a little connection to trigger the logic
1352 server = Connection(context, None)
1353 server.set_accept_state()
1354
1355 client = Connection(Context(TLSv1_METHOD), None)
1356 client.set_connect_state()
1357
1358 self._interactInMemory(server, client)
1359
1360 self.assertEqual([(server, None)], args)
1361
1362
1363 def test_servername(self):
1364 """
1365 When a client specifies a server name in its hello message, the callback
Jonathan Ballet648875f2011-07-16 14:14:58 +09001366 passed to :py:obj:`Contexts.set_tlsext_servername_callback` is invoked and the
1367 result of :py:obj:`Connection.get_servername` is that server name.
Jean-Paul Calderonec4cb6582011-05-26 18:47:00 -04001368 """
1369 args = []
1370 def servername(conn):
1371 args.append((conn, conn.get_servername()))
1372 context = Context(TLSv1_METHOD)
1373 context.set_tlsext_servername_callback(servername)
1374
1375 # Necessary to actually accept the connection
1376 context.use_privatekey(load_privatekey(FILETYPE_PEM, server_key_pem))
1377 context.use_certificate(load_certificate(FILETYPE_PEM, server_cert_pem))
1378
1379 # Do a little connection to trigger the logic
1380 server = Connection(context, None)
1381 server.set_accept_state()
1382
1383 client = Connection(Context(TLSv1_METHOD), None)
1384 client.set_connect_state()
1385 client.set_tlsext_host_name(b("foo1.example.com"))
1386
1387 self._interactInMemory(server, client)
1388
1389 self.assertEqual([(server, b("foo1.example.com"))], args)
1390
1391
1392
Jean-Paul Calderonee0fcf512012-02-13 09:10:15 -05001393class SessionTests(TestCase):
1394 """
1395 Unit tests for :py:obj:`OpenSSL.SSL.Session`.
1396 """
1397 def test_construction(self):
1398 """
1399 :py:class:`Session` can be constructed with no arguments, creating a new
1400 instance of that type.
1401 """
1402 new_session = Session()
1403 self.assertTrue(isinstance(new_session, Session))
1404
1405
1406 def test_construction_wrong_args(self):
1407 """
1408 If any arguments are passed to :py:class:`Session`, :py:obj:`TypeError`
1409 is raised.
1410 """
1411 self.assertRaises(TypeError, Session, 123)
1412 self.assertRaises(TypeError, Session, "hello")
1413 self.assertRaises(TypeError, Session, object())
1414
1415
1416
Jean-Paul Calderone9485f2c2010-07-29 22:38:42 -04001417class ConnectionTests(TestCase, _LoopbackMixin):
Rick Deane15b1472009-07-09 15:53:42 -05001418 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001419 Unit tests for :py:obj:`OpenSSL.SSL.Connection`.
Rick Deane15b1472009-07-09 15:53:42 -05001420 """
Jean-Paul Calderone541eaf22010-09-09 18:55:08 -04001421 # XXX get_peer_certificate -> None
1422 # XXX sock_shutdown
1423 # XXX master_key -> TypeError
1424 # XXX server_random -> TypeError
1425 # XXX state_string
1426 # XXX connect -> TypeError
1427 # XXX connect_ex -> TypeError
1428 # XXX set_connect_state -> TypeError
1429 # XXX set_accept_state -> TypeError
1430 # XXX renegotiate_pending
1431 # XXX do_handshake -> TypeError
1432 # XXX bio_read -> TypeError
1433 # XXX recv -> TypeError
1434 # XXX send -> TypeError
1435 # XXX bio_write -> TypeError
1436
Rick Deane15b1472009-07-09 15:53:42 -05001437 def test_type(self):
1438 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001439 :py:obj:`Connection` and :py:obj:`ConnectionType` refer to the same type object and
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001440 can be used to create instances of that type.
Rick Deane15b1472009-07-09 15:53:42 -05001441 """
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001442 self.assertIdentical(Connection, ConnectionType)
Rick Deane15b1472009-07-09 15:53:42 -05001443 ctx = Context(TLSv1_METHOD)
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001444 self.assertConsistentType(Connection, 'Connection', ctx, None)
Rick Deane15b1472009-07-09 15:53:42 -05001445
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001446
Jean-Paul Calderone4fd058a2009-11-22 11:46:42 -05001447 def test_get_context(self):
1448 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001449 :py:obj:`Connection.get_context` returns the :py:obj:`Context` instance used to
1450 construct the :py:obj:`Connection` instance.
Jean-Paul Calderone4fd058a2009-11-22 11:46:42 -05001451 """
1452 context = Context(TLSv1_METHOD)
1453 connection = Connection(context, None)
1454 self.assertIdentical(connection.get_context(), context)
1455
1456
1457 def test_get_context_wrong_args(self):
1458 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001459 :py:obj:`Connection.get_context` raises :py:obj:`TypeError` if called with any
Jean-Paul Calderone4fd058a2009-11-22 11:46:42 -05001460 arguments.
1461 """
1462 connection = Connection(Context(TLSv1_METHOD), None)
1463 self.assertRaises(TypeError, connection.get_context, None)
1464
1465
Jean-Paul Calderone95613b72011-05-25 22:30:21 -04001466 def test_set_context_wrong_args(self):
1467 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001468 :py:obj:`Connection.set_context` raises :py:obj:`TypeError` if called with a
1469 non-:py:obj:`Context` instance argument or with any number of arguments other
Jean-Paul Calderone95613b72011-05-25 22:30:21 -04001470 than 1.
1471 """
1472 ctx = Context(TLSv1_METHOD)
1473 connection = Connection(ctx, None)
1474 self.assertRaises(TypeError, connection.set_context)
1475 self.assertRaises(TypeError, connection.set_context, object())
1476 self.assertRaises(TypeError, connection.set_context, "hello")
1477 self.assertRaises(TypeError, connection.set_context, 1)
1478 self.assertRaises(TypeError, connection.set_context, 1, 2)
1479 self.assertRaises(
1480 TypeError, connection.set_context, Context(TLSv1_METHOD), 2)
1481 self.assertIdentical(ctx, connection.get_context())
1482
1483
1484 def test_set_context(self):
1485 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001486 :py:obj:`Connection.set_context` specifies a new :py:obj:`Context` instance to be used
Jean-Paul Calderone95613b72011-05-25 22:30:21 -04001487 for the connection.
1488 """
1489 original = Context(SSLv23_METHOD)
1490 replacement = Context(TLSv1_METHOD)
1491 connection = Connection(original, None)
1492 connection.set_context(replacement)
1493 self.assertIdentical(replacement, connection.get_context())
1494 # Lose our references to the contexts, just in case the Connection isn't
1495 # properly managing its own contributions to their reference counts.
1496 del original, replacement
Jean-Paul Calderonec4cb6582011-05-26 18:47:00 -04001497 collect()
1498
1499
1500 def test_set_tlsext_host_name_wrong_args(self):
1501 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001502 If :py:obj:`Connection.set_tlsext_host_name` is called with a non-byte string
Jean-Paul Calderonec4cb6582011-05-26 18:47:00 -04001503 argument or a byte string with an embedded NUL or other than one
Jonathan Ballet648875f2011-07-16 14:14:58 +09001504 argument, :py:obj:`TypeError` is raised.
Jean-Paul Calderonec4cb6582011-05-26 18:47:00 -04001505 """
1506 conn = Connection(Context(TLSv1_METHOD), None)
1507 self.assertRaises(TypeError, conn.set_tlsext_host_name)
1508 self.assertRaises(TypeError, conn.set_tlsext_host_name, object())
1509 self.assertRaises(TypeError, conn.set_tlsext_host_name, 123, 456)
1510 self.assertRaises(
1511 TypeError, conn.set_tlsext_host_name, b("with\0null"))
1512
1513 if version_info >= (3,):
1514 # On Python 3.x, don't accidentally implicitly convert from text.
1515 self.assertRaises(
1516 TypeError,
1517 conn.set_tlsext_host_name, b("example.com").decode("ascii"))
Jean-Paul Calderone95613b72011-05-25 22:30:21 -04001518
1519
Jean-Paul Calderone871a4d82011-05-26 19:24:02 -04001520 def test_get_servername_wrong_args(self):
1521 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001522 :py:obj:`Connection.get_servername` raises :py:obj:`TypeError` if called with any
Jean-Paul Calderone871a4d82011-05-26 19:24:02 -04001523 arguments.
1524 """
1525 connection = Connection(Context(TLSv1_METHOD), None)
1526 self.assertRaises(TypeError, connection.get_servername, object())
1527 self.assertRaises(TypeError, connection.get_servername, 1)
1528 self.assertRaises(TypeError, connection.get_servername, "hello")
1529
1530
Jean-Paul Calderone1d69a722010-07-29 09:05:53 -04001531 def test_pending(self):
Jean-Paul Calderone93dba222010-09-08 22:59:37 -04001532 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001533 :py:obj:`Connection.pending` returns the number of bytes available for
Jean-Paul Calderone93dba222010-09-08 22:59:37 -04001534 immediate read.
1535 """
Jean-Paul Calderone1d69a722010-07-29 09:05:53 -04001536 connection = Connection(Context(TLSv1_METHOD), None)
1537 self.assertEquals(connection.pending(), 0)
1538
1539
1540 def test_pending_wrong_args(self):
Jean-Paul Calderone93dba222010-09-08 22:59:37 -04001541 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001542 :py:obj:`Connection.pending` raises :py:obj:`TypeError` if called with any arguments.
Jean-Paul Calderone93dba222010-09-08 22:59:37 -04001543 """
Jean-Paul Calderone1d69a722010-07-29 09:05:53 -04001544 connection = Connection(Context(TLSv1_METHOD), None)
1545 self.assertRaises(TypeError, connection.pending, None)
1546
1547
Jean-Paul Calderonecfecc242010-07-29 22:47:06 -04001548 def test_connect_wrong_args(self):
Jean-Paul Calderone93dba222010-09-08 22:59:37 -04001549 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001550 :py:obj:`Connection.connect` raises :py:obj:`TypeError` if called with a non-address
Jean-Paul Calderone93dba222010-09-08 22:59:37 -04001551 argument or with the wrong number of arguments.
1552 """
Jean-Paul Calderonecfecc242010-07-29 22:47:06 -04001553 connection = Connection(Context(TLSv1_METHOD), socket())
1554 self.assertRaises(TypeError, connection.connect, None)
Jean-Paul Calderone93dba222010-09-08 22:59:37 -04001555 self.assertRaises(TypeError, connection.connect)
1556 self.assertRaises(TypeError, connection.connect, ("127.0.0.1", 1), None)
Jean-Paul Calderonecfecc242010-07-29 22:47:06 -04001557
1558
Jean-Paul Calderone8bdeba22010-07-29 09:45:07 -04001559 def test_connect_refused(self):
Jean-Paul Calderone93dba222010-09-08 22:59:37 -04001560 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001561 :py:obj:`Connection.connect` raises :py:obj:`socket.error` if the underlying socket
Jean-Paul Calderone93dba222010-09-08 22:59:37 -04001562 connect method raises it.
1563 """
Jean-Paul Calderone8bdeba22010-07-29 09:45:07 -04001564 client = socket()
1565 context = Context(TLSv1_METHOD)
1566 clientSSL = Connection(context, client)
1567 exc = self.assertRaises(error, clientSSL.connect, ("127.0.0.1", 1))
Jean-Paul Calderone35adf9d2010-07-29 18:40:44 -04001568 self.assertEquals(exc.args[0], ECONNREFUSED)
Jean-Paul Calderone8bdeba22010-07-29 09:45:07 -04001569
1570
1571 def test_connect(self):
Jean-Paul Calderone93dba222010-09-08 22:59:37 -04001572 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001573 :py:obj:`Connection.connect` establishes a connection to the specified address.
Jean-Paul Calderone93dba222010-09-08 22:59:37 -04001574 """
Jean-Paul Calderone0bcb0e02010-07-29 09:49:59 -04001575 port = socket()
1576 port.bind(('', 0))
1577 port.listen(3)
1578
1579 clientSSL = Connection(Context(TLSv1_METHOD), socket())
Jean-Paul Calderoneb6e0fd92010-09-19 09:22:13 -04001580 clientSSL.connect(('127.0.0.1', port.getsockname()[1]))
1581 # XXX An assertion? Or something?
Jean-Paul Calderone0bcb0e02010-07-29 09:49:59 -04001582
1583
Jean-Paul Calderone7b614872010-09-24 17:43:44 -04001584 if platform == "darwin":
1585 "connect_ex sometimes causes a kernel panic on OS X 10.6.4"
1586 else:
1587 def test_connect_ex(self):
1588 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001589 If there is a connection error, :py:obj:`Connection.connect_ex` returns the
Jean-Paul Calderone7b614872010-09-24 17:43:44 -04001590 errno instead of raising an exception.
1591 """
1592 port = socket()
1593 port.bind(('', 0))
1594 port.listen(3)
Jean-Paul Calderone55d91f42010-07-29 19:22:17 -04001595
Jean-Paul Calderone7b614872010-09-24 17:43:44 -04001596 clientSSL = Connection(Context(TLSv1_METHOD), socket())
1597 clientSSL.setblocking(False)
1598 result = clientSSL.connect_ex(port.getsockname())
1599 expected = (EINPROGRESS, EWOULDBLOCK)
1600 self.assertTrue(
1601 result in expected, "%r not in %r" % (result, expected))
Jean-Paul Calderone55d91f42010-07-29 19:22:17 -04001602
1603
Jean-Paul Calderonecfecc242010-07-29 22:47:06 -04001604 def test_accept_wrong_args(self):
Jean-Paul Calderone93dba222010-09-08 22:59:37 -04001605 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001606 :py:obj:`Connection.accept` raises :py:obj:`TypeError` if called with any arguments.
Jean-Paul Calderone93dba222010-09-08 22:59:37 -04001607 """
Jean-Paul Calderonecfecc242010-07-29 22:47:06 -04001608 connection = Connection(Context(TLSv1_METHOD), socket())
1609 self.assertRaises(TypeError, connection.accept, None)
1610
1611
Jean-Paul Calderone0bcb0e02010-07-29 09:49:59 -04001612 def test_accept(self):
Jean-Paul Calderone93dba222010-09-08 22:59:37 -04001613 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001614 :py:obj:`Connection.accept` accepts a pending connection attempt and returns a
1615 tuple of a new :py:obj:`Connection` (the accepted client) and the address the
Jean-Paul Calderone93dba222010-09-08 22:59:37 -04001616 connection originated from.
1617 """
Jean-Paul Calderone8bdeba22010-07-29 09:45:07 -04001618 ctx = Context(TLSv1_METHOD)
1619 ctx.use_privatekey(load_privatekey(FILETYPE_PEM, server_key_pem))
1620 ctx.use_certificate(load_certificate(FILETYPE_PEM, server_cert_pem))
Jean-Paul Calderone0bcb0e02010-07-29 09:49:59 -04001621 port = socket()
1622 portSSL = Connection(ctx, port)
1623 portSSL.bind(('', 0))
1624 portSSL.listen(3)
Jean-Paul Calderone8bdeba22010-07-29 09:45:07 -04001625
Jean-Paul Calderone0bcb0e02010-07-29 09:49:59 -04001626 clientSSL = Connection(Context(TLSv1_METHOD), socket())
Jean-Paul Calderoneb6e0fd92010-09-19 09:22:13 -04001627
1628 # Calling portSSL.getsockname() here to get the server IP address sounds
1629 # great, but frequently fails on Windows.
1630 clientSSL.connect(('127.0.0.1', portSSL.getsockname()[1]))
Jean-Paul Calderone8bdeba22010-07-29 09:45:07 -04001631
Jean-Paul Calderone0bcb0e02010-07-29 09:49:59 -04001632 serverSSL, address = portSSL.accept()
1633
1634 self.assertTrue(isinstance(serverSSL, Connection))
1635 self.assertIdentical(serverSSL.get_context(), ctx)
1636 self.assertEquals(address, clientSSL.getsockname())
Jean-Paul Calderone8bdeba22010-07-29 09:45:07 -04001637
1638
Jean-Paul Calderonecfecc242010-07-29 22:47:06 -04001639 def test_shutdown_wrong_args(self):
Jean-Paul Calderone93dba222010-09-08 22:59:37 -04001640 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001641 :py:obj:`Connection.shutdown` raises :py:obj:`TypeError` if called with the wrong
Jean-Paul Calderone93dba222010-09-08 22:59:37 -04001642 number of arguments or with arguments other than integers.
1643 """
Jean-Paul Calderonecfecc242010-07-29 22:47:06 -04001644 connection = Connection(Context(TLSv1_METHOD), None)
1645 self.assertRaises(TypeError, connection.shutdown, None)
Jean-Paul Calderone1d3e0222010-07-29 22:52:45 -04001646 self.assertRaises(TypeError, connection.get_shutdown, None)
1647 self.assertRaises(TypeError, connection.set_shutdown)
1648 self.assertRaises(TypeError, connection.set_shutdown, None)
1649 self.assertRaises(TypeError, connection.set_shutdown, 0, 1)
Jean-Paul Calderonecfecc242010-07-29 22:47:06 -04001650
1651
Jean-Paul Calderone9485f2c2010-07-29 22:38:42 -04001652 def test_shutdown(self):
Jean-Paul Calderone93dba222010-09-08 22:59:37 -04001653 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001654 :py:obj:`Connection.shutdown` performs an SSL-level connection shutdown.
Jean-Paul Calderone93dba222010-09-08 22:59:37 -04001655 """
Jean-Paul Calderone9485f2c2010-07-29 22:38:42 -04001656 server, client = self._loopback()
Jean-Paul Calderonee4f6b472010-07-29 22:50:58 -04001657 self.assertFalse(server.shutdown())
1658 self.assertEquals(server.get_shutdown(), SENT_SHUTDOWN)
Jean-Paul Calderone9485f2c2010-07-29 22:38:42 -04001659 self.assertRaises(ZeroReturnError, client.recv, 1024)
Jean-Paul Calderonee4f6b472010-07-29 22:50:58 -04001660 self.assertEquals(client.get_shutdown(), RECEIVED_SHUTDOWN)
1661 client.shutdown()
1662 self.assertEquals(client.get_shutdown(), SENT_SHUTDOWN|RECEIVED_SHUTDOWN)
1663 self.assertRaises(ZeroReturnError, server.recv, 1024)
1664 self.assertEquals(server.get_shutdown(), SENT_SHUTDOWN|RECEIVED_SHUTDOWN)
Jean-Paul Calderone9485f2c2010-07-29 22:38:42 -04001665
1666
Jean-Paul Calderonec89eef22010-07-29 22:51:58 -04001667 def test_set_shutdown(self):
Jean-Paul Calderone93dba222010-09-08 22:59:37 -04001668 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001669 :py:obj:`Connection.set_shutdown` sets the state of the SSL connection shutdown
Jean-Paul Calderone93dba222010-09-08 22:59:37 -04001670 process.
1671 """
Jean-Paul Calderonec89eef22010-07-29 22:51:58 -04001672 connection = Connection(Context(TLSv1_METHOD), socket())
1673 connection.set_shutdown(RECEIVED_SHUTDOWN)
1674 self.assertEquals(connection.get_shutdown(), RECEIVED_SHUTDOWN)
1675
1676
Jean-Paul Calderonef73a3cb2014-02-09 08:49:06 -05001677 if not PY3:
1678 def test_set_shutdown_long(self):
1679 """
1680 On Python 2 :py:obj:`Connection.set_shutdown` accepts an argument
1681 of type :py:obj:`long` as well as :py:obj:`int`.
1682 """
1683 connection = Connection(Context(TLSv1_METHOD), socket())
1684 connection.set_shutdown(long(RECEIVED_SHUTDOWN))
1685 self.assertEquals(connection.get_shutdown(), RECEIVED_SHUTDOWN)
1686
1687
Jean-Paul Calderonecfecc242010-07-29 22:47:06 -04001688 def test_app_data_wrong_args(self):
Jean-Paul Calderone93dba222010-09-08 22:59:37 -04001689 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001690 :py:obj:`Connection.set_app_data` raises :py:obj:`TypeError` if called with other than
1691 one argument. :py:obj:`Connection.get_app_data` raises :py:obj:`TypeError` if called
Jean-Paul Calderone93dba222010-09-08 22:59:37 -04001692 with any arguments.
1693 """
Jean-Paul Calderonecfecc242010-07-29 22:47:06 -04001694 conn = Connection(Context(TLSv1_METHOD), None)
1695 self.assertRaises(TypeError, conn.get_app_data, None)
1696 self.assertRaises(TypeError, conn.set_app_data)
1697 self.assertRaises(TypeError, conn.set_app_data, None, None)
1698
1699
Jean-Paul Calderone1bd8c792010-07-29 09:51:06 -04001700 def test_app_data(self):
Jean-Paul Calderone93dba222010-09-08 22:59:37 -04001701 """
1702 Any object can be set as app data by passing it to
Jonathan Ballet648875f2011-07-16 14:14:58 +09001703 :py:obj:`Connection.set_app_data` and later retrieved with
1704 :py:obj:`Connection.get_app_data`.
Jean-Paul Calderone93dba222010-09-08 22:59:37 -04001705 """
Jean-Paul Calderone1bd8c792010-07-29 09:51:06 -04001706 conn = Connection(Context(TLSv1_METHOD), None)
1707 app_data = object()
1708 conn.set_app_data(app_data)
1709 self.assertIdentical(conn.get_app_data(), app_data)
1710
1711
Jean-Paul Calderonecfecc242010-07-29 22:47:06 -04001712 def test_makefile(self):
Jean-Paul Calderone93dba222010-09-08 22:59:37 -04001713 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001714 :py:obj:`Connection.makefile` is not implemented and calling that method raises
1715 :py:obj:`NotImplementedError`.
Jean-Paul Calderone93dba222010-09-08 22:59:37 -04001716 """
Jean-Paul Calderonecfecc242010-07-29 22:47:06 -04001717 conn = Connection(Context(TLSv1_METHOD), None)
1718 self.assertRaises(NotImplementedError, conn.makefile)
1719
1720
Jean-Paul Calderone20222ae2011-05-19 21:43:46 -04001721 def test_get_peer_cert_chain_wrong_args(self):
1722 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001723 :py:obj:`Connection.get_peer_cert_chain` raises :py:obj:`TypeError` if called with any
Jean-Paul Calderone20222ae2011-05-19 21:43:46 -04001724 arguments.
1725 """
1726 conn = Connection(Context(TLSv1_METHOD), None)
1727 self.assertRaises(TypeError, conn.get_peer_cert_chain, 1)
1728 self.assertRaises(TypeError, conn.get_peer_cert_chain, "foo")
1729 self.assertRaises(TypeError, conn.get_peer_cert_chain, object())
1730 self.assertRaises(TypeError, conn.get_peer_cert_chain, [])
1731
1732
1733 def test_get_peer_cert_chain(self):
1734 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001735 :py:obj:`Connection.get_peer_cert_chain` returns a list of certificates which
Jean-Paul Calderone20222ae2011-05-19 21:43:46 -04001736 the connected server returned for the certification verification.
1737 """
1738 chain = _create_certificate_chain()
1739 [(cakey, cacert), (ikey, icert), (skey, scert)] = chain
1740
1741 serverContext = Context(TLSv1_METHOD)
1742 serverContext.use_privatekey(skey)
1743 serverContext.use_certificate(scert)
1744 serverContext.add_extra_chain_cert(icert)
1745 serverContext.add_extra_chain_cert(cacert)
1746 server = Connection(serverContext, None)
1747 server.set_accept_state()
1748
1749 # Create the client
1750 clientContext = Context(TLSv1_METHOD)
1751 clientContext.set_verify(VERIFY_NONE, verify_cb)
1752 client = Connection(clientContext, None)
1753 client.set_connect_state()
1754
1755 self._interactInMemory(client, server)
1756
1757 chain = client.get_peer_cert_chain()
1758 self.assertEqual(len(chain), 3)
Jean-Paul Calderonee33300c2011-05-19 21:44:38 -04001759 self.assertEqual(
Jean-Paul Calderone24a42432011-05-19 22:21:18 -04001760 "Server Certificate", chain[0].get_subject().CN)
Jean-Paul Calderonee33300c2011-05-19 21:44:38 -04001761 self.assertEqual(
Jean-Paul Calderone24a42432011-05-19 22:21:18 -04001762 "Intermediate Certificate", chain[1].get_subject().CN)
Jean-Paul Calderonee33300c2011-05-19 21:44:38 -04001763 self.assertEqual(
Jean-Paul Calderone24a42432011-05-19 22:21:18 -04001764 "Authority Certificate", chain[2].get_subject().CN)
1765
1766
1767 def test_get_peer_cert_chain_none(self):
1768 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09001769 :py:obj:`Connection.get_peer_cert_chain` returns :py:obj:`None` if the peer sends no
Jean-Paul Calderone24a42432011-05-19 22:21:18 -04001770 certificate chain.
1771 """
1772 ctx = Context(TLSv1_METHOD)
1773 ctx.use_privatekey(load_privatekey(FILETYPE_PEM, server_key_pem))
1774 ctx.use_certificate(load_certificate(FILETYPE_PEM, server_cert_pem))
1775 server = Connection(ctx, None)
1776 server.set_accept_state()
1777 client = Connection(Context(TLSv1_METHOD), None)
1778 client.set_connect_state()
1779 self._interactInMemory(client, server)
1780 self.assertIdentical(None, server.get_peer_cert_chain())
Jean-Paul Calderone20222ae2011-05-19 21:43:46 -04001781
1782
Jean-Paul Calderone64eaffc2012-02-13 11:53:49 -05001783 def test_get_session_wrong_args(self):
1784 """
1785 :py:obj:`Connection.get_session` raises :py:obj:`TypeError` if called
1786 with any arguments.
1787 """
1788 ctx = Context(TLSv1_METHOD)
1789 server = Connection(ctx, None)
1790 self.assertRaises(TypeError, server.get_session, 123)
1791 self.assertRaises(TypeError, server.get_session, "hello")
1792 self.assertRaises(TypeError, server.get_session, object())
1793
1794
1795 def test_get_session_unconnected(self):
1796 """
1797 :py:obj:`Connection.get_session` returns :py:obj:`None` when used with
1798 an object which has not been connected.
1799 """
1800 ctx = Context(TLSv1_METHOD)
1801 server = Connection(ctx, None)
1802 session = server.get_session()
1803 self.assertIdentical(None, session)
1804
1805
1806 def test_server_get_session(self):
1807 """
1808 On the server side of a connection, :py:obj:`Connection.get_session`
1809 returns a :py:class:`Session` instance representing the SSL session for
1810 that connection.
1811 """
1812 server, client = self._loopback()
1813 session = server.get_session()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001814 self.assertIsInstance(session, Session)
Jean-Paul Calderone64eaffc2012-02-13 11:53:49 -05001815
1816
1817 def test_client_get_session(self):
1818 """
1819 On the client side of a connection, :py:obj:`Connection.get_session`
1820 returns a :py:class:`Session` instance representing the SSL session for
1821 that connection.
1822 """
1823 server, client = self._loopback()
1824 session = client.get_session()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001825 self.assertIsInstance(session, Session)
Jean-Paul Calderone64eaffc2012-02-13 11:53:49 -05001826
1827
Jean-Paul Calderonefef5c4b2012-02-14 16:31:52 -05001828 def test_set_session_wrong_args(self):
1829 """
1830 If called with an object that is not an instance of :py:class:`Session`,
1831 or with other than one argument, :py:obj:`Connection.set_session` raises
1832 :py:obj:`TypeError`.
1833 """
1834 ctx = Context(TLSv1_METHOD)
1835 connection = Connection(ctx, None)
1836 self.assertRaises(TypeError, connection.set_session)
1837 self.assertRaises(TypeError, connection.set_session, 123)
1838 self.assertRaises(TypeError, connection.set_session, "hello")
1839 self.assertRaises(TypeError, connection.set_session, object())
1840 self.assertRaises(
1841 TypeError, connection.set_session, Session(), Session())
1842
1843
1844 def test_client_set_session(self):
1845 """
1846 :py:obj:`Connection.set_session`, when used prior to a connection being
1847 established, accepts a :py:class:`Session` instance and causes an
1848 attempt to re-use the session it represents when the SSL handshake is
1849 performed.
1850 """
1851 key = load_privatekey(FILETYPE_PEM, server_key_pem)
1852 cert = load_certificate(FILETYPE_PEM, server_cert_pem)
1853 ctx = Context(TLSv1_METHOD)
1854 ctx.use_privatekey(key)
1855 ctx.use_certificate(cert)
1856 ctx.set_session_id("unity-test")
1857
1858 def makeServer(socket):
1859 server = Connection(ctx, socket)
1860 server.set_accept_state()
1861 return server
1862
1863 originalServer, originalClient = self._loopback(
1864 serverFactory=makeServer)
1865 originalSession = originalClient.get_session()
1866
1867 def makeClient(socket):
1868 client = self._loopbackClientFactory(socket)
1869 client.set_session(originalSession)
1870 return client
1871 resumedServer, resumedClient = self._loopback(
1872 serverFactory=makeServer,
1873 clientFactory=makeClient)
1874
1875 # This is a proxy: in general, we have no access to any unique
1876 # identifier for the session (new enough versions of OpenSSL expose a
1877 # hash which could be usable, but "new enough" is very, very new).
1878 # Instead, exploit the fact that the master key is re-used if the
1879 # session is re-used. As long as the master key for the two connections
1880 # is the same, the session was re-used!
1881 self.assertEqual(
1882 originalServer.master_key(), resumedServer.master_key())
1883
1884
Jean-Paul Calderone5ea41492012-02-14 16:51:35 -05001885 def test_set_session_wrong_method(self):
1886 """
Jean-Paul Calderone068cb592012-02-14 16:52:43 -05001887 If :py:obj:`Connection.set_session` is passed a :py:class:`Session`
1888 instance associated with a context using a different SSL method than the
1889 :py:obj:`Connection` is using, a :py:class:`OpenSSL.SSL.Error` is
1890 raised.
Jean-Paul Calderone5ea41492012-02-14 16:51:35 -05001891 """
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 # Intentionally use a different, incompatible method here.
1910 client = Connection(Context(SSLv3_METHOD), socket)
1911 client.set_connect_state()
1912 client.set_session(originalSession)
1913 return client
1914
1915 self.assertRaises(
1916 Error,
1917 self._loopback, clientFactory=makeClient, serverFactory=makeServer)
1918
1919
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001920 def test_wantWriteError(self):
1921 """
1922 :py:obj:`Connection` methods which generate output raise
1923 :py:obj:`OpenSSL.SSL.WantWriteError` if writing to the connection's BIO
1924 fail indicating a should-write state.
1925 """
1926 client_socket, server_socket = socket_pair()
1927 # Fill up the client's send buffer so Connection won't be able to write
1928 # anything.
Jean-Paul Calderone7d7c9c22014-02-18 16:38:26 -05001929 msg = b"x" * 512
Jean-Paul Calderone22c28b42014-02-18 16:40:34 -05001930 for i in range(2048):
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07001931 try:
1932 client_socket.send(msg)
1933 except error as e:
1934 if e.errno == EWOULDBLOCK:
1935 break
1936 raise
1937 else:
1938 self.fail(
1939 "Failed to fill socket buffer, cannot test BIO want write")
1940
1941 ctx = Context(TLSv1_METHOD)
1942 conn = Connection(ctx, client_socket)
1943 # Client's speak first, so make it an SSL client
1944 conn.set_connect_state()
1945 self.assertRaises(WantWriteError, conn.do_handshake)
1946
1947 # XXX want_read
1948
Fedor Brunner416f4a12014-03-28 13:18:38 +01001949 def test_get_finished_before_connect(self):
Fedor Brunner5747b932014-03-05 14:22:34 +01001950 """
Jean-Paul Calderone5b05b482014-03-30 11:28:54 -04001951 :py:obj:`Connection.get_finished` returns :py:obj:`None` before TLS
1952 handshake is completed.
Fedor Brunner5747b932014-03-05 14:22:34 +01001953 """
Fedor Brunner5747b932014-03-05 14:22:34 +01001954 ctx = Context(TLSv1_METHOD)
1955 connection = Connection(ctx, None)
1956 self.assertEqual(connection.get_finished(), None)
Fedor Brunner416f4a12014-03-28 13:18:38 +01001957
Jean-Paul Calderone5b05b482014-03-30 11:28:54 -04001958
Fedor Brunner416f4a12014-03-28 13:18:38 +01001959 def test_get_peer_finished_before_connect(self):
1960 """
Jean-Paul Calderone5b05b482014-03-30 11:28:54 -04001961 :py:obj:`Connection.get_peer_finished` returns :py:obj:`None` before
1962 TLS handshake is completed.
Fedor Brunner416f4a12014-03-28 13:18:38 +01001963 """
Fedor Brunner416f4a12014-03-28 13:18:38 +01001964 ctx = Context(TLSv1_METHOD)
1965 connection = Connection(ctx, None)
Fedor Brunner5747b932014-03-05 14:22:34 +01001966 self.assertEqual(connection.get_peer_finished(), None)
1967
Jean-Paul Calderone5b05b482014-03-30 11:28:54 -04001968
Fedor Brunner416f4a12014-03-28 13:18:38 +01001969 def test_get_finished(self):
1970 """
1971 :py:obj:`Connection.get_finished` method returns the TLS Finished
Jean-Paul Calderone5b05b482014-03-30 11:28:54 -04001972 message send from client, or server. Finished messages are send during
1973 TLS handshake.
Fedor Brunner416f4a12014-03-28 13:18:38 +01001974 """
1975
Fedor Brunner5747b932014-03-05 14:22:34 +01001976 server, client = self._loopback()
1977
1978 self.assertNotEqual(server.get_finished(), None)
1979 self.assertTrue(len(server.get_finished()) > 0)
Fedor Brunner416f4a12014-03-28 13:18:38 +01001980
Jean-Paul Calderoned979f232014-03-30 11:58:00 -04001981
Fedor Brunner416f4a12014-03-28 13:18:38 +01001982 def test_get_peer_finished(self):
1983 """
1984 :py:obj:`Connection.get_peer_finished` method returns the TLS Finished
Jean-Paul Calderone5b05b482014-03-30 11:28:54 -04001985 message received from client, or server. Finished messages are send
1986 during TLS handshake.
Fedor Brunner416f4a12014-03-28 13:18:38 +01001987 """
Fedor Brunner416f4a12014-03-28 13:18:38 +01001988 server, client = self._loopback()
1989
1990 self.assertNotEqual(server.get_peer_finished(), None)
Fedor Brunner5747b932014-03-05 14:22:34 +01001991 self.assertTrue(len(server.get_peer_finished()) > 0)
1992
Jean-Paul Calderone5b05b482014-03-30 11:28:54 -04001993
Fedor Brunner416f4a12014-03-28 13:18:38 +01001994 def test_tls_finished_message_symmetry(self):
1995 """
Jean-Paul Calderone5b05b482014-03-30 11:28:54 -04001996 The TLS Finished message send by server must be the TLS Finished message
Fedor Brunner416f4a12014-03-28 13:18:38 +01001997 received by client.
1998
Jean-Paul Calderone5b05b482014-03-30 11:28:54 -04001999 The TLS Finished message send by client must be the TLS Finished message
Fedor Brunner416f4a12014-03-28 13:18:38 +01002000 received by server.
2001 """
Fedor Brunner416f4a12014-03-28 13:18:38 +01002002 server, client = self._loopback()
2003
Fedor Brunner5747b932014-03-05 14:22:34 +01002004 self.assertEqual(server.get_finished(), client.get_peer_finished())
2005 self.assertEqual(client.get_finished(), server.get_peer_finished())
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002006
Jean-Paul Calderone5b05b482014-03-30 11:28:54 -04002007
Fedor Brunner2cffdbc2014-03-10 10:35:23 +01002008 def test_get_cipher_name_before_connect(self):
2009 """
Jean-Paul Calderone5b05b482014-03-30 11:28:54 -04002010 :py:obj:`Connection.get_cipher_name` returns :py:obj:`None` if no
2011 connection has been established.
Fedor Brunner2cffdbc2014-03-10 10:35:23 +01002012 """
2013 ctx = Context(TLSv1_METHOD)
2014 conn = Connection(ctx, None)
Jean-Paul Calderone069e2bf2014-03-29 18:21:58 -04002015 self.assertIdentical(conn.get_cipher_name(), None)
Fedor Brunner2cffdbc2014-03-10 10:35:23 +01002016
Jean-Paul Calderonedbd76272014-03-29 18:09:40 -04002017
Fedor Brunnerd95014a2014-03-03 17:34:41 +01002018 def test_get_cipher_name(self):
2019 """
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04002020 :py:obj:`Connection.get_cipher_name` returns a :py:class:`unicode`
2021 string giving the name of the currently used cipher.
Fedor Brunnerd95014a2014-03-03 17:34:41 +01002022 """
Fedor Brunnerd95014a2014-03-03 17:34:41 +01002023 server, client = self._loopback()
2024 server_cipher_name, client_cipher_name = \
2025 server.get_cipher_name(), client.get_cipher_name()
2026
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04002027 self.assertIsInstance(server_cipher_name, text_type)
2028 self.assertIsInstance(client_cipher_name, text_type)
Fedor Brunnerd95014a2014-03-03 17:34:41 +01002029
2030 self.assertEqual(server_cipher_name, client_cipher_name)
2031
Jean-Paul Calderonedbd76272014-03-29 18:09:40 -04002032
Fedor Brunner2cffdbc2014-03-10 10:35:23 +01002033 def test_get_cipher_version_before_connect(self):
2034 """
Jean-Paul Calderone5b05b482014-03-30 11:28:54 -04002035 :py:obj:`Connection.get_cipher_version` returns :py:obj:`None` if no
2036 connection has been established.
Fedor Brunner2cffdbc2014-03-10 10:35:23 +01002037 """
2038 ctx = Context(TLSv1_METHOD)
2039 conn = Connection(ctx, None)
Jean-Paul Calderone069e2bf2014-03-29 18:21:58 -04002040 self.assertIdentical(conn.get_cipher_version(), None)
Fedor Brunner2cffdbc2014-03-10 10:35:23 +01002041
Jean-Paul Calderonedbd76272014-03-29 18:09:40 -04002042
Fedor Brunnerd95014a2014-03-03 17:34:41 +01002043 def test_get_cipher_version(self):
2044 """
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04002045 :py:obj:`Connection.get_cipher_version` returns a :py:class:`unicode`
2046 string giving the protocol name of the currently used cipher.
Fedor Brunnerd95014a2014-03-03 17:34:41 +01002047 """
Fedor Brunnerd95014a2014-03-03 17:34:41 +01002048 server, client = self._loopback()
2049 server_cipher_version, client_cipher_version = \
2050 server.get_cipher_version(), client.get_cipher_version()
2051
Jean-Paul Calderone7f0ded42014-03-30 10:34:17 -04002052 self.assertIsInstance(server_cipher_version, text_type)
2053 self.assertIsInstance(client_cipher_version, text_type)
Fedor Brunnerd95014a2014-03-03 17:34:41 +01002054
2055 self.assertEqual(server_cipher_version, client_cipher_version)
2056
Jean-Paul Calderonedbd76272014-03-29 18:09:40 -04002057
Fedor Brunner2cffdbc2014-03-10 10:35:23 +01002058 def test_get_cipher_bits_before_connect(self):
2059 """
Jean-Paul Calderone5b05b482014-03-30 11:28:54 -04002060 :py:obj:`Connection.get_cipher_bits` returns :py:obj:`None` if no
2061 connection has been established.
Fedor Brunner2cffdbc2014-03-10 10:35:23 +01002062 """
2063 ctx = Context(TLSv1_METHOD)
2064 conn = Connection(ctx, None)
Jean-Paul Calderone069e2bf2014-03-29 18:21:58 -04002065 self.assertIdentical(conn.get_cipher_bits(), None)
Fedor Brunner2cffdbc2014-03-10 10:35:23 +01002066
Jean-Paul Calderonedbd76272014-03-29 18:09:40 -04002067
Fedor Brunnerd95014a2014-03-03 17:34:41 +01002068 def test_get_cipher_bits(self):
2069 """
Jean-Paul Calderone5b05b482014-03-30 11:28:54 -04002070 :py:obj:`Connection.get_cipher_bits` returns the number of secret bits
2071 of the currently used cipher.
Fedor Brunnerd95014a2014-03-03 17:34:41 +01002072 """
Fedor Brunnerd95014a2014-03-03 17:34:41 +01002073 server, client = self._loopback()
2074 server_cipher_bits, client_cipher_bits = \
2075 server.get_cipher_bits(), client.get_cipher_bits()
2076
Fedor Brunner2cffdbc2014-03-10 10:35:23 +01002077 self.assertIsInstance(server_cipher_bits, int)
2078 self.assertIsInstance(client_cipher_bits, int)
Fedor Brunnerd95014a2014-03-03 17:34:41 +01002079
2080 self.assertEqual(server_cipher_bits, client_cipher_bits)
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002081
Jean-Paul Calderone9cbbe262011-01-05 14:53:43 -05002082
2083
2084class ConnectionGetCipherListTests(TestCase):
2085 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002086 Tests for :py:obj:`Connection.get_cipher_list`.
Jean-Paul Calderone9cbbe262011-01-05 14:53:43 -05002087 """
2088 def test_wrong_args(self):
Jean-Paul Calderone77fa2602011-01-05 18:23:39 -05002089 """
2090 :py:obj:`Connection.get_cipher_list` raises :py:obj:`TypeError` if called with any
2091 arguments.
Jean-Paul Calderone9cbbe262011-01-05 14:53:43 -05002092 """
2093 connection = Connection(Context(TLSv1_METHOD), None)
2094 self.assertRaises(TypeError, connection.get_cipher_list, None)
2095
Jonathan Ballet648875f2011-07-16 14:14:58 +09002096
Jean-Paul Calderone9cbbe262011-01-05 14:53:43 -05002097 def test_result(self):
2098 """
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002099 :py:obj:`Connection.get_cipher_list` returns a :py:obj:`list` of
2100 :py:obj:`bytes` giving the names of the ciphers which might be used.
Jean-Paul Calderonea8fb0c82010-09-09 18:04:56 -04002101 """
Jean-Paul Calderonef135e622010-07-28 19:14:16 -04002102 connection = Connection(Context(TLSv1_METHOD), None)
2103 ciphers = connection.get_cipher_list()
2104 self.assertTrue(isinstance(ciphers, list))
2105 for cipher in ciphers:
2106 self.assertTrue(isinstance(cipher, str))
2107
2108
2109
Jean-Paul Calderone9cbbe262011-01-05 14:53:43 -05002110class ConnectionSendTests(TestCase, _LoopbackMixin):
2111 """
2112 Tests for :py:obj:`Connection.send`
2113 """
2114 def test_wrong_args(self):
2115 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -05002116 When called with arguments other than string argument for its first
2117 parameter or more than two arguments, :py:obj:`Connection.send` raises
2118 :py:obj:`TypeError`.
Jean-Paul Calderone9cbbe262011-01-05 14:53:43 -05002119 """
2120 connection = Connection(Context(TLSv1_METHOD), None)
2121 self.assertRaises(TypeError, connection.send)
2122 self.assertRaises(TypeError, connection.send, object())
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -05002123 self.assertRaises(TypeError, connection.send, "foo", object(), "bar")
Jean-Paul Calderone9cbbe262011-01-05 14:53:43 -05002124
2125
2126 def test_short_bytes(self):
2127 """
2128 When passed a short byte string, :py:obj:`Connection.send` transmits all of it
2129 and returns the number of bytes sent.
2130 """
2131 server, client = self._loopback()
2132 count = server.send(b('xy'))
2133 self.assertEquals(count, 2)
2134 self.assertEquals(client.recv(2), b('xy'))
2135
2136 try:
2137 memoryview
2138 except NameError:
2139 "cannot test sending memoryview without memoryview"
2140 else:
2141 def test_short_memoryview(self):
2142 """
2143 When passed a memoryview onto a small number of bytes,
Jonathan Ballet648875f2011-07-16 14:14:58 +09002144 :py:obj:`Connection.send` transmits all of them and returns the number of
Jean-Paul Calderone9cbbe262011-01-05 14:53:43 -05002145 bytes sent.
2146 """
2147 server, client = self._loopback()
2148 count = server.send(memoryview(b('xy')))
2149 self.assertEquals(count, 2)
2150 self.assertEquals(client.recv(2), b('xy'))
2151
2152
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02002153 try:
2154 buffer
2155 except NameError:
2156 "cannot test sending buffer without buffer"
2157 else:
2158 def test_short_buffer(self):
2159 """
2160 When passed a buffer containing a small number of bytes,
2161 :py:obj:`Connection.send` transmits all of them and returns the number of
2162 bytes sent.
2163 """
2164 server, client = self._loopback()
2165 count = server.send(buffer(b('xy')))
2166 self.assertEquals(count, 2)
2167 self.assertEquals(client.recv(2), b('xy'))
2168
2169
Jean-Paul Calderone691e6c92011-01-21 22:04:35 -05002170
Jean-Paul Calderone8ea22522010-07-29 09:39:39 -04002171class ConnectionSendallTests(TestCase, _LoopbackMixin):
2172 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002173 Tests for :py:obj:`Connection.sendall`.
Jean-Paul Calderone8ea22522010-07-29 09:39:39 -04002174 """
Jean-Paul Calderonea8fb0c82010-09-09 18:04:56 -04002175 def test_wrong_args(self):
Jean-Paul Calderone8ea22522010-07-29 09:39:39 -04002176 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -05002177 When called with arguments other than a string argument for its first
2178 parameter or with more than two arguments, :py:obj:`Connection.sendall`
2179 raises :py:obj:`TypeError`.
Jean-Paul Calderone8ea22522010-07-29 09:39:39 -04002180 """
2181 connection = Connection(Context(TLSv1_METHOD), None)
2182 self.assertRaises(TypeError, connection.sendall)
2183 self.assertRaises(TypeError, connection.sendall, object())
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -05002184 self.assertRaises(
2185 TypeError, connection.sendall, "foo", object(), "bar")
Jean-Paul Calderone8ea22522010-07-29 09:39:39 -04002186
2187
Jean-Paul Calderone7ca48b52010-07-28 18:57:21 -04002188 def test_short(self):
2189 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002190 :py:obj:`Connection.sendall` transmits all of the bytes in the string passed to
Jean-Paul Calderone7ca48b52010-07-28 18:57:21 -04002191 it.
2192 """
2193 server, client = self._loopback()
Jean-Paul Calderonea9868832010-08-22 21:38:34 -04002194 server.sendall(b('x'))
2195 self.assertEquals(client.recv(1), b('x'))
Jean-Paul Calderone7ca48b52010-07-28 18:57:21 -04002196
2197
Jean-Paul Calderone691e6c92011-01-21 22:04:35 -05002198 try:
2199 memoryview
2200 except NameError:
2201 "cannot test sending memoryview without memoryview"
2202 else:
2203 def test_short_memoryview(self):
2204 """
2205 When passed a memoryview onto a small number of bytes,
Jonathan Ballet648875f2011-07-16 14:14:58 +09002206 :py:obj:`Connection.sendall` transmits all of them.
Jean-Paul Calderone691e6c92011-01-21 22:04:35 -05002207 """
2208 server, client = self._loopback()
2209 server.sendall(memoryview(b('x')))
2210 self.assertEquals(client.recv(1), b('x'))
2211
2212
Markus Unterwaditzer8e41d022014-04-19 12:27:11 +02002213 try:
2214 buffer
2215 except NameError:
2216 "cannot test sending buffers without buffers"
2217 else:
2218 def test_short_buffers(self):
2219 """
2220 When passed a buffer containing a small number of bytes,
2221 :py:obj:`Connection.sendall` transmits all of them.
2222 """
2223 server, client = self._loopback()
2224 server.sendall(buffer(b('x')))
2225 self.assertEquals(client.recv(1), b('x'))
2226
2227
Jean-Paul Calderone7ca48b52010-07-28 18:57:21 -04002228 def test_long(self):
Jean-Paul Calderonea8fb0c82010-09-09 18:04:56 -04002229 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002230 :py:obj:`Connection.sendall` transmits all of the bytes in the string passed to
Jean-Paul Calderonea8fb0c82010-09-09 18:04:56 -04002231 it even if this requires multiple calls of an underlying write function.
2232 """
Jean-Paul Calderone7ca48b52010-07-28 18:57:21 -04002233 server, client = self._loopback()
Jean-Paul Calderone6241c702010-09-16 19:59:24 -04002234 # Should be enough, underlying SSL_write should only do 16k at a time.
2235 # On Windows, after 32k of bytes the write will block (forever - because
2236 # no one is yet reading).
Jean-Paul Calderone9e4c1352010-09-19 09:34:43 -04002237 message = b('x') * (1024 * 32 - 1) + b('y')
Jean-Paul Calderone7ca48b52010-07-28 18:57:21 -04002238 server.sendall(message)
2239 accum = []
2240 received = 0
2241 while received < len(message):
Jean-Paul Calderoneb1f7f5f2010-08-22 21:40:52 -04002242 data = client.recv(1024)
2243 accum.append(data)
2244 received += len(data)
Jean-Paul Calderonef4047852010-09-19 09:45:57 -04002245 self.assertEquals(message, b('').join(accum))
Jean-Paul Calderone7ca48b52010-07-28 18:57:21 -04002246
2247
Jean-Paul Calderone974bdc02010-07-28 19:06:10 -04002248 def test_closed(self):
2249 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002250 If the underlying socket is closed, :py:obj:`Connection.sendall` propagates the
Jean-Paul Calderone974bdc02010-07-28 19:06:10 -04002251 write error from the low level write call.
2252 """
2253 server, client = self._loopback()
Jean-Paul Calderone05d43e82010-09-24 18:01:36 -04002254 server.sock_shutdown(2)
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002255 exc = self.assertRaises(SysCallError, server.sendall, b"hello, world")
Konstantinos Koukopoulos541150d2014-01-31 01:00:19 +02002256 if platform == "win32":
2257 self.assertEqual(exc.args[0], ESHUTDOWN)
2258 else:
2259 self.assertEqual(exc.args[0], EPIPE)
Jean-Paul Calderone974bdc02010-07-28 19:06:10 -04002260
Jean-Paul Calderone7ca48b52010-07-28 18:57:21 -04002261
Jean-Paul Calderone1d69a722010-07-29 09:05:53 -04002262
Jean-Paul Calderone8ea22522010-07-29 09:39:39 -04002263class ConnectionRenegotiateTests(TestCase, _LoopbackMixin):
2264 """
2265 Tests for SSL renegotiation APIs.
2266 """
2267 def test_renegotiate_wrong_args(self):
Jean-Paul Calderonea8fb0c82010-09-09 18:04:56 -04002268 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002269 :py:obj:`Connection.renegotiate` raises :py:obj:`TypeError` if called with any
Jean-Paul Calderonea8fb0c82010-09-09 18:04:56 -04002270 arguments.
2271 """
Jean-Paul Calderone8ea22522010-07-29 09:39:39 -04002272 connection = Connection(Context(TLSv1_METHOD), None)
2273 self.assertRaises(TypeError, connection.renegotiate, None)
2274
2275
Jean-Paul Calderonecfecc242010-07-29 22:47:06 -04002276 def test_total_renegotiations_wrong_args(self):
Jean-Paul Calderonea8fb0c82010-09-09 18:04:56 -04002277 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002278 :py:obj:`Connection.total_renegotiations` raises :py:obj:`TypeError` if called with
Jean-Paul Calderonea8fb0c82010-09-09 18:04:56 -04002279 any arguments.
2280 """
Jean-Paul Calderonecfecc242010-07-29 22:47:06 -04002281 connection = Connection(Context(TLSv1_METHOD), None)
2282 self.assertRaises(TypeError, connection.total_renegotiations, None)
2283
2284
2285 def test_total_renegotiations(self):
Jean-Paul Calderonea8fb0c82010-09-09 18:04:56 -04002286 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002287 :py:obj:`Connection.total_renegotiations` returns :py:obj:`0` before any
Jean-Paul Calderonea8fb0c82010-09-09 18:04:56 -04002288 renegotiations have happened.
2289 """
Jean-Paul Calderonecfecc242010-07-29 22:47:06 -04002290 connection = Connection(Context(TLSv1_METHOD), None)
2291 self.assertEquals(connection.total_renegotiations(), 0)
2292
2293
Jean-Paul Calderone8ea22522010-07-29 09:39:39 -04002294# def test_renegotiate(self):
2295# """
2296# """
2297# server, client = self._loopback()
2298
2299# server.send("hello world")
2300# self.assertEquals(client.recv(len("hello world")), "hello world")
2301
2302# self.assertEquals(server.total_renegotiations(), 0)
2303# self.assertTrue(server.renegotiate())
2304
2305# server.setblocking(False)
2306# client.setblocking(False)
2307# while server.renegotiate_pending():
2308# client.do_handshake()
2309# server.do_handshake()
2310
2311# self.assertEquals(server.total_renegotiations(), 1)
2312
2313
2314
2315
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002316class ErrorTests(TestCase):
2317 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002318 Unit tests for :py:obj:`OpenSSL.SSL.Error`.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002319 """
2320 def test_type(self):
2321 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002322 :py:obj:`Error` is an exception type.
Jean-Paul Calderone68649052009-07-17 21:14:27 -04002323 """
2324 self.assertTrue(issubclass(Error, Exception))
Rick Deane15b1472009-07-09 15:53:42 -05002325 self.assertEqual(Error.__name__, 'Error')
Rick Deane15b1472009-07-09 15:53:42 -05002326
2327
2328
Jean-Paul Calderone327d8f92008-12-28 21:55:56 -05002329class ConstantsTests(TestCase):
2330 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002331 Tests for the values of constants exposed in :py:obj:`OpenSSL.SSL`.
Jean-Paul Calderone327d8f92008-12-28 21:55:56 -05002332
2333 These are values defined by OpenSSL intended only to be used as flags to
2334 OpenSSL APIs. The only assertions it seems can be made about them is
2335 their values.
2336 """
Jean-Paul Calderoned811b682008-12-28 22:59:15 -05002337 # unittest.TestCase has no skip mechanism
2338 if OP_NO_QUERY_MTU is not None:
2339 def test_op_no_query_mtu(self):
2340 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002341 The value of :py:obj:`OpenSSL.SSL.OP_NO_QUERY_MTU` is 0x1000, the value of
Jean-Paul Calderone64efa2c2011-09-11 10:00:09 -04002342 :py:const:`SSL_OP_NO_QUERY_MTU` defined by :file:`openssl/ssl.h`.
Jean-Paul Calderoned811b682008-12-28 22:59:15 -05002343 """
2344 self.assertEqual(OP_NO_QUERY_MTU, 0x1000)
2345 else:
2346 "OP_NO_QUERY_MTU unavailable - OpenSSL version may be too old"
Jean-Paul Calderone327d8f92008-12-28 21:55:56 -05002347
2348
Jean-Paul Calderoned811b682008-12-28 22:59:15 -05002349 if OP_COOKIE_EXCHANGE is not None:
2350 def test_op_cookie_exchange(self):
2351 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002352 The value of :py:obj:`OpenSSL.SSL.OP_COOKIE_EXCHANGE` is 0x2000, the value
Jean-Paul Calderone64efa2c2011-09-11 10:00:09 -04002353 of :py:const:`SSL_OP_COOKIE_EXCHANGE` defined by :file:`openssl/ssl.h`.
Jean-Paul Calderoned811b682008-12-28 22:59:15 -05002354 """
2355 self.assertEqual(OP_COOKIE_EXCHANGE, 0x2000)
2356 else:
2357 "OP_COOKIE_EXCHANGE unavailable - OpenSSL version may be too old"
Jean-Paul Calderone327d8f92008-12-28 21:55:56 -05002358
2359
Jean-Paul Calderoned811b682008-12-28 22:59:15 -05002360 if OP_NO_TICKET is not None:
2361 def test_op_no_ticket(self):
2362 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002363 The value of :py:obj:`OpenSSL.SSL.OP_NO_TICKET` is 0x4000, the value of
Jean-Paul Calderone64efa2c2011-09-11 10:00:09 -04002364 :py:const:`SSL_OP_NO_TICKET` defined by :file:`openssl/ssl.h`.
Jean-Paul Calderoned811b682008-12-28 22:59:15 -05002365 """
2366 self.assertEqual(OP_NO_TICKET, 0x4000)
Jean-Paul Calderonecebd1782011-09-11 10:01:31 -04002367 else:
Jean-Paul Calderoned811b682008-12-28 22:59:15 -05002368 "OP_NO_TICKET unavailable - OpenSSL version may be too old"
Rick Dean5b7b6372009-04-01 11:34:06 -05002369
2370
Jean-Paul Calderonec62d4c12011-09-08 18:29:32 -04002371 if OP_NO_COMPRESSION is not None:
2372 def test_op_no_compression(self):
2373 """
Jean-Paul Calderone64efa2c2011-09-11 10:00:09 -04002374 The value of :py:obj:`OpenSSL.SSL.OP_NO_COMPRESSION` is 0x20000, the value
2375 of :py:const:`SSL_OP_NO_COMPRESSION` defined by :file:`openssl/ssl.h`.
Jean-Paul Calderonec62d4c12011-09-08 18:29:32 -04002376 """
2377 self.assertEqual(OP_NO_COMPRESSION, 0x20000)
2378 else:
2379 "OP_NO_COMPRESSION unavailable - OpenSSL version may be too old"
2380
2381
Jean-Paul Calderone313bf012012-02-08 13:02:49 -05002382 def test_sess_cache_off(self):
2383 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -05002384 The value of :py:obj:`OpenSSL.SSL.SESS_CACHE_OFF` 0x0, the value of
2385 :py:obj:`SSL_SESS_CACHE_OFF` defined by ``openssl/ssl.h``.
Jean-Paul Calderone313bf012012-02-08 13:02:49 -05002386 """
2387 self.assertEqual(0x0, SESS_CACHE_OFF)
2388
2389
2390 def test_sess_cache_client(self):
2391 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -05002392 The value of :py:obj:`OpenSSL.SSL.SESS_CACHE_CLIENT` 0x1, the value of
2393 :py:obj:`SSL_SESS_CACHE_CLIENT` defined by ``openssl/ssl.h``.
Jean-Paul Calderone313bf012012-02-08 13:02:49 -05002394 """
2395 self.assertEqual(0x1, SESS_CACHE_CLIENT)
2396
2397
2398 def test_sess_cache_server(self):
2399 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -05002400 The value of :py:obj:`OpenSSL.SSL.SESS_CACHE_SERVER` 0x2, the value of
2401 :py:obj:`SSL_SESS_CACHE_SERVER` defined by ``openssl/ssl.h``.
Jean-Paul Calderone313bf012012-02-08 13:02:49 -05002402 """
2403 self.assertEqual(0x2, SESS_CACHE_SERVER)
2404
2405
2406 def test_sess_cache_both(self):
2407 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -05002408 The value of :py:obj:`OpenSSL.SSL.SESS_CACHE_BOTH` 0x3, the value of
2409 :py:obj:`SSL_SESS_CACHE_BOTH` defined by ``openssl/ssl.h``.
Jean-Paul Calderone313bf012012-02-08 13:02:49 -05002410 """
2411 self.assertEqual(0x3, SESS_CACHE_BOTH)
2412
2413
2414 def test_sess_cache_no_auto_clear(self):
2415 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -05002416 The value of :py:obj:`OpenSSL.SSL.SESS_CACHE_NO_AUTO_CLEAR` 0x80, the
2417 value of :py:obj:`SSL_SESS_CACHE_NO_AUTO_CLEAR` defined by
2418 ``openssl/ssl.h``.
Jean-Paul Calderone313bf012012-02-08 13:02:49 -05002419 """
2420 self.assertEqual(0x80, SESS_CACHE_NO_AUTO_CLEAR)
2421
2422
2423 def test_sess_cache_no_internal_lookup(self):
2424 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -05002425 The value of :py:obj:`OpenSSL.SSL.SESS_CACHE_NO_INTERNAL_LOOKUP` 0x100,
2426 the value of :py:obj:`SSL_SESS_CACHE_NO_INTERNAL_LOOKUP` defined by
2427 ``openssl/ssl.h``.
Jean-Paul Calderone313bf012012-02-08 13:02:49 -05002428 """
2429 self.assertEqual(0x100, SESS_CACHE_NO_INTERNAL_LOOKUP)
2430
2431
2432 def test_sess_cache_no_internal_store(self):
2433 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -05002434 The value of :py:obj:`OpenSSL.SSL.SESS_CACHE_NO_INTERNAL_STORE` 0x200,
2435 the value of :py:obj:`SSL_SESS_CACHE_NO_INTERNAL_STORE` defined by
2436 ``openssl/ssl.h``.
Jean-Paul Calderone313bf012012-02-08 13:02:49 -05002437 """
2438 self.assertEqual(0x200, SESS_CACHE_NO_INTERNAL_STORE)
2439
2440
2441 def test_sess_cache_no_internal(self):
2442 """
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -05002443 The value of :py:obj:`OpenSSL.SSL.SESS_CACHE_NO_INTERNAL` 0x300, the
2444 value of :py:obj:`SSL_SESS_CACHE_NO_INTERNAL` defined by
2445 ``openssl/ssl.h``.
Jean-Paul Calderone313bf012012-02-08 13:02:49 -05002446 """
2447 self.assertEqual(0x300, SESS_CACHE_NO_INTERNAL)
2448
2449
Jean-Paul Calderoneeeee26a2009-04-27 11:24:30 -04002450
Jean-Paul Calderonebf37f0f2010-07-31 14:56:20 -04002451class MemoryBIOTests(TestCase, _LoopbackMixin):
Rick Deanb71c0d22009-04-01 14:09:23 -05002452 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002453 Tests for :py:obj:`OpenSSL.SSL.Connection` using a memory BIO.
Rick Deanb71c0d22009-04-01 14:09:23 -05002454 """
Jean-Paul Calderonece8324d2009-07-16 12:22:52 -04002455 def _server(self, sock):
2456 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002457 Create a new server-side SSL :py:obj:`Connection` object wrapped around
2458 :py:obj:`sock`.
Jean-Paul Calderonece8324d2009-07-16 12:22:52 -04002459 """
Jean-Paul Calderoneaff0fc42009-04-27 17:13:34 -04002460 # Create the server side Connection. This is mostly setup boilerplate
2461 # - use TLSv1, use a particular certificate, etc.
2462 server_ctx = Context(TLSv1_METHOD)
2463 server_ctx.set_options(OP_NO_SSLv2 | OP_NO_SSLv3 | OP_SINGLE_DH_USE )
2464 server_ctx.set_verify(VERIFY_PEER|VERIFY_FAIL_IF_NO_PEER_CERT|VERIFY_CLIENT_ONCE, verify_cb)
2465 server_store = server_ctx.get_cert_store()
2466 server_ctx.use_privatekey(load_privatekey(FILETYPE_PEM, server_key_pem))
2467 server_ctx.use_certificate(load_certificate(FILETYPE_PEM, server_cert_pem))
2468 server_ctx.check_privatekey()
2469 server_store.add_cert(load_certificate(FILETYPE_PEM, root_cert_pem))
Rick Deanb1ccd562009-07-09 23:52:39 -05002470 # Here the Connection is actually created. If None is passed as the 2nd
2471 # parameter, it indicates a memory BIO should be created.
2472 server_conn = Connection(server_ctx, sock)
Jean-Paul Calderoneaff0fc42009-04-27 17:13:34 -04002473 server_conn.set_accept_state()
2474 return server_conn
2475
2476
Jean-Paul Calderonece8324d2009-07-16 12:22:52 -04002477 def _client(self, sock):
2478 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002479 Create a new client-side SSL :py:obj:`Connection` object wrapped around
2480 :py:obj:`sock`.
Jean-Paul Calderonece8324d2009-07-16 12:22:52 -04002481 """
2482 # Now create the client side Connection. Similar boilerplate to the
2483 # above.
Jean-Paul Calderoneaff0fc42009-04-27 17:13:34 -04002484 client_ctx = Context(TLSv1_METHOD)
2485 client_ctx.set_options(OP_NO_SSLv2 | OP_NO_SSLv3 | OP_SINGLE_DH_USE )
2486 client_ctx.set_verify(VERIFY_PEER|VERIFY_FAIL_IF_NO_PEER_CERT|VERIFY_CLIENT_ONCE, verify_cb)
2487 client_store = client_ctx.get_cert_store()
2488 client_ctx.use_privatekey(load_privatekey(FILETYPE_PEM, client_key_pem))
2489 client_ctx.use_certificate(load_certificate(FILETYPE_PEM, client_cert_pem))
2490 client_ctx.check_privatekey()
2491 client_store.add_cert(load_certificate(FILETYPE_PEM, root_cert_pem))
Rick Deanb1ccd562009-07-09 23:52:39 -05002492 client_conn = Connection(client_ctx, sock)
Jean-Paul Calderoneaff0fc42009-04-27 17:13:34 -04002493 client_conn.set_connect_state()
2494 return client_conn
2495
2496
Jean-Paul Calderonece8324d2009-07-16 12:22:52 -04002497 def test_memoryConnect(self):
Jean-Paul Calderone958299e2009-04-27 12:59:12 -04002498 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002499 Two :py:obj:`Connection`s which use memory BIOs can be manually connected by
Jean-Paul Calderone958299e2009-04-27 12:59:12 -04002500 reading from the output of each and writing those bytes to the input of
2501 the other and in this way establish a connection and exchange
2502 application-level bytes with each other.
2503 """
Jean-Paul Calderonece8324d2009-07-16 12:22:52 -04002504 server_conn = self._server(None)
2505 client_conn = self._client(None)
Rick Deanb71c0d22009-04-01 14:09:23 -05002506
Jean-Paul Calderone958299e2009-04-27 12:59:12 -04002507 # There should be no key or nonces yet.
2508 self.assertIdentical(server_conn.master_key(), None)
2509 self.assertIdentical(server_conn.client_random(), None)
2510 self.assertIdentical(server_conn.server_random(), None)
Rick Deanb71c0d22009-04-01 14:09:23 -05002511
Jean-Paul Calderone958299e2009-04-27 12:59:12 -04002512 # First, the handshake needs to happen. We'll deliver bytes back and
2513 # forth between the client and server until neither of them feels like
2514 # speaking any more.
Jean-Paul Calderonebf37f0f2010-07-31 14:56:20 -04002515 self.assertIdentical(
2516 self._interactInMemory(client_conn, server_conn), None)
Jean-Paul Calderone958299e2009-04-27 12:59:12 -04002517
2518 # Now that the handshake is done, there should be a key and nonces.
2519 self.assertNotIdentical(server_conn.master_key(), None)
2520 self.assertNotIdentical(server_conn.client_random(), None)
2521 self.assertNotIdentical(server_conn.server_random(), None)
Jean-Paul Calderone6c051e62009-07-05 13:50:34 -04002522 self.assertEquals(server_conn.client_random(), client_conn.client_random())
2523 self.assertEquals(server_conn.server_random(), client_conn.server_random())
2524 self.assertNotEquals(server_conn.client_random(), server_conn.server_random())
2525 self.assertNotEquals(client_conn.client_random(), client_conn.server_random())
Jean-Paul Calderone958299e2009-04-27 12:59:12 -04002526
2527 # Here are the bytes we'll try to send.
Jean-Paul Calderonea441fdc2010-08-22 21:33:57 -04002528 important_message = b('One if by land, two if by sea.')
Rick Deanb71c0d22009-04-01 14:09:23 -05002529
Jean-Paul Calderone958299e2009-04-27 12:59:12 -04002530 server_conn.write(important_message)
2531 self.assertEquals(
Jean-Paul Calderonebf37f0f2010-07-31 14:56:20 -04002532 self._interactInMemory(client_conn, server_conn),
Jean-Paul Calderone958299e2009-04-27 12:59:12 -04002533 (client_conn, important_message))
2534
2535 client_conn.write(important_message[::-1])
2536 self.assertEquals(
Jean-Paul Calderonebf37f0f2010-07-31 14:56:20 -04002537 self._interactInMemory(client_conn, server_conn),
Jean-Paul Calderone958299e2009-04-27 12:59:12 -04002538 (server_conn, important_message[::-1]))
Rick Deanb71c0d22009-04-01 14:09:23 -05002539
2540
Jean-Paul Calderonece8324d2009-07-16 12:22:52 -04002541 def test_socketConnect(self):
Rick Deanb1ccd562009-07-09 23:52:39 -05002542 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002543 Just like :py:obj:`test_memoryConnect` but with an actual socket.
Jean-Paul Calderonece8324d2009-07-16 12:22:52 -04002544
2545 This is primarily to rule out the memory BIO code as the source of
Jonathan Ballet648875f2011-07-16 14:14:58 +09002546 any problems encountered while passing data over a :py:obj:`Connection` (if
Jean-Paul Calderonece8324d2009-07-16 12:22:52 -04002547 this test fails, there must be a problem outside the memory BIO
2548 code, as no memory BIO is involved here). Even though this isn't a
2549 memory BIO test, it's convenient to have it here.
Rick Deanb1ccd562009-07-09 23:52:39 -05002550 """
Jean-Paul Calderone06c7cc92010-09-24 23:52:00 -04002551 server_conn, client_conn = self._loopback()
Rick Deanb1ccd562009-07-09 23:52:39 -05002552
Jean-Paul Calderonea441fdc2010-08-22 21:33:57 -04002553 important_message = b("Help me Obi Wan Kenobi, you're my only hope.")
Rick Deanb1ccd562009-07-09 23:52:39 -05002554 client_conn.send(important_message)
2555 msg = server_conn.recv(1024)
2556 self.assertEqual(msg, important_message)
2557
2558 # Again in the other direction, just for fun.
2559 important_message = important_message[::-1]
2560 server_conn.send(important_message)
2561 msg = client_conn.recv(1024)
2562 self.assertEqual(msg, important_message)
2563
2564
Jean-Paul Calderonefc4ed0f2009-04-27 11:51:27 -04002565 def test_socketOverridesMemory(self):
Rick Deanb71c0d22009-04-01 14:09:23 -05002566 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002567 Test that :py:obj:`OpenSSL.SSL.bio_read` and :py:obj:`OpenSSL.SSL.bio_write` don't
2568 work on :py:obj:`OpenSSL.SSL.Connection`() that use sockets.
Rick Deanb71c0d22009-04-01 14:09:23 -05002569 """
2570 context = Context(SSLv3_METHOD)
2571 client = socket()
2572 clientSSL = Connection(context, client)
2573 self.assertRaises( TypeError, clientSSL.bio_read, 100)
2574 self.assertRaises( TypeError, clientSSL.bio_write, "foo")
Jean-Paul Calderone07acf3f2009-05-05 13:23:28 -04002575 self.assertRaises( TypeError, clientSSL.bio_shutdown )
Jean-Paul Calderoneaff0fc42009-04-27 17:13:34 -04002576
2577
2578 def test_outgoingOverflow(self):
2579 """
2580 If more bytes than can be written to the memory BIO are passed to
Jonathan Ballet648875f2011-07-16 14:14:58 +09002581 :py:obj:`Connection.send` at once, the number of bytes which were written is
Jean-Paul Calderoneaff0fc42009-04-27 17:13:34 -04002582 returned and that many bytes from the beginning of the input can be
2583 read from the other end of the connection.
2584 """
Jean-Paul Calderonece8324d2009-07-16 12:22:52 -04002585 server = self._server(None)
2586 client = self._client(None)
Jean-Paul Calderoneaff0fc42009-04-27 17:13:34 -04002587
Jean-Paul Calderonebf37f0f2010-07-31 14:56:20 -04002588 self._interactInMemory(client, server)
Jean-Paul Calderoneaff0fc42009-04-27 17:13:34 -04002589
2590 size = 2 ** 15
Jean-Paul Calderone4f0467a2014-01-11 11:58:41 -05002591 sent = client.send(b"x" * size)
Jean-Paul Calderoneaff0fc42009-04-27 17:13:34 -04002592 # Sanity check. We're trying to test what happens when the entire
2593 # input can't be sent. If the entire input was sent, this test is
2594 # meaningless.
2595 self.assertTrue(sent < size)
2596
Jean-Paul Calderonebf37f0f2010-07-31 14:56:20 -04002597 receiver, received = self._interactInMemory(client, server)
Jean-Paul Calderoneaff0fc42009-04-27 17:13:34 -04002598 self.assertIdentical(receiver, server)
2599
2600 # We can rely on all of these bytes being received at once because
2601 # _loopback passes 2 ** 16 to recv - more than 2 ** 15.
2602 self.assertEquals(len(received), sent)
Jean-Paul Calderone3ad85d42009-04-30 20:24:35 -04002603
2604
2605 def test_shutdown(self):
2606 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002607 :py:obj:`Connection.bio_shutdown` signals the end of the data stream from
2608 which the :py:obj:`Connection` reads.
Jean-Paul Calderone3ad85d42009-04-30 20:24:35 -04002609 """
Jean-Paul Calderonece8324d2009-07-16 12:22:52 -04002610 server = self._server(None)
Jean-Paul Calderone3ad85d42009-04-30 20:24:35 -04002611 server.bio_shutdown()
2612 e = self.assertRaises(Error, server.recv, 1024)
2613 # We don't want WantReadError or ZeroReturnError or anything - it's a
2614 # handshake failure.
2615 self.assertEquals(e.__class__, Error)
Jean-Paul Calderone0b88b6a2009-07-05 12:44:41 -04002616
2617
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07002618 def test_unexpectedEndOfFile(self):
2619 """
2620 If the connection is lost before an orderly SSL shutdown occurs,
2621 :py:obj:`OpenSSL.SSL.SysCallError` is raised with a message of
2622 "Unexpected EOF".
2623 """
2624 server_conn, client_conn = self._loopback()
2625 client_conn.sock_shutdown(SHUT_RDWR)
2626 exc = self.assertRaises(SysCallError, server_conn.recv, 1024)
2627 self.assertEqual(exc.args, (-1, "Unexpected EOF"))
2628
2629
Ziga Seilnachtf93bf102009-10-23 09:51:07 +02002630 def _check_client_ca_list(self, func):
Jean-Paul Calderone911c9112009-10-24 11:12:00 -04002631 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002632 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 -04002633
Jonathan Ballet78b92a22011-07-16 08:07:26 +09002634 :param func: A function which will be called with the server context
Jean-Paul Calderone911c9112009-10-24 11:12:00 -04002635 before the client and server are connected to each other. This
2636 function should specify a list of CAs for the server to send to the
2637 client and return that same list. The list will be used to verify
Jonathan Ballet648875f2011-07-16 14:14:58 +09002638 that :py:obj:`get_client_ca_list` returns the proper value at various
Jean-Paul Calderone911c9112009-10-24 11:12:00 -04002639 times.
2640 """
Ziga Seilnacht679c4262009-09-01 01:32:29 +02002641 server = self._server(None)
2642 client = self._client(None)
Ziga Seilnachtf93bf102009-10-23 09:51:07 +02002643 self.assertEqual(client.get_client_ca_list(), [])
2644 self.assertEqual(server.get_client_ca_list(), [])
Ziga Seilnacht679c4262009-09-01 01:32:29 +02002645 ctx = server.get_context()
2646 expected = func(ctx)
Ziga Seilnachtf93bf102009-10-23 09:51:07 +02002647 self.assertEqual(client.get_client_ca_list(), [])
2648 self.assertEqual(server.get_client_ca_list(), expected)
Jean-Paul Calderonebf37f0f2010-07-31 14:56:20 -04002649 self._interactInMemory(client, server)
Ziga Seilnachtf93bf102009-10-23 09:51:07 +02002650 self.assertEqual(client.get_client_ca_list(), expected)
2651 self.assertEqual(server.get_client_ca_list(), expected)
Ziga Seilnacht679c4262009-09-01 01:32:29 +02002652
2653
Jean-Paul Calderone911c9112009-10-24 11:12:00 -04002654 def test_set_client_ca_list_errors(self):
Ziga Seilnacht679c4262009-09-01 01:32:29 +02002655 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002656 :py:obj:`Context.set_client_ca_list` raises a :py:obj:`TypeError` if called with a
Jean-Paul Calderone911c9112009-10-24 11:12:00 -04002657 non-list or a list that contains objects other than X509Names.
Ziga Seilnacht679c4262009-09-01 01:32:29 +02002658 """
2659 ctx = Context(TLSv1_METHOD)
Ziga Seilnachtf93bf102009-10-23 09:51:07 +02002660 self.assertRaises(TypeError, ctx.set_client_ca_list, "spam")
2661 self.assertRaises(TypeError, ctx.set_client_ca_list, ["spam"])
2662 self.assertIdentical(ctx.set_client_ca_list([]), None)
Ziga Seilnacht679c4262009-09-01 01:32:29 +02002663
2664
Jean-Paul Calderone911c9112009-10-24 11:12:00 -04002665 def test_set_empty_ca_list(self):
Ziga Seilnacht679c4262009-09-01 01:32:29 +02002666 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002667 If passed an empty list, :py:obj:`Context.set_client_ca_list` configures the
Jean-Paul Calderone911c9112009-10-24 11:12:00 -04002668 context to send no CA names to the client and, on both the server and
Jonathan Ballet648875f2011-07-16 14:14:58 +09002669 client sides, :py:obj:`Connection.get_client_ca_list` returns an empty list
Jean-Paul Calderone911c9112009-10-24 11:12:00 -04002670 after the connection is set up.
2671 """
2672 def no_ca(ctx):
2673 ctx.set_client_ca_list([])
2674 return []
2675 self._check_client_ca_list(no_ca)
2676
2677
2678 def test_set_one_ca_list(self):
2679 """
2680 If passed a list containing a single X509Name,
Jonathan Ballet648875f2011-07-16 14:14:58 +09002681 :py:obj:`Context.set_client_ca_list` configures the context to send that CA
Jean-Paul Calderone911c9112009-10-24 11:12:00 -04002682 name to the client and, on both the server and client sides,
Jonathan Ballet648875f2011-07-16 14:14:58 +09002683 :py:obj:`Connection.get_client_ca_list` returns a list containing that
Jean-Paul Calderone911c9112009-10-24 11:12:00 -04002684 X509Name after the connection is set up.
2685 """
2686 cacert = load_certificate(FILETYPE_PEM, root_cert_pem)
2687 cadesc = cacert.get_subject()
2688 def single_ca(ctx):
2689 ctx.set_client_ca_list([cadesc])
2690 return [cadesc]
2691 self._check_client_ca_list(single_ca)
2692
2693
2694 def test_set_multiple_ca_list(self):
2695 """
2696 If passed a list containing multiple X509Name objects,
Jonathan Ballet648875f2011-07-16 14:14:58 +09002697 :py:obj:`Context.set_client_ca_list` configures the context to send those CA
Jean-Paul Calderone911c9112009-10-24 11:12:00 -04002698 names to the client and, on both the server and client sides,
Jonathan Ballet648875f2011-07-16 14:14:58 +09002699 :py:obj:`Connection.get_client_ca_list` returns a list containing those
Jean-Paul Calderone911c9112009-10-24 11:12:00 -04002700 X509Names after the connection is set up.
2701 """
2702 secert = load_certificate(FILETYPE_PEM, server_cert_pem)
2703 clcert = load_certificate(FILETYPE_PEM, server_cert_pem)
2704
2705 sedesc = secert.get_subject()
2706 cldesc = clcert.get_subject()
2707
2708 def multiple_ca(ctx):
2709 L = [sedesc, cldesc]
2710 ctx.set_client_ca_list(L)
2711 return L
2712 self._check_client_ca_list(multiple_ca)
2713
2714
2715 def test_reset_ca_list(self):
2716 """
2717 If called multiple times, only the X509Names passed to the final call
Jonathan Ballet648875f2011-07-16 14:14:58 +09002718 of :py:obj:`Context.set_client_ca_list` are used to configure the CA names
Jean-Paul Calderone911c9112009-10-24 11:12:00 -04002719 sent to the client.
Ziga Seilnacht679c4262009-09-01 01:32:29 +02002720 """
2721 cacert = load_certificate(FILETYPE_PEM, root_cert_pem)
2722 secert = load_certificate(FILETYPE_PEM, server_cert_pem)
2723 clcert = load_certificate(FILETYPE_PEM, server_cert_pem)
2724
2725 cadesc = cacert.get_subject()
2726 sedesc = secert.get_subject()
2727 cldesc = clcert.get_subject()
2728
Ziga Seilnachtf93bf102009-10-23 09:51:07 +02002729 def changed_ca(ctx):
2730 ctx.set_client_ca_list([sedesc, cldesc])
2731 ctx.set_client_ca_list([cadesc])
Ziga Seilnacht679c4262009-09-01 01:32:29 +02002732 return [cadesc]
Ziga Seilnachtf93bf102009-10-23 09:51:07 +02002733 self._check_client_ca_list(changed_ca)
Ziga Seilnacht679c4262009-09-01 01:32:29 +02002734
Jean-Paul Calderone911c9112009-10-24 11:12:00 -04002735
2736 def test_mutated_ca_list(self):
2737 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002738 If the list passed to :py:obj:`Context.set_client_ca_list` is mutated
Jean-Paul Calderone911c9112009-10-24 11:12:00 -04002739 afterwards, this does not affect the list of CA names sent to the
2740 client.
2741 """
2742 cacert = load_certificate(FILETYPE_PEM, root_cert_pem)
2743 secert = load_certificate(FILETYPE_PEM, server_cert_pem)
2744
2745 cadesc = cacert.get_subject()
2746 sedesc = secert.get_subject()
2747
Ziga Seilnachtf93bf102009-10-23 09:51:07 +02002748 def mutated_ca(ctx):
Ziga Seilnacht679c4262009-09-01 01:32:29 +02002749 L = [cadesc]
Ziga Seilnachtf93bf102009-10-23 09:51:07 +02002750 ctx.set_client_ca_list([cadesc])
Ziga Seilnacht679c4262009-09-01 01:32:29 +02002751 L.append(sedesc)
2752 return [cadesc]
Ziga Seilnachtf93bf102009-10-23 09:51:07 +02002753 self._check_client_ca_list(mutated_ca)
Ziga Seilnacht679c4262009-09-01 01:32:29 +02002754
2755
Jean-Paul Calderone911c9112009-10-24 11:12:00 -04002756 def test_add_client_ca_errors(self):
Ziga Seilnacht679c4262009-09-01 01:32:29 +02002757 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002758 :py:obj:`Context.add_client_ca` raises :py:obj:`TypeError` if called with a non-X509
Jean-Paul Calderone911c9112009-10-24 11:12:00 -04002759 object or with a number of arguments other than one.
Ziga Seilnacht679c4262009-09-01 01:32:29 +02002760 """
2761 ctx = Context(TLSv1_METHOD)
2762 cacert = load_certificate(FILETYPE_PEM, root_cert_pem)
Jean-Paul Calderone911c9112009-10-24 11:12:00 -04002763 self.assertRaises(TypeError, ctx.add_client_ca)
Ziga Seilnachtf93bf102009-10-23 09:51:07 +02002764 self.assertRaises(TypeError, ctx.add_client_ca, "spam")
Jean-Paul Calderone911c9112009-10-24 11:12:00 -04002765 self.assertRaises(TypeError, ctx.add_client_ca, cacert, cacert)
Ziga Seilnacht679c4262009-09-01 01:32:29 +02002766
2767
Jean-Paul Calderone055a9172009-10-24 13:45:11 -04002768 def test_one_add_client_ca(self):
Ziga Seilnacht679c4262009-09-01 01:32:29 +02002769 """
Jean-Paul Calderone055a9172009-10-24 13:45:11 -04002770 A certificate's subject can be added as a CA to be sent to the client
Jonathan Ballet648875f2011-07-16 14:14:58 +09002771 with :py:obj:`Context.add_client_ca`.
Jean-Paul Calderone055a9172009-10-24 13:45:11 -04002772 """
2773 cacert = load_certificate(FILETYPE_PEM, root_cert_pem)
2774 cadesc = cacert.get_subject()
2775 def single_ca(ctx):
2776 ctx.add_client_ca(cacert)
2777 return [cadesc]
2778 self._check_client_ca_list(single_ca)
2779
2780
2781 def test_multiple_add_client_ca(self):
2782 """
2783 Multiple CA names can be sent to the client by calling
Jonathan Ballet648875f2011-07-16 14:14:58 +09002784 :py:obj:`Context.add_client_ca` with multiple X509 objects.
Jean-Paul Calderone055a9172009-10-24 13:45:11 -04002785 """
2786 cacert = load_certificate(FILETYPE_PEM, root_cert_pem)
2787 secert = load_certificate(FILETYPE_PEM, server_cert_pem)
2788
2789 cadesc = cacert.get_subject()
2790 sedesc = secert.get_subject()
2791
2792 def multiple_ca(ctx):
2793 ctx.add_client_ca(cacert)
2794 ctx.add_client_ca(secert)
2795 return [cadesc, sedesc]
2796 self._check_client_ca_list(multiple_ca)
2797
2798
2799 def test_set_and_add_client_ca(self):
2800 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002801 A call to :py:obj:`Context.set_client_ca_list` followed by a call to
2802 :py:obj:`Context.add_client_ca` results in using the CA names from the first
Jean-Paul Calderone055a9172009-10-24 13:45:11 -04002803 call and the CA name from the second call.
Ziga Seilnacht679c4262009-09-01 01:32:29 +02002804 """
2805 cacert = load_certificate(FILETYPE_PEM, root_cert_pem)
2806 secert = load_certificate(FILETYPE_PEM, server_cert_pem)
2807 clcert = load_certificate(FILETYPE_PEM, server_cert_pem)
2808
2809 cadesc = cacert.get_subject()
2810 sedesc = secert.get_subject()
2811 cldesc = clcert.get_subject()
2812
Ziga Seilnachtf93bf102009-10-23 09:51:07 +02002813 def mixed_set_add_ca(ctx):
2814 ctx.set_client_ca_list([cadesc, sedesc])
2815 ctx.add_client_ca(clcert)
Ziga Seilnacht679c4262009-09-01 01:32:29 +02002816 return [cadesc, sedesc, cldesc]
Ziga Seilnachtf93bf102009-10-23 09:51:07 +02002817 self._check_client_ca_list(mixed_set_add_ca)
Ziga Seilnacht679c4262009-09-01 01:32:29 +02002818
Jean-Paul Calderone055a9172009-10-24 13:45:11 -04002819
2820 def test_set_after_add_client_ca(self):
2821 """
Jonathan Ballet648875f2011-07-16 14:14:58 +09002822 A call to :py:obj:`Context.set_client_ca_list` after a call to
2823 :py:obj:`Context.add_client_ca` replaces the CA name specified by the former
Jean-Paul Calderone055a9172009-10-24 13:45:11 -04002824 call with the names specified by the latter cal.
2825 """
2826 cacert = load_certificate(FILETYPE_PEM, root_cert_pem)
2827 secert = load_certificate(FILETYPE_PEM, server_cert_pem)
2828 clcert = load_certificate(FILETYPE_PEM, server_cert_pem)
2829
2830 cadesc = cacert.get_subject()
2831 sedesc = secert.get_subject()
Jean-Paul Calderone055a9172009-10-24 13:45:11 -04002832
Ziga Seilnachtf93bf102009-10-23 09:51:07 +02002833 def set_replaces_add_ca(ctx):
2834 ctx.add_client_ca(clcert)
2835 ctx.set_client_ca_list([cadesc])
2836 ctx.add_client_ca(secert)
Ziga Seilnacht679c4262009-09-01 01:32:29 +02002837 return [cadesc, sedesc]
Ziga Seilnachtf93bf102009-10-23 09:51:07 +02002838 self._check_client_ca_list(set_replaces_add_ca)
Ziga Seilnacht679c4262009-09-01 01:32:29 +02002839
Jean-Paul Calderone0b88b6a2009-07-05 12:44:41 -04002840
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07002841
2842class ConnectionBIOTests(TestCase):
2843 """
2844 Tests for :py:obj:`Connection.bio_read` and :py:obj:`Connection.bio_write`.
2845 """
2846 def test_wantReadError(self):
2847 """
2848 :py:obj:`Connection.bio_read` raises :py:obj:`OpenSSL.SSL.WantReadError`
2849 if there are no bytes available to be read from the BIO.
2850 """
2851 ctx = Context(TLSv1_METHOD)
2852 conn = Connection(ctx, None)
2853 self.assertRaises(WantReadError, conn.bio_read, 1024)
2854
2855
Jean-Paul Calderonebef4f4c2014-02-02 18:13:31 -05002856 def test_buffer_size(self):
2857 """
2858 :py:obj:`Connection.bio_read` accepts an integer giving the maximum
2859 number of bytes to read and return.
2860 """
2861 ctx = Context(TLSv1_METHOD)
2862 conn = Connection(ctx, None)
2863 conn.set_connect_state()
2864 try:
2865 conn.do_handshake()
2866 except WantReadError:
2867 pass
2868 data = conn.bio_read(2)
2869 self.assertEqual(2, len(data))
2870
2871
2872 if not PY3:
2873 def test_buffer_size_long(self):
2874 """
2875 On Python 2 :py:obj:`Connection.bio_read` accepts values of type
2876 :py:obj:`long` as well as :py:obj:`int`.
2877 """
2878 ctx = Context(TLSv1_METHOD)
2879 conn = Connection(ctx, None)
2880 conn.set_connect_state()
2881 try:
2882 conn.do_handshake()
2883 except WantReadError:
2884 pass
2885 data = conn.bio_read(long(2))
2886 self.assertEqual(2, len(data))
2887
2888
2889
Jean-Paul Calderoned899af02013-03-19 22:10:37 -07002890
Jean-Paul Calderone31e85a82011-03-21 19:13:35 -04002891class InfoConstantTests(TestCase):
2892 """
2893 Tests for assorted constants exposed for use in info callbacks.
2894 """
2895 def test_integers(self):
2896 """
2897 All of the info constants are integers.
2898
2899 This is a very weak test. It would be nice to have one that actually
2900 verifies that as certain info events happen, the value passed to the
2901 info callback matches up with the constant exposed by OpenSSL.SSL.
2902 """
2903 for const in [
2904 SSL_ST_CONNECT, SSL_ST_ACCEPT, SSL_ST_MASK, SSL_ST_INIT,
2905 SSL_ST_BEFORE, SSL_ST_OK, SSL_ST_RENEGOTIATE,
2906 SSL_CB_LOOP, SSL_CB_EXIT, SSL_CB_READ, SSL_CB_WRITE, SSL_CB_ALERT,
2907 SSL_CB_READ_ALERT, SSL_CB_WRITE_ALERT, SSL_CB_ACCEPT_LOOP,
2908 SSL_CB_ACCEPT_EXIT, SSL_CB_CONNECT_LOOP, SSL_CB_CONNECT_EXIT,
2909 SSL_CB_HANDSHAKE_START, SSL_CB_HANDSHAKE_DONE]:
2910
2911 self.assertTrue(isinstance(const, int))
2912
Ziga Seilnacht44611bf2009-08-31 20:49:30 +02002913
Jean-Paul Calderone0b88b6a2009-07-05 12:44:41 -04002914if __name__ == '__main__':
2915 main()