com.dalsemi.onewire.container
Class SHAiButton

java.lang.Object
  |
  +--com.dalsemi.onewire.container.SHAiButton

public class SHAiButton
extends java.lang.Object

Higher level access class for a DS1963S, Sha iButton.

This method makes use of several tricks to enhance performance on TINI. For instance, most methods are synchronized so that I can use instance variable byte arrays rather than creating new byte arrays every time a transacation is performed. This could hurt performance if you are doing multi-threaded applications, but the usefullness of having several threads contending to talk to a single iButton is questionable since the methods in DSPortAdapter 'beginExclusive' and 'endExclusive' should be used.

A SHAiButton can be a coprocessor or a user. A coprocessor button verifies signatures and signs data for user ibuttons. A coprocessor might be located inside a vending machine, where a person would bring their user iButton. When the user iButton is pressed to the Blue Dot to perform a transaction, the coprocessor would first verify that this button belongs to the system, i.e that it has the same secret (example: a Visa terminal making sure the iButton had a Visa account installed). Then the coprocessor would verify the signed data, or the money, to make sure it was valid. If someone tried to overwrire their money file, even with a previously valid money file (to 'restore' an earlier amount of money) it would be invalid because the signature includes the write cycle counter, which is incremented every time a page is written to. So the coprocessor verifies the money, then signs a new data file that contains the new amount of money.

The coprocessor has two secrets that are not even accessible from this class: One secret that is shared with the user iButtons--this is the authentication secret. It lets the system know that the user iButton belongs to the same group as the coprocessor. The second secret exists only on the coprocessor--it is used to sign and verify the money files.

This class makes no calls to the adapter class, i.e. it doesn't do any direct talking to the device.

Version:
0.00, 28 Aug 2000

Field Summary
static int AUTHENTICATION_FAILED_ERROR
          Useful constant for getLastError().
static int BIND_SECRET_ERROR
          Useful constant for getLastError().
static int CRC_ERROR
          Useful constant for getLastError().
static int ERASE_SCRATCHPAD_ERROR
          Useful constant for getLastError().
static int NO_COPROCESSOR_ERROR
          Useful constant for getLastError().
static int NO_ERROR
          Useful constant for getLastError().
static int NO_USER_ERROR
          Useful constant for getLastError().
static int READ_AUTHENTICATED_ERROR
          Useful constant for getLastError().
static int READ_MEMORY_PAGE_ERROR
          Useful constant for getLastError().
static int READ_SCRATCHPAD_ERROR
          Useful constant for getLastError().
static int SHA_FUNCTION_ERROR
          Useful constant for getLastError().
static int VERIFICATION_FAILED_ERROR
          Useful constant for getLastError().
static int WRITE_MEMORY_PAGE_ERROR
          Useful constant for getLastError().
static int WRITE_SCRATCHPAD_ERROR
          Useful constant for getLastError().
 
Constructor Summary
SHAiButton(OneWireContainer18 ibc)
          Constructor SHAiButton
 
Method Summary
 int answerChallenge(byte[] challenge, byte[] mac, byte[] pagedata)
          Answers a challenge from the coprocessor by signing a data page with the authentication secret.
 boolean generateChallenge(int page_number, int offset, byte[] ch)
          Generates a 3 byte random challenge in the iButton, sufficient to be used in answering a challenge by a user iButton.
 byte[] getBindCode()
          Get the 7 byte binding data.
 byte[] getBindData()
          Get the 32 byte binding data.
 int getLastError()
          Returns the last error that occurred.
 int getUserFileExtension()
          Returns the extension of this coprocessor's service file.
 java.lang.String getUserFileName()
          Returns the name of this coprocessor's service file.
 boolean isCoprocessor()
          Determines if this SHAiButton has enough of its parameters set to be a coprocessor iButton.
 int readFile(int start_page, byte[] page)
          Utility to read a TMEX file starting at a specified page.
 void setAuthenticationPageNumber(int pg)
          Sets the page that the authentication secret is installed on.
 void setBindCode(byte[] buf, int offset)
          Sets the code to bind used in signatures.
 void setBindData(byte[] buf, int offset)
          Sets the binding data for this Sha iButton.
 void setFilename(byte[] buf, int start)
          Sets the file name for this coprocessor's service file.
 void setInitialSignature(byte[] sig_ini, int start)
          Sets the initial signature.
 void setSigningChallenge(byte[] ch, int start)
          Sets the signing challenge.
 void setSigningPageNumber(int pg)
          Sets the page used to generate signatures.
 boolean setUser(int file_page_number)
          Sets up this SHAiButton as a user iButton.
 void setWorkspacePageNumber(int pg)
          Page the iButton will use to re-generate user iButton specific secrets.
 boolean signDataFile(SHAiButton user, int newbalance, int write_cycle_counter, byte[] pagedata)
          Makes this coprocessor produce a signature for a new amount of money for the user SHAiButton, then places the new money file on the user.
 java.lang.String toString()
          Returns a string with the unique address of the SHA iButton in hex.
 int verifyAuthentication(SHAiButton user, byte[] pagedata)
          Determines if the 'user' SHAiButton belongs to the system defined by this Coprocessor iButton.
 boolean verifyUserMoney(byte[] userpage, SHAiButton user, int wcc)
          This method allows a coprocessor to verify the money file from a user iButton.
 
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Field Detail

NO_ERROR

public static final int NO_ERROR
Useful constant for getLastError(). Means no error occurred.

ERASE_SCRATCHPAD_ERROR

public static final int ERASE_SCRATCHPAD_ERROR
Useful constant for getLastError(). Probably due to a communication error, meaning a retry might succeed.

WRITE_SCRATCHPAD_ERROR

public static final int WRITE_SCRATCHPAD_ERROR
Useful constant for getLastError(). Probably due to a communication error, meaning a retry might succeed.

READ_SCRATCHPAD_ERROR

public static final int READ_SCRATCHPAD_ERROR
Useful constant for getLastError(). Probably due to a communication error, meaning a retry might succeed.

READ_MEMORY_PAGE_ERROR

public static final int READ_MEMORY_PAGE_ERROR
Useful constant for getLastError(). Probably due to a communication error, meaning a retry might succeed.

READ_AUTHENTICATED_ERROR

public static final int READ_AUTHENTICATED_ERROR
Useful constant for getLastError(). Probably due to a communication error, meaning a retry might succeed.

BIND_SECRET_ERROR

public static final int BIND_SECRET_ERROR
Useful constant for getLastError(). Probably due to a communication error, meaning a retry might succeed.

WRITE_MEMORY_PAGE_ERROR

public static final int WRITE_MEMORY_PAGE_ERROR
Useful constant for getLastError(). Probably due to a communication error, meaning a retry might succeed.

SHA_FUNCTION_ERROR

public static final int SHA_FUNCTION_ERROR
Useful constant for getLastError(). Probably due to a communication error, meaning a retry might succeed.

CRC_ERROR

public static final int CRC_ERROR
Useful constant for getLastError(). Probably due to a communication error, meaning a retry might succeed.

NO_COPROCESSOR_ERROR

public static final int NO_COPROCESSOR_ERROR
Useful constant for getLastError(). Means that the coprocessor SHAiButton object has not been successfully setup.

NO_USER_ERROR

public static final int NO_USER_ERROR
Useful constant for getLastError(). Means that the user SHAiButton object has not been successfully setup.

AUTHENTICATION_FAILED_ERROR

public static final int AUTHENTICATION_FAILED_ERROR
Useful constant for getLastError(). It is possible this error is due to a communication error, and that a retry will be successful. However, it can also mean that the user SHAiButton does not belong to the system (could not authenticate).

VERIFICATION_FAILED_ERROR

public static final int VERIFICATION_FAILED_ERROR
Useful constant for getLastError(). It is possible this error is due to a communication error, and that a retry will be successful. However, it can also mean that the user SHAiButton's money data file is invalid (has been tampered with).
Constructor Detail

SHAiButton

public SHAiButton(OneWireContainer18 ibc)
Constructor SHAiButton
Parameters:
ibc -  
Method Detail

setBindData

public void setBindData(byte[] buf,
                        int offset)
Sets the binding data for this Sha iButton. This should be 32 bytes. Anything shorter will result in an ArrayIndexOutOfBounds exception. Anything longer will be ignored. This data is used to bind secrets to user/roaming iButtons and also to re-create user signatures in Coprocessor buttons.
Parameters:
buf - Byte buffer with the binding data. Must be at least offset+32 bytes long.
offset - Offset to start reading from the buffer. 32 bytes will be read from offset.

setBindCode

public void setBindCode(byte[] buf,
                        int offset)
Sets the code to bind used in signatures. This data is written to the scratchpad for binding secrets to iButtons and also to recreate user iButton signatures on Coprocessor iButtons. This data should only be 7 bytes long.
Parameters:
buf - Byte buffer with the binding data. Must be at least offset+32 bytes long.
offset - Offset to start reading from the buffer. 32 bytes will be read from offset.

getBindData

public byte[] getBindData()
Get the 32 byte binding data. This data is used to bind secrets to user/roaming iButtons and also to re-create user signatures in Coprocessor buttons.
Returns:
Byte array of length 32.

getBindCode

public byte[] getBindCode()
Get the 7 byte binding data. This data is used to bind secrets to user/roaming iButtons and also to re-create user signatures in Coprocessor buttons.
Returns:
Byte array of length 7.

answerChallenge

public int answerChallenge(byte[] challenge,
                           byte[] mac,
                           byte[] pagedata)
                    throws OneWireIOException,
                           OneWireException
Answers a challenge from the coprocessor by signing a data page with the authentication secret. If the coprocessor can verify this signature, then the iButton belongs to the system (has nothing to do with the validity of the signed data in the page).
Parameters:
challenge - A 3 byte random challenge. This must be generated by the DS1963S.
mac - A holding place for the returned signature. The coprocessor will use this signature to check the authentication. This must be at least 20 bytes long.
pagedata - A holding place for the page data. The coprocessor must know the data that was on the page in order to recreate the user signature. This array must be at least 32 bytes long.
Returns:
The write cycle counter value of the read page. Also, the field 'mac' will contain the 20 byte signature that is generated by the authenticate command. Also, the field 'pagedata' will contain the 32 bytes of the page used by the iButton to sign the data.
Throws:
OneWireIOException -  
OneWireException -  

generateChallenge

public boolean generateChallenge(int page_number,
                                 int offset,
                                 byte[] ch)
                          throws OneWireIOException,
                                 OneWireException
Generates a 3 byte random challenge in the iButton, sufficient to be used in answering a challenge by a user iButton.
Parameters:
page_number - The page number that the random number generation will be based on. Cannot be 0 or 8.
offset - When this function runs in the iButton, 20 bytes of pseudo-random data will be generated. You can pick from where in this data you would like to pull your 3 bytes.
ch - The 3 byte challenge is returned here. This byte array must be of length 3 or more.
Returns:
True if successful.
Throws:
OneWireIOException -  
OneWireException -  

verifyAuthentication

public int verifyAuthentication(SHAiButton user,
                                byte[] pagedata)
                         throws OneWireException,
                                OneWireIOException
Determines if the 'user' SHAiButton belongs to the system defined by this Coprocessor iButton. You must be a coprocessor to call this function. The TMEX page with the money signature is returned in pagedata.
Parameters:
user - The SHAiButton that will answer the challenge and be authenticated. This SHAiButton must be a user iButton (it must have had setUser called).
pagedata - The contents of the data page that will be used by 'user' to generate the authentication signature. This byte array must be AT LEAST 32 bytes long. The data will be copied into this array.
Returns:
The write cycle counter of the verified authentication page, or -1 if it could not authenticate (the iButton does not belong to the system).
Throws:
OneWireException -  
OneWireIOException -  

isCoprocessor

public boolean isCoprocessor()
Determines if this SHAiButton has enough of its parameters set to be a coprocessor iButton. To be a coprocessor, the following must be set:
The initial signature defaults to 20 bytes of 0x00's. The binding code and binding data default to all 0x0ff's. The signing challenge defaults to 3 bytes of 0x00's.
Returns:
True if this button can act as a coprocessor.

toString

public java.lang.String toString()
Returns a string with the unique address of the SHA iButton in hex.
Overrides:
toString in class java.lang.Object
Returns:
A string with the unique address of the SHA iButton in hex.

setUser

public boolean setUser(int file_page_number)
Sets up this SHAiButton as a user iButton.
Parameters:
file_page_number - The page number of the SHAiButton that contains the money file.
Returns:
True if successful.

setInitialSignature

public void setInitialSignature(byte[] sig_ini,
                                int start)
Sets the initial signature.

The initial signature is only used by coprocessor iButtons.
Parameters:
sig_ini - Byte array containing the new initial signature. Up to 20 bytes will be copied if sig_ini's length permits.
start - Index to start reading the new initial signature from sig_ini.

setSigningChallenge

public void setSigningChallenge(byte[] ch,
                                int start)
Sets the signing challenge.

The signing challenge is only used by coprocessor iButtons.
Parameters:
ch - Byte array containing the new random challenge. Up to 3 bytes wil be copied, if ch.length permits.
start - Index into the array 'ch' to start copying from.

setFilename

public void setFilename(byte[] buf,
                        int start)
Sets the file name for this coprocessor's service file. Example: DLSM.102
   buf[0] = (byte)'D';
   buf[1] = (byte)'L';
   buf[2] = (byte)'S';
   buf[3] = (byte)'M';
   buf[4] = (byte)102;
 
This function must be called to initialize a coprocessor.
Parameters:
buf - Byte array containing the file name and extension. See above. 5 bytes must be available to copy.
start - Index to start copying from byte array.

setSigningPageNumber

public void setSigningPageNumber(int pg)
Sets the page used to generate signatures. Valid choices are 0 and 8.

This function must be called to initialize a coprocessor.
Parameters:
pg - Page number for generating signatures. Valid choices are 0 and 8.

setAuthenticationPageNumber

public void setAuthenticationPageNumber(int pg)
Sets the page that the authentication secret is installed on.

This function must be called to initialize a coprocessor.
Parameters:
pg - Page the installation secret is installed on.

setWorkspacePageNumber

public void setWorkspacePageNumber(int pg)
Page the iButton will use to re-generate user iButton specific secrets. No data should be stored here, as it will be overridden when the system tries to authenticate.

This function must be called to initialize a coprocessor.
Parameters:
pg - Workspace page number.

getUserFileName

public java.lang.String getUserFileName()
Returns the name of this coprocessor's service file. Throws a null pointer exception if the file name has not been set.
Returns:
String of length 4.

getUserFileExtension

public int getUserFileExtension()
Returns the extension of this coprocessor's service file. Throws a null pointer exception if the file name has not been set.
Returns:
File extension.

signDataFile

public boolean signDataFile(SHAiButton user,
                            int newbalance,
                            int write_cycle_counter,
                            byte[] pagedata)
                     throws OneWireIOException,
                            OneWireException
Makes this coprocessor produce a signature for a new amount of money for the user SHAiButton, then places the new money file on the user.
Parameters:
user - SHAiButton object that has been intiialized as a user.
newbalance - New balance to be stored on the user SHA iButton.
write_cycle_counter - The current write cycle counter of the user iButton's money page. The write cycle counter is part of the signature to make sure someone does not try to 're-install' money. If this is initialization of the SHA iButton, make this argument -1 and the code will determine the value of the write cycle counter to use. This costs extra time, so do not call with this argument as -1 in normal transactions.
pagedata - The money data page.
Returns:
True if successful.
Throws:
OneWireIOException -  
OneWireException -  

verifyUserMoney

public boolean verifyUserMoney(byte[] userpage,
                               SHAiButton user,
                               int wcc)
                        throws OneWireIOException,
                               OneWireException
This method allows a coprocessor to verify the money file from a user iButton.
Parameters:
userpage - The full 32 byte TMEX file from the user SHA iButton.
user - The SHAiButton object intialized as a user object.
wcc - The write cycle counter of the user's money page.
Returns:
True if the data file is valid.
Throws:
OneWireIOException -  
OneWireException -  

readFile

public int readFile(int start_page,
                    byte[] page)
             throws OneWireIOException,
                    OneWireException
Utility to read a TMEX file starting at a specified page.

Call readFile(0) to read the root directory.
Parameters:
start_page - Page of the DS1963S to start reading from.
page - Byte array to put the file into. Either the entire file will be placed in this buffer or up to page.length bytes will be placed.
Returns:
Integer length of data read.
Throws:
OneWireIOException -  
OneWireException -  

getLastError

public int getLastError()
Returns the last error that occurred. See above for a description of different errors.
Returns:
Integer representing last error.