1 /** 2 * --------- 3 * |.##> <##.| Open Smart Card Development Platform (www.openscdp.org) 4 * |# #| 5 * |# #| Copyright (c) 1999-2026 CardContact Systems GmbH 6 * |'##> <##'| 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 Public Key File Format 25 */ 26 27 var File = require("scsh/file/File").File; 28 var SmartCardHSM = require("scsh/sc-hsm/SmartCardHSM").SmartCardHSM; 29 var CVC = require("scsh/eac/CVC").CVC; 30 31 32 33 /** 34 * Create a Public Key File object. 35 * 36 * @class Read and write encoded SmartCard-HSM public keys. 37 * @constructor 38 * @param {String} arg the file to read from 39 * @param {CVC[]} arg the certificate chain with the public key first. 40 */ 41 function PublicKeyFile(arg) { 42 if (typeof(arg == "string")) { 43 var f = new File(arg); 44 var bin = f.readAllAsBinary(); 45 this.parse(bin); 46 } else { 47 this.chain = arg; 48 } 49 } 50 51 exports.PublicKeyFile = PublicKeyFile; 52 53 54 55 PublicKeyFile.prototype.getChain = function() { 56 return this.chain; 57 } 58 59 60 61 /** 62 * Parse the binary file content as TLV structure and validate the certificate chain. 63 * 64 * @param {ByteString} content the file content. 65 */ 66 PublicKeyFile.prototype.parse = function(content) { 67 if (content.byteAt(0) != 0x30) { 68 throw new GPError(module.id, GPError.INVALID_DATA, 0, "File does not contain a public key with certificates"); 69 } 70 71 var a = new ASN1(content); 72 73 if (a.get(0).tag == ASN1.OBJECT_IDENTIFIER) { 74 var oid = new ByteString("CardContact 4 3 1", OID); 75 assert(a.get(0).value.equals(oid), "Invalid file format"); 76 var pk = new CVC(a.find(0x63).get(0)); 77 var devcert = new CVC(a.find(0x62).get(0)); 78 var dicacert = new CVC(a.find(0x61).get(0)); 79 } else { 80 var pk = new CVC(a.get(0)); 81 var devcert = new CVC(a.get(1)); 82 var dicacert = new CVC(a.get(2)); 83 } 84 85 var crypto = new Crypto(); 86 assert(dicacert.verifyWithCVC(crypto, SmartCardHSM.rootCerts[dicacert.getCAR()])); 87 assert(devcert.verifyWith(crypto, dicacert.getPublicKey(SmartCardHSM.rootCerts.UTSRCACC100001.getPublicKey()), dicacert.getPublicKeyOID())); 88 89 this.chain = [ pk, devcert, dicacert ]; 90 } 91 92 93 94 /** 95 * Encode the certificate chain in TLV encoding. 96 * 97 * @type ByteString 98 * @return the encoded content for the file 99 */ 100 PublicKeyFile.prototype.encode = function() { 101 102 var asn = new ASN1(ASN1.SEQUENCE, 103 new ASN1(ASN1.OBJECT_IDENTIFIER, new ByteString("CardContact 4 3 1", OID)), 104 new ASN1(0x61, this.chain[2].getASN1()), 105 new ASN1(0x62, this.chain[1].getASN1()), 106 new ASN1(0x63, this.chain[0].getASN1()) 107 ); 108 109 // print(asn); 110 return asn.getBytes(); 111 } 112