blob: 77a0c8555ebed24b7ad929017eed5082ff416593 [file] [log] [blame]
Jean-Paul Calderone8b63d452008-03-21 18:31:12 -04001# Copyright (C) Jean-Paul Calderone 2008, All rights reserved
2
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -05003"""
4Unit tests for L{OpenSSL.crypto}.
5"""
6
Jean-Paul Calderone0b88b6a2009-07-05 12:44:41 -04007from unittest import main
8
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04009import os, re
Jean-Paul Calderone653f5582009-04-01 14:42:32 -040010from os import popen2
Rick Dean47262da2009-07-08 16:17:17 -050011from datetime import datetime, timedelta
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -050012
13from OpenSSL.crypto import TYPE_RSA, TYPE_DSA, Error, PKey, PKeyType
Jean-Paul Calderone78381d22008-03-06 23:35:22 -050014from OpenSSL.crypto import X509, X509Type, X509Name, X509NameType
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -050015from OpenSSL.crypto import X509Req, X509ReqType
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -050016from OpenSSL.crypto import X509Extension, X509ExtensionType
Rick Dean5b7b6372009-04-01 11:34:06 -050017from OpenSSL.crypto import load_certificate, load_privatekey
Jean-Paul Calderonef17e4212009-04-01 14:21:40 -040018from OpenSSL.crypto import FILETYPE_PEM, FILETYPE_ASN1, FILETYPE_TEXT
Jean-Paul Calderone71919862009-04-01 13:01:19 -040019from OpenSSL.crypto import dump_certificate, load_certificate_request
20from OpenSSL.crypto import dump_certificate_request, dump_privatekey
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -040021from OpenSSL.crypto import PKCS7Type, load_pkcs7_data
Rick Dean4c9ad612009-07-17 15:05:22 -050022from OpenSSL.crypto import PKCS12Type, load_pkcs12, PKCS12
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -040023from OpenSSL.crypto import NetscapeSPKI, NetscapeSPKIType
Jean-Paul Calderone0b88b6a2009-07-05 12:44:41 -040024from OpenSSL.test.util import TestCase
Rick Dean94e46fd2009-07-18 14:51:24 -050025
26
27root_cert_pem = """-----BEGIN CERTIFICATE-----
28MIIC7TCCAlagAwIBAgIIPQzE4MbeufQwDQYJKoZIhvcNAQEFBQAwWDELMAkGA1UE
29BhMCVVMxCzAJBgNVBAgTAklMMRAwDgYDVQQHEwdDaGljYWdvMRAwDgYDVQQKEwdU
30ZXN0aW5nMRgwFgYDVQQDEw9UZXN0aW5nIFJvb3QgQ0EwIhgPMjAwOTAzMjUxMjM2
31NThaGA8yMDE3MDYxMTEyMzY1OFowWDELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAklM
32MRAwDgYDVQQHEwdDaGljYWdvMRAwDgYDVQQKEwdUZXN0aW5nMRgwFgYDVQQDEw9U
33ZXN0aW5nIFJvb3QgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAPmaQumL
34urpE527uSEHdL1pqcDRmWzu+98Y6YHzT/J7KWEamyMCNZ6fRW1JCR782UQ8a07fy
352xXsKy4WdKaxyG8CcatwmXvpvRQ44dSANMihHELpANTdyVp6DCysED6wkQFurHlF
361dshEaJw8b/ypDhmbVIo6Ci1xvCJqivbLFnbAgMBAAGjgbswgbgwHQYDVR0OBBYE
37FINVdy1eIfFJDAkk51QJEo3IfgSuMIGIBgNVHSMEgYAwfoAUg1V3LV4h8UkMCSTn
38VAkSjch+BK6hXKRaMFgxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJJTDEQMA4GA1UE
39BxMHQ2hpY2FnbzEQMA4GA1UEChMHVGVzdGluZzEYMBYGA1UEAxMPVGVzdGluZyBS
40b290IENBggg9DMTgxt659DAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GB
41AGGCDazMJGoWNBpc03u6+smc95dEead2KlZXBATOdFT1VesY3+nUOqZhEhTGlDMi
42hkgaZnzoIq/Uamidegk4hirsCT/R+6vsKAAxNTcBjUeZjlykCJWy5ojShGftXIKY
43w/njVbKMXrvc83qmTdGl3TAM0fxQIpqgcglFLveEBgzn
44-----END CERTIFICATE-----
45"""
46
47root_key_pem = """-----BEGIN RSA PRIVATE KEY-----
48MIICXQIBAAKBgQD5mkLpi7q6ROdu7khB3S9aanA0Zls7vvfGOmB80/yeylhGpsjA
49jWen0VtSQke/NlEPGtO38tsV7CsuFnSmschvAnGrcJl76b0UOOHUgDTIoRxC6QDU
503claegwsrBA+sJEBbqx5RdXbIRGicPG/8qQ4Zm1SKOgotcbwiaor2yxZ2wIDAQAB
51AoGBAPCgMpmLxzwDaUmcFbTJUvlLW1hoxNNYSu2jIZm1k/hRAcE60JYwvBkgz3UB
52yMEh0AtLxYe0bFk6EHah11tMUPgscbCq73snJ++8koUw+csk22G65hOs51bVb7Aa
536JBe67oLzdtvgCUFAA2qfrKzWRZzAdhUirQUZgySZk+Xq1pBAkEA/kZG0A6roTSM
54BVnx7LnPfsycKUsTumorpXiylZJjTi9XtmzxhrYN6wgZlDOOwOLgSQhszGpxVoMD
55u3gByT1b2QJBAPtL3mSKdvwRu/+40zaZLwvSJRxaj0mcE4BJOS6Oqs/hS1xRlrNk
56PpQ7WJ4yM6ZOLnXzm2mKyxm50Mv64109FtMCQQDOqS2KkjHaLowTGVxwC0DijMfr
57I9Lf8sSQk32J5VWCySWf5gGTfEnpmUa41gKTMJIbqZZLucNuDcOtzUaeWZlZAkA8
58ttXigLnCqR486JDPTi9ZscoZkZ+w7y6e/hH8t6d5Vjt48JVyfjPIaJY+km58LcN3
596AWSeGAdtRFHVzR7oHjVAkB4hutvxiOeiIVQNBhM6RSI9aBPMI21DoX2JRoxvNW2
60cbvAhow217X9V0dVerEOKxnNYspXRrh36h7k4mQA+sDq
61-----END RSA PRIVATE KEY-----
62"""
63
64server_cert_pem = """-----BEGIN CERTIFICATE-----
65MIICKDCCAZGgAwIBAgIJAJn/HpR21r/8MA0GCSqGSIb3DQEBBQUAMFgxCzAJBgNV
66BAYTAlVTMQswCQYDVQQIEwJJTDEQMA4GA1UEBxMHQ2hpY2FnbzEQMA4GA1UEChMH
67VGVzdGluZzEYMBYGA1UEAxMPVGVzdGluZyBSb290IENBMCIYDzIwMDkwMzI1MTIz
68NzUzWhgPMjAxNzA2MTExMjM3NTNaMBgxFjAUBgNVBAMTDWxvdmVseSBzZXJ2ZXIw
69gZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAL6m+G653V0tpBC/OKl22VxOi2Cv
70lK4TYu9LHSDP9uDVTe7V5D5Tl6qzFoRRx5pfmnkqT5B+W9byp2NU3FC5hLm5zSAr
71b45meUhjEJ/ifkZgbNUjHdBIGP9MAQUHZa5WKdkGIJvGAvs8UzUqlr4TBWQIB24+
72lJ+Ukk/CRgasrYwdAgMBAAGjNjA0MB0GA1UdDgQWBBS4kC7Ij0W1TZXZqXQFAM2e
73gKEG2DATBgNVHSUEDDAKBggrBgEFBQcDATANBgkqhkiG9w0BAQUFAAOBgQBh30Li
74dJ+NlxIOx5343WqIBka3UbsOb2kxWrbkVCrvRapCMLCASO4FqiKWM+L0VDBprqIp
752mgpFQ6FHpoIENGvJhdEKpptQ5i7KaGhnDNTfdy3x1+h852G99f1iyj0RmbuFcM8
76uzujnS8YXWvM7DM1Ilozk4MzPug8jzFp5uhKCQ==
77-----END CERTIFICATE-----
78"""
79
80server_key_pem = """-----BEGIN RSA PRIVATE KEY-----
81MIICWwIBAAKBgQC+pvhuud1dLaQQvzipdtlcTotgr5SuE2LvSx0gz/bg1U3u1eQ+
82U5eqsxaEUceaX5p5Kk+QflvW8qdjVNxQuYS5uc0gK2+OZnlIYxCf4n5GYGzVIx3Q
83SBj/TAEFB2WuVinZBiCbxgL7PFM1Kpa+EwVkCAduPpSflJJPwkYGrK2MHQIDAQAB
84AoGAbwuZ0AR6JveahBaczjfnSpiFHf+mve2UxoQdpyr6ROJ4zg/PLW5K/KXrC48G
85j6f3tXMrfKHcpEoZrQWUfYBRCUsGD5DCazEhD8zlxEHahIsqpwA0WWssJA2VOLEN
86j6DuV2pCFbw67rfTBkTSo32ahfXxEKev5KswZk0JIzH3ooECQQDgzS9AI89h0gs8
87Dt+1m11Rzqo3vZML7ZIyGApUzVan+a7hbc33nbGRkAXjHaUBJO31it/H6dTO+uwX
88msWwNG5ZAkEA2RyFKs5xR5USTFaKLWCgpH/ydV96KPOpBND7TKQx62snDenFNNbn
89FwwOhpahld+vqhYk+pfuWWUpQciE+Bu7ZQJASjfT4sQv4qbbKK/scePicnDdx9th
904e1EeB9xwb+tXXXUo/6Bor/AcUNwfiQ6Zt9PZOK9sR3lMZSsP7rMi7kzuQJABie6
911sXXjFH7nNJvRG4S39cIxq8YRYTy68II/dlB2QzGpKxV/POCxbJ/zu0CU79tuYK7
92NaeNCFfH3aeTrX0LyQJAMBWjWmeKM2G2sCExheeQK0ROnaBC8itCECD4Jsve4nqf
93r50+LF74iLXFwqysVCebPKMOpDWp/qQ1BbJQIPs7/A==
94-----END RSA PRIVATE KEY-----
95"""
96
97client_cert_pem = """-----BEGIN CERTIFICATE-----
98MIICJjCCAY+gAwIBAgIJAKxpFI5lODkjMA0GCSqGSIb3DQEBBQUAMFgxCzAJBgNV
99BAYTAlVTMQswCQYDVQQIEwJJTDEQMA4GA1UEBxMHQ2hpY2FnbzEQMA4GA1UEChMH
100VGVzdGluZzEYMBYGA1UEAxMPVGVzdGluZyBSb290IENBMCIYDzIwMDkwMzI1MTIz
101ODA1WhgPMjAxNzA2MTExMjM4MDVaMBYxFDASBgNVBAMTC3VnbHkgY2xpZW50MIGf
102MA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDAZh/SRtNm5ntMT4qb6YzEpTroMlq2
103rn+GrRHRiZ+xkCw/CGNhbtPir7/QxaUj26BSmQrHw1bGKEbPsWiW7bdXSespl+xK
104iku4G/KvnnmWdeJHqsiXeUZtqurMELcPQAw9xPHEuhqqUJvvEoMTsnCEqGM+7Dtb
105oCRajYyHfluARQIDAQABozYwNDAdBgNVHQ4EFgQUNQB+qkaOaEVecf1J3TTUtAff
1060fAwEwYDVR0lBAwwCgYIKwYBBQUHAwIwDQYJKoZIhvcNAQEFBQADgYEAyv/Jh7gM
107Q3OHvmsFEEvRI+hsW8y66zK4K5de239Y44iZrFYkt7Q5nBPMEWDj4F2hLYWL/qtI
1089Zdr0U4UDCU9SmmGYh4o7R4TZ5pGFvBYvjhHbkSFYFQXZxKUi+WUxplP6I0wr2KJ
109PSTJCjJOn3xo2NTKRgV1gaoTf2EhL+RG8TQ=
110-----END CERTIFICATE-----
111"""
112
113client_key_pem = """-----BEGIN RSA PRIVATE KEY-----
114MIICXgIBAAKBgQDAZh/SRtNm5ntMT4qb6YzEpTroMlq2rn+GrRHRiZ+xkCw/CGNh
115btPir7/QxaUj26BSmQrHw1bGKEbPsWiW7bdXSespl+xKiku4G/KvnnmWdeJHqsiX
116eUZtqurMELcPQAw9xPHEuhqqUJvvEoMTsnCEqGM+7DtboCRajYyHfluARQIDAQAB
117AoGATkZ+NceY5Glqyl4mD06SdcKfV65814vg2EL7V9t8+/mi9rYL8KztSXGlQWPX
118zuHgtRoMl78yQ4ZJYOBVo+nsx8KZNRCEBlE19bamSbQLCeQMenWnpeYyQUZ908gF
119h6L9qsFVJepgA9RDgAjyDoS5CaWCdCCPCH2lDkdcqC54SVUCQQDseuduc4wi8h4t
120V8AahUn9fn9gYfhoNuM0gdguTA0nPLVWz4hy1yJiWYQe0H7NLNNTmCKiLQaJpAbb
121TC6vE8C7AkEA0Ee8CMJUc20BnGEmxwgWcVuqFWaKCo8jTH1X38FlATUsyR3krjW2
122dL3yDD9NwHxsYP7nTKp/U8MV7U9IBn4y/wJBAJl7H0/BcLeRmuJk7IqJ7b635iYB
123D/9beFUw3MUXmQXZUfyYz39xf6CDZsu1GEdEC5haykeln3Of4M9d/4Kj+FcCQQCY
124si6xwT7GzMDkk/ko684AV3KPc/h6G0yGtFIrMg7J3uExpR/VdH2KgwMkZXisSMvw
125JJEQjOMCVsEJlRk54WWjAkEAzoZNH6UhDdBK5F38rVt/y4SEHgbSfJHIAmPS32Kq
126f6GGcfNpip0Uk7q7udTKuX7Q/buZi/C4YW7u3VKAquv9NA==
127-----END RSA PRIVATE KEY-----
128"""
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -0400129
Jean-Paul Calderone20131f52009-04-01 12:05:45 -0400130cleartextCertificatePEM = """-----BEGIN CERTIFICATE-----
131MIIC7TCCAlagAwIBAgIIPQzE4MbeufQwDQYJKoZIhvcNAQEFBQAwWDELMAkGA1UE
132BhMCVVMxCzAJBgNVBAgTAklMMRAwDgYDVQQHEwdDaGljYWdvMRAwDgYDVQQKEwdU
133ZXN0aW5nMRgwFgYDVQQDEw9UZXN0aW5nIFJvb3QgQ0EwIhgPMjAwOTAzMjUxMjM2
134NThaGA8yMDE3MDYxMTEyMzY1OFowWDELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAklM
135MRAwDgYDVQQHEwdDaGljYWdvMRAwDgYDVQQKEwdUZXN0aW5nMRgwFgYDVQQDEw9U
136ZXN0aW5nIFJvb3QgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAPmaQumL
137urpE527uSEHdL1pqcDRmWzu+98Y6YHzT/J7KWEamyMCNZ6fRW1JCR782UQ8a07fy
1382xXsKy4WdKaxyG8CcatwmXvpvRQ44dSANMihHELpANTdyVp6DCysED6wkQFurHlF
1391dshEaJw8b/ypDhmbVIo6Ci1xvCJqivbLFnbAgMBAAGjgbswgbgwHQYDVR0OBBYE
140FINVdy1eIfFJDAkk51QJEo3IfgSuMIGIBgNVHSMEgYAwfoAUg1V3LV4h8UkMCSTn
141VAkSjch+BK6hXKRaMFgxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJJTDEQMA4GA1UE
142BxMHQ2hpY2FnbzEQMA4GA1UEChMHVGVzdGluZzEYMBYGA1UEAxMPVGVzdGluZyBS
143b290IENBggg9DMTgxt659DAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GB
144AGGCDazMJGoWNBpc03u6+smc95dEead2KlZXBATOdFT1VesY3+nUOqZhEhTGlDMi
145hkgaZnzoIq/Uamidegk4hirsCT/R+6vsKAAxNTcBjUeZjlykCJWy5ojShGftXIKY
146w/njVbKMXrvc83qmTdGl3TAM0fxQIpqgcglFLveEBgzn
147-----END CERTIFICATE-----
148"""
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -0400149
Jean-Paul Calderone20131f52009-04-01 12:05:45 -0400150cleartextPrivateKeyPEM = """-----BEGIN RSA PRIVATE KEY-----
151MIICXQIBAAKBgQD5mkLpi7q6ROdu7khB3S9aanA0Zls7vvfGOmB80/yeylhGpsjA
152jWen0VtSQke/NlEPGtO38tsV7CsuFnSmschvAnGrcJl76b0UOOHUgDTIoRxC6QDU
1533claegwsrBA+sJEBbqx5RdXbIRGicPG/8qQ4Zm1SKOgotcbwiaor2yxZ2wIDAQAB
154AoGBAPCgMpmLxzwDaUmcFbTJUvlLW1hoxNNYSu2jIZm1k/hRAcE60JYwvBkgz3UB
155yMEh0AtLxYe0bFk6EHah11tMUPgscbCq73snJ++8koUw+csk22G65hOs51bVb7Aa
1566JBe67oLzdtvgCUFAA2qfrKzWRZzAdhUirQUZgySZk+Xq1pBAkEA/kZG0A6roTSM
157BVnx7LnPfsycKUsTumorpXiylZJjTi9XtmzxhrYN6wgZlDOOwOLgSQhszGpxVoMD
158u3gByT1b2QJBAPtL3mSKdvwRu/+40zaZLwvSJRxaj0mcE4BJOS6Oqs/hS1xRlrNk
159PpQ7WJ4yM6ZOLnXzm2mKyxm50Mv64109FtMCQQDOqS2KkjHaLowTGVxwC0DijMfr
160I9Lf8sSQk32J5VWCySWf5gGTfEnpmUa41gKTMJIbqZZLucNuDcOtzUaeWZlZAkA8
161ttXigLnCqR486JDPTi9ZscoZkZ+w7y6e/hH8t6d5Vjt48JVyfjPIaJY+km58LcN3
1626AWSeGAdtRFHVzR7oHjVAkB4hutvxiOeiIVQNBhM6RSI9aBPMI21DoX2JRoxvNW2
163cbvAhow217X9V0dVerEOKxnNYspXRrh36h7k4mQA+sDq
164-----END RSA PRIVATE KEY-----
165"""
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -0400166
Rick Dean5b7b6372009-04-01 11:34:06 -0500167cleartextCertificateRequestPEM = (
168 "-----BEGIN CERTIFICATE REQUEST-----\n"
169 "MIIBnjCCAQcCAQAwXjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAklMMRAwDgYDVQQH\n"
170 "EwdDaGljYWdvMRcwFQYDVQQKEw5NeSBDb21wYW55IEx0ZDEXMBUGA1UEAxMORnJl\n"
171 "ZGVyaWNrIERlYW4wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANp6Y17WzKSw\n"
172 "BsUWkXdqg6tnXy8H8hA1msCMWpc+/2KJ4mbv5NyD6UD+/SqagQqulPbF/DFea9nA\n"
173 "E0zhmHJELcM8gUTIlXv/cgDWnmK4xj8YkjVUiCdqKRAKeuzLG1pGmwwF5lGeJpXN\n"
174 "xQn5ecR0UYSOWj6TTGXB9VyUMQzCClcBAgMBAAGgADANBgkqhkiG9w0BAQUFAAOB\n"
175 "gQAAJGuF/R/GGbeC7FbFW+aJgr9ee0Xbl6nlhu7pTe67k+iiKT2dsl2ti68MVTnu\n"
176 "Vrb3HUNqOkiwsJf6kCtq5oPn3QVYzTa76Dt2y3Rtzv6boRSlmlfrgS92GNma8JfR\n"
177 "oICQk3nAudi6zl1Dix3BCv1pUp5KMtGn3MeDEi6QFGy2rA==\n"
178 "-----END CERTIFICATE REQUEST-----\n")
179
Jean-Paul Calderone20131f52009-04-01 12:05:45 -0400180encryptedPrivateKeyPEM = """-----BEGIN RSA PRIVATE KEY-----
181Proc-Type: 4,ENCRYPTED
182DEK-Info: DES-EDE3-CBC,9573604A18579E9E
Jean-Paul Calderone5ef86512008-04-26 19:06:28 -0400183
Jean-Paul Calderone20131f52009-04-01 12:05:45 -0400184SHOho56WxDkT0ht10UTeKc0F5u8cqIa01kzFAmETw0MAs8ezYtK15NPdCXUm3X/2
185a17G7LSF5bkxOgZ7vpXyMzun/owrj7CzvLxyncyEFZWvtvzaAhPhvTJtTIB3kf8B
1868+qRcpTGK7NgXEgYBW5bj1y4qZkD4zCL9o9NQzsKI3Ie8i0239jsDOWR38AxjXBH
187mGwAQ4Z6ZN5dnmM4fhMIWsmFf19sNyAML4gHenQCHhmXbjXeVq47aC2ProInJbrm
188+00TcisbAQ40V9aehVbcDKtS4ZbMVDwncAjpXpcncC54G76N6j7F7wL7L/FuXa3A
189fvSVy9n2VfF/pJ3kYSflLHH2G/DFxjF7dl0GxhKPxJjp3IJi9VtuvmN9R2jZWLQF
190tfC8dXgy/P9CfFQhlinqBTEwgH0oZ/d4k4NVFDSdEMaSdmBAjlHpc+Vfdty3HVnV
191rKXj//wslsFNm9kIwJGIgKUa/n2jsOiydrsk1mgH7SmNCb3YHgZhbbnq0qLat/HC
192gHDt3FHpNQ31QzzL3yrenFB2L9osIsnRsDTPFNi4RX4SpDgNroxOQmyzCCV6H+d4
193o1mcnNiZSdxLZxVKccq0AfRpHqpPAFnJcQHP6xyT9MZp6fBa0XkxDnt9kNU8H3Qw
1947SJWZ69VXjBUzMlQViLuaWMgTnL+ZVyFZf9hTF7U/ef4HMLMAVNdiaGG+G+AjCV/
195MbzjS007Oe4qqBnCWaFPSnJX6uLApeTbqAxAeyCql56ULW5x6vDMNC3dwjvS/CEh
19611n8RkgFIQA0AhuKSIg3CbuartRsJnWOLwgLTzsrKYL4yRog1RJrtw==
197-----END RSA PRIVATE KEY-----
198"""
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -0400199encryptedPrivateKeyPEMPassphrase = "foobar"
200
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -0400201# Some PKCS#7 stuff. Generated with the openssl command line:
202#
203# openssl crl2pkcs7 -inform pem -outform pem -certfile s.pem -nocrl
204#
205# with a certificate and key (but the key should be irrelevant) in s.pem
206pkcs7Data = """\
207-----BEGIN PKCS7-----
208MIIDNwYJKoZIhvcNAQcCoIIDKDCCAyQCAQExADALBgkqhkiG9w0BBwGgggMKMIID
209BjCCAm+gAwIBAgIBATANBgkqhkiG9w0BAQQFADB7MQswCQYDVQQGEwJTRzERMA8G
210A1UEChMITTJDcnlwdG8xFDASBgNVBAsTC00yQ3J5cHRvIENBMSQwIgYDVQQDExtN
211MkNyeXB0byBDZXJ0aWZpY2F0ZSBNYXN0ZXIxHTAbBgkqhkiG9w0BCQEWDm5ncHNA
212cG9zdDEuY29tMB4XDTAwMDkxMDA5NTEzMFoXDTAyMDkxMDA5NTEzMFowUzELMAkG
213A1UEBhMCU0cxETAPBgNVBAoTCE0yQ3J5cHRvMRIwEAYDVQQDEwlsb2NhbGhvc3Qx
214HTAbBgkqhkiG9w0BCQEWDm5ncHNAcG9zdDEuY29tMFwwDQYJKoZIhvcNAQEBBQAD
215SwAwSAJBAKy+e3dulvXzV7zoTZWc5TzgApr8DmeQHTYC8ydfzH7EECe4R1Xh5kwI
216zOuuFfn178FBiS84gngaNcrFi0Z5fAkCAwEAAaOCAQQwggEAMAkGA1UdEwQCMAAw
217LAYJYIZIAYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0G
218A1UdDgQWBBTPhIKSvnsmYsBVNWjj0m3M2z0qVTCBpQYDVR0jBIGdMIGagBT7hyNp
21965w6kxXlxb8pUU/+7Sg4AaF/pH0wezELMAkGA1UEBhMCU0cxETAPBgNVBAoTCE0y
220Q3J5cHRvMRQwEgYDVQQLEwtNMkNyeXB0byBDQTEkMCIGA1UEAxMbTTJDcnlwdG8g
221Q2VydGlmaWNhdGUgTWFzdGVyMR0wGwYJKoZIhvcNAQkBFg5uZ3BzQHBvc3QxLmNv
222bYIBADANBgkqhkiG9w0BAQQFAAOBgQA7/CqT6PoHycTdhEStWNZde7M/2Yc6BoJu
223VwnW8YxGO8Sn6UJ4FeffZNcYZddSDKosw8LtPOeWoK3JINjAk5jiPQ2cww++7QGG
224/g5NDjxFZNDJP1dGiLAxPW6JXwov4v0FmdzfLOZ01jDcgQQZqEpYlgpuI5JEWUQ9
225Ho4EzbYCOaEAMQA=
226-----END PKCS7-----
227"""
228
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -0400229
Jean-Paul Calderone18808652009-07-05 12:54:05 -0400230class X509ExtTests(TestCase):
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400231 """
232 Tests for L{OpenSSL.crypto.X509Extension}.
233 """
234
235 def setUp(self):
236 """
237 Create a new private key and start a certificate request (for a test
238 method to finish in one way or another).
239 """
240 # Basic setup stuff to generate a certificate
241 self.pkey = PKey()
242 self.pkey.generate_key(TYPE_RSA, 384)
243 self.req = X509Req()
244 self.req.set_pubkey(self.pkey)
245 # Authority good you have.
246 self.req.get_subject().commonName = "Yoda root CA"
247 self.x509 = X509()
248 self.subject = self.x509.get_subject()
249 self.subject.commonName = self.req.get_subject().commonName
250 self.x509.set_issuer(self.subject)
251 self.x509.set_pubkey(self.pkey)
252 now = datetime.now().strftime("%Y%m%d%H%M%SZ")
253 expire = (datetime.now() + timedelta(days=100)).strftime("%Y%m%d%H%M%SZ")
254 self.x509.set_notBefore(now)
255 self.x509.set_notAfter(expire)
256
257
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400258 def test_type(self):
259 """
260 L{X509Extension} and L{X509ExtensionType} refer to the same type object
261 and can be used to create instances of that type.
262 """
263 self.assertIdentical(X509Extension, X509ExtensionType)
264 self.assertConsistentType(
265 X509Extension, 'X509Extension', 'basicConstraints', True, 'CA:true')
266
267
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500268 def test_construction(self):
269 """
270 L{X509Extension} accepts an extension type name, a critical flag,
271 and an extension value and returns an L{X509ExtensionType} instance.
272 """
Jean-Paul Calderone2ee1e7c2008-12-31 14:58:38 -0500273 basic = X509Extension('basicConstraints', True, 'CA:true')
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500274 self.assertTrue(
275 isinstance(basic, X509ExtensionType),
276 "%r is of type %r, should be %r" % (
277 basic, type(basic), X509ExtensionType))
278
Jean-Paul Calderone2ee1e7c2008-12-31 14:58:38 -0500279 comment = X509Extension('nsComment', False, 'pyOpenSSL unit test')
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500280 self.assertTrue(
281 isinstance(comment, X509ExtensionType),
282 "%r is of type %r, should be %r" % (
283 comment, type(comment), X509ExtensionType))
284
285
Jean-Paul Calderone391585f2008-12-31 14:36:31 -0500286 def test_invalid_extension(self):
287 """
288 L{X509Extension} raises something if it is passed a bad extension
289 name or value.
290 """
291 self.assertRaises(
292 Error, X509Extension, 'thisIsMadeUp', False, 'hi')
293 self.assertRaises(
294 Error, X509Extension, 'basicConstraints', False, 'blah blah')
295
Jean-Paul Calderone2ee1e7c2008-12-31 14:58:38 -0500296 # Exercise a weird one (an extension which uses the r2i method). This
297 # exercises the codepath that requires a non-NULL ctx to be passed to
298 # X509V3_EXT_nconf. It can't work now because we provide no
299 # configuration database. It might be made to work in the future.
300 self.assertRaises(
301 Error, X509Extension, 'proxyCertInfo', True,
302 'language:id-ppl-anyLanguage,pathlen:1,policy:text:AB')
303
Jean-Paul Calderone391585f2008-12-31 14:36:31 -0500304
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500305 def test_get_critical(self):
306 """
307 L{X509ExtensionType.get_critical} returns the value of the
308 extension's critical flag.
309 """
Jean-Paul Calderone2ee1e7c2008-12-31 14:58:38 -0500310 ext = X509Extension('basicConstraints', True, 'CA:true')
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500311 self.assertTrue(ext.get_critical())
Jean-Paul Calderone2ee1e7c2008-12-31 14:58:38 -0500312 ext = X509Extension('basicConstraints', False, 'CA:true')
Jean-Paul Calderonee7db4b42008-12-31 13:39:24 -0500313 self.assertFalse(ext.get_critical())
314
Jean-Paul Calderone7535dab2008-03-06 18:53:11 -0500315
Jean-Paul Calderonef8c5fab2008-12-31 15:53:48 -0500316 def test_get_short_name(self):
317 """
318 L{X509ExtensionType.get_short_name} returns a string giving the short
319 type name of the extension.
320 """
321 ext = X509Extension('basicConstraints', True, 'CA:true')
322 self.assertEqual(ext.get_short_name(), 'basicConstraints')
323 ext = X509Extension('nsComment', True, 'foo bar')
324 self.assertEqual(ext.get_short_name(), 'nsComment')
325
326
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400327 def test_unused_subject(self):
Rick Dean47262da2009-07-08 16:17:17 -0500328 """
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400329 The C{subject} parameter to L{X509Extension} may be provided for an
330 extension which does not use it and is ignored in this case.
Rick Dean47262da2009-07-08 16:17:17 -0500331 """
Jean-Paul Calderonef0179c72009-07-17 15:48:22 -0400332 ext1 = X509Extension('basicConstraints', False, 'CA:TRUE', subject=self.x509)
333 self.x509.add_extensions([ext1])
334 self.x509.sign(self.pkey, 'sha1')
335 # This is a little lame. Can we think of a better way?
336 text = dump_certificate(FILETYPE_TEXT, self.x509)
337 self.assertTrue('X509v3 Basic Constraints:' in text)
338 self.assertTrue('CA:TRUE' in text)
339
340
341 def test_subject(self):
342 """
343 If an extension requires a subject, the C{subject} parameter to
344 L{X509Extension} provides its value.
345 """
346 ext3 = X509Extension('subjectKeyIdentifier', False, 'hash', subject=self.x509)
347 self.x509.add_extensions([ext3])
348 self.x509.sign(self.pkey, 'sha1')
349 text = dump_certificate(FILETYPE_TEXT, self.x509)
350 self.assertTrue('X509v3 Subject Key Identifier:' in text)
351
352
353 def test_missing_subject(self):
354 """
355 If an extension requires a subject and the C{subject} parameter is
356 given no value, something happens.
357 """
358 self.assertRaises(
359 Error, X509Extension, 'subjectKeyIdentifier', False, 'hash')
360
361
362 def test_invalid_subject(self):
363 """
364 If the C{subject} parameter is given a value which is not an L{X509}
365 instance, L{TypeError} is raised.
366 """
367 for badObj in [True, object(), "hello", [], self]:
368 self.assertRaises(
369 TypeError,
370 X509Extension,
371 'basicConstraints', False, 'CA:TRUE', subject=badObj)
372
373
374 def test_unused_issuer(self):
375 """
376 The C{issuer} parameter to L{X509Extension} may be provided for an
377 extension which does not use it and is ignored in this case.
378 """
379 ext1 = X509Extension('basicConstraints', False, 'CA:TRUE', issuer=self.x509)
380 self.x509.add_extensions([ext1])
381 self.x509.sign(self.pkey, 'sha1')
382 text = dump_certificate(FILETYPE_TEXT, self.x509)
383 self.assertTrue('X509v3 Basic Constraints:' in text)
384 self.assertTrue('CA:TRUE' in text)
385
386
387 def test_issuer(self):
388 """
389 If an extension requires a issuer, the C{issuer} parameter to
390 L{X509Extension} provides its value.
391 """
392 ext2 = X509Extension(
393 'authorityKeyIdentifier', False, 'issuer:always',
394 issuer=self.x509)
395 self.x509.add_extensions([ext2])
396 self.x509.sign(self.pkey, 'sha1')
397 text = dump_certificate(FILETYPE_TEXT, self.x509)
398 self.assertTrue('X509v3 Authority Key Identifier:' in text)
399 self.assertTrue('DirName:/CN=Yoda root CA' in text)
400
401
402 def test_missing_issuer(self):
403 """
404 If an extension requires an issue and the C{issuer} parameter is given
405 no value, something happens.
406 """
407 self.assertRaises(
408 Error,
409 X509Extension,
410 'authorityKeyIdentifier', False, 'keyid:always,issuer:always')
411
412
413 def test_invalid_issuer(self):
414 """
415 If the C{issuer} parameter is given a value which is not an L{X509}
416 instance, L{TypeError} is raised.
417 """
418 for badObj in [True, object(), "hello", [], self]:
419 self.assertRaises(
420 TypeError,
421 X509Extension,
422 'authorityKeyIdentifier', False, 'keyid:always,issuer:always',
423 issuer=badObj)
Rick Dean47262da2009-07-08 16:17:17 -0500424
425
Jean-Paul Calderone391585f2008-12-31 14:36:31 -0500426
Jean-Paul Calderone18808652009-07-05 12:54:05 -0400427class PKeyTests(TestCase):
Jean-Paul Calderoneac930e12008-03-06 18:50:51 -0500428 """
429 Unit tests for L{OpenSSL.crypto.PKey}.
430 """
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400431 def test_type(self):
432 """
433 L{PKey} and L{PKeyType} refer to the same type object and can be used
434 to create instances of that type.
435 """
436 self.assertIdentical(PKey, PKeyType)
437 self.assertConsistentType(PKey, 'PKey')
438
439
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500440 def test_construction(self):
441 """
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400442 L{PKey} takes no arguments and returns a new L{PKey} instance.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500443 """
444 self.assertRaises(TypeError, PKey, None)
445 key = PKey()
446 self.assertTrue(
447 isinstance(key, PKeyType),
448 "%r is of type %r, should be %r" % (key, type(key), PKeyType))
449
450
451 def test_pregeneration(self):
452 """
453 L{PKeyType.bits} and L{PKeyType.type} return C{0} before the key is
454 generated.
455 """
456 key = PKey()
457 self.assertEqual(key.type(), 0)
458 self.assertEqual(key.bits(), 0)
459
460
461 def test_failedGeneration(self):
462 """
Jean-Paul Calderoneab82db72008-03-06 00:09:31 -0500463 L{PKeyType.generate_key} takes two arguments, the first giving the key
464 type as one of L{TYPE_RSA} or L{TYPE_DSA} and the second giving the
465 number of bits to generate. If an invalid type is specified or
466 generation fails, L{Error} is raised. If an invalid number of bits is
467 specified, L{ValueError} or L{Error} is raised.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500468 """
469 key = PKey()
470 self.assertRaises(TypeError, key.generate_key)
471 self.assertRaises(TypeError, key.generate_key, 1, 2, 3)
472 self.assertRaises(TypeError, key.generate_key, "foo", "bar")
473 self.assertRaises(Error, key.generate_key, -1, 0)
Jean-Paul Calderoneab82db72008-03-06 00:09:31 -0500474
Jean-Paul Calderoneab82db72008-03-06 00:09:31 -0500475 self.assertRaises(ValueError, key.generate_key, TYPE_RSA, -1)
476 self.assertRaises(ValueError, key.generate_key, TYPE_RSA, 0)
Jean-Paul Calderoned71fe982008-03-06 00:31:50 -0500477
478 # XXX RSA generation for small values of bits is fairly buggy in a wide
479 # range of OpenSSL versions. I need to figure out what the safe lower
480 # bound for a reasonable number of OpenSSL versions is and explicitly
481 # check for that in the wrapper. The failure behavior is typically an
482 # infinite loop inside OpenSSL.
483
484 # self.assertRaises(Error, key.generate_key, TYPE_RSA, 2)
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500485
486 # XXX DSA generation seems happy with any number of bits. The DSS
487 # says bits must be between 512 and 1024 inclusive. OpenSSL's DSA
488 # generator doesn't seem to care about the upper limit at all. For
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500489 # the lower limit, it uses 512 if anything smaller is specified.
Jean-Paul Calderoned8782ad2008-03-04 23:39:59 -0500490 # So, it doesn't seem possible to make generate_key fail for
491 # TYPE_DSA with a bits argument which is at least an int.
492
493 # self.assertRaises(Error, key.generate_key, TYPE_DSA, -7)
494
495
496 def test_rsaGeneration(self):
497 """
498 L{PKeyType.generate_key} generates an RSA key when passed
499 L{TYPE_RSA} as a type and a reasonable number of bits.
500 """
501 bits = 128
502 key = PKey()
503 key.generate_key(TYPE_RSA, bits)
504 self.assertEqual(key.type(), TYPE_RSA)
505 self.assertEqual(key.bits(), bits)
506
507
508 def test_dsaGeneration(self):
509 """
510 L{PKeyType.generate_key} generates a DSA key when passed
511 L{TYPE_DSA} as a type and a reasonable number of bits.
512 """
513 # 512 is a magic number. The DSS (Digital Signature Standard)
514 # allows a minimum of 512 bits for DSA. DSA_generate_parameters
515 # will silently promote any value below 512 to 512.
516 bits = 512
517 key = PKey()
518 key.generate_key(TYPE_DSA, bits)
519 self.assertEqual(key.type(), TYPE_DSA)
520 self.assertEqual(key.bits(), bits)
521
522
523 def test_regeneration(self):
524 """
525 L{PKeyType.generate_key} can be called multiple times on the same
526 key to generate new keys.
527 """
528 key = PKey()
529 for type, bits in [(TYPE_RSA, 512), (TYPE_DSA, 576)]:
530 key.generate_key(type, bits)
531 self.assertEqual(key.type(), type)
532 self.assertEqual(key.bits(), bits)
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500533
534
535
Jean-Paul Calderone18808652009-07-05 12:54:05 -0400536class X509NameTests(TestCase):
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500537 """
538 Unit tests for L{OpenSSL.crypto.X509Name}.
539 """
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500540 def _x509name(self, **attrs):
541 # XXX There's no other way to get a new X509Name yet.
542 name = X509().get_subject()
543 attrs = attrs.items()
544 # Make the order stable - order matters!
545 attrs.sort(lambda (k1, v1), (k2, v2): cmp(v1, v2))
546 for k, v in attrs:
547 setattr(name, k, v)
548 return name
549
550
Rick Deane15b1472009-07-09 15:53:42 -0500551 def test_type(self):
552 """
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400553 The type of X509Name objects is L{X509NameType}.
Rick Deane15b1472009-07-09 15:53:42 -0500554 """
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400555 self.assertIdentical(X509Name, X509NameType)
556 self.assertEqual(X509NameType.__name__, 'X509Name')
557 self.assertTrue(isinstance(X509NameType, type))
558
Rick Deane15b1472009-07-09 15:53:42 -0500559 name = self._x509name()
560 self.assertTrue(
561 isinstance(name, X509NameType),
562 "%r is of type %r, should be %r" % (
563 name, type(name), X509NameType))
Rick Deane15b1472009-07-09 15:53:42 -0500564
565
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500566 def test_attributes(self):
567 """
568 L{X509NameType} instances have attributes for each standard (?)
569 X509Name field.
570 """
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500571 name = self._x509name()
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500572 name.commonName = "foo"
573 self.assertEqual(name.commonName, "foo")
574 self.assertEqual(name.CN, "foo")
575 name.CN = "baz"
576 self.assertEqual(name.commonName, "baz")
577 self.assertEqual(name.CN, "baz")
578 name.commonName = "bar"
579 self.assertEqual(name.commonName, "bar")
580 self.assertEqual(name.CN, "bar")
581 name.CN = "quux"
582 self.assertEqual(name.commonName, "quux")
583 self.assertEqual(name.CN, "quux")
584
585
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500586 def test_copy(self):
587 """
588 L{X509Name} creates a new L{X509NameType} instance with all the same
589 attributes as an existing L{X509NameType} instance when called with
590 one.
591 """
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500592 name = self._x509name(commonName="foo", emailAddress="bar@example.com")
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500593
594 copy = X509Name(name)
595 self.assertEqual(copy.commonName, "foo")
596 self.assertEqual(copy.emailAddress, "bar@example.com")
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500597
598 # Mutate the copy and ensure the original is unmodified.
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500599 copy.commonName = "baz"
600 self.assertEqual(name.commonName, "foo")
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500601
602 # Mutate the original and ensure the copy is unmodified.
Jean-Paul Calderoneeff3cd92008-03-05 22:35:26 -0500603 name.emailAddress = "quux@example.com"
604 self.assertEqual(copy.emailAddress, "bar@example.com")
605
Jean-Paul Calderonee098dc72008-03-06 18:36:19 -0500606
607 def test_repr(self):
608 """
609 L{repr} passed an L{X509NameType} instance should return a string
610 containing a description of the type and the NIDs which have been set
611 on it.
612 """
613 name = self._x509name(commonName="foo", emailAddress="bar")
614 self.assertEqual(
615 repr(name),
616 "<X509Name object '/emailAddress=bar/CN=foo'>")
617
618
619 def test_comparison(self):
620 """
621 L{X509NameType} instances should compare based on their NIDs.
622 """
623 def _equality(a, b, assertTrue, assertFalse):
624 assertTrue(a == b, "(%r == %r) --> False" % (a, b))
625 assertFalse(a != b)
626 assertTrue(b == a)
627 assertFalse(b != a)
628
629 def assertEqual(a, b):
630 _equality(a, b, self.assertTrue, self.assertFalse)
631
632 # Instances compare equal to themselves.
633 name = self._x509name()
634 assertEqual(name, name)
635
636 # Empty instances should compare equal to each other.
637 assertEqual(self._x509name(), self._x509name())
638
639 # Instances with equal NIDs should compare equal to each other.
640 assertEqual(self._x509name(commonName="foo"),
641 self._x509name(commonName="foo"))
642
643 # Instance with equal NIDs set using different aliases should compare
644 # equal to each other.
645 assertEqual(self._x509name(commonName="foo"),
646 self._x509name(CN="foo"))
647
648 # Instances with more than one NID with the same values should compare
649 # equal to each other.
650 assertEqual(self._x509name(CN="foo", organizationalUnitName="bar"),
651 self._x509name(commonName="foo", OU="bar"))
652
653 def assertNotEqual(a, b):
654 _equality(a, b, self.assertFalse, self.assertTrue)
655
656 # Instances with different values for the same NID should not compare
657 # equal to each other.
658 assertNotEqual(self._x509name(CN="foo"),
659 self._x509name(CN="bar"))
660
661 # Instances with different NIDs should not compare equal to each other.
662 assertNotEqual(self._x509name(CN="foo"),
663 self._x509name(OU="foo"))
664
665 def _inequality(a, b, assertTrue, assertFalse):
666 assertTrue(a < b)
667 assertTrue(a <= b)
668 assertTrue(b > a)
669 assertTrue(b >= a)
670 assertFalse(a > b)
671 assertFalse(a >= b)
672 assertFalse(b < a)
673 assertFalse(b <= a)
674
675 def assertLessThan(a, b):
676 _inequality(a, b, self.assertTrue, self.assertFalse)
677
678 # An X509Name with a NID with a value which sorts less than the value
679 # of the same NID on another X509Name compares less than the other
680 # X509Name.
681 assertLessThan(self._x509name(CN="abc"),
682 self._x509name(CN="def"))
683
684 def assertGreaterThan(a, b):
685 _inequality(a, b, self.assertFalse, self.assertTrue)
686
687 # An X509Name with a NID with a value which sorts greater than the
688 # value of the same NID on another X509Name compares greater than the
689 # other X509Name.
690 assertGreaterThan(self._x509name(CN="def"),
691 self._x509name(CN="abc"))
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -0500692
693
Jean-Paul Calderone110cd092008-03-24 17:27:42 -0400694 def test_hash(self):
695 """
696 L{X509Name.hash} returns an integer hash based on the value of the
697 name.
698 """
699 a = self._x509name(CN="foo")
700 b = self._x509name(CN="foo")
701 self.assertEqual(a.hash(), b.hash())
702 a.CN = "bar"
703 self.assertNotEqual(a.hash(), b.hash())
704
705
Jean-Paul Calderonee957a002008-03-25 15:16:51 -0400706 def test_der(self):
707 """
708 L{X509Name.der} returns the DER encoded form of the name.
709 """
710 a = self._x509name(CN="foo", C="US")
711 self.assertEqual(
712 a.der(),
713 '0\x1b1\x0b0\t\x06\x03U\x04\x06\x13\x02US'
714 '1\x0c0\n\x06\x03U\x04\x03\x13\x03foo')
715
716
Jean-Paul Calderonec54cc182008-03-26 21:11:07 -0400717 def test_get_components(self):
718 """
719 L{X509Name.get_components} returns a C{list} of two-tuples of C{str}
720 giving the NIDs and associated values which make up the name.
721 """
722 a = self._x509name()
723 self.assertEqual(a.get_components(), [])
724 a.CN = "foo"
725 self.assertEqual(a.get_components(), [("CN", "foo")])
726 a.organizationalUnitName = "bar"
727 self.assertEqual(
728 a.get_components(),
729 [("CN", "foo"), ("OU", "bar")])
730
Jean-Paul Calderone110cd092008-03-24 17:27:42 -0400731
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -0400732class _PKeyInteractionTestsMixin:
733 """
734 Tests which involve another thing and a PKey.
735 """
736 def signable(self):
737 """
738 Return something with a C{set_pubkey}, C{set_pubkey}, and C{sign} method.
739 """
740 raise NotImplementedError()
741
742
743 def test_signWithUngenerated(self):
744 """
745 L{X509Req.sign} raises L{ValueError} when pass a L{PKey} with no parts.
746 """
747 request = self.signable()
748 key = PKey()
749 self.assertRaises(ValueError, request.sign, key, 'MD5')
750
751
752 def test_signWithPublicKey(self):
753 """
754 L{X509Req.sign} raises L{ValueError} when pass a L{PKey} with no
755 private part as the signing key.
756 """
757 request = self.signable()
758 key = PKey()
759 key.generate_key(TYPE_RSA, 512)
760 request.set_pubkey(key)
761 pub = request.get_pubkey()
762 self.assertRaises(ValueError, request.sign, pub, 'MD5')
763
764
765
Jean-Paul Calderone18808652009-07-05 12:54:05 -0400766class X509ReqTests(TestCase, _PKeyInteractionTestsMixin):
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -0500767 """
768 Tests for L{OpenSSL.crypto.X509Req}.
769 """
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -0400770 def signable(self):
771 """
772 Create and return a new L{X509Req}.
773 """
774 return X509Req()
775
776
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400777 def test_type(self):
778 """
779 L{X509Req} and L{X509ReqType} refer to the same type object and can be
780 used to create instances of that type.
781 """
782 self.assertIdentical(X509Req, X509ReqType)
783 self.assertConsistentType(X509Req, 'X509Req')
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -0500784
785
786 def test_construction(self):
787 """
788 L{X509Req} takes no arguments and returns an L{X509ReqType} instance.
789 """
790 request = X509Req()
791 self.assertTrue(
792 isinstance(request, X509ReqType),
793 "%r is of type %r, should be %r" % (request, type(request), X509ReqType))
794
795
Jean-Paul Calderone8dd19b82008-12-28 20:41:16 -0500796 def test_version(self):
797 """
798 L{X509ReqType.set_version} sets the X.509 version of the certificate
799 request. L{X509ReqType.get_version} returns the X.509 version of
800 the certificate request. The initial value of the version is 0.
801 """
802 request = X509Req()
803 self.assertEqual(request.get_version(), 0)
804 request.set_version(1)
805 self.assertEqual(request.get_version(), 1)
806 request.set_version(3)
807 self.assertEqual(request.get_version(), 3)
808
809
Jean-Paul Calderone2aa2b332008-03-06 21:43:14 -0500810 def test_get_subject(self):
811 """
812 L{X509ReqType.get_subject} returns an L{X509Name} for the subject of
813 the request and which is valid even after the request object is
814 otherwise dead.
815 """
816 request = X509Req()
817 subject = request.get_subject()
818 self.assertTrue(
819 isinstance(subject, X509NameType),
820 "%r is of type %r, should be %r" % (subject, type(subject), X509NameType))
821 subject.commonName = "foo"
822 self.assertEqual(request.get_subject().commonName, "foo")
823 del request
824 subject.commonName = "bar"
825 self.assertEqual(subject.commonName, "bar")
Jean-Paul Calderone78381d22008-03-06 23:35:22 -0500826
827
828
Jean-Paul Calderone18808652009-07-05 12:54:05 -0400829class X509Tests(TestCase, _PKeyInteractionTestsMixin):
Jean-Paul Calderone78381d22008-03-06 23:35:22 -0500830 """
831 Tests for L{OpenSSL.crypto.X509}.
832 """
Jean-Paul Calderone5ef86512008-04-26 19:06:28 -0400833 pemData = cleartextCertificatePEM + cleartextPrivateKeyPEM
Jean-Paul Calderone8114b452008-03-25 15:27:59 -0400834
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -0400835 def signable(self):
836 """
837 Create and return a new L{X509}.
838 """
839 return X509()
840
841
Jean-Paul Calderone68649052009-07-17 21:14:27 -0400842 def test_type(self):
843 """
844 L{X509} and L{X509Type} refer to the same type object and can be used
845 to create instances of that type.
846 """
847 self.assertIdentical(X509, X509Type)
848 self.assertConsistentType(X509, 'X509')
849
850
Jean-Paul Calderone78381d22008-03-06 23:35:22 -0500851 def test_construction(self):
852 """
853 L{X509} takes no arguments and returns an instance of L{X509Type}.
854 """
855 certificate = X509()
856 self.assertTrue(
857 isinstance(certificate, X509Type),
858 "%r is of type %r, should be %r" % (certificate,
859 type(certificate),
860 X509Type))
Rick Deane15b1472009-07-09 15:53:42 -0500861 self.assertEqual(type(X509Type).__name__, 'type')
862 self.assertEqual(type(certificate).__name__, 'X509')
863 self.assertEqual(type(certificate), X509Type)
Rick Dean04113e72009-07-16 12:06:35 -0500864 self.assertEqual(type(certificate), X509)
Jean-Paul Calderone78381d22008-03-06 23:35:22 -0500865
866
867 def test_serial_number(self):
868 """
869 The serial number of an L{X509Type} can be retrieved and modified with
870 L{X509Type.get_serial_number} and L{X509Type.set_serial_number}.
871 """
872 certificate = X509()
873 self.assertRaises(TypeError, certificate.set_serial_number)
874 self.assertRaises(TypeError, certificate.set_serial_number, 1, 2)
875 self.assertRaises(TypeError, certificate.set_serial_number, "1")
876 self.assertRaises(TypeError, certificate.set_serial_number, 5.5)
877 self.assertEqual(certificate.get_serial_number(), 0)
878 certificate.set_serial_number(1)
879 self.assertEqual(certificate.get_serial_number(), 1)
880 certificate.set_serial_number(2 ** 32 + 1)
881 self.assertEqual(certificate.get_serial_number(), 2 ** 32 + 1)
882 certificate.set_serial_number(2 ** 64 + 1)
883 self.assertEqual(certificate.get_serial_number(), 2 ** 64 + 1)
Jean-Paul Calderone525ef802008-03-09 20:39:42 -0400884 certificate.set_serial_number(2 ** 128 + 1)
885 self.assertEqual(certificate.get_serial_number(), 2 ** 128 + 1)
886
887
888 def _setBoundTest(self, which):
889 """
890 L{X509Type.set_notBefore} takes a string in the format of an ASN1
891 GENERALIZEDTIME and sets the beginning of the certificate's validity
892 period to it.
893 """
894 certificate = X509()
895 set = getattr(certificate, 'set_not' + which)
896 get = getattr(certificate, 'get_not' + which)
897
Jean-Paul Calderonee0615b52008-03-09 21:44:46 -0400898 # Starts with no value.
899 self.assertEqual(get(), None)
900
Jean-Paul Calderone525ef802008-03-09 20:39:42 -0400901 # GMT (Or is it UTC?) -exarkun
902 when = "20040203040506Z"
903 set(when)
904 self.assertEqual(get(), when)
905
906 # A plus two hours and thirty minutes offset
907 when = "20040203040506+0530"
908 set(when)
909 self.assertEqual(get(), when)
910
911 # A minus one hour fifteen minutes offset
912 when = "20040203040506-0115"
913 set(when)
914 self.assertEqual(get(), when)
915
916 # An invalid string results in a ValueError
917 self.assertRaises(ValueError, set, "foo bar")
918
919
920 def test_set_notBefore(self):
921 """
922 L{X509Type.set_notBefore} takes a string in the format of an ASN1
923 GENERALIZEDTIME and sets the beginning of the certificate's validity
924 period to it.
925 """
926 self._setBoundTest("Before")
927
928
929 def test_set_notAfter(self):
930 """
931 L{X509Type.set_notAfter} takes a string in the format of an ASN1
932 GENERALIZEDTIME and sets the end of the certificate's validity period
933 to it.
934 """
935 self._setBoundTest("After")
Jean-Paul Calderone76576d52008-03-24 16:04:46 -0400936
937
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -0400938 def test_get_notBefore(self):
939 """
940 L{X509Type.get_notBefore} returns a string in the format of an ASN1
941 GENERALIZEDTIME even for certificates which store it as UTCTIME
942 internally.
943 """
Jean-Paul Calderone8114b452008-03-25 15:27:59 -0400944 cert = load_certificate(FILETYPE_PEM, self.pemData)
Jean-Paul Calderone20131f52009-04-01 12:05:45 -0400945 self.assertEqual(cert.get_notBefore(), "20090325123658Z")
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -0400946
Rick Dean38a05c82009-07-18 01:41:30 -0500947
948 def test_get_notAfter(self):
949 """
950 L{X509Type.get_notAfter} returns a string in the format of an ASN1
951 GENERALIZEDTIME even for certificates which store it as UTCTIME
952 internally.
953 """
954 cert = load_certificate(FILETYPE_PEM, self.pemData)
955 self.assertEqual(cert.get_notAfter(), "20170611123658Z")
956
957
958 def test_digest(self):
959 """
960 L{X509.digest} returns a string giving ":"-separated hex-encoded words
961 of the digest of the certificate.
962 """
963 cert = X509()
964 self.assertEqual(
965 cert.digest("md5"),
966 "A8:EB:07:F8:53:25:0A:F2:56:05:C5:A5:C4:C4:C7:15")
967
968
969
Rick Dean623ee362009-07-17 12:22:16 -0500970class PKCS12Tests(TestCase):
971 """
Jean-Paul Calderone9389c922009-07-25 12:24:04 -0400972 Test for L{OpenSSL.crypto.PKCS12} and L{OpenSSL.crypto.load_pkcs12}.
Rick Dean623ee362009-07-17 12:22:16 -0500973 """
974 pemData = cleartextCertificatePEM + cleartextPrivateKeyPEM
975
Jean-Paul Calderonec3a41f72009-07-25 12:36:02 -0400976 def test_type(self):
977 """
978 L{PKCS12Type} is a type object.
979 """
980 self.assertIdentical(PKCS12, PKCS12Type)
981 self.assertConsistentType(PKCS12, 'PKCS12')
982
983
Rick Deanf94096c2009-07-18 14:23:06 -0500984 def test_empty_construction(self):
Rick Dean38a05c82009-07-18 01:41:30 -0500985 """
Jean-Paul Calderonedc857b52009-07-25 12:25:07 -0400986 L{PKCS12} returns a new instance of L{PKCS12} with no certificate,
987 private key, CA certificates, or friendly name.
Rick Dean38a05c82009-07-18 01:41:30 -0500988 """
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -0400989 p12 = PKCS12()
Rick Dean623ee362009-07-17 12:22:16 -0500990 self.assertEqual(None, p12.get_certificate())
991 self.assertEqual(None, p12.get_privatekey())
992 self.assertEqual(None, p12.get_ca_certificates())
Rick Dean42d69e12009-07-20 11:36:08 -0500993 self.assertEqual(None, p12.get_friendlyname())
Rick Dean623ee362009-07-17 12:22:16 -0500994
Rick Dean38a05c82009-07-18 01:41:30 -0500995
Rick Dean623ee362009-07-17 12:22:16 -0500996 def test_type_errors(self):
Rick Dean38a05c82009-07-18 01:41:30 -0500997 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -0400998 The L{PKCS12} setter functions (C{set_certificate}, C{set_privatekey},
999 C{set_ca_certificates}, and C{set_friendlyname}) raise L{TypeError}
1000 when passed objects of types other than those expected.
Rick Dean38a05c82009-07-18 01:41:30 -05001001 """
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04001002 p12 = PKCS12()
Rick Dean623ee362009-07-17 12:22:16 -05001003 self.assertRaises(TypeError, p12.set_certificate, 3)
Rick Deanf94096c2009-07-18 14:23:06 -05001004 self.assertRaises(TypeError, p12.set_certificate, PKey())
1005 self.assertRaises(TypeError, p12.set_certificate, X509)
Rick Dean623ee362009-07-17 12:22:16 -05001006 self.assertRaises(TypeError, p12.set_privatekey, 3)
Rick Deanf94096c2009-07-18 14:23:06 -05001007 self.assertRaises(TypeError, p12.set_privatekey, 'legbone')
1008 self.assertRaises(TypeError, p12.set_privatekey, X509())
Rick Dean623ee362009-07-17 12:22:16 -05001009 self.assertRaises(TypeError, p12.set_ca_certificates, 3)
1010 self.assertRaises(TypeError, p12.set_ca_certificates, X509())
1011 self.assertRaises(TypeError, p12.set_ca_certificates, (3, 4))
Rick Deanf94096c2009-07-18 14:23:06 -05001012 self.assertRaises(TypeError, p12.set_ca_certificates, ( PKey(), ))
Rick Dean42d69e12009-07-20 11:36:08 -05001013 self.assertRaises(TypeError, p12.set_friendlyname, 6)
1014 self.assertRaises(TypeError, p12.set_friendlyname, ('foo', 'bar'))
Rick Dean623ee362009-07-17 12:22:16 -05001015
Rick Dean38a05c82009-07-18 01:41:30 -05001016
Rick Dean623ee362009-07-17 12:22:16 -05001017 def test_key_only(self):
1018 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001019 A L{PKCS12} with only a private key can be exported using
1020 L{PKCS12.export} and loaded again using L{load_pkcs12}.
Rick Dean623ee362009-07-17 12:22:16 -05001021 """
1022 passwd = 'blah'
1023 p12 = PKCS12()
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04001024 pkey = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001025 p12.set_privatekey(pkey)
Rick Dean623ee362009-07-17 12:22:16 -05001026 self.assertEqual(None, p12.get_certificate())
1027 self.assertEqual(pkey, p12.get_privatekey())
Rick Dean321a0512009-08-13 17:21:29 -05001028 try:
1029 dumped_p12 = p12.export(passphrase=passwd, iter=2, maciter=3)
1030 except Error:
1031 # Some versions of OpenSSL will throw an exception
1032 # for this nearly useless PKCS12 we tried to generate:
1033 # [('PKCS12 routines', 'PKCS12_create', 'invalid null argument')]
1034 return
Rick Dean623ee362009-07-17 12:22:16 -05001035 p12 = load_pkcs12(dumped_p12, passwd)
1036 self.assertEqual(None, p12.get_ca_certificates())
1037 self.assertEqual(None, p12.get_certificate())
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001038
1039 # OpenSSL fails to bring the key back to us. So sad. Perhaps in the
1040 # future this will be improved.
1041 self.assertTrue(isinstance(p12.get_privatekey(), (PKey, type(None))))
Rick Dean623ee362009-07-17 12:22:16 -05001042
Rick Dean38a05c82009-07-18 01:41:30 -05001043
Rick Dean623ee362009-07-17 12:22:16 -05001044 def test_cert_only(self):
1045 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001046 A L{PKCS12} with only a certificate can be exported using
1047 L{PKCS12.export} and loaded again using L{load_pkcs12}.
Rick Dean623ee362009-07-17 12:22:16 -05001048 """
1049 passwd = 'blah'
1050 p12 = PKCS12()
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04001051 cert = load_certificate(FILETYPE_PEM, cleartextCertificatePEM)
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001052 p12.set_certificate(cert)
Rick Dean623ee362009-07-17 12:22:16 -05001053 self.assertEqual(cert, p12.get_certificate())
1054 self.assertEqual(None, p12.get_privatekey())
Rick Dean321a0512009-08-13 17:21:29 -05001055 try:
1056 dumped_p12 = p12.export(passphrase=passwd, iter=2, maciter=3)
1057 except Error:
1058 # Some versions of OpenSSL will throw an exception
1059 # for this nearly useless PKCS12 we tried to generate:
1060 # [('PKCS12 routines', 'PKCS12_create', 'invalid null argument')]
1061 return
Rick Dean623ee362009-07-17 12:22:16 -05001062 p12 = load_pkcs12(dumped_p12, passwd)
1063 self.assertEqual(None, p12.get_privatekey())
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001064
1065 # OpenSSL fails to bring the cert back to us. Groany mcgroan.
1066 self.assertTrue(isinstance(p12.get_certificate(), (X509, type(None))))
1067
1068 # Oh ho. It puts the certificate into the ca certificates list, in
1069 # fact. Totally bogus, I would think. Nevertheless, let's exploit
1070 # that to check to see if it reconstructed the certificate we expected
1071 # it to. At some point, hopefully this will change so that
1072 # p12.get_certificate() is actually what returns the loaded
1073 # certificate.
1074 self.assertEqual(
1075 cleartextCertificatePEM,
1076 dump_certificate(FILETYPE_PEM, p12.get_ca_certificates()[0]))
Rick Dean623ee362009-07-17 12:22:16 -05001077
1078
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001079 def gen_pkcs12(self, cert_pem=None, key_pem=None, ca_pem=None, friendly_name=None):
Rick Dean623ee362009-07-17 12:22:16 -05001080 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001081 Generate a PKCS12 object with components from PEM. Verify that the set
1082 functions return None.
Rick Dean623ee362009-07-17 12:22:16 -05001083 """
Rick Deanf94096c2009-07-18 14:23:06 -05001084 p12 = PKCS12()
1085 if cert_pem:
1086 ret = p12.set_certificate(load_certificate(FILETYPE_PEM, cert_pem))
1087 self.assertEqual(ret, None)
1088 if key_pem:
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001089 ret = p12.set_privatekey(load_privatekey(FILETYPE_PEM, key_pem))
Rick Deanf94096c2009-07-18 14:23:06 -05001090 self.assertEqual(ret, None)
1091 if ca_pem:
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001092 ret = p12.set_ca_certificates((load_certificate(FILETYPE_PEM, ca_pem),))
Rick Deanf94096c2009-07-18 14:23:06 -05001093 self.assertEqual(ret, None)
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001094 if friendly_name:
1095 ret = p12.set_friendlyname(friendly_name)
Rick Dean42d69e12009-07-20 11:36:08 -05001096 self.assertEqual(ret, None)
Rick Deanf94096c2009-07-18 14:23:06 -05001097 return p12
1098
1099
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001100 def check_recovery(self, p12_str, key=None, cert=None, ca=None, passwd='',
1101 extra=()):
Rick Deanf94096c2009-07-18 14:23:06 -05001102 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001103 Use openssl program to confirm three components are recoverable from a
1104 PKCS12 string.
Rick Deanf94096c2009-07-18 14:23:06 -05001105 """
1106 if key:
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001107 recovered_key = _runopenssl(
1108 p12_str, "pkcs12", '-nocerts', '-nodes', '-passin',
1109 'pass:' + passwd, *extra)
Rick Deanf94096c2009-07-18 14:23:06 -05001110 self.assertEqual(recovered_key[-len(key):], key)
1111 if cert:
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001112 recovered_cert = _runopenssl(
1113 p12_str, "pkcs12", '-clcerts', '-nodes', '-passin',
1114 'pass:' + passwd, '-nokeys', *extra)
Rick Deanf94096c2009-07-18 14:23:06 -05001115 self.assertEqual(recovered_cert[-len(cert):], cert)
1116 if ca:
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001117 recovered_cert = _runopenssl(
1118 p12_str, "pkcs12", '-cacerts', '-nodes', '-passin',
1119 'pass:' + passwd, '-nokeys', *extra)
Rick Deanf94096c2009-07-18 14:23:06 -05001120 self.assertEqual(recovered_cert[-len(ca):], ca)
1121
1122
1123 def test_load_pkcs12(self):
1124 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001125 A PKCS12 string generated using the openssl command line can be loaded
1126 with L{load_pkcs12} and its components extracted and examined.
Rick Deanf94096c2009-07-18 14:23:06 -05001127 """
Rick Dean623ee362009-07-17 12:22:16 -05001128 passwd = 'whatever'
1129 pem = client_key_pem + client_cert_pem
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001130 p12_str = _runopenssl(
1131 pem, "pkcs12", '-export', '-clcerts', '-passout', 'pass:' + passwd)
Rick Dean623ee362009-07-17 12:22:16 -05001132 p12 = load_pkcs12(p12_str, passwd)
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04001133 # verify
Rick Deanf94096c2009-07-18 14:23:06 -05001134 self.assertTrue(isinstance(p12, PKCS12))
Rick Dean623ee362009-07-17 12:22:16 -05001135 cert_pem = dump_certificate(FILETYPE_PEM, p12.get_certificate())
1136 self.assertEqual(cert_pem, client_cert_pem)
1137 key_pem = dump_privatekey(FILETYPE_PEM, p12.get_privatekey())
1138 self.assertEqual(key_pem, client_key_pem)
1139 self.assertEqual(None, p12.get_ca_certificates())
Rick Deanf94096c2009-07-18 14:23:06 -05001140
Rick Deanee568302009-07-24 09:56:29 -05001141
1142 def test_load_pkcs12_garbage(self):
1143 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001144 L{load_pkcs12} raises L{OpenSSL.crypto.Error} when passed a string
1145 which is not a PKCS12 dump.
Rick Deanee568302009-07-24 09:56:29 -05001146 """
1147 passwd = 'whatever'
1148 e = self.assertRaises(Error, load_pkcs12, 'fruit loops', passwd)
1149 self.assertEqual( e[0][0][0], 'asn1 encoding routines')
1150 self.assertEqual( len(e[0][0]), 3)
1151
1152
Rick Deanf94096c2009-07-18 14:23:06 -05001153 def test_replace(self):
1154 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001155 L{PKCS12.set_certificate} replaces the certificate in a PKCS12 cluster.
1156 L{PKCS12.set_privatekey} replaces the private key.
1157 L{PKCS12.set_ca_certificates} replaces the CA certificates.
Rick Deanf94096c2009-07-18 14:23:06 -05001158 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001159 p12 = self.gen_pkcs12(client_cert_pem, client_key_pem, root_cert_pem)
1160 p12.set_certificate(load_certificate(FILETYPE_PEM, server_cert_pem))
1161 p12.set_privatekey(load_privatekey(FILETYPE_PEM, server_key_pem))
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04001162 root_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
Rick Deanf94096c2009-07-18 14:23:06 -05001163 client_cert = load_certificate(FILETYPE_PEM, client_cert_pem)
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001164 p12.set_ca_certificates([root_cert]) # not a tuple
Rick Dean623ee362009-07-17 12:22:16 -05001165 self.assertEqual(1, len(p12.get_ca_certificates()))
1166 self.assertEqual(root_cert, p12.get_ca_certificates()[0])
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001167 p12.set_ca_certificates([client_cert, root_cert])
Rick Deanf94096c2009-07-18 14:23:06 -05001168 self.assertEqual(2, len(p12.get_ca_certificates()))
1169 self.assertEqual(client_cert, p12.get_ca_certificates()[0])
1170 self.assertEqual(root_cert, p12.get_ca_certificates()[1])
1171
1172
1173 def test_friendly_name(self):
1174 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001175 The I{friendlyName} of a PKCS12 can be set and retrieved via
1176 L{PKCS12.get_friendlyname} and L{PKCS12_set_friendlyname}, and a
1177 L{PKCS12} with a friendly name set can be dumped with L{PKCS12.export}.
Rick Deanf94096c2009-07-18 14:23:06 -05001178 """
Rick Deanf94096c2009-07-18 14:23:06 -05001179 passwd = 'Dogmeat[]{}!@#$%^&*()~`?/.,<>-_+=";:'
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001180 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
1181 for friendly_name in ['Serverlicious', None, '###']:
Rick Dean42d69e12009-07-20 11:36:08 -05001182 p12.set_friendlyname(friendly_name)
1183 self.assertEqual(p12.get_friendlyname(), friendly_name)
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04001184 dumped_p12 = p12.export(passphrase=passwd, iter=2, maciter=3)
Rick Dean42d69e12009-07-20 11:36:08 -05001185 reloaded_p12 = load_pkcs12(dumped_p12, passwd)
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001186 self.assertEqual(
1187 p12.get_friendlyname(),reloaded_p12.get_friendlyname())
Jean-Paul Calderonea202edb2009-07-25 12:22:12 -04001188 # We would use the openssl program to confirm the friendly
1189 # name, but it is not possible. The pkcs12 command
1190 # does not store the friendly name in the cert's
Rick Dean42d69e12009-07-20 11:36:08 -05001191 # alias, which we could then extract.
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001192 self.check_recovery(
1193 dumped_p12, key=server_key_pem, cert=server_cert_pem,
1194 ca=root_cert_pem, passwd=passwd)
Rick Deanf94096c2009-07-18 14:23:06 -05001195
1196
1197 def test_various_empty_passphrases(self):
1198 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001199 Test that missing, None, and '' passphrases are identical for PKCS12
1200 export.
Rick Deanf94096c2009-07-18 14:23:06 -05001201 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001202 p12 = self.gen_pkcs12(client_cert_pem, client_key_pem, root_cert_pem)
Rick Dean623ee362009-07-17 12:22:16 -05001203 passwd = ''
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001204 dumped_p12_empty = p12.export(iter=2, maciter=0, passphrase=passwd)
1205 dumped_p12_none = p12.export(iter=3, maciter=2, passphrase=None)
1206 dumped_p12_nopw = p12.export(iter=9, maciter=4)
1207 for dumped_p12 in [dumped_p12_empty, dumped_p12_none, dumped_p12_nopw]:
1208 self.check_recovery(
1209 dumped_p12, key=client_key_pem, cert=client_cert_pem,
1210 ca=root_cert_pem, passwd=passwd)
Rick Deanf94096c2009-07-18 14:23:06 -05001211
1212
1213 def test_removing_ca_cert(self):
1214 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001215 Passing C{None} to L{PKCS12.set_ca_certificates} removes all CA
1216 certificates.
Rick Deanf94096c2009-07-18 14:23:06 -05001217 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001218 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
1219 p12.set_ca_certificates(None)
Rick Dean623ee362009-07-17 12:22:16 -05001220 self.assertEqual(None, p12.get_ca_certificates())
Rick Deanf94096c2009-07-18 14:23:06 -05001221
1222
1223 def test_export_without_mac(self):
1224 """
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001225 Exporting a PKCS12 with a C{maciter} of C{-1} excludes the MAC
1226 entirely.
Rick Deanf94096c2009-07-18 14:23:06 -05001227 """
1228 passwd = 'Lake Michigan'
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001229 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
Rick Dean623ee362009-07-17 12:22:16 -05001230 dumped_p12 = p12.export(maciter=-1, passphrase=passwd, iter=2)
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -04001231 self.check_recovery(
1232 dumped_p12, key=server_key_pem, cert=server_cert_pem,
1233 passwd=passwd, extra=('-nomacver',))
1234
1235
1236 def test_load_without_mac(self):
1237 """
1238 Loading a PKCS12 without a MAC does something other than crash.
1239 """
1240 passwd = 'Lake Michigan'
1241 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
1242 dumped_p12 = p12.export(maciter=-1, passphrase=passwd, iter=2)
Rick Dean321a0512009-08-13 17:21:29 -05001243 try:
1244 recovered_p12 = load_pkcs12(dumped_p12, passwd)
1245 # The person who generated this PCKS12 should be flogged,
1246 # or better yet we should have a means to determine
1247 # whether a PCKS12 had a MAC that was verified.
1248 # Anyway, libopenssl chooses to allow it, so the
1249 # pyopenssl binding does as well.
1250 self.assertTrue(isinstance(recovered_p12, PKCS12))
1251 except Error:
1252 # Failing here with an exception is preferred as some openssl
1253 # versions do.
1254 pass
Rick Dean623ee362009-07-17 12:22:16 -05001255
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04001256
Rick Dean25bcc1f2009-07-20 11:53:13 -05001257 def test_zero_len_list_for_ca(self):
1258 """
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04001259 A PKCS12 with an empty CA certificates list can be exported.
Rick Dean25bcc1f2009-07-20 11:53:13 -05001260 """
1261 passwd = 'Hobie 18'
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04001262 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem)
1263 p12.set_ca_certificates([])
Rick Dean25bcc1f2009-07-20 11:53:13 -05001264 self.assertEqual((), p12.get_ca_certificates())
1265 dumped_p12 = p12.export(passphrase=passwd, iter=3)
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04001266 self.check_recovery(
1267 dumped_p12, key=server_key_pem, cert=server_cert_pem,
1268 passwd=passwd)
Rick Dean25bcc1f2009-07-20 11:53:13 -05001269
1270
Rick Deanf94096c2009-07-18 14:23:06 -05001271 def test_export_without_args(self):
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04001272 """
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04001273 All the arguments to L{PKCS12.export} are optional.
Jean-Paul Calderone38a646d2008-03-25 15:16:18 -04001274 """
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04001275 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
Rick Deanf94096c2009-07-18 14:23:06 -05001276 dumped_p12 = p12.export() # no args
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04001277 self.check_recovery(
1278 dumped_p12, key=server_key_pem, cert=server_cert_pem, passwd='')
Rick Deanf94096c2009-07-18 14:23:06 -05001279
1280
1281 def test_key_cert_mismatch(self):
1282 """
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04001283 L{PKCS12.export} raises an exception when a key and certificate
1284 mismatch.
Rick Deanf94096c2009-07-18 14:23:06 -05001285 """
Jean-Paul Calderoneda1ffa72009-07-25 21:24:34 -04001286 p12 = self.gen_pkcs12(server_cert_pem, client_key_pem, root_cert_pem)
1287 self.assertRaises(Error, p12.export)
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04001288
1289
1290
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04001291# These quoting functions taken directly from Twisted's twisted.python.win32.
1292_cmdLineQuoteRe = re.compile(r'(\\*)"')
1293_cmdLineQuoteRe2 = re.compile(r'(\\+)\Z')
1294def cmdLineQuote(s):
1295 """
1296 Internal method for quoting a single command-line argument.
1297
1298 @type: C{str}
1299 @param s: A single unquoted string to quote for something that is expecting
1300 cmd.exe-style quoting
1301
1302 @rtype: C{str}
1303 @return: A cmd.exe-style quoted string
1304
1305 @see: U{http://www.perlmonks.org/?node_id=764004}
1306 """
1307 s = _cmdLineQuoteRe2.sub(r"\1\1", _cmdLineQuoteRe.sub(r'\1\1\\"', s))
1308 return '"%s"' % s
1309
1310
1311
1312def quoteArguments(arguments):
1313 """
1314 Quote an iterable of command-line arguments for passing to CreateProcess or
1315 a similar API. This allows the list passed to C{reactor.spawnProcess} to
1316 match the child process's C{sys.argv} properly.
1317
1318 @type arguments: C{iterable} of C{str}
1319 @param arguments: An iterable of unquoted arguments to quote
1320
1321 @rtype: C{str}
1322 @return: A space-delimited string containing quoted versions of L{arguments}
1323 """
1324 return ' '.join(map(cmdLineQuote, arguments))
1325
1326
Rick Dean4c9ad612009-07-17 15:05:22 -05001327def _runopenssl(pem, *args):
1328 """
1329 Run the command line openssl tool with the given arguments and write
Rick Dean55d1ce62009-08-13 17:40:24 -05001330 the given PEM to its stdin. Not safe for quotes.
Rick Dean4c9ad612009-07-17 15:05:22 -05001331 """
Jean-Paul Calderone038de952009-08-21 12:16:06 -04001332 if os.name == 'posix':
Jean-Paul Calderone7b874db2009-08-27 12:32:47 -04001333 command = "openssl " + " ".join(["'%s'" % (arg.replace("'", "'\\''"),) for arg in args])
Rick Dean55d1ce62009-08-13 17:40:24 -05001334 else:
Jean-Paul Calderone50924502009-08-27 12:47:55 -04001335 command = "openssl " + quoteArguments(args)
Jean-Paul Calderone038de952009-08-21 12:16:06 -04001336 write, read = popen2(command, "b")
Rick Dean4c9ad612009-07-17 15:05:22 -05001337 write.write(pem)
1338 write.close()
1339 return read.read()
1340
1341
1342
Jean-Paul Calderone18808652009-07-05 12:54:05 -04001343class FunctionTests(TestCase):
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04001344 """
1345 Tests for free-functions in the L{OpenSSL.crypto} module.
1346 """
1347 def test_load_privatekey_wrongPassphrase(self):
1348 """
1349 L{load_privatekey} raises L{OpenSSL.crypto.Error} when it is passed an
1350 encrypted PEM and an incorrect passphrase.
1351 """
1352 self.assertRaises(
1353 Error,
1354 load_privatekey, FILETYPE_PEM, encryptedPrivateKeyPEM, "quack")
1355
1356
1357 def test_load_privatekey_passphrase(self):
1358 """
1359 L{load_privatekey} can create a L{PKey} object from an encrypted PEM
1360 string if given the passphrase.
1361 """
1362 key = load_privatekey(
1363 FILETYPE_PEM, encryptedPrivateKeyPEM,
1364 encryptedPrivateKeyPEMPassphrase)
1365 self.assertTrue(isinstance(key, PKeyType))
1366
1367
1368 def test_load_privatekey_wrongPassphraseCallback(self):
1369 """
1370 L{load_privatekey} raises L{OpenSSL.crypto.Error} when it is passed an
1371 encrypted PEM and a passphrase callback which returns an incorrect
1372 passphrase.
1373 """
1374 called = []
1375 def cb(*a):
1376 called.append(None)
1377 return "quack"
1378 self.assertRaises(
1379 Error,
1380 load_privatekey, FILETYPE_PEM, encryptedPrivateKeyPEM, cb)
1381 self.assertTrue(called)
1382
1383 def test_load_privatekey_passphraseCallback(self):
1384 """
1385 L{load_privatekey} can create a L{PKey} object from an encrypted PEM
1386 string if given a passphrase callback which returns the correct
1387 password.
1388 """
1389 called = []
1390 def cb(writing):
1391 called.append(writing)
1392 return encryptedPrivateKeyPEMPassphrase
1393 key = load_privatekey(FILETYPE_PEM, encryptedPrivateKeyPEM, cb)
1394 self.assertTrue(isinstance(key, PKeyType))
1395 self.assertEqual(called, [False])
1396
1397
1398 def test_dump_privatekey_passphrase(self):
1399 """
1400 L{dump_privatekey} writes an encrypted PEM when given a passphrase.
1401 """
1402 passphrase = "foo"
1403 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
1404 pem = dump_privatekey(FILETYPE_PEM, key, "blowfish", passphrase)
1405 self.assertTrue(isinstance(pem, str))
1406 loadedKey = load_privatekey(FILETYPE_PEM, pem, passphrase)
1407 self.assertTrue(isinstance(loadedKey, PKeyType))
1408 self.assertEqual(loadedKey.type(), key.type())
1409 self.assertEqual(loadedKey.bits(), key.bits())
1410
Jean-Paul Calderonef17e4212009-04-01 14:21:40 -04001411
Rick Dean5b7b6372009-04-01 11:34:06 -05001412 def test_dump_certificate(self):
1413 """
1414 L{dump_certificate} writes PEM, DER, and text.
1415 """
Jean-Paul Calderonef17e4212009-04-01 14:21:40 -04001416 pemData = cleartextCertificatePEM + cleartextPrivateKeyPEM
Rick Dean5b7b6372009-04-01 11:34:06 -05001417 cert = load_certificate(FILETYPE_PEM, pemData)
1418 dumped_pem = dump_certificate(FILETYPE_PEM, cert)
1419 self.assertEqual(dumped_pem, cleartextCertificatePEM)
1420 dumped_der = dump_certificate(FILETYPE_ASN1, cert)
Rick Dean4c9ad612009-07-17 15:05:22 -05001421 good_der = _runopenssl(dumped_pem, "x509", "-outform", "DER")
Rick Dean5b7b6372009-04-01 11:34:06 -05001422 self.assertEqual(dumped_der, good_der)
1423 cert2 = load_certificate(FILETYPE_ASN1, dumped_der)
1424 dumped_pem2 = dump_certificate(FILETYPE_PEM, cert2)
1425 self.assertEqual(dumped_pem2, cleartextCertificatePEM)
1426 dumped_text = dump_certificate(FILETYPE_TEXT, cert)
Rick Dean4c9ad612009-07-17 15:05:22 -05001427 good_text = _runopenssl(dumped_pem, "x509", "-noout", "-text")
Rick Dean5b7b6372009-04-01 11:34:06 -05001428 self.assertEqual(dumped_text, good_text)
1429
1430
1431 def test_dump_privatekey(self):
1432 """
1433 L{dump_privatekey} writes a PEM, DER, and text.
1434 """
1435 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
1436 dumped_pem = dump_privatekey(FILETYPE_PEM, key)
1437 self.assertEqual(dumped_pem, cleartextPrivateKeyPEM)
1438 dumped_der = dump_privatekey(FILETYPE_ASN1, key)
Jean-Paul Calderonef17e4212009-04-01 14:21:40 -04001439 # XXX This OpenSSL call writes "writing RSA key" to standard out. Sad.
Rick Dean4c9ad612009-07-17 15:05:22 -05001440 good_der = _runopenssl(dumped_pem, "rsa", "-outform", "DER")
Rick Dean5b7b6372009-04-01 11:34:06 -05001441 self.assertEqual(dumped_der, good_der)
1442 key2 = load_privatekey(FILETYPE_ASN1, dumped_der)
1443 dumped_pem2 = dump_privatekey(FILETYPE_PEM, key2)
1444 self.assertEqual(dumped_pem2, cleartextPrivateKeyPEM)
1445 dumped_text = dump_privatekey(FILETYPE_TEXT, key)
Rick Dean4c9ad612009-07-17 15:05:22 -05001446 good_text = _runopenssl(dumped_pem, "rsa", "-noout", "-text")
Rick Dean5b7b6372009-04-01 11:34:06 -05001447 self.assertEqual(dumped_text, good_text)
1448
Jean-Paul Calderonef17e4212009-04-01 14:21:40 -04001449
Rick Dean5b7b6372009-04-01 11:34:06 -05001450 def test_dump_certificate_request(self):
1451 """
1452 L{dump_certificate_request} writes a PEM, DER, and text.
1453 """
1454 req = load_certificate_request(FILETYPE_PEM, cleartextCertificateRequestPEM)
1455 dumped_pem = dump_certificate_request(FILETYPE_PEM, req)
1456 self.assertEqual(dumped_pem, cleartextCertificateRequestPEM)
1457 dumped_der = dump_certificate_request(FILETYPE_ASN1, req)
Rick Dean4c9ad612009-07-17 15:05:22 -05001458 good_der = _runopenssl(dumped_pem, "req", "-outform", "DER")
Rick Dean5b7b6372009-04-01 11:34:06 -05001459 self.assertEqual(dumped_der, good_der)
1460 req2 = load_certificate_request(FILETYPE_ASN1, dumped_der)
1461 dumped_pem2 = dump_certificate_request(FILETYPE_PEM, req2)
1462 self.assertEqual(dumped_pem2, cleartextCertificateRequestPEM)
1463 dumped_text = dump_certificate_request(FILETYPE_TEXT, req)
Rick Dean4c9ad612009-07-17 15:05:22 -05001464 good_text = _runopenssl(dumped_pem, "req", "-noout", "-text")
Rick Dean5b7b6372009-04-01 11:34:06 -05001465 self.assertEqual(dumped_text, good_text)
1466
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -04001467
1468 def test_dump_privatekey_passphraseCallback(self):
1469 """
1470 L{dump_privatekey} writes an encrypted PEM when given a callback which
1471 returns the correct passphrase.
1472 """
1473 passphrase = "foo"
1474 called = []
1475 def cb(writing):
1476 called.append(writing)
1477 return passphrase
1478 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
1479 pem = dump_privatekey(FILETYPE_PEM, key, "blowfish", cb)
1480 self.assertTrue(isinstance(pem, str))
1481 self.assertEqual(called, [True])
1482 loadedKey = load_privatekey(FILETYPE_PEM, pem, passphrase)
1483 self.assertTrue(isinstance(loadedKey, PKeyType))
1484 self.assertEqual(loadedKey.type(), key.type())
1485 self.assertEqual(loadedKey.bits(), key.bits())
Rick Dean5b7b6372009-04-01 11:34:06 -05001486
1487
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04001488 def test_load_pkcs7_data(self):
1489 """
1490 L{load_pkcs7_data} accepts a PKCS#7 string and returns an instance of
1491 L{PKCS7Type}.
1492 """
1493 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
1494 self.assertTrue(isinstance(pkcs7, PKCS7Type))
1495
1496
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04001497
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001498class PKCS7Tests(TestCase):
1499 """
1500 Tests for L{PKCS7Type}.
1501 """
1502 def test_type(self):
1503 """
1504 L{PKCS7Type} is a type object.
1505 """
1506 self.assertTrue(isinstance(PKCS7Type, type))
1507 self.assertEqual(PKCS7Type.__name__, 'PKCS7')
1508
1509 # XXX This doesn't currently work.
1510 # self.assertIdentical(PKCS7, PKCS7Type)
1511
1512
1513
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04001514class NetscapeSPKITests(TestCase):
1515 """
1516 Tests for L{OpenSSL.crypto.NetscapeSPKI}.
1517 """
Jean-Paul Calderone68649052009-07-17 21:14:27 -04001518 def test_type(self):
1519 """
1520 L{NetscapeSPKI} and L{NetscapeSPKIType} refer to the same type object
1521 and can be used to create instances of that type.
1522 """
1523 self.assertIdentical(NetscapeSPKI, NetscapeSPKIType)
1524 self.assertConsistentType(NetscapeSPKI, 'NetscapeSPKI')
1525
1526
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -04001527 def test_construction(self):
1528 """
1529 L{NetscapeSPKI} returns an instance of L{NetscapeSPKIType}.
1530 """
1531 nspki = NetscapeSPKI()
1532 self.assertTrue(isinstance(nspki, NetscapeSPKIType))
1533
1534
1535
James Yonan7c2e5d32010-02-27 05:45:50 -07001536class SignVerifyTests(TestCase):
1537 """
1538 Tests for L{OpenSSL.crypto.sign} and L{OpenSSL.crypto.verify}.
1539 """
1540 def test_sign_verify(self):
1541 from OpenSSL.crypto import sign, verify
1542
1543 content = "It was a bright cold day in April, and the clocks were striking thirteen. Winston Smith, his chin nuzzled into his breast in an effort to escape the vile wind, slipped quickly through the glass doors of Victory Mansions, though not quickly enough to prevent a swirl of gritty dust from entering along with him."
1544 priv_key = load_privatekey (FILETYPE_PEM, root_key_pem) # sign the content with this private key
1545 good_cert = load_certificate(FILETYPE_PEM, root_cert_pem) # verify the content with this cert
1546 bad_cert = load_certificate(FILETYPE_PEM, server_cert_pem) # certificate unrelated to priv_key, used to trigger an error
1547
1548 for digest in ('md5', 'sha1'):
1549 sig = sign(priv_key, content, digest)
1550
1551 # Verify the signature of content, will throw an exception if error.
1552 verify(good_cert, sig, content, digest)
1553
1554 # This should fail because the certificate doesn't match the
1555 # private key that was used to sign the content.
1556 self.assertRaises(Error, verify, bad_cert, sig, content, digest)
1557
1558 # This should fail because we've "tainted" the content after
1559 # signing it.
1560 self.assertRaises(Error, verify, good_cert, sig, content+"tainted", digest)
1561
1562 # test that unknown digest types fail
1563 self.assertRaises(ValueError, sign, priv_key, content, "strange-digest")
1564 self.assertRaises(ValueError, verify, good_cert, sig, content, "strange-digest")
1565
Rick Dean5b7b6372009-04-01 11:34:06 -05001566if __name__ == '__main__':
1567 main()