fix: align session state across transitions
This commit is contained in:
+5
@@ -40,6 +40,11 @@ class AndroidKeystoreCredentialCipher(
|
||||
return cipher.doFinal(ciphertext)
|
||||
}
|
||||
|
||||
override fun resetPermanentlyInvalidatedKey() {
|
||||
val keyStore = KeyStore.getInstance(ANDROID_KEY_STORE).apply { load(null) }
|
||||
if (keyStore.containsAlias(keyAlias)) keyStore.deleteEntry(keyAlias)
|
||||
}
|
||||
|
||||
private fun secretKey(): SecretKey {
|
||||
val keyStore = KeyStore.getInstance(ANDROID_KEY_STORE).apply { load(null) }
|
||||
(keyStore.getKey(keyAlias, null) as? SecretKey)?.let { return it }
|
||||
|
||||
+2
@@ -6,4 +6,6 @@ interface CredentialCipher {
|
||||
fun encrypt(profileId: ProviderProfileId, plaintext: ByteArray): ByteArray
|
||||
|
||||
fun decrypt(profileId: ProviderProfileId, encrypted: ByteArray): ByteArray
|
||||
|
||||
fun resetPermanentlyInvalidatedKey()
|
||||
}
|
||||
|
||||
+6
@@ -46,6 +46,9 @@ class KeystoreCredentialStore(
|
||||
} catch (error: Exception) {
|
||||
if (error.isPermanentCredentialFailure()) {
|
||||
try {
|
||||
if (error.hasPermanentlyInvalidatedKey()) {
|
||||
cipher.resetPermanentlyInvalidatedKey()
|
||||
}
|
||||
dataStore.edit { it.remove(credentialKey(profileId)) }
|
||||
DomainResult.Success(null)
|
||||
} catch (cleanupError: CancellationException) {
|
||||
@@ -122,6 +125,9 @@ private fun DataInputStream.readByteArray(maxSize: Int): ByteArray {
|
||||
return ByteArray(length).also(::readFully)
|
||||
}
|
||||
|
||||
private fun Throwable.hasPermanentlyInvalidatedKey(): Boolean =
|
||||
this is KeyPermanentlyInvalidatedException || cause?.hasPermanentlyInvalidatedKey() == true
|
||||
|
||||
private fun Throwable.isPermanentCredentialFailure(): Boolean = when (this) {
|
||||
is AEADBadTagException,
|
||||
is KeyPermanentlyInvalidatedException,
|
||||
|
||||
+2
@@ -39,5 +39,7 @@ class CredentialCleanupFailureTest {
|
||||
override fun encrypt(profileId: ProviderProfileId, plaintext: ByteArray): ByteArray = plaintext
|
||||
|
||||
override fun decrypt(profileId: ProviderProfileId, encrypted: ByteArray): ByteArray = encrypted
|
||||
|
||||
override fun resetPermanentlyInvalidatedKey() = Unit
|
||||
}
|
||||
}
|
||||
|
||||
+4
@@ -69,6 +69,8 @@ class CredentialStoreTest {
|
||||
override fun decrypt(profileId: ProviderProfileId, encrypted: ByteArray): ByteArray {
|
||||
throw IllegalArgumentException("Credential payload is truncated")
|
||||
}
|
||||
|
||||
override fun resetPermanentlyInvalidatedKey() = Unit
|
||||
}
|
||||
|
||||
private class ReversingCipher : CredentialCipher {
|
||||
@@ -81,5 +83,7 @@ class CredentialStoreTest {
|
||||
require(decoded.copyOfRange(0, delimiter).decodeToString() == profileId.value)
|
||||
return decoded.copyOfRange(delimiter + 1, decoded.size)
|
||||
}
|
||||
|
||||
override fun resetPermanentlyInvalidatedKey() = Unit
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user