/// <summary> /// 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. /// </summary> private bool writeTransactionData(SHAiButtonUser user, int transID, int balance, byte[] accountData) { //init local vars int acctPageNum = user.AccountPageNumber; // data type code - dynamic: 0x00, static: 0x01 accountData[I_DATA_TYPE_CODE] = 0x01; // conversion factor - 2 data bytes accountData[I_CONVERSION_FACTOR + 0] = 0x8B; accountData[I_CONVERSION_FACTOR + 1] = 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) { OneWireEventSource.Log.Debug("Was A, now using B"); // length of the TMEX file accountData[I_FILE_LENGTH] = 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)((int)((uint)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 { OneWireEventSource.Log.Debug("Was B, now using A"); // length of the TMEX file accountData[I_FILE_LENGTH] = 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)((int)((uint)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); } OneWireEventSource.Log.Debug("------------------------------------"); OneWireEventSource.Log.Debug("writing transaction data"); OneWireEventSource.Log.Debug("acctPageNum: " + acctPageNum); OneWireEventSource.Log.Debug("accountData: " + Convert.toHexString(accountData)); OneWireEventSource.Log.Debug("------------------------------------"); // write it to the button try { if (user.writeAccountData(accountData, 0)) { return(true); } } catch (OneWireException owe) { OneWireEventSource.Log.Debug(owe.ToString()); } this.lastError = SHATransaction.USER_WRITE_DATA_FAILED; return(false); }
/// <summary> /// Does the writing of transaction data to the user button as well /// as actually signing the data with the coprocessor. /// </summary> private bool writeTransactionData(SHAiButtonUser user, int transID, int balance, byte[] accountData) { //init local vars SHAiButtonCopr copr = this.copr; int acctPageNum = user.AccountPageNumber; byte[] scratchpad = this.writeTransactionData_scratchpad; // length of the TMEX file - 28 data, 1 cont. ptr accountData[I_FILE_LENGTH] = (byte)29; // transaction ID - 2 data bytes accountData[I_TRANSACTION_ID + 0] = (byte)transID; accountData[I_TRANSACTION_ID + 1] = (byte)((int)((uint)transID >> 8)); // conversion factor - 2 data bytes accountData[I_CONVERSION_FACTOR + 0] = 0x8B; accountData[I_CONVERSION_FACTOR + 1] = 0x48; // account balance - 3 data bytes Convert.toByteArray(balance, accountData, I_BALANCE, 3); // initial signature - 20 data bytes copr.getInitialSignature(accountData, I_SIGNATURE); // data type code - dynamic: 0x00, static: 0x01 accountData[I_DATA_TYPE_CODE] = 0x01; // continuation pointer for TMEX file accountData[I_CONTINUATION_PTR] = 0x00; // clear out the crc16 - 2 data bytes accountData[I_FILE_CRC16 + 0] = 0x00; accountData[I_FILE_CRC16 + 1] = 0x00; //we need to increment the writeCycleCounter since we will be writing to the part int wcc = user.WriteCycleCounter; if (wcc > 0) { //copy the write cycle counter into scratchpad Convert.toByteArray(wcc + 1, scratchpad, 8, 4); } else { if (user.hasWriteCycleCounter()) { // failed to read account data this.lastError = SHATransaction.USER_READ_AUTH_FAILED; return(false); } Array.Copy(ffBlock, 0, scratchpad, 8, 4); } // svcPageNumber, followed by address of device scratchpad[12] = (byte)acctPageNum; user.getAddress(scratchpad, 13, 7); // copy in the signing challenge copr.getSigningChallenge(scratchpad, 20); // sign the data, return the mac right into accountData copr.createDataSignature(accountData, scratchpad, accountData, I_SIGNATURE); //after signature make sure to dump in the inverted CRC int crc = ~CRC16.compute(accountData, 0, accountData[I_FILE_LENGTH] + 1, acctPageNum); //set the the crc16 bytes accountData[I_FILE_CRC16 + 0] = (byte)crc; accountData[I_FILE_CRC16 + 1] = (byte)(crc >> 8); //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\// OneWireEventSource.Log.Debug("------------------------------------"); OneWireEventSource.Log.Debug("writing transaction data"); OneWireEventSource.Log.Debug("acctPageNum: " + acctPageNum); OneWireEventSource.Log.Debug("accountData: " + Convert.toHexString(accountData)); OneWireEventSource.Log.Debug("------------------------------------"); //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\// // write it to the button try { if (user.writeAccountData(accountData, 0)) { return(true); } } catch (OneWireException owe) { OneWireEventSource.Log.Debug(owe.ToString()); } this.lastError = SHATransaction.USER_WRITE_DATA_FAILED; return(false); }