~myers-1/pyopenssl/npn

« back to all changes in this revision

Viewing changes to test/test_ssl.py

  • Committer: Jean-Paul Calderone
  • Date: 2010-01-25 22:55:30 UTC
  • mfrom: (126 trunk)
  • mto: This revision was merged to the branch mainline in revision 129.
  • Revision ID: exarkun@divmod.com-20100125225530-5e9nsb6bzoesoz42
merge trunk and resolve simple conflict

Show diffs side-by-side

added added

removed removed

Lines of Context:
6
6
 
7
7
from sys import platform
8
8
from socket import socket
9
 
from os import makedirs, symlink
 
9
from os import makedirs
10
10
from os.path import join
11
11
from unittest import main
12
12
 
17
17
from OpenSSL.SSL import VERIFY_PEER, VERIFY_FAIL_IF_NO_PEER_CERT, VERIFY_CLIENT_ONCE
18
18
from OpenSSL.test.util import TestCase
19
19
from OpenSSL.test.test_crypto import cleartextCertificatePEM, cleartextPrivateKeyPEM
 
20
from OpenSSL.test.test_crypto import client_cert_pem, client_key_pem, server_cert_pem, server_key_pem, root_cert_pem
20
21
try:
21
22
    from OpenSSL.SSL import OP_NO_QUERY_MTU
22
23
except ImportError:
41
42
    port.listen(1)
42
43
    client = socket()
43
44
    client.setblocking(False)
44
 
    client.connect_ex(port.getsockname())
 
45
    client.connect_ex(("127.0.0.1", port.getsockname()[1]))
45
46
    client.setblocking(True)
46
47
    server = port.accept()[0]
47
48
 
193
194
        cert = clientSSL.get_peer_certificate()
194
195
        self.assertEqual(cert.get_subject().CN, 'Testing Root CA')
195
196
 
 
197
 
196
198
    def test_load_verify_file(self):
197
199
        """
198
200
        L{Context.load_verify_locations} accepts a file name and uses the
223
225
        """
224
226
        capath = self.mktemp()
225
227
        makedirs(capath)
226
 
        cafile = join(capath, 'cert.pem')
227
 
        fObj = file(cafile, 'w')
228
 
        fObj.write(cleartextCertificatePEM)
229
 
        fObj.close()
230
 
 
231
228
        # Hash value computed manually with c_rehash to avoid depending on
232
229
        # c_rehash in the test suite.
233
 
        symlink('cert.pem', join(capath, 'c7adac82.0'))
 
230
        cafile = join(capath, 'c7adac82.0')
 
231
        fObj = file(cafile, 'w')
 
232
        fObj.write(cleartextCertificatePEM)
 
233
        fObj.close()
234
234
 
235
235
        self._load_verify_locations_test(None, capath)
236
236
 
237
237
 
238
 
    def test_set_default_verify_paths(self):
239
 
        """
240
 
        L{Context.set_default_verify_paths} causes the platform-specific CA
241
 
        certificate locations to be used for verification purposes.
242
 
        """
243
 
        # Testing this requires a server with a certificate signed by one of
244
 
        # the CAs in the platform CA location.  Getting one of those costs
245
 
        # money.  Fortunately (or unfortunately, depending on your
246
 
        # perspective), it's easy to think of a public server on the
247
 
        # internet which has such a certificate.  Connecting to the network
248
 
        # in a unit test is bad, but it's the only way I can think of to
249
 
        # really test this. -exarkun
250
 
 
251
 
        # Arg, verisign.com doesn't speak TLSv1
252
 
        context = Context(SSLv3_METHOD)
253
 
        context.set_default_verify_paths()
254
 
        context.set_verify(
255
 
            VERIFY_PEER, 
256
 
            lambda conn, cert, errno, depth, preverify_ok: preverify_ok)
257
 
 
258
 
        client = socket()
259
 
        client.connect(('verisign.com', 443))
260
 
        clientSSL = Connection(context, client)
261
 
        clientSSL.set_connect_state()
262
 
        clientSSL.do_handshake()
263
 
        clientSSL.send('GET / HTTP/1.0\r\n\r\n')
264
 
        self.assertTrue(clientSSL.recv(1024))
265
 
    if platform == "darwin":
266
 
        test_set_default_verify_paths.todo = (
267
 
            "set_default_verify_paths appears not to work on OS X - a "
268
 
            "problem with the supplied OpenSSL, perhaps?")
 
238
    if platform in ("darwin", "win32"):
 
239
        "set_default_verify_paths appears not to work on OS X or Windows"
 
240
        "See LP#404343 and LP#404344."
 
241
    else:
 
242
        def test_set_default_verify_paths(self):
 
243
            """
 
244
            L{Context.set_default_verify_paths} causes the platform-specific CA
 
245
            certificate locations to be used for verification purposes.
 
246
            """
 
247
            # Testing this requires a server with a certificate signed by one of
 
248
            # the CAs in the platform CA location.  Getting one of those costs
 
249
            # money.  Fortunately (or unfortunately, depending on your
 
250
            # perspective), it's easy to think of a public server on the
 
251
            # internet which has such a certificate.  Connecting to the network
 
252
            # in a unit test is bad, but it's the only way I can think of to
 
253
            # really test this. -exarkun
 
254
 
 
255
            # Arg, verisign.com doesn't speak TLSv1
 
256
            context = Context(SSLv3_METHOD)
 
257
            context.set_default_verify_paths()
 
258
            context.set_verify(
 
259
                VERIFY_PEER,
 
260
                lambda conn, cert, errno, depth, preverify_ok: preverify_ok)
 
261
 
 
262
            client = socket()
 
263
            client.connect(('verisign.com', 443))
 
264
            clientSSL = Connection(context, client)
 
265
            clientSSL.set_connect_state()
 
266
            clientSSL.do_handshake()
 
267
            clientSSL.send('GET / HTTP/1.0\r\n\r\n')
 
268
            self.assertTrue(clientSSL.recv(1024))
269
269
 
270
270
 
271
271
    def test_set_default_verify_paths_signature(self):
278
278
        self.assertRaises(TypeError, context.set_default_verify_paths, 1)
279
279
        self.assertRaises(TypeError, context.set_default_verify_paths, "")
280
280
 
 
281
    def test_add_extra_chain_cert_invalid_cert(self):
 
282
        """
 
283
        L{Context.add_extra_chain_cert} raises L{TypeError} if called with
 
284
        other than one argument or if called with an object which is not an
 
285
        instance of L{X509}.
 
286
        """
 
287
        context = Context(TLSv1_METHOD)
 
288
        self.assertRaises(TypeError, context.add_extra_chain_cert)
 
289
        self.assertRaises(TypeError, context.add_extra_chain_cert, object())
 
290
        self.assertRaises(TypeError, context.add_extra_chain_cert, object(), object())
 
291
 
 
292
 
 
293
    def test_add_extra_chain_cert(self):
 
294
        """
 
295
        L{Context.add_extra_chain_cert} accepts an L{X509} instance to add to
 
296
        the certificate chain.
 
297
        """
 
298
        context = Context(TLSv1_METHOD)
 
299
        context.add_extra_chain_cert(load_certificate(FILETYPE_PEM, cleartextCertificatePEM))
 
300
        # XXX Oh no, actually asserting something about its behavior would be really hard.
 
301
        # See #477521.
 
302
 
281
303
 
282
304
 
283
305
class ConnectionTests(TestCase):
294
316
        self.assertConsistentType(Connection, 'Connection', ctx, None)
295
317
 
296
318
 
 
319
    def test_get_context(self):
 
320
        """
 
321
        L{Connection.get_context} returns the L{Context} instance used to
 
322
        construct the L{Connection} instance.
 
323
        """
 
324
        context = Context(TLSv1_METHOD)
 
325
        connection = Connection(context, None)
 
326
        self.assertIdentical(connection.get_context(), context)
 
327
 
 
328
 
 
329
    def test_get_context_wrong_args(self):
 
330
        """
 
331
        L{Connection.get_context} raises L{TypeError} if called with any
 
332
        arguments.
 
333
        """
 
334
        connection = Connection(Context(TLSv1_METHOD), None)
 
335
        self.assertRaises(TypeError, connection.get_context, None)
 
336
 
 
337
 
297
338
 
298
339
class ErrorTests(TestCase):
299
340
    """
351
392
 
352
393
 
353
394
 
354
 
root_cert_pem = """-----BEGIN CERTIFICATE-----
355
 
MIIC7TCCAlagAwIBAgIIPQzE4MbeufQwDQYJKoZIhvcNAQEFBQAwWDELMAkGA1UE
356
 
BhMCVVMxCzAJBgNVBAgTAklMMRAwDgYDVQQHEwdDaGljYWdvMRAwDgYDVQQKEwdU
357
 
ZXN0aW5nMRgwFgYDVQQDEw9UZXN0aW5nIFJvb3QgQ0EwIhgPMjAwOTAzMjUxMjM2
358
 
NThaGA8yMDE3MDYxMTEyMzY1OFowWDELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAklM
359
 
MRAwDgYDVQQHEwdDaGljYWdvMRAwDgYDVQQKEwdUZXN0aW5nMRgwFgYDVQQDEw9U
360
 
ZXN0aW5nIFJvb3QgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAPmaQumL
361
 
urpE527uSEHdL1pqcDRmWzu+98Y6YHzT/J7KWEamyMCNZ6fRW1JCR782UQ8a07fy
362
 
2xXsKy4WdKaxyG8CcatwmXvpvRQ44dSANMihHELpANTdyVp6DCysED6wkQFurHlF
363
 
1dshEaJw8b/ypDhmbVIo6Ci1xvCJqivbLFnbAgMBAAGjgbswgbgwHQYDVR0OBBYE
364
 
FINVdy1eIfFJDAkk51QJEo3IfgSuMIGIBgNVHSMEgYAwfoAUg1V3LV4h8UkMCSTn
365
 
VAkSjch+BK6hXKRaMFgxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJJTDEQMA4GA1UE
366
 
BxMHQ2hpY2FnbzEQMA4GA1UEChMHVGVzdGluZzEYMBYGA1UEAxMPVGVzdGluZyBS
367
 
b290IENBggg9DMTgxt659DAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GB
368
 
AGGCDazMJGoWNBpc03u6+smc95dEead2KlZXBATOdFT1VesY3+nUOqZhEhTGlDMi
369
 
hkgaZnzoIq/Uamidegk4hirsCT/R+6vsKAAxNTcBjUeZjlykCJWy5ojShGftXIKY
370
 
w/njVbKMXrvc83qmTdGl3TAM0fxQIpqgcglFLveEBgzn
371
 
-----END CERTIFICATE-----
372
 
"""
373
 
 
374
 
root_key_pem = """-----BEGIN RSA PRIVATE KEY-----
375
 
MIICXQIBAAKBgQD5mkLpi7q6ROdu7khB3S9aanA0Zls7vvfGOmB80/yeylhGpsjA
376
 
jWen0VtSQke/NlEPGtO38tsV7CsuFnSmschvAnGrcJl76b0UOOHUgDTIoRxC6QDU
377
 
3claegwsrBA+sJEBbqx5RdXbIRGicPG/8qQ4Zm1SKOgotcbwiaor2yxZ2wIDAQAB
378
 
AoGBAPCgMpmLxzwDaUmcFbTJUvlLW1hoxNNYSu2jIZm1k/hRAcE60JYwvBkgz3UB
379
 
yMEh0AtLxYe0bFk6EHah11tMUPgscbCq73snJ++8koUw+csk22G65hOs51bVb7Aa
380
 
6JBe67oLzdtvgCUFAA2qfrKzWRZzAdhUirQUZgySZk+Xq1pBAkEA/kZG0A6roTSM
381
 
BVnx7LnPfsycKUsTumorpXiylZJjTi9XtmzxhrYN6wgZlDOOwOLgSQhszGpxVoMD
382
 
u3gByT1b2QJBAPtL3mSKdvwRu/+40zaZLwvSJRxaj0mcE4BJOS6Oqs/hS1xRlrNk
383
 
PpQ7WJ4yM6ZOLnXzm2mKyxm50Mv64109FtMCQQDOqS2KkjHaLowTGVxwC0DijMfr
384
 
I9Lf8sSQk32J5VWCySWf5gGTfEnpmUa41gKTMJIbqZZLucNuDcOtzUaeWZlZAkA8
385
 
ttXigLnCqR486JDPTi9ZscoZkZ+w7y6e/hH8t6d5Vjt48JVyfjPIaJY+km58LcN3
386
 
6AWSeGAdtRFHVzR7oHjVAkB4hutvxiOeiIVQNBhM6RSI9aBPMI21DoX2JRoxvNW2
387
 
cbvAhow217X9V0dVerEOKxnNYspXRrh36h7k4mQA+sDq
388
 
-----END RSA PRIVATE KEY-----
389
 
"""
390
 
 
391
 
server_cert_pem = """-----BEGIN CERTIFICATE-----
392
 
MIICKDCCAZGgAwIBAgIJAJn/HpR21r/8MA0GCSqGSIb3DQEBBQUAMFgxCzAJBgNV
393
 
BAYTAlVTMQswCQYDVQQIEwJJTDEQMA4GA1UEBxMHQ2hpY2FnbzEQMA4GA1UEChMH
394
 
VGVzdGluZzEYMBYGA1UEAxMPVGVzdGluZyBSb290IENBMCIYDzIwMDkwMzI1MTIz
395
 
NzUzWhgPMjAxNzA2MTExMjM3NTNaMBgxFjAUBgNVBAMTDWxvdmVseSBzZXJ2ZXIw
396
 
gZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAL6m+G653V0tpBC/OKl22VxOi2Cv
397
 
lK4TYu9LHSDP9uDVTe7V5D5Tl6qzFoRRx5pfmnkqT5B+W9byp2NU3FC5hLm5zSAr
398
 
b45meUhjEJ/ifkZgbNUjHdBIGP9MAQUHZa5WKdkGIJvGAvs8UzUqlr4TBWQIB24+
399
 
lJ+Ukk/CRgasrYwdAgMBAAGjNjA0MB0GA1UdDgQWBBS4kC7Ij0W1TZXZqXQFAM2e
400
 
gKEG2DATBgNVHSUEDDAKBggrBgEFBQcDATANBgkqhkiG9w0BAQUFAAOBgQBh30Li
401
 
dJ+NlxIOx5343WqIBka3UbsOb2kxWrbkVCrvRapCMLCASO4FqiKWM+L0VDBprqIp
402
 
2mgpFQ6FHpoIENGvJhdEKpptQ5i7KaGhnDNTfdy3x1+h852G99f1iyj0RmbuFcM8
403
 
uzujnS8YXWvM7DM1Ilozk4MzPug8jzFp5uhKCQ==
404
 
-----END CERTIFICATE-----
405
 
"""
406
 
 
407
 
server_key_pem = """-----BEGIN RSA PRIVATE KEY-----
408
 
MIICWwIBAAKBgQC+pvhuud1dLaQQvzipdtlcTotgr5SuE2LvSx0gz/bg1U3u1eQ+
409
 
U5eqsxaEUceaX5p5Kk+QflvW8qdjVNxQuYS5uc0gK2+OZnlIYxCf4n5GYGzVIx3Q
410
 
SBj/TAEFB2WuVinZBiCbxgL7PFM1Kpa+EwVkCAduPpSflJJPwkYGrK2MHQIDAQAB
411
 
AoGAbwuZ0AR6JveahBaczjfnSpiFHf+mve2UxoQdpyr6ROJ4zg/PLW5K/KXrC48G
412
 
j6f3tXMrfKHcpEoZrQWUfYBRCUsGD5DCazEhD8zlxEHahIsqpwA0WWssJA2VOLEN
413
 
j6DuV2pCFbw67rfTBkTSo32ahfXxEKev5KswZk0JIzH3ooECQQDgzS9AI89h0gs8
414
 
Dt+1m11Rzqo3vZML7ZIyGApUzVan+a7hbc33nbGRkAXjHaUBJO31it/H6dTO+uwX
415
 
msWwNG5ZAkEA2RyFKs5xR5USTFaKLWCgpH/ydV96KPOpBND7TKQx62snDenFNNbn
416
 
FwwOhpahld+vqhYk+pfuWWUpQciE+Bu7ZQJASjfT4sQv4qbbKK/scePicnDdx9th
417
 
4e1EeB9xwb+tXXXUo/6Bor/AcUNwfiQ6Zt9PZOK9sR3lMZSsP7rMi7kzuQJABie6
418
 
1sXXjFH7nNJvRG4S39cIxq8YRYTy68II/dlB2QzGpKxV/POCxbJ/zu0CU79tuYK7
419
 
NaeNCFfH3aeTrX0LyQJAMBWjWmeKM2G2sCExheeQK0ROnaBC8itCECD4Jsve4nqf
420
 
r50+LF74iLXFwqysVCebPKMOpDWp/qQ1BbJQIPs7/A==
421
 
-----END RSA PRIVATE KEY-----
422
 
"""
423
 
 
424
 
client_cert_pem = """-----BEGIN CERTIFICATE-----
425
 
MIICJjCCAY+gAwIBAgIJAKxpFI5lODkjMA0GCSqGSIb3DQEBBQUAMFgxCzAJBgNV
426
 
BAYTAlVTMQswCQYDVQQIEwJJTDEQMA4GA1UEBxMHQ2hpY2FnbzEQMA4GA1UEChMH
427
 
VGVzdGluZzEYMBYGA1UEAxMPVGVzdGluZyBSb290IENBMCIYDzIwMDkwMzI1MTIz
428
 
ODA1WhgPMjAxNzA2MTExMjM4MDVaMBYxFDASBgNVBAMTC3VnbHkgY2xpZW50MIGf
429
 
MA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDAZh/SRtNm5ntMT4qb6YzEpTroMlq2
430
 
rn+GrRHRiZ+xkCw/CGNhbtPir7/QxaUj26BSmQrHw1bGKEbPsWiW7bdXSespl+xK
431
 
iku4G/KvnnmWdeJHqsiXeUZtqurMELcPQAw9xPHEuhqqUJvvEoMTsnCEqGM+7Dtb
432
 
oCRajYyHfluARQIDAQABozYwNDAdBgNVHQ4EFgQUNQB+qkaOaEVecf1J3TTUtAff
433
 
0fAwEwYDVR0lBAwwCgYIKwYBBQUHAwIwDQYJKoZIhvcNAQEFBQADgYEAyv/Jh7gM
434
 
Q3OHvmsFEEvRI+hsW8y66zK4K5de239Y44iZrFYkt7Q5nBPMEWDj4F2hLYWL/qtI
435
 
9Zdr0U4UDCU9SmmGYh4o7R4TZ5pGFvBYvjhHbkSFYFQXZxKUi+WUxplP6I0wr2KJ
436
 
PSTJCjJOn3xo2NTKRgV1gaoTf2EhL+RG8TQ=
437
 
-----END CERTIFICATE-----
438
 
"""
439
 
 
440
 
client_key_pem = """-----BEGIN RSA PRIVATE KEY-----
441
 
MIICXgIBAAKBgQDAZh/SRtNm5ntMT4qb6YzEpTroMlq2rn+GrRHRiZ+xkCw/CGNh
442
 
btPir7/QxaUj26BSmQrHw1bGKEbPsWiW7bdXSespl+xKiku4G/KvnnmWdeJHqsiX
443
 
eUZtqurMELcPQAw9xPHEuhqqUJvvEoMTsnCEqGM+7DtboCRajYyHfluARQIDAQAB
444
 
AoGATkZ+NceY5Glqyl4mD06SdcKfV65814vg2EL7V9t8+/mi9rYL8KztSXGlQWPX
445
 
zuHgtRoMl78yQ4ZJYOBVo+nsx8KZNRCEBlE19bamSbQLCeQMenWnpeYyQUZ908gF
446
 
h6L9qsFVJepgA9RDgAjyDoS5CaWCdCCPCH2lDkdcqC54SVUCQQDseuduc4wi8h4t
447
 
V8AahUn9fn9gYfhoNuM0gdguTA0nPLVWz4hy1yJiWYQe0H7NLNNTmCKiLQaJpAbb
448
 
TC6vE8C7AkEA0Ee8CMJUc20BnGEmxwgWcVuqFWaKCo8jTH1X38FlATUsyR3krjW2
449
 
dL3yDD9NwHxsYP7nTKp/U8MV7U9IBn4y/wJBAJl7H0/BcLeRmuJk7IqJ7b635iYB
450
 
D/9beFUw3MUXmQXZUfyYz39xf6CDZsu1GEdEC5haykeln3Of4M9d/4Kj+FcCQQCY
451
 
si6xwT7GzMDkk/ko684AV3KPc/h6G0yGtFIrMg7J3uExpR/VdH2KgwMkZXisSMvw
452
 
JJEQjOMCVsEJlRk54WWjAkEAzoZNH6UhDdBK5F38rVt/y4SEHgbSfJHIAmPS32Kq
453
 
f6GGcfNpip0Uk7q7udTKuX7Q/buZi/C4YW7u3VKAquv9NA==
454
 
-----END RSA PRIVATE KEY-----
455
 
"""
456
 
 
457
395
def verify_cb(conn, cert, errnum, depth, ok):
458
396
    return ok
459
397
 
615
553
            established = True  # assume the best
616
554
            for ssl in client_conn, server_conn:
617
555
                try:
618
 
                    # Generally a recv() or send() could also work instead 
619
 
                    # of do_handshake(), and we would stop on the first 
 
556
                    # Generally a recv() or send() could also work instead
 
557
                    # of do_handshake(), and we would stop on the first
620
558
                    # non-exception.
621
559
                    ssl.do_handshake()
622
560
                except WantReadError:
687
625
        self.assertEquals(e.__class__, Error)
688
626
 
689
627
 
 
628
    def _check_client_ca_list(self, func):
 
629
        """
 
630
        Verify the return value of the C{get_client_ca_list} method for server and client connections.
 
631
 
 
632
        @param func: A function which will be called with the server context
 
633
            before the client and server are connected to each other.  This
 
634
            function should specify a list of CAs for the server to send to the
 
635
            client and return that same list.  The list will be used to verify
 
636
            that C{get_client_ca_list} returns the proper value at various
 
637
            times.
 
638
        """
 
639
        server = self._server(None)
 
640
        client = self._client(None)
 
641
        self.assertEqual(client.get_client_ca_list(), [])
 
642
        self.assertEqual(server.get_client_ca_list(), [])
 
643
        ctx = server.get_context()
 
644
        expected = func(ctx)
 
645
        self.assertEqual(client.get_client_ca_list(), [])
 
646
        self.assertEqual(server.get_client_ca_list(), expected)
 
647
        self._loopback(client, server)
 
648
        self.assertEqual(client.get_client_ca_list(), expected)
 
649
        self.assertEqual(server.get_client_ca_list(), expected)
 
650
 
 
651
 
 
652
    def test_set_client_ca_list_errors(self):
 
653
        """
 
654
        L{Context.set_client_ca_list} raises a L{TypeError} if called with a
 
655
        non-list or a list that contains objects other than X509Names.
 
656
        """
 
657
        ctx = Context(TLSv1_METHOD)
 
658
        self.assertRaises(TypeError, ctx.set_client_ca_list, "spam")
 
659
        self.assertRaises(TypeError, ctx.set_client_ca_list, ["spam"])
 
660
        self.assertIdentical(ctx.set_client_ca_list([]), None)
 
661
 
 
662
 
 
663
    def test_set_empty_ca_list(self):
 
664
        """
 
665
        If passed an empty list, L{Context.set_client_ca_list} configures the
 
666
        context to send no CA names to the client and, on both the server and
 
667
        client sides, L{Connection.get_client_ca_list} returns an empty list
 
668
        after the connection is set up.
 
669
        """
 
670
        def no_ca(ctx):
 
671
            ctx.set_client_ca_list([])
 
672
            return []
 
673
        self._check_client_ca_list(no_ca)
 
674
 
 
675
 
 
676
    def test_set_one_ca_list(self):
 
677
        """
 
678
        If passed a list containing a single X509Name,
 
679
        L{Context.set_client_ca_list} configures the context to send that CA
 
680
        name to the client and, on both the server and client sides,
 
681
        L{Connection.get_client_ca_list} returns a list containing that
 
682
        X509Name after the connection is set up.
 
683
        """
 
684
        cacert = load_certificate(FILETYPE_PEM, root_cert_pem)
 
685
        cadesc = cacert.get_subject()
 
686
        def single_ca(ctx):
 
687
            ctx.set_client_ca_list([cadesc])
 
688
            return [cadesc]
 
689
        self._check_client_ca_list(single_ca)
 
690
 
 
691
 
 
692
    def test_set_multiple_ca_list(self):
 
693
        """
 
694
        If passed a list containing multiple X509Name objects,
 
695
        L{Context.set_client_ca_list} configures the context to send those CA
 
696
        names to the client and, on both the server and client sides,
 
697
        L{Connection.get_client_ca_list} returns a list containing those
 
698
        X509Names after the connection is set up.
 
699
        """
 
700
        secert = load_certificate(FILETYPE_PEM, server_cert_pem)
 
701
        clcert = load_certificate(FILETYPE_PEM, server_cert_pem)
 
702
 
 
703
        sedesc = secert.get_subject()
 
704
        cldesc = clcert.get_subject()
 
705
 
 
706
        def multiple_ca(ctx):
 
707
            L = [sedesc, cldesc]
 
708
            ctx.set_client_ca_list(L)
 
709
            return L
 
710
        self._check_client_ca_list(multiple_ca)
 
711
 
 
712
 
 
713
    def test_reset_ca_list(self):
 
714
        """
 
715
        If called multiple times, only the X509Names passed to the final call
 
716
        of L{Context.set_client_ca_list} are used to configure the CA names
 
717
        sent to the client.
 
718
        """
 
719
        cacert = load_certificate(FILETYPE_PEM, root_cert_pem)
 
720
        secert = load_certificate(FILETYPE_PEM, server_cert_pem)
 
721
        clcert = load_certificate(FILETYPE_PEM, server_cert_pem)
 
722
 
 
723
        cadesc = cacert.get_subject()
 
724
        sedesc = secert.get_subject()
 
725
        cldesc = clcert.get_subject()
 
726
 
 
727
        def changed_ca(ctx):
 
728
            ctx.set_client_ca_list([sedesc, cldesc])
 
729
            ctx.set_client_ca_list([cadesc])
 
730
            return [cadesc]
 
731
        self._check_client_ca_list(changed_ca)
 
732
 
 
733
 
 
734
    def test_mutated_ca_list(self):
 
735
        """
 
736
        If the list passed to L{Context.set_client_ca_list} is mutated
 
737
        afterwards, this does not affect the list of CA names sent to the
 
738
        client.
 
739
        """
 
740
        cacert = load_certificate(FILETYPE_PEM, root_cert_pem)
 
741
        secert = load_certificate(FILETYPE_PEM, server_cert_pem)
 
742
 
 
743
        cadesc = cacert.get_subject()
 
744
        sedesc = secert.get_subject()
 
745
 
 
746
        def mutated_ca(ctx):
 
747
            L = [cadesc]
 
748
            ctx.set_client_ca_list([cadesc])
 
749
            L.append(sedesc)
 
750
            return [cadesc]
 
751
        self._check_client_ca_list(mutated_ca)
 
752
 
 
753
 
 
754
    def test_add_client_ca_errors(self):
 
755
        """
 
756
        L{Context.add_client_ca} raises L{TypeError} if called with a non-X509
 
757
        object or with a number of arguments other than one.
 
758
        """
 
759
        ctx = Context(TLSv1_METHOD)
 
760
        cacert = load_certificate(FILETYPE_PEM, root_cert_pem)
 
761
        self.assertRaises(TypeError, ctx.add_client_ca)
 
762
        self.assertRaises(TypeError, ctx.add_client_ca, "spam")
 
763
        self.assertRaises(TypeError, ctx.add_client_ca, cacert, cacert)
 
764
 
 
765
 
 
766
    def test_one_add_client_ca(self):
 
767
        """
 
768
        A certificate's subject can be added as a CA to be sent to the client
 
769
        with L{Context.add_client_ca}.
 
770
        """
 
771
        cacert = load_certificate(FILETYPE_PEM, root_cert_pem)
 
772
        cadesc = cacert.get_subject()
 
773
        def single_ca(ctx):
 
774
            ctx.add_client_ca(cacert)
 
775
            return [cadesc]
 
776
        self._check_client_ca_list(single_ca)
 
777
 
 
778
 
 
779
    def test_multiple_add_client_ca(self):
 
780
        """
 
781
        Multiple CA names can be sent to the client by calling
 
782
        L{Context.add_client_ca} with multiple X509 objects.
 
783
        """
 
784
        cacert = load_certificate(FILETYPE_PEM, root_cert_pem)
 
785
        secert = load_certificate(FILETYPE_PEM, server_cert_pem)
 
786
 
 
787
        cadesc = cacert.get_subject()
 
788
        sedesc = secert.get_subject()
 
789
 
 
790
        def multiple_ca(ctx):
 
791
            ctx.add_client_ca(cacert)
 
792
            ctx.add_client_ca(secert)
 
793
            return [cadesc, sedesc]
 
794
        self._check_client_ca_list(multiple_ca)
 
795
 
 
796
 
 
797
    def test_set_and_add_client_ca(self):
 
798
        """
 
799
        A call to L{Context.set_client_ca_list} followed by a call to
 
800
        L{Context.add_client_ca} results in using the CA names from the first
 
801
        call and the CA name from the second call.
 
802
        """
 
803
        cacert = load_certificate(FILETYPE_PEM, root_cert_pem)
 
804
        secert = load_certificate(FILETYPE_PEM, server_cert_pem)
 
805
        clcert = load_certificate(FILETYPE_PEM, server_cert_pem)
 
806
 
 
807
        cadesc = cacert.get_subject()
 
808
        sedesc = secert.get_subject()
 
809
        cldesc = clcert.get_subject()
 
810
 
 
811
        def mixed_set_add_ca(ctx):
 
812
            ctx.set_client_ca_list([cadesc, sedesc])
 
813
            ctx.add_client_ca(clcert)
 
814
            return [cadesc, sedesc, cldesc]
 
815
        self._check_client_ca_list(mixed_set_add_ca)
 
816
 
 
817
 
 
818
    def test_set_after_add_client_ca(self):
 
819
        """
 
820
        A call to L{Context.set_client_ca_list} after a call to
 
821
        L{Context.add_client_ca} replaces the CA name specified by the former
 
822
        call with the names specified by the latter cal.
 
823
        """
 
824
        cacert = load_certificate(FILETYPE_PEM, root_cert_pem)
 
825
        secert = load_certificate(FILETYPE_PEM, server_cert_pem)
 
826
        clcert = load_certificate(FILETYPE_PEM, server_cert_pem)
 
827
 
 
828
        cadesc = cacert.get_subject()
 
829
        sedesc = secert.get_subject()
 
830
        cldesc = clcert.get_subject()
 
831
 
 
832
        def set_replaces_add_ca(ctx):
 
833
            ctx.add_client_ca(clcert)
 
834
            ctx.set_client_ca_list([cadesc])
 
835
            ctx.add_client_ca(secert)
 
836
            return [cadesc, sedesc]
 
837
        self._check_client_ca_list(set_replaces_add_ca)
 
838
 
 
839
 
690
840
 
691
841
if __name__ == '__main__':
692
842
    main()