package sega.a7; import javacard.framework.JCSystem; import javacard.framework.Util; import javacard.security.MessageDigest; public class Command { protected short m_ee_cmd; protected short m_ee_recvPacketSize; protected short m_ee_sendPacketSize; protected short[] m_ramD_setSendPacketSize; protected short m_ee_tag; protected MakePacket m_ee_packet; protected AppData m_ee_data; protected MessageDigest m_ee_sha1; private static final short ERROR_PACKET_SIZE = 26; protected static final short SET_SEND_PACKET_SIZE_ARRAY_SIZE = 1; protected byte[] m_ramD_outData; protected short[] m_ramD_outDataInfo; public Command(short cmd, short recvPacketSize, short sendPacketSize, AppData data, MakePacket packet, MessageDigest sha1) { this.m_ee_cmd = (short) cmd; this.m_ee_data = data; this.m_ee_packet = packet; this.m_ee_recvPacketSize = (short) recvPacketSize; this.m_ee_sendPacketSize = (short) sendPacketSize; this.m_ee_tag = AppConfig.A7_TAG_RQU_COMMAND; this.m_ee_sha1 = sha1; this.m_ramD_setSendPacketSize = JCSystem.makeTransientShortArray((short) 1, (byte) 1); this.m_ramD_setSendPacketSize[0] = this.m_ee_sendPacketSize; this.m_ramD_outData = data.getSendOutBuffer_ramD(); this.m_ramD_outDataInfo = data.getSendOutInfo_ramD(); } public boolean select() { this.m_ramD_setSendPacketSize[0] = this.m_ee_sendPacketSize; return true; } public short core(byte[] data, short dataOffset, short dataLength) { return AppConfig.A7_SUCCESS; } public short execute(byte[] data, short dataOffset, short dataLength, byte[] dst, short dstOffset, short dstLength) { short ramD_error = checkHeader(data, dataOffset, dataLength); if (ramD_error != AppConfig.A7_SUCCESS) return makeErrorPacket(ramD_error, dst, dstOffset, dstLength); ramD_error = checkFooter(data, dataOffset, dataLength); if (ramD_error != AppConfig.A7_SUCCESS) return makeErrorPacket(ramD_error, dst, dstOffset, dstLength); this.m_ramD_outDataInfo[0] = 0; this.m_ramD_outDataInfo[1] = 0; ramD_error = core(data, dataOffset, dataLength); if (ramD_error != AppConfig.A7_SUCCESS) return makeErrorPacket(ramD_error, dst, dstOffset, dstLength); return makeSendPacket(AppConfig.A7_TAG_RSP_COMMAND, this.m_ramD_setSendPacketSize[0], ramD_error, this.m_ramD_outData, this.m_ramD_outDataInfo[0], this.m_ramD_outDataInfo[1], dst, dstOffset, dstLength); } public short getCmd_ee() { return this.m_ee_cmd; } protected short setSendPacketSize_ramD(short sendSize) { this.m_ramD_setSendPacketSize[0] = sendSize; return this.m_ramD_setSendPacketSize[0]; } /** * Validate packet header. * The header is 6 bytes. * 2 bytes: tag * 2 bytes: paramsize * 2 bytes: command */ protected short checkHeader(byte[] data, short dataOfset, short dataLength) { short ramD_paramsize = Util.getShort(data, (short) (dataOfset + AppConfig.A7_PARAMSIZE_OFFSET)); if (dataLength != ramD_paramsize) return AppConfig.A7_BAD_DATASIZE; short ramD_tag = Util.getShort(data, (short) (dataOfset + AppConfig.A7_TAG_OFFSET)); if (ramD_tag != this.m_ee_tag) return AppConfig.A7_BAD_TAG; if (this.m_ee_recvPacketSize != 0 && dataLength != this.m_ee_recvPacketSize) return AppConfig.A7_BAD_DATASIZE; return AppConfig.A7_SUCCESS; } /** * Validate an unauthenticated packet footer. * The footer is a 20 byte SHA1 sum of the packet. */ protected short checkFooter(byte[] data, short dataOffset, short dataLength) { short ramD_paramsize = (short) (dataOffset + dataLength - AppConfig.A7_CHECKSUM_SIZE); byte[] ramD_buffer = this.m_ee_data.getFooterBuffer_ramD(); this.m_ee_sha1.reset(); this.m_ee_sha1.doFinal(data, dataOffset, (short) (dataLength - AppConfig.A7_CHECKSUM_SIZE), ramD_buffer, (short) 0); if (Util.arrayCompare(data, ramD_paramsize, ramD_buffer, (short) 0, (short) AppConfig.A7_CHECKSUM_SIZE) != 0) return AppConfig.A7_SUMFAIL; return AppConfig.A7_SUCCESS; } protected short makeSendPacket(short tag, short paramSize, short result, byte[] data, short dataOffset, short dataSize, byte[] sendPacket, short packetOffset, short packetLength) { if (!this.m_ee_packet.setData(null, (short) 0, (short) 0, tag, paramSize, result, this.m_ee_cmd, data, dataOffset, dataSize, null, (short) 0, (short) 0, null, (short) 0, (short) 0, sendPacket, packetOffset, packetLength, this.m_ee_sha1, null)) { return makeErrorPacket(AppConfig.A7_FAIL, sendPacket, packetOffset, packetLength); } return paramSize; } protected short makeErrorPacket(short error, byte[] sendPacket, short packetOffset, short packetLength) { this.m_ee_data.setLastError_ramD(error); this.m_ee_packet.setData(null, (short) 0, (short) 0, AppConfig.A7_TAG_RSP_COMMAND, ERROR_PACKET_SIZE, error, this.m_ee_cmd, null, (short) 0, (short) 0, null, (short) 0, (short) 0, null, (short) 0, (short) 0, sendPacket, packetOffset, packetLength, this.m_ee_sha1, null); return ERROR_PACKET_SIZE; } }