That fuck shit the fascists are using
at master 104 lines 4.1 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.security.SecureRandom; 12 13/** 14 * A provider that is responsible for creating or retrieving the AttachmentSecret model. 15 * 16 * On modern Android, the serialized secrets are themselves encrypted using a key that lives 17 * in the system KeyStore, for whatever that is worth. 18 */ 19public class AttachmentSecretProvider { 20 21 private static AttachmentSecretProvider provider; 22 23 public static synchronized AttachmentSecretProvider getInstance(@NonNull Context context) { 24 if (provider == null) provider = new AttachmentSecretProvider(context.getApplicationContext()); 25 return provider; 26 } 27 28 private final Context context; 29 30 private AttachmentSecret attachmentSecret; 31 32 private AttachmentSecretProvider(@NonNull Context context) { 33 this.context = context.getApplicationContext(); 34 } 35 36 public synchronized AttachmentSecret getOrCreateAttachmentSecret() { 37 if (attachmentSecret != null) return attachmentSecret; 38 39 String unencryptedSecret = TextSecurePreferences.getAttachmentUnencryptedSecret(context); 40 String encryptedSecret = TextSecurePreferences.getAttachmentEncryptedSecret(context); 41 42 if (unencryptedSecret != null) attachmentSecret = getUnencryptedAttachmentSecret(context, unencryptedSecret); 43 else if (encryptedSecret != null) attachmentSecret = getEncryptedAttachmentSecret(encryptedSecret); 44 else attachmentSecret = createAndStoreAttachmentSecret(context); 45 46 return attachmentSecret; 47 } 48 49 public synchronized AttachmentSecret setClassicKey(@NonNull Context context, @NonNull byte[] classicCipherKey, @NonNull byte[] classicMacKey) { 50 AttachmentSecret currentSecret = getOrCreateAttachmentSecret(); 51 currentSecret.setClassicCipherKey(classicCipherKey); 52 currentSecret.setClassicMacKey(classicMacKey); 53 54 storeAttachmentSecret(context, attachmentSecret); 55 56 return attachmentSecret; 57 } 58 59 private AttachmentSecret getUnencryptedAttachmentSecret(@NonNull Context context, @NonNull String unencryptedSecret) 60 { 61 AttachmentSecret attachmentSecret = AttachmentSecret.fromString(unencryptedSecret); 62 63 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { 64 return attachmentSecret; 65 } else { 66 KeyStoreHelper.SealedData encryptedSecret = KeyStoreHelper.seal(attachmentSecret.serialize().getBytes()); 67 68 TextSecurePreferences.setAttachmentEncryptedSecret(context, encryptedSecret.serialize()); 69 TextSecurePreferences.setAttachmentUnencryptedSecret(context, null); 70 71 return attachmentSecret; 72 } 73 } 74 75 private AttachmentSecret getEncryptedAttachmentSecret(@NonNull String serializedEncryptedSecret) { 76 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { 77 throw new AssertionError("OS downgrade not supported. KeyStore sealed data exists on platform < M!"); 78 } else { 79 KeyStoreHelper.SealedData encryptedSecret = KeyStoreHelper.SealedData.fromString(serializedEncryptedSecret); 80 return AttachmentSecret.fromString(new String(KeyStoreHelper.unseal(encryptedSecret))); 81 } 82 } 83 84 private AttachmentSecret createAndStoreAttachmentSecret(@NonNull Context context) { 85 SecureRandom random = new SecureRandom(); 86 byte[] secret = new byte[32]; 87 random.nextBytes(secret); 88 89 AttachmentSecret attachmentSecret = new AttachmentSecret(null, null, secret); 90 storeAttachmentSecret(context, attachmentSecret); 91 92 return attachmentSecret; 93 } 94 95 private void storeAttachmentSecret(@NonNull Context context, @NonNull AttachmentSecret attachmentSecret) { 96 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { 97 KeyStoreHelper.SealedData encryptedSecret = KeyStoreHelper.seal(attachmentSecret.serialize().getBytes()); 98 TextSecurePreferences.setAttachmentEncryptedSecret(context, encryptedSecret.serialize()); 99 } else { 100 TextSecurePreferences.setAttachmentUnencryptedSecret(context, attachmentSecret.serialize()); 101 } 102 } 103 104}