• 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.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