📄 shaibuttoncopr.java
字号:
System.arraycopy(scratchpad, 8 + (offset % 17), ch, start, 3); //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\ if(DEBUG) { IOHelper.writeLine("-----------------------------------------------------------"); IOHelper.writeLine("COPR DEBUG"); IOHelper.writeLine("address:"); IOHelper.writeLine("speed: " + this.ibc.getAdapter().getSpeed()); IOHelper.writeBytesHex(address, 0, 8); IOHelper.writeLine("Challenge:"); IOHelper.writeBytesHex(ch, start, 3); ch[start] = (byte)0x01; ch[start+1] = (byte)0x02; ch[start+2] = (byte)0x03; IOHelper.writeBytesHex(ch, start, 3); IOHelper.writeLine("-----------------------------------------------------------"); } //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\ ibcL.useResume(false); return true; } else this.lastError = this.SHA_FUNCTION_FAILED; } else this.lastError = this.ERASE_SCRATCHPAD_FAILED; ibcL.useResume(false); return false; } /** * <p>Determines if a <code>SHAiButtonUser</code> belongs to the system * defined by this Coprocessor iButton.See the usage example in this * class for initializing a Coprocessor iButton.</p> * * <p>The first step in user authentication is to recreate the user's * unique secret on the coprocessor button using * <code>bindSecretToiButton(int,byte[],byte[],int)</code>. Then the * coprocessor signs the pageData to produce a MAC. If the MAC matches * that produced by the user, the user belongs to the system.</p> * * <p>The TMEX formatted page with the user's account data is in the * 32-byte parameter <code>pageData</code>. If the verification * is successful, the data data signature must still be verified with * the <code>verifySignature()</code> method.</p> * * <p>Failure of this method does not necessarily mean that * the User iButton does not belong to the system. It is possible that * a communication disruption here could cause a CRC error that * would be indistinguishable from a failed authentication. However, * repeated attempts should reveal whether it was truly a communication * problem or a User iButton that does not belong to the system.</p> * * @param fullBindCode 15-byte binding code used to recreate user iButtons * unique secret in the coprocessor. * @param pageData 32-byte buffer containing the data page holding the user's * account data. * @param scratchpad the 32-byte scratchpad contents for which the * signature is generated. This will contain parameters such * as the user's write cycle counter for the page, the user's * 1-wire address, and the page number where account data is * stored. * @param verify_mac the 20-byte buffer containing the user's authentication * response to the coprocessor's challenge. * * @return <code>true</code> if the operation was successful and the user's * MAC matches that generated by the coprocessor. * * @throws 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'. * @throws OneWireException on a communication or setup error with the 1-Wire * adapter * * @see #generateChallenge(int,byte[],int) * @see #verifySignature(byte[],byte[],byte[]) * @see OneWireContainer18#bindSecretToiButton(int,byte[],byte[],int) * @see OneWireContainer18#SHAFunction(byte,int) * @see OneWireContainer18#matchScratchPad(byte[]) * @see #getLastError() */ public boolean verifyAuthentication(byte[] fullBindCode, byte[] pageData, byte[] scratchpad, byte[] verify_mac, byte authCmd) throws OneWireIOException, OneWireException { //clear any errors this.lastError = this.NO_ERROR; //maintain local reference to container OneWireContainer18 ibcL = this.ibc; int addr = this.wspcPageNumber << 5; int wspc = this.wspcPageNumber; //recreate the user's secret on the coprocessor. if(!ibcL.bindSecretToiButton(this.authPageNumber, this.bindData, fullBindCode, wspc)) { this.lastError = this.BIND_SECRET_FAILED; //bind secret failed return false; } ibcL.useResume(true); //\\//\\//\\//\\//\\//\\//\\////\\////\\////\\////\\////\\////\\// if(DEBUG) { IOHelper.writeLine("-----------------------------------------------------------"); IOHelper.writeLine("COPR DEBUG - verifyAuthentication"); IOHelper.write("address: "); IOHelper.writeBytesHex(address, 0, 8); IOHelper.writeLine("speed: " + this.ibc.getAdapter().getSpeed()); IOHelper.writeLine("pageData"); IOHelper.writeBytesHex(pageData); IOHelper.writeLine("scratchpad"); IOHelper.writeBytesHex(scratchpad); IOHelper.writeLine("authCmd: " + authCmd); IOHelper.writeLine("bindData: "); IOHelper.writeBytesHex(bindData); IOHelper.writeLine("fullBindCode: "); IOHelper.writeBytesHex(fullBindCode); IOHelper.writeLine("-----------------------------------------------------------"); } //\\//\\//\\//\\//\\//\\//\\////\\////\\////\\////\\////\\////\\// //write the account data if(!ibcL.writeDataPage(wspc, pageData)) { this.lastError = this.WRITE_DATA_PAGE_FAILED; ibcL.useResume(false); return false; } //write the scratchapd data if(!ibcL.writeScratchPad(wspc, 0, scratchpad, 0, 32)) { this.lastError = this.WRITE_SCRATCHPAD_FAILED; ibcL.useResume(false); return false; } //generate the MAC if(ibcL.SHAFunction(authCmd, addr)) { if(ibcL.matchScratchPad(verify_mac)) { ibcL.useResume(false); return true; } else this.lastError = this.MATCH_SCRATCHPAD_FAILED; } else this.lastError = this.SHA_FUNCTION_FAILED; ibcL.useResume(false); return false; } /** * <P>Verifies a User iButton's signed data on this Coprocessor iButton. * The Coprocessor must recreate the signature based on the data in the * file and the contents of the given scratchpad, and then match that * with the signature passed in verify_mac.</P> * * @param pageData the full 32 byte TMEX file from the User iButton * (from <code>verifyAuthentication</code>) with the * @param scratchpad the 32-byte scratchpad contents for which the * signature is generated. This will contain parameters such * as the user's write cycle counter for the page, the user's * 1-wire address, and the page number where account data is * stored. * @param verify_mac the 20-byte buffer containing the signature the user * had stored with the account data file. * * @return <code>true<code> if the data file is valid, <code>false</code> * if an error occurred (use <code>getLastError()</code> for more * information on the type of error) * * @throws 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'. * @throws OneWireException on a communication or setup error with the 1-Wire * adapter * * @see #verifyAuthentication(byte[],byte[],byte[],byte[],byte) * @see #getLastError() */ public boolean verifySignature(byte[] pageData, byte[] scratchpad, byte[] verify_mac) throws OneWireIOException, OneWireException { //clear any errors this.lastError = this.NO_ERROR; //maintain local reference to container OneWireContainer18 ibcL = this.ibc; int addr = this.signPageNumber << 5; //now we are ready to make a signature if (!ibcL.writeDataPage(this.signPageNumber, pageData)) { this.lastError = this.WRITE_DATA_PAGE_FAILED; ibcL.useResume(false); return false; } ibcL.useResume(true); if (!ibcL.writeScratchPad(0, 0, scratchpad, 0, 32)) { this.lastError = this.WRITE_SCRATCHPAD_FAILED; ibcL.useResume(false); return false; } //\\//\\//\\//\\//\\//\\//\\////\\////\\////\\////\\////\\////\\// if(DEBUG) { IOHelper.writeLine("-----------------------------------------------------------"); IOHelper.writeLine("COPR DEBUG - verifySignature"); IOHelper.write("address: "); IOHelper.writeBytesHex(address, 0, 8); IOHelper.writeLine("speed: " + this.ibc.getAdapter().getSpeed()); IOHelper.writeLine("-----------------------------------------------------------"); } //\\//\\//\\//\\//\\//\\//\\////\\////\\////\\////\\////\\////\\// //sign that baby! if (ibcL.SHAFunction(ibcL.VALIDATE_DATA_PAGE, addr)) { if (ibcL.matchScratchPad(verify_mac)) { ibcL.useResume(false); return true; } else this.lastError = this.MATCH_SCRATCHPAD_FAILED; } else this.lastError = this.SHA_FUNCTION_FAILED; ibcL.useResume(false); return false; } // *********************************************************************** // End SHA iButton Methods // *********************************************************************** /** * Returns a string representing the 1-Wire address of this SHAiButton. * * @return a string containing the 8-byte address of this 1-Wire device. */ public String toString () { return "COPR: "+this.ibc.getAddressAsString() + ", provider: " + this.providerName + ", version: " + this.version; } /** * Configuration helper. Used also by Coprocessor VM */ protected void fromStream(InputStream is) throws IOException { is.read(this.filename,0,5); this.signPageNumber = is.read(); this.authPageNumber = is.read(); this.wspcPageNumber = is.read(); this.version = is.read(); is.skip(4);//skip date info is.read(this.bindData,0,32); is.read(this.bindCode,0,7); is.read(this.signingChallenge,0,3); int namelen = is.read(); int siglen = is.read(); int auxlen = is.read(); byte[] l_providerName = new byte[namelen]; is.read(l_providerName); this.providerName = new String(l_providerName); int cnt = Math.min(this.initialSignature.length, siglen); is.read(this.initialSignature,0,cnt); byte[] l_auxData = new byte[auxlen]; is.read(l_auxData); this.auxData = new String(l_auxData); this.encCode = is.read(); this.DS1961Scompatible = (is.read()!=0); } /** * Configuration saving method. Used also by Coprocessor VM */ protected void toStream(OutputStream os) throws IOException { //first part written is completely standard format os.write(this.filename,0,5); os.write(this.signPageNumber); os.write(this.authPageNumber); os.write(this.wspcPageNumber); os.write(this.version); //month, date, and year ignored os.write(1); os.write(1); os.write(0); os.write(100); os.write(this.bindData); os.write(this.bindCode); os.write(this.signingChallenge); byte[] l_providerName = this.providerName.getBytes(); byte[] l_auxData = this.auxData.getBytes(); os.write((byte)l_providerName.length); os.write((byte)this.initialSignature.length); os.write((byte)l_auxData.length); os.write(l_providerName,0,(byte)l_providerName.length); os.write(this.initialSignature,0,(byte)this.initialSignature.length); os.write(l_auxData,0,(byte)l_auxData.length); os.write(this.encCode); os.write(this.DS1961Scompatible?0x55:0x00); os.flush(); } // *********************************************************************** // Begin Static Utility Methods // *********************************************************************** /** * <P>Static method that reformats the inputted authentication secret * so it is compatible with the DS1961S. This means that for every * group of 47 bytes in the secret, bytes at indices 32-35 and indices * 44-46 are all set to 0xFF. Check the format for secret generation * in the DS1961S data sheet to verify format of digest buffer.</P> * * <P>Note that if a coprocessor button uses this formatted secret, * this function should be called for all user buttons including the * DS1963S and DS1961S to ensure compatibility</P> * * @param auth_secret the authentication secret to be reformatted. * * @return a reformatted authentication secret, with the appropriate * padding for DS1961S interaction. */ public static byte[] reformatFor1961S(byte[] auth_secret) { int numPartials = (auth_secret.length/47) + 1; byte[] new_secret = new byte[47*numPartials]; for(int i=0; i<numPartials; i++) { int cnt = Math.min(auth_secret.length - (i*47), 47); System.arraycopy(auth_secret, i*47, new_secret, i*47, cnt); new_secret[i*47 + 32] = (byte)0xFF; new_secret[i*47 + 33] = (byte)0xFF; new_secret[i*47 + 34] = (byte)0xFF; new_secret[i*47 + 35] = (byte)0xFF; new_secret[i*47 + 44] = (byte)0xFF; new_secret[i*47 + 45] = (byte)0xFF; new_secret[i*47 + 46] = (byte)0xFF; } return new_secret; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -