mirror of
https://github.com/bitwarden/android.git
synced 2025-12-10 09:56:45 -06:00
Add logging for Biometric errors (#5621)
This commit is contained in:
parent
1799d0b716
commit
3c0818232f
@ -7,6 +7,7 @@ import com.bitwarden.annotation.OmitFromCoverage
|
||||
import com.x8bit.bitwarden.BuildConfig
|
||||
import com.x8bit.bitwarden.data.auth.datasource.disk.AuthDiskSource
|
||||
import com.x8bit.bitwarden.data.platform.datasource.disk.SettingsDiskSource
|
||||
import timber.log.Timber
|
||||
import java.security.InvalidAlgorithmParameterException
|
||||
import java.security.InvalidKeyException
|
||||
import java.security.KeyStore
|
||||
@ -45,9 +46,11 @@ class BiometricsEncryptionManagerImpl(
|
||||
}
|
||||
val cipher = try {
|
||||
Cipher.getInstance(CIPHER_TRANSFORMATION)
|
||||
} catch (_: NoSuchAlgorithmException) {
|
||||
} catch (nsae: NoSuchAlgorithmException) {
|
||||
Timber.w(nsae, "createCipherOrNull failed to get cipher instance")
|
||||
return null
|
||||
} catch (_: NoSuchPaddingException) {
|
||||
} catch (nspe: NoSuchPaddingException) {
|
||||
Timber.w(nspe, "createCipherOrNull failed to get cipher instance")
|
||||
return null
|
||||
}
|
||||
// Instantiate integrity values.
|
||||
@ -124,20 +127,25 @@ class BiometricsEncryptionManagerImpl(
|
||||
private fun generateKeyOrNull(userId: String): SecretKey? {
|
||||
val keyGen = try {
|
||||
KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, ENCRYPTION_KEYSTORE_NAME)
|
||||
} catch (_: NoSuchAlgorithmException) {
|
||||
} catch (nsae: NoSuchAlgorithmException) {
|
||||
Timber.w(nsae, "generateKeyOrNull failed to get key generator instance")
|
||||
return null
|
||||
} catch (_: NoSuchProviderException) {
|
||||
} catch (nspe: NoSuchProviderException) {
|
||||
Timber.w(nspe, "generateKeyOrNull failed to get key generator instance")
|
||||
return null
|
||||
} catch (_: IllegalArgumentException) {
|
||||
} catch (iae: IllegalArgumentException) {
|
||||
Timber.w(iae, "generateKeyOrNull failed to get key generator instance")
|
||||
return null
|
||||
}
|
||||
|
||||
return try {
|
||||
keyGen.init(getKeyGenParameterSpec(userId = userId))
|
||||
keyGen.generateKey()
|
||||
} catch (_: InvalidAlgorithmParameterException) {
|
||||
} catch (iape: InvalidAlgorithmParameterException) {
|
||||
Timber.w(iape, "generateKeyOrNull failed to initialize and generate key")
|
||||
null
|
||||
} catch (_: ProviderException) {
|
||||
} catch (pe: ProviderException) {
|
||||
Timber.w(pe, "generateKeyOrNull failed to initialize and generate key")
|
||||
null
|
||||
}
|
||||
}
|
||||
@ -150,14 +158,17 @@ class BiometricsEncryptionManagerImpl(
|
||||
keystore
|
||||
.getKey(encryptionKeyName(userId = userId), null)
|
||||
?.let { it as SecretKey }
|
||||
} catch (_: KeyStoreException) {
|
||||
} catch (kse: KeyStoreException) {
|
||||
// keystore was not loaded
|
||||
Timber.w(kse, "getSecretKeyOrNull failed to retrieve secret key")
|
||||
null
|
||||
} catch (_: NoSuchAlgorithmException) {
|
||||
} catch (nsae: NoSuchAlgorithmException) {
|
||||
// keystore algorithm cannot be found
|
||||
Timber.w(nsae, "getSecretKeyOrNull failed to retrieve secret key")
|
||||
null
|
||||
} catch (_: UnrecoverableKeyException) {
|
||||
} catch (uke: UnrecoverableKeyException) {
|
||||
// key could not be recovered
|
||||
Timber.w(uke, "getSecretKeyOrNull failed to retrieve secret key")
|
||||
null
|
||||
}
|
||||
|
||||
@ -174,16 +185,19 @@ class BiometricsEncryptionManagerImpl(
|
||||
?.let { init(Cipher.DECRYPT_MODE, secretKey, IvParameterSpec(it)) }
|
||||
?: init(Cipher.ENCRYPT_MODE, secretKey)
|
||||
true
|
||||
} catch (_: KeyPermanentlyInvalidatedException) {
|
||||
} catch (kpie: KeyPermanentlyInvalidatedException) {
|
||||
// Biometric has changed
|
||||
Timber.w(kpie, "initializeCipher failed to initialize cipher")
|
||||
destroyBiometrics(userId = userId)
|
||||
false
|
||||
} catch (_: UnrecoverableKeyException) {
|
||||
} catch (uke: UnrecoverableKeyException) {
|
||||
// Biometric was disabled and re-enabled
|
||||
Timber.w(uke, "initializeCipher failed to initialize cipher")
|
||||
destroyBiometrics(userId = userId)
|
||||
false
|
||||
} catch (_: InvalidKeyException) {
|
||||
} catch (ike: InvalidKeyException) {
|
||||
// User has no key
|
||||
Timber.w(ike, "initializeCipher failed to initialize cipher")
|
||||
destroyBiometrics(userId = userId)
|
||||
true
|
||||
}
|
||||
|
||||
@ -35,6 +35,8 @@ import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
import java.security.GeneralSecurityException
|
||||
import java.time.Instant
|
||||
import javax.crypto.Cipher
|
||||
|
||||
@ -501,9 +503,14 @@ class SettingsRepositoryImpl(
|
||||
.onSuccess { biometricsKey ->
|
||||
authDiskSource.storeUserBiometricUnlockKey(
|
||||
userId = userId,
|
||||
biometricsKey = cipher
|
||||
.doFinal(biometricsKey.encodeToByteArray())
|
||||
.toString(Charsets.ISO_8859_1),
|
||||
biometricsKey = try {
|
||||
cipher
|
||||
.doFinal(biometricsKey.encodeToByteArray())
|
||||
.toString(Charsets.ISO_8859_1)
|
||||
} catch (e: GeneralSecurityException) {
|
||||
Timber.w(e, "setupBiometricsKey failed encrypt the biometric key")
|
||||
return BiometricsKeyResult.Error(error = e)
|
||||
},
|
||||
)
|
||||
authDiskSource.storeUserBiometricInitVector(userId = userId, iv = cipher.iv)
|
||||
}
|
||||
|
||||
@ -121,6 +121,7 @@ import kotlinx.coroutines.flow.stateIn
|
||||
import kotlinx.coroutines.flow.update
|
||||
import kotlinx.coroutines.launch
|
||||
import retrofit2.HttpException
|
||||
import timber.log.Timber
|
||||
import java.security.GeneralSecurityException
|
||||
import java.time.Clock
|
||||
import java.time.temporal.ChronoUnit
|
||||
@ -572,6 +573,7 @@ class VaultRepositoryImpl(
|
||||
.doFinal(biometricsKey.toByteArray(Charsets.ISO_8859_1))
|
||||
.decodeToString()
|
||||
} catch (e: GeneralSecurityException) {
|
||||
Timber.w(e, "unlockVaultWithBiometrics failed when decrypting biometrics key")
|
||||
return VaultUnlockResult.BiometricDecodingError(error = e)
|
||||
}
|
||||
}
|
||||
@ -585,6 +587,7 @@ class VaultRepositoryImpl(
|
||||
.doFinal(biometricsKey.encodeToByteArray())
|
||||
.toString(Charsets.ISO_8859_1)
|
||||
} catch (e: GeneralSecurityException) {
|
||||
Timber.w(e, "unlockVaultWithBiometrics failed to migrate the user to IV encryption")
|
||||
return VaultUnlockResult.BiometricDecodingError(error = e)
|
||||
}
|
||||
} else {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user