Smart Card Guy

Smart Card, Java Card, PCI DSS, IoT Device Security

Java CardからのAPDU処理 - APDU Class

Java CardでのAPDU処理

  • javacard.framework.APDU
  • Card上のAppletはCADと直接やり取りはしない。必ず、JCRE(Java Card Runtime Env)を経由。
  • JCREがAPDU object (APDU buffer - internal byte array)を作成

C-APDU, R-APDUおさらい

C-APDU

f:id:blog-guy:20180630102534p:plain

R-APDU

f:id:blog-guy:20180630102552p:plain

C-APDUの解析

  • appletのprocess methodが呼ばれる際、APDU bufferには最初の5バイトが利用可能
  • 最初の4 byte : APDU Header [CLS, INS, P1, P2]
  • 5 byte目 : length field [P3]

f:id:blog-guy:20190222171540p:plain

Case 1 - No command data, no reponse data

P3 : 0

Case 2 - No command data, send reponse data

P3 : Le field

Case 3 - Receive command data, no reponse data

P3 : Lc field

Case 4 - Receive command data, send reponse data

Case 3とCase 2を合わせたCase

Code Sample (sample HelloWorld)

   public void process(APDU apdu) {
        byte buffer[] = apdu.getBuffer();

        // check SELECT APDU command
        if ((buffer[ISO7816.OFFSET_CLA] == 0) &&
                (buffer[ISO7816.OFFSET_INS] == (byte) (0xA4))) {
            return;
        }

        short bytesRead = apdu.setIncomingAndReceive();
        short echoOffset = (short) 0;

        while (bytesRead > 0) {
            Util.arrayCopyNonAtomic(buffer, ISO7816.OFFSET_CDATA, echoBytes, echoOffset, bytesRead);
            echoOffset += bytesRead;
            bytesRead = apdu.receiveBytes(ISO7816.OFFSET_CDATA);
        }

        apdu.setOutgoing();
        apdu.setOutgoingLength((short) (echoOffset + 5));

        // echo header
        apdu.sendBytes((short) 0, (short) 5);
        // echo data
        apdu.sendBytesLong(echoBytes, (short) 0, echoOffset);
    }

Link