otr4j is part of my GSoC 09' project and is encouraged by the SIP Communicator development. otr4j is an implementation of the OTR (Off-the-Record) protocol in java.

Sunday, October 11, 2009

otr4j I/O redesign almost complete

otr4j (the java Off-the-Record library), I/O redesign is almost complete now. The plan was to create a dedicated java.net.otr4j.io package that would host various I/O streams for optimal message serialization/deserialization.

The java.net.otr4j.io package development is complete now. It has been developed independently from the existing otr4j code base because it was not possible to both develop the package and refactor it's dependencies at the same time.

As soon as I complete the refactoring and make sure everything works as expected, I will commit the code.

These code changes will fix issue 1 (Enhance serialization/deserialization) and issue 8 (non-(ISO Latin 1) characters do not display correctly), both of which are very important.


Thursday, September 17, 2009

Life After GSoC

GSoC is not that important to split the time before and after it (GSoC), but I liked that subject because it reminds of a well known song I was listening to in my earliest youth :>

So what's going on after GSoC (relevant to GSoC)?

The truth is that I don't have much free time, but I try to devote some time in otr4j and SIP Communicator. The SIP Communicator plugin is in a good state but there are some open issues for otr4j.

I have already worked on otr4j issue 3 because there was demand. Currently I'm reading Java I/O so I can work on issue 1 with more confidence.

The code changes required for closing issue 1 would affect 20-25% of the code approximately and will improve code quality and readability a lot and a bit it's efficiency.

Another thing I've started working on is a port of otr4j in .NET (otr4net), I think that will follow IO changes because I want to have a good model before I finish the port.

That's about it :)

Saturday, August 22, 2009

Debugging SIP Communicator Tests

In order to debug SIP Communicator tests we have to define a similar run configuration as the one we use to debug SIP Communicator (non-tests), only this time we need to define some more properties (as VM arguments).

These properties come from the testing.properties and accounts.properties files, that SIP Communicator does not yet have the ability to read.

-Daccounts.icq.TESTED_IMPL_ACCOUNT_ID=
-Daccounts.icq.TESTED_IMPL_PWD=
-Daccounts.icq.TESTING_IMPL_ACCOUNT_ID=
-Daccounts.icq.TESTING_IMPL_PWD=
-Daccounts.icq.CONTACT_LIST=
-Daccounts.sip.PRESERVE_PEER_INFO=false
-Daccounts.sip.account1.USER_ID=
-Daccounts.sip.account1.DISPLAY_NAME=
-Daccounts.sip.account1.PASSWORD=
-Daccounts.sip.account1.SERVER_ADDRESS=
-Daccounts.sip.account1.SERVER_PORT=
-Daccounts.sip.account1.PROXY_ADDRESS=
-Daccounts.sip.account1.PROXY_PORT=
-Daccounts.sip.account2.USER_ID=
-Daccounts.sip.account2.DISPLAY_NAME=
-Daccounts.sip.account2.PASSWORD=
-Daccounts.sip.account2.SERVER_ADDRESS=
-Daccounts.sip.account2.SERVER_PORT=
-Daccounts.sip.account2.PROXY_ADDRESS=
-Daccounts.sip.account2.PROXY_PORT=
-Daccounts.jabber.account1.USER_ID=
-Daccounts.jabber.account1.SERVER_PORT=
-Daccounts.jabber.account1.PASSWORD=
-Daccounts.jabber.account1.SERVER_ADDRESS=
-Daccounts.jabber.account2.USER_ID=
-Daccounts.jabber.account2.PASSWORD=
-Daccounts.jabber.account2.SERVER_ADDRESS=
-Daccounts.jabber.account2.SERVER_PORT=
-Daccounts.jabber.CONTACT_LIST=
-Daccounts.reporting.JABBER_REPORT_LIST=
-Daccounts.msn.account1.USER_ID=
-Daccounts.msn.account1.PASSWORD=
-Daccounts.msn.account2.USER_ID=
-Daccounts.msn.account2.PASSWORD=
-Daccounts.msn.CONTACT_LIST=
-Daccounts.reporting.MSN_REPORT_LIST=
-Daccounts.yahoo.account1.USER_ID=
-Daccounts.yahoo.account1.PASSWORD=
-Daccounts.yahoo.account2.USER_ID=
-Daccounts.yahoo.account2.PASSWORD=
-Daccounts.yahoo.CONTACT_LIST=
-Daccounts.reporting.YAHOO_REPORT_LIST=
-Daccounts.gibberish.account1.USER_ID=gibacc1
-Daccounts.gibberish.account1.PASSWORD=whatever
-Daccounts.gibberish.account2.USER_ID=gibacc2
-Daccounts.gibberish.account2.PASSWORD=whatever2
-Daccounts.gibberish.CONTACT_LIST=test-group.user1

-Dnet.java.sip.communicator.slick.runner.TEST_LIST=JabberProtocolProviderSlick
-Dnet.java.sip.communicator.CONFIGURATION_FILE_NAME=testing.sip-communicator.xml

Monday, August 17, 2009

August 17 Update

Here's a summary of the project's current status.. Screenshots of the current UI can be found in the OTR Plugin UI Picasa Web Album.

1. Make the OTR plugin register an encryption button in the tool (Implemented) and menu (Implemented) bars of the chat window.
2. The above mentioned button should indicate the status of the current chat (Implemented)
3. The above mentioned button should also contain (at least) the following options

* Start an ecnrypted chat (Implemented)
* End encrypted chat (Implemented)
* Authenticate/Verify contact (Implemented)
* Auto encrypt every session with this contact (Implemented)
* Help/ What is this (Implemented)

4. Implement support for clients that do not have OTR (Implemented)
5. Add support for incoming fragmented messages (Pending, otr4j has to be extended)
6. Configuration intertface that allows generating and displaying our own key as well as managing other people’s keys (Implemented, screenshot)
7. JUnit tests that run with every protocol (Pending)

Saturday, August 15, 2009

August 15 Update

Here's a summary of the project's current status.. Screenshots of the current UI can be found in the OTR Plugin UI Picasa Web Album.

1. Make the OTR plugin register an encryption button in the tool (Implemented, see bellow) and menu (Implemented) bars of the chat window.

Current implementation adds a button in the tool bar which is dummy for the time being. I'm not sure what this button should do. For example it could be a toggle button (start/stop encryption) or it could bring up the whole OTR menu.

UPDATE, August 16: Toggle button functionality implemented.

2. The above mentioned button should indicate the status of the current chat (Implemented)
3. The above mentioned button should also contain (at least) the following options

* Start an ecnrypted chat (Implemented)
* End encrypted chat (Implemented)
* Authenticate/Verify contact (Implemented)
* Auto encrypt every session with this contact (Implemented)
* Help/ What is this (Implemented)

4. Implement support for clients that do not have OTR (Implemented)
5. Add support for incoming fragmented messages (Pending, otr4j has to be extended)
6. Configuration intertface that allows generating and displaying our own key as well as managing other people’s keys (Pending)
7. JUnit tests that run with every protocol (Pending)

Tuesday, August 11, 2009

Midterm milestones status

Here's a summary of the project's current status

1. Make the OTR plugin register an encryption button in the tool (Pending, see bellow) and menu (Implemented) bars of the chat window

Current implementation adds a button in the tool bar which is dummy for the time being. I'm not sure what this button should do. For example it could be a toggle button (start/stop encryption) or it could bring up the whole OTR menu.

2. The above mentioned button should indicate the status of the current chat (Implemented)
3. The above mentioned button should also contain (at least) the following options

* Start an ecnrypted chat (Implemented)
* End encrypted chat (Implemented)
* Authenticate/Verify contact (Implemented)
* Auto encrypt every session with this contact (Pending. This can only be set globally in the configuration form for the time being.)
* Help/ What is this (Implemented)

4. Implement support for clients that do not have OTR (Implemented)
5. Add support for incoming fragmented messages (Pending, otr4j has to be extended)
6. Configuration intertface that allows generating and displaying our own key as well as managing other people’s keys (Pending)
7. JUnit tests that run with every protocol (Pending)

Thursday, July 23, 2009

Progress by July 23

After solving the signature generation/verification puzzles, the two last first term milestones where reached.

More specifically, message transformation operation sets where added earlier tonight for MSN, Yahoo! and ICQ (Jabber transformation set has been added some time ago). Now OtrTransformationLayer can hook into all of these protocols (MSN, Yahoo!, ICQ and Jabber) and provide encrypted communication!

Wednesday, July 15, 2009

DSA Signature sign/verify using JCE/BouncyCastle/libgcrypt

In my previous update I described various interoperability problems in the signing/verification process.

- Problem 1: signing with standard JCE and verifying with BouncyCastle (and vica versa)

The answer to this problem is that... the BouncyCastle DSA code does not perform the SHA1 hash of the message; they expect you to do that and pass the 20 byte hash in rather than the message. The JCE code automatically does the hashing for you; you just pass it the message you want to get signed, as ghstark and Werner mention here and here accordingly.

- Problem 2: signing with BouncyCastle and verifying with libgcrypt (and vica versa)

This problem is slightly more complicated and in order to understand what's going on I had to debug SIP Communicator/otr4j/BC & Pidgin/libotr/libgcrypt simultaneously. Fortunately we got to an end.

The BC DSA signature algorithm implements the latest standard according to FIPS-186-3 while libgcrypt adheres to FIPS-186-1, FIPS-186-2.

According to FIPS-186-3/p. DSA Signature Generation, (r,s) should be generated as follows:

Let N be the bit length of q. Let min(N, outlen) denote the minimum of the positive integers N and outlen, where outlen is the bit length of the hash function output block. The signature of a message M consists of the pair of numbers r and s that is computed according to the following equations:

r = (g^k mod p) mod q.
z = the leftmost min(N, outlen) bits of Hash(M).
s = (k^-1 (z + xr)) mod q.

while according to FIPS-186-1, FIPS-186-2
z = Hash(M)

Full topic discussion is available here.

Finally, Ian Goldberg in this thread provided a solution to this problem to pass to the signature generator (Hash(M) mod q) rather than truncating the Hash(M) value.

Note that this solution will not work with standard JCE because it requires a DSA signer implementation that doesn't hash it's input...

Friday, July 10, 2009

First term period results

Here I present the results from my first term period. The list is based on my first term planning.

  • Develop a java library that handles encryption (see The current state of OTR libraries in Java)
    • Build methods to Assemble/Dissasemble OTR Messages and tests to verify things work properly
      • OTR Query Messages
      • Tagged plaintext messages
      • OTR Error Messages (Completed)
      • D-H Commit Message
      • D-H Key Message
      • Reveal Signature Message
      • Signature Message
      • Data Message (Completed)
    • Handle state transitions for the following actions (detailed description of state transitions here),build key management infrastructure (NOTE: key management for the library, not SC) and build tests to verify things work properly
      In this period functionality for Requesting an OTR conversation, Authenticated Key Exchange (AKE), and Data Exchange will be added.
      • Plaintext message without the whitespace tag
      • Plaintext message with the whitespace tag
      • Query Message
      • Error Message
      • D-H Commit Message
      • D-H Key Message (Completed)
      • Reveal Signature Message
      • Signature Message
      • Version 1 Key Exchange Message
      • Data Message
      • User requests to start an OTR conversation
      • User requests to end an OTR conversation
      • User types a message to be sent (Completed)
  • Create a transformation operation set (Completed)
  • Implement support for the transformation set in all protocols (Failed)
  • Implement an OTR encryption bundle prototype/proof of concept that encrypts all conversations (Failed)

I have created a transformation set for jabber as an initial effort to incorporate otr4j in SIP Communicator. I've chosen jabber because it is an open standard with server implementation, such as OpenFire, freely available.

I did not proceed into creating transformation sets for the rest of the protocols because there is an issue that the DSA signature (generated with standard JCE) does not verify in Pidgin/libotr, this action is taken in the OTR Protocol Draft, High Level Overview, Authenticated Key Exchange, Step 9. I tried to sign using BouncyCastle Lightweight API instead of the Standard JCE, but that failed too.

To make sure the signature I use is correct, I created a set of test cases to verify signatures created with bouncycastle using the Sun JCE provider and visa versa, but that failed too.

I posted a question about this issue today in several places (CodeRanch, Sun Forums, SIP Communicator dev-list), but I have received no answer yet, so I need to further investigate this issue.

Sunday, July 5, 2009

OSGi + BouncyCastle Round 3

In OSGi + BouncyCastle Round 2 I described the problems I was facing while trying to wire up BouncyCastle in SIP Communicator, so as to be used as alternate JCE provider. There where two important problems.

Problem A is this exception [java] java.net.MalformedURLException: invalid url: reference:file:sc-bundles/protocol-msn.jar!/ (java.net.MalformedURLException: Unknown protocol: reference) during AES128-CTR encryption.

The solution to this problem was found by Werner Dittmann in this email. Briefly, I needed to install the "unlimited strength crypto policies" from Sun which are available here in the Other Downloads section. This is not an acceptable solution off course, so we will have to find an alternative (which is pretty obvious, drop the alternative JCE provider and use BouncyCastle Lightweight API).

Problem B is that running SIP Communicator from within Eclipse, and only from within Eclipse, the bundle-plugin-otr fails to generate a D-H key pair using BouncyCastle as alternate provider with class "org.bouncycastle.crypto.CipherParameters"'s signer information does not match signer information of other classes in the same package.

This email in the BouncyCastle developers mailing list mentions that the cause for this exception most likely is an incorrect installation of BouncyCastle, which in my case I guess that means a class path problem.

This guess makes sense, because when Eclipse launches SIP Communicator sets the classpath to whatever the buildpath is. The buildpath in my case contained both bouncycastle and zrtp4j which both export org.bouncycastle.crypto.*. Apparently there is a conflict there.

In this case we could have a bouncycastle bundle that both otr4j and zrtp4j will use or remove zrtp4j from the classpath (we could also update the "How to configure Eclipse to compile and debug SIP Communicator" to contain only the most required libs, like felix, in the classpath).

Friday, July 3, 2009

OSGi + BouncyCastle, Round 2

This is getting crazy... What I'm trying to do is wire up BouncyCastle correctly, so as to be used as alternate JCE provider by otr4j (or at least from within a sc-bundle), so the OtrTransformLayer can work properly..

What I've tried is:

A) Import every single package of BouncyCastle (I found those packages using this snippet) in org.osgi.framework.system.packages.extra + any other packages required (discover them through ClassDefNotFound exceptions + this snippet) in felix.client.run.properties file.

B) Import all of those packages in bundle-plugin-otr in build.xml.

So with this setup...

Running SIP Communicator using "ant run" seems to be partially working. We can generate D-H key pair using BouncyCastle as alternate provider, but I get (Problem A) [java] java.net.MalformedURLException: invalid url: reference:file:sc-bundles/protocol-msn.jar!/ (java.net.MalformedURLException: Unknown protocol: reference), like in this SIP Communicator issue. So let's try to debug this problem!

Running SIP Communicator using Eclipse, fails to generate a D-H key pair using BouncyCastle as alternate provider (Problem B) with class "org.bouncycastle.crypto.CipherParameters"'s signer information does not match signer information of other classes in the same package, so I cannot debug the above problem... So let's try to debug this problem!

The BouncyCastle signed jar does not have debug information, so attaching the BouncyCastle source code and installing a breakpoint in org.bouncycastle.jce.provider.JDKKeyPairGenerator$DH constructor gives me Unable to install breakpoint due to missing line numbers (Problem C), so I cannot debug the above problem, and this problem can only be resolved if we recompile the BouncyCastle lib, and it won't be a signed jar anymore.

To the bottom line, even if I didn't care about the first problem, the most important problem is that I cannot debug properly (Problem B). To the very bottom line, this probably means refactoring otr4j so as to use the BouncyCastle lightweight API instead of the BouncyCastle JCE provider. This would solve Problem C, and hopefully Problem B as well.

The setup I've used is r5496 of my branch.. I checked it in for reference.

UPDATE: There are solutions to these problems, and I discuss them in OSGi + BouncyCastle Round 3.

Tuesday, June 30, 2009

OSGi Bundle of BouncyCastle / Alternate JCE Provider

BouncyCastle comes in the form of signed jar, and there is a good reason for doing so. Java JCE Reference Guide states very clearly that providers need to be signed by a trusted entity to be plugged into the JCE framework.

So, if you try to OSGi bundle BouncyCastle the resulting jar won't be signed anymore, and JCE won't be able to authenticate the BouncyCastle provider.

This is the reason we see problems like this: ZRTP integration (possible) OSGi bundle related problem and this: bouncy castle exception with osgi. Two workarounds would be to...
  1. OSGi bundle BouncyCastle, but loose it's ability to be an alternate JCE provider
  2. Add it in the org.osgi.framework.system.packages.extra list in the felix.client.run.properties and make sure it's in the class path as it is mentioned here.
If you finally choose to OSGi bundle BouncyCastle, make sure that no manifest merging occurs, or else OSGi won't be able to start your bundle, it will probably fail with something like this:

java.lang.NullPointerException
at java.util.jar.Manifest$FastInputStream.fill(Unknown Source)
at java.util.jar.Manifest$FastInputStream.readLine(Unknown Source)
at java.util.jar.Manifest$FastInputStream.readLine(Unknown Source)
at java.util.jar.Attributes.read(Unknown Source)
at java.util.jar.Manifest.read(Unknown Source)
at java.util.jar.Manifest.(Unknown Source)
at org.apache.felix.framework.searchpolicy.ContentLoaderImpl.calculateContentPath(ContentLoaderImpl.java:344)
at org.apache.felix.framework.searchpolicy.ContentLoaderImpl.initializeContentPath(ContentLoaderImpl.java:315)
at org.apache.felix.framework.searchpolicy.ContentLoaderImpl.getClassPath(ContentLoaderImpl.java:90)
at org.apache.felix.framework.searchpolicy.ContentClassLoader.findClass(ContentClassLoader.java:154)
at org.apache.felix.framework.searchpolicy.ContentClassLoader.loadClassFromModule(ContentClassLoader.java:94)
at org.apache.felix.framework.searchpolicy.ContentLoaderImpl.getClass(ContentLoaderImpl.java:166)
at org.apache.felix.framework.searchpolicy.R4Wire.getClass(R4Wire.java:105)
at org.apache.felix.framework.searchpolicy.R4SearchPolicyCore.searchImports(R4SearchPolicyCore.java:505)
at org.apache.felix.framework.searchpolicy.R4SearchPolicyCore.findClassOrResource(R4SearchPolicyCore.java:466)
at org.apache.felix.framework.searchpolicy.R4SearchPolicyCore.findClass(R4SearchPolicyCore.java:185)
at org.apache.felix.framework.searchpolicy.R4SearchPolicy.findClass(R4SearchPolicy.java:45)
at org.apache.felix.moduleloader.ModuleImpl.getClass(ModuleImpl.java:216)
at org.apache.felix.framework.Felix.createBundleActivator(Felix.java:3468)
at org.apache.felix.framework.Felix._startBundle(Felix.java:1649)
at org.apache.felix.framework.Felix.startBundle(Felix.java:1578)
at org.apache.felix.framework.Felix.setFrameworkStartLevel(Felix.java:1172)
at org.apache.felix.framework.StartLevelImpl.run(StartLevelImpl.java:265)
at java.lang.Thread.run(Unknown Source)
java.lang.NullPointerException
at org.apache.felix.framework.searchpolicy.ContentClassLoader.findClass(ContentClassLoader.java:154)
at org.apache.felix.framework.searchpolicy.ContentClassLoader.loadClassFromModule(ContentClassLoader.java:94)
at org.apache.felix.framework.searchpolicy.ContentLoaderImpl.getClass(ContentLoaderImpl.java:166)
at org.apache.felix.framework.searchpolicy.R4Wire.getClass(R4Wire.java:105)
at org.apache.felix.framework.searchpolicy.R4SearchPolicyCore.searchImports(R4SearchPolicyCore.java:505)
at org.apache.felix.framework.searchpolicy.R4SearchPolicyCore.findClassOrResource(R4SearchPolicyCore.java:466)
at org.apache.felix.framework.searchpolicy.R4SearchPolicyCore.findClass(R4SearchPolicyCore.java:185)
at org.apache.felix.framework.searchpolicy.R4SearchPolicy.findClass(R4SearchPolicy.java:45)
at org.apache.felix.moduleloader.ModuleImpl.getClass(ModuleImpl.java:216)
at org.apache.felix.framework.Felix.createBundleActivator(Felix.java:3468)
at org.apache.felix.framework.Felix._startBundle(Felix.java:1649)
at org.apache.felix.framework.Felix.startBundle(Felix.java:1578)
at org.apache.felix.framework.Felix.setFrameworkStartLevel(Felix.java:1172)
at org.apache.felix.framework.StartLevelImpl.run(StartLevelImpl.java:265)
at java.lang.Thread.run(Unknown Source)

Subversion, SourceGear's Diffmerge and Cygwin

A while back in my Arsenal Selection post I described a way to use SourceGear's Diffmerge with Mercurial. No that I started to commit stuff to my SIP Communicator branch, I needed to do the same with SVN (which I run under Cygwin).

It turns out to be a little trickier with SVN firstly because SVN is not that versatile as Mercurial and second because I use SVN under Cygwin which results in paths being delivered in diffmerge Cygwinized.

To enable a 3d party diff tool you need add something like this in your ~/.subversion/config file (c:\cygwin\home\your_user\.subversion\config):

diff-cmd = diffwrapper.sh

With the help of Eric's post Living with Subversion and Pete's post Subversion, KDiff3, and Cygwin I've built diffwrapper.sh to look like this:

#!/bin/sh

LEFT=`cygpath -d ${6}`
RIGHT=`cygpath -d ${7}`

# thanks to jtr for the sed regex
LEFT_NAME=`echo ${3} | sed 's/.*\/\([^/]*\)/\1/'`
RIGHT_NAME=`echo ${5} | sed 's/.*\/\([^/]*\)/\1/'` #src/net/java/sip/communicator/impl/protocol/jabber/OperationSetInstantMessageTransformJabberImpl.java (revision 0)

/cygdrive/c/Program\ Files/SourceGear/Vault\ Client/sgdm.exe /title1:"$LEFT_NAME" "$LEFT" /title2:"$RIGHT_NAME" "$RIGHT"

Now you need to make sure that diffwrapper.sh script is somewhere in your PATH. I've added in ~/bin, and did

echo export PATH="\$PATH:$HOME/bin" >> ~/.bashrc

Update: Friday, 24 July, 2009
Here's a mergewrapper.sh script
#!/bin/sh
local=`cygpath -d ${3}`
remote=`cygpath -d ${2}`
base=`cygpath -d ${1}`
merged=`cygpath -d ${4}`
/cygdrive/c/Program\ Files/SourceGear/Vault\ Client/sgdm.exe /result:"$merged" /title1:"Local" /title2:"Merged" /title3:"Remote" "$local" "$merged" "$remote"

Saturday, June 27, 2009

Publishing your java.net SVN commits using Yahoo! Pipes

hapdaniel has a nice post about HTTPS, Pipes and YQL. Based on that post, here's a pipe that builds an RSS feed that shows your personal SVN commits to SIP Communicator.

Working with your SVN branch - Merge trunk changes to your branch


Now that the java otr library otr4j is functional, I wanted to merge any trunk changes back to my SIP Communicator branch, prior tto getting to work with SIP Communicator. I decided to post this because I always find my self googling for the answer..

this actually involves 4 commands:
  1. svn update, you run svn update to sync your working copy so svn info will show you updated information.
  2. svn info, running svn info will reveal the current HEAD revision (r2) as well as the revision of the last change of your branch (r1).
  3. svn merge, having these two pieces of information you can run svn merge -r r1:r2 trunk_location
  4. svn ci -m "Merged trunk changes r1:r2 into my branch"
Update: Friday, July 24, 2009

If you have time I would recommend reading at least Subversion in Action and Branching and Merging from the book Version Control with Subversion.

The procedure described above is not correct. It is simpler in >= 1.5 setups and, occasionally, more complicated in < 1.5 setups.

MiniMax and stsp on #svn channel on Freenode kindly answered my questions regarding some issues I had. I have to incorporate the outcome of the discussion here but until then here's the log.

Friday, June 26, 2009

OTR4j Authenticated Key Eexchange Log in Chainsaw V2


Screen capture of Chainsaw V2 visualizing otr4j running the Off-the-Record (OTR) Authenticated Key Exchange.

Sunday, June 21, 2009

Progress by June 25

It's been a while I haven't update the blog. Well this is all but true for the otr4j library!

I have been working on it during the past 14 days, and I am pretty happy to announce that with the latest changes just a few minutes ago, goal "June 25" has been reached. That is, as of revision 068510f52f otr4j can successfully run an Authenticated Key Exchange, and exchange encrypted data.

Tomorrow I will write new tests and improve existing ones to make sure the implementation is fully functional.

After that I will dive into SIP Communicator and will start working for goal July 05.

Thursday, June 11, 2009

Progress by June 11

Did a relatively big code refactoring. First of, I purged some elements that where obtrusive like huge javadocs and getters/setters. Both can be added at a later development stage when the library will be relatively stable.

Simplified how messages are assembled/disassembled. Now one can disassemble a message by calling the appropriate constructor, and can assemble messages by calling the toString() method of a message instance.

Implemented state transition handling and message reply dispatching mechanism when receiving
  • Plain text messages (with or without whitespace)
  • Query messages
  • Error messages
  • D-H Commit messages
  • D-H key messages
Created or adopted existing test cases, for refactored functionality (assemble/disassemble) and new functionality of handling state transitions respectively.

The project now uses Mercurial. Get a local copy of the repository with this command:

hg clone https://otr4j.googlecode.com/hg/ otr4j

Tuesday, June 9, 2009

Arsenal selection

I feel much more productive in Eclipse, and I also find it less obtrusive so I switched back to it.

A promising plugin, unfortunately not officially supported, for integrating Mercurial with Eclipse exists, and I installed it. IMHO the plugin is very nice and clean (I downloaded the source) BUT -as it usually happens..- I did some wrong clicks here and there and I messed up my source tree..

Then (in a bright moment I guess..) I thought I'd better switch to the command line (, I am aware of TortoiseHg, but I want my terminal back!) where I can have full control of what I’m doing (step by step..). So there I was, back at the beginning, using Eclipse and the command line :D and as I had already lost quite some time clicking around the various windows, I got back to work.

Finally (and thankfully..), I completed my changes and I wanted a tool to compare the diffs. I wanted a tool that would do folder diffing/directory diffing/folder compare/”call it what you like”, because I had done many changes and I wanted an overview picture of them.

I stumbled upon this stackoverflow post which led me to use WinMerge, because it is free, and even better it’s open source! I had to download the setup executable to get it to work because WinMergeU.exe depends on MFC7.1 and I could not find the the Microsoft VC++ 2003 Redistributable Package. The tool works fine, in fact it works great and I liked a lot.

If anyone wants to use WinMerge add this to the Mercurial.ini:

[extensions]
hgext.extdiff =
[extdiff]
cmd.wmdiff = C:\Program Files\WinMerge\WinMergeU.exe
opts.wmdiff = /r /e /x /ub

and then run hg wmdiff

But, (in yet another bright moment I guess..) I thought I’d try SourceGear’s DiffMerge which am used to it’s coloring conventions. This tool has folder diffing/directory diffing/folder compare/”call it what you like” and most importantly, it seemed to be a little faster than WinMerge.

If anyone want to use Sourcegear’s DiffMerge tool add this to the Mercurial.ini:

[extensions]
hgext.extdiff =
[extdiff]
cmd.sgdm = C:\Program Files\SourceGear\Vault Client\sgdm.exe

and run then hg sgdm

That’s all with my arsenal selection. If you ask me, it was a little boring to do all this stuff, but one has to do changes to his development toolset from time to time :-)

Sunday, June 7, 2009

Have you checked out some cool features of NetBeans?

I wanted an overall picture of otr4j, so I thought a good idea would be to create a class diagram.

Initially, I checked what's the Eclipse way of doing this. It seems although there are tools for modeling in Eclipse, they don't support reverse engineering source code into UML diagrams, so I thought "this must be something Eclipse developers do with some 3rd party -not very expensive- application..".

I browsed the web for a while, but found nothing standard except from ArgoUML maybe (one should define standard off course..). I eventually settled with NetBeans.

I was aware of the fact that NetBeans has support for reverse engineering Java Applications but didn't consider using it from the beginning because I wanted to build up my existing Eclipse skills.

The good stuff about NetBeans don't end here, it even has Mercurial support by default, which made me want to use Mercurial and let me be productive at the same time. Apparently I was very wrong about NetBeans..

I got so excited that I just made a question in the post where Mercurial support for Google Code has been announced, asking when it will go public. Now that Mercurial is working for me, I want to push my change sets!

Thursday, June 4, 2009

Progress by June 04

I think it's about time for another update on the otr4j library development progress..

First of all, a new dependency has been added, the BouncyCastle Java Cryptography Library.

The default security provider fails to generate a D-H KeyPair with a modulus larger than 1024 bits with the following message: "Prime size must be multiple of 64, and can only range from 512 to 1024". OTR uses a specific 1536 bit prime, so incorporating the BouncyCastle library was inevitable.

Furthermore, I have revisited some of the methods for assembling/disassembling the various OTR messages. I mostly changed the method signatures, for example instead of passing BigIntegers and byte arrays, I now pass DHPublicKey or PublicKey interfaces, which seems to be a better choice for cleaner code.

I have also made progress on handling state transitions, but this area still needs a lot of work.

I expect that by June 10 (next Wednesday) there will be proper code structure for state transition handling and that the library will successfully "receive" (through test cases) plain text (with or without whitespace tags), query messages, error messages, D-H commit messages and D-H key messages.

Lastly, I started using Mercurial, so to run the code (the tests) you must have mercurial to import the repository. The code for this preview release is available here.

Wednesday, May 27, 2009

Progress by May 26

Assembling/Disassembling of all OTR messages is now supported. All operations are accompanied by the corresponding test units.

I have also started working in handling state transitions.. It starts to get exciting!!

This is the direct link to this preview release.

P.S. As I read my previous blog posts, it seems that the post length is reduced over time; I want to believe that this is because the actual code length increases..

Wednesday, May 20, 2009

Progress by May 20

The library can now disassemble all message types except tagged plain text messages. Whoever is interested in the library can download it from the project home page here: http://code.google.com/p/otr4j/ or use this direct link.

Unit testing and logging has been implemented for the so far functionality, so you can extract the library somewhere, run

ant junit
and see what happens.

Monday, May 11, 2009

First term Planning

Here I present a first plan of the first term period. Numbered items correspond to top level requirement items. Also, dates are maximum values, hopefully it won't take that long!

  • Develop a java library that handles encryption (see The current state of OTR libraries in Java)
    • Build methods to Assemble/Dissasemble OTR Messages and tests to verify things work properly
      • OTR Query Messages
      • Tagged plaintext messages
      • OTR Error Messages (May 20)
      • D-H Commit Message
      • D-H Key Message
      • Reveal Signature Message
      • Signature Message
      • Data Message (May 25)
    • Handle state transitions for the following actions (detailed description of state transitions here),build key management infrastructure (NOTE: key management for the library, not SC) and build tests to verify things work properly
      In this period functionality for Requesting an OTR conversation, Authenticated Key Exchange (AKE), and Data Exchange will be added.
      • Plaintext message without the whitespace tag
      • Plaintext message with the whitespace tag
      • Query Message
      • Error Message
      • D-H Commit Message
      • D-H Key Message (June 10)
      • Reveal Signature Message
      • Signature Message
      • Version 1 Key Exchange Message
      • Data Message
      • User requests to start an OTR conversation
      • User requests to end an OTR conversation
      • User types a message to be sent (June 25)
  • Create a transformation operation set
  • Implement support for the transformation set in all protocols
  • Implement an OTR encryption bundle prototype/proof of concept that encrypts all conversations (July 05)

Comments and critiques are very welcome :-)

The current state of OTR libraries in Java

Existing Implementations

  • jOTR is a Java framework that provides the base functionality for OTR (Off The Record) support. It is intended to be a java version of the c-based libotr, and be completely compatible with it. Sounds great but, there is no source code although the project is more than a year old.

  • Ian Goldberg, lead developer of the OTR development team, mentions an otr library for Java (java-otr) (here) that is in the workings. There is no source code or binaries, only a mentioning so I sent a follow up mail (here) with no reply, so we can't rely on this.

  • libjotr ibjotr is a Off-The-Record library in native java. It was developed for libkara but can also be used with other applications written in java. This seems to be the first and only existing implementation for OTR in Java. libjotr is working but it will be hard to use it with an other messenger than kara without modfying the API. It is also OTR v2 only. No support for Version 1. These information are confirmed by Markus, libjotr developer.

OTR4j

Having considered the above solutions, I plan to develop my own library (otr4j) for integration with SipCommunicator and any other IM, as described in my initial post.

Thursday, April 30, 2009

Create a simple plugin for SipCommunicator with an external library and debug in Eclipse

Setting up the library project

  • Create a new java project that will host your library, this will be our foo4j lib. Make sure you create a proper project layout (folder structure) for you project, in order for the ant buildfile in step 3 to work.

  • Create a foo class with two dummy methods like this:

    package net.java.foo4j;

    public class Foo {
    public void helloWorld() {
    System.out.println("Hello World!");
    }

    public void byeWorld() {
    System.out.println("Bye World!");
    }
    }
  • Create a build.xml (ant buildfile) like the one bellow to produce a foo4j.jar file and build the project.

    <?xml version="1.0" ?>

    <project default="main" name="otr4j">
    <property name="src.dir" value="src" />
    <property name="build.dir" value="bin" />
    <property name="classes.dir" value="${build.dir}/classes" />
    <property name="jar.dir" value="${build.dir}/jar" />
    <target name="clean">
    <delete dir="${build.dir}" />
    </target>
    <target name="main" depends="compile, compress"
    description="Main target">
    <echo>
    Building the .jar file.
    </echo>
    </target>
    <target name="compile" description="Compilation target">
    <mkdir dir="${classes.dir}" />
    <javac srcdir="${src.dir}" destdir="${classes.dir}" debug="true" />
    </target>
    <target name="compress" description="Compression target">
    <mkdir dir="${jar.dir}" />
    <jar destfile="${jar.dir}/${ant.project.name}.jar"
    basedir="${classes.dir}" />
    </target>
    </project>

Setting up SipCommunicator

Our plugin will be build as an OSGi bundle. What helped me understand OSGi, is Clement Escoffier's paper "Developing an OSGi-like service platform for .NET", just skip all the .NET stuff.

In this paper you can find a high level overview of the OSGi framework. there are various sources on the web that can help you better
understand OSGi once you get the high level picture.

For the purpuses of this mini-guide, our strategy will be to build an OSGi bundle, and plug it into SipCommunicator. This OSGi -plugged in SipCommunicator- bundle will be our plugin, so I may use the term bundle and plugin interchangibly.

  • Edit the properties of SipCommunicator project and add foo4j project in the Java Build Path.
  • Create a class (FooActivator) that will implement the BundleActivator Interface. This class will handle the starting and stopping of our plugin.
     
    package net.java.sip.communicator.plugin.foo;

    import org.osgi.framework.BundleActivator;
    import net.java.foo4j.Foo;

    public class FooActivator implements BundleActivator {
    @Override
    public void start(BundleContext arg0) throws Exception {
    Foo foo = new Foo();
    foo.helloWorld();
    }

    @Override
    public void stop(BundleContext arg0) throws Exception {
    Foo foo = new Foo();
    foo.byeWorld();
    }
    }
  • Create the manifest for you bundle

    Bundle-Activator: net.java.sip.communicator.plugin.otr.FooActivator
    Bundle-Name: The infamous foo plugin!
    Bundle-Description: A plug-in that will help burgers accomplish their master plan to rule the world.
    Bundle-Vendor: sip-communicator.org
    Bundle-Version: 0.0.1
    System-Bundle: yes
    Export-Package: net.java.sip.communicator.plugin.foo,
    net.java.foo4j,
    Import-Package: net.java.sip.communicator.service.protocol,
    net.java.sip.communicator.service.protocol.event,
    net.java.sip.communicator.util,
    org.osgi.framework
    Pay attention that our bundle exports the net.java.foo4j package.
  • Edit SipCommunicator's build.xml and add an ant build target for our bundle

    <!-- BUNDLE-PLUGIN-OTR -->
    <target name="bundle-plugin-otr">
    <!-- Creates a bundle for the plugin OTR.-->
    <jar compress="false" destfile="${bundles.dest}/otr-plugin.jar"
    manifest="${src}/net/java/sip/communicator/plugin/otr/otr.manifest.mf">
    <zipfileset dir="${dest}/net/java/sip/communicator/plugin/otr"
    prefix="net/java/sip/communicator/plugin/otr"/>
    <zipfileset dir="PATH_TO_FOO4j_PROJECT/bin/jar/foo4j.jar"
    prefix="net/java/foo4j"/>
    </jar>
    </target>
    Make sure that you change PATH_TO_FOO4j_PROJECT
    to something meaningful.


We're done, now you should be able to debug SipCommunicator as it described in the official guide here.

Thursday, April 23, 2009

Initial Commit err.. Thoughts!

Hello World!

In this post, I will try to present my initial thoughts on how will I be implementing the OTR messaging project.

OTR Protocol Very High Level Overview

OTR assumes a network model which provides in-order delivery of messages, but that some messages may not get delivered at all (for example, if the user disconnects). There may be an active attacker, who is allowed to perform a Denial of Service attack, but not to learn the contents of messages.

  • Alice signals to Bob that she would like (using an OTR Query Message) or is willing (using a whitespace-tagged plaintext message) to use OTR to communicate. Either mechanism should convey the version(s) of OTR that Alice is willing to use.

  • Bob initiates the authenticated key exchange (AKE) with Alice. Version 2 of OTR uses a variant of the SIGMA protocol as its AKE.

  • Alice and Bob exchange Data Messages to send information to each other.

This text is taken from the OTR protocol description here.

Implementation

Overview

I plan to split my development efforts into two parts. The first part will be building a new reusable Java library for OTR (otr4j) and the second part incorporating that library in SipCommunicator.

Java library for OTR - otr4j

OTR4j architecture will be service driven, i.e. you have a state object, e.g. OtrlUserState, that you pass over to a service, e.g. MessageServiceImpl, with other required parameters for the service to work. I have already uploaded a skeleton of the library in Google Code http://code.google.com/p/otr4j/. Nothing functional yet, just a bunch of interfaces that may change in the future.

SipCommunicator Integration

SipCommunicator is build on top of Felix, so it makes sense to integrate the otr4j via an OSGi bundle, therefore the integration should be as simple as creating an OtrActivator class (I don't include it here because it would make the post too lengthy... )
This class is only a tiny tiny tiny (...) draft of the final OtrActivator and it doesn't have any GUI hooks, it just implements the BundleActivator interface that is required for the class to be an OSGi bundle and MessageListener and ServiceListener to hook to the inbound/outbound message traffic.

All of the above writing is “near to theory”, issues for further discussion will arise as soon as actual coding starts.

My Commits to SIP Communicator

Mercurial commits to project otr4j on Google Code