Thursday, March 4, 2010

SSL Again

I finally got SSL working in PAW.

The code in the previous post is working. The problem was fixed by disabling keep alive in the Brazil framework.
 Actually I can't tell if this is a problem with the Brazil framework or Android.

HTTPS can now be enabled in the PAW server settings.


Anyway it's working and performance does not seem to suffer too much.

Tuesday, March 2, 2010

PAW Server for Android and SSL

After receiving user feedback from Stephen I decided to have a look how to implement SSL connections for PAW.

As Stephen pointed out, and of course he is correct, security is not very high in PAW as it is possible to modify data on the device.
First thing I did was to check how SSL works on standard Java.
This was fairly easy and worked on first try:

int port = 9999;
System.setProperty("javax.net.ssl.keyStore", "android-keystore");
System.setProperty("javax.net.ssl.keyStorePassword", "android");
ServerSocketFactory ssocketFactory = SSLServerSocketFactory.getDefault();
ServerSocket ssocket = ssocketFactory.createServerSocket(port);
Socket socket = ssocket.accept();

Unfortunately that didn't work at all on Android. I only received an normal ServerSocket without any SSL support.
After some googeling the code looked like this:

import javax.net.ssl.SSLServerSocketFactory;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.KeyManagerFactory;
import java.security.KeyStore;

try {
    int port = 9999;
    char[] passphrase = "android".toCharArray();

 ctx = SSLContext.getInstance("TLS");

 kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
 //BKS
 ks = KeyStore.getInstance (KeyStore.getDefaultType());

 ks.load(new FileInputStream("/sdcard/pawKeystore"),passphrase);
 kmf.init(ks, passphrase);
 ctx.init(kmf.getKeyManagers(), null, null);

 ssf = ctx.getServerSocketFactory();
 ssocket = ssf.createServerSocket(port);
 ssocket.accept();

} catch (e) {
    print(e);
}

This code is in principle working. Actually the code can be executed inside the PAW BeanShell Console (if a keystore exists).

What I didn't know was that the keystore format on Android is not the same as in standard Java. The format uses by Android is BKS which is not supported by the Java keytool out of the box.

To get BKS working the JCE provider from BouncyCastle has to be downloaded and the JAR file has to be extracted to $JAVA_HOME/jre/lib/ext/. After that the following line has to be added to the file $JAVA_HOME/jre/lib/security/java.security:

security.provider.9=org.bouncycastle.jce.provider.BouncyCastleProvider

The number behind security.provider. depends on your Java installation. After that a keystore file can be created with the following command line:

keytool -genkey -keyalg RSA -keysize 1024 -alias alias -keystore pawKeystore -validity 3650 -storetype BKS

On my Galaxy I noticed that when running the code not all connections were accepted, which was strange. In addition there would be minor changes necessary to the underlying Brazil framework, because SSLSockets throw additional Exceptions which do not occur when standard  Sockets are used.

But after setting it all up it didn't work because of connection problems and when it worked from time to time it was horribly slow.
The connections problems might be a problem within Android, because for the application this all should be transparent.

I would have really liked to implement SSL within PAW but at the moment I just don't get it working.