2 #include "wvfileutils.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
)
115 WVPASSEQ(t509
.get_subject(), dname
);
116 WVPASSEQ(t509
.get_issuer(), dname
);
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");
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.
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
);
147 rsa
.decode(WvRSAKey::RsaPEM
, rsakeytext
);
148 WVPASSEQ(WvX509::certreq(t509
.get_subject(), rsa
),
152 WvX509Mgr
t509(dName
, 1024);
153 basic_test(t509
, dName1
);
157 t509
.decode(WvX509::CertPEM
, signedcerttext
);
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...
170 t509
.decode(WvRSAKey::RsaPEM
, WvString::null
);
171 t509
.decode(WvX509::CertPEM
, "");
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")
183 t509
.decode(WvX509::CertPEM
, signedcerttext
);
184 t509
.decode(WvRSAKey::RsaPEM
, rsakeytext
);
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");
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
);
254 WvRSAKey
rsakey(DEFAULT_KEYLEN
);
255 t509
.decode(WvRSAKey::RsaHex
, rsakey
.encode(WvRSAKey::RsaHex
));
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
269 t509
.decode(WvX509Mgr::CertPEM
, carillon_cert
);
272 WVPASSEQ("CA Issuers - URI:http://www.carillon.ca/caops/medium-test-ca.crt",
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);
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
);
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);
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
);
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",
331 WvX509Mgr
cacert("CN=test.foo.com,DC=foo,DC=com", DEFAULT_KEYLEN
, true);
332 WvString certpem
= cacert
.signreq(certreq
);
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")
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);
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")
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
401 t509
.decode(WvX509Mgr::CertPEM
, carillon_cert
);
403 WVPASS(t509
.get_basic_constraints(is_ca
, pathlen
));
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
));
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
));
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",
431 WvX509Mgr
cacert("CN=test.foo.com, DC=foo, DC=com", DEFAULT_KEYLEN
, true);
432 WvString certpem
= cacert
.signreq(certreq
);
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
),
447 cert
.set_policy_mapping(list
);
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",
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
);
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
);
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);
504 cert1
.encode(mode
, buf
);
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
);
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());
527 fprintf(stderr
, "Write result: %s\n", f
.errstr().cstr());
531 if (mode
== WvX509::CertPEM
)
532 cert2
.decode(WvX509::CertFilePEM
, tmpfile
);
534 cert2
.decode(WvX509::CertFileDER
, 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");
564 cert2
.read_p12(p12fname
, "123");
565 WVPASS(cert2
.isok());
566 WVPASSEQ(cert1
.get_ski(), cert2
.get_ski());
569 cert3
.read_p12(p12fname
, "321");
570 WVFAIL(cert3
.isok());
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"
598 "-----END CERTIFICATE-----";
600 WVTEST_MAIN("get_fingerprint")
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");