Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added fallback mechanism for android #610

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 22 additions & 1 deletion KeychainExample/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import SegmentedControlTab from 'react-native-segmented-control-tab';
import * as Keychain from 'react-native-keychain';

const ACCESS_CONTROL_OPTIONS = ['None', 'Passcode', 'Password'];
const ACCESS_CONTROL_OPTIONS_ANDROID = ['None'];
const ACCESS_CONTROL_OPTIONS_ANDROID = ['None', 'Fallback'];
const ACCESS_CONTROL_MAP = [
null,
Keychain.ACCESS_CONTROL.DEVICE_PASSCODE,
Expand All @@ -22,6 +22,7 @@ const ACCESS_CONTROL_MAP = [
];
const ACCESS_CONTROL_MAP_ANDROID = [
null,
Keychain.ACCESS_CONTROL.BIOMETRY_ANY_OR_DEVICE_PASSCODE,
Keychain.ACCESS_CONTROL.BIOMETRY_CURRENT_SET,
];
const SECURITY_LEVEL_OPTIONS = ['Any', 'Software', 'Hardware'];
Expand All @@ -39,6 +40,13 @@ const SECURITY_STORAGE_MAP = [
Keychain.STORAGE_TYPE.RSA,
];

const ACCESS_CTRL_TO_AUTH_TYPE = {
[Keychain.ACCESS_CONTROL.BIOMETRY_ANY]:
Keychain.AUTHENTICATION_TYPE.BIOMETRICS,
[Keychain.ACCESS_CONTROL.BIOMETRY_ANY_OR_DEVICE_PASSCODE]:
Keychain.AUTHENTICATION_TYPE.DEVICE_PASSCODE_OR_BIOMETRICS,
};

export default class KeychainExample extends Component {
state = {
username: '',
Expand Down Expand Up @@ -94,6 +102,18 @@ export default class KeychainExample extends Component {
cancel: 'Cancel',
},
};
if (this.state.accessControl) {
options.authenticationType =
ACCESS_CTRL_TO_AUTH_TYPE[this.state.accessControl];
options.accessControl = this.state.accessControl;
}
if (
Platform.OS === 'android' &&
options.authenticationType ===
Keychain.AUTHENTICATION_TYPE.DEVICE_PASSCODE_OR_BIOMETRICS
) {
options.authenticationPrompt.cancel = '';
}
const credentials = await Keychain.getGenericPassword(options);
if (credentials) {
this.setState({ ...credentials, status: 'Credentials loaded!' });
Expand Down Expand Up @@ -340,6 +360,7 @@ const styles = StyleSheet.create({
fontWeight: '500',
fontSize: 15,
marginBottom: 5,
color: 'black',
},
input: {
color: '#000',
Expand Down
14 changes: 13 additions & 1 deletion android/src/main/java/com/oblador/keychain/KeychainModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ public class KeychainModule extends ReactContextBaseJavaModule {
public static final String IRIS_SUPPORTED_NAME = "Iris";
public static final String EMPTY_STRING = "";
public static final String WARMING_UP_ALIAS = "warmingUp";
public static final String AUTHENTICATION_TYPE = "authenticationType";

private static final String LOG_TAG = KeychainModule.class.getSimpleName();

Expand All @@ -74,6 +75,13 @@ public class KeychainModule extends ReactContextBaseJavaModule {
String BIOMETRY_CURRENT_SET_OR_DEVICE_PASSCODE = "BiometryCurrentSetOrDevicePasscode";
}

@StringDef({AuthenticateType.BIOMETRICS
, AuthenticateType.DEVICE_PASSCODE_OR_BIOMETRICS})
@interface AuthenticateType {
String DEVICE_PASSCODE_OR_BIOMETRICS = "AuthenticationWithBiometricsDevicePasscode";
String BIOMETRICS = "AuthenticationWithBiometrics";
}

@interface AuthPromptOptions {
String TITLE = "title";
String SUBTITLE = "subtitle";
Expand Down Expand Up @@ -618,7 +626,11 @@ private static PromptInfo getPromptInfo(@Nullable final ReadableMap options) {
}

/* PromptInfo is only used in Biometric-enabled RSA storage and can only be unlocked by a strong biometric */
promptInfoBuilder.setAllowedAuthenticators(BiometricManager.Authenticators.BIOMETRIC_STRONG);
int allowedAuthenticators = BiometricManager.Authenticators.BIOMETRIC_STRONG;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R && options.hasKey(AUTHENTICATION_TYPE) && options.getString(AUTHENTICATION_TYPE).equals(AuthenticateType.DEVICE_PASSCODE_OR_BIOMETRICS)) {
allowedAuthenticators = BiometricManager.Authenticators.BIOMETRIC_STRONG | BiometricManager.Authenticators.DEVICE_CREDENTIAL;
}
promptInfoBuilder.setAllowedAuthenticators(allowedAuthenticators);

/* Bypass confirmation to avoid KeyStore unlock timeout being exceeded when using passive biometrics */
promptInfoBuilder.setConfirmationRequired(false);
Expand Down