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

📄 javapursecrypto.java

📁 javacard 程序
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
        // AID    buffer[2] = FCI_AID_TAG;    buffer[3] = JCSystem.getAID().getBytes(buffer, (short)4);    short offset=(short)(3+buffer[3]);        // PROPRIETARY DATA     buffer[offset++] = (byte)FCI_PROPERIETARY.length;     offset = Util.arrayCopyNonAtomic(FCI_PROPERIETARY, (short)0,				     buffer, offset,				     (short)FCI_PROPERIETARY.length);        // FCI template length    buffer[1] = (byte)(offset-(short)2);        apdu.setOutgoingAndSend((short)0, offset);  }    /**   * Handles Initialize Transaction APDU.   * <p>See <em>Java Card 2.1 Reference Implementation User's Guide</em> for details.   *   * @param apdu APDU object   */  private void processInitializeTransaction(APDU apdu)  {    if (transientBools[TRANSACTION_INITIALIZED])      ISOException.throwIt(SW_COMMAND_OUT_OF_SEQUENCE);    if (!userPIN.isValidated())      ISOException.throwIt(ISO7816.SW_SECURITY_STATUS_NOT_SATISFIED);    byte[] buffer = apdu.getBuffer();    if (buffer[ISO7816.OFFSET_LC] != LC_IT)      ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);    if (buffer[ISO7816.OFFSET_P2] != 0)      ISOException.throwIt(ISO7816.SW_INCORRECT_P1P2);    apdu.setIncomingAndReceive();    // get expected data    byte transactionType = buffer[ISO7816.OFFSET_P1];    transientShorts[TRANSACTION_TYPE_IX] = transactionType;    short amount = Util.getShort(buffer, ISO7816.OFFSET_CDATA);    transientShorts[AMOUNT_IX] = amount;        short balance = checkTransactionValues(transactionType, amount);        // Increment TN in Transient Memory & compute signature    short newTN = (short)(TN + 1);    transientShorts[TN_IX] = newTN;    Util.arrayCopyNonAtomic(buffer, CAD_ID_OFFSET, CAD_ID_array, START, ID_LENGTH);        // Send	R-APDU    short offset = Util.arrayCopyNonAtomic(ID_Purse, START, buffer, START, ID_LENGTH);    offset = Util.arrayCopyNonAtomic(ExpDate, START, buffer, offset, DATE_LENGTH);    offset = Util.setShort(buffer, offset, balance);    offset = Util.setShort(buffer, offset, newTN);    // The crypto processing could be done here    sig.init(deskey, Signature.MODE_SIGN);    short sigLength = sig.sign(buffer, START, (short)(offset - START), 				byteArray8, (short)0);    offset = Util.arrayCopyNonAtomic(byteArray8, START, buffer, offset, SIGNATURE_LENGTH);        apdu.setOutgoingAndSend(START, (short)(offset - START));    transientBools[TRANSACTION_INITIALIZED] = true;  }    /**   * Handles Complete Transaction APDU.   * @param apdu APDU object   */  private void processCompleteTransaction(APDU apdu)  {    if (!transientBools[TRANSACTION_INITIALIZED])      ISOException.throwIt(SW_COMMAND_OUT_OF_SEQUENCE);    byte[] buffer = apdu.getBuffer();    if (buffer[ISO7816.OFFSET_LC] != LC_CT)      ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);    if ((buffer[ISO7816.OFFSET_P1] != 0) || (buffer[ISO7816.OFFSET_P2] != 0))      ISOException.throwIt(ISO7816.SW_INCORRECT_P1P2);        apdu.setIncomingAndReceive();    // get expected data        //restore transaction data from transient    short newTN = transientShorts[TN_IX];    short amount = transientShorts[AMOUNT_IX];    short newBalance = transientShorts[NEW_BALANCE_IX];    //The signature verification     //get CLA, INS, P1, P2, LC    short offset = Util.arrayCopyNonAtomic(buffer, (short)0, MAC_buffer,(byte)0, (short)5);    Util.arrayCopyNonAtomic(buffer, offset, byteArray8,(byte)0, SIGNATURE_LENGTH);    Util.arrayCopyNonAtomic(buffer, (short)(offset + SIGNATURE_LENGTH), MAC_buffer,(byte)5, (short)DATETIME_LENGTH);    sig.init(deskey, Signature.MODE_VERIFY);    boolean signatureOK = sig.verify(MAC_buffer, (short)0, (short)10,						  byteArray8,						  START,						  SIGNATURE_LENGTH);        //prepare transaction record in APDU buffer    offset = Util.setShort(buffer, START, newTN);    buffer[offset] = (byte)transientShorts[TRANSACTION_TYPE_IX];    offset++;    offset = Util.setShort(buffer, offset, amount);    //CAD ID was left in this array from Initialize Transaction    offset = Util.arrayCopyNonAtomic(CAD_ID_array, START, buffer, offset, ID_LENGTH);        //Date and time are copied in APDU buffer to where they should go    //in the transaction record.    short balanceOffset = offset =      Util.arrayCopyNonAtomic(buffer, (short)(ISO7816.OFFSET_CDATA + 8), buffer,			      offset, DATETIME_LENGTH);    //Balance and SW will be added to transactionRecord	later    if (!signatureOK){      //Branch for unsuccessful transaction. Balance is not updated,      //otherwise transactionLog is recorded the same way as in successful transaction      offset = Util.setShort(buffer, offset, transientShorts[CURRENT_BALANCE_IX]); // old balance      Util.setShort(buffer, offset, SW_WRONG_SIGNATURE);      //done with preparing transaction record            byte[] theRecord = transactionLogFile.getNewLogRecord();      //The following	few	steps have to be performed atomically!      JCSystem.beginTransaction();      TN = newTN;      Util.arrayCopy(buffer, START,		     theRecord, START, TRANSACTION_RECORD_LENGTH);      transactionLogFile.updateNewLogRecord();      JCSystem.commitTransaction();            //Now we can throw exception      transientBools[TRANSACTION_INITIALIZED] = false;      ISOException.throwIt(SW_WRONG_SIGNATURE);    } else {      //Branch for successful transaction.      offset = Util.setShort(buffer, offset, transientShorts[NEW_BALANCE_IX]);      Util.setShort(buffer, offset, ISO7816.SW_NO_ERROR);      // done with preparing transaction record            byte[] theRecord = transactionLogFile.getNewLogRecord();      //The following few steps have to be performed atomically!      JCSystem.beginTransaction();      TN = transientShorts[TN_IX];      //Update balance      Util.setShort(balancesRecord, START, newBalance);      Util.arrayCopy(buffer, START,		     theRecord, START, TRANSACTION_RECORD_LENGTH);      transactionLogFile.updateNewLogRecord();      JCSystem.commitTransaction();    }        // Do loyalty work    // We have all the information in the buffer, the loyalty applets shouldn't    // know transaction number and the balance of purse - so we zero out these    // fields first    Util.setShort(buffer, START, (short)0);    Util.setShort(buffer, balanceOffset, (short)0);    short loyaltyCADValue = Util.getShort(CAD_ID_array, START);    for (byte loyaltyIndex = 0; loyaltyIndex < MAX_LOYALTY; loyaltyIndex++)      if (loyaltyCAD[loyaltyIndex] == loyaltyCADValue)	{ loyaltySIO[loyaltyIndex].grantPoints (buffer);break;}        offset = Util.setShort(MAC_buffer, START, newBalance);    Util.setShort(MAC_buffer, offset, SW_SUCCESS);    sig.init(deskey, Signature.MODE_SIGN);    short sigLength = sig.sign(MAC_buffer, (short)0, (short)4,     				byteArray8, (short)0);        //send R-APDU    offset = Util.setShort(buffer, START, newBalance);    offset = Util.arrayCopyNonAtomic(byteArray8, START, buffer, offset, SIGNATURE_LENGTH);    apdu.setOutgoingAndSend(START, (short)(offset - START));        transientBools[TRANSACTION_INITIALIZED] = false;  }      /**   * Handles Initialize Parameter Update APDU.   *   * <p><em>NOTE:</em> In this sample implementation we assume that all the   * Parameter Updates are performed in somewhat secured facility and therefor   * the tearing of the card is not an issue. That's why we don't do any   * transactional protection while processing Initialize and Complete   * Parameter Update APDU commands.   *   * @param apdu APDU object   */  private void processInitializeUpdate(APDU apdu)  {    if (transientBools[UPDATE_INITIALIZED])      ISOException.throwIt(SW_COMMAND_OUT_OF_SEQUENCE);    if (!masterPIN.isValidated() && isPersonalized)      ISOException.throwIt(ISO7816.SW_SECURITY_STATUS_NOT_SATISFIED);        byte[] buffer = apdu.getBuffer();    if ((buffer[ISO7816.OFFSET_P1] != 0) || (buffer[ISO7816.OFFSET_P2] != 0))      ISOException.throwIt(ISO7816.SW_INCORRECT_P1P2);        // Because this is a case 2 command (outgoing data only), the contents of P3    //  are undefined. In T=0, P3 is Le. In T=1, P3 is Lc. Therefore, we don't    //  bother to test the contents of buffer[ISO7816.OFFSET_LC].            PUN++; //Increment parameter Update Number        // Send R-APDU    short offset = Util.arrayCopyNonAtomic(ID_Purse, START, buffer, START, ID_LENGTH);    offset = Util.arrayCopyNonAtomic(ExpDate, START, buffer, offset, DATE_LENGTH);    offset = Util.setShort(buffer, offset, PUN);    apdu.setOutgoingAndSend(START, (short)(offset - START));        transientBools[UPDATE_INITIALIZED] = true;  }    /**   * Handles Complete Parameter Update APDU.   * @param apdu APDU object   */  private void processCompleteUpdate(APDU apdu)  {    if (!transientBools[UPDATE_INITIALIZED])      ISOException.throwIt(SW_COMMAND_OUT_OF_SEQUENCE);    byte[] buffer = apdu.getBuffer();    if ((buffer[ISO7816.OFFSET_P1] != 0) || (buffer[ISO7816.OFFSET_P2] != 0))      ISOException.throwIt(ISO7816.SW_INCORRECT_P1P2);    short count = apdu.setIncomingAndReceive();    // get expected data    byte lc = buffer[ISO7816.OFFSET_LC];    //The signature verification     //get CLA, INS, P1, P2, LC    //message to sign length    short messageLength = (short)(lc - SIGNATURE_LENGTH + 5);    short offset = Util.arrayCopyNonAtomic(buffer, (short)0, MAC_buffer,(byte)0, (short)messageLength);    offset = Util.arrayCopyNonAtomic(buffer, offset, byteArray8,(byte)0, SIGNATURE_LENGTH);     // verify signature if in coming apdu    sig.init(deskey, Signature.MODE_VERIFY);    boolean signatureOK = sig.verify(MAC_buffer, (short)0, messageLength,						  byteArray8,						  START,						  SIGNATURE_LENGTH);   if (!signatureOK)      ISOException.throwIt(SW_WRONG_SIGNATURE);    switch (buffer[TLV_OFFSET]) {    case MASTER_PIN_UPDATE:	updatePIN(apdu, masterPIN); setIsPersonalized(); break;    case USER_PIN_UPDATE: 	updatePIN(apdu, userPIN); break;    case EXP_DATE_UPDATE: 	updateParameterValue(apdu, ExpDate); break;    case PURSE_ID_UPDATE: 	updateParameterValue(apdu, ID_Purse); break;    case MAX_BAL_UPDATE: 	updateBalanceValue(apdu, OFFSET_BAL_MAX); break;    case MAX_M_UPDATE: 		updateBalanceValue(apdu, OFFSET_AMOUNT_MAX); break;    case VERSION_UPDATE: 	updateParametersFile(apdu); break;    case LOYALTY1_UPDATE:	updateLoyaltyProgram(apdu, (byte)0); break;    case LOYALTY2_UPDATE:	updateLoyaltyProgram(apdu, (byte)1); break;    case LOYALTY3_UPDATE:	updateLoyaltyProgram(apdu, (byte)2); break;    case LOYALTY4_UPDATE:	updateLoyaltyProgram(apdu, (byte)3); break;    default: ISOException.throwIt(ISO7816.SW_FUNC_NOT_SUPPORTED);    }        //sign the return message    //Admittedly, this is a poor MAC, but this message only returns the status    //(what is MACed here) and the MAC itself. A real application should return a    //little more information.    offset = Util.setShort(MAC_buffer, START, SW_SUCCESS);    sig.init(deskey, Signature.MODE_SIGN);    short sigLength = sig.sign(MAC_buffer, (short)0, (short)2,    				byteArray8, (short)0);        //send R-APDU    //offset = Util.arrayCopyNonAtomic(byteArray8, START, buffer, offset, SIGNATURE_LENGTH);    Util.arrayCopyNonAtomic(byteArray8, START, buffer, START, SIGNATURE_LENGTH);    apdu.setOutgoingAndSend(START, SIGNATURE_LENGTH);        transientBools[UPDATE_INITIALIZED] = false;      }    /**   * Handles Verify Pin APDU.   * @param apdu APDU object   */  private void processVerifyPIN(APDU apdu)  {    byte[] buffer = apdu.getBuffer();    byte pinLength = buffer[ISO7816.OFFSET_LC];    byte triesRemaining	= (byte)0;    short count = apdu.setIncomingAndReceive();    // get expected data    if (count < pinLength) ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);    byte pinType = buffer[ISO7816.OFFSET_P2];    switch (pinType) {    case MASTER_PIN:      if (!masterPIN.check(buffer, ISO7816.OFFSET_CDATA, pinLength)){	triesRemaining = masterPIN.getTriesRemaining();	//The last nibble of return	code is	number of remaining	tries	ISOException.throwIt((short)(SW_PIN_FAILED + triesRemaining));      }      break;    case USER_PIN:      if (!userPIN.check(buffer, ISO7816.OFFSET_CDATA, pinLength)){	triesRemaining = userPIN.getTriesRemaining();	//The last nibble of return	code is	number of remaining	tries	ISOException.throwIt((short)(SW_PIN_FAILED + triesRemaining));      }      break;    default: ISOException.throwIt(ISO7816.SW_INCORRECT_P1P2);    }  }  /**   * Verifies numerical limitations on Transaction Amount.   *   * <p><em>NOTE:</em> With some values of maxBalance and maxAmount the logic   * in this method might become somewhat unrealistic. It's the result of using   * short arithmetic on values which might be too big to fit in short variables.   *   * @param transactionType type of transaction.   * @param amount transaction amount.   * @return new balance   */  private short checkTransactionValues(byte transactionType, short amount)  {    short newBalance;

⌨️ 快捷键说明

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