Java Examples for javacard.framework.APDU

The following java examples will help you to understand the usage of javacard.framework.APDU. These source code samples are taken from different open source projects.

Example 1
Project: jcardsim-master  File: SimulatorRuntime.java View source code
/**
     * Transmit APDU to previous selected applet
     * @param command command apdu
     * @return response apdu
     */
public byte[] transmitCommand(byte[] command) throws SystemException {
    activateSimulatorRuntimeInstance();
    final ApduCase apduCase = ApduCase.getCase(command);
    final byte[] theSW = new byte[2];
    byte[] response;
    Applet applet = getApplet(getAID());
    selecting = false;
    // check if there is an applet to be selected
    if (!apduCase.isExtended() && isAppletSelectionApdu(command)) {
        AID newAid = findAppletForSelectApdu(command, apduCase);
        if (newAid != null) {
            deselect(lookupApplet(getAID()));
            currentAID = newAid;
            applet = getApplet(getAID());
            selecting = true;
        } else if (applet == null) {
            Util.setShort(theSW, (short) 0, ISO7816.SW_APPLET_SELECT_FAILED);
            return theSW;
        }
    }
    if (applet == null) {
        Util.setShort(theSW, (short) 0, ISO7816.SW_COMMAND_NOT_ALLOWED);
        return theSW;
    }
    if (apduCase.isExtended()) {
        if (applet instanceof ExtendedLength) {
            usingExtendedAPDUs = true;
        } else {
            Util.setShort(theSW, (short) 0, ISO7816.SW_WRONG_LENGTH);
            return theSW;
        }
    } else {
        usingExtendedAPDUs = false;
    }
    responseBufferSize = 0;
    APDU apdu = getCurrentAPDU();
    try {
        if (selecting) {
            boolean success;
            try {
                success = applet.select();
            } catch (Exception e) {
                success = false;
            }
            if (!success) {
                throw new ISOException(ISO7816.SW_APPLET_SELECT_FAILED);
            }
        }
        // set apdu
        resetAPDU(apdu, apduCase, command);
        applet.process(apdu);
        Util.setShort(theSW, (short) 0, (short) 0x9000);
    } catch (Throwable e) {
        Util.setShort(theSW, (short) 0, ISO7816.SW_UNKNOWN);
        if (e instanceof CardException) {
            Util.setShort(theSW, (short) 0, ((CardException) e).getReason());
        } else if (e instanceof CardRuntimeException) {
            Util.setShort(theSW, (short) 0, ((CardRuntimeException) e).getReason());
        }
    } finally {
        selecting = false;
        resetAPDU(apdu, null, null);
    }
    // if theSW = 0x61XX or 0x9XYZ than return data (ISO7816-3)
    if (theSW[0] == 0x61 || (theSW[0] >= (byte) 0x90 && theSW[0] <= (byte) 0x9F)) {
        response = new byte[responseBufferSize + 2];
        Util.arrayCopyNonAtomic(responseBuffer, (short) 0, response, (short) 0, responseBufferSize);
        Util.arrayCopyNonAtomic(theSW, (short) 0, response, responseBufferSize, (short) 2);
    } else {
        response = theSW;
    }
    return response;
}
Example 2
Project: CardExamples-master  File: STPayP.java View source code
/**
     * Processes incoming APDU command.
     * <p>
     * Supported commands (<b>CLA INS</b>):
     * <ul>
     * <li><b>00 A4</b>: Select
     * <li><b>80 50</b>: Initialize Update [from Issuer]
     * <li><b>80 80</b>: Get Card Profile [from card agent]
     * <li><b>80 82</b>: Get PTP_SUK [from card agent]
     * <li><b>80 84</b>: Get Mobile Key [from card agent]
     * <li><b>80 90</b>: Send Agent Notification [from Issuer]
     * <li><b>80 A0</b>: Initialize Mobile PIN [from card agent]
     * <li><b>80 E2</b>: Store Data [from Issuer]
     * <li><b>80 F0</b>: Set Status [from Issuer]
     * <li><b>84 82</b>: External Authenticate [from Issuer]
     * <li><b>84 E2</b>: Store Data, Secured [from Issuer]
     * <li><b>84 F0</b>: Set Status, Secured [from Issuer]
     * </ul>
     * 
     * @param apdu
     *            the incoming <code>APDU</code> object
     * @see javacard.framework.Applet.process
     */
public void process(APDU apdu) throws ISOException {
    byte[] apduBuffer = apdu.getBuffer();
    byte protocolMedia = (byte) (APDU.getProtocol() & APDU.PROTOCOL_MEDIA_MASK);
    if (selectingApplet()) {
        // Check if card is terminated.
        if (this.gpState == GPSystem.CARD_TERMINATED) {
            ISOException.throwIt(ISO7816.SW_FUNC_NOT_SUPPORTED);
        }
        // Check if P1=0x04 and P2=0x00.
        if (Util.getShort(apduBuffer, ISO7816.OFFSET_P1) != (short) 0x0400) {
            ISOException.throwIt(ISO7816.SW_INCORRECT_P1P2);
        }
        // Check AID, partial select not supported.
        short aidLength = apdu.setIncomingAndReceive();
        if (!JCSystem.getAID().equals(apduBuffer, ISO7816.OFFSET_CDATA, (byte) aidLength)) {
            ISOException.throwIt(ISO7816.SW_FILE_NOT_FOUND);
        }
        // Create/reset global transient data.
        // NOTE: Buffer contents should already be reset. This forces reset.
        Util.arrayFillNonAtomic(this.transientByteBuffer, (short) 0, Constants.SIZE_TBB, (byte) 0x00);
        // Construct Select response data.
        if (protocolMedia == APDU.PROTOCOL_MEDIA_SOFT) {
            // Return VERSION if Select command is from card agent.
            apdu.setOutgoingAndSend((short) 0, Util.arrayCopyNonAtomic(VERSION, (short) 0, apduBuffer, (short) 0, (short) VERSION.length));
            return;
        } else // Check if applet is not personalized.
        if (this.gpState != GPSystem.SECURITY_DOMAIN_PERSONALIZED) {
            // Set FCI Template tag.
            apduBuffer[(byte) 0] = Constants.TAG_FCI_TEMPLATE;
            // Set DF Name tag.
            apduBuffer[(byte) 2] = Constants.TAG_DF_NAME;
            // Set DF Name length and DF Name value.
            apduBuffer[(byte) 3] = JCSystem.getAID().getBytes(apduBuffer, (short) 4);
            // Set FCI Template length.
            apduBuffer[(byte) 1] = (byte) (apduBuffer[(byte) 3] + (byte) 2);
            // Send Select response.
            apdu.setOutgoingAndSend((short) 0, (short) (apduBuffer[(byte) 1] + (byte) 2));
            // Go to Personalized state.
            this.transientByteBuffer[Constants.TBB_OFFSET_STATE] = Constants.APP_STATE_PERSO;
            return;
        }
        // Retrieve personalized FCI response and send Select response.
        apdu.setOutgoingAndSend((short) 0, Util.arrayCopyNonAtomic(this.selectResponse, (short) 0, apduBuffer, (short) 0, (short) this.selectResponse.length));
        // Go to Selected state.
        this.transientByteBuffer[Constants.TBB_OFFSET_STATE] = Constants.APP_STATE_SELECTED;
        // IF 'Application Blocked' in Previous Transaction History is set
        if ((this.personalizedPersistentByteBuffer[Constants.PPBB_OFFSET_PREVIOUS_TRANSACTION_HISTORY] & Constants.PREVIOUS_TRANSACTION_HISTORY_BIT_APP_BLOCKED) != (byte) 0x00) {
            // Return FCI with SW=0x6283.
            ISOException.throwIt(Constants.SW_WARNING_SELECTED_FILE_INVALIDATED);
        }
        return;
    }
    // Retrieve current application state.
    byte appState = this.transientByteBuffer[Constants.TBB_OFFSET_STATE];
    // Handle commands starting from ones that have higher timing dependence.
    // Get CLA (ignore logical channel bits) and INS.
    short capduClaIns = (short) (Util.getShort(apduBuffer, ISO7816.OFFSET_CLA) & (short) 0xFCFF);
    switch(capduClaIns) {
        case Constants.CLA_INS_GET_CARD_PROFILE:
            {
                if (this.gpState != GPSystem.SECURITY_DOMAIN_PERSONALIZED) {
                    ISOException.throwIt(ISO7816.SW_COMMAND_NOT_ALLOWED);
                }
                if (protocolMedia != APDU.PROTOCOL_MEDIA_SOFT) {
                    ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED);
                }
                try {
                    getCardProfile(apdu);
                    if (this.mobilePin == null) {
                        // Send message to card agent to trigger Mobile PIN initialization.
                        try {
                            sendRemoteNotificationMessage(RMI_FUNCTION_MOBILE_PIN_CHANGE, true);
                        } catch (Exception e) {
                            System.out.println("sendToAgentSecured exception: " + e.getMessage());
                        }
                    }
                } catch (ISOException isoe) {
                    ISOException.throwIt(isoe.getReason());
                }
                return;
            }
        case Constants.CLA_INS_GET_PTP_SUK:
            {
                if (this.gpState != GPSystem.SECURITY_DOMAIN_PERSONALIZED) {
                    ISOException.throwIt(ISO7816.SW_COMMAND_NOT_ALLOWED);
                }
                if (protocolMedia != APDU.PROTOCOL_MEDIA_SOFT) {
                    ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED);
                }
                getPtpSuk(apdu);
                return;
            }
        case Constants.CLA_INS_GET_MOBILE_KEY:
            {
                if (protocolMedia != APDU.PROTOCOL_MEDIA_SOFT) {
                    ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED);
                }
                getMobileKey(apdu);
                return;
            }
        case Constants.CLA_INS_INITIALIZE_MOBILE_PIN:
            {
                if (this.gpState != GPSystem.SECURITY_DOMAIN_PERSONALIZED) {
                    ISOException.throwIt(ISO7816.SW_COMMAND_NOT_ALLOWED);
                }
                if (protocolMedia != APDU.PROTOCOL_MEDIA_SOFT) {
                    ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED);
                }
                // Check if P1=0x00 and P2=0x00.
                if (Util.getShort(apduBuffer, ISO7816.OFFSET_P1) != (short) 0x0000) {
                    ISOException.throwIt(ISO7816.SW_INCORRECT_P1P2);
                }
                short cdataLength = apdu.setIncomingAndReceive();
                // Check if Lc>=4 and Lc<=8.
                if ((cdataLength != (short) (apduBuffer[ISO7816.OFFSET_LC] & (short) 0x00FF)) || (cdataLength < (short) 4) || (cdataLength > (short) 8)) {
                    ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
                }
                this.mobilePin = new byte[cdataLength];
                Util.arrayCopyNonAtomic(apduBuffer, ISO7816.OFFSET_CDATA, this.mobilePin, (short) 0, cdataLength);
                // Send message to card agent to trigger Get PTP_SUK command.
                try {
                    sendRemoteNotificationMessage(RMI_FUNCTION_PTP_SUK, false);
                } catch (Exception e) {
                }
                return;
            }
        case Constants.CLA_INS_SEND_AGENT_NOTIFICATON:
            {
                // Check if P1=0x00 and P2=0x00.
                if (Util.getShort(apduBuffer, ISO7816.OFFSET_P1) != (short) 0x0000) {
                    ISOException.throwIt(ISO7816.SW_INCORRECT_P1P2);
                }
                // Send message to card agent to trigger Get PTP_SUK command.
                try {
                    sendRemoteNotificationMessage(RMI_FUNCTION_PTP_SUK, true);
                } catch (Exception e) {
                    ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED);
                }
                return;
            }
        case Constants.CLA_INS_INITIALIZE_UPDATE:
            {
                // Process Initialize for Update command.
                // NOTE: Allowed post-personalization.
                /*
            // Check if applet is already personalized.
            if (appState != Constants.APP_STATE_PERSO) {
                ISOException.throwIt(ISO7816.SW_COMMAND_NOT_ALLOWED);
            }
            */
                // Obtain handle to SecureChannel interface.
                this.secureChannel = GPSystem.getSecureChannel();
                this.secureChannel.resetSecurity();
                // Use GP API to process the APDU.
                // Note: Returns SW=0x6700 if Lc is not 0x08.
                short respLen = this.secureChannel.processSecurity(apdu);
                apdu.setOutgoingAndSend(ISO7816.OFFSET_CDATA, respLen);
                return;
            }
        case Constants.CLA_INS_EXTERNAL_AUTHENTICATE:
            {
                if (this.secureChannel == null) {
                    ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED);
                }
                // Use GP API to process the APDU.
                // Note: If Initialize Update has not been processed, processSecurity automatically returns SW=0x6985.
                // Note: If External Authenticate has already been processed, processSecurity automatically returns SW=0x6985.
                this.secureChannel.processSecurity(apdu);
                return;
            }
        case Constants.CLA_INS_SET_STATUS:
        case Constants.CLA_INS_SET_STATUS_SECURED:
            {
                // NOTE: Only allowed post-personalization.
                if ((this.gpState == GPSystem.APPLICATION_SELECTABLE) || (this.gpState == GPSystem.CARD_TERMINATED)) {
                    ISOException.throwIt(ISO7816.SW_COMMAND_NOT_ALLOWED);
                }
                // Check if External Authenticate has been performed successfully.
                if ((byte) (this.secureChannel.getSecurityLevel() & SecureChannel.AUTHENTICATED) != SecureChannel.AUTHENTICATED) {
                    ISOException.throwIt(ISO7816.SW_SECURITY_STATUS_NOT_SATISFIED);
                }
                // Check if P1 indicates status type is "Application or Supplementary Security Domain" 
                // and if P2 indicates supported state control.
                byte stateControl = apduBuffer[ISO7816.OFFSET_P2];
                if ((apduBuffer[ISO7816.OFFSET_P1] != (byte) 0x40) || ((stateControl != GPSystem.SECURITY_DOMAIN_PERSONALIZED) && (stateControl != GPSystem.CARD_LOCKED) && (stateControl != GPSystem.CARD_TERMINATED))) {
                    ISOException.throwIt(ISO7816.SW_INCORRECT_P1P2);
                }
                short cdataLength = apdu.setIncomingAndReceive();
                // Check GP security level is C_MAC or C_MAC+C_DECRYPTION.
                if ((this.secureChannel.getSecurityLevel() & (byte) 0x03) >= SecureChannel.C_MAC) {
                    // Use GP API to unwrap data.
                    try {
                        cdataLength = this.secureChannel.unwrap(apduBuffer, (short) 0, (short) (ISO7816.OFFSET_CDATA + cdataLength));
                    } catch (ISOException isoe) {
                        ISOException.throwIt(ISO7816.SW_SECURITY_STATUS_NOT_SATISFIED);
                    }
                    cdataLength -= ISO7816.OFFSET_CDATA;
                }
                // Validate AID.
                apduBuffer[(byte) 64] = JCSystem.getAID().getBytes(apduBuffer, (short) 65);
                if ((cdataLength != apduBuffer[(byte) 64]) || (Util.arrayCompare(apduBuffer, ISO7816.OFFSET_CDATA, apduBuffer, (short) 65, cdataLength) != (byte) 0)) {
                    ISOException.throwIt(ISO7816.SW_WRONG_DATA);
                }
                byte rmiFunction = (byte) 0;
                if (stateControl == GPSystem.SECURITY_DOMAIN_PERSONALIZED) {
                    if (this.gpState != GPSystem.SECURITY_DOMAIN_PERSONALIZED) {
                        // Send message to card agent to indicate card activated.
                        rmiFunction = RMI_FUNCTION_PTP_CP;
                    }
                } else if (stateControl == GPSystem.CARD_LOCKED) {
                    if (this.gpState != GPSystem.CARD_LOCKED) {
                        // Send message to card agent to indicate card deactivated.
                        rmiFunction = RMI_FUNCTION_DEACTIVATE;
                    }
                } else {
                    try {
                        setStateTerminated();
                    } catch (IOException e) {
                    }
                    // Send message to card agent to indicate card terminated.
                    rmiFunction = RMI_FUNCTION_REMOTE_WIPE;
                }
                // Update GP state.
                this.gpState = stateControl;
                if (rmiFunction != (byte) 0) {
                    // Send message to card agent.
                    try {
                        sendRemoteNotificationMessage(rmiFunction, true);
                    } catch (Exception e) {
                        ISOException.throwIt(ISO7816.SW_WARNING_STATE_UNCHANGED);
                    }
                }
                return;
            }
        case Constants.CLA_INS_STORE_DATA:
        case Constants.CLA_INS_STORE_DATA_SECURED:
            {
                // Check if External Authenticate has been performed successfully.
                if ((byte) (this.secureChannel.getSecurityLevel() & SecureChannel.AUTHENTICATED) != SecureChannel.AUTHENTICATED) {
                    ISOException.throwIt(ISO7816.SW_SECURITY_STATUS_NOT_SATISFIED);
                }
                byte p1 = apduBuffer[ISO7816.OFFSET_P1];
                storeData(apdu);
                // Check if last Store Data command.
                if ((p1 & (byte) 0x80) == (byte) 0x80) {
                    // Check perso state.
                    if (appState == Constants.APP_STATE_PERSO) {
                        // Build Card Profile.
                        this.cardProfile.setSfi1Record1(this.records.getRecord((byte) 1, (short) 1));
                        this.cardProfile.setSfi2Record1(this.records.getRecord((byte) 2, (short) 1));
                        this.cardProfile.setSfi2Record2(this.records.getRecord((byte) 2, (short) 2));
                        this.cardProfile.setSfi2Record3(this.records.getRecord((byte) 2, (short) 3));
                        // Check if all mandatory data objects are personalized.
                        // Return DGI or tag of missing data elements separated by 'FF'.
                        short offset = (short) 0;
                        if (this.cardProfile.getTagA5Data() == null) {
                            offset = Util.setShort(apduBuffer, offset, (short) 0x9102);
                        }
                        if ((this.cardProfile.getAip() == null) || (this.cardProfile.getAfl() == null)) {
                            if (offset > (short) 0) {
                                apduBuffer[offset++] = (byte) 0xFF;
                            }
                            offset = Util.setShort(apduBuffer, offset, (short) 0xB005);
                        }
                        if ((this.cardProfile.getSfi1Record1() == null) && (this.cardProfile.getSfi2Record1() == null)) {
                            if (offset > (short) 0) {
                                apduBuffer[offset++] = (byte) 0xFF;
                            }
                            offset = Util.setShort(apduBuffer, offset, (short) 0x0101);
                            apduBuffer[offset++] = (byte) 0xFF;
                            offset = Util.setShort(apduBuffer, offset, (short) 0x0201);
                        }
                        if (!this.mkAC.isInitialized()) {
                            if (offset > (short) 0) {
                                apduBuffer[offset++] = (byte) 0xFF;
                            }
                            offset = Util.setShort(apduBuffer, offset, (short) 0x8000);
                        }
                        if (!this.mkIDN.isInitialized()) {
                            if (offset > (short) 0) {
                                apduBuffer[offset++] = (byte) 0xFF;
                            }
                            offset = Util.setShort(apduBuffer, offset, (short) 0xA006);
                        }
                        if (offset > (short) 0) {
                            apdu.setOutgoingAndSend((short) 0, offset);
                            //ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED);
                            return;
                        }
                        String recordData;
                        int track2DataOffset = 0;
                        if (this.cardProfile.getSfi2Record1() != null) {
                            recordData = DataUtil.byteArrayToHexString(this.cardProfile.getSfi2Record1());
                            track2DataOffset = recordData.indexOf("571") + 4;
                        } else {
                            recordData = DataUtil.byteArrayToHexString(this.cardProfile.getSfi1Record1());
                            track2DataOffset = recordData.indexOf("9F6B1") + 6;
                        }
                        int separatorOffset = recordData.indexOf("D", track2DataOffset);
                        String pan = recordData.substring(track2DataOffset, separatorOffset);
                        String tempExpDate = "20" + recordData.substring(separatorOffset + 1, separatorOffset + 5);
                        Calendar expDate = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
                        expDate.set(Integer.parseInt(tempExpDate.substring(0, 4)), // Next month 0th day which reverts to this month last day.
                        Integer.parseInt(tempExpDate.substring(4)), 0, // Last hour, minute, second of the day.
                        23, 59, 59);
                        try {
                            setStatePersonalized(pan, expDate, "", "");
                        } catch (Exception e) {
                        }
                        // Update application life cycle state to personalized.
                        gpState = GPSystem.SECURITY_DOMAIN_PERSONALIZED;
                    } else if (gpState == GPSystem.SECURITY_DOMAIN_PERSONALIZED) {
                        // Send message to card agent to trigger card update.
                        try {
                            sendRemoteNotificationMessage(RMI_FUNCTION_PTP_CP, true);
                        } catch (Exception e) {
                            ISOException.throwIt(ISO7816.SW_WARNING_STATE_UNCHANGED);
                        }
                    }
                }
                return;
            }
        default:
    }
    // Get CLA byte, ignore logical channels bits.
    byte claByte = (byte) (capduClaIns >> (byte) 8);
    if ((claByte == ISO7816.CLA_ISO7816) || (claByte == Constants.CLA_PROPRIETARY) || (claByte == Constants.CLA_PROPRIETARY_SECURE)) {
        ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
    } else {
        ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);
    }
}
Example 3
Project: AppletPlayground-master  File: CardEdge.java View source code
public void process(APDU apdu) {
    if (selectingApplet())
        ISOException.throwIt(ISO7816.SW_NO_ERROR);
    byte[] buffer = apdu.getBuffer();
    // check SELECT APDU command
    if ((buffer[ISO7816.OFFSET_CLA] == 0) && (buffer[ISO7816.OFFSET_INS] == (byte) 0xA4))
        return;
    // command structure
    if (buffer[ISO7816.OFFSET_CLA] != CardEdge_CLA)
        ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);
    byte ins = buffer[ISO7816.OFFSET_INS];
    if (!setupDone && (ins != (byte) INS_SETUP))
        ISOException.throwIt(SW_SETUP_NOT_DONE);
    if (setupDone && (ins == (byte) INS_SETUP))
        ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
    switch(ins) {
        case INS_SETUP:
            setup(apdu, buffer);
            break;
        case INS_GEN_KEYPAIR:
            GenerateKeyPair(apdu, buffer);
            break;
        case INS_GEN_KEYSYM:
            GenerateSymmetricKey(apdu, buffer);
            break;
        case INS_IMPORT_KEY:
            ImportKey(apdu, buffer);
            break;
        case INS_GET_PUBLIC_FROM_PRIVATE:
            getPublicKeyFromPrivate(apdu, buffer);
            break;
        //			break;
        case INS_COMPUTE_CRYPT:
            ComputeCrypt(apdu, buffer);
            break;
        case INS_COMPUTE_SIGN:
            ComputeSign(apdu, buffer);
            break;
        case INS_VERIFY_PIN:
            VerifyPIN(apdu, buffer);
            break;
        case INS_CREATE_PIN:
            CreatePIN(apdu, buffer);
            break;
        case INS_CHANGE_PIN:
            ChangePIN(apdu, buffer);
            break;
        case INS_UNBLOCK_PIN:
            UnblockPIN(apdu, buffer);
            break;
        case INS_LOGOUT_ALL:
            LogOutAll();
            break;
        //			break;
        case INS_CREATE_OBJ:
            CreateObject(apdu, buffer);
            break;
        case INS_DELETE_OBJ:
            DeleteObject(apdu, buffer);
            break;
        case INS_READ_OBJ:
            ReadObject(apdu, buffer);
            break;
        case INS_WRITE_OBJ:
            WriteObject(apdu, buffer);
            break;
        case INS_SIZE_OBJ:
            GetObjectSize(apdu, buffer);
            break;
        case INS_LIST_PINS:
            ListPINs(apdu, buffer);
            break;
        case INS_LIST_OBJECTS:
            ListObjects(apdu, buffer);
            break;
        case INS_LIST_KEYS:
            ListKeys(apdu, buffer);
            break;
        case INS_GET_STATUS:
            GetStatus(apdu, buffer);
            break;
        case INS_COMPUTE_SHA512:
            // only for debug purpose
            ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
            //computeSha512(apdu, buffer);
            break;
        case INS_COMPUTE_HMAC:
            //ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED); // only for debug purpose
            computeHmac(apdu, buffer);
            break;
        case INS_BIP32_IMPORT_SEED:
            importBIP32Seed(apdu, buffer);
            break;
        case INS_BIP32_GET_AUTHENTIKEY:
            getBIP32AuthentiKey(apdu, buffer);
            break;
        case INS_BIP32_GET_EXTENDED_KEY:
            getBIP32ExtendedKey(apdu, buffer);
            break;
        case INS_SIGN_MESSAGE:
            signMessage(apdu, buffer);
            break;
        case INS_SIGN_SHORT_MESSAGE:
            signShortMessage(apdu, buffer);
            break;
        case INS_SIGN_TRANSACTION:
            SignTransaction(apdu, buffer);
            break;
        case INS_BIP32_SET_EXTENDED_KEY:
            // only for debug purpose
            ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
            //setBIP32ExtendedKey(apdu, buffer);
            break;
        case INS_PARSE_TRANSACTION:
            ParseTransaction(apdu, buffer);
            break;
        //			break;
        default:
            ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
    }
}
Example 4
Project: phoneme-qtopia-master  File: AccessSATImpl.java View source code
/**
     * Sets the data in the out buffer.
     * @param length length of data
     */
public void setOutBufferData(short length) {
    byte[] buffer = apduBuffer;
    outDataSize = Util.arrayCopy(buffer, (short) 0, outBuffer, outDataSize, length);
    // restore the bytes from the original command APDU in
    // the APDU buffer because the data recieved in the 
    // envelope is suppose to be available while
    // in processToolkit method
    Util.arrayCopy(inBuffer, (short) 0, buffer, (short) 0, (short) length);
}
Example 5
Project: ledger-javacard-master  File: LedgerWalletApplet.java View source code
private static void handleGetAttestation(APDU apdu) throws ISOException {
    short offset = (short) 0;
    byte[] buffer = apdu.getBuffer();
    Util.arrayCopyNonAtomic(attestationPublic, (short) 0, buffer, offset, (short) 65);
    offset += (short) 65;
    Util.arrayCopyNonAtomic(attestationSignature, (short) 0, buffer, offset, (short) attestationSignature.length);
    offset += (short) (attestationSignature.length);
    apdu.setOutgoingAndSend((short) 0, offset);
}
Example 6
Project: tem_fw-master  File: TEMApplet.java View source code
public void process(APDU apdu) {
    // Good practice: Return 9000 on SELECT
    if (selectingApplet()) {
        return;
    }
    byte[] buf = apdu.getBuffer();
    byte[] temBuffer;
    byte bufferIndex;
    short bufferSize;
    byte[] outBuffer;
    byte outBufferIndex;
    short outputLength;
    short counterIndex;
    byte keyIndex;
    switch(buf[ISO7816.OFFSET_INS]) {
        ///////////////// LIFECYCLE ///////////////////////////			
        case 0x10:
            /**
			 * 	INS 0x10 -- Activate TEM
			 * Parameters:
			 * 	none
			 * Returns:
			 * 	nothing
			 * Throws:
			 *  69 86 (command not allowed) -- if the tag has not been set
			 * Remarks:
			 *  this should be called in the factory to initialize the TEM
			 */
            if (TEMBuffers.init() == false)
                ISOException.throwIt(ISO7816.SW_COMMAND_NOT_ALLOWED);
            TEMTag.init();
            TEMCrypto.init();
            TEMStore.init();
            TEMExecution.init();
            TEMBuffers.layout();
            JCSystem.requestObjectDeletion();
            TEMApplet.sendSuccess(apdu);
            break;
        case 0x11:
            /**
			 * 	INS 0x11 -- Kill TEM
			 * Parameters:
			 * 	none
			 * Returns:
			 * 	nothing
			 * Throws:
			 *  69 86 (command not allowed) -- if the tag has not been set
			 * Remarks:
			 *  this renders a TEM useless and requires re-issuing
			 *  the TEM applet can be uninstalled once this is called
			 */
            if (TEMBuffers.deinit() == false)
                ISOException.throwIt(ISO7816.SW_COMMAND_NOT_ALLOWED);
            TEMExecution.deinit();
            TEMStore.deinit();
            TEMCrypto.deinit();
            TEMTag.deinit();
            JCSystem.requestObjectDeletion();
            TEMApplet.sendSuccess(apdu);
            break;
        case 0x12:
            /**
		   *  INS 0x12 -- Retrieve TEM firmware version
		   * Parameters:
		   *  none:
		   * Returns:
		   *  
		   */
            TEMApplet.sendSuccessAndShort(apdu, TEMApplet.FIRMWARE_VER);
            break;
        case 0x20:
            /**
			 * 	INS 0x20 -- Allocate buffer
			 * Parameters:
			 * 	(P1, P2) -- buffer size
			 * Returns:
			 * 	byte -- buffer ID (0xFF for failure)
			 * Throws:
			 *  6A 84 (file full) -- if there's not enough memory for the buffer
			 */
            bufferSize = Util.getShort(buf, ISO7816.OFFSET_P1);
            bufferIndex = TEMBuffers.create(bufferSize);
            if (bufferIndex == TEMBuffers.INVALID_BUFFER)
                ISOException.throwIt(ISO7816.SW_FILE_FULL);
            TEMApplet.sendSuccessAndByte(apdu, bufferIndex);
            break;
        case 0x21:
            /**
			 * 	INS 0x21 -- Release buffer
			 * Parameters:
			 * 	P1 -- buffer ID
			 * Returns:
			 * 	nothing
			 * Throws:
			 *  nothing -- an invalid buffer ID is a NOP
			 */
            bufferIndex = buf[ISO7816.OFFSET_P1];
            TEMBuffers.release(bufferIndex);
            TEMApplet.sendSuccess(apdu);
            break;
        case 0x22:
            /**
			 * 	INS 0x22 -- Get buffer length
			 * Parameters:
			 * 	P1 -- buffer ID
			 * Returns:
			 * 	short -- buffer length
			 * Throws:
			 *  6A 86 (incorrect P1P2) -- if given an invalid buffer ID
			 */
            bufferIndex = buf[ISO7816.OFFSET_P1];
            if (!TEMBuffers.isPublic(bufferIndex) || TEMBuffers.pin(bufferIndex) == false)
                ISOException.throwIt(ISO7816.SW_INCORRECT_P1P2);
            TEMApplet.sendSuccessAndShort(apdu, TEMBuffers.size(bufferIndex));
            TEMBuffers.unpin(bufferIndex);
            break;
        case 0x23:
            /**
			 * 	INS 0x23 -- Read buffer chunk
			 * Parameters:
			 * 	P1 -- buffer ID
			 *  P2 -- chunk number (0-based, each chunk is TEMBuffers.chunkSize bytes)
			 * Returns:
			 * 	? bytes -- the requested chunk (exactly TEMBuffers.chunkSize bytes,
			 *                                  unless this is the last chunk)
			 * Throws:
			 *  6A 86 (incorrect P1P2) -- if the buffer ID or chunk number is invalid
			 * Remarks:
			 *  it is possible to get a 0 bytes return if the buffer fits in N chunks
			 *  and P2 == N; this facilitates reading the buffer w/o needing to query
			 *  its length separately
			 */
            bufferIndex = buf[ISO7816.OFFSET_P1];
            short bufferOffset = (short) (buf[ISO7816.OFFSET_P2] * TEMBuffers.chunkSize);
            temBuffer = (TEMBuffers.isPublic(bufferIndex) && TEMBuffers.pin(bufferIndex)) ? TEMBuffers.get(bufferIndex) : null;
            bufferSize = TEMBuffers.size(bufferIndex);
            if (temBuffer == null || bufferOffset > bufferSize)
                ISOException.throwIt(ISO7816.SW_INCORRECT_P1P2);
            apdu.setOutgoing();
            outputLength = (bufferSize - bufferOffset >= TEMBuffers.chunkSize) ? TEMBuffers.chunkSize : (short) (bufferSize - bufferOffset);
            apdu.setOutgoingLength(outputLength);
            apdu.sendBytesLong(temBuffer, bufferOffset, outputLength);
            TEMBuffers.unpin(bufferIndex);
            break;
        case 0x24:
            /**
			 * 	INS 0x24 -- Write buffer chunk
			 * Parameters:
			 * 	P1 -- buffer ID
			 *  P2 -- chunk number (0-based, each chunk is TEMBuffers.chunkSize bytes)
			 *  Lc -- number of bytes to write to the chunk (should be
			 *        TEMBuffers.chunkSize, unless this is the last last chunk)
			 *  Lc bytes -- the chunk data
			 * Returns:
			 *  nothing
			 * Throws:
			 *  6A 86 (incorrect P1P2) -- if the buffer ID or chunk number is invalid
			 */
            bufferIndex = buf[ISO7816.OFFSET_P1];
            bufferOffset = (short) (buf[ISO7816.OFFSET_P2] * TEMBuffers.chunkSize);
            bufferSize = apdu.setIncomingAndReceive();
            temBuffer = (TEMBuffers.isPublic(bufferIndex) && TEMBuffers.pin(bufferIndex)) ? TEMBuffers.get(bufferIndex) : null;
            if (temBuffer == null || (bufferOffset + bufferSize > TEMBuffers.size(bufferIndex)))
                ISOException.throwIt(ISO7816.SW_INCORRECT_P1P2);
            Util.arrayCopyNonAtomic(buf, ISO7816.OFFSET_CDATA, temBuffer, bufferOffset, bufferSize);
            TEMBuffers.unpin(bufferIndex);
            TEMApplet.sendSuccess(apdu);
            break;
        case 0x25:
            /**
			 * INS 0x25 -- Reset and get buffer chunk length.
			 * Parameters:
			 *  none
			 * Returns:
			 *  short -- the length, in bytes, of a buffer chunk
			 */
            TEMBuffers.guessChunkSize();
            TEMApplet.sendSuccessAndShort(apdu, TEMBuffers.chunkSize);
            break;
        case 0x26:
            /**
			 * INS 0x26 -- Releases all the TEM buffers.
			 * Parameters:
			 *  none
			 * Returns:
			 *  nothing
			 */
            TEMBuffers.releaseAll();
            TEMApplet.sendSuccess(apdu);
            break;
        case 0x27:
            /**
			 * INS 0x27 -- Stat the TEM keys or buffers.
			 * Parameters:
			 *  P1 -- 0 for buffers, 1 for keys
			 * Returns:
			 *  the state of the TEM buffers
			 *    3 shorts - available memory
			 *               (PERMANENT, CLEAR_ON_RESET, CLEAR_ON_DESELECT)
			 *    4 bytes for each buffer entry
			 *      byte - buffer type
			 *        0: NOT_A_TRANSIENT_OBJECT 
			 *        1: CLEAR_ON_RESET
			 *        2: CLEAR_ON_DESELECT
			 *        0x40: set if the buffer is taken
			 *        0x80: set if the buffer is pinned
			 *      short - requested buffer length (bytes)
			 *      short - buffer length (bytes)
			 *  the state of the TEM keys
			 *    4 bytes for each allocated key
			 *      byte - key ID
			 *      byte - key type
			 *        0x99: SYMMETRIC_KEY 
			 *        0x55: ASYMMETRIC_PUBKEY
			 *        0xAA: ASYMMETRIC_PRIVKEY
			 *      short - key length (bits)
			 */
            if (buf[ISO7816.OFFSET_P1] == 0)
                bufferSize = TEMBuffers.stat(buf, (short) 0);
            else
                bufferSize = TEMCrypto.stat(buf, (short) 0);
            apdu.setOutgoingAndSend((short) 0, bufferSize);
            break;
        case 0x28:
            /**
       *  INS 0x28 -- Release key
       * Parameters:
       *  P1 -- key ID
       * Returns:
       *  nothing
       * Throws:
       *  nothing -- an invalid key ID is a NOP
       */
            // NOTE: this key-related method must be implemented on production TEMs to
            //       prevent SEClosure DOSing by filling the key store 
            keyIndex = buf[ISO7816.OFFSET_P1];
            TEMCrypto.releaseKey(keyIndex);
            TEMApplet.sendSuccess(apdu);
            break;
        case 0x30:
            /**
			 * 	INS 0x30 -- Set tag
			 * Parameters:
			 * 	P1 -- buffer ID of the buffer containing the tag data
			 * Returns:
			 * 	nothing
			 * Throws:
			 *  69 86 (command not allowed) -- the tag has already been set
			 *  6A 84 (file full) -- there is not enough memory for the tag
			 */
            bufferIndex = buf[ISO7816.OFFSET_P1];
            if (!TEMBuffers.isPublic(bufferIndex) || TEMBuffers.pin(bufferIndex) == false)
                ISOException.throwIt(ISO7816.SW_FILE_FULL);
            temBuffer = TEMBuffers.get(bufferIndex);
            TEMTag.set(temBuffer, (short) 0, TEMBuffers.size(bufferIndex));
            TEMBuffers.unpin(bufferIndex);
            TEMApplet.sendSuccess(apdu);
            break;
        case 0x31:
            /**
			 * 	INS 0x31 -- Get tag length
			 * Parameters:
			 * 	none
			 * Returns:
			 * 	short -- tag length
			 * Throws:
			 *  69 86 (command not allowed) -- the tag has not been set yet
			 */
            if (TEMTag.tag != null)
                TEMApplet.sendSuccessAndShort(apdu, (short) TEMTag.tag.length);
            else
                ISOException.throwIt(ISO7816.SW_COMMAND_NOT_ALLOWED);
            break;
        case 0x32:
            if (TEMTag.tag == null)
                ISOException.throwIt(ISO7816.SW_COMMAND_NOT_ALLOWED);
            bufferIndex = buf[ISO7816.OFFSET_P1];
            bufferOffset = Util.getShort(buf, ISO7816.OFFSET_CDATA);
            bufferSize = Util.getShort(buf, (short) (ISO7816.OFFSET_CDATA + (short) 2));
            temBuffer = (TEMBuffers.isPublic(bufferIndex) && TEMBuffers.pin(bufferIndex)) ? TEMBuffers.get(bufferIndex) : null;
            if (temBuffer == null || (bufferSize > TEMBuffers.size(bufferIndex)))
                ISOException.throwIt(ISO7816.SW_INCORRECT_P1P2);
            Util.arrayCopyNonAtomic(TEMTag.tag, bufferOffset, temBuffer, (short) 0, bufferSize);
            TEMBuffers.unpin(bufferIndex);
            TEMApplet.sendSuccess(apdu);
            break;
        case 0x50:
            if (TEMExecution.status != TEMExecution.STATUS_NOSEC)
                TEMExecution.unbindSec();
            bufferIndex = buf[ISO7816.OFFSET_P1];
            keyIndex = buf[ISO7816.OFFSET_P2];
            if (TEMBuffers.pin(bufferIndex) == false)
                ISOException.throwIt(ISO7816.SW_INCORRECT_P1P2);
            TEMExecution.bindSecPack(keyIndex, bufferIndex);
            TEMBuffers.unpin(bufferIndex);
            if (TEMExecution.status != TEMExecution.STATUS_READY)
                TEMBuffers.release(bufferIndex);
            TEMApplet.sendSuccessAndByte(apdu, ((TEMExecution.status == TEMExecution.STATUS_READY) ? (byte) 1 : (byte) 0));
            break;
        case 0x51:
            /**
			 * 	INS 0x51 -- Unbind SEC
			 * Parameters:
			 *  none
			 * Returns:
			 *  if the SEC executed succesfully 
			 *   byte -- buffer ID of a buffer containing the SEC output
			 *   short -- number of bytes in the SEC output
			 *            (the buffer might be bigger, and padded w/ garbage)
			 *  else
			 *   nothing
			 * Throws:
			 *  69 86 (command not allowed) -- execution engine not in the right state
			 * Remarks:
			 *  the buffer containing the SEC is released before the SEC is executed
			 */
            // abusing keyIndex to mean secStatus
            keyIndex = TEMExecution.status;
            outBufferIndex = TEMExecution.outBufferIndex;
            outputLength = TEMExecution.outLength;
            TEMExecution.unbindSec();
            if (keyIndex == TEMExecution.STATUS_SUCCESS)
                TEMApplet.sendSuccessAndByteShort(apdu, outBufferIndex, outputLength);
            else
                TEMApplet.sendSuccess(apdu);
            break;
        case 0x52:
            /**
			 * 	INS 0x52 -- Execute bound SEC
			 * Parameters:
			 *  none
			 * Returns:
			 *  byte -- status of the execution engine after the SEC execution
			 * Throws:
			 *  6A 86 (incorrect P1P2) -- invalid buffer ID
			 *  69 86 (command not allowed) -- execution engine not in the right state
			 */
            if (TEMExecution.status != TEMExecution.STATUS_READY || TEMBuffers.pin(TEMExecution.i_secBufferIndex) == false)
                ISOException.throwIt(ISO7816.SW_COMMAND_NOT_ALLOWED);
            TEMExecution.execute();
            TEMBuffers.unpin(TEMExecution.i_secBufferIndex);
            TEMApplet.sendSuccessAndByte(apdu, TEMExecution.status);
            break;
        case 0x53:
            /**
			 * 	INS 0x53 -- Solve Persistent Store fault
			 * Parameters:
			 *  short -- the next cell to be used by psnew
			 * Returns:
			 *  nothing
			 * Throws:
			 *  69 86 (command not allowed) -- execution engine not in the right state
			 * Remarks:
			 *  this is a no-op if the SECpack containing the SEC isn't appropriately
			 *  flagged; this command is only implemented on dev TEMs
			 */
            if (TEMExecution.status != TEMExecution.STATUS_PSFAULT)
                ISOException.throwIt(ISO7816.SW_COMMAND_NOT_ALLOWED);
            // abusing outputLength to mean nextCell
            outputLength = Util.getShort(buf, ISO7816.OFFSET_P1);
            TEMExecution.solvePStoreFault(outputLength);
            TEMApplet.sendSuccess(apdu);
            break;
        case (byte) 0x54:
            /**
			 * 	INS 0x54 -- Stat the execution engine
			 * Parameters:
			 *  nothing
			 * Returns:
			 *  the trace (may be empty if the SECpack doesn't allow tracing)
			 * Throws:
			 *  6A 86 (incorrect P1P2) -- if given an invalid buffer ID
			 *  69 86 (command not allowed) -- if the execution engine is not in the right state
			 * Remarks:
			 *  this is a no-op if the SECpack containing the SEC isn't appropriately flagged
			 *  this command is only implemented on dev TEMs
			 */
            bufferSize = TEMExecution.devTrace(buf, (short) 0);
            apdu.setOutgoingAndSend((short) 0, bufferSize);
            break;
        case 0x40:
            /**
			 * 	INS 0x40 -- Generate Key or Key Pair
			 * Parameters:
			 * 	P1 -- key type (0x00 PKS key pair, 0x80 symmetric key)
			 * Returns:
			 *  byte -- key ID of private key
			 *  byte -- key ID of public key (0 for symmetric keys)
			 * Throws:
			 *  6A 84 (file full) -- if there's not enough memory for the keys
			 */
            // generate key pair
            counterIndex = TEMCrypto.generateKey(buf[ISO7816.OFFSET_P1] == 0x00);
            // counterIndex is abused to hold (privKeyIndex, pubKeyIndex)			
            TEMApplet.sendSuccessAndShort(apdu, counterIndex);
            break;
        case 0x41:
            /**
			 * 	INS 0x41 -- Load key
			 * Parameters:
			 * 	P1 -- buffer ID of the buffer containing key data
			 * Returns:
			 * 	byte - key ID of the loaded key
			 * Throws:
			 *  6A 86 (incorrect P1P2) -- if given an invalid buffer ID
			 *  6A 84 (file full) -- if there's not enough memory for the key
			 */
            bufferIndex = buf[ISO7816.OFFSET_P1];
            if (TEMBuffers.pin(bufferIndex) == false)
                ISOException.throwIt(ISO7816.SW_INCORRECT_P1P2);
            temBuffer = TEMBuffers.get(bufferIndex);
            keyIndex = TEMCrypto.loadKey(temBuffer, (short) 0);
            TEMApplet.sendSuccessAndByte(apdu, keyIndex);
            break;
        case 0x42:
            /**
			 * 	INS 0x42 -- Save key
			 * Parameters:
			 * 	P1 -- key ID of the key to be saved
			 * Returns:
			 * 	byte - buffer ID of buffer containing key material
			 *  short - number of bytes in the output key
			 *          (the buffer may be bigger, and padded w/ garbage)
			 * Throws:
			 *  6A 86 (incorrect P1P2) -- if given an invalid key ID
			 *  6A 84 (file full) -- if there's not enough memory for the buffer
			 */
            keyIndex = buf[ISO7816.OFFSET_P1];
            bufferSize = TEMCrypto.getKeyLength(keyIndex);
            bufferIndex = TEMBuffers.create(bufferSize);
            if (TEMBuffers.pin(bufferIndex) == false)
                ISOException.throwIt(ISO7816.SW_INCORRECT_P1P2);
            temBuffer = TEMBuffers.get(bufferIndex);
            outputLength = TEMCrypto.saveKey(keyIndex, temBuffer, (short) 0);
            TEMApplet.sendSuccessAndByteShort(apdu, bufferIndex, outputLength);
            break;
        case 0x43:
        /**
			 * 	INS 0x43 -- Encrypt data
			 * Parameters:
			 * 	P1 -- key ID of the encryption key
			 *  P2 -- buffer ID of the buffer containing the data to be encrypted
			 * Returns:
			 * 	byte - buffer ID of buffer containing encrypted data
			 *  short -- number of bytes in the encrypted output
			 *           (the buffer may be bigger, padded w/ garbage) 
			 * Throws:
			 *  6A 86 (incorrect P1P2) -- if given an invalid key ID or buffer ID
			 *  6A 84 (file full) -- if there's not enough memory for the buffer
			 * Remarks:
			 *  the input buffer is not released automatically
			 */
        case 0x44:
            /**
			 * 	INS 0x44 -- Decrypt data
			 * Parameters:
			 * 	P1 -- key ID of the encryption key
			 *  P2 -- buffer ID of the buffer containing the data to be decrypted
			 * Returns:
			 * 	byte - buffer ID of buffer containing decrypted data
			 *  short -- number of bytes in the decrypted output
			 *           (the buffer may be bigger, amd padded w/ garbage) 
			 * Throws:
			 *  6A 86 (incorrect P1P2) -- if given an invalid key ID or buffer ID
			 *  6A 84 (file full) -- if there's not enough memory for the buffer
			 * Remarks:
			 *  the input buffer is not released automatically
			 */
            keyIndex = buf[ISO7816.OFFSET_P1];
            bufferIndex = buf[ISO7816.OFFSET_P2];
            if (TEMBuffers.pin(bufferIndex) == false)
                ISOException.throwIt(ISO7816.SW_INCORRECT_P1P2);
            temBuffer = TEMBuffers.get(bufferIndex);
            boolean encrypting = (buf[ISO7816.OFFSET_INS] == 0x43);
            bufferSize = TEMBuffers.size(bufferIndex);
            outputLength = (encrypting) ? TEMCrypto.getEncryptedDataSize(keyIndex, bufferSize) : bufferSize;
            outBufferIndex = TEMBuffers.create(outputLength);
            TEMBuffers.pin(outBufferIndex);
            outBuffer = TEMBuffers.get(outBufferIndex);
            if (outBuffer == null)
                ISOException.throwIt(ISO7816.SW_FILE_FULL);
            outputLength = TEMCrypto.cryptWithKey(keyIndex, temBuffer, (short) 0, bufferSize, outBuffer, (short) 0, encrypting);
            TEMBuffers.unpin(outBufferIndex);
            TEMBuffers.unpin(bufferIndex);
            TEMApplet.sendSuccessAndByteShort(apdu, outBufferIndex, outputLength);
            break;
        default:
            // good practice: If you don't know the INStruction, say so:
            ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
    }
}
Example 7
Project: sim-password-manager-master  File: PasswordManagerApplet.java View source code
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);
    }
}
Example 8
Project: sbcred_javacard-master  File: CardApplet.java View source code
/**
     * 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);
    }
}
Example 9
Project: ykneo-openpgp-master  File: OpenPGPSecureMessaging.java View source code
/**
	 * Unwraps (verify and decrypt) the command APDU located in the APDU buffer.
	 * The command buffer has to be filled by the APDU.setIncomingAndReceive()
	 * method beforehand. The verified and decrypted command data get placed at
	 * the start of the APDU buffer.
	 * 
	 * @return the length value encoded by DO97, 0 if this object is missing.
	 */
public short unwrapCommandAPDU() {
    byte[] buf = APDU.getCurrentAPDUBuffer();
    short apdu_p = (short) (ISO7816.OFFSET_CDATA & 0xff);
    short start_p = apdu_p;
    short le = 0;
    short do87DataLen = 0;
    short do87Data_p = 0;
    short do87LenBytes = 0;
    short hdrLen = 4;
    short hdrPadLen = (short) (8 - hdrLen);
    incrementSSC();
    if (buf[apdu_p] == (byte) 0x87) {
        apdu_p++;
        // do87
        if ((buf[apdu_p] & 0xff) > 0x80) {
            do87LenBytes = (short) (buf[apdu_p] & 0x7f);
            apdu_p++;
        } else {
            do87LenBytes = 1;
        }
        if (// sanity check
        do87LenBytes > 2)
            ISOException.throwIt(SW_INTERNAL_ERROR);
        for (short i = 0; i < do87LenBytes; i++) {
            do87DataLen += (short) ((buf[(short) (apdu_p + i)] & 0xff) << (short) ((do87LenBytes - 1 - i) * 8));
        }
        apdu_p += do87LenBytes;
        if (buf[apdu_p] != 1) {
            ISOException.throwIt(SW_INTERNAL_ERROR);
        }
        // store pointer to data and defer decrypt to after mac check (do8e)
        do87Data_p = (short) (apdu_p + 1);
        apdu_p += do87DataLen;
        // compensate for 0x01 marker
        do87DataLen--;
    }
    if (buf[apdu_p] == (byte) 0x97) {
        // do97
        if (buf[++apdu_p] != 1)
            ISOException.throwIt(SW_INTERNAL_ERROR);
        le = (short) (buf[++apdu_p] & 0xff);
        apdu_p++;
    }
    // do8e
    if (buf[apdu_p] != (byte) 0x8e) {
        ISOException.throwIt(SW_INTERNAL_ERROR);
    }
    if (buf[++apdu_p] != 8) {
        ISOException.throwIt(ISO7816.SW_DATA_INVALID);
    }
    // verify mac
    verifier.update(ssc, (short) 0, (short) ssc.length);
    verifier.update(buf, (short) 0, hdrLen);
    verifier.update(PAD_DATA, (short) 0, hdrPadLen);
    if (!verifier.verify(buf, start_p, (short) (apdu_p - 1 - start_p), buf, (short) (apdu_p + 1), MAC_SIZE)) {
        ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED);
    }
    short lc = 0;
    if (do87DataLen != 0) {
        // decrypt data, and leave room for lc
        lc = decipher.doFinal(buf, do87Data_p, do87DataLen, buf, (short) (hdrLen + 1));
        buf[hdrLen] = (byte) (lc & 0xff);
    }
    return le;
}
Example 10
Project: IsoApplet-master  File: IsoApplet.java View source code
/**
     * \brief Processes an incoming APDU.
     *
     * \see APDU.
     *
     * \param apdu The incoming APDU.
     */
@Override
public void process(APDU apdu) {
    byte buffer[] = apdu.getBuffer();
    byte ins = buffer[ISO7816.OFFSET_INS];
    //  - byte 2: Feature bitmap (used to distinguish between applet features)
    if (selectingApplet()) {
        buffer[0] = API_VERSION_MAJOR;
        buffer[1] = API_VERSION_MINOR;
        buffer[2] = api_features;
        apdu.setOutgoingAndSend((short) 0, (short) 3);
        return;
    }
    // No secure messaging at the moment
    if (apdu.isSecureMessagingCLA()) {
        ISOException.throwIt(ISO7816.SW_SECURE_MESSAGING_NOT_SUPPORTED);
    }
    // Command chaining checks
    if (ram_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 (DEF_EXT_APDU || (ins != INS_PERFORM_SECURITY_OPERATION && ins != INS_GENERATE_ASYMMETRIC_KEYPAIR && ins != INS_PUT_DATA)) {
            ISOException.throwIt(ISO7816.SW_COMMAND_CHAINING_NOT_SUPPORTED);
        }
        if (ram_chaining_cache[RAM_CHAINING_CACHE_OFFSET_CURRENT_INS] == 0 && ram_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);
            }
            ram_chaining_cache[RAM_CHAINING_CACHE_OFFSET_CURRENT_INS] = ins;
            ram_chaining_cache[RAM_CHAINING_CACHE_OFFSET_CURRENT_P1P2] = p1p2;
        } else if (ram_chaining_cache[RAM_CHAINING_CACHE_OFFSET_CURRENT_INS] != ins || ram_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(SW_COMMAND_NOT_ALLOWED_GENERAL);
        } else if (!isCommandChainingCLA(apdu)) {
            /* A chain is ending, set the current INS and P1P2 to zero to indicate that. */
            ram_chaining_cache[RAM_CHAINING_CACHE_OFFSET_CURRENT_INS] = 0;
            ram_chaining_cache[RAM_CHAINING_CACHE_OFFSET_CURRENT_P1P2] = 0;
        }
    }
    // If the card expects a GET RESPONSE, no other operation should be requested.
    if (ram_chaining_cache[RAM_CHAINING_CACHE_OFFSET_BYTES_REMAINING] > 0 && ins != INS_GET_RESPONSE) {
        ISOException.throwIt(SW_COMMAND_NOT_ALLOWED_GENERAL);
    }
    if (apdu.isISOInterindustryCLA()) {
        switch(ins) {
            case ISO7816.INS_SELECT:
                fs.processSelectFile(apdu);
                break;
            case INS_READ_BINARY:
                fs.processReadBinary(apdu);
                break;
            case INS_VERIFY:
                processVerify(apdu);
                break;
            case INS_MANAGE_SECURITY_ENVIRONMENT:
                processManageSecurityEnvironment(apdu);
                break;
            case INS_PERFORM_SECURITY_OPERATION:
                processPerformSecurityOperation(apdu);
                break;
            case INS_CREATE_FILE:
                fs.processCreateFile(apdu);
                break;
            case INS_UPDATE_BINARY:
                fs.processUpdateBinary(apdu);
                break;
            case INS_CHANGE_REFERENCE_DATA:
                processChangeReferenceData(apdu);
                break;
            case INS_DELETE_FILE:
                fs.processDeleteFile(apdu);
                break;
            case INS_GENERATE_ASYMMETRIC_KEYPAIR:
                processGenerateAsymmetricKeypair(apdu);
                break;
            case INS_RESET_RETRY_COUNTER:
                processResetRetryCounter(apdu);
                break;
            case INS_GET_RESPONSE:
                processGetResponse(apdu);
                break;
            case INS_PUT_DATA:
                processPutData(apdu);
                break;
            case INS_GET_CHALLENGE:
                processGetChallenge(apdu);
                break;
            default:
                ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
        }
    // switch
    } else {
        ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);
    }
}
Example 11
Project: SatoChipApplet-master  File: CardEdge.java View source code
public void process(APDU apdu) {
    if (selectingApplet())
        ISOException.throwIt(ISO7816.SW_NO_ERROR);
    byte[] buffer = apdu.getBuffer();
    // check SELECT APDU command
    if ((buffer[ISO7816.OFFSET_CLA] == 0) && (buffer[ISO7816.OFFSET_INS] == (byte) 0xA4))
        return;
    // command structure
    if (buffer[ISO7816.OFFSET_CLA] != CardEdge_CLA)
        ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);
    byte ins = buffer[ISO7816.OFFSET_INS];
    if (!setupDone && (ins != (byte) INS_SETUP))
        ISOException.throwIt(SW_SETUP_NOT_DONE);
    if (setupDone && (ins == (byte) INS_SETUP))
        ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
    switch(ins) {
        case INS_SETUP:
            setup(apdu, buffer);
            break;
        case INS_GEN_KEYPAIR:
            GenerateKeyPair(apdu, buffer);
            break;
        case INS_GEN_KEYSYM:
            GenerateSymmetricKey(apdu, buffer);
            break;
        case INS_IMPORT_KEY:
            ImportKey(apdu, buffer);
            break;
        case INS_GET_PUBLIC_FROM_PRIVATE:
            getPublicKeyFromPrivate(apdu, buffer);
            break;
        //			break;
        case INS_COMPUTE_CRYPT:
            ComputeCrypt(apdu, buffer);
            break;
        case INS_COMPUTE_SIGN:
            ComputeSign(apdu, buffer);
            break;
        case INS_VERIFY_PIN:
            VerifyPIN(apdu, buffer);
            break;
        case INS_CREATE_PIN:
            CreatePIN(apdu, buffer);
            break;
        case INS_CHANGE_PIN:
            ChangePIN(apdu, buffer);
            break;
        case INS_UNBLOCK_PIN:
            UnblockPIN(apdu, buffer);
            break;
        case INS_LOGOUT_ALL:
            LogOutAll();
            break;
        //			break;
        case INS_CREATE_OBJ:
            CreateObject(apdu, buffer);
            break;
        case INS_DELETE_OBJ:
            DeleteObject(apdu, buffer);
            break;
        case INS_READ_OBJ:
            ReadObject(apdu, buffer);
            break;
        case INS_WRITE_OBJ:
            WriteObject(apdu, buffer);
            break;
        case INS_SIZE_OBJ:
            GetObjectSize(apdu, buffer);
            break;
        case INS_LIST_PINS:
            ListPINs(apdu, buffer);
            break;
        case INS_LIST_OBJECTS:
            ListObjects(apdu, buffer);
            break;
        case INS_LIST_KEYS:
            ListKeys(apdu, buffer);
            break;
        case INS_GET_STATUS:
            GetStatus(apdu, buffer);
            break;
        case INS_COMPUTE_SHA512:
            // only for debug purpose
            ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
            //computeSha512(apdu, buffer);
            break;
        case INS_COMPUTE_HMAC:
            //ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED); // only for debug purpose
            computeHmac(apdu, buffer);
            break;
        case INS_BIP32_IMPORT_SEED:
            importBIP32Seed(apdu, buffer);
            break;
        case INS_BIP32_GET_AUTHENTIKEY:
            getBIP32AuthentiKey(apdu, buffer);
            break;
        case INS_BIP32_GET_EXTENDED_KEY:
            getBIP32ExtendedKey(apdu, buffer);
            break;
        case INS_SIGN_MESSAGE:
            signMessage(apdu, buffer);
            break;
        case INS_SIGN_SHORT_MESSAGE:
            signShortMessage(apdu, buffer);
            break;
        case INS_SIGN_TRANSACTION:
            SignTransaction(apdu, buffer);
            break;
        case INS_BIP32_SET_EXTENDED_KEY:
            // only for debug purpose
            ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
            //setBIP32ExtendedKey(apdu, buffer);
            break;
        case INS_PARSE_TRANSACTION:
            ParseTransaction(apdu, buffer);
            break;
        //			break;
        default:
            ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
    }
}
Example 12
Project: ant-javacard-master  File: EmptyInt.java View source code
public void process(APDU arg0) throws ISOException {
}