⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 javapursecrypto.java

📁 一个javacard的身份验证程序
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
     *     * @param transactionType type of transaction.     * @param amount transaction amount.     * @return new balance     */    private short checkTransactionValues(byte transactionType, short amount) {        short newBalance;        short currentBalance = Util.getShort(balancesRecord, OFFSET_BAL_CURRENT);        short maxBalance = Util.getShort(balancesRecord, OFFSET_BAL_MAX);        short maxAmount = Util.getShort(balancesRecord, OFFSET_AMOUNT_MAX);        switch (transactionType) {        case CREDIT : {            newBalance = (short)(currentBalance + amount);            transientShorts[NEW_BALANCE_IX] = newBalance;            if (newBalance > maxBalance || newBalance < 0) 	//to prevent rollover            ISOException.throwIt(SW_CREDIT_TOO_HIGH);            break;        }        case DEBIT : {            if (amount > maxAmount) ISOException.throwIt(SW_AMOUNT_TOO_HIGH);            newBalance = (short)(currentBalance - amount);            transientShorts[NEW_BALANCE_IX] = newBalance;            if (newBalance < 0)ISOException.throwIt(SW_NOT_ENOUGH_FUNDS);            break;        }        default	:            ISOException.throwIt(ISO7816.SW_INCORRECT_P1P2);        }        transientShorts[CURRENT_BALANCE_IX] = currentBalance;        return currentBalance;    }        /**     * Updates PIN.     * @param apdu APDU object     * @param PIN OwnerPIN object (masterPIN or userPIN)     */        private void updatePIN(APDU apdu, OwnerPIN PIN) {        byte[] buffer = apdu.getBuffer();        PIN.update(buffer, (short)(TLV_OFFSET + 2),	buffer[TLV_OFFSET + 1]);    }        /**     * Set JavaPurse in personalized state.     * It happens only once - after the first update of masterPIN     */        private void setIsPersonalized() {        if (!isPersonalized) isPersonalized = true;//happens only once    }        /**     * Update value of a Expiration Date or ID_Purse. Also updates corresponding     * records in Parameters File     * @param apdu APDU object     * @param value the byte array to be updated     */        private void updateParameterValue(APDU apdu, byte[] value) {        byte[] buffer = apdu.getBuffer();        Util.arrayCopyNonAtomic(buffer, (short)(TLV_OFFSET + 2), value,             START, buffer[TLV_OFFSET + 1]);        updateParametersFile(apdu);    }        /**     * Updates values of maximum balance or maximum amount for transaction in the     * balancesRecord.     * @param apdu APDU object     * @param offset the offset in balancesRecord to be updated     */        private void updateBalanceValue(APDU apdu, short offset) {        byte[] buffer = apdu.getBuffer();        Util.arrayCopyNonAtomic(buffer, (short)(TLV_OFFSET + 2),             balancesRecord, offset, SHORT_LENGTH);    }        /**     * Updates record in Parameters File.     * @param apdu APDU object     */        private void updateParametersFile(APDU apdu) {        byte[] buffer = apdu.getBuffer();        byte recordNumber = parametersFile.findRecord(buffer[TLV_OFFSET]);//match tag                if (recordNumber == (byte)0) {            /*             * The record is not found. We have to create a new record.             * NOTE: This is an example that a requirement to perform all memory             * allocations (all "new") in class constructor is not an absolute one.             */            byte[] newRecord = new byte[buffer[TLV_OFFSET + 1] + 2];            Util.arrayCopyNonAtomic(buffer, TLV_OFFSET, newRecord, START,            (short)(buffer[TLV_OFFSET + 1] + 2));            parametersFile.addRecord(newRecord);        } else {            byte[] theRecord = parametersFile.getRecord(recordNumber);            Util.arrayCopyNonAtomic(buffer, TLV_OFFSET, theRecord, START,                (short)(buffer[TLV_OFFSET + 1] + 2));        }    }        /**     * Selects file by FID according to ISO7816-4.     * This implementation doesn't support all variations of SELECT command     * in the standard, but provides reasonable subset for selection by FID     * (P1==2).     * @param apdu APDU object     */        private void processSelectFile(APDU apdu) {                byte[] buffer = apdu.getBuffer();                // get the apdu data        apdu.setIncomingAndReceive();                if (buffer[ISO7816.OFFSET_P1] == (byte)2) {                        //  select file by FID            if ( buffer[ISO7816.OFFSET_LC] != (byte)2)                ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);            short fid = Util.getShort(buffer, ISO7816.OFFSET_CDATA);            switch (fid) {            case PARAMETERS_FID:            case TRANSACTION_LOG_FID:            case BALANCES_FID:                transientShorts[SELECTED_FILE_IX] = fid;                break;            default:                  ISOException.throwIt(ISO7816.SW_FILE_NOT_FOUND);            }        } else            ISOException.throwIt(ISO7816.SW_FUNC_NOT_SUPPORTED);    }        /**     * Reads a record by the record number or reads the first occurrence     * of the record by the record identifier.     * This implementation doesn't support all variations of READ RECORD command     * in the ISO 7816-4 standard, but provides reasonable subset of it.	It is     * here to demonstrate that even without "built-in" support for ISO 7816     * File System an Applet can have the behavior prescribed by the standard.     *     * @param apdu APDU object     */        private void processReadRecord(APDU apdu) {            // used to hold the record read        byte record[] = null;        short fid = 0;                // get the APDU buffer and fields in the APDU header        byte buffer[] = apdu.getBuffer();        byte P1 = buffer[ISO7816.OFFSET_P1];        byte P2 = buffer[ISO7816.OFFSET_P2];                // process file selection here  according to ISO 7816-4, 6.5.3        // P2 = xxxxxyyy        // if xxxxx = 0, use the current selected file        //    xxxxx(not all equal) = other value, select EF by SFI as        //         specified in xxxxx                if ( (P2 >> 3) == 0 ) {            if (transientShorts[SELECTED_FILE_IX] == (short)0)                ISOException.throwIt(ISO7816.SW_COMMAND_NOT_ALLOWED);            else                 fid = transientShorts[SELECTED_FILE_IX];        } else {            // Short file identifier            byte sfi = (byte) ( ( P2 >> 3 ) & 0x1F );            fid = Util.makeShort(FID_BYTE, sfi);            switch (fid) {            case PARAMETERS_FID:            case TRANSACTION_LOG_FID:            case BALANCES_FID:                transientShorts[SELECTED_FILE_IX] = fid;                break;            default:                  ISOException.throwIt(ISO7816.SW_FILE_NOT_FOUND);            }        }                // check for security status (validated PIN)        switch (fid) {        case TRANSACTION_LOG_FID:        case BALANCES_FID:            if (!userPIN.isValidated())                ISOException.throwIt(ISO7816.SW_SECURITY_STATUS_NOT_SATISFIED);            break;        case PARAMETERS_FID:            if (!masterPIN.isValidated())                ISOException.throwIt(ISO7816.SW_SECURITY_STATUS_NOT_SATISFIED);        }                // get the last three bits of P2        P2 = (byte) (P2 & 0x07);                // select the record by record number        if ( ( P2 & 0x04 ) != 0 ){                        if ( P2 == 0x04 ) {            // P1 = 00 indicates in ISO 7816-4 the current record: we don't            // support it in this implementation            if (P1 == 0)                ISOException.throwIt(ISO7816.SW_RECORD_NOT_FOUND);            switch (fid) {            case BALANCES_FID:                // There is only one record in balancesRecord                if (P1 == 1)                    record = balancesRecord;                else                     ISOException.throwIt(ISO7816.SW_RECORD_NOT_FOUND);                break;            case TRANSACTION_LOG_FID:                record = transactionLogFile.getRecord(P1);                break;            case PARAMETERS_FID:              record = parametersFile.getRecord(P1);            }                        if (record == null)                ISOException.throwIt(ISO7816.SW_FILE_NOT_FOUND);          } else            ISOException.throwIt(ISO7816.SW_FUNC_NOT_SUPPORTED);        } else {            // select record by record identifier (first byte of the record)                        // read the first occurrence            if ( P2 == 0) {                switch (fid) {                case BALANCES_FID:                    // There is only one record in balancesRecords                    if (balancesRecord[0] == P1)                        record = balancesRecord;                    else                         ISOException.throwIt(ISO7816.SW_RECORD_NOT_FOUND);                    break;                case TRANSACTION_LOG_FID:                    P1 = transactionLogFile.findRecord(P1);                    if  (P1 == 0 )                        ISOException.throwIt(ISO7816.SW_RECORD_NOT_FOUND);                    else                        record = transactionLogFile.getRecord(P1);                    break;                case PARAMETERS_FID:                    P1 = parametersFile.findRecord(P1);                    if  (P1 == 0 )                        ISOException.throwIt(ISO7816.SW_RECORD_NOT_FOUND);                    else                        record = parametersFile.getRecord(P1);                }            } else {                // function not supported, when P2 = 1, 2, 3                ISOException.throwIt(ISO7816.SW_FUNC_NOT_SUPPORTED);            }        }                // set the data transfer direction to outbound        short Le = apdu.setOutgoing();                // if Lr < Le, set Le == Lr        // otherwise send exactly Le bytes back        if (record.length < Le) {          Le = (short)record.length;        }                apdu.setOutgoingLength(Le);        apdu.sendBytesLong(record, (short)0, Le);    }        /**     * Updates loyalty program.     * It takes standard TLV record for Parameter Update, interprets first     * two bytes as loyaltyCAD (to be compared with first two bytes of CAD ID     * in a transaction), the rest of record as AID for loyalty applet.     * In case of successful retrieval of Shareable Interface Object with this AID     * it is stored as an element of array, and method grantPoints of this loyalty     * applet will be called in transaction to grant loyalty points. If SIO is not     * returned, or loyaltyCAD in parameter is 0 the corresponding elements in     * loyaltyCAD  and loyaltySIO arrays are cleared. The Parameters File is updated.     *     * @param apdu APDU object     * @param loyaltyIndex index to loyaltyCAD and loyaltySIO arrays     * @see com.sun.javacard.JavaLoyalty.JavaLoyalty     */        private void updateLoyaltyProgram(APDU apdu, byte loyaltyIndex) {        byte[] buffer = apdu.getBuffer();        loyaltyCAD[loyaltyIndex] = Util.getShort(buffer,(short) (TLV_OFFSET+2));        if (loyaltyCAD[loyaltyIndex] != (short)0) {                        AID loyaltyAID =  JCSystem.lookupAID(buffer, (short) (TLV_OFFSET+4),                (byte)(buffer[TLV_OFFSET+1]-2));            if (loyaltyAID != null) {                loyaltySIO[loyaltyIndex] = (JavaLoyaltyInterface)                JCSystem.getAppletShareableInterfaceObject(loyaltyAID, (byte)0);                if (loyaltySIO[loyaltyIndex] == null)                    loyaltyCAD[loyaltyIndex] = (short)0;            } else                loyaltyCAD[loyaltyIndex] = (short)0;        }        if (loyaltyCAD[loyaltyIndex] == (short)0) {            // clean-up            buffer[TLV_OFFSET+1] = (byte)2;            Util.arrayFillNonAtomic (buffer,(short) (TLV_OFFSET+2),                (short) (buffer.length - TLV_OFFSET - 2), (byte)0);        }        updateParametersFile(apdu);    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -