1 /* 2 * Copyright (C) 2021 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.os.ServiceManager; 22 import android.os.ServiceSpecificException; 23 import android.security.maintenance.IKeystoreMaintenance; 24 import android.system.keystore2.Domain; 25 import android.system.keystore2.KeyDescriptor; 26 import android.system.keystore2.ResponseCode; 27 import android.util.Log; 28 29 /** 30 * @hide This is the client side for IKeystoreUserManager AIDL. 31 * It shall only be used by the LockSettingsService. 32 */ 33 public class AndroidKeyStoreMaintenance { 34 private static final String TAG = "AndroidKeyStoreMaintenance"; 35 36 public static final int SYSTEM_ERROR = ResponseCode.SYSTEM_ERROR; 37 public static final int INVALID_ARGUMENT = ResponseCode.INVALID_ARGUMENT; 38 public static final int PERMISSION_DENIED = ResponseCode.PERMISSION_DENIED; 39 public static final int KEY_NOT_FOUND = ResponseCode.KEY_NOT_FOUND; 40 getService()41 private static IKeystoreMaintenance getService() { 42 return IKeystoreMaintenance.Stub.asInterface( 43 ServiceManager.checkService("android.security.maintenance")); 44 } 45 46 /** 47 * Informs Keystore 2.0 about adding a user 48 * 49 * @param userId - Android user id of the user being added 50 * @return 0 if successful or a {@code ResponseCode} 51 * @hide 52 */ onUserAdded(@onNull int userId)53 public static int onUserAdded(@NonNull int userId) { 54 try { 55 getService().onUserAdded(userId); 56 return 0; 57 } catch (ServiceSpecificException e) { 58 Log.e(TAG, "onUserAdded failed", e); 59 return e.errorCode; 60 } catch (Exception e) { 61 Log.e(TAG, "Can not connect to keystore", e); 62 return SYSTEM_ERROR; 63 } 64 } 65 66 /** 67 * Informs Keystore 2.0 about removing a usergit mer 68 * 69 * @param userId - Android user id of the user being removed 70 * @return 0 if successful or a {@code ResponseCode} 71 * @hide 72 */ onUserRemoved(int userId)73 public static int onUserRemoved(int userId) { 74 try { 75 getService().onUserRemoved(userId); 76 return 0; 77 } catch (ServiceSpecificException e) { 78 Log.e(TAG, "onUserRemoved failed", e); 79 return e.errorCode; 80 } catch (Exception e) { 81 Log.e(TAG, "Can not connect to keystore", e); 82 return SYSTEM_ERROR; 83 } 84 } 85 86 /** 87 * Informs Keystore 2.0 about changing user's password 88 * 89 * @param userId - Android user id of the user 90 * @param password - a secret derived from the synthetic password provided by the 91 * LockSettingService 92 * @return 0 if successful or a {@code ResponseCode} 93 * @hide 94 */ onUserPasswordChanged(int userId, @Nullable byte[] password)95 public static int onUserPasswordChanged(int userId, @Nullable byte[] password) { 96 try { 97 getService().onUserPasswordChanged(userId, password); 98 return 0; 99 } catch (ServiceSpecificException e) { 100 Log.e(TAG, "onUserPasswordChanged failed", e); 101 return e.errorCode; 102 } catch (Exception e) { 103 Log.e(TAG, "Can not connect to keystore", e); 104 return SYSTEM_ERROR; 105 } 106 } 107 108 /** 109 * Informs Keystore 2.0 that an app was uninstalled and the corresponding namspace is to 110 * be cleared. 111 */ clearNamespace(@omain int domain, long namespace)112 public static int clearNamespace(@Domain int domain, long namespace) { 113 try { 114 getService().clearNamespace(domain, namespace); 115 return 0; 116 } catch (ServiceSpecificException e) { 117 Log.e(TAG, "clearNamespace failed", e); 118 return e.errorCode; 119 } catch (Exception e) { 120 Log.e(TAG, "Can not connect to keystore", e); 121 return SYSTEM_ERROR; 122 } 123 } 124 125 /** 126 * Queries user state from Keystore 2.0. 127 * 128 * @param userId - Android user id of the user. 129 * @return UserState enum variant as integer if successful or an error 130 */ getState(int userId)131 public static int getState(int userId) { 132 try { 133 return getService().getState(userId); 134 } catch (ServiceSpecificException e) { 135 Log.e(TAG, "getState failed", e); 136 return e.errorCode; 137 } catch (Exception e) { 138 Log.e(TAG, "Can not connect to keystore", e); 139 return SYSTEM_ERROR; 140 } 141 } 142 143 /** 144 * Informs Keystore 2.0 that an off body event was detected. 145 */ onDeviceOffBody()146 public static void onDeviceOffBody() { 147 try { 148 getService().onDeviceOffBody(); 149 } catch (Exception e) { 150 // TODO This fails open. This is not a regression with respect to keystore1 but it 151 // should get fixed. 152 Log.e(TAG, "Error while reporting device off body event.", e); 153 } 154 } 155 156 /** 157 * Migrates a key given by the source descriptor to the location designated by the destination 158 * descriptor. 159 * 160 * @param source - The key to migrate may be specified by Domain.APP, Domain.SELINUX, or 161 * Domain.KEY_ID. The caller needs the permissions use, delete, and grant for the 162 * source namespace. 163 * @param destination - The new designation for the key may be specified by Domain.APP or 164 * Domain.SELINUX. The caller need the permission rebind for the destination 165 * namespace. 166 * 167 * @return * 0 on success 168 * * KEY_NOT_FOUND if the source did not exists. 169 * * PERMISSION_DENIED if any of the required permissions was missing. 170 * * INVALID_ARGUMENT if the destination was occupied or any domain value other than 171 * the allowed once were specified. 172 * * SYSTEM_ERROR if an unexpected error occurred. 173 */ migrateKeyNamespace(KeyDescriptor source, KeyDescriptor destination)174 public static int migrateKeyNamespace(KeyDescriptor source, KeyDescriptor destination) { 175 try { 176 getService().migrateKeyNamespace(source, destination); 177 return 0; 178 } catch (ServiceSpecificException e) { 179 Log.e(TAG, "migrateKeyNamespace failed", e); 180 return e.errorCode; 181 } catch (Exception e) { 182 Log.e(TAG, "Can not connect to keystore", e); 183 return SYSTEM_ERROR; 184 } 185 } 186 } 187