That fuck shit the fascists are using
at master 91 lines 3.2 kB view raw
1package org.tm.archive.crypto; 2 3 4import android.content.Context; 5import android.os.Build; 6 7import androidx.annotation.NonNull; 8 9import org.tm.archive.util.TextSecurePreferences; 10 11import java.io.IOException; 12import java.security.SecureRandom; 13 14/** 15 * It can be rather expensive to read from the keystore, so this class caches the key in memory 16 * after it is created. 17 */ 18public final class DatabaseSecretProvider { 19 20 private static volatile DatabaseSecret instance; 21 22 public static DatabaseSecret getOrCreateDatabaseSecret(@NonNull Context context) { 23 if (instance == null) { 24 synchronized (DatabaseSecretProvider.class) { 25 if (instance == null) { 26 instance = getOrCreate(context); 27 } 28 } 29 } 30 31 return instance; 32 } 33 34 private DatabaseSecretProvider() { 35 } 36 37 private static @NonNull DatabaseSecret getOrCreate(@NonNull Context context) { 38 String unencryptedSecret = TextSecurePreferences.getDatabaseUnencryptedSecret(context); 39 String encryptedSecret = TextSecurePreferences.getDatabaseEncryptedSecret(context); 40 41 if (unencryptedSecret != null) return getUnencryptedDatabaseSecret(context, unencryptedSecret); 42 else if (encryptedSecret != null) return getEncryptedDatabaseSecret(encryptedSecret); 43 else return createAndStoreDatabaseSecret(context); 44 } 45 46 private static @NonNull DatabaseSecret getUnencryptedDatabaseSecret(@NonNull Context context, @NonNull String unencryptedSecret) 47 { 48 try { 49 DatabaseSecret databaseSecret = new DatabaseSecret(unencryptedSecret); 50 51 if (Build.VERSION.SDK_INT < 23) { 52 return databaseSecret; 53 } else { 54 KeyStoreHelper.SealedData encryptedSecret = KeyStoreHelper.seal(databaseSecret.asBytes()); 55 56 TextSecurePreferences.setDatabaseEncryptedSecret(context, encryptedSecret.serialize()); 57 TextSecurePreferences.setDatabaseUnencryptedSecret(context, null); 58 59 return databaseSecret; 60 } 61 } catch (IOException e) { 62 throw new AssertionError(e); 63 } 64 } 65 66 private static @NonNull DatabaseSecret getEncryptedDatabaseSecret(@NonNull String serializedEncryptedSecret) { 67 if (Build.VERSION.SDK_INT < 23) { 68 throw new AssertionError("OS downgrade not supported. KeyStore sealed data exists on platform < M!"); 69 } else { 70 KeyStoreHelper.SealedData encryptedSecret = KeyStoreHelper.SealedData.fromString(serializedEncryptedSecret); 71 return new DatabaseSecret(KeyStoreHelper.unseal(encryptedSecret)); 72 } 73 } 74 75 private static @NonNull DatabaseSecret createAndStoreDatabaseSecret(@NonNull Context context) { 76 SecureRandom random = new SecureRandom(); 77 byte[] secret = new byte[32]; 78 random.nextBytes(secret); 79 80 DatabaseSecret databaseSecret = new DatabaseSecret(secret); 81 82 if (Build.VERSION.SDK_INT >= 23) { 83 KeyStoreHelper.SealedData encryptedSecret = KeyStoreHelper.seal(databaseSecret.asBytes()); 84 TextSecurePreferences.setDatabaseEncryptedSecret(context, encryptedSecret.serialize()); 85 } else { 86 TextSecurePreferences.setDatabaseUnencryptedSecret(context, databaseSecret.asString()); 87 } 88 89 return databaseSecret; 90 } 91}