/// <summary>
        /// <P>Initialize a DS1961S as a fresh user iButton for a given SHA service.
        /// This constructor not only creates the service file for the user iButton
        /// using the TMEX file structure, but it also installs the master
        /// authentication secret and binds it to the iButton (making it unique for
        /// a particular button).  Optionally, the device can be formatted before
        /// the service file is installed.</P>
        ///
        /// <P>Note: With this constructor, the master secret is installed and bound
        /// to the iButton, so the final secret is none by the object.  For that
        /// reason, a hardware coprocessor is not necessary for generating the
        /// write-authorization MAC.</P>
        /// </summary>
        /// <param name="copr"> The SHAiButtonCopr to which the user object is tied.  This
        ///        Coprocessor contains the necessary binding code and service
        ///        filename, necessary for both locating a user and recreating his
        ///        unique secret. </param>
        /// <param name="owc"> The DS1963S iButton that this object will refer to. </param>
        /// <param name="formatDevice"> If <code>true</code>, the TMEX filesystem will be
        ///        formatted before the account service file is created. </param>
        /// <param name="authSecret"> The master authentication secret for the systm.
        /// </param>
        /// <exception cref="OneWireIOException"> on a 1-Wire communication error such as
        ///         reading an incorrect CRC from a 1-Wire device.  This could be
        ///         caused by a physical interruption in the 1-Wire Network due to
        ///         shorts or a newly arriving 1-Wire device issuing a 'presence pulse'. </exception>
        /// <exception cref="OneWireException"> on a communication or setup error with the 1-Wire
        ///         adapter
        /// </exception>
        /// <seealso cref= #SHAiButtonUser33(SHAiButtonCopr,SHAiButtonCopr,OneWireContainer33) </seealso>
        /// <seealso cref= #SHAiButtonUser33(SHAiButtonCopr,SHAiButtonCopr) </seealso>
        public SHAiButtonUser33(SHAiButtonCopr copr, OneWireContainer33 owc, bool formatDevice, byte[] authSecret) : this(copr, copr)
        {
            //setup service filename

            //hold container reference
            this.ibc33 = owc;

            //and address
            this.address = owc.Address;

            //clear out old secret first
            byte[] NullSecret = new byte[8];
            for (int i = 0; i < 8; i++)
            {
                NullSecret[i] = 0x00;
            }

            if (!this.ibc33.loadFirstSecret(NullSecret, 0))
            {
                throw new OneWireException("Failed to null out device secret.");
            }

            if (!owc.installMasterSecret(0, authSecret))
            {
                throw new OneWireException("Install Master Secret failed");
            }

            if (!createServiceFile(owc, strServiceFilename, formatDevice))
            {
                throw new OneWireException("Failed to create service file.");
            }

            //setup the fullBindCode with rest of info
            this.fullBindCode[4] = (byte)this.accountPageNumber;
            Array.Copy(this.address, 0, this.fullBindCode, 5, 7);

            if (!owc.bindSecretToiButton(this.accountPageNumber, copr.BindData))
            {
                throw new OneWireException("Bind Secret to iButton failed");
            }

            //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
            if (DEBUG)
            {
                IOHelper.writeLine("------------------------------------");
                IOHelper.writeLine("Initialized DS1961S User");
                IOHelper.writeLine("address");
                IOHelper.writeBytesHex(owc.Address);
                IOHelper.writeLine("serviceFilename: " + strServiceFilename);
                IOHelper.writeLine("accountPageNumber: " + accountPageNumber);
                IOHelper.writeLine("authSecret");
                IOHelper.writeBytesHex(authSecret);
                IOHelper.writeLine("bindData");
                IOHelper.writeBytesHex(copr.bindData);
                IOHelper.writeLine("bindCode");
                IOHelper.writeBytesHex(copr.bindCode);
                IOHelper.writeLine("------------------------------------");
            }
            //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
        }
Exemple #2
0
        /// <summary>
        /// <P>Creates a mostly unitialized SHAiButtonUser object.  This constructor
        /// merely copies the coprocessors 7 byte binding code into a local cache
        /// and stores the name of the account service file used for all user
        /// iButtons.</P>
        ///
        /// <P>Since this constructor leaves data unitialized, you should be very
        /// careful with the use of it.  It is expected that after calling this
        /// constructor, the user will call <code>setiButton</code> to finish the
        /// initialization process.  On memory-starved platforms, this should help
        /// optimize memory usage.</P>
        /// </summary>
        /// <param name="copr"> The SHAiButtonCopr to which the user object is tied.  This
        ///        Coprocessor contains the necessary binding code and service
        ///        filename, necessary for both locating a user and recreating his
        ///        unique secret.
        /// </param>
        /// <seealso cref= #SHAiButtonUser18(SHAiButtonCopr,OneWireContainer18,bool,byte[]) </seealso>
        /// <seealso cref= #SHAiButtonUser18(SHAiButtonCopr) </seealso>
        public SHAiButtonUser18(SHAiButtonCopr copr)
        {
            //save a copy of the binding code
            copr.getBindCode(this.fullBindCode, 0);
            Array.Copy(this.fullBindCode, 4, this.fullBindCode, 12, 3);

            //create string representation of service filename
            copr.getFilename(this.serviceFile, 0);
            this.strServiceFilename = Encoding.Unicode.GetString(this.serviceFile) + "." + (int)copr.FilenameExt;
        }
Exemple #3
0
        /// <summary>
        /// <P>Creates a valid SHAiButtonUser object.  If the service file,
        /// whose name is taken from the <code>SHAiButtonCopr</code>, is not
        /// found on the user iButton, a OneWireException is thrown with the
        /// message "Invalid SHA user".</P>
        /// </summary>
        /// <param name="copr"> The SHAiButtonCopr to which the user object is tied.  This
        ///        Coprocessor contains the necessary binding code and service
        ///        filename, necessary for both locating a user and recreating his
        ///        unique secret. </param>
        /// <param name="owc"> The DS1963S iButton that this object will refer to.
        /// </param>
        /// <exception cref="OneWireIOException"> on a 1-Wire communication error such as
        ///         reading an incorrect CRC from a 1-Wire device.  This could be
        ///         caused by a physical interruption in the 1-Wire Network due to
        ///         shorts or a newly arriving 1-Wire device issuing a 'presence pulse'. </exception>
        /// <exception cref="OneWireException"> on a communication or setup error with the 1-Wire
        ///         adapter
        /// </exception>
        /// <seealso cref= #SHAiButtonUser18(SHAiButtonCopr,OneWireContainer18,bool,byte[]) </seealso>
        /// <seealso cref= #SHAiButtonUser18(SHAiButtonCopr) </seealso>
        public SHAiButtonUser18(SHAiButtonCopr copr, OneWireContainer18 owc) : this(copr)
        {
            //setup service filename

            //hold container reference and address
            if (!setiButton18(owc))
            {
                throw new OneWireException("Invalid SHA user");
            }
        }
Exemple #4
0
        /// <summary>
        /// <P>Initialize a DS1963S as a fresh user iButton for a given SHA service.
        /// This constructor not only creates the service file for the user iButton
        /// using the TMEX file structure, but it also installs the master
        /// authentication secret and binds it to the iButton (making it unique for
        /// a particular button).  Optionally, the device can be formatted before
        /// the service file is installed.</P>
        /// </summary>
        /// <param name="copr"> The SHAiButtonCopr to which the user object is tied.  This
        ///        Coprocessor contains the necessary binding code and service
        ///        filename, necessary for both locating a user and recreating his
        ///        unique secret. </param>
        /// <param name="owc"> The DS1963S iButton that this object will refer to. </param>
        /// <param name="formatDevice"> If <code>true</code>, the TMEX filesystem will be
        ///        formatted before the account service file is created. </param>
        /// <param name="authSecret"> The master authentication secret for the systm.
        /// </param>
        /// <exception cref="OneWireIOException"> on a 1-Wire communication error such as
        ///         reading an incorrect CRC from a 1-Wire device.  This could be
        ///         caused by a physical interruption in the 1-Wire Network due to
        ///         shorts or a newly arriving 1-Wire device issuing a 'presence pulse'. </exception>
        /// <exception cref="OneWireException"> on a communication or setup error with the 1-Wire
        ///         adapter
        /// </exception>
        /// <seealso cref= #SHAiButtonUser18(SHAiButtonCopr,OneWireContainer18) </seealso>
        /// <seealso cref= #SHAiButtonUser18(SHAiButtonCopr) </seealso>
        public SHAiButtonUser18(SHAiButtonCopr copr, OneWireContainer18 owc, bool formatDevice, byte[] authSecret) : this(copr)
        {
            //setup service filename

            //hold container reference
            this.ibc = owc;

            //and address
            this.address = owc.Address;

            if (!createServiceFile(owc, strServiceFilename, formatDevice))
            {
                throw new OneWireException("Failed to create service file.");
            }

            //save a copy of the binding code
            copr.getBindCode(this.fullBindCode, 0);
            Array.Copy(this.fullBindCode, 4, this.fullBindCode, 12, 3);

            //setup the fullBindCode with rest of info
            this.fullBindCode[4] = (byte)this.accountPageNumber;
            Array.Copy(this.address, 0, this.fullBindCode, 5, 7);

            if (!owc.installMasterSecret(accountPageNumber, authSecret, accountPageNumber & 7))
            {
                throw new OneWireException("Install Master Secret failed");
            }

            //not in critical path, so getBindBlah() is okay.
            if (!owc.bindSecretToiButton(accountPageNumber, copr.BindData, this.fullBindCode, accountPageNumber & 7))
            {
                throw new OneWireException("Bind Secret to iButton failed");
            }

            //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
            if (DEBUG)
            {
                IOHelper.writeLine("------------------------------------");
                IOHelper.writeLine("Initialized User");
                IOHelper.writeLine("address");
                IOHelper.writeBytesHex(owc.Address);
                IOHelper.writeLine("serviceFilename: " + strServiceFilename);
                IOHelper.writeLine("accountPageNumber: " + accountPageNumber);
                IOHelper.writeLine("authSecret");
                IOHelper.writeBytesHex(authSecret);
                IOHelper.writeLine("bindData");
                IOHelper.writeBytesHex(copr.bindData);
                IOHelper.writeLine("bindCode");
                IOHelper.writeBytesHex(copr.bindCode);
                IOHelper.writeLine("------------------------------------");
            }
            //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
        }
        /// <summary>
        /// <P>Creates a mostly unitialized SHAiButtonUser object.  This constructor
        /// merely copies the coprocessors 7 byte binding code into a local cache
        /// and stores the name of the account service file used for all user
        /// iButtons.</P>
        ///
        /// <P>Since this constructor leaves data unitialized, you should be very
        /// careful with the use of it.  It is expected that after calling this
        /// constructor, the user will call <code>setiButton</code> to finish the
        /// initialization process.  On memory-starved platforms, this should help
        /// optimize memory usage.</P>
        ///
        /// <P>Note: The same coprocessor can be used for write-authorization as
        /// authentication if you're transaction system is using unsigned transaction
        /// data.</P>
        /// </summary>
        /// <param name="copr"> The SHAiButtonCopr to which the user object is tied.  This
        ///        Coprocessor contains the necessary binding code and service
        ///        filename, necessary for both locating a user and recreating his
        ///        unique secret. </param>
        /// <param name="authCopr"> The SHAiButtonCopr used to generate the write-authorization
        ///        MAC for the copy-scratchpad command of the DS1961S.
        ///
        /// </param>
        /// <seealso cref= #SHAiButtonUser33(SHAiButtonCopr,OneWireContainer33,bool,byte[]) </seealso>
        /// <seealso cref= #SHAiButtonUser33(SHAiButtonCopr,SHAiButtonCopr,OneWireContainer33) </seealso>
        public SHAiButtonUser33(SHAiButtonCopr copr, SHAiButtonCopr authCopr)
        {
            //hold a reference to the coprocessor
            this.copr = authCopr;

            //make sure fullBindCode has appropriate ff padding
            Array.Copy(ffBlock, 0, this.fullBindCode, 0, 15);

            //create string representation of service filename
            copr.getFilename(this.serviceFile, 0);
            this.strServiceFilename = Encoding.Unicode.GetString(this.serviceFile) + "." + (int)copr.FilenameExt;
        }
    /// <summary>
    /// Method main
    ///
    /// </summary>
    /// <param name="args">
    /// </param>
    /// <exception cref="OneWireException"> </exception>
    /// <exception cref="OneWireIOException">
    ///  </exception>
    public static void Main3(string[] args)
    {
        //coprocessor
        long coprID = 0;

        // attempt to open the sha.properties file
        sha_properties = new Properties();
        if (!sha_properties.loadLocalFile("sha.properties"))
        {
            Debug.WriteLine("loading default sha.properties!");
            Assembly asm = typeof(SHADebitDemo.MainPage).GetTypeInfo().Assembly;
            sha_properties.loadResourceFile(asm, "SHADebitDemo.sha.properties");
        }

        // ------------------------------------------------------------
        // Instantiate coprocessor containers
        // ------------------------------------------------------------
        SHAiButtonCopr     copr   = null;
        OneWireContainer18 copr18 = new OneWireContainer18();

        copr18.setSpeed(DSPortAdapter.SPEED_REGULAR, false);
        copr18.SpeedCheck = false;

        // ------------------------------------------------------------
        // Setup the adapter for the coprocessor
        // ------------------------------------------------------------
        DSPortAdapter coprAdapter = null;
        string        coprAdapterName = null, coprPort = null;

        try
        {
            coprAdapterName = sha_properties.getProperty("copr.adapter", "{DS9097U}");
            coprPort        = sha_properties.getProperty("copr.port", "COM1");

            if (string.ReferenceEquals(coprPort, null) || string.ReferenceEquals(coprAdapterName, null))
            {
                coprAdapter = OneWireAccessProvider.DefaultAdapter;
            }
            else
            {
                coprAdapter = OneWireAccessProvider.getAdapter(coprAdapterName, coprPort);
            }

            IOHelper.writeLine("Coprocessor adapter loaded, adapter: " + coprAdapter.AdapterName + " port: " + coprAdapter.PortName);

            coprAdapter.adapterDetected();
            coprAdapter.targetFamily(0x18);
            coprAdapter.beginExclusive(true);
            coprAdapter.setSearchAllDevices();
            coprAdapter.reset();
        }
        catch (Exception e)
        {
            IOHelper.writeLine("Error initializing coprocessor adapter");
            Debug.WriteLine(e.ToString());
            Debug.Write(e.StackTrace);
            return;
        }

        // ------------------------------------------------------------
        // Find the coprocessor
        // ------------------------------------------------------------
        if (sha_properties.getPropertyBoolean("copr.simulated.isSimulated", false))
        {
            string coprVMfilename = sha_properties.getProperty("copr.simulated.filename");
            // ---------------------------------------------------------
            // Load emulated coprocessor
            // ---------------------------------------------------------
            try
            {
                copr = new SHAiButtonCoprVM(coprVMfilename);
            }
            catch (Exception e)
            {
                IOHelper.writeLine("Invalid Coprocessor Data File");
                Debug.WriteLine(e.ToString());
                Debug.Write(e.StackTrace);
                return;
            }
        }
        else
        {
            // ---------------------------------------------------------
            // Get the name of the coprocessor service file
            // ---------------------------------------------------------
            string filename = sha_properties.getProperty("copr.filename", "COPR.0");

            // ---------------------------------------------------------
            // Check for hardcoded coprocessor address
            // ---------------------------------------------------------
            byte[] coprAddress = sha_properties.getPropertyBytes("copr.address", null);
            long   lookupID    = 0;
            if (coprAddress != null)
            {
                lookupID = Address.toLong(coprAddress);

                IOHelper.write("Looking for coprocessor: ");
                IOHelper.writeLineHex(lookupID);
            }

            // ---------------------------------------------------------
            // Find hardware coprocessor
            // ---------------------------------------------------------
            try
            {
                bool next = coprAdapter.findFirstDevice();
                while (copr == null && next)
                {
                    try
                    {
                        long tmpCoprID = coprAdapter.AddressAsLong;
                        if (coprAddress == null || tmpCoprID == lookupID)
                        {
                            IOHelper.write("Loading coprocessor file: " + filename + " from device: ");
                            IOHelper.writeLineHex(tmpCoprID);

                            copr18.setupContainer(coprAdapter, tmpCoprID);
                            copr = new SHAiButtonCopr(copr18, filename);

                            //save coprocessor ID
                            coprID = tmpCoprID;
                        }
                    }
                    catch (Exception e)
                    {
                        IOHelper.writeLine(e);
                    }

                    next = coprAdapter.findNextDevice();
                }
            }
            catch (Exception)
            {
                ;
            }
        }

        if (copr == null)
        {
            IOHelper.writeLine("No Coprocessor found!");
            return;
        }

        IOHelper.writeLine(copr);
        IOHelper.writeLine();


        // ------------------------------------------------------------
        // Create the SHADebit transaction types
        // ------------------------------------------------------------
        //stores DS1963S transaction data
        SHATransaction trans     = null;
        string         transType = sha_properties.getProperty("ds1961s.transaction.type", "Signed");

        if (transType.ToLower().IndexOf("unsigned", StringComparison.Ordinal) >= 0)
        {
            trans = new SHADebitUnsigned(copr, 10000, 50);
        }
        else
        {
            trans = new SHADebit(copr, 10000, 50);
        }

        // ------------------------------------------------------------
        // Create the User Buttons objects
        // ------------------------------------------------------------
        //holds DS1963S user buttons
        OneWireContainer33 owc33 = new OneWireContainer33();

        owc33.setSpeed(DSPortAdapter.SPEED_REGULAR, false);
        //owc33.setSpeedCheck(false);

        // ------------------------------------------------------------
        // Get the adapter for the user
        // ------------------------------------------------------------
        DSPortAdapter adapter = null;
        string        userAdapterName = null, userPort = null;

        try
        {
            userAdapterName = sha_properties.getProperty("user.adapter", "{DS9097U}");
            userPort        = sha_properties.getProperty("user.port", "COM9");

            if (string.ReferenceEquals(userPort, null) || string.ReferenceEquals(userAdapterName, null))
            {
                if (!string.ReferenceEquals(coprAdapterName, null) && !string.ReferenceEquals(coprPort, null))
                {
                    adapter = OneWireAccessProvider.DefaultAdapter;
                }
                else
                {
                    adapter = coprAdapter;
                }
            }
            else if (userAdapterName.Equals(coprAdapterName) && userPort.Equals(coprPort))
            {
                adapter = coprAdapter;
            }
            else
            {
                adapter = OneWireAccessProvider.getAdapter(userAdapterName, userPort);
            }

            IOHelper.writeLine("User adapter loaded, adapter: " + adapter.AdapterName + " port: " + adapter.PortName);

            byte[] families = new byte[] { 0x33, unchecked ((byte)0xB3) };

            adapter.adapterDetected();
            adapter.targetFamily(families);
            adapter.beginExclusive(false);
            adapter.setSearchAllDevices();
            adapter.reset();
        }
        catch (Exception e)
        {
            IOHelper.writeLine("Error initializing user adapter.");
            Debug.WriteLine(e.ToString());
            Debug.Write(e.StackTrace);
            return;
        }

        // ---------------------------------------------------------------
        // Search for the button
        // ---------------------------------------------------------------
        try
        {
            long tmpID = -1;
            bool next  = adapter.findFirstDevice();
            for (; tmpID == -1 && next; next = adapter.findNextDevice())
            {
                tmpID = adapter.AddressAsLong;
                if (tmpID == coprID)
                {
                    tmpID = -1;
                }
                else
                {
                    owc33.setupContainer(adapter, tmpID);
                }
            }

            if (tmpID == -1)
            {
                IOHelper.writeLine("No buttons found!");
                return;
            }
        }
        catch (Exception)
        {
            IOHelper.writeLine("Adapter error while searching.");
            return;
        }

        IOHelper.write("Setting up user button: ");
        IOHelper.writeBytesHex(owc33.Address);
        IOHelper.writeLine();

        IOHelper.writeLine("How would you like to enter the authentication secret (unlimited bytes)? ");
        byte[] auth_secret = getBytes(0);
        IOHelper.writeBytes(auth_secret);
        IOHelper.writeLine();

        auth_secret = SHAiButtonCopr.reformatFor1961S(auth_secret);
        IOHelper.writeLine("Reformatted for compatibility with 1961S buttons");
        IOHelper.writeBytes(auth_secret);
        IOHelper.writeLine("");

        IOHelper.writeLine("Initial Balance in Cents? ");
        int initialBalance = IOHelper.readInt(100);

        trans.setParameter(SHADebit.INITIAL_AMOUNT, initialBalance);

        SHAiButtonUser user = new SHAiButtonUser33(copr, owc33, true, auth_secret);

        if (trans.setupTransactionData(user))
        {
            IOHelper.writeLine("Transaction data installation succeeded");
        }
        else
        {
            IOHelper.writeLine("Failed to initialize transaction data");
        }

        IOHelper.writeLine(user);
    }
        /// <summary>
        /// <P>Writes the account data to the SHAiButton.  First, this function
        /// asserts that the account page number is known.  The account data is
        /// copied from dataBuffer starting at the offset.  If there are less
        /// than 32 bytes available to copy, this function only copies the bytes
        /// that are available.</P>
        ///
        /// <P>Note that for the DS1961S user button, an authorization MAC must
        /// be generated for the copy-scratchpad command.  Since the scratchpad
        /// is only 8 bytes long, this must be done 4 times to write a page of
        /// data.  So, this function only writes (in 8 byte blocks) the bytes
        /// that have changed.</P>
        /// </summary>
        /// <param name="dataBuffer"> the buffer to copy the account data from </param>
        /// <param name="offset"> the index into the buffer where copying should begin </param>
        /// <returns> whether or not the data write succeeded
        /// </returns>
        /// <exception cref="OneWireIOException"> on a 1-Wire communication error such as
        ///         reading an incorrect CRC from a 1-Wire device.  This could be
        ///         caused by a physical interruption in the 1-Wire Network due to
        ///         shorts or a newly arriving 1-Wire device issuing a 'presence pulse'. </exception>
        /// <exception cref="OneWireException"> on a communication or setup error with the 1-Wire
        ///         adapter </exception>
        public override bool writeAccountData(byte[] dataBuffer, int offset)
        {
            lock (this)
            {
                //local vars.
                OneWireContainer33 ibcL         = this.ibc33;
                byte[]             copyAuth     = this.writeAccountData_copyAuth;
                byte[]             scratchpad   = this.writeAccountData_scratchpad;
                byte[]             pageData     = this.writeAccountData_pageData;
                byte[]             fullBindCode = this.fullBindCode;
                SHAiButtonCopr     coprL        = this.copr;

                //make sure account info is properly setup
                if (!checkAccountPageInfo(ibcL))
                {
                    return(false);
                }

                //if the part is being initialized, the container class "knows"
                //the secret already.  no need for a coprocessor.
                if (ibcL.ContainerSecretSet)
                {
                    //use container to write the data page, since it knows the secret
                    ibcL.writeDataPage(this.accountPageNumber, dataBuffer);
                    //update the data cache
                    Array.Copy(dataBuffer, offset, this.accountData, 0, 32);
                }
                else
                {
                    //since the container's secret is not set, we have to use the
                    //coprocessor for generating the copy scratchpad authorization.
                    if (coprL == null)
                    {
                        throw new OneWireException("No Write Authorization Coprocessor Available!");
                    }

                    //copy the data cache into a working page;
                    Array.Copy(this.accountData, 0, pageData, 0, 32);

                    //takes four write/copies to actually write the data page.
                    for (int i = 24; i >= 0; i -= 8)
                    {
                        int index = offset + i;
                        //only perform any action if the data needs to be updated
                        if ((dataBuffer[index] != accountData[i]) || (dataBuffer[index + 1] != accountData[i + 1]) || (dataBuffer[index + 2] != accountData[i + 2]) || (dataBuffer[index + 3] != accountData[i + 3]) || (dataBuffer[index + 4] != accountData[i + 4]) || (dataBuffer[index + 5] != accountData[i + 5]) || (dataBuffer[index + 6] != accountData[i + 6]) || (dataBuffer[index + 7] != accountData[i + 7]))
                        {
                            //format the working page for generating the
                            //appropriate copy authorization mac
                            pageData[28] = dataBuffer[index];
                            pageData[29] = dataBuffer[index + 1];
                            pageData[30] = dataBuffer[index + 2];
                            pageData[31] = dataBuffer[index + 3];

                            //format the scratchpad for generating the
                            //appropriate copy authorization mac
                            scratchpad[8]  = dataBuffer[index + 4];
                            scratchpad[9]  = dataBuffer[index + 5];
                            scratchpad[10] = dataBuffer[index + 6];
                            scratchpad[11] = dataBuffer[index + 7];

                            //add in the page num and address
                            Array.Copy(this.fullBindCode, 4, scratchpad, 12, 11);

                            //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
                            if (DEBUG)
                            {
                                IOHelper.writeLine("------------------------------------------------------------");
                                IOHelper.writeLine("SHAiButtonUser33 - writeAccountData loop ");
                                IOHelper.writeLine("current account data state: ");
                                IOHelper.writeBytesHex(this.accountData);
                                IOHelper.writeLine("current byte block: " + i);
                                IOHelper.writeLine("New bytes for block: ");
                                IOHelper.writeBytesHex(dataBuffer, index, 8);
                                IOHelper.writeLine("------------------------------------------------------------");
                            }
                            //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\

                            //get the copy authorization mac
                            coprL.createDataSignatureAuth(pageData, scratchpad, copyAuth, 0, fullBindCode);

                            //only need to pass it to coprocessor once
                            fullBindCode = null;

                            //write 8 bytes of data to the DS1961S scratchpad
                            if (!ibcL.writeScratchpad(this.accountPageNumber, i, dataBuffer, index, 8))
                            {
                                //operation failed
                                return(false);
                            }

                            //copy scratchpad to page
                            if (!ibcL.copyScratchpad(this.accountPageNumber, i, copyAuth, 0))
                            {
                                //operation failed
                                return(false);
                            }

                            //update cache of account data
                            Array.Copy(dataBuffer, index, this.accountData, i, 8);

                            //update our working copy of the account data
                            Array.Copy(this.accountData, 0, pageData, 0, 32);
                        }
                    }
                }
                return(true);
            }
        }
Exemple #8
0
    /// <summary>
    /// Method main
    ///
    /// </summary>
    /// <param name="args">
    /// </param>
    /// <exception cref="OneWireException"> </exception>
    /// <exception cref="OneWireIOException">
    ///  </exception>
    public static void Main1(string[] args)
    {
        byte[] sign_secret = null;
        byte[] auth_secret = null;

        // attempt to open the sha.properties file
        sha_properties = new Properties();
        if (!sha_properties.loadLocalFile("sha.properties"))
        {
            Debug.WriteLine("loading default sha.properties!");
            Assembly asm = typeof(SHADebitDemo.MainPage).GetTypeInfo().Assembly;
            sha_properties.loadResourceFile(asm, "SHADebitDemo.sha.properties");
        }

        // ------------------------------------------------------------
        // Instantiate coprocessor containers
        // ------------------------------------------------------------
        SHAiButtonCopr     copr   = null;
        OneWireContainer18 copr18 = new OneWireContainer18();

        //TODO copr18.setSpeed(DSPortAdapter.SPEED_OVERDRIVE, false);
        copr18.SpeedCheck = false;

        // ------------------------------------------------------------
        // Setup the adapter for the coprocessor
        // ------------------------------------------------------------
        DSPortAdapter coprAdapter = null;
        string        coprAdapterName = null, coprPort = null;

        try
        {
            coprAdapterName = sha_properties.getProperty("copr.adapter");
            coprPort        = sha_properties.getProperty("copr.port");

            if (string.ReferenceEquals(coprPort, null) || string.ReferenceEquals(coprAdapterName, null))
            {
                coprAdapter = OneWireAccessProvider.DefaultAdapter;
            }
            else
            {
                coprAdapter = OneWireAccessProvider.getAdapter(coprAdapterName, coprPort);
            }

            Debug.WriteLine("Coprocessor adapter loaded, adapter: " + coprAdapter.AdapterName + " port: " + coprAdapter.PortName);

            coprAdapter.adapterDetected();
            coprAdapter.targetFamily(0x18);
            coprAdapter.beginExclusive(true);
            coprAdapter.reset();
            coprAdapter.setSearchAllDevices();
            coprAdapter.reset();
            coprAdapter.putByte(0x3c);
            //TODO coprAdapter.Speed = DSPortAdapter.SPEED_OVERDRIVE;
        }
        catch (Exception e)
        {
            Debug.WriteLine("Error initializing coprocessor adapter");
            Debug.WriteLine(e.ToString());
            Debug.Write(e.StackTrace);
            return;
        }

        // ---------------------------------------------------------
        // Get the name of the coprocessor service file
        // ---------------------------------------------------------
        string filename = sha_properties.getProperty("copr.filename", "COPR.0");

        bool   next = false;
        bool   vmSaveSecrets  = true;
        string coprVMfilename = null;

        // ------------------------------------------------------------
        // Find the coprocessor
        // ------------------------------------------------------------
        if (sha_properties.getPropertyBoolean("copr.simulated.isSimulated", false))
        {
            coprVMfilename = sha_properties.getProperty("copr.simulated.filename");
            vmSaveSecrets  = sha_properties.getPropertyBoolean("copr.simulated.saveSecrets", true);

            // ---------------------------------------------------------
            // Load emulated coprocessor
            // ---------------------------------------------------------
            Debug.WriteLine("Setting up simulated Copressor.");
            Debug.WriteLine("Would you like to emulate another coprocessor? (y)");
            //if (IOHelper.readLine().ToUpper()[0] == 'Y')
            //{
            //    //    OneWireContainer18 ibc = new OneWireContainer18();
            //    ibc.SpeedCheck = false;
            //    try
            //    {
            //        next = coprAdapter.findFirstDevice();
            //        while (next && copr == null)
            //        {
            //            try
            //            {
            //                Debug.WriteLine(coprAdapter.AddressAsLong);
            //                ibc.setupContainer(coprAdapter, coprAdapter.AddressAsLong);
            //                copr = new SHAiButtonCopr(ibc, filename);
            //            }
            //            catch (Exception e)
            //            {
            //                Debug.WriteLine(e.ToString());
            //                Debug.Write(e.StackTrace);
            //            }
            //            next = coprAdapter.findNextDevice();
            //        }
            //    }
            //    catch (Exception)
            //    {
            //        ;
            //    }
            //    if (copr == null)
            //    {
            //        Debug.WriteLine("No coprocessor found to emulate");
            //        return;
            //    }

            //    Debug.WriteLine("");
            //    Debug.WriteLine("Emulating Coprocessor: " + ibc.AddressAsString);
            //    Debug.WriteLine("");

            //    //now that we got all that, we need a signing secret and an authentication secret
            //    Debug.WriteLine("How would you like to enter the signing secret (unlimited bytes)? ");
            //    sign_secret = new byte[] { 0, 0, 0, 0 }; //TODO
            //    IOHelper.writeBytes(sign_secret);

            //    Debug.WriteLine("");
            //    Debug.WriteLine("How would you like to enter the authentication secret (unlimited bytes)? ");
            //    auth_secret = new byte[] { 0, 0, 0, 0 }; //TODO
            //    IOHelper.writeBytes(auth_secret);

            //    Debug.WriteLine("");
            //    if (copr.DS1961Scompatible)
            //    {
            //        //reformat the auth_secret
            //        auth_secret = SHAiButtonCopr.reformatFor1961S(auth_secret);
            //        IOHelper.writeBytes(auth_secret);
            //    }
            //    Debug.WriteLine("");
            //    copr = new SHAiButtonCoprVM(ibc, filename, sign_secret, auth_secret);

            //    ((SHAiButtonCoprVM)copr).save(coprVMfilename, true);

            //    Debug.WriteLine(copr);
            //    return;
            //}
        }
        //else
        {
            // ---------------------------------------------------------
            // Check for hardcoded coprocessor address
            // ---------------------------------------------------------
            byte[] coprAddress = sha_properties.getPropertyBytes("copr.address", null);
            long   lookupID = 0, coprID = -1;
            if (coprAddress != null)
            {
                lookupID = com.dalsemi.onewire.utils.Address.toLong(coprAddress);

                Debug.Write("Looking for coprocessor: " + lookupID.ToString("x"));
            }

            // ---------------------------------------------------------
            // Find hardware coprocessor
            // ---------------------------------------------------------
            try
            {
                next = coprAdapter.findFirstDevice();
                while (copr == null && next)
                {
                    try
                    {
                        long tmpCoprID = coprAdapter.AddressAsLong;
                        if (coprAddress == null || tmpCoprID == lookupID)
                        {
                            Debug.WriteLine("Loading coprocessor file: " + filename + " from device: " + tmpCoprID.ToString("x"));

                            copr18.setupContainer(coprAdapter, tmpCoprID);

                            //save coprocessor ID
                            coprID = tmpCoprID;
                        }
                    }
                    catch (Exception e)
                    {
                        Debug.WriteLine(e);
                    }

                    next = coprAdapter.findNextDevice();
                }
            }
            catch (Exception)
            {
                ;
            }

            if (coprID == -1)
            {
                Debug.WriteLine("No Coprocessor found!");
                return;
            }

            Debug.WriteLine("Setting up DS1963S as Coprocessor: " + com.dalsemi.onewire.utils.Address.ToString(copr18.Address));
        }

        // Now that we've got a suitable button for creating a coprocessor,
        // let's ask the user for all the necessary paramters.

        Debug.Write("Enter the name of the coprocessor file (usually 'COPR') : ");
        byte[] coprname = { (byte)'C', (byte)'O', (byte)'P', (byte)'R' }; //com.dalsemi.onewire.utils.IOHelper.readBytesAsc(4, ' ');

        Debug.Write("Enter the file extension of the coprocessor file (0) : ");
        int coprext = 0; // com.dalsemi.onewire.utils.IOHelper.readInt(0);

        Debug.Write("Enter the name of the service file (4 characters) : ");
        byte[] name = { (byte)'S', (byte)'V', (byte)'C', (byte)'F' }; // com.dalsemi.onewire.utils.IOHelper.readBytesAsc(4, ' ');

        Debug.Write("Enter the file extension of the service file (102 for Money) : ");
        byte ext = 102; // (byte)com.dalsemi.onewire.utils.IOHelper.readInt(102);

        Debug.Write("Enter authentication page number (7) : ");
        int auth_page = 7; // com.dalsemi.onewire.utils.IOHelper.readInt(7);

        if (auth_page < 7)
        {
            Debug.WriteLine("Authentication page too low, default to 7");
            auth_page = 7;
        }
        if (auth_page == 8)
        {
            Debug.WriteLine("Page already taken, default to 7");
            auth_page = 7;
        }

        Debug.Write("Enter workspace page number (9) : ");
        int work_page = 9; //TODO com.dalsemi.onewire.utils.IOHelper.readInt(9);

        if (work_page < 7)
        {
            Debug.WriteLine("Workspace page too low, default to 9");
            work_page = 9;
        }
        if ((work_page == 8) || (work_page == auth_page))
        {
            Debug.WriteLine("Page already taken, default to 9");
            work_page = 9;
        }

        Debug.Write("Enter version number (1) : ");
        int version = 1; //TODO com.dalsemi.onewire.utils.IOHelper.readInt(1);

        Debug.WriteLine("How would you like to enter the binding data (32 bytes)? ");
        byte[] bind_data = getBytes(32);

        Debug.WriteLine("How would you like to enter the binding code (7 bytes)? ");
        byte[] bind_code = getBytes(7);

        // This could be done on the button
        //java.util.Random random = new java.util.Random();
        //random.nextBytes(chlg);
        //  Need to know what the challenge is so that I can reproduce it!
        byte[] chlg = new byte[] { 0x00, 0x00, 0x00 };

        Debug.WriteLine("Enter a human-readable provider name: ");
        string provider_name = com.dalsemi.onewire.utils.IOHelper.readLine();

        Debug.WriteLine("Enter an initial signature in HEX (all 0' default): ");
        byte[] sig_ini = com.dalsemi.onewire.utils.IOHelper.readBytesHex(20, 0);

        Debug.WriteLine("Enter any additional text you would like store on the coprocessor: ");
        string aux_data = com.dalsemi.onewire.utils.IOHelper.readLine();

        Debug.WriteLine("Enter an encryption code (0): ");
        int enc_code = com.dalsemi.onewire.utils.IOHelper.readInt(0);

        //now that we got all that, we need a signing secret and an authentication secret
        Debug.WriteLine("How would you like to enter the signing secret (unlimited bytes)? ");
        sign_secret = new byte[] { 0, 0, 0, 0 }; //TODO
        com.dalsemi.onewire.utils.IOHelper.writeBytes(sign_secret);

        Debug.WriteLine("");
        Debug.WriteLine("How would you like to enter the authentication secret (unlimited bytes)? ");
        auth_secret = new byte[] { 0, 0, 0, 0 }; //TODO
        com.dalsemi.onewire.utils.IOHelper.writeBytes(auth_secret);

        Debug.WriteLine("");
        Debug.WriteLine("Would you like to reformat the authentication secret for the 1961S? (y or n)");
        string s = com.dalsemi.onewire.utils.IOHelper.readLine();

        if (s.ToUpper()[0] == 'Y')
        {
            //reformat the auth_secret
            auth_secret = SHAiButtonCopr.reformatFor1961S(auth_secret);
            com.dalsemi.onewire.utils.IOHelper.writeLine("authentication secret");
            com.dalsemi.onewire.utils.IOHelper.writeBytes(auth_secret);
            com.dalsemi.onewire.utils.IOHelper.writeLine();
        }

        // signing page must be 8, using secret 0
        int sign_page = 8;

        if (!string.ReferenceEquals(coprVMfilename, null))
        {
            byte[] RomID = new byte[] { 0x18, 0x20, 0xAF, 0x02, 0x00, 0x00, 0x00, 0xE7 };
            RomID = sha_properties.getPropertyBytes("copr.simulated.address", RomID);

            copr = new SHAiButtonCoprVM(RomID, sign_page, auth_page, work_page, version, enc_code, ext, name, Encoding.UTF8.GetBytes(provider_name), bind_data, bind_code, Encoding.UTF8.GetBytes(aux_data), sig_ini, chlg, sign_secret, auth_secret);
            ((SHAiButtonCoprVM)copr).save(coprVMfilename, vmSaveSecrets);
        }
        else
        {
            string coprFilename = coprname.ToString() + "." + coprext;
            // initialize this OneWireContainer18 as a valid coprocessor
            copr = new SHAiButtonCopr(copr18, coprFilename, true, sign_page, auth_page, work_page, version, enc_code, ext, name, Encoding.UTF8.GetBytes(provider_name), bind_data, bind_code, Encoding.UTF8.GetBytes(aux_data), sig_ini, chlg, sign_secret, auth_secret);
        }
        Debug.WriteLine("Initialized Coprocessor");
        Debug.WriteLine(copr.ToString());

        Debug.WriteLine("done");
    }
 /// <summary>
 /// SHADebitUnsigned 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.
 /// </summary>
 /// <param name="copr"> The coprocessor used for authentication and data
 ///             signing in this transaction. </param>
 public SHADebitUnsigned(SHAiButtonCopr copr) : base(copr)
 {
     resetParameters();
 }
 /// <summary>
 /// SHADebitUnsigned 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.
 /// </summary>
 /// <param name="copr"> The coprocessor used for authentication and data
 ///             signing in this transaction. </param>
 public SHADebitUnsigned(SHAiButtonCopr copr, int initialAmount, int debitAmount) : base(copr)
 {
     this.initialAmount = initialAmount;
     this.debitAmount   = debitAmount;
 }
    public static void Main0(string[] args)
    {
        //coprocessor
        long coprID   = 0;
        long lookupID = 0;
        bool next;

        // ------------------------------------------------------------
        // Check for valid path to sha.properties file on the cmd line.
        // ------------------------------------------------------------
        for (int i = 0; i < args.Length; i++)
        {
            string arg = args[i].ToUpper();
            if (arg.IndexOf("-P", StringComparison.Ordinal) == 0)
            {
                string sha_props_path;
                if (arg.Length == 2)
                {
                    sha_props_path = args[++i];
                }
                else
                {
                    sha_props_path = arg.Substring(2);
                }

                // attempt to open the sha.properties file
                sha_properties = new Properties();
                if (!sha_properties.loadLocalFile("sha.properties"))
                {
                    Debug.WriteLine("loading default sha.properties!");
                    Assembly asm = typeof(SHADebitDemo.MainPage).GetTypeInfo().Assembly;
                    sha_properties.loadResourceFile(asm, "SHADebitDemo.sha.properties");
                }
            }
            else
            {
                printUsageString();
                return;
            }
        }


        // ------------------------------------------------------------
        // Instantiate coprocessor containers
        // ------------------------------------------------------------
        SHAiButtonCopr     copr   = null;
        OneWireContainer18 copr18 = new OneWireContainer18();

        copr18.setSpeed(DSPortAdapter.SPEED_OVERDRIVE, false);
        copr18.SpeedCheck = false;

        // ------------------------------------------------------------
        // Setup the adapter for the coprocessor
        // ------------------------------------------------------------
        DSPortAdapter coprAdapter = null;
        string        coprAdapterName = null, coprPort = null;

        try
        {
            coprAdapterName = sha_properties.getProperty("copr.adapter");
            coprPort        = sha_properties.getProperty("copr.port");

            if (string.ReferenceEquals(coprPort, null) || string.ReferenceEquals(coprAdapterName, null))
            {
                coprAdapter = OneWireAccessProvider.DefaultAdapter;
            }
            else
            {
                coprAdapter = OneWireAccessProvider.getAdapter(coprAdapterName, coprPort);
            }

            IOHelper.writeLine("Coprocessor adapter loaded, adapter: " + coprAdapter.AdapterName + " port: " + coprAdapter.PortName);

            coprAdapter.adapterDetected();
            coprAdapter.targetFamily(0x18);
            coprAdapter.beginExclusive(true);
            coprAdapter.reset();
            coprAdapter.setSearchAllDevices();
            coprAdapter.reset();
            coprAdapter.putByte(0x3c);
            coprAdapter.Speed = DSPortAdapter.SPEED_OVERDRIVE;
        }
        catch (Exception e)
        {
            IOHelper.writeLine("Error initializing coprocessor adapter");
            Debug.WriteLine(e.ToString());
            Debug.Write(e.StackTrace);
            return;
        }

        // ------------------------------------------------------------
        // Find the coprocessor
        // ------------------------------------------------------------
        if (sha_properties.getPropertyBoolean("copr.simulated.isSimulated", false))
        {
            string coprVMfilename = sha_properties.getProperty("copr.simulated.filename");
            // ---------------------------------------------------------
            // Load emulated coprocessor
            // ---------------------------------------------------------
            try
            {
                copr = new SHAiButtonCoprVM(coprVMfilename);
            }
            catch (Exception e)
            {
                IOHelper.writeLine("Invalid Coprocessor Data File");
                Debug.WriteLine(e.ToString());
                Debug.Write(e.StackTrace);
                return;
            }
        }
        else
        {
            // ---------------------------------------------------------
            // Get the name of the coprocessor service file
            // ---------------------------------------------------------
            string filename = sha_properties.getProperty("copr.filename", "COPR.0");

            // ---------------------------------------------------------
            // Check for hardcoded coprocessor address
            // ---------------------------------------------------------
            byte[] coprAddress = sha_properties.getPropertyBytes("copr.address", null);
            lookupID = 0;
            if (coprAddress != null)
            {
                lookupID = Address.toLong(coprAddress);

                IOHelper.write("Looking for coprocessor: ");
                IOHelper.writeLineHex(lookupID);
            }

            // ---------------------------------------------------------
            // Find hardware coprocessor
            // ---------------------------------------------------------
            try
            {
                next = coprAdapter.findFirstDevice();
                while (copr == null && next)
                {
                    try
                    {
                        long tmpCoprID = coprAdapter.AddressAsLong;
                        if (coprAddress == null || tmpCoprID == lookupID)
                        {
                            IOHelper.write("Loading coprocessor file: " + filename + " from device: ");
                            IOHelper.writeLineHex(tmpCoprID);

                            copr18.setupContainer(coprAdapter, tmpCoprID);
                            copr = new SHAiButtonCopr(copr18, filename);

                            //save coprocessor ID
                            coprID = tmpCoprID;
                        }
                    }
                    catch (Exception e)
                    {
                        IOHelper.writeLine(e);
                    }

                    next = coprAdapter.findNextDevice();
                }
            }
            catch (Exception)
            {
                ;
            }
        }

        if (copr == null)
        {
            IOHelper.writeLine("No Coprocessor found!");
            return;
        }

        IOHelper.writeLine(copr);
        IOHelper.writeLine();


        // ------------------------------------------------------------
        // Create the SHADebit transaction types
        // ------------------------------------------------------------
        //stores DS1963S transaction type
        SHATransaction debit18 = null;

        string transType18 = sha_properties.getProperty("transaction.type", "signed");

        transType18 = transType18.ToLower();
        if (transType18.Equals("signed"))
        {
            debit18 = new SHADebit(copr, 10000, 50);
        }
        else
        {
            debit18 = new SHADebitUnsigned(copr, 10000, 50);
        }

        //stores DS1961S transaction type
        SHATransaction debit33 = null;

        string transType33 = sha_properties.getProperty("ds1961s.transaction.type", "unsigned");

        transType33 = transType33.ToLower();
        if (transType33.Equals(transType18))
        {
            debit33 = debit18;
        }
        else if (transType33.IndexOf("unsigned", StringComparison.Ordinal) >= 0)
        {
            //everything is seemless if you use the authentication secret
            //as the button's secret.
            debit33 = new SHADebitUnsigned(copr, 10000, 50);
        }
        else
        {
            //if the 1961S uses the authentication secret,
            //you'll need another button for generating the
            //write authorization MAC, but you can share the
            //1963S debit code for signed data.
            debit33 = new SHADebit(copr, 10000, 50);
        }

        //Transaction super class, swap variable
        SHATransaction trans = null;

        // ------------------------------------------------------------
        // Get the write-authorization coprocessor for ds1961S
        // ------------------------------------------------------------
        //first get the write authorization adapter
        DSPortAdapter authAdapter = null;
        string        authAdapterName = null, authPort = null;

        try
        {
            authAdapterName = sha_properties.getProperty("ds1961s.copr.adapter");
            authPort        = sha_properties.getProperty("ds1961s.copr.port");

            if (string.ReferenceEquals(authAdapterName, null) || string.ReferenceEquals(authAdapterName, null))
            {
                if (!string.ReferenceEquals(coprAdapterName, null) && !string.ReferenceEquals(coprPort, null))
                {
                    authAdapter = OneWireAccessProvider.DefaultAdapter;
                }
                else
                {
                    authAdapter = coprAdapter;
                }
            }
            else if (coprAdapterName.Equals(authAdapterName) && coprPort.Equals(authPort))
            {
                authAdapter = coprAdapter;
            }
            else
            {
                authAdapter = OneWireAccessProvider.getAdapter(authAdapterName, authPort);
            }

            IOHelper.writeLine("Write-Authorization adapter loaded, adapter: " + authAdapter.AdapterName + " port: " + authAdapter.PortName);

            byte[] families = new byte[] { 0x18 };

            authAdapter.adapterDetected();
            authAdapter.targetFamily(families);
            authAdapter.beginExclusive(false);
            authAdapter.reset();
            authAdapter.setSearchAllDevices();
            authAdapter.reset();
            authAdapter.putByte(0x3c);
            authAdapter.Speed = DSPortAdapter.SPEED_OVERDRIVE;
        }
        catch (Exception e)
        {
            IOHelper.writeLine("Error initializing write-authorization adapter.");
            Debug.WriteLine(e.ToString());
            Debug.Write(e.StackTrace);
            return;
        }

        //now find the coprocessor
        SHAiButtonCopr authCopr = null;

        // -----------------------------------------------------------
        // Check for hardcoded write-authorizaton coprocessor address
        // -----------------------------------------------------------
        byte[] authCoprAddress = sha_properties.getPropertyBytes("ds1961s.copr.address", null);
        lookupID = 0;
        if (authCoprAddress != null)
        {
            lookupID = Address.toLong(authCoprAddress);

            IOHelper.write("Looking for coprocessor: ");
            IOHelper.writeLineHex(lookupID);
        }
        if (lookupID == coprID)
        {
            //it's the same as the standard coprocessor.
            //valid only if we're not signing the data
            authCopr = copr;
        }
        else
        {
            // ---------------------------------------------------------
            // Find write-authorization coprocessor
            // ---------------------------------------------------------
            try
            {
                string             filename = sha_properties.getProperty("ds1961s.copr.filename", "COPR.1");
                OneWireContainer18 auth18   = new OneWireContainer18();
                auth18.setSpeed(DSPortAdapter.SPEED_OVERDRIVE, false);
                auth18.SpeedCheck = false;

                next = authAdapter.findFirstDevice();
                while (authCopr == null && next)
                {
                    try
                    {
                        long tmpAuthID = authAdapter.AddressAsLong;
                        if (authCoprAddress == null || tmpAuthID == lookupID)
                        {
                            IOHelper.write("Loading coprocessor file: " + filename + " from device: ");
                            IOHelper.writeLineHex(tmpAuthID);

                            auth18.setupContainer(authAdapter, tmpAuthID);
                            authCopr = new SHAiButtonCopr(auth18, filename);
                        }
                    }
                    catch (Exception e)
                    {
                        IOHelper.writeLine(e);
                    }

                    next = authAdapter.findNextDevice();
                }
            }
            catch (Exception e)
            {
                IOHelper.writeLine(e);
            }
            if (authCopr == null)
            {
                IOHelper.writeLine("no write-authorization coprocessor found");
                if (copr is SHAiButtonCoprVM)
                {
                    authCopr = copr;
                    IOHelper.writeLine("Re-using SHAiButtonCoprVM");
                }
            }
        }

        IOHelper.writeLine(authCopr);
        IOHelper.writeLine();

        // ------------------------------------------------------------
        // Create the User Buttons objects
        // ------------------------------------------------------------
        //holds DS1963S user buttons
        SHAiButtonUser18   user18 = new SHAiButtonUser18(copr);
        OneWireContainer18 owc18  = new OneWireContainer18();

        owc18.setSpeed(DSPortAdapter.SPEED_OVERDRIVE, false);
        owc18.SpeedCheck = false;

        //holds DS1961S user buttons
        SHAiButtonUser33   user33 = new SHAiButtonUser33(copr, authCopr);
        OneWireContainer33 owc33  = new OneWireContainer33();

        owc33.setSpeed(DSPortAdapter.SPEED_OVERDRIVE, false);
        //owc33.setSpeedCheck(false);

        //Holds generic user type, swap variable
        SHAiButtonUser user = null;

        // ------------------------------------------------------------
        // Get the adapter for the user
        // ------------------------------------------------------------
        DSPortAdapter adapter = null;
        string        userAdapterName = null, userPort = null;

        try
        {
            userAdapterName = sha_properties.getProperty("user.adapter");
            userPort        = sha_properties.getProperty("user.port");

            if (string.ReferenceEquals(userPort, null) || string.ReferenceEquals(userAdapterName, null))
            {
                if (!string.ReferenceEquals(coprAdapterName, null) && !string.ReferenceEquals(coprPort, null))
                {
                    if (!string.ReferenceEquals(authAdapterName, null) && !string.ReferenceEquals(authPort, null))
                    {
                        adapter = OneWireAccessProvider.DefaultAdapter;
                    }
                    else
                    {
                        adapter = authAdapter;
                    }
                }
                else
                {
                    adapter = coprAdapter;
                }
            }
            else if (userAdapterName.Equals(authAdapterName) && userPort.Equals(authPort))
            {
                adapter = authAdapter;
            }
            else if (userAdapterName.Equals(coprAdapterName) && userPort.Equals(coprPort))
            {
                adapter = coprAdapter;
            }
            else
            {
                adapter = OneWireAccessProvider.getAdapter(userAdapterName, userPort);
            }

            IOHelper.writeLine("User adapter loaded, adapter: " + adapter.AdapterName + " port: " + adapter.PortName);

            byte[] families = new byte[] { 0x18, 0x33 };
            families = sha_properties.getPropertyBytes("transaction.familyCodes", families);
            IOHelper.write("Supporting the following family codes: ");
            IOHelper.writeBytesHex(" ", families, 0, families.Length);

            adapter.adapterDetected();
            adapter.targetFamily(families);
            adapter.beginExclusive(true);
            adapter.reset();
            adapter.setSearchAllDevices();
            adapter.reset();
            adapter.putByte(0x3c);
            adapter.Speed = DSPortAdapter.SPEED_OVERDRIVE;
        }
        catch (Exception e)
        {
            IOHelper.writeLine("Error initializing user adapter.");
            Debug.WriteLine(e.ToString());
            Debug.Write(e.StackTrace);
            return;
        }

        //timing variables
        long t0 = 0, t1 = 0, t2 = 0, t3 = 0, t4 = 0, t5 = 0;

        //address of current device
        byte[] address = new byte[8];

        //result of findNextDevice/findFirstDevice
        next = false;

        //holds list of known buttons
        long[] buttons = new long[16];
        //count of how many buttons are in buttons array
        int index = 0;

        //temporary id representing current button
        long tmpID = -1;

        //array of buttons looked at during this search
        long[] temp = new long[16];
        //count of how many buttons in temp array
        int cIndex = 0;

        //flag indiciating whether or not temp array represents
        //the complete list of buttons on the network.
        bool wholeList = false;

        Debug.WriteLine("");
        Debug.WriteLine("");
        Debug.WriteLine("**********************************************************");
        Debug.WriteLine("   Beginning The Main Application Loop (Search & Debit)");
        Debug.WriteLine("           Press Enter to Exit Application");
        Debug.WriteLine("**********************************************************");
        Debug.WriteLine("");

        //application infinite loop
        for (bool applicationFinished = false; !applicationFinished;)
        {
            try
            {
                if (coprAdapter != adapter)
                {
                    //in case coprocessor communication got hosed, make sure
                    //the coprocessor adapter is in overdrive
                    coprAdapter.Speed = DSPortAdapter.SPEED_REGULAR;
                    coprAdapter.reset();
                    coprAdapter.putByte(0x3c);        //overdrive skip rom
                    coprAdapter.Speed = DSPortAdapter.SPEED_OVERDRIVE;
                }
                if (authAdapter != coprAdapter && authAdapter != adapter)
                {
                    //in case coprocessor communication with the write-
                    //authorization coprocessor got hosed, make sure
                    //the coprocessor adapter is in overdrive
                    authAdapter.Speed = DSPortAdapter.SPEED_REGULAR;
                    authAdapter.reset();
                    authAdapter.putByte(0x3c);        //overdrive skip rom
                    authAdapter.Speed = DSPortAdapter.SPEED_OVERDRIVE;
                }
            }
            catch (Exception)
            {
                ;
            }

            // ---------------------------------------------------------
            // Search for new buttons
            // ---------------------------------------------------------
            bool buttonSearch = true;

            //Button search loop, waits forever until new button appears.
            while (buttonSearch && !applicationFinished)
            {
                wholeList = false;
                t0        = Stopwatch.GetTimestamp() * TimeSpan.TicksPerMillisecond;
                try
                {
                    //Go into overdrive
                    adapter.Speed = DSPortAdapter.SPEED_REGULAR;
                    adapter.reset();
                    adapter.putByte(0x3c);        //overdrive skip rom
                    adapter.Speed = DSPortAdapter.SPEED_OVERDRIVE;

                    // Begin search for new buttons
                    if (!next)
                    {
                        wholeList = true;
                        next      = adapter.findFirstDevice();
                    }

                    for (tmpID = -1, cIndex = 0; next && (tmpID == -1); next = adapter.findNextDevice())
                    {
                        tmpID = adapter.AddressAsLong;
                        if (tmpID != coprID)
                        {
                            temp[cIndex++] = tmpID;
                            for (int i = 0; i < index; i++)
                            {
                                if (buttons[i] == tmpID)
                                {                 //been here all along
                                    tmpID = -1;
                                    i     = index;
                                }
                            }

                            if (tmpID != -1)
                            {
                                //populate address array
                                adapter.getAddress(address);
                            }
                        }
                        else
                        {
                            tmpID = -1;
                        }
                    }

                    //if we found a new button
                    if (tmpID != -1)
                    {
                        //add it to the main list
                        buttons[index++] = tmpID;

                        //quite searching, we got one!
                        buttonSearch = false;
                    }
                    else if (wholeList)
                    {
                        //went through whole list with nothing new
                        //update the main list of buttons
                        buttons = temp;
                        index   = cIndex;

                        //if user presses the enter key, we'll quit and clean up nicely
//TODO				  applicationFinished = (System.in.available() > 0);
                    }
                }
                catch (Exception e)
                {
                    if (DEBUG)
                    {
                        IOHelper.writeLine("adapter hiccup while searching");
                        Debug.WriteLine(e.ToString());
                        Debug.Write(e.StackTrace);
                    }
                }
            }

            if (applicationFinished)
            {
                continue;
            }

            // ---------------------------------------------------------
            // Perform the transaction
            // ---------------------------------------------------------
            try
            {
                t1 = Stopwatch.GetTimestamp() * TimeSpan.TicksPerMillisecond;

                //de-ref the user
                user = null;

                //check for button family code
                if ((tmpID & 0x18) == (byte)0x18)
                {
                    //get transactions for ds1963s
                    trans = debit18;
                    owc18.setupContainer(adapter, address);
                    if (user18.setiButton18(owc18))
                    {
                        user = user18;
                    }
                }
                else if ((tmpID & 0x33) == (byte)0x33)
                {
                    //get transactions for 1961S
                    trans = debit33;
                    owc33.setupContainer(adapter, address);
                    if (user33.setiButton33(owc33))
                    {
                        user = user33;
                    }
                }

                if (user != null)
                {
                    Debug.WriteLine("");
                    Debug.WriteLine(user.ToString());
                    t2 = Stopwatch.GetTimestamp() * TimeSpan.TicksPerMillisecond;
                    if (trans.verifyUser(user))
                    {
                        t3 = Stopwatch.GetTimestamp() * TimeSpan.TicksPerMillisecond;
                        if (trans.verifyTransactionData(user))
                        {
                            t4 = Stopwatch.GetTimestamp() * TimeSpan.TicksPerMillisecond;
                            if (!trans.executeTransaction(user, true))
                            {
                                Debug.WriteLine("Execute Transaction Failed");
                            }
                            t5 = Stopwatch.GetTimestamp() * TimeSpan.TicksPerMillisecond;

                            Debug.WriteLine("  Debit Amount: $00.50");
                            Debug.Write("User's balance: $");
                            int balance = trans.getParameter(SHADebit.USER_BALANCE);
                            Debug.WriteLine(com.dalsemi.onewire.utils.Convert.ToString(balance / 100d, 2));
                        }
                        else
                        {
                            Debug.WriteLine("Verify Transaction Data Failed");
                        }
                    }
                    else
                    {
                        Debug.WriteLine("Verify User Authentication Failed");
                    }
                }
                else
                {
                    Debug.WriteLine("Not a SHA user of this service");
                }

                Debug.Write("Total time: ");
                Debug.WriteLine(t5 - t0);
                Debug.Write("Executing transaction took: ");
                Debug.WriteLine(t5 - t4);
                Debug.Write("Verifying data took: ");
                Debug.WriteLine(t4 - t3);
                Debug.Write("Verifying user took: ");
                Debug.WriteLine(t3 - t2);
                Debug.Write("Loading user data took: ");
                Debug.WriteLine(t2 - t1);
                Debug.Write("Finding user took: ");
                Debug.WriteLine(t1 - t0);

                //report all errors
                if (trans.LastError != 0)
                {
                    IOHelper.writeLine("Last Error Code: ");
                    IOHelper.writeLine(trans.LastError);
                    if (trans.LastError == SHATransaction.COPROCESSOR_FAILURE)
                    {
                        IOHelper.writeLine("COPR Error Code: ");
                        IOHelper.writeLine(copr.LastError);
                    }
                }
            }
            catch (Exception e)
            {
                Debug.WriteLine("Transaction failed!");
                Debug.WriteLine(e.ToString());
                Debug.Write(e.StackTrace);
            }
        }

        // --------------------------------------------------------------
        // Some Friendly Cleanup
        // --------------------------------------------------------------
        adapter.endExclusive();
        coprAdapter.endExclusive();
        authAdapter.endExclusive();
    }
Exemple #12
0
        /// <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);
        }
 /// <summary>
 /// 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.
 /// </summary>
 /// <param name="copr">       The coprocessor used for authentication and data
 ///                   signing in this transaction. </param>
 /// <param name="extra_data"> The 7 bytes of extra data to be used instead
 ///                   of the balance. </param>
 /// <param name="len">        The len, 7 or less of the data.  It is 0 padded. </param>
 public SHASoftAuth(SHAiButtonCopr copr, byte[] extra_data, int len) : base(copr)
 {
     Array.Copy(extra_data, 0, this.master_ver_data, 0, len);
 }
 /// <summary>
 /// 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.
 /// </summary>
 /// <param name="copr"> The coprocessor used for authentication and data
 ///             signing in this transaction. </param>
 public SHASoftAuth(SHAiButtonCopr copr) : base(copr)
 {
     resetParameters();
 }
 /// <summary>
 /// <P>Creates a new SHATransaction, ensuring that reference to
 /// the coprocessor is saved and the errors are cleared.</P>
 /// </summary>
 protected internal SHATransaction(SHAiButtonCopr copr)
 {
     this.copr      = copr;
     this.lastError = 0;
 }