📄 shadebitunsigned.java
字号:
// attempt to update the page boolean success = false; try { success = writeTransactionData(user, transID, this.userBalance, accountData); } catch(Exception e) { /* sink */ } //if write didn't succeeded or if we need to perform //a verification step anyways, let's double-check what //the user has on the button. if(verifySuccess || !success) { //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\ if(DEBUG) { System.out.println("attempting to re-write transaction data: "); System.out.print("cur Data: "); System.out.println(Convert.toHexString(accountData, 0, 32, " ")); System.out.print("old data: "); System.out.println(Convert.toHexString(oldAcctData, 0, 32, " ")); } //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\ boolean dataOK = false; int cnt = MAX_RETRY_CNT; do { try { // let's refresh the page user.refreshDevice(); //calling verify user re-issues a challenge-response //and reloads the cached account data in the user object. if(verifyUser(user)) { //compare the user's account data against the working //copy and the backup copy. if(user.readAccountData(newAcctData,0)) { //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\ if(DEBUG) { System.out.print("new data: "); System.out.println(Convert.toHexString(newAcctData, 0, 32, " ")); } //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\ boolean isOld = true; boolean isCur = true; for(int i=0; i<32 && (isOld||isCur); i++) { //match the backup isOld = isOld && (newAcctData[i]==oldAcctData[i]); //match the working copy isCur = isCur && (newAcctData[i]==accountData[i]); } if(isOld) { //if it matches the backup copy, we didn't write anything //and the data is still okay, but we didn't do a debit dataOK = true; success = false; } else if(isCur) { dataOK = true; success = true; } else { int cnt2 = MAX_RETRY_CNT; do { //iBUTTON DATA IS TOTALLY HOSED //keep trying to get account data on the button try { success = writeTransactionData(user, transID, this.userBalance, accountData); } catch(OneWireIOException owioe) { if(cnt2==0) throw owioe; } catch(OneWireException owe) { if(cnt2==0) throw owe; } } while(cnt2-->0 && !success); } } } } catch(OneWireIOException owioe) { if(cnt==0) throw owioe; } catch(OneWireException owe) { if(cnt==0) throw owe; } } while(!dataOK && cnt-->0); if(!dataOK) { //couldn't fix the data after 255 retries IOHelper.writeLine("Catastrophic Failure!"); success = false; } } return success; } private byte[] writeTransactionData_scratchpad = new byte[32]; /** * Does the writing of transaction data to the user button as well * as actually signing the data with the coprocessor. * * No need to synchronize wince the methods that call this * private method will be synchronized. */ private final boolean writeTransactionData(SHAiButtonUser user, int transID, int balance, byte[] accountData) throws OneWireException, OneWireIOException { //init local vars int acctPageNum = user.getAccountPageNumber(); // data type code - dynamic: 0x00, static: 0x01 accountData[I_DATA_TYPE_CODE] = 0x01; // conversion factor - 2 data bytes accountData[I_CONVERSION_FACTOR+0] = (byte)0x8B; accountData[I_CONVERSION_FACTOR+1] = (byte)0x48; // zero-out the don't care bytes accountData[I_DONT_CARE] = 0x00; accountData[I_DONT_CARE+1] = 0x00; accountData[I_DONT_CARE+2] = 0x00; accountData[I_DONT_CARE+3] = 0x00; if(accountData[I_FILE_LENGTH]==RECORD_A_LENGTH) { //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\ if(DEBUG) System.out.println("Was A, now using B"); //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\ // length of the TMEX file accountData[I_FILE_LENGTH] = (byte)RECORD_B_LENGTH; // account balance - 3 data bytes Convert.toByteArray(balance, accountData, I_BALANCE_B, 3); // transaction ID - 2 data bytes accountData[I_TRANSACTION_ID_B+0] = (byte)transID; accountData[I_TRANSACTION_ID_B+1] = (byte)(transID>>>8); // continuation pointer for TMEX file accountData[I_CONTINUATION_PTR_B] = 0x00; // clear out the crc16 - 2 data bytes accountData[I_FILE_CRC16_B+0] = 0x00; accountData[I_FILE_CRC16_B+1] = 0x00; // dump in the inverted CRC int crc = ~CRC16.compute(accountData, 0, accountData[I_FILE_LENGTH] + 1, acctPageNum); accountData[I_FILE_CRC16_B+0] = (byte)crc; accountData[I_FILE_CRC16_B+1] = (byte)(crc>>8); } else { //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\ if(DEBUG) System.out.println("Was B, now using A"); //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\ // length of the TMEX file accountData[I_FILE_LENGTH] = (byte)RECORD_A_LENGTH; // account balance - 3 data bytes Convert.toByteArray(balance, accountData, I_BALANCE_A, 3); // transaction ID - 2 data bytes accountData[I_TRANSACTION_ID_A+0] = (byte)transID; accountData[I_TRANSACTION_ID_A+1] = (byte)(transID>>>8); // continuation pointer for TMEX file accountData[I_CONTINUATION_PTR_A] = 0x00; // clear out the crc16 - 2 data bytes accountData[I_FILE_CRC16_A+0] = 0x00; accountData[I_FILE_CRC16_A+1] = 0x00; // dump in the inverted CRC int crc = ~CRC16.compute(accountData, 0, accountData[I_FILE_LENGTH] + 1, acctPageNum); accountData[I_FILE_CRC16_A+0] = (byte)crc; accountData[I_FILE_CRC16_A+1] = (byte)(crc>>8); } //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\// if(DEBUG) { IOHelper.writeLine("------------------------------------"); IOHelper.writeLine("writing transaction data"); IOHelper.writeLine("acctPageNum: " + acctPageNum); IOHelper.writeLine("accountData"); IOHelper.writeBytesHex(accountData); IOHelper.writeLine("------------------------------------"); } //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\// // write it to the button try { if(user.writeAccountData(accountData, 0)) return true; } catch(OneWireException owe) { if(DEBUG) IOHelper.writeLine(owe); } this.lastError = this.USER_WRITE_DATA_FAILED; return false; } /** * <P>Retrieves the value of a particular parameter for this * debit transaction.</P> * * <P><B>Valid Parameters</B> * <UL> * <LI><code>SHADebit.DEBIT_AMOUNT</code></LI> * <LI><code>SHADebit.INITIAL_AMOUNT</code></LI> * <LI><code>SHADebit.USER_BALANCE</code></LI> * </UL> * </P> * * <P>Note that the value of <code>SHADebit.USER_BALANCE</code> will * be set after calling <code>verifyTransactionData(SHAiButtonUser)</code> * and after calling <code>executeTransaction(SHAiButtonUser)</code>.</P> * * @return The value of the requested parameter. * * @throws IllegalArgumentException if an invalid parameter type * is requested. */ public synchronized int getParameter(int type) { switch(type) { case DEBIT_AMOUNT: return debitAmount; case INITIAL_AMOUNT: return initialAmount; case USER_BALANCE: return userBalance; default: return -1; } } /** * <P>Sets the value of a particular parameter for this * debit transaction.</P> * * <P><B>Valid Parameters</B> * <UL> * <LI><code>SHADebit.DEBIT_AMOUNT</code></LI> * <LI><code>SHADebit.INITIAL_AMOUNT</code></LI> * </UL> * </P> * * @param type Specifies the parameter type (<code>SHADebit.DEBIT_AMOUNT</code> or * <code>SHADebit.INITIAL_AMOUNT</code>) * @return </code>true</code> if a valid parameter type was specified * and the value of the parameter is positive. * * @throws IllegalArgumentException if an invalid parameter type * is requested. */ public synchronized boolean setParameter(int type, int param) { switch(type) { case DEBIT_AMOUNT: debitAmount = param; break; case INITIAL_AMOUNT: initialAmount = param; break; default: return false; } return true; } /** * <p>Resets all transaction parameters to default values</p> */ public synchronized void resetParameters() { debitAmount = 50; //50 cents initialAmount = 90000; //100 dollars userBalance = 0; //0 dollars }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -