FileDocCategorySizeDatePackage
CustomCardAccessor.javaAPI DocJava Card6155Wed Mar 22 21:07:26 GMT 2006com.sun.javacard.clientsamples.securepurseclient

CustomCardAccessor

public class CustomCardAccessor extends Object implements CardAccessor

Fields Summary
private static final byte
INS_SELECT
private static final byte
APDU_CMD_MASK
private static final byte
CLA_ISO7816
private static final byte
CLA_AUTH
private static final byte
INS_AUTH
static final byte
APDU_SM_MASK_TYPE4
private static final boolean
debug
private static final ResourceBundle
msg
private CardAccessor
ca
Constructors Summary
public CustomCardAccessor(CardAccessor ca)
Creates a new instance of CustomCardAccessor

    
           
         
        this.ca = ca;
    
Methods Summary
public booleanauthenticateUser(short ID)

        byte[] externalAuthCommand = new byte[8];
        externalAuthCommand[0] = CLA_AUTH;
        externalAuthCommand[1] = INS_AUTH;

        externalAuthCommand[4] = 2;  // Lc
        externalAuthCommand[5] = (byte)(ID>>8);
        externalAuthCommand[6] = (byte)ID;
        externalAuthCommand[7] = 0x7F;


        try {
            byte[] response = this.exchangeAPDU( externalAuthCommand );
            if(response[response.length-2] != (byte)0x90 || response[response.length-1] != 0x00) return false;
            else return true;
        }catch (Exception e){
            return false;
        }

    
public voidcloseCard()

        ca.closeCard();
    
public byte[]exchangeAPDU(byte[] sendData)
Modifies the data and calls ca.exchangeAPDU to perform the actual send. The data returned from the smart card is returned by this method within the exchangeApdu object

param
apdu The command APDU to be sent to the smart card
return
The response APDU returned from the card. null if none available.
throws
Exception if a communication error or timeout occurred

        
        final boolean select = isSelect(sendData);
        
        
        byte[] dataWithChecksum;
        
        if(select) {
            dataWithChecksum = new byte[ sendData.length ];
            System.arraycopy(sendData, 0, dataWithChecksum, 0, sendData.length);
        }
        else {
            // set secure bits in CLA
            sendData[0] |= APDU_SM_MASK_TYPE4;
            
            dataWithChecksum = new byte[ sendData.length + 2];
            System.arraycopy(sendData, 0, dataWithChecksum, 0, sendData.length-1);
            dataWithChecksum[dataWithChecksum.length-1] = sendData[sendData.length-1];
            
            int Lc = dataWithChecksum[4];
            
            short csum = 0;
            for(short n = 5; n<Lc+5; ++n) {
                csum += sendData[n];
            }
            
            dataWithChecksum[Lc+5] = (byte) (csum>>8);
            dataWithChecksum[Lc+6] = (byte) (csum);
            
            dataWithChecksum[4] += 2;  // increase Lc
            
        }
        
        
        if(debug) {
            for(int i=0; i<dataWithChecksum.length;++i) {
                System.out.print(Integer.toHexString(dataWithChecksum[i] & 0x00FF) + " ");
            }
            System.out.println();
        }
        byte[] receiveDataWithChecksum =  ca.exchangeAPDU( dataWithChecksum );
        
        byte[] receiveData;
        
        if(debug) {
            for(int i=0; i<receiveDataWithChecksum.length;++i) {
                System.out.print(Integer.toHexString(receiveDataWithChecksum[i] & 0x00FF) + " ");
            }
            System.out.println();
            System.out.println();
        }
        
        if(!select)  // verify the checksum
        {
            int Le = receiveDataWithChecksum.length - 2;   // 2 bytes reserved for SW
            
            if(debug) {
                System.out.println("Le=" + Le);
            }
            
            short csum1 = 0;
            for(short n = 2; n<Le; ++n) {
                csum1 += receiveDataWithChecksum[n];
            }
            
            short csum2 = (short)
            (
            (receiveDataWithChecksum[receiveDataWithChecksum.length - 2]<<8)
            |
            (receiveDataWithChecksum[receiveDataWithChecksum.length - 1] & 0x00FF)
            );
            
            if(debug) {
                
                System.out.println("csum1=" + csum1);
                System.out.println("csum2=" + csum2);
            }
            
            if(csum1 != csum2) throw new java.io.IOException(msg.getString("msg01"));
            
            receiveData = new byte[receiveDataWithChecksum.length-2];
            System.arraycopy(receiveDataWithChecksum, 0, receiveData, 0, receiveData.length);
            
        }
        else {
            receiveData = new byte[receiveDataWithChecksum.length];
            System.arraycopy(receiveDataWithChecksum, 0, receiveData, 0, receiveData.length);
            
        }
        
        if(debug) {
            for(int i=0; i<receiveData.length;++i) {
                System.out.print(Integer.toHexString(receiveData[i] & 0x00FF) + " ");
            }
            System.out.println();
            System.out.println();
        }
        
        return receiveData;
    
private booleanisSelect(byte[] buffer)

        if(buffer.length < 2) return false;

        if((buffer[0]&APDU_CMD_MASK)==CLA_ISO7816 && buffer[1]==INS_SELECT) {
            if(debug) {
                System.out.println(msg.getString("msg02"));
            }
            return true;
        }
        else {
            return false;
        }