From 23730bbf7a258478bbc6319ada77a2cb47f2e518 Mon Sep 17 00:00:00 2001 From: Nick Parker Date: Fri, 16 Jul 2021 14:57:39 -0500 Subject: [PATCH] Allow keying of database --- .../database/sqlcipher/SQLiteConnection.java | 19 ++++++++++----- .../android_database_SQLiteConnection.cpp | 24 ++++++++++++++++++- 2 files changed, 36 insertions(+), 7 deletions(-) diff --git a/sqlcipher/src/main/java/net/zetetic/database/sqlcipher/SQLiteConnection.java b/sqlcipher/src/main/java/net/zetetic/database/sqlcipher/SQLiteConnection.java index b57bb7c..de09db9 100644 --- a/sqlcipher/src/main/java/net/zetetic/database/sqlcipher/SQLiteConnection.java +++ b/sqlcipher/src/main/java/net/zetetic/database/sqlcipher/SQLiteConnection.java @@ -20,12 +20,8 @@ package net.zetetic.database.sqlcipher; -import net.zetetic.database.sqlcipher.CloseGuard; - import android.database.Cursor; import android.database.CursorWindow; -import net.zetetic.database.DatabaseUtils; -import net.zetetic.database.sqlcipher.SQLiteDebug.DbStats; import android.os.CancellationSignal; import android.os.OperationCanceledException; import android.os.ParcelFileDescriptor; @@ -34,11 +30,13 @@ import android.util.Log; import android.util.LruCache; import android.util.Printer; +import net.zetetic.database.DatabaseUtils; +import net.zetetic.database.sqlcipher.SQLiteDebug.DbStats; + import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.Map; -import java.util.regex.Pattern; /** * Represents a SQLite database connection. @@ -119,6 +117,7 @@ public final class SQLiteConnection implements CancellationSignal.OnCancelListen // we can ensure that we detach the signal at the right time. private int mCancellationSignalAttachCount; + private static native void nativeKey(long connectionPtr, byte[] password); private static native long nativeOpen(String path, int openFlags, String label, boolean enableTrace, boolean enableProfile); private static native void nativeClose(long connectionPtr); @@ -214,7 +213,15 @@ public final class SQLiteConnection implements CancellationSignal.OnCancelListen mConnectionPtr = nativeOpen(mConfiguration.path, mConfiguration.openFlags, mConfiguration.label, SQLiteDebug.DEBUG_SQL_STATEMENTS, SQLiteDebug.DEBUG_SQL_TIME); - + if(mConfiguration.databaseHook != null){ + mConfiguration.databaseHook.preKey(this); + } + if(mConfiguration.password != null && mConfiguration.password.length > 0){ + nativeKey(mConnectionPtr, mConfiguration.password); + } + if(mConfiguration.databaseHook != null){ + mConfiguration.databaseHook.postKey(this); + } setPageSize(); setForeignKeyModeFromConfiguration(); setJournalSizeLimit(); diff --git a/sqlcipher/src/main/jni/sqlcipher/android_database_SQLiteConnection.cpp b/sqlcipher/src/main/jni/sqlcipher/android_database_SQLiteConnection.cpp index fa2bcb8..5692add 100644 --- a/sqlcipher/src/main/jni/sqlcipher/android_database_SQLiteConnection.cpp +++ b/sqlcipher/src/main/jni/sqlcipher/android_database_SQLiteConnection.cpp @@ -138,6 +138,26 @@ static int coll_localized( return rc; } +static void nativeKey(JNIEnv* env, jclass clazz, jlong connectionPtr, jbyteArray keyArray) { + int rc = 0; + jsize size = 0; + jbyte *key = nullptr; + auto* connection = reinterpret_cast(connectionPtr); + if(connection) { + ALOGV("Keying connection %p", connection->db); + key = env->GetByteArrayElements(keyArray, nullptr); + size = env->GetArrayLength(keyArray); + rc = sqlite3_key(connection->db, key, size); + } + if(key) { + env->ReleaseByteArrayElements(keyArray, key, JNI_ABORT); + } + if (rc != SQLITE_OK) { + ALOGE("sqlite3_key(%p) failed: %d", connection->db, rc); + throw_sqlite3_exception(env, connection->db, "Could not key db."); + } +} + static jlong nativeOpen(JNIEnv* env, jclass clazz, jstring pathStr, jint openFlags, jstring labelStr, jboolean enableTrace, jboolean enableProfile) { int sqliteFlags; @@ -819,7 +839,9 @@ static jboolean nativeHasCodec(JNIEnv* env, jobject clazz){ static JNINativeMethod sMethods[] = { /* name, signature, funcPtr */ - { "nativeOpen", "(Ljava/lang/String;ILjava/lang/String;ZZ)J", + {"nativeKey", "(J[B)V", + (void*)nativeKey }, + {"nativeOpen", "(Ljava/lang/String;ILjava/lang/String;ZZ)J", (void*)nativeOpen }, { "nativeClose", "(J)V", (void*)nativeClose },