blob: ded427eb244a2425fafd903314920068091911d3 [file] [log] [blame]
Chia-chi Yeh44039172009-09-21 11:53:59 +08001/*
2 * Copyright (C) 2009 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
17package android.security;
18
Svetoslav2dac95d2015-04-30 11:30:33 -070019import android.app.ActivityThread;
20import android.app.Application;
Alex Klyubin54183932015-05-08 15:25:48 -070021import android.app.KeyguardManager;
Alex Klyubin708fc9402015-04-28 18:58:47 -070022import android.content.Context;
Kevin Chyn55966422017-10-23 16:08:47 -070023import android.content.pm.PackageManager;
Alex Klyubin2d7a85c2015-04-30 11:43:53 -070024import android.hardware.fingerprint.FingerprintManager;
Chad Brubakere6a461342015-02-10 21:33:23 -080025import android.os.Binder;
26import android.os.IBinder;
Chad Brubakera91a8502015-05-07 10:02:22 -070027import android.os.Process;
Kenny Root6b776452012-11-02 15:40:32 -070028import android.os.RemoteException;
29import android.os.ServiceManager;
Chad Brubakera91a8502015-05-07 10:02:22 -070030import android.os.UserHandle;
Chad Brubakere6a461342015-02-10 21:33:23 -080031import android.security.keymaster.ExportResult;
32import android.security.keymaster.KeyCharacteristics;
33import android.security.keymaster.KeymasterArguments;
Chad Brubaker5e73c0e2015-03-21 22:46:43 -070034import android.security.keymaster.KeymasterBlob;
Shawn Willden8d8c7472016-02-02 08:27:39 -070035import android.security.keymaster.KeymasterCertificateChain;
Alex Klyubinb4834ae2015-04-02 15:53:46 -070036import android.security.keymaster.KeymasterDefs;
Chad Brubakere6a461342015-02-10 21:33:23 -080037import android.security.keymaster.OperationResult;
Alex Klyubin3f8d4d82015-05-13 09:15:00 -070038import android.security.keystore.KeyExpiredException;
39import android.security.keystore.KeyNotYetValidException;
40import android.security.keystore.KeyPermanentlyInvalidatedException;
Frank Salimea5e0382018-01-23 22:42:29 -080041import android.security.keystore.StrongBoxUnavailableException;
Alex Klyubin3f8d4d82015-05-13 09:15:00 -070042import android.security.keystore.UserNotAuthenticatedException;
Kenny Root6b776452012-11-02 15:40:32 -070043import android.util.Log;
Chia-chi Yeh44039172009-09-21 11:53:59 +080044
Alex Klyubinae6cb7a2015-06-22 18:09:35 -070045import java.math.BigInteger;
Alex Klyubinad9ba102015-04-21 15:17:24 -070046import java.security.InvalidKeyException;
Alex Klyubin708fc9402015-04-28 18:58:47 -070047import java.util.List;
Kenny Rootb91773b2013-09-05 13:03:16 -070048import java.util.Locale;
49
Chia-chi Yeh44039172009-09-21 11:53:59 +080050/**
Brian Carlstrom46703b02011-04-06 15:41:29 -070051 * @hide This should not be made public in its present form because it
52 * assumes that private and secret key bytes are available and would
53 * preclude the use of hardware crypto.
Chia-chi Yeh44039172009-09-21 11:53:59 +080054 */
55public class KeyStore {
Kenny Root6b776452012-11-02 15:40:32 -070056 private static final String TAG = "KeyStore";
Brian Carlstrom5cfee3f2011-05-31 01:00:15 -070057
Dmitry Dementyevefc43112017-10-27 23:10:28 -070058 // ResponseCodes - see system/security/keystore/include/keystore/keystore.h
Brian Carlstrom7e4b1a42011-06-01 15:29:29 -070059 public static final int NO_ERROR = 1;
60 public static final int LOCKED = 2;
61 public static final int UNINITIALIZED = 3;
62 public static final int SYSTEM_ERROR = 4;
63 public static final int PROTOCOL_ERROR = 5;
64 public static final int PERMISSION_DENIED = 6;
65 public static final int KEY_NOT_FOUND = 7;
66 public static final int VALUE_CORRUPTED = 8;
67 public static final int UNDEFINED_ACTION = 9;
68 public static final int WRONG_PASSWORD = 10;
Frank Salimea5e0382018-01-23 22:42:29 -080069 public static final int HARDWARE_TYPE_UNAVAILABLE = -68;
Brian Carlstrom5cfee3f2011-05-31 01:00:15 -070070
Chad Brubaker560d6532015-04-24 10:32:18 -070071 /**
72 * Per operation authentication is needed before this operation is valid.
73 * This is returned from {@link #begin} when begin succeeds but the operation uses
74 * per-operation authentication and must authenticate before calling {@link #update} or
75 * {@link #finish}.
76 */
77 public static final int OP_AUTH_NEEDED = 15;
78
Kenny Root2eeda722013-04-10 11:30:58 -070079 // Used for UID field to indicate the calling UID.
80 public static final int UID_SELF = -1;
81
82 // Flags for "put" "import" and "generate"
83 public static final int FLAG_NONE = 0;
Alex Klyubin54183932015-05-08 15:25:48 -070084
85 /**
86 * Indicates that this key (or key pair) must be encrypted at rest. This will protect the key
87 * (or key pair) with the secure lock screen credential (e.g., password, PIN, or pattern).
88 *
89 * <p>Note that this requires that the secure lock screen (e.g., password, PIN, pattern) is set
90 * up, otherwise key (or key pair) generation or import will fail. Moreover, this key (or key
91 * pair) will be deleted when the secure lock screen is disabled or reset (e.g., by the user or
92 * a Device Administrator). Finally, this key (or key pair) cannot be used until the user
93 * unlocks the secure lock screen after boot.
94 *
95 * @see KeyguardManager#isDeviceSecure()
96 */
Kenny Roota3788b02013-04-10 10:37:55 -070097 public static final int FLAG_ENCRYPTED = 1;
98
Rubin Xu12b644d2017-04-21 19:21:42 +010099 /**
Janis Danisevskis0aadf932017-12-18 17:28:52 -0800100 * Select Software keymaster device, which as of this writing is the lowest security
101 * level available on an android device. If neither FLAG_STRONGBOX nor FLAG_SOFTWARE is provided
102 * A TEE based keymaster implementation is implied.
103 *
104 * Need to be in sync with KeyStoreFlag in system/security/keystore/include/keystore/keystore.h
105 * For historical reasons this corresponds to the KEYSTORE_FLAG_FALLBACK flag.
106 */
107 public static final int FLAG_SOFTWARE = 1 << 1;
108
109 /**
Rubin Xu12b644d2017-04-21 19:21:42 +0100110 * A private flag that's only available to system server to indicate that this key is part of
111 * device encryption flow so it receives special treatment from keystore. For example this key
112 * will not be super encrypted, and it will be stored separately under an unique UID instead
113 * of the caller UID i.e. SYSTEM.
114 *
115 * Need to be in sync with KeyStoreFlag in system/security/keystore/include/keystore/keystore.h
116 */
117 public static final int FLAG_CRITICAL_TO_DEVICE_ENCRYPTION = 1 << 3;
118
Janis Danisevskis0aadf932017-12-18 17:28:52 -0800119 /**
120 * Select Strongbox keymaster device, which as of this writing the the highest security level
121 * available an android devices. If neither FLAG_STRONGBOX nor FLAG_SOFTWARE is provided
122 * A TEE based keymaster implementation is implied.
123 *
124 * Need to be in sync with KeyStoreFlag in system/security/keystore/include/keystore/keystore.h
125 */
126 public static final int FLAG_STRONGBOX = 1 << 4;
127
Brian Carlstrom5cfee3f2011-05-31 01:00:15 -0700128 // States
129 public enum State { UNLOCKED, LOCKED, UNINITIALIZED };
Chia-chi Yeh44039172009-09-21 11:53:59 +0800130
Chia-chi Yeh44039172009-09-21 11:53:59 +0800131 private int mError = NO_ERROR;
132
Kenny Root6b776452012-11-02 15:40:32 -0700133 private final IKeystoreService mBinder;
Alex Klyubin2d7a85c2015-04-30 11:43:53 -0700134 private final Context mContext;
Kenny Root6b776452012-11-02 15:40:32 -0700135
Chad Brubakere6a461342015-02-10 21:33:23 -0800136 private IBinder mToken;
137
Kenny Root6b776452012-11-02 15:40:32 -0700138 private KeyStore(IKeystoreService binder) {
139 mBinder = binder;
Alex Klyubin3f8d4d82015-05-13 09:15:00 -0700140 mContext = getApplicationContext();
Alex Klyubin2d7a85c2015-04-30 11:43:53 -0700141 }
142
Alex Klyubindcdaf872015-05-13 15:57:09 -0700143 public static Context getApplicationContext() {
Alex Klyubina99b8b52015-06-11 13:27:34 -0700144 Application application = ActivityThread.currentApplication();
Alex Klyubin2d7a85c2015-04-30 11:43:53 -0700145 if (application == null) {
146 throw new IllegalStateException(
Alex Klyubina99b8b52015-06-11 13:27:34 -0700147 "Failed to obtain application Context from ActivityThread");
Alex Klyubin2d7a85c2015-04-30 11:43:53 -0700148 }
149 return application;
Kenny Root6b776452012-11-02 15:40:32 -0700150 }
Chia-chi Yeh44039172009-09-21 11:53:59 +0800151
152 public static KeyStore getInstance() {
Kenny Root6b776452012-11-02 15:40:32 -0700153 IKeystoreService keystore = IKeystoreService.Stub.asInterface(ServiceManager
154 .getService("android.security.keystore"));
155 return new KeyStore(keystore);
Chia-chi Yeh44039172009-09-21 11:53:59 +0800156 }
157
Chad Brubakere6a461342015-02-10 21:33:23 -0800158 private synchronized IBinder getToken() {
159 if (mToken == null) {
160 mToken = new Binder();
161 }
162 return mToken;
163 }
164
Chad Brubakere35d49f2015-05-12 15:19:52 -0700165 public State state(int userId) {
Kenny Root6b776452012-11-02 15:40:32 -0700166 final int ret;
167 try {
Chad Brubakere35d49f2015-05-12 15:19:52 -0700168 ret = mBinder.getState(userId);
Kenny Root6b776452012-11-02 15:40:32 -0700169 } catch (RemoteException e) {
170 Log.w(TAG, "Cannot connect to keystore", e);
171 throw new AssertionError(e);
172 }
173
174 switch (ret) {
Brian Carlstrom5cfee3f2011-05-31 01:00:15 -0700175 case NO_ERROR: return State.UNLOCKED;
176 case LOCKED: return State.LOCKED;
177 case UNINITIALIZED: return State.UNINITIALIZED;
178 default: throw new AssertionError(mError);
179 }
Chia-chi Yeh44039172009-09-21 11:53:59 +0800180 }
181
Chad Brubakere35d49f2015-05-12 15:19:52 -0700182 public State state() {
183 return state(UserHandle.myUserId());
184 }
185
Kenny Rootb9594ce2013-02-14 10:18:38 -0800186 public boolean isUnlocked() {
187 return state() == State.UNLOCKED;
188 }
189
Chad Brubaker5bbf0482015-09-09 14:53:52 -0700190 public byte[] get(String key, int uid) {
Kenny Root6b776452012-11-02 15:40:32 -0700191 try {
Dmitry Dementyevefc43112017-10-27 23:10:28 -0700192 key = key != null ? key : "";
Chad Brubaker5bbf0482015-09-09 14:53:52 -0700193 return mBinder.get(key, uid);
Kenny Root6b776452012-11-02 15:40:32 -0700194 } catch (RemoteException e) {
195 Log.w(TAG, "Cannot connect to keystore", e);
196 return null;
Dmitry Dementyevefc43112017-10-27 23:10:28 -0700197 } catch (android.os.ServiceSpecificException e) {
198 Log.w(TAG, "KeyStore exception", e);
199 return null;
Kenny Root6b776452012-11-02 15:40:32 -0700200 }
Chia-chi Yeh44039172009-09-21 11:53:59 +0800201 }
202
Chad Brubaker5bbf0482015-09-09 14:53:52 -0700203 public byte[] get(String key) {
204 return get(key, UID_SELF);
205 }
206
Kenny Roota3788b02013-04-10 10:37:55 -0700207 public boolean put(String key, byte[] value, int uid, int flags) {
Alex Klyubin3ceb1a02015-06-05 15:51:06 -0700208 return insert(key, value, uid, flags) == NO_ERROR;
209 }
210
211 public int insert(String key, byte[] value, int uid, int flags) {
Kenny Root6b776452012-11-02 15:40:32 -0700212 try {
Dmitry Dementyevefc43112017-10-27 23:10:28 -0700213 if (value == null) {
214 value = new byte[0];
215 }
Alex Klyubin3ceb1a02015-06-05 15:51:06 -0700216 return mBinder.insert(key, value, uid, flags);
Kenny Root78ad8492013-02-13 17:02:57 -0800217 } catch (RemoteException e) {
218 Log.w(TAG, "Cannot connect to keystore", e);
Alex Klyubin3ceb1a02015-06-05 15:51:06 -0700219 return SYSTEM_ERROR;
Kenny Root78ad8492013-02-13 17:02:57 -0800220 }
221 }
222
Kenny Root78ad8492013-02-13 17:02:57 -0800223 public boolean delete(String key, int uid) {
224 try {
Robin Leee4487ea2016-02-29 17:43:54 +0000225 int ret = mBinder.del(key, uid);
226 return (ret == NO_ERROR || ret == KEY_NOT_FOUND);
Kenny Root6b776452012-11-02 15:40:32 -0700227 } catch (RemoteException e) {
228 Log.w(TAG, "Cannot connect to keystore", e);
229 return false;
230 }
Chia-chi Yeh44039172009-09-21 11:53:59 +0800231 }
232
233 public boolean delete(String key) {
Kenny Root2eeda722013-04-10 11:30:58 -0700234 return delete(key, UID_SELF);
Kenny Root78ad8492013-02-13 17:02:57 -0800235 }
236
237 public boolean contains(String key, int uid) {
Kenny Root6b776452012-11-02 15:40:32 -0700238 try {
Kenny Root78ad8492013-02-13 17:02:57 -0800239 return mBinder.exist(key, uid) == NO_ERROR;
Kenny Root6b776452012-11-02 15:40:32 -0700240 } catch (RemoteException e) {
241 Log.w(TAG, "Cannot connect to keystore", e);
242 return false;
243 }
Chia-chi Yeh44039172009-09-21 11:53:59 +0800244 }
245
246 public boolean contains(String key) {
Kenny Root2eeda722013-04-10 11:30:58 -0700247 return contains(key, UID_SELF);
Chia-chi Yeh44039172009-09-21 11:53:59 +0800248 }
249
Chad Brubakere35d49f2015-05-12 15:19:52 -0700250 /**
251 * List all entries in the keystore for {@code uid} starting with {@code prefix}.
252 */
253 public String[] list(String prefix, int uid) {
Kenny Root6b776452012-11-02 15:40:32 -0700254 try {
Chad Brubakere35d49f2015-05-12 15:19:52 -0700255 return mBinder.list(prefix, uid);
Kenny Root6b776452012-11-02 15:40:32 -0700256 } catch (RemoteException e) {
257 Log.w(TAG, "Cannot connect to keystore", e);
Chia-chi Yeh44039172009-09-21 11:53:59 +0800258 return null;
Dmitry Dementyevefc43112017-10-27 23:10:28 -0700259 } catch (android.os.ServiceSpecificException e) {
260 Log.w(TAG, "KeyStore exception", e);
261 return null;
Chia-chi Yeh44039172009-09-21 11:53:59 +0800262 }
Chia-chi Yeh44039172009-09-21 11:53:59 +0800263 }
264
Chad Brubakere35d49f2015-05-12 15:19:52 -0700265 public String[] list(String prefix) {
266 return list(prefix, UID_SELF);
267 }
268
Chia-chi Yeh44039172009-09-21 11:53:59 +0800269 public boolean reset() {
Kenny Root6b776452012-11-02 15:40:32 -0700270 try {
271 return mBinder.reset() == NO_ERROR;
272 } catch (RemoteException e) {
273 Log.w(TAG, "Cannot connect to keystore", e);
274 return false;
275 }
Chia-chi Yeh44039172009-09-21 11:53:59 +0800276 }
277
Chad Brubakere35d49f2015-05-12 15:19:52 -0700278 /**
279 * Attempt to lock the keystore for {@code user}.
280 *
281 * @param user Android user to lock.
282 * @return whether {@code user}'s keystore was locked.
283 */
284 public boolean lock(int userId) {
Kenny Root6b776452012-11-02 15:40:32 -0700285 try {
Chad Brubakere35d49f2015-05-12 15:19:52 -0700286 return mBinder.lock(userId) == NO_ERROR;
Kenny Root6b776452012-11-02 15:40:32 -0700287 } catch (RemoteException e) {
288 Log.w(TAG, "Cannot connect to keystore", e);
289 return false;
290 }
Chia-chi Yeh44039172009-09-21 11:53:59 +0800291 }
292
Chad Brubakere35d49f2015-05-12 15:19:52 -0700293 public boolean lock() {
294 return lock(UserHandle.myUserId());
295 }
296
Chad Brubakera91a8502015-05-07 10:02:22 -0700297 /**
298 * Attempt to unlock the keystore for {@code user} with the password {@code password}.
299 * This is required before keystore entries created with FLAG_ENCRYPTED can be accessed or
300 * created.
301 *
302 * @param user Android user ID to operate on
303 * @param password user's keystore password. Should be the most recent value passed to
304 * {@link #onUserPasswordChanged} for the user.
305 *
306 * @return whether the keystore was unlocked.
307 */
308 public boolean unlock(int userId, String password) {
Kenny Root6b776452012-11-02 15:40:32 -0700309 try {
Dmitry Dementyevefc43112017-10-27 23:10:28 -0700310 password = password != null ? password : "";
Chad Brubakera91a8502015-05-07 10:02:22 -0700311 mError = mBinder.unlock(userId, password);
Kenny Root6b776452012-11-02 15:40:32 -0700312 return mError == NO_ERROR;
313 } catch (RemoteException e) {
314 Log.w(TAG, "Cannot connect to keystore", e);
315 return false;
316 }
Chia-chi Yeh44039172009-09-21 11:53:59 +0800317 }
318
Chad Brubakera91a8502015-05-07 10:02:22 -0700319 public boolean unlock(String password) {
320 return unlock(UserHandle.getUserId(Process.myUid()), password);
321 }
322
Chad Brubakere35d49f2015-05-12 15:19:52 -0700323 /**
324 * Check if the keystore for {@code userId} is empty.
325 */
326 public boolean isEmpty(int userId) {
Kenny Root6b776452012-11-02 15:40:32 -0700327 try {
Chad Brubakere35d49f2015-05-12 15:19:52 -0700328 return mBinder.isEmpty(userId) != 0;
Kenny Root6b776452012-11-02 15:40:32 -0700329 } catch (RemoteException e) {
330 Log.w(TAG, "Cannot connect to keystore", e);
331 return false;
332 }
Kenny Root5423e682011-11-14 08:43:13 -0800333 }
334
Chad Brubakere35d49f2015-05-12 15:19:52 -0700335 public boolean isEmpty() {
336 return isEmpty(UserHandle.myUserId());
337 }
338
Kenny Roota3985982013-08-16 14:03:29 -0700339 public boolean generate(String key, int uid, int keyType, int keySize, int flags,
340 byte[][] args) {
Kenny Root6b776452012-11-02 15:40:32 -0700341 try {
Chad Brubaker7a2c9732015-01-13 17:41:22 -0800342 return mBinder.generate(key, uid, keyType, keySize, flags,
343 new KeystoreArguments(args)) == NO_ERROR;
Kenny Root78ad8492013-02-13 17:02:57 -0800344 } catch (RemoteException e) {
345 Log.w(TAG, "Cannot connect to keystore", e);
346 return false;
347 }
348 }
349
Kenny Roota3788b02013-04-10 10:37:55 -0700350 public boolean importKey(String keyName, byte[] key, int uid, int flags) {
Kenny Root78ad8492013-02-13 17:02:57 -0800351 try {
Kenny Roota3788b02013-04-10 10:37:55 -0700352 return mBinder.import_key(keyName, key, uid, flags) == NO_ERROR;
Kenny Root6b776452012-11-02 15:40:32 -0700353 } catch (RemoteException e) {
354 Log.w(TAG, "Cannot connect to keystore", e);
355 return false;
356 }
Kenny Root5423e682011-11-14 08:43:13 -0800357 }
358
Kenny Root5423e682011-11-14 08:43:13 -0800359 public byte[] sign(String key, byte[] data) {
Kenny Root6b776452012-11-02 15:40:32 -0700360 try {
361 return mBinder.sign(key, data);
362 } catch (RemoteException e) {
363 Log.w(TAG, "Cannot connect to keystore", e);
364 return null;
Dmitry Dementyevefc43112017-10-27 23:10:28 -0700365 } catch (android.os.ServiceSpecificException e) {
366 Log.w(TAG, "KeyStore exception", e);
367 return null;
Kenny Root6b776452012-11-02 15:40:32 -0700368 }
Dmitry Dementyevefc43112017-10-27 23:10:28 -0700369
Kenny Root5423e682011-11-14 08:43:13 -0800370 }
371
372 public boolean verify(String key, byte[] data, byte[] signature) {
Kenny Root6b776452012-11-02 15:40:32 -0700373 try {
Dmitry Dementyevefc43112017-10-27 23:10:28 -0700374 signature = signature != null ? signature : new byte[0];
Kenny Root6b776452012-11-02 15:40:32 -0700375 return mBinder.verify(key, data, signature) == NO_ERROR;
376 } catch (RemoteException e) {
377 Log.w(TAG, "Cannot connect to keystore", e);
378 return false;
Dmitry Dementyevefc43112017-10-27 23:10:28 -0700379 } catch (android.os.ServiceSpecificException e) {
380 Log.w(TAG, "KeyStore exception", e);
381 return false;
Kenny Root6b776452012-11-02 15:40:32 -0700382 }
Dmitry Dementyevefc43112017-10-27 23:10:28 -0700383
Kenny Root5423e682011-11-14 08:43:13 -0800384 }
385
Janis Danisevskisb50e9f62017-06-08 17:53:34 -0700386 public String grant(String key, int uid) {
Kenny Root6b776452012-11-02 15:40:32 -0700387 try {
Janis Danisevskisb50e9f62017-06-08 17:53:34 -0700388 String grantAlias = mBinder.grant(key, uid);
389 if (grantAlias == "") return null;
390 return grantAlias;
Kenny Root6b776452012-11-02 15:40:32 -0700391 } catch (RemoteException e) {
392 Log.w(TAG, "Cannot connect to keystore", e);
Janis Danisevskisb50e9f62017-06-08 17:53:34 -0700393 return null;
Kenny Root6b776452012-11-02 15:40:32 -0700394 }
Kenny Root5423e682011-11-14 08:43:13 -0800395 }
396
397 public boolean ungrant(String key, int uid) {
Kenny Root6b776452012-11-02 15:40:32 -0700398 try {
399 return mBinder.ungrant(key, uid) == NO_ERROR;
400 } catch (RemoteException e) {
401 Log.w(TAG, "Cannot connect to keystore", e);
402 return false;
Kenny Root473c7122012-08-17 21:13:48 -0700403 }
Kenny Root473c7122012-08-17 21:13:48 -0700404 }
405
406 /**
407 * Returns the last modification time of the key in milliseconds since the
408 * epoch. Will return -1L if the key could not be found or other error.
409 */
Chad Brubaker5bbf0482015-09-09 14:53:52 -0700410 public long getmtime(String key, int uid) {
Kenny Root6b776452012-11-02 15:40:32 -0700411 try {
Chad Brubaker5bbf0482015-09-09 14:53:52 -0700412 final long millis = mBinder.getmtime(key, uid);
Kenny Roote66769a2013-02-04 15:49:11 -0800413 if (millis == -1L) {
414 return -1L;
415 }
416
417 return millis * 1000L;
Kenny Root6b776452012-11-02 15:40:32 -0700418 } catch (RemoteException e) {
419 Log.w(TAG, "Cannot connect to keystore", e);
420 return -1L;
421 }
Kenny Root473c7122012-08-17 21:13:48 -0700422 }
423
Chad Brubaker5bbf0482015-09-09 14:53:52 -0700424 public long getmtime(String key) {
425 return getmtime(key, UID_SELF);
426 }
427
Alex Klyubin469cbf52015-06-04 12:36:27 -0700428 // TODO: remove this when it's removed from Settings
Kenny Root5cb5cec2013-03-29 11:14:17 -0700429 public boolean isHardwareBacked() {
Kenny Rootb91773b2013-09-05 13:03:16 -0700430 return isHardwareBacked("RSA");
431 }
432
433 public boolean isHardwareBacked(String keyType) {
Kenny Root5cb5cec2013-03-29 11:14:17 -0700434 try {
Kenny Rootb91773b2013-09-05 13:03:16 -0700435 return mBinder.is_hardware_backed(keyType.toUpperCase(Locale.US)) == NO_ERROR;
Kenny Root5cb5cec2013-03-29 11:14:17 -0700436 } catch (RemoteException e) {
437 Log.w(TAG, "Cannot connect to keystore", e);
438 return false;
439 }
440 }
441
Kenny Rootd72317a2013-04-01 15:59:59 -0700442 public boolean clearUid(int uid) {
443 try {
444 return mBinder.clear_uid(uid) == NO_ERROR;
445 } catch (RemoteException e) {
446 Log.w(TAG, "Cannot connect to keystore", e);
447 return false;
448 }
449 }
450
Chia-chi Yeh44039172009-09-21 11:53:59 +0800451 public int getLastError() {
452 return mError;
453 }
Chad Brubakere6a461342015-02-10 21:33:23 -0800454
Janis Danisevskis0aadf932017-12-18 17:28:52 -0800455 public boolean addRngEntropy(byte[] data, int flags) {
Chad Brubakere6a461342015-02-10 21:33:23 -0800456 try {
Janis Danisevskis0aadf932017-12-18 17:28:52 -0800457 return mBinder.addRngEntropy(data, flags) == NO_ERROR;
Chad Brubakere6a461342015-02-10 21:33:23 -0800458 } catch (RemoteException e) {
459 Log.w(TAG, "Cannot connect to keystore", e);
460 return false;
461 }
462 }
463
Chad Brubakerdae79e52015-03-27 14:28:35 -0700464 public int generateKey(String alias, KeymasterArguments args, byte[] entropy, int uid,
465 int flags, KeyCharacteristics outCharacteristics) {
Chad Brubakere6a461342015-02-10 21:33:23 -0800466 try {
Dmitry Dementyevefc43112017-10-27 23:10:28 -0700467 entropy = entropy != null ? entropy : new byte[0];
468 args = args != null ? args : new KeymasterArguments();
Chad Brubakerdae79e52015-03-27 14:28:35 -0700469 return mBinder.generateKey(alias, args, entropy, uid, flags, outCharacteristics);
Chad Brubakere6a461342015-02-10 21:33:23 -0800470 } catch (RemoteException e) {
471 Log.w(TAG, "Cannot connect to keystore", e);
472 return SYSTEM_ERROR;
473 }
474 }
475
Chad Brubakerdae79e52015-03-27 14:28:35 -0700476 public int generateKey(String alias, KeymasterArguments args, byte[] entropy, int flags,
Chad Brubakere6a461342015-02-10 21:33:23 -0800477 KeyCharacteristics outCharacteristics) {
Chad Brubakerdae79e52015-03-27 14:28:35 -0700478 return generateKey(alias, args, entropy, UID_SELF, flags, outCharacteristics);
Chad Brubakere6a461342015-02-10 21:33:23 -0800479 }
480
Chad Brubaker5e73c0e2015-03-21 22:46:43 -0700481 public int getKeyCharacteristics(String alias, KeymasterBlob clientId, KeymasterBlob appId,
Chad Brubaker5bbf0482015-09-09 14:53:52 -0700482 int uid, KeyCharacteristics outCharacteristics) {
Chad Brubakere6a461342015-02-10 21:33:23 -0800483 try {
Dmitry Dementyevefc43112017-10-27 23:10:28 -0700484 clientId = clientId != null ? clientId : new KeymasterBlob(new byte[0]);
485 appId = appId != null ? appId : new KeymasterBlob(new byte[0]);
Chad Brubaker5bbf0482015-09-09 14:53:52 -0700486 return mBinder.getKeyCharacteristics(alias, clientId, appId, uid, outCharacteristics);
Chad Brubakere6a461342015-02-10 21:33:23 -0800487 } catch (RemoteException e) {
488 Log.w(TAG, "Cannot connect to keystore", e);
489 return SYSTEM_ERROR;
490 }
491 }
492
Chad Brubaker5bbf0482015-09-09 14:53:52 -0700493 public int getKeyCharacteristics(String alias, KeymasterBlob clientId, KeymasterBlob appId,
494 KeyCharacteristics outCharacteristics) {
495 return getKeyCharacteristics(alias, clientId, appId, UID_SELF, outCharacteristics);
496 }
497
Chad Brubakere6a461342015-02-10 21:33:23 -0800498 public int importKey(String alias, KeymasterArguments args, int format, byte[] keyData,
499 int uid, int flags, KeyCharacteristics outCharacteristics) {
500 try {
501 return mBinder.importKey(alias, args, format, keyData, uid, flags,
502 outCharacteristics);
503 } catch (RemoteException e) {
504 Log.w(TAG, "Cannot connect to keystore", e);
505 return SYSTEM_ERROR;
506 }
507 }
508
509 public int importKey(String alias, KeymasterArguments args, int format, byte[] keyData,
510 int flags, KeyCharacteristics outCharacteristics) {
511 return importKey(alias, args, format, keyData, UID_SELF, flags, outCharacteristics);
512 }
513
Frank Salim21d9c1d2017-12-19 22:38:09 -0800514 public int importWrappedKey(String wrappedKeyAlias, byte[] wrappedKey,
515 String wrappingKeyAlias,
516 byte[] maskingKey, KeymasterArguments args, long rootSid, long fingerprintSid, int uid,
517 KeyCharacteristics outCharacteristics) {
518 try {
519 return mBinder.importWrappedKey(wrappedKeyAlias, wrappedKey, wrappingKeyAlias,
520 maskingKey, args, rootSid, fingerprintSid, outCharacteristics);
521 } catch (RemoteException e) {
522 Log.w(TAG, "Cannot connect to keystore", e);
523 return SYSTEM_ERROR;
524 }
525 }
526
Chad Brubaker5e73c0e2015-03-21 22:46:43 -0700527 public ExportResult exportKey(String alias, int format, KeymasterBlob clientId,
Chad Brubaker5bbf0482015-09-09 14:53:52 -0700528 KeymasterBlob appId, int uid) {
Chad Brubakere6a461342015-02-10 21:33:23 -0800529 try {
Dmitry Dementyevefc43112017-10-27 23:10:28 -0700530 clientId = clientId != null ? clientId : new KeymasterBlob(new byte[0]);
531 appId = appId != null ? appId : new KeymasterBlob(new byte[0]);
Chad Brubaker5bbf0482015-09-09 14:53:52 -0700532 return mBinder.exportKey(alias, format, clientId, appId, uid);
533 } catch (RemoteException e) {
534 Log.w(TAG, "Cannot connect to keystore", e);
535 return null;
536 }
537 }
538 public ExportResult exportKey(String alias, int format, KeymasterBlob clientId,
539 KeymasterBlob appId) {
540 return exportKey(alias, format, clientId, appId, UID_SELF);
541 }
542
543 public OperationResult begin(String alias, int purpose, boolean pruneable,
544 KeymasterArguments args, byte[] entropy, int uid) {
545 try {
Dmitry Dementyevefc43112017-10-27 23:10:28 -0700546 args = args != null ? args : new KeymasterArguments();
547 entropy = entropy != null ? entropy : new byte[0];
Chad Brubaker5bbf0482015-09-09 14:53:52 -0700548 return mBinder.begin(getToken(), alias, purpose, pruneable, args, entropy, uid);
Chad Brubakere6a461342015-02-10 21:33:23 -0800549 } catch (RemoteException e) {
550 Log.w(TAG, "Cannot connect to keystore", e);
551 return null;
552 }
553 }
554
555 public OperationResult begin(String alias, int purpose, boolean pruneable,
Chad Brubaker966486e2015-06-01 12:57:06 -0700556 KeymasterArguments args, byte[] entropy) {
Dmitry Dementyevefc43112017-10-27 23:10:28 -0700557 entropy = entropy != null ? entropy : new byte[0];
558 args = args != null ? args : new KeymasterArguments();
Chad Brubaker5bbf0482015-09-09 14:53:52 -0700559 return begin(alias, purpose, pruneable, args, entropy, UID_SELF);
Chad Brubakere6a461342015-02-10 21:33:23 -0800560 }
561
562 public OperationResult update(IBinder token, KeymasterArguments arguments, byte[] input) {
563 try {
Dmitry Dementyevefc43112017-10-27 23:10:28 -0700564 arguments = arguments != null ? arguments : new KeymasterArguments();
565 input = input != null ? input : new byte[0];
Chad Brubakere6a461342015-02-10 21:33:23 -0800566 return mBinder.update(token, arguments, input);
567 } catch (RemoteException e) {
568 Log.w(TAG, "Cannot connect to keystore", e);
569 return null;
570 }
571 }
572
Chad Brubaker8a077012015-05-29 12:32:51 -0700573 public OperationResult finish(IBinder token, KeymasterArguments arguments, byte[] signature,
574 byte[] entropy) {
Chad Brubakere6a461342015-02-10 21:33:23 -0800575 try {
Dmitry Dementyevefc43112017-10-27 23:10:28 -0700576 arguments = arguments != null ? arguments : new KeymasterArguments();
577 entropy = entropy != null ? entropy : new byte[0];
578 signature = signature != null ? signature : new byte[0];
Chad Brubaker8a077012015-05-29 12:32:51 -0700579 return mBinder.finish(token, arguments, signature, entropy);
Chad Brubakere6a461342015-02-10 21:33:23 -0800580 } catch (RemoteException e) {
581 Log.w(TAG, "Cannot connect to keystore", e);
582 return null;
583 }
584 }
585
Chad Brubaker8a077012015-05-29 12:32:51 -0700586 public OperationResult finish(IBinder token, KeymasterArguments arguments, byte[] signature) {
587 return finish(token, arguments, signature, null);
588 }
589
Chad Brubakere6a461342015-02-10 21:33:23 -0800590 public int abort(IBinder token) {
591 try {
592 return mBinder.abort(token);
593 } catch (RemoteException e) {
594 Log.w(TAG, "Cannot connect to keystore", e);
595 return SYSTEM_ERROR;
596 }
597 }
Chad Brubaker5654b362015-03-17 16:59:52 -0700598
599 /**
600 * Check if the operation referenced by {@code token} is currently authorized.
601 *
Alex Klyubin708fc9402015-04-28 18:58:47 -0700602 * @param token An operation token returned by a call to
603 * {@link #begin(String, int, boolean, KeymasterArguments, byte[], KeymasterArguments) begin}.
Chad Brubaker5654b362015-03-17 16:59:52 -0700604 */
605 public boolean isOperationAuthorized(IBinder token) {
606 try {
607 return mBinder.isOperationAuthorized(token);
608 } catch (RemoteException e) {
609 Log.w(TAG, "Cannot connect to keystore", e);
610 return false;
611 }
612 }
613
614 /**
615 * Add an authentication record to the keystore authorization table.
616 *
617 * @param authToken The packed bytes of a hw_auth_token_t to be provided to keymaster.
618 * @return {@code KeyStore.NO_ERROR} on success, otherwise an error value corresponding to
619 * a {@code KeymasterDefs.KM_ERROR_} value or {@code KeyStore} ResponseCode.
620 */
621 public int addAuthToken(byte[] authToken) {
622 try {
623 return mBinder.addAuthToken(authToken);
624 } catch (RemoteException e) {
625 Log.w(TAG, "Cannot connect to keystore", e);
626 return SYSTEM_ERROR;
627 }
628 }
Alex Klyubinb4834ae2015-04-02 15:53:46 -0700629
Alex Klyubinad9ba102015-04-21 15:17:24 -0700630 /**
Chad Brubakera91a8502015-05-07 10:02:22 -0700631 * Notify keystore that a user's password has changed.
632 *
633 * @param userId the user whose password changed.
634 * @param newPassword the new password or "" if the password was removed.
635 */
636 public boolean onUserPasswordChanged(int userId, String newPassword) {
637 // Parcel.cpp doesn't support deserializing null strings and treats them as "". Make that
638 // explicit here.
639 if (newPassword == null) {
640 newPassword = "";
641 }
642 try {
643 return mBinder.onUserPasswordChanged(userId, newPassword) == NO_ERROR;
644 } catch (RemoteException e) {
645 Log.w(TAG, "Cannot connect to keystore", e);
646 return false;
647 }
648 }
649
Chad Brubaker83ce0952015-05-12 13:00:02 -0700650 /**
651 * Notify keystore that a user was added.
652 *
653 * @param userId the new user.
654 * @param parentId the parent of the new user, or -1 if the user has no parent. If parentId is
655 * specified then the new user's keystore will be intialized with the same secure lockscreen
656 * password as the parent.
657 */
658 public void onUserAdded(int userId, int parentId) {
659 try {
660 mBinder.onUserAdded(userId, parentId);
661 } catch (RemoteException e) {
662 Log.w(TAG, "Cannot connect to keystore", e);
663 }
664 }
665
666 /**
667 * Notify keystore that a user was added.
668 *
669 * @param userId the new user.
670 */
671 public void onUserAdded(int userId) {
672 onUserAdded(userId, -1);
673 }
674
675 /**
676 * Notify keystore that a user was removed.
677 *
678 * @param userId the removed user.
679 */
680 public void onUserRemoved(int userId) {
681 try {
682 mBinder.onUserRemoved(userId);
683 } catch (RemoteException e) {
684 Log.w(TAG, "Cannot connect to keystore", e);
685 }
686 }
687
Chad Brubakera91a8502015-05-07 10:02:22 -0700688 public boolean onUserPasswordChanged(String newPassword) {
689 return onUserPasswordChanged(UserHandle.getUserId(Process.myUid()), newPassword);
690 }
691
Shawn Willden8d8c7472016-02-02 08:27:39 -0700692 public int attestKey(
693 String alias, KeymasterArguments params, KeymasterCertificateChain outChain) {
694 try {
Dmitry Dementyevefc43112017-10-27 23:10:28 -0700695 if (params == null) {
696 params = new KeymasterArguments();
697 }
698 if (outChain == null) {
699 outChain = new KeymasterCertificateChain();
700 }
Shawn Willden8d8c7472016-02-02 08:27:39 -0700701 return mBinder.attestKey(alias, params, outChain);
702 } catch (RemoteException e) {
703 Log.w(TAG, "Cannot connect to keystore", e);
704 return SYSTEM_ERROR;
705 }
706 }
707
Bartosz Fabianowski237f4b362017-04-24 13:57:46 +0200708 public int attestDeviceIds(KeymasterArguments params, KeymasterCertificateChain outChain) {
709 try {
Dmitry Dementyevefc43112017-10-27 23:10:28 -0700710 if (params == null) {
711 params = new KeymasterArguments();
712 }
713 if (outChain == null) {
714 outChain = new KeymasterCertificateChain();
715 }
Bartosz Fabianowski237f4b362017-04-24 13:57:46 +0200716 return mBinder.attestDeviceIds(params, outChain);
717 } catch (RemoteException e) {
718 Log.w(TAG, "Cannot connect to keystore", e);
719 return SYSTEM_ERROR;
720 }
721 }
722
Tucker Sylvestrob32aae22016-06-23 17:23:33 -0400723 /**
724 * Notify keystore that the device went off-body.
725 */
726 public void onDeviceOffBody() {
727 try {
728 mBinder.onDeviceOffBody();
729 } catch (RemoteException e) {
730 Log.w(TAG, "Cannot connect to keystore", e);
731 }
732 }
Shawn Willden8d8c7472016-02-02 08:27:39 -0700733
Janis Danisevskis7dacad82018-01-24 15:12:11 -0800734 // Keep in sync with confirmationui/1.0/types.hal.
735 public static final int CONFIRMATIONUI_OK = 0;
736 public static final int CONFIRMATIONUI_CANCELED = 1;
737 public static final int CONFIRMATIONUI_ABORTED = 2;
738 public static final int CONFIRMATIONUI_OPERATION_PENDING = 3;
739 public static final int CONFIRMATIONUI_IGNORED = 4;
740 public static final int CONFIRMATIONUI_SYSTEM_ERROR = 5;
741 public static final int CONFIRMATIONUI_UNIMPLEMENTED = 6;
742 public static final int CONFIRMATIONUI_UNEXPECTED = 7;
743 public static final int CONFIRMATIONUI_UIERROR = 0x10000;
744 public static final int CONFIRMATIONUI_UIERROR_MISSING_GLYPH = 0x10001;
745 public static final int CONFIRMATIONUI_UIERROR_MESSAGE_TOO_LONG = 0x10002;
746 public static final int CONFIRMATIONUI_UIERROR_MALFORMED_UTF8_ENCODING = 0x10003;
747
748 /**
749 * Requests keystore call into the confirmationui HAL to display a prompt.
750 *
751 * @param listener the binder to use for callbacks.
752 * @param promptText the prompt to display.
753 * @param extraData extra data / nonce from application.
754 * @param locale the locale as a BCP 47 langauge tag.
755 * @param uiOptionsAsFlags the UI options to use, as flags.
756 * @return one of the {@code CONFIRMATIONUI_*} constants, for
757 * example {@code KeyStore.CONFIRMATIONUI_OK}.
758 */
759 public int presentConfirmationPrompt(IBinder listener, String promptText, byte[] extraData,
760 String locale, int uiOptionsAsFlags) {
761 try {
762 return mBinder.presentConfirmationPrompt(listener, promptText, extraData, locale,
763 uiOptionsAsFlags);
764 } catch (RemoteException e) {
765 Log.w(TAG, "Cannot connect to keystore", e);
766 return CONFIRMATIONUI_SYSTEM_ERROR;
767 }
768 }
769
770 /**
771 * Requests keystore call into the confirmationui HAL to cancel displaying a prompt.
772 *
773 * @param listener the binder passed to the {@link #presentConfirmationPrompt} method.
774 * @return one of the {@code CONFIRMATIONUI_*} constants, for
775 * example {@code KeyStore.CONFIRMATIONUI_OK}.
776 */
777 public int cancelConfirmationPrompt(IBinder listener) {
778 try {
779 return mBinder.cancelConfirmationPrompt(listener);
780 } catch (RemoteException e) {
781 Log.w(TAG, "Cannot connect to keystore", e);
782 return CONFIRMATIONUI_SYSTEM_ERROR;
783 }
784 }
785
Chad Brubakera91a8502015-05-07 10:02:22 -0700786 /**
Alex Klyubinad9ba102015-04-21 15:17:24 -0700787 * Returns a {@link KeyStoreException} corresponding to the provided keystore/keymaster error
788 * code.
789 */
Alex Klyubindcdaf872015-05-13 15:57:09 -0700790 public static KeyStoreException getKeyStoreException(int errorCode) {
Alex Klyubinb4834ae2015-04-02 15:53:46 -0700791 if (errorCode > 0) {
792 // KeyStore layer error
793 switch (errorCode) {
794 case NO_ERROR:
795 return new KeyStoreException(errorCode, "OK");
796 case LOCKED:
Alex Klyubin54183932015-05-08 15:25:48 -0700797 return new KeyStoreException(errorCode, "User authentication required");
Alex Klyubinb4834ae2015-04-02 15:53:46 -0700798 case UNINITIALIZED:
799 return new KeyStoreException(errorCode, "Keystore not initialized");
800 case SYSTEM_ERROR:
801 return new KeyStoreException(errorCode, "System error");
802 case PERMISSION_DENIED:
803 return new KeyStoreException(errorCode, "Permission denied");
804 case KEY_NOT_FOUND:
805 return new KeyStoreException(errorCode, "Key not found");
806 case VALUE_CORRUPTED:
807 return new KeyStoreException(errorCode, "Key blob corrupted");
Alex Klyubin058de022015-04-29 17:32:00 -0700808 case OP_AUTH_NEEDED:
809 return new KeyStoreException(errorCode, "Operation requires authorization");
Alex Klyubinb4834ae2015-04-02 15:53:46 -0700810 default:
811 return new KeyStoreException(errorCode, String.valueOf(errorCode));
812 }
813 } else {
814 // Keymaster layer error
815 switch (errorCode) {
816 case KeymasterDefs.KM_ERROR_INVALID_AUTHORIZATION_TIMEOUT:
817 // The name of this parameter significantly differs between Keymaster and
818 // framework APIs. Use the framework wording to make life easier for developers.
819 return new KeyStoreException(errorCode,
820 "Invalid user authentication validity duration");
821 default:
822 return new KeyStoreException(errorCode,
823 KeymasterDefs.getErrorMessage(errorCode));
824 }
825 }
826 }
827
Alex Klyubinad9ba102015-04-21 15:17:24 -0700828 /**
829 * Returns an {@link InvalidKeyException} corresponding to the provided
830 * {@link KeyStoreException}.
831 */
Alex Klyubindcdaf872015-05-13 15:57:09 -0700832 public InvalidKeyException getInvalidKeyException(
Alex Klyubin3876b1b2015-09-09 14:55:03 -0700833 String keystoreKeyAlias, int uid, KeyStoreException e) {
Alex Klyubinb4834ae2015-04-02 15:53:46 -0700834 switch (e.getErrorCode()) {
Alex Klyubin54183932015-05-08 15:25:48 -0700835 case LOCKED:
836 return new UserNotAuthenticatedException();
Alex Klyubinb4834ae2015-04-02 15:53:46 -0700837 case KeymasterDefs.KM_ERROR_KEY_EXPIRED:
838 return new KeyExpiredException();
839 case KeymasterDefs.KM_ERROR_KEY_NOT_YET_VALID:
840 return new KeyNotYetValidException();
841 case KeymasterDefs.KM_ERROR_KEY_USER_NOT_AUTHENTICATED:
Alex Klyubin058de022015-04-29 17:32:00 -0700842 case OP_AUTH_NEEDED:
Alex Klyubin708fc9402015-04-28 18:58:47 -0700843 {
844 // We now need to determine whether the key/operation can become usable if user
845 // authentication is performed, or whether it can never become usable again.
846 // User authentication requirements are contained in the key's characteristics. We
847 // need to check whether these requirements can be be satisfied by asking the user
848 // to authenticate.
849 KeyCharacteristics keyCharacteristics = new KeyCharacteristics();
850 int getKeyCharacteristicsErrorCode =
Alex Klyubin3876b1b2015-09-09 14:55:03 -0700851 getKeyCharacteristics(keystoreKeyAlias, null, null, uid,
852 keyCharacteristics);
Alex Klyubin708fc9402015-04-28 18:58:47 -0700853 if (getKeyCharacteristicsErrorCode != NO_ERROR) {
854 return new InvalidKeyException(
855 "Failed to obtained key characteristics",
856 getKeyStoreException(getKeyCharacteristicsErrorCode));
857 }
Alex Klyubinae6cb7a2015-06-22 18:09:35 -0700858 List<BigInteger> keySids =
859 keyCharacteristics.getUnsignedLongs(KeymasterDefs.KM_TAG_USER_SECURE_ID);
Alex Klyubin708fc9402015-04-28 18:58:47 -0700860 if (keySids.isEmpty()) {
861 // Key is not bound to any SIDs -- no amount of authentication will help here.
862 return new KeyPermanentlyInvalidatedException();
863 }
864 long rootSid = GateKeeper.getSecureUserId();
Alex Klyubinae6cb7a2015-06-22 18:09:35 -0700865 if ((rootSid != 0) && (keySids.contains(KeymasterArguments.toUint64(rootSid)))) {
Alex Klyubin708fc9402015-04-28 18:58:47 -0700866 // One of the key's SIDs is the current root SID -- user can be authenticated
867 // against that SID.
868 return new UserNotAuthenticatedException();
869 }
870
871 long fingerprintOnlySid = getFingerprintOnlySid();
872 if ((fingerprintOnlySid != 0)
Alex Klyubinae6cb7a2015-06-22 18:09:35 -0700873 && (keySids.contains(KeymasterArguments.toUint64(fingerprintOnlySid)))) {
Alex Klyubin708fc9402015-04-28 18:58:47 -0700874 // One of the key's SIDs is the current fingerprint SID -- user can be
875 // authenticated against that SID.
876 return new UserNotAuthenticatedException();
877 }
878
879 // None of the key's SIDs can ever be authenticated
880 return new KeyPermanentlyInvalidatedException();
881 }
Janis Danisevskisd07d3382017-09-01 14:45:16 -0700882 case UNINITIALIZED:
883 return new KeyPermanentlyInvalidatedException();
Alex Klyubinb4834ae2015-04-02 15:53:46 -0700884 default:
Alex Klyubinad9ba102015-04-21 15:17:24 -0700885 return new InvalidKeyException("Keystore operation failed", e);
Alex Klyubinb4834ae2015-04-02 15:53:46 -0700886 }
887 }
888
Alex Klyubin2d7a85c2015-04-30 11:43:53 -0700889 private long getFingerprintOnlySid() {
Kevin Chyn55966422017-10-23 16:08:47 -0700890 final PackageManager packageManager = mContext.getPackageManager();
891 if (!packageManager.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)) {
892 return 0;
893 }
Alex Klyubina99b8b52015-06-11 13:27:34 -0700894 FingerprintManager fingerprintManager = mContext.getSystemService(FingerprintManager.class);
Alex Klyubin2d7a85c2015-04-30 11:43:53 -0700895 if (fingerprintManager == null) {
Alex Klyubin708fc9402015-04-28 18:58:47 -0700896 return 0;
897 }
898
Alex Klyubina99b8b52015-06-11 13:27:34 -0700899 // TODO: Restore USE_FINGERPRINT permission check in
900 // FingerprintManager.getAuthenticatorId once the ID is no longer needed here.
Alex Klyubin2d7a85c2015-04-30 11:43:53 -0700901 return fingerprintManager.getAuthenticatorId();
Svetoslav2dac95d2015-04-30 11:30:33 -0700902 }
903
Alex Klyubinad9ba102015-04-21 15:17:24 -0700904 /**
905 * Returns an {@link InvalidKeyException} corresponding to the provided keystore/keymaster error
906 * code.
907 */
Alex Klyubin3876b1b2015-09-09 14:55:03 -0700908 public InvalidKeyException getInvalidKeyException(String keystoreKeyAlias, int uid,
909 int errorCode) {
910 return getInvalidKeyException(keystoreKeyAlias, uid, getKeyStoreException(errorCode));
Alex Klyubinb4834ae2015-04-02 15:53:46 -0700911 }
Chia-chi Yeh44039172009-09-21 11:53:59 +0800912}