Wrong CAP file version error message
I'm trying to write a loader application that will send a CAP file into JavaCard, and then install it automatically.
I have developed my JavaCard Applet by using Eclipse3.1.0 and JCOP30.
After running my JavaCard Applet by Eclipse, I got its CAP file in folder [b\bin\FVSCardPkg\javacard\
But when I run my loader application with this CAP file, the error message will display:
EX: msg Wrong CAP file version, class class com.ibm.jc.JCException
Wrong CAP file version
at com.ibm.jc.CapFile.parseHeader(Unknown Source)
at com.ibm.jc.CapFile.readCapFile(Unknown Source)
at com.ibm.jc.CapFile.<init>(Unknown Source)
at LoaderPkg.loader.load(loader.java:35)
at LoaderPkg.loader.main(loader.java:20)
This is my loader application source code:
import java.io.*;
import com.ibm.jc.*;
import com.ibm.jc.terminal.*;
/**
* Sample /**
* Sample loader. Demonstrates how to use the offcard API to download
* a cap-file on a JCOP41V22 Engineering sample card and listing of applets loaded will
* follow.
*/
publicclass loader{
privatefinalstatic String termName ="pcsc:4";// Real card
//private final static String termName = "Remote"; // Simulator
protectedstaticfinalbyte[] JCOP_CARD_MANAGER_AID ={ (byte) 0xa0, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00};
protectedstaticfinalbyte defaultInstallParam[] ={ -55, 0};
static String[] capFileName={"D:/MyCardPkg.cap"};
publicstaticvoid main(String[] args){
try{
loader l =new loader();
l.load();
}catch(Exception e){
System.err.println("EX: msg " + e.getMessage() +", class " + e.getClass());
e.printStackTrace(System.err);
}
System.exit(0);
//Likewise for simulation, be patient the port takes time to close.
//Use command line "netstate" to check the disapperance of the port before
// activating JCShell command to read the simulated card.
}
private loader(){}
privatevoid load()throws Exception{
CapFile capFile =new CapFile(capFileName[0],null);
System.out.println("Package name: " + capFile.pkg);
byte[][] applets = capFile.aids;
if ((applets ==null) || (applets.length == 0)){
thrownew RuntimeException("no applets in cap file");
}
// Get connection to terminal, take note that jcop.exe is required to be activated
// in simulation mode.
System.out.println("Open terminal ...");
//Make sure that the simulator jcop.exe is activated before unmarking this satement
//Remember to delete the downloaded applet before running otherwise error is
//expected if the simulator finds the existence of the applet with the
//same pakage name ID and AID
//Issue /close command at "cm" prompt if the card is in use,, ie it should
//have "-" prompt. Be patient that the port takes time to close. Use command line
//"netstate" to check the disapperance of the port before running.
// pcsc:4=Card Terminal Or Remote=LocalHost Terminal
JCTerminal term = JCTerminal.getInstance(termName,null);
//For real JCOP41V22 card, please unmark this statement and delete the downloaded
//applet before running. Error expected if the card finds the existence of the applet
//with the same pakage name ID and AID
//Issue /close command at "cm" prompt if the card is in use,, ie it should
//have "-" prompt.
term.open();
// Add in this statement for real card which requires some response time
term.waitForCard(5000);
// Create a logging terminal spitting out the APDUs on standard out
TraceJCTerminal _term =new TraceJCTerminal();
_term.setLog(new PrintWriter(System.out));
_term.init(term);
term = _term;
// Get JavaCard representative, passing NULL resets card and returns ATR
System.out.println("Get card ...");
JCard card =new JCard(term, null, 2000);
// Get the off-card representative for the card manager and use it to
// select the on-card CardManager
System.out.println("Select card manager ...");
CardManager cardManager =new CardManager(card, CardManager.daid);
cardManager.select();
// For downloading something, we have to be authenticated to card manager.
// For this, the keys must be set. The keys to use should of course
// be configurable as well.
byte[] dfltKey = c2b("404142434445464748494a4b4c4d4e4f");
cardManager.setKey(new OPKey(255, 1, OPKey.DES_ECB, dfltKey));
cardManager.setKey(new OPKey(255, 2, OPKey.DES_ECB, dfltKey));
cardManager.setKey(new OPKey(255, 3, OPKey.DES_ECB, dfltKey));
cardManager.setKey(new OPKey(1, 1, OPKey.DES_ECB, c2b("707172737475767778797a7b7c7d7e7f")));
cardManager.setKey(new OPKey(1, 2, OPKey.DES_ECB, c2b("606162636465666768696a6b6c6d6e6f")));
cardManager.setKey(new OPKey(1, 3, OPKey.DES_ECB, c2b("505152535455565758595a5b5c5d5e5f")));
System.out.println("init Update ...");
cardManager.initializeUpdate(255,0);
System.out.println("Authenticate to card manager ...");
cardManager.externalAuthenticate(OPApplet.APDU_CLR);
// And load the cap-file, do not forget to call installForLoad
System.out.println("Loading cap-file ...");
byte[] cardManagerAid = cardManager.getAID();
cardManager.installForLoad(capFile.pkgId,0, capFile.pkgId.length, cardManagerAid, 0, cardManagerAid.length, null, 0, null, 0, 0, null, 0);
cardManager.load(capFile, null, CardManager.LOAD_ALL, null, cardManager.getMaxBlockLen());
byte[] capaid = capFile.aids[0];
System.out.println("Finished loading !");
// Install applet, we try to install the first applet given in the
// cap file, and try to instantiate it under the same AID as given for its
// representation in the cap file. No installation data is passed.
System.out.println("Installing applet ...");
cardManager.installForInstallAndMakeSelectable(capFile.pkgId, 0, capFile.pkgId.length, capaid,0, capaid.length, capaid, 0, capaid.length, 0, defaultInstallParam, 0, defaultInstallParam.length, null, 0);
System.out.println("Install succeeded!");
// synchronize state with on-card card manager
System.out.println("Update!");
cardManager.update();
// Print information regarding card manager, applets and packages on-card
JCInfo info = JCInfo.INFO;
System.out.println("\nCardManager AID : " + JCInfo.dataToString(cardManager.getAID()));
System.out.println("CardManager state : " + info.toString("card.status", (byte) cardManager.getState()) +"\n");
//Echountered error 6A 86 with this statement:Object[] app = cardManager.getApplets(CardManager.GET_APPLETS,
//CardManager.CVM_FORMAT_HEX, true);
//Solved the bug by playing the integers in arg0 and arg1.
Object[] app = cardManager.getApplets(1,true);
if (app ==null){
System.out.println("No applets installed on-card");
}else{
System.out.println("Applets:");
for (int i = 0; i < app.length; i++){
System.out.println(info.toString("applet.status", (byte) ((OPApplet) app[i]).getState()) +" " + JCInfo.dataToString(((OPApplet) app[i]).getAID()));
}
}
// List packages on card
// Encountered error with this statement:Object[] lf = cardManager.getLoadFiles(CardManager.CVM_FORMAT_HEX, true);
// Solved the bug by setting arg0 = 0,
Object[] lf = cardManager.getLoadFiles(true);
if (lf ==null){
System.out.println("No packages installed on-card");
}else{
System.out.println("Packages:");
for (int i = 0; i < lf.length; i++){
System.out.println(info.toString("loadfile.status", (byte)((LoadFile) lf[i]).getState()) +" " + JCInfo.dataToString(((LoadFile) lf[i]).getAID()));
}
}
term.close();
}
static String numbers ="0123456789abcdef";
privatebyte[] c2b(String s){
if (s ==null)returnnull;
if (s.length() % 2 != 0)thrownew RuntimeException("invalid length");
byte[] result =newbyte[s.length() / 2];
for (int i = 0; i < s.length(); i += 2){
int i1 = numbers.indexOf(s.charAt(i));
if (i1 == -1)thrownew RuntimeException("invalid number");
int i2 = numbers.indexOf(s.charAt(i + 1));
if (i2 == -1)thrownew RuntimeException("invalid number");
result[i / 2] = (byte) ((i1 << 4) | i2);
}
return result;
}
}
How to solve this problem?
Thank you in advance.

