@capgo/capacitor-native-biometric
Advanced tools
@@ -24,2 +24,3 @@ package ee.forgr.biometric; | ||
| import java.security.NoSuchAlgorithmException; | ||
| import java.security.ProviderException; | ||
| import java.security.UnrecoverableKeyException; | ||
@@ -216,2 +217,19 @@ import java.security.cert.CertificateException; | ||
| private void generateSecretKey() throws GeneralSecurityException { | ||
| try { | ||
| buildAuthKey(true); | ||
| } catch (ProviderException e) { | ||
| // Some OEM Keymaster/TEE implementations (notably Xiaomi/MIUI and Oppo/ColorOS) reject | ||
| // setInvalidatedByBiometricEnrollment(true) and throw a generic ProviderException | ||
| // ("Keystore key generation failed"). Retry once without that flag. | ||
| try { | ||
| buildAuthKey(false); | ||
| } catch (ProviderException retryError) { | ||
| // ProviderException is unchecked and would otherwise crash AuthActivity.onCreate. | ||
| // Convert it so callers handle it gracefully (return null -> error result). | ||
| throw new GeneralSecurityException("Keystore key generation failed", retryError); | ||
| } | ||
| } | ||
| } | ||
| private void buildAuthKey(boolean invalidatedByEnrollment) throws GeneralSecurityException { | ||
| KeyGenerator keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore"); | ||
@@ -235,3 +253,3 @@ KeyGenParameterSpec.Builder builder = new KeyGenParameterSpec.Builder( | ||
| if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { | ||
| if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P && invalidatedByEnrollment) { | ||
| builder.setInvalidatedByBiometricEnrollment(true); | ||
@@ -279,2 +297,22 @@ } | ||
| boolean invalidatedByEnrollment = Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && accessControl == 1; | ||
| try { | ||
| return buildCredentialKey(alias, invalidatedByEnrollment); | ||
| } catch (ProviderException e) { | ||
| // Xiaomi/MIUI and Oppo/ColorOS Keymasters may reject setInvalidatedByBiometricEnrollment(true) | ||
| // with a generic ProviderException. Retry without it when it was requested. | ||
| if (invalidatedByEnrollment) { | ||
| try { | ||
| return buildCredentialKey(alias, false); | ||
| } catch (ProviderException retryError) { | ||
| throw new GeneralSecurityException("Keystore key generation failed", retryError); | ||
| } | ||
| } | ||
| // ProviderException is unchecked; convert it so callers handle it gracefully | ||
| // (return null -> error result) instead of crashing AuthActivity.onCreate. | ||
| throw new GeneralSecurityException("Keystore key generation failed", e); | ||
| } | ||
| } | ||
| private SecretKey buildCredentialKey(String alias, boolean invalidatedByEnrollment) throws GeneralSecurityException { | ||
| KeyGenerator keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore"); | ||
@@ -297,3 +335,3 @@ KeyGenParameterSpec.Builder builder = new KeyGenParameterSpec.Builder( | ||
| if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { | ||
| builder.setInvalidatedByBiometricEnrollment(accessControl == 1); | ||
| builder.setInvalidatedByBiometricEnrollment(invalidatedByEnrollment); | ||
| } | ||
@@ -300,0 +338,0 @@ |
@@ -14,3 +14,3 @@ import Foundation | ||
| public class NativeBiometricPlugin: CAPPlugin, CAPBridgedPlugin { | ||
| private let pluginVersion: String = "8.4.9" | ||
| private let pluginVersion: String = "8.4.10" | ||
| public let identifier = "NativeBiometricPlugin" | ||
@@ -17,0 +17,0 @@ public let jsName = "NativeBiometric" |
+1
-1
| { | ||
| "name": "@capgo/capacitor-native-biometric", | ||
| "version": "8.4.9", | ||
| "version": "8.4.10", | ||
| "description": "This plugin gives access to the native biometric apis for android and iOS", | ||
@@ -5,0 +5,0 @@ "main": "dist/plugin.cjs.js", |
261664
0.81%3009
1.21%