/** * Process the READ BINARY instruction (0xB0) ISO7816-4 Section 7.2.3 * * <p>We handle only the INS == 0xB0 case. */ private void processReadBinary(APDU apdu) { if (state != STATE_PERSONALISED) { ISOException.throwIt(SW_CONDITIONS_NOT_SATISFIED); } byte[] buf = apdu.getBuffer(); byte p1 = buf[OFFSET_P1]; byte p2 = buf[OFFSET_P2]; short offset = 0; short ef = -1; if ((byte) (p1 & MASK_SFI) == MASK_SFI) { byte sfi = (byte) (p1 & ~MASK_SFI); if (sfi >= 0x1F) { ISOException.throwIt(SW_INCORRECT_P1P2); } ef = fileSystem.findCurrentSFI(sfi); if (ef == -1) { ISOException.throwIt(SW_FILE_NOT_FOUND); } ef = fileSystem.fileStructure[ef]; offset = unsigned(p2); } else { ef = fileSystem.getCurrentIndex(); if (fileSystem.getFile(ef) == null) { ISOException.throwIt(SW_COMMAND_NOT_ALLOWED); } offset = Util.makeShort(p1, p2); } byte[] file = fileSystem.getFile(ef); if (offset > file.length) { ISOException.throwIt(SW_INCORRECT_P1P2); } if (fileSystem.getPerm(ef) == FileSystem.PERM_PIN && !pin.isValidated()) { ISOException.throwIt(SW_SECURITY_STATUS_NOT_SATISFIED); } short le = apdu.setOutgoing(); if (le == 0 || le == 256) { le = (short) (file.length - offset); if (le > 256) le = 256; } boolean eof = false; if ((short) (file.length - offset) < le) { le = (short) (file.length - offset); eof = true; } apdu.setOutgoingLength(le); apdu.sendBytesLong(file, offset, le); if (eof) { ISOException.throwIt(SW_END_OF_FILE); } }
/** * Processes an incoming APDU. * * @see APDU * @param apdu the incoming APDU * @exception ISOException with the response bytes per ISO 7816-4 */ public void process(APDU apdu) { byte buffer[] = apdu.getBuffer(); 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); }
// Common method that sets the size of the output to the global variable size and sends the // content of the global variable output private void send(APDU apdu) { apdu.setOutgoing(); apdu.setOutgoingLength(size); apdu.sendBytesLong(output, (short) 0, size); }