Restore support for openssl 0.9.7 (Debian Sarge).
[wvstreams.git] / crypto / t / wvx509.t.cc
blob8de7c32d34e4a0ddd925f13cd929dc1ef010e47d
1 #include "wvfile.h"
2 #include "wvfileutils.h"
3 #include "wvrsa.h"
4 #include "wvtest.h"
5 #include "wvx509.h"
6 #include "wvx509mgr.h"
7 #include "wvautoconf.h"
9 // default keylen for where we're not using pre-existing certs
10 const static int DEFAULT_KEYLEN = 512;
12 // carillon cert: has a number of interesting characteristics (policy,
13 // aia information, ...) which we can test against
14 const static char carillon_cert[] =
15 "-----BEGIN CERTIFICATE-----\n"
16 "MIIFSzCCBDOgAwIBAgIBAzANBgkqhkiG9w0BAQUFADCBgDELMAkGA1UEBhMCQ0Ex\n"
17 "KzApBgNVBAoTIkNhcmlsbG9uIEluZm9ybWF0aW9uIFNlY3VyaXR5IEluYy4xHzAd\n"
18 "BgNVBAsTFkNlcnRpZmljYXRpb24gU2VydmljZXMxIzAhBgNVBAMTGlRlc3QgQ2Vy\n"
19 "dGlmaWNhdGUgQXV0aG9yaXR5MB4XDTA2MTIyNDIyMzgzNVoXDTA5MTIyMzIyMzgz\n"
20 "NVowgYIxCzAJBgNVBAYTAkNBMSswKQYDVQQKDCJDYXJpbGxvbiBJbmZvcm1hdGlv\n"
21 "biBTZWN1cml0eSBJbmMuMQ4wDAYDVQQLDAVVc2VyczEVMBMGA1UEAwwMVGVzdGlu\n"
22 "ZyBVc2VyMR8wHQYJKoZIhvcNAQkBFhB0ZXN0QGNhcmlsbG9uLmNhMIGfMA0GCSqG\n"
23 "SIb3DQEBAQUAA4GNADCBiQKBgQCwYnEgxl9uly9EeXg6N/SLzx6ZB5iU/REgB1bi\n"
24 "9u/4O7S7ebAh5VKO8JIo+0JaHW7pBFM0ywe3KvHwpvdsHvmRCQ4+Qze8itFuhDSS\n"
25 "TFJ7eP9bxiyroYIaRuS9G3xrM6jGdkw1IhmN2FDpWXBTWtfF/8Lor4p9TemGUARl\n"
26 "prfDjQIDAQABo4ICTjCCAkowCQYDVR0TBAIwADAOBgNVHQ8BAf8EBAMCB4AwUAYJ\n"
27 "YIZIAYb4QgENBEMWQURvIE5vdCB0cnVzdCAtIENlcnRpUGF0aCBjb21wbGlhbnQg\n"
28 "SUQgQ2VydCBmb3IgVEVTVCBwdXJwb3NlcyBvbmx5MB0GA1UdDgQWBBRI8EWCS88U\n"
29 "Hug1TLLei5iiJGJSXTAfBgNVHSMEGDAWgBQZ8G5V0iRoGnd6l8LUaI01I0M3+jAb\n"
30 "BgNVHREEFDASgRB0ZXN0QGNhcmlsbG9uLmNhMEsGCCsGAQUFBwEBBD8wPTA7Bggr\n"
31 "BgEFBQcwAoYvaHR0cDovL3d3dy5jYXJpbGxvbi5jYS9jYW9wcy9tZWRpdW0tdGVz\n"
32 "dC1jYS5jcnQwPQYDVR0fBDYwNDAyoDCgLoYsaHR0cDovL3d3dy5jYXJpbGxvbi5j\n"
33 "YS9jYW9wcy9tZWRpdW0tY3JsMS5jcmwwgfEGA1UdIASB6TCB5jBuBgsrBgEEAYHD\n"
34 "XgEBZTBfMF0GCCsGAQUFBwICMFEwKRoiQ2FyaWxsb24gSW5mb3JtYXRpb24gU2Vj\n"
35 "dXJpdHkgSW5jLjADAgEBGiRURVNUIG1lZGl1bSBzdyBwb2xpY3kgLSBkbyBub3Qg\n"
36 "dHJ1c3QwdAYLKwYBBAGBw14BAWYwZTBjBggrBgEFBQcCAjBXMCkaIkNhcmlsbG9u\n"
37 "IEluZm9ybWF0aW9uIFNlY3VyaXR5IEluYy4wAwIBARoqVEVTVCBtZWRpdW0gaGFy\n"
38 "ZHdhcmUgcG9saWN5IC0gZG8gbm90IHRydXN0MA0GCSqGSIb3DQEBBQUAA4IBAQAH\n"
39 "NnhF+cbDe2jCPZ8J36Vb9p7QBFhGHiPQKpWVgEISjfYDqyilDUMvqo1RshBnxdTt\n"
40 "cPMu1MxcQOOvU1f3jRCJPngzzZXW91zOZKQREPanekUcil7ZrY9MPgpIPqMgGw5h\n"
41 "rX5R/RyAG/vkfJXe5SMd4GeUOuPuDVCxM3y2cylT0TS5zaWSYNdmERDm5tp2fHlj\n"
42 "rqE1w9PZDeLz9ZhKfo/pcxCvE7RdS1Zhpi3KMUEtDXq9RN2D81mvo1TyzHvm84QB\n"
43 "R7Z/1y/HH8vZj7q//xJrJt/IqPuXcYUacaS520ouzPhXNRkMxl4VZ8fCGnbrqPig\n"
44 "0KUUwRu2l4LDN9drx+L5\n"
45 "-----END CERTIFICATE-----\n";
47 const static char rsakeytext[] =
48 "-----BEGIN RSA PRIVATE KEY-----\n"
49 "MIICXgIBAAKBgQDVQrw1PHhLm2qSGl24SAb4+mJb2jPW0UwsbodDG5Da0h405zUp\n"
50 "0U5yL7zKNQG6BYvuV5bCUeo6Q0uvd7D6eKE7VqzcVHVJfM2KvfKOI5eMiu76pz6V\n"
51 "XxnW53kEdw1ZiCnCQTK1JntJn41ZsWxY7mQ3PLBpcobNIdoyUDwXIOFwOQIDAQAB\n"
52 "AoGAVcyuqgB1KX4Sx0tCT4TzATLDZc8JMjEso2eoldA+XDtTGde3pOZn2DrqirP+\n"
53 "yNe4b6Dfr7iDMwOmLKdMFcl4nAmE8UnOQWFtW52SCWFGLdiSqD8hn0gbKoYvaGDu\n"
54 "vlqN/KvKen0AxiveYS6T24GFzHejr2RVcmT4m5UogNGFR90CQQD7VcPzfcPJZ3c1\n"
55 "jWiJvoUrzdLqYactRoKidm+O7AVjMU7xkXCPLGgXbzVoyuzx11z1D/nFUE615t/v\n"
56 "vkKVsnTDAkEA2TgOnSX6gSClZLUy7bWoSHQwcuj3Ogt2C0zA9p/sRgRaAuNCDWNC\n"
57 "OmkRAHjbOtJK0tChxoG0BYdyv9WIZ5bHUwJBANf+0xH06UezNY2+YzLNmyEUF8j5\n"
58 "93Q/fpEke6c2S0L94zxTo4pHvYU2O449pvgH/4lUG3FpHNvS+GzO8+Y2oYUCQQC8\n"
59 "Nf8rmOmqEvBcB0jegQUT6mDEYCk+yQl6FwInb0AZFtIrKGBmGzgaRkkuAInsOKQO\n"
60 "cCmMR3wFQmxh3ZI4N4PzAkEA4YbOing3yMDXxUFByZMKSX6oqwNePuVfK1IHmoUP\n"
61 "oZxEIiwTN7rE9kRV1OFDUwvGiqcegSxjf6SUgdpBC7Du9A==\n"
62 "-----END RSA PRIVATE KEY-----\n";
64 const static char x509certtext[] =
65 "-----BEGIN CERTIFICATE-----\n"
66 "MIICXDCCAcWgAwIBAgIEM7WjbjANBgkqhkiG9w0BAQUFADBBMRUwEwYDVQQDEwx0\n"
67 "ZXN0LmZvby5jb20xEzARBgoJkiaJk/IsZAEZEwNmb28xEzARBgoJkiaJk/IsZAEZ\n"
68 "EwNjb20wHhcNMDQwMzI2MjEwNTI5WhcNMTQwMzI0MjEwNTI5WjBBMRUwEwYDVQQD\n"
69 "Ewx0ZXN0LmZvby5jb20xEzARBgoJkiaJk/IsZAEZEwNmb28xEzARBgoJkiaJk/Is\n"
70 "ZAEZEwNjb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANVCvDU8eEubapIa\n"
71 "XbhIBvj6YlvaM9bRTCxuh0MbkNrSHjTnNSnRTnIvvMo1AboFi+5XlsJR6jpDS693\n"
72 "sPp4oTtWrNxUdUl8zYq98o4jl4yK7vqnPpVfGdbneQR3DVmIKcJBMrUme0mfjVmx\n"
73 "bFjuZDc8sGlyhs0h2jJQPBcg4XA5AgMBAAGjYTBfMBEGCWCGSAGG+EIBAQQEAwIG\n"
74 "QDAbBglghkgBhvhCAQwEDhYMdGVzdC5mb28uY29tMA4GA1UdDwEB/wQEAwICpDAd\n"
75 "BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDQYJKoZIhvcNAQEFBQADgYEA\n"
76 "D8WtaiTyx3DkHiJwC7EHVCOTqRctuS+3x1y0b2CO/3ijWASg+UDvGFKpAT4i6EF4\n"
77 "/e1aTgQEJ3a29XQEKamk5Py2AAb7acBbuKIUzEzcFx4QzzY+fdz1PgKz4DiUypZj\n"
78 "UFCAL0f74uuFTQ7ylt6F0m554LSniOHDOEzyBZZq/bk=\n"
79 "-----END CERTIFICATE-----\n";
81 const static char certreqtext[] =
82 "-----BEGIN CERTIFICATE REQUEST-----\n"
83 "MIIBazCB1QIBADAsMSowKAYKCZImiZPyLGQBGRMadGVzdC5mb28uY29tL0RDPWZv\n"
84 "by9EQz1jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANVCvDU8eEubapIa\n"
85 "XbhIBvj6YlvaM9bRTCxuh0MbkNrSHjTnNSnRTnIvvMo1AboFi+5XlsJR6jpDS693\n"
86 "sPp4oTtWrNxUdUl8zYq98o4jl4yK7vqnPpVfGdbneQR3DVmIKcJBMrUme0mfjVmx\n"
87 "bFjuZDc8sGlyhs0h2jJQPBcg4XA5AgMBAAGgADANBgkqhkiG9w0BAQUFAAOBgQA3\n"
88 "+zj1ZCRGOqCyWJFT0J6P+LJxn57My7GKkUihXQFo6xym98kKfYwc7HTIVq+clnYA\n"
89 "rqmoQu1THFu6mVRdM9zp2zmRBtsmOxKkhx89RtNDhKu75HQE8S5xGmCPyZhFA0eX\n"
90 "elfqYQM30sg+MeZVTccV0wCd9augzYa2qA8MExu7SQ==\n"
91 "-----END CERTIFICATE REQUEST-----\n";
93 const static char signedcerttext[] =
94 "-----BEGIN CERTIFICATE-----\n"
95 "MIICiDCCAfGgAwIBAgIBATANBgkqhkiG9w0BAQQFADAUMRIwEAYDVQQKEwlOSVRJ\n"
96 "LVRFU1QwHhcNMDQwMzMwMTgzOTM4WhcNMDUwMzMwMTgzOTM4WjBkMQswCQYDVQQG\n"
97 "EwJDQTEPMA0GA1UECBMGUXVlYmVjMREwDwYDVQQHEwhNb250cmVhbDESMBAGA1UE\n"
98 "ChMJVGVzdHkgT25lMR0wGwYDVQQDExRhcmlhMi53ZWF2ZXJuZXQubnVsbDCBnzAN\n"
99 "BgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAtQcmm+hJqHI+xy1vdpyaTiKPOk58TJSH\n"
100 "dtj1JTZLmM7ZIDFZKgVAQvX+Y3V8wnCsKnF4U0fW14T0uHEWHhPjrCq+XBgw2NJA\n"
101 "GnKXZDX9QXDHKqBj7ttF+gTXztkpdBYjY9eHFfsETWbm7jgqLx6nDo2MULmipXWr\n"
102 "FM19VkZgRjUCAwEAAaOBmTCBljAJBgNVHRMEAjAAMCwGCWCGSAGG+EIBDQQfFh1P\n"
103 "cGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUzpHzxgB4JiHt\n"
104 "/EbtqgfEbSpsThUwPAYDVR0jBDUwM4AUx1ECvcgeUvpwQJNQs2g3qq0CPzWhGKQW\n"
105 "MBQxEjAQBgNVBAoTCU5JVEktVEVTVIIBADANBgkqhkiG9w0BAQQFAAOBgQCLUpzC\n"
106 "nPlIYTDK7rq1Mh/Bqcw0RYamxUOCMsNmkMBovb37yfmo4k+HfhiHhiM6Ao6H5GIF\n"
107 "+p09tcn1Iotrek1IGrXsH7Hjkpzf8lkqwEjygIJ0iAWMqAI4AVoRx/5JrG+8ePPU\n"
108 "rKZf8WzBwn45ibb+xwtjdQXVro1l+K4UATTHLQ==\n"
109 "-----END CERTIFICATE-----\n";
112 static void basic_test(WvX509 &t509, WvStringParm dname)
114 WVPASS(t509.isok());
115 WVPASSEQ(t509.get_subject(), dname);
116 WVPASSEQ(t509.get_issuer(), dname);
120 WVTEST_MAIN("X509")
122 // Setup a new DN entry, like a server would set.
123 const WvString dName("cn=test.foo.com,dc=foo,dc=com");
124 const WvString dName1("/CN=test.foo.com/DC=foo/DC=com");
125 const WvString dName2("/C=CA/ST=Quebec/L=Montreal/O=Testy One/CN=aria2.weavernet.null/DC=webmaster@weavernet.null");
128 WvX509Mgr t509;
129 WVFAIL(t509.isok());
130 WVFAIL(t509.test());
133 // WIN32 people! If your unit tests are crashing here, you probably
134 // linked openssl with a different version of msvcr*.dll than the
135 // unit test. We pass a FILE* from one to the other here, and it
136 // won't work if there's a library mismatch.
138 WvX509Mgr t509;
139 t509.decode(WvRSAKey::RsaPEM, rsakeytext);
140 t509.decode(WvX509::CertPEM, x509certtext);
141 basic_test(t509, dName1);
142 WvString certencode = t509.encode(WvX509::CertPEM);
143 WVPASSEQ(certencode, x509certtext);
144 WvString rsaencode = t509.encode(WvRSAKey::RsaPEM);
145 WVPASSEQ(rsaencode, rsakeytext);
146 WvRSAKey rsa;
147 rsa.decode(WvRSAKey::RsaPEM, rsakeytext);
148 WVPASSEQ(WvX509::certreq(t509.get_subject(), rsa),
149 certreqtext);
152 WvX509Mgr t509(dName, 1024);
153 basic_test(t509, dName1);
156 WvX509 t509;
157 t509.decode(WvX509::CertPEM, signedcerttext);
158 WVPASS(t509.isok());
159 WVFAIL(t509.validate()); // this certificate has expired
160 WVPASSEQ(t509.get_subject(), "/C=CA/ST=Quebec/L=Montreal/O=Testy One/CN=aria2.weavernet.null");
161 WVPASSEQ(t509.get_issuer(), "/O=NITI-TEST");
162 WVPASSEQ(t509.get_ski(),
163 "CE:91:F3:C6:00:78:26:21:ED:FC:46:ED:AA:07:C4:6D:2A:6C:4E:15");
164 WVPASSEQ(t509.get_aki(),
165 "C7:51:02:BD:C8:1E:52:FA:70:40:93:50:B3:68:37:AA:AD:02:3F:35");
168 // Now we stress test it to make sure that it fails predictably...
169 WvX509Mgr t509;
170 t509.decode(WvRSAKey::RsaPEM, WvString::null);
171 t509.decode(WvX509::CertPEM, "");
172 WVFAIL(t509.test());
173 WVFAIL(t509.isok());
174 WVFAIL(t509.get_subject() == "/CN=test.foo.com/DC=foo/DC=com");
175 WVFAIL(t509.get_issuer() == "/CN=test.foo.com/DC=foo/DC=com");
180 WVTEST_MAIN("mismatched key / certificate")
182 WvX509Mgr t509;
183 t509.decode(WvX509::CertPEM, signedcerttext);
184 t509.decode(WvRSAKey::RsaPEM, rsakeytext);
185 WVFAIL(t509.isok());
186 WVFAIL(t509.test());
190 WVTEST_MAIN("Hexified encoding/decoding")
192 const char cert_hex[] ="3082030030820269a003020102020460ad1ad"
193 "5300d06092a864886f70d010105050030818e310b3009060355040613024341310"
194 "f300d060355040813065175656265633111300f060355040713084d6f6e7472656"
195 "16c31123010060355040a13095465737479204f6e65311d301b060355040313146"
196 "1726961322e7765617665726e65742e6e756c6c31283026060a0992268993f22c6"
197 "4011916187765626d6173746572407765617665726e65742e6e756c6c301e170d3"
198 "034303333313230343235315a170d3134303332393230343235315a30818e310b3"
199 "009060355040613024341310f300d060355040813065175656265633111300f060"
200 "355040713084d6f6e747265616c31123010060355040a13095465737479204f6e6"
201 "5311d301b0603550403131461726961322e7765617665726e65742e6e756c6c312"
202 "83026060a0992268993f22c64011916187765626d6173746572407765617665726"
203 "e65742e6e756c6c30819f300d06092a864886f70d010101050003818d003081890"
204 "2818100b507269be849a8723ec72d6f769c9a4e228f3a4e7c4c948776d8f525364"
205 "b98ced92031592a054042f5fe63757cc270ac2a71785347d6d784f4b871161e13e"
206 "3ac2abe5c1830d8d2401a72976435fd4170c72aa063eedb45fa04d7ced92974162"
207 "363d78715fb044d66e6ee382a2f1ea70e8d8c50b9a2a575ab14cd7d56466046350"
208 "203010001a3693067301106096086480186f842010104040302064030230609608"
209 "6480186f842010c0416161461726961322e7765617665726e65742e6e756c6c300"
210 "e0603551d0f0101ff0404030202a4301d0603551d250416301406082b060105050"
211 "7030106082b06010505070302300d06092a864886f70d010105050003818100b2b"
212 "fe7b80feec0bfe23250f5d9eb3d409364628c001fee50185eb755ffb863093fe23"
213 "973c939fdd03bc90b32eb697f1eb9b4a7a0134ee78a509992da0d803af22b5148a"
214 "76b197a54126be4a3d03897ed6cc98e77e65b797aee3f3b66c17afb4a2fd6dc498"
215 "cd86f4d7952cfde7d1e044a38373f80b9d1da51461267a83d967f24";
217 const char rsa_hex[] = "3082025e02010002818100b507269be849a872"
218 "3ec72d6f769c9a4e228f3a4e7c4c948776d8f525364b98ced92031592a054042f5"
219 "fe63757cc270ac2a71785347d6d784f4b871161e13e3ac2abe5c1830d8d2401a72"
220 "976435fd4170c72aa063eedb45fa04d7ced92974162363d78715fb044d66e6ee38"
221 "2a2f1ea70e8d8c50b9a2a575ab14cd7d5646604635020301000102818100b277a4"
222 "469c10d1f21f95f963240a6bcd9020a818ec4e0b3829a0e6bd92f3a0687c825264"
223 "571aea29999efbaabe1e6b3a3075c16c492cb338ae928f5a80b897005fdeca7966"
224 "14f58329552bfd117755fae42ba39aa3266bb2560377d5d747e31ddfd2ae1bbd9b"
225 "8979e8748d4d47573588a4140715fbc14ea373f2461517749641024100f0b0ddee"
226 "376d6e08c9dc0bce540e9b464bf23121241cf6dd69fd67c9e195c6dce0ddb47012"
227 "56761567a8c70fff3e12cc412e8cb74f120eb620d7d129624c359d024100c08acd"
228 "153fe5f801c81a85a62b63f50b9346ebe350a18c3aecd11379a17093f52fdea874"
229 "df97b22189dd4ca479723422c0a5b5124873e087f316cbf681d2fb79024100810c"
230 "33517fc25a56b7f4151861151bc78afca5bec1200e741459db85f03f5fca197e85"
231 "39f97b0600dffd2c0db5aa5065d724e02980698c1db66a4028d21d4e3902405e57"
232 "a48574f9c9bb95c0e91bb2c7179ac45f4bd5e5fc4229dd3fd4bb144f852fee74bb"
233 "360918db3f73bdeb7febc1f9a9cd9b644dc112864216ea64a634969c81024100e5"
234 "453ec9a3cdbe2fe17e86b32e998fe8713066ed254a60390f7898e4e536dea92af7"
235 "743d55a35fad75c14fe1e239251c471e133ca8e85ef3a1d3c5b6b288bfda";
237 const WvString dName2("/C=CA/ST=Quebec/L=Montreal/O=Testy One/CN=aria2.weavernet.null/DC=webmaster@weavernet.null");
239 WvX509Mgr t509;
240 t509.decode(WvX509Mgr::CertHex, cert_hex);
241 t509.decode(WvRSAKey::RsaHex, rsa_hex);
242 basic_test(t509, dName2);
244 WVPASSEQ(t509.get_serial(), "1621957333");
245 WVPASSEQ(t509.encode(WvX509Mgr::CertHex), cert_hex);
246 WVPASSEQ(t509.encode(WvRSAKey::RsaHex), rsa_hex);
250 WVTEST_MAIN("Replacing key failure")
252 WvX509Mgr t509("cn=test.foo.com,dc=foo,dc=com", DEFAULT_KEYLEN);
253 WVPASS(t509.test());
254 WvRSAKey rsakey(DEFAULT_KEYLEN);
255 t509.decode(WvRSAKey::RsaHex, rsakey.encode(WvRSAKey::RsaHex));
256 WVFAIL(t509.test());
260 WVTEST_MAIN("Get extensions memory corruption")
262 // this test validates a workaround for a bug
263 // in openssl 0.9.8 -- where getting certain attributes using
264 // ASN1_item_d2i could cause openssl to shuffle around
265 // const pointers, leading to weird memory behaviour on
266 // destroys
268 WvX509 t509;
269 t509.decode(WvX509Mgr::CertPEM, carillon_cert);
271 WVPASS(t509.isok());
272 WVPASSEQ("CA Issuers - URI:http://www.carillon.ca/caops/medium-test-ca.crt",
273 t509.get_aia());
277 WVTEST_MAIN("set_aia")
279 // yeah, the certificate generated doesn't make much sense here,
280 // but we're only testing that the extension works properly
282 WvX509Mgr x("cn=test.foo.com,dc=foo,dc=com", DEFAULT_KEYLEN, false);
283 WvStringList ca_in;
284 WvStringList ocsp_in;
285 ca_in.append("http://localhost/~wlach/testca.pem");
286 ca_in.append("http://localhost/~wlach/testca-alt.pem");
287 ocsp_in.append("http://localhost/~wlach/blah.ocsp");
288 ocsp_in.append("http://localhost/~wlach/blarg.ocsp");
290 x.set_aia(ca_in, ocsp_in);
291 WvStringList ca_out;
292 x.get_ca_urls(ca_out);
293 WvStringList ocsp_out;
294 x.get_ocsp(ocsp_out);
296 WVPASSEQ(ca_in.popstr(), ca_out.popstr());
297 WVPASSEQ(ca_in.popstr(), ca_out.popstr());
298 WVPASSEQ(ocsp_in.popstr(), ocsp_out.popstr());
299 WVPASSEQ(ocsp_in.popstr(), ocsp_out.popstr());
300 WVPASSEQ(ca_in.count(), 0);
301 WVPASSEQ(ca_out.count(), 0);
302 WVPASSEQ(ocsp_in.count(), 0);
303 WVPASSEQ(ocsp_out.count(), 0);
307 WVTEST_MAIN("set_crl_dp")
309 WvX509Mgr x("cn=test.foo.com,dc=foo,dc=com", DEFAULT_KEYLEN, false);
310 WvStringList dp_in;
311 dp_in.append("http://localhost/~wlach/testca.crl");
312 dp_in.append("http://localhost/~wlach/testca-alt.crl");
313 x.set_crl_urls(dp_in);
315 WvStringList dp_out;
316 x.get_crl_urls(dp_out);
318 WVPASSEQ(dp_in.popstr(), dp_out.popstr());
319 WVPASSEQ(dp_in.popstr(), dp_out.popstr());
320 WVPASSEQ(dp_in.count(), 0);
321 WVPASSEQ(dp_out.count(), 0);
325 WVTEST_MAIN("certreq / signreq / signcert")
327 // certificate request
328 WvRSAKey rsakey(DEFAULT_KEYLEN);
329 WvString certreq = WvX509Mgr::certreq("cn=test.signed.com,dc=signed,dc=com",
330 rsakey);
331 WvX509Mgr cacert("CN=test.foo.com,DC=foo,DC=com", DEFAULT_KEYLEN, true);
332 WvString certpem = cacert.signreq(certreq);
334 WvX509 cert;
335 cert.decode(WvX509Mgr::CertPEM, certpem);
337 // test that it initially checks out
338 WVPASS(cert.issuedbyca(cacert));
339 WVPASS(cert.signedbyca(cacert));
341 // change some stuff, verify that tests fail
342 WvStringList ca_in, ocsp_in;
343 ca_in.append("http://localhost/~wlach/testca.pem");
344 ca_in.append("http://localhost/~wlach/testca-alt.pem");
345 cert.set_aia(ca_in, ocsp_in);
346 WVPASS(cert.issuedbyca(cacert));
347 WVFAIL(cert.signedbyca(cacert));
349 // should pass again after re-signing
350 cacert.signcert(cert);
351 WVPASSEQ(cert.get_issuer(), cacert.get_subject());
352 WVPASS(cert.issuedbyca(cacert));
353 WVPASS(cert.signedbyca(cacert));
357 WVTEST_MAIN("certificate policies")
359 WvX509 t509;
360 t509.decode(WvX509Mgr::CertPEM, carillon_cert);
362 WvStringList policies;
363 WVPASS(t509.get_policies(policies));
364 WVPASSEQ(policies.popstr(), "1.3.6.1.4.1.25054.1.1.101");
365 WVPASSEQ(policies.popstr(), "1.3.6.1.4.1.25054.1.1.102");
366 WVPASSEQ(policies.count(), 0);
368 policies.zap();
369 WvX509Mgr cacert("CN=test.foo.com, DC=foo, DC=com", DEFAULT_KEYLEN, true);
370 WVFAIL(cacert.get_policies(policies));
371 WVPASSEQ(policies.count(), 0);
375 WVTEST_MAIN("certificate policies set and get")
377 WvX509Mgr x("cn=test.foo.com,dc=foo,dc=com", DEFAULT_KEYLEN, false);
378 WvStringList policies_in;
379 policies_in.append("1.2.3.4");
380 policies_in.append("1.2.3.5");
381 x.set_policies(policies_in);
383 WvStringList policies_out;
384 x.get_policies(policies_out);
386 WVPASSEQ(policies_in.popstr(), policies_out.popstr());
387 WVPASSEQ(policies_in.popstr(), policies_out.popstr());
388 WVPASSEQ(policies_in.count(), 0);
389 WVPASSEQ(policies_out.count(), 0);
393 WVTEST_MAIN("basic constraints")
395 bool is_ca;
396 int pathlen;
398 // the carillon cert is a user cert, so it should have no path length,
399 // and the ca bit of basicConstraints set to false
400 WvX509 t509;
401 t509.decode(WvX509Mgr::CertPEM, carillon_cert);
403 WVPASS(t509.get_basic_constraints(is_ca, pathlen));
404 WVFAIL(is_ca);
405 WVPASSEQ(pathlen, (-1)); // no path length restriction
407 // by default, a CA certificate we create should have the ca bit set to
408 // true, and no path length restriction.
409 WvX509Mgr cacert("CN=test.foo.com, DC=foo, DC=com", DEFAULT_KEYLEN, true);
410 WVPASS(cacert.get_basic_constraints(is_ca, pathlen));
411 WVPASS(is_ca);
412 WVPASSEQ(pathlen, (-1)); // no path length restriction
414 // now, let's try setting the path length, and see what the result is
415 cacert.set_basic_constraints(true, 5);
416 WVPASS(cacert.get_basic_constraints(is_ca, pathlen));
417 WVPASS(is_ca);
418 WVPASSEQ(pathlen, 5);
424 #ifdef HAVE_OPENSSL_POLICY_MAPPING
425 WVTEST_MAIN("get/set certificate policy extensions")
427 WvRSAKey rsakey(DEFAULT_KEYLEN);
429 WvString certreq = WvX509Mgr::certreq("cn=test.signed.com,dc=signed,dc=com",
430 rsakey);
431 WvX509Mgr cacert("CN=test.foo.com, DC=foo, DC=com", DEFAULT_KEYLEN, true);
432 WvString certpem = cacert.signreq(certreq);
434 WvX509Mgr cert;
435 cert.decode(WvX509Mgr::CertPEM, certpem);
437 int require_explicit_policy_in = 10;
438 int inhibit_policy_mapping_in = 5;
439 cert.set_policy_constraints(require_explicit_policy_in,
440 inhibit_policy_mapping_in);
442 WvString issuer_domain_in = "2.16.840.1.101.3.2.1.48.1";
443 WvString subject_domain_in = "2.16.840.1.101.3.2.1.48.2";
444 WvX509Mgr::PolicyMapList list;
445 list.append(new WvX509Mgr::PolicyMap(issuer_domain_in, subject_domain_in),
446 true);
447 cert.set_policy_mapping(list);
448 list.zap();
449 cacert.signcert(cert);
451 int require_explicit_policy_out = 0;
452 int inhibit_policy_mapping_out = 0;
453 cert.get_policy_constraints(require_explicit_policy_out,
454 inhibit_policy_mapping_out);
455 WVPASSEQ(require_explicit_policy_in, require_explicit_policy_out);
456 WVPASSEQ(inhibit_policy_mapping_in, inhibit_policy_mapping_out);
458 WVPASS(cert.get_policy_mapping(list));
459 WVPASSEQ(list.count(), 1);
460 if (list.count() > 0)
462 WvX509Mgr::PolicyMap *map = list.first();
463 WVPASSEQ(map->issuer_domain, issuer_domain_in);
464 WVPASSEQ(map->subject_domain, subject_domain_in);
469 WVTEST_MAIN("ski / aki")
471 WvRSAKey rsakey(DEFAULT_KEYLEN);
472 WvString certreq = WvX509Mgr::certreq("cn=test.signed.com,dc=signed,dc=com",
473 rsakey);
474 WvX509Mgr cacert("CN=test.foo.com, DC=foo, DC=com", DEFAULT_KEYLEN, true);
476 WvString certpem = cacert.signreq(certreq);
477 wvcon->print("\n%s\n", certpem);
478 WvX509Mgr cert;
479 cert.decode(WvX509Mgr::CertPEM, certpem);
480 WVPASS(!!cert.get_ski());
481 WVPASS(!!cert.get_aki());
482 WVPASS(!!cacert.get_ski());
483 WVFAIL(!!cacert.get_aki());
484 WVPASSEQ(cert.get_aki(), cacert.get_ski());
486 #endif // HAVE_OPENSSL_POLICY_MAPPING
488 bool test_encode_decode_str(WvX509::DumpMode mode)
490 WvX509Mgr cert1("cn=test.foo.com,dc=foo,dc=com", DEFAULT_KEYLEN, false);
491 WvString s = cert1.encode(mode);
492 WvX509Mgr cert2;
493 cert2.decode(mode, s);
495 WVPASSEQ(cert1.get_subject(), cert2.get_subject());
496 return cert1.get_subject() == cert2.get_subject();
500 bool test_encode_decode_buf(WvX509::DumpMode mode)
502 WvX509Mgr cert1("cn=test.foo.com,dc=foo,dc=com", DEFAULT_KEYLEN, false);
503 WvDynBuf buf;
504 cert1.encode(mode, buf);
505 WvX509Mgr cert2;
506 cert2.decode(mode, buf);
508 WVPASSEQ(cert1.get_subject(), cert2.get_subject());
509 return cert1.get_subject() == cert2.get_subject();
513 bool test_encode_load_file(WvX509::DumpMode mode)
515 WvString tmpfile = wvtmpfilename("cert");
517 WvX509Mgr cert1("cn=test.foo.com,dc=foo,dc=com", DEFAULT_KEYLEN, false);
519 WvFile f(tmpfile, O_WRONLY);
520 WvDynBuf buf;
521 cert1.encode(mode, buf);
522 fprintf(stderr, "Encode to file '%s' (%ld bytes)\n",
523 tmpfile.cstr(), (long)buf.used());
524 size_t used = buf.used(), len;
525 len = f.write(buf, buf.used());
526 WVPASSEQ(len, used);
527 fprintf(stderr, "Write result: %s\n", f.errstr().cstr());
530 WvX509Mgr cert2;
531 if (mode == WvX509::CertPEM)
532 cert2.decode(WvX509::CertFilePEM, tmpfile);
533 else
534 cert2.decode(WvX509::CertFileDER, tmpfile);
536 unlink(tmpfile);
538 WVPASSEQ(cert1.get_subject(), cert2.get_subject());
539 return cert1.get_subject() == cert2.get_subject();
543 WVTEST_MAIN("encode / decode / load")
545 WVPASS(test_encode_decode_str(WvX509::CertPEM));
546 WVPASS(test_encode_decode_str(WvX509::CertHex));
548 WVPASS(test_encode_decode_buf(WvX509::CertPEM));
549 WVPASS(test_encode_decode_buf(WvX509::CertHex));
550 WVPASS(test_encode_decode_buf(WvX509::CertDER));
552 WVPASS(test_encode_load_file(WvX509::CertPEM));
553 WVPASS(test_encode_load_file(WvX509::CertDER));
557 WVTEST_MAIN("pkcs12")
559 WvX509Mgr cert1("CN=test.foo.com, DC=foo, DC=com", DEFAULT_KEYLEN, true);
560 WvString p12fname = wvtmpfilename("p12");
561 cert1.write_p12(p12fname, "123");
563 WvX509Mgr cert2;
564 cert2.read_p12(p12fname, "123");
565 WVPASS(cert2.isok());
566 WVPASSEQ(cert1.get_ski(), cert2.get_ski());
568 WvX509Mgr cert3;
569 cert3.read_p12(p12fname, "321");
570 WVFAIL(cert3.isok());
572 ::unlink(p12fname);
576 const char random_cert[] = "-----BEGIN CERTIFICATE-----\n"
577 "MIIDvzCCAqegAwIBAgIEShc7yDANBgkqhkiG9w0BAQUFADBWMR0wGwYDVQQDExRj\n"
578 "b250aW5nZW5jeXdvcmtzLmNvbTEgMB4GCgmSJomT8ixkARkTEGNvbnRpbmdlbmN5\n"
579 "d29ya3MxEzARBgoJkiaJk/IsZAEZEwNjb20wHhcNMDgwNzMxMjAyMzE4WhcNMTgw\n"
580 "NzI5MjAyMzE4WjBWMR0wGwYDVQQDExRjb250aW5nZW5jeXdvcmtzLmNvbTEgMB4G\n"
581 "CgmSJomT8ixkARkTEGNvbnRpbmdlbmN5d29ya3MxEzARBgoJkiaJk/IsZAEZEwNj\n"
582 "b20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCrFneQgdQSoVfzCDNu\n"
583 "IAXhFpaCJvxDzWPCCZXWPf1/OlncskrRs4FirMnrPUyvw74krPh4lVILKZxIp+Io\n"
584 "s7DX8oPHct1ZjQoi7eK7r6iva38ghI3YFPtZSXC3z1DllKzUTezBzNJDkhg/SqUX\n"
585 "ne4NNw1mZ90Q07Y8KgREyjJ8/A0+jUNoQ3TydXPWsdNevP6jcczyULbzhlZrCj5J\n"
586 "7c21sSWkrm7HUegvJNPPv7vX67onYCMhj0f8Fsiw7TqacmmrJksrW3ifpCf5smIZ\n"
587 "/W8F9RwSefnVLn1TA2UoNAFTPDxwPVWFuOEkP8ObDnZXzfWc5WHRbXeVLnTAKbab\n"
588 "T6slAgMBAAGjgZQwgZEwHQYDVR0OBBYEFGryLpBlzbGgYCcpX/MbiAQj8nb8MBEG\n"
589 "CWCGSAGG+EIBAQQEAwIGQDAjBglghkgBhvhCAQwEFhYUY29udGluZ2VuY3l3b3Jr\n"
590 "cy5jb20wDgYDVR0PAQH/BAQDAgOoMAkGA1UdEwQCMAAwHQYDVR0lBBYwFAYIKwYB\n"
591 "BQUHAwEGCCsGAQUFBwMCMA0GCSqGSIb3DQEBBQUAA4IBAQBkWsSLHPmDajwg12AT\n"
592 "2QW3pxJKVu46nfdgLLTo6bQekAF+kYRERjbC9E/T5Eia5+6yTUbWR8xxDZoftkSK\n"
593 "/m3h7/Y+mqb13XiOowTkiJWzL5kwdv3Pb4O5X7YYMcNC4Rnax806b5pplXmzDY9Z\n"
594 "rqq/uP6wsRFiu5S7UcfA+KjoTrjMYsSLERAEus5RaP9J6uDvdBn0PwdfTT5rr2yb\n"
595 "et8AuJcBLFfFuLXPKfUlbnMe29BUr9s1A01OfHDCmzVN8hAhndBs2xDI1FOy9xDt\n"
596 "QXj9z/yvsK0AYwxknkHKqRboW//DVk6tcsL9dCiGSlZta5ob5yt6KK+R5X+rtQ0W\n"
597 "InR4\n"
598 "-----END CERTIFICATE-----";
600 WVTEST_MAIN("get_fingerprint")
602 WvX509 foo;
603 foo.decode(WvX509::CertPEM, random_cert);
605 WVPASSEQ(foo.get_fingerprint(WvX509::FingerSHA1),
606 "CA:49:50:D4:44:51:0B:AD:46:4F:E8:6C:3B:B2:3E:3F:61:31:27:ED");
607 WVPASSEQ(foo.get_fingerprint(WvX509::FingerMD5),
608 "53:FD:C7:D4:8F:45:AE:1D:90:14:45:B4:0C:1B:02:BD");