Migrate backup passphrase to be keystore-encrypted when available.

This commit is contained in:
Greyson Parrelli 2019-02-07 09:47:06 -08:00
parent db1ad39c6b
commit c9a0a66f18
4 changed files with 64 additions and 7 deletions

View File

@ -34,7 +34,7 @@ public class BackupDialog {
button.setOnClickListener(v -> {
CheckBox confirmationCheckBox = dialog.findViewById(R.id.confirmation_check);
if (confirmationCheckBox.isChecked()) {
TextSecurePreferences.setBackupPassphrase(context, Util.join(password, " "));
BackupPassphrase.set(context, Util.join(password, " "));
TextSecurePreferences.setBackupEnabled(context, true);
LocalBackupListener.schedule(context);
@ -75,7 +75,7 @@ public class BackupDialog {
.setMessage(R.string.BackupDialog_disable_and_delete_all_local_backups)
.setNegativeButton(android.R.string.cancel, null)
.setPositiveButton(R.string.BackupDialog_delete_backups_statement, (dialog, which) -> {
TextSecurePreferences.setBackupPassphrase(context, null);
BackupPassphrase.set(context, null);
TextSecurePreferences.setBackupEnabled(context, false);
BackupUtil.deleteAllBackups();
preference.setChecked(false);

View File

@ -0,0 +1,47 @@
package org.thoughtcrime.securesms.backup;
import android.content.Context;
import android.os.Build;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import org.thoughtcrime.securesms.crypto.KeyStoreHelper;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
/**
* Allows the getting and setting of the backup passphrase, which is stored encrypted on API >= 23.
*/
public class BackupPassphrase {
private static final String TAG = BackupPassphrase.class.getSimpleName();
public static String get(@NonNull Context context) {
String passphrase = TextSecurePreferences.getBackupPassphrase(context);
String encryptedPassphrase = TextSecurePreferences.getEncryptedBackupPassphrase(context);
if (Build.VERSION.SDK_INT < 23 || (passphrase == null && encryptedPassphrase == null)) {
return passphrase;
}
if (encryptedPassphrase == null) {
Log.i(TAG, "Migrating to encrypted passphrase.");
set(context, passphrase);
encryptedPassphrase = TextSecurePreferences.getEncryptedBackupPassphrase(context);
}
KeyStoreHelper.SealedData data = KeyStoreHelper.SealedData.fromString(encryptedPassphrase);
return new String(KeyStoreHelper.unseal(data));
}
public static void set(@NonNull Context context, @Nullable String passphrase) {
if (passphrase == null || Build.VERSION.SDK_INT < 23) {
TextSecurePreferences.setBackupPassphrase(context, passphrase);
TextSecurePreferences.setEncryptedBackupPassphrase(context, null);
} else {
KeyStoreHelper.SealedData encryptedPassphrase = KeyStoreHelper.seal(passphrase.getBytes());
TextSecurePreferences.setEncryptedBackupPassphrase(context, encryptedPassphrase.serialize());
TextSecurePreferences.setBackupPassphrase(context, null);
}
}
}

View File

@ -5,6 +5,7 @@ import android.Manifest;
import android.content.Context;
import android.support.annotation.NonNull;
import org.thoughtcrime.securesms.backup.BackupPassphrase;
import org.thoughtcrime.securesms.jobmanager.SafeData;
import org.thoughtcrime.securesms.logging.Log;
@ -68,7 +69,7 @@ public class LocalBackupJob extends ContextJob {
R.drawable.ic_signal_backup);
try {
String backupPassword = TextSecurePreferences.getBackupPassphrase(context);
String backupPassword = BackupPassphrase.get(context);
File backupDirectory = StorageUtil.getBackupDirectory();
String timestamp = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss", Locale.US).format(new Date());
String fileName = String.format("signal-%s.backup", timestamp);

View File

@ -138,10 +138,11 @@ public class TextSecurePreferences {
private static final String ACTIVE_SIGNED_PRE_KEY_ID = "pref_active_signed_pre_key_id";
private static final String NEXT_SIGNED_PRE_KEY_ID = "pref_next_signed_pre_key_id";
public static final String BACKUP_ENABLED = "pref_backup_enabled";
private static final String BACKUP_PASSPHRASE = "pref_backup_passphrase";
private static final String BACKUP_TIME = "pref_backup_next_time";
public static final String BACKUP_NOW = "pref_backup_create";
public static final String BACKUP_ENABLED = "pref_backup_enabled";
private static final String BACKUP_PASSPHRASE = "pref_backup_passphrase";
private static final String ENCRYPTED_BACKUP_PASSPHRASE = "pref_encrypted_backup_passphrase";
private static final String BACKUP_TIME = "pref_backup_next_time";
public static final String BACKUP_NOW = "pref_backup_create";
public static final String SCREEN_LOCK = "pref_android_screen_lock";
public static final String SCREEN_LOCK_TIMEOUT = "pref_android_screen_lock_timeout";
@ -231,6 +232,14 @@ public class TextSecurePreferences {
return getStringPreference(context, BACKUP_PASSPHRASE, null);
}
public static void setEncryptedBackupPassphrase(@NonNull Context context, @Nullable String encryptedPassphrase) {
setStringPreference(context, ENCRYPTED_BACKUP_PASSPHRASE, encryptedPassphrase);
}
public static @Nullable String getEncryptedBackupPassphrase(@NonNull Context context) {
return getStringPreference(context, ENCRYPTED_BACKUP_PASSPHRASE, null);
}
public static void setBackupEnabled(@NonNull Context context, boolean value) {
setBooleanPreference(context, BACKUP_ENABLED, value);
}