That fuck shit the fascists are using
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}