本文整理汇总了Java中javacard.framework.ISO7816.OFFSET_INS属性的典型用法代码示例。如果您正苦于以下问题:Java ISO7816.OFFSET_INS属性的具体用法?Java ISO7816.OFFSET_INS怎么用?Java ISO7816.OFFSET_INS使用的例子?那么恭喜您, 这里精选的属性代码示例或许可以为您提供帮助。您也可以进一步了解该属性所在类javacard.framework.ISO7816
的用法示例。
在下文中一共展示了ISO7816.OFFSET_INS属性的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Java代码示例。
示例1: process
public void process(APDU apdu) {
// Good practice: Return 9000 on SELECT
if (selectingApplet()) {
return;
}
byte[] buf = apdu.getBuffer();
switch (buf[ISO7816.OFFSET_INS]) {
case (byte) 0x00:
handleGetPRand(apdu);
break;
case (byte) 0x01:
handleGetCmac(apdu);
break;
default:
// good practice: If you don't know the INStruction, say so:
ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
}
}
示例2: process
public void process(APDU apdu) {
// Good practice: Return 9000 on SELECT
if (selectingApplet()) {
return;
}
byte[] incomingBuf = apdu.getBuffer();
short length = apdu.setIncomingAndReceive();
if(!usChannel.isSessionSecure()){
usChannel.establishSecureSession(apdu, incomingBuf);
}else{
if(incomingBuf[ISO7816.OFFSET_INS] == 0x20){
usChannel.resetSessionState();
}else{
short decodedLC = usChannel.decodeIncoming(apdu, incomingBuf, length);
if(decodedLC > 0){
usChannel.encodeAndSend(apdu, incomingBuf, ISO7816.OFFSET_CDATA, (short)(incomingBuf[ISO7816.OFFSET_LC] & 0x00FF));
}
}
}
}
示例3: process
@Override
public void process(APDU apdu) {
byte buffer[] = apdu.getBuffer();
byte ins = buffer[ISO7816.OFFSET_INS];
if (apdu.isSecureMessagingCLA()) {
ISOException.throwIt(ISO7816.SW_SECURE_MESSAGING_NOT_SUPPORTED);
}
switch (ins) {
case ISO7816.INS_SELECT:
doSelect(apdu);
break;
case INS_VERIFY_PIN:
doVerifyPin(apdu);
break;
case INS_CHANGE_REFERENCE_DATA:
doChangePIN(apdu);
break;
case INS_GET_DATA:
doGetData(apdu);
break;
case INS_GET_RESPONSE:
io.getResponse(apdu);
break;
case INS_PUT_DATA:
doPutData(apdu);
break;
case INS_GENERATE_ASYMMETRIC_KEYPAIR:
doGenerateKeyPair(apdu);
break;
case INS_GENERAL_AUTHENTICATE:
doGeneralAuthenticate(apdu);
break;
default:
ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
break;
}
}
示例4: process
public void process(APDU apdu) throws ISOException {
if (selectingApplet()) {
return;
}
byte[] buffer = apdu.getBuffer();
short dataLength = (short)2;
switch(buffer[ISO7816.OFFSET_INS]) {
case INS_TEST_EC:
testEc(buffer);
break;
case INS_TEST_ECDH:
testEcdh(buffer);
break;
case INS_TEST_RIPEMD160:
testRipemd160(buffer);
break;
case INS_TEST_SHA512:
testSha512(buffer);
break;
case INS_TEST_BIP32_GEN:
testBip32Gen(buffer);
break;
case INS_TEST_BIP32_DERIVATION:
testBip32Derive(buffer, (buffer[ISO7816.OFFSET_P1] == (byte)0));
break;
default:
ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
}
apdu.setOutgoingAndSend((short)0, dataLength);
}
示例5: decrypt
private void decrypt(APDU apdu) {
byte[] buffer = apdu.getBuffer();
// PW1 with 0x82
if (!pins[PIN_INDEX_PW1].isValidated() || !pinSubmitted[1]) {
ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED);
}
if (!confidentialityKey.getPrivate().isInitialized()) {
ISOException.throwIt(ISO7816.SW_FILE_NOT_FOUND);
}
boolean firstCommand = (commandChainingBuffer[TEMP_INS] != buffer[ISO7816.OFFSET_INS]);
// Mark the command chain as bad so it stays in this state in case of exception.
short len = apdu.setIncomingAndReceive();
if (len < 1) {
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
}
if (firstCommand) {
Util.arrayCopyNonAtomic(buffer, (short) (ISO7816.OFFSET_CDATA + 1), commandChainingBuffer,
TEMP_GET_RESPONSE_DATA, (short) (len - 1));
len = (short) (len - 1);
} else {
short existing = Util.getShort(commandChainingBuffer, TEMP_GET_RESPONSE_LENGTH);
if ((short) (len + existing) > RSA_KEY_LENGTH_BYTES) {
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
}
Util.arrayCopyNonAtomic(buffer, ISO7816.OFFSET_CDATA, commandChainingBuffer,
(short) (TEMP_GET_RESPONSE_DATA + existing), len);
len += existing;
}
if (len < RSA_KEY_LENGTH_BYTES) {
commandChainingBuffer[TEMP_INS] = CMD_COMPUTE_PSO;
Util.setShort(commandChainingBuffer, TEMP_GET_RESPONSE_LENGTH, len);
return; // For compatibily with GPG
}
// We have enough bytes to decrypt.
cipherRSA.init(confidentialityKey.getPrivate(), Cipher.MODE_DECRYPT);
len = cipherRSA.doFinal(commandChainingBuffer, TEMP_GET_RESPONSE_DATA, RSA_KEY_LENGTH_BYTES,
buffer, (short) 0);
apdu.setOutgoingAndSend((short) 0, len);
}
示例6: process
/**
* Process an incoming APDU command, i.e. select the appropriate method
*/
public void process(APDU apdu) {
// Good practice: Return 9000 on SELECT
if (selectingApplet()) return;
// Select the appropriate method
apdu.setIncomingAndReceive();
byte[] buffer = apdu.getBuffer();
switch (buffer[ISO7816.OFFSET_INS]) {
case (byte) 0x01:
initialise(apdu);
break;
case (byte) 0x02:
personalise(apdu);
break;
case (byte) 0x03:
getAttribute(apdu);
break;
case (byte) 0x04:
getKey(apdu);
break;
default:
// Good practice: If you don't know the INStruction, say so:
ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
}
}
示例7: process
public void process(APDU apdu) throws ISOException {
byte[] buff = apdu.getBuffer();
if (selectingApplet()) {
return;
}
// account for logical channels
if (((byte) (buff[ISO7816.OFFSET_CLA] & (byte) 0xFC)) != CLA) {
ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);
}
switch (buff[ISO7816.OFFSET_INS]) {
case INS_GET_STATUS:
getInitStatus(apdu);
break;
case INS_GEN_RANDOM:
prng(apdu);
break;
case INS_GEN_KEY:
generateKeys(apdu);
break;
case INS_ENCRYPT:
encrypt(apdu);
break;
case INS_DECRYPT:
decrypt(apdu);
break;
case INS_CLEAR:
clear(apdu);
break;
default:
ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
}
}
示例8: process
public void process(APDU apdu) throws ISOException {
byte[] buffer = apdu.getBuffer();
if (selectingApplet()) {
if (attestationCertificateSet) {
Util.arrayCopyNonAtomic(VERSION, (short)0, buffer, (short)0, (short)VERSION.length);
apdu.setOutgoingAndSend((short)0, (short)VERSION.length);
}
return;
}
if (buffer[ISO7816.OFFSET_CLA] == PROPRIETARY_CLA) {
if (attestationCertificateSet) {
ISOException.throwIt(ISO7816.SW_SECURITY_STATUS_NOT_SATISFIED);
}
switch(buffer[ISO7816.OFFSET_INS]) {
case FIDO_ADM_SET_ATTESTATION_CERT:
handleSetAttestationCert(apdu);
break;
default:
ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
}
}
else if (buffer[ISO7816.OFFSET_CLA] == FIDO_CLA) {
if (!attestationCertificateSet) {
ISOException.throwIt(ISO7816.SW_SECURITY_STATUS_NOT_SATISFIED);
}
switch(buffer[ISO7816.OFFSET_INS]) {
case FIDO_INS_ENROLL:
handleEnroll(apdu);
break;
case FIDO_INS_SIGN:
handleSign(apdu);
break;
case FIDO_INS_VERSION:
handleVersion(apdu);
break;
case ISO_INS_GET_DATA:
handleGetData(apdu);
break;
default:
ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
}
}
else {
ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);
}
}
示例9: processChainInitialization
public void processChainInitialization(APDU apdu) {
byte buffer[] = apdu.getBuffer();
byte ins = buffer[ISO7816.OFFSET_INS];
// Command chaining checks & initialization
if(chaining_cache[RAM_CHAINING_CACHE_OFFSET_CURRENT_INS] != 0 || isCommandChainingCLA(apdu)) {
short p1p2 = Util.getShort(buffer, ISO7816.OFFSET_P1);
/*
* Command chaining only for:
* - PERFORM SECURITY OPERATION
* - GENERATE ASYMMETRIC KEYKAIR
* - PUT DATA
* when not using extended APDUs.
*/
if( (ins != GidsApplet.INS_PERFORM_SECURITY_OPERATION
&& ins != GidsApplet.INS_GENERATE_ASYMMETRIC_KEYPAIR
&& ins != GidsApplet.INS_PUT_DATA)) {
ISOException.throwIt(ErrorCode.SW_COMMAND_CHAINING_NOT_SUPPORTED);
}
if(chaining_cache[RAM_CHAINING_CACHE_OFFSET_CURRENT_INS] == 0
&& chaining_cache[RAM_CHAINING_CACHE_OFFSET_CURRENT_P1P2] == 0) {
/* A new chain is starting - set the current INS and P1P2. */
if(ins == 0) {
ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
}
chaining_cache[RAM_CHAINING_CACHE_OFFSET_CURRENT_INS] = ins;
chaining_cache[RAM_CHAINING_CACHE_OFFSET_CURRENT_P1P2] = p1p2;
} else if(chaining_cache[RAM_CHAINING_CACHE_OFFSET_CURRENT_INS] != ins
|| chaining_cache[RAM_CHAINING_CACHE_OFFSET_CURRENT_P1P2] != p1p2) {
/* The current chain is not yet completed,
* but an apdu not part of the chain had been received. */
ISOException.throwIt(ErrorCode.SW_COMMAND_NOT_ALLOWED_GENERAL);
} else if(!isCommandChainingCLA(apdu)) {
/* A chain is ending, set the current INS and P1P2 to zero to indicate that. */
chaining_cache[RAM_CHAINING_CACHE_OFFSET_CURRENT_INS] = 0;
chaining_cache[RAM_CHAINING_CACHE_OFFSET_CURRENT_P1P2] = 0;
}
}
// If the card expects a GET RESPONSE, no other operation should be requested.
if(chaining_cache[RAM_CHAINING_CACHE_OFFSET_BYTES_REMAINING] > 0 && ins != GidsApplet.INS_GET_RESPONSE) {
// clear the buffer
Clear(true);
}
if (ins != GidsApplet.INS_PUT_DATA) {
clearCachedRecord();
}
}
示例10: sendData
/**
* \brief Send the data from ram_buf, using either extended APDUs or GET RESPONSE.
*
* \param apdu The APDU object, in STATE_OUTGOING state.
*
* \param pos The position in ram_buf at where the data begins
*
* \param len The length of the data to be sent. If zero, 9000 will be
* returned
*/
private void sendData(APDU apdu) {
short le;
short remaininglen = 0;
byte data[] = null;
short pos = chaining_cache[RAM_CHAINING_CACHE_OFFSET_CURRENT_POS];
le = apdu.setOutgoing();
// le has not been set
if(le == 0) {
// we get here when called from the Shared VMWare reader
byte ins = apdu.getBuffer()[ISO7816.OFFSET_INS];
if ( ins != GidsApplet.INS_GENERATE_ASYMMETRIC_KEYPAIR) {
le = 256;
} else {
le = 0;
}
}
if (chaining_object[CHAINING_OBJECT] == null) {
data = ram_buf;
remaininglen = chaining_cache[RAM_CHAINING_CACHE_OFFSET_BYTES_REMAINING];
} else if (chaining_object[CHAINING_OBJECT] instanceof Record) {
Record record = (Record) (chaining_object[CHAINING_OBJECT]);
data = record.GetData();
remaininglen = (short) (((short) data.length) - pos);
} else if (chaining_object[CHAINING_OBJECT] instanceof Record[]) {
data = ram_buf;
remaininglen = copyRecordsToRamBuf(le);
pos = 0;
}
// We have 256 Bytes send-capacity per APDU.
short sendLen = remaininglen > le ? le : remaininglen;
apdu.setOutgoingLength(sendLen);
apdu.sendBytesLong(data, pos, sendLen);
// the position when using Record[] is maintened by copyRecordsToRamBuf
if (chaining_object[CHAINING_OBJECT] == null || !(chaining_object[CHAINING_OBJECT] instanceof Record[])) {
chaining_cache[RAM_CHAINING_CACHE_OFFSET_CURRENT_POS]+= sendLen;
}
if (chaining_object[CHAINING_OBJECT] == null) {
chaining_cache[RAM_CHAINING_CACHE_OFFSET_BYTES_REMAINING] -= sendLen;
}
remaininglen -= sendLen;
if(remaininglen > 0) {
short nextRespLen = remaininglen > 256 ? 256 : remaininglen;
ISOException.throwIt( (short)(ISO7816.SW_BYTES_REMAINING_00 | nextRespLen) );
} else {
Clear(true);
return;
}
}
示例11: process
/**
* \brief Processes an incoming APDU.
*
* \see APDU.
*
* \param apdu The incoming APDU.
*/
public void process(APDU apdu) {
byte buffer[] = apdu.getBuffer();
byte ins = buffer[ISO7816.OFFSET_INS];
// No secure messaging at the moment
if((buffer[ISO7816.OFFSET_CLA] & 0x0C) != 0) {
ISOException.throwIt(ISO7816.SW_SECURE_MESSAGING_NOT_SUPPORTED);
}
transmitManager.processChainInitialization(apdu);
if((buffer[ISO7816.OFFSET_CLA] & 0xE0) == 0) {
switch (ins) {
case INS_ACTIVATE_FILE:
fs.processActivateFile(apdu);
break;
case INS_CREATE_FILE:
fs.processCreateFile(apdu);
break;
case INS_CHANGE_REFERENCE_DATA:
pinManager.processChangeReferenceData(apdu);
break;
case INS_DELETE_FILE:
fs.processDeleteFile(apdu);
break;
case INS_GENERAL_AUTHENTICATE:
pinManager.processGeneralAuthenticate(apdu);
break;
case INS_GENERATE_ASYMMETRIC_KEYPAIR:
processGenerateAsymmetricKeypair(apdu);
break;
case INS_GET_DATA:
processGetData(apdu);
break;
case INS_GET_RESPONSE:
transmitManager.processGetResponse(apdu);
break;
case INS_MANAGE_SECURITY_ENVIRONMENT:
processManageSecurityEnvironment(apdu);
break;
case INS_PERFORM_SECURITY_OPERATION:
processPerformSecurityOperation(apdu);
break;
case INS_PUT_DATA:
processPutData(apdu);
break;
case INS_RESET_RETRY_COUNTER:
pinManager.processResetRetryCounter(apdu);
break;
case ISO7816.INS_SELECT:
fs.processSelectFile(apdu, selectingApplet());
break;
case INS_TERMINATE_DF:
processTerminateDF(apdu);
break;
case INS_VERIFY:
pinManager.processVerify(apdu);
break;
default:
ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
} // switch
} else {
ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);
}
}
示例12: establishSecureSession
/**
* Handles all key agreement (secure channel initialization) operation according to the current state of the secure channel
*
* @param apdu apdu reference for the APDU object used by this Applet
* @param incomingBuf reference to the APDU buffer that contains key agreement (secure channel initialization) data
* @throws CardException
*/
public void establishSecureSession(APDU apdu, byte[] incomingBuf) {
byte ins = incomingBuf[ISO7816.OFFSET_INS];
if ((connectionTries < MAX_PASSWORD_TRY_LIMIT) ) {
switch (ins) {
case INS_KEY_AGREEMENT_01:
Util.arrayFillNonAtomic(temp_outputBuf, (short)0x00, (short)0x300, (byte)0x00);
currentStage[(short) 0x00] = 0x00;
if(usmileKeyAgreement.initWithSRP(apdu, incomingBuf)){
currentStage[(short) 0x00] = 0x01;
}
break;
case INS_KEY_AGREEMENT_02:
if (currentStage[(short) 0x00] == 0x01) {
connectionTries++;
if (usmileKeyAgreement.authenticate(apdu, incomingBuf)){
currentStage[(short) 0x00] = 0x02;
usmileSecureMessaging.initSecureMessaging(temp_outputBuf, (short)0x00, (short)0x20);
if(incomingBuf[ISO7816.OFFSET_P1] == INS_PASSWORD_CHANGE){
currentStage[(short) 0x00] = 0x03;
}else{
sessionState[0] = 0x01;
connectionTries = (byte)0x00;
}
} else {
ISOException.throwIt(ISO7816.SW_DATA_INVALID);
}
}
break;
case INS_PASSWORD_CHANGE:
/**
* for changing password
* in the authentication stage if INS and P1 are set 04 ... calculate key agreement static values again
*
* and reset the session. Session has to be reestablished using the new password
*/
if(currentStage[ 0x00] == 0x03){
short len = usmileSecureMessaging.unwrapApdu(incomingBuf, (short)(incomingBuf[ISO7816.OFFSET_LC] & 0xff));
Util.arrayFillNonAtomic(temp_outputBuf, (short)0x00, (short)0x340, (byte)0x00);
Util.arrayCopy(incomingBuf, ISO7816.OFFSET_CDATA, temp_outputBuf, (short)0x00, len);
/**
* clear password from the incoming buffer
*/
Util.arrayFillNonAtomic(incomingBuf, ISO7816.OFFSET_CDATA, len, (byte)0x00);
usmileKeyAgreement.staticComputations(temp_outputBuf, (byte) 0, len);
currentStage[(short) 0x00] = 0x00;
connectionTries = (byte)0x00;
resetSessionState();
}
break;
default:
break;
}
} else if (connectionTries >= MAX_PASSWORD_TRY_LIMIT ) {
// terminate ...
ISOException.throwIt(SW_BLOCKED);
}
}
示例13: generateAsymetricKey
/**
* GENERATE KEY APDU implementation.
*/
private void generateAsymetricKey(APDU apdu) {
byte[] buffer = apdu.getBuffer();
//lc=2
if (apdu.setIncomingAndReceive() != 1) {
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
}
KeyPair key = getKey(buffer[ISO7816.OFFSET_CDATA]);
if (buffer[ISO7816.OFFSET_P1] == (byte) 0x81) {
if (!(key.getPublic()).isInitialized()) {
ISOException.throwIt(ISO7816.SW_FILE_NOT_FOUND);
}
} else {
if (!pins[PIN_INDEX_PW3].isValidated()) {
ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED);
}
JCSystem.beginTransaction();
key.genKeyPair();
if (buffer[ISO7816.OFFSET_CDATA] == (byte)0xB6) {
signatureCounter[0] = 0;
signatureCounter[1] = 0;
signatureCounter[2] = 0;
}
JCSystem.commitTransaction();
}
// Send the TLV data and public exponent using the APDU buffer.
buffer[ISO7816.OFFSET_CDATA] = 0x7F;
buffer[(short) (ISO7816.OFFSET_CDATA + 1)] = 0x49;
buffer[(short) (ISO7816.OFFSET_CDATA + 2)] = (byte) 0x82;
buffer[(short) (ISO7816.OFFSET_CDATA + 5)] = (byte) 0x82;
short length = ((RSAPublicKey) key.getPublic()).getExponent(
buffer, (short) (ISO7816.OFFSET_CDATA + 7));
buffer[(short) (ISO7816.OFFSET_CDATA + 6)] = (byte) length;
short pos = (short) (ISO7816.OFFSET_CDATA + 7 + length);
buffer[pos] = (byte) 0x81;
buffer[(short) (pos + 1)] = (byte) 0x82;
Util.setShort(buffer, (short) (pos + 2), RSA_KEY_LENGTH_BYTES);
Util.setShort(buffer, (short) (ISO7816.OFFSET_CDATA + 3),
(short) (pos + RSA_KEY_LENGTH_BYTES - ISO7816.OFFSET_CDATA - 1));
apdu.setOutgoingAndSend(ISO7816.OFFSET_CDATA, (short) (length + 11));
// And the modulus using get response.
Util.setShort(commandChainingBuffer, TEMP_GET_RESPONSE_LENGTH, RSA_KEY_LENGTH_BYTES);
((RSAPublicKey) key.getPublic()).getModulus(commandChainingBuffer, TEMP_GET_RESPONSE_DATA);
// Skip leading zero byte.
if (commandChainingBuffer[TEMP_GET_RESPONSE_DATA] == 0) {//��==0 ��GetModulusʧ��
Util.setShort(commandChainingBuffer, TEMP_GET_RESPONSE_OFFSET,
(short) (TEMP_GET_RESPONSE_DATA + 1));
} else {
Util.setShort(commandChainingBuffer, TEMP_GET_RESPONSE_OFFSET, TEMP_GET_RESPONSE_DATA);
}
commandChainingBuffer[TEMP_INS] = buffer[ISO7816.OFFSET_INS];
ISOException.throwIt(ISO7816.SW_BYTES_REMAINING_00);
}
示例14: process
public void process(APDU apdu) throws ISOException {
if(selectingApplet()) {
return;
}
short sendlen = 0;
short recvlen = apdu.setIncomingAndReceive();
byte[] buf = apdu.getBuffer();
byte ins = buf[ISO7816.OFFSET_INS];
KeyPair pair = null;
byte operation = 0;
if((ins & 0x0f) == 0x01) {
operation = GENERATE;
} else if((ins & 0x0f) == 0x02) {
operation = SIGN;
} else {
ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
}
switch(ins & 0xf0) {
case 0x00:
pair = brainpoolp256r1;
break;
case 0x10:
pair = secp256r1;
break;
case 0x20:
pair = brainpoolp320r1;
break;
case 0x30:
pair = brainpoolp256t1;
break;
case 0x40:
pair = secp256k1;
break;
case 0x50:
pair = gost2001;
break;
case 0x60:
pair = frp256v1;
break;
default:
ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
}
if(operation == GENERATE) {
pair.genKeyPair();
ECPublicKey pubKey = (ECPublicKey) pair.getPublic();
sendlen = pubKey.getW(buf, _0);
} else if(operation == SIGN) {
signature.init(pair.getPrivate(), Signature.MODE_SIGN);
sendlen = signature.sign(buf, ISO7816.OFFSET_CDATA, recvlen, buf, _0);
}
if(sendlen > 0) {
apdu.setOutgoingAndSend(_0, sendlen);
}
}
示例15: process
@Override
public void process(APDU apdu) throws ISOException {
if (selectingApplet()) {
return;
}
byte[] buffer = apdu.getBuffer();
if (buffer[ISO7816.OFFSET_CLA] != NFCFORUM_CLA) {
ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);
}
switch(buffer[ISO7816.OFFSET_INS]) {
case INS_SELECT: {
apdu.setIncomingAndReceive();
short selectedFile = Util.getShort(buffer, ISO7816.OFFSET_CDATA);
switch(selectedFile) {
case EF_CONTAINER:
scratch[OFFSET_SELECTED_FILE] = SELECTED_FILE_CONTAINER;
break;
case EF_NDEF:
scratch[OFFSET_SELECTED_FILE] = SELECTED_FILE_NDEF;
break;
default:
ISOException.throwIt(ISO7816.SW_FILE_NOT_FOUND);
}
}
break;
case INS_READ: {
short offset = Util.makeShort(buffer[ISO7816.OFFSET_P1], buffer[ISO7816.OFFSET_P2]);
if (scratch[OFFSET_SELECTED_FILE] == SELECTED_FILE_NONE) {
ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED);
}
byte[] fileData = null;
switch(scratch[OFFSET_SELECTED_FILE]) {
case SELECTED_FILE_CONTAINER:
fileData = CONTAINER_DATA;
break;
case SELECTED_FILE_NDEF:
fileData = FILE_DATA;
break;
}
if (offset >= (short)fileData.length) {
ISOException.throwIt(ISO7816.SW_INCORRECT_P1P2);
}
short sizeRead = (short)(buffer[ISO7816.OFFSET_LC] & 0xff);
short blockLength = (((short)(offset + sizeRead) > (short)fileData.length) ? (short)(fileData.length - offset) : sizeRead);
Util.arrayCopyNonAtomic(fileData, offset, buffer, (short)0, blockLength);
apdu.setOutgoingAndSend((short)0, blockLength);
}
break;
}
}