JCOP4Initializer.js

Summary

Initializer for JCOP4 cards


Class Summary
JCOP4Initializer  

/**
 *  ---------
 * |.##> <##.|  SmartCard-HSM Support Scripts
 * |#       #|
 * |#       #|  Copyright (c) 2011-2012 CardContact Software & System Consulting
 * |'##> <##'|  Andreas Schwier, 32429 Minden, Germany (www.cardcontact.de)
 *  ---------
 *
 * Consult your license package for usage terms and conditions.
 *
 * @fileoverview Initializer for JCOP4 cards
 */


load("keys.js");


function JCOP4Initializer(job) {
	this.job = job;
	this.jcopkeys = JCOPKeys.JCOP4;
	this.customerkeys = CustomerKeys;

	this.aid = new ByteString("A000000151000000", HEX);

	this.af = new ApplicationFactory(new Crypto());
	this.af.addApplicationProfile("profiles/ap_jcop_cardmanager_jcop4_kst.xml");
	this.af.addApplicationProfile("profiles/ap_jcop_cardmanager_jcop4_kmc.xml");
}

exports.JCOP4Initializer = JCOP4Initializer;

JCOP4Initializer.type = "initializer";



JCOP4Initializer.prototype.determineConfigId = function(card) {
	var iddata = card.sendApdu(0x80, 0xCA, 0x00, 0xFE, new ByteString("DF28", HEX), 0);

	print("IDENTIFY returns:");
	print(iddata);

	var a = new ASN1(0x30, (new ASN1(iddata)).get(0).value);
	var a = new ASN1(a.getBytes());

	var epromid = a.find(0x01).value;
	print("EEPROM ID          " + epromid.toString(HEX));
	var configid = epromid.bytes(1,3).toString(HEX);
	print("  Configuration ID " + configid);
	var backgroundid = epromid.bytes(4,8);
	print("  Background ID    " + backgroundid.toString(HEX));
	print("Patch ID           " + a.find(0x02).value.toString(HEX));
	var pbid = a.find(0x03).value;
	print("Platform build ID  " + pbid.bytes(0, 16).toString(ASCII) + "-" + pbid.bytes(16, 8).toString(HEX));
	print("FIPS Mode          " + a.find(0x05).value.toString(HEX));
	print("Pre-perso state    " + a.find(0x07).value.toString(HEX));
	print("ROM ID             " + a.find(0x08).value.toString(HEX));

	return configid;
}



JCOP4Initializer.prototype.determineKeyVersion = function(card) {
	card.sendApdu(0x00, 0xA4, 0x04, 0x00, this.aid, [0x9000, 0x6D00]);

	var kit = card.sendApdu(0x00, 0xCA, 0x00, 0xE0, 0, [0x9000, 0x6982]);

	if (card.SW == 0x6982) {
		return 0xFF;
	}

	var kid = kit.byteAt(3);
	print("ISD Key Version    " + kid);
	return kid;
}



JCOP4Initializer.prototype.handleCard = function(card) {

	card.reset(Card.RESET_COLD);
	var configid = this.determineConfigId(card);
	var kid = this.determineKeyVersion(card);

	if (typeof(this.job.RequiredKID) == "object") {
		if (this.job.RequiredKID.indexOf(kid) < 0) {
			print("KID does not match requirement");
			return "OK";
		}
	}

	var jkeys = this.jcopkeys[configid];

	if (kid == 255) {
		if (typeof(jkeys) == "undefined") {
			throw new Error("Configuration id " + configid + " not found. Entry in keys.js missing ?");
		}

		this.addKey("K_ENC", jkeys.transportKey.bytes(0, 16));
		this.addKey("K_MAC", jkeys.transportKey.bytes(16, 16));
		this.addKey("K_DEK", jkeys.transportKey.bytes(32, 16));
	} else {
		var a = new ASN1(this.customerkeys[this.job.Keys].KST);
		this.addKey("K_ENC", a.get(0).value);
		this.addKey("K_MAC", a.get(1).value);
		this.addKey("K_DEK", a.get(2).value);
	}

	var data = {
		applAid: new ByteString("E82B0601040181C31F0201", HEX)
	};

	var dm = {
		get: function(name, fixed, length, encoding) {
			if (typeof(data[name]) == "undefined") {
				return null;
			}

			return data[name];
		}
	}

	var appl = this.af.getApplicationInstance(dm, this.aid, card, this.job.Profile);
	appl.key = this.keys;

	for (var i = 0; i < this.job.Steps.length; i++) {
		var e = this.job.Steps[i];
		if (typeof(e) == "string") {
			appl.run(this.job.Steps[i]);
		} else {
			data = e.data;
			appl.run(e.step);
		}
	}

	return "OK";
}



JCOP4Initializer.prototype.addKey = function(name, value) {
	var key = new Key();
	key.setComponent(Key.DES, value);
	this.keys[name] = key;
}



JCOP4Initializer.prototype.configure = function() {
	this.keys = [];

	this.addKey("KMC", this.customerkeys[this.job.Keys].KMC);

	var a = new ASN1(this.customerkeys[this.job.Keys].KST);
	this.addKey("K_SENC", a.get(0).value);
	this.addKey("K_SMAC", a.get(1).value);
	this.addKey("K_SDEK", a.get(2).value);
}


Documentation generated by JSDoc on Thu Apr 3 11:32:15 2025