Wednesday, August 8, 2012

Trying SQLCipher with Cordova iOS SQLitePlugin

NOTICE (June 2015): These instructions are completely out-of-date, the following Cordova plugin supports sqlcipher out-of-the-box: https://github.com/litehelpers/Cordova-sqlcipher-adapter

UPDATE (OLD): please see the updated directions posted on my new blog.

I have already documented running the Cordova SQLitePlugin PhoneGap/Cordova SQLitePlugin for Android with SQLCipher for Android here and here for rebuilding SQLite for Android from source. Here I document the steps I am taking to run SQLCipher with the Cordova-SQLitePlugin PhoneGap-SQLitePlugin for iOS.

The first step is to create the (test) app project. I created a Cordova 2.0 project using the command line tool create as documented here and here.

Next I follow the directions from SQLCipher for iOS integration to build the project with SQLCipher (hold off on the integration code for now). For this case I am using OpenSSL 1.0.1c. Download from http://www.openssl.org/source/ and extract.

Under the project folder, git clone git://github.com/sqlcipher/sqlcipher.git and git://github.com/sqlcipher/openssl-xcode.git

Now open the app project, open Xcode --> Preferences menu, Locations, Source Trees, then add the setting OPENSSL_SRC that points to the location of the extracted OpenSSL source tree.

Add the subproject references for the sqlcipher xcodeproject and openssl-xcode/openssl.xcodeproj. I selected the top-level project item and alt-command-a to add each subproject reference.

Configure build dependencies: select the app target, click the build phases tab, and add the target dependencies both openssl/crypto and sqlcipher. Under link binary with libraries section add libcrypto.a and libsqlcipher.a but make sure there is no libsqlite3 library.

Holding off on setting build architectures and CFLAGS for now. Under other C flags add
-DSQLITE_HAS_CODEC for both debug and release projects. It should now be possible to build the project.

Building with SQLitePlugin: add the SQLitePlugin.[hm] to the Xcode project Plugins folder and the project should still build. Make the following patch to SQLitePlugin.m:


$ git diff Plugins/SQLitePlugin.m
diff --git a/iOS/Plugins/SQLitePlugin.m b/iOS/Plugins/SQLitePlugin.m
index 444a78b..65b5b61 100644
--- a/iOS/Plugins/SQLitePlugin.m
+++ b/iOS/Plugins/SQLitePlugin.m
@@ -70,7 +70,10 @@
         [self respond:callback withString:@"{ message: 'Unable to open DB' }" withType:@"error"];
         return;
     }
-    
+
+    const char* key = [@"BIGSecret" UTF8String];
+    sqlite3_key(db, key, strlen(key));
+
     NSValue *dbPointer = [NSValue valueWithPointer:db];
     [openDBs setObject:dbPointer forKey: dbPath];
     [self respond:callback withString: @"{ message: 'Database opened' }" withType:@"success"];


and build should still be working. Add SQLitePlugin to Cordova.plist resources, Install SQLitePlugin.js into the www directory, add a small test program using the SQLitePlugin, and try running.

To be honest, I do not really like the number of external projects that have to be assembled and cobbled together to make SQLCipher work with the Cordova-SQLitePlugin for a Cordova project. I would like to find a solution that allows someone to just setup a simple project, add some files as necessary, and run.