1 /** 2 * CVC EAC1.1 tests 3 * 4 * Copyright: 5 * (C) 2008 Falko Strenzke (strenzke@flexsecure.de) 6 * 2008 Jack Lloyd 7 * (C) 2014-2015 Etienne Cimon 8 * 9 * License: 10 * Botan is released under the Simplified BSD License (see LICENSE.md) 11 */ 12 module botan.cert.cvc.test; 13 14 import botan.constants; 15 static if (BOTAN_TEST && BOTAN_HAS_CARD_VERIFIABLE_CERTIFICATES): 16 17 import botan.test; 18 import botan.rng.auto_rng; 19 import botan.pubkey.algo.ecdsa; 20 import botan.pubkey.algo.rsa; 21 22 import botan.cert.x509.x509cert; 23 import botan.cert.x509.x509self; 24 import botan.asn1.oids; 25 import botan.cert.cvc.cvc_self; 26 import botan.cert.cvc.cvc_ado; 27 import botan.cert.cvc.cvc_cert; 28 import botan.cert.cvc.signed_obj; 29 import botan.utils.types; 30 import std.datetime; 31 32 33 // helper functions 34 void helperWriteFile(in EACSignedObject to_write, in string file_path) 35 { 36 Array!ubyte sv = to_write.BER_encode(); 37 File cert_file = File(file_path, "wb+"); 38 cert_file.write(sv.ptr[0 .. sv.length]); 39 } 40 41 42 bool helperFilesEqual(in string file_path1, in string file_path2) 43 { 44 File cert_1_in = File(file_path1, "r"); 45 File cert_2_in = File(file_path2, "r"); 46 Vector!ubyte sv1; 47 Vector!ubyte sv2; 48 if (!cert_1_in.ok || !cert_2_in.ok) 49 { 50 return false; 51 } 52 while (!cert_1_in.eof && !cert_1_in.error) 53 { 54 ubyte[16] now; 55 auto data = cert_1_in.rawRead(now.ptr[0 .. now.length]); 56 sv1.pushBack(data); 57 } 58 while (!cert_2_in.eof && !cert_2_in.error) 59 { 60 ubyte[16] now; 61 auto data = cert_2_in.rawRead(now.ptr[0 .. now.length]); 62 sv2.pushBack(data); 63 } 64 if (sv1.length == 0) 65 { 66 return false; 67 } 68 return sv1 == sv2; 69 } 70 71 void testEncGenSelfsigned(RandomNumberGenerator rng) 72 { 73 74 size_t fails; 75 size_t total_tests; 76 scope(exit) testReport("testEncGenSelfSigned", total_tests, fails); 77 78 EAC11CVCOptions opts; 79 //opts.cpi = 0; 80 opts.chr = ASN1Chr("my_opt_chr"); // not used 81 opts.car = ASN1Car("my_opt_car"); 82 opts.cex = ASN1Cex("2010 08 13"); 83 opts.ced = ASN1Ced("2010 07 27"); 84 opts.holder_auth_templ = 0xC1; 85 opts.hash_alg = "SHA-256"; 86 87 // creating a non sense selfsigned cert w/o dom pars 88 ECGroup dom_pars = ECGroup(OID("1.3.36.3.3.2.8.1.1.11")); 89 auto key = ECDSAPrivateKey(rng, dom_pars); 90 key.setParameterEncoding(EC_DOMPAR_ENC_IMPLICITCA); 91 EAC11CVC cert = createSelfSignedCert(key, opts, rng); 92 { 93 Array!ubyte der = cert.BER_encode(); 94 File cert_file = File("../test_data/ecc/my_cv_cert.ber", "wb+"); 95 //cert_file << der; // this is bad !!! 96 cert_file.write(cast(string) der.ptr[0 .. der.length]); 97 } 98 99 EAC11CVC cert_in = EAC11CVC("../test_data/ecc/my_cv_cert.ber"); 100 mixin( CHECK(` cert == cert_in `) ); 101 // encoding it again while it has no dp 102 { 103 Array!ubyte der2 = cert_in.BER_encode(); 104 File cert_file2 = File("../test_data/ecc/my_cv_cert2.ber", "wb+"); 105 cert_file2.write(der2.ptr[0 .. der2.length]); 106 } 107 // read both and compare them 108 { 109 File cert_1_in = File("../test_data/ecc/my_cv_cert.ber", "r"); 110 File cert_2_in = File("../test_data/ecc/my_cv_cert2.ber", "r"); 111 Vector!ubyte sv1; 112 Vector!ubyte sv2; 113 if (!cert_1_in.ok || !cert_2_in.ok) 114 { 115 mixin( CHECK_MESSAGE( `false`, "could not read certificate files" ) ); 116 } 117 while (!cert_1_in.eof && !cert_1_in.error) 118 { 119 ubyte[16] now; 120 auto data = cert_1_in.rawRead(now.ptr[0 .. now.length]); 121 sv1.pushBack(data); 122 } 123 while (!cert_2_in.eof && !cert_2_in.error) 124 { 125 ubyte[16] now; 126 auto data = cert_2_in.rawRead(now.ptr[0 .. now.length]); 127 sv2.pushBack(data); 128 } 129 mixin( CHECK(` sv1.length > 10 `) ); 130 mixin( CHECK_MESSAGE( `sv1 == sv2`, "reencoded file of cert without domain parameters is different from original" ) ); 131 } 132 //cout " ~reading cert again"); 133 mixin( CHECK(` cert_in.getCar().value() == "my_opt_car" `) ); 134 mixin( CHECK(` cert_in.getChr().value() == "my_opt_car" `) ); 135 mixin( CHECK(` cert_in.getCed().toString() == "20100727" `) ); 136 mixin( CHECK(` cert_in.getCed().readableString() == "2010/07/27 " `) ); 137 138 bool ill_date_exc = false; 139 try 140 { 141 ASN1Ced("1999 01 01"); 142 } 143 catch (Exception) 144 { 145 ill_date_exc = true; 146 } 147 mixin( CHECK(` ill_date_exc `) ); 148 149 bool ill_date_exc2 = false; 150 try 151 { 152 ASN1Ced("2100 01 01"); 153 } 154 catch (Exception) 155 { 156 ill_date_exc2 = true; 157 } 158 mixin( CHECK(` ill_date_exc2 `) ); 159 //cout " ~readable = '" ~ cert_in.getCed().readableString() " ~'"); 160 Unique!PublicKey p_pk = cert_in.subjectPublicKey(); 161 ECDSAPublicKey p_ecdsa_pk = cast(ECDSAPublicKey)(*p_pk); 162 163 // let´s see if encoding is truely implicitca, because this is what the key should have 164 // been set to when decoding (see above)(because it has no domain params): 165 166 mixin( CHECK(` p_ecdsa_pk.domainFormat() == EC_DOMPAR_ENC_IMPLICITCA `) ); 167 bool exc = false; 168 try 169 { 170 logTrace("order = ", p_ecdsa_pk.domain().getOrder().dup.toString()); 171 } 172 catch (InvalidState) 173 { 174 exc = true; 175 } 176 mixin( CHECK(` exc `) ); 177 // set them and try again 178 //cert_in -> setDomainParameters(dom_pars); 179 Unique!PublicKey p_pk2 = cert_in.subjectPublicKey(); 180 ECDSAPublicKey p_ecdsa_pk2 = cast(ECDSAPublicKey)(*p_pk2); 181 //p_ecdsa_pk2 -> setDomainParameters(dom_pars); 182 mixin( CHECK(` p_ecdsa_pk2.domain().getOrder() == dom_pars.getOrder() `) ); 183 bool ver_ec = cert_in.checkSignature(*p_pk2); 184 mixin( CHECK_MESSAGE( `ver_ec`, "could not positively verify correct selfsigned cvc certificate" ) ); 185 186 } 187 188 void testEncGenReq(RandomNumberGenerator rng) 189 { 190 191 size_t fails; 192 size_t total_tests; 193 scope(exit)testReport("testEncGenReq", total_tests, fails); 194 195 EAC11CVCOptions opts; 196 197 //opts.cpi = 0; 198 opts.chr = ASN1Chr("my_opt_chr"); 199 opts.hash_alg = "SHA-160"; 200 201 // creating a non sense selfsigned cert w/o dom pars 202 ECGroup dom_pars = ECGroup(OID("1.3.132.0.8")); 203 auto key = ECDSAPrivateKey(rng, dom_pars); 204 key.setParameterEncoding(EC_DOMPAR_ENC_IMPLICITCA); 205 EAC11Req req = createCvcReq(key, opts.chr, opts.hash_alg, rng); 206 { 207 Array!ubyte der = req.BER_encode(); 208 File req_file = File("../test_data/ecc/my_cv_req.ber", "wb+"); 209 req_file.write(der.ptr[0 .. der.length]); 210 } 211 212 // read and check signature... 213 EAC11Req req_in = EAC11Req("../test_data/ecc/my_cv_req.ber"); 214 //req_in.setDomainParameters(dom_pars); 215 Unique!PublicKey p_pk = req_in.subjectPublicKey(); 216 ECDSAPublicKey p_ecdsa_pk = cast(ECDSAPublicKey)(*p_pk); 217 //p_ecdsa_pk.setDomainParameters(dom_pars); 218 mixin( CHECK(` p_ecdsa_pk.domain().getOrder() == dom_pars.getOrder() `) ); 219 bool ver_ec = req_in.checkSignature(*p_pk); 220 mixin( CHECK_MESSAGE( `ver_ec`, "could not positively verify correct selfsigned (created by myself) cvc request" ) ); 221 } 222 223 void testCvcReqExt(RandomNumberGenerator) 224 { 225 size_t fails; 226 size_t total_tests; 227 scope(exit)testReport("testCvcReqExt", total_tests, fails); 228 EAC11Req req_in = EAC11Req("../test_data/ecc/DE1_flen_chars_cvcRequest_ECDSA.der"); 229 ECGroup dom_pars = ECGroup(OID("1.3.36.3.3.2.8.1.1.5")); // "german curve" 230 //req_in.setDomainParameters(dom_pars); 231 Unique!PublicKey p_pk = req_in.subjectPublicKey(); 232 ECDSAPublicKey p_ecdsa_pk = cast(ECDSAPublicKey)(*p_pk); 233 //p_ecdsa_pk.setDomainParameters(dom_pars); 234 mixin( CHECK(` p_ecdsa_pk.domain().getOrder() == dom_pars.getOrder() `) ); 235 bool ver_ec = req_in.checkSignature(*p_pk); 236 mixin( CHECK_MESSAGE( `ver_ec`, "could not positively verify correct selfsigned (external testdata) cvc request" ) ); 237 } 238 239 void testCvcAdoExt(RandomNumberGenerator) 240 { size_t fails; 241 size_t total_tests; 242 scope(exit)testReport("testCvcAdoExt", total_tests, fails); 243 EAC11ADO req_in = EAC11ADO("../test_data/ecc/ado.cvcreq"); 244 ECGroup dom_pars = ECGroup(OID("1.3.36.3.3.2.8.1.1.5")); // "german curve" 245 //cout " ~car = " ~ req_in.getCar().value()); 246 //req_in.setDomainParameters(dom_pars); 247 } 248 249 void testCvcAdoCreation(RandomNumberGenerator rng) 250 { 251 size_t fails; 252 size_t total_tests; 253 scope(exit)testReport("testCvcAdoCreation", total_tests, fails); 254 EAC11CVCOptions opts; 255 //opts.cpi = 0; 256 opts.chr = ASN1Chr("my_opt_chr"); 257 opts.hash_alg = "SHA-256"; 258 259 // creating a non sense selfsigned cert w/o dom pars 260 ECGroup dom_pars = ECGroup(OID("1.3.36.3.3.2.8.1.1.11")); 261 //cout " ~mod = " ~ hex << dom_pars.getCurve().getP()); 262 auto req_key = ECDSAPrivateKey(rng, dom_pars); 263 req_key.setParameterEncoding(EC_DOMPAR_ENC_IMPLICITCA); 264 //EAC11Req req = createCvcReq(req_key, opts); 265 EAC11Req req = createCvcReq(req_key, opts.chr, opts.hash_alg, rng); 266 { 267 Array!ubyte der = req.BER_encode(); 268 File req_file = File("../test_data/ecc/my_cv_req.ber", "wb+"); 269 req_file.write(der.ptr[0 .. der.length]); 270 } 271 272 // create an ado with that req 273 auto ado_key = ECDSAPrivateKey(rng, dom_pars); 274 EAC11CVCOptions ado_opts; 275 ado_opts.car = ASN1Car("my_ado_car"); 276 ado_opts.hash_alg = "SHA-256"; // must be equal to req´s hash alg, because ado takes his sig_algo from it´s request 277 278 //EAC11ADO ado = createAdoReq(ado_key, req, ado_opts); 279 EAC11ADO ado = createAdoReq(ado_key, req, ado_opts.car, rng); 280 mixin( CHECK_MESSAGE( `ado.checkSignature(ado_key)`, "failure of ado verification after creation" ) ); 281 282 { 283 File ado_file = File("../test_data/ecc/ado", "wb+"); 284 Array!ubyte ado_der = ado.BER_encode(); 285 ado_file.write(ado_der.ptr[0 .. ado_der.length]); 286 } 287 // read it again and check the signature 288 EAC11ADO ado2 = EAC11ADO("../test_data/ecc/ado"); 289 mixin( CHECK(` ado == ado2 `) ); 290 //ECDSAPublicKey p_ado_pk = cast(ECDSAPublicKey)(&ado_key); 291 //bool ver = ado2.checkSignature(*p_ado_pk); 292 bool ver = ado2.checkSignature(ado_key); 293 mixin( CHECK_MESSAGE( `ver`, "failure of ado verification after reloading" ) ); 294 } 295 296 void testCvcAdoComparison(RandomNumberGenerator rng) 297 { 298 size_t fails; 299 size_t total_tests; 300 scope(exit)testReport("testCvcAdoComparison", total_tests, fails); 301 EAC11CVCOptions opts; 302 //opts.cpi = 0; 303 opts.chr = ASN1Chr("my_opt_chr"); 304 opts.hash_alg = "SHA-224"; 305 306 // creating a non sense selfsigned cert w/o dom pars 307 ECGroup dom_pars = ECGroup(OID("1.3.36.3.3.2.8.1.1.11")); 308 auto req_key = ECDSAPrivateKey(rng, dom_pars); 309 req_key.setParameterEncoding(EC_DOMPAR_ENC_IMPLICITCA); 310 //EAC11Req req = createCvcReq(req_key, opts); 311 EAC11Req req = createCvcReq(req_key, opts.chr, opts.hash_alg, rng); 312 313 // create an ado with that req 314 auto ado_key = ECDSAPrivateKey(rng, dom_pars); 315 EAC11CVCOptions ado_opts; 316 ado_opts.car = ASN1Car("my_ado_car1"); 317 ado_opts.hash_alg = "SHA-224"; // must be equal to req's hash alg, because ado takes his sig_algo from it's request 318 //EAC11ADO ado = createAdoReq(ado_key, req, ado_opts); 319 EAC11ADO ado = createAdoReq(ado_key, req, ado_opts.car, rng); 320 mixin( CHECK_MESSAGE( `ado.checkSignature(ado_key)`, "failure of ado verification after creation" ) ); 321 // make a second one for comparison 322 EAC11CVCOptions opts2; 323 //opts2.cpi = 0; 324 opts2.chr = ASN1Chr("my_opt_chr"); 325 opts2.hash_alg = "SHA-160"; // this is the only difference 326 auto req_key2 = ECDSAPrivateKey(rng, dom_pars); 327 req_key.setParameterEncoding(EC_DOMPAR_ENC_IMPLICITCA); 328 //EAC11Req req2 = createCvcReq(req_key2, opts2, rng); 329 EAC11Req req2 = createCvcReq(req_key2, opts2.chr, opts2.hash_alg, rng); 330 auto ado_key2 = ECDSAPrivateKey(rng, dom_pars); 331 EAC11CVCOptions ado_opts2; 332 ado_opts2.car = ASN1Car("my_ado_car1"); 333 ado_opts2.hash_alg = "SHA-160"; // must be equal to req's hash alg, because ado takes his sig_algo from it's request 334 335 EAC11ADO ado2 = createAdoReq(ado_key2, req2, ado_opts2.car, rng); 336 mixin( CHECK_MESSAGE( `ado2.checkSignature(ado_key2)`, "failure of ado verification after creation" ) ); 337 338 mixin( CHECK_MESSAGE( `ado != ado2`, "ado s found to be equal where they are not" ) ); 339 // std::ofstream ado_file("../test_data/ecc/ado"); 340 // Vector!ubyte ado_der(ado.BER_encode()); 341 // ado_file.write((char*)ado_der.ptr, ado_der.length); 342 // ado_file.close(); 343 // read it again and check the signature 344 345 // EAC11ADO ado2("../test_data/ecc/ado"); 346 // ECDSAPublicKey p_ado_pk = cast(ECDSAPublicKey)(&ado_key); 347 // //bool ver = ado2.checkSignature(p_ado_pk); 348 // bool ver = ado2.checkSignature(ado_key); 349 // mixin( CHECK_MESSAGE( ver, "failure of ado verification after reloading" ) ); 350 } 351 352 void testEacTime(RandomNumberGenerator) 353 { 354 size_t fails; 355 size_t total_tests; 356 scope(exit)testReport("testEacTime", total_tests, fails); 357 EACTime time = EACTime(Clock.currTime(UTC())); 358 // logTrace("time as string = " ~ time.toString()); 359 EACTime sooner = EACTime("", (cast(ASN1Tag)99)); 360 //X509Time sooner("", (cast(ASN1Tag)99)); 361 sooner.setTo("2007 12 12"); 362 // logTrace("sooner as string = " ~ sooner.toString()); 363 EACTime later = EACTime("2007 12 13"); 364 //X509Time later("2007 12 13"); 365 // logTrace("later as string = " ~ later.toString()); 366 mixin( CHECK(` sooner <= later `) ); 367 mixin( CHECK(` sooner == sooner `) ); 368 369 ASN1Cex my_cex = ASN1Cex("2007 08 01"); 370 my_cex.addMonths(12); 371 mixin( CHECK(` my_cex.getYear() == 2008 `) ); 372 mixin( CHECK_MESSAGE( ` my_cex.getMonth() == 8 `, "shoult be 8, was `, my_cex.getMonth(), `" ) ); 373 374 my_cex.addMonths(4); 375 mixin( CHECK(` my_cex.getYear() == 2008 `) ); 376 mixin( CHECK(` my_cex.getMonth() == 12 `) ); 377 378 my_cex.addMonths(4); 379 mixin( CHECK(` my_cex.getYear() == 2009 `) ); 380 mixin( CHECK(` my_cex.getMonth() == 4 `) ); 381 382 my_cex.addMonths(41); 383 mixin( CHECK(` my_cex.getYear() == 2012 `) ); 384 mixin( CHECK(` my_cex.getMonth() == 9 `) ); 385 386 387 388 } 389 390 void testVerCvca(RandomNumberGenerator) 391 { 392 size_t fails; 393 size_t total_tests; 394 scope(exit)testReport("testVerCvca", total_tests, fails); 395 EAC11CVC req_in = EAC11CVC("../test_data/ecc/cvca01.cv.crt"); 396 397 bool exc = false; 398 399 Unique!PublicKey p_pk2 = req_in.subjectPublicKey(); 400 ECDSAPublicKey p_ecdsa_pk2 = cast(ECDSAPublicKey)(*p_pk2); 401 bool ver_ec = req_in.checkSignature(*p_pk2); 402 mixin( CHECK_MESSAGE( `ver_ec`, "could not positively verify correct selfsigned cvca certificate" ) ); 403 404 try 405 { 406 p_ecdsa_pk2.domain().getOrder(); 407 } 408 catch (InvalidState) 409 { 410 exc = true; 411 } 412 mixin( CHECK(` !exc `) ); 413 } 414 415 void testCopyAndAssignment(RandomNumberGenerator) 416 { 417 size_t fails; 418 size_t total_tests; 419 scope(exit)testReport("testCopyAndAssignment", total_tests, fails); 420 EAC11CVC cert_in = EAC11CVC("../test_data/ecc/cvca01.cv.crt"); 421 EAC11CVC cert_cp = EAC11CVC(cert_in); 422 EAC11CVC cert_ass = cert_in; 423 mixin( CHECK(` cert_in == cert_cp `) ); 424 mixin( CHECK(` cert_in == cert_ass `) ); 425 426 EAC11ADO ado_in = EAC11ADO("../test_data/ecc/ado.cvcreq"); 427 //ECGroup dom_pars = ECGroup(OID("1.3.36.3.3.2.8.1.1.5")); // "german curve" 428 EAC11ADO ado_cp = EAC11ADO(ado_in); 429 EAC11ADO ado_ass = ado_in; 430 mixin( CHECK(` ado_in == ado_cp `) ); 431 mixin( CHECK(` ado_in == ado_ass `) ); 432 433 EAC11Req req_in = EAC11Req("../test_data/ecc/DE1_flen_chars_cvcRequest_ECDSA.der"); 434 //ECGroup dom_pars = ECGroup(OID("1.3.36.3.3.2.8.1.1.5")); // "german curve" 435 EAC11Req req_cp = EAC11Req(req_in); 436 EAC11Req req_ass = req_in; 437 mixin( CHECK(` req_in == req_cp `) ); 438 mixin( CHECK(` req_in == req_ass `) ); 439 } 440 441 void testEacStrIllegalValues(RandomNumberGenerator) 442 { 443 size_t fails; 444 size_t total_tests; 445 scope(exit)testReport("testCopyAndAssignment", total_tests, fails); 446 bool exc = false; 447 try 448 { 449 EAC11CVC("../test_data/ecc/cvca_illegal_chars.cv.crt"); 450 451 } 452 catch (DecodingError) 453 { 454 exc = true; 455 } 456 mixin( CHECK(` exc `) ); 457 458 bool exc2 = false; 459 try 460 { 461 EAC11CVC("../test_data/ecc/cvca_illegal_chars2.cv.crt"); 462 463 } 464 catch (DecodingError) 465 { 466 exc2 = true; 467 } 468 mixin( CHECK(` exc2 `) ); 469 } 470 471 void testTmpEacStrEnc(RandomNumberGenerator) 472 { 473 size_t fails; 474 size_t total_tests; 475 scope(exit)testReport("testTmpEacStrEnc", total_tests, fails); 476 bool exc = false; 477 try 478 { 479 ASN1Car("abc!+-µ\n"); 480 } 481 catch (InvalidArgument) 482 { 483 exc = true; 484 } 485 mixin( CHECK(` exc `) ); 486 // string val = car.iso8859(); 487 // logTrace("car 8859 = " ~ val); 488 // logTrace(hex <<(unsigned char)val[1]); 489 } 490 491 void testCvcChain(RandomNumberGenerator rng) 492 { 493 size_t fails; 494 size_t total_tests; 495 scope(exit)testReport("testCvcChain", total_tests, fails); 496 ECGroup dom_pars = ECGroup(OID("1.3.36.3.3.2.8.1.1.5")); // "german curve" 497 auto cvca_privk = ECDSAPrivateKey(rng, dom_pars); 498 string hash = "SHA-224"; 499 ASN1Car car = ASN1Car("DECVCA00001"); 500 EAC11CVC cvca_cert = cvc_self.createCvca(cvca_privk, hash, car, true, true, 12, rng); 501 { 502 File cvca_file = File("../test_data/ecc/cvc_chain_cvca.cer","wb+"); 503 Array!ubyte cvca_sv = cvca_cert.BER_encode(); 504 cvca_file.write(cast(string) cvca_sv.ptr[0 .. cvca_sv.length]); 505 } 506 507 auto cvca_privk2 = ECDSAPrivateKey(rng, dom_pars); 508 ASN1Car car2 = ASN1Car("DECVCA00002"); 509 EAC11CVC cvca_cert2 = cvc_self.createCvca(cvca_privk2, hash, car2, true, true, 12, rng); 510 EAC11CVC link12 = cvc_self.linkCvca(cvca_cert, cvca_privk, cvca_cert2, rng); 511 { 512 Array!ubyte link12_sv = link12.BER_encode(); 513 File link12_file = File("../test_data/ecc/cvc_chain_link12.cer", "wb+"); 514 link12_file.write(link12_sv.ptr[0 .. link12_sv.length]); 515 } 516 517 // verify the link 518 mixin( CHECK(` link12.checkSignature(cvca_privk) `) ); 519 EAC11CVC link12_reloaded = EAC11CVC("../test_data/ecc/cvc_chain_link12.cer"); 520 EAC11CVC cvca1_reloaded = EAC11CVC("../test_data/ecc/cvc_chain_cvca.cer"); 521 Unique!PublicKey cvca1_rel_pk = cvca1_reloaded.subjectPublicKey(); 522 mixin( CHECK(` link12_reloaded.checkSignature(*cvca1_rel_pk) `) ); 523 524 // create first round dvca-req 525 auto dvca_priv_key = ECDSAPrivateKey(rng, dom_pars); 526 EAC11Req dvca_req = cvc_self.createCvcReq(dvca_priv_key, ASN1Chr("DEDVCAEPASS"), hash, rng); 527 { 528 File dvca_file = File("../test_data/ecc/cvc_chain_dvca_req.cer", "wb+"); 529 Array!ubyte dvca_sv = dvca_req.BER_encode(); 530 dvca_file.write(dvca_sv.ptr[0 .. dvca_sv.length]); 531 } 532 533 // sign the dvca_request 534 EAC11CVC dvca_cert1 = cvc_self.signRequest(cvca_cert, cvca_privk, dvca_req, 1, 5, true, 3, 1, rng); 535 mixin( CHECK(` dvca_cert1.getCar().iso8859() == "DECVCA00001" `) ); 536 mixin( CHECK(` dvca_cert1.getChr().iso8859() == "DEDVCAEPASS00001" `) ); 537 helperWriteFile(dvca_cert1, "../test_data/ecc/cvc_chain_dvca_cert1.cer"); 538 539 // make a second round dvca ado request 540 auto dvca_priv_key2 = ECDSAPrivateKey(rng, dom_pars); 541 EAC11Req dvca_req2 = cvc_self.createCvcReq(dvca_priv_key2, ASN1Chr("DEDVCAEPASS"), hash, rng); 542 { 543 File dvca_file2 = File("../test_data/ecc/cvc_chain_dvca_req2.cer", "wb+"); 544 Array!ubyte dvca_sv2 = dvca_req2.BER_encode(); 545 dvca_file2.write(dvca_sv2.ptr[0 .. dvca_sv2.length]); 546 } 547 548 EAC11ADO dvca_ado2 = createAdoReq(dvca_priv_key, dvca_req2, ASN1Car(dvca_cert1.getChr().iso8859()), rng); 549 helperWriteFile(dvca_ado2, "../test_data/ecc/cvc_chain_dvca_ado2.cer"); 550 551 // verify the ado and sign the request too 552 553 Unique!PublicKey ap_pk = dvca_cert1.subjectPublicKey(); 554 ECDSAPublicKey cert_pk = cast(ECDSAPublicKey)(*ap_pk); 555 556 //cert_pk.setDomainParameters(dom_pars); 557 //logTrace("dvca_cert.public_point.length = " ~ ec::EC2OSP(cert_pk.get_publicPoint(), ec::PointGFp.COMPRESSED).length); 558 EAC11CVC dvca_cert1_reread = EAC11CVC("../test_data/ecc/cvc_chain_cvca.cer"); 559 mixin( CHECK(` dvca_ado2.checkSignature(cert_pk) `) ); 560 561 mixin( CHECK(` dvca_ado2.checkSignature(dvca_priv_key) `) ); // must also work 562 563 EAC11Req dvca_req2b = EAC11Req(dvca_ado2.getRequest()); 564 helperWriteFile(dvca_req2b, "../test_data/ecc/cvc_chain_dvca_req2b.cer"); 565 mixin( CHECK(` helperFilesEqual("../test_data/ecc/cvc_chain_dvca_req2b.cer", "../test_data/ecc/cvc_chain_dvca_req2.cer") `) ); 566 EAC11CVC dvca_cert2 = cvc_self.signRequest(cvca_cert, cvca_privk, dvca_req2b, 2, 5, true, 3, 1, rng); 567 mixin( CHECK(` dvca_cert2.getCar().iso8859() == "DECVCA00001" `) ); 568 CHECK_MESSAGE(`dvca_cert2.getChr().iso8859() == "DEDVCAEPASS00002"`, "chr = ` ~ dvca_cert2.getChr().iso8859() ~ `"); 569 570 // make a first round IS request 571 auto is_priv_key = ECDSAPrivateKey(rng, dom_pars); 572 EAC11Req is_req = cvc_self.createCvcReq(is_priv_key, ASN1Chr("DEIS"), hash, rng); 573 helperWriteFile(is_req, "../test_data/ecc/cvc_chain_is_req.cer"); 574 575 // sign the IS request 576 //dvca_cert1.setDomainParameters(dom_pars); 577 EAC11CVC is_cert1 = cvc_self.signRequest(dvca_cert1, dvca_priv_key, is_req, 1, 5, true, 3, 1, rng); 578 mixin( CHECK_MESSAGE( `is_cert1.getCar().iso8859() == "DEDVCAEPASS00001"`, "car = ` ~ is_cert1.getCar().iso8859() ~ `" ) ); 579 mixin( CHECK(` is_cert1.getChr().iso8859() == "DEIS00001" `) ); 580 helperWriteFile(is_cert1, "../test_data/ecc/cvc_chain_is_cert.cer"); 581 582 // verify the signature of the certificate 583 mixin( CHECK(` is_cert1.checkSignature(dvca_priv_key) `) ); 584 } 585 586 static if (BOTAN_HAS_TESTS && !SKIP_CVC_TEST) unittest 587 { 588 589 logDebug("Testing cvc/test.d ..."); 590 Unique!AutoSeededRNG rng = new AutoSeededRNG; 591 592 logTrace("testEncGenSelfsigned"); 593 testEncGenSelfsigned(*rng); 594 logTrace("testEncGenReq"); 595 testEncGenReq(*rng); 596 logTrace("testCvcReqExt"); 597 testCvcReqExt(*rng); 598 logTrace("testCvcAdoExt"); 599 testCvcAdoExt(*rng); 600 logTrace("testCvcAdoCreation"); 601 testCvcAdoCreation(*rng); 602 logTrace("testCvcAdoComparison"); 603 testCvcAdoComparison(*rng); 604 logTrace("testEacTime"); 605 testEacTime(*rng); 606 logTrace("testVerCvca"); 607 testVerCvca(*rng); 608 logTrace("testCopyAndAssignment"); 609 testCopyAndAssignment(*rng); 610 logTrace("testEacStrIllegalValues"); 611 testEacStrIllegalValues(*rng); 612 logTrace("testTmpEacStrEnc"); 613 testTmpEacStrEnc(*rng); 614 logTrace("testCvcChain"); 615 testCvcChain(*rng); 616 }