diff --git a/apps/android/app/src/main/cpp/simplex-api.c b/apps/android/app/src/main/cpp/simplex-api.c index e6114feb46..bfa259008a 100644 --- a/apps/android/app/src/main/cpp/simplex-api.c +++ b/apps/android/app/src/main/cpp/simplex-api.c @@ -22,44 +22,33 @@ Java_chat_simplex_app_SimplexAppKt_initHS(__unused JNIEnv *env, __unused jclass } // from simplex-chat -typedef void* chat_ctrl; +typedef long* chat_ctrl; extern char *chat_migrate_init(const char *path, const char *key, chat_ctrl *ctrl); - -extern char *chat_migrate_db(const char *path, const char *key); -extern chat_ctrl chat_init_key(const char *path, const char *key); -extern chat_ctrl chat_init(const char *path); // deprecated extern char *chat_send_cmd(chat_ctrl ctrl, const char *cmd); extern char *chat_recv_msg(chat_ctrl ctrl); // deprecated extern char *chat_recv_msg_wait(chat_ctrl ctrl, const int wait); extern char *chat_parse_markdown(const char *str); -JNIEXPORT jstring JNICALL -Java_chat_simplex_app_SimplexAppKt_chatMigrateDB(JNIEnv *env, __unused jclass clazz, jstring dbPath, jstring dbKey) { +JNIEXPORT jobjectArray JNICALL +Java_chat_simplex_app_SimplexAppKt_chatMigrateInit(JNIEnv *env, __unused jclass clazz, jstring dbPath, jstring dbKey) { const char *_dbPath = (*env)->GetStringUTFChars(env, dbPath, JNI_FALSE); const char *_dbKey = (*env)->GetStringUTFChars(env, dbKey, JNI_FALSE); - jstring res = (*env)->NewStringUTF(env, chat_migrate_db(_dbPath, _dbKey)); + jlong _ctrl = (jlong) 0; + jstring res = (*env)->NewStringUTF(env, chat_migrate_init(_dbPath, _dbKey, &_ctrl)); (*env)->ReleaseStringUTFChars(env, dbPath, _dbPath); (*env)->ReleaseStringUTFChars(env, dbKey, _dbKey); - return res; -} -JNIEXPORT jlong JNICALL -Java_chat_simplex_app_SimplexAppKt_chatInitKey(JNIEnv *env, __unused jclass clazz, jstring dbPath, jstring dbKey) { - const char *_dbPath = (*env)->GetStringUTFChars(env, dbPath, JNI_FALSE); - const char *_dbKey = (*env)->GetStringUTFChars(env, dbKey, JNI_FALSE); - jlong ctrl = (jlong)chat_init_key(_dbPath, _dbKey); - (*env)->ReleaseStringUTFChars(env, dbPath, _dbPath); - (*env)->ReleaseStringUTFChars(env, dbKey, _dbKey); - return ctrl; -} - -JNIEXPORT jlong JNICALL -Java_chat_simplex_app_SimplexAppKt_chatInit(JNIEnv *env, __unused jclass clazz, jstring dbPath) { - const char *_dbPath = (*env)->GetStringUTFChars(env, dbPath, JNI_FALSE); - jlong ctrl = (jlong)chat_init(_dbPath); - (*env)->ReleaseStringUTFChars(env, dbPath, _dbPath); - return ctrl; + // Creating array of Object's (boxed values can be passed, eg. Long instead of long) + jobjectArray ret = (jobjectArray)(*env)->NewObjectArray(env, 2, (*env)->FindClass(env, "java/lang/Object"), NULL); + // Java's String + (*env)->SetObjectArrayElement(env, ret, 0, res); + // Java's Long + (*env)->SetObjectArrayElement(env, ret, 1, + (*env)->NewObject(env, (*env)->FindClass(env, "java/lang/Long"), + (*env)->GetMethodID(env, (*env)->FindClass(env, "java/lang/Long"), "", "(J)V"), + _ctrl)); + return ret; } JNIEXPORT jstring JNICALL diff --git a/apps/android/app/src/main/java/chat/simplex/app/SimplexApp.kt b/apps/android/app/src/main/java/chat/simplex/app/SimplexApp.kt index b81e19e9a2..369addf822 100644 --- a/apps/android/app/src/main/java/chat/simplex/app/SimplexApp.kt +++ b/apps/android/app/src/main/java/chat/simplex/app/SimplexApp.kt @@ -10,6 +10,7 @@ import chat.simplex.app.views.helpers.* import chat.simplex.app.views.onboarding.OnboardingStage import chat.simplex.app.views.usersettings.NotificationsMode import kotlinx.coroutines.* +import kotlinx.serialization.decodeFromString import java.io.BufferedReader import java.io.InputStreamReader import java.util.* @@ -26,9 +27,7 @@ external fun pipeStdOutToSocket(socketName: String) : Int // SimpleX API typealias ChatCtrl = Long -external fun chatMigrateDB(dbPath: String, dbKey: String): String -external fun chatInitKey(dbPath: String, dbKey: String): ChatCtrl -external fun chatInit(dbPath: String): ChatCtrl +external fun chatMigrateInit(dbPath: String, dbKey: String): Array external fun chatSendCmd(ctrl: ChatCtrl, msg: String): String external fun chatRecvMsg(ctrl: ChatCtrl): String external fun chatRecvMsgWait(ctrl: ChatCtrl, timeout: Int): String @@ -38,20 +37,24 @@ class SimplexApp: Application(), LifecycleEventObserver { lateinit var chatController: ChatController fun initChatController(useKey: String? = null, startChat: Boolean = true) { - val dbKey = useKey ?: DatabaseUtils.getDatabaseKey() ?: "" - val res = DatabaseUtils.migrateChatDatabase(dbKey) - val ctrl = if (res.second is DBMigrationResult.OK) { - chatInitKey(getFilesDirectory(applicationContext), dbKey) + val dbKey = useKey ?: DatabaseUtils.useDatabaseKey() ?: "" + val dbAbsolutePathPrefix = getFilesDirectory(SimplexApp.context) + val migrated: Array = chatMigrateInit(dbAbsolutePathPrefix, dbKey) + val res: DBMigrationResult = kotlin.runCatching { + json.decodeFromString(migrated[0] as String) + }.getOrElse { DBMigrationResult.Unknown(migrated[0] as String) } + val ctrl = if (res is DBMigrationResult.OK) { + migrated[1] as Long } else null if (::chatController.isInitialized) { chatController.ctrl = ctrl } else { chatController = ChatController(ctrl, ntfManager, applicationContext, appPreferences) } - chatModel.chatDbEncrypted.value = res.first - chatModel.chatDbStatus.value = res.second - if (res.second != DBMigrationResult.OK) { - Log.d(TAG, "Unable to migrate successfully: ${res.second}") + chatModel.chatDbEncrypted.value = dbKey != "" + chatModel.chatDbStatus.value = res + if (res != DBMigrationResult.OK) { + Log.d(TAG, "Unable to migrate successfully: $res") } else if (startChat) { // If we migrated successfully means previous re-encryption process on database level finished successfully too if (appPreferences.encryptionStartedAt.get() != null) appPreferences.encryptionStartedAt.set(null) diff --git a/apps/android/app/src/main/java/chat/simplex/app/views/helpers/DatabaseUtils.kt b/apps/android/app/src/main/java/chat/simplex/app/views/helpers/DatabaseUtils.kt index 9e07bcc7d0..0409789e1f 100644 --- a/apps/android/app/src/main/java/chat/simplex/app/views/helpers/DatabaseUtils.kt +++ b/apps/android/app/src/main/java/chat/simplex/app/views/helpers/DatabaseUtils.kt @@ -3,7 +3,6 @@ package chat.simplex.app.views.helpers import android.util.Log import chat.simplex.app.* import chat.simplex.app.model.AppPreferences -import chat.simplex.app.model.json import chat.simplex.app.views.usersettings.Cryptor import kotlinx.serialization.* import java.io.File @@ -41,31 +40,27 @@ object DatabaseUtils { appPreferences.initializationVectorDBPassphrase.set(null) } - fun migrateChatDatabase(useKey: String? = null): Pair { - Log.d(TAG, "migrateChatDatabase ${appPreferences.storeDBPassphrase.get()}") - val dbAbsolutePathPrefix = getFilesDirectory(SimplexApp.context) + fun useDatabaseKey(): String { + Log.d(TAG, "useDatabaseKey ${appPreferences.storeDBPassphrase.get()}") var dbKey = "" val useKeychain = appPreferences.storeDBPassphrase.get() - if (useKey != null) { - dbKey = useKey - } else if (useKeychain) { + if (useKeychain) { if (!hasDatabase(SimplexApp.context.dataDir.absolutePath)) { dbKey = randomDatabasePassword() + setDatabaseKey(dbKey) appPreferences.initialRandomDBPassphrase.set(true) } else { dbKey = getDatabaseKey() ?: "" } } - Log.d(TAG, "migrateChatDatabase DB path: $dbAbsolutePathPrefix") - val migrated = chatMigrateDB(dbAbsolutePathPrefix, dbKey) - val res: DBMigrationResult = kotlin.runCatching { - json.decodeFromString(migrated) - }.getOrElse { DBMigrationResult.Unknown(migrated) } - val encrypted = dbKey != "" - return encrypted to res + return dbKey } - private fun randomDatabasePassword(): String = ByteArray(32).apply { SecureRandom().nextBytes(this) }.toBase64String() + private fun randomDatabasePassword(): String { + val s = ByteArray(32) + SecureRandom().nextBytes(s) + return s.toBase64String().replace("\n", "") + } } @Serializable diff --git a/apps/ios/Shared/Views/Database/DatabaseEncryptionView.swift b/apps/ios/Shared/Views/Database/DatabaseEncryptionView.swift index 764a44917d..442fa15e33 100644 --- a/apps/ios/Shared/Views/Database/DatabaseEncryptionView.swift +++ b/apps/ios/Shared/Views/Database/DatabaseEncryptionView.swift @@ -318,11 +318,11 @@ enum PassphraseStrength { init(passphrase s: String) { let enthropy = passphraseEnthropy(s) - self = enthropy > 60 + self = enthropy > 100 ? .strong - : enthropy > 45 + : enthropy > 70 ? .reasonable - : enthropy > 30 + : enthropy > 40 ? .weak : .veryWeak }