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.RemoteException; 22 import android.os.ServiceManager; 23 import android.os.ServiceSpecificException; 24 import android.os.StrictMode; 25 import android.security.maintenance.IKeystoreMaintenance; 26 import android.system.keystore2.Domain; 27 import android.system.keystore2.KeyDescriptor; 28 import android.system.keystore2.ResponseCode; 29 import android.util.Log; 30 31 /** 32 * @hide This is the client side for IKeystoreMaintenance AIDL. 33 * It is used mainly by LockSettingsService. 34 */ 35 public class AndroidKeyStoreMaintenance { 36 private static final String TAG = "AndroidKeyStoreMaintenance"; 37 38 public static final int SYSTEM_ERROR = ResponseCode.SYSTEM_ERROR; 39 public static final int INVALID_ARGUMENT = ResponseCode.INVALID_ARGUMENT; 40 public static final int PERMISSION_DENIED = ResponseCode.PERMISSION_DENIED; 41 public static final int KEY_NOT_FOUND = ResponseCode.KEY_NOT_FOUND; 42 getService()43 private static IKeystoreMaintenance getService() { 44 return IKeystoreMaintenance.Stub.asInterface( 45 ServiceManager.checkService("android.security.maintenance")); 46 } 47 48 /** 49 * Informs Keystore 2.0 about adding a user 50 * 51 * @param userId - Android user id of the user being added 52 * @return 0 if successful or a {@code ResponseCode} 53 * @hide 54 */ onUserAdded(int userId)55 public static int onUserAdded(int userId) { 56 StrictMode.noteDiskWrite(); 57 try { 58 getService().onUserAdded(userId); 59 return 0; 60 } catch (ServiceSpecificException e) { 61 Log.e(TAG, "onUserAdded failed", e); 62 return e.errorCode; 63 } catch (Exception e) { 64 Log.e(TAG, "Can not connect to keystore", e); 65 return SYSTEM_ERROR; 66 } 67 } 68 69 /** 70 * Tells Keystore to create a user's super keys and store them encrypted by the given secret. 71 * 72 * @param userId - Android user id of the user 73 * @param password - a secret derived from the user's synthetic password 74 * @param allowExisting - true if the keys already existing should not be considered an error 75 * @return 0 if successful or a {@code ResponseCode} 76 * @hide 77 */ initUserSuperKeys(int userId, @NonNull byte[] password, boolean allowExisting)78 public static int initUserSuperKeys(int userId, @NonNull byte[] password, 79 boolean allowExisting) { 80 StrictMode.noteDiskWrite(); 81 try { 82 getService().initUserSuperKeys(userId, password, allowExisting); 83 return 0; 84 } catch (ServiceSpecificException e) { 85 Log.e(TAG, "initUserSuperKeys failed", e); 86 return e.errorCode; 87 } catch (Exception e) { 88 Log.e(TAG, "Can not connect to keystore", e); 89 return SYSTEM_ERROR; 90 } 91 } 92 93 /** 94 * Informs Keystore 2.0 about removing a user 95 * 96 * @param userId - Android user id of the user being removed 97 * @return 0 if successful or a {@code ResponseCode} 98 * @hide 99 */ onUserRemoved(int userId)100 public static int onUserRemoved(int userId) { 101 StrictMode.noteDiskWrite(); 102 try { 103 getService().onUserRemoved(userId); 104 return 0; 105 } catch (ServiceSpecificException e) { 106 Log.e(TAG, "onUserRemoved failed", e); 107 return e.errorCode; 108 } catch (Exception e) { 109 Log.e(TAG, "Can not connect to keystore", e); 110 return SYSTEM_ERROR; 111 } 112 } 113 114 /** 115 * Informs Keystore 2.0 about changing user's password 116 * 117 * @param userId - Android user id of the user 118 * @param password - a secret derived from the synthetic password provided by the 119 * LockSettingsService 120 * @return 0 if successful or a {@code ResponseCode} 121 * @hide 122 */ onUserPasswordChanged(int userId, @Nullable byte[] password)123 public static int onUserPasswordChanged(int userId, @Nullable byte[] password) { 124 StrictMode.noteDiskWrite(); 125 try { 126 getService().onUserPasswordChanged(userId, password); 127 return 0; 128 } catch (ServiceSpecificException e) { 129 Log.e(TAG, "onUserPasswordChanged failed", e); 130 return e.errorCode; 131 } catch (Exception e) { 132 Log.e(TAG, "Can not connect to keystore", e); 133 return SYSTEM_ERROR; 134 } 135 } 136 137 /** 138 * Tells Keystore that a user's LSKF is being removed, ie the user's lock screen is changing to 139 * Swipe or None. Keystore uses this notification to delete the user's auth-bound keys. 140 * 141 * @param userId - Android user id of the user 142 * @return 0 if successful or a {@code ResponseCode} 143 * @hide 144 */ onUserLskfRemoved(int userId)145 public static int onUserLskfRemoved(int userId) { 146 StrictMode.noteDiskWrite(); 147 try { 148 getService().onUserLskfRemoved(userId); 149 return 0; 150 } catch (ServiceSpecificException e) { 151 Log.e(TAG, "onUserLskfRemoved failed", e); 152 return e.errorCode; 153 } catch (Exception e) { 154 Log.e(TAG, "Can not connect to keystore", e); 155 return SYSTEM_ERROR; 156 } 157 } 158 159 /** 160 * Informs Keystore 2.0 that an app was uninstalled and the corresponding namespace is to 161 * be cleared. 162 */ clearNamespace(@omain int domain, long namespace)163 public static int clearNamespace(@Domain int domain, long namespace) { 164 StrictMode.noteDiskWrite(); 165 try { 166 getService().clearNamespace(domain, namespace); 167 return 0; 168 } catch (ServiceSpecificException e) { 169 Log.e(TAG, "clearNamespace failed", e); 170 return e.errorCode; 171 } catch (Exception e) { 172 Log.e(TAG, "Can not connect to keystore", e); 173 return SYSTEM_ERROR; 174 } 175 } 176 177 /** 178 * Migrates a key given by the source descriptor to the location designated by the destination 179 * descriptor. 180 * 181 * @param source - The key to migrate may be specified by Domain.APP, Domain.SELINUX, or 182 * Domain.KEY_ID. The caller needs the permissions use, delete, and grant for the 183 * source namespace. 184 * @param destination - The new designation for the key may be specified by Domain.APP or 185 * Domain.SELINUX. The caller need the permission rebind for the destination 186 * namespace. 187 * 188 * @return * 0 on success 189 * * KEY_NOT_FOUND if the source did not exist. 190 * * PERMISSION_DENIED if any of the required permissions was missing. 191 * * INVALID_ARGUMENT if the destination was occupied or any domain value other than 192 * the allowed ones was specified. 193 * * SYSTEM_ERROR if an unexpected error occurred. 194 */ migrateKeyNamespace(KeyDescriptor source, KeyDescriptor destination)195 public static int migrateKeyNamespace(KeyDescriptor source, KeyDescriptor destination) { 196 StrictMode.noteDiskWrite(); 197 try { 198 getService().migrateKeyNamespace(source, destination); 199 return 0; 200 } catch (ServiceSpecificException e) { 201 Log.e(TAG, "migrateKeyNamespace failed", e); 202 return e.errorCode; 203 } catch (Exception e) { 204 Log.e(TAG, "Can not connect to keystore", e); 205 return SYSTEM_ERROR; 206 } 207 } 208 209 /** 210 * Returns the list of Application UIDs that have auth-bound keys that are bound to 211 * the given SID. This enables warning the user when they are about to invalidate 212 * a SID (for example, removing the LSKF). 213 * 214 * @param userId - The ID of the user the SID is associated with. 215 * @param userSecureId - The SID in question. 216 * 217 * @return A list of app UIDs. 218 */ getAllAppUidsAffectedBySid(int userId, long userSecureId)219 public static long[] getAllAppUidsAffectedBySid(int userId, long userSecureId) 220 throws KeyStoreException { 221 StrictMode.noteDiskWrite(); 222 try { 223 return getService().getAppUidsAffectedBySid(userId, userSecureId); 224 } catch (RemoteException | NullPointerException e) { 225 throw new KeyStoreException(SYSTEM_ERROR, 226 "Failure to connect to Keystore while trying to get apps affected by SID."); 227 } catch (ServiceSpecificException e) { 228 throw new KeyStoreException(e.errorCode, 229 "Keystore error while trying to get apps affected by SID."); 230 } 231 } 232 233 /** 234 * Deletes all keys in all KeyMint devices. 235 * Called by RecoverySystem before rebooting to recovery in order to delete all KeyMint keys, 236 * including synthetic password protector keys (used by LockSettingsService), as well as keys 237 * protecting DE and metadata encryption keys (used by vold). This ensures that FBE-encrypted 238 * data is unrecoverable even if the data wipe in recovery is interrupted or skipped. 239 */ deleteAllKeys()240 public static void deleteAllKeys() throws KeyStoreException { 241 StrictMode.noteDiskWrite(); 242 try { 243 getService().deleteAllKeys(); 244 } catch (RemoteException | NullPointerException e) { 245 throw new KeyStoreException(SYSTEM_ERROR, 246 "Failure to connect to Keystore while trying to delete all keys."); 247 } catch (ServiceSpecificException e) { 248 throw new KeyStoreException(e.errorCode, 249 "Keystore error while trying to delete all keys."); 250 } 251 } 252 } 253