• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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