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

📄 javapursecrypto.java

📁 javacard 程序
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
    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 + -