Initial import to Tizen
[profile/ivi/python-pyOpenSSL.git] / OpenSSL / test / test_crypto.py
1 # Copyright (c) Jean-Paul Calderone
2 # See LICENSE file for details.
3
4 """
5 Unit tests for L{OpenSSL.crypto}.
6 """
7
8 from unittest import main
9
10 import os, re
11 from subprocess import PIPE, Popen
12 from datetime import datetime, timedelta
13
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
28
29
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-----
48 """)
49
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-----
65 """)
66
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-----
81 """)
82
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-----
98 """)
99
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-----
114 """)
115
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-----
131 """)
132
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-----
151 """)
152
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-----
168 """)
169
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-----
181 """)
182
183 encryptedPrivateKeyPEM = b("""-----BEGIN RSA PRIVATE KEY-----
184 Proc-Type: 4,ENCRYPTED
185 DEK-Info: DES-EDE3-CBC,9573604A18579E9E
186
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-----
201 """)
202 encryptedPrivateKeyPEMPassphrase = b("foobar")
203
204 # Some PKCS#7 stuff.  Generated with the openssl command line:
205 #
206 #    openssl crl2pkcs7 -inform pem -outform pem -certfile s.pem -nocrl
207 #
208 # with a certificate and key (but the key should be irrelevant) in s.pem
209 pkcs7Data = b("""\
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
228 Ho4EzbYCOaEAMQA=
229 -----END PKCS7-----
230 """)
231
232 crlData = b("""\
233 -----BEGIN X509 CRL-----
234 MIIBWzCBxTANBgkqhkiG9w0BAQQFADBYMQswCQYDVQQGEwJVUzELMAkGA1UECBMC
235 SUwxEDAOBgNVBAcTB0NoaWNhZ28xEDAOBgNVBAoTB1Rlc3RpbmcxGDAWBgNVBAMT
236 D1Rlc3RpbmcgUm9vdCBDQRcNMDkwNzI2MDQzNDU2WhcNMTIwOTI3MDI0MTUyWjA8
237 MBUCAgOrGA8yMDA5MDcyNTIzMzQ1NlowIwICAQAYDzIwMDkwNzI1MjMzNDU2WjAM
238 MAoGA1UdFQQDCgEEMA0GCSqGSIb3DQEBBAUAA4GBAEBt7xTs2htdD3d4ErrcGAw1
239 4dKcVnIWTutoI7xxen26Wwvh8VCsT7i/UeP+rBl9rC/kfjWjzQk3/zleaarGTpBT
240 0yp4HXRFFoRhhSE/hP+eteaPXRgrsNRLHe9ZDd69wmh7J1wMDb0m81RG7kqcbsid
241 vrzEeLDRiiPl92dyyWmu
242 -----END X509 CRL-----
243 """)
244
245 class X509ExtTests(TestCase):
246     """
247     Tests for L{OpenSSL.crypto.X509Extension}.
248     """
249
250     def setUp(self):
251         """
252         Create a new private key and start a certificate request (for a test
253         method to finish in one way or another).
254         """
255         # Basic setup stuff to generate a certificate
256         self.pkey = PKey()
257         self.pkey.generate_key(TYPE_RSA, 384)
258         self.req = X509Req()
259         self.req.set_pubkey(self.pkey)
260         # Authority good you have.
261         self.req.get_subject().commonName = "Yoda root CA"
262         self.x509 = X509()
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)
271
272
273     def test_str(self):
274         """
275         The string representation of L{X509Extension} instances as returned by
276         C{str} includes stuff.
277         """
278         # This isn't necessarily the best string representation.  Perhaps it
279         # will be changed/improved in the future.
280         self.assertEquals(
281             str(X509Extension(b('basicConstraints'), True, b('CA:false'))),
282             'CA:FALSE')
283
284
285     def test_type(self):
286         """
287         L{X509Extension} and L{X509ExtensionType} refer to the same type object
288         and can be used to create instances of that type.
289         """
290         self.assertIdentical(X509Extension, X509ExtensionType)
291         self.assertConsistentType(
292             X509Extension,
293             'X509Extension', b('basicConstraints'), True, b('CA:true'))
294
295
296     def test_construction(self):
297         """
298         L{X509Extension} accepts an extension type name, a critical flag,
299         and an extension value and returns an L{X509ExtensionType} instance.
300         """
301         basic = X509Extension(b('basicConstraints'), True, b('CA:true'))
302         self.assertTrue(
303             isinstance(basic, X509ExtensionType),
304             "%r is of type %r, should be %r" % (
305                 basic, type(basic), X509ExtensionType))
306
307         comment = X509Extension(
308             b('nsComment'), False, b('pyOpenSSL unit test'))
309         self.assertTrue(
310             isinstance(comment, X509ExtensionType),
311             "%r is of type %r, should be %r" % (
312                 comment, type(comment), X509ExtensionType))
313
314
315     def test_invalid_extension(self):
316         """
317         L{X509Extension} raises something if it is passed a bad extension
318         name or value.
319         """
320         self.assertRaises(
321             Error, X509Extension, b('thisIsMadeUp'), False, b('hi'))
322         self.assertRaises(
323             Error, X509Extension, b('basicConstraints'), False, b('blah blah'))
324
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.
329         self.assertRaises(
330             Error, X509Extension, b('proxyCertInfo'), True,
331             b('language:id-ppl-anyLanguage,pathlen:1,policy:text:AB'))
332
333
334     def test_get_critical(self):
335         """
336         L{X509ExtensionType.get_critical} returns the value of the
337         extension's critical flag.
338         """
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())
343
344
345     def test_get_short_name(self):
346         """
347         L{X509ExtensionType.get_short_name} returns a string giving the short
348         type name of the extension.
349         """
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'))
354
355
356     def test_get_data(self):
357         """
358         L{X509Extension.get_data} returns a string giving the data of the
359         extension.
360         """
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'))
364
365
366     def test_get_data_wrong_args(self):
367         """
368         L{X509Extension.get_data} raises L{TypeError} if passed any arguments.
369         """
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)
374
375
376     def test_unused_subject(self):
377         """
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.
380         """
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)
389
390
391     def test_subject(self):
392         """
393         If an extension requires a subject, the C{subject} parameter to
394         L{X509Extension} provides its value.
395         """
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)
402
403
404     def test_missing_subject(self):
405         """
406         If an extension requires a subject and the C{subject} parameter is
407         given no value, something happens.
408         """
409         self.assertRaises(
410             Error, X509Extension, b('subjectKeyIdentifier'), False, b('hash'))
411
412
413     def test_invalid_subject(self):
414         """
415         If the C{subject} 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                 'basicConstraints', False, 'CA:TRUE', subject=badObj)
423
424
425     def test_unused_issuer(self):
426         """
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.
429         """
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)
437
438
439     def test_issuer(self):
440         """
441         If an extension requires a issuer, the C{issuer} parameter to
442         L{X509Extension} provides its value.
443         """
444         ext2 = X509Extension(
445             b('authorityKeyIdentifier'), False, b('issuer:always'),
446             issuer=self.x509)
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)
452
453
454     def test_missing_issuer(self):
455         """
456         If an extension requires an issue and the C{issuer} parameter is given
457         no value, something happens.
458         """
459         self.assertRaises(
460             Error,
461             X509Extension,
462             b('authorityKeyIdentifier'), False,
463             b('keyid:always,issuer:always'))
464
465
466     def test_invalid_issuer(self):
467         """
468         If the C{issuer} parameter is given a value which is not an L{X509}
469         instance, L{TypeError} is raised.
470         """
471         for badObj in [True, object(), "hello", [], self]:
472             self.assertRaises(
473                 TypeError,
474                 X509Extension,
475                 'authorityKeyIdentifier', False, 'keyid:always,issuer:always',
476                 issuer=badObj)
477
478
479
480 class PKeyTests(TestCase):
481     """
482     Unit tests for L{OpenSSL.crypto.PKey}.
483     """
484     def test_type(self):
485         """
486         L{PKey} and L{PKeyType} refer to the same type object and can be used
487         to create instances of that type.
488         """
489         self.assertIdentical(PKey, PKeyType)
490         self.assertConsistentType(PKey, 'PKey')
491
492
493     def test_construction(self):
494         """
495         L{PKey} takes no arguments and returns a new L{PKey} instance.
496         """
497         self.assertRaises(TypeError, PKey, None)
498         key = PKey()
499         self.assertTrue(
500             isinstance(key, PKeyType),
501             "%r is of type %r, should be %r" % (key, type(key), PKeyType))
502
503
504     def test_pregeneration(self):
505         """
506         L{PKeyType.bits} and L{PKeyType.type} return C{0} before the key is
507         generated.
508         """
509         key = PKey()
510         self.assertEqual(key.type(), 0)
511         self.assertEqual(key.bits(), 0)
512
513
514     def test_failedGeneration(self):
515         """
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.
521         """
522         key = PKey()
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)
527
528         self.assertRaises(ValueError, key.generate_key, TYPE_RSA, -1)
529         self.assertRaises(ValueError, key.generate_key, TYPE_RSA, 0)
530
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.
536
537         # self.assertRaises(Error, key.generate_key, TYPE_RSA, 2)
538
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.
545
546         # self.assertRaises(Error, key.generate_key, TYPE_DSA, -7)
547
548
549     def test_rsaGeneration(self):
550         """
551         L{PKeyType.generate_key} generates an RSA key when passed
552         L{TYPE_RSA} as a type and a reasonable number of bits.
553         """
554         bits = 128
555         key = PKey()
556         key.generate_key(TYPE_RSA, bits)
557         self.assertEqual(key.type(), TYPE_RSA)
558         self.assertEqual(key.bits(), bits)
559
560
561     def test_dsaGeneration(self):
562         """
563         L{PKeyType.generate_key} generates a DSA key when passed
564         L{TYPE_DSA} as a type and a reasonable number of bits.
565         """
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.
569         bits = 512
570         key = PKey()
571         key.generate_key(TYPE_DSA, bits)
572         self.assertEqual(key.type(), TYPE_DSA)
573         self.assertEqual(key.bits(), bits)
574
575
576     def test_regeneration(self):
577         """
578         L{PKeyType.generate_key} can be called multiple times on the same
579         key to generate new keys.
580         """
581         key = PKey()
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)
586
587
588
589 class X509NameTests(TestCase):
590     """
591     Unit tests for L{OpenSSL.crypto.X509Name}.
592     """
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!
598         def key(attr):
599             return attr[1]
600         attrs.sort(key=key)
601         for k, v in attrs:
602             setattr(name, k, v)
603         return name
604
605
606     def test_type(self):
607         """
608         The type of X509Name objects is L{X509NameType}.
609         """
610         self.assertIdentical(X509Name, X509NameType)
611         self.assertEqual(X509NameType.__name__, 'X509Name')
612         self.assertTrue(isinstance(X509NameType, type))
613
614         name = self._x509name()
615         self.assertTrue(
616             isinstance(name, X509NameType),
617             "%r is of type %r, should be %r" % (
618                 name, type(name), X509NameType))
619
620
621     def test_attributes(self):
622         """
623         L{X509NameType} instances have attributes for each standard (?)
624         X509Name field.
625         """
626         name = self._x509name()
627         name.commonName = "foo"
628         self.assertEqual(name.commonName, "foo")
629         self.assertEqual(name.CN, "foo")
630         name.CN = "baz"
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")
636         name.CN = "quux"
637         self.assertEqual(name.commonName, "quux")
638         self.assertEqual(name.CN, "quux")
639
640
641     def test_copy(self):
642         """
643         L{X509Name} creates a new L{X509NameType} instance with all the same
644         attributes as an existing L{X509NameType} instance when called with
645         one.
646         """
647         name = self._x509name(commonName="foo", emailAddress="bar@example.com")
648
649         copy = X509Name(name)
650         self.assertEqual(copy.commonName, "foo")
651         self.assertEqual(copy.emailAddress, "bar@example.com")
652
653         # Mutate the copy and ensure the original is unmodified.
654         copy.commonName = "baz"
655         self.assertEqual(name.commonName, "foo")
656
657         # Mutate the original and ensure the copy is unmodified.
658         name.emailAddress = "quux@example.com"
659         self.assertEqual(copy.emailAddress, "bar@example.com")
660
661
662     def test_repr(self):
663         """
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
666         on it.
667         """
668         name = self._x509name(commonName="foo", emailAddress="bar")
669         self.assertEqual(
670             repr(name),
671             "<X509Name object '/emailAddress=bar/CN=foo'>")
672
673
674     def test_comparison(self):
675         """
676         L{X509NameType} instances should compare based on their NIDs.
677         """
678         def _equality(a, b, assertTrue, assertFalse):
679             assertTrue(a == b, "(%r == %r) --> False" % (a, b))
680             assertFalse(a != b)
681             assertTrue(b == a)
682             assertFalse(b != a)
683
684         def assertEqual(a, b):
685             _equality(a, b, self.assertTrue, self.assertFalse)
686
687         # Instances compare equal to themselves.
688         name = self._x509name()
689         assertEqual(name, name)
690
691         # Empty instances should compare equal to each other.
692         assertEqual(self._x509name(), self._x509name())
693
694         # Instances with equal NIDs should compare equal to each other.
695         assertEqual(self._x509name(commonName="foo"),
696                     self._x509name(commonName="foo"))
697
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"))
702
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"))
707
708         def assertNotEqual(a, b):
709             _equality(a, b, self.assertFalse, self.assertTrue)
710
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"))
715
716         # Instances with different NIDs should not compare equal to each other.
717         assertNotEqual(self._x509name(CN="foo"),
718                        self._x509name(OU="foo"))
719
720         def _inequality(a, b, assertTrue, assertFalse):
721             assertTrue(a < b)
722             assertTrue(a <= b)
723             assertTrue(b > a)
724             assertTrue(b >= a)
725             assertFalse(a > b)
726             assertFalse(a >= b)
727             assertFalse(b < a)
728             assertFalse(b <= a)
729
730         def assertLessThan(a, b):
731             _inequality(a, b, self.assertTrue, self.assertFalse)
732
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
735         # X509Name.
736         assertLessThan(self._x509name(CN="abc"),
737                        self._x509name(CN="def"))
738
739         def assertGreaterThan(a, b):
740             _inequality(a, b, self.assertFalse, self.assertTrue)
741
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
744         # other X509Name.
745         assertGreaterThan(self._x509name(CN="def"),
746                           self._x509name(CN="abc"))
747
748
749     def test_hash(self):
750         """
751         L{X509Name.hash} returns an integer hash based on the value of the
752         name.
753         """
754         a = self._x509name(CN="foo")
755         b = self._x509name(CN="foo")
756         self.assertEqual(a.hash(), b.hash())
757         a.CN = "bar"
758         self.assertNotEqual(a.hash(), b.hash())
759
760
761     def test_der(self):
762         """
763         L{X509Name.der} returns the DER encoded form of the name.
764         """
765         a = self._x509name(CN="foo", C="US")
766         self.assertEqual(
767             a.der(),
768             b('0\x1b1\x0b0\t\x06\x03U\x04\x06\x13\x02US'
769               '1\x0c0\n\x06\x03U\x04\x03\x13\x03foo'))
770
771
772     def test_get_components(self):
773         """
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.
776         """
777         a = self._x509name()
778         self.assertEqual(a.get_components(), [])
779         a.CN = "foo"
780         self.assertEqual(a.get_components(), [(b("CN"), b("foo"))])
781         a.organizationalUnitName = "bar"
782         self.assertEqual(
783             a.get_components(),
784             [(b("CN"), b("foo")), (b("OU"), b("bar"))])
785
786
787 class _PKeyInteractionTestsMixin:
788     """
789     Tests which involve another thing and a PKey.
790     """
791     def signable(self):
792         """
793         Return something with a C{set_pubkey}, C{set_pubkey}, and C{sign} method.
794         """
795         raise NotImplementedError()
796
797
798     def test_signWithUngenerated(self):
799         """
800         L{X509Req.sign} raises L{ValueError} when pass a L{PKey} with no parts.
801         """
802         request = self.signable()
803         key = PKey()
804         self.assertRaises(ValueError, request.sign, key, 'MD5')
805
806
807     def test_signWithPublicKey(self):
808         """
809         L{X509Req.sign} raises L{ValueError} when pass a L{PKey} with no
810         private part as the signing key.
811         """
812         request = self.signable()
813         key = PKey()
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')
818
819
820     def test_signWithUnknownDigest(self):
821         """
822         L{X509Req.sign} raises L{ValueError} when passed a digest name which is
823         not known.
824         """
825         request = self.signable()
826         key = PKey()
827         key.generate_key(TYPE_RSA, 512)
828         self.assertRaises(ValueError, request.sign, key, "monkeys")
829
830
831     def test_sign(self):
832         """
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.
835         """
836         request = self.signable()
837         key = PKey()
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.
846             key = PKey()
847             key.generate_key(TYPE_RSA, 512)
848             self.assertRaises(Error, request.verify, key)
849
850
851
852
853 class X509ReqTests(TestCase, _PKeyInteractionTestsMixin):
854     """
855     Tests for L{OpenSSL.crypto.X509Req}.
856     """
857     def signable(self):
858         """
859         Create and return a new L{X509Req}.
860         """
861         return X509Req()
862
863
864     def test_type(self):
865         """
866         L{X509Req} and L{X509ReqType} refer to the same type object and can be
867         used to create instances of that type.
868         """
869         self.assertIdentical(X509Req, X509ReqType)
870         self.assertConsistentType(X509Req, 'X509Req')
871
872
873     def test_construction(self):
874         """
875         L{X509Req} takes no arguments and returns an L{X509ReqType} instance.
876         """
877         request = X509Req()
878         self.assertTrue(
879             isinstance(request, X509ReqType),
880             "%r is of type %r, should be %r" % (request, type(request), X509ReqType))
881
882
883     def test_version(self):
884         """
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.
888         """
889         request = X509Req()
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)
895
896
897     def test_version_wrong_args(self):
898         """
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
902         arguments.
903         """
904         request = X509Req()
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)
909
910
911     def test_get_subject(self):
912         """
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
915         otherwise dead.
916         """
917         request = X509Req()
918         subject = request.get_subject()
919         self.assertTrue(
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")
924         del request
925         subject.commonName = "bar"
926         self.assertEqual(subject.commonName, "bar")
927
928
929     def test_get_subject_wrong_args(self):
930         """
931         L{X509ReqType.get_subject} raises L{TypeError} if called with any
932         arguments.
933         """
934         request = X509Req()
935         self.assertRaises(TypeError, request.get_subject, None)
936
937
938     def test_add_extensions(self):
939         """
940         L{X509Req.add_extensions} accepts a C{list} of L{X509Extension}
941         instances and adds them to the X509 request.
942         """
943         request = X509Req()
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.
947
948
949     def test_add_extensions_wrong_args(self):
950         """
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}
954         instances.
955         """
956         request = X509Req()
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)
961
962
963
964 class X509Tests(TestCase, _PKeyInteractionTestsMixin):
965     """
966     Tests for L{OpenSSL.crypto.X509}.
967     """
968     pemData = cleartextCertificatePEM + cleartextPrivateKeyPEM
969
970     extpem = """
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-----
989     """
990     def signable(self):
991         """
992         Create and return a new L{X509}.
993         """
994         return X509()
995
996
997     def test_type(self):
998         """
999         L{X509} and L{X509Type} refer to the same type object and can be used
1000         to create instances of that type.
1001         """
1002         self.assertIdentical(X509, X509Type)
1003         self.assertConsistentType(X509, 'X509')
1004
1005
1006     def test_construction(self):
1007         """
1008         L{X509} takes no arguments and returns an instance of L{X509Type}.
1009         """
1010         certificate = X509()
1011         self.assertTrue(
1012             isinstance(certificate, X509Type),
1013             "%r is of type %r, should be %r" % (certificate,
1014                                                 type(certificate),
1015                                                 X509Type))
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)
1020
1021
1022     def test_get_version_wrong_args(self):
1023         """
1024         L{X509.get_version} raises L{TypeError} if invoked with any arguments.
1025         """
1026         cert = X509()
1027         self.assertRaises(TypeError, cert.get_version, None)
1028
1029
1030     def test_set_version_wrong_args(self):
1031         """
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}.
1034         """
1035         cert = X509()
1036         self.assertRaises(TypeError, cert.set_version)
1037         self.assertRaises(TypeError, cert.set_version, None)
1038         self.assertRaises(TypeError, cert.set_version, 1, None)
1039
1040
1041     def test_version(self):
1042         """
1043         L{X509.set_version} sets the certificate version number.
1044         L{X509.get_version} retrieves it.
1045         """
1046         cert = X509()
1047         cert.set_version(1234)
1048         self.assertEquals(cert.get_version(), 1234)
1049
1050
1051     def test_get_serial_number_wrong_args(self):
1052         """
1053         L{X509.get_serial_number} raises L{TypeError} if invoked with any
1054         arguments.
1055         """
1056         cert = X509()
1057         self.assertRaises(TypeError, cert.get_serial_number, None)
1058
1059
1060     def test_serial_number(self):
1061         """
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}.
1064         """
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)
1079
1080
1081     def _setBoundTest(self, which):
1082         """
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
1085         period to it.
1086         """
1087         certificate = X509()
1088         set = getattr(certificate, 'set_not' + which)
1089         get = getattr(certificate, 'get_not' + which)
1090
1091         # Starts with no value.
1092         self.assertEqual(get(), None)
1093
1094         # GMT (Or is it UTC?) -exarkun
1095         when = b("20040203040506Z")
1096         set(when)
1097         self.assertEqual(get(), when)
1098
1099         # A plus two hours and thirty minutes offset
1100         when = b("20040203040506+0530")
1101         set(when)
1102         self.assertEqual(get(), when)
1103
1104         # A minus one hour fifteen minutes offset
1105         when = b("20040203040506-0115")
1106         set(when)
1107         self.assertEqual(get(), when)
1108
1109         # An invalid string results in a ValueError
1110         self.assertRaises(ValueError, set, b("foo bar"))
1111
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"))
1116
1117
1118     # XXX ASN1_TIME (not GENERALIZEDTIME)
1119
1120     def test_set_notBefore(self):
1121         """
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
1124         period to it.
1125         """
1126         self._setBoundTest("Before")
1127
1128
1129     def test_set_notAfter(self):
1130         """
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
1133         to it.
1134         """
1135         self._setBoundTest("After")
1136
1137
1138     def test_get_notBefore(self):
1139         """
1140         L{X509Type.get_notBefore} returns a string in the format of an ASN1
1141         GENERALIZEDTIME even for certificates which store it as UTCTIME
1142         internally.
1143         """
1144         cert = load_certificate(FILETYPE_PEM, self.pemData)
1145         self.assertEqual(cert.get_notBefore(), b("20090325123658Z"))
1146
1147
1148     def test_get_notAfter(self):
1149         """
1150         L{X509Type.get_notAfter} returns a string in the format of an ASN1
1151         GENERALIZEDTIME even for certificates which store it as UTCTIME
1152         internally.
1153         """
1154         cert = load_certificate(FILETYPE_PEM, self.pemData)
1155         self.assertEqual(cert.get_notAfter(), b("20170611123658Z"))
1156
1157
1158     def test_gmtime_adj_notBefore_wrong_args(self):
1159         """
1160         L{X509Type.gmtime_adj_notBefore} raises L{TypeError} if called with the
1161         wrong number of arguments or a non-C{int} argument.
1162         """
1163         cert = X509()
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)
1167
1168
1169     def test_gmtime_adj_notBefore(self):
1170         """
1171         L{X509Type.gmtime_adj_notBefore} changes the not-before timestamp to be
1172         the current time plus the number of seconds passed in.
1173         """
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")))
1178
1179
1180     def test_gmtime_adj_notAfter_wrong_args(self):
1181         """
1182         L{X509Type.gmtime_adj_notAfter} raises L{TypeError} if called with the
1183         wrong number of arguments or a non-C{int} argument.
1184         """
1185         cert = X509()
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)
1189
1190
1191     def test_gmtime_adj_notAfter(self):
1192         """
1193         L{X509Type.gmtime_adj_notAfter} changes the not-after timestamp to be
1194         the current time plus the number of seconds passed in.
1195         """
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")))
1200
1201
1202     def test_has_expired_wrong_args(self):
1203         """
1204         L{X509Type.has_expired} raises L{TypeError} if called with any
1205         arguments.
1206         """
1207         cert = X509()
1208         self.assertRaises(TypeError, cert.has_expired, None)
1209
1210
1211     def test_has_expired(self):
1212         """
1213         L{X509Type.has_expired} returns C{True} if the certificate's not-after
1214         time is in the past.
1215         """
1216         cert = X509()
1217         cert.gmtime_adj_notAfter(-1)
1218         self.assertTrue(cert.has_expired())
1219
1220
1221     def test_has_not_expired(self):
1222         """
1223         L{X509Type.has_expired} returns C{False} if the certificate's not-after
1224         time is in the future.
1225         """
1226         cert = X509()
1227         cert.gmtime_adj_notAfter(2)
1228         self.assertFalse(cert.has_expired())
1229
1230
1231     def test_digest(self):
1232         """
1233         L{X509.digest} returns a string giving ":"-separated hex-encoded words
1234         of the digest of the certificate.
1235         """
1236         cert = X509()
1237         self.assertEqual(
1238             cert.digest("md5"),
1239             b("A8:EB:07:F8:53:25:0A:F2:56:05:C5:A5:C4:C4:C7:15"))
1240
1241
1242     def _extcert(self, pkey, extensions):
1243         cert = X509()
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)
1250
1251         cert.add_extensions(extensions)
1252         return load_certificate(
1253             FILETYPE_PEM, dump_certificate(FILETYPE_PEM, cert))
1254
1255
1256     def test_extension_count(self):
1257         """
1258         L{X509.get_extension_count} returns the number of extensions that are
1259         present in the certificate.
1260         """
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'))
1266
1267         # Try a certificate with no extensions at all.
1268         c = self._extcert(pkey, [])
1269         self.assertEqual(c.get_extension_count(), 0)
1270
1271         # And a certificate with one
1272         c = self._extcert(pkey, [ca])
1273         self.assertEqual(c.get_extension_count(), 1)
1274
1275         # And a certificate with several
1276         c = self._extcert(pkey, [ca, key, subjectAltName])
1277         self.assertEqual(c.get_extension_count(), 3)
1278
1279
1280     def test_get_extension(self):
1281         """
1282         L{X509.get_extension} takes an integer and returns an L{X509Extension}
1283         corresponding to the extension at that index.
1284         """
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'))
1290
1291         cert = self._extcert(pkey, [ca, key, subjectAltName])
1292
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'))
1297
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'))
1302
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'))
1307
1308         self.assertRaises(IndexError, cert.get_extension, -1)
1309         self.assertRaises(IndexError, cert.get_extension, 4)
1310         self.assertRaises(TypeError, cert.get_extension, "hello")
1311
1312
1313     def test_invalid_digest_algorithm(self):
1314         """
1315         L{X509.digest} raises L{ValueError} if called with an unrecognized hash
1316         algorithm.
1317         """
1318         cert = X509()
1319         self.assertRaises(ValueError, cert.digest, "monkeys")
1320
1321
1322     def test_get_subject_wrong_args(self):
1323         """
1324         L{X509.get_subject} raises L{TypeError} if called with any arguments.
1325         """
1326         cert = X509()
1327         self.assertRaises(TypeError, cert.get_subject, None)
1328
1329
1330     def test_get_subject(self):
1331         """
1332         L{X509.get_subject} returns an L{X509Name} instance.
1333         """
1334         cert = load_certificate(FILETYPE_PEM, self.pemData)
1335         subj = cert.get_subject()
1336         self.assertTrue(isinstance(subj, X509Name))
1337         self.assertEquals(
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'))])
1341
1342
1343     def test_set_subject_wrong_args(self):
1344         """
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}.
1347         """
1348         cert = X509()
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)
1352
1353
1354     def test_set_subject(self):
1355         """
1356         L{X509.set_subject} changes the subject of the certificate to the one
1357         passed in.
1358         """
1359         cert = X509()
1360         name = cert.get_subject()
1361         name.C = 'AU'
1362         name.O = 'Unit Tests'
1363         cert.set_subject(name)
1364         self.assertEquals(
1365             cert.get_subject().get_components(),
1366             [(b('C'), b('AU')), (b('O'), b('Unit Tests'))])
1367
1368
1369     def test_get_issuer_wrong_args(self):
1370         """
1371         L{X509.get_issuer} raises L{TypeError} if called with any arguments.
1372         """
1373         cert = X509()
1374         self.assertRaises(TypeError, cert.get_issuer, None)
1375
1376
1377     def test_get_issuer(self):
1378         """
1379         L{X509.get_issuer} returns an L{X509Name} instance.
1380         """
1381         cert = load_certificate(FILETYPE_PEM, self.pemData)
1382         subj = cert.get_issuer()
1383         self.assertTrue(isinstance(subj, X509Name))
1384         comp = subj.get_components()
1385         self.assertEquals(
1386             comp,
1387             [(b('C'), b('US')), (b('ST'), b('IL')), (b('L'), b('Chicago')),
1388              (b('O'), b('Testing')), (b('CN'), b('Testing Root CA'))])
1389
1390
1391     def test_set_issuer_wrong_args(self):
1392         """
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}.
1395         """
1396         cert = X509()
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)
1400
1401
1402     def test_set_issuer(self):
1403         """
1404         L{X509.set_issuer} changes the issuer of the certificate to the one
1405         passed in.
1406         """
1407         cert = X509()
1408         name = cert.get_issuer()
1409         name.C = 'AU'
1410         name.O = 'Unit Tests'
1411         cert.set_issuer(name)
1412         self.assertEquals(
1413             cert.get_issuer().get_components(),
1414             [(b('C'), b('AU')), (b('O'), b('Unit Tests'))])
1415
1416
1417     def test_get_pubkey_uninitialized(self):
1418         """
1419         When called on a certificate with no public key, L{X509.get_pubkey}
1420         raises L{OpenSSL.crypto.Error}.
1421         """
1422         cert = X509()
1423         self.assertRaises(Error, cert.get_pubkey)
1424
1425
1426     def test_subject_name_hash_wrong_args(self):
1427         """
1428         L{X509.subject_name_hash} raises L{TypeError} if called with any
1429         arguments.
1430         """
1431         cert = X509()
1432         self.assertRaises(TypeError, cert.subject_name_hash, None)
1433
1434
1435     def test_subject_name_hash(self):
1436         """
1437         L{X509.subject_name_hash} returns the hash of the certificate's subject
1438         name.
1439         """
1440         cert = load_certificate(FILETYPE_PEM, self.pemData)
1441         self.assertEquals(cert.subject_name_hash(), 3350047874)
1442
1443
1444
1445 class PKCS12Tests(TestCase):
1446     """
1447     Test for L{OpenSSL.crypto.PKCS12} and L{OpenSSL.crypto.load_pkcs12}.
1448     """
1449     pemData = cleartextCertificatePEM + cleartextPrivateKeyPEM
1450
1451     def test_type(self):
1452         """
1453         L{PKCS12Type} is a type object.
1454         """
1455         self.assertIdentical(PKCS12, PKCS12Type)
1456         self.assertConsistentType(PKCS12, 'PKCS12')
1457
1458
1459     def test_empty_construction(self):
1460         """
1461         L{PKCS12} returns a new instance of L{PKCS12} with no certificate,
1462         private key, CA certificates, or friendly name.
1463         """
1464         p12 = PKCS12()
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())
1469
1470
1471     def test_type_errors(self):
1472         """
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.
1476         """
1477         p12 = PKCS12()
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'))
1490
1491
1492     def test_key_only(self):
1493         """
1494         A L{PKCS12} with only a private key can be exported using
1495         L{PKCS12.export} and loaded again using L{load_pkcs12}.
1496         """
1497         passwd = 'blah'
1498         p12 = 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())
1503         try:
1504             dumped_p12 = p12.export(passphrase=passwd, iter=2, maciter=3)
1505         except Error:
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')]
1509             return
1510         p12 = load_pkcs12(dumped_p12, passwd)
1511         self.assertEqual(None, p12.get_ca_certificates())
1512         self.assertEqual(None, p12.get_certificate())
1513
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))))
1517
1518
1519     def test_cert_only(self):
1520         """
1521         A L{PKCS12} with only a certificate can be exported using
1522         L{PKCS12.export} and loaded again using L{load_pkcs12}.
1523         """
1524         passwd = 'blah'
1525         p12 = 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())
1530         try:
1531             dumped_p12 = p12.export(passphrase=passwd, iter=2, maciter=3)
1532         except Error:
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')]
1536             return
1537         p12 = load_pkcs12(dumped_p12, passwd)
1538         self.assertEqual(None, p12.get_privatekey())
1539
1540         # OpenSSL fails to bring the cert back to us.  Groany mcgroan.
1541         self.assertTrue(isinstance(p12.get_certificate(), (X509, type(None))))
1542
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
1548         # certificate.
1549         self.assertEqual(
1550             cleartextCertificatePEM,
1551             dump_certificate(FILETYPE_PEM, p12.get_ca_certificates()[0]))
1552
1553
1554     def gen_pkcs12(self, cert_pem=None, key_pem=None, ca_pem=None, friendly_name=None):
1555         """
1556         Generate a PKCS12 object with components from PEM.  Verify that the set
1557         functions return None.
1558         """
1559         p12 = PKCS12()
1560         if cert_pem:
1561             ret = p12.set_certificate(load_certificate(FILETYPE_PEM, cert_pem))
1562             self.assertEqual(ret, None)
1563         if key_pem:
1564             ret = p12.set_privatekey(load_privatekey(FILETYPE_PEM, key_pem))
1565             self.assertEqual(ret, None)
1566         if ca_pem:
1567             ret = p12.set_ca_certificates((load_certificate(FILETYPE_PEM, ca_pem),))
1568             self.assertEqual(ret, None)
1569         if friendly_name:
1570             ret = p12.set_friendlyname(friendly_name)
1571             self.assertEqual(ret, None)
1572         return p12
1573
1574
1575     def check_recovery(self, p12_str, key=None, cert=None, ca=None, passwd='',
1576                        extra=()):
1577         """
1578         Use openssl program to confirm three components are recoverable from a
1579         PKCS12 string.
1580         """
1581         if key:
1582             recovered_key = _runopenssl(
1583                 p12_str, "pkcs12", '-nocerts', '-nodes', '-passin',
1584                 'pass:' + passwd, *extra)
1585             self.assertEqual(recovered_key[-len(key):], key)
1586         if cert:
1587             recovered_cert = _runopenssl(
1588                 p12_str, "pkcs12", '-clcerts', '-nodes', '-passin',
1589                 'pass:' + passwd, '-nokeys', *extra)
1590             self.assertEqual(recovered_cert[-len(cert):], cert)
1591         if ca:
1592             recovered_cert = _runopenssl(
1593                 p12_str, "pkcs12", '-cacerts', '-nodes', '-passin',
1594                 'pass:' + passwd, '-nokeys', *extra)
1595             self.assertEqual(recovered_cert[-len(ca):], ca)
1596
1597
1598     def test_load_pkcs12(self):
1599         """
1600         A PKCS12 string generated using the openssl command line can be loaded
1601         with L{load_pkcs12} and its components extracted and examined.
1602         """
1603         passwd = 'whatever'
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)
1608         # verify
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())
1615
1616
1617     def test_load_pkcs12_garbage(self):
1618         """
1619         L{load_pkcs12} raises L{OpenSSL.crypto.Error} when passed a string
1620         which is not a PKCS12 dump.
1621         """
1622         passwd = 'whatever'
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)
1626
1627
1628     def test_replace(self):
1629         """
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.
1633         """
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])
1646
1647
1648     def test_friendly_name(self):
1649         """
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}.
1653         """
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)
1661             self.assertEqual(
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)
1670
1671
1672     def test_various_empty_passphrases(self):
1673         """
1674         Test that missing, None, and '' passphrases are identical for PKCS12
1675         export.
1676         """
1677         p12 = self.gen_pkcs12(client_cert_pem, client_key_pem, root_cert_pem)
1678         passwd = ''
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)
1686
1687
1688     def test_removing_ca_cert(self):
1689         """
1690         Passing C{None} to L{PKCS12.set_ca_certificates} removes all CA
1691         certificates.
1692         """
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())
1696
1697
1698     def test_export_without_mac(self):
1699         """
1700         Exporting a PKCS12 with a C{maciter} of C{-1} excludes the MAC
1701         entirely.
1702         """
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',))
1709
1710
1711     def test_load_without_mac(self):
1712         """
1713         Loading a PKCS12 without a MAC does something other than crash.
1714         """
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)
1718         try:
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))
1726         except Error:
1727             # Failing here with an exception is preferred as some openssl
1728             # versions do.
1729             pass
1730
1731
1732     def test_zero_len_list_for_ca(self):
1733         """
1734         A PKCS12 with an empty CA certificates list can be exported.
1735         """
1736         passwd = 'Hobie 18'
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,
1743             passwd=passwd)
1744
1745
1746     def test_export_without_args(self):
1747         """
1748         All the arguments to L{PKCS12.export} are optional.
1749         """
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='')
1754
1755
1756     def test_key_cert_mismatch(self):
1757         """
1758         L{PKCS12.export} raises an exception when a key and certificate
1759         mismatch.
1760         """
1761         p12 = self.gen_pkcs12(server_cert_pem, client_key_pem, root_cert_pem)
1762         self.assertRaises(Error, p12.export)
1763
1764
1765
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):
1770     """
1771     Internal method for quoting a single command-line argument.
1772
1773     @type: C{str}
1774     @param s: A single unquoted string to quote for something that is expecting
1775         cmd.exe-style quoting
1776
1777     @rtype: C{str}
1778     @return: A cmd.exe-style quoted string
1779
1780     @see: U{http://www.perlmonks.org/?node_id=764004}
1781     """
1782     s = _cmdLineQuoteRe2.sub(r"\1\1", _cmdLineQuoteRe.sub(r'\1\1\\"', s))
1783     return '"%s"' % s
1784
1785
1786
1787 def quoteArguments(arguments):
1788     """
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.
1792
1793     @type arguments: C{iterable} of C{str}
1794     @param arguments: An iterable of unquoted arguments to quote
1795
1796     @rtype: C{str}
1797     @return: A space-delimited string containing quoted versions of L{arguments}
1798     """
1799     return ' '.join(map(cmdLineQuote, arguments))
1800
1801
1802
1803 def _runopenssl(pem, *args):
1804     """
1805     Run the command line openssl tool with the given arguments and write
1806     the given PEM to its stdin.  Not safe for quotes.
1807     """
1808     if os.name == 'posix':
1809         command = "openssl " + " ".join([
1810                 "'%s'" % (arg.replace("'", "'\\''"),) for arg in args])
1811     else:
1812         command = "openssl " + quoteArguments(args)
1813     proc = Popen(command, shell=True, stdin=PIPE, stdout=PIPE)
1814     proc.stdin.write(pem)
1815     proc.stdin.close()
1816     return proc.stdout.read()
1817
1818
1819
1820 class FunctionTests(TestCase):
1821     """
1822     Tests for free-functions in the L{OpenSSL.crypto} module.
1823     """
1824
1825     def test_load_privatekey_invalid_format(self):
1826         """
1827         L{load_privatekey} raises L{ValueError} if passed an unknown filetype.
1828         """
1829         self.assertRaises(ValueError, load_privatekey, 100, root_key_pem)
1830
1831
1832     def test_load_privatekey_invalid_passphrase_type(self):
1833         """
1834         L{load_privatekey} raises L{TypeError} if passed a passphrase that is
1835         neither a c{str} nor a callable.
1836         """
1837         self.assertRaises(
1838             TypeError,
1839             load_privatekey,
1840             FILETYPE_PEM, encryptedPrivateKeyPEMPassphrase, object())
1841
1842
1843     def test_load_privatekey_wrong_args(self):
1844         """
1845         L{load_privatekey} raises L{TypeError} if called with the wrong number
1846         of arguments.
1847         """
1848         self.assertRaises(TypeError, load_privatekey)
1849
1850
1851     def test_load_privatekey_wrongPassphrase(self):
1852         """
1853         L{load_privatekey} raises L{OpenSSL.crypto.Error} when it is passed an
1854         encrypted PEM and an incorrect passphrase.
1855         """
1856         self.assertRaises(
1857             Error,
1858             load_privatekey, FILETYPE_PEM, encryptedPrivateKeyPEM, b("quack"))
1859
1860
1861     def test_load_privatekey_passphrase(self):
1862         """
1863         L{load_privatekey} can create a L{PKey} object from an encrypted PEM
1864         string if given the passphrase.
1865         """
1866         key = load_privatekey(
1867             FILETYPE_PEM, encryptedPrivateKeyPEM,
1868             encryptedPrivateKeyPEMPassphrase)
1869         self.assertTrue(isinstance(key, PKeyType))
1870
1871
1872     def test_load_privatekey_wrongPassphraseCallback(self):
1873         """
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
1876         passphrase.
1877         """
1878         called = []
1879         def cb(*a):
1880             called.append(None)
1881             return "quack"
1882         self.assertRaises(
1883             Error,
1884             load_privatekey, FILETYPE_PEM, encryptedPrivateKeyPEM, cb)
1885         self.assertTrue(called)
1886
1887
1888     def test_load_privatekey_passphraseCallback(self):
1889         """
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
1892         password.
1893         """
1894         called = []
1895         def cb(writing):
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])
1901
1902
1903     def test_load_privatekey_passphrase_exception(self):
1904         """
1905         An exception raised by the passphrase callback passed to
1906         L{load_privatekey} causes L{OpenSSL.crypto.Error} to be raised.
1907
1908         This isn't as nice as just letting the exception pass through.  The
1909         behavior might be changed to that eventually.
1910         """
1911         def broken(ignored):
1912             raise RuntimeError("This is not working.")
1913         self.assertRaises(
1914             Error,
1915             load_privatekey,
1916             FILETYPE_PEM, encryptedPrivateKeyPEM, broken)
1917
1918
1919     def test_dump_privatekey_wrong_args(self):
1920         """
1921         L{dump_privatekey} raises L{TypeError} if called with the wrong number
1922         of arguments.
1923         """
1924         self.assertRaises(TypeError, dump_privatekey)
1925
1926
1927     def test_dump_privatekey_unknown_cipher(self):
1928         """
1929         L{dump_privatekey} raises L{ValueError} if called with an unrecognized
1930         cipher name.
1931         """
1932         key = PKey()
1933         key.generate_key(TYPE_RSA, 512)
1934         self.assertRaises(
1935             ValueError, dump_privatekey,
1936             FILETYPE_PEM, key, "zippers", "passphrase")
1937
1938
1939     def test_dump_privatekey_invalid_passphrase_type(self):
1940         """
1941         L{dump_privatekey} raises L{TypeError} if called with a passphrase which
1942         is neither a C{str} nor a callable.
1943         """
1944         key = PKey()
1945         key.generate_key(TYPE_RSA, 512)
1946         self.assertRaises(
1947             TypeError,
1948             dump_privatekey, FILETYPE_PEM, key, "blowfish", object())
1949
1950
1951     def test_dump_privatekey_invalid_filetype(self):
1952         """
1953         L{dump_privatekey} raises L{ValueError} if called with an unrecognized
1954         filetype.
1955         """
1956         key = PKey()
1957         key.generate_key(TYPE_RSA, 512)
1958         self.assertRaises(ValueError, dump_privatekey, 100, key)
1959
1960
1961     def test_dump_privatekey_passphrase(self):
1962         """
1963         L{dump_privatekey} writes an encrypted PEM when given a passphrase.
1964         """
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())
1973
1974
1975     def test_dump_certificate(self):
1976         """
1977         L{dump_certificate} writes PEM, DER, and text.
1978         """
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)
1992
1993
1994     def test_dump_privatekey(self):
1995         """
1996         L{dump_privatekey} writes a PEM, DER, and text.
1997         """
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)
2011
2012
2013     def test_dump_certificate_request(self):
2014         """
2015         L{dump_certificate_request} writes a PEM, DER, and text.
2016         """
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)
2030
2031
2032     def test_dump_privatekey_passphraseCallback(self):
2033         """
2034         L{dump_privatekey} writes an encrypted PEM when given a callback which
2035         returns the correct passphrase.
2036         """
2037         passphrase = b("foo")
2038         called = []
2039         def cb(writing):
2040             called.append(writing)
2041             return passphrase
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())
2050
2051
2052     def test_load_pkcs7_data(self):
2053         """
2054         L{load_pkcs7_data} accepts a PKCS#7 string and returns an instance of
2055         L{PKCS7Type}.
2056         """
2057         pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2058         self.assertTrue(isinstance(pkcs7, PKCS7Type))
2059
2060
2061
2062 class PKCS7Tests(TestCase):
2063     """
2064     Tests for L{PKCS7Type}.
2065     """
2066     def test_type(self):
2067         """
2068         L{PKCS7Type} is a type object.
2069         """
2070         self.assertTrue(isinstance(PKCS7Type, type))
2071         self.assertEqual(PKCS7Type.__name__, 'PKCS7')
2072
2073         # XXX This doesn't currently work.
2074         # self.assertIdentical(PKCS7, PKCS7Type)
2075
2076
2077     # XXX Opposite results for all these following methods
2078
2079     def test_type_is_signed_wrong_args(self):
2080         """
2081         L{PKCS7Type.type_is_signed} raises L{TypeError} if called with any
2082         arguments.
2083         """
2084         pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2085         self.assertRaises(TypeError, pkcs7.type_is_signed, None)
2086
2087
2088     def test_type_is_signed(self):
2089         """
2090         L{PKCS7Type.type_is_signed} returns C{True} if the PKCS7 object is of
2091         the type I{signed}.
2092         """
2093         pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2094         self.assertTrue(pkcs7.type_is_signed())
2095
2096
2097     def test_type_is_enveloped_wrong_args(self):
2098         """
2099         L{PKCS7Type.type_is_enveloped} raises L{TypeError} if called with any
2100         arguments.
2101         """
2102         pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2103         self.assertRaises(TypeError, pkcs7.type_is_enveloped, None)
2104
2105
2106     def test_type_is_enveloped(self):
2107         """
2108         L{PKCS7Type.type_is_enveloped} returns C{False} if the PKCS7 object is
2109         not of the type I{enveloped}.
2110         """
2111         pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2112         self.assertFalse(pkcs7.type_is_enveloped())
2113
2114
2115     def test_type_is_signedAndEnveloped_wrong_args(self):
2116         """
2117         L{PKCS7Type.type_is_signedAndEnveloped} raises L{TypeError} if called
2118         with any arguments.
2119         """
2120         pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2121         self.assertRaises(TypeError, pkcs7.type_is_signedAndEnveloped, None)
2122
2123
2124     def test_type_is_signedAndEnveloped(self):
2125         """
2126         L{PKCS7Type.type_is_signedAndEnveloped} returns C{False} if the PKCS7
2127         object is not of the type I{signed and enveloped}.
2128         """
2129         pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2130         self.assertFalse(pkcs7.type_is_signedAndEnveloped())
2131
2132
2133     def test_type_is_data(self):
2134         """
2135         L{PKCS7Type.type_is_data} returns C{False} if the PKCS7 object is not of
2136         the type data.
2137         """
2138         pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2139         self.assertFalse(pkcs7.type_is_data())
2140
2141
2142     def test_type_is_data_wrong_args(self):
2143         """
2144         L{PKCS7Type.type_is_data} raises L{TypeError} if called with any
2145         arguments.
2146         """
2147         pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2148         self.assertRaises(TypeError, pkcs7.type_is_data, None)
2149
2150
2151     def test_get_type_name_wrong_args(self):
2152         """
2153         L{PKCS7Type.get_type_name} raises L{TypeError} if called with any
2154         arguments.
2155         """
2156         pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2157         self.assertRaises(TypeError, pkcs7.get_type_name, None)
2158
2159
2160     def test_get_type_name(self):
2161         """
2162         L{PKCS7Type.get_type_name} returns a C{str} giving the type name.
2163         """
2164         pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2165         self.assertEquals(pkcs7.get_type_name(), b('pkcs7-signedData'))
2166
2167
2168     def test_attribute(self):
2169         """
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.
2172         """
2173         pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
2174         self.assertRaises(AttributeError, getattr, pkcs7, "foo")
2175
2176
2177
2178 class NetscapeSPKITests(TestCase, _PKeyInteractionTestsMixin):
2179     """
2180     Tests for L{OpenSSL.crypto.NetscapeSPKI}.
2181     """
2182     def signable(self):
2183         """
2184         Return a new L{NetscapeSPKI} for use with signing tests.
2185         """
2186         return NetscapeSPKI()
2187
2188
2189     def test_type(self):
2190         """
2191         L{NetscapeSPKI} and L{NetscapeSPKIType} refer to the same type object
2192         and can be used to create instances of that type.
2193         """
2194         self.assertIdentical(NetscapeSPKI, NetscapeSPKIType)
2195         self.assertConsistentType(NetscapeSPKI, 'NetscapeSPKI')
2196
2197
2198     def test_construction(self):
2199         """
2200         L{NetscapeSPKI} returns an instance of L{NetscapeSPKIType}.
2201         """
2202         nspki = NetscapeSPKI()
2203         self.assertTrue(isinstance(nspki, NetscapeSPKIType))
2204
2205
2206     def test_invalid_attribute(self):
2207         """
2208         Accessing a non-existent attribute of a L{NetscapeSPKI} instance causes
2209         an L{AttributeError} to be raised.
2210         """
2211         nspki = NetscapeSPKI()
2212         self.assertRaises(AttributeError, lambda: nspki.foo)
2213
2214
2215     def test_b64_encode(self):
2216         """
2217         L{NetscapeSPKI.b64_encode} encodes the certificate to a base64 blob.
2218         """
2219         nspki = NetscapeSPKI()
2220         blob = nspki.b64_encode()
2221         self.assertTrue(isinstance(blob, bytes))
2222
2223
2224
2225 class RevokedTests(TestCase):
2226     """
2227     Tests for L{OpenSSL.crypto.Revoked}
2228     """
2229     def test_construction(self):
2230         """
2231         Confirm we can create L{OpenSSL.crypto.Revoked}.  Check
2232         that it is empty.
2233         """
2234         revoked = Revoked()
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)
2240
2241
2242     def test_construction_wrong_args(self):
2243         """
2244         Calling L{OpenSSL.crypto.Revoked} with any arguments results
2245         in a L{TypeError} being raised.
2246         """
2247         self.assertRaises(TypeError, Revoked, None)
2248         self.assertRaises(TypeError, Revoked, 1)
2249         self.assertRaises(TypeError, Revoked, "foo")
2250
2251
2252     def test_serial(self):
2253         """
2254         Confirm we can set and get serial numbers from
2255         L{OpenSSL.crypto.Revoked}.  Confirm errors are handled
2256         with grace.
2257         """
2258         revoked = Revoked()
2259         ret = revoked.set_serial(b('10b'))
2260         self.assertEquals(ret, None)
2261         ser = revoked.get_serial()
2262         self.assertEquals(ser, b('010B'))
2263
2264         revoked.set_serial(b('31ppp'))  # a type error would be nice
2265         ser = revoked.get_serial()
2266         self.assertEquals(ser, b('31'))
2267
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, "")
2273
2274
2275     def test_date(self):
2276         """
2277         Confirm we can set and get revocation dates from
2278         L{OpenSSL.crypto.Revoked}.  Confirm errors are handled
2279         with grace.
2280         """
2281         revoked = Revoked()
2282         date = revoked.get_rev_date()
2283         self.assertEquals(date, None)
2284
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)
2290
2291
2292     def test_reason(self):
2293         """
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.
2297         """
2298         revoked = Revoked()
2299         for r in revoked.all_reasons():
2300             for x in range(2):
2301                 ret = revoked.set_reason(r)
2302                 self.assertEquals(ret, None)
2303                 reason = revoked.get_reason()
2304                 self.assertEquals(
2305                     reason.lower().replace(b(' '), b('')),
2306                     r.lower().replace(b(' '), b('')))
2307                 r = reason # again with the resp of get
2308
2309         revoked.set_reason(None)
2310         self.assertEqual(revoked.get_reason(), None)
2311
2312
2313     def test_set_reason_wrong_arguments(self):
2314         """
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.
2318         """
2319         revoked = Revoked()
2320         self.assertRaises(TypeError, revoked.set_reason, 100)
2321         self.assertRaises(ValueError, revoked.set_reason, b('blue'))
2322
2323
2324     def test_get_reason_wrong_arguments(self):
2325         """
2326         Calling L{OpenSSL.crypto.Revoked.get_reason} with any
2327         arguments results in L{TypeError} being raised.
2328         """
2329         revoked = Revoked()
2330         self.assertRaises(TypeError, revoked.get_reason, None)
2331         self.assertRaises(TypeError, revoked.get_reason, 1)
2332         self.assertRaises(TypeError, revoked.get_reason, "foo")
2333
2334
2335
2336 class CRLTests(TestCase):
2337     """
2338     Tests for L{OpenSSL.crypto.CRL}
2339     """
2340     cert = load_certificate(FILETYPE_PEM, cleartextCertificatePEM)
2341     pkey = load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)
2342
2343     def test_construction(self):
2344         """
2345         Confirm we can create L{OpenSSL.crypto.CRL}.  Check
2346         that it is empty
2347         """
2348         crl = CRL()
2349         self.assertTrue( isinstance(crl, CRL) )
2350         self.assertEqual(crl.get_revoked(), None)
2351
2352
2353     def test_construction_wrong_args(self):
2354         """
2355         Calling L{OpenSSL.crypto.CRL} with any number of arguments
2356         results in a L{TypeError} being raised.
2357         """
2358         self.assertRaises(TypeError, CRL, 1)
2359         self.assertRaises(TypeError, CRL, "")
2360         self.assertRaises(TypeError, CRL, None)
2361
2362
2363     def test_export(self):
2364         """
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.
2368         """
2369         crl = CRL()
2370         revoked = Revoked()
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)
2376
2377         # PEM format
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'))
2383
2384         # DER format
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'))
2390
2391         # text format
2392         dumped_text = crl.export(self.cert, self.pkey, type=FILETYPE_TEXT)
2393         self.assertEqual(text, dumped_text)
2394
2395
2396     def test_add_revoked_keyword(self):
2397         """
2398         L{OpenSSL.CRL.add_revoked} accepts its single argument as the
2399         I{revoked} keyword argument.
2400         """
2401         crl = CRL()
2402         revoked = Revoked()
2403         crl.add_revoked(revoked=revoked)
2404         self.assertTrue(isinstance(crl.get_revoked()[0], Revoked))
2405
2406
2407     def test_export_wrong_args(self):
2408         """
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.
2413         """
2414         crl = CRL()
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")
2418
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)
2423
2424
2425     def test_export_unknown_filetype(self):
2426         """
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.
2430         """
2431         crl = CRL()
2432         self.assertRaises(ValueError, crl.export, self.cert, self.pkey, 100, 10)
2433
2434
2435     def test_get_revoked(self):
2436         """
2437         Use python to create a simple CRL with two revocations.
2438         Get back the L{Revoked} using L{OpenSSL.CRL.get_revoked} and
2439         verify them.
2440         """
2441         crl = CRL()
2442
2443         revoked = Revoked()
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)
2451
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)
2460
2461
2462     def test_get_revoked_wrong_args(self):
2463         """
2464         Calling L{OpenSSL.CRL.get_revoked} with any arguments results
2465         in a L{TypeError} being raised.
2466         """
2467         crl = CRL()
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)
2472
2473
2474     def test_add_revoked_wrong_args(self):
2475         """
2476         Calling L{OpenSSL.CRL.add_revoked} with other than one
2477         argument results in a L{TypeError} being raised.
2478         """
2479         crl = CRL()
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")
2483
2484
2485     def test_load_crl(self):
2486         """
2487         Load a known CRL and inspect its revocations.  Both
2488         PEM and DER formats are loaded.
2489         """
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'))
2497
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'))
2506
2507
2508     def test_load_crl_wrong_args(self):
2509         """
2510         Calling L{OpenSSL.crypto.load_crl} with other than two
2511         arguments results in a L{TypeError} being raised.
2512         """
2513         self.assertRaises(TypeError, load_crl)
2514         self.assertRaises(TypeError, load_crl, FILETYPE_PEM)
2515         self.assertRaises(TypeError, load_crl, FILETYPE_PEM, crlData, None)
2516
2517
2518     def test_load_crl_bad_filetype(self):
2519         """
2520         Calling L{OpenSSL.crypto.load_crl} with an unknown file type
2521         raises a L{ValueError}.
2522         """
2523         self.assertRaises(ValueError, load_crl, 100, crlData)
2524
2525
2526     def test_load_crl_bad_data(self):
2527         """
2528         Calling L{OpenSSL.crypto.load_crl} with file data which can't
2529         be loaded raises a L{OpenSSL.crypto.Error}.
2530         """
2531         self.assertRaises(Error, load_crl, FILETYPE_PEM, "hello, world")
2532
2533
2534 class SignVerifyTests(TestCase):
2535     """
2536     Tests for L{OpenSSL.crypto.sign} and L{OpenSSL.crypto.verify}.
2537     """
2538     def test_sign_verify(self):
2539         """
2540         L{sign} generates a cryptographic signature which L{verify} can check.
2541         """
2542         content = b(
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.")
2548
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)
2555
2556         for digest in ['md5', 'sha1']:
2557             sig = sign(priv_key, content, digest)
2558
2559             # Verify the signature of content, will throw an exception if error.
2560             verify(good_cert, sig, content, digest)
2561
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)
2565
2566             # This should fail because we've "tainted" the content after
2567             # signing it.
2568             self.assertRaises(
2569                 Error, verify,
2570                 good_cert, sig, content + b("tainted"), digest)
2571
2572         # test that unknown digest types fail
2573         self.assertRaises(
2574             ValueError, sign, priv_key, content, "strange-digest")
2575         self.assertRaises(
2576             ValueError, verify, good_cert, sig, content, "strange-digest")
2577
2578
2579 if __name__ == '__main__':
2580     main()