1 /* 2 * Copyright (C) 2020 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.security; 18 19 import android.annotation.NonNull; 20 import android.annotation.Nullable; 21 import android.hardware.biometrics.BiometricConstants; 22 import android.hardware.security.keymint.HardwareAuthToken; 23 import android.hardware.security.keymint.HardwareAuthenticatorType; 24 import android.os.RemoteException; 25 import android.os.ServiceManager; 26 import android.os.ServiceSpecificException; 27 import android.os.StrictMode; 28 import android.security.authorization.IKeystoreAuthorization; 29 import android.system.keystore2.ResponseCode; 30 import android.util.Log; 31 32 /** 33 * @hide This is the client side for IKeystoreAuthorization AIDL. 34 * It shall only be used by biometric authentication providers and Gatekeeper. 35 */ 36 public class KeyStoreAuthorization { 37 private static final String TAG = "KeyStoreAuthorization"; 38 39 public static final int SYSTEM_ERROR = ResponseCode.SYSTEM_ERROR; 40 41 private static final KeyStoreAuthorization sInstance = new KeyStoreAuthorization(); 42 getInstance()43 public static KeyStoreAuthorization getInstance() { 44 return sInstance; 45 } 46 47 /** 48 * @return an instance of IKeystoreAuthorization 49 */ getService()50 private IKeystoreAuthorization getService() { 51 return IKeystoreAuthorization.Stub.asInterface( 52 ServiceManager.checkService("android.security.authorization")); 53 } 54 55 /** 56 * Adds an auth token to keystore2. 57 * 58 * @param authToken created by Android authenticators. 59 * @return 0 if successful or {@code ResponseCode.SYSTEM_ERROR}. 60 */ addAuthToken(@onNull HardwareAuthToken authToken)61 public int addAuthToken(@NonNull HardwareAuthToken authToken) { 62 StrictMode.noteSlowCall("addAuthToken"); 63 try { 64 getService().addAuthToken(authToken); 65 return 0; 66 } catch (RemoteException | NullPointerException e) { 67 Log.w(TAG, "Can not connect to keystore", e); 68 return SYSTEM_ERROR; 69 } catch (ServiceSpecificException e) { 70 return e.errorCode; 71 } 72 } 73 74 /** 75 * Add an auth token to Keystore 2.0 in the legacy serialized auth token format. 76 * @param authToken 77 * @return 0 if successful or a {@code ResponseCode}. 78 */ addAuthToken(@onNull byte[] authToken)79 public int addAuthToken(@NonNull byte[] authToken) { 80 return addAuthToken(AuthTokenUtils.toHardwareAuthToken(authToken)); 81 } 82 83 /** 84 * Tells Keystore that the device is now unlocked for a user. 85 * 86 * @param userId - the user's Android user ID 87 * @param password - a secret derived from the user's synthetic password, if the unlock method 88 * is LSKF (or equivalent) and thus has made the synthetic password available 89 * @return 0 if successful or a {@code ResponseCode}. 90 */ onDeviceUnlocked(int userId, @Nullable byte[] password)91 public int onDeviceUnlocked(int userId, @Nullable byte[] password) { 92 StrictMode.noteDiskWrite(); 93 try { 94 getService().onDeviceUnlocked(userId, password); 95 return 0; 96 } catch (RemoteException | NullPointerException e) { 97 Log.w(TAG, "Can not connect to keystore", e); 98 return SYSTEM_ERROR; 99 } catch (ServiceSpecificException e) { 100 return e.errorCode; 101 } 102 } 103 104 /** 105 * Tells Keystore that the device is now locked for a user. 106 * 107 * @param userId - the user's Android user ID 108 * @param unlockingSids - list of biometric SIDs with which the device may be unlocked again 109 * @param weakUnlockEnabled - true if non-strong biometric or trust agent unlock is enabled 110 * @return 0 if successful or a {@code ResponseCode}. 111 */ onDeviceLocked(int userId, @NonNull long[] unlockingSids, boolean weakUnlockEnabled)112 public int onDeviceLocked(int userId, @NonNull long[] unlockingSids, 113 boolean weakUnlockEnabled) { 114 StrictMode.noteDiskWrite(); 115 try { 116 getService().onDeviceLocked(userId, unlockingSids, weakUnlockEnabled); 117 return 0; 118 } catch (RemoteException | NullPointerException e) { 119 Log.w(TAG, "Can not connect to keystore", e); 120 return SYSTEM_ERROR; 121 } catch (ServiceSpecificException e) { 122 return e.errorCode; 123 } 124 } 125 126 /** 127 * Gets the last authentication time of the given user and authenticators. 128 * 129 * @param userId user id 130 * @param authenticatorTypes an array of {@link HardwareAuthenticatorType}. 131 * @return the last authentication time or 132 * {@link BiometricConstants#BIOMETRIC_NO_AUTHENTICATION}. 133 */ getLastAuthTime(long userId, @HardwareAuthenticatorType int[] authenticatorTypes)134 public long getLastAuthTime(long userId, @HardwareAuthenticatorType int[] authenticatorTypes) { 135 try { 136 return getService().getLastAuthTime(userId, authenticatorTypes); 137 } catch (RemoteException | NullPointerException e) { 138 Log.w(TAG, "Error getting last auth time: " + e); 139 return BiometricConstants.BIOMETRIC_NO_AUTHENTICATION; 140 } catch (ServiceSpecificException e) { 141 // This is returned when the feature flag test fails in keystore2 142 if (e.errorCode == ResponseCode.PERMISSION_DENIED) { 143 throw new UnsupportedOperationException(); 144 } 145 return BiometricConstants.BIOMETRIC_NO_AUTHENTICATION; 146 } 147 } 148 149 } 150