blob: 24a08b0ed99252b1bbc5a883c45977195314a9ac [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"""
5Unit tests for L{OpenSSL.SSL}.
6"""
7
Jean-Paul Calderone8322d782010-09-17 19:22:31 -04008from errno import ECONNREFUSED, EINPROGRESS, EWOULDBLOCK
Jean-Paul Calderone52f0d8b2009-03-07 09:10:19 -05009from sys import platform
Jean-Paul Calderone8bdeba22010-07-29 09:45:07 -040010from socket import error, socket
Jean-Paul Calderonea65cf6c2009-07-19 10:26:52 -040011from os import makedirs
Jean-Paul Calderone1cb5d022008-09-07 20:58:50 -040012from os.path import join
Jean-Paul Calderone0b88b6a2009-07-05 12:44:41 -040013from unittest import main
Jean-Paul Calderone460cc1f2009-03-07 11:31:12 -050014
Jean-Paul Calderone20222ae2011-05-19 21:43:46 -040015from OpenSSL.crypto import TYPE_RSA, FILETYPE_PEM
Jean-Paul Calderone7526d172010-09-09 17:55:31 -040016from OpenSSL.crypto import PKey, X509, X509Extension
17from OpenSSL.crypto import dump_privatekey, load_privatekey
18from OpenSSL.crypto import dump_certificate, load_certificate
19
Jean-Paul Calderone9f2e38e2011-04-14 09:36:55 -040020from OpenSSL.SSL import OPENSSL_VERSION_NUMBER, SSLEAY_VERSION, SSLEAY_CFLAGS
21from OpenSSL.SSL import SSLEAY_PLATFORM, SSLEAY_DIR, SSLEAY_BUILT_ON
Jean-Paul Calderonee4f6b472010-07-29 22:50:58 -040022from OpenSSL.SSL import SENT_SHUTDOWN, RECEIVED_SHUTDOWN
Jean-Paul Calderone30c09ea2008-03-21 17:04:05 -040023from OpenSSL.SSL import SSLv2_METHOD, SSLv3_METHOD, SSLv23_METHOD, TLSv1_METHOD
Jean-Paul Calderone68649052009-07-17 21:14:27 -040024from OpenSSL.SSL import OP_NO_SSLv2, OP_NO_SSLv3, OP_SINGLE_DH_USE
Jean-Paul Calderone20222ae2011-05-19 21:43:46 -040025from OpenSSL.SSL import (
26 VERIFY_PEER, VERIFY_FAIL_IF_NO_PEER_CERT, VERIFY_CLIENT_ONCE, VERIFY_NONE)
27from OpenSSL.SSL import (
28 Error, SysCallError, WantReadError, ZeroReturnError, SSLeay_version)
Jean-Paul Calderone7526d172010-09-09 17:55:31 -040029from OpenSSL.SSL import Context, ContextType, Connection, ConnectionType
30
Jean-Paul Calderone9e4eeae2010-08-22 21:32:52 -040031from OpenSSL.test.util import TestCase, bytes, b
Jean-Paul Calderone20222ae2011-05-19 21:43:46 -040032from OpenSSL.test.test_crypto import (
33 cleartextCertificatePEM, cleartextPrivateKeyPEM)
34from OpenSSL.test.test_crypto import (
35 client_cert_pem, client_key_pem, server_cert_pem, server_key_pem,
36 root_cert_pem)
37
Jean-Paul Calderone4bccf5e2008-12-28 22:50:42 -050038try:
39 from OpenSSL.SSL import OP_NO_QUERY_MTU
40except ImportError:
41 OP_NO_QUERY_MTU = None
42try:
43 from OpenSSL.SSL import OP_COOKIE_EXCHANGE
44except ImportError:
45 OP_COOKIE_EXCHANGE = None
46try:
47 from OpenSSL.SSL import OP_NO_TICKET
48except ImportError:
49 OP_NO_TICKET = None
Jean-Paul Calderone5ef86512008-04-26 19:06:28 -040050
Jean-Paul Calderone31e85a82011-03-21 19:13:35 -040051from OpenSSL.SSL import (
52 SSL_ST_CONNECT, SSL_ST_ACCEPT, SSL_ST_MASK, SSL_ST_INIT, SSL_ST_BEFORE,
53 SSL_ST_OK, SSL_ST_RENEGOTIATE,
54 SSL_CB_LOOP, SSL_CB_EXIT, SSL_CB_READ, SSL_CB_WRITE, SSL_CB_ALERT,
55 SSL_CB_READ_ALERT, SSL_CB_WRITE_ALERT, SSL_CB_ACCEPT_LOOP,
56 SSL_CB_ACCEPT_EXIT, SSL_CB_CONNECT_LOOP, SSL_CB_CONNECT_EXIT,
57 SSL_CB_HANDSHAKE_START, SSL_CB_HANDSHAKE_DONE)
Jean-Paul Calderone30c09ea2008-03-21 17:04:05 -040058
Jean-Paul Calderone6ace4782010-09-09 18:43:40 -040059# openssl dhparam 128 -out dh-128.pem (note that 128 is a small number of bits
60# to use)
61dhparam = """\
62-----BEGIN DH PARAMETERS-----
63MBYCEQCobsg29c9WZP/54oAPcwiDAgEC
64-----END DH PARAMETERS-----
65"""
66
67
Jean-Paul Calderonebf37f0f2010-07-31 14:56:20 -040068def verify_cb(conn, cert, errnum, depth, ok):
Jean-Paul Calderonebf37f0f2010-07-31 14:56:20 -040069 return ok
70
Jean-Paul Calderone20222ae2011-05-19 21:43:46 -040071
Rick Deanb1ccd562009-07-09 23:52:39 -050072def socket_pair():
Jean-Paul Calderone1a9613b2009-07-16 12:13:36 -040073 """
Jean-Paul Calderone68649052009-07-17 21:14:27 -040074 Establish and return a pair of network sockets connected to each other.
Jean-Paul Calderone1a9613b2009-07-16 12:13:36 -040075 """
76 # Connect a pair of sockets
Rick Deanb1ccd562009-07-09 23:52:39 -050077 port = socket()
78 port.bind(('', 0))
79 port.listen(1)
80 client = socket()
81 client.setblocking(False)
Jean-Paul Calderonef23c5d92009-07-23 17:58:15 -040082 client.connect_ex(("127.0.0.1", port.getsockname()[1]))
Jean-Paul Calderone94b24a82009-07-16 19:11:38 -040083 client.setblocking(True)
Rick Deanb1ccd562009-07-09 23:52:39 -050084 server = port.accept()[0]
Rick Deanb1ccd562009-07-09 23:52:39 -050085
Jean-Paul Calderone1a9613b2009-07-16 12:13:36 -040086 # Let's pass some unencrypted data to make sure our socket connection is
87 # fine. Just one byte, so we don't have to worry about buffers getting
88 # filled up or fragmentation.
Jean-Paul Calderone9e4eeae2010-08-22 21:32:52 -040089 server.send(b("x"))
90 assert client.recv(1024) == b("x")
91 client.send(b("y"))
92 assert server.recv(1024) == b("y")
Rick Deanb1ccd562009-07-09 23:52:39 -050093
Jean-Paul Calderone7ca48b52010-07-28 18:57:21 -040094 # Most of our callers want non-blocking sockets, make it easy for them.
Jean-Paul Calderone94b24a82009-07-16 19:11:38 -040095 server.setblocking(False)
96 client.setblocking(False)
97
Rick Deanb1ccd562009-07-09 23:52:39 -050098 return (server, client)
99
100
Jean-Paul Calderone94b24a82009-07-16 19:11:38 -0400101
Jean-Paul Calderonef8742032010-09-25 00:00:32 -0400102def handshake(client, server):
103 conns = [client, server]
104 while conns:
105 for conn in conns:
106 try:
107 conn.do_handshake()
108 except WantReadError:
109 pass
110 else:
111 conns.remove(conn)
112
113
Jean-Paul Calderone20222ae2011-05-19 21:43:46 -0400114def _create_certificate_chain():
115 """
116 Construct and return a chain of certificates.
117
118 1. A new self-signed certificate authority certificate (cacert)
119 2. A new intermediate certificate signed by cacert (icert)
120 3. A new server certificate signed by icert (scert)
121 """
122 caext = X509Extension(b('basicConstraints'), False, b('CA:true'))
123
124 # Step 1
125 cakey = PKey()
126 cakey.generate_key(TYPE_RSA, 512)
127 cacert = X509()
128 cacert.get_subject().commonName = "Authority Certificate"
129 cacert.set_issuer(cacert.get_subject())
130 cacert.set_pubkey(cakey)
131 cacert.set_notBefore(b("20000101000000Z"))
132 cacert.set_notAfter(b("20200101000000Z"))
133 cacert.add_extensions([caext])
134 cacert.set_serial_number(0)
135 cacert.sign(cakey, "sha1")
136
137 # Step 2
138 ikey = PKey()
139 ikey.generate_key(TYPE_RSA, 512)
140 icert = X509()
141 icert.get_subject().commonName = "Intermediate Certificate"
142 icert.set_issuer(cacert.get_subject())
143 icert.set_pubkey(ikey)
144 icert.set_notBefore(b("20000101000000Z"))
145 icert.set_notAfter(b("20200101000000Z"))
146 icert.add_extensions([caext])
147 icert.set_serial_number(0)
148 icert.sign(cakey, "sha1")
149
150 # Step 3
151 skey = PKey()
152 skey.generate_key(TYPE_RSA, 512)
153 scert = X509()
154 scert.get_subject().commonName = "Server Certificate"
155 scert.set_issuer(icert.get_subject())
156 scert.set_pubkey(skey)
157 scert.set_notBefore(b("20000101000000Z"))
158 scert.set_notAfter(b("20200101000000Z"))
159 scert.add_extensions([
160 X509Extension(b('basicConstraints'), True, b('CA:false'))])
161 scert.set_serial_number(0)
162 scert.sign(ikey, "sha1")
163
164 return [(cakey, cacert), (ikey, icert), (skey, scert)]
165
166
167
Jean-Paul Calderonebf37f0f2010-07-31 14:56:20 -0400168class _LoopbackMixin:
Jean-Paul Calderonea8fb0c82010-09-09 18:04:56 -0400169 """
170 Helper mixin which defines methods for creating a connected socket pair and
171 for forcing two connected SSL sockets to talk to each other via memory BIOs.
172 """
Jean-Paul Calderonebf37f0f2010-07-31 14:56:20 -0400173 def _loopback(self):
174 (server, client) = socket_pair()
175
176 ctx = Context(TLSv1_METHOD)
177 ctx.use_privatekey(load_privatekey(FILETYPE_PEM, server_key_pem))
178 ctx.use_certificate(load_certificate(FILETYPE_PEM, server_cert_pem))
179 server = Connection(ctx, server)
180 server.set_accept_state()
181 client = Connection(Context(TLSv1_METHOD), client)
182 client.set_connect_state()
183
Jean-Paul Calderonef8742032010-09-25 00:00:32 -0400184 handshake(client, server)
Jean-Paul Calderonebf37f0f2010-07-31 14:56:20 -0400185
186 server.setblocking(True)
187 client.setblocking(True)
188 return server, client
189
190
191 def _interactInMemory(self, client_conn, server_conn):
192 """
193 Try to read application bytes from each of the two L{Connection}
194 objects. Copy bytes back and forth between their send/receive buffers
195 for as long as there is anything to copy. When there is nothing more
196 to copy, return C{None}. If one of them actually manages to deliver
197 some application bytes, return a two-tuple of the connection from which
198 the bytes were read and the bytes themselves.
199 """
200 wrote = True
201 while wrote:
202 # Loop until neither side has anything to say
203 wrote = False
204
205 # Copy stuff from each side's send buffer to the other side's
206 # receive buffer.
207 for (read, write) in [(client_conn, server_conn),
208 (server_conn, client_conn)]:
209
210 # Give the side a chance to generate some more bytes, or
211 # succeed.
212 try:
Jean-Paul Calderone20222ae2011-05-19 21:43:46 -0400213 data = read.recv(2 ** 16)
Jean-Paul Calderonebf37f0f2010-07-31 14:56:20 -0400214 except WantReadError:
215 # It didn't succeed, so we'll hope it generated some
216 # output.
217 pass
218 else:
219 # It did succeed, so we'll stop now and let the caller deal
220 # with it.
Jean-Paul Calderone20222ae2011-05-19 21:43:46 -0400221 return (read, data)
Jean-Paul Calderonebf37f0f2010-07-31 14:56:20 -0400222
223 while True:
224 # Keep copying as long as there's more stuff there.
225 try:
226 dirty = read.bio_read(4096)
227 except WantReadError:
228 # Okay, nothing more waiting to be sent. Stop
229 # processing this send buffer.
230 break
231 else:
232 # Keep track of the fact that someone generated some
233 # output.
234 wrote = True
235 write.bio_write(dirty)
236
237
Jean-Paul Calderone20222ae2011-05-19 21:43:46 -0400238
Jean-Paul Calderone9f2e38e2011-04-14 09:36:55 -0400239class VersionTests(TestCase):
240 """
241 Tests for version information exposed by
242 L{OpenSSL.SSL.SSLeay_version} and
243 L{OpenSSL.SSL.OPENSSL_VERSION_NUMBER}.
244 """
245 def test_OPENSSL_VERSION_NUMBER(self):
246 """
247 L{OPENSSL_VERSION_NUMBER} is an integer with status in the low
248 byte and the patch, fix, minor, and major versions in the
249 nibbles above that.
250 """
251 self.assertTrue(isinstance(OPENSSL_VERSION_NUMBER, int))
252
253
254 def test_SSLeay_version(self):
255 """
256 L{SSLeay_version} takes a version type indicator and returns
257 one of a number of version strings based on that indicator.
258 """
259 versions = {}
260 for t in [SSLEAY_VERSION, SSLEAY_CFLAGS, SSLEAY_BUILT_ON,
261 SSLEAY_PLATFORM, SSLEAY_DIR]:
262 version = SSLeay_version(t)
263 versions[version] = t
264 self.assertTrue(isinstance(version, bytes))
265 self.assertEqual(len(versions), 5)
266
267
Jean-Paul Calderonebf37f0f2010-07-31 14:56:20 -0400268
269class ContextTests(TestCase, _LoopbackMixin):
Jean-Paul Calderone30c09ea2008-03-21 17:04:05 -0400270 """
271 Unit tests for L{OpenSSL.SSL.Context}.
272 """
273 def test_method(self):
274 """
275 L{Context} can be instantiated with one of L{SSLv2_METHOD},
276 L{SSLv3_METHOD}, L{SSLv23_METHOD}, or L{TLSv1_METHOD}.
277 """
Jean-Paul Calderone9f2e38e2011-04-14 09:36:55 -0400278 for meth in [SSLv3_METHOD, SSLv23_METHOD, TLSv1_METHOD]:
Jean-Paul Calderone30c09ea2008-03-21 17:04:05 -0400279 Context(meth)
Jean-Paul Calderone9f2e38e2011-04-14 09:36:55 -0400280
281 try:
282 Context(SSLv2_METHOD)
283 except ValueError:
284 # Some versions of OpenSSL have SSLv2, some don't.
285 # Difficult to say in advance.
286 pass
287
Jean-Paul Calderone30c09ea2008-03-21 17:04:05 -0400288 self.assertRaises(TypeError, Context, "")
289 self.assertRaises(ValueError, Context, 10)
290
291
Rick Deane15b1472009-07-09 15:53:42 -0500292 def test_type(self):
293 """
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400294 L{Context} and L{ContextType} refer to the same type object and can be
295 used to create instances of that type.
Rick Deane15b1472009-07-09 15:53:42 -0500296 """
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400297 self.assertIdentical(Context, ContextType)
298 self.assertConsistentType(Context, 'Context', TLSv1_METHOD)
Rick Deane15b1472009-07-09 15:53:42 -0500299
300
Jean-Paul Calderone30c09ea2008-03-21 17:04:05 -0400301 def test_use_privatekey(self):
302 """
303 L{Context.use_privatekey} takes an L{OpenSSL.crypto.PKey} instance.
304 """
305 key = PKey()
306 key.generate_key(TYPE_RSA, 128)
307 ctx = Context(TLSv1_METHOD)
308 ctx.use_privatekey(key)
309 self.assertRaises(TypeError, ctx.use_privatekey, "")
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -0400310
311
Jean-Paul Calderonebd479162010-07-30 18:03:25 -0400312 def test_set_app_data_wrong_args(self):
313 """
314 L{Context.set_app_data} raises L{TypeError} if called with other than
315 one argument.
316 """
317 context = Context(TLSv1_METHOD)
318 self.assertRaises(TypeError, context.set_app_data)
319 self.assertRaises(TypeError, context.set_app_data, None, None)
320
321
322 def test_get_app_data_wrong_args(self):
323 """
324 L{Context.get_app_data} raises L{TypeError} if called with any
325 arguments.
326 """
327 context = Context(TLSv1_METHOD)
328 self.assertRaises(TypeError, context.get_app_data, None)
329
330
331 def test_app_data(self):
332 """
333 L{Context.set_app_data} stores an object for later retrieval using
334 L{Context.get_app_data}.
335 """
336 app_data = object()
337 context = Context(TLSv1_METHOD)
338 context.set_app_data(app_data)
339 self.assertIdentical(context.get_app_data(), app_data)
340
341
Jean-Paul Calderone40569ca2010-07-30 18:04:58 -0400342 def test_set_options_wrong_args(self):
343 """
344 L{Context.set_options} raises L{TypeError} if called with the wrong
345 number of arguments or a non-C{int} argument.
346 """
347 context = Context(TLSv1_METHOD)
348 self.assertRaises(TypeError, context.set_options)
349 self.assertRaises(TypeError, context.set_options, None)
350 self.assertRaises(TypeError, context.set_options, 1, None)
351
352
Jean-Paul Calderone5ebb44a2010-07-30 18:09:41 -0400353 def test_set_timeout_wrong_args(self):
354 """
355 L{Context.set_timeout} raises L{TypeError} if called with the wrong
356 number of arguments or a non-C{int} argument.
357 """
358 context = Context(TLSv1_METHOD)
359 self.assertRaises(TypeError, context.set_timeout)
360 self.assertRaises(TypeError, context.set_timeout, None)
361 self.assertRaises(TypeError, context.set_timeout, 1, None)
362
363
364 def test_get_timeout_wrong_args(self):
365 """
366 L{Context.get_timeout} raises L{TypeError} if called with any arguments.
367 """
368 context = Context(TLSv1_METHOD)
369 self.assertRaises(TypeError, context.get_timeout, None)
370
371
372 def test_timeout(self):
373 """
374 L{Context.set_timeout} sets the session timeout for all connections
375 created using the context object. L{Context.get_timeout} retrieves this
376 value.
377 """
378 context = Context(TLSv1_METHOD)
379 context.set_timeout(1234)
380 self.assertEquals(context.get_timeout(), 1234)
381
382
Jean-Paul Calderonee2b69512010-07-30 18:22:06 -0400383 def test_set_verify_depth_wrong_args(self):
384 """
385 L{Context.set_verify_depth} raises L{TypeError} if called with the wrong
386 number of arguments or a non-C{int} argument.
387 """
388 context = Context(TLSv1_METHOD)
389 self.assertRaises(TypeError, context.set_verify_depth)
390 self.assertRaises(TypeError, context.set_verify_depth, None)
391 self.assertRaises(TypeError, context.set_verify_depth, 1, None)
392
393
394 def test_get_verify_depth_wrong_args(self):
395 """
396 L{Context.get_verify_depth} raises L{TypeError} if called with any arguments.
397 """
398 context = Context(TLSv1_METHOD)
399 self.assertRaises(TypeError, context.get_verify_depth, None)
400
401
402 def test_verify_depth(self):
403 """
404 L{Context.set_verify_depth} sets the number of certificates in a chain
405 to follow before giving up. The value can be retrieved with
406 L{Context.get_verify_depth}.
407 """
408 context = Context(TLSv1_METHOD)
409 context.set_verify_depth(11)
410 self.assertEquals(context.get_verify_depth(), 11)
411
412
Jean-Paul Calderone389d76d2010-07-30 17:57:53 -0400413 def _write_encrypted_pem(self, passphrase):
Jean-Paul Calderonea8fb0c82010-09-09 18:04:56 -0400414 """
415 Write a new private key out to a new file, encrypted using the given
416 passphrase. Return the path to the new file.
417 """
Jean-Paul Calderone389d76d2010-07-30 17:57:53 -0400418 key = PKey()
419 key.generate_key(TYPE_RSA, 128)
420 pemFile = self.mktemp()
Jean-Paul Calderonea9868832010-08-22 21:38:34 -0400421 fObj = open(pemFile, 'w')
422 pem = dump_privatekey(FILETYPE_PEM, key, "blowfish", passphrase)
423 fObj.write(pem.decode('ascii'))
Jean-Paul Calderone389d76d2010-07-30 17:57:53 -0400424 fObj.close()
425 return pemFile
426
427
Jean-Paul Calderonef4480622010-08-02 18:25:03 -0400428 def test_set_passwd_cb_wrong_args(self):
429 """
430 L{Context.set_passwd_cb} raises L{TypeError} if called with the
431 wrong arguments or with a non-callable first argument.
432 """
433 context = Context(TLSv1_METHOD)
434 self.assertRaises(TypeError, context.set_passwd_cb)
435 self.assertRaises(TypeError, context.set_passwd_cb, None)
436 self.assertRaises(TypeError, context.set_passwd_cb, lambda: None, None, None)
437
438
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -0400439 def test_set_passwd_cb(self):
440 """
441 L{Context.set_passwd_cb} accepts a callable which will be invoked when
442 a private key is loaded from an encrypted PEM.
443 """
Jean-Paul Calderonea9868832010-08-22 21:38:34 -0400444 passphrase = b("foobar")
Jean-Paul Calderone389d76d2010-07-30 17:57:53 -0400445 pemFile = self._write_encrypted_pem(passphrase)
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -0400446 calledWith = []
447 def passphraseCallback(maxlen, verify, extra):
448 calledWith.append((maxlen, verify, extra))
449 return passphrase
450 context = Context(TLSv1_METHOD)
451 context.set_passwd_cb(passphraseCallback)
452 context.use_privatekey_file(pemFile)
453 self.assertTrue(len(calledWith), 1)
454 self.assertTrue(isinstance(calledWith[0][0], int))
455 self.assertTrue(isinstance(calledWith[0][1], int))
456 self.assertEqual(calledWith[0][2], None)
Jean-Paul Calderone5ef86512008-04-26 19:06:28 -0400457
458
Jean-Paul Calderone389d76d2010-07-30 17:57:53 -0400459 def test_passwd_callback_exception(self):
460 """
461 L{Context.use_privatekey_file} propagates any exception raised by the
462 passphrase callback.
463 """
Jean-Paul Calderonea9868832010-08-22 21:38:34 -0400464 pemFile = self._write_encrypted_pem(b("monkeys are nice"))
Jean-Paul Calderone389d76d2010-07-30 17:57:53 -0400465 def passphraseCallback(maxlen, verify, extra):
466 raise RuntimeError("Sorry, I am a fail.")
467
468 context = Context(TLSv1_METHOD)
469 context.set_passwd_cb(passphraseCallback)
470 self.assertRaises(RuntimeError, context.use_privatekey_file, pemFile)
471
472
473 def test_passwd_callback_false(self):
474 """
475 L{Context.use_privatekey_file} raises L{OpenSSL.SSL.Error} if the
476 passphrase callback returns a false value.
477 """
Jean-Paul Calderonea9868832010-08-22 21:38:34 -0400478 pemFile = self._write_encrypted_pem(b("monkeys are nice"))
Jean-Paul Calderone389d76d2010-07-30 17:57:53 -0400479 def passphraseCallback(maxlen, verify, extra):
480 return None
481
482 context = Context(TLSv1_METHOD)
483 context.set_passwd_cb(passphraseCallback)
484 self.assertRaises(Error, context.use_privatekey_file, pemFile)
485
486
487 def test_passwd_callback_non_string(self):
488 """
489 L{Context.use_privatekey_file} raises L{OpenSSL.SSL.Error} if the
490 passphrase callback returns a true non-string value.
491 """
Jean-Paul Calderonea9868832010-08-22 21:38:34 -0400492 pemFile = self._write_encrypted_pem(b("monkeys are nice"))
Jean-Paul Calderone389d76d2010-07-30 17:57:53 -0400493 def passphraseCallback(maxlen, verify, extra):
494 return 10
495
496 context = Context(TLSv1_METHOD)
497 context.set_passwd_cb(passphraseCallback)
498 self.assertRaises(Error, context.use_privatekey_file, pemFile)
499
500
501 def test_passwd_callback_too_long(self):
502 """
503 If the passphrase returned by the passphrase callback returns a string
504 longer than the indicated maximum length, it is truncated.
505 """
506 # A priori knowledge!
Jean-Paul Calderonea9868832010-08-22 21:38:34 -0400507 passphrase = b("x") * 1024
Jean-Paul Calderone389d76d2010-07-30 17:57:53 -0400508 pemFile = self._write_encrypted_pem(passphrase)
509 def passphraseCallback(maxlen, verify, extra):
510 assert maxlen == 1024
Jean-Paul Calderoneb1f7f5f2010-08-22 21:40:52 -0400511 return passphrase + b("y")
Jean-Paul Calderone389d76d2010-07-30 17:57:53 -0400512
513 context = Context(TLSv1_METHOD)
514 context.set_passwd_cb(passphraseCallback)
515 # This shall succeed because the truncated result is the correct
516 # passphrase.
517 context.use_privatekey_file(pemFile)
518
519
Jean-Paul Calderone5ef86512008-04-26 19:06:28 -0400520 def test_set_info_callback(self):
521 """
522 L{Context.set_info_callback} accepts a callable which will be invoked
523 when certain information about an SSL connection is available.
524 """
Rick Deanb1ccd562009-07-09 23:52:39 -0500525 (server, client) = socket_pair()
Jean-Paul Calderone5ef86512008-04-26 19:06:28 -0400526
527 clientSSL = Connection(Context(TLSv1_METHOD), client)
528 clientSSL.set_connect_state()
529
530 called = []
531 def info(conn, where, ret):
532 called.append((conn, where, ret))
533 context = Context(TLSv1_METHOD)
534 context.set_info_callback(info)
535 context.use_certificate(
536 load_certificate(FILETYPE_PEM, cleartextCertificatePEM))
537 context.use_privatekey(
538 load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM))
539
Jean-Paul Calderone5ef86512008-04-26 19:06:28 -0400540 serverSSL = Connection(context, server)
541 serverSSL.set_accept_state()
542
543 while not called:
544 for ssl in clientSSL, serverSSL:
545 try:
546 ssl.do_handshake()
547 except WantReadError:
548 pass
549
550 # Kind of lame. Just make sure it got called somehow.
551 self.assertTrue(called)
Jean-Paul Calderonee1bd4322008-09-07 20:17:17 -0400552
553
Jean-Paul Calderone1cb5d022008-09-07 20:58:50 -0400554 def _load_verify_locations_test(self, *args):
Jean-Paul Calderonea8fb0c82010-09-09 18:04:56 -0400555 """
556 Create a client context which will verify the peer certificate and call
557 its C{load_verify_locations} method with C{*args}. Then connect it to a
558 server and ensure that the handshake succeeds.
559 """
Rick Deanb1ccd562009-07-09 23:52:39 -0500560 (server, client) = socket_pair()
Jean-Paul Calderonee1bd4322008-09-07 20:17:17 -0400561
Jean-Paul Calderonee1bd4322008-09-07 20:17:17 -0400562 clientContext = Context(TLSv1_METHOD)
Jean-Paul Calderone1cb5d022008-09-07 20:58:50 -0400563 clientContext.load_verify_locations(*args)
Jean-Paul Calderonee1bd4322008-09-07 20:17:17 -0400564 # Require that the server certificate verify properly or the
565 # connection will fail.
566 clientContext.set_verify(
567 VERIFY_PEER,
568 lambda conn, cert, errno, depth, preverify_ok: preverify_ok)
569
570 clientSSL = Connection(clientContext, client)
571 clientSSL.set_connect_state()
572
Jean-Paul Calderonee1bd4322008-09-07 20:17:17 -0400573 serverContext = Context(TLSv1_METHOD)
574 serverContext.use_certificate(
575 load_certificate(FILETYPE_PEM, cleartextCertificatePEM))
576 serverContext.use_privatekey(
577 load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM))
578
579 serverSSL = Connection(serverContext, server)
580 serverSSL.set_accept_state()
581
Jean-Paul Calderonef8742032010-09-25 00:00:32 -0400582 # Without load_verify_locations above, the handshake
583 # will fail:
584 # Error: [('SSL routines', 'SSL3_GET_SERVER_CERTIFICATE',
585 # 'certificate verify failed')]
586 handshake(clientSSL, serverSSL)
Jean-Paul Calderonee1bd4322008-09-07 20:17:17 -0400587
588 cert = clientSSL.get_peer_certificate()
Jean-Paul Calderone20131f52009-04-01 12:05:45 -0400589 self.assertEqual(cert.get_subject().CN, 'Testing Root CA')
Jean-Paul Calderone5075fce2008-09-07 20:18:55 -0400590
Jean-Paul Calderone12608a82009-11-07 10:35:15 -0500591
Jean-Paul Calderone1cb5d022008-09-07 20:58:50 -0400592 def test_load_verify_file(self):
593 """
594 L{Context.load_verify_locations} accepts a file name and uses the
595 certificates within for verification purposes.
596 """
597 cafile = self.mktemp()
Jean-Paul Calderonea9868832010-08-22 21:38:34 -0400598 fObj = open(cafile, 'w')
Jean-Paul Calderoneb1f7f5f2010-08-22 21:40:52 -0400599 fObj.write(cleartextCertificatePEM.decode('ascii'))
Jean-Paul Calderone1cb5d022008-09-07 20:58:50 -0400600 fObj.close()
601
602 self._load_verify_locations_test(cafile)
603
Jean-Paul Calderone5075fce2008-09-07 20:18:55 -0400604
605 def test_load_verify_invalid_file(self):
606 """
607 L{Context.load_verify_locations} raises L{Error} when passed a
608 non-existent cafile.
609 """
610 clientContext = Context(TLSv1_METHOD)
611 self.assertRaises(
612 Error, clientContext.load_verify_locations, self.mktemp())
Jean-Paul Calderone1cb5d022008-09-07 20:58:50 -0400613
614
615 def test_load_verify_directory(self):
616 """
617 L{Context.load_verify_locations} accepts a directory name and uses
618 the certificates within for verification purposes.
619 """
620 capath = self.mktemp()
621 makedirs(capath)
Jean-Paul Calderone24dfb332011-05-04 18:10:26 -0400622 # Hash values computed manually with c_rehash to avoid depending on
623 # c_rehash in the test suite. One is from OpenSSL 0.9.8, the other
624 # from OpenSSL 1.0.0.
625 for name in ['c7adac82.0', 'c3705638.0']:
626 cafile = join(capath, name)
627 fObj = open(cafile, 'w')
628 fObj.write(cleartextCertificatePEM.decode('ascii'))
629 fObj.close()
Jean-Paul Calderone1cb5d022008-09-07 20:58:50 -0400630
Jean-Paul Calderone1cb5d022008-09-07 20:58:50 -0400631 self._load_verify_locations_test(None, capath)
632
633
Jean-Paul Calderonef4480622010-08-02 18:25:03 -0400634 def test_load_verify_locations_wrong_args(self):
635 """
636 L{Context.load_verify_locations} raises L{TypeError} if called with
637 the wrong number of arguments or with non-C{str} arguments.
638 """
639 context = Context(TLSv1_METHOD)
640 self.assertRaises(TypeError, context.load_verify_locations)
641 self.assertRaises(TypeError, context.load_verify_locations, object())
642 self.assertRaises(TypeError, context.load_verify_locations, object(), object())
643 self.assertRaises(TypeError, context.load_verify_locations, None, None, None)
644
645
Jean-Paul Calderone7ca48b52010-07-28 18:57:21 -0400646 if platform == "win32":
647 "set_default_verify_paths appears not to work on Windows. "
Jean-Paul Calderone28fb8f02009-07-24 18:01:31 -0400648 "See LP#404343 and LP#404344."
649 else:
650 def test_set_default_verify_paths(self):
651 """
652 L{Context.set_default_verify_paths} causes the platform-specific CA
653 certificate locations to be used for verification purposes.
654 """
655 # Testing this requires a server with a certificate signed by one of
656 # the CAs in the platform CA location. Getting one of those costs
657 # money. Fortunately (or unfortunately, depending on your
658 # perspective), it's easy to think of a public server on the
659 # internet which has such a certificate. Connecting to the network
660 # in a unit test is bad, but it's the only way I can think of to
661 # really test this. -exarkun
Jean-Paul Calderone1cb5d022008-09-07 20:58:50 -0400662
Jean-Paul Calderone28fb8f02009-07-24 18:01:31 -0400663 # Arg, verisign.com doesn't speak TLSv1
664 context = Context(SSLv3_METHOD)
665 context.set_default_verify_paths()
666 context.set_verify(
Ziga Seilnacht44611bf2009-08-31 20:49:30 +0200667 VERIFY_PEER,
Jean-Paul Calderone28fb8f02009-07-24 18:01:31 -0400668 lambda conn, cert, errno, depth, preverify_ok: preverify_ok)
Jean-Paul Calderone1cb5d022008-09-07 20:58:50 -0400669
Jean-Paul Calderone28fb8f02009-07-24 18:01:31 -0400670 client = socket()
671 client.connect(('verisign.com', 443))
672 clientSSL = Connection(context, client)
673 clientSSL.set_connect_state()
674 clientSSL.do_handshake()
675 clientSSL.send('GET / HTTP/1.0\r\n\r\n')
676 self.assertTrue(clientSSL.recv(1024))
Jean-Paul Calderone9eadb962008-09-07 21:20:44 -0400677
678
679 def test_set_default_verify_paths_signature(self):
680 """
681 L{Context.set_default_verify_paths} takes no arguments and raises
682 L{TypeError} if given any.
683 """
684 context = Context(TLSv1_METHOD)
685 self.assertRaises(TypeError, context.set_default_verify_paths, None)
686 self.assertRaises(TypeError, context.set_default_verify_paths, 1)
687 self.assertRaises(TypeError, context.set_default_verify_paths, "")
Jean-Paul Calderone327d8f92008-12-28 21:55:56 -0500688
Jean-Paul Calderonef4480622010-08-02 18:25:03 -0400689
Jean-Paul Calderone12608a82009-11-07 10:35:15 -0500690 def test_add_extra_chain_cert_invalid_cert(self):
691 """
692 L{Context.add_extra_chain_cert} raises L{TypeError} if called with
693 other than one argument or if called with an object which is not an
694 instance of L{X509}.
695 """
696 context = Context(TLSv1_METHOD)
697 self.assertRaises(TypeError, context.add_extra_chain_cert)
698 self.assertRaises(TypeError, context.add_extra_chain_cert, object())
699 self.assertRaises(TypeError, context.add_extra_chain_cert, object(), object())
700
701
Jean-Paul Calderonef4480622010-08-02 18:25:03 -0400702 def _handshake_test(self, serverContext, clientContext):
703 """
704 Verify that a client and server created with the given contexts can
705 successfully handshake and communicate.
706 """
707 serverSocket, clientSocket = socket_pair()
708
Jean-Paul Calderonebf37f0f2010-07-31 14:56:20 -0400709 server = Connection(serverContext, serverSocket)
Jean-Paul Calderone9485f2c2010-07-29 22:38:42 -0400710 server.set_accept_state()
Jean-Paul Calderonebf37f0f2010-07-31 14:56:20 -0400711
Jean-Paul Calderonef4480622010-08-02 18:25:03 -0400712 client = Connection(clientContext, clientSocket)
713 client.set_connect_state()
714
715 # Make them talk to each other.
716 # self._interactInMemory(client, server)
717 for i in range(3):
718 for s in [client, server]:
719 try:
720 s.do_handshake()
721 except WantReadError:
722 pass
723
724
725 def test_add_extra_chain_cert(self):
726 """
727 L{Context.add_extra_chain_cert} accepts an L{X509} instance to add to
728 the certificate chain.
729
730 See L{_create_certificate_chain} for the details of the certificate
731 chain tested.
732
733 The chain is tested by starting a server with scert and connecting
734 to it with a client which trusts cacert and requires verification to
735 succeed.
736 """
Jean-Paul Calderone20222ae2011-05-19 21:43:46 -0400737 chain = _create_certificate_chain()
Jean-Paul Calderonef4480622010-08-02 18:25:03 -0400738 [(cakey, cacert), (ikey, icert), (skey, scert)] = chain
739
Jean-Paul Calderonebf37f0f2010-07-31 14:56:20 -0400740 # Dump the CA certificate to a file because that's the only way to load
741 # it as a trusted CA in the client context.
742 for cert, name in [(cacert, 'ca.pem'), (icert, 'i.pem'), (scert, 's.pem')]:
Jean-Paul Calderonea9868832010-08-22 21:38:34 -0400743 fObj = open(name, 'w')
Jean-Paul Calderoneb1f7f5f2010-08-22 21:40:52 -0400744 fObj.write(dump_certificate(FILETYPE_PEM, cert).decode('ascii'))
Jean-Paul Calderonebf37f0f2010-07-31 14:56:20 -0400745 fObj.close()
746
747 for key, name in [(cakey, 'ca.key'), (ikey, 'i.key'), (skey, 's.key')]:
Jean-Paul Calderonea9868832010-08-22 21:38:34 -0400748 fObj = open(name, 'w')
Jean-Paul Calderoneb1f7f5f2010-08-22 21:40:52 -0400749 fObj.write(dump_privatekey(FILETYPE_PEM, key).decode('ascii'))
Jean-Paul Calderonebf37f0f2010-07-31 14:56:20 -0400750 fObj.close()
751
Jean-Paul Calderonef4480622010-08-02 18:25:03 -0400752 # Create the server context
753 serverContext = Context(TLSv1_METHOD)
754 serverContext.use_privatekey(skey)
755 serverContext.use_certificate(scert)
Jean-Paul Calderone16cf03d2010-09-08 18:53:39 -0400756 # The client already has cacert, we only need to give them icert.
Jean-Paul Calderonef4480622010-08-02 18:25:03 -0400757 serverContext.add_extra_chain_cert(icert)
758
Jean-Paul Calderonebf37f0f2010-07-31 14:56:20 -0400759 # Create the client
760 clientContext = Context(TLSv1_METHOD)
761 clientContext.set_verify(
762 VERIFY_PEER | VERIFY_FAIL_IF_NO_PEER_CERT, verify_cb)
763 clientContext.load_verify_locations('ca.pem')
Jean-Paul Calderone9485f2c2010-07-29 22:38:42 -0400764
Jean-Paul Calderonef4480622010-08-02 18:25:03 -0400765 # Try it out.
766 self._handshake_test(serverContext, clientContext)
767
768
Jean-Paul Calderonef4480622010-08-02 18:25:03 -0400769 def test_use_certificate_chain_file(self):
770 """
771 L{Context.use_certificate_chain_file} reads a certificate chain from
772 the specified file.
773
774 The chain is tested by starting a server with scert and connecting
775 to it with a client which trusts cacert and requires verification to
776 succeed.
777 """
Jean-Paul Calderone20222ae2011-05-19 21:43:46 -0400778 chain = _create_certificate_chain()
Jean-Paul Calderonef4480622010-08-02 18:25:03 -0400779 [(cakey, cacert), (ikey, icert), (skey, scert)] = chain
780
781 # Write out the chain file.
782 chainFile = self.mktemp()
Jean-Paul Calderonea9868832010-08-22 21:38:34 -0400783 fObj = open(chainFile, 'w')
Jean-Paul Calderonef4480622010-08-02 18:25:03 -0400784 # Most specific to least general.
Jean-Paul Calderonea9868832010-08-22 21:38:34 -0400785 fObj.write(dump_certificate(FILETYPE_PEM, scert).decode('ascii'))
786 fObj.write(dump_certificate(FILETYPE_PEM, icert).decode('ascii'))
787 fObj.write(dump_certificate(FILETYPE_PEM, cacert).decode('ascii'))
Jean-Paul Calderonef4480622010-08-02 18:25:03 -0400788 fObj.close()
789
790 serverContext = Context(TLSv1_METHOD)
791 serverContext.use_certificate_chain_file(chainFile)
792 serverContext.use_privatekey(skey)
793
Jean-Paul Calderonea9868832010-08-22 21:38:34 -0400794 fObj = open('ca.pem', 'w')
795 fObj.write(dump_certificate(FILETYPE_PEM, cacert).decode('ascii'))
Jean-Paul Calderonef4480622010-08-02 18:25:03 -0400796 fObj.close()
797
798 clientContext = Context(TLSv1_METHOD)
799 clientContext.set_verify(
800 VERIFY_PEER | VERIFY_FAIL_IF_NO_PEER_CERT, verify_cb)
801 clientContext.load_verify_locations('ca.pem')
802
803 self._handshake_test(serverContext, clientContext)
804
Jean-Paul Calderonee0d79362010-08-03 18:46:46 -0400805 # XXX load_client_ca
806 # XXX set_session_id
Jean-Paul Calderone0294e3d2010-09-09 18:17:48 -0400807
808 def test_get_verify_mode_wrong_args(self):
809 """
810 L{Context.get_verify_mode} raises L{TypeError} if called with any
811 arguments.
812 """
813 context = Context(TLSv1_METHOD)
814 self.assertRaises(TypeError, context.get_verify_mode, None)
815
816
817 def test_get_verify_mode(self):
818 """
819 L{Context.get_verify_mode} returns the verify mode flags previously
820 passed to L{Context.set_verify}.
821 """
822 context = Context(TLSv1_METHOD)
823 self.assertEquals(context.get_verify_mode(), 0)
824 context.set_verify(
825 VERIFY_PEER | VERIFY_CLIENT_ONCE, lambda *args: None)
826 self.assertEquals(
827 context.get_verify_mode(), VERIFY_PEER | VERIFY_CLIENT_ONCE)
828
Jean-Paul Calderone6ace4782010-09-09 18:43:40 -0400829
830 def test_load_tmp_dh_wrong_args(self):
831 """
832 L{Context.load_tmp_dh} raises L{TypeError} if called with the wrong
833 number of arguments or with a non-C{str} argument.
834 """
835 context = Context(TLSv1_METHOD)
836 self.assertRaises(TypeError, context.load_tmp_dh)
837 self.assertRaises(TypeError, context.load_tmp_dh, "foo", None)
838 self.assertRaises(TypeError, context.load_tmp_dh, object())
839
840
841 def test_load_tmp_dh_missing_file(self):
842 """
843 L{Context.load_tmp_dh} raises L{OpenSSL.SSL.Error} if the specified file
844 does not exist.
845 """
846 context = Context(TLSv1_METHOD)
847 self.assertRaises(Error, context.load_tmp_dh, "hello")
848
849
850 def test_load_tmp_dh(self):
851 """
852 L{Context.load_tmp_dh} loads Diffie-Hellman parameters from the
853 specified file.
854 """
855 context = Context(TLSv1_METHOD)
856 dhfilename = self.mktemp()
857 dhfile = open(dhfilename, "w")
858 dhfile.write(dhparam)
859 dhfile.close()
860 context.load_tmp_dh(dhfilename)
861 # XXX What should I assert here? -exarkun
862
863
864 def test_set_cipher_list(self):
865 """
866 L{Context.set_cipher_list} accepts a C{str} naming the ciphers which
867 connections created with the context object will be able to choose from.
868 """
869 context = Context(TLSv1_METHOD)
870 context.set_cipher_list("hello world:EXP-RC4-MD5")
871 conn = Connection(context, None)
872 self.assertEquals(conn.get_cipher_list(), ["EXP-RC4-MD5"])
Jean-Paul Calderone9485f2c2010-07-29 22:38:42 -0400873
Jean-Paul Calderone9485f2c2010-07-29 22:38:42 -0400874
875
876class ConnectionTests(TestCase, _LoopbackMixin):
Rick Deane15b1472009-07-09 15:53:42 -0500877 """
878 Unit tests for L{OpenSSL.SSL.Connection}.
879 """
Jean-Paul Calderone541eaf22010-09-09 18:55:08 -0400880 # XXX want_write
881 # XXX want_read
882 # XXX get_peer_certificate -> None
883 # XXX sock_shutdown
884 # XXX master_key -> TypeError
885 # XXX server_random -> TypeError
886 # XXX state_string
887 # XXX connect -> TypeError
888 # XXX connect_ex -> TypeError
889 # XXX set_connect_state -> TypeError
890 # XXX set_accept_state -> TypeError
891 # XXX renegotiate_pending
892 # XXX do_handshake -> TypeError
893 # XXX bio_read -> TypeError
894 # XXX recv -> TypeError
895 # XXX send -> TypeError
896 # XXX bio_write -> TypeError
897
Rick Deane15b1472009-07-09 15:53:42 -0500898 def test_type(self):
899 """
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400900 L{Connection} and L{ConnectionType} refer to the same type object and
901 can be used to create instances of that type.
Rick Deane15b1472009-07-09 15:53:42 -0500902 """
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400903 self.assertIdentical(Connection, ConnectionType)
Rick Deane15b1472009-07-09 15:53:42 -0500904 ctx = Context(TLSv1_METHOD)
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400905 self.assertConsistentType(Connection, 'Connection', ctx, None)
Rick Deane15b1472009-07-09 15:53:42 -0500906
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400907
Jean-Paul Calderone4fd058a2009-11-22 11:46:42 -0500908 def test_get_context(self):
909 """
910 L{Connection.get_context} returns the L{Context} instance used to
911 construct the L{Connection} instance.
912 """
913 context = Context(TLSv1_METHOD)
914 connection = Connection(context, None)
915 self.assertIdentical(connection.get_context(), context)
916
917
918 def test_get_context_wrong_args(self):
919 """
920 L{Connection.get_context} raises L{TypeError} if called with any
921 arguments.
922 """
923 connection = Connection(Context(TLSv1_METHOD), None)
924 self.assertRaises(TypeError, connection.get_context, None)
925
926
Jean-Paul Calderone95613b72011-05-25 22:30:21 -0400927 def test_set_context_wrong_args(self):
928 """
929 L{Connection.set_context} raises L{TypeError} if called with a
930 non-L{Context} instance argument or with any number of arguments other
931 than 1.
932 """
933 ctx = Context(TLSv1_METHOD)
934 connection = Connection(ctx, None)
935 self.assertRaises(TypeError, connection.set_context)
936 self.assertRaises(TypeError, connection.set_context, object())
937 self.assertRaises(TypeError, connection.set_context, "hello")
938 self.assertRaises(TypeError, connection.set_context, 1)
939 self.assertRaises(TypeError, connection.set_context, 1, 2)
940 self.assertRaises(
941 TypeError, connection.set_context, Context(TLSv1_METHOD), 2)
942 self.assertIdentical(ctx, connection.get_context())
943
944
945 def test_set_context(self):
946 """
947 L{Connection.set_context} specifies a new L{Context} instance to be used
948 for the connection.
949 """
950 original = Context(SSLv23_METHOD)
951 replacement = Context(TLSv1_METHOD)
952 connection = Connection(original, None)
953 connection.set_context(replacement)
954 self.assertIdentical(replacement, connection.get_context())
955 # Lose our references to the contexts, just in case the Connection isn't
956 # properly managing its own contributions to their reference counts.
957 del original, replacement
958 import gc
959 gc.collect()
960
961
Jean-Paul Calderone1d69a722010-07-29 09:05:53 -0400962 def test_pending(self):
Jean-Paul Calderone93dba222010-09-08 22:59:37 -0400963 """
964 L{Connection.pending} returns the number of bytes available for
965 immediate read.
966 """
Jean-Paul Calderone1d69a722010-07-29 09:05:53 -0400967 connection = Connection(Context(TLSv1_METHOD), None)
968 self.assertEquals(connection.pending(), 0)
969
970
971 def test_pending_wrong_args(self):
Jean-Paul Calderone93dba222010-09-08 22:59:37 -0400972 """
973 L{Connection.pending} raises L{TypeError} if called with any arguments.
974 """
Jean-Paul Calderone1d69a722010-07-29 09:05:53 -0400975 connection = Connection(Context(TLSv1_METHOD), None)
976 self.assertRaises(TypeError, connection.pending, None)
977
978
Jean-Paul Calderonecfecc242010-07-29 22:47:06 -0400979 def test_connect_wrong_args(self):
Jean-Paul Calderone93dba222010-09-08 22:59:37 -0400980 """
981 L{Connection.connect} raises L{TypeError} if called with a non-address
982 argument or with the wrong number of arguments.
983 """
Jean-Paul Calderonecfecc242010-07-29 22:47:06 -0400984 connection = Connection(Context(TLSv1_METHOD), socket())
985 self.assertRaises(TypeError, connection.connect, None)
Jean-Paul Calderone93dba222010-09-08 22:59:37 -0400986 self.assertRaises(TypeError, connection.connect)
987 self.assertRaises(TypeError, connection.connect, ("127.0.0.1", 1), None)
Jean-Paul Calderonecfecc242010-07-29 22:47:06 -0400988
989
Jean-Paul Calderone8bdeba22010-07-29 09:45:07 -0400990 def test_connect_refused(self):
Jean-Paul Calderone93dba222010-09-08 22:59:37 -0400991 """
992 L{Connection.connect} raises L{socket.error} if the underlying socket
993 connect method raises it.
994 """
Jean-Paul Calderone8bdeba22010-07-29 09:45:07 -0400995 client = socket()
996 context = Context(TLSv1_METHOD)
997 clientSSL = Connection(context, client)
998 exc = self.assertRaises(error, clientSSL.connect, ("127.0.0.1", 1))
Jean-Paul Calderone35adf9d2010-07-29 18:40:44 -0400999 self.assertEquals(exc.args[0], ECONNREFUSED)
Jean-Paul Calderone8bdeba22010-07-29 09:45:07 -04001000
1001
1002 def test_connect(self):
Jean-Paul Calderone93dba222010-09-08 22:59:37 -04001003 """
1004 L{Connection.connect} establishes a connection to the specified address.
1005 """
Jean-Paul Calderone0bcb0e02010-07-29 09:49:59 -04001006 port = socket()
1007 port.bind(('', 0))
1008 port.listen(3)
1009
1010 clientSSL = Connection(Context(TLSv1_METHOD), socket())
Jean-Paul Calderoneb6e0fd92010-09-19 09:22:13 -04001011 clientSSL.connect(('127.0.0.1', port.getsockname()[1]))
1012 # XXX An assertion? Or something?
Jean-Paul Calderone0bcb0e02010-07-29 09:49:59 -04001013
1014
Jean-Paul Calderone7b614872010-09-24 17:43:44 -04001015 if platform == "darwin":
1016 "connect_ex sometimes causes a kernel panic on OS X 10.6.4"
1017 else:
1018 def test_connect_ex(self):
1019 """
1020 If there is a connection error, L{Connection.connect_ex} returns the
1021 errno instead of raising an exception.
1022 """
1023 port = socket()
1024 port.bind(('', 0))
1025 port.listen(3)
Jean-Paul Calderone55d91f42010-07-29 19:22:17 -04001026
Jean-Paul Calderone7b614872010-09-24 17:43:44 -04001027 clientSSL = Connection(Context(TLSv1_METHOD), socket())
1028 clientSSL.setblocking(False)
1029 result = clientSSL.connect_ex(port.getsockname())
1030 expected = (EINPROGRESS, EWOULDBLOCK)
1031 self.assertTrue(
1032 result in expected, "%r not in %r" % (result, expected))
Jean-Paul Calderone55d91f42010-07-29 19:22:17 -04001033
1034
Jean-Paul Calderonecfecc242010-07-29 22:47:06 -04001035 def test_accept_wrong_args(self):
Jean-Paul Calderone93dba222010-09-08 22:59:37 -04001036 """
1037 L{Connection.accept} raises L{TypeError} if called with any arguments.
1038 """
Jean-Paul Calderonecfecc242010-07-29 22:47:06 -04001039 connection = Connection(Context(TLSv1_METHOD), socket())
1040 self.assertRaises(TypeError, connection.accept, None)
1041
1042
Jean-Paul Calderone0bcb0e02010-07-29 09:49:59 -04001043 def test_accept(self):
Jean-Paul Calderone93dba222010-09-08 22:59:37 -04001044 """
1045 L{Connection.accept} accepts a pending connection attempt and returns a
1046 tuple of a new L{Connection} (the accepted client) and the address the
1047 connection originated from.
1048 """
Jean-Paul Calderone8bdeba22010-07-29 09:45:07 -04001049 ctx = Context(TLSv1_METHOD)
1050 ctx.use_privatekey(load_privatekey(FILETYPE_PEM, server_key_pem))
1051 ctx.use_certificate(load_certificate(FILETYPE_PEM, server_cert_pem))
Jean-Paul Calderone0bcb0e02010-07-29 09:49:59 -04001052 port = socket()
1053 portSSL = Connection(ctx, port)
1054 portSSL.bind(('', 0))
1055 portSSL.listen(3)
Jean-Paul Calderone8bdeba22010-07-29 09:45:07 -04001056
Jean-Paul Calderone0bcb0e02010-07-29 09:49:59 -04001057 clientSSL = Connection(Context(TLSv1_METHOD), socket())
Jean-Paul Calderoneb6e0fd92010-09-19 09:22:13 -04001058
1059 # Calling portSSL.getsockname() here to get the server IP address sounds
1060 # great, but frequently fails on Windows.
1061 clientSSL.connect(('127.0.0.1', portSSL.getsockname()[1]))
Jean-Paul Calderone8bdeba22010-07-29 09:45:07 -04001062
Jean-Paul Calderone0bcb0e02010-07-29 09:49:59 -04001063 serverSSL, address = portSSL.accept()
1064
1065 self.assertTrue(isinstance(serverSSL, Connection))
1066 self.assertIdentical(serverSSL.get_context(), ctx)
1067 self.assertEquals(address, clientSSL.getsockname())
Jean-Paul Calderone8bdeba22010-07-29 09:45:07 -04001068
1069
Jean-Paul Calderonecfecc242010-07-29 22:47:06 -04001070 def test_shutdown_wrong_args(self):
Jean-Paul Calderone93dba222010-09-08 22:59:37 -04001071 """
1072 L{Connection.shutdown} raises L{TypeError} if called with the wrong
1073 number of arguments or with arguments other than integers.
1074 """
Jean-Paul Calderonecfecc242010-07-29 22:47:06 -04001075 connection = Connection(Context(TLSv1_METHOD), None)
1076 self.assertRaises(TypeError, connection.shutdown, None)
Jean-Paul Calderone1d3e0222010-07-29 22:52:45 -04001077 self.assertRaises(TypeError, connection.get_shutdown, None)
1078 self.assertRaises(TypeError, connection.set_shutdown)
1079 self.assertRaises(TypeError, connection.set_shutdown, None)
1080 self.assertRaises(TypeError, connection.set_shutdown, 0, 1)
Jean-Paul Calderonecfecc242010-07-29 22:47:06 -04001081
1082
Jean-Paul Calderone9485f2c2010-07-29 22:38:42 -04001083 def test_shutdown(self):
Jean-Paul Calderone93dba222010-09-08 22:59:37 -04001084 """
1085 L{Connection.shutdown} performs an SSL-level connection shutdown.
1086 """
Jean-Paul Calderone9485f2c2010-07-29 22:38:42 -04001087 server, client = self._loopback()
Jean-Paul Calderonee4f6b472010-07-29 22:50:58 -04001088 self.assertFalse(server.shutdown())
1089 self.assertEquals(server.get_shutdown(), SENT_SHUTDOWN)
Jean-Paul Calderone9485f2c2010-07-29 22:38:42 -04001090 self.assertRaises(ZeroReturnError, client.recv, 1024)
Jean-Paul Calderonee4f6b472010-07-29 22:50:58 -04001091 self.assertEquals(client.get_shutdown(), RECEIVED_SHUTDOWN)
1092 client.shutdown()
1093 self.assertEquals(client.get_shutdown(), SENT_SHUTDOWN|RECEIVED_SHUTDOWN)
1094 self.assertRaises(ZeroReturnError, server.recv, 1024)
1095 self.assertEquals(server.get_shutdown(), SENT_SHUTDOWN|RECEIVED_SHUTDOWN)
Jean-Paul Calderone9485f2c2010-07-29 22:38:42 -04001096
1097
Jean-Paul Calderonec89eef22010-07-29 22:51:58 -04001098 def test_set_shutdown(self):
Jean-Paul Calderone93dba222010-09-08 22:59:37 -04001099 """
1100 L{Connection.set_shutdown} sets the state of the SSL connection shutdown
1101 process.
1102 """
Jean-Paul Calderonec89eef22010-07-29 22:51:58 -04001103 connection = Connection(Context(TLSv1_METHOD), socket())
1104 connection.set_shutdown(RECEIVED_SHUTDOWN)
1105 self.assertEquals(connection.get_shutdown(), RECEIVED_SHUTDOWN)
1106
1107
Jean-Paul Calderonecfecc242010-07-29 22:47:06 -04001108 def test_app_data_wrong_args(self):
Jean-Paul Calderone93dba222010-09-08 22:59:37 -04001109 """
1110 L{Connection.set_app_data} raises L{TypeError} if called with other than
1111 one argument. L{Connection.get_app_data} raises L{TypeError} if called
1112 with any arguments.
1113 """
Jean-Paul Calderonecfecc242010-07-29 22:47:06 -04001114 conn = Connection(Context(TLSv1_METHOD), None)
1115 self.assertRaises(TypeError, conn.get_app_data, None)
1116 self.assertRaises(TypeError, conn.set_app_data)
1117 self.assertRaises(TypeError, conn.set_app_data, None, None)
1118
1119
Jean-Paul Calderone1bd8c792010-07-29 09:51:06 -04001120 def test_app_data(self):
Jean-Paul Calderone93dba222010-09-08 22:59:37 -04001121 """
1122 Any object can be set as app data by passing it to
1123 L{Connection.set_app_data} and later retrieved with
1124 L{Connection.get_app_data}.
1125 """
Jean-Paul Calderone1bd8c792010-07-29 09:51:06 -04001126 conn = Connection(Context(TLSv1_METHOD), None)
1127 app_data = object()
1128 conn.set_app_data(app_data)
1129 self.assertIdentical(conn.get_app_data(), app_data)
1130
1131
Jean-Paul Calderonecfecc242010-07-29 22:47:06 -04001132 def test_makefile(self):
Jean-Paul Calderone93dba222010-09-08 22:59:37 -04001133 """
1134 L{Connection.makefile} is not implemented and calling that method raises
1135 L{NotImplementedError}.
1136 """
Jean-Paul Calderonecfecc242010-07-29 22:47:06 -04001137 conn = Connection(Context(TLSv1_METHOD), None)
1138 self.assertRaises(NotImplementedError, conn.makefile)
1139
1140
Jean-Paul Calderone20222ae2011-05-19 21:43:46 -04001141 def test_get_peer_cert_chain_wrong_args(self):
1142 """
1143 L{Connection.get_peer_cert_chain} raises L{TypeError} if called with any
1144 arguments.
1145 """
1146 conn = Connection(Context(TLSv1_METHOD), None)
1147 self.assertRaises(TypeError, conn.get_peer_cert_chain, 1)
1148 self.assertRaises(TypeError, conn.get_peer_cert_chain, "foo")
1149 self.assertRaises(TypeError, conn.get_peer_cert_chain, object())
1150 self.assertRaises(TypeError, conn.get_peer_cert_chain, [])
1151
1152
1153 def test_get_peer_cert_chain(self):
1154 """
1155 L{Connection.get_peer_cert_chain} returns a list of certificates which
1156 the connected server returned for the certification verification.
1157 """
1158 chain = _create_certificate_chain()
1159 [(cakey, cacert), (ikey, icert), (skey, scert)] = chain
1160
1161 serverContext = Context(TLSv1_METHOD)
1162 serverContext.use_privatekey(skey)
1163 serverContext.use_certificate(scert)
1164 serverContext.add_extra_chain_cert(icert)
1165 serverContext.add_extra_chain_cert(cacert)
1166 server = Connection(serverContext, None)
1167 server.set_accept_state()
1168
1169 # Create the client
1170 clientContext = Context(TLSv1_METHOD)
1171 clientContext.set_verify(VERIFY_NONE, verify_cb)
1172 client = Connection(clientContext, None)
1173 client.set_connect_state()
1174
1175 self._interactInMemory(client, server)
1176
1177 chain = client.get_peer_cert_chain()
1178 self.assertEqual(len(chain), 3)
Jean-Paul Calderonee33300c2011-05-19 21:44:38 -04001179 self.assertEqual(
Jean-Paul Calderone24a42432011-05-19 22:21:18 -04001180 "Server Certificate", chain[0].get_subject().CN)
Jean-Paul Calderonee33300c2011-05-19 21:44:38 -04001181 self.assertEqual(
Jean-Paul Calderone24a42432011-05-19 22:21:18 -04001182 "Intermediate Certificate", chain[1].get_subject().CN)
Jean-Paul Calderonee33300c2011-05-19 21:44:38 -04001183 self.assertEqual(
Jean-Paul Calderone24a42432011-05-19 22:21:18 -04001184 "Authority Certificate", chain[2].get_subject().CN)
1185
1186
1187 def test_get_peer_cert_chain_none(self):
1188 """
1189 L{Connection.get_peer_cert_chain} returns C{None} if the peer sends no
1190 certificate chain.
1191 """
1192 ctx = Context(TLSv1_METHOD)
1193 ctx.use_privatekey(load_privatekey(FILETYPE_PEM, server_key_pem))
1194 ctx.use_certificate(load_certificate(FILETYPE_PEM, server_cert_pem))
1195 server = Connection(ctx, None)
1196 server.set_accept_state()
1197 client = Connection(Context(TLSv1_METHOD), None)
1198 client.set_connect_state()
1199 self._interactInMemory(client, server)
1200 self.assertIdentical(None, server.get_peer_cert_chain())
Jean-Paul Calderone20222ae2011-05-19 21:43:46 -04001201
1202
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001203
Jean-Paul Calderonef135e622010-07-28 19:14:16 -04001204class ConnectionGetCipherListTests(TestCase):
Jean-Paul Calderonea8fb0c82010-09-09 18:04:56 -04001205 """
1206 Tests for L{Connection.get_cipher_list}.
1207 """
Jean-Paul Calderone54a2bc02010-09-09 17:52:38 -04001208 def test_wrong_args(self):
Jean-Paul Calderonea8fb0c82010-09-09 18:04:56 -04001209 """
1210 L{Connection.get_cipher_list} raises L{TypeError} if called with any
1211 arguments.
1212 """
Jean-Paul Calderonef135e622010-07-28 19:14:16 -04001213 connection = Connection(Context(TLSv1_METHOD), None)
1214 self.assertRaises(TypeError, connection.get_cipher_list, None)
1215
1216
1217 def test_result(self):
Jean-Paul Calderonea8fb0c82010-09-09 18:04:56 -04001218 """
1219 L{Connection.get_cipher_list} returns a C{list} of C{str} giving the
1220 names of the ciphers which might be used.
1221 """
Jean-Paul Calderonef135e622010-07-28 19:14:16 -04001222 connection = Connection(Context(TLSv1_METHOD), None)
1223 ciphers = connection.get_cipher_list()
1224 self.assertTrue(isinstance(ciphers, list))
1225 for cipher in ciphers:
1226 self.assertTrue(isinstance(cipher, str))
1227
1228
1229
Jean-Paul Calderone9cbbe262011-01-05 14:53:43 -05001230class ConnectionSendTests(TestCase, _LoopbackMixin):
1231 """
1232 Tests for L{Connection.send}
1233 """
1234 def test_wrong_args(self):
1235 """
1236 When called with arguments other than a single string,
Jean-Paul Calderone77fa2602011-01-05 18:23:39 -05001237 L{Connection.send} raises L{TypeError}.
Jean-Paul Calderone9cbbe262011-01-05 14:53:43 -05001238 """
1239 connection = Connection(Context(TLSv1_METHOD), None)
Jean-Paul Calderone77fa2602011-01-05 18:23:39 -05001240 self.assertRaises(TypeError, connection.send)
1241 self.assertRaises(TypeError, connection.send, object())
1242 self.assertRaises(TypeError, connection.send, "foo", "bar")
Jean-Paul Calderone9cbbe262011-01-05 14:53:43 -05001243
1244
1245 def test_short_bytes(self):
1246 """
1247 When passed a short byte string, L{Connection.send} transmits all of it
1248 and returns the number of bytes sent.
1249 """
1250 server, client = self._loopback()
1251 count = server.send(b('xy'))
1252 self.assertEquals(count, 2)
1253 self.assertEquals(client.recv(2), b('xy'))
1254
1255 try:
1256 memoryview
1257 except NameError:
1258 "cannot test sending memoryview without memoryview"
1259 else:
1260 def test_short_memoryview(self):
1261 """
1262 When passed a memoryview onto a small number of bytes,
1263 L{Connection.send} transmits all of them and returns the number of
1264 bytes sent.
1265 """
1266 server, client = self._loopback()
1267 count = server.send(memoryview(b('xy')))
1268 self.assertEquals(count, 2)
1269 self.assertEquals(client.recv(2), b('xy'))
1270
1271
Jean-Paul Calderone691e6c92011-01-21 22:04:35 -05001272
Jean-Paul Calderone8ea22522010-07-29 09:39:39 -04001273class ConnectionSendallTests(TestCase, _LoopbackMixin):
1274 """
1275 Tests for L{Connection.sendall}.
1276 """
Jean-Paul Calderonea8fb0c82010-09-09 18:04:56 -04001277 def test_wrong_args(self):
Jean-Paul Calderone8ea22522010-07-29 09:39:39 -04001278 """
1279 When called with arguments other than a single string,
1280 L{Connection.sendall} raises L{TypeError}.
1281 """
1282 connection = Connection(Context(TLSv1_METHOD), None)
1283 self.assertRaises(TypeError, connection.sendall)
1284 self.assertRaises(TypeError, connection.sendall, object())
1285 self.assertRaises(TypeError, connection.sendall, "foo", "bar")
1286
1287
Jean-Paul Calderone7ca48b52010-07-28 18:57:21 -04001288 def test_short(self):
1289 """
1290 L{Connection.sendall} transmits all of the bytes in the string passed to
1291 it.
1292 """
1293 server, client = self._loopback()
Jean-Paul Calderonea9868832010-08-22 21:38:34 -04001294 server.sendall(b('x'))
1295 self.assertEquals(client.recv(1), b('x'))
Jean-Paul Calderone7ca48b52010-07-28 18:57:21 -04001296
1297
Jean-Paul Calderone691e6c92011-01-21 22:04:35 -05001298 try:
1299 memoryview
1300 except NameError:
1301 "cannot test sending memoryview without memoryview"
1302 else:
1303 def test_short_memoryview(self):
1304 """
1305 When passed a memoryview onto a small number of bytes,
1306 L{Connection.sendall} transmits all of them.
1307 """
1308 server, client = self._loopback()
1309 server.sendall(memoryview(b('x')))
1310 self.assertEquals(client.recv(1), b('x'))
1311
1312
Jean-Paul Calderone7ca48b52010-07-28 18:57:21 -04001313 def test_long(self):
Jean-Paul Calderonea8fb0c82010-09-09 18:04:56 -04001314 """
1315 L{Connection.sendall} transmits all of the bytes in the string passed to
1316 it even if this requires multiple calls of an underlying write function.
1317 """
Jean-Paul Calderone7ca48b52010-07-28 18:57:21 -04001318 server, client = self._loopback()
Jean-Paul Calderone6241c702010-09-16 19:59:24 -04001319 # Should be enough, underlying SSL_write should only do 16k at a time.
1320 # On Windows, after 32k of bytes the write will block (forever - because
1321 # no one is yet reading).
Jean-Paul Calderone9e4c1352010-09-19 09:34:43 -04001322 message = b('x') * (1024 * 32 - 1) + b('y')
Jean-Paul Calderone7ca48b52010-07-28 18:57:21 -04001323 server.sendall(message)
1324 accum = []
1325 received = 0
1326 while received < len(message):
Jean-Paul Calderoneb1f7f5f2010-08-22 21:40:52 -04001327 data = client.recv(1024)
1328 accum.append(data)
1329 received += len(data)
Jean-Paul Calderonef4047852010-09-19 09:45:57 -04001330 self.assertEquals(message, b('').join(accum))
Jean-Paul Calderone7ca48b52010-07-28 18:57:21 -04001331
1332
Jean-Paul Calderone974bdc02010-07-28 19:06:10 -04001333 def test_closed(self):
1334 """
1335 If the underlying socket is closed, L{Connection.sendall} propagates the
1336 write error from the low level write call.
1337 """
1338 server, client = self._loopback()
Jean-Paul Calderone05d43e82010-09-24 18:01:36 -04001339 server.sock_shutdown(2)
Jean-Paul Calderone974bdc02010-07-28 19:06:10 -04001340 self.assertRaises(SysCallError, server.sendall, "hello, world")
1341
Jean-Paul Calderone7ca48b52010-07-28 18:57:21 -04001342
Jean-Paul Calderone1d69a722010-07-29 09:05:53 -04001343
Jean-Paul Calderone8ea22522010-07-29 09:39:39 -04001344class ConnectionRenegotiateTests(TestCase, _LoopbackMixin):
1345 """
1346 Tests for SSL renegotiation APIs.
1347 """
1348 def test_renegotiate_wrong_args(self):
Jean-Paul Calderonea8fb0c82010-09-09 18:04:56 -04001349 """
1350 L{Connection.renegotiate} raises L{TypeError} if called with any
1351 arguments.
1352 """
Jean-Paul Calderone8ea22522010-07-29 09:39:39 -04001353 connection = Connection(Context(TLSv1_METHOD), None)
1354 self.assertRaises(TypeError, connection.renegotiate, None)
1355
1356
Jean-Paul Calderonecfecc242010-07-29 22:47:06 -04001357 def test_total_renegotiations_wrong_args(self):
Jean-Paul Calderonea8fb0c82010-09-09 18:04:56 -04001358 """
1359 L{Connection.total_renegotiations} raises L{TypeError} if called with
1360 any arguments.
1361 """
Jean-Paul Calderonecfecc242010-07-29 22:47:06 -04001362 connection = Connection(Context(TLSv1_METHOD), None)
1363 self.assertRaises(TypeError, connection.total_renegotiations, None)
1364
1365
1366 def test_total_renegotiations(self):
Jean-Paul Calderonea8fb0c82010-09-09 18:04:56 -04001367 """
1368 L{Connection.total_renegotiations} returns C{0} before any
1369 renegotiations have happened.
1370 """
Jean-Paul Calderonecfecc242010-07-29 22:47:06 -04001371 connection = Connection(Context(TLSv1_METHOD), None)
1372 self.assertEquals(connection.total_renegotiations(), 0)
1373
1374
Jean-Paul Calderone8ea22522010-07-29 09:39:39 -04001375# def test_renegotiate(self):
1376# """
1377# """
1378# server, client = self._loopback()
1379
1380# server.send("hello world")
1381# self.assertEquals(client.recv(len("hello world")), "hello world")
1382
1383# self.assertEquals(server.total_renegotiations(), 0)
1384# self.assertTrue(server.renegotiate())
1385
1386# server.setblocking(False)
1387# client.setblocking(False)
1388# while server.renegotiate_pending():
1389# client.do_handshake()
1390# server.do_handshake()
1391
1392# self.assertEquals(server.total_renegotiations(), 1)
1393
1394
1395
1396
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001397class ErrorTests(TestCase):
1398 """
1399 Unit tests for L{OpenSSL.SSL.Error}.
1400 """
1401 def test_type(self):
1402 """
1403 L{Error} is an exception type.
1404 """
1405 self.assertTrue(issubclass(Error, Exception))
Rick Deane15b1472009-07-09 15:53:42 -05001406 self.assertEqual(Error.__name__, 'Error')
Rick Deane15b1472009-07-09 15:53:42 -05001407
1408
1409
Jean-Paul Calderone327d8f92008-12-28 21:55:56 -05001410class ConstantsTests(TestCase):
1411 """
1412 Tests for the values of constants exposed in L{OpenSSL.SSL}.
1413
1414 These are values defined by OpenSSL intended only to be used as flags to
1415 OpenSSL APIs. The only assertions it seems can be made about them is
1416 their values.
1417 """
Jean-Paul Calderoned811b682008-12-28 22:59:15 -05001418 # unittest.TestCase has no skip mechanism
1419 if OP_NO_QUERY_MTU is not None:
1420 def test_op_no_query_mtu(self):
1421 """
1422 The value of L{OpenSSL.SSL.OP_NO_QUERY_MTU} is 0x1000, the value of
1423 I{SSL_OP_NO_QUERY_MTU} defined by I{openssl/ssl.h}.
1424 """
1425 self.assertEqual(OP_NO_QUERY_MTU, 0x1000)
1426 else:
1427 "OP_NO_QUERY_MTU unavailable - OpenSSL version may be too old"
Jean-Paul Calderone327d8f92008-12-28 21:55:56 -05001428
1429
Jean-Paul Calderoned811b682008-12-28 22:59:15 -05001430 if OP_COOKIE_EXCHANGE is not None:
1431 def test_op_cookie_exchange(self):
1432 """
1433 The value of L{OpenSSL.SSL.OP_COOKIE_EXCHANGE} is 0x2000, the value
1434 of I{SSL_OP_COOKIE_EXCHANGE} defined by I{openssl/ssl.h}.
1435 """
1436 self.assertEqual(OP_COOKIE_EXCHANGE, 0x2000)
1437 else:
1438 "OP_COOKIE_EXCHANGE unavailable - OpenSSL version may be too old"
Jean-Paul Calderone327d8f92008-12-28 21:55:56 -05001439
1440
Jean-Paul Calderoned811b682008-12-28 22:59:15 -05001441 if OP_NO_TICKET is not None:
1442 def test_op_no_ticket(self):
1443 """
1444 The value of L{OpenSSL.SSL.OP_NO_TICKET} is 0x4000, the value of
1445 I{SSL_OP_NO_TICKET} defined by I{openssl/ssl.h}.
1446 """
1447 self.assertEqual(OP_NO_TICKET, 0x4000)
1448 else:
1449 "OP_NO_TICKET unavailable - OpenSSL version may be too old"
Rick Dean5b7b6372009-04-01 11:34:06 -05001450
1451
Jean-Paul Calderoneeeee26a2009-04-27 11:24:30 -04001452
Jean-Paul Calderonebf37f0f2010-07-31 14:56:20 -04001453class MemoryBIOTests(TestCase, _LoopbackMixin):
Rick Deanb71c0d22009-04-01 14:09:23 -05001454 """
Jean-Paul Calderone958299e2009-04-27 12:59:12 -04001455 Tests for L{OpenSSL.SSL.Connection} using a memory BIO.
Rick Deanb71c0d22009-04-01 14:09:23 -05001456 """
Jean-Paul Calderonece8324d2009-07-16 12:22:52 -04001457 def _server(self, sock):
1458 """
1459 Create a new server-side SSL L{Connection} object wrapped around
1460 C{sock}.
1461 """
Jean-Paul Calderoneaff0fc42009-04-27 17:13:34 -04001462 # Create the server side Connection. This is mostly setup boilerplate
1463 # - use TLSv1, use a particular certificate, etc.
1464 server_ctx = Context(TLSv1_METHOD)
1465 server_ctx.set_options(OP_NO_SSLv2 | OP_NO_SSLv3 | OP_SINGLE_DH_USE )
1466 server_ctx.set_verify(VERIFY_PEER|VERIFY_FAIL_IF_NO_PEER_CERT|VERIFY_CLIENT_ONCE, verify_cb)
1467 server_store = server_ctx.get_cert_store()
1468 server_ctx.use_privatekey(load_privatekey(FILETYPE_PEM, server_key_pem))
1469 server_ctx.use_certificate(load_certificate(FILETYPE_PEM, server_cert_pem))
1470 server_ctx.check_privatekey()
1471 server_store.add_cert(load_certificate(FILETYPE_PEM, root_cert_pem))
Rick Deanb1ccd562009-07-09 23:52:39 -05001472 # Here the Connection is actually created. If None is passed as the 2nd
1473 # parameter, it indicates a memory BIO should be created.
1474 server_conn = Connection(server_ctx, sock)
Jean-Paul Calderoneaff0fc42009-04-27 17:13:34 -04001475 server_conn.set_accept_state()
1476 return server_conn
1477
1478
Jean-Paul Calderonece8324d2009-07-16 12:22:52 -04001479 def _client(self, sock):
1480 """
1481 Create a new client-side SSL L{Connection} object wrapped around
1482 C{sock}.
1483 """
1484 # Now create the client side Connection. Similar boilerplate to the
1485 # above.
Jean-Paul Calderoneaff0fc42009-04-27 17:13:34 -04001486 client_ctx = Context(TLSv1_METHOD)
1487 client_ctx.set_options(OP_NO_SSLv2 | OP_NO_SSLv3 | OP_SINGLE_DH_USE )
1488 client_ctx.set_verify(VERIFY_PEER|VERIFY_FAIL_IF_NO_PEER_CERT|VERIFY_CLIENT_ONCE, verify_cb)
1489 client_store = client_ctx.get_cert_store()
1490 client_ctx.use_privatekey(load_privatekey(FILETYPE_PEM, client_key_pem))
1491 client_ctx.use_certificate(load_certificate(FILETYPE_PEM, client_cert_pem))
1492 client_ctx.check_privatekey()
1493 client_store.add_cert(load_certificate(FILETYPE_PEM, root_cert_pem))
Rick Deanb1ccd562009-07-09 23:52:39 -05001494 client_conn = Connection(client_ctx, sock)
Jean-Paul Calderoneaff0fc42009-04-27 17:13:34 -04001495 client_conn.set_connect_state()
1496 return client_conn
1497
1498
Jean-Paul Calderonece8324d2009-07-16 12:22:52 -04001499 def test_memoryConnect(self):
Jean-Paul Calderone958299e2009-04-27 12:59:12 -04001500 """
1501 Two L{Connection}s which use memory BIOs can be manually connected by
1502 reading from the output of each and writing those bytes to the input of
1503 the other and in this way establish a connection and exchange
1504 application-level bytes with each other.
1505 """
Jean-Paul Calderonece8324d2009-07-16 12:22:52 -04001506 server_conn = self._server(None)
1507 client_conn = self._client(None)
Rick Deanb71c0d22009-04-01 14:09:23 -05001508
Jean-Paul Calderone958299e2009-04-27 12:59:12 -04001509 # There should be no key or nonces yet.
1510 self.assertIdentical(server_conn.master_key(), None)
1511 self.assertIdentical(server_conn.client_random(), None)
1512 self.assertIdentical(server_conn.server_random(), None)
Rick Deanb71c0d22009-04-01 14:09:23 -05001513
Jean-Paul Calderone958299e2009-04-27 12:59:12 -04001514 # First, the handshake needs to happen. We'll deliver bytes back and
1515 # forth between the client and server until neither of them feels like
1516 # speaking any more.
Jean-Paul Calderonebf37f0f2010-07-31 14:56:20 -04001517 self.assertIdentical(
1518 self._interactInMemory(client_conn, server_conn), None)
Jean-Paul Calderone958299e2009-04-27 12:59:12 -04001519
1520 # Now that the handshake is done, there should be a key and nonces.
1521 self.assertNotIdentical(server_conn.master_key(), None)
1522 self.assertNotIdentical(server_conn.client_random(), None)
1523 self.assertNotIdentical(server_conn.server_random(), None)
Jean-Paul Calderone6c051e62009-07-05 13:50:34 -04001524 self.assertEquals(server_conn.client_random(), client_conn.client_random())
1525 self.assertEquals(server_conn.server_random(), client_conn.server_random())
1526 self.assertNotEquals(server_conn.client_random(), server_conn.server_random())
1527 self.assertNotEquals(client_conn.client_random(), client_conn.server_random())
Jean-Paul Calderone958299e2009-04-27 12:59:12 -04001528
1529 # Here are the bytes we'll try to send.
Jean-Paul Calderonea441fdc2010-08-22 21:33:57 -04001530 important_message = b('One if by land, two if by sea.')
Rick Deanb71c0d22009-04-01 14:09:23 -05001531
Jean-Paul Calderone958299e2009-04-27 12:59:12 -04001532 server_conn.write(important_message)
1533 self.assertEquals(
Jean-Paul Calderonebf37f0f2010-07-31 14:56:20 -04001534 self._interactInMemory(client_conn, server_conn),
Jean-Paul Calderone958299e2009-04-27 12:59:12 -04001535 (client_conn, important_message))
1536
1537 client_conn.write(important_message[::-1])
1538 self.assertEquals(
Jean-Paul Calderonebf37f0f2010-07-31 14:56:20 -04001539 self._interactInMemory(client_conn, server_conn),
Jean-Paul Calderone958299e2009-04-27 12:59:12 -04001540 (server_conn, important_message[::-1]))
Rick Deanb71c0d22009-04-01 14:09:23 -05001541
1542
Jean-Paul Calderonece8324d2009-07-16 12:22:52 -04001543 def test_socketConnect(self):
Rick Deanb1ccd562009-07-09 23:52:39 -05001544 """
Jean-Paul Calderonece8324d2009-07-16 12:22:52 -04001545 Just like L{test_memoryConnect} but with an actual socket.
1546
1547 This is primarily to rule out the memory BIO code as the source of
1548 any problems encountered while passing data over a L{Connection} (if
1549 this test fails, there must be a problem outside the memory BIO
1550 code, as no memory BIO is involved here). Even though this isn't a
1551 memory BIO test, it's convenient to have it here.
Rick Deanb1ccd562009-07-09 23:52:39 -05001552 """
Jean-Paul Calderone06c7cc92010-09-24 23:52:00 -04001553 server_conn, client_conn = self._loopback()
Rick Deanb1ccd562009-07-09 23:52:39 -05001554
Jean-Paul Calderonea441fdc2010-08-22 21:33:57 -04001555 important_message = b("Help me Obi Wan Kenobi, you're my only hope.")
Rick Deanb1ccd562009-07-09 23:52:39 -05001556 client_conn.send(important_message)
1557 msg = server_conn.recv(1024)
1558 self.assertEqual(msg, important_message)
1559
1560 # Again in the other direction, just for fun.
1561 important_message = important_message[::-1]
1562 server_conn.send(important_message)
1563 msg = client_conn.recv(1024)
1564 self.assertEqual(msg, important_message)
1565
1566
Jean-Paul Calderonefc4ed0f2009-04-27 11:51:27 -04001567 def test_socketOverridesMemory(self):
Rick Deanb71c0d22009-04-01 14:09:23 -05001568 """
1569 Test that L{OpenSSL.SSL.bio_read} and L{OpenSSL.SSL.bio_write} don't
1570 work on L{OpenSSL.SSL.Connection}() that use sockets.
1571 """
1572 context = Context(SSLv3_METHOD)
1573 client = socket()
1574 clientSSL = Connection(context, client)
1575 self.assertRaises( TypeError, clientSSL.bio_read, 100)
1576 self.assertRaises( TypeError, clientSSL.bio_write, "foo")
Jean-Paul Calderone07acf3f2009-05-05 13:23:28 -04001577 self.assertRaises( TypeError, clientSSL.bio_shutdown )
Jean-Paul Calderoneaff0fc42009-04-27 17:13:34 -04001578
1579
1580 def test_outgoingOverflow(self):
1581 """
1582 If more bytes than can be written to the memory BIO are passed to
1583 L{Connection.send} at once, the number of bytes which were written is
1584 returned and that many bytes from the beginning of the input can be
1585 read from the other end of the connection.
1586 """
Jean-Paul Calderonece8324d2009-07-16 12:22:52 -04001587 server = self._server(None)
1588 client = self._client(None)
Jean-Paul Calderoneaff0fc42009-04-27 17:13:34 -04001589
Jean-Paul Calderonebf37f0f2010-07-31 14:56:20 -04001590 self._interactInMemory(client, server)
Jean-Paul Calderoneaff0fc42009-04-27 17:13:34 -04001591
1592 size = 2 ** 15
1593 sent = client.send("x" * size)
1594 # Sanity check. We're trying to test what happens when the entire
1595 # input can't be sent. If the entire input was sent, this test is
1596 # meaningless.
1597 self.assertTrue(sent < size)
1598
Jean-Paul Calderonebf37f0f2010-07-31 14:56:20 -04001599 receiver, received = self._interactInMemory(client, server)
Jean-Paul Calderoneaff0fc42009-04-27 17:13:34 -04001600 self.assertIdentical(receiver, server)
1601
1602 # We can rely on all of these bytes being received at once because
1603 # _loopback passes 2 ** 16 to recv - more than 2 ** 15.
1604 self.assertEquals(len(received), sent)
Jean-Paul Calderone3ad85d42009-04-30 20:24:35 -04001605
1606
1607 def test_shutdown(self):
1608 """
1609 L{Connection.bio_shutdown} signals the end of the data stream from
1610 which the L{Connection} reads.
1611 """
Jean-Paul Calderonece8324d2009-07-16 12:22:52 -04001612 server = self._server(None)
Jean-Paul Calderone3ad85d42009-04-30 20:24:35 -04001613 server.bio_shutdown()
1614 e = self.assertRaises(Error, server.recv, 1024)
1615 # We don't want WantReadError or ZeroReturnError or anything - it's a
1616 # handshake failure.
1617 self.assertEquals(e.__class__, Error)
Jean-Paul Calderone0b88b6a2009-07-05 12:44:41 -04001618
1619
Ziga Seilnachtf93bf102009-10-23 09:51:07 +02001620 def _check_client_ca_list(self, func):
Jean-Paul Calderone911c9112009-10-24 11:12:00 -04001621 """
1622 Verify the return value of the C{get_client_ca_list} method for server and client connections.
1623
1624 @param func: A function which will be called with the server context
1625 before the client and server are connected to each other. This
1626 function should specify a list of CAs for the server to send to the
1627 client and return that same list. The list will be used to verify
1628 that C{get_client_ca_list} returns the proper value at various
1629 times.
1630 """
Ziga Seilnacht679c4262009-09-01 01:32:29 +02001631 server = self._server(None)
1632 client = self._client(None)
Ziga Seilnachtf93bf102009-10-23 09:51:07 +02001633 self.assertEqual(client.get_client_ca_list(), [])
1634 self.assertEqual(server.get_client_ca_list(), [])
Ziga Seilnacht679c4262009-09-01 01:32:29 +02001635 ctx = server.get_context()
1636 expected = func(ctx)
Ziga Seilnachtf93bf102009-10-23 09:51:07 +02001637 self.assertEqual(client.get_client_ca_list(), [])
1638 self.assertEqual(server.get_client_ca_list(), expected)
Jean-Paul Calderonebf37f0f2010-07-31 14:56:20 -04001639 self._interactInMemory(client, server)
Ziga Seilnachtf93bf102009-10-23 09:51:07 +02001640 self.assertEqual(client.get_client_ca_list(), expected)
1641 self.assertEqual(server.get_client_ca_list(), expected)
Ziga Seilnacht679c4262009-09-01 01:32:29 +02001642
1643
Jean-Paul Calderone911c9112009-10-24 11:12:00 -04001644 def test_set_client_ca_list_errors(self):
Ziga Seilnacht679c4262009-09-01 01:32:29 +02001645 """
Jean-Paul Calderone911c9112009-10-24 11:12:00 -04001646 L{Context.set_client_ca_list} raises a L{TypeError} if called with a
1647 non-list or a list that contains objects other than X509Names.
Ziga Seilnacht679c4262009-09-01 01:32:29 +02001648 """
1649 ctx = Context(TLSv1_METHOD)
Ziga Seilnachtf93bf102009-10-23 09:51:07 +02001650 self.assertRaises(TypeError, ctx.set_client_ca_list, "spam")
1651 self.assertRaises(TypeError, ctx.set_client_ca_list, ["spam"])
1652 self.assertIdentical(ctx.set_client_ca_list([]), None)
Ziga Seilnacht679c4262009-09-01 01:32:29 +02001653
1654
Jean-Paul Calderone911c9112009-10-24 11:12:00 -04001655 def test_set_empty_ca_list(self):
Ziga Seilnacht679c4262009-09-01 01:32:29 +02001656 """
Jean-Paul Calderone911c9112009-10-24 11:12:00 -04001657 If passed an empty list, L{Context.set_client_ca_list} configures the
1658 context to send no CA names to the client and, on both the server and
1659 client sides, L{Connection.get_client_ca_list} returns an empty list
1660 after the connection is set up.
1661 """
1662 def no_ca(ctx):
1663 ctx.set_client_ca_list([])
1664 return []
1665 self._check_client_ca_list(no_ca)
1666
1667
1668 def test_set_one_ca_list(self):
1669 """
1670 If passed a list containing a single X509Name,
1671 L{Context.set_client_ca_list} configures the context to send that CA
1672 name to the client and, on both the server and client sides,
1673 L{Connection.get_client_ca_list} returns a list containing that
1674 X509Name after the connection is set up.
1675 """
1676 cacert = load_certificate(FILETYPE_PEM, root_cert_pem)
1677 cadesc = cacert.get_subject()
1678 def single_ca(ctx):
1679 ctx.set_client_ca_list([cadesc])
1680 return [cadesc]
1681 self._check_client_ca_list(single_ca)
1682
1683
1684 def test_set_multiple_ca_list(self):
1685 """
1686 If passed a list containing multiple X509Name objects,
1687 L{Context.set_client_ca_list} configures the context to send those CA
1688 names to the client and, on both the server and client sides,
1689 L{Connection.get_client_ca_list} returns a list containing those
1690 X509Names after the connection is set up.
1691 """
1692 secert = load_certificate(FILETYPE_PEM, server_cert_pem)
1693 clcert = load_certificate(FILETYPE_PEM, server_cert_pem)
1694
1695 sedesc = secert.get_subject()
1696 cldesc = clcert.get_subject()
1697
1698 def multiple_ca(ctx):
1699 L = [sedesc, cldesc]
1700 ctx.set_client_ca_list(L)
1701 return L
1702 self._check_client_ca_list(multiple_ca)
1703
1704
1705 def test_reset_ca_list(self):
1706 """
1707 If called multiple times, only the X509Names passed to the final call
1708 of L{Context.set_client_ca_list} are used to configure the CA names
1709 sent to the client.
Ziga Seilnacht679c4262009-09-01 01:32:29 +02001710 """
1711 cacert = load_certificate(FILETYPE_PEM, root_cert_pem)
1712 secert = load_certificate(FILETYPE_PEM, server_cert_pem)
1713 clcert = load_certificate(FILETYPE_PEM, server_cert_pem)
1714
1715 cadesc = cacert.get_subject()
1716 sedesc = secert.get_subject()
1717 cldesc = clcert.get_subject()
1718
Ziga Seilnachtf93bf102009-10-23 09:51:07 +02001719 def changed_ca(ctx):
1720 ctx.set_client_ca_list([sedesc, cldesc])
1721 ctx.set_client_ca_list([cadesc])
Ziga Seilnacht679c4262009-09-01 01:32:29 +02001722 return [cadesc]
Ziga Seilnachtf93bf102009-10-23 09:51:07 +02001723 self._check_client_ca_list(changed_ca)
Ziga Seilnacht679c4262009-09-01 01:32:29 +02001724
Jean-Paul Calderone911c9112009-10-24 11:12:00 -04001725
1726 def test_mutated_ca_list(self):
1727 """
1728 If the list passed to L{Context.set_client_ca_list} is mutated
1729 afterwards, this does not affect the list of CA names sent to the
1730 client.
1731 """
1732 cacert = load_certificate(FILETYPE_PEM, root_cert_pem)
1733 secert = load_certificate(FILETYPE_PEM, server_cert_pem)
1734
1735 cadesc = cacert.get_subject()
1736 sedesc = secert.get_subject()
1737
Ziga Seilnachtf93bf102009-10-23 09:51:07 +02001738 def mutated_ca(ctx):
Ziga Seilnacht679c4262009-09-01 01:32:29 +02001739 L = [cadesc]
Ziga Seilnachtf93bf102009-10-23 09:51:07 +02001740 ctx.set_client_ca_list([cadesc])
Ziga Seilnacht679c4262009-09-01 01:32:29 +02001741 L.append(sedesc)
1742 return [cadesc]
Ziga Seilnachtf93bf102009-10-23 09:51:07 +02001743 self._check_client_ca_list(mutated_ca)
Ziga Seilnacht679c4262009-09-01 01:32:29 +02001744
1745
Jean-Paul Calderone911c9112009-10-24 11:12:00 -04001746 def test_add_client_ca_errors(self):
Ziga Seilnacht679c4262009-09-01 01:32:29 +02001747 """
Jean-Paul Calderone911c9112009-10-24 11:12:00 -04001748 L{Context.add_client_ca} raises L{TypeError} if called with a non-X509
1749 object or with a number of arguments other than one.
Ziga Seilnacht679c4262009-09-01 01:32:29 +02001750 """
1751 ctx = Context(TLSv1_METHOD)
1752 cacert = load_certificate(FILETYPE_PEM, root_cert_pem)
Jean-Paul Calderone911c9112009-10-24 11:12:00 -04001753 self.assertRaises(TypeError, ctx.add_client_ca)
Ziga Seilnachtf93bf102009-10-23 09:51:07 +02001754 self.assertRaises(TypeError, ctx.add_client_ca, "spam")
Jean-Paul Calderone911c9112009-10-24 11:12:00 -04001755 self.assertRaises(TypeError, ctx.add_client_ca, cacert, cacert)
Ziga Seilnacht679c4262009-09-01 01:32:29 +02001756
1757
Jean-Paul Calderone055a9172009-10-24 13:45:11 -04001758 def test_one_add_client_ca(self):
Ziga Seilnacht679c4262009-09-01 01:32:29 +02001759 """
Jean-Paul Calderone055a9172009-10-24 13:45:11 -04001760 A certificate's subject can be added as a CA to be sent to the client
1761 with L{Context.add_client_ca}.
1762 """
1763 cacert = load_certificate(FILETYPE_PEM, root_cert_pem)
1764 cadesc = cacert.get_subject()
1765 def single_ca(ctx):
1766 ctx.add_client_ca(cacert)
1767 return [cadesc]
1768 self._check_client_ca_list(single_ca)
1769
1770
1771 def test_multiple_add_client_ca(self):
1772 """
1773 Multiple CA names can be sent to the client by calling
1774 L{Context.add_client_ca} with multiple X509 objects.
1775 """
1776 cacert = load_certificate(FILETYPE_PEM, root_cert_pem)
1777 secert = load_certificate(FILETYPE_PEM, server_cert_pem)
1778
1779 cadesc = cacert.get_subject()
1780 sedesc = secert.get_subject()
1781
1782 def multiple_ca(ctx):
1783 ctx.add_client_ca(cacert)
1784 ctx.add_client_ca(secert)
1785 return [cadesc, sedesc]
1786 self._check_client_ca_list(multiple_ca)
1787
1788
1789 def test_set_and_add_client_ca(self):
1790 """
1791 A call to L{Context.set_client_ca_list} followed by a call to
1792 L{Context.add_client_ca} results in using the CA names from the first
1793 call and the CA name from the second call.
Ziga Seilnacht679c4262009-09-01 01:32:29 +02001794 """
1795 cacert = load_certificate(FILETYPE_PEM, root_cert_pem)
1796 secert = load_certificate(FILETYPE_PEM, server_cert_pem)
1797 clcert = load_certificate(FILETYPE_PEM, server_cert_pem)
1798
1799 cadesc = cacert.get_subject()
1800 sedesc = secert.get_subject()
1801 cldesc = clcert.get_subject()
1802
Ziga Seilnachtf93bf102009-10-23 09:51:07 +02001803 def mixed_set_add_ca(ctx):
1804 ctx.set_client_ca_list([cadesc, sedesc])
1805 ctx.add_client_ca(clcert)
Ziga Seilnacht679c4262009-09-01 01:32:29 +02001806 return [cadesc, sedesc, cldesc]
Ziga Seilnachtf93bf102009-10-23 09:51:07 +02001807 self._check_client_ca_list(mixed_set_add_ca)
Ziga Seilnacht679c4262009-09-01 01:32:29 +02001808
Jean-Paul Calderone055a9172009-10-24 13:45:11 -04001809
1810 def test_set_after_add_client_ca(self):
1811 """
1812 A call to L{Context.set_client_ca_list} after a call to
1813 L{Context.add_client_ca} replaces the CA name specified by the former
1814 call with the names specified by the latter cal.
1815 """
1816 cacert = load_certificate(FILETYPE_PEM, root_cert_pem)
1817 secert = load_certificate(FILETYPE_PEM, server_cert_pem)
1818 clcert = load_certificate(FILETYPE_PEM, server_cert_pem)
1819
1820 cadesc = cacert.get_subject()
1821 sedesc = secert.get_subject()
Jean-Paul Calderone055a9172009-10-24 13:45:11 -04001822
Ziga Seilnachtf93bf102009-10-23 09:51:07 +02001823 def set_replaces_add_ca(ctx):
1824 ctx.add_client_ca(clcert)
1825 ctx.set_client_ca_list([cadesc])
1826 ctx.add_client_ca(secert)
Ziga Seilnacht679c4262009-09-01 01:32:29 +02001827 return [cadesc, sedesc]
Ziga Seilnachtf93bf102009-10-23 09:51:07 +02001828 self._check_client_ca_list(set_replaces_add_ca)
Ziga Seilnacht679c4262009-09-01 01:32:29 +02001829
Jean-Paul Calderone0b88b6a2009-07-05 12:44:41 -04001830
Jean-Paul Calderone31e85a82011-03-21 19:13:35 -04001831class InfoConstantTests(TestCase):
1832 """
1833 Tests for assorted constants exposed for use in info callbacks.
1834 """
1835 def test_integers(self):
1836 """
1837 All of the info constants are integers.
1838
1839 This is a very weak test. It would be nice to have one that actually
1840 verifies that as certain info events happen, the value passed to the
1841 info callback matches up with the constant exposed by OpenSSL.SSL.
1842 """
1843 for const in [
1844 SSL_ST_CONNECT, SSL_ST_ACCEPT, SSL_ST_MASK, SSL_ST_INIT,
1845 SSL_ST_BEFORE, SSL_ST_OK, SSL_ST_RENEGOTIATE,
1846 SSL_CB_LOOP, SSL_CB_EXIT, SSL_CB_READ, SSL_CB_WRITE, SSL_CB_ALERT,
1847 SSL_CB_READ_ALERT, SSL_CB_WRITE_ALERT, SSL_CB_ACCEPT_LOOP,
1848 SSL_CB_ACCEPT_EXIT, SSL_CB_CONNECT_LOOP, SSL_CB_CONNECT_EXIT,
1849 SSL_CB_HANDSHAKE_START, SSL_CB_HANDSHAKE_DONE]:
1850
1851 self.assertTrue(isinstance(const, int))
1852
Ziga Seilnacht44611bf2009-08-31 20:49:30 +02001853
Jean-Paul Calderone0b88b6a2009-07-05 12:44:41 -04001854if __name__ == '__main__':
1855 main()