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


Reply via email to