1 /*
2 * CVC EAC1.1 tests
3 *
4 * (C) 2008 Falko Strenzke (strenzke@flexsecure.de)
5 * 2008 Jack Lloyd
6 */
7
8 #include "validate.h"
9 #include <botan/build.h>
10
11 #if defined(BOTAN_HAS_CARD_VERIFIABLE_CERTIFICATES)
12
13 #include <iosfwd>
14 #include <iostream>
15 #include <iterator>
16 #include <algorithm>
17 #include <fstream>
18 #include <vector>
19 #include <memory>
20
21 #include <botan/ecdsa.h>
22 #include <botan/rsa.h>
23
24 #include <botan/x509cert.h>
25 #include <botan/x509self.h>
26 #include <botan/oids.h>
27 #include <botan/cvc_self.h>
28 #include <botan/cvc_cert.h>
29 #include <botan/cvc_ado.h>
30 #include <botan/time.h>
31
32 #define TEST_DATA_DIR "checks/ecc_testdata"
33
34 using namespace Botan;
35
36 #define CHECK_MESSAGE(expr, print) try { if(!(expr)) std::cout << print << "\n"; } catch(std::exception& e) { std::cout << __FUNCTION__ << ": " << e.what() << "\n"; }
37 #define CHECK(expr) try { if(!(expr)) std::cout << #expr << "\n"; } catch(std::exception& e) { std::cout << __FUNCTION__ << ": " << e.what() << "\n"; }
38
39 namespace {
40
41 // helper functions
helper_write_file(EAC_Signed_Object const & to_write,std::string const & file_path)42 void helper_write_file(EAC_Signed_Object const& to_write, std::string const& file_path)
43 {
44 SecureVector<byte> sv = to_write.BER_encode();
45 std::ofstream cert_file(file_path.c_str(), std::ios::binary);
46 cert_file.write((char*)&sv[0], sv.size());
47 cert_file.close();
48 }
49
helper_files_equal(std::string const & file_path1,std::string const & file_path2)50 bool helper_files_equal(std::string const& file_path1, std::string const& file_path2)
51 {
52 std::ifstream cert_1_in(file_path1.c_str());
53 std::ifstream cert_2_in(file_path2.c_str());
54 SecureVector<byte> sv1;
55 SecureVector<byte> sv2;
56 if (!cert_1_in || !cert_2_in)
57 {
58 return false;
59 }
60 while (!cert_1_in.eof())
61 {
62 char now;
63 cert_1_in.read(&now, 1);
64 sv1.push_back(now);
65 }
66 while (!cert_2_in.eof())
67 {
68 char now;
69 cert_2_in.read(&now, 1);
70 sv2.push_back(now);
71 }
72 if (sv1.size() == 0)
73 {
74 return false;
75 }
76 return sv1 == sv2;
77 }
78
test_enc_gen_selfsigned(RandomNumberGenerator & rng)79 void test_enc_gen_selfsigned(RandomNumberGenerator& rng)
80 {
81 std::cout << '.' << std::flush;
82
83 EAC1_1_CVC_Options opts;
84 //opts.cpi = 0;
85 opts.chr = ASN1_Chr("my_opt_chr"); // not used
86 opts.car = ASN1_Car("my_opt_car");
87 opts.cex = ASN1_Cex("2010 08 13");
88 opts.ced = ASN1_Ced("2010 07 27");
89 opts.holder_auth_templ = 0xC1;
90 opts.hash_alg = "SHA-256";
91
92 // creating a non sense selfsigned cert w/o dom pars
93 EC_Group dom_pars(OID("1.3.36.3.3.2.8.1.1.11"));
94 ECDSA_PrivateKey key(rng, dom_pars);
95 key.set_parameter_encoding(EC_DOMPAR_ENC_IMPLICITCA);
96 EAC1_1_CVC cert = CVC_EAC::create_self_signed_cert(key, opts, rng);
97
98 SecureVector<byte> der(cert.BER_encode());
99 std::ofstream cert_file;
100 cert_file.open(TEST_DATA_DIR "/my_cv_cert.ber", std::ios::binary);
101 //cert_file << der; // this is bad !!!
102 cert_file.write((char*)&der[0], der.size());
103 cert_file.close();
104
105 EAC1_1_CVC cert_in(TEST_DATA_DIR "/my_cv_cert.ber");
106 CHECK(cert == cert_in);
107 // encoding it again while it has no dp
108 SecureVector<byte> der2(cert_in.BER_encode());
109 std::ofstream cert_file2(TEST_DATA_DIR "/my_cv_cert2.ber", std::ios::binary);
110 cert_file2.write((char*)&der2[0], der2.size());
111 cert_file2.close();
112 // read both and compare them
113 std::ifstream cert_1_in(TEST_DATA_DIR "/my_cv_cert.ber");
114 std::ifstream cert_2_in(TEST_DATA_DIR "/my_cv_cert2.ber");
115 SecureVector<byte> sv1;
116 SecureVector<byte> sv2;
117 if (!cert_1_in || !cert_2_in)
118 {
119 CHECK_MESSAGE(false, "could not read certificate files");
120 }
121 while (!cert_1_in.eof())
122 {
123 char now;
124
125 cert_1_in.read(&now, 1);
126 sv1.push_back(now);
127 }
128 while (!cert_2_in.eof())
129 {
130 char now;
131 cert_2_in.read(&now, 1);
132 sv2.push_back(now);
133 }
134 CHECK(sv1.size() > 10);
135 CHECK_MESSAGE(sv1 == sv2, "reencoded file of cert without domain parameters is different from original");
136
137 //cout << "reading cert again\n";
138 CHECK(cert_in.get_car().value() == "my_opt_car");
139 CHECK(cert_in.get_chr().value() == "my_opt_car");
140 CHECK(cert_in.get_ced().as_string() == "20100727");
141 CHECK(cert_in.get_ced().readable_string() == "2010/07/27 ");
142
143 bool ill_date_exc = false;
144 try
145 {
146 ASN1_Ced("1999 01 01");
147 }
148 catch (...)
149 {
150 ill_date_exc = true;
151 }
152 CHECK(ill_date_exc);
153
154 bool ill_date_exc2 = false;
155 try
156 {
157 ASN1_Ced("2100 01 01");
158 }
159 catch (...)
160 {
161 ill_date_exc2 = true;
162 }
163 CHECK(ill_date_exc2);
164 //cout << "readable = '" << cert_in.get_ced().readable_string() << "'\n";
165 std::auto_ptr<Public_Key> p_pk(cert_in.subject_public_key());
166 //auto_ptr<ECDSA_PublicKey> ecdsa_pk(dynamic_cast<auto_ptr<ECDSA_PublicKey> >(p_pk));
167 ECDSA_PublicKey* p_ecdsa_pk = dynamic_cast<ECDSA_PublicKey*>(p_pk.get());
168 // let´s see if encoding is truely implicitca, because this is what the key should have
169 // been set to when decoding (see above)(because it has no domain params):
170 //cout << "encoding = " << p_ecdsa_pk->get_parameter_encoding() << std::endl;
171 CHECK(p_ecdsa_pk->domain_format() == EC_DOMPAR_ENC_IMPLICITCA);
172 bool exc = false;
173 try
174 {
175 std::cout << "order = " << p_ecdsa_pk->domain().get_order() << std::endl;
176 }
177 catch (Invalid_State)
178 {
179 exc = true;
180 }
181 CHECK(exc);
182 // set them and try again
183 //cert_in.set_domain_parameters(dom_pars);
184 std::auto_ptr<Public_Key> p_pk2(cert_in.subject_public_key());
185 ECDSA_PublicKey* p_ecdsa_pk2 = dynamic_cast<ECDSA_PublicKey*>(p_pk2.get());
186 //p_ecdsa_pk2->set_domain_parameters(dom_pars);
187 CHECK(p_ecdsa_pk2->domain().get_order() == dom_pars.get_order());
188 bool ver_ec = cert_in.check_signature(*p_pk2);
189 CHECK_MESSAGE(ver_ec, "could not positively verify correct selfsigned cvc certificate");
190 }
191
test_enc_gen_req(RandomNumberGenerator & rng)192 void test_enc_gen_req(RandomNumberGenerator& rng)
193 {
194 std::cout << "." << std::flush;
195
196 EAC1_1_CVC_Options opts;
197
198 //opts.cpi = 0;
199 opts.chr = ASN1_Chr("my_opt_chr");
200 opts.hash_alg = "SHA-160";
201
202 // creating a non sense selfsigned cert w/o dom pars
203 EC_Group dom_pars(OID("1.3.132.0.8"));
204 ECDSA_PrivateKey key(rng, dom_pars);
205 key.set_parameter_encoding(EC_DOMPAR_ENC_IMPLICITCA);
206 EAC1_1_Req req = CVC_EAC::create_cvc_req(key, opts.chr, opts.hash_alg, rng);
207 SecureVector<byte> der(req.BER_encode());
208 std::ofstream req_file(TEST_DATA_DIR "/my_cv_req.ber", std::ios::binary);
209 req_file.write((char*)&der[0], der.size());
210 req_file.close();
211
212 // read and check signature...
213 EAC1_1_Req req_in(TEST_DATA_DIR "/my_cv_req.ber");
214 //req_in.set_domain_parameters(dom_pars);
215 std::auto_ptr<Public_Key> p_pk(req_in.subject_public_key());
216 ECDSA_PublicKey* p_ecdsa_pk = dynamic_cast<ECDSA_PublicKey*>(p_pk.get());
217 //p_ecdsa_pk->set_domain_parameters(dom_pars);
218 CHECK(p_ecdsa_pk->domain().get_order() == dom_pars.get_order());
219 bool ver_ec = req_in.check_signature(*p_pk);
220 CHECK_MESSAGE(ver_ec, "could not positively verify correct selfsigned (created by myself) cvc request");
221 }
222
test_cvc_req_ext(RandomNumberGenerator &)223 void test_cvc_req_ext(RandomNumberGenerator&)
224 {
225 std::cout << "." << std::flush;
226
227 EAC1_1_Req req_in(TEST_DATA_DIR "/DE1_flen_chars_cvcRequest_ECDSA.der");
228 EC_Group dom_pars(OID("1.3.36.3.3.2.8.1.1.5")); // "german curve"
229 //req_in.set_domain_parameters(dom_pars);
230 std::auto_ptr<Public_Key> p_pk(req_in.subject_public_key());
231 ECDSA_PublicKey* p_ecdsa_pk = dynamic_cast<ECDSA_PublicKey*>(p_pk.get());
232 //p_ecdsa_pk->set_domain_parameters(dom_pars);
233 CHECK(p_ecdsa_pk->domain().get_order() == dom_pars.get_order());
234 bool ver_ec = req_in.check_signature(*p_pk);
235 CHECK_MESSAGE(ver_ec, "could not positively verify correct selfsigned (external testdata) cvc request");
236 }
237
test_cvc_ado_ext(RandomNumberGenerator &)238 void test_cvc_ado_ext(RandomNumberGenerator&)
239 {
240 std::cout << "." << std::flush;
241
242 EAC1_1_ADO req_in(TEST_DATA_DIR "/ado.cvcreq");
243 EC_Group dom_pars(OID("1.3.36.3.3.2.8.1.1.5")); // "german curve"
244 //cout << "car = " << req_in.get_car().value() << std::endl;
245 //req_in.set_domain_parameters(dom_pars);
246 }
247
test_cvc_ado_creation(RandomNumberGenerator & rng)248 void test_cvc_ado_creation(RandomNumberGenerator& rng)
249 {
250 std::cout << "." << std::flush;
251
252 EAC1_1_CVC_Options opts;
253 //opts.cpi = 0;
254 opts.chr = ASN1_Chr("my_opt_chr");
255 opts.hash_alg = "SHA-256";
256
257 // creating a non sense selfsigned cert w/o dom pars
258 EC_Group dom_pars(OID("1.3.36.3.3.2.8.1.1.11"));
259 //cout << "mod = " << hex << dom_pars.get_curve().get_p() << std::endl;
260 ECDSA_PrivateKey req_key(rng, dom_pars);
261 req_key.set_parameter_encoding(EC_DOMPAR_ENC_IMPLICITCA);
262 //EAC1_1_Req req = CVC_EAC::create_cvc_req(req_key, opts);
263 EAC1_1_Req req = CVC_EAC::create_cvc_req(req_key, opts.chr, opts.hash_alg, rng);
264 SecureVector<byte> der(req.BER_encode());
265 std::ofstream req_file(TEST_DATA_DIR "/my_cv_req.ber", std::ios::binary);
266 req_file.write((char*)&der[0], der.size());
267 req_file.close();
268
269 // create an ado with that req
270 ECDSA_PrivateKey ado_key(rng, dom_pars);
271 EAC1_1_CVC_Options ado_opts;
272 ado_opts.car = ASN1_Car("my_ado_car");
273 ado_opts.hash_alg = "SHA-256"; // must be equal to req´s hash alg, because ado takes his sig_algo from it´s request
274
275 //EAC1_1_ADO ado = CVC_EAC::create_ado_req(ado_key, req, ado_opts);
276 EAC1_1_ADO ado = CVC_EAC::create_ado_req(ado_key, req, ado_opts.car, rng);
277 CHECK_MESSAGE(ado.check_signature(ado_key), "failure of ado verification after creation");
278
279 std::ofstream ado_file(TEST_DATA_DIR "/ado", std::ios::binary);
280 SecureVector<byte> ado_der(ado.BER_encode());
281 ado_file.write((char*)&ado_der[0], ado_der.size());
282 ado_file.close();
283 // read it again and check the signature
284 EAC1_1_ADO ado2(TEST_DATA_DIR "/ado");
285 CHECK(ado == ado2);
286 //ECDSA_PublicKey* p_ado_pk = dynamic_cast<ECDSA_PublicKey*>(&ado_key);
287 //bool ver = ado2.check_signature(*p_ado_pk);
288 bool ver = ado2.check_signature(ado_key);
289 CHECK_MESSAGE(ver, "failure of ado verification after reloading");
290 }
291
test_cvc_ado_comparison(RandomNumberGenerator & rng)292 void test_cvc_ado_comparison(RandomNumberGenerator& rng)
293 {
294 std::cout << "." << std::flush;
295
296 EAC1_1_CVC_Options opts;
297 //opts.cpi = 0;
298 opts.chr = ASN1_Chr("my_opt_chr");
299 opts.hash_alg = "SHA-224";
300
301 // creating a non sense selfsigned cert w/o dom pars
302 EC_Group dom_pars(OID("1.3.36.3.3.2.8.1.1.11"));
303 ECDSA_PrivateKey req_key(rng, dom_pars);
304 req_key.set_parameter_encoding(EC_DOMPAR_ENC_IMPLICITCA);
305 //EAC1_1_Req req = CVC_EAC::create_cvc_req(req_key, opts);
306 EAC1_1_Req req = CVC_EAC::create_cvc_req(req_key, opts.chr, opts.hash_alg, rng);
307
308
309 // create an ado with that req
310 ECDSA_PrivateKey ado_key(rng, dom_pars);
311 EAC1_1_CVC_Options ado_opts;
312 ado_opts.car = ASN1_Car("my_ado_car1");
313 ado_opts.hash_alg = "SHA-224"; // must be equal to req's hash alg, because ado takes his sig_algo from it's request
314 //EAC1_1_ADO ado = CVC_EAC::create_ado_req(ado_key, req, ado_opts);
315 EAC1_1_ADO ado = CVC_EAC::create_ado_req(ado_key, req, ado_opts.car, rng);
316 CHECK_MESSAGE(ado.check_signature(ado_key), "failure of ado verification after creation");
317 // make a second one for comparison
318 EAC1_1_CVC_Options opts2;
319 //opts2.cpi = 0;
320 opts2.chr = ASN1_Chr("my_opt_chr");
321 opts2.hash_alg = "SHA-160"; // this is the only difference
322 ECDSA_PrivateKey req_key2(rng, dom_pars);
323 req_key.set_parameter_encoding(EC_DOMPAR_ENC_IMPLICITCA);
324 //EAC1_1_Req req2 = CVC_EAC::create_cvc_req(req_key2, opts2, rng);
325 EAC1_1_Req req2 = CVC_EAC::create_cvc_req(req_key2, opts2.chr, opts2.hash_alg, rng);
326 ECDSA_PrivateKey ado_key2(rng, dom_pars);
327 EAC1_1_CVC_Options ado_opts2;
328 ado_opts2.car = ASN1_Car("my_ado_car1");
329 ado_opts2.hash_alg = "SHA-160"; // must be equal to req's hash alg, because ado takes his sig_algo from it's request
330
331 EAC1_1_ADO ado2 = CVC_EAC::create_ado_req(ado_key2, req2, ado_opts2.car, rng);
332 CHECK_MESSAGE(ado2.check_signature(ado_key2), "failure of ado verification after creation");
333
334 CHECK_MESSAGE(ado != ado2, "ado's found to be equal where they are not");
335 // std::ofstream ado_file(TEST_DATA_DIR "/ado");
336 // SecureVector<byte> ado_der(ado.BER_encode());
337 // ado_file.write((char*)&ado_der[0], ado_der.size());
338 // ado_file.close();
339 // read it again and check the signature
340
341 // EAC1_1_ADO ado2(TEST_DATA_DIR "/ado");
342 // ECDSA_PublicKey* p_ado_pk = dynamic_cast<ECDSA_PublicKey*>(&ado_key);
343 // //bool ver = ado2.check_signature(*p_ado_pk);
344 // bool ver = ado2.check_signature(ado_key);
345 // CHECK_MESSAGE(ver, "failure of ado verification after reloading");
346 }
347
test_eac_time(RandomNumberGenerator &)348 void test_eac_time(RandomNumberGenerator&)
349 {
350 std::cout << "." << std::flush;
351
352 const u64bit current_time = system_time();
353 EAC_Time time(current_time);
354 // std::cout << "time as std::string = " << time.as_string() << std::endl;
355 EAC_Time sooner("", ASN1_Tag(99));
356 //X509_Time sooner("", ASN1_Tag(99));
357 sooner.set_to("2007 12 12");
358 // std::cout << "sooner as std::string = " << sooner.as_string() << std::endl;
359 EAC_Time later("2007 12 13");
360 //X509_Time later("2007 12 13");
361 // std::cout << "later as std::string = " << later.as_string() << std::endl;
362 CHECK(sooner <= later);
363 CHECK(sooner == sooner);
364
365 ASN1_Cex my_cex("2007 08 01");
366 my_cex.add_months(12);
367 CHECK(my_cex.get_year() == 2008);
368 CHECK_MESSAGE(my_cex.get_month() == 8, "shoult be 8, was " << my_cex.get_month());
369
370 my_cex.add_months(4);
371 CHECK(my_cex.get_year() == 2008);
372 CHECK(my_cex.get_month() == 12);
373
374 my_cex.add_months(4);
375 CHECK(my_cex.get_year() == 2009);
376 CHECK(my_cex.get_month() == 4);
377
378 my_cex.add_months(41);
379 CHECK(my_cex.get_year() == 2012);
380 CHECK(my_cex.get_month() == 9);
381
382
383
384 }
385
test_ver_cvca(RandomNumberGenerator &)386 void test_ver_cvca(RandomNumberGenerator&)
387 {
388 std::cout << "." << std::flush;
389
390 EAC1_1_CVC req_in(TEST_DATA_DIR "/cvca01.cv.crt");
391
392 //auto_ptr<ECDSA_PublicKey> ecdsa_pk(dynamic_cast<auto_ptr<ECDSA_PublicKey> >(p_pk));
393 //ECDSA_PublicKey* p_ecdsa_pk = dynamic_cast<ECDSA_PublicKey*>(p_pk.get());
394 bool exc = false;
395
396 std::auto_ptr<Public_Key> p_pk2(req_in.subject_public_key());
397 ECDSA_PublicKey* p_ecdsa_pk2 = dynamic_cast<ECDSA_PublicKey*>(p_pk2.get());
398 bool ver_ec = req_in.check_signature(*p_pk2);
399 CHECK_MESSAGE(ver_ec, "could not positively verify correct selfsigned cvca certificate");
400
401 try
402 {
403 p_ecdsa_pk2->domain().get_order();
404 }
405 catch (Invalid_State)
406 {
407 exc = true;
408 }
409 CHECK(!exc);
410 }
411
test_copy_and_assignment(RandomNumberGenerator &)412 void test_copy_and_assignment(RandomNumberGenerator&)
413 {
414 std::cout << "." << std::flush;
415
416 EAC1_1_CVC cert_in(TEST_DATA_DIR "/cvca01.cv.crt");
417 EAC1_1_CVC cert_cp(cert_in);
418 EAC1_1_CVC cert_ass = cert_in;
419 CHECK(cert_in == cert_cp);
420 CHECK(cert_in == cert_ass);
421
422 EAC1_1_ADO ado_in(TEST_DATA_DIR "/ado.cvcreq");
423 //EC_Group dom_pars(OID("1.3.36.3.3.2.8.1.1.5")); // "german curve"
424 EAC1_1_ADO ado_cp(ado_in);
425 EAC1_1_ADO ado_ass = ado_in;
426 CHECK(ado_in == ado_cp);
427 CHECK(ado_in == ado_ass);
428
429 EAC1_1_Req req_in(TEST_DATA_DIR "/DE1_flen_chars_cvcRequest_ECDSA.der");
430 //EC_Group dom_pars(OID("1.3.36.3.3.2.8.1.1.5")); // "german curve"
431 EAC1_1_Req req_cp(req_in);
432 EAC1_1_Req req_ass = req_in;
433 CHECK(req_in == req_cp);
434 CHECK(req_in == req_ass);
435 }
436
test_eac_str_illegal_values(RandomNumberGenerator &)437 void test_eac_str_illegal_values(RandomNumberGenerator&)
438 {
439 std::cout << "." << std::flush;
440
441 bool exc = false;
442 try
443 {
444 EAC1_1_CVC(TEST_DATA_DIR "/cvca_illegal_chars.cv.crt");
445
446 }
447 catch (Decoding_Error)
448 {
449 exc = true;
450 }
451 CHECK(exc);
452
453 bool exc2 = false;
454 try
455 {
456 EAC1_1_CVC(TEST_DATA_DIR "/cvca_illegal_chars2.cv.crt");
457
458 }
459 catch (Decoding_Error)
460 {
461 exc2 = true;
462 }
463 CHECK(exc2);
464 }
465
test_tmp_eac_str_enc(RandomNumberGenerator &)466 void test_tmp_eac_str_enc(RandomNumberGenerator&)
467 {
468 std::cout << "." << std::flush;
469
470 bool exc = false;
471 try
472 {
473 ASN1_Car("abc!+-µ\n");
474 }
475 catch (Invalid_Argument)
476 {
477 exc = true;
478 }
479 CHECK(exc);
480 // std::string val = car.iso_8859();
481 // std::cout << "car 8859 = " << val << std::endl;
482 // std::cout << hex <<(unsigned char)val[1] << std::endl;
483
484
485 }
486
test_cvc_chain(RandomNumberGenerator & rng)487 void test_cvc_chain(RandomNumberGenerator& rng)
488 {
489 std::cout << "." << std::flush;
490
491 EC_Group dom_pars(OID("1.3.36.3.3.2.8.1.1.5")); // "german curve"
492 ECDSA_PrivateKey cvca_privk(rng, dom_pars);
493 std::string hash("SHA-224");
494 ASN1_Car car("DECVCA00001");
495 EAC1_1_CVC cvca_cert = DE_EAC::create_cvca(cvca_privk, hash, car, true, true, 12, rng);
496 std::ofstream cvca_file(TEST_DATA_DIR "/cvc_chain_cvca.cer", std::ios::binary);
497 SecureVector<byte> cvca_sv = cvca_cert.BER_encode();
498 cvca_file.write((char*)&cvca_sv[0], cvca_sv.size());
499 cvca_file.close();
500
501 ECDSA_PrivateKey cvca_privk2(rng, dom_pars);
502 ASN1_Car car2("DECVCA00002");
503 EAC1_1_CVC cvca_cert2 = DE_EAC::create_cvca(cvca_privk2, hash, car2, true, true, 12, rng);
504 EAC1_1_CVC link12 = DE_EAC::link_cvca(cvca_cert, cvca_privk, cvca_cert2, rng);
505 SecureVector<byte> link12_sv = link12.BER_encode();
506 std::ofstream link12_file(TEST_DATA_DIR "/cvc_chain_link12.cer", std::ios::binary);
507 link12_file.write((char*)&link12_sv[0], link12_sv.size());
508 link12_file.close();
509
510 // verify the link
511 CHECK(link12.check_signature(cvca_privk));
512 EAC1_1_CVC link12_reloaded(TEST_DATA_DIR "/cvc_chain_link12.cer");
513 EAC1_1_CVC cvca1_reloaded(TEST_DATA_DIR "/cvc_chain_cvca.cer");
514 std::auto_ptr<Public_Key> cvca1_rel_pk(cvca1_reloaded.subject_public_key());
515 CHECK(link12_reloaded.check_signature(*cvca1_rel_pk));
516
517 // create first round dvca-req
518 ECDSA_PrivateKey dvca_priv_key(rng, dom_pars);
519 EAC1_1_Req dvca_req = DE_EAC::create_cvc_req(dvca_priv_key, ASN1_Chr("DEDVCAEPASS"), hash, rng);
520 std::ofstream dvca_file(TEST_DATA_DIR "/cvc_chain_dvca_req.cer", std::ios::binary);
521 SecureVector<byte> dvca_sv = dvca_req.BER_encode();
522 dvca_file.write((char*)&dvca_sv[0], dvca_sv.size());
523 dvca_file.close();
524
525 // sign the dvca_request
526 EAC1_1_CVC dvca_cert1 = DE_EAC::sign_request(cvca_cert, cvca_privk, dvca_req, 1, 5, true, 3, 1, rng);
527 CHECK(dvca_cert1.get_car().iso_8859() == "DECVCA00001");
528 CHECK(dvca_cert1.get_chr().iso_8859() == "DEDVCAEPASS00001");
529 helper_write_file(dvca_cert1, TEST_DATA_DIR "/cvc_chain_dvca_cert1.cer");
530
531 // make a second round dvca ado request
532 ECDSA_PrivateKey dvca_priv_key2(rng, dom_pars);
533 EAC1_1_Req dvca_req2 = DE_EAC::create_cvc_req(dvca_priv_key2, ASN1_Chr("DEDVCAEPASS"), hash, rng);
534 std::ofstream dvca_file2(TEST_DATA_DIR "/cvc_chain_dvca_req2.cer", std::ios::binary);
535 SecureVector<byte> dvca_sv2 = dvca_req2.BER_encode();
536 dvca_file2.write((char*)&dvca_sv2[0], dvca_sv2.size());
537 dvca_file2.close();
538 EAC1_1_ADO dvca_ado2 = CVC_EAC::create_ado_req(dvca_priv_key, dvca_req2,
539 ASN1_Car(dvca_cert1.get_chr().iso_8859()), rng);
540 helper_write_file(dvca_ado2, TEST_DATA_DIR "/cvc_chain_dvca_ado2.cer");
541
542 // verify the ado and sign the request too
543
544 std::auto_ptr<Public_Key> ap_pk(dvca_cert1.subject_public_key());
545 ECDSA_PublicKey* cert_pk = dynamic_cast<ECDSA_PublicKey*>(ap_pk.get());
546
547 //cert_pk->set_domain_parameters(dom_pars);
548 //std::cout << "dvca_cert.public_point.size() = " << ec::EC2OSP(cert_pk->get_public_point(), ec::PointGFp::COMPRESSED).size() << std::endl;
549 EAC1_1_CVC dvca_cert1_reread(TEST_DATA_DIR "/cvc_chain_cvca.cer");
550 CHECK(dvca_ado2.check_signature(*cert_pk));
551
552 CHECK(dvca_ado2.check_signature(dvca_priv_key)); // must also work
553
554 EAC1_1_Req dvca_req2b = dvca_ado2.get_request();
555 helper_write_file(dvca_req2b, TEST_DATA_DIR "/cvc_chain_dvca_req2b.cer");
556 CHECK(helper_files_equal(TEST_DATA_DIR "/cvc_chain_dvca_req2b.cer", TEST_DATA_DIR "/cvc_chain_dvca_req2.cer"));
557 EAC1_1_CVC dvca_cert2 = DE_EAC::sign_request(cvca_cert, cvca_privk, dvca_req2b, 2, 5, true, 3, 1, rng);
558 CHECK(dvca_cert2.get_car().iso_8859() == "DECVCA00001");
559 CHECK_MESSAGE(dvca_cert2.get_chr().iso_8859() == "DEDVCAEPASS00002",
560 "chr = " << dvca_cert2.get_chr().iso_8859());
561
562 // make a first round IS request
563 ECDSA_PrivateKey is_priv_key(rng, dom_pars);
564 EAC1_1_Req is_req = DE_EAC::create_cvc_req(is_priv_key, ASN1_Chr("DEIS"), hash, rng);
565 helper_write_file(is_req, TEST_DATA_DIR "/cvc_chain_is_req.cer");
566
567 // sign the IS request
568 //dvca_cert1.set_domain_parameters(dom_pars);
569 EAC1_1_CVC is_cert1 = DE_EAC::sign_request(dvca_cert1, dvca_priv_key, is_req, 1, 5, true, 3, 1, rng);
570 CHECK_MESSAGE(is_cert1.get_car().iso_8859() == "DEDVCAEPASS00001", "car = " << is_cert1.get_car().iso_8859());
571 CHECK(is_cert1.get_chr().iso_8859() == "DEIS00001");
572 helper_write_file(is_cert1, TEST_DATA_DIR "/cvc_chain_is_cert.cer");
573
574 // verify the signature of the certificate
575 CHECK(is_cert1.check_signature(dvca_priv_key));
576 }
577
578 }
579
do_cvc_tests(Botan::RandomNumberGenerator & rng)580 u32bit do_cvc_tests(Botan::RandomNumberGenerator& rng)
581 {
582 std::cout << "Testing CVC: " << std::flush;
583
584 test_enc_gen_selfsigned(rng);
585 test_enc_gen_req(rng);
586 test_cvc_req_ext(rng);
587 test_cvc_ado_ext(rng);
588 test_cvc_ado_creation(rng);
589 test_cvc_ado_comparison(rng);
590 test_eac_time(rng);
591 test_ver_cvca(rng);
592 test_copy_and_assignment(rng);
593 test_eac_str_illegal_values(rng);
594 test_tmp_eac_str_enc(rng);
595 test_cvc_chain(rng);
596 std::cout << std::endl;
597
598 return 0;
599 }
600 #else
do_cvc_tests(Botan::RandomNumberGenerator &)601 u32bit do_cvc_tests(Botan::RandomNumberGenerator&) { return 0; }
602 #endif
603