      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