Search code examples
smartcardjavacardapdusmartcard-readersmartcardio

How to access Pinpad of a Smartcard Reader when developing a Javacard Applet


I am relatively new to Javacard and I am in the process of developing my own Javacard Applet which works quite well until now. I am also writing a host program to communicate with my card (via APDUs), this program is written in Java and uses the javax.smartcardio library as well as apdu4j.

My goal now is to use my reader's integrated Pinpad to ask the user for a PIN and then forward the entered PIN to the Smartcard which will verify the PIN. I already wrote the code on the card which will verify the PIN (CLA: 0x80, INS: 0x04, P1: 0x00, P2: 0x00, pin data), but I have no idea how to tell the Reader to probe for a PIN and then forward this information to the Card.

My Card is a J3H145 by NXP (Javacard 3.0.4 / ISO7816 / ISO14443) and my Reader is a ReinerSCT cyberJack RFID standard.

Thank you in advance.


Solution

  • If anyone is wondering, I found out how to do it.

    public static byte[] verifyPin(Card card) throws CardException {
        byte[] command = new byte[]{
                0x00, //Timeout
                0x00, //Timeout
                0x00, //Format
                0x0f, //PIN Block
                0x00, //PIN length format
                0x04, //Max PIN size
                0x04, //Min PIN size
                0x02, //Entry validation condition (02 = press OK)
                0x01, //Number of messages
                0x04, //Language
                0x09, //Language
                0x00, //Message index
                0x00, //TeoPrologue
                0x00, 0x00,
                0x04, 0x00, 0x00, 0x00, //APDU length
                (byte) CLA, INS_VERIFY_PIN, 0x00, 0x00};
        return card.transmitControlCommand(CONTROL_CODE_VERIFY, command);
    }
    

    This is java code using javax.smartcardio to verify a PIN. You can read detailed information about the command data here. The CLA and INS_VERIFY_PIN are the desired target for the PIN data (your applet). You can get the CONTROL_CODE_VERIFY with the following code:

    public static void parseControlCodes(Card card) throws CardException {
        int CONTROL_CODE_GET_FEATURES = SCard.CARD_CTL_CODE(3400);
        byte[] res = card.transmitControlCommand(CONTROL_CODE_GET_FEATURES, new byte[0]);
        for(int i = 0; i < res.length; i++){
            if(res[i] == 0x06){
                CONTROL_CODE_VERIFY = ByteBuffer.wrap(res, i+2, 4).getInt();
            }
            
        }
    }
    

    Scard.CARD_CTL_CODE is a method of apdu4j.