1 /** 2 * --------- 3 * |.##> <##.| Open Smart Card Development Platform (www.openscdp.org) 4 * |# #| 5 * |# #| Copyright (c) 1999-2010 CardContact Software & System Consulting 6 * |'##> <##'| Andreas Schwier, 32429 Minden, Germany (www.cardcontact.de) 7 * --------- 8 * 9 * This file is part of OpenSCDP. 10 * 11 * OpenSCDP is free software; you can redistribute it and/or modify 12 * it under the terms of the GNU General Public License version 2 as 13 * published by the Free Software Foundation. 14 * 15 * OpenSCDP is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU General Public License for more details. 19 * 20 * You should have received a copy of the GNU General Public License 21 * along with OpenSCDP; if not, write to the Free Software 22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 23 * 24 * @fileoverview Simple CVC-CA 25 */ 26 27 28 // Imports 29 var CVC = require('scsh/eac/CVC').CVC; 30 var CVCertificateStore = require('scsh/eac/CVCertificateStore').CVCertificateStore; 31 var PublicKeyReference = require('scsh/eac/PublicKeyReference').PublicKeyReference; 32 var EAC2CVRequestGenerator = require('scsh/eac/EAC2CVRequestGenerator').EAC2CVRequestGenerator; 33 var EAC2CVCertificateGenerator = require('scsh/eac/EAC2CVCertificateGenerator').EAC2CVCertificateGenerator; 34 35 36 37 /** 38 * Creates a new CVC-CA instance 39 * 40 * @class Class supporting a certification authority that can issue CVC certificates 41 * for the EAC protocol. 42 * 43 * @constructor 44 * @param {Crypto} crypto the crypto provider to use 45 * @param {CVCertificateStore} certstore the certificate store to use 46 * @param {String} path the path of holderIDs (eg. "/UTCVCA/UTDVCA/UTTERM") 47 */ 48 function CVCCA(crypto, certstore, holderId, parentId, path) { 49 GPSystem.log(GPSystem.DEBUG, module.id, "new(" + crypto + "," + certstore + "," + holderId + "," + parentId + "," + path + ")"); 50 51 this.crypto = crypto; 52 this.certstore = certstore; 53 54 if (typeof(path) == "undefined") { // ToDo: Remove after migration 55 this.holderId = holderId; 56 this.parentId = parentId; 57 58 if (this.isRootCA()) { // CVCA 59 this.path = "/" + holderId; 60 } else { // DVCA 61 this.path = "/" + parentId + "/" + holderId; 62 } 63 } else { 64 this.path = path; 65 var pe = path.substr(1).split("/"); 66 var l = pe.length; 67 assert(l >= 1); 68 this.holderId = pe[l - 1]; 69 if (l > 1) { 70 this.parentId = pe[l - 2]; 71 } else { 72 this.parentId = this.holderId; 73 } 74 } 75 this.keyspec = new Key(); 76 this.keyspec.setComponent(Key.ECC_CURVE_OID, new ByteString("brainpoolP256r1", OID)); 77 this.taAlgorithmIdentifier = new ByteString("id-TA-ECDSA-SHA-256", OID); 78 this.countryseq = null; 79 } 80 81 exports.CVCCA = CVCCA; 82 83 84 85 /** 86 * Set factory generating EACCryptoProvider for private key operations (create, use, delete) 87 * 88 * @param {EACCryptoProvider} eaccp the EAC Crypto Provider for this instance 89 * @param {String} eaccpid the instance id 90 */ 91 CVCCA.prototype.setEACCryptoProviderFactory = function(eaccpf, eaccpid) { 92 this.eaccpf = eaccpf; 93 this.eaccpid = eaccpid; 94 } 95 96 97 98 /** 99 * Return a suitable crypto instance 100 * 101 */ 102 CVCCA.prototype.getCrypto = function() { 103 GPSystem.log(GPSystem.DEBUG, module.id, "getCrypto()"); 104 105 if (this.crypto) { 106 return this.crypto; 107 } 108 109 if (this.eaccpf) { 110 var eaccp = this.eaccpf.getEACCryptoProvider(this.eaccpid, true); 111 return eaccp.getCrypto(); 112 } 113 114 return this.certstore.getCrypto() 115 } 116 117 118 119 /** 120 * Returns true if this is a root CA 121 * 122 * @returns true if this is a root CA 123 * @type boolean 124 */ 125 CVCCA.prototype.isRootCA = function() { 126 GPSystem.log(GPSystem.DEBUG, module.id, "isRootCA()"); 127 128 return this.holderId == this.parentId; 129 } 130 131 132 133 /** 134 * Returns true if this CA has a certificate. 135 * 136 * @returns true if this CA is operational 137 * @type boolean 138 */ 139 CVCCA.prototype.hasCertificate = function() { 140 GPSystem.log(GPSystem.DEBUG, module.id, "hasCertificate()"); 141 142 var currentchr = this.certstore.getCurrentCHR(this.path); 143 return currentchr != null; 144 } 145 146 147 148 /** 149 * Returns true if this CA is operational. 150 * 151 * @returns true if this CA is operational 152 * @type boolean 153 */ 154 CVCCA.prototype.isOperational = function() { 155 GPSystem.log(GPSystem.DEBUG, module.id, "isOperational()"); 156 157 var currentchr = this.certstore.getCurrentCHR(this.path); 158 if (currentchr == null) { 159 return false; 160 } 161 var cvc = this.certstore.getCertificate(this.path, currentchr); 162 return !cvc.isExpired(); 163 } 164 165 166 167 /** 168 * Sets the key specification for generating requests 169 * 170 * @param {Key} keyparam a key object containing key parameters (e.g. EC Curve) 171 * @param {ByteString} algorithm the terminal authentication algorithm object identifier 172 */ 173 CVCCA.prototype.setKeySpec = function(keyparam, algorithm) { 174 GPSystem.log(GPSystem.DEBUG, module.id, "setKeySpec(" + keyparam + "," + algorithm + ")"); 175 176 this.keyspec = keyparam; 177 this.taAlgorithmIdentifier = algorithm; 178 } 179 180 181 182 /** 183 * Set flags that controls the removal of the previous key if the certificate for the new key is imported 184 * 185 * @param {boolean} removePreviousKey true to remove, false to keep 186 */ 187 CVCCA.prototype.setRemovePreviousKey = function(removePreviousKey) { 188 GPSystem.log(GPSystem.DEBUG, module.id, "setRemovePreviousKey(" + removePreviousKey + ")"); 189 190 this.removePreviousKey = removePreviousKey; 191 } 192 193 194 195 /** 196 * Set country code to be included in sequence number of public key reference 197 * 198 * @param {String} countryseq the two character country code 199 */ 200 CVCCA.prototype.setCountryCodeForSequence = function(countryseq) { 201 GPSystem.log(GPSystem.DEBUG, module.id, "setCountryCodeForSequence(" + countryseq + ")"); 202 203 this.countryseq = countryseq; 204 } 205 206 207 208 /** 209 * Return private key handle, either from EACCryptoProvider or Certificate Store 210 * 211 */ 212 CVCCA.prototype.getPrivateKey = function(path, chr) { 213 GPSystem.log(GPSystem.DEBUG, module.id, "getPrivateKey(" + path + "," + chr + ")"); 214 215 if (this.eaccpf) { 216 var eaccp = this.eaccpf.getEACCryptoProvider(this.eaccpid, true); 217 218 var blob = this.certstore.getSigner(path, chr); 219 var prkey = eaccp.getPrivateKey(path, chr, blob); 220 221 if (prkey && !blob) { // Have a key but no matching signer 222 GPSystem.log(GPSystem.DEBUG, module.id, "Signer " + chr + " not found in database, but on crypto device. Creating signer now."); 223 224 // Calculate current signer number 225 var seq = chr.getSequenceNo(); 226 var cnt = parseInt(seq.substr(-5), 10); // Full 5 digit sequence 227 if (isNaN(cnt)) { 228 var cnt = parseInt(seq.substr(-3), 10); // 3 Digit sequence number 229 } 230 231 GPSystem.log(GPSystem.DEBUG, module.id, "Setting signer number to " + cnt); 232 this.certstore.setSignerNo(path, cnt); 233 this.certstore.newSigner(path, chr); 234 } 235 return prkey; 236 } else { 237 return this.certstore.getPrivateKey(path, chr); 238 } 239 } 240 241 242 243 /** 244 * Generate a certificate request 245 * 246 * @param {PublicKeyReference} car the CA at which this request is addressed 247 * @param {boolean} forceInitial force an initial request, even if a current certificate is available 248 * @param {boolean} signinitial sign with initial key (sequence = 00000) 249 * @return the certificate request 250 * @type CVC 251 */ 252 CVCCA.prototype.generateRequest = function(car, forceinitial, signinitial) { 253 GPSystem.log(GPSystem.DEBUG, module.id, "generateRequest(" + car + "," + forceinitial + "," + signinitial + ")"); 254 255 if (typeof(this.certstore.sc) != "undefined") { 256 return this.generateRequestHSM(car, forceinitial, signinitial); 257 } 258 259 if (this.eaccpf) { 260 var eaccp = this.eaccpf.getEACCryptoProvider(this.eaccpid, true); 261 if (typeof(eaccp.generateRequest) == "function") { 262 return this.generateRequestHSMCP(eaccp, car, forceinitial, signinitial); 263 } 264 } 265 266 // Obtain key parameter 267 268 if (typeof(this.keyspec.getComponent(Key.ECC_P)) != "undefined") { 269 var prk = new Key(this.keyspec); 270 prk.setType(Key.PRIVATE); 271 var keyalg = Crypto.EC; 272 } else { 273 var prk = new Key(); 274 prk.setType(Key.PRIVATE); 275 var keyalg = Crypto.RSA; 276 } 277 var puk = new Key(this.keyspec); 278 puk.setType(Key.PUBLIC); 279 280 // Determine CHR 281 var currentchr = this.certstore.getCurrentCHR(this.path); 282 var nextchr = this.certstore.getNextCHR(this.path, this.countryseq); 283 284 // Generate key pair 285 if (this.eaccpf) { 286 var eaccp = this.eaccpf.getEACCryptoProvider(this.eaccpid, true); 287 eaccp.generateKeyPair(this.path, nextchr, keyalg, prk, puk); 288 } else { 289 this.certstore.generateKeyPair(this.path, nextchr, keyalg, prk, puk); 290 } 291 292 // Generate certificate request 293 var reqGenerator = new EAC2CVRequestGenerator(this.getCrypto()); 294 295 // Set CPI 296 reqGenerator.setProfileIdentifier(0x00); 297 298 // Set public key for request 299 reqGenerator.setPublicKey(puk); 300 301 // Set oid of algorithm 302 reqGenerator.setTAAlgorithmIdentifier(this.taAlgorithmIdentifier); 303 304 // Set CHR for the request 305 reqGenerator.setCHR(nextchr); 306 307 if ((typeof(car) != "undefined") && (car != null)) { 308 reqGenerator.setCAR(car); 309 } 310 311 if ((currentchr != null) && !forceinitial) { 312 var previousprk = this.getPrivateKey(this.path, currentchr); 313 var previouscvc = this.certstore.getCertificate(this.path, currentchr); 314 var req = reqGenerator.generateAuthenticatedCVRequest(prk, previousprk, currentchr, previouscvc.getPublicKeyOID()); 315 } else { 316 // Generate the request 317 if (signinitial) { 318 var initialchr = new PublicKeyReference(nextchr.getHolder() + "00000"); 319 var firstprk = this.getPrivateKey(this.path, initialchr); 320 var req = reqGenerator.generateAuthenticatedCVRequest(prk, firstprk, initialchr); 321 } else { 322 var req = reqGenerator.generateCVRequest(prk); 323 } 324 } 325 326 req = new CVC(req); 327 328 this.certstore.storeRequest(this.path, req); 329 330 return req; 331 } 332 333 334 335 /** 336 * Generate a certificate request using a SmartCard-HSM based private key 337 * 338 * @param {PublicKeyReference} car the CA at which this request is addressed 339 * @param {boolean} forceInitial force an initial request, even if a current certificate is available 340 * @param {boolean} signinitial sign with initial key (sequence = 00000) 341 * @return the certificate request 342 * @type CVC 343 */ 344 CVCCA.prototype.generateRequestHSM = function(car, forceinitial, signinitial) { 345 GPSystem.log(GPSystem.DEBUG, module.id, "generateRequestHSM(" + car + "," + forceinitial + "," + signinitial + ")"); 346 347 var req = this.certstore.generateRequest(this.path, car, forceinitial, signinitial, this.keyspec, this.taAlgorithmIdentifier, this.countryseq); 348 this.certstore.storeRequest(this.path, req); 349 350 return req; 351 } 352 353 354 355 /** 356 * Generate a certificate request using a SmartCard-HSM based private key via EACCryptoProvider 357 * 358 * @param {EACCryptoProvider} prov the EACCryptoProvider 359 * @param {PublicKeyReference} car the CA at which this request is addressed 360 * @param {boolean} forceInitial force an initial request, even if a current certificate is available 361 * @param {boolean} signinitial sign with initial key (sequence = 00000) 362 * @return the certificate request 363 * @type CVC 364 */ 365 CVCCA.prototype.generateRequestHSMCP = function(prov, car, forceinitial, signinitial) { 366 GPSystem.log(GPSystem.DEBUG, module.id, "generateRequestHSM(" + car + "," + forceinitial + "," + signinitial + ")"); 367 368 // Determine CHR 369 var currentchr = this.certstore.getCurrentCHR(this.path); 370 do { 371 var nextchr = this.certstore.getNextCHR(this.path, this.countryseq); 372 var prk = this.getPrivateKey(this.path, nextchr); 373 if (!prk) { 374 break; 375 } 376 GPSystem.log(GPSystem.INFO, module.id, "CHR " + nextchr + " already in use, skipping to next CHR"); 377 } while (true); 378 379 var req = prov.generateRequest(this.path, currentchr, nextchr, car, forceinitial, signinitial, this.keyspec, this.taAlgorithmIdentifier); 380 this.certstore.storeRequest(this.path, req); 381 this.certstore.newSigner(this.path, nextchr); 382 383 return req; 384 } 385 386 387 388 /** 389 * Counter-sign a request 390 * 391 * @param {CVC} req the initial request 392 * @return the certificate request 393 * @type CVC 394 */ 395 CVCCA.prototype.counterSignRequest = function(request) { 396 GPSystem.log(GPSystem.DEBUG, module.id, "counterSignRequest('" + request + "')"); 397 398 assert(!request.isAuthenticatedRequest()); 399 400 var car = this.certstore.getCurrentCHR(this.path); 401 assert(car != null); 402 403 var cacvc = this.certstore.getCertificate(this.path, car); 404 assert(cacvc != null); 405 406 var signingTAAlgorithmIdentifier = cacvc.getPublicKeyOID(); 407 var prk = this.getPrivateKey(this.path, car); 408 409 var req = EAC2CVRequestGenerator.signAuthenticatedCVRequest(this.getCrypto(), request.getASN1(), prk, car, signingTAAlgorithmIdentifier); 410 return new CVC(req); 411 } 412 413 414 415 /** 416 * Generate an initial certificate request 417 * 418 * @param {PublicKeyReference} car the CA at which this request is addressed 419 * @return the certificate request 420 * @type CVC 421 */ 422 CVCCA.prototype.generateInitialRequest = function(car) { 423 GPSystem.log(GPSystem.DEBUG, module.id, "generateInitialRequest(" + car + ")"); 424 425 return this.generateRequest(car, true, false); 426 } 427 428 429 430 /** 431 * Generate a signed initial certificate request 432 * 433 * @param {PublicKeyReference} car the CA at which this request is addressed 434 * @return the certificate request 435 * @type CVC 436 */ 437 CVCCA.prototype.generateSignedInitialRequest = function(car) { 438 GPSystem.log(GPSystem.DEBUG, module.id, "generateSignedInitialRequest(" + car + ")"); 439 440 return this.generateRequest(car, true, true); 441 } 442 443 444 445 /** 446 * Generate certificate for certificate request 447 * 448 * <p>Certificate contents is defined through the policy object:</p> 449 * <pre> 450 * var policy = { certificateValidityDays: 2, 451 * chatRoleOID: new ByteString("id-IS", OID), 452 * chatRights: new ByteString("E3", HEX), 453 * includeDomainParameter: true, 454 * extensions: [] 455 * }; 456 * </pre> 457 * 458 * @param {CVC} req the certificate request 459 * @param {Object} policy the object with policy settings 460 * @returns the certificate 461 * @type CVC 462 */ 463 CVCCA.prototype.generateCertificate = function(req, policy) { 464 GPSystem.log(GPSystem.DEBUG, module.id, "generateCertificate('" + req + "'" + policy + ")"); 465 466 var car = this.certstore.getCurrentCHR(this.path); 467 var maxExpDate = null; 468 var signingTAAlgorithmIdentifier = req.getPublicKeyOID(); 469 470 if (car == null) { // No CA certificate found 471 if (this.isRootCA()) { 472 car = req.getCHR(); // Generate a self-signed root certificate 473 } else { 474 throw new GPError("CVCCA", GPError.INVALID_DATA, 0, "No current certificate found"); 475 } 476 } else { 477 var cacvc = this.certstore.getCertificate(this.path, car); 478 var signingTAAlgorithmIdentifier = cacvc.getPublicKeyOID(); 479 if (policy.shellModelForExpirationDate) { 480 maxExpDate = cacvc.getCXD(); 481 } 482 } 483 484 var generator = new EAC2CVCertificateGenerator(this.getCrypto()); 485 generator.setCAR(car); 486 generator.setCHR(req.getCHR()); 487 var effDate = new Date(); 488 if (policy.ced) { 489 effDate = policy.ced; 490 } 491 effDate.setHours(12, 0, 0, 0); 492 var expDate = new Date((policy.certificateValidityDays - 1) * (1000 * 60 * 60 * 24) + effDate.getTime()); 493 expDate.setHours(12, 0, 0, 0); 494 495 if (maxExpDate != null) { 496 if (effDate.getTime() > maxExpDate.getTime()) { 497 throw new GPError("CVCCA", GPError.INVALID_DATA, 0, "CA certificate is expired"); 498 } 499 // Expiration date of issued certificate must not exceed expiration date of issuing CA 500 if (expDate.getTime() > maxExpDate.getTime()) { 501 expDate = maxExpDate; 502 } 503 } 504 505 generator.setEffectiveDate(effDate); 506 generator.setExpiryDate(expDate); 507 generator.setChatOID(policy.chatRoleOID); 508 generator.setChatAuthorizationLevel(policy.chatRights); 509 generator.setPublicKey(req.getPublicKey()); 510 generator.setProfileIdentifier(0x00); 511 if (policy.publicKeyOID) { 512 generator.setTAAlgorithmIdentifier(policy.publicKeyOID); 513 } else { 514 generator.setTAAlgorithmIdentifier(req.getPublicKeyOID()); 515 } 516 517 generator.setIncludeDomainParameters(policy.includeDomainParameter); 518 generator.setExtensions(policy.extensions); 519 var prk = this.getPrivateKey(this.path, car); 520 var cvc = generator.generateCVCertificate(prk, signingTAAlgorithmIdentifier); 521 522 return cvc; 523 } 524 525 526 527 /** 528 * Store issued certificate 529 * 530 * @param {CVC} cert a newly issued certificate 531 */ 532 CVCCA.prototype.storeCertificate = function(cert) { 533 GPSystem.log(GPSystem.DEBUG, module.id, "storeCertificate('" + cert + "')"); 534 535 var chrHolder = cert.getCHR().getHolder(); 536 this.certstore.storeCertificate(this.path + "/" + chrHolder, cert, false); 537 } 538 539 540 541 /** 542 * Remove previous key 543 * 544 * @param {PublicKeyReference} previous the previously used CHR 545 */ 546 CVCCA.prototype.removePreviouslyUsedKey = function(previous) { 547 GPSystem.log(GPSystem.DEBUG, module.id, "removePreviouslyUsedKey('" + previous + "')"); 548 549 if (previous.equals(this.certstore.getCurrentCHR(this.path))) { 550 GPSystem.log(GPSystem.INFO, module.id, "CHR " + previous + " is still the active key. Not deleting it"); 551 return; 552 } 553 554 if (this.eaccpf) { 555 var eaccp = this.eaccpf.getEACCryptoProvider(this.eaccpid, true); 556 eaccp.deletePrivateKey(this.path, previous); 557 } else { 558 this.certstore.deletePrivateKey(this.path, previous); 559 } 560 } 561 562 563 564 /** 565 * Import a certificate into the certificate store and make it the current certificate 566 * 567 * @param {CVC} cert the certificate 568 */ 569 CVCCA.prototype.importCertificate = function(cert) { 570 GPSystem.log(GPSystem.DEBUG, module.id, "importCertificate('" + cert + "')"); 571 572 var chr = cert.getCHR(); 573 var prk = this.getPrivateKey(this.path, chr); 574 if (prk == null) { 575 throw new GPError("CVCCA", GPError.INVALID_DATA, 0, "Invalid certificate, no matching private key"); 576 } 577 var c = this.certstore.getCertificate(this.path, cert.getCHR()); 578 if (c != null) { 579 GPSystem.log(GPSystem.INFO, module.id, "Certificate " + c + " already existing"); 580 } 581 582 // Save currentchr 583 var currentchr = this.certstore.getCurrentCHR(this.path); 584 585 if (this.isRootCA() && !this.isOperational()) { 586 this.certstore.storeCertificate(this.path, cert, (c == null)); 587 } else { 588 if (!this.certstore.insertCertificate(this.getCrypto(), cert, this.path)) { 589 throw new GPError("CVCCA", GPError.CRYPTO_FAILED, 0, "Could not validate certificate"); 590 } 591 } 592 if (this.removePreviousKey && currentchr) { 593 this.removePreviouslyUsedKey(currentchr); 594 } 595 } 596 597 598 599 /** 600 * Import a list of certificates into the certificate store 601 * 602 * @param {CVC[]} certs the list of certificates 603 */ 604 CVCCA.prototype.importCertificates = function(certs) { 605 GPSystem.log(GPSystem.DEBUG, module.id, "importCertificates('" + certs + "')"); 606 607 // Save currentchr 608 var currentchr = this.certstore.getCurrentCHR(this.path); 609 610 var list = this.certstore.insertCertificates(this.getCrypto(), certs, true, this.path); 611 612 if (this.removePreviousKey && currentchr) { 613 this.removePreviouslyUsedKey(currentchr); 614 } 615 616 return list; 617 } 618 619 620 621 /** 622 * Returns a list of relevant certificates. 623 * 624 * <p>If the CA is the root CA, then all self-signed and link certificates are returned.</p> 625 * <p>If the CA is a DVCA, then all certificates of the associated root and the current 626 * DVCA certificate is returned.</p> 627 * 628 * @param {PublicKeyReference} fromCAR the optional starting point for the list if not a root CA 629 */ 630 CVCCA.prototype.getCertificateList = function(fromCAR) { 631 GPSystem.log(GPSystem.DEBUG, module.id, "getCertificateList(" + fromCAR + ")"); 632 633 var list; 634 635 if (this.isRootCA()) { 636 list = this.certstore.listCertificates(this.path); 637 } else { 638 var path = this.path; 639 640 while(true) { 641 var chr = this.certstore.getCurrentCHR(path); 642 if (chr == null) { 643 var ofs = path.lastIndexOf("/"); 644 if (ofs == 0) { 645 list = []; 646 } else { 647 path = path.substr(0, ofs); 648 continue; 649 } 650 } else { 651 list = this.certstore.getCertificateChain(path, chr, fromCAR); 652 } 653 break; 654 } 655 } 656 657 return list; 658 } 659 660 661 662 /** 663 * Return certificate issued by this CA 664 * 665 * @param {PublicKeyReference} chr the certificate holder reference 666 * @returns the certificate or null if not found 667 * @type CVC 668 */ 669 CVCCA.prototype.getIssuedCertificate = function(chr) { 670 GPSystem.log(GPSystem.DEBUG, module.id, "getIssuedCertificate(" + chr + ")"); 671 672 var path = this.path + "/" + chr.getHolder(); 673 674 var cvc = this.certstore.getCertificate(path, chr); 675 if (cvc == null) { 676 GPSystem.trace("No certificate found for " + chr); 677 return null; 678 } 679 680 return cvc; 681 } 682 683 684 685 /** 686 * Return authentic public key with domain parameter for a given CHR subordinate to the CA 687 * 688 * @param {PublicKeyReference} chr the certificate holder reference 689 * @returns the public key or null 690 * @type Key 691 */ 692 CVCCA.prototype.getAuthenticPublicKey = function(chr) { 693 GPSystem.log(GPSystem.DEBUG, module.id, "getAuthenticPublicKey(" + chr + ")"); 694 695 var cvc = this.getIssuedCertificate(chr); 696 697 if (cvc == null) { 698 return null; 699 } 700 701 if (this.isRootCA()) { 702 var dp = this.certstore.getDomainParameter(cvc.getCAR()); 703 } else { 704 var dvcacvc = this.certstore.getCertificate(this.path, cvc.getCAR()); 705 if (dvcacvc == null) { 706 GPSystem.trace("No certificate found for " + cvc.getCAR()); 707 return null; 708 } 709 var dp = this.certstore.getDomainParameter(dvcacvc.getCAR()); 710 } 711 712 return(cvc.getPublicKey(dp)); 713 } 714 715 716 717 CVCCA.test = function(daofcvca, daofdvca, daofterm) { 718 719 var crypto = new Crypto(); 720 721 var ss = new CVCertificateStore(daofcvca); 722 ss.setContextMarker(0); 723 var cvca = new CVCCA(crypto, ss, null, null, "/UTCVCA"); 724 725 // Create a new request 726 var req = cvca.generateRequest(null, false); 727 GPSystem.trace("Request: " + req); 728 GPSystem.trace(req.getASN1()); 729 730 assert(req.verifyWith(crypto, req.getPublicKey())); 731 732 // Create self-signed or link certificate based on request 733 var policy = { certificateValidityDays: 2, 734 chatRoleOID: new ByteString("id-IS", OID), 735 chatRights: new ByteString("E3", HEX), 736 includeDomainParameter: true, 737 extensions: [] 738 }; 739 var cert = cvca.generateCertificate(req, policy); 740 GPSystem.trace("Certificate: " + cert); 741 GPSystem.trace(cert.getASN1()); 742 743 // Import certificate into store, making it the most current certificate 744 cvca.importCertificate(cert); 745 746 // Generate additional self-signed root certificate 747 // This must be done after the link certificate has been imported 748 var policy = { certificateValidityDays: 2, 749 chatRoleOID: new ByteString("id-IS", OID), 750 chatRights: new ByteString("E3", HEX), 751 includeDomainParameter: true, 752 extensions: [] 753 }; 754 var cert = cvca.generateCertificate(req, policy); 755 GPSystem.trace("Certificate: " + cert); 756 GPSystem.trace(cert.getASN1()); 757 758 // Import certificate into store, making it the most current certificate 759 cvca.importCertificate(cert); 760 761 var ss = new CVCertificateStore(daofdvca); 762 ss.setContextMarker(1); 763 var dvca = new CVCCA(crypto, ss, null, null, "/UTCVCA/UTDVCA"); 764 765 var certlist = cvca.getCertificateList(); 766 var list = dvca.importCertificates(certlist); 767 768 if (list.length > 0) { 769 GPSystem.trace("Warning: Could not import the following certificates"); 770 for (var i = 0; i < list.length; i++) { 771 GPSystem.trace(list[i]); 772 } 773 } 774 775 // Create a new request 776 var req = dvca.generateRequest(null, false); 777 GPSystem.trace("Request: " + req); 778 GPSystem.trace(req.getASN1()); 779 780 // Sign this request with root CA 781 // This must be done after the link certificate has been imported 782 var policy = { certificateValidityDays: 2, 783 chatRoleOID: new ByteString("id-IS", OID), 784 chatRights: new ByteString("A3", HEX), 785 includeDomainParameter: false, 786 extensions: [] 787 }; 788 var cert = cvca.generateCertificate(req, policy); 789 GPSystem.trace("Certificate: " + cert); 790 GPSystem.trace(cert.getASN1()); 791 792 cvca.storeCertificate(cert); 793 dvca.importCertificate(cert); 794 795 796 var ss = new CVCertificateStore(daofterm); 797 ss.setContextMarker(2); 798 var term = new CVCCA(crypto, ss, null, null, "/UTCVCA/UTDVCA/UTTERM"); 799 800 term.setRemovePreviousKey(true); 801 802 var certlist = dvca.getCertificateList(); 803 GPSystem.trace("Certificate list: "); 804 GPSystem.trace(certlist); 805 var list = term.importCertificates(certlist); 806 807 if (list.length > 0) { 808 GPSystem.trace("Warning: Could not import the following certificates"); 809 for (var i = 0; i < list.length; i++) { 810 GPSystem.trace(list[i]); 811 } 812 } 813 814 // Create a new request 815 var req = term.generateRequest(null, false); 816 GPSystem.trace("Request: " + req); 817 GPSystem.trace(req.getASN1()); 818 819 // Sign this request with DVCA 820 // This must be done after the link certificate has been imported 821 var policy = { certificateValidityDays: 2, 822 chatRoleOID: new ByteString("id-IS", OID), 823 chatRights: new ByteString("23", HEX), 824 includeDomainParameter: false, 825 extensions: [] 826 }; 827 var cert = dvca.generateCertificate(req, policy); 828 GPSystem.trace("Certificate: " + cert); 829 GPSystem.trace(cert.getASN1()); 830 831 dvca.storeCertificate(cert); 832 term.importCertificate(cert); 833 } 834