Hello,

I am having major problems creating a file system for a MPCOS-EMV card.
I have attached the code that I am using to create the file system, my
opencard.properties file and the Set Environment batch file as text.

Below is the output I receive with the opencard.properties file as it is
above:

Starting TestMPCOS...

Waiting for card...

Card detected

java.lang.ClassNotFoundException: CardService implementing interface
opencard.op
t.iso.fs.FileSystemCardService
        at
opencard.core.service.CardServiceRegistry.getCardServiceInstance(Card
ServiceRegistry.java:269)
        at
opencard.core.service.SmartCard.getCardService(SmartCard.java:331)
        at TestMPCOS.<init>(TestMPCOS.java:53)
        at TestMPCOS.main(TestMPCOS.java:105)
Press any key to continue . . .



And below is the output I receive if I uncomment:
\
com.gemplus.opencard.service.gpk.file.GPKFileSystemService
in the opencard.properties file:

Starting TestMPCOS...
java.lang.ClassCastException:
com.gemplus.opencard.service.gpk.file.GPKFileSyste
mService
        at
opencard.core.service.SmartCard.configureServiceRegistry(SmartCard.ja
va:218)
        at opencard.core.service.SmartCard.start(SmartCard.java:535)
        at TestMPCOS.main(TestMPCOS.java:96)
Press any key to continue . . .

I'm really stuck on this, Can anyone help me?

Best Regards
John Crook
// Gemplus Imports
import com.gemplus.opencard.service.gpk.admin.AdministrativeCardService;
import com.gemplus.opencard.service.gpk.admin.GPKAdministrativeService;
import com.gemplus.opencard.service.gpk.file.FileUtilityCardService;
import com.gemplus.opencard.service.gpk.file.GPKFileSystemService;
import com.gemplus.opencard.service.gpk.file.GPKFileUtilityService;
import com.gemplus.opencard.service.gpk.security.GPKAdministrativeCredential;
import com.gemplus.opencard.service.gpk.security.GPKCredentialStore;

// Java Imports
import java.security.InvalidKeyException;

// Opencard Imports
import opencard.core.service.*;
import opencard.core.terminal.*;
import opencard.opt.iso.fs.*;
import opencard.opt.iso.fs.FileSystemCardService;
import opencard.opt.security.CredentialBag;

// Cryptix imports
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import javax.crypto.spec.DESKeySpec;

// Class TestMPCOS
public class TestMPCOS{

  private SmartCard sc = null;

  private GPKFileSystemService     fss;
  private GPKFileUtilityService    fus;

  private static final CardFilePath    root = new CardFilePath(":3F00");
  private static final CardFilePath    ef_3F01 = new CardFilePath(":3F00:3F01");
  private static final CardFilePath    df_0200 = new CardFilePath(":3F00:0200");
  private static final CardFilePath    ef_0201 = new CardFilePath(":3F00:0200:0201");

  // Constructor
  public TestMPCOS(SmartCard sc)
      throws CardServiceException, ClassNotFoundException, CardServiceException,
	     CardTerminalException, InvalidKeyException {

    this.sc = sc;

    boolean extAuth = false;

    // Instanciate file CardServices
    fss = (GPKFileSystemService) sc.getCardService(FileSystemCardService.class, true);
    fus = (GPKFileUtilityService) sc.getCardService(FileUtilityCardService.class, true);

    // Provide credentials for Administrative key :3F00:3F01
    CredentialBag               bag = new CredentialBag();
    GPKCredentialStore          store = new GPKCredentialStore();
    GPKAdministrativeCredential credential = new GPKAdministrativeCredential();

    store.storeCredential(0, credential);
    bag.addCredentialStore(store);
    fss.provideCredentials(ef_3F01, bag);

    // Erase Card
    System.out.println("Erasing Card...");
    fus.eraseCard();

    // create DF(0x0200)
    System.out.println("\nCreate DF " + df_0200);
    fus.createDF(df_0200, extAuth, null);

    // create EF(0x0201)
    System.out.println("\nCreate EF " + ef_0201);
    fus.createTransparentFile(ef_0201, 100, null);

    // update binary
    System.out.println("\nUpdate to " + ef_0201);
    byte[] updateData = new byte[100];
    for(int i = 0; i < 100; i++) {
      updateData[i] = (byte)i;
    }
    Util.printBytes("updateData = \n", updateData);
    fss.update(ef_0201, 0, updateData, 0, 100);

    // read binary
    System.out.println("\nRead from " + ef_0201);
    byte[] readData = fss.read(ef_0201, 0, 100);
    Util.printBytes("readData = \n", readData);

  }

  // Main()
  public static void main(String[] args) {
    try {
      SmartCard.start();

      // wait for a smartcard with file access support
      System.out.println("\nWaiting for card...\n");
      CardRequest cr = new CardRequest();
      SmartCard   card = SmartCard.waitForCard(cr);
      System.out.println("Card detected\n");

      // Instantiate the TestMPCOS class
      TestMPCOS test1 = new TestMPCOS(card);

    } catch(Exception e) {
      e.printStackTrace();
    }
    finally {
      try {
        SmartCard.shutdown();
        System.exit(0);
      } catch(Exception e) {
        e.printStackTrace();
      }
    }
  }
}

abstract class Util {

        // Computes teh checksum needed for PK_Send & Load Private Key
        public static byte computePKChecksum(byte[] bArray, int len) {
            // NOTE checksum = COM(XOR(tag||value))
            // COM(X) = X^0xFF
            byte chksum = (byte)0xFF;
            for(int i =0; i<len; i++)
                chksum = (byte)(chksum^bArray[i]);
            return chksum;
        }

        // Swaps the bytes(order) used in PK_Send function
        public static void swapForPKSend(byte[] source, int offSource, byte[] dest, int offDest, int len) {
            int j = len-1;
            for (int i=0; i<len; i++,j--)
                dest[offDest+i] = source[offSource+j];
        }

        // Copies len number of bytes from the array<source>(at offset = offSource) to the array<dest>(offset = offDest).
        public static void arrayCopy(byte[] source, int offSource, byte[] dest, int offDest, int len) {
            for(int i=0; i<len; i++)
                dest[offDest+i] = source[offSource+i];
        }

	    // An utility for debugging...
        public static void debug(boolean deb, String prompt, byte[] byteArray) {
            if(deb)
                Util.printBytes(prompt, byteArray);
        }

	    // An utility to print byte array
        public static void printBytes(String prompt, byte[] byteArray) {
            String strByteArray = Util.toString(byteArray);
            System.out.println(prompt + strByteArray);
        }

        // Does the 3DES encryption.
        public static byte[] doEncrypt(byte[] inpText, byte[] key) throws Exception {
            byte [] tmp = new byte[8];
            try {
                SecretKeySpec skSpecL = new SecretKeySpec(key, 0, 8, new String("DES"));
	            SecretKey kL = (SecretKey)skSpecL;
	            SecretKeySpec skSpecR = new SecretKeySpec(key, 8, 8, new String("DES"));
	            SecretKey kR = (SecretKey)skSpecR;
                Cipher des = Cipher.getInstance("DES"+"/ECB/None");

	            // DES Encrypt
		        des.init(Cipher.ENCRYPT_MODE, kL);
		        tmp = des.doFinal(inpText);
		        // DES Decrypt
		        des.init(Cipher.DECRYPT_MODE, kR);
		        tmp = des.doFinal(tmp);
		        // DES Encrypt
		        des.init(Cipher.ENCRYPT_MODE, kL);
		        tmp = des.doFinal(tmp);
	        }catch(Exception e) {
                e.printStackTrace();
            }
	        return tmp;
        }

        // Computes the 16 bytes 3DES session key
        public static byte[] computeSessionKey(byte[] inpText, byte[] key) throws Exception{
            byte [] tmp = new byte[16];
            try {
                SecretKeySpec skSpecL = new SecretKeySpec(key, 0, 8, new String("DES"));
	            SecretKey kL = (SecretKey)skSpecL;
	            SecretKeySpec skSpecR = new SecretKeySpec(key, 8, 8, new String("DES"));
	            SecretKey kR = (SecretKey)skSpecR;
                Cipher des = Cipher.getInstance("DES"+"/ECB/None");

	            // DES Encrypt
	            des.init(Cipher.ENCRYPT_MODE, kL);
	            byte[] tmp1 = des.doFinal(inpText);
	            // DES Decrypt
	            des.init(Cipher.DECRYPT_MODE, kR);
	            tmp1 = des.doFinal(tmp1);
	            // DES Encrypt
	            des.init(Cipher.ENCRYPT_MODE, kL);
	            tmp1 = des.doFinal(tmp1);

	            // DES Encrypt
	            des.init(Cipher.ENCRYPT_MODE, kR);
	            byte[] tmp2 = des.doFinal(inpText);
	            // DES Decrypt
	            des.init(Cipher.DECRYPT_MODE, kL);
	            tmp2 = des.doFinal(tmp2);
	            // DES Encrypt
	            des.init(Cipher.ENCRYPT_MODE, kR);
	            tmp2 = des.doFinal(tmp2);

	            // Concatenate
                for(int i=0; i<8; i++)
                    tmp[i] = tmp1[i];
                for(int i=0; i<8; i++)
                    tmp[i+8] = tmp2[i];
            }catch(Exception e) {
                e.printStackTrace();
            }
            return tmp;
        }

	    // Returns a byte array from a string of hexadecimal digits.
	    public static byte[] hexFromString(String hex) {
		    int len	= hex.length();
		    byte[] buf = new byte[((len + 1) / 2)];

		    int i =	0, j = 0;
		    if ((len % 2) == 1)
		        buf[j++] = (byte) fromDigit(hex.charAt(i++));

		    while (i < len)	{
		        buf[j++] = (byte) ((fromDigit(hex.charAt(i++)) << 4) |
					    fromDigit(hex.charAt(i++)));
		    }
		    return buf;
	    }


	    // Returns the number from 0 to 15 corresponding to	the hex	digit <i>ch</i>.
	    public static int fromDigit(char	ch) {
		    if (ch >= '0' && ch <= '9')
		        return ch -	'0';
		    if (ch >= 'A' && ch <= 'F')
		        return ch -	'A' + 10;
		    if (ch >= 'a' && ch <= 'f')
		        return ch -	'a' + 10;
		    throw new IllegalArgumentException("invalid hex	digit '" + ch +	"'");
        }


	    //Compares	two byte arrays	for equality.
	    public static boolean areEqual (byte[] a, byte[]	b) {
		    int aLength = a.length;
		    if (aLength != b.length)
		        return false;
		    for (int i = 0;	i < aLength; i++)
		        if (a[i] !=	b[i])
			        return false;
		        return true;
	    }


	    //Returns a string	of hexadecimal digits from a byte array. Each
	    //byte is converted to 2 hex symbols.
	    public static String toString( byte[] ba	) {
		    int length = ba.length;
		    char[] buf = new char[length * 2];
		    for (int i = 0,	j = 0, k; i < length; )	{
		        k =	ba[i++];
		        buf[j++] = HEX_DIGITS[(k >>> 4) & 0x0F];
		        buf[j++] = HEX_DIGITS[ k	    & 0x0F];
		    }
		    return new String(buf);
	    }

	    public static final char[]	HEX_DIGITS = {
		    '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
	    };
}

Attachment: opencard.properties
Description: Binary data

@echo off
rem *************************************************************
rem * Local OCF Configuration                                   * 
rem *************************************************************
rem * Modifying these settings should be sufficient to          *
rem * run the demo applications.                                *
rem *                                                           *
rem * Where the OpenCard Framework is installed                 *
set OCF_INSTALLDIR=C:\OpenCard\OCF1.2\
rem *                                                           *
rem * The next two Variables are only needed when using a       *
rem * Pure Java CardTerminal.                                   *
rem *                                                           *
rem * Path to the Comm API classes (comm.jar)                   *
set OCF_COMMAPI=
rem *                                                           *
rem * Path to the OCF CardTerminal classes provided by          *
rem * the reader hardware vendor                                *
set OCF_PUREJAVA_CARDTERMINAL=
rem *                                                           *
rem * Set Classpath for JDK1.1                                  *
set OCF_CLASSPATH=%CLASSPATH%
rem *                                                           *
rem *************************************************************
rem * No changes should be neccessary below this point.         *
rem *************************************************************


rem *************************************************************
rem * OCF base classes                                          *
rem *************************************************************

set OCF_CLASSPATH=%OCF_CLASSPATH%;%OCF_INSTALLDIR%lib\base-core.jar
set OCF_CLASSPATH=%OCF_CLASSPATH%;%OCF_INSTALLDIR%lib\base-opt.jar
set OCF_CLASSPATH=%OCF_CLASSPATH%;%OCF_INSTALLDIR%lib\reference-services.jar
set OCF_CLASSPATH=%OCF_CLASSPATH%;%OCF_INSTALLDIR%lib\gemplus-gpk-0.1.jar
set OCF_CLASSPATH=%OCF_CLASSPATH%;%OCF_INSTALLDIR%lib\gemplus-service-0.3.jar

rem *************************************************************
rem * Classes needed for OCF demos                              *
rem *************************************************************

set OCF_CLASSPATH=%OCF_CLASSPATH%;%OCF_INSTALLDIR%lib\sb-demo.jar
set OCF_CLASSPATH=%OCF_CLASSPATH%;%OCF_INSTALLDIR%lib\sb-demo-ext.jar


rem *************************************************************
rem * CardTerminal configuration                                *
rem *************************************************************

rem PC/SC CardTerminal classes
set OCF_CLASSPATH=%OCF_CLASSPATH%;%OCF_INSTALLDIR%lib\reference-terminals-windows.jar
rem Add OCF PC/SC dll's to search path
set PATH=%PATH%;%OCF_INSTALLDIR%lib

rem Pure Java CardTermial classes (Java Communications API needed)
set OCF_CLASSPATH=%OCF_CLASSPATH%;%OCF_COMMAPI%
set OCF_CLASSPATH=%OCF_CLASSPATH%;%OCF_PUREJAVA_CARDTERMINAL%

rem *************************************************************
rem * END of configuration                                      *
rem *************************************************************

echo Setting up environment...
echo (Edit %OCF_INSTALLDIR%\demos\setenv.bat
echo to change these settings.)
echo ------------------------------------------------------------ 
echo OCF_INSTALLDIR=%OCF_INSTALLDIR%
echo OCF_CLASSPATH=%OCF_CLASSPATH%
echo PATH=%PATH%
echo ------------------------------------------------------------ 

Reply via email to