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

📄 shasoftauth.java

📁 这是一个以JAVA编写的程序,本人还没有试过,是一个简单的温度控制系统
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
      user.readAccountData(accountData,0);      //get the user's verification data      System.arraycopy(accountData,I_VERDATA,this.ver_data,0,7);      //get the mac from the account data page      System.arraycopy(accountData, I_SIGNATURE, verify_mac, 0, 20);      //now lets reset the mac      copr.getInitialSignature(accountData, I_SIGNATURE);      //and reset the CRC      accountData[I_FILE_CRC16+0] = (byte)0;      accountData[I_FILE_CRC16+1] = (byte)0;      //now we also need to get things like wcc, user_page_number, user ID      if(wcc<0)      {         if(user.hasWriteCycleCounter())         {            // failed to read account data            this.lastError = USER_READ_AUTH_FAILED;            return false;         }         //has no write cycle counter         System.arraycopy(ffBlock, 0, scratchpad, 8, 4);      }      else      {         //copy the write cycle counter into scratchpad         Convert.toByteArray(wcc, scratchpad, 8, 4);      }      scratchpad[12] = (byte)user.getAccountPageNumber();      user.getAddress(scratchpad, 13, 7);           copr.getSigningChallenge(scratchpad, 20);            if(!copr.verifySignature(accountData, scratchpad, verify_mac))      {         this.lastError = COPROCESSOR_FAILURE;         return false;      }            return true;   }      //prevent malloc'ing in critical path   private byte[] executeTransaction_accountData = new byte[32];   private byte[] executeTransaction_oldAcctData = new byte[32];   private byte[] executeTransaction_newAcctData = new byte[32];   //private byte[] executeTransaction_scratchpad = new byte[32];   /**    * <P>Performs the signed debit, subtracting the debit amount from    * the user's balance and storing the new, signed account data on the    * user's iButton.  The debit amount can be set using    * <code>transaction.setParameter(SHADebit.DEBIT_AMOUNT, 50)</code>,    * where the value is in units of cents (i.e. for 1 dollar, use 100).</P>    *     * <P><B>Flow of action: </B>    *   <ul>    *     <li> Read the account data from user </li>    *     <li> Extract account balance </li>    *     <li> Reset the digital signature </li>    *     <li> Use coprocessor to sign account data </li>    *     <li> Insert the new digital signature </li>    *     <li> Write the account data to the user </li>    *   </ul></P>    *     * <P>If previous steps have been executed, all "Read" commands on    * the user are reading from cached data.</P>    *     * @param user          SHAiButtonUser upon which the transaction occurs.    * @param verifySuccess A boolean to let this method know if verification    *                      was successful.    *     * @return <code>true</code> if and only if the user has enough in the    * account balance to perform the requested debit AND a new digital    * signature is successfully created AND the account data has been written    * to the button.    *     * @see SHAiButtonUser#readAccountData(byte[],int)    * @see SHAiButtonUser#writeAccountData(byte[],int)    * @see SHAiButtonCopr#createDataSignature(byte[],byte[],byte[],int)    * @see #getLastError()    */   public synchronized boolean executeTransaction(SHAiButtonUser user,                                                   boolean verifySuccess)      throws OneWireException, OneWireIOException   {      //clear any error      this.lastError = NO_ERROR;            //init local vars      //holds the working copy of account data      byte[] accountData = this.executeTransaction_accountData;      //holds the backup copy of account data before writing      byte[] oldAcctData = this.executeTransaction_oldAcctData;      //holds the account data read back for checking      byte[] newAcctData = this.executeTransaction_newAcctData;            //if verifyUser was called, this is a read of cached data      user.readAccountData(accountData,0);            //before we update the account data array at all, let's make a backup copy      System.arraycopy(accountData, 0, oldAcctData, 0, 32);            //get the user's verification data      System.arraycopy(accountData,I_VERDATA,this.ver_data,0,7);                  boolean success         = writeTransactionData(user, this.master_ver_data, accountData);            //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)      {         boolean dataOK = false;         int cnt = MAX_RETRY_CNT;         do         {            //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))               {                  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;                  }                  else                  {                     //iBUTTON DATA IS TOTALLY HOSED                     //keep trying to get account data on the button                     success = writeTransactionData(user,                                                     this.ver_data,                                                     accountData);                  }               }            }         }         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.    */   private final boolean writeTransactionData(SHAiButtonUser user,                                               byte[] ver_data,                                               byte[] accountData)      throws OneWireException, OneWireIOException   {      //init local vars      SHAiButtonCopr copr = this.copr;      int    acctPageNum  = user.getAccountPageNumber();      byte[] scratchpad   = this.writeTransactionData_scratchpad;            // length of the TMEX file - 28 data, 1 cont. ptr      accountData[I_FILE_LENGTH] = (byte)29;            System.arraycopy(ver_data,0,accountData,I_VERDATA,7);            // 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.getWriteCycleCounter();      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 = this.USER_READ_AUTH_FAILED;            return false;         }         System.arraycopy(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);            //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//      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)   {      return 0;   }         /**    * <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, byte[] data, int offset,                                        int len)   {   	if(type==VERIFICATION_DATA)   	{         System.arraycopy(this.ver_data,0,data,offset,len);         return 0;      }      throw new IllegalArgumentException("Invalid Parameter type");   }         /**    * <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,                                            byte[] data, int offset, int len)   {   	if(type==VERIFICATION_DATA)     	   System.arraycopy(data,offset,this.master_ver_data,0,len);     	else     	   return false;      return true;   }   /**    * <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)   {      return false;   }         /**    * <p>Resets all transaction parameters to default values</p>    */   public synchronized void resetParameters()   {   	for(int i=0; i<7; i++)   	{   	   ver_data[i] = 0x00;   	   master_ver_data[i] = 0x00;   	}   	   }   }

⌨️ 快捷键说明

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