1 # Copyright (c) Jean-Paul Calderone
2 # See LICENSE file for details.
5 Unit tests for L{OpenSSL.crypto}.
8 from unittest import main
11 from subprocess import PIPE, Popen
12 from datetime import datetime, timedelta
14 from OpenSSL.crypto import TYPE_RSA, TYPE_DSA, Error, PKey, PKeyType
15 from OpenSSL.crypto import X509, X509Type, X509Name, X509NameType
16 from OpenSSL.crypto import X509Req, X509ReqType
17 from OpenSSL.crypto import X509Extension, X509ExtensionType
18 from OpenSSL.crypto import load_certificate, load_privatekey
19 from OpenSSL.crypto import FILETYPE_PEM, FILETYPE_ASN1, FILETYPE_TEXT
20 from OpenSSL.crypto import dump_certificate, load_certificate_request
21 from OpenSSL.crypto import dump_certificate_request, dump_privatekey
22 from OpenSSL.crypto import PKCS7Type, load_pkcs7_data
23 from OpenSSL.crypto import PKCS12, PKCS12Type, load_pkcs12
24 from OpenSSL.crypto import CRL, Revoked, load_crl
25 from OpenSSL.crypto import NetscapeSPKI, NetscapeSPKIType
26 from OpenSSL.crypto import sign, verify
27 from OpenSSL.test.util import TestCase, bytes, b
30 root_cert_pem = b("""-----BEGIN CERTIFICATE-----
31 MIIC7TCCAlagAwIBAgIIPQzE4MbeufQwDQYJKoZIhvcNAQEFBQAwWDELMAkGA1UE
32 BhMCVVMxCzAJBgNVBAgTAklMMRAwDgYDVQQHEwdDaGljYWdvMRAwDgYDVQQKEwdU
33 ZXN0aW5nMRgwFgYDVQQDEw9UZXN0aW5nIFJvb3QgQ0EwIhgPMjAwOTAzMjUxMjM2
34 NThaGA8yMDE3MDYxMTEyMzY1OFowWDELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAklM
35 MRAwDgYDVQQHEwdDaGljYWdvMRAwDgYDVQQKEwdUZXN0aW5nMRgwFgYDVQQDEw9U
36 ZXN0aW5nIFJvb3QgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAPmaQumL
37 urpE527uSEHdL1pqcDRmWzu+98Y6YHzT/J7KWEamyMCNZ6fRW1JCR782UQ8a07fy
38 2xXsKy4WdKaxyG8CcatwmXvpvRQ44dSANMihHELpANTdyVp6DCysED6wkQFurHlF
39 1dshEaJw8b/ypDhmbVIo6Ci1xvCJqivbLFnbAgMBAAGjgbswgbgwHQYDVR0OBBYE
40 FINVdy1eIfFJDAkk51QJEo3IfgSuMIGIBgNVHSMEgYAwfoAUg1V3LV4h8UkMCSTn
41 VAkSjch+BK6hXKRaMFgxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJJTDEQMA4GA1UE
42 BxMHQ2hpY2FnbzEQMA4GA1UEChMHVGVzdGluZzEYMBYGA1UEAxMPVGVzdGluZyBS
43 b290IENBggg9DMTgxt659DAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GB
44 AGGCDazMJGoWNBpc03u6+smc95dEead2KlZXBATOdFT1VesY3+nUOqZhEhTGlDMi
45 hkgaZnzoIq/Uamidegk4hirsCT/R+6vsKAAxNTcBjUeZjlykCJWy5ojShGftXIKY
46 w/njVbKMXrvc83qmTdGl3TAM0fxQIpqgcglFLveEBgzn
47 -----END CERTIFICATE-----
50 root_key_pem = b("""-----BEGIN RSA PRIVATE KEY-----
51 MIICXQIBAAKBgQD5mkLpi7q6ROdu7khB3S9aanA0Zls7vvfGOmB80/yeylhGpsjA
52 jWen0VtSQke/NlEPGtO38tsV7CsuFnSmschvAnGrcJl76b0UOOHUgDTIoRxC6QDU
53 3claegwsrBA+sJEBbqx5RdXbIRGicPG/8qQ4Zm1SKOgotcbwiaor2yxZ2wIDAQAB
54 AoGBAPCgMpmLxzwDaUmcFbTJUvlLW1hoxNNYSu2jIZm1k/hRAcE60JYwvBkgz3UB
55 yMEh0AtLxYe0bFk6EHah11tMUPgscbCq73snJ++8koUw+csk22G65hOs51bVb7Aa
56 6JBe67oLzdtvgCUFAA2qfrKzWRZzAdhUirQUZgySZk+Xq1pBAkEA/kZG0A6roTSM
57 BVnx7LnPfsycKUsTumorpXiylZJjTi9XtmzxhrYN6wgZlDOOwOLgSQhszGpxVoMD
58 u3gByT1b2QJBAPtL3mSKdvwRu/+40zaZLwvSJRxaj0mcE4BJOS6Oqs/hS1xRlrNk
59 PpQ7WJ4yM6ZOLnXzm2mKyxm50Mv64109FtMCQQDOqS2KkjHaLowTGVxwC0DijMfr
60 I9Lf8sSQk32J5VWCySWf5gGTfEnpmUa41gKTMJIbqZZLucNuDcOtzUaeWZlZAkA8
61 ttXigLnCqR486JDPTi9ZscoZkZ+w7y6e/hH8t6d5Vjt48JVyfjPIaJY+km58LcN3
62 6AWSeGAdtRFHVzR7oHjVAkB4hutvxiOeiIVQNBhM6RSI9aBPMI21DoX2JRoxvNW2
63 cbvAhow217X9V0dVerEOKxnNYspXRrh36h7k4mQA+sDq
64 -----END RSA PRIVATE KEY-----
67 server_cert_pem = b("""-----BEGIN CERTIFICATE-----
68 MIICKDCCAZGgAwIBAgIJAJn/HpR21r/8MA0GCSqGSIb3DQEBBQUAMFgxCzAJBgNV
69 BAYTAlVTMQswCQYDVQQIEwJJTDEQMA4GA1UEBxMHQ2hpY2FnbzEQMA4GA1UEChMH
70 VGVzdGluZzEYMBYGA1UEAxMPVGVzdGluZyBSb290IENBMCIYDzIwMDkwMzI1MTIz
71 NzUzWhgPMjAxNzA2MTExMjM3NTNaMBgxFjAUBgNVBAMTDWxvdmVseSBzZXJ2ZXIw
72 gZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAL6m+G653V0tpBC/OKl22VxOi2Cv
73 lK4TYu9LHSDP9uDVTe7V5D5Tl6qzFoRRx5pfmnkqT5B+W9byp2NU3FC5hLm5zSAr
74 b45meUhjEJ/ifkZgbNUjHdBIGP9MAQUHZa5WKdkGIJvGAvs8UzUqlr4TBWQIB24+
75 lJ+Ukk/CRgasrYwdAgMBAAGjNjA0MB0GA1UdDgQWBBS4kC7Ij0W1TZXZqXQFAM2e
76 gKEG2DATBgNVHSUEDDAKBggrBgEFBQcDATANBgkqhkiG9w0BAQUFAAOBgQBh30Li
77 dJ+NlxIOx5343WqIBka3UbsOb2kxWrbkVCrvRapCMLCASO4FqiKWM+L0VDBprqIp
78 2mgpFQ6FHpoIENGvJhdEKpptQ5i7KaGhnDNTfdy3x1+h852G99f1iyj0RmbuFcM8
79 uzujnS8YXWvM7DM1Ilozk4MzPug8jzFp5uhKCQ==
80 -----END CERTIFICATE-----
83 server_key_pem = b("""-----BEGIN RSA PRIVATE KEY-----
84 MIICWwIBAAKBgQC+pvhuud1dLaQQvzipdtlcTotgr5SuE2LvSx0gz/bg1U3u1eQ+
85 U5eqsxaEUceaX5p5Kk+QflvW8qdjVNxQuYS5uc0gK2+OZnlIYxCf4n5GYGzVIx3Q
86 SBj/TAEFB2WuVinZBiCbxgL7PFM1Kpa+EwVkCAduPpSflJJPwkYGrK2MHQIDAQAB
87 AoGAbwuZ0AR6JveahBaczjfnSpiFHf+mve2UxoQdpyr6ROJ4zg/PLW5K/KXrC48G
88 j6f3tXMrfKHcpEoZrQWUfYBRCUsGD5DCazEhD8zlxEHahIsqpwA0WWssJA2VOLEN
89 j6DuV2pCFbw67rfTBkTSo32ahfXxEKev5KswZk0JIzH3ooECQQDgzS9AI89h0gs8
90 Dt+1m11Rzqo3vZML7ZIyGApUzVan+a7hbc33nbGRkAXjHaUBJO31it/H6dTO+uwX
91 msWwNG5ZAkEA2RyFKs5xR5USTFaKLWCgpH/ydV96KPOpBND7TKQx62snDenFNNbn
92 FwwOhpahld+vqhYk+pfuWWUpQciE+Bu7ZQJASjfT4sQv4qbbKK/scePicnDdx9th
93 4e1EeB9xwb+tXXXUo/6Bor/AcUNwfiQ6Zt9PZOK9sR3lMZSsP7rMi7kzuQJABie6
94 1sXXjFH7nNJvRG4S39cIxq8YRYTy68II/dlB2QzGpKxV/POCxbJ/zu0CU79tuYK7
95 NaeNCFfH3aeTrX0LyQJAMBWjWmeKM2G2sCExheeQK0ROnaBC8itCECD4Jsve4nqf
96 r50+LF74iLXFwqysVCebPKMOpDWp/qQ1BbJQIPs7/A==
97 -----END RSA PRIVATE KEY-----
100 client_cert_pem = b("""-----BEGIN CERTIFICATE-----
101 MIICJjCCAY+gAwIBAgIJAKxpFI5lODkjMA0GCSqGSIb3DQEBBQUAMFgxCzAJBgNV
102 BAYTAlVTMQswCQYDVQQIEwJJTDEQMA4GA1UEBxMHQ2hpY2FnbzEQMA4GA1UEChMH
103 VGVzdGluZzEYMBYGA1UEAxMPVGVzdGluZyBSb290IENBMCIYDzIwMDkwMzI1MTIz
104 ODA1WhgPMjAxNzA2MTExMjM4MDVaMBYxFDASBgNVBAMTC3VnbHkgY2xpZW50MIGf
105 MA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDAZh/SRtNm5ntMT4qb6YzEpTroMlq2
106 rn+GrRHRiZ+xkCw/CGNhbtPir7/QxaUj26BSmQrHw1bGKEbPsWiW7bdXSespl+xK
107 iku4G/KvnnmWdeJHqsiXeUZtqurMELcPQAw9xPHEuhqqUJvvEoMTsnCEqGM+7Dtb
108 oCRajYyHfluARQIDAQABozYwNDAdBgNVHQ4EFgQUNQB+qkaOaEVecf1J3TTUtAff
109 0fAwEwYDVR0lBAwwCgYIKwYBBQUHAwIwDQYJKoZIhvcNAQEFBQADgYEAyv/Jh7gM
110 Q3OHvmsFEEvRI+hsW8y66zK4K5de239Y44iZrFYkt7Q5nBPMEWDj4F2hLYWL/qtI
111 9Zdr0U4UDCU9SmmGYh4o7R4TZ5pGFvBYvjhHbkSFYFQXZxKUi+WUxplP6I0wr2KJ
112 PSTJCjJOn3xo2NTKRgV1gaoTf2EhL+RG8TQ=
113 -----END CERTIFICATE-----
116 client_key_pem = b("""-----BEGIN RSA PRIVATE KEY-----
117 MIICXgIBAAKBgQDAZh/SRtNm5ntMT4qb6YzEpTroMlq2rn+GrRHRiZ+xkCw/CGNh
118 btPir7/QxaUj26BSmQrHw1bGKEbPsWiW7bdXSespl+xKiku4G/KvnnmWdeJHqsiX
119 eUZtqurMELcPQAw9xPHEuhqqUJvvEoMTsnCEqGM+7DtboCRajYyHfluARQIDAQAB
120 AoGATkZ+NceY5Glqyl4mD06SdcKfV65814vg2EL7V9t8+/mi9rYL8KztSXGlQWPX
121 zuHgtRoMl78yQ4ZJYOBVo+nsx8KZNRCEBlE19bamSbQLCeQMenWnpeYyQUZ908gF
122 h6L9qsFVJepgA9RDgAjyDoS5CaWCdCCPCH2lDkdcqC54SVUCQQDseuduc4wi8h4t
123 V8AahUn9fn9gYfhoNuM0gdguTA0nPLVWz4hy1yJiWYQe0H7NLNNTmCKiLQaJpAbb
124 TC6vE8C7AkEA0Ee8CMJUc20BnGEmxwgWcVuqFWaKCo8jTH1X38FlATUsyR3krjW2
125 dL3yDD9NwHxsYP7nTKp/U8MV7U9IBn4y/wJBAJl7H0/BcLeRmuJk7IqJ7b635iYB
126 D/9beFUw3MUXmQXZUfyYz39xf6CDZsu1GEdEC5haykeln3Of4M9d/4Kj+FcCQQCY
127 si6xwT7GzMDkk/ko684AV3KPc/h6G0yGtFIrMg7J3uExpR/VdH2KgwMkZXisSMvw
128 JJEQjOMCVsEJlRk54WWjAkEAzoZNH6UhDdBK5F38rVt/y4SEHgbSfJHIAmPS32Kq
129 f6GGcfNpip0Uk7q7udTKuX7Q/buZi/C4YW7u3VKAquv9NA==
130 -----END RSA PRIVATE KEY-----
133 cleartextCertificatePEM = b("""-----BEGIN CERTIFICATE-----
134 MIIC7TCCAlagAwIBAgIIPQzE4MbeufQwDQYJKoZIhvcNAQEFBQAwWDELMAkGA1UE
135 BhMCVVMxCzAJBgNVBAgTAklMMRAwDgYDVQQHEwdDaGljYWdvMRAwDgYDVQQKEwdU
136 ZXN0aW5nMRgwFgYDVQQDEw9UZXN0aW5nIFJvb3QgQ0EwIhgPMjAwOTAzMjUxMjM2
137 NThaGA8yMDE3MDYxMTEyMzY1OFowWDELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAklM
138 MRAwDgYDVQQHEwdDaGljYWdvMRAwDgYDVQQKEwdUZXN0aW5nMRgwFgYDVQQDEw9U
139 ZXN0aW5nIFJvb3QgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAPmaQumL
140 urpE527uSEHdL1pqcDRmWzu+98Y6YHzT/J7KWEamyMCNZ6fRW1JCR782UQ8a07fy
141 2xXsKy4WdKaxyG8CcatwmXvpvRQ44dSANMihHELpANTdyVp6DCysED6wkQFurHlF
142 1dshEaJw8b/ypDhmbVIo6Ci1xvCJqivbLFnbAgMBAAGjgbswgbgwHQYDVR0OBBYE
143 FINVdy1eIfFJDAkk51QJEo3IfgSuMIGIBgNVHSMEgYAwfoAUg1V3LV4h8UkMCSTn
144 VAkSjch+BK6hXKRaMFgxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJJTDEQMA4GA1UE
145 BxMHQ2hpY2FnbzEQMA4GA1UEChMHVGVzdGluZzEYMBYGA1UEAxMPVGVzdGluZyBS
146 b290IENBggg9DMTgxt659DAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GB
147 AGGCDazMJGoWNBpc03u6+smc95dEead2KlZXBATOdFT1VesY3+nUOqZhEhTGlDMi
148 hkgaZnzoIq/Uamidegk4hirsCT/R+6vsKAAxNTcBjUeZjlykCJWy5ojShGftXIKY
149 w/njVbKMXrvc83qmTdGl3TAM0fxQIpqgcglFLveEBgzn
150 -----END CERTIFICATE-----
153 cleartextPrivateKeyPEM = b("""-----BEGIN RSA PRIVATE KEY-----
154 MIICXQIBAAKBgQD5mkLpi7q6ROdu7khB3S9aanA0Zls7vvfGOmB80/yeylhGpsjA
155 jWen0VtSQke/NlEPGtO38tsV7CsuFnSmschvAnGrcJl76b0UOOHUgDTIoRxC6QDU
156 3claegwsrBA+sJEBbqx5RdXbIRGicPG/8qQ4Zm1SKOgotcbwiaor2yxZ2wIDAQAB
157 AoGBAPCgMpmLxzwDaUmcFbTJUvlLW1hoxNNYSu2jIZm1k/hRAcE60JYwvBkgz3UB
158 yMEh0AtLxYe0bFk6EHah11tMUPgscbCq73snJ++8koUw+csk22G65hOs51bVb7Aa
159 6JBe67oLzdtvgCUFAA2qfrKzWRZzAdhUirQUZgySZk+Xq1pBAkEA/kZG0A6roTSM
160 BVnx7LnPfsycKUsTumorpXiylZJjTi9XtmzxhrYN6wgZlDOOwOLgSQhszGpxVoMD
161 u3gByT1b2QJBAPtL3mSKdvwRu/+40zaZLwvSJRxaj0mcE4BJOS6Oqs/hS1xRlrNk
162 PpQ7WJ4yM6ZOLnXzm2mKyxm50Mv64109FtMCQQDOqS2KkjHaLowTGVxwC0DijMfr
163 I9Lf8sSQk32J5VWCySWf5gGTfEnpmUa41gKTMJIbqZZLucNuDcOtzUaeWZlZAkA8
164 ttXigLnCqR486JDPTi9ZscoZkZ+w7y6e/hH8t6d5Vjt48JVyfjPIaJY+km58LcN3
165 6AWSeGAdtRFHVzR7oHjVAkB4hutvxiOeiIVQNBhM6RSI9aBPMI21DoX2JRoxvNW2
166 cbvAhow217X9V0dVerEOKxnNYspXRrh36h7k4mQA+sDq
167 -----END RSA PRIVATE KEY-----
170 cleartextCertificateRequestPEM = b("""-----BEGIN CERTIFICATE REQUEST-----
171 MIIBnjCCAQcCAQAwXjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAklMMRAwDgYDVQQH
172 EwdDaGljYWdvMRcwFQYDVQQKEw5NeSBDb21wYW55IEx0ZDEXMBUGA1UEAxMORnJl
173 ZGVyaWNrIERlYW4wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANp6Y17WzKSw
174 BsUWkXdqg6tnXy8H8hA1msCMWpc+/2KJ4mbv5NyD6UD+/SqagQqulPbF/DFea9nA
175 E0zhmHJELcM8gUTIlXv/cgDWnmK4xj8YkjVUiCdqKRAKeuzLG1pGmwwF5lGeJpXN
176 xQn5ecR0UYSOWj6TTGXB9VyUMQzCClcBAgMBAAGgADANBgkqhkiG9w0BAQUFAAOB
177 gQAAJGuF/R/GGbeC7FbFW+aJgr9ee0Xbl6nlhu7pTe67k+iiKT2dsl2ti68MVTnu
178 Vrb3HUNqOkiwsJf6kCtq5oPn3QVYzTa76Dt2y3Rtzv6boRSlmlfrgS92GNma8JfR
179 oICQk3nAudi6zl1Dix3BCv1pUp5KMtGn3MeDEi6QFGy2rA==
180 -----END CERTIFICATE REQUEST-----
183 encryptedPrivateKeyPEM = b("""-----BEGIN RSA PRIVATE KEY-----
184 Proc-Type: 4,ENCRYPTED
185 DEK-Info: DES-EDE3-CBC,9573604A18579E9E
187 SHOho56WxDkT0ht10UTeKc0F5u8cqIa01kzFAmETw0MAs8ezYtK15NPdCXUm3X/2
188 a17G7LSF5bkxOgZ7vpXyMzun/owrj7CzvLxyncyEFZWvtvzaAhPhvTJtTIB3kf8B
189 8+qRcpTGK7NgXEgYBW5bj1y4qZkD4zCL9o9NQzsKI3Ie8i0239jsDOWR38AxjXBH
190 mGwAQ4Z6ZN5dnmM4fhMIWsmFf19sNyAML4gHenQCHhmXbjXeVq47aC2ProInJbrm
191 +00TcisbAQ40V9aehVbcDKtS4ZbMVDwncAjpXpcncC54G76N6j7F7wL7L/FuXa3A
192 fvSVy9n2VfF/pJ3kYSflLHH2G/DFxjF7dl0GxhKPxJjp3IJi9VtuvmN9R2jZWLQF
193 tfC8dXgy/P9CfFQhlinqBTEwgH0oZ/d4k4NVFDSdEMaSdmBAjlHpc+Vfdty3HVnV
194 rKXj//wslsFNm9kIwJGIgKUa/n2jsOiydrsk1mgH7SmNCb3YHgZhbbnq0qLat/HC
195 gHDt3FHpNQ31QzzL3yrenFB2L9osIsnRsDTPFNi4RX4SpDgNroxOQmyzCCV6H+d4
196 o1mcnNiZSdxLZxVKccq0AfRpHqpPAFnJcQHP6xyT9MZp6fBa0XkxDnt9kNU8H3Qw
197 7SJWZ69VXjBUzMlQViLuaWMgTnL+ZVyFZf9hTF7U/ef4HMLMAVNdiaGG+G+AjCV/
198 MbzjS007Oe4qqBnCWaFPSnJX6uLApeTbqAxAeyCql56ULW5x6vDMNC3dwjvS/CEh
199 11n8RkgFIQA0AhuKSIg3CbuartRsJnWOLwgLTzsrKYL4yRog1RJrtw==
200 -----END RSA PRIVATE KEY-----
202 encryptedPrivateKeyPEMPassphrase = b("foobar")
204 # Some PKCS#7 stuff. Generated with the openssl command line:
206 # openssl crl2pkcs7 -inform pem -outform pem -certfile s.pem -nocrl
208 # with a certificate and key (but the key should be irrelevant) in s.pem
210 -----BEGIN PKCS7-----
211 MIIDNwYJKoZIhvcNAQcCoIIDKDCCAyQCAQExADALBgkqhkiG9w0BBwGgggMKMIID
212 BjCCAm+gAwIBAgIBATANBgkqhkiG9w0BAQQFADB7MQswCQYDVQQGEwJTRzERMA8G
213 A1UEChMITTJDcnlwdG8xFDASBgNVBAsTC00yQ3J5cHRvIENBMSQwIgYDVQQDExtN
214 MkNyeXB0byBDZXJ0aWZpY2F0ZSBNYXN0ZXIxHTAbBgkqhkiG9w0BCQEWDm5ncHNA
215 cG9zdDEuY29tMB4XDTAwMDkxMDA5NTEzMFoXDTAyMDkxMDA5NTEzMFowUzELMAkG
216 A1UEBhMCU0cxETAPBgNVBAoTCE0yQ3J5cHRvMRIwEAYDVQQDEwlsb2NhbGhvc3Qx
217 HTAbBgkqhkiG9w0BCQEWDm5ncHNAcG9zdDEuY29tMFwwDQYJKoZIhvcNAQEBBQAD
218 SwAwSAJBAKy+e3dulvXzV7zoTZWc5TzgApr8DmeQHTYC8ydfzH7EECe4R1Xh5kwI
219 zOuuFfn178FBiS84gngaNcrFi0Z5fAkCAwEAAaOCAQQwggEAMAkGA1UdEwQCMAAw
220 LAYJYIZIAYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0G
221 A1UdDgQWBBTPhIKSvnsmYsBVNWjj0m3M2z0qVTCBpQYDVR0jBIGdMIGagBT7hyNp
222 65w6kxXlxb8pUU/+7Sg4AaF/pH0wezELMAkGA1UEBhMCU0cxETAPBgNVBAoTCE0y
223 Q3J5cHRvMRQwEgYDVQQLEwtNMkNyeXB0byBDQTEkMCIGA1UEAxMbTTJDcnlwdG8g
224 Q2VydGlmaWNhdGUgTWFzdGVyMR0wGwYJKoZIhvcNAQkBFg5uZ3BzQHBvc3QxLmNv
225 bYIBADANBgkqhkiG9w0BAQQFAAOBgQA7/CqT6PoHycTdhEStWNZde7M/2Yc6BoJu
226 VwnW8YxGO8Sn6UJ4FeffZNcYZddSDKosw8LtPOeWoK3JINjAk5jiPQ2cww++7QGG
227 /g5NDjxFZNDJP1dGiLAxPW6JXwov4v0FmdzfLOZ01jDcgQQZqEpYlgpuI5JEWUQ9
233 -----BEGIN X509 CRL-----
234 MIIBWzCBxTANBgkqhkiG9w0BAQQFADBYMQswCQYDVQQGEwJVUzELMAkGA1UECBMC
235 SUwxEDAOBgNVBAcTB0NoaWNhZ28xEDAOBgNVBAoTB1Rlc3RpbmcxGDAWBgNVBAMT
236 D1Rlc3RpbmcgUm9vdCBDQRcNMDkwNzI2MDQzNDU2WhcNMTIwOTI3MDI0MTUyWjA8
237 MBUCAgOrGA8yMDA5MDcyNTIzMzQ1NlowIwICAQAYDzIwMDkwNzI1MjMzNDU2WjAM
238 MAoGA1UdFQQDCgEEMA0GCSqGSIb3DQEBBAUAA4GBAEBt7xTs2htdD3d4ErrcGAw1
239 4dKcVnIWTutoI7xxen26Wwvh8VCsT7i/UeP+rBl9rC/kfjWjzQk3/zleaarGTpBT
240 0yp4HXRFFoRhhSE/hP+eteaPXRgrsNRLHe9ZDd69wmh7J1wMDb0m81RG7kqcbsid
242 -----END X509 CRL-----
245 class X509ExtTests(TestCase):
247 Tests for L{OpenSSL.crypto.X509Extension}.
252 Create a new private key and start a certificate request (for a test
253 method to finish in one way or another).
255 # Basic setup stuff to generate a certificate
257 self.pkey.generate_key(TYPE_RSA, 384)
259 self.req.set_pubkey(self.pkey)
260 # Authority good you have.
261 self.req.get_subject().commonName = "Yoda root CA"
263 self.subject = self.x509.get_subject()
264 self.subject.commonName = self.req.get_subject().commonName
265 self.x509.set_issuer(self.subject)
266 self.x509.set_pubkey(self.pkey)
267 now = b(datetime.now().strftime("%Y%m%d%H%M%SZ"))
268 expire = b((datetime.now() + timedelta(days=100)).strftime("%Y%m%d%H%M%SZ"))
269 self.x509.set_notBefore(now)
270 self.x509.set_notAfter(expire)
275 The string representation of L{X509Extension} instances as returned by
276 C{str} includes stuff.
278 # This isn't necessarily the best string representation. Perhaps it
279 # will be changed/improved in the future.
281 str(X509Extension(b('basicConstraints'), True, b('CA:false'))),
287 L{X509Extension} and L{X509ExtensionType} refer to the same type object
288 and can be used to create instances of that type.
290 self.assertIdentical(X509Extension, X509ExtensionType)
291 self.assertConsistentType(
293 'X509Extension', b('basicConstraints'), True, b('CA:true'))
296 def test_construction(self):
298 L{X509Extension} accepts an extension type name, a critical flag,
299 and an extension value and returns an L{X509ExtensionType} instance.
301 basic = X509Extension(b('basicConstraints'), True, b('CA:true'))
303 isinstance(basic, X509ExtensionType),
304 "%r is of type %r, should be %r" % (
305 basic, type(basic), X509ExtensionType))
307 comment = X509Extension(
308 b('nsComment'), False, b('pyOpenSSL unit test'))
310 isinstance(comment, X509ExtensionType),
311 "%r is of type %r, should be %r" % (
312 comment, type(comment), X509ExtensionType))
315 def test_invalid_extension(self):
317 L{X509Extension} raises something if it is passed a bad extension
321 Error, X509Extension, b('thisIsMadeUp'), False, b('hi'))
323 Error, X509Extension, b('basicConstraints'), False, b('blah blah'))
325 # Exercise a weird one (an extension which uses the r2i method). This
326 # exercises the codepath that requires a non-NULL ctx to be passed to
327 # X509V3_EXT_nconf. It can't work now because we provide no
328 # configuration database. It might be made to work in the future.
330 Error, X509Extension, b('proxyCertInfo'), True,
331 b('language:id-ppl-anyLanguage,pathlen:1,policy:text:AB'))
334 def test_get_critical(self):
336 L{X509ExtensionType.get_critical} returns the value of the
337 extension's critical flag.
339 ext = X509Extension(b('basicConstraints'), True, b('CA:true'))
340 self.assertTrue(ext.get_critical())
341 ext = X509Extension(b('basicConstraints'), False, b('CA:true'))
342 self.assertFalse(ext.get_critical())
345 def test_get_short_name(self):
347 L{X509ExtensionType.get_short_name} returns a string giving the short
348 type name of the extension.
350 ext = X509Extension(b('basicConstraints'), True, b('CA:true'))
351 self.assertEqual(ext.get_short_name(), b('basicConstraints'))
352 ext = X509Extension(b('nsComment'), True, b('foo bar'))
353 self.assertEqual(ext.get_short_name(), b('nsComment'))
356 def test_get_data(self):
358 L{X509Extension.get_data} returns a string giving the data of the
361 ext = X509Extension(b('basicConstraints'), True, b('CA:true'))
362 # Expect to get back the DER encoded form of CA:true.
363 self.assertEqual(ext.get_data(), b('0\x03\x01\x01\xff'))
366 def test_get_data_wrong_args(self):
368 L{X509Extension.get_data} raises L{TypeError} if passed any arguments.
370 ext = X509Extension(b('basicConstraints'), True, b('CA:true'))
371 self.assertRaises(TypeError, ext.get_data, None)
372 self.assertRaises(TypeError, ext.get_data, "foo")
373 self.assertRaises(TypeError, ext.get_data, 7)
376 def test_unused_subject(self):
378 The C{subject} parameter to L{X509Extension} may be provided for an
379 extension which does not use it and is ignored in this case.
381 ext1 = X509Extension(
382 b('basicConstraints'), False, b('CA:TRUE'), subject=self.x509)
383 self.x509.add_extensions([ext1])
384 self.x509.sign(self.pkey, 'sha1')
385 # This is a little lame. Can we think of a better way?
386 text = dump_certificate(FILETYPE_TEXT, self.x509)
387 self.assertTrue(b('X509v3 Basic Constraints:') in text)
388 self.assertTrue(b('CA:TRUE') in text)
391 def test_subject(self):
393 If an extension requires a subject, the C{subject} parameter to
394 L{X509Extension} provides its value.
396 ext3 = X509Extension(
397 b('subjectKeyIdentifier'), False, b('hash'), subject=self.x509)
398 self.x509.add_extensions([ext3])
399 self.x509.sign(self.pkey, 'sha1')
400 text = dump_certificate(FILETYPE_TEXT, self.x509)
401 self.assertTrue(b('X509v3 Subject Key Identifier:') in text)
404 def test_missing_subject(self):
406 If an extension requires a subject and the C{subject} parameter is
407 given no value, something happens.
410 Error, X509Extension, b('subjectKeyIdentifier'), False, b('hash'))
413 def test_invalid_subject(self):
415 If the C{subject} parameter is given a value which is not an L{X509}
416 instance, L{TypeError} is raised.
418 for badObj in [True, object(), "hello", [], self]:
422 'basicConstraints', False, 'CA:TRUE', subject=badObj)
425 def test_unused_issuer(self):
427 The C{issuer} parameter to L{X509Extension} may be provided for an
428 extension which does not use it and is ignored in this case.
430 ext1 = X509Extension(
431 b('basicConstraints'), False, b('CA:TRUE'), issuer=self.x509)
432 self.x509.add_extensions([ext1])
433 self.x509.sign(self.pkey, 'sha1')
434 text = dump_certificate(FILETYPE_TEXT, self.x509)
435 self.assertTrue(b('X509v3 Basic Constraints:') in text)
436 self.assertTrue(b('CA:TRUE') in text)
439 def test_issuer(self):
441 If an extension requires a issuer, the C{issuer} parameter to
442 L{X509Extension} provides its value.
444 ext2 = X509Extension(
445 b('authorityKeyIdentifier'), False, b('issuer:always'),
447 self.x509.add_extensions([ext2])
448 self.x509.sign(self.pkey, 'sha1')
449 text = dump_certificate(FILETYPE_TEXT, self.x509)
450 self.assertTrue(b('X509v3 Authority Key Identifier:') in text)
451 self.assertTrue(b('DirName:/CN=Yoda root CA') in text)
454 def test_missing_issuer(self):
456 If an extension requires an issue and the C{issuer} parameter is given
457 no value, something happens.
462 b('authorityKeyIdentifier'), False,
463 b('keyid:always,issuer:always'))
466 def test_invalid_issuer(self):
468 If the C{issuer} parameter is given a value which is not an L{X509}
469 instance, L{TypeError} is raised.
471 for badObj in [True, object(), "hello", [], self]:
475 'authorityKeyIdentifier', False, 'keyid:always,issuer:always',
480 class PKeyTests(TestCase):
482 Unit tests for L{OpenSSL.crypto.PKey}.
486 L{PKey} and L{PKeyType} refer to the same type object and can be used
487 to create instances of that type.
489 self.assertIdentical(PKey, PKeyType)
490 self.assertConsistentType(PKey, 'PKey')
493 def test_construction(self):
495 L{PKey} takes no arguments and returns a new L{PKey} instance.
497 self.assertRaises(TypeError, PKey, None)
500 isinstance(key, PKeyType),
501 "%r is of type %r, should be %r" % (key, type(key), PKeyType))
504 def test_pregeneration(self):
506 L{PKeyType.bits} and L{PKeyType.type} return C{0} before the key is
510 self.assertEqual(key.type(), 0)
511 self.assertEqual(key.bits(), 0)
514 def test_failedGeneration(self):
516 L{PKeyType.generate_key} takes two arguments, the first giving the key
517 type as one of L{TYPE_RSA} or L{TYPE_DSA} and the second giving the
518 number of bits to generate. If an invalid type is specified or
519 generation fails, L{Error} is raised. If an invalid number of bits is
520 specified, L{ValueError} or L{Error} is raised.
523 self.assertRaises(TypeError, key.generate_key)
524 self.assertRaises(TypeError, key.generate_key, 1, 2, 3)
525 self.assertRaises(TypeError, key.generate_key, "foo", "bar")
526 self.assertRaises(Error, key.generate_key, -1, 0)
528 self.assertRaises(ValueError, key.generate_key, TYPE_RSA, -1)
529 self.assertRaises(ValueError, key.generate_key, TYPE_RSA, 0)
531 # XXX RSA generation for small values of bits is fairly buggy in a wide
532 # range of OpenSSL versions. I need to figure out what the safe lower
533 # bound for a reasonable number of OpenSSL versions is and explicitly
534 # check for that in the wrapper. The failure behavior is typically an
535 # infinite loop inside OpenSSL.
537 # self.assertRaises(Error, key.generate_key, TYPE_RSA, 2)
539 # XXX DSA generation seems happy with any number of bits. The DSS
540 # says bits must be between 512 and 1024 inclusive. OpenSSL's DSA
541 # generator doesn't seem to care about the upper limit at all. For
542 # the lower limit, it uses 512 if anything smaller is specified.
543 # So, it doesn't seem possible to make generate_key fail for
544 # TYPE_DSA with a bits argument which is at least an int.
546 # self.assertRaises(Error, key.generate_key, TYPE_DSA, -7)
549 def test_rsaGeneration(self):
551 L{PKeyType.generate_key} generates an RSA key when passed
552 L{TYPE_RSA} as a type and a reasonable number of bits.
556 key.generate_key(TYPE_RSA, bits)
557 self.assertEqual(key.type(), TYPE_RSA)
558 self.assertEqual(key.bits(), bits)
561 def test_dsaGeneration(self):
563 L{PKeyType.generate_key} generates a DSA key when passed
564 L{TYPE_DSA} as a type and a reasonable number of bits.
566 # 512 is a magic number. The DSS (Digital Signature Standard)
567 # allows a minimum of 512 bits for DSA. DSA_generate_parameters
568 # will silently promote any value below 512 to 512.
571 key.generate_key(TYPE_DSA, bits)
572 self.assertEqual(key.type(), TYPE_DSA)
573 self.assertEqual(key.bits(), bits)
576 def test_regeneration(self):
578 L{PKeyType.generate_key} can be called multiple times on the same
579 key to generate new keys.
582 for type, bits in [(TYPE_RSA, 512), (TYPE_DSA, 576)]:
583 key.generate_key(type, bits)
584 self.assertEqual(key.type(), type)
585 self.assertEqual(key.bits(), bits)
589 class X509NameTests(TestCase):
591 Unit tests for L{OpenSSL.crypto.X509Name}.
593 def _x509name(self, **attrs):
594 # XXX There's no other way to get a new X509Name yet.
595 name = X509().get_subject()
596 attrs = list(attrs.items())
597 # Make the order stable - order matters!
608 The type of X509Name objects is L{X509NameType}.
610 self.assertIdentical(X509Name, X509NameType)
611 self.assertEqual(X509NameType.__name__, 'X509Name')
612 self.assertTrue(isinstance(X509NameType, type))
614 name = self._x509name()
616 isinstance(name, X509NameType),
617 "%r is of type %r, should be %r" % (
618 name, type(name), X509NameType))
621 def test_attributes(self):
623 L{X509NameType} instances have attributes for each standard (?)
626 name = self._x509name()
627 name.commonName = "foo"
628 self.assertEqual(name.commonName, "foo")
629 self.assertEqual(name.CN, "foo")
631 self.assertEqual(name.commonName, "baz")
632 self.assertEqual(name.CN, "baz")
633 name.commonName = "bar"
634 self.assertEqual(name.commonName, "bar")
635 self.assertEqual(name.CN, "bar")
637 self.assertEqual(name.commonName, "quux")
638 self.assertEqual(name.CN, "quux")
643 L{X509Name} creates a new L{X509NameType} instance with all the same
644 attributes as an existing L{X509NameType} instance when called with
647 name = self._x509name(commonName="foo", emailAddress="bar@example.com")
649 copy = X509Name(name)
650 self.assertEqual(copy.commonName, "foo")
651 self.assertEqual(copy.emailAddress, "bar@example.com")
653 # Mutate the copy and ensure the original is unmodified.
654 copy.commonName = "baz"
655 self.assertEqual(name.commonName, "foo")
657 # Mutate the original and ensure the copy is unmodified.
658 name.emailAddress = "quux@example.com"
659 self.assertEqual(copy.emailAddress, "bar@example.com")
664 L{repr} passed an L{X509NameType} instance should return a string
665 containing a description of the type and the NIDs which have been set
668 name = self._x509name(commonName="foo", emailAddress="bar")
671 "<X509Name object '/emailAddress=bar/CN=foo'>")
674 def test_comparison(self):
676 L{X509NameType} instances should compare based on their NIDs.
678 def _equality(a, b, assertTrue, assertFalse):
679 assertTrue(a == b, "(%r == %r) --> False" % (a, b))
684 def assertEqual(a, b):
685 _equality(a, b, self.assertTrue, self.assertFalse)
687 # Instances compare equal to themselves.
688 name = self._x509name()
689 assertEqual(name, name)
691 # Empty instances should compare equal to each other.
692 assertEqual(self._x509name(), self._x509name())
694 # Instances with equal NIDs should compare equal to each other.
695 assertEqual(self._x509name(commonName="foo"),
696 self._x509name(commonName="foo"))
698 # Instance with equal NIDs set using different aliases should compare
699 # equal to each other.
700 assertEqual(self._x509name(commonName="foo"),
701 self._x509name(CN="foo"))
703 # Instances with more than one NID with the same values should compare
704 # equal to each other.
705 assertEqual(self._x509name(CN="foo", organizationalUnitName="bar"),
706 self._x509name(commonName="foo", OU="bar"))
708 def assertNotEqual(a, b):
709 _equality(a, b, self.assertFalse, self.assertTrue)
711 # Instances with different values for the same NID should not compare
712 # equal to each other.
713 assertNotEqual(self._x509name(CN="foo"),
714 self._x509name(CN="bar"))
716 # Instances with different NIDs should not compare equal to each other.
717 assertNotEqual(self._x509name(CN="foo"),
718 self._x509name(OU="foo"))
720 def _inequality(a, b, assertTrue, assertFalse):
730 def assertLessThan(a, b):
731 _inequality(a, b, self.assertTrue, self.assertFalse)
733 # An X509Name with a NID with a value which sorts less than the value
734 # of the same NID on another X509Name compares less than the other
736 assertLessThan(self._x509name(CN="abc"),
737 self._x509name(CN="def"))
739 def assertGreaterThan(a, b):
740 _inequality(a, b, self.assertFalse, self.assertTrue)
742 # An X509Name with a NID with a value which sorts greater than the
743 # value of the same NID on another X509Name compares greater than the
745 assertGreaterThan(self._x509name(CN="def"),
746 self._x509name(CN="abc"))
751 L{X509Name.hash} returns an integer hash based on the value of the
754 a = self._x509name(CN="foo")
755 b = self._x509name(CN="foo")
756 self.assertEqual(a.hash(), b.hash())
758 self.assertNotEqual(a.hash(), b.hash())
763 L{X509Name.der} returns the DER encoded form of the name.
765 a = self._x509name(CN="foo", C="US")
768 b('0\x1b1\x0b0\t\x06\x03U\x04\x06\x13\x02US'
769 '1\x0c0\n\x06\x03U\x04\x03\x13\x03foo'))
772 def test_get_components(self):
774 L{X509Name.get_components} returns a C{list} of two-tuples of C{str}
775 giving the NIDs and associated values which make up the name.
778 self.assertEqual(a.get_components(), [])
780 self.assertEqual(a.get_components(), [(b("CN"), b("foo"))])
781 a.organizationalUnitName = "bar"
784 [(b("CN"), b("foo")), (b("OU"), b("bar"))])
787 class _PKeyInteractionTestsMixin:
789 Tests which involve another thing and a PKey.
793 Return something with a C{set_pubkey}, C{set_pubkey}, and C{sign} method.
795 raise NotImplementedError()
798 def test_signWithUngenerated(self):
800 L{X509Req.sign} raises L{ValueError} when pass a L{PKey} with no parts.
802 request = self.signable()
804 self.assertRaises(ValueError, request.sign, key, 'MD5')
807 def test_signWithPublicKey(self):
809 L{X509Req.sign} raises L{ValueError} when pass a L{PKey} with no
810 private part as the signing key.
812 request = self.signable()
814 key.generate_key(TYPE_RSA, 512)
815 request.set_pubkey(key)
816 pub = request.get_pubkey()
817 self.assertRaises(ValueError, request.sign, pub, 'MD5')
820 def test_signWithUnknownDigest(self):
822 L{X509Req.sign} raises L{ValueError} when passed a digest name which is
825 request = self.signable()
827 key.generate_key(TYPE_RSA, 512)
828 self.assertRaises(ValueError, request.sign, key, "monkeys")
833 L{X509Req.sign} succeeds when passed a private key object and a valid
834 digest function. C{X509Req.verify} can be used to check the signature.
836 request = self.signable()
838 key.generate_key(TYPE_RSA, 512)
839 request.set_pubkey(key)
840 request.sign(key, 'MD5')
841 # If the type has a verify method, cover that too.
842 if getattr(request, 'verify', None) is not None:
843 pub = request.get_pubkey()
844 self.assertTrue(request.verify(pub))
845 # Make another key that won't verify.
847 key.generate_key(TYPE_RSA, 512)
848 self.assertRaises(Error, request.verify, key)
853 class X509ReqTests(TestCase, _PKeyInteractionTestsMixin):
855 Tests for L{OpenSSL.crypto.X509Req}.
859 Create and return a new L{X509Req}.
866 L{X509Req} and L{X509ReqType} refer to the same type object and can be
867 used to create instances of that type.
869 self.assertIdentical(X509Req, X509ReqType)
870 self.assertConsistentType(X509Req, 'X509Req')
873 def test_construction(self):
875 L{X509Req} takes no arguments and returns an L{X509ReqType} instance.
879 isinstance(request, X509ReqType),
880 "%r is of type %r, should be %r" % (request, type(request), X509ReqType))
883 def test_version(self):
885 L{X509ReqType.set_version} sets the X.509 version of the certificate
886 request. L{X509ReqType.get_version} returns the X.509 version of
887 the certificate request. The initial value of the version is 0.
890 self.assertEqual(request.get_version(), 0)
891 request.set_version(1)
892 self.assertEqual(request.get_version(), 1)
893 request.set_version(3)
894 self.assertEqual(request.get_version(), 3)
897 def test_version_wrong_args(self):
899 L{X509ReqType.set_version} raises L{TypeError} if called with the wrong
900 number of arguments or with a non-C{int} argument.
901 L{X509ReqType.get_version} raises L{TypeError} if called with any
905 self.assertRaises(TypeError, request.set_version)
906 self.assertRaises(TypeError, request.set_version, "foo")
907 self.assertRaises(TypeError, request.set_version, 1, 2)
908 self.assertRaises(TypeError, request.get_version, None)
911 def test_get_subject(self):
913 L{X509ReqType.get_subject} returns an L{X509Name} for the subject of
914 the request and which is valid even after the request object is
918 subject = request.get_subject()
920 isinstance(subject, X509NameType),
921 "%r is of type %r, should be %r" % (subject, type(subject), X509NameType))
922 subject.commonName = "foo"
923 self.assertEqual(request.get_subject().commonName, "foo")
925 subject.commonName = "bar"
926 self.assertEqual(subject.commonName, "bar")
929 def test_get_subject_wrong_args(self):
931 L{X509ReqType.get_subject} raises L{TypeError} if called with any
935 self.assertRaises(TypeError, request.get_subject, None)
938 def test_add_extensions(self):
940 L{X509Req.add_extensions} accepts a C{list} of L{X509Extension}
941 instances and adds them to the X509 request.
944 request.add_extensions([
945 X509Extension(b('basicConstraints'), True, b('CA:false'))])
946 # XXX Add get_extensions so the rest of this unit test can be written.
949 def test_add_extensions_wrong_args(self):
951 L{X509Req.add_extensions} raises L{TypeError} if called with the wrong
952 number of arguments or with a non-C{list}. Or it raises L{ValueError}
953 if called with a C{list} containing objects other than L{X509Extension}
957 self.assertRaises(TypeError, request.add_extensions)
958 self.assertRaises(TypeError, request.add_extensions, object())
959 self.assertRaises(ValueError, request.add_extensions, [object()])
960 self.assertRaises(TypeError, request.add_extensions, [], None)
964 class X509Tests(TestCase, _PKeyInteractionTestsMixin):
966 Tests for L{OpenSSL.crypto.X509}.
968 pemData = cleartextCertificatePEM + cleartextPrivateKeyPEM
971 -----BEGIN CERTIFICATE-----
972 MIIC3jCCAkegAwIBAgIJAJHFjlcCgnQzMA0GCSqGSIb3DQEBBQUAMEcxCzAJBgNV
973 BAYTAlNFMRUwEwYDVQQIEwxXZXN0ZXJib3R0b20xEjAQBgNVBAoTCUNhdGFsb2dp
974 eDENMAsGA1UEAxMEUm9vdDAeFw0wODA0MjIxNDQ1MzhaFw0wOTA0MjIxNDQ1Mzha
975 MFQxCzAJBgNVBAYTAlNFMQswCQYDVQQIEwJXQjEUMBIGA1UEChMLT3Blbk1ldGFk
976 aXIxIjAgBgNVBAMTGW5vZGUxLm9tMi5vcGVubWV0YWRpci5vcmcwgZ8wDQYJKoZI
977 hvcNAQEBBQADgY0AMIGJAoGBAPIcQMrwbk2nESF/0JKibj9i1x95XYAOwP+LarwT
978 Op4EQbdlI9SY+uqYqlERhF19w7CS+S6oyqx0DRZSk4Y9dZ9j9/xgm2u/f136YS1u
979 zgYFPvfUs6PqYLPSM8Bw+SjJ+7+2+TN+Tkiof9WP1cMjodQwOmdsiRbR0/J7+b1B
980 hec1AgMBAAGjgcQwgcEwCQYDVR0TBAIwADAsBglghkgBhvhCAQ0EHxYdT3BlblNT
981 TCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFIdHsBcMVVMbAO7j6NCj
982 03HgLnHaMB8GA1UdIwQYMBaAFL2h9Bf9Mre4vTdOiHTGAt7BRY/8MEYGA1UdEQQ/
983 MD2CDSouZXhhbXBsZS5vcmeCESoub20yLmV4bWFwbGUuY29thwSC7wgKgRNvbTJA
984 b3Blbm1ldGFkaXIub3JnMA0GCSqGSIb3DQEBBQUAA4GBALd7WdXkp2KvZ7/PuWZA
985 MPlIxyjS+Ly11+BNE0xGQRp9Wz+2lABtpgNqssvU156+HkKd02rGheb2tj7MX9hG
986 uZzbwDAZzJPjzDQDD7d3cWsrVcfIdqVU7epHqIadnOF+X0ghJ39pAm6VVadnSXCt
987 WpOdIpB8KksUTCzV591Nr1wd
988 -----END CERTIFICATE-----
992 Create and return a new L{X509}.
999 L{X509} and L{X509Type} refer to the same type object and can be used
1000 to create instances of that type.
1002 self.assertIdentical(X509, X509Type)
1003 self.assertConsistentType(X509, 'X509')
1006 def test_construction(self):
1008 L{X509} takes no arguments and returns an instance of L{X509Type}.
1010 certificate = X509()
1012 isinstance(certificate, X509Type),
1013 "%r is of type %r, should be %r" % (certificate,
1016 self.assertEqual(type(X509Type).__name__, 'type')
1017 self.assertEqual(type(certificate).__name__, 'X509')
1018 self.assertEqual(type(certificate), X509Type)
1019 self.assertEqual(type(certificate), X509)
1022 def test_get_version_wrong_args(self):
1024 L{X509.get_version} raises L{TypeError} if invoked with any arguments.
1027 self.assertRaises(TypeError, cert.get_version, None)
1030 def test_set_version_wrong_args(self):
1032 L{X509.set_version} raises L{TypeError} if invoked with the wrong number
1033 of arguments or an argument not of type C{int}.
1036 self.assertRaises(TypeError, cert.set_version)
1037 self.assertRaises(TypeError, cert.set_version, None)
1038 self.assertRaises(TypeError, cert.set_version, 1, None)
1041 def test_version(self):
1043 L{X509.set_version} sets the certificate version number.
1044 L{X509.get_version} retrieves it.
1047 cert.set_version(1234)
1048 self.assertEquals(cert.get_version(), 1234)
1051 def test_get_serial_number_wrong_args(self):
1053 L{X509.get_serial_number} raises L{TypeError} if invoked with any
1057 self.assertRaises(TypeError, cert.get_serial_number, None)
1060 def test_serial_number(self):
1062 The serial number of an L{X509Type} can be retrieved and modified with
1063 L{X509Type.get_serial_number} and L{X509Type.set_serial_number}.
1065 certificate = X509()
1066 self.assertRaises(TypeError, certificate.set_serial_number)
1067 self.assertRaises(TypeError, certificate.set_serial_number, 1, 2)
1068 self.assertRaises(TypeError, certificate.set_serial_number, "1")
1069 self.assertRaises(TypeError, certificate.set_serial_number, 5.5)
1070 self.assertEqual(certificate.get_serial_number(), 0)
1071 certificate.set_serial_number(1)
1072 self.assertEqual(certificate.get_serial_number(), 1)
1073 certificate.set_serial_number(2 ** 32 + 1)
1074 self.assertEqual(certificate.get_serial_number(), 2 ** 32 + 1)
1075 certificate.set_serial_number(2 ** 64 + 1)
1076 self.assertEqual(certificate.get_serial_number(), 2 ** 64 + 1)
1077 certificate.set_serial_number(2 ** 128 + 1)
1078 self.assertEqual(certificate.get_serial_number(), 2 ** 128 + 1)
1081 def _setBoundTest(self, which):
1083 L{X509Type.set_notBefore} takes a string in the format of an ASN1
1084 GENERALIZEDTIME and sets the beginning of the certificate's validity
1087 certificate = X509()
1088 set = getattr(certificate, 'set_not' + which)
1089 get = getattr(certificate, 'get_not' + which)
1091 # Starts with no value.
1092 self.assertEqual(get(), None)
1094 # GMT (Or is it UTC?) -exarkun
1095 when = b("20040203040506Z")
1097 self.assertEqual(get(), when)
1099 # A plus two hours and thirty minutes offset
1100 when = b("20040203040506+0530")
1102 self.assertEqual(get(), when)
1104 # A minus one hour fifteen minutes offset
1105 when = b("20040203040506-0115")
1107 self.assertEqual(get(), when)
1109 # An invalid string results in a ValueError
1110 self.assertRaises(ValueError, set, b("foo bar"))
1112 # The wrong number of arguments results in a TypeError.
1113 self.assertRaises(TypeError, set)
1114 self.assertRaises(TypeError, set, b("20040203040506Z"), b("20040203040506Z"))
1115 self.assertRaises(TypeError, get, b("foo bar"))
1118 # XXX ASN1_TIME (not GENERALIZEDTIME)
1120 def test_set_notBefore(self):
1122 L{X509Type.set_notBefore} takes a string in the format of an ASN1
1123 GENERALIZEDTIME and sets the beginning of the certificate's validity
1126 self._setBoundTest("Before")
1129 def test_set_notAfter(self):
1131 L{X509Type.set_notAfter} takes a string in the format of an ASN1
1132 GENERALIZEDTIME and sets the end of the certificate's validity period
1135 self._setBoundTest("After")
1138 def test_get_notBefore(self):
1140 L{X509Type.get_notBefore} returns a string in the format of an ASN1
1141 GENERALIZEDTIME even for certificates which store it as UTCTIME
1144 cert = load_certificate(FILETYPE_PEM, self.pemData)
1145 self.assertEqual(cert.get_notBefore(), b("20090325123658Z"))
1148 def test_get_notAfter(self):
1150 L{X509Type.get_notAfter} returns a string in the format of an ASN1
1151 GENERALIZEDTIME even for certificates which store it as UTCTIME
1154 cert = load_certificate(FILETYPE_PEM, self.pemData)
1155 self.assertEqual(cert.get_notAfter(), b("20170611123658Z"))
1158 def test_gmtime_adj_notBefore_wrong_args(self):
1160 L{X509Type.gmtime_adj_notBefore} raises L{TypeError} if called with the
1161 wrong number of arguments or a non-C{int} argument.
1164 self.assertRaises(TypeError, cert.gmtime_adj_notBefore)
1165 self.assertRaises(TypeError, cert.gmtime_adj_notBefore, None)
1166 self.assertRaises(TypeError, cert.gmtime_adj_notBefore, 123, None)
1169 def test_gmtime_adj_notBefore(self):
1171 L{X509Type.gmtime_adj_notBefore} changes the not-before timestamp to be
1172 the current time plus the number of seconds passed in.
1174 cert = load_certificate(FILETYPE_PEM, self.pemData)
1175 now = datetime.utcnow() + timedelta(seconds=100)
1176 cert.gmtime_adj_notBefore(100)
1177 self.assertEqual(cert.get_notBefore(), b(now.strftime("%Y%m%d%H%M%SZ")))
1180 def test_gmtime_adj_notAfter_wrong_args(self):
1182 L{X509Type.gmtime_adj_notAfter} raises L{TypeError} if called with the
1183 wrong number of arguments or a non-C{int} argument.
1186 self.assertRaises(TypeError, cert.gmtime_adj_notAfter)
1187 self.assertRaises(TypeError, cert.gmtime_adj_notAfter, None)
1188 self.assertRaises(TypeError, cert.gmtime_adj_notAfter, 123, None)
1191 def test_gmtime_adj_notAfter(self):
1193 L{X509Type.gmtime_adj_notAfter} changes the not-after timestamp to be
1194 the current time plus the number of seconds passed in.
1196 cert = load_certificate(FILETYPE_PEM, self.pemData)
1197 now = datetime.utcnow() + timedelta(seconds=100)
1198 cert.gmtime_adj_notAfter(100)
1199 self.assertEqual(cert.get_notAfter(), b(now.strftime("%Y%m%d%H%M%SZ")))
1202 def test_has_expired_wrong_args(self):
1204 L{X509Type.has_expired} raises L{TypeError} if called with any
1208 self.assertRaises(TypeError, cert.has_expired, None)
1211 def test_has_expired(self):
1213 L{X509Type.has_expired} returns C{True} if the certificate's not-after
1214 time is in the past.
1217 cert.gmtime_adj_notAfter(-1)
1218 self.assertTrue(cert.has_expired())
1221 def test_has_not_expired(self):
1223 L{X509Type.has_expired} returns C{False} if the certificate's not-after
1224 time is in the future.
1227 cert.gmtime_adj_notAfter(2)
1228 self.assertFalse(cert.has_expired())
1231 def test_digest(self):
1233 L{X509.digest} returns a string giving ":"-separated hex-encoded words
1234 of the digest of the certificate.
1239 b("A8:EB:07:F8:53:25:0A:F2:56:05:C5:A5:C4:C4:C7:15"))
1242 def _extcert(self, pkey, extensions):
1244 cert.set_pubkey(pkey)
1245 cert.get_subject().commonName = "Unit Tests"
1246 cert.get_issuer().commonName = "Unit Tests"
1247 when = b(datetime.now().strftime("%Y%m%d%H%M%SZ"))
1248 cert.set_notBefore(when)
1249 cert.set_notAfter(when)
1251 cert.add_extensions(extensions)
1252 return load_certificate(
1253 FILETYPE_PEM, dump_certificate(FILETYPE_PEM, cert))
1256 def test_extension_count(self):
1258 L{X509.get_extension_count} returns the number of extensions that are
1259 present in the certificate.
1261 pkey = load_privatekey(FILETYPE_PEM, client_key_pem)
1262 ca = X509Extension(b('basicConstraints'), True, b('CA:FALSE'))
1263 key = X509Extension(b('keyUsage'), True, b('digitalSignature'))
1264 subjectAltName = X509Extension(
1265 b('subjectAltName'), True, b('DNS:example.com'))
1267 # Try a certificate with no extensions at all.
1268 c = self._extcert(pkey, [])
1269 self.assertEqual(c.get_extension_count(), 0)
1271 # And a certificate with one
1272 c = self._extcert(pkey, [ca])
1273 self.assertEqual(c.get_extension_count(), 1)
1275 # And a certificate with several
1276 c = self._extcert(pkey, [ca, key, subjectAltName])
1277 self.assertEqual(c.get_extension_count(), 3)
1280 def test_get_extension(self):
1282 L{X509.get_extension} takes an integer and returns an L{X509Extension}
1283 corresponding to the extension at that index.
1285 pkey = load_privatekey(FILETYPE_PEM, client_key_pem)
1286 ca = X509Extension(b('basicConstraints'), True, b('CA:FALSE'))
1287 key = X509Extension(b('keyUsage'), True, b('digitalSignature'))
1288 subjectAltName = X509Extension(
1289 b('subjectAltName'), False, b('DNS:example.com'))
1291 cert = self._extcert(pkey, [ca, key, subjectAltName])
1293 ext = cert.get_extension(0)
1294 self.assertTrue(isinstance(ext, X509Extension))
1295 self.assertTrue(ext.get_critical())
1296 self.assertEqual(ext.get_short_name(), b('basicConstraints'))
1298 ext = cert.get_extension(1)
1299 self.assertTrue(isinstance(ext, X509Extension))
1300 self.assertTrue(ext.get_critical())
1301 self.assertEqual(ext.get_short_name(), b('keyUsage'))
1303 ext = cert.get_extension(2)
1304 self.assertTrue(isinstance(ext, X509Extension))
1305 self.assertFalse(ext.get_critical())
1306 self.assertEqual(ext.get_short_name(), b('subjectAltName'))
1308 self.assertRaises(IndexError, cert.get_extension, -1)
1309 self.assertRaises(IndexError, cert.get_extension, 4)
1310 self.assertRaises(TypeError, cert.get_extension, "hello")
1313 def test_invalid_digest_algorithm(self):
1315 L{X509.digest} raises L{ValueError} if called with an unrecognized hash
1319 self.assertRaises(ValueError, cert.digest, "monkeys")
1322 def test_get_subject_wrong_args(self):
1324 L{X509.get_subject} raises L{TypeError} if called with any arguments.
1327 self.assertRaises(TypeError, cert.get_subject, None)
1330 def test_get_subject(self):
1332 L{X509.get_subject} returns an L{X509Name} instance.
1334 cert = load_certificate(FILETYPE_PEM, self.pemData)
1335 subj = cert.get_subject()
1336 self.assertTrue(isinstance(subj, X509Name))
1338 subj.get_components(),
1339 [(b('C'), b('US')), (b('ST'), b('IL')), (b('L'), b('Chicago')),
1340 (b('O'), b('Testing')), (b('CN'), b('Testing Root CA'))])
1343 def test_set_subject_wrong_args(self):
1345 L{X509.set_subject} raises a L{TypeError} if called with the wrong
1346 number of arguments or an argument not of type L{X509Name}.
1349 self.assertRaises(TypeError, cert.set_subject)
1350 self.assertRaises(TypeError, cert.set_subject, None)
1351 self.assertRaises(TypeError, cert.set_subject, cert.get_subject(), None)
1354 def test_set_subject(self):
1356 L{X509.set_subject} changes the subject of the certificate to the one
1360 name = cert.get_subject()
1362 name.O = 'Unit Tests'
1363 cert.set_subject(name)
1365 cert.get_subject().get_components(),
1366 [(b('C'), b('AU')), (b('O'), b('Unit Tests'))])
1369 def test_get_issuer_wrong_args(self):
1371 L{X509.get_issuer} raises L{TypeError} if called with any arguments.
1374 self.assertRaises(TypeError, cert.get_issuer, None)
1377 def test_get_issuer(self):
1379 L{X509.get_issuer} returns an L{X509Name} instance.
1381 cert = load_certificate(FILETYPE_PEM, self.pemData)
1382 subj = cert.get_issuer()
1383 self.assertTrue(isinstance(subj, X509Name))
1384 comp = subj.get_components()
1387 [(b('C'), b('US')), (b('ST'), b('IL')), (b('L'), b('Chicago')),
1388 (b('O'), b('Testing')), (b('CN'), b('Testing Root CA'))])
1391 def test_set_issuer_wrong_args(self):
1393 L{X509.set_issuer} raises a L{TypeError} if called with the wrong
1394 number of arguments or an argument not of type L{X509Name}.
1397 self.assertRaises(TypeError, cert.set_issuer)
1398 self.assertRaises(TypeError, cert.set_issuer, None)
1399 self.assertRaises(TypeError, cert.set_issuer, cert.get_issuer(), None)
1402 def test_set_issuer(self):
1404 L{X509.set_issuer} changes the issuer of the certificate to the one
1408 name = cert.get_issuer()
1410 name.O = 'Unit Tests'
1411 cert.set_issuer(name)
1413 cert.get_issuer().get_components(),
1414 [(b('C'), b('AU')), (b('O'), b('Unit Tests'))])
1417 def test_get_pubkey_uninitialized(self):
1419 When called on a certificate with no public key, L{X509.get_pubkey}
1420 raises L{OpenSSL.crypto.Error}.
1423 self.assertRaises(Error, cert.get_pubkey)
1426 def test_subject_name_hash_wrong_args(self):
1428 L{X509.subject_name_hash} raises L{TypeError} if called with any
1432 self.assertRaises(TypeError, cert.subject_name_hash, None)
1435 def test_subject_name_hash(self):
1437 L{X509.subject_name_hash} returns the hash of the certificate's subject
1440 cert = load_certificate(FILETYPE_PEM, self.pemData)
1441 self.assertEquals(cert.subject_name_hash(), 3350047874)
1445 class PKCS12Tests(TestCase):
1447 Test for L{OpenSSL.crypto.PKCS12} and L{OpenSSL.crypto.load_pkcs12}.
1449 pemData = cleartextCertificatePEM + cleartextPrivateKeyPEM
1451 def test_type(self):
1453 L{PKCS12Type} is a type object.
1455 self.assertIdentical(PKCS12, PKCS12Type)
1456 self.assertConsistentType(PKCS12, 'PKCS12')
1459 def test_empty_construction(self):
1461 L{PKCS12} returns a new instance of L{PKCS12} with no certificate,
1462 private key, CA certificates, or friendly name.
1465 self.assertEqual(None, p12.get_certificate())
1466 self.assertEqual(None, p12.get_privatekey())
1467 self.assertEqual(None, p12.get_ca_certificates())
1468 self.assertEqual(None, p12.get_friendlyname())
1471 def test_type_errors(self):
1473 The L{PKCS12} setter functions (C{set_certificate}, C{set_privatekey},
1474 C{set_ca_certificates}, and C{set_friendlyname}) raise L{TypeError}
1475 when passed objects of types other than those expected.
1478 self.assertRaises(TypeError, p12.set_certificate, 3)
1479 self.assertRaises(TypeError, p12.set_certificate, PKey())
1480 self.assertRaises(TypeError, p12.set_certificate, X509)
1481 self.assertRaises(TypeError, p12.set_privatekey, 3)
1482 self.assertRaises(TypeError, p12.set_privatekey, 'legbone')
1483 self.assertRaises(TypeError, p12.set_privatekey, X509())
1484 self.assertRaises(TypeError, p12.set_ca_certificates, 3)
1485 self.assertRaises(TypeError, p12.set_ca_certificates, X509())
1486 self.assertRaises(TypeError, p12.set_ca_certificates, (3, 4))
1487 self.assertRaises(TypeError, p12.set_ca_certificates, ( PKey(), ))
1488 self.assertRaises(TypeError, p12.set_friendlyname, 6)
1489 self.assertRaises(TypeError, p12.set_friendlyname, ('foo', 'bar'))
1492 def test_key_only(self):
1494 A L{PKCS12} with only a private key can be exported using
1495 L{PKCS12.export} and loaded again using L{load_pkcs12}.
1499 pkey = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
1500 p12.set_privatekey(pkey)
1501 self.assertEqual(None, p12.get_certificate())
1502 self.assertEqual(pkey, p12.get_privatekey())
1504 dumped_p12 = p12.export(passphrase=passwd, iter=2, maciter=3)
1506 # Some versions of OpenSSL will throw an exception
1507 # for this nearly useless PKCS12 we tried to generate:
1508 # [('PKCS12 routines', 'PKCS12_create', 'invalid null argument')]
1510 p12 = load_pkcs12(dumped_p12, passwd)
1511 self.assertEqual(None, p12.get_ca_certificates())
1512 self.assertEqual(None, p12.get_certificate())
1514 # OpenSSL fails to bring the key back to us. So sad. Perhaps in the
1515 # future this will be improved.
1516 self.assertTrue(isinstance(p12.get_privatekey(), (PKey, type(None))))
1519 def test_cert_only(self):
1521 A L{PKCS12} with only a certificate can be exported using
1522 L{PKCS12.export} and loaded again using L{load_pkcs12}.
1526 cert = load_certificate(FILETYPE_PEM, cleartextCertificatePEM)
1527 p12.set_certificate(cert)
1528 self.assertEqual(cert, p12.get_certificate())
1529 self.assertEqual(None, p12.get_privatekey())
1531 dumped_p12 = p12.export(passphrase=passwd, iter=2, maciter=3)
1533 # Some versions of OpenSSL will throw an exception
1534 # for this nearly useless PKCS12 we tried to generate:
1535 # [('PKCS12 routines', 'PKCS12_create', 'invalid null argument')]
1537 p12 = load_pkcs12(dumped_p12, passwd)
1538 self.assertEqual(None, p12.get_privatekey())
1540 # OpenSSL fails to bring the cert back to us. Groany mcgroan.
1541 self.assertTrue(isinstance(p12.get_certificate(), (X509, type(None))))
1543 # Oh ho. It puts the certificate into the ca certificates list, in
1544 # fact. Totally bogus, I would think. Nevertheless, let's exploit
1545 # that to check to see if it reconstructed the certificate we expected
1546 # it to. At some point, hopefully this will change so that
1547 # p12.get_certificate() is actually what returns the loaded
1550 cleartextCertificatePEM,
1551 dump_certificate(FILETYPE_PEM, p12.get_ca_certificates()[0]))
1554 def gen_pkcs12(self, cert_pem=None, key_pem=None, ca_pem=None, friendly_name=None):
1556 Generate a PKCS12 object with components from PEM. Verify that the set
1557 functions return None.
1561 ret = p12.set_certificate(load_certificate(FILETYPE_PEM, cert_pem))
1562 self.assertEqual(ret, None)
1564 ret = p12.set_privatekey(load_privatekey(FILETYPE_PEM, key_pem))
1565 self.assertEqual(ret, None)
1567 ret = p12.set_ca_certificates((load_certificate(FILETYPE_PEM, ca_pem),))
1568 self.assertEqual(ret, None)
1570 ret = p12.set_friendlyname(friendly_name)
1571 self.assertEqual(ret, None)
1575 def check_recovery(self, p12_str, key=None, cert=None, ca=None, passwd='',
1578 Use openssl program to confirm three components are recoverable from a
1582 recovered_key = _runopenssl(
1583 p12_str, "pkcs12", '-nocerts', '-nodes', '-passin',
1584 'pass:' + passwd, *extra)
1585 self.assertEqual(recovered_key[-len(key):], key)
1587 recovered_cert = _runopenssl(
1588 p12_str, "pkcs12", '-clcerts', '-nodes', '-passin',
1589 'pass:' + passwd, '-nokeys', *extra)
1590 self.assertEqual(recovered_cert[-len(cert):], cert)
1592 recovered_cert = _runopenssl(
1593 p12_str, "pkcs12", '-cacerts', '-nodes', '-passin',
1594 'pass:' + passwd, '-nokeys', *extra)
1595 self.assertEqual(recovered_cert[-len(ca):], ca)
1598 def test_load_pkcs12(self):
1600 A PKCS12 string generated using the openssl command line can be loaded
1601 with L{load_pkcs12} and its components extracted and examined.
1604 pem = client_key_pem + client_cert_pem
1605 p12_str = _runopenssl(
1606 pem, "pkcs12", '-export', '-clcerts', '-passout', 'pass:' + passwd)
1607 p12 = load_pkcs12(p12_str, passwd)
1609 self.assertTrue(isinstance(p12, PKCS12))
1610 cert_pem = dump_certificate(FILETYPE_PEM, p12.get_certificate())
1611 self.assertEqual(cert_pem, client_cert_pem)
1612 key_pem = dump_privatekey(FILETYPE_PEM, p12.get_privatekey())
1613 self.assertEqual(key_pem, client_key_pem)
1614 self.assertEqual(None, p12.get_ca_certificates())
1617 def test_load_pkcs12_garbage(self):
1619 L{load_pkcs12} raises L{OpenSSL.crypto.Error} when passed a string
1620 which is not a PKCS12 dump.
1623 e = self.assertRaises(Error, load_pkcs12, 'fruit loops', passwd)
1624 self.assertEqual( e.args[0][0][0], 'asn1 encoding routines')
1625 self.assertEqual( len(e.args[0][0]), 3)
1628 def test_replace(self):
1630 L{PKCS12.set_certificate} replaces the certificate in a PKCS12 cluster.
1631 L{PKCS12.set_privatekey} replaces the private key.
1632 L{PKCS12.set_ca_certificates} replaces the CA certificates.
1634 p12 = self.gen_pkcs12(client_cert_pem, client_key_pem, root_cert_pem)
1635 p12.set_certificate(load_certificate(FILETYPE_PEM, server_cert_pem))
1636 p12.set_privatekey(load_privatekey(FILETYPE_PEM, server_key_pem))
1637 root_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
1638 client_cert = load_certificate(FILETYPE_PEM, client_cert_pem)
1639 p12.set_ca_certificates([root_cert]) # not a tuple
1640 self.assertEqual(1, len(p12.get_ca_certificates()))
1641 self.assertEqual(root_cert, p12.get_ca_certificates()[0])
1642 p12.set_ca_certificates([client_cert, root_cert])
1643 self.assertEqual(2, len(p12.get_ca_certificates()))
1644 self.assertEqual(client_cert, p12.get_ca_certificates()[0])
1645 self.assertEqual(root_cert, p12.get_ca_certificates()[1])
1648 def test_friendly_name(self):
1650 The I{friendlyName} of a PKCS12 can be set and retrieved via
1651 L{PKCS12.get_friendlyname} and L{PKCS12_set_friendlyname}, and a
1652 L{PKCS12} with a friendly name set can be dumped with L{PKCS12.export}.
1654 passwd = 'Dogmeat[]{}!@#$%^&*()~`?/.,<>-_+=";:'
1655 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
1656 for friendly_name in [b('Serverlicious'), None, b('###')]:
1657 p12.set_friendlyname(friendly_name)
1658 self.assertEqual(p12.get_friendlyname(), friendly_name)
1659 dumped_p12 = p12.export(passphrase=passwd, iter=2, maciter=3)
1660 reloaded_p12 = load_pkcs12(dumped_p12, passwd)
1662 p12.get_friendlyname(),reloaded_p12.get_friendlyname())
1663 # We would use the openssl program to confirm the friendly
1664 # name, but it is not possible. The pkcs12 command
1665 # does not store the friendly name in the cert's
1666 # alias, which we could then extract.
1667 self.check_recovery(
1668 dumped_p12, key=server_key_pem, cert=server_cert_pem,
1669 ca=root_cert_pem, passwd=passwd)
1672 def test_various_empty_passphrases(self):
1674 Test that missing, None, and '' passphrases are identical for PKCS12
1677 p12 = self.gen_pkcs12(client_cert_pem, client_key_pem, root_cert_pem)
1679 dumped_p12_empty = p12.export(iter=2, maciter=0, passphrase=passwd)
1680 dumped_p12_none = p12.export(iter=3, maciter=2, passphrase=None)
1681 dumped_p12_nopw = p12.export(iter=9, maciter=4)
1682 for dumped_p12 in [dumped_p12_empty, dumped_p12_none, dumped_p12_nopw]:
1683 self.check_recovery(
1684 dumped_p12, key=client_key_pem, cert=client_cert_pem,
1685 ca=root_cert_pem, passwd=passwd)
1688 def test_removing_ca_cert(self):
1690 Passing C{None} to L{PKCS12.set_ca_certificates} removes all CA
1693 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
1694 p12.set_ca_certificates(None)
1695 self.assertEqual(None, p12.get_ca_certificates())
1698 def test_export_without_mac(self):
1700 Exporting a PKCS12 with a C{maciter} of C{-1} excludes the MAC
1703 passwd = 'Lake Michigan'
1704 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
1705 dumped_p12 = p12.export(maciter=-1, passphrase=passwd, iter=2)
1706 self.check_recovery(
1707 dumped_p12, key=server_key_pem, cert=server_cert_pem,
1708 passwd=passwd, extra=('-nomacver',))
1711 def test_load_without_mac(self):
1713 Loading a PKCS12 without a MAC does something other than crash.
1715 passwd = 'Lake Michigan'
1716 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
1717 dumped_p12 = p12.export(maciter=-1, passphrase=passwd, iter=2)
1719 recovered_p12 = load_pkcs12(dumped_p12, passwd)
1720 # The person who generated this PCKS12 should be flogged,
1721 # or better yet we should have a means to determine
1722 # whether a PCKS12 had a MAC that was verified.
1723 # Anyway, libopenssl chooses to allow it, so the
1724 # pyopenssl binding does as well.
1725 self.assertTrue(isinstance(recovered_p12, PKCS12))
1727 # Failing here with an exception is preferred as some openssl
1732 def test_zero_len_list_for_ca(self):
1734 A PKCS12 with an empty CA certificates list can be exported.
1737 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem)
1738 p12.set_ca_certificates([])
1739 self.assertEqual((), p12.get_ca_certificates())
1740 dumped_p12 = p12.export(passphrase=passwd, iter=3)
1741 self.check_recovery(
1742 dumped_p12, key=server_key_pem, cert=server_cert_pem,
1746 def test_export_without_args(self):
1748 All the arguments to L{PKCS12.export} are optional.
1750 p12 = self.gen_pkcs12(server_cert_pem, server_key_pem, root_cert_pem)
1751 dumped_p12 = p12.export() # no args
1752 self.check_recovery(
1753 dumped_p12, key=server_key_pem, cert=server_cert_pem, passwd='')
1756 def test_key_cert_mismatch(self):
1758 L{PKCS12.export} raises an exception when a key and certificate
1761 p12 = self.gen_pkcs12(server_cert_pem, client_key_pem, root_cert_pem)
1762 self.assertRaises(Error, p12.export)
1766 # These quoting functions taken directly from Twisted's twisted.python.win32.
1767 _cmdLineQuoteRe = re.compile(r'(\\*)"')
1768 _cmdLineQuoteRe2 = re.compile(r'(\\+)\Z')
1769 def cmdLineQuote(s):
1771 Internal method for quoting a single command-line argument.
1774 @param s: A single unquoted string to quote for something that is expecting
1775 cmd.exe-style quoting
1778 @return: A cmd.exe-style quoted string
1780 @see: U{http://www.perlmonks.org/?node_id=764004}
1782 s = _cmdLineQuoteRe2.sub(r"\1\1", _cmdLineQuoteRe.sub(r'\1\1\\"', s))
1787 def quoteArguments(arguments):
1789 Quote an iterable of command-line arguments for passing to CreateProcess or
1790 a similar API. This allows the list passed to C{reactor.spawnProcess} to
1791 match the child process's C{sys.argv} properly.
1793 @type arguments: C{iterable} of C{str}
1794 @param arguments: An iterable of unquoted arguments to quote
1797 @return: A space-delimited string containing quoted versions of L{arguments}
1799 return ' '.join(map(cmdLineQuote, arguments))
1803 def _runopenssl(pem, *args):
1805 Run the command line openssl tool with the given arguments and write
1806 the given PEM to its stdin. Not safe for quotes.
1808 if os.name == 'posix':
1809 command = "openssl " + " ".join([
1810 "'%s'" % (arg.replace("'", "'\\''"),) for arg in args])
1812 command = "openssl " + quoteArguments(args)
1813 proc = Popen(command, shell=True, stdin=PIPE, stdout=PIPE)
1814 proc.stdin.write(pem)
1816 return proc.stdout.read()
1820 class FunctionTests(TestCase):
1822 Tests for free-functions in the L{OpenSSL.crypto} module.
1825 def test_load_privatekey_invalid_format(self):
1827 L{load_privatekey} raises L{ValueError} if passed an unknown filetype.
1829 self.assertRaises(ValueError, load_privatekey, 100, root_key_pem)
1832 def test_load_privatekey_invalid_passphrase_type(self):
1834 L{load_privatekey} raises L{TypeError} if passed a passphrase that is
1835 neither a c{str} nor a callable.
1840 FILETYPE_PEM, encryptedPrivateKeyPEMPassphrase, object())
1843 def test_load_privatekey_wrong_args(self):
1845 L{load_privatekey} raises L{TypeError} if called with the wrong number
1848 self.assertRaises(TypeError, load_privatekey)
1851 def test_load_privatekey_wrongPassphrase(self):
1853 L{load_privatekey} raises L{OpenSSL.crypto.Error} when it is passed an
1854 encrypted PEM and an incorrect passphrase.
1858 load_privatekey, FILETYPE_PEM, encryptedPrivateKeyPEM, b("quack"))
1861 def test_load_privatekey_passphrase(self):
1863 L{load_privatekey} can create a L{PKey} object from an encrypted PEM
1864 string if given the passphrase.
1866 key = load_privatekey(
1867 FILETYPE_PEM, encryptedPrivateKeyPEM,
1868 encryptedPrivateKeyPEMPassphrase)
1869 self.assertTrue(isinstance(key, PKeyType))
1872 def test_load_privatekey_wrongPassphraseCallback(self):
1874 L{load_privatekey} raises L{OpenSSL.crypto.Error} when it is passed an
1875 encrypted PEM and a passphrase callback which returns an incorrect
1884 load_privatekey, FILETYPE_PEM, encryptedPrivateKeyPEM, cb)
1885 self.assertTrue(called)
1888 def test_load_privatekey_passphraseCallback(self):
1890 L{load_privatekey} can create a L{PKey} object from an encrypted PEM
1891 string if given a passphrase callback which returns the correct
1896 called.append(writing)
1897 return encryptedPrivateKeyPEMPassphrase
1898 key = load_privatekey(FILETYPE_PEM, encryptedPrivateKeyPEM, cb)
1899 self.assertTrue(isinstance(key, PKeyType))
1900 self.assertEqual(called, [False])
1903 def test_load_privatekey_passphrase_exception(self):
1905 An exception raised by the passphrase callback passed to
1906 L{load_privatekey} causes L{OpenSSL.crypto.Error} to be raised.
1908 This isn't as nice as just letting the exception pass through. The
1909 behavior might be changed to that eventually.
1911 def broken(ignored):
1912 raise RuntimeError("This is not working.")
1916 FILETYPE_PEM, encryptedPrivateKeyPEM, broken)
1919 def test_dump_privatekey_wrong_args(self):
1921 L{dump_privatekey} raises L{TypeError} if called with the wrong number
1924 self.assertRaises(TypeError, dump_privatekey)
1927 def test_dump_privatekey_unknown_cipher(self):
1929 L{dump_privatekey} raises L{ValueError} if called with an unrecognized
1933 key.generate_key(TYPE_RSA, 512)
1935 ValueError, dump_privatekey,
1936 FILETYPE_PEM, key, "zippers", "passphrase")
1939 def test_dump_privatekey_invalid_passphrase_type(self):
1941 L{dump_privatekey} raises L{TypeError} if called with a passphrase which
1942 is neither a C{str} nor a callable.
1945 key.generate_key(TYPE_RSA, 512)
1948 dump_privatekey, FILETYPE_PEM, key, "blowfish", object())
1951 def test_dump_privatekey_invalid_filetype(self):
1953 L{dump_privatekey} raises L{ValueError} if called with an unrecognized
1957 key.generate_key(TYPE_RSA, 512)
1958 self.assertRaises(ValueError, dump_privatekey, 100, key)
1961 def test_dump_privatekey_passphrase(self):
1963 L{dump_privatekey} writes an encrypted PEM when given a passphrase.
1965 passphrase = b("foo")
1966 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
1967 pem = dump_privatekey(FILETYPE_PEM, key, "blowfish", passphrase)
1968 self.assertTrue(isinstance(pem, bytes))
1969 loadedKey = load_privatekey(FILETYPE_PEM, pem, passphrase)
1970 self.assertTrue(isinstance(loadedKey, PKeyType))
1971 self.assertEqual(loadedKey.type(), key.type())
1972 self.assertEqual(loadedKey.bits(), key.bits())
1975 def test_dump_certificate(self):
1977 L{dump_certificate} writes PEM, DER, and text.
1979 pemData = cleartextCertificatePEM + cleartextPrivateKeyPEM
1980 cert = load_certificate(FILETYPE_PEM, pemData)
1981 dumped_pem = dump_certificate(FILETYPE_PEM, cert)
1982 self.assertEqual(dumped_pem, cleartextCertificatePEM)
1983 dumped_der = dump_certificate(FILETYPE_ASN1, cert)
1984 good_der = _runopenssl(dumped_pem, "x509", "-outform", "DER")
1985 self.assertEqual(dumped_der, good_der)
1986 cert2 = load_certificate(FILETYPE_ASN1, dumped_der)
1987 dumped_pem2 = dump_certificate(FILETYPE_PEM, cert2)
1988 self.assertEqual(dumped_pem2, cleartextCertificatePEM)
1989 dumped_text = dump_certificate(FILETYPE_TEXT, cert)
1990 good_text = _runopenssl(dumped_pem, "x509", "-noout", "-text")
1991 self.assertEqual(dumped_text, good_text)
1994 def test_dump_privatekey(self):
1996 L{dump_privatekey} writes a PEM, DER, and text.
1998 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
1999 dumped_pem = dump_privatekey(FILETYPE_PEM, key)
2000 self.assertEqual(dumped_pem, cleartextPrivateKeyPEM)
2001 dumped_der = dump_privatekey(FILETYPE_ASN1, key)
2002 # XXX This OpenSSL call writes "writing RSA key" to standard out. Sad.
2003 good_der = _runopenssl(dumped_pem, "rsa", "-outform", "DER")
2004 self.assertEqual(dumped_der, good_der)
2005 key2 = load_privatekey(FILETYPE_ASN1, dumped_der)
2006 dumped_pem2 = dump_privatekey(FILETYPE_PEM, key2)
2007 self.assertEqual(dumped_pem2, cleartextPrivateKeyPEM)
2008 dumped_text = dump_privatekey(FILETYPE_TEXT, key)
2009 good_text = _runopenssl(dumped_pem, "rsa", "-noout", "-text")
2010 self.assertEqual(dumped_text, good_text)
2013 def test_dump_certificate_request(self):
2015 L{dump_certificate_request} writes a PEM, DER, and text.
2017 req = load_certificate_request(FILETYPE_PEM, cleartextCertificateRequestPEM)
2018 dumped_pem = dump_certificate_request(FILETYPE_PEM, req)
2019 self.assertEqual(dumped_pem, cleartextCertificateRequestPEM)
2020 dumped_der = dump_certificate_request(FILETYPE_ASN1, req)
2021 good_der = _runopenssl(dumped_pem, "req", "-outform", "DER")
2022 self.assertEqual(dumped_der, good_der)
2023 req2 = load_certificate_request(FILETYPE_ASN1, dumped_der)
2024 dumped_pem2 = dump_certificate_request(FILETYPE_PEM, req2)
2025 self.assertEqual(dumped_pem2, cleartextCertificateRequestPEM)
2026 dumped_text = dump_certificate_request(FILETYPE_TEXT, req)
2027 good_text = _runopenssl(dumped_pem, "req", "-noout", "-text")
2028 self.assertEqual(dumped_text, good_text)
2029 self.assertRaises(ValueError, dump_certificate_request, 100, req)
2032 def test_dump_privatekey_passphraseCallback(self):
2034 L{dump_privatekey} writes an encrypted PEM when given a callback which
2035 returns the correct passphrase.
2037 passphrase = b("foo")
2040 called.append(writing)
2042 key = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
2043 pem = dump_privatekey(FILETYPE_PEM, key, "blowfish", cb)
2044 self.assertTrue(isinstance(pem, bytes))
2045 self.assertEqual(called, [True])
2046 loadedKey = load_privatekey(FILETYPE_PEM, pem, passphrase)
2047 self.assertTrue(isinstance(loadedKey, PKeyType))
2048 self.assertEqual(loadedKey.type(), key.type())
2049 self.assertEqual(loadedKey.bits(), key.bits())
2052 def test_load_pkcs7_data(self):
2054 L{load_pkcs7_data} accepts a PKCS#7 string and returns an instance of
2057 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2058 self.assertTrue(isinstance(pkcs7, PKCS7Type))
2062 class PKCS7Tests(TestCase):
2064 Tests for L{PKCS7Type}.
2066 def test_type(self):
2068 L{PKCS7Type} is a type object.
2070 self.assertTrue(isinstance(PKCS7Type, type))
2071 self.assertEqual(PKCS7Type.__name__, 'PKCS7')
2073 # XXX This doesn't currently work.
2074 # self.assertIdentical(PKCS7, PKCS7Type)
2077 # XXX Opposite results for all these following methods
2079 def test_type_is_signed_wrong_args(self):
2081 L{PKCS7Type.type_is_signed} raises L{TypeError} if called with any
2084 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2085 self.assertRaises(TypeError, pkcs7.type_is_signed, None)
2088 def test_type_is_signed(self):
2090 L{PKCS7Type.type_is_signed} returns C{True} if the PKCS7 object is of
2093 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2094 self.assertTrue(pkcs7.type_is_signed())
2097 def test_type_is_enveloped_wrong_args(self):
2099 L{PKCS7Type.type_is_enveloped} raises L{TypeError} if called with any
2102 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2103 self.assertRaises(TypeError, pkcs7.type_is_enveloped, None)
2106 def test_type_is_enveloped(self):
2108 L{PKCS7Type.type_is_enveloped} returns C{False} if the PKCS7 object is
2109 not of the type I{enveloped}.
2111 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2112 self.assertFalse(pkcs7.type_is_enveloped())
2115 def test_type_is_signedAndEnveloped_wrong_args(self):
2117 L{PKCS7Type.type_is_signedAndEnveloped} raises L{TypeError} if called
2120 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2121 self.assertRaises(TypeError, pkcs7.type_is_signedAndEnveloped, None)
2124 def test_type_is_signedAndEnveloped(self):
2126 L{PKCS7Type.type_is_signedAndEnveloped} returns C{False} if the PKCS7
2127 object is not of the type I{signed and enveloped}.
2129 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2130 self.assertFalse(pkcs7.type_is_signedAndEnveloped())
2133 def test_type_is_data(self):
2135 L{PKCS7Type.type_is_data} returns C{False} if the PKCS7 object is not of
2138 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2139 self.assertFalse(pkcs7.type_is_data())
2142 def test_type_is_data_wrong_args(self):
2144 L{PKCS7Type.type_is_data} raises L{TypeError} if called with any
2147 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2148 self.assertRaises(TypeError, pkcs7.type_is_data, None)
2151 def test_get_type_name_wrong_args(self):
2153 L{PKCS7Type.get_type_name} raises L{TypeError} if called with any
2156 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2157 self.assertRaises(TypeError, pkcs7.get_type_name, None)
2160 def test_get_type_name(self):
2162 L{PKCS7Type.get_type_name} returns a C{str} giving the type name.
2164 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2165 self.assertEquals(pkcs7.get_type_name(), b('pkcs7-signedData'))
2168 def test_attribute(self):
2170 If an attribute other than one of the methods tested here is accessed on
2171 an instance of L{PKCS7Type}, L{AttributeError} is raised.
2173 pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2174 self.assertRaises(AttributeError, getattr, pkcs7, "foo")
2178 class NetscapeSPKITests(TestCase, _PKeyInteractionTestsMixin):
2180 Tests for L{OpenSSL.crypto.NetscapeSPKI}.
2184 Return a new L{NetscapeSPKI} for use with signing tests.
2186 return NetscapeSPKI()
2189 def test_type(self):
2191 L{NetscapeSPKI} and L{NetscapeSPKIType} refer to the same type object
2192 and can be used to create instances of that type.
2194 self.assertIdentical(NetscapeSPKI, NetscapeSPKIType)
2195 self.assertConsistentType(NetscapeSPKI, 'NetscapeSPKI')
2198 def test_construction(self):
2200 L{NetscapeSPKI} returns an instance of L{NetscapeSPKIType}.
2202 nspki = NetscapeSPKI()
2203 self.assertTrue(isinstance(nspki, NetscapeSPKIType))
2206 def test_invalid_attribute(self):
2208 Accessing a non-existent attribute of a L{NetscapeSPKI} instance causes
2209 an L{AttributeError} to be raised.
2211 nspki = NetscapeSPKI()
2212 self.assertRaises(AttributeError, lambda: nspki.foo)
2215 def test_b64_encode(self):
2217 L{NetscapeSPKI.b64_encode} encodes the certificate to a base64 blob.
2219 nspki = NetscapeSPKI()
2220 blob = nspki.b64_encode()
2221 self.assertTrue(isinstance(blob, bytes))
2225 class RevokedTests(TestCase):
2227 Tests for L{OpenSSL.crypto.Revoked}
2229 def test_construction(self):
2231 Confirm we can create L{OpenSSL.crypto.Revoked}. Check
2235 self.assertTrue(isinstance(revoked, Revoked))
2236 self.assertEquals(type(revoked), Revoked)
2237 self.assertEquals(revoked.get_serial(), b('00'))
2238 self.assertEquals(revoked.get_rev_date(), None)
2239 self.assertEquals(revoked.get_reason(), None)
2242 def test_construction_wrong_args(self):
2244 Calling L{OpenSSL.crypto.Revoked} with any arguments results
2245 in a L{TypeError} being raised.
2247 self.assertRaises(TypeError, Revoked, None)
2248 self.assertRaises(TypeError, Revoked, 1)
2249 self.assertRaises(TypeError, Revoked, "foo")
2252 def test_serial(self):
2254 Confirm we can set and get serial numbers from
2255 L{OpenSSL.crypto.Revoked}. Confirm errors are handled
2259 ret = revoked.set_serial(b('10b'))
2260 self.assertEquals(ret, None)
2261 ser = revoked.get_serial()
2262 self.assertEquals(ser, b('010B'))
2264 revoked.set_serial(b('31ppp')) # a type error would be nice
2265 ser = revoked.get_serial()
2266 self.assertEquals(ser, b('31'))
2268 self.assertRaises(ValueError, revoked.set_serial, b('pqrst'))
2269 self.assertRaises(TypeError, revoked.set_serial, 100)
2270 self.assertRaises(TypeError, revoked.get_serial, 1)
2271 self.assertRaises(TypeError, revoked.get_serial, None)
2272 self.assertRaises(TypeError, revoked.get_serial, "")
2275 def test_date(self):
2277 Confirm we can set and get revocation dates from
2278 L{OpenSSL.crypto.Revoked}. Confirm errors are handled
2282 date = revoked.get_rev_date()
2283 self.assertEquals(date, None)
2285 now = b(datetime.now().strftime("%Y%m%d%H%M%SZ"))
2286 ret = revoked.set_rev_date(now)
2287 self.assertEqual(ret, None)
2288 date = revoked.get_rev_date()
2289 self.assertEqual(date, now)
2292 def test_reason(self):
2294 Confirm we can set and get revocation reasons from
2295 L{OpenSSL.crypto.Revoked}. The "get" need to work
2296 as "set". Likewise, each reason of all_reasons() must work.
2299 for r in revoked.all_reasons():
2301 ret = revoked.set_reason(r)
2302 self.assertEquals(ret, None)
2303 reason = revoked.get_reason()
2305 reason.lower().replace(b(' '), b('')),
2306 r.lower().replace(b(' '), b('')))
2307 r = reason # again with the resp of get
2309 revoked.set_reason(None)
2310 self.assertEqual(revoked.get_reason(), None)
2313 def test_set_reason_wrong_arguments(self):
2315 Calling L{OpenSSL.crypto.Revoked.set_reason} with other than
2316 one argument, or an argument which isn't a valid reason,
2317 results in L{TypeError} or L{ValueError} being raised.
2320 self.assertRaises(TypeError, revoked.set_reason, 100)
2321 self.assertRaises(ValueError, revoked.set_reason, b('blue'))
2324 def test_get_reason_wrong_arguments(self):
2326 Calling L{OpenSSL.crypto.Revoked.get_reason} with any
2327 arguments results in L{TypeError} being raised.
2330 self.assertRaises(TypeError, revoked.get_reason, None)
2331 self.assertRaises(TypeError, revoked.get_reason, 1)
2332 self.assertRaises(TypeError, revoked.get_reason, "foo")
2336 class CRLTests(TestCase):
2338 Tests for L{OpenSSL.crypto.CRL}
2340 cert = load_certificate(FILETYPE_PEM, cleartextCertificatePEM)
2341 pkey = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
2343 def test_construction(self):
2345 Confirm we can create L{OpenSSL.crypto.CRL}. Check
2349 self.assertTrue( isinstance(crl, CRL) )
2350 self.assertEqual(crl.get_revoked(), None)
2353 def test_construction_wrong_args(self):
2355 Calling L{OpenSSL.crypto.CRL} with any number of arguments
2356 results in a L{TypeError} being raised.
2358 self.assertRaises(TypeError, CRL, 1)
2359 self.assertRaises(TypeError, CRL, "")
2360 self.assertRaises(TypeError, CRL, None)
2363 def test_export(self):
2365 Use python to create a simple CRL with a revocation, and export
2366 the CRL in formats of PEM, DER and text. Those outputs are verified
2367 with the openssl program.
2371 now = b(datetime.now().strftime("%Y%m%d%H%M%SZ"))
2372 revoked.set_rev_date(now)
2373 revoked.set_serial(b('3ab'))
2374 revoked.set_reason(b('sUpErSeDEd'))
2375 crl.add_revoked(revoked)
2378 dumped_crl = crl.export(self.cert, self.pkey, days=20)
2379 text = _runopenssl(dumped_crl, "crl", "-noout", "-text")
2380 text.index(b('Serial Number: 03AB'))
2381 text.index(b('Superseded'))
2382 text.index(b('Issuer: /C=US/ST=IL/L=Chicago/O=Testing/CN=Testing Root CA'))
2385 dumped_crl = crl.export(self.cert, self.pkey, FILETYPE_ASN1)
2386 text = _runopenssl(dumped_crl, "crl", "-noout", "-text", "-inform", "DER")
2387 text.index(b('Serial Number: 03AB'))
2388 text.index(b('Superseded'))
2389 text.index(b('Issuer: /C=US/ST=IL/L=Chicago/O=Testing/CN=Testing Root CA'))
2392 dumped_text = crl.export(self.cert, self.pkey, type=FILETYPE_TEXT)
2393 self.assertEqual(text, dumped_text)
2396 def test_add_revoked_keyword(self):
2398 L{OpenSSL.CRL.add_revoked} accepts its single argument as the
2399 I{revoked} keyword argument.
2403 crl.add_revoked(revoked=revoked)
2404 self.assertTrue(isinstance(crl.get_revoked()[0], Revoked))
2407 def test_export_wrong_args(self):
2409 Calling L{OpenSSL.CRL.export} with fewer than two or more than
2410 four arguments, or with arguments other than the certificate,
2411 private key, integer file type, and integer number of days it
2412 expects, results in a L{TypeError} being raised.
2415 self.assertRaises(TypeError, crl.export)
2416 self.assertRaises(TypeError, crl.export, self.cert)
2417 self.assertRaises(TypeError, crl.export, self.cert, self.pkey, FILETYPE_PEM, 10, "foo")
2419 self.assertRaises(TypeError, crl.export, None, self.pkey, FILETYPE_PEM, 10)
2420 self.assertRaises(TypeError, crl.export, self.cert, None, FILETYPE_PEM, 10)
2421 self.assertRaises(TypeError, crl.export, self.cert, self.pkey, None, 10)
2422 self.assertRaises(TypeError, crl.export, self.cert, FILETYPE_PEM, None)
2425 def test_export_unknown_filetype(self):
2427 Calling L{OpenSSL.CRL.export} with a file type other than
2428 L{FILETYPE_PEM}, L{FILETYPE_ASN1}, or L{FILETYPE_TEXT} results
2429 in a L{ValueError} being raised.
2432 self.assertRaises(ValueError, crl.export, self.cert, self.pkey, 100, 10)
2435 def test_get_revoked(self):
2437 Use python to create a simple CRL with two revocations.
2438 Get back the L{Revoked} using L{OpenSSL.CRL.get_revoked} and
2444 now = b(datetime.now().strftime("%Y%m%d%H%M%SZ"))
2445 revoked.set_rev_date(now)
2446 revoked.set_serial(b('3ab'))
2447 crl.add_revoked(revoked)
2448 revoked.set_serial(b('100'))
2449 revoked.set_reason(b('sUpErSeDEd'))
2450 crl.add_revoked(revoked)
2452 revs = crl.get_revoked()
2453 self.assertEqual(len(revs), 2)
2454 self.assertEqual(type(revs[0]), Revoked)
2455 self.assertEqual(type(revs[1]), Revoked)
2456 self.assertEqual(revs[0].get_serial(), b('03AB'))
2457 self.assertEqual(revs[1].get_serial(), b('0100'))
2458 self.assertEqual(revs[0].get_rev_date(), now)
2459 self.assertEqual(revs[1].get_rev_date(), now)
2462 def test_get_revoked_wrong_args(self):
2464 Calling L{OpenSSL.CRL.get_revoked} with any arguments results
2465 in a L{TypeError} being raised.
2468 self.assertRaises(TypeError, crl.get_revoked, None)
2469 self.assertRaises(TypeError, crl.get_revoked, 1)
2470 self.assertRaises(TypeError, crl.get_revoked, "")
2471 self.assertRaises(TypeError, crl.get_revoked, "", 1, None)
2474 def test_add_revoked_wrong_args(self):
2476 Calling L{OpenSSL.CRL.add_revoked} with other than one
2477 argument results in a L{TypeError} being raised.
2480 self.assertRaises(TypeError, crl.add_revoked)
2481 self.assertRaises(TypeError, crl.add_revoked, 1, 2)
2482 self.assertRaises(TypeError, crl.add_revoked, "foo", "bar")
2485 def test_load_crl(self):
2487 Load a known CRL and inspect its revocations. Both
2488 PEM and DER formats are loaded.
2490 crl = load_crl(FILETYPE_PEM, crlData)
2491 revs = crl.get_revoked()
2492 self.assertEqual(len(revs), 2)
2493 self.assertEqual(revs[0].get_serial(), b('03AB'))
2494 self.assertEqual(revs[0].get_reason(), None)
2495 self.assertEqual(revs[1].get_serial(), b('0100'))
2496 self.assertEqual(revs[1].get_reason(), b('Superseded'))
2498 der = _runopenssl(crlData, "crl", "-outform", "DER")
2499 crl = load_crl(FILETYPE_ASN1, der)
2500 revs = crl.get_revoked()
2501 self.assertEqual(len(revs), 2)
2502 self.assertEqual(revs[0].get_serial(), b('03AB'))
2503 self.assertEqual(revs[0].get_reason(), None)
2504 self.assertEqual(revs[1].get_serial(), b('0100'))
2505 self.assertEqual(revs[1].get_reason(), b('Superseded'))
2508 def test_load_crl_wrong_args(self):
2510 Calling L{OpenSSL.crypto.load_crl} with other than two
2511 arguments results in a L{TypeError} being raised.
2513 self.assertRaises(TypeError, load_crl)
2514 self.assertRaises(TypeError, load_crl, FILETYPE_PEM)
2515 self.assertRaises(TypeError, load_crl, FILETYPE_PEM, crlData, None)
2518 def test_load_crl_bad_filetype(self):
2520 Calling L{OpenSSL.crypto.load_crl} with an unknown file type
2521 raises a L{ValueError}.
2523 self.assertRaises(ValueError, load_crl, 100, crlData)
2526 def test_load_crl_bad_data(self):
2528 Calling L{OpenSSL.crypto.load_crl} with file data which can't
2529 be loaded raises a L{OpenSSL.crypto.Error}.
2531 self.assertRaises(Error, load_crl, FILETYPE_PEM, "hello, world")
2534 class SignVerifyTests(TestCase):
2536 Tests for L{OpenSSL.crypto.sign} and L{OpenSSL.crypto.verify}.
2538 def test_sign_verify(self):
2540 L{sign} generates a cryptographic signature which L{verify} can check.
2543 "It was a bright cold day in April, and the clocks were striking "
2544 "thirteen. Winston Smith, his chin nuzzled into his breast in an "
2545 "effort to escape the vile wind, slipped quickly through the "
2546 "glass doors of Victory Mansions, though not quickly enough to "
2547 "prevent a swirl of gritty dust from entering along with him.")
2549 # sign the content with this private key
2550 priv_key = load_privatekey(FILETYPE_PEM, root_key_pem)
2551 # verify the content with this cert
2552 good_cert = load_certificate(FILETYPE_PEM, root_cert_pem)
2553 # certificate unrelated to priv_key, used to trigger an error
2554 bad_cert = load_certificate(FILETYPE_PEM, server_cert_pem)
2556 for digest in ['md5', 'sha1']:
2557 sig = sign(priv_key, content, digest)
2559 # Verify the signature of content, will throw an exception if error.
2560 verify(good_cert, sig, content, digest)
2562 # This should fail because the certificate doesn't match the
2563 # private key that was used to sign the content.
2564 self.assertRaises(Error, verify, bad_cert, sig, content, digest)
2566 # This should fail because we've "tainted" the content after
2570 good_cert, sig, content + b("tainted"), digest)
2572 # test that unknown digest types fail
2574 ValueError, sign, priv_key, content, "strange-digest")
2576 ValueError, verify, good_cert, sig, content, "strange-digest")
2579 if __name__ == '__main__':