/*
* ---------
* |.##> <##.| Open Smart Card Development Platform (www.openscdp.org)
* |# #|
* |# #| Copyright (c) 1999-2006 CardContact Software & System Consulting
* |'##> <##'| Andreas Schwier, 32429 Minden, Germany (www.cardcontact.de)
* ---------
*
* This file is part of OpenSCDP.
*
* OpenSCDP is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* OpenSCDP is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenSCDP; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* Global Platform Card Explorer
*/
load("tools.js");
load("tools/CardOutlineFactory.js");
if (typeof(masterSENC) == "undefined")
masterSENC = new Key("kp_jcop_default_s-enc.xml");
if (typeof(masterSMAC) == "undefined")
masterSMAC = new Key("kp_jcop_default_s-mac.xml");
function OutlineCardManager(factory, application) {
this.factory = factory;
this.application = application;
this.card = application.card; // Required by OutlineDataObject
this.issuerSecurityDomain = null;
this.applications = null;
this.loadfiles = null;
// Create OutlineNode object and register in OutlineCardManager object
var view = new OutlineNode("Card Manager (" + application.aid + ")", true);
view.setUserObject(this);
view.setContextMenu(["Authenticate"]);
this.view = view;
this.authenticated = false;
}
//
// Event handler for expand notifications
//
OutlineCardManager.prototype.expandListener = function() {
if (this.expanded)
return;
var view = this.view;
try {
var fcp = this.application.select();
this.fcp = fcp;
if (fcp && (fcp.length > 1)) {
var fcpmodel = this.factory.newOutlineFCP(fcp);
view.insert(fcpmodel.view);
}
var d = this.factory.newOutlineDataObject(this, 0x42, "Issuer Identification Number", "");
view.insert(d.view);
var d = this.factory.newOutlineDataObject(this, 0x45, "Card Image Number", "");
view.insert(d.view);
var d = this.factory.newOutlineDataObject(this, 0x66, "Card Data", "asn1");
view.insert(d.view);
var d = this.factory.newOutlineDataObject(this, 0xE0, "Key Information Template", "tlvlist");
view.insert(d.view);
var d = this.factory.newOutlineDataObject(this, 0xC1, "Sequence Counter of the default Key Version Number", "");
view.insert(d.view);
var d = this.factory.newOutlineDataObject(this, 0xC2, "Confirmation Counter", "");
view.insert(d.view);
var d = this.factory.newOutlineDataObject(this, 0x9F7F, "Card Production Life Cycle (JCOP)", "");
view.insert(d.view);
}
catch(e) {
print(e);
}
this.expanded = true;
}
OutlineCardManager.prototype.authenticate = function() {
if (!this.expanded) {
print("Please expand card manager before authentication");
return;
}
GPAuthenticate(this.application.card, this.application.crypto, masterSENC, masterSMAC);
this.authenticated = true;
var filter = new ByteString("4F00", HEX);
var view = this.view;
if (this.issuerSecurityDomain) {
view.remove(this.issuerSecurityDomain.view);
}
var r = this.application.sendApdu(0x80, 0xF2, 0x80, 0x00, filter, 0x00, [0x9000]);
this.issuerSecurityDomain = new OutlineModuleList(this.application, "Issuer Security Domain", r, 0, false);
view.insert(this.issuerSecurityDomain.view);
if (this.applications) {
view.remove(this.applications.view);
}
var r = this.application.sendApdu(0x80, 0xF2, 0x40, 0x00, filter, 0x00, [0x9000, 0x6A88]);
this.applications = new OutlineModuleList(this.application, "Application Instances", r, 1, true);
view.insert(this.applications.view);
if (this.loadfiles) {
view.remove(this.loadfiles.view);
}
// 2.1.x cards support option P1 = 0x10 to list load files and modules
// 2.0.1 cards only support P1 = 0x20 to list load files
var r = this.application.sendApdu(0x80, 0xF2, 0x10, 0x00, filter, 0x00, [0x9000, 0x6A88, 0x6A86]);
if (this.application.card.SW == 0x6A86) {
var r = this.application.sendApdu(0x80, 0xF2, 0x20, 0x00, filter, 0x00, [0x9000, 0x6A88]);
this.loadfiles = new OutlineModuleList(this.application, "Load Files", r, 2, true);
view.insert(this.loadfiles.view);
} else {
this.loadfiles = new OutlineModuleList(this.application, "Load Files and Modules", r, 3, true);
view.insert(this.loadfiles.view);
}
}
//
// Action handler
//
OutlineCardManager.prototype.actionListener = function(node, action) {
switch(action) {
case "Authenticate":
node.userObject.authenticate();
break;
}
}
//
// Return a string for a Global Platform Life Cycle Status
//
function lcs2string(type, lcs) {
s = "UNKNOWN";
if (type == 0) { // Issuer Security Domain
switch(lcs) {
case 0x01: s = "OP_READY"; break;
case 0x07: s = "INITIALIZED"; break;
case 0x0F: s = "SECURED"; break;
case 0x7F: s = "CARD_LOCKED"; break;
case 0xFF: s = "TERMINATED"; break;
}
} else {
switch(lcs & 0x8F) {
case 0x01: s = "LOADED"; break;
case 0x03: s = "INSTALLED"; break;
case 0x07: s = "SELECTABLE"; break;
case 0x0F: s = "PERSONALIZED"; break;
case 0x8F: s = "LOCKED"; break;
}
}
return s;
}
//
// Return a string for a Global Platform application privilege
//
function priv2string(priv) {
if (priv == 0)
return("");
s = "(";
if (priv & 0x80)
s += "SecDom ";
if (priv & 0x40)
s += "DAP ";
if (priv & 0x20)
s += "DelMan ";
if (priv & 0x10)
s += "CrdLck ";
if (priv & 0x08)
s += "CrdTrm ";
if (priv & 0x04)
s += "DefSel ";
if (priv & 0x02)
s += "CVM ";
if (priv & 0x01)
s += "MDAP ";
s += ")";
return s;
}
//
// Create an outline for AID identified objects managed by the card manager
//
// cm Card manager application object
// name Name of module list
// desc Descriptor returned by GET_STATUS
// type 0 - Issuer Security Domain, 1 - Application, 2 - Load File
// deletable true, if module can be deleted
//
function OutlineModuleList(cm, name, desc, type, deletable) {
this.cm = cm;
this.name = name;
var view = new OutlineNode(name, true);
view.setUserObject(this);
this.view = view;
var offset = 0;
while(offset < desc.length) {
var lenaid = desc.byteAt(offset++);
var aid = desc.bytes(offset, lenaid);
offset += lenaid;
var lcs = desc.byteAt(offset++);
var priv = desc.byteAt(offset++);
var name = aid.toString(16) + " " + lcs2string(type, lcs) + " " + priv2string(priv);
var n = new OutlineModuleListEntry(cm, name, aid, deletable);
view.insert(n.view);
if (type == 3) {
var count = desc.byteAt(offset++);
while (count--) {
lenaid = desc.byteAt(offset++);
aid = desc.bytes(offset, lenaid);
offset += lenaid;
var m = new OutlineNode("Module " + aid.toString(16));
n.view.insert(m);
}
}
}
}
function OutlineModuleListEntry(cm, name, aid, deletable) {
this.cm = cm;
this.aid = aid;
var view = new OutlineNode(name, false);
view.setUserObject(this);
if (deletable) {
view.setContextMenu(["Delete"]);
}
this.view = view;
}
OutlineModuleListEntry.prototype.actionListener = function(node, action) {
var aid = node.userObject.aid;
/*
var b = new ByteString("4F", HEX);
b = b.concat(aid.getLV(TLV.EMV));
this.cm.sendApdu(0x80, 0xE4, 0x00, 0x00, b);
*/
this.cm.deleteAID(aid);
print("Delete " + aid + " : " + this.cm.card.SWMSG);
node.remove();
}
//
// Overwrite default outline factory to tailor some nodes
//
function GPCardOutlineFactory() {
}
// Inherit from prototype
GPCardOutlineFactory.prototype = new CardOutlineFactory();
// Restore constructor
GPCardOutlineFactory.constructor = GPCardOutlineFactory;
// Overwrite newOutlineApplet() function
GPCardOutlineFactory.prototype.newOutlineApplet = function(instance) {
assert(instance instanceof GPSecurityDomain);
return new OutlineCardManager(this, instance);
}
var card = new Card(_scsh3.reader, "../profiles/cp_jcop41.xml");
var crypto = new Crypto();
// Create card outline factory
var of = new GPCardOutlineFactory();
// Create application factory that holds all application profiles
var af = new ApplicationFactory(crypto);
af.addApplicationProfile("ap_jcop_cardmanager.xml");
var aidlist = null;
try {
var jcop = new OutlineCard(of, card, af, aidlist);
jcop.view.show();
}
catch(e) {
print("No card in reader or problem with reset: " + e);
}
© Copyright 2003 - 2013 CardContact Software & System Consulting, Minden, Germany
