THUNDERKRYPT: THUNDERBIRD EXTENSION Version: 1.0 Date: 08.03.2009 Authors: Dirk, Eduardo, Zakaria Description: Thunderkrypt adds java-based decryption to Mozilla Thunderbird > 1.5 The current document describes the development process of the Thunderkrypt-Extension for Thunderbird. More information about building extensions for Thunderbird is available at Building a Thunderbird extension: http://kb.mozillazine.org/getting_started_with_extension_development https://developer.mozilla.org/en/building_a_thunderbird_extension Preferences made easy: http://www.fstoffel.de/tbblog/2008/04/12/preferences-made-easy/ Extension Development: https://developer.mozilla.org/en/setting_up_extension_development_environment http://ted.mielczarek.org/code/mozilla/extensiondev/ http://ted.mielczarek.org/code/mozilla/extensionwiz/ Just a quick note - since one of the latest nightly builds it s possible to use java classes from your extensions javascript code. Looks like this: var javastring = new java.lang.string("that's just a test text"); alert(javastring.length()); - 1 -
CONTENTS 1 USER DOCUMENTATION... 3 1.1 INSTALLATION... 3 1.2 FUNCTIONALITY... 4 2 ADJUSTMENTS... 5 3 SETTING UP THE DEVELOPMENT ENVIRONMENT... 5 3.1 THE LAYOUT OF CONTENT WITHIN THE XPI FILE:... 5 3.2 CREATE THE INSTALL MANIFEST... 6 3.3 CREATING THE CHROME.MANIFEST... 7 4 FILE DESCRIPTION... 10 5 HOW DOES IT WORK... 13 5.1 COMMUNICATION OF JAVASCRIPT WITH JAVA... 13 5.2 DECRYPTION PROCESS... 14 6 SIGNATURE... 15-2 -
1 USER DOCUMENTATION 1.1 INSTALLATION (1) If you have the xpi-file, just copy it into the Thunderbird extension folder and start Thunderbird. You will be prompted for installation. Alternatively you can install it using Extras Add-ins Install in Thunderbird. (2) If you have the development folder (just the contents of the xpi-file), just copy the thunderkrypt@pikolab.net folder in the Thunderbird extension folder. (3) Note that the folder needs to have the same name as the extension ID from the install.rdf included within the extension. Alternatively the full path to the folder can be put into a named with the extension name. This file needs to be in the Thunderbird extension folder. Note that after making any changes to the extension, Thunderbird needs to be restarted. After the first start, the path to the java location needs to be entered in Thunderbird Extras Add-ons Thunderkrypt Preferences. Then Thunderbird needs to be restarted again. (4) To build a xpi-file, basically the contents of the extension's folder (not the extension folder itself) need to be zipped up, and after that the zip file needs to be renamed to have a.xpi extension. More information on that: http://www.fstoffel.de/tbblog/2008/11/12/easy-way-to-build-xpi-files/ http://ted.mielczarek.org/code/mozilla/extensiondev/ - 3 -
1.2 FUNCTIONALITY (1) Entering the java path in preferences: (2) Menu Thunderkrypt with menu items decrypt email and About. (3) To decrypt an email, the email needs to be selected and then Thunderkrypt decrypt email. After that a dialog will pop up that asks for the pin and the decrypted mail will show up in a message window. - 4 -
2 ADJUSTMENTS In order to use the TUD-Card, some adjustments must be made. The session key must be read from the card reader (and not from the KeyStore, as done actually). This needs to be adjusted in the file ReadEncryptedEMail.java in the following code: //skey ist thes session key that must be read from the card. encryptedkey is the encrypted session key Key skey; keycipher.init(cipher.unwrap_mode, key); skey = keycipher.unwrap(encryptedkey, alg, Cipher.SECRET_KEY); So the skey from the TUD-Card needs to be read. The PIN is stored in the variable pin, so it may be used directly. All the code that uses the Keystore may then be removed, since it is not needed anymore when using the card. Eventually, the Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files 6 need to be downloaded from: http://java.sun.com/javase/downloads/index.jsp. 3 SETTING UP THE DEVELOPMENT ENVIRONMENT 3.1 THE LAYOUT OF CONTENT WITHIN THE XPI FILE: extension.xpi: /install.rdf //the description file for the extension. /chrome.manifest //Tells Thunderbird where chrome files are. /chrome/ /chrome/content/ // XUL, JavaScript /chrome/content/mainoverlay.xul //file describing UI elements to add /chrome/content/overlay.js //file with scripts to run in Thunderbird - 5 -
3.2 CREATE THE INSTALL MANIFEST install.rdf file is used by the Extension Manager when installing an XPI file and when registering an extension at specified location: <?xml version="1.0"?> <RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:em="http://www.mozilla.org/2004/em-rdf#"> <Description about="urn:mozilla:install-manifest"> <em:id>thunderkrypt@pikolab.net</em:id> <em:version>0.0</em:version> <!-- Target Application this extension can install into, with minimum and maximum supported versions. --> <em:targetapplication> <Description> <em:id>{3550f703-e582-4d05-9a08-453d09bdfdc6}</em:id> <em:minversion>1.5</em:minversion> <em:maxversion>2.0.0.*</em:maxversion> </Description> </em:targetapplication> <!-- Front End MetaData --> <em:name>thunderkrypt</em:name> <em:description>thunderbird Cryptography Addon</em:description> <em:creator>dirk, Eduardo, Zakaria</em:creator> </Description> </RDF> thunderkrypt@pikolab.net the ID of the extension. This is some value you come up with to identify your extension uniquely in email address format. {3550f703-e582-4d05-9a08-453d09bdfdc6} Thunderbird's application ID. Without this exact number it will not install. More detailed information about the Install Manifest is available at https://developer.mozilla.org/en/install_manifests. - 6 -
3.3 CREATING THE CHROME.MANIFEST A supplier of chrome for a given window type is called a chrome provider. The providers work together to supply a complete set of chrome for a particular window, from the images on the toolbar buttons to the files that describe the text, content and appearance of the window itself. The Chrome Registry: The Gecko runtime maintains a service known as the chrome registry that provides mappings from chrome package names to the physical location of chrome packages on disk. This chrome registry is configurable and persistent, and thus a user can install different chrome providers, and select a preferred skin and locale. In order to inform the chrome registry of the available chrome, a text manifest is used: this manifest is "chrome.manifest" in the root of an extension, or theme, and chrome/*.manifest in a XULRunner application. The plaintext chrome manifests are in a simple line-based format. Each line is parsed individually; if the line is parsable the chrome registry takes the action identified by that line; otherwise the chrome registry ignores that line (and prints a warning message in the runtime error console). There are three basic types of chrome providers: (1) Content: The main source file for a window description comes from the content provider, and it can be any file type viewable from within Mozilla. It will typically be a XUL file, since XUL is designed for describing the contents of windows and dialogs. The JavaScript files that define the user interface are also contained within the content packages, as well as most XBL binding files. (2) Locale: Localizable applications keep all their localized information in locale providers. This allows translators to plug in a different chrome package to translate an application without altering the rest of the source code. The two main types of localizable files are DTD files and Java-style properties files. (3) Skin: A skin provider is responsible for providing a complete set of files that describe the visual appearance of the chrome. Typically a skin provider will provide CSS files and images. - 7 -
Manifest Instructions: (1) Comments: A line is a comment if it begins with the character '#'; any other characters on the line are ignored. # this line is a comment - you can put whatever you want here (2) Content: A content package is registered with the line content packagename uri/to/files/ [flags] This will register a location to use when resolving the URI chrome://packagename/content/... The URI may be absolute or relative to the location of the manifest file. Note, that it must end with an '/'. (3) Locale: A locale package is registered with the line locale packagename localename uri/to/files/ [flags] This will register a locale package when resolving the URI chrome://packagename/locale/.... (4) Skin: A skin package is registered with the line skin packagename skinname uri/to/files/ [flags] This will register a skin package when resolving the URI chrome://packagename/skin/.... (5) Overlay XUL overlays are registered with the following syntax: overlay chrome://uri-to-be-overlaid chrome://overlay-uri [flags] - 8 -
Example Chrome.Manifest Content krypt chrome/content/ locale krypt en-us chrome/locale/en-us/ overlay chrome://messenger/content/messenger.xul chrome://krypt/content/mainoverlay.xul overlay chrome://messenger/content/messengercompose/messengercompose.xul chrome://krypt/content/compose.xul Line 1 registers a content provider. It registers a location to use when resolving the URI chrome://krypt/content/ Line 2 registers a locale package. Line 3 registers an overlay for chrome://messenger/content/messenger.xul, that allows to modify Thunderbird s main window UI from the mainoverlay.xul file. Line 4 registers an overlay for chrome://messenger/content/messengercompose/messengercompose.xul, that allows to modify Thunderbird s compose - window UI from the compose.xul file. More detailed information about chrome is available at https://developer.mozilla.org/en/chrome_registration - 9 -
4 FILE DESCRIPTION The following table provides a brief summary of contained files in the present extension relative to the path folder of the extension: \extensions\thunderkrypt@pikolab.net\ File chrome.manifest install.rdf Description Tells Firefox where the chrome files are and what to do with them. All the necessary registrations are made here, for example the UI windows and locale files. The description file for the extension ("Install manifest") Details of the plugin are given here, like its ID, name, version number, and supported Thunderbird versions. chrome\content\communication.js chrome\content\compose.js The communication and the message handling with the local java server is managed here. For that a socket connection is opened and managed. Functions are defined to send messages to the local server and to format them, and to handle incoming messages from the java server. This script is loaded by the compose.xul by <script type="application/x-javascript" src="chrome://krypt/content/compose.js" /> Provides methods to intercept message sending and to add signature attachments (not completed, refer to section 6). chrome\content\compose.xul Modify Thunderbird s compose - window UI from the compose.xul file. - 10 -
chrome\content\mainoverlay.xul chrome\content\options.xul chrome\content\overlay.js Modify Thunderbird s main window UI from the mainoverlay.xul file. The Thunderkrypt-Menu is added here. Modify Thunderkrypt s preferences in Thunderbird ExtrasAddons Thunderkrypt Preferences This script is loaded from the mainoverlay.xul by <script src="overlay.js"/> The script is the main javascript file. It is responsible for launching Java (with the necessary JARS) and the local server. The local server then listens to a socket and waits for messages. This file also catches when a user wants to decrypt an email, and creates the necessary message to send to the local server. He then waits for the respective signal from the java server that the decrypted email is ready, and then it shows it on a new window. When Thunderbird is closed, it tells the java server so that he can delete the temporary files it used. chrome\defaults\preferences\prefs.js chrome\locale\en-us\prefwindow.dtd Preference dialog to enter java path. Document Type Definition file which is used to internationalize xul. Used in options.xul by <!DOCTYPE prefwindow SYSTEM "chrome://krypt/locale/prefwindow.dtd"> It defines the message to be shown when the user wants to set his java path. data\ Folder where the decrypted and encrypted emails are saved temporarily. The p12 is also saved here if using a - 11 -
p12 file in the extension. jars\bcprov-jdk16-141.jar jars\mail.jar jars\thunderkrypt.jar jars\thunderkrypt.jar\localserver.class jars\thunderkrypt.jar\readencryptedem ail.class jars\thunderkrypt.jar\org\bouncycastle\ BouncyCastle Security Provider JavaMail API All the classes are saved here, like LocalServer and ReadEncryptedEMail. This is the Java Local Server. It opens a socket connection and listens to the specified port. It then parses the received message and depending of it takes the appropriate action, like decrypting the email, saving the PIN, deleting temp files, etc. This file is on charge of the whole decryption, mainly in the method savedecryptedmail. It then writes the decrypted email on the specified location. Modified BouncyCastle classes (actually very little modifications, like some methods we needed made public) - 12 -
5 HOW DOES IT WORK 5.1 COMMUNICATION OF JAVASCRIPT WITH JAVA The whole application is based on passing of messages from javascript to a java local server and back from the local server to javascript. When Thunderbird is started, the Java Local Server class is started and opens a socket listening to a port. Javascript is then able to send him XML messages and then get a response back. The different types of messages sent from javascript to the java server are: (1) <thunderkrypt:message> </thunderkrypt:message> This are the envelope XML tags used for every message sent to java. Each message is contained inside them. (2) <thunderkrypt:encryptedmessage> </thunderkrypt:encryptedmessage> This is the message passed to java containing an encrypted email in order for the java local server to decrypt it and save it in a temporary file on disk. When the Java Server is finished with the decryption, it sends Javascript a message back signalizing it: < /thunderkrypt:decryptedmessagesent>. Then, Thunderbird reads the decrypted email from the file and displays it. (3) <thunderkrypt:encryptedpassword> </thunderkrypt:encryptedpassword> This is the message passed to java containing the PIN for the TUD-Card. If not using the TUD-Card it contains the password for the KeyStore. At the moment it is not encrypted, but it can be extended to send the encrypted PIN for security. (4) <thunderkrypt:exit /> Javascript tells Java that it was exited, so java can delete all temporary files used and close the Java Server. This is needed because next time we will open thunderbird, it will start listening to the same port again. The files must be deleted for security reasons. Decrypted files should not be left on disk. - 13 -
(5) <thunderkrypt:dir> </thunderkrypt:dir> This message is sent from Thunderbird in order to tell the Java Local Server where the Thunderbird Extensions Directory is located, so that java can save the temporary files there. Java is launched from the file overlay.js (launchjava()). The files communication.js and localserver.java are doing the communication between JavaScript and Java. The communication.js sends messages (helo) to the localserver.java and waits for answers from the localserver.java. The method handleconnection in localserver.java parses the incoming messages and depending on it, takes an action (see the XML Messages sent). 5.2 DECRYPTION PROCESS The process is initiated by calling function ondecryptmenuitemcommand() in overlay.js. This sends a message (see above) to the localserver.java. The method handleconnection in localserver.java handles the decryption process: byte[] messageasbytes = command.getbytes(); if (pin=="") throw new Exception("Kann nicht entschlüsseln, da PIN nicht geschickt wurde!"); //here is the decryption made: it receives the message bytes senddecryptedmessage(messageasbytes,out); senddecryptedmessage writes the message as a file into a temporary file. The file ReadEncryptedEMail.java is responsible for the decryption process. MessageSender.handleAnswer = function(answer) in the communication.js waits for the answer <thunderkrypt:decryptedmessagesent /> and displays the decrypted.eml (the decrypted temporary file). - 14 -
6 SIGNATURE This functionality is not completed yet. The basic idea is to sign an email by sending this mail to the java-server. The Server will sign the received mail and save it on disk. After this, the signature of the mail will be attached in the opened mail-compose-window. For testing we have tried to attach a file from a temp directory, the content of the file for this test is not relevant. The process of the attachment of the signature will be the same. The problem with that attached signature is that it is just recognized as a normal attachment. To indicate that the attachment is a signature of an email, we need to manipulate the attachment content type header field of the attachment before sending the email. When modifying it manually, the attachment is recognized as a signature. That means we save the mail as file (*.eml). The attached signature in the mail must have a valid format for this test. After that we open the file with a text editor, and we change the content type of the attachment from attachment to signature. You can insert the correct values by comparing it with a valid signed mail. The attachment will be recognized as a signature. Therefore, a method that manipulates the header in the javascript-code before sending the email, needs to be found. - 15 -