?? connection.java
字號(hào):
for (int y=0;y<numberOfAddresses;y++) { if (addressesArray[y].indexOf("@"+domain)==addressesArray[y].length()-("@"+domain).length() && recipients[x].regionMatches(0,addressesArray[y],0,addressesArray[y].indexOf("@"))) { String fingerprintReceived = Conversions.bytesToHexString(new HushSHA1().SHA1Hash(Conversions.hexStringToBytes(pubKeys[x]))); if (!fingerprints(y).equals(fingerprintReceived)) { hushApplet.statusBar(spaces+"Bad public key for "+recipients[x]+spaces); return false; } } } } } /* Encrypt the body with a randomly generated * Blowfish key and append SHA1 Hash */ byte[] bodyKey = new byte[16]; randStream.nextBytes(bodyKey); BlowfishCipher bodyCipher = new BlowfishCipher(); bodyCipher.setKey(bodyKey); hushApplet.statusBar(spaces+"Encrypting message body"+spaces); body = wrap("----- HushMail v1.0 -----\n"+ Conversions.bytesToHexString(bodyCipher.stringEncrypt(body)) + "\n-" + Conversions.bytesToHexString(new HushSHA1().SHA1Hash(body)) + "\n----- End -----\n",false,false); hushApplet.statusBar(spaces+"Body encrypted"+spaces); /* Concatenate the body key and a SHA1Hash of the body key into one array */ byte[] bodyHash = new HushSHA1().SHA1Hash(bodyKey); byte[] bodyKeyAndHash = new byte[bodyKey.length+bodyHash.length]; System.arraycopy(bodyKey,0,bodyKeyAndHash,0,bodyKey.length); System.arraycopy(bodyHash,0,bodyKeyAndHash,bodyKey.length,bodyHash.length); for (int x=0;x<recipients.length;x++) { String encryption = "Hush-encryption: "; if (recipients[x].equals(username)||recipients[x].equals("/self/")) { /* If recipient is self * Blowfish the body key using the users passphrase */ encryption = encryption + "Hush Private 1.0\n"; encryption = encryption + wrap("Hush-keyblock: " + Conversions.bytesToHexString(passCipher.encrypt(bodyKeyAndHash)), false, true) + "\n"; } else { hushApplet.statusBar(spaces+"Encrypting to "+recipients[x]+spaces); ElGamalCipher pubKeyCipher = new ElGamalCipher(); pubKeyCipher.setRandomStream(randStream); pubKeyCipher.setPublicKey(Conversions.hexStringToBytes(pubKeys[x])); encryption = encryption + "Hush Public 1.0\n"; encryption = encryption + wrap("Hush-keyblock: " + Conversions.bytesToHexString(pubKeyCipher.hushEncrypt(bodyKeyAndHash,bodyKeyAndHash.length)), false, true) + "\n"; } String message = new String(headers[x]+encryption+"\n"+body); if (save || recipients[x].equals("/self/")) { hushApplet.statusBar(spaces+"Saving copy in '"+saveFolder+"'"+spaces); encryptAndWrite("SAVEMESSAGE\n"+saveFolder+"\n"+String.valueOf(message.length())+"\n"+message); readAndDecrypt(); if (!in.readLine().equals("OK")) throw new IOException(); } else { hushApplet.statusBar(spaces+"Sending message"+spaces); encryptAndWrite("SENDMESSAGE\n"+String.valueOf(message.length())+"\n"+message); readAndDecrypt(); if (!in.readLine().equals("OK")) throw new IOException(); } } return true; } /** * Retrieves address information from server: * numberOfAddresses set to number of addresses in * addressbook. * The variables nicknameArray, fullnameArray, * and addressesArray, are set to appropriate values * from addressbook on server */ void getAddresses() throws IOException { encryptAndWrite("GETADDRESSES\n"); readAndDecrypt(); if (!in.readLine().equals("OK")) throw new IOException(); numberOfAddresses = Integer.parseInt(in.readLine()); nicknameArray = new String[numberOfAddresses]; fullnameArray = new String[numberOfAddresses]; addressesArray = new String[numberOfAddresses]; fingerprintsArray = new String[numberOfAddresses]; for (int x=0;x<numberOfAddresses;x++) { nicknameArray[x] = in.readLine(); fullnameArray[x] = in.readLine(); addressesArray[x] = in.readLine(); fingerprintsArray[x] = in.readLine(); } } void deleteAddress(String passedNickname) throws IOException { encryptAndWrite("DELETEADDRESS\n"+passedNickname+"\n"); readAndDecrypt(); if (!in.readLine().equals("OK")) throw new IOException(); } boolean addAddress(String passedNickname,String passedFullname,String passedAddress) throws IOException { passedFullname = passedFullname.replace('"','\''); String fingerprint = ""; if ((passedAddress+"\n").indexOf("@"+domain+"\n")!=-1) { String newAddressUser = passedAddress.substring(0,passedAddress.indexOf("@")); encryptAndWrite("GETPUBLICKEY\n"+newAddressUser); readAndDecrypt(); if (!in.readLine().equals("OK")) throw new IOException(); String response=in.readLine(); if (response.equals("NOT APPROVED")) { hushApplet.statusBar(spaces+"No such HushMail user: "+newAddressUser+spaces); return false; } else fingerprint=Conversions.bytesToHexString(new HushSHA1().SHA1Hash(Conversions.hexStringToBytes(in.readLine()))); } encryptAndWrite("NEWADDRESS\n"+passedNickname+"\n"+passedFullname+"\n"+passedAddress+"\n"+fingerprint+"\n"); readAndDecrypt(); if (!in.readLine().equals("OK")) throw new IOException(); return true; } String linewrap(String inString, int linelength) { StringBuffer outStringBuf = new StringBuffer(); outStringBuf.ensureCapacity(inString.length()+inString.length()/linelength+2); int place = 0; for (int x=0;x<inString.length();x++) { outStringBuf.append(inString.substring(x,x+1)); if (inString.substring(x,x+1).equals("\n")) place=0; else if (++place==linelength) { outStringBuf.append(inString.substring(x,x+1)+"\n"); place=0; } } return outStringBuf.toString(); } String wordwrap(String inString, int linelength) { StringBuffer outStringBuf = new StringBuffer(); outStringBuf.ensureCapacity(inString.length()+inString.length()/linelength+2); int place = 0; String line=""; for (int x=0;x<inString.length();x++) { line = line + inString.substring(x,x+1); place++; if (line.regionMatches(line.length()-1,"\n",0,1)) place=0; else if (place>=linelength) { int lastSpace = line.lastIndexOf(' '); if (lastSpace!=-1 && lastSpace!=0) { outStringBuf.append(line.substring(0,lastSpace)+"\n"); if (lastSpace==line.length()-1) line=" "; else line=line.substring(lastSpace+1); place=line.length(); } } } return outStringBuf.toString(); } String wrap(String inString, boolean isParagraph, boolean isHeader) { /** * This function wraps Strings longer then 72 characters */ String space = ""; int resetPlace = 0; if (isHeader) { space = " "; resetPlace = 0; } String term = "\n"; StringBuffer outStringBuf = new StringBuffer(); outStringBuf.ensureCapacity(inString.length()*2); int place = 0; for (int x=0;x<inString.length();x++) { term = "\n"; if (x+1<inString.length() && inString.charAt(x+1)=='\n') term = ""; if (inString.charAt(x)=='\n') { outStringBuf.append("\n"); place=0; } else if (place==71 && !isParagraph) { outStringBuf.append(inString.charAt(x)+term+space); place=resetPlace; } else if (place>=71 &&(inString.charAt(x)==','||inString.charAt(x)=='-'|| inString.charAt(x)==' ')) { outStringBuf.append(inString.charAt(x)+term+space); place=resetPlace; } else { outStringBuf.append(inString.charAt(x)); place++; } } return outStringBuf.toString(); } /** * This method should be called when a task requires * the use of the socket connection */ boolean use() throws IOException { hushApplet.startBlinkingText(); if (initialUse) { /* Increment count of threads using socket */ ++socketRequests; s = new Socket(serverAddress,serverPort); s.setSoTimeout(60000); s.setTcpNoDelay(false); out = new BufferedOutputStream(s.getOutputStream()); eIn = new BufferedInputStream(s.getInputStream()); /* Send sessionID to server, so that the server can find the sessionKey */ out.write(sessionIDBytes); /* Send username and half of hash of passphrase */ encryptAndWrite("CONNECT\n"+username+"\n"+Conversions.bytesToHexString(halfPassphraseHash)+"\n"); /* Check for acceptance of username and passphrase */ readAndDecrypt(); if (!in.readLine().equals("OK")) throw new IOException(); if (!in.readLine().equals("APPROVED")) { /* Exit to "BadLogin" page */ try { URL u = new URL(hushApplet.exitpage+"?action=BadLogin&username="+username()); hushApplet.getAppletContext().showDocument(u); } catch (MalformedURLException m) {System.out.println("MalformedURL");} eIn.close(); out.close(); s.close(); return false; } String publicKey = in.readLine(); if (publicKey!=null) fingerprint = Conversions.bytesToHexString(new HushSHA1().SHA1Hash(Conversions.hexStringToBytes(publicKey))); String encPrivKeyString = in.readLine(); if (encPrivKeyString!=null) encPrivKey = Conversions.hexStringToBytes(encPrivKeyString); initialUse = false; } else { /* Execute only if no other threads are currently using the socket */ if (++socketRequests==1) { s = new Socket(serverAddress,serverPort); s.setSoTimeout(180000); s.setTcpNoDelay(true); out = new BufferedOutputStream(s.getOutputStream()); eIn = new BufferedInputStream(s.getInputStream()); /* Send sessionID to server, so that the server can find the sessionKey */ out.write(sessionIDBytes); encryptAndWrite("RECONNECT\n"+username+"\n"); /* Check for approval for continuation of session */ readAndDecrypt(); if (!in.readLine().equals("OK")) throw new IOException(); if (!in.readLine().equals("APPROVED")) { try { URL u = new URL(hushApplet.exitpage+"?action=NotApproved&username="+username()); hushApplet.getAppletContext().showDocument(u); hushApplet.removeAll(); hushApplet.paintAll(hushApplet.getGraphics()); wipeMessage(); killPassCipher(); } catch (MalformedURLException m) {System.out.println("MalformedURL");} eIn.close(); out.close(); s.close(); return false; } } } return true; } /** * This method should be called when a task using * the socket connection has been completed */ void done() { hushApplet.stopBlinkingText(); if (s==null) return; /* decrement count of threads using socket * if count is zero then terminate the socket */ if (--socketRequests==0) { try { out.close(); eIn.close(); s.close(); } catch (IOException e1) {System.out.println("IOException");} } } /* This signals the server to delete the session record * and terminates the socket */ void quit() { if (s==null) return; try { encryptAndWrite("QUIT\n"); out.close(); eIn.close(); s.close(); } catch (IOException e1) {System.out.println("IOException");} } /** * This methods send the parameter string to the * server, calling appropriate encryption methods * and indicating the length. */ private void encryptAndWrite(String output) { try { /* Send 16 bytes indicating the length of the output to follow */ byte[] encOutputBytes = blowfishPipe.stringEncrypt(output); int outLength = encOutputBytes.length; out.write(blowfishPipe.encrypt(Conversions.intToBytes(outLength))); out.write(encOutputBytes); out.flush(); } catch (IOException e) {System.out.println("IOException");} } /** * This method reads in a set of bytes from the server * calls appropriate decryption methods, and stores a resulting * string in a buffer for later access. */ private void readAndDecrypt() throws IOException { /* read in 16 bytes indicating the length of the input to follow */ byte lengthBytes[] = new byte[16]; int bytesRead = eIn.read(lengthBytes); while (bytesRead<16) bytesRead=bytesRead+eIn.read(lengthBytes,bytesRead,16-bytesRead); int inLength = Conversions.bytesToInt(blowfishPipe.decrypt(lengthBytes)); if (inLength==0) throw new IOException(); /* read and decrypt the requested number of bytes */ byte[] eBuf = new byte[inLength]; bytesRead = eIn.read(eBuf); while (bytesRead<inLength) bytesRead=bytesRead+eIn.read(eBuf,bytesRead,inLength-bytesRead); String inString = blowfishPipe.stringDecrypt(eBuf); byte[] trimmedBytes = new byte[inString.length()]; inString.getBytes(0,inString.length(),trimmedBytes,0); in = new DataInputStream(new ByteArrayInputStream(trimmedBytes)); } /** * Variables and methods for a queue of bits * intended to store random values for later access */ ByteQueue randBytes = new ByteQueue(); void enqueueBit(long l, int bits) { randBytes.enqueueBits(l,bits); if (randBytes.bytesAvailable()>0) { byte[] available = randBytes.dequeueBytes(randBytes.bytesAvailable()); randStream.enqueueBytes(available); } }} // end Connection.java
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -