repair-prkd.js

Summary

Repair a missing PRKD section in a key backup


Method Summary
static void dumpKeyBLOB(keyblob)
          

/**
 *  ---------
 * |.##> <##.|  SmartCard-HSM Support Scripts
 * |#       #|
 * |#       #|  Copyright (c) 2011-2015 CardContact Software & System Consulting
 * |'##> <##'|  Andreas Schwier, 32429 Minden, Germany (www.cardcontact.de)
 *  ---------
 *
 * Consult your license package for usage terms and conditions.
 *
 * @fileoverview Repair a missing PRKD section in a key backup
 */

var File = require("scsh/file/File").File;
var SmartCardHSM = require("scsh/sc-hsm/SmartCardHSM").SmartCardHSM;



function dumpKeyBLOB(keyblob) {
	// Verify MAC on last 16 byte of blob

	var keytype = keyblob.byteAt(8);
	print("Values from key blob:");
	print("---------------------");
	print("KCV                   : " + keyblob.bytes(0, 8).toString(HEX) + "    [Must match the KCV of the DKEK for import]");
	print("Key type              : " + keytype + "    [5=RSA, 6=RSA-CRT, 12=ECC, 15=AES]");

	var ofs = 9;
	var len = keyblob.bytes(ofs, 2).toUnsigned();

	if ((keytype == 15) && (keyblob.byteAt(ofs + 2) != 0x60)) {
		print("Default Algorithm ID  : " + keyblob.bytes(ofs + 2, len).toString(HEX) + " (" + len + ")     [Wrong encoding in V3.0 to V3.2]");
	} else {
		print("Default Algorithm ID  : " + keyblob.bytes(ofs + 2, len).toString(OID) + " (" + len + ")     [Default algorithm]");
	}

	ofs += len + 2;
	var len = keyblob.bytes(ofs, 2).toUnsigned();

	print("Allowed Algorithm IDs : " + keyblob.bytes(ofs + 2, len).toString(HEX) + " (" + len + ")");

	ofs += len + 2;
	var len = keyblob.bytes(ofs, 2).toUnsigned();

	print("Access Conditions     : " + keyblob.bytes(ofs + 2, len).toString(HEX) + " (" + len + ")    [Not used]");

	ofs += len + 2;
	var len = keyblob.bytes(ofs, 2).toUnsigned();

	print("Key OID               : " + keyblob.bytes(ofs + 2, len).toString(HEX) + " (" + len + ")    [Not used]");
}



var fn = Dialog.prompt("Select key backup", "", null, "*.wky");

print(fn);

// Read binary key backup
var f = new File(fn);
var bin = f.readAllAsBinary();
f.close();

// Decode ASN.1 structure
var outerseq = new ASN1(bin);

print("Dump of backup file");
print(outerseq);

var sections = outerseq.elements;
print("Key backup contains " + sections + " sections (Should be between 2 and 3)");

if ((sections < 1) || (outerseq.get(0).tag != ASN1.OCTET_STRING)) {
	throw new Error("First section does not contain a vaild key blob. Can't repair");
}

var blob = outerseq.get(0).value;

if (blob.length < 16) {
	throw new Error("Key blob too small. Can't repair");
}

dumpKeyBLOB(blob);

var i = 1;
var prkd = null;

if ((i < sections) && (outerseq.get(i).get(0).get(0).tag == ASN1.UTF8String)) {
	// Valid PRKD found
	prkd = outerseq.get(i);
	i++;
}

var cert = null;
var label = "";
var keysize = 2048;
var id = "01";

if ((i < sections) && ((outerseq.get(i).tag == ASN1.SEQUENCE) || (outerseq.get(i).tag == 0x67))) {
	var cert = outerseq.get(i);
	if (cert.tag == ASN1.SEQUENCE) {
		var x = new X509(cert.getBytes());
		print(x);
	} else {
		var x = new CVC(cert.getBytes());
		print(x);
	}
}

if (prkd == null) {
	print("Corrupted backup detected: Missing PRKD section");

	var label = Dialog.prompt("Enter a label for the key", label );
	if (label == null) {
		throw new Error("User abort");
	}

	var keysize = Dialog.prompt("Enter key size in bits", "" + keysize );
	if (keysize == null) {
		throw new Error("User abort");
	}
	keysize = parseInt(keysize);

	var id = Dialog.prompt("Enter key id as hex string", id );
	if (id == null) {
		throw new Error("User abort");
	}
	id = new ByteString(id, HEX);

	var keytype = blob.byteAt(8);
	switch(keytype) {
		case 5:
		case 6:
			prkd = SmartCardHSM.buildPrkDforRSA(id, label, keysize);
			break;
		case 12:
			prkd = SmartCardHSM.buildPrkDforECC(id, label, keysize);
			break;
		case 15:
			prkd = SmartCardHSM.buildSKDforAES(id, label, keysize);
			break;
		default:
			throw new Error("Unsupported key type");
	}

	var nseq = new ASN1(ASN1.SEQUENCE);
	nseq.add(outerseq.get(0));
	nseq.add(prkd);
	if (cert != null) {
		nseq.add(cert);
	}

	print(nseq);

	var nfn = fn.substr(0, fn.lastIndexOf(".")) + "-fixed.wky";
	var f = new File(nfn);
	f.writeAll(nseq.getBytes());
	f.close();
	print("Fixed backup written to " + nfn);
} else {
	print("No problem found");
}




Documentation generated by JSDoc on Sat Feb 24 15:17:19 2024