implement GET DATA + STORE DATA
This commit is contained in:
parent
add5da6ce8
commit
7edee9c594
|
@ -25,6 +25,8 @@ public class KeycardApplet extends Applet {
|
|||
static final byte INS_SIGN = (byte) 0xC0;
|
||||
static final byte INS_SET_PINLESS_PATH = (byte) 0xC1;
|
||||
static final byte INS_EXPORT_KEY = (byte) 0xC2;
|
||||
static final byte INS_GET_DATA = (byte) 0xCA;
|
||||
static final byte INS_STORE_DATA = (byte) 0xE2;
|
||||
|
||||
static final short SW_REFERENCED_DATA_NOT_FOUND = (short) 0x6A88;
|
||||
|
||||
|
@ -35,6 +37,7 @@ public class KeycardApplet extends Applet {
|
|||
static final byte KEY_PATH_MAX_DEPTH = 10;
|
||||
static final byte PAIRING_MAX_CLIENT_COUNT = 5;
|
||||
static final byte UID_LENGTH = 16;
|
||||
static final byte MAX_DATA_LENGTH = 127;
|
||||
|
||||
static final short CHAIN_CODE_SIZE = 32;
|
||||
static final short KEY_UID_LENGTH = 32;
|
||||
|
@ -141,6 +144,8 @@ public class KeycardApplet extends Applet {
|
|||
|
||||
private byte[] derivationOutput;
|
||||
|
||||
private byte[] data;
|
||||
|
||||
/**
|
||||
* Invoked during applet installation. Creates an instance of this class. The installation parameters are passed in
|
||||
* the given buffer.
|
||||
|
@ -201,6 +206,8 @@ public class KeycardApplet extends Applet {
|
|||
|
||||
derivationOutput = JCSystem.makeTransientByteArray((short) (Crypto.KEY_SECRET_SIZE + CHAIN_CODE_SIZE), JCSystem.CLEAR_ON_RESET);
|
||||
|
||||
data = new byte[MAX_DATA_LENGTH + 1];
|
||||
|
||||
register(bArray, (short) (bOffset + 1), bArray[bOffset]);
|
||||
}
|
||||
|
||||
|
@ -283,6 +290,12 @@ public class KeycardApplet extends Applet {
|
|||
case INS_EXPORT_KEY:
|
||||
exportKey(apdu);
|
||||
break;
|
||||
case INS_GET_DATA:
|
||||
getData(apdu);
|
||||
break;
|
||||
case INS_STORE_DATA:
|
||||
storeData(apdu);
|
||||
break;
|
||||
default:
|
||||
ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
|
||||
break;
|
||||
|
@ -1434,6 +1447,52 @@ public class KeycardApplet extends Applet {
|
|||
secureChannel.respond(apdu, len, ISO7816.SW_NO_ERROR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes the GET DATA command.
|
||||
*
|
||||
* @param apdu the JCRE-owned APDU object.
|
||||
*/
|
||||
private void getData(APDU apdu) {
|
||||
byte[] apduBuffer = apdu.getBuffer();
|
||||
|
||||
if (secureChannel.isOpen()) {
|
||||
secureChannel.preprocessAPDU(apduBuffer);
|
||||
}
|
||||
|
||||
short outLen = Util.makeShort((byte) 0x00, data[0]);
|
||||
Util.arrayCopyNonAtomic(data, (short) 1, apduBuffer, SecureChannel.SC_OUT_OFFSET, outLen);
|
||||
|
||||
if (secureChannel.isOpen()) {
|
||||
secureChannel.respond(apdu, outLen, ISO7816.SW_NO_ERROR);
|
||||
} else {
|
||||
apdu.setOutgoingAndSend(SecureChannel.SC_OUT_OFFSET, outLen);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes the STORE DATA command. Requires an open secure channel and the PIN to be verified.
|
||||
*
|
||||
* @param apdu the JCRE-owned APDU object.
|
||||
*/
|
||||
private void storeData(APDU apdu) {
|
||||
byte[] apduBuffer = apdu.getBuffer();
|
||||
secureChannel.preprocessAPDU(apduBuffer);
|
||||
|
||||
if (!pin.isValidated()) {
|
||||
ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED);
|
||||
}
|
||||
|
||||
short dataLen = Util.makeShort((byte) 0x00, apduBuffer[ISO7816.OFFSET_LC]);
|
||||
|
||||
if (dataLen > MAX_DATA_LENGTH) {
|
||||
ISOException.throwIt(ISO7816.SW_WRONG_DATA);
|
||||
}
|
||||
|
||||
JCSystem.beginTransaction();
|
||||
Util.arrayCopy(apduBuffer, ISO7816.OFFSET_LC, data, (short) 0, (short)(dataLen + 1));
|
||||
JCSystem.commitTransaction();
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method to verify if all the bytes in the buffer between off (included) and off + len (excluded) are digits.
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue