From 7d15c602a6f13305159fc9fb04b72c260d8b28a0 Mon Sep 17 00:00:00 2001 From: Alan Evans Date: Thu, 23 Jan 2020 16:49:19 -0500 Subject: [PATCH] Enable KBS. --- app/build.gradle | 4 +- .../lock/PinHashing_hashPin_Test.java | 58 +++++++++++++- .../dependencies/ApplicationDependencies.java | 2 - .../securesms/lock/PinHashing.java | 15 ++-- .../lock/RegistrationLockDialog.java | 77 ++++++++----------- .../RegistrationPinV2MigrationJob.java | 8 +- .../service/CodeVerificationRequest.java | 15 +--- .../securesms/util/FeatureFlags.java | 13 +--- .../data/kbs_pin_normalization_vectors.json | 10 +++ app/src/test/resources/data/kbs_vectors.json | 54 ++++++++----- app/witness-verifications.gradle | 4 +- 11 files changed, 149 insertions(+), 111 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index f97e27ee6..67725321f 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -117,7 +117,7 @@ dependencies { implementation project(':libsignal-service') - implementation 'org.signal:argon2:13.0@aar' + implementation 'org.signal:argon2:13.1@aar' implementation 'org.signal:ringrtc-android:0.3.1' implementation "me.leolin:ShortcutBadger:1.1.16" @@ -229,7 +229,7 @@ android { buildConfigField "int", "CONTENT_PROXY_PORT", "443" buildConfigField "String", "SIGNAL_AGENT", "\"OWA\"" buildConfigField "String", "MRENCLAVE", "\"cd6cfc342937b23b1bdd3bbf9721aa5615ac9ff50a75c5527d441cd3276826c9\"" - buildConfigField "String", "KEY_BACKUP_ENCLAVE_NAME", "\"\"" + buildConfigField "String", "KEY_BACKUP_ENCLAVE_NAME", "\"fe7c1bfae98f9b073d220366ea31163ee82f6d04bead774f71ca8e5c40847bfe\"" buildConfigField "String", "KEY_BACKUP_MRENCLAVE", "\"a3baab19ef6ce6f34ab9ebb25ba722725ae44a8872dc0ff08ad6d83a9489de87\"" buildConfigField "String", "UNIDENTIFIED_SENDER_TRUST_ROOT", "\"BXu6QIKVz5MA8gstzfOgRQGqyLqOwNKHL6INkv3IHWMF\"" buildConfigField "String[]", "LANGUAGES", "new String[]{\"" + autoResConfig().collect { s -> s.replace('-r', '_') }.join('", "') + '"}' diff --git a/app/src/androidTest/java/org/thoughtcrime/securesms/lock/PinHashing_hashPin_Test.java b/app/src/androidTest/java/org/thoughtcrime/securesms/lock/PinHashing_hashPin_Test.java index 5a1824c61..5b8f365b0 100644 --- a/app/src/androidTest/java/org/thoughtcrime/securesms/lock/PinHashing_hashPin_Test.java +++ b/app/src/androidTest/java/org/thoughtcrime/securesms/lock/PinHashing_hashPin_Test.java @@ -10,34 +10,84 @@ import java.io.IOException; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; public final class PinHashing_hashPin_Test { @Test public void argon2_hashed_pin_password() throws IOException { + String pin = "password"; byte[] backupId = Hex.fromStringCondensed("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"); MasterKey masterKey = new MasterKey(Hex.fromStringCondensed("202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f")); - HashedPin hashedPin = PinHashing.hashPin("password", () -> backupId); + HashedPin hashedPin = PinHashing.hashPin(pin, () -> backupId); KbsData kbsData = hashedPin.createNewKbsData(masterKey); - assertArrayEquals(Hex.fromStringCondensed("ab7e8499d21f80a6600b3b9ee349ac6d72c07e3359fe885a934ba7aa844429f8"), hashedPin.getKbsAccessKey()); + assertArrayEquals(hashedPin.getKbsAccessKey(), kbsData.getKbsAccessKey()); assertArrayEquals(Hex.fromStringCondensed("ab7e8499d21f80a6600b3b9ee349ac6d72c07e3359fe885a934ba7aa844429f8"), kbsData.getKbsAccessKey()); assertArrayEquals(Hex.fromStringCondensed("3f33ce58eb25b40436592a30eae2a8fabab1899095f4e2fba6e2d0dc43b4a2d9cac5a3931748522393951e0e54dec769"), kbsData.getCipherText()); assertEquals(masterKey, kbsData.getMasterKey()); + + String localPinHash = PinHashing.localPinHash(pin); + assertTrue(PinHashing.verifyLocalPinHash(localPinHash, pin)); } @Test public void argon2_hashed_pin_another_password() throws IOException { + String pin = "anotherpassword"; byte[] backupId = Hex.fromStringCondensed("202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f"); MasterKey masterKey = new MasterKey(Hex.fromStringCondensed("88a787415a2ecd79da0d1016a82a27c5c695c9a19b88b0aa1d35683280aa9a67")); - HashedPin hashedPin = PinHashing.hashPin("anotherpassword ", () -> backupId); + HashedPin hashedPin = PinHashing.hashPin(pin, () -> backupId); KbsData kbsData = hashedPin.createNewKbsData(masterKey); - assertArrayEquals(Hex.fromStringCondensed("301d9dd1e96f20ce51083f67d3298fd37b97525de8324d5e12ed2d407d3d927b"), hashedPin.getKbsAccessKey()); + assertArrayEquals(hashedPin.getKbsAccessKey(), kbsData.getKbsAccessKey()); assertArrayEquals(Hex.fromStringCondensed("301d9dd1e96f20ce51083f67d3298fd37b97525de8324d5e12ed2d407d3d927b"), kbsData.getKbsAccessKey()); assertArrayEquals(Hex.fromStringCondensed("9d9b05402ea39c17ff1c9298c8a0e86784a352aa02a74943bf8bcf07ec0f4b574a5b786ad0182c8d308d9eb06538b8c9"), kbsData.getCipherText()); assertEquals(masterKey, kbsData.getMasterKey()); + + String localPinHash = PinHashing.localPinHash(pin); + assertTrue(PinHashing.verifyLocalPinHash(localPinHash, pin)); + } + + @Test + public void argon2_hashed_pin_password_with_spaces_diacritics_and_non_arabic_numerals() throws IOException { + String pin = " Pass६örd "; + byte[] backupId = Hex.fromStringCondensed("cba811749042b303a6a7efa5ccd160aea5e3ea243c8d2692bd13d515732f51a8"); + MasterKey masterKey = new MasterKey(Hex.fromStringCondensed("9571f3fde1e58588ba49bcf82be1b301ca3859a6f59076f79a8f47181ef952bf")); + + HashedPin hashedPin = PinHashing.hashPin(pin, () -> backupId); + KbsData kbsData = hashedPin.createNewKbsData(masterKey); + + assertArrayEquals(hashedPin.getKbsAccessKey(), kbsData.getKbsAccessKey()); + assertArrayEquals(Hex.fromStringCondensed("ab645acdccc1652a48a34b2ac6926340ff35c03034013f68760f20013f028dd8"), kbsData.getKbsAccessKey()); + assertArrayEquals(Hex.fromStringCondensed("11c0ba1834db15e47c172f6c987c64bd4cfc69c6047dd67a022afeec0165a10943f204d5b8f37b3cb7bab21c6dfc39c8"), kbsData.getCipherText()); + assertEquals(masterKey, kbsData.getMasterKey()); + + assertEquals("577939bccb2b6638c39222d5a97998a867c5e154e30b82cc120f2dd07a3de987", kbsData.getMasterKey().deriveRegistrationLock()); + + String localPinHash = PinHashing.localPinHash(pin); + assertTrue(PinHashing.verifyLocalPinHash(localPinHash, pin)); + } + + @Test + public void argon2_hashed_pin_password_with_just_non_arabic_numerals() throws IOException { + String pin = " ६१८ "; + byte[] backupId = Hex.fromStringCondensed("717dc111a98423a57196512606822fca646c653facd037c10728f14ba0be2ab3"); + MasterKey masterKey = new MasterKey(Hex.fromStringCondensed("0432d735b32f66d0e3a70d4f9cc821a8529521a4937d26b987715d8eff4e4c54")); + + HashedPin hashedPin = PinHashing.hashPin(pin, () -> backupId); + KbsData kbsData = hashedPin.createNewKbsData(masterKey); + + + assertArrayEquals(hashedPin.getKbsAccessKey(), kbsData.getKbsAccessKey()); + assertArrayEquals(Hex.fromStringCondensed("d2fedabd0d4c17a371491c9722578843a26be3b4923e28d452ab2fc5491e794b"), kbsData.getKbsAccessKey()); + assertArrayEquals(Hex.fromStringCondensed("877ef871ef1fc668401c717ef21aa12e8523579fb1ff4474b76f28c2293537c80cc7569996c9e0229bea7f378e3a824e"), kbsData.getCipherText()); + assertEquals(masterKey, kbsData.getMasterKey()); + + assertEquals("23a75cb1df1a87df45cc2ed167c2bdc85ab1220b847c88761b0005cac907fce5", kbsData.getMasterKey().deriveRegistrationLock()); + + String localPinHash = PinHashing.localPinHash(pin); + assertTrue(PinHashing.verifyLocalPinHash(localPinHash, pin)); } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/dependencies/ApplicationDependencies.java b/app/src/main/java/org/thoughtcrime/securesms/dependencies/ApplicationDependencies.java index 08df65289..d61d3f2e6 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/dependencies/ApplicationDependencies.java +++ b/app/src/main/java/org/thoughtcrime/securesms/dependencies/ApplicationDependencies.java @@ -12,7 +12,6 @@ import org.thoughtcrime.securesms.keyvalue.KeyValueStore; import org.thoughtcrime.securesms.push.SignalServiceNetworkAccess; import org.thoughtcrime.securesms.recipients.LiveRecipientCache; import org.thoughtcrime.securesms.service.IncomingMessageObserver; -import org.thoughtcrime.securesms.util.FeatureFlags; import org.thoughtcrime.securesms.util.FrameRateTracker; import org.thoughtcrime.securesms.util.IasKeyStore; import org.thoughtcrime.securesms.util.TextSecurePreferences; @@ -69,7 +68,6 @@ public class ApplicationDependencies { } public static synchronized @NonNull KeyBackupService getKeyBackupService() { - if (!FeatureFlags.kbs()) throw new AssertionError(); return getSignalServiceAccountManager().getKeyBackupService(IasKeyStore.getIasKeyStore(application), BuildConfig.KEY_BACKUP_ENCLAVE_NAME, BuildConfig.KEY_BACKUP_MRENCLAVE, diff --git a/app/src/main/java/org/thoughtcrime/securesms/lock/PinHashing.java b/app/src/main/java/org/thoughtcrime/securesms/lock/PinHashing.java index af3f38d72..ff90e28e8 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/lock/PinHashing.java +++ b/app/src/main/java/org/thoughtcrime/securesms/lock/PinHashing.java @@ -1,12 +1,12 @@ package org.thoughtcrime.securesms.lock; import androidx.annotation.NonNull; -import androidx.annotation.Nullable; import org.signal.argon2.Argon2; import org.signal.argon2.Argon2Exception; import org.signal.argon2.MemoryCost; import org.signal.argon2.Type; +import org.signal.argon2.UnknownTypeException; import org.signal.argon2.Version; import org.thoughtcrime.securesms.util.Util; import org.whispersystems.signalservice.api.KeyBackupService; @@ -15,9 +15,6 @@ import org.whispersystems.signalservice.internal.registrationpin.PinHasher; public final class PinHashing { - private static final Type KBS_PIN_ARGON_TYPE = Type.Argon2id; - private static final Type LOCAL_PIN_ARGON_TYPE = Type.Argon2i; - private PinHashing() { } @@ -25,7 +22,7 @@ public final class PinHashing { return PinHasher.hashPin(PinHasher.normalize(pin), password -> { try { return new Argon2.Builder(Version.V13) - .type(KBS_PIN_ARGON_TYPE) + .type(Type.Argon2id) .memoryCost(MemoryCost.MiB(16)) .parallelism(1) .iterations(32) @@ -43,7 +40,7 @@ public final class PinHashing { byte[] normalized = PinHasher.normalize(pin); try { return new Argon2.Builder(Version.V13) - .type(LOCAL_PIN_ARGON_TYPE) + .type(Type.Argon2i) .memoryCost(MemoryCost.KiB(256)) .parallelism(1) .iterations(50) @@ -58,6 +55,10 @@ public final class PinHashing { public static boolean verifyLocalPinHash(@NonNull String localPinHash, @NonNull String pin) { byte[] normalized = PinHasher.normalize(pin); - return Argon2.verify(localPinHash, normalized, LOCAL_PIN_ARGON_TYPE); + try { + return Argon2.verify(localPinHash, normalized); + } catch (UnknownTypeException e) { + throw new AssertionError(e); + } } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/lock/RegistrationLockDialog.java b/app/src/main/java/org/thoughtcrime/securesms/lock/RegistrationLockDialog.java index ca343dd6c..40e1547af 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/lock/RegistrationLockDialog.java +++ b/app/src/main/java/org/thoughtcrime/securesms/lock/RegistrationLockDialog.java @@ -35,7 +35,6 @@ import org.thoughtcrime.securesms.keyvalue.KbsValues; import org.thoughtcrime.securesms.keyvalue.SignalStore; import org.thoughtcrime.securesms.logging.Log; import org.thoughtcrime.securesms.migrations.RegistrationPinV2MigrationJob; -import org.thoughtcrime.securesms.util.FeatureFlags; import org.thoughtcrime.securesms.util.ServiceUtil; import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.thoughtcrime.securesms.util.ThemeUtil; @@ -126,10 +125,8 @@ public final class RegistrationLockDialog { dialog.dismiss(); RegistrationLockReminders.scheduleReminder(context, true); - if (FeatureFlags.kbs()) { - Log.i(TAG, "Pin V1 successfully remembered, scheduling a migration to V2"); - ApplicationDependencies.getJobManager().add(new RegistrationPinV2MigrationJob()); - } + Log.i(TAG, "Pin V1 successfully remembered, scheduling a migration to V2"); + ApplicationDependencies.getJobManager().add(new RegistrationPinV2MigrationJob()); } }); } @@ -201,34 +198,27 @@ public final class RegistrationLockDialog { @Override protected Boolean doInBackground(Void... voids) { try { - if (!FeatureFlags.kbs()) { - Log.i(TAG, "Setting V1 pin"); - SignalServiceAccountManager accountManager = ApplicationDependencies.getSignalServiceAccountManager(); - accountManager.setPin(pinValue); - TextSecurePreferences.setDeprecatedRegistrationLockPin(context, pinValue); + Log.i(TAG, "Setting pin on KBS"); + + KbsValues kbsValues = SignalStore.kbsValues(); + MasterKey masterKey = kbsValues.getOrCreateMasterKey(); + KeyBackupService keyBackupService = ApplicationDependencies.getKeyBackupService(); + KeyBackupService.PinChangeSession pinChangeSession = keyBackupService.newPinChangeSession(); + HashedPin hashedPin = PinHashing.hashPin(pinValue, pinChangeSession); + RegistrationLockData kbsData = pinChangeSession.setPin(hashedPin, masterKey); + RegistrationLockData restoredData = keyBackupService.newRestoreSession(kbsData.getTokenResponse()) + .restorePin(hashedPin); + + if (!restoredData.getMasterKey().equals(masterKey)) { + throw new AssertionError("Failed to set the pin correctly"); } else { - Log.i(TAG, "Setting pin on KBS"); - - KbsValues kbsValues = SignalStore.kbsValues(); - MasterKey masterKey = kbsValues.getOrCreateMasterKey(); - KeyBackupService keyBackupService = ApplicationDependencies.getKeyBackupService(); - KeyBackupService.PinChangeSession pinChangeSession = keyBackupService.newPinChangeSession(); - HashedPin hashedPin = PinHashing.hashPin(pinValue, pinChangeSession); - RegistrationLockData kbsData = pinChangeSession.setPin(hashedPin, masterKey); - RegistrationLockData restoredData = keyBackupService.newRestoreSession(kbsData.getTokenResponse()) - .restorePin(hashedPin); - - if (!restoredData.getMasterKey().equals(masterKey)) { - throw new AssertionError("Failed to set the pin correctly"); - } else { - Log.i(TAG, "Set and retrieved pin on KBS successfully"); - } - - kbsValues.setRegistrationLockMasterKey(restoredData, PinHashing.localPinHash(pinValue)); - TextSecurePreferences.clearOldRegistrationLockPin(context); - TextSecurePreferences.setRegistrationLockLastReminderTime(context, System.currentTimeMillis()); - TextSecurePreferences.setRegistrationLockNextReminderInterval(context, RegistrationLockReminders.INITIAL_INTERVAL); + Log.i(TAG, "Set and retrieved pin on KBS successfully"); } + + kbsValues.setRegistrationLockMasterKey(restoredData, PinHashing.localPinHash(pinValue)); + TextSecurePreferences.clearOldRegistrationLockPin(context); + TextSecurePreferences.setRegistrationLockLastReminderTime(context, System.currentTimeMillis()); + TextSecurePreferences.setRegistrationLockNextReminderInterval(context, RegistrationLockReminders.INITIAL_INTERVAL); return true; } catch (IOException | UnauthenticatedResponseException | KeyBackupServicePinException e) { Log.w(TAG, e); @@ -282,23 +272,18 @@ public final class RegistrationLockDialog { @Override protected Boolean doInBackground(Void... voids) { try { - if (!FeatureFlags.kbs()) { + Log.i(TAG, "Removing v2 registration lock pin from server"); + KbsValues kbsValues = SignalStore.kbsValues(); + TokenResponse currentToken = kbsValues.getRegistrationLockTokenResponse(); + + KeyBackupService keyBackupService = ApplicationDependencies.getKeyBackupService(); + keyBackupService.newPinChangeSession(currentToken).removePin(); + kbsValues.clearRegistrationLock(); + + // It is possible a migration has not occurred, in this case, we need to remove the old V1 Pin + if (TextSecurePreferences.isV1RegistrationLockEnabled(context)) { Log.i(TAG, "Removing v1 registration lock pin from server"); ApplicationDependencies.getSignalServiceAccountManager().removeV1Pin(); - } else { - Log.i(TAG, "Removing v2 registration lock pin from server"); - KbsValues kbsValues = SignalStore.kbsValues(); - TokenResponse currentToken = kbsValues.getRegistrationLockTokenResponse(); - - KeyBackupService keyBackupService = ApplicationDependencies.getKeyBackupService(); - keyBackupService.newPinChangeSession(currentToken).removePin(); - kbsValues.clearRegistrationLock(); - - // It is possible a migration has not occurred, in this case, we need to remove the old V1 Pin - if (TextSecurePreferences.isV1RegistrationLockEnabled(context)) { - Log.i(TAG, "Removing v1 registration lock pin from server"); - ApplicationDependencies.getSignalServiceAccountManager().removeV1Pin(); - } } TextSecurePreferences.clearOldRegistrationLockPin(context); return true; diff --git a/app/src/main/java/org/thoughtcrime/securesms/migrations/RegistrationPinV2MigrationJob.java b/app/src/main/java/org/thoughtcrime/securesms/migrations/RegistrationPinV2MigrationJob.java index 63ce4a907..1003e81b5 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/migrations/RegistrationPinV2MigrationJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/migrations/RegistrationPinV2MigrationJob.java @@ -13,7 +13,6 @@ import org.thoughtcrime.securesms.keyvalue.KbsValues; import org.thoughtcrime.securesms.keyvalue.SignalStore; import org.thoughtcrime.securesms.lock.PinHashing; import org.thoughtcrime.securesms.logging.Log; -import org.thoughtcrime.securesms.util.FeatureFlags; import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.whispersystems.signalservice.api.KeyBackupService; import org.whispersystems.signalservice.api.KeyBackupServicePinException; @@ -23,6 +22,7 @@ import org.whispersystems.signalservice.api.kbs.MasterKey; import org.whispersystems.signalservice.internal.contacts.crypto.UnauthenticatedResponseException; import java.io.IOException; +import java.util.concurrent.TimeUnit; /** * Deliberately not a {@link MigrationJob} because it is not something that needs to run at app start. @@ -41,6 +41,7 @@ public final class RegistrationPinV2MigrationJob extends BaseJob { .addConstraint(NetworkConstraint.KEY) .setLifespan(Job.Parameters.IMMORTAL) .setMaxAttempts(Job.Parameters.UNLIMITED) + .setMaxBackoff(TimeUnit.HOURS.toMillis(2)) .build()); } @@ -55,11 +56,6 @@ public final class RegistrationPinV2MigrationJob extends BaseJob { @Override protected void onRun() throws IOException, UnauthenticatedResponseException, KeyBackupServicePinException { - if (!FeatureFlags.kbs()) { - Log.i(TAG, "Not migrating pin to KBS"); - return; - } - if (!TextSecurePreferences.isV1RegistrationLockEnabled(context)) { Log.i(TAG, "Registration lock disabled"); return; diff --git a/app/src/main/java/org/thoughtcrime/securesms/registration/service/CodeVerificationRequest.java b/app/src/main/java/org/thoughtcrime/securesms/registration/service/CodeVerificationRequest.java index 66ab07b67..3e7634f04 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/registration/service/CodeVerificationRequest.java +++ b/app/src/main/java/org/thoughtcrime/securesms/registration/service/CodeVerificationRequest.java @@ -27,7 +27,6 @@ import org.thoughtcrime.securesms.push.AccountManagerFactory; import org.thoughtcrime.securesms.recipients.RecipientId; import org.thoughtcrime.securesms.service.DirectoryRefreshListener; import org.thoughtcrime.securesms.service.RotateSignedPreKeyListener; -import org.thoughtcrime.securesms.util.FeatureFlags; import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.whispersystems.libsignal.IdentityKeyPair; import org.whispersystems.libsignal.state.PreKeyRecord; @@ -55,7 +54,6 @@ public final class CodeVerificationRequest { static TokenResponse getToken(@Nullable String basicStorageCredentials) throws IOException { if (basicStorageCredentials == null) return null; - if (!FeatureFlags.kbs()) return null; return ApplicationDependencies.getKeyBackupService().getToken(basicStorageCredentials); } @@ -214,10 +212,8 @@ public final class CodeVerificationRequest { //noinspection deprecation Only acceptable place to write the old pin enabled state. TextSecurePreferences.setV1RegistrationLockEnabled(context, pin != null); if (pin != null) { - if (FeatureFlags.kbs()) { - Log.i(TAG, "Pin V1 successfully entered during registration, scheduling a migration to Pin V2"); - ApplicationDependencies.getJobManager().add(new RegistrationPinV2MigrationJob()); - } + Log.i(TAG, "Pin V1 successfully entered during registration, scheduling a migration to Pin V2"); + ApplicationDependencies.getJobManager().add(new RegistrationPinV2MigrationJob()); } } else { SignalStore.kbsValues().setRegistrationLockMasterKey(kbsData, PinHashing.localPinHash(pin)); @@ -230,8 +226,6 @@ public final class CodeVerificationRequest { } private static void repostPinToResetTries(@NonNull Context context, @Nullable String pin, @NonNull RegistrationLockData kbsData) { - if (!FeatureFlags.kbs()) return; - if (pin == null) return; KeyBackupService keyBackupService = ApplicationDependencies.getKeyBackupService(); @@ -264,11 +258,6 @@ public final class CodeVerificationRequest { return null; } - if (!FeatureFlags.kbs()) { - Log.w(TAG, "User appears to have a KBS pin, but this build has KBS off."); - return null; - } - KeyBackupService keyBackupService = ApplicationDependencies.getKeyBackupService(); Log.i(TAG, "Opening key backup service session"); diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/FeatureFlags.java b/app/src/main/java/org/thoughtcrime/securesms/util/FeatureFlags.java index f6174aeeb..dc4d6df1e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/FeatureFlags.java +++ b/app/src/main/java/org/thoughtcrime/securesms/util/FeatureFlags.java @@ -40,7 +40,6 @@ public final class FeatureFlags { private static final String PROFILE_DISPLAY = generateKey("profileDisplay"); private static final String MESSAGE_REQUESTS = generateKey("messageRequests"); private static final String USERNAMES = generateKey("usernames"); - private static final String KBS = generateKey("kbs"); private static final String STORAGE_SERVICE = generateKey("storageService"); private static final String REACTION_SENDING = generateKey("reactionSending"); @@ -54,7 +53,6 @@ public final class FeatureFlags { put(PROFILE_DISPLAY, false); put(MESSAGE_REQUESTS, false); put(USERNAMES, false); - put(KBS, false); put(STORAGE_SERVICE, false); }}; @@ -105,16 +103,9 @@ public final class FeatureFlags { return value; } - /** Set or migrate PIN to KBS */ - public static boolean kbs() { - return getValue(KBS, false); - } - - /** Storage service. Requires {@link #kbs()}. */ + /** Storage service. */ public static boolean storageService() { - boolean value = getValue(STORAGE_SERVICE, false); - if (value && !kbs()) throw new MissingFlagRequirementError(); - return value; + return getValue(STORAGE_SERVICE, false); } /** Send support for reactions. */ diff --git a/app/src/test/resources/data/kbs_pin_normalization_vectors.json b/app/src/test/resources/data/kbs_pin_normalization_vectors.json index 33a5ba68b..317f2e9b7 100644 --- a/app/src/test/resources/data/kbs_pin_normalization_vectors.json +++ b/app/src/test/resources/data/kbs_pin_normalization_vectors.json @@ -53,6 +53,16 @@ "pin": "١٢٣٤٥A", "bytes": "d9a1d9a2d9a3d9a4d9a541" }, + { + "name": "Leading and trailing spaces around non-arabic digits", + "pin": " ١٢٣٤٥ ", + "bytes": "3132333435" + }, + { + "name": "Space in non-arabic digits", + "pin": "١٢٣ ٤٥٦", + "bytes": "d9a1d9a2d9a320d9a4d9a5d9a6" + }, { "name": "NFKD Test, Double Char", "pin": "Ä", diff --git a/app/src/test/resources/data/kbs_vectors.json b/app/src/test/resources/data/kbs_vectors.json index c4522e6d5..cd5c3cc48 100644 --- a/app/src/test/resources/data/kbs_vectors.json +++ b/app/src/test/resources/data/kbs_vectors.json @@ -1,20 +1,38 @@ [ - { - "pin":"password", - "backup_id":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", - "argon2_hash":"44652df80490fc66bb864a9e638b2f7dc9e20649671dd66bbb9c37bee2bfecf1ab7e8499d21f80a6600b3b9ee349ac6d72c07e3359fe885a934ba7aa844429f8", - "master_key":"202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", - "kbs_access_key":"ab7e8499d21f80a6600b3b9ee349ac6d72c07e3359fe885a934ba7aa844429f8", - "iv_and_cipher":"3f33ce58eb25b40436592a30eae2a8fabab1899095f4e2fba6e2d0dc43b4a2d9cac5a3931748522393951e0e54dec769", - "registration_lock":"2bf7988224ba35d3554966c65e8dc8c54974b034bdd44cabfd3f15fdb185e3c6" - }, - { - "pin":"anotherpassword", - "backup_id":"202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", - "argon2_hash":"b6f16aa0591732e339b7e99cdd5fd6586a1c285c9d66876947fd82f66ed99757301d9dd1e96f20ce51083f67d3298fd37b97525de8324d5e12ed2d407d3d927b", - "master_key":"88a787415a2ecd79da0d1016a82a27c5c695c9a19b88b0aa1d35683280aa9a67", - "kbs_access_key":"301d9dd1e96f20ce51083f67d3298fd37b97525de8324d5e12ed2d407d3d927b", - "iv_and_cipher":"9d9b05402ea39c17ff1c9298c8a0e86784a352aa02a74943bf8bcf07ec0f4b574a5b786ad0182c8d308d9eb06538b8c9", - "registration_lock":"4a458afa1b07493b23ee9b3f287b70416b2388ca39b5b8c27b4b7585bf73f413" - } + { + "pin": "password", + "backup_id": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "argon2_hash": "44652df80490fc66bb864a9e638b2f7dc9e20649671dd66bbb9c37bee2bfecf1ab7e8499d21f80a6600b3b9ee349ac6d72c07e3359fe885a934ba7aa844429f8", + "master_key": "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "kbs_access_key": "ab7e8499d21f80a6600b3b9ee349ac6d72c07e3359fe885a934ba7aa844429f8", + "iv_and_cipher": "3f33ce58eb25b40436592a30eae2a8fabab1899095f4e2fba6e2d0dc43b4a2d9cac5a3931748522393951e0e54dec769", + "registration_lock": "2bf7988224ba35d3554966c65e8dc8c54974b034bdd44cabfd3f15fdb185e3c6" + }, + { + "pin": "anotherpassword", + "backup_id": "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "argon2_hash": "b6f16aa0591732e339b7e99cdd5fd6586a1c285c9d66876947fd82f66ed99757301d9dd1e96f20ce51083f67d3298fd37b97525de8324d5e12ed2d407d3d927b", + "master_key": "88a787415a2ecd79da0d1016a82a27c5c695c9a19b88b0aa1d35683280aa9a67", + "kbs_access_key": "301d9dd1e96f20ce51083f67d3298fd37b97525de8324d5e12ed2d407d3d927b", + "iv_and_cipher": "9d9b05402ea39c17ff1c9298c8a0e86784a352aa02a74943bf8bcf07ec0f4b574a5b786ad0182c8d308d9eb06538b8c9", + "registration_lock": "4a458afa1b07493b23ee9b3f287b70416b2388ca39b5b8c27b4b7585bf73f413" + }, + { + "pin": " Pass६örd ", + "backup_id": "cba811749042b303a6a7efa5ccd160aea5e3ea243c8d2692bd13d515732f51a8", + "argon2_hash": "54853336a666eb66fbe8eb7a224b3ad3f457991ed74895b22ea9c6a4a46eda40ab645acdccc1652a48a34b2ac6926340ff35c03034013f68760f20013f028dd8", + "master_key": "9571f3fde1e58588ba49bcf82be1b301ca3859a6f59076f79a8f47181ef952bf", + "kbs_access_key": "ab645acdccc1652a48a34b2ac6926340ff35c03034013f68760f20013f028dd8", + "iv_and_cipher": "11c0ba1834db15e47c172f6c987c64bd4cfc69c6047dd67a022afeec0165a10943f204d5b8f37b3cb7bab21c6dfc39c8", + "registration_lock": "577939bccb2b6638c39222d5a97998a867c5e154e30b82cc120f2dd07a3de987" + }, + { + "pin": " ६१८ ", + "backup_id": "717dc111a98423a57196512606822fca646c653facd037c10728f14ba0be2ab3", + "argon2_hash": "8e9082faa57488f9ef98a6423c416a9974fb4d7c6bfc5b4f24de8e93afea199cd2fedabd0d4c17a371491c9722578843a26be3b4923e28d452ab2fc5491e794b", + "master_key": "0432d735b32f66d0e3a70d4f9cc821a8529521a4937d26b987715d8eff4e4c54", + "kbs_access_key": "d2fedabd0d4c17a371491c9722578843a26be3b4923e28d452ab2fc5491e794b", + "iv_and_cipher": "877ef871ef1fc668401c717ef21aa12e8523579fb1ff4474b76f28c2293537c80cc7569996c9e0229bea7f378e3a824e", + "registration_lock": "23a75cb1df1a87df45cc2ed167c2bdc85ab1220b847c88761b0005cac907fce5" + } ] \ No newline at end of file diff --git a/app/witness-verifications.gradle b/app/witness-verifications.gradle index 661385ace..d1247974b 100644 --- a/app/witness-verifications.gradle +++ b/app/witness-verifications.gradle @@ -351,8 +351,8 @@ dependencyVerification { ['org.signal:android-database-sqlcipher:3.5.9-S3', '33d4063336893af00b9d68b418e7b290cace74c20ce8aacffddc0911010d3d73'], - ['org.signal:argon2:13.0', - '34709776041840533a15e79d8abc4ebce6d0aa99bf8d39bd4202ef5791296f72'], + ['org.signal:argon2:13.1', + '0f686ccff0d4842bfcc74d92e8dc780a5f159b9376e37a1189fabbcdac458bef'], ['org.signal:ringrtc-android:0.3.1', '785c422a2322f810141d85f63eab3874961b19face886daaf140ab011d39e166'],