Wednesday, June 22, 2011

BerrySync: Launching Opera mini xor BlackBerry's Native Browser

An important part of BerrySync will be actually opening up URLs in the browser(s) on your BlackBerry.
After doing a little research I worked out how to not only open the native browser but third party browsers as well.

Opening Native Browser

browserSession = Browser.getDefaultSession();
browserSession.displayPage("http://www.BlackBerry.com");
browserSession.showBrowser(); 

Wasn't that painless and easy?

Opening 3rd Party Browsers, Opera Mini in this case
Also worthy of note is that fact that this block of code doesn't stop at just browser, you can invoke any third party app by replacing "Opera Mini" or making another if clause. See below or Pastebin.

int[] apps = CodeModuleManager.getModuleHandles();
ApplicationDescriptor[] ad;
ApplicationDescriptor holder;
String[] args = {"google.com"};
for(int i = 0, len = apps.length; i < len; i ++){
    ad = CodeModuleManager.getApplicationDescriptors(apps[i]);
    if(ad != null){
        for(int j = 0, adlen = ad.length; j < adlen; j++){
            if(ad[j].getName().equals("Opera Mini")){
                holder = new ApplicationDescriptor(ad[j], args);
                try {
                    ApplicationManager.getApplicationManager().runApplication(holder);
                    break;    //Needed
                } catch (ApplicationManagerException failedToOpen) {}
            }
        }
    }
} 


Code Walkthrough
This code scans through all installed modules on a BlackBerry, it tries to get the application descriptor on each and verifies it against the name of the app you wish to run. The args step is optional, but for our purposes we want to open Opera and goto the specified URL. Lastly the break is needed to stop multiple instances of the app opening since I found that many apps had more then one matching application descriptor

Wednesday, June 15, 2011

BerrySync: How does Firefox Sync use cryptography

I have a blog post explaining how to get FireFox Sync JSON, just having that encrypted JSON isn't enough. So what now?

Sync's Cryptography

When we started work, I used this blog to identify and determine how sync was using expecting it's clients to implement cryptography.

However some issues come along with not understanding cryptography and having never had to use it before, Sync updated and simplified their model in 1.6 and only today with a lot of help from moznet's #sync channel I got a usable understanding of the implementation. Here goes it:

Decrypting the Sync JSON:

There are a few assumptions in you should expect to handle Sync's data.

All of the keys are symmetric which means, one key that can perform both encryption and decryption. These keys are 256 Bit AESKeys used in a mode that requires Initialization Vectors.

Additionally all of Sync's keys have a paired hmac and this is used to verify what you're decrypting is what was encrypted so you should verify each object before decrypting it.

And lastly all JSON received from the server is Base64 encoded and needs to be decoded to be used.
  1. Generate the decryption key's bytes and its hmac bytes from the account's sync key
  2. Create a 256 bit AES Key from the bytes in step 1, along with the Initialization Vector on the crypto/keys object
  3. Decrypt the crypto/keys cipher with the key made in step 2. This reveals a base64 encoded key and hmac pair
  4. Assuming you have a users tab collection object (from a previous post), use the key bytes from step 3. and the specific tab object's Initialization Vector to create another 256 bit AES Key
  5. Decrypt the tab objects payload with the key made in step 4.
  6. Profit!

BerrySync: Firefox Sync's JSON urls

I've been working on BerrySync for just over a month now. We've gotten a lot closer to obtaining usable Firefox Sync data, just an update: yesterday I implemented Sync's credential expectations, and last week we determined the url semantics and got a trivial HTTP connector with a work queue implemented on the BlackBerry. 

Getting the Sync JSON:

  1. With the user's account info, create their sync username: http://bit.ly/mkoeRx
    1.  If it's an old sync account there account name becomes the username
    2. New accounts are emails, which need:
      1. Lowercase it
      2. SHA1 digest it
      3. Base32 encode it
      4. Lowercase it again
  2. GET request http://auth.services.mozilla.com/user/1.0/syncUsername/node/weave
    1. This returns your weave server's address.
  3. GET request weaveServer/1.1/syncUsername/storage/crypto/keys
    • Example Url from Sync 1.1 API
    • All weave node requests will require your syncUsername and account password for authentication
    • This returns a JSON specified here
So I have this implemented in our application BerrySync, currently it's encrusted with RIM libraries and not a library itself, just a workable class that contains a stack of url's which a worker thread plows through returning the results asynchronously.

Giving Back

I intend to package this HTTP connector built in Java as an open source library, hopefully it will contribute to Firefox Sync's third party ecosystem!

Tuesday, June 7, 2011

BerrySync - Unit Testing in Blackberry Apps

Pains
Building Berrysync from the ground up hasn't come without it's challenges. Most notably as of recent has been our incorporation of test driven development, for many people that brings JUnit to mind. To my surprise JUnit without including its dependencies will not natively run on the BlackBerry Java core, and even more interesting is the fact that JUnit comes bundled in the BlackBerry Developer Eclipse!

Thanks to some googling and blog posts lost in my browser history I came across this awesome tool called BUnit. It seems to be the only reliable way to unit test inside a BlackBerry app.

Using BUnit in Your Project
You'll need to define an alternate entry point to your application and add some logic to the App's entry point, here are the steps:
  1. In BlackBerry_App_Descriptor.xml -> click Alternate entry points
  2. Click add provide a name, click ok
  3. Click on what you just added and provide an Application Argument and/or an icon
  4. Open MyApp, and provide this logic (eg. Application Argument = bunit)

    public static void main(String[] args){
        if (args != null && args.length > 0 && args[0].equals("bunit")){
            TestRunner tester = new TestRunner();
            tester.enterEventDispatcher();
        }else{
            MyApp theApp = new MyApp();       
            theApp.enterEventDispatcher();
        }
    }




Two entry points allows this, where BerrySync is our application and B-unit is the unit tester


Tips On Usage
Now I assume the limitations of BUnit and the major benefits of JUnit come from java Reflection. Which you guessed it, isn't included in the BlackBerry JRE. Sooo much to my disappointment in each test suite you need to manually specify the number of tests, and later on invoke them in a switch. On top of that you'll need to add your suites to runner manually.

A snippet of my test suite: http://pastebin.com/mq9QzpkW


I also had to add a few Assertion functions, graciously BUnit provided the file to place them in.

assertEquals(String test, byte[] expected, byte[] actual)
assertNotEquals(String test, byte[] expected, byte[] actual)


here they are too! http://pastebin.com/H3R69XC6

ScreenShot
<- Berrysync's unit tester running as is