144039172627d1c15737ea73836ad375559d76211Chia-chi Yeh/* 244039172627d1c15737ea73836ad375559d76211Chia-chi Yeh * Copyright (C) 2009 The Android Open Source Project 344039172627d1c15737ea73836ad375559d76211Chia-chi Yeh * 444039172627d1c15737ea73836ad375559d76211Chia-chi Yeh * Licensed under the Apache License, Version 2.0 (the "License"); 544039172627d1c15737ea73836ad375559d76211Chia-chi Yeh * you may not use this file except in compliance with the License. 644039172627d1c15737ea73836ad375559d76211Chia-chi Yeh * You may obtain a copy of the License at 744039172627d1c15737ea73836ad375559d76211Chia-chi Yeh * 844039172627d1c15737ea73836ad375559d76211Chia-chi Yeh * http://www.apache.org/licenses/LICENSE-2.0 944039172627d1c15737ea73836ad375559d76211Chia-chi Yeh * 1044039172627d1c15737ea73836ad375559d76211Chia-chi Yeh * Unless required by applicable law or agreed to in writing, software 1144039172627d1c15737ea73836ad375559d76211Chia-chi Yeh * distributed under the License is distributed on an "AS IS" BASIS, 1244039172627d1c15737ea73836ad375559d76211Chia-chi Yeh * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1344039172627d1c15737ea73836ad375559d76211Chia-chi Yeh * See the License for the specific language governing permissions and 1444039172627d1c15737ea73836ad375559d76211Chia-chi Yeh * limitations under the License. 1544039172627d1c15737ea73836ad375559d76211Chia-chi Yeh */ 1644039172627d1c15737ea73836ad375559d76211Chia-chi Yeh 1744039172627d1c15737ea73836ad375559d76211Chia-chi Yehpackage android.security; 1844039172627d1c15737ea73836ad375559d76211Chia-chi Yeh 192dac95d03399bb9fa59999e4964d7f8bcd485c38Svetoslavimport android.app.ActivityThread; 202dac95d03399bb9fa59999e4964d7f8bcd485c38Svetoslavimport android.app.Application; 215418393c58d1d80fe37a209ab931f6d56bd46a86Alex Klyubinimport android.app.KeyguardManager; 22708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubinimport android.content.Context; 232d7a85cd2b2ab4dbbe09354c6ae1668bff51a514Alex Klyubinimport android.hardware.fingerprint.FingerprintManager; 24e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubakerimport android.os.Binder; 25e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubakerimport android.os.IBinder; 26a91a8504191d91d288c55821caa5bf00c9be26a2Chad Brubakerimport android.os.Process; 276b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Rootimport android.os.RemoteException; 286b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Rootimport android.os.ServiceManager; 29a91a8504191d91d288c55821caa5bf00c9be26a2Chad Brubakerimport android.os.UserHandle; 30e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubakerimport android.security.keymaster.ExportResult; 31e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubakerimport android.security.keymaster.KeyCharacteristics; 32e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubakerimport android.security.keymaster.KeymasterArguments; 335e73c0eec2bc77222a5a87fb2a135d8303836411Chad Brubakerimport android.security.keymaster.KeymasterBlob; 348d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willdenimport android.security.keymaster.KeymasterCertificateChain; 35b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubinimport android.security.keymaster.KeymasterDefs; 36e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubakerimport android.security.keymaster.OperationResult; 373f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubinimport android.security.keystore.KeyExpiredException; 383f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubinimport android.security.keystore.KeyNotYetValidException; 393f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubinimport android.security.keystore.KeyPermanentlyInvalidatedException; 403f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubinimport android.security.keystore.UserNotAuthenticatedException; 416b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Rootimport android.util.Log; 4244039172627d1c15737ea73836ad375559d76211Chia-chi Yeh 43ae6cb7aad56bb006769cd8a69b92af7236644fc1Alex Klyubinimport java.math.BigInteger; 44ad9ba10ecda10c14e46d00f40fc3e431cc2d9bc2Alex Klyubinimport java.security.InvalidKeyException; 45708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubinimport java.util.List; 46b91773bce1126d28a93f73fbef18f3a79245f24eKenny Rootimport java.util.Locale; 47b91773bce1126d28a93f73fbef18f3a79245f24eKenny Root 4844039172627d1c15737ea73836ad375559d76211Chia-chi Yeh/** 4946703b099516c383a6882815bcf9cd4df0ec538dBrian Carlstrom * @hide This should not be made public in its present form because it 5046703b099516c383a6882815bcf9cd4df0ec538dBrian Carlstrom * assumes that private and secret key bytes are available and would 5146703b099516c383a6882815bcf9cd4df0ec538dBrian Carlstrom * preclude the use of hardware crypto. 5244039172627d1c15737ea73836ad375559d76211Chia-chi Yeh */ 5344039172627d1c15737ea73836ad375559d76211Chia-chi Yehpublic class KeyStore { 546b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root private static final String TAG = "KeyStore"; 555cfee3fabb3482c6a6df1c8b6f21e843cf214527Brian Carlstrom 565cfee3fabb3482c6a6df1c8b6f21e843cf214527Brian Carlstrom // ResponseCodes 577e4b1a488dd02c4bf6156379e36834e9e01c5b1bBrian Carlstrom public static final int NO_ERROR = 1; 587e4b1a488dd02c4bf6156379e36834e9e01c5b1bBrian Carlstrom public static final int LOCKED = 2; 597e4b1a488dd02c4bf6156379e36834e9e01c5b1bBrian Carlstrom public static final int UNINITIALIZED = 3; 607e4b1a488dd02c4bf6156379e36834e9e01c5b1bBrian Carlstrom public static final int SYSTEM_ERROR = 4; 617e4b1a488dd02c4bf6156379e36834e9e01c5b1bBrian Carlstrom public static final int PROTOCOL_ERROR = 5; 627e4b1a488dd02c4bf6156379e36834e9e01c5b1bBrian Carlstrom public static final int PERMISSION_DENIED = 6; 637e4b1a488dd02c4bf6156379e36834e9e01c5b1bBrian Carlstrom public static final int KEY_NOT_FOUND = 7; 647e4b1a488dd02c4bf6156379e36834e9e01c5b1bBrian Carlstrom public static final int VALUE_CORRUPTED = 8; 657e4b1a488dd02c4bf6156379e36834e9e01c5b1bBrian Carlstrom public static final int UNDEFINED_ACTION = 9; 667e4b1a488dd02c4bf6156379e36834e9e01c5b1bBrian Carlstrom public static final int WRONG_PASSWORD = 10; 675cfee3fabb3482c6a6df1c8b6f21e843cf214527Brian Carlstrom 68560d653e554882218232cd0fe4711be42145727aChad Brubaker /** 69560d653e554882218232cd0fe4711be42145727aChad Brubaker * Per operation authentication is needed before this operation is valid. 70560d653e554882218232cd0fe4711be42145727aChad Brubaker * This is returned from {@link #begin} when begin succeeds but the operation uses 71560d653e554882218232cd0fe4711be42145727aChad Brubaker * per-operation authentication and must authenticate before calling {@link #update} or 72560d653e554882218232cd0fe4711be42145727aChad Brubaker * {@link #finish}. 73560d653e554882218232cd0fe4711be42145727aChad Brubaker */ 74560d653e554882218232cd0fe4711be42145727aChad Brubaker public static final int OP_AUTH_NEEDED = 15; 75560d653e554882218232cd0fe4711be42145727aChad Brubaker 762eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root // Used for UID field to indicate the calling UID. 772eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root public static final int UID_SELF = -1; 782eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root 792eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root // Flags for "put" "import" and "generate" 802eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root public static final int FLAG_NONE = 0; 815418393c58d1d80fe37a209ab931f6d56bd46a86Alex Klyubin 825418393c58d1d80fe37a209ab931f6d56bd46a86Alex Klyubin /** 835418393c58d1d80fe37a209ab931f6d56bd46a86Alex Klyubin * Indicates that this key (or key pair) must be encrypted at rest. This will protect the key 845418393c58d1d80fe37a209ab931f6d56bd46a86Alex Klyubin * (or key pair) with the secure lock screen credential (e.g., password, PIN, or pattern). 855418393c58d1d80fe37a209ab931f6d56bd46a86Alex Klyubin * 865418393c58d1d80fe37a209ab931f6d56bd46a86Alex Klyubin * <p>Note that this requires that the secure lock screen (e.g., password, PIN, pattern) is set 875418393c58d1d80fe37a209ab931f6d56bd46a86Alex Klyubin * up, otherwise key (or key pair) generation or import will fail. Moreover, this key (or key 885418393c58d1d80fe37a209ab931f6d56bd46a86Alex Klyubin * pair) will be deleted when the secure lock screen is disabled or reset (e.g., by the user or 895418393c58d1d80fe37a209ab931f6d56bd46a86Alex Klyubin * a Device Administrator). Finally, this key (or key pair) cannot be used until the user 905418393c58d1d80fe37a209ab931f6d56bd46a86Alex Klyubin * unlocks the secure lock screen after boot. 915418393c58d1d80fe37a209ab931f6d56bd46a86Alex Klyubin * 925418393c58d1d80fe37a209ab931f6d56bd46a86Alex Klyubin * @see KeyguardManager#isDeviceSecure() 935418393c58d1d80fe37a209ab931f6d56bd46a86Alex Klyubin */ 94a3788b00bb221e20abdd42f747d2af419e0a088cKenny Root public static final int FLAG_ENCRYPTED = 1; 95a3788b00bb221e20abdd42f747d2af419e0a088cKenny Root 9612b644d275b121dd952a4a564fa65b9c18c9b22cRubin Xu /** 9712b644d275b121dd952a4a564fa65b9c18c9b22cRubin Xu * A private flag that's only available to system server to indicate that this key is part of 9812b644d275b121dd952a4a564fa65b9c18c9b22cRubin Xu * device encryption flow so it receives special treatment from keystore. For example this key 9912b644d275b121dd952a4a564fa65b9c18c9b22cRubin Xu * will not be super encrypted, and it will be stored separately under an unique UID instead 10012b644d275b121dd952a4a564fa65b9c18c9b22cRubin Xu * of the caller UID i.e. SYSTEM. 10112b644d275b121dd952a4a564fa65b9c18c9b22cRubin Xu * 10212b644d275b121dd952a4a564fa65b9c18c9b22cRubin Xu * Need to be in sync with KeyStoreFlag in system/security/keystore/include/keystore/keystore.h 10312b644d275b121dd952a4a564fa65b9c18c9b22cRubin Xu */ 10412b644d275b121dd952a4a564fa65b9c18c9b22cRubin Xu public static final int FLAG_CRITICAL_TO_DEVICE_ENCRYPTION = 1 << 3; 10512b644d275b121dd952a4a564fa65b9c18c9b22cRubin Xu 1065cfee3fabb3482c6a6df1c8b6f21e843cf214527Brian Carlstrom // States 1075cfee3fabb3482c6a6df1c8b6f21e843cf214527Brian Carlstrom public enum State { UNLOCKED, LOCKED, UNINITIALIZED }; 10844039172627d1c15737ea73836ad375559d76211Chia-chi Yeh 10944039172627d1c15737ea73836ad375559d76211Chia-chi Yeh private int mError = NO_ERROR; 11044039172627d1c15737ea73836ad375559d76211Chia-chi Yeh 1116b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root private final IKeystoreService mBinder; 1122d7a85cd2b2ab4dbbe09354c6ae1668bff51a514Alex Klyubin private final Context mContext; 1136b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root 114e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker private IBinder mToken; 115e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker 1166b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root private KeyStore(IKeystoreService binder) { 1176b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root mBinder = binder; 1183f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mContext = getApplicationContext(); 1192d7a85cd2b2ab4dbbe09354c6ae1668bff51a514Alex Klyubin } 1202d7a85cd2b2ab4dbbe09354c6ae1668bff51a514Alex Klyubin 121dcdaf87ed0aa99073638bcfe645949f130f0c7adAlex Klyubin public static Context getApplicationContext() { 122a99b8b5e3fe456b74b9f86e12bebebb5e418f58eAlex Klyubin Application application = ActivityThread.currentApplication(); 1232d7a85cd2b2ab4dbbe09354c6ae1668bff51a514Alex Klyubin if (application == null) { 1242d7a85cd2b2ab4dbbe09354c6ae1668bff51a514Alex Klyubin throw new IllegalStateException( 125a99b8b5e3fe456b74b9f86e12bebebb5e418f58eAlex Klyubin "Failed to obtain application Context from ActivityThread"); 1262d7a85cd2b2ab4dbbe09354c6ae1668bff51a514Alex Klyubin } 1272d7a85cd2b2ab4dbbe09354c6ae1668bff51a514Alex Klyubin return application; 1286b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root } 12944039172627d1c15737ea73836ad375559d76211Chia-chi Yeh 13044039172627d1c15737ea73836ad375559d76211Chia-chi Yeh public static KeyStore getInstance() { 1316b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root IKeystoreService keystore = IKeystoreService.Stub.asInterface(ServiceManager 1326b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root .getService("android.security.keystore")); 1336b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root return new KeyStore(keystore); 13444039172627d1c15737ea73836ad375559d76211Chia-chi Yeh } 13544039172627d1c15737ea73836ad375559d76211Chia-chi Yeh 136e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker private synchronized IBinder getToken() { 137e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker if (mToken == null) { 138e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker mToken = new Binder(); 139e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker } 140e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker return mToken; 141e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker } 142e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker 143e35d49f0d2853b79470ec890113bf4dcef03ab88Chad Brubaker public State state(int userId) { 1446b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root final int ret; 1456b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root try { 146e35d49f0d2853b79470ec890113bf4dcef03ab88Chad Brubaker ret = mBinder.getState(userId); 1476b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root } catch (RemoteException e) { 1486b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root Log.w(TAG, "Cannot connect to keystore", e); 1496b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root throw new AssertionError(e); 1506b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root } 1516b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root 1526b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root switch (ret) { 1535cfee3fabb3482c6a6df1c8b6f21e843cf214527Brian Carlstrom case NO_ERROR: return State.UNLOCKED; 1545cfee3fabb3482c6a6df1c8b6f21e843cf214527Brian Carlstrom case LOCKED: return State.LOCKED; 1555cfee3fabb3482c6a6df1c8b6f21e843cf214527Brian Carlstrom case UNINITIALIZED: return State.UNINITIALIZED; 1565cfee3fabb3482c6a6df1c8b6f21e843cf214527Brian Carlstrom default: throw new AssertionError(mError); 1575cfee3fabb3482c6a6df1c8b6f21e843cf214527Brian Carlstrom } 158b9594ce9ebb3f5f303a280f04312ae5754ce3560Kenny Root } 159b9594ce9ebb3f5f303a280f04312ae5754ce3560Kenny Root 160e35d49f0d2853b79470ec890113bf4dcef03ab88Chad Brubaker public State state() { 161e35d49f0d2853b79470ec890113bf4dcef03ab88Chad Brubaker return state(UserHandle.myUserId()); 162e35d49f0d2853b79470ec890113bf4dcef03ab88Chad Brubaker } 163e35d49f0d2853b79470ec890113bf4dcef03ab88Chad Brubaker 164b9594ce9ebb3f5f303a280f04312ae5754ce3560Kenny Root public boolean isUnlocked() { 165b9594ce9ebb3f5f303a280f04312ae5754ce3560Kenny Root return state() == State.UNLOCKED; 16644039172627d1c15737ea73836ad375559d76211Chia-chi Yeh } 16744039172627d1c15737ea73836ad375559d76211Chia-chi Yeh 1685bbf04803f050296a6deab10a3c7104743c4e38cChad Brubaker public byte[] get(String key, int uid) { 1696b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root try { 1705bbf04803f050296a6deab10a3c7104743c4e38cChad Brubaker return mBinder.get(key, uid); 1716b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root } catch (RemoteException e) { 1726b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root Log.w(TAG, "Cannot connect to keystore", e); 1736b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root return null; 1746b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root } 17544039172627d1c15737ea73836ad375559d76211Chia-chi Yeh } 17644039172627d1c15737ea73836ad375559d76211Chia-chi Yeh 1775bbf04803f050296a6deab10a3c7104743c4e38cChad Brubaker public byte[] get(String key) { 1785bbf04803f050296a6deab10a3c7104743c4e38cChad Brubaker return get(key, UID_SELF); 1795bbf04803f050296a6deab10a3c7104743c4e38cChad Brubaker } 1805bbf04803f050296a6deab10a3c7104743c4e38cChad Brubaker 181a3788b00bb221e20abdd42f747d2af419e0a088cKenny Root public boolean put(String key, byte[] value, int uid, int flags) { 1823ceb1a04b44539c2b2c3afec6df487fe128911f2Alex Klyubin return insert(key, value, uid, flags) == NO_ERROR; 1833ceb1a04b44539c2b2c3afec6df487fe128911f2Alex Klyubin } 1843ceb1a04b44539c2b2c3afec6df487fe128911f2Alex Klyubin 1853ceb1a04b44539c2b2c3afec6df487fe128911f2Alex Klyubin public int insert(String key, byte[] value, int uid, int flags) { 1866b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root try { 1873ceb1a04b44539c2b2c3afec6df487fe128911f2Alex Klyubin return mBinder.insert(key, value, uid, flags); 1886b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root } catch (RemoteException e) { 1896b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root Log.w(TAG, "Cannot connect to keystore", e); 1903ceb1a04b44539c2b2c3afec6df487fe128911f2Alex Klyubin return SYSTEM_ERROR; 1916b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root } 19244039172627d1c15737ea73836ad375559d76211Chia-chi Yeh } 19344039172627d1c15737ea73836ad375559d76211Chia-chi Yeh 19478ad849163a7b01073b46fbd7d818392720005d1Kenny Root public boolean delete(String key, int uid) { 1956b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root try { 196e4487ea288e9fea837995d9bc4608c8a4a253ec8Robin Lee int ret = mBinder.del(key, uid); 197e4487ea288e9fea837995d9bc4608c8a4a253ec8Robin Lee return (ret == NO_ERROR || ret == KEY_NOT_FOUND); 1986b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root } catch (RemoteException e) { 1996b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root Log.w(TAG, "Cannot connect to keystore", e); 2006b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root return false; 2016b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root } 20244039172627d1c15737ea73836ad375559d76211Chia-chi Yeh } 20344039172627d1c15737ea73836ad375559d76211Chia-chi Yeh 20478ad849163a7b01073b46fbd7d818392720005d1Kenny Root public boolean delete(String key) { 2052eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root return delete(key, UID_SELF); 20678ad849163a7b01073b46fbd7d818392720005d1Kenny Root } 20778ad849163a7b01073b46fbd7d818392720005d1Kenny Root 20878ad849163a7b01073b46fbd7d818392720005d1Kenny Root public boolean contains(String key, int uid) { 2096b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root try { 21078ad849163a7b01073b46fbd7d818392720005d1Kenny Root return mBinder.exist(key, uid) == NO_ERROR; 2116b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root } catch (RemoteException e) { 2126b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root Log.w(TAG, "Cannot connect to keystore", e); 2136b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root return false; 2146b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root } 21544039172627d1c15737ea73836ad375559d76211Chia-chi Yeh } 21644039172627d1c15737ea73836ad375559d76211Chia-chi Yeh 21778ad849163a7b01073b46fbd7d818392720005d1Kenny Root public boolean contains(String key) { 2182eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root return contains(key, UID_SELF); 21978ad849163a7b01073b46fbd7d818392720005d1Kenny Root } 22078ad849163a7b01073b46fbd7d818392720005d1Kenny Root 221e35d49f0d2853b79470ec890113bf4dcef03ab88Chad Brubaker /** 222e35d49f0d2853b79470ec890113bf4dcef03ab88Chad Brubaker * List all entries in the keystore for {@code uid} starting with {@code prefix}. 223e35d49f0d2853b79470ec890113bf4dcef03ab88Chad Brubaker */ 224e35d49f0d2853b79470ec890113bf4dcef03ab88Chad Brubaker public String[] list(String prefix, int uid) { 2256b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root try { 226e35d49f0d2853b79470ec890113bf4dcef03ab88Chad Brubaker return mBinder.list(prefix, uid); 2276b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root } catch (RemoteException e) { 2286b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root Log.w(TAG, "Cannot connect to keystore", e); 22944039172627d1c15737ea73836ad375559d76211Chia-chi Yeh return null; 23044039172627d1c15737ea73836ad375559d76211Chia-chi Yeh } 23144039172627d1c15737ea73836ad375559d76211Chia-chi Yeh } 23244039172627d1c15737ea73836ad375559d76211Chia-chi Yeh 233e35d49f0d2853b79470ec890113bf4dcef03ab88Chad Brubaker public String[] list(String prefix) { 234e35d49f0d2853b79470ec890113bf4dcef03ab88Chad Brubaker return list(prefix, UID_SELF); 235e35d49f0d2853b79470ec890113bf4dcef03ab88Chad Brubaker } 236e35d49f0d2853b79470ec890113bf4dcef03ab88Chad Brubaker 23744039172627d1c15737ea73836ad375559d76211Chia-chi Yeh public boolean reset() { 2386b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root try { 2396b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root return mBinder.reset() == NO_ERROR; 2406b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root } catch (RemoteException e) { 2416b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root Log.w(TAG, "Cannot connect to keystore", e); 2426b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root return false; 2436b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root } 24444039172627d1c15737ea73836ad375559d76211Chia-chi Yeh } 24544039172627d1c15737ea73836ad375559d76211Chia-chi Yeh 246e35d49f0d2853b79470ec890113bf4dcef03ab88Chad Brubaker /** 247e35d49f0d2853b79470ec890113bf4dcef03ab88Chad Brubaker * Attempt to lock the keystore for {@code user}. 248e35d49f0d2853b79470ec890113bf4dcef03ab88Chad Brubaker * 249e35d49f0d2853b79470ec890113bf4dcef03ab88Chad Brubaker * @param user Android user to lock. 250e35d49f0d2853b79470ec890113bf4dcef03ab88Chad Brubaker * @return whether {@code user}'s keystore was locked. 251e35d49f0d2853b79470ec890113bf4dcef03ab88Chad Brubaker */ 252e35d49f0d2853b79470ec890113bf4dcef03ab88Chad Brubaker public boolean lock(int userId) { 2536b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root try { 254e35d49f0d2853b79470ec890113bf4dcef03ab88Chad Brubaker return mBinder.lock(userId) == NO_ERROR; 2556b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root } catch (RemoteException e) { 2566b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root Log.w(TAG, "Cannot connect to keystore", e); 2576b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root return false; 2586b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root } 25944039172627d1c15737ea73836ad375559d76211Chia-chi Yeh } 26044039172627d1c15737ea73836ad375559d76211Chia-chi Yeh 261e35d49f0d2853b79470ec890113bf4dcef03ab88Chad Brubaker public boolean lock() { 262e35d49f0d2853b79470ec890113bf4dcef03ab88Chad Brubaker return lock(UserHandle.myUserId()); 263e35d49f0d2853b79470ec890113bf4dcef03ab88Chad Brubaker } 264e35d49f0d2853b79470ec890113bf4dcef03ab88Chad Brubaker 265a91a8504191d91d288c55821caa5bf00c9be26a2Chad Brubaker /** 266a91a8504191d91d288c55821caa5bf00c9be26a2Chad Brubaker * Attempt to unlock the keystore for {@code user} with the password {@code password}. 267a91a8504191d91d288c55821caa5bf00c9be26a2Chad Brubaker * This is required before keystore entries created with FLAG_ENCRYPTED can be accessed or 268a91a8504191d91d288c55821caa5bf00c9be26a2Chad Brubaker * created. 269a91a8504191d91d288c55821caa5bf00c9be26a2Chad Brubaker * 270a91a8504191d91d288c55821caa5bf00c9be26a2Chad Brubaker * @param user Android user ID to operate on 271a91a8504191d91d288c55821caa5bf00c9be26a2Chad Brubaker * @param password user's keystore password. Should be the most recent value passed to 272a91a8504191d91d288c55821caa5bf00c9be26a2Chad Brubaker * {@link #onUserPasswordChanged} for the user. 273a91a8504191d91d288c55821caa5bf00c9be26a2Chad Brubaker * 274a91a8504191d91d288c55821caa5bf00c9be26a2Chad Brubaker * @return whether the keystore was unlocked. 275a91a8504191d91d288c55821caa5bf00c9be26a2Chad Brubaker */ 276a91a8504191d91d288c55821caa5bf00c9be26a2Chad Brubaker public boolean unlock(int userId, String password) { 2776b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root try { 278a91a8504191d91d288c55821caa5bf00c9be26a2Chad Brubaker mError = mBinder.unlock(userId, password); 2796b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root return mError == NO_ERROR; 2806b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root } catch (RemoteException e) { 2816b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root Log.w(TAG, "Cannot connect to keystore", e); 2826b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root return false; 2836b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root } 28444039172627d1c15737ea73836ad375559d76211Chia-chi Yeh } 28544039172627d1c15737ea73836ad375559d76211Chia-chi Yeh 286a91a8504191d91d288c55821caa5bf00c9be26a2Chad Brubaker public boolean unlock(String password) { 287a91a8504191d91d288c55821caa5bf00c9be26a2Chad Brubaker return unlock(UserHandle.getUserId(Process.myUid()), password); 288a91a8504191d91d288c55821caa5bf00c9be26a2Chad Brubaker } 289a91a8504191d91d288c55821caa5bf00c9be26a2Chad Brubaker 290e35d49f0d2853b79470ec890113bf4dcef03ab88Chad Brubaker /** 291e35d49f0d2853b79470ec890113bf4dcef03ab88Chad Brubaker * Check if the keystore for {@code userId} is empty. 292e35d49f0d2853b79470ec890113bf4dcef03ab88Chad Brubaker */ 293e35d49f0d2853b79470ec890113bf4dcef03ab88Chad Brubaker public boolean isEmpty(int userId) { 2946b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root try { 295e35d49f0d2853b79470ec890113bf4dcef03ab88Chad Brubaker return mBinder.isEmpty(userId) != 0; 2966b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root } catch (RemoteException e) { 2976b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root Log.w(TAG, "Cannot connect to keystore", e); 2986b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root return false; 2996b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root } 3005423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root } 3015423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root 302e35d49f0d2853b79470ec890113bf4dcef03ab88Chad Brubaker public boolean isEmpty() { 303e35d49f0d2853b79470ec890113bf4dcef03ab88Chad Brubaker return isEmpty(UserHandle.myUserId()); 304e35d49f0d2853b79470ec890113bf4dcef03ab88Chad Brubaker } 305e35d49f0d2853b79470ec890113bf4dcef03ab88Chad Brubaker 306a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root public boolean generate(String key, int uid, int keyType, int keySize, int flags, 307a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root byte[][] args) { 3086b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root try { 3097a2c973db7756a60f1cdd6cf67411115c1576081Chad Brubaker return mBinder.generate(key, uid, keyType, keySize, flags, 3107a2c973db7756a60f1cdd6cf67411115c1576081Chad Brubaker new KeystoreArguments(args)) == NO_ERROR; 3116b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root } catch (RemoteException e) { 3126b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root Log.w(TAG, "Cannot connect to keystore", e); 3136b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root return false; 3146b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root } 3155423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root } 3165423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root 317a3788b00bb221e20abdd42f747d2af419e0a088cKenny Root public boolean importKey(String keyName, byte[] key, int uid, int flags) { 3186b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root try { 319a3788b00bb221e20abdd42f747d2af419e0a088cKenny Root return mBinder.import_key(keyName, key, uid, flags) == NO_ERROR; 3206b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root } catch (RemoteException e) { 3216b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root Log.w(TAG, "Cannot connect to keystore", e); 3226b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root return false; 3236b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root } 3245423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root } 32578ad849163a7b01073b46fbd7d818392720005d1Kenny Root 3265423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root public byte[] sign(String key, byte[] data) { 3276b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root try { 3286b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root return mBinder.sign(key, data); 3296b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root } catch (RemoteException e) { 3306b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root Log.w(TAG, "Cannot connect to keystore", e); 3316b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root return null; 3326b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root } 3335423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root } 3345423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root 3355423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root public boolean verify(String key, byte[] data, byte[] signature) { 3366b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root try { 3376b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root return mBinder.verify(key, data, signature) == NO_ERROR; 3386b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root } catch (RemoteException e) { 3396b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root Log.w(TAG, "Cannot connect to keystore", e); 3406b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root return false; 3416b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root } 3425423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root } 3435423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root 3445423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root public boolean grant(String key, int uid) { 3456b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root try { 3466b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root return mBinder.grant(key, uid) == NO_ERROR; 3476b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root } catch (RemoteException e) { 3486b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root Log.w(TAG, "Cannot connect to keystore", e); 3496b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root return false; 3506b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root } 3515423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root } 3525423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root 3535423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root public boolean ungrant(String key, int uid) { 3546b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root try { 3556b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root return mBinder.ungrant(key, uid) == NO_ERROR; 3566b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root } catch (RemoteException e) { 3576b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root Log.w(TAG, "Cannot connect to keystore", e); 3586b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root return false; 359473c712b19bad992ab4eafcd43175fdce77b913dKenny Root } 360473c712b19bad992ab4eafcd43175fdce77b913dKenny Root } 361473c712b19bad992ab4eafcd43175fdce77b913dKenny Root 362473c712b19bad992ab4eafcd43175fdce77b913dKenny Root /** 363473c712b19bad992ab4eafcd43175fdce77b913dKenny Root * Returns the last modification time of the key in milliseconds since the 364473c712b19bad992ab4eafcd43175fdce77b913dKenny Root * epoch. Will return -1L if the key could not be found or other error. 365473c712b19bad992ab4eafcd43175fdce77b913dKenny Root */ 3665bbf04803f050296a6deab10a3c7104743c4e38cChad Brubaker public long getmtime(String key, int uid) { 3675b1f037829bff93877a6257db69f4e7723a27e20Brian Carlstrom try { 3685bbf04803f050296a6deab10a3c7104743c4e38cChad Brubaker final long millis = mBinder.getmtime(key, uid); 369e66769ad5194cb4533d1087416a2e804ac384285Kenny Root if (millis == -1L) { 370e66769ad5194cb4533d1087416a2e804ac384285Kenny Root return -1L; 371e66769ad5194cb4533d1087416a2e804ac384285Kenny Root } 372e66769ad5194cb4533d1087416a2e804ac384285Kenny Root 373e66769ad5194cb4533d1087416a2e804ac384285Kenny Root return millis * 1000L; 3746b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root } catch (RemoteException e) { 3756b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root Log.w(TAG, "Cannot connect to keystore", e); 3766b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root return -1L; 3775b1f037829bff93877a6257db69f4e7723a27e20Brian Carlstrom } 3785b1f037829bff93877a6257db69f4e7723a27e20Brian Carlstrom } 3795b1f037829bff93877a6257db69f4e7723a27e20Brian Carlstrom 3805bbf04803f050296a6deab10a3c7104743c4e38cChad Brubaker public long getmtime(String key) { 3815bbf04803f050296a6deab10a3c7104743c4e38cChad Brubaker return getmtime(key, UID_SELF); 3825bbf04803f050296a6deab10a3c7104743c4e38cChad Brubaker } 3835bbf04803f050296a6deab10a3c7104743c4e38cChad Brubaker 3845f1d965f7d7e1df50981ffed8faa11fbcc17ca22Kenny Root public boolean duplicate(String srcKey, int srcUid, String destKey, int destUid) { 385bd79419ef84ae31f3765721b50aa413fa462d1d1Kenny Root try { 3865f1d965f7d7e1df50981ffed8faa11fbcc17ca22Kenny Root return mBinder.duplicate(srcKey, srcUid, destKey, destUid) == NO_ERROR; 387bd79419ef84ae31f3765721b50aa413fa462d1d1Kenny Root } catch (RemoteException e) { 388bd79419ef84ae31f3765721b50aa413fa462d1d1Kenny Root Log.w(TAG, "Cannot connect to keystore", e); 389bd79419ef84ae31f3765721b50aa413fa462d1d1Kenny Root return false; 390bd79419ef84ae31f3765721b50aa413fa462d1d1Kenny Root } 391bd79419ef84ae31f3765721b50aa413fa462d1d1Kenny Root } 392bd79419ef84ae31f3765721b50aa413fa462d1d1Kenny Root 393469cbf5156ad54650726ade59f2ee5aa01359ec2Alex Klyubin // TODO: remove this when it's removed from Settings 3945cb5cec6a4a4d5432d4ce6468c12de9508db1633Kenny Root public boolean isHardwareBacked() { 395b91773bce1126d28a93f73fbef18f3a79245f24eKenny Root return isHardwareBacked("RSA"); 396b91773bce1126d28a93f73fbef18f3a79245f24eKenny Root } 397b91773bce1126d28a93f73fbef18f3a79245f24eKenny Root 398b91773bce1126d28a93f73fbef18f3a79245f24eKenny Root public boolean isHardwareBacked(String keyType) { 3995cb5cec6a4a4d5432d4ce6468c12de9508db1633Kenny Root try { 400b91773bce1126d28a93f73fbef18f3a79245f24eKenny Root return mBinder.is_hardware_backed(keyType.toUpperCase(Locale.US)) == NO_ERROR; 4015cb5cec6a4a4d5432d4ce6468c12de9508db1633Kenny Root } catch (RemoteException e) { 4025cb5cec6a4a4d5432d4ce6468c12de9508db1633Kenny Root Log.w(TAG, "Cannot connect to keystore", e); 4035cb5cec6a4a4d5432d4ce6468c12de9508db1633Kenny Root return false; 4045cb5cec6a4a4d5432d4ce6468c12de9508db1633Kenny Root } 4055cb5cec6a4a4d5432d4ce6468c12de9508db1633Kenny Root } 4065cb5cec6a4a4d5432d4ce6468c12de9508db1633Kenny Root 407d72317abd79ddf95d48c8f35bf1070900ff55b5eKenny Root public boolean clearUid(int uid) { 408d72317abd79ddf95d48c8f35bf1070900ff55b5eKenny Root try { 409d72317abd79ddf95d48c8f35bf1070900ff55b5eKenny Root return mBinder.clear_uid(uid) == NO_ERROR; 410d72317abd79ddf95d48c8f35bf1070900ff55b5eKenny Root } catch (RemoteException e) { 411d72317abd79ddf95d48c8f35bf1070900ff55b5eKenny Root Log.w(TAG, "Cannot connect to keystore", e); 412d72317abd79ddf95d48c8f35bf1070900ff55b5eKenny Root return false; 413d72317abd79ddf95d48c8f35bf1070900ff55b5eKenny Root } 414d72317abd79ddf95d48c8f35bf1070900ff55b5eKenny Root } 415d72317abd79ddf95d48c8f35bf1070900ff55b5eKenny Root 4166b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root public int getLastError() { 4176b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root return mError; 41834c47c855815d731e6deb55748ff690b0ec7b53fNick Kralevich } 419e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker 420e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker public boolean addRngEntropy(byte[] data) { 421e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker try { 422e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker return mBinder.addRngEntropy(data) == NO_ERROR; 423e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker } catch (RemoteException e) { 424e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker Log.w(TAG, "Cannot connect to keystore", e); 425e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker return false; 426e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker } 427e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker } 428e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker 429dae79e540844741fc35c648efe8bbb00fc8ab781Chad Brubaker public int generateKey(String alias, KeymasterArguments args, byte[] entropy, int uid, 430dae79e540844741fc35c648efe8bbb00fc8ab781Chad Brubaker int flags, KeyCharacteristics outCharacteristics) { 431e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker try { 432dae79e540844741fc35c648efe8bbb00fc8ab781Chad Brubaker return mBinder.generateKey(alias, args, entropy, uid, flags, outCharacteristics); 433e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker } catch (RemoteException e) { 434e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker Log.w(TAG, "Cannot connect to keystore", e); 435e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker return SYSTEM_ERROR; 436e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker } 437e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker } 438e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker 439dae79e540844741fc35c648efe8bbb00fc8ab781Chad Brubaker public int generateKey(String alias, KeymasterArguments args, byte[] entropy, int flags, 440e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker KeyCharacteristics outCharacteristics) { 441dae79e540844741fc35c648efe8bbb00fc8ab781Chad Brubaker return generateKey(alias, args, entropy, UID_SELF, flags, outCharacteristics); 442e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker } 443e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker 4445e73c0eec2bc77222a5a87fb2a135d8303836411Chad Brubaker public int getKeyCharacteristics(String alias, KeymasterBlob clientId, KeymasterBlob appId, 4455bbf04803f050296a6deab10a3c7104743c4e38cChad Brubaker int uid, KeyCharacteristics outCharacteristics) { 446e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker try { 4475bbf04803f050296a6deab10a3c7104743c4e38cChad Brubaker return mBinder.getKeyCharacteristics(alias, clientId, appId, uid, outCharacteristics); 448e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker } catch (RemoteException e) { 449e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker Log.w(TAG, "Cannot connect to keystore", e); 450e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker return SYSTEM_ERROR; 451e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker } 452e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker } 453e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker 4545bbf04803f050296a6deab10a3c7104743c4e38cChad Brubaker public int getKeyCharacteristics(String alias, KeymasterBlob clientId, KeymasterBlob appId, 4555bbf04803f050296a6deab10a3c7104743c4e38cChad Brubaker KeyCharacteristics outCharacteristics) { 4565bbf04803f050296a6deab10a3c7104743c4e38cChad Brubaker return getKeyCharacteristics(alias, clientId, appId, UID_SELF, outCharacteristics); 4575bbf04803f050296a6deab10a3c7104743c4e38cChad Brubaker } 4585bbf04803f050296a6deab10a3c7104743c4e38cChad Brubaker 459e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker public int importKey(String alias, KeymasterArguments args, int format, byte[] keyData, 460e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker int uid, int flags, KeyCharacteristics outCharacteristics) { 461e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker try { 462e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker return mBinder.importKey(alias, args, format, keyData, uid, flags, 463e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker outCharacteristics); 464e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker } catch (RemoteException e) { 465e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker Log.w(TAG, "Cannot connect to keystore", e); 466e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker return SYSTEM_ERROR; 467e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker } 468e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker } 469e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker 470e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker public int importKey(String alias, KeymasterArguments args, int format, byte[] keyData, 471e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker int flags, KeyCharacteristics outCharacteristics) { 472e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker return importKey(alias, args, format, keyData, UID_SELF, flags, outCharacteristics); 473e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker } 474e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker 4755e73c0eec2bc77222a5a87fb2a135d8303836411Chad Brubaker public ExportResult exportKey(String alias, int format, KeymasterBlob clientId, 4765bbf04803f050296a6deab10a3c7104743c4e38cChad Brubaker KeymasterBlob appId, int uid) { 477e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker try { 4785bbf04803f050296a6deab10a3c7104743c4e38cChad Brubaker return mBinder.exportKey(alias, format, clientId, appId, uid); 479e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker } catch (RemoteException e) { 480e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker Log.w(TAG, "Cannot connect to keystore", e); 481e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker return null; 482e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker } 483e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker } 4845bbf04803f050296a6deab10a3c7104743c4e38cChad Brubaker public ExportResult exportKey(String alias, int format, KeymasterBlob clientId, 4855bbf04803f050296a6deab10a3c7104743c4e38cChad Brubaker KeymasterBlob appId) { 4865bbf04803f050296a6deab10a3c7104743c4e38cChad Brubaker return exportKey(alias, format, clientId, appId, UID_SELF); 4875bbf04803f050296a6deab10a3c7104743c4e38cChad Brubaker } 488e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker 489e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker public OperationResult begin(String alias, int purpose, boolean pruneable, 4905bbf04803f050296a6deab10a3c7104743c4e38cChad Brubaker KeymasterArguments args, byte[] entropy, int uid) { 491e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker try { 4925bbf04803f050296a6deab10a3c7104743c4e38cChad Brubaker return mBinder.begin(getToken(), alias, purpose, pruneable, args, entropy, uid); 493e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker } catch (RemoteException e) { 494e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker Log.w(TAG, "Cannot connect to keystore", e); 495e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker return null; 496e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker } 497e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker } 498e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker 4995bbf04803f050296a6deab10a3c7104743c4e38cChad Brubaker public OperationResult begin(String alias, int purpose, boolean pruneable, 5005bbf04803f050296a6deab10a3c7104743c4e38cChad Brubaker KeymasterArguments args, byte[] entropy) { 5015bbf04803f050296a6deab10a3c7104743c4e38cChad Brubaker return begin(alias, purpose, pruneable, args, entropy, UID_SELF); 5025bbf04803f050296a6deab10a3c7104743c4e38cChad Brubaker } 5035bbf04803f050296a6deab10a3c7104743c4e38cChad Brubaker 504e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker public OperationResult update(IBinder token, KeymasterArguments arguments, byte[] input) { 505e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker try { 506e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker return mBinder.update(token, arguments, input); 507e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker } catch (RemoteException e) { 508e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker Log.w(TAG, "Cannot connect to keystore", e); 509e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker return null; 510e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker } 511e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker } 512e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker 5138a07701f3817ad0b76b82cfc464868e8f57e359dChad Brubaker public OperationResult finish(IBinder token, KeymasterArguments arguments, byte[] signature, 5148a07701f3817ad0b76b82cfc464868e8f57e359dChad Brubaker byte[] entropy) { 515e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker try { 5168a07701f3817ad0b76b82cfc464868e8f57e359dChad Brubaker return mBinder.finish(token, arguments, signature, entropy); 517e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker } catch (RemoteException e) { 518e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker Log.w(TAG, "Cannot connect to keystore", e); 519e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker return null; 520e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker } 521e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker } 522e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker 5238a07701f3817ad0b76b82cfc464868e8f57e359dChad Brubaker public OperationResult finish(IBinder token, KeymasterArguments arguments, byte[] signature) { 5248a07701f3817ad0b76b82cfc464868e8f57e359dChad Brubaker return finish(token, arguments, signature, null); 5258a07701f3817ad0b76b82cfc464868e8f57e359dChad Brubaker } 5268a07701f3817ad0b76b82cfc464868e8f57e359dChad Brubaker 527e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker public int abort(IBinder token) { 528e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker try { 529e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker return mBinder.abort(token); 530e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker } catch (RemoteException e) { 531e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker Log.w(TAG, "Cannot connect to keystore", e); 532e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker return SYSTEM_ERROR; 533e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker } 534e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker } 5355654b36b4667431e49d27c07a06d275656071e75Chad Brubaker 5365654b36b4667431e49d27c07a06d275656071e75Chad Brubaker /** 5375654b36b4667431e49d27c07a06d275656071e75Chad Brubaker * Check if the operation referenced by {@code token} is currently authorized. 5385654b36b4667431e49d27c07a06d275656071e75Chad Brubaker * 539708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubin * @param token An operation token returned by a call to 540708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubin * {@link #begin(String, int, boolean, KeymasterArguments, byte[], KeymasterArguments) begin}. 5415654b36b4667431e49d27c07a06d275656071e75Chad Brubaker */ 5425654b36b4667431e49d27c07a06d275656071e75Chad Brubaker public boolean isOperationAuthorized(IBinder token) { 5435654b36b4667431e49d27c07a06d275656071e75Chad Brubaker try { 5445654b36b4667431e49d27c07a06d275656071e75Chad Brubaker return mBinder.isOperationAuthorized(token); 5455654b36b4667431e49d27c07a06d275656071e75Chad Brubaker } catch (RemoteException e) { 5465654b36b4667431e49d27c07a06d275656071e75Chad Brubaker Log.w(TAG, "Cannot connect to keystore", e); 5475654b36b4667431e49d27c07a06d275656071e75Chad Brubaker return false; 5485654b36b4667431e49d27c07a06d275656071e75Chad Brubaker } 5495654b36b4667431e49d27c07a06d275656071e75Chad Brubaker } 5505654b36b4667431e49d27c07a06d275656071e75Chad Brubaker 5515654b36b4667431e49d27c07a06d275656071e75Chad Brubaker /** 5525654b36b4667431e49d27c07a06d275656071e75Chad Brubaker * Add an authentication record to the keystore authorization table. 5535654b36b4667431e49d27c07a06d275656071e75Chad Brubaker * 5545654b36b4667431e49d27c07a06d275656071e75Chad Brubaker * @param authToken The packed bytes of a hw_auth_token_t to be provided to keymaster. 5555654b36b4667431e49d27c07a06d275656071e75Chad Brubaker * @return {@code KeyStore.NO_ERROR} on success, otherwise an error value corresponding to 5565654b36b4667431e49d27c07a06d275656071e75Chad Brubaker * a {@code KeymasterDefs.KM_ERROR_} value or {@code KeyStore} ResponseCode. 5575654b36b4667431e49d27c07a06d275656071e75Chad Brubaker */ 5585654b36b4667431e49d27c07a06d275656071e75Chad Brubaker public int addAuthToken(byte[] authToken) { 5595654b36b4667431e49d27c07a06d275656071e75Chad Brubaker try { 5605654b36b4667431e49d27c07a06d275656071e75Chad Brubaker return mBinder.addAuthToken(authToken); 5615654b36b4667431e49d27c07a06d275656071e75Chad Brubaker } catch (RemoteException e) { 5625654b36b4667431e49d27c07a06d275656071e75Chad Brubaker Log.w(TAG, "Cannot connect to keystore", e); 5635654b36b4667431e49d27c07a06d275656071e75Chad Brubaker return SYSTEM_ERROR; 5645654b36b4667431e49d27c07a06d275656071e75Chad Brubaker } 5655654b36b4667431e49d27c07a06d275656071e75Chad Brubaker } 566b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin 567ad9ba10ecda10c14e46d00f40fc3e431cc2d9bc2Alex Klyubin /** 568a91a8504191d91d288c55821caa5bf00c9be26a2Chad Brubaker * Notify keystore that a user's password has changed. 569a91a8504191d91d288c55821caa5bf00c9be26a2Chad Brubaker * 570a91a8504191d91d288c55821caa5bf00c9be26a2Chad Brubaker * @param userId the user whose password changed. 571a91a8504191d91d288c55821caa5bf00c9be26a2Chad Brubaker * @param newPassword the new password or "" if the password was removed. 572a91a8504191d91d288c55821caa5bf00c9be26a2Chad Brubaker */ 573a91a8504191d91d288c55821caa5bf00c9be26a2Chad Brubaker public boolean onUserPasswordChanged(int userId, String newPassword) { 574a91a8504191d91d288c55821caa5bf00c9be26a2Chad Brubaker // Parcel.cpp doesn't support deserializing null strings and treats them as "". Make that 575a91a8504191d91d288c55821caa5bf00c9be26a2Chad Brubaker // explicit here. 576a91a8504191d91d288c55821caa5bf00c9be26a2Chad Brubaker if (newPassword == null) { 577a91a8504191d91d288c55821caa5bf00c9be26a2Chad Brubaker newPassword = ""; 578a91a8504191d91d288c55821caa5bf00c9be26a2Chad Brubaker } 579a91a8504191d91d288c55821caa5bf00c9be26a2Chad Brubaker try { 580a91a8504191d91d288c55821caa5bf00c9be26a2Chad Brubaker return mBinder.onUserPasswordChanged(userId, newPassword) == NO_ERROR; 581a91a8504191d91d288c55821caa5bf00c9be26a2Chad Brubaker } catch (RemoteException e) { 582a91a8504191d91d288c55821caa5bf00c9be26a2Chad Brubaker Log.w(TAG, "Cannot connect to keystore", e); 583a91a8504191d91d288c55821caa5bf00c9be26a2Chad Brubaker return false; 584a91a8504191d91d288c55821caa5bf00c9be26a2Chad Brubaker } 585a91a8504191d91d288c55821caa5bf00c9be26a2Chad Brubaker } 586a91a8504191d91d288c55821caa5bf00c9be26a2Chad Brubaker 58783ce095c848b972156256855d0f2a2ff4aa068fdChad Brubaker /** 58883ce095c848b972156256855d0f2a2ff4aa068fdChad Brubaker * Notify keystore that a user was added. 58983ce095c848b972156256855d0f2a2ff4aa068fdChad Brubaker * 59083ce095c848b972156256855d0f2a2ff4aa068fdChad Brubaker * @param userId the new user. 59183ce095c848b972156256855d0f2a2ff4aa068fdChad Brubaker * @param parentId the parent of the new user, or -1 if the user has no parent. If parentId is 59283ce095c848b972156256855d0f2a2ff4aa068fdChad Brubaker * specified then the new user's keystore will be intialized with the same secure lockscreen 59383ce095c848b972156256855d0f2a2ff4aa068fdChad Brubaker * password as the parent. 59483ce095c848b972156256855d0f2a2ff4aa068fdChad Brubaker */ 59583ce095c848b972156256855d0f2a2ff4aa068fdChad Brubaker public void onUserAdded(int userId, int parentId) { 59683ce095c848b972156256855d0f2a2ff4aa068fdChad Brubaker try { 59783ce095c848b972156256855d0f2a2ff4aa068fdChad Brubaker mBinder.onUserAdded(userId, parentId); 59883ce095c848b972156256855d0f2a2ff4aa068fdChad Brubaker } catch (RemoteException e) { 59983ce095c848b972156256855d0f2a2ff4aa068fdChad Brubaker Log.w(TAG, "Cannot connect to keystore", e); 60083ce095c848b972156256855d0f2a2ff4aa068fdChad Brubaker } 60183ce095c848b972156256855d0f2a2ff4aa068fdChad Brubaker } 60283ce095c848b972156256855d0f2a2ff4aa068fdChad Brubaker 60383ce095c848b972156256855d0f2a2ff4aa068fdChad Brubaker /** 60483ce095c848b972156256855d0f2a2ff4aa068fdChad Brubaker * Notify keystore that a user was added. 60583ce095c848b972156256855d0f2a2ff4aa068fdChad Brubaker * 60683ce095c848b972156256855d0f2a2ff4aa068fdChad Brubaker * @param userId the new user. 60783ce095c848b972156256855d0f2a2ff4aa068fdChad Brubaker */ 60883ce095c848b972156256855d0f2a2ff4aa068fdChad Brubaker public void onUserAdded(int userId) { 60983ce095c848b972156256855d0f2a2ff4aa068fdChad Brubaker onUserAdded(userId, -1); 61083ce095c848b972156256855d0f2a2ff4aa068fdChad Brubaker } 61183ce095c848b972156256855d0f2a2ff4aa068fdChad Brubaker 61283ce095c848b972156256855d0f2a2ff4aa068fdChad Brubaker /** 61383ce095c848b972156256855d0f2a2ff4aa068fdChad Brubaker * Notify keystore that a user was removed. 61483ce095c848b972156256855d0f2a2ff4aa068fdChad Brubaker * 61583ce095c848b972156256855d0f2a2ff4aa068fdChad Brubaker * @param userId the removed user. 61683ce095c848b972156256855d0f2a2ff4aa068fdChad Brubaker */ 61783ce095c848b972156256855d0f2a2ff4aa068fdChad Brubaker public void onUserRemoved(int userId) { 61883ce095c848b972156256855d0f2a2ff4aa068fdChad Brubaker try { 61983ce095c848b972156256855d0f2a2ff4aa068fdChad Brubaker mBinder.onUserRemoved(userId); 62083ce095c848b972156256855d0f2a2ff4aa068fdChad Brubaker } catch (RemoteException e) { 62183ce095c848b972156256855d0f2a2ff4aa068fdChad Brubaker Log.w(TAG, "Cannot connect to keystore", e); 62283ce095c848b972156256855d0f2a2ff4aa068fdChad Brubaker } 62383ce095c848b972156256855d0f2a2ff4aa068fdChad Brubaker } 62483ce095c848b972156256855d0f2a2ff4aa068fdChad Brubaker 625a91a8504191d91d288c55821caa5bf00c9be26a2Chad Brubaker public boolean onUserPasswordChanged(String newPassword) { 626a91a8504191d91d288c55821caa5bf00c9be26a2Chad Brubaker return onUserPasswordChanged(UserHandle.getUserId(Process.myUid()), newPassword); 627a91a8504191d91d288c55821caa5bf00c9be26a2Chad Brubaker } 628a91a8504191d91d288c55821caa5bf00c9be26a2Chad Brubaker 6298d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden public int attestKey( 6308d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden String alias, KeymasterArguments params, KeymasterCertificateChain outChain) { 6318d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden try { 6328d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden return mBinder.attestKey(alias, params, outChain); 6338d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden } catch (RemoteException e) { 6348d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden Log.w(TAG, "Cannot connect to keystore", e); 6358d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden return SYSTEM_ERROR; 6368d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden } 6378d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden } 6388d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden 639237f4b369bfd8021882007d103b9921fca789263Bartosz Fabianowski public int attestDeviceIds(KeymasterArguments params, KeymasterCertificateChain outChain) { 640237f4b369bfd8021882007d103b9921fca789263Bartosz Fabianowski try { 641237f4b369bfd8021882007d103b9921fca789263Bartosz Fabianowski return mBinder.attestDeviceIds(params, outChain); 642237f4b369bfd8021882007d103b9921fca789263Bartosz Fabianowski } catch (RemoteException e) { 643237f4b369bfd8021882007d103b9921fca789263Bartosz Fabianowski Log.w(TAG, "Cannot connect to keystore", e); 644237f4b369bfd8021882007d103b9921fca789263Bartosz Fabianowski return SYSTEM_ERROR; 645237f4b369bfd8021882007d103b9921fca789263Bartosz Fabianowski } 646237f4b369bfd8021882007d103b9921fca789263Bartosz Fabianowski } 647237f4b369bfd8021882007d103b9921fca789263Bartosz Fabianowski 648b32aae2a46bc3678e11c7f0ca88e01a192829490Tucker Sylvestro /** 649b32aae2a46bc3678e11c7f0ca88e01a192829490Tucker Sylvestro * Notify keystore that the device went off-body. 650b32aae2a46bc3678e11c7f0ca88e01a192829490Tucker Sylvestro */ 651b32aae2a46bc3678e11c7f0ca88e01a192829490Tucker Sylvestro public void onDeviceOffBody() { 652b32aae2a46bc3678e11c7f0ca88e01a192829490Tucker Sylvestro try { 653b32aae2a46bc3678e11c7f0ca88e01a192829490Tucker Sylvestro mBinder.onDeviceOffBody(); 654b32aae2a46bc3678e11c7f0ca88e01a192829490Tucker Sylvestro } catch (RemoteException e) { 655b32aae2a46bc3678e11c7f0ca88e01a192829490Tucker Sylvestro Log.w(TAG, "Cannot connect to keystore", e); 656b32aae2a46bc3678e11c7f0ca88e01a192829490Tucker Sylvestro } 657b32aae2a46bc3678e11c7f0ca88e01a192829490Tucker Sylvestro } 6588d8c7477746c357d54f586fc92e8d422a4fc6441Shawn Willden 659a91a8504191d91d288c55821caa5bf00c9be26a2Chad Brubaker /** 660ad9ba10ecda10c14e46d00f40fc3e431cc2d9bc2Alex Klyubin * Returns a {@link KeyStoreException} corresponding to the provided keystore/keymaster error 661ad9ba10ecda10c14e46d00f40fc3e431cc2d9bc2Alex Klyubin * code. 662ad9ba10ecda10c14e46d00f40fc3e431cc2d9bc2Alex Klyubin */ 663dcdaf87ed0aa99073638bcfe645949f130f0c7adAlex Klyubin public static KeyStoreException getKeyStoreException(int errorCode) { 664b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin if (errorCode > 0) { 665b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin // KeyStore layer error 666b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin switch (errorCode) { 667b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin case NO_ERROR: 668b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin return new KeyStoreException(errorCode, "OK"); 669b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin case LOCKED: 6705418393c58d1d80fe37a209ab931f6d56bd46a86Alex Klyubin return new KeyStoreException(errorCode, "User authentication required"); 671b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin case UNINITIALIZED: 672b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin return new KeyStoreException(errorCode, "Keystore not initialized"); 673b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin case SYSTEM_ERROR: 674b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin return new KeyStoreException(errorCode, "System error"); 675b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin case PERMISSION_DENIED: 676b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin return new KeyStoreException(errorCode, "Permission denied"); 677b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin case KEY_NOT_FOUND: 678b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin return new KeyStoreException(errorCode, "Key not found"); 679b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin case VALUE_CORRUPTED: 680b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin return new KeyStoreException(errorCode, "Key blob corrupted"); 681058de02073a129301d391c22b050f2d65adadb0fAlex Klyubin case OP_AUTH_NEEDED: 682058de02073a129301d391c22b050f2d65adadb0fAlex Klyubin return new KeyStoreException(errorCode, "Operation requires authorization"); 683b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin default: 684b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin return new KeyStoreException(errorCode, String.valueOf(errorCode)); 685b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin } 686b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin } else { 687b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin // Keymaster layer error 688b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin switch (errorCode) { 689b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin case KeymasterDefs.KM_ERROR_INVALID_AUTHORIZATION_TIMEOUT: 690b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin // The name of this parameter significantly differs between Keymaster and 691b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin // framework APIs. Use the framework wording to make life easier for developers. 692b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin return new KeyStoreException(errorCode, 693b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin "Invalid user authentication validity duration"); 694b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin default: 695b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin return new KeyStoreException(errorCode, 696b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin KeymasterDefs.getErrorMessage(errorCode)); 697b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin } 698b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin } 699b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin } 700b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin 701ad9ba10ecda10c14e46d00f40fc3e431cc2d9bc2Alex Klyubin /** 702ad9ba10ecda10c14e46d00f40fc3e431cc2d9bc2Alex Klyubin * Returns an {@link InvalidKeyException} corresponding to the provided 703ad9ba10ecda10c14e46d00f40fc3e431cc2d9bc2Alex Klyubin * {@link KeyStoreException}. 704ad9ba10ecda10c14e46d00f40fc3e431cc2d9bc2Alex Klyubin */ 705dcdaf87ed0aa99073638bcfe645949f130f0c7adAlex Klyubin public InvalidKeyException getInvalidKeyException( 7063876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin String keystoreKeyAlias, int uid, KeyStoreException e) { 707b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin switch (e.getErrorCode()) { 7085418393c58d1d80fe37a209ab931f6d56bd46a86Alex Klyubin case LOCKED: 7095418393c58d1d80fe37a209ab931f6d56bd46a86Alex Klyubin return new UserNotAuthenticatedException(); 710b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin case KeymasterDefs.KM_ERROR_KEY_EXPIRED: 711b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin return new KeyExpiredException(); 712b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin case KeymasterDefs.KM_ERROR_KEY_NOT_YET_VALID: 713b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin return new KeyNotYetValidException(); 714b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin case KeymasterDefs.KM_ERROR_KEY_USER_NOT_AUTHENTICATED: 715058de02073a129301d391c22b050f2d65adadb0fAlex Klyubin case OP_AUTH_NEEDED: 716708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubin { 717708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubin // We now need to determine whether the key/operation can become usable if user 718708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubin // authentication is performed, or whether it can never become usable again. 719708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubin // User authentication requirements are contained in the key's characteristics. We 720708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubin // need to check whether these requirements can be be satisfied by asking the user 721708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubin // to authenticate. 722708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubin KeyCharacteristics keyCharacteristics = new KeyCharacteristics(); 723708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubin int getKeyCharacteristicsErrorCode = 7243876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin getKeyCharacteristics(keystoreKeyAlias, null, null, uid, 7253876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin keyCharacteristics); 726708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubin if (getKeyCharacteristicsErrorCode != NO_ERROR) { 727708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubin return new InvalidKeyException( 728708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubin "Failed to obtained key characteristics", 729708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubin getKeyStoreException(getKeyCharacteristicsErrorCode)); 730708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubin } 731ae6cb7aad56bb006769cd8a69b92af7236644fc1Alex Klyubin List<BigInteger> keySids = 732ae6cb7aad56bb006769cd8a69b92af7236644fc1Alex Klyubin keyCharacteristics.getUnsignedLongs(KeymasterDefs.KM_TAG_USER_SECURE_ID); 733708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubin if (keySids.isEmpty()) { 734708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubin // Key is not bound to any SIDs -- no amount of authentication will help here. 735708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubin return new KeyPermanentlyInvalidatedException(); 736708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubin } 737708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubin long rootSid = GateKeeper.getSecureUserId(); 738ae6cb7aad56bb006769cd8a69b92af7236644fc1Alex Klyubin if ((rootSid != 0) && (keySids.contains(KeymasterArguments.toUint64(rootSid)))) { 739708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubin // One of the key's SIDs is the current root SID -- user can be authenticated 740708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubin // against that SID. 741708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubin return new UserNotAuthenticatedException(); 742708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubin } 743708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubin 744708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubin long fingerprintOnlySid = getFingerprintOnlySid(); 745708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubin if ((fingerprintOnlySid != 0) 746ae6cb7aad56bb006769cd8a69b92af7236644fc1Alex Klyubin && (keySids.contains(KeymasterArguments.toUint64(fingerprintOnlySid)))) { 747708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubin // One of the key's SIDs is the current fingerprint SID -- user can be 748708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubin // authenticated against that SID. 749708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubin return new UserNotAuthenticatedException(); 750708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubin } 751708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubin 752708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubin // None of the key's SIDs can ever be authenticated 753708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubin return new KeyPermanentlyInvalidatedException(); 754708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubin } 755b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin default: 756ad9ba10ecda10c14e46d00f40fc3e431cc2d9bc2Alex Klyubin return new InvalidKeyException("Keystore operation failed", e); 757b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin } 758b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin } 759b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin 7602d7a85cd2b2ab4dbbe09354c6ae1668bff51a514Alex Klyubin private long getFingerprintOnlySid() { 761a99b8b5e3fe456b74b9f86e12bebebb5e418f58eAlex Klyubin FingerprintManager fingerprintManager = mContext.getSystemService(FingerprintManager.class); 7622d7a85cd2b2ab4dbbe09354c6ae1668bff51a514Alex Klyubin if (fingerprintManager == null) { 763708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubin return 0; 764708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubin } 765708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubin 766a99b8b5e3fe456b74b9f86e12bebebb5e418f58eAlex Klyubin // TODO: Restore USE_FINGERPRINT permission check in 767a99b8b5e3fe456b74b9f86e12bebebb5e418f58eAlex Klyubin // FingerprintManager.getAuthenticatorId once the ID is no longer needed here. 7682d7a85cd2b2ab4dbbe09354c6ae1668bff51a514Alex Klyubin return fingerprintManager.getAuthenticatorId(); 7692dac95d03399bb9fa59999e4964d7f8bcd485c38Svetoslav } 7702dac95d03399bb9fa59999e4964d7f8bcd485c38Svetoslav 771ad9ba10ecda10c14e46d00f40fc3e431cc2d9bc2Alex Klyubin /** 772ad9ba10ecda10c14e46d00f40fc3e431cc2d9bc2Alex Klyubin * Returns an {@link InvalidKeyException} corresponding to the provided keystore/keymaster error 773ad9ba10ecda10c14e46d00f40fc3e431cc2d9bc2Alex Klyubin * code. 774ad9ba10ecda10c14e46d00f40fc3e431cc2d9bc2Alex Klyubin */ 7753876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin public InvalidKeyException getInvalidKeyException(String keystoreKeyAlias, int uid, 7763876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin int errorCode) { 7773876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin return getInvalidKeyException(keystoreKeyAlias, uid, getKeyStoreException(errorCode)); 778b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin } 77944039172627d1c15737ea73836ad375559d76211Chia-chi Yeh} 780