mirror of
https://github.com/oxen-io/session-android.git
synced 2024-12-18 05:57:44 +00:00
Synchronize Cipher in KeystoreHelper
This commit is contained in:
commit
ba9dab33c5
@ -45,11 +45,16 @@ public final class KeyStoreHelper {
|
|||||||
private static final String ANDROID_KEY_STORE = "AndroidKeyStore";
|
private static final String ANDROID_KEY_STORE = "AndroidKeyStore";
|
||||||
private static final String KEY_ALIAS = "SignalSecret";
|
private static final String KEY_ALIAS = "SignalSecret";
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.M)
|
private static final Object lock = new Object();
|
||||||
|
|
||||||
public static SealedData seal(@NonNull byte[] input) {
|
public static SealedData seal(@NonNull byte[] input) {
|
||||||
SecretKey secretKey = getOrCreateKeyStoreEntry();
|
SecretKey secretKey = getOrCreateKeyStoreEntry();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
// Cipher operations are not thread-safe so we synchronize over them through doFinal to
|
||||||
|
// prevent crashes with quickly repeated encrypt/decrypt operations
|
||||||
|
// https://github.com/mozilla-mobile/android-components/issues/5342
|
||||||
|
synchronized (lock) {
|
||||||
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
|
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
|
||||||
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
|
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
|
||||||
|
|
||||||
@ -57,32 +62,35 @@ public final class KeyStoreHelper {
|
|||||||
byte[] data = cipher.doFinal(input);
|
byte[] data = cipher.doFinal(input);
|
||||||
|
|
||||||
return new SealedData(iv, data);
|
return new SealedData(iv, data);
|
||||||
|
}
|
||||||
} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException e) {
|
} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException e) {
|
||||||
throw new AssertionError(e);
|
throw new AssertionError(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.M)
|
|
||||||
public static byte[] unseal(@NonNull SealedData sealedData) {
|
public static byte[] unseal(@NonNull SealedData sealedData) {
|
||||||
SecretKey secretKey = getKeyStoreEntry();
|
SecretKey secretKey = getKeyStoreEntry();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
// Cipher operations are not thread-safe so we synchronize over them through doFinal to
|
||||||
|
// prevent crashes with quickly repeated encrypt/decrypt operations
|
||||||
|
// https://github.com/mozilla-mobile/android-components/issues/5342
|
||||||
|
synchronized (lock) {
|
||||||
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
|
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
|
||||||
cipher.init(Cipher.DECRYPT_MODE, secretKey, new GCMParameterSpec(128, sealedData.iv));
|
cipher.init(Cipher.DECRYPT_MODE, secretKey, new GCMParameterSpec(128, sealedData.iv));
|
||||||
|
|
||||||
return cipher.doFinal(sealedData.data);
|
return cipher.doFinal(sealedData.data);
|
||||||
|
}
|
||||||
} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | InvalidAlgorithmParameterException | IllegalBlockSizeException | BadPaddingException e) {
|
} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | InvalidAlgorithmParameterException | IllegalBlockSizeException | BadPaddingException e) {
|
||||||
throw new AssertionError(e);
|
throw new AssertionError(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.M)
|
|
||||||
private static SecretKey getOrCreateKeyStoreEntry() {
|
private static SecretKey getOrCreateKeyStoreEntry() {
|
||||||
if (hasKeyStoreEntry()) return getKeyStoreEntry();
|
if (hasKeyStoreEntry()) return getKeyStoreEntry();
|
||||||
else return createKeyStoreEntry();
|
else return createKeyStoreEntry();
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.M)
|
|
||||||
private static SecretKey createKeyStoreEntry() {
|
private static SecretKey createKeyStoreEntry() {
|
||||||
try {
|
try {
|
||||||
KeyGenerator keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, ANDROID_KEY_STORE);
|
KeyGenerator keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, ANDROID_KEY_STORE);
|
||||||
@ -99,7 +107,6 @@ public final class KeyStoreHelper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.M)
|
|
||||||
private static SecretKey getKeyStoreEntry() {
|
private static SecretKey getKeyStoreEntry() {
|
||||||
KeyStore keyStore = getKeyStore();
|
KeyStore keyStore = getKeyStore();
|
||||||
|
|
||||||
@ -137,7 +144,6 @@ public final class KeyStoreHelper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.M)
|
|
||||||
private static boolean hasKeyStoreEntry() {
|
private static boolean hasKeyStoreEntry() {
|
||||||
try {
|
try {
|
||||||
KeyStore ks = KeyStore.getInstance(ANDROID_KEY_STORE);
|
KeyStore ks = KeyStore.getInstance(ANDROID_KEY_STORE);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user