Author: bback
Date: 2006-03-11 11:16:22 +0000 (Sat, 11 Mar 2006)
New Revision: 8225
Modified:
trunk/apps/frost-0.7/source/frost/gui/MessageFrame.java
trunk/apps/frost-0.7/source/frost/messages/MessageCreationException.java
trunk/apps/frost-0.7/source/frost/messages/MessageObject.java
trunk/apps/frost-0.7/source/frost/threads/MessageDownloadThread.java
trunk/apps/frost-0.7/source/frost/threads/MessageUploadThread.java
Log:
rewrote encrypted msgs, now the complete xml msg is encrypted and sent as
base64 content in another xml file
Modified: trunk/apps/frost-0.7/source/frost/gui/MessageFrame.java
===================================================================
--- trunk/apps/frost-0.7/source/frost/gui/MessageFrame.java 2006-03-11
00:27:02 UTC (rev 8224)
+++ trunk/apps/frost-0.7/source/frost/gui/MessageFrame.java 2006-03-11
11:16:22 UTC (rev 8225)
@@ -1325,7 +1325,7 @@
}
Identity recipient = null;
- if( encrypt.isEnabled() && encrypt.isSelected() ) {
+ if( encrypt.isSelected() ) {
recipient = (Identity)buddies.getSelectedItem();
if( recipient == null ) {
JOptionPane.showMessageDialog( this,
Modified:
trunk/apps/frost-0.7/source/frost/messages/MessageCreationException.java
===================================================================
--- trunk/apps/frost-0.7/source/frost/messages/MessageCreationException.java
2006-03-11 00:27:02 UTC (rev 8224)
+++ trunk/apps/frost-0.7/source/frost/messages/MessageCreationException.java
2006-03-11 11:16:22 UTC (rev 8225)
@@ -12,6 +12,11 @@
private boolean empty = false;
+ public final static int MSG_NOT_FOR_ME = 1;
+ public final static int DECRYPT_FAILED = 2;
+
+ int msgNo;
+
/**
* @param message
* @param cause
@@ -39,7 +44,12 @@
super(message);
this.empty = empty;
}
-
+
+ public MessageCreationException(String message, int msgno) {
+ super(message);
+ this.msgNo = msgno;
+ }
+
/**
* This method returns true if message creation failed because the file
* only contained the word "Empty"
@@ -60,4 +70,9 @@
public void setEmpty(boolean empty) {
this.empty = empty;
}
+
+ public int getMessageNo() {
+ return msgNo;
+ }
+
}
Modified: trunk/apps/frost-0.7/source/frost/messages/MessageObject.java
===================================================================
--- trunk/apps/frost-0.7/source/frost/messages/MessageObject.java
2006-03-11 00:27:02 UTC (rev 8224)
+++ trunk/apps/frost-0.7/source/frost/messages/MessageObject.java
2006-03-11 11:16:22 UTC (rev 8225)
@@ -19,14 +19,16 @@
package frost.messages;
-import java.io.File;
+import java.io.*;
import java.util.*;
import java.util.logging.*;
+import org.bouncycastle.util.encoders.*;
import org.w3c.dom.*;
-import org.xml.sax.SAXException;
+import org.xml.sax.*;
import frost.*;
+import frost.identities.*;
public class MessageObject implements XMLizable
{
@@ -96,6 +98,8 @@
loadFile();
// ensure basic contents and formats
analyzeFile();
+ } catch (MessageCreationException exception) {
+ throw exception;
} catch (Exception exception) {
throw new MessageCreationException(
"Invalid input file '" +
file.getName() + "' for MessageObject (load/analyze failed).", exception);
@@ -419,7 +423,7 @@
/**
* Parses the XML file and passes the FrostMessage element to XMLize
load method.
*/
- protected void loadFile() throws Exception {
+ protected void loadFile() throws Exception, MessageCreationException {
Document doc = null;
try {
doc = XMLTools.parseXmlFile(this.file, false);
@@ -428,15 +432,62 @@
if (file.renameTo(badMessage)) {
logger.log(Level.SEVERE, "Error - send the file
badmessage.xml to a dev for analysis, more details below:", ex);
}
- }
+ }
if( doc == null ) {
throw new Exception("Error - MessageObject.loadFile: couldn't
parse XML Document - " +
"File name: '" + file.getName()
+ "'");
}
-
+
Element rootNode = doc.getDocumentElement();
+ // transparently decrypt and continue load on success
+ if( rootNode.getTagName().equals("EncryptedFrostMessage") ) {
+ // get recipient (must be I to continue)
+ recipient = XMLTools.getChildElementsCDATAValue(rootNode,
"recipient");
+ if( recipient == null ) {
+ // no recipient
+ throw new Exception("Error - encrypted message contains no
'recipient' section.");
+ }
+ FrostIdentities identities = Core.getInstance().getIdentities();
+ if( !recipient.equals(identities.getMyId().getUniqueName()) ) {
+ // not for me
+ throw new MessageCreationException("Info: Encrypted message is
not for me.",
+ MessageCreationException.MSG_NOT_FOR_ME);
+ }
+ String base64enc = XMLTools.getChildElementsCDATAValue(rootNode,
"content");
+ if( base64enc == null ) {
+ // no content
+ throw new Exception("Error - encrypted message contains no
'content' section.");
+ }
+ byte[] base64bytes = base64enc.getBytes("ISO-8859-1");
+ byte[] encBytes = Base64.decode(base64bytes);
+ // decrypt content
+ byte[] decContent = Core.getCrypto().decrypt(encBytes,
identities.getMyId().getPrivKey());
+ if( decContent == null ) {
+ logger.log(Level.SEVERE, "TOFDN: Encrypted message could not
be decrypted!");
+ throw new MessageCreationException("Error: Encrypted message
could not be decrypted.",
+ MessageCreationException.DECRYPT_FAILED);
+ }
+ // decContent is an complete XML file, save it to file and load it
+ FileAccess.writeFile(decContent, this.file);
+ // try to load again
+ try {
+ doc = XMLTools.parseXmlFile(this.file, false);
+ } catch(Exception ex) { // xml format error
+ File badMessage = new File("badmessage.xml");
+ if (file.renameTo(badMessage)) {
+ logger.log(Level.SEVERE, "Error - send the file
badmessage.xml to a dev for analysis, more details below:", ex);
+ }
+ }
+
+ if( doc == null ) {
+ throw new Exception("Error - MessageObject.loadFile: couldn't
parse XML Document - " +
+ "File name: '" + file.getName() + "'");
+ }
+ rootNode = doc.getDocumentElement();
+ }
+
if( rootNode.getTagName().equals("FrostMessage") == false ) {
File badMessage = new File("badmessage.xml");
if (file.renameTo(badMessage)) {
@@ -504,7 +555,7 @@
* Does not change the internal File pointer.
*/
public boolean saveToFile(File f) {
- File tmpFile = new File(f.getPath() + ".tmp");
+ File tmpFile = new File(f.getPath() + "sav.tmp");
boolean success = false;
try {
Document doc = XMLTools.createDomDocument();
@@ -514,9 +565,7 @@
logger.log(Level.SEVERE, "Error while saving message.", e);
}
if (success && tmpFile.length() > 0) {
- if( f.delete() == false ) {
- logger.log(Level.SEVERE, "Error while saving message, delete
failed.");
- }
+ f.delete();
if( tmpFile.renameTo(f) == false ) {
logger.log(Level.SEVERE, "Error while saving message, renameTo
failed.");
return false;
@@ -526,7 +575,49 @@
}
return success;
}
+
+ /**
+ * Encrypt the complete XML message file with public key of recipient and
+ * create an EncryptedFrostMessage XML file that contains the encryted
content
+ * in base64 format. Saves the resulting XML file into targetFile.
+ *
+ * @param recipientPublicKey
+ * @param targetFile
+ * @return
+ */
+ public static boolean encryptForRecipientAndSaveCopy(File msgFile,
Identity recipient, File targetFile) {
+ byte[] xmlContent = FileAccess.readByteArray(msgFile);
+ byte[] encContent = Core.getCrypto().encrypt(xmlContent,
recipient.getKey());
+ String base64enc;
+ try {
+ base64enc = new String(Base64.encode(encContent), "ISO-8859-1");
+ } catch (UnsupportedEncodingException ex) {
+ logger.log(Level.SEVERE, "ISO-8859-1 encoding is not supported.",
ex);
+ return false;
+ }
+
+ Document doc = XMLTools.createDomDocument();
+ Element el = doc.createElement("EncryptedFrostMessage");
+ CDATASection cdata;
+ Element current;
+
+ // recipient
+ current = doc.createElement("recipient");
+ cdata =
doc.createCDATASection(Mixed.makeSafeXML(recipient.getUniqueName()));
+ current.appendChild(cdata);
+ el.appendChild(current);
+
+ // base64 content
+ current = doc.createElement("content");
+ cdata = doc.createCDATASection(base64enc);
+ current.appendChild(cdata);
+ el.appendChild(current);
+
+ doc.appendChild(el);
+ return XMLTools.writeXmlFile(doc, targetFile.getPath());
+ }
+
public void setBoard(String board) {
this.board = board;
}
Modified: trunk/apps/frost-0.7/source/frost/threads/MessageDownloadThread.java
===================================================================
--- trunk/apps/frost-0.7/source/frost/threads/MessageDownloadThread.java
2006-03-11 00:27:02 UTC (rev 8224)
+++ trunk/apps/frost-0.7/source/frost/threads/MessageDownloadThread.java
2006-03-11 11:16:22 UTC (rev 8225)
@@ -245,6 +245,16 @@
try {
currentMsg = new VerifyableMessageObject(testMe);
+ } catch (MessageCreationException ex) {
+ logger.log(Level.WARNING, "TOFDN: Exception thrown in
downloadDate(GregorianCalendar calDL)", ex);
+ if( ex.getMessageNo() ==
MessageCreationException.MSG_NOT_FOR_ME ) {
+ FileAccess.writeFile(MSG_NOT_FOR_ME, testMe); // this
file is ignored by the gui
+ } else if( ex.getMessageNo() ==
MessageCreationException.DECRYPT_FAILED ) {
+ FileAccess.writeFile(DECRYPT_FAILED, testMe); // this
file is ignored by the gui
+ } else {
+ FileAccess.writeFile(BROKEN_MSG, testMe); // this file
is ignored by the gui
+ }
+ continue;
} catch (Exception ex) {
logger.log(Level.SEVERE, "TOFDN: Exception thrown in
downloadDate(GregorianCalendar calDL)", ex);
// file could not be read, mark it invalid not to confuse
gui
@@ -259,28 +269,6 @@
continue;
}
- // check if msg is encrypted for me
- if (currentMsg.getRecipient() != null &&
currentMsg.getRecipient().length() > 0 )
- {
- if(
!currentMsg.getRecipient().equals(identities.getMyId().getUniqueName()) ) {
- logger.fine("TOFDN: Encrypted message was not for
me.");
- FileAccess.writeFile(MSG_NOT_FOR_ME, testMe); // this
file is ignored by the gui
- continue;
- } else {
- // decrypt msg content encrypted for me
- String encContent = currentMsg.getContent();
- String decContent =
Core.getCrypto().decrypt(encContent, identities.getMyId().getPrivKey());
- if( decContent == null ) {
- logger.log(Level.SEVERE, "TOFDN: Encrypted message
from "+currentMsg.getFrom()+
- " could not be decrypted!");
- FileAccess.writeFile(DECRYPT_FAILED, testMe); //
this file is ignored by the gui
- continue;
- }
- currentMsg.setContent(decContent);
- logger.fine("TOFDN: Decrypted an encrypted message for
me, sender was "+currentMsg.getFrom());
- }
- }
-
// check if we have the owner (sender) already on the lists
String _owner = currentMsg.getFrom();
Identity owner = identities.getIdentity(_owner);
Modified: trunk/apps/frost-0.7/source/frost/threads/MessageUploadThread.java
===================================================================
--- trunk/apps/frost-0.7/source/frost/threads/MessageUploadThread.java
2006-03-11 00:27:02 UTC (rev 8224)
+++ trunk/apps/frost-0.7/source/frost/threads/MessageUploadThread.java
2006-03-11 11:16:22 UTC (rev 8225)
@@ -346,20 +346,12 @@
if( message.getSignature() != null && message.getSignature().length()
> 0 && // we signed, so encrypt is possible
encryptForRecipient != null )
{
- // TODO: rewrite encryption. Write complete signed XML to disk,
encrypt it, encode64 it and
- // save a new XML containing the receiver and the base64
content only.
-
- // encrypt signed content
- String encContent = Core.getCrypto().encrypt(message.getContent(),
encryptForRecipient.getKey());
- if( encContent == null ) {
+ // encrypt file to temp. upload file
+
if(!MessageObject.encryptForRecipientAndSaveCopy(unsentMessageFile,
encryptForRecipient, uploadFile)) {
+ logger.severe("This was a HARD error, file was NOT uploaded,
please report to a dev!");
return false;
}
- message.setContent(encContent);
- // save changed msg again, but to tmp upload file
- if (!message.saveToFile(uploadFile)) {
- logger.severe("This was a HARD error and the file to upload is
lost, please report to a dev!");
- return false;
- }
+
} else if( encryptForRecipient != null ) {
logger.log(Level.SEVERE, "TOFUP: ALERT - can't encrypt message if
sender is Anonymous! Will not send message!");
return false; // unable to encrypt