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

📄 shasoftauth.java

📁 这是一个以JAVA编写的程序,本人还没有试过,是一个简单的温度控制系统
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/*--------------------------------------------------------------------------- * Copyright (C) 1999-2001 Dallas Semiconductor Corporation, All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY,  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL DALLAS SEMICONDUCTOR BE LIABLE FOR ANY CLAIM, DAMAGES * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * Except as contained in this notice, the name of Dallas Semiconductor * shall not be used except as stated in the Dallas Semiconductor * Branding Policy. *--------------------------------------------------------------------------- */package com.dalsemi.onewire.application.sha;import java.io.*;import com.dalsemi.onewire.*;import com.dalsemi.onewire.adapter.*;import com.dalsemi.onewire.container.*;import com.dalsemi.onewire.utils.*;/** * <P>This class implements an software authrization account application for  * SHA Transactions.  The account data is stored on the user iButtons after * being digitally signed by a virtual machine coprocessor. Account data * consists of the following: *  <UL> *    <LI> 1 byte: Length of the account file</LI> *    <LI> 2 bytes: Transaction ID</LI> *    <LI> 2 bytes: Account Money Conversion Factor</LI> *    <LI> 3 bytes: Account Balance</LI> *    <LI>20 bytes: Account Data Signature</LI> *    <LI> 1 byte: Account data type (dynamic or static)</LI> *    <LI> 1 byte: File continuation pointer</LI> *    <LI> 2 bytes: CRC16 of entire 30 bytes seeded with the page number</LI> *    <LI> <B>32 bytes Total</B></LI> *  </UL></P> *  * <P>A typical use case for this class might be as follows: * <pre> *   OneWireContainer18 coprOWC18 = new OneWireContainer18(adapter,address); *    *   //COPR.0 is the filename for coprocessor service data *   SHAiButtonCopr copr = new SHAiButtonCopr(coprOWC18,"COPR.0"); *  *   //Initial amount for new users is $100, and debit amount is 50 cents *   byte[] ver_data = new byte[] {0x00,0x01,0x02,0x03,0x04,0x05,0x06}; *   SATransaction trans = new SHAsoftauth(copr, ver_data, 7); *  *   OneWireContainer18 owc18 = new OneWireContainer18(adapter, userAddress); *  *   //The following constructor erases all transaction data from the user and *   //installs the system authentication secret on the user iButton. *   SHAiButtonUser user = new SHAiButtonUser18(copr, owc18, true, authSecret); *  *   //creates account data on iButton *   if(trans.setupTransactionData(user)) *      System.out.println("Account data installed successfully"); *   else *      System.out.println("Account data installation failed"); *  *   //... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... *  *   //"challenges" user iButton *   if(trans.verifyUser(user)) *   { *      System.out.println("User Verified Successfully"); *  *      //checks data signature *      if(trans.verifyTransactionData(user)) *      { *         System.out.println("Account Data Verified Successfully"); *  *         //writes verification data to user iButton *         System.out.println("User's verification data: "); *         softauth.getParameter(SHASoftAuth.VERIFICATION_DATA, *                               ver_data,0,7); *         IOHelper.writeBytes(ver_data); *      } *   } *  *   //... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... *  *   if(trans.getLastError()!=0) *   { *      System.err.println("Error code: " + trans.getLastError()); *   } * </pre></P> *  * <p>This class makes use of several performance enhancements for TINI. * For instance, most methods are <code>synchronized</code> to access instance variable * byte arrays rather than creating new byte arrays every time a transaction * is performed.  This could hurt performance in multi-threaded * applications, but the usefulness of having several threads contending * to talk to a single iButton is questionable since the methods in  * <code>com.dalsemi.onewire.adapter.DSPortAdapter</code> * <code>beginExclusive(boolean)</code> and <code>endExclusive()</code> should be used.</p> *  * @see SHATransaction * @see SHAiButtonCopr * @see SHAiButtonUser * * @version 1.00 * @author  SKH */public class SHASoftAuth    extends SHATransaction{   /** Used for fast FF copy */   private static final byte[] ffBlock       = new byte[] { (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF,                      (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF };      // ************************************************************** //   // Type constants   // used to update/retrieve parameters of transaction   // ************************************************************** //      /** Update the verification data */   public static final int VERIFICATION_DATA = 2;      /** indices for fields in user account file */   public static final int I_FILE_LENGTH = 0;   public static final int I_DATA_TYPE_CODE = 1;   public static final int I_SIGNATURE = 2;   public static final int I_VERDATA = 22;   public static final int I_CONTINUATION_PTR = 29;   public static final int I_FILE_CRC16 = 30;      // ************************************************************** //   // Member variables   // ************************************************************** //   /** Data to be stored on the iButton for Verification */   private byte[] ver_data = new byte[] {0x00, 0x00, 0x00, 0x00, 0x00,                                          0x00, 0x00};      /** Data that is to be written to the iButton for Verification */   private byte[] master_ver_data = new byte[] {0x00, 0x00, 0x00, 0x00,                                                0x00, 0x00, 0x00};                                               /** User apps should never call this */   protected SHASoftAuth() {;}   /**    * SHADebit constructor.  <code>copr</code> is the SHAiButtonCopr    * that is used to perform this transaction.  After saving a    * reference to the SHA coprocessor, this constructor resets all    * parameters for this type of transaction to their default values.    *     * @param copr The coprocessor used for authentication and data    *             signing in this transaction.    */   public SHASoftAuth(SHAiButtonCopr copr)   {      super(copr);            resetParameters();   }      /**    * SHADebit constructor.  <code>copr</code> is the SHAiButtonCopr    * that is used to perform this transaction.  After saving a    * reference to the SHA coprocessor, this constructor resets all    * parameters for this type of transaction to their default values.    *     * @param copr       The coprocessor used for authentication and data    *                   signing in this transaction.    * @param extra_data The 7 bytes of extra data to be used instead    *                   of the balance.    * @param len        The len, 7 or less of the data.  It is 0 padded.    */   public SHASoftAuth(SHAiButtonCopr copr, byte[] extra_data,                        int len)   {      super(copr);            System.arraycopy(extra_data,0,this.master_ver_data,0,len);   }      /**    * <P>Setup account data on a fresh user iButton.  Prior to calling    * setup transaction data, the authentication secret for the iButton    * should already be setup and a directory entry (as well as at least    * an empty placeholder file) should exist for the account data.  If    * you constructed the SHAiButtonUser using     * <code>SHAiButtonUser(SHAiButtonCopr,OneWireContainer18,boolean,byte[])</code>    * the secret has been setup for you and you should know call this    * function.  If you try to install the authentication secret after    * creating the account data, you will destroy all account data on the    * iButton.</P>    *     * <P>You can set the value of the intial account balance by calling    * <code>transaction.setParameter(SHADebit.INITIAL_AMOUNT,10000)</code>    * where the value of the units is in cents (i.e. 10000 = $100).</P>    *     * <P><B>Flow of action: </B>    *   <ul>    *     <li> Generate generic account page </li>    *     <li> Insert the initial balance into account data </li>    *     <li> Create a signature using coprocessor </li>    *     <li> Insert the digital signature </li>    *     <li> Write account data page to iButton </li>    *   </ul></P>    *     * @param user SHAiButtonUser upon which the transaction occurs.    *     * @return <code>true</code>if and only if the signature is    * successfully created by the coprocessor AND the data is    * successfully written to the user iButton.    *     * @see SHAiButtonCopr#createDataSignature(byte[],byte[],byte[],int)    * @see SHAiButtonUser#writeAccountData(byte[],int)    * @see #getLastError()    */   public boolean setupTransactionData(SHAiButtonUser user)      throws OneWireException, OneWireIOException   {      //clear any error      lastError = NO_ERROR;      // not in critical path, so malloc'ing is okay      byte[] accountData = new byte[32];            return writeTransactionData(user, this.master_ver_data, accountData);   }   //prevent malloc'ing in the critical path   private byte[] verifyUser_fullBindCode = new byte[15];   private byte[] verifyUser_scratchpad   = new byte[32];   private byte[] verifyUser_accountData  = new byte[32];   private byte[] verifyUser_mac          = new byte[20];   private byte[] verifyUser_chlg         = new byte[3];   /**    * <P>Verifies user's authentication response.  User is "authenticated" if    * and only if the digital signature generated the user iButton matches    * the digital signature generated by the coprocessor after the user's    * unique secret has been recreated on the coprocessor.</P>    *     * <P><B>Flow of action: </B>    *   <ul>    *     <li> Generate 3-byte "challenge" on coprocessor </li>    *     <li> Write challenge to scratchpad of user </li>    *     <li> Read account data page with signature </li>    *     <li> Attempt to match user's signature with the coprocessor </li>    *   </ul></P>    *     * @param user SHAiButtonUser upon which the transaction occurs.    *     * @see SHAiButtonCopr#generateChallenge(int,byte[],int)    * @see SHAiButtonCopr#verifyAuthentication(byte[],byte[],byte[],byte[],byte)    * @see SHAiButtonUser#readAccountData(byte[],int,byte[],int,byte[],int)    * @see #getLastError()    */   public synchronized boolean verifyUser(SHAiButtonUser user)      throws OneWireException, OneWireIOException   {      //clear any error      this.lastError = this.NO_ERROR;      //local vars      byte[] fullBindCode = this.verifyUser_fullBindCode;      byte[] scratchpad   = this.verifyUser_scratchpad;      byte[] accountData  = this.verifyUser_accountData;      byte[] mac          = this.verifyUser_mac;      byte[] chlg         = this.verifyUser_chlg;            //Generate random challenge. This must be done on the       //coprocessor, otherwise flags aren't setup for VALIDATE_PAGE.      if(!copr.generateChallenge(0, chlg, 0))      {         lastError = COPR_COMPUTE_CHALLENGE_FAILED;         return false;      }            //have user answer the challenge      int wcc = user.readAccountData(chlg, 0, accountData, 0, mac, 0);            if(wcc<0)      {         if(user.hasWriteCycleCounter())         {            // failed to read account data            this.lastError = this.USER_READ_AUTH_FAILED;            return false;         }         System.arraycopy(ffBlock, 0, scratchpad, 8, 4);      }      else      {         //copy the write cycle counter into scratchpad         Convert.toByteArray(wcc, scratchpad, 8, 4);      }            //get the user's fullBindCode, formatted for user device      user.getFullBindCode(fullBindCode, 0);            //get the user address and page num from fullBindCode      System.arraycopy(fullBindCode, 4, scratchpad, 12, 8);            //set the same challenge bytes      System.arraycopy(chlg, 0, scratchpad, 20, 3);            //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//      if(DEBUG)      {         IOHelper.writeLine("------------------------------------");         IOHelper.writeLine("Verifying user");         IOHelper.writeLine("chlg");         IOHelper.writeBytesHex(chlg);         IOHelper.writeLine("accountData");         IOHelper.writeBytesHex(accountData);         IOHelper.writeLine("mac");         IOHelper.writeBytesHex(mac);         IOHelper.writeLine("wcc: " + user.getWriteCycleCounter());         IOHelper.writeLine("fullBindCode");         IOHelper.writeBytesHex(fullBindCode);         IOHelper.writeLine("scratchpad");         IOHelper.writeBytesHex(scratchpad);         IOHelper.writeLine("------------------------------------");      }      //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//            if(!copr.verifyAuthentication(fullBindCode,                                     accountData,                                     scratchpad, mac,                                    user.getAuthorizationCommand()))      {         this.lastError = this.COPROCESSOR_FAILURE;         return false;      }            return true;   }   //prevent malloc'ing in the critical path   private byte[] verifyData_fullBindCode = new byte[32];   private byte[] verifyData_scratchpad   = new byte[32];   private byte[] verifyData_accountData  = new byte[32];   private byte[] verifyData_mac          = new byte[20];   /**    * <P>Verifies user's account data.  Account data is "verified" if the    * digital signature matches the signature recreated by the     * coprocessor.</P>    *     * <P><B>Flow of action: </B>    *   <ul>    *     <li> Read the account data from user </li>    *     <li> Get verification data </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.    *     * @return <code>true</code> if and only if the account balance is     * greater than zero and digital signature matches the signature    * recreated by the coprocessor.    *     * @see SHAiButtonUser#readAccountData(byte[],int)    * @see SHAiButtonCopr#verifySignature(byte[],byte[],byte[])    * @see #getLastError()    */   public synchronized boolean verifyTransactionData(SHAiButtonUser user)      throws OneWireException, OneWireIOException   {      //clear any error      this.lastError = NO_ERROR;      //init local vars      byte[] scratchpad  = this.verifyData_scratchpad;      byte[] accountData = this.verifyData_accountData;      byte[] verify_mac  = this.verifyData_mac;      //if verifyUser was called, this is a read of cached data      int wcc = user.getWriteCycleCounter();            //if verifyUser was called, this is a read of cached data

⌨️ 快捷键说明

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