Move the KeyValueDatabase to a separate physical database.

This commit is contained in:
Greyson Parrelli
2021-01-05 11:50:20 -05:00
committed by Alan Evans
parent 46d412a6c3
commit c466dba8c4
10 changed files with 228 additions and 50 deletions

View File

@@ -11,18 +11,30 @@ import org.thoughtcrime.securesms.util.TextSecurePreferences;
import java.io.IOException;
import java.security.SecureRandom;
public class DatabaseSecretProvider {
/**
* It can be rather expensive to read from the keystore, so this class caches the key in memory
* after it is created.
*/
public final class DatabaseSecretProvider {
@SuppressWarnings("unused")
private static final String TAG = DatabaseSecretProvider.class.getSimpleName();
private static volatile DatabaseSecret instance;
private final Context context;
public static DatabaseSecret getOrCreateDatabaseSecret(@NonNull Context context) {
if (instance == null) {
synchronized (DatabaseSecretProvider.class) {
if (instance == null) {
instance = getOrCreate(context);
}
}
}
public DatabaseSecretProvider(@NonNull Context context) {
this.context = context.getApplicationContext();
return instance;
}
public DatabaseSecret getOrCreateDatabaseSecret() {
private DatabaseSecretProvider() {
}
private static @NonNull DatabaseSecret getOrCreate(@NonNull Context context) {
String unencryptedSecret = TextSecurePreferences.getDatabaseUnencryptedSecret(context);
String encryptedSecret = TextSecurePreferences.getDatabaseEncryptedSecret(context);
@@ -31,12 +43,12 @@ public class DatabaseSecretProvider {
else return createAndStoreDatabaseSecret(context);
}
private DatabaseSecret getUnencryptedDatabaseSecret(@NonNull Context context, @NonNull String unencryptedSecret)
private static @NonNull DatabaseSecret getUnencryptedDatabaseSecret(@NonNull Context context, @NonNull String unencryptedSecret)
{
try {
DatabaseSecret databaseSecret = new DatabaseSecret(unencryptedSecret);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
if (Build.VERSION.SDK_INT < 23) {
return databaseSecret;
} else {
KeyStoreHelper.SealedData encryptedSecret = KeyStoreHelper.seal(databaseSecret.asBytes());
@@ -51,8 +63,8 @@ public class DatabaseSecretProvider {
}
}
private DatabaseSecret getEncryptedDatabaseSecret(@NonNull String serializedEncryptedSecret) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
private static @NonNull DatabaseSecret getEncryptedDatabaseSecret(@NonNull String serializedEncryptedSecret) {
if (Build.VERSION.SDK_INT < 23) {
throw new AssertionError("OS downgrade not supported. KeyStore sealed data exists on platform < M!");
} else {
KeyStoreHelper.SealedData encryptedSecret = KeyStoreHelper.SealedData.fromString(serializedEncryptedSecret);
@@ -60,14 +72,14 @@ public class DatabaseSecretProvider {
}
}
private DatabaseSecret createAndStoreDatabaseSecret(@NonNull Context context) {
private static @NonNull DatabaseSecret createAndStoreDatabaseSecret(@NonNull Context context) {
SecureRandom random = new SecureRandom();
byte[] secret = new byte[32];
random.nextBytes(secret);
DatabaseSecret databaseSecret = new DatabaseSecret(secret);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (Build.VERSION.SDK_INT >= 23) {
KeyStoreHelper.SealedData encryptedSecret = KeyStoreHelper.seal(databaseSecret.asBytes());
TextSecurePreferences.setDatabaseEncryptedSecret(context, encryptedSecret.serialize());
} else {