JCOP4Initializer.js
Summary
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