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