KeyStore.java revision dcdaf87ed0aa99073638bcfe645949f130f0c7ad
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; 226bf52c4271bd0483174fe3755caedb778693791eAdam Langleyimport com.android.org.conscrypt.NativeConstants; 23a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root 24708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubinimport android.content.Context; 252d7a85cd2b2ab4dbbe09354c6ae1668bff51a514Alex Klyubinimport android.hardware.fingerprint.FingerprintManager; 26e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubakerimport android.os.Binder; 27e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubakerimport android.os.IBinder; 28a91a8504191d91d288c55821caa5bf00c9be26a2Chad Brubakerimport android.os.Process; 296b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Rootimport android.os.RemoteException; 306b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Rootimport android.os.ServiceManager; 31a91a8504191d91d288c55821caa5bf00c9be26a2Chad Brubakerimport android.os.UserHandle; 32e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubakerimport android.security.keymaster.ExportResult; 33e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubakerimport android.security.keymaster.KeyCharacteristics; 34e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubakerimport android.security.keymaster.KeymasterArguments; 355e73c0eec2bc77222a5a87fb2a135d8303836411Chad Brubakerimport android.security.keymaster.KeymasterBlob; 36b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubinimport android.security.keymaster.KeymasterDefs; 37e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubakerimport android.security.keymaster.OperationResult; 383f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubinimport android.security.keystore.KeyExpiredException; 393f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubinimport android.security.keystore.KeyNotYetValidException; 403f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubinimport android.security.keystore.KeyPermanentlyInvalidatedException; 413f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubinimport android.security.keystore.KeyProperties; 423f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubinimport android.security.keystore.UserNotAuthenticatedException; 436b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Rootimport android.util.Log; 4444039172627d1c15737ea73836ad375559d76211Chia-chi Yeh 45ad9ba10ecda10c14e46d00f40fc3e431cc2d9bc2Alex Klyubinimport java.security.InvalidKeyException; 46708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubinimport java.util.List; 47b91773bce1126d28a93f73fbef18f3a79245f24eKenny Rootimport java.util.Locale; 48b91773bce1126d28a93f73fbef18f3a79245f24eKenny Root 4944039172627d1c15737ea73836ad375559d76211Chia-chi Yeh/** 5046703b099516c383a6882815bcf9cd4df0ec538dBrian Carlstrom * @hide This should not be made public in its present form because it 5146703b099516c383a6882815bcf9cd4df0ec538dBrian Carlstrom * assumes that private and secret key bytes are available and would 5246703b099516c383a6882815bcf9cd4df0ec538dBrian Carlstrom * preclude the use of hardware crypto. 5344039172627d1c15737ea73836ad375559d76211Chia-chi Yeh */ 5444039172627d1c15737ea73836ad375559d76211Chia-chi Yehpublic class KeyStore { 556b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root private static final String TAG = "KeyStore"; 565cfee3fabb3482c6a6df1c8b6f21e843cf214527Brian Carlstrom 575cfee3fabb3482c6a6df1c8b6f21e843cf214527Brian Carlstrom // ResponseCodes 587e4b1a488dd02c4bf6156379e36834e9e01c5b1bBrian Carlstrom public static final int NO_ERROR = 1; 597e4b1a488dd02c4bf6156379e36834e9e01c5b1bBrian Carlstrom public static final int LOCKED = 2; 607e4b1a488dd02c4bf6156379e36834e9e01c5b1bBrian Carlstrom public static final int UNINITIALIZED = 3; 617e4b1a488dd02c4bf6156379e36834e9e01c5b1bBrian Carlstrom public static final int SYSTEM_ERROR = 4; 627e4b1a488dd02c4bf6156379e36834e9e01c5b1bBrian Carlstrom public static final int PROTOCOL_ERROR = 5; 637e4b1a488dd02c4bf6156379e36834e9e01c5b1bBrian Carlstrom public static final int PERMISSION_DENIED = 6; 647e4b1a488dd02c4bf6156379e36834e9e01c5b1bBrian Carlstrom public static final int KEY_NOT_FOUND = 7; 657e4b1a488dd02c4bf6156379e36834e9e01c5b1bBrian Carlstrom public static final int VALUE_CORRUPTED = 8; 667e4b1a488dd02c4bf6156379e36834e9e01c5b1bBrian Carlstrom public static final int UNDEFINED_ACTION = 9; 677e4b1a488dd02c4bf6156379e36834e9e01c5b1bBrian Carlstrom public static final int WRONG_PASSWORD = 10; 685cfee3fabb3482c6a6df1c8b6f21e843cf214527Brian Carlstrom 69560d653e554882218232cd0fe4711be42145727aChad Brubaker /** 70560d653e554882218232cd0fe4711be42145727aChad Brubaker * Per operation authentication is needed before this operation is valid. 71560d653e554882218232cd0fe4711be42145727aChad Brubaker * This is returned from {@link #begin} when begin succeeds but the operation uses 72560d653e554882218232cd0fe4711be42145727aChad Brubaker * per-operation authentication and must authenticate before calling {@link #update} or 73560d653e554882218232cd0fe4711be42145727aChad Brubaker * {@link #finish}. 74560d653e554882218232cd0fe4711be42145727aChad Brubaker */ 75560d653e554882218232cd0fe4711be42145727aChad Brubaker public static final int OP_AUTH_NEEDED = 15; 76560d653e554882218232cd0fe4711be42145727aChad Brubaker 772eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root // Used for UID field to indicate the calling UID. 782eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root public static final int UID_SELF = -1; 792eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root 802eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root // Flags for "put" "import" and "generate" 812eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root public static final int FLAG_NONE = 0; 825418393c58d1d80fe37a209ab931f6d56bd46a86Alex Klyubin 835418393c58d1d80fe37a209ab931f6d56bd46a86Alex Klyubin /** 845418393c58d1d80fe37a209ab931f6d56bd46a86Alex Klyubin * Indicates that this key (or key pair) must be encrypted at rest. This will protect the key 855418393c58d1d80fe37a209ab931f6d56bd46a86Alex Klyubin * (or key pair) with the secure lock screen credential (e.g., password, PIN, or pattern). 865418393c58d1d80fe37a209ab931f6d56bd46a86Alex Klyubin * 875418393c58d1d80fe37a209ab931f6d56bd46a86Alex Klyubin * <p>Note that this requires that the secure lock screen (e.g., password, PIN, pattern) is set 885418393c58d1d80fe37a209ab931f6d56bd46a86Alex Klyubin * up, otherwise key (or key pair) generation or import will fail. Moreover, this key (or key 895418393c58d1d80fe37a209ab931f6d56bd46a86Alex Klyubin * pair) will be deleted when the secure lock screen is disabled or reset (e.g., by the user or 905418393c58d1d80fe37a209ab931f6d56bd46a86Alex Klyubin * a Device Administrator). Finally, this key (or key pair) cannot be used until the user 915418393c58d1d80fe37a209ab931f6d56bd46a86Alex Klyubin * unlocks the secure lock screen after boot. 925418393c58d1d80fe37a209ab931f6d56bd46a86Alex Klyubin * 935418393c58d1d80fe37a209ab931f6d56bd46a86Alex Klyubin * @see KeyguardManager#isDeviceSecure() 945418393c58d1d80fe37a209ab931f6d56bd46a86Alex Klyubin */ 95a3788b00bb221e20abdd42f747d2af419e0a088cKenny Root public static final int FLAG_ENCRYPTED = 1; 96a3788b00bb221e20abdd42f747d2af419e0a088cKenny Root 975cfee3fabb3482c6a6df1c8b6f21e843cf214527Brian Carlstrom // States 985cfee3fabb3482c6a6df1c8b6f21e843cf214527Brian Carlstrom public enum State { UNLOCKED, LOCKED, UNINITIALIZED }; 9944039172627d1c15737ea73836ad375559d76211Chia-chi Yeh 10044039172627d1c15737ea73836ad375559d76211Chia-chi Yeh private int mError = NO_ERROR; 10144039172627d1c15737ea73836ad375559d76211Chia-chi Yeh 1026b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root private final IKeystoreService mBinder; 1032d7a85cd2b2ab4dbbe09354c6ae1668bff51a514Alex Klyubin private final Context mContext; 1046b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root 105e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker private IBinder mToken; 106e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker 1076b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root private KeyStore(IKeystoreService binder) { 1086b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root mBinder = binder; 1093f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin mContext = getApplicationContext(); 1102d7a85cd2b2ab4dbbe09354c6ae1668bff51a514Alex Klyubin } 1112d7a85cd2b2ab4dbbe09354c6ae1668bff51a514Alex Klyubin 112dcdaf87ed0aa99073638bcfe645949f130f0c7adAlex Klyubin public static Context getApplicationContext() { 1132d7a85cd2b2ab4dbbe09354c6ae1668bff51a514Alex Klyubin ActivityThread activityThread = ActivityThread.currentActivityThread(); 1142d7a85cd2b2ab4dbbe09354c6ae1668bff51a514Alex Klyubin if (activityThread == null) { 1152d7a85cd2b2ab4dbbe09354c6ae1668bff51a514Alex Klyubin throw new IllegalStateException( 1162d7a85cd2b2ab4dbbe09354c6ae1668bff51a514Alex Klyubin "Failed to obtain application Context: no ActivityThread"); 1172d7a85cd2b2ab4dbbe09354c6ae1668bff51a514Alex Klyubin } 1182d7a85cd2b2ab4dbbe09354c6ae1668bff51a514Alex Klyubin Application application = activityThread.getApplication(); 1192d7a85cd2b2ab4dbbe09354c6ae1668bff51a514Alex Klyubin if (application == null) { 1202d7a85cd2b2ab4dbbe09354c6ae1668bff51a514Alex Klyubin throw new IllegalStateException( 1212d7a85cd2b2ab4dbbe09354c6ae1668bff51a514Alex Klyubin "Failed to obtain application Context: no Application"); 1222d7a85cd2b2ab4dbbe09354c6ae1668bff51a514Alex Klyubin } 1232d7a85cd2b2ab4dbbe09354c6ae1668bff51a514Alex Klyubin return application; 1246b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root } 12544039172627d1c15737ea73836ad375559d76211Chia-chi Yeh 12644039172627d1c15737ea73836ad375559d76211Chia-chi Yeh public static KeyStore getInstance() { 1276b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root IKeystoreService keystore = IKeystoreService.Stub.asInterface(ServiceManager 1286b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root .getService("android.security.keystore")); 1296b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root return new KeyStore(keystore); 13044039172627d1c15737ea73836ad375559d76211Chia-chi Yeh } 13144039172627d1c15737ea73836ad375559d76211Chia-chi Yeh 132e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker private synchronized IBinder getToken() { 133e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker if (mToken == null) { 134e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker mToken = new Binder(); 135e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker } 136e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker return mToken; 137e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker } 138e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker 139dcdaf87ed0aa99073638bcfe645949f130f0c7adAlex Klyubin public static int getKeyTypeForAlgorithm(@KeyProperties.KeyAlgorithmEnum String keyType) { 1403f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin if (KeyProperties.KEY_ALGORITHM_RSA.equalsIgnoreCase(keyType)) { 1416bf52c4271bd0483174fe3755caedb778693791eAdam Langley return NativeConstants.EVP_PKEY_RSA; 1423f8d4d840894468f2be8a5b56ff266cef2d71c50Alex Klyubin } else if (KeyProperties.KEY_ALGORITHM_EC.equalsIgnoreCase(keyType)) { 1436bf52c4271bd0483174fe3755caedb778693791eAdam Langley return NativeConstants.EVP_PKEY_EC; 144a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root } else { 14521a76df55cf4b956f4d34f57c7b9e694d0363f54Alex Klyubin return -1; 146a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root } 147a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root } 148a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root 1495cfee3fabb3482c6a6df1c8b6f21e843cf214527Brian Carlstrom public State state() { 1506b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root final int ret; 1516b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root try { 1526b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root ret = mBinder.test(); 1536b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root } catch (RemoteException e) { 1546b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root Log.w(TAG, "Cannot connect to keystore", e); 1556b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root throw new AssertionError(e); 1566b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root } 1576b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root 1586b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root switch (ret) { 1595cfee3fabb3482c6a6df1c8b6f21e843cf214527Brian Carlstrom case NO_ERROR: return State.UNLOCKED; 1605cfee3fabb3482c6a6df1c8b6f21e843cf214527Brian Carlstrom case LOCKED: return State.LOCKED; 1615cfee3fabb3482c6a6df1c8b6f21e843cf214527Brian Carlstrom case UNINITIALIZED: return State.UNINITIALIZED; 1625cfee3fabb3482c6a6df1c8b6f21e843cf214527Brian Carlstrom default: throw new AssertionError(mError); 1635cfee3fabb3482c6a6df1c8b6f21e843cf214527Brian Carlstrom } 164b9594ce9ebb3f5f303a280f04312ae5754ce3560Kenny Root } 165b9594ce9ebb3f5f303a280f04312ae5754ce3560Kenny Root 166b9594ce9ebb3f5f303a280f04312ae5754ce3560Kenny Root public boolean isUnlocked() { 167b9594ce9ebb3f5f303a280f04312ae5754ce3560Kenny Root return state() == State.UNLOCKED; 16844039172627d1c15737ea73836ad375559d76211Chia-chi Yeh } 16944039172627d1c15737ea73836ad375559d76211Chia-chi Yeh 1705cfee3fabb3482c6a6df1c8b6f21e843cf214527Brian Carlstrom public byte[] get(String key) { 1716b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root try { 1726b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root return mBinder.get(key); 1736b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root } catch (RemoteException e) { 1746b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root Log.w(TAG, "Cannot connect to keystore", e); 1756b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root return null; 1766b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root } 17744039172627d1c15737ea73836ad375559d76211Chia-chi Yeh } 17844039172627d1c15737ea73836ad375559d76211Chia-chi Yeh 179a3788b00bb221e20abdd42f747d2af419e0a088cKenny Root public boolean put(String key, byte[] value, int uid, int flags) { 1806b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root try { 181a3788b00bb221e20abdd42f747d2af419e0a088cKenny Root return mBinder.insert(key, value, uid, flags) == NO_ERROR; 1826b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root } catch (RemoteException e) { 1836b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root Log.w(TAG, "Cannot connect to keystore", e); 1846b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root return false; 1856b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root } 18644039172627d1c15737ea73836ad375559d76211Chia-chi Yeh } 18744039172627d1c15737ea73836ad375559d76211Chia-chi Yeh 18878ad849163a7b01073b46fbd7d818392720005d1Kenny Root public boolean delete(String key, int uid) { 1896b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root try { 19078ad849163a7b01073b46fbd7d818392720005d1Kenny Root return mBinder.del(key, uid) == NO_ERROR; 1916b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root } catch (RemoteException e) { 1926b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root Log.w(TAG, "Cannot connect to keystore", e); 1936b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root return false; 1946b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root } 19544039172627d1c15737ea73836ad375559d76211Chia-chi Yeh } 19644039172627d1c15737ea73836ad375559d76211Chia-chi Yeh 19778ad849163a7b01073b46fbd7d818392720005d1Kenny Root public boolean delete(String key) { 1982eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root return delete(key, UID_SELF); 19978ad849163a7b01073b46fbd7d818392720005d1Kenny Root } 20078ad849163a7b01073b46fbd7d818392720005d1Kenny Root 20178ad849163a7b01073b46fbd7d818392720005d1Kenny Root public boolean contains(String key, int uid) { 2026b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root try { 20378ad849163a7b01073b46fbd7d818392720005d1Kenny Root return mBinder.exist(key, uid) == NO_ERROR; 2046b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root } catch (RemoteException e) { 2056b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root Log.w(TAG, "Cannot connect to keystore", e); 2066b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root return false; 2076b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root } 20844039172627d1c15737ea73836ad375559d76211Chia-chi Yeh } 20944039172627d1c15737ea73836ad375559d76211Chia-chi Yeh 21078ad849163a7b01073b46fbd7d818392720005d1Kenny Root public boolean contains(String key) { 2112eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root return contains(key, UID_SELF); 21278ad849163a7b01073b46fbd7d818392720005d1Kenny Root } 21378ad849163a7b01073b46fbd7d818392720005d1Kenny Root 21478ad849163a7b01073b46fbd7d818392720005d1Kenny Root public String[] saw(String prefix, int uid) { 2156b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root try { 21678ad849163a7b01073b46fbd7d818392720005d1Kenny Root return mBinder.saw(prefix, uid); 2176b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root } catch (RemoteException e) { 2186b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root Log.w(TAG, "Cannot connect to keystore", e); 21944039172627d1c15737ea73836ad375559d76211Chia-chi Yeh return null; 22044039172627d1c15737ea73836ad375559d76211Chia-chi Yeh } 22144039172627d1c15737ea73836ad375559d76211Chia-chi Yeh } 22244039172627d1c15737ea73836ad375559d76211Chia-chi Yeh 22378ad849163a7b01073b46fbd7d818392720005d1Kenny Root public String[] saw(String prefix) { 2242eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root return saw(prefix, UID_SELF); 22578ad849163a7b01073b46fbd7d818392720005d1Kenny Root } 22678ad849163a7b01073b46fbd7d818392720005d1Kenny Root 22744039172627d1c15737ea73836ad375559d76211Chia-chi Yeh public boolean reset() { 2286b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root try { 2296b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root return mBinder.reset() == NO_ERROR; 2306b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root } catch (RemoteException e) { 2316b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root Log.w(TAG, "Cannot connect to keystore", e); 2326b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root return false; 2336b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root } 23444039172627d1c15737ea73836ad375559d76211Chia-chi Yeh } 23544039172627d1c15737ea73836ad375559d76211Chia-chi Yeh 23644039172627d1c15737ea73836ad375559d76211Chia-chi Yeh public boolean lock() { 2376b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root try { 2386b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root return mBinder.lock() == NO_ERROR; 2396b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root } catch (RemoteException e) { 2406b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root Log.w(TAG, "Cannot connect to keystore", e); 2416b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root return false; 2426b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root } 24344039172627d1c15737ea73836ad375559d76211Chia-chi Yeh } 24444039172627d1c15737ea73836ad375559d76211Chia-chi Yeh 245a91a8504191d91d288c55821caa5bf00c9be26a2Chad Brubaker /** 246a91a8504191d91d288c55821caa5bf00c9be26a2Chad Brubaker * Attempt to unlock the keystore for {@code user} with the password {@code password}. 247a91a8504191d91d288c55821caa5bf00c9be26a2Chad Brubaker * This is required before keystore entries created with FLAG_ENCRYPTED can be accessed or 248a91a8504191d91d288c55821caa5bf00c9be26a2Chad Brubaker * created. 249a91a8504191d91d288c55821caa5bf00c9be26a2Chad Brubaker * 250a91a8504191d91d288c55821caa5bf00c9be26a2Chad Brubaker * @param user Android user ID to operate on 251a91a8504191d91d288c55821caa5bf00c9be26a2Chad Brubaker * @param password user's keystore password. Should be the most recent value passed to 252a91a8504191d91d288c55821caa5bf00c9be26a2Chad Brubaker * {@link #onUserPasswordChanged} for the user. 253a91a8504191d91d288c55821caa5bf00c9be26a2Chad Brubaker * 254a91a8504191d91d288c55821caa5bf00c9be26a2Chad Brubaker * @return whether the keystore was unlocked. 255a91a8504191d91d288c55821caa5bf00c9be26a2Chad Brubaker */ 256a91a8504191d91d288c55821caa5bf00c9be26a2Chad Brubaker public boolean unlock(int userId, String password) { 2576b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root try { 258a91a8504191d91d288c55821caa5bf00c9be26a2Chad Brubaker mError = mBinder.unlock(userId, password); 2596b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root return mError == NO_ERROR; 2606b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root } catch (RemoteException e) { 2616b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root Log.w(TAG, "Cannot connect to keystore", e); 2626b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root return false; 2636b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root } 26444039172627d1c15737ea73836ad375559d76211Chia-chi Yeh } 26544039172627d1c15737ea73836ad375559d76211Chia-chi Yeh 266a91a8504191d91d288c55821caa5bf00c9be26a2Chad Brubaker public boolean unlock(String password) { 267a91a8504191d91d288c55821caa5bf00c9be26a2Chad Brubaker return unlock(UserHandle.getUserId(Process.myUid()), password); 268a91a8504191d91d288c55821caa5bf00c9be26a2Chad Brubaker } 269a91a8504191d91d288c55821caa5bf00c9be26a2Chad Brubaker 2705cfee3fabb3482c6a6df1c8b6f21e843cf214527Brian Carlstrom public boolean isEmpty() { 2716b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root try { 2726b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root return mBinder.zero() == KEY_NOT_FOUND; 2736b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root } catch (RemoteException e) { 2746b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root Log.w(TAG, "Cannot connect to keystore", e); 2756b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root return false; 2766b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root } 2775423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root } 2785423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root 279a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root public boolean generate(String key, int uid, int keyType, int keySize, int flags, 280a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root byte[][] args) { 2816b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root try { 2827a2c973db7756a60f1cdd6cf67411115c1576081Chad Brubaker return mBinder.generate(key, uid, keyType, keySize, flags, 2837a2c973db7756a60f1cdd6cf67411115c1576081Chad Brubaker new KeystoreArguments(args)) == NO_ERROR; 2846b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root } catch (RemoteException e) { 2856b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root Log.w(TAG, "Cannot connect to keystore", e); 2866b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root return false; 2876b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root } 2885423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root } 2895423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root 290a3788b00bb221e20abdd42f747d2af419e0a088cKenny Root public boolean importKey(String keyName, byte[] key, int uid, int flags) { 2916b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root try { 292a3788b00bb221e20abdd42f747d2af419e0a088cKenny Root return mBinder.import_key(keyName, key, uid, flags) == NO_ERROR; 2936b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root } catch (RemoteException e) { 2946b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root Log.w(TAG, "Cannot connect to keystore", e); 2956b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root return false; 2966b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root } 2975423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root } 2985423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root 2995423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root public byte[] getPubkey(String key) { 3006b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root try { 3016b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root return mBinder.get_pubkey(key); 3026b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root } catch (RemoteException e) { 3036b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root Log.w(TAG, "Cannot connect to keystore", e); 3046b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root return null; 3056b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root } 3065423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root } 3075423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root 30878ad849163a7b01073b46fbd7d818392720005d1Kenny Root public boolean delKey(String key, int uid) { 3096b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root try { 31078ad849163a7b01073b46fbd7d818392720005d1Kenny Root return mBinder.del_key(key, uid) == 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 31778ad849163a7b01073b46fbd7d818392720005d1Kenny Root public boolean delKey(String key) { 3182eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root return delKey(key, UID_SELF); 31978ad849163a7b01073b46fbd7d818392720005d1Kenny Root } 32078ad849163a7b01073b46fbd7d818392720005d1Kenny Root 3215423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root public byte[] sign(String key, byte[] data) { 3226b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root try { 3236b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root return mBinder.sign(key, data); 3246b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root } catch (RemoteException e) { 3256b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root Log.w(TAG, "Cannot connect to keystore", e); 3266b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root return null; 3276b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root } 3285423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root } 3295423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root 3305423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root public boolean verify(String key, byte[] data, byte[] signature) { 3316b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root try { 3326b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root return mBinder.verify(key, data, signature) == NO_ERROR; 3336b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root } catch (RemoteException e) { 3346b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root Log.w(TAG, "Cannot connect to keystore", e); 3356b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root return false; 3366b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root } 3375423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root } 3385423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root 3395423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root public boolean grant(String key, int uid) { 3406b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root try { 3416b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root return mBinder.grant(key, uid) == NO_ERROR; 3426b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root } catch (RemoteException e) { 3436b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root Log.w(TAG, "Cannot connect to keystore", e); 3446b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root return false; 3456b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root } 3465423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root } 3475423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root 3485423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root public boolean ungrant(String key, int uid) { 3496b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root try { 3506b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root return mBinder.ungrant(key, uid) == NO_ERROR; 3516b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root } catch (RemoteException e) { 3526b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root Log.w(TAG, "Cannot connect to keystore", e); 3536b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root return false; 354473c712b19bad992ab4eafcd43175fdce77b913dKenny Root } 355473c712b19bad992ab4eafcd43175fdce77b913dKenny Root } 356473c712b19bad992ab4eafcd43175fdce77b913dKenny Root 357473c712b19bad992ab4eafcd43175fdce77b913dKenny Root /** 358473c712b19bad992ab4eafcd43175fdce77b913dKenny Root * Returns the last modification time of the key in milliseconds since the 359473c712b19bad992ab4eafcd43175fdce77b913dKenny Root * epoch. Will return -1L if the key could not be found or other error. 360473c712b19bad992ab4eafcd43175fdce77b913dKenny Root */ 361473c712b19bad992ab4eafcd43175fdce77b913dKenny Root public long getmtime(String key) { 3625b1f037829bff93877a6257db69f4e7723a27e20Brian Carlstrom try { 363e66769ad5194cb4533d1087416a2e804ac384285Kenny Root final long millis = mBinder.getmtime(key); 364e66769ad5194cb4533d1087416a2e804ac384285Kenny Root if (millis == -1L) { 365e66769ad5194cb4533d1087416a2e804ac384285Kenny Root return -1L; 366e66769ad5194cb4533d1087416a2e804ac384285Kenny Root } 367e66769ad5194cb4533d1087416a2e804ac384285Kenny Root 368e66769ad5194cb4533d1087416a2e804ac384285Kenny Root return millis * 1000L; 3696b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root } catch (RemoteException e) { 3706b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root Log.w(TAG, "Cannot connect to keystore", e); 3716b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root return -1L; 3725b1f037829bff93877a6257db69f4e7723a27e20Brian Carlstrom } 3735b1f037829bff93877a6257db69f4e7723a27e20Brian Carlstrom } 3745b1f037829bff93877a6257db69f4e7723a27e20Brian Carlstrom 3755f1d965f7d7e1df50981ffed8faa11fbcc17ca22Kenny Root public boolean duplicate(String srcKey, int srcUid, String destKey, int destUid) { 376bd79419ef84ae31f3765721b50aa413fa462d1d1Kenny Root try { 3775f1d965f7d7e1df50981ffed8faa11fbcc17ca22Kenny Root return mBinder.duplicate(srcKey, srcUid, destKey, destUid) == NO_ERROR; 378bd79419ef84ae31f3765721b50aa413fa462d1d1Kenny Root } catch (RemoteException e) { 379bd79419ef84ae31f3765721b50aa413fa462d1d1Kenny Root Log.w(TAG, "Cannot connect to keystore", e); 380bd79419ef84ae31f3765721b50aa413fa462d1d1Kenny Root return false; 381bd79419ef84ae31f3765721b50aa413fa462d1d1Kenny Root } 382bd79419ef84ae31f3765721b50aa413fa462d1d1Kenny Root } 383bd79419ef84ae31f3765721b50aa413fa462d1d1Kenny Root 384b91773bce1126d28a93f73fbef18f3a79245f24eKenny Root // TODO remove this when it's removed from Settings 3855cb5cec6a4a4d5432d4ce6468c12de9508db1633Kenny Root public boolean isHardwareBacked() { 386b91773bce1126d28a93f73fbef18f3a79245f24eKenny Root return isHardwareBacked("RSA"); 387b91773bce1126d28a93f73fbef18f3a79245f24eKenny Root } 388b91773bce1126d28a93f73fbef18f3a79245f24eKenny Root 389b91773bce1126d28a93f73fbef18f3a79245f24eKenny Root public boolean isHardwareBacked(String keyType) { 3905cb5cec6a4a4d5432d4ce6468c12de9508db1633Kenny Root try { 391b91773bce1126d28a93f73fbef18f3a79245f24eKenny Root return mBinder.is_hardware_backed(keyType.toUpperCase(Locale.US)) == NO_ERROR; 3925cb5cec6a4a4d5432d4ce6468c12de9508db1633Kenny Root } catch (RemoteException e) { 3935cb5cec6a4a4d5432d4ce6468c12de9508db1633Kenny Root Log.w(TAG, "Cannot connect to keystore", e); 3945cb5cec6a4a4d5432d4ce6468c12de9508db1633Kenny Root return false; 3955cb5cec6a4a4d5432d4ce6468c12de9508db1633Kenny Root } 3965cb5cec6a4a4d5432d4ce6468c12de9508db1633Kenny Root } 3975cb5cec6a4a4d5432d4ce6468c12de9508db1633Kenny Root 398d72317abd79ddf95d48c8f35bf1070900ff55b5eKenny Root public boolean clearUid(int uid) { 399d72317abd79ddf95d48c8f35bf1070900ff55b5eKenny Root try { 400d72317abd79ddf95d48c8f35bf1070900ff55b5eKenny Root return mBinder.clear_uid(uid) == NO_ERROR; 401d72317abd79ddf95d48c8f35bf1070900ff55b5eKenny Root } catch (RemoteException e) { 402d72317abd79ddf95d48c8f35bf1070900ff55b5eKenny Root Log.w(TAG, "Cannot connect to keystore", e); 403d72317abd79ddf95d48c8f35bf1070900ff55b5eKenny Root return false; 404d72317abd79ddf95d48c8f35bf1070900ff55b5eKenny Root } 405d72317abd79ddf95d48c8f35bf1070900ff55b5eKenny Root } 406d72317abd79ddf95d48c8f35bf1070900ff55b5eKenny Root 407f0246a8a14d69680d1776620e75a485cf963e574Robin Lee public boolean resetUid(int uid) { 408f0246a8a14d69680d1776620e75a485cf963e574Robin Lee try { 409f0246a8a14d69680d1776620e75a485cf963e574Robin Lee mError = mBinder.reset_uid(uid); 410f0246a8a14d69680d1776620e75a485cf963e574Robin Lee return mError == NO_ERROR; 411f0246a8a14d69680d1776620e75a485cf963e574Robin Lee } catch (RemoteException e) { 412f0246a8a14d69680d1776620e75a485cf963e574Robin Lee Log.w(TAG, "Cannot connect to keystore", e); 413f0246a8a14d69680d1776620e75a485cf963e574Robin Lee return false; 414f0246a8a14d69680d1776620e75a485cf963e574Robin Lee } 415f0246a8a14d69680d1776620e75a485cf963e574Robin Lee } 416f0246a8a14d69680d1776620e75a485cf963e574Robin Lee 417f0246a8a14d69680d1776620e75a485cf963e574Robin Lee public boolean syncUid(int sourceUid, int targetUid) { 418f0246a8a14d69680d1776620e75a485cf963e574Robin Lee try { 419f0246a8a14d69680d1776620e75a485cf963e574Robin Lee mError = mBinder.sync_uid(sourceUid, targetUid); 420f0246a8a14d69680d1776620e75a485cf963e574Robin Lee return mError == NO_ERROR; 421f0246a8a14d69680d1776620e75a485cf963e574Robin Lee } catch (RemoteException e) { 422f0246a8a14d69680d1776620e75a485cf963e574Robin Lee Log.w(TAG, "Cannot connect to keystore", e); 423f0246a8a14d69680d1776620e75a485cf963e574Robin Lee return false; 424f0246a8a14d69680d1776620e75a485cf963e574Robin Lee } 425f0246a8a14d69680d1776620e75a485cf963e574Robin Lee } 426f0246a8a14d69680d1776620e75a485cf963e574Robin Lee 427f0246a8a14d69680d1776620e75a485cf963e574Robin Lee public boolean passwordUid(String password, int uid) { 428f0246a8a14d69680d1776620e75a485cf963e574Robin Lee try { 429f0246a8a14d69680d1776620e75a485cf963e574Robin Lee mError = mBinder.password_uid(password, uid); 430f0246a8a14d69680d1776620e75a485cf963e574Robin Lee return mError == NO_ERROR; 431f0246a8a14d69680d1776620e75a485cf963e574Robin Lee } catch (RemoteException e) { 432f0246a8a14d69680d1776620e75a485cf963e574Robin Lee Log.w(TAG, "Cannot connect to keystore", e); 433f0246a8a14d69680d1776620e75a485cf963e574Robin Lee return false; 434f0246a8a14d69680d1776620e75a485cf963e574Robin Lee } 435f0246a8a14d69680d1776620e75a485cf963e574Robin Lee } 436f0246a8a14d69680d1776620e75a485cf963e574Robin Lee 4376b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root public int getLastError() { 4386b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root return mError; 43934c47c855815d731e6deb55748ff690b0ec7b53fNick Kralevich } 440e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker 441e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker public boolean addRngEntropy(byte[] data) { 442e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker try { 443e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker return mBinder.addRngEntropy(data) == NO_ERROR; 444e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker } catch (RemoteException e) { 445e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker Log.w(TAG, "Cannot connect to keystore", e); 446e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker return false; 447e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker } 448e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker } 449e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker 450dae79e540844741fc35c648efe8bbb00fc8ab781Chad Brubaker public int generateKey(String alias, KeymasterArguments args, byte[] entropy, int uid, 451dae79e540844741fc35c648efe8bbb00fc8ab781Chad Brubaker int flags, KeyCharacteristics outCharacteristics) { 452e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker try { 453dae79e540844741fc35c648efe8bbb00fc8ab781Chad Brubaker return mBinder.generateKey(alias, args, entropy, uid, flags, outCharacteristics); 454e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker } catch (RemoteException e) { 455e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker Log.w(TAG, "Cannot connect to keystore", e); 456e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker return SYSTEM_ERROR; 457e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker } 458e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker } 459e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker 460dae79e540844741fc35c648efe8bbb00fc8ab781Chad Brubaker public int generateKey(String alias, KeymasterArguments args, byte[] entropy, int flags, 461e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker KeyCharacteristics outCharacteristics) { 462dae79e540844741fc35c648efe8bbb00fc8ab781Chad Brubaker return generateKey(alias, args, entropy, UID_SELF, flags, outCharacteristics); 463e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker } 464e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker 4655e73c0eec2bc77222a5a87fb2a135d8303836411Chad Brubaker public int getKeyCharacteristics(String alias, KeymasterBlob clientId, KeymasterBlob appId, 466e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker KeyCharacteristics outCharacteristics) { 467e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker try { 468e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker return mBinder.getKeyCharacteristics(alias, clientId, appId, outCharacteristics); 469e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker } catch (RemoteException e) { 470e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker Log.w(TAG, "Cannot connect to keystore", e); 471e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker return SYSTEM_ERROR; 472e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker } 473e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker } 474e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker 475e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker public int importKey(String alias, KeymasterArguments args, int format, byte[] keyData, 476e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker int uid, int flags, KeyCharacteristics outCharacteristics) { 477e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker try { 478e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker return mBinder.importKey(alias, args, format, keyData, uid, flags, 479e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker outCharacteristics); 480e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker } catch (RemoteException e) { 481e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker Log.w(TAG, "Cannot connect to keystore", e); 482e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker return SYSTEM_ERROR; 483e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker } 484e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker } 485e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker 486e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker public int importKey(String alias, KeymasterArguments args, int format, byte[] keyData, 487e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker int flags, KeyCharacteristics outCharacteristics) { 488e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker return importKey(alias, args, format, keyData, UID_SELF, flags, outCharacteristics); 489e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker } 490e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker 4915e73c0eec2bc77222a5a87fb2a135d8303836411Chad Brubaker public ExportResult exportKey(String alias, int format, KeymasterBlob clientId, 4925e73c0eec2bc77222a5a87fb2a135d8303836411Chad Brubaker KeymasterBlob appId) { 493e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker try { 494e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker return mBinder.exportKey(alias, format, clientId, appId); 495e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker } catch (RemoteException e) { 496e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker Log.w(TAG, "Cannot connect to keystore", e); 497e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker return null; 498e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker } 499e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker } 500e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker 501e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker public OperationResult begin(String alias, int purpose, boolean pruneable, 502dae79e540844741fc35c648efe8bbb00fc8ab781Chad Brubaker KeymasterArguments args, byte[] entropy, KeymasterArguments outArgs) { 503e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker try { 504dae79e540844741fc35c648efe8bbb00fc8ab781Chad Brubaker return mBinder.begin(getToken(), alias, purpose, pruneable, args, entropy, outArgs); 505e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker } catch (RemoteException e) { 506e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker Log.w(TAG, "Cannot connect to keystore", e); 507e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker return null; 508e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker } 509e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker } 510e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker 511e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker public OperationResult update(IBinder token, KeymasterArguments arguments, byte[] input) { 512e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker try { 513e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker return mBinder.update(token, arguments, input); 514e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker } catch (RemoteException e) { 515e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker Log.w(TAG, "Cannot connect to keystore", e); 516e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker return null; 517e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker } 518e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker } 519e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker 520e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker public OperationResult finish(IBinder token, KeymasterArguments arguments, byte[] signature) { 521e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker try { 522e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker return mBinder.finish(token, arguments, signature); 523e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker } catch (RemoteException e) { 524e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker Log.w(TAG, "Cannot connect to keystore", e); 525e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker return null; 526e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker } 527e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker } 528e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker 529e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker public int abort(IBinder token) { 530e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker try { 531e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker return mBinder.abort(token); 532e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker } catch (RemoteException e) { 533e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker Log.w(TAG, "Cannot connect to keystore", e); 534e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker return SYSTEM_ERROR; 535e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker } 536e6a461341ccf3b952427daf40c973d9914cdb270Chad Brubaker } 5375654b36b4667431e49d27c07a06d275656071e75Chad Brubaker 5385654b36b4667431e49d27c07a06d275656071e75Chad Brubaker /** 5395654b36b4667431e49d27c07a06d275656071e75Chad Brubaker * Check if the operation referenced by {@code token} is currently authorized. 5405654b36b4667431e49d27c07a06d275656071e75Chad Brubaker * 541708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubin * @param token An operation token returned by a call to 542708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubin * {@link #begin(String, int, boolean, KeymasterArguments, byte[], KeymasterArguments) begin}. 5435654b36b4667431e49d27c07a06d275656071e75Chad Brubaker */ 5445654b36b4667431e49d27c07a06d275656071e75Chad Brubaker public boolean isOperationAuthorized(IBinder token) { 5455654b36b4667431e49d27c07a06d275656071e75Chad Brubaker try { 5465654b36b4667431e49d27c07a06d275656071e75Chad Brubaker return mBinder.isOperationAuthorized(token); 5475654b36b4667431e49d27c07a06d275656071e75Chad Brubaker } catch (RemoteException e) { 5485654b36b4667431e49d27c07a06d275656071e75Chad Brubaker Log.w(TAG, "Cannot connect to keystore", e); 5495654b36b4667431e49d27c07a06d275656071e75Chad Brubaker return false; 5505654b36b4667431e49d27c07a06d275656071e75Chad Brubaker } 5515654b36b4667431e49d27c07a06d275656071e75Chad Brubaker } 5525654b36b4667431e49d27c07a06d275656071e75Chad Brubaker 5535654b36b4667431e49d27c07a06d275656071e75Chad Brubaker /** 5545654b36b4667431e49d27c07a06d275656071e75Chad Brubaker * Add an authentication record to the keystore authorization table. 5555654b36b4667431e49d27c07a06d275656071e75Chad Brubaker * 5565654b36b4667431e49d27c07a06d275656071e75Chad Brubaker * @param authToken The packed bytes of a hw_auth_token_t to be provided to keymaster. 5575654b36b4667431e49d27c07a06d275656071e75Chad Brubaker * @return {@code KeyStore.NO_ERROR} on success, otherwise an error value corresponding to 5585654b36b4667431e49d27c07a06d275656071e75Chad Brubaker * a {@code KeymasterDefs.KM_ERROR_} value or {@code KeyStore} ResponseCode. 5595654b36b4667431e49d27c07a06d275656071e75Chad Brubaker */ 5605654b36b4667431e49d27c07a06d275656071e75Chad Brubaker public int addAuthToken(byte[] authToken) { 5615654b36b4667431e49d27c07a06d275656071e75Chad Brubaker try { 5625654b36b4667431e49d27c07a06d275656071e75Chad Brubaker return mBinder.addAuthToken(authToken); 5635654b36b4667431e49d27c07a06d275656071e75Chad Brubaker } catch (RemoteException e) { 5645654b36b4667431e49d27c07a06d275656071e75Chad Brubaker Log.w(TAG, "Cannot connect to keystore", e); 5655654b36b4667431e49d27c07a06d275656071e75Chad Brubaker return SYSTEM_ERROR; 5665654b36b4667431e49d27c07a06d275656071e75Chad Brubaker } 5675654b36b4667431e49d27c07a06d275656071e75Chad Brubaker } 568b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin 569ad9ba10ecda10c14e46d00f40fc3e431cc2d9bc2Alex Klyubin /** 570a91a8504191d91d288c55821caa5bf00c9be26a2Chad Brubaker * Notify keystore that a user's password has changed. 571a91a8504191d91d288c55821caa5bf00c9be26a2Chad Brubaker * 572a91a8504191d91d288c55821caa5bf00c9be26a2Chad Brubaker * @param userId the user whose password changed. 573a91a8504191d91d288c55821caa5bf00c9be26a2Chad Brubaker * @param newPassword the new password or "" if the password was removed. 574a91a8504191d91d288c55821caa5bf00c9be26a2Chad Brubaker */ 575a91a8504191d91d288c55821caa5bf00c9be26a2Chad Brubaker public boolean onUserPasswordChanged(int userId, String newPassword) { 576a91a8504191d91d288c55821caa5bf00c9be26a2Chad Brubaker // Parcel.cpp doesn't support deserializing null strings and treats them as "". Make that 577a91a8504191d91d288c55821caa5bf00c9be26a2Chad Brubaker // explicit here. 578a91a8504191d91d288c55821caa5bf00c9be26a2Chad Brubaker if (newPassword == null) { 579a91a8504191d91d288c55821caa5bf00c9be26a2Chad Brubaker newPassword = ""; 580a91a8504191d91d288c55821caa5bf00c9be26a2Chad Brubaker } 581a91a8504191d91d288c55821caa5bf00c9be26a2Chad Brubaker try { 582a91a8504191d91d288c55821caa5bf00c9be26a2Chad Brubaker return mBinder.onUserPasswordChanged(userId, newPassword) == NO_ERROR; 583a91a8504191d91d288c55821caa5bf00c9be26a2Chad Brubaker } catch (RemoteException e) { 584a91a8504191d91d288c55821caa5bf00c9be26a2Chad Brubaker Log.w(TAG, "Cannot connect to keystore", e); 585a91a8504191d91d288c55821caa5bf00c9be26a2Chad Brubaker return false; 586a91a8504191d91d288c55821caa5bf00c9be26a2Chad Brubaker } 587a91a8504191d91d288c55821caa5bf00c9be26a2Chad Brubaker } 588a91a8504191d91d288c55821caa5bf00c9be26a2Chad Brubaker 58983ce095c848b972156256855d0f2a2ff4aa068fdChad Brubaker /** 59083ce095c848b972156256855d0f2a2ff4aa068fdChad Brubaker * Notify keystore that a user was added. 59183ce095c848b972156256855d0f2a2ff4aa068fdChad Brubaker * 59283ce095c848b972156256855d0f2a2ff4aa068fdChad Brubaker * @param userId the new user. 59383ce095c848b972156256855d0f2a2ff4aa068fdChad Brubaker * @param parentId the parent of the new user, or -1 if the user has no parent. If parentId is 59483ce095c848b972156256855d0f2a2ff4aa068fdChad Brubaker * specified then the new user's keystore will be intialized with the same secure lockscreen 59583ce095c848b972156256855d0f2a2ff4aa068fdChad Brubaker * password as the parent. 59683ce095c848b972156256855d0f2a2ff4aa068fdChad Brubaker */ 59783ce095c848b972156256855d0f2a2ff4aa068fdChad Brubaker public void onUserAdded(int userId, int parentId) { 59883ce095c848b972156256855d0f2a2ff4aa068fdChad Brubaker try { 59983ce095c848b972156256855d0f2a2ff4aa068fdChad Brubaker mBinder.onUserAdded(userId, parentId); 60083ce095c848b972156256855d0f2a2ff4aa068fdChad Brubaker } catch (RemoteException e) { 60183ce095c848b972156256855d0f2a2ff4aa068fdChad Brubaker Log.w(TAG, "Cannot connect to keystore", e); 60283ce095c848b972156256855d0f2a2ff4aa068fdChad Brubaker } 60383ce095c848b972156256855d0f2a2ff4aa068fdChad Brubaker } 60483ce095c848b972156256855d0f2a2ff4aa068fdChad Brubaker 60583ce095c848b972156256855d0f2a2ff4aa068fdChad Brubaker /** 60683ce095c848b972156256855d0f2a2ff4aa068fdChad Brubaker * Notify keystore that a user was added. 60783ce095c848b972156256855d0f2a2ff4aa068fdChad Brubaker * 60883ce095c848b972156256855d0f2a2ff4aa068fdChad Brubaker * @param userId the new user. 60983ce095c848b972156256855d0f2a2ff4aa068fdChad Brubaker */ 61083ce095c848b972156256855d0f2a2ff4aa068fdChad Brubaker public void onUserAdded(int userId) { 61183ce095c848b972156256855d0f2a2ff4aa068fdChad Brubaker onUserAdded(userId, -1); 61283ce095c848b972156256855d0f2a2ff4aa068fdChad Brubaker } 61383ce095c848b972156256855d0f2a2ff4aa068fdChad Brubaker 61483ce095c848b972156256855d0f2a2ff4aa068fdChad Brubaker /** 61583ce095c848b972156256855d0f2a2ff4aa068fdChad Brubaker * Notify keystore that a user was removed. 61683ce095c848b972156256855d0f2a2ff4aa068fdChad Brubaker * 61783ce095c848b972156256855d0f2a2ff4aa068fdChad Brubaker * @param userId the removed user. 61883ce095c848b972156256855d0f2a2ff4aa068fdChad Brubaker */ 61983ce095c848b972156256855d0f2a2ff4aa068fdChad Brubaker public void onUserRemoved(int userId) { 62083ce095c848b972156256855d0f2a2ff4aa068fdChad Brubaker try { 62183ce095c848b972156256855d0f2a2ff4aa068fdChad Brubaker mBinder.onUserRemoved(userId); 62283ce095c848b972156256855d0f2a2ff4aa068fdChad Brubaker } catch (RemoteException e) { 62383ce095c848b972156256855d0f2a2ff4aa068fdChad Brubaker Log.w(TAG, "Cannot connect to keystore", e); 62483ce095c848b972156256855d0f2a2ff4aa068fdChad Brubaker } 62583ce095c848b972156256855d0f2a2ff4aa068fdChad Brubaker } 62683ce095c848b972156256855d0f2a2ff4aa068fdChad Brubaker 627a91a8504191d91d288c55821caa5bf00c9be26a2Chad Brubaker public boolean onUserPasswordChanged(String newPassword) { 628a91a8504191d91d288c55821caa5bf00c9be26a2Chad Brubaker return onUserPasswordChanged(UserHandle.getUserId(Process.myUid()), newPassword); 629a91a8504191d91d288c55821caa5bf00c9be26a2Chad Brubaker } 630a91a8504191d91d288c55821caa5bf00c9be26a2Chad Brubaker 631a91a8504191d91d288c55821caa5bf00c9be26a2Chad Brubaker /** 632ad9ba10ecda10c14e46d00f40fc3e431cc2d9bc2Alex Klyubin * Returns a {@link KeyStoreException} corresponding to the provided keystore/keymaster error 633ad9ba10ecda10c14e46d00f40fc3e431cc2d9bc2Alex Klyubin * code. 634ad9ba10ecda10c14e46d00f40fc3e431cc2d9bc2Alex Klyubin */ 635dcdaf87ed0aa99073638bcfe645949f130f0c7adAlex Klyubin public static KeyStoreException getKeyStoreException(int errorCode) { 636b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin if (errorCode > 0) { 637b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin // KeyStore layer error 638b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin switch (errorCode) { 639b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin case NO_ERROR: 640b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin return new KeyStoreException(errorCode, "OK"); 641b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin case LOCKED: 6425418393c58d1d80fe37a209ab931f6d56bd46a86Alex Klyubin return new KeyStoreException(errorCode, "User authentication required"); 643b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin case UNINITIALIZED: 644b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin return new KeyStoreException(errorCode, "Keystore not initialized"); 645b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin case SYSTEM_ERROR: 646b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin return new KeyStoreException(errorCode, "System error"); 647b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin case PERMISSION_DENIED: 648b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin return new KeyStoreException(errorCode, "Permission denied"); 649b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin case KEY_NOT_FOUND: 650b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin return new KeyStoreException(errorCode, "Key not found"); 651b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin case VALUE_CORRUPTED: 652b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin return new KeyStoreException(errorCode, "Key blob corrupted"); 653058de02073a129301d391c22b050f2d65adadb0fAlex Klyubin case OP_AUTH_NEEDED: 654058de02073a129301d391c22b050f2d65adadb0fAlex Klyubin return new KeyStoreException(errorCode, "Operation requires authorization"); 655b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin default: 656b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin return new KeyStoreException(errorCode, String.valueOf(errorCode)); 657b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin } 658b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin } else { 659b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin // Keymaster layer error 660b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin switch (errorCode) { 661b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin case KeymasterDefs.KM_ERROR_INVALID_AUTHORIZATION_TIMEOUT: 662b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin // The name of this parameter significantly differs between Keymaster and 663b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin // framework APIs. Use the framework wording to make life easier for developers. 664b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin return new KeyStoreException(errorCode, 665b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin "Invalid user authentication validity duration"); 666b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin default: 667b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin return new KeyStoreException(errorCode, 668b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin KeymasterDefs.getErrorMessage(errorCode)); 669b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin } 670b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin } 671b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin } 672b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin 673ad9ba10ecda10c14e46d00f40fc3e431cc2d9bc2Alex Klyubin /** 674ad9ba10ecda10c14e46d00f40fc3e431cc2d9bc2Alex Klyubin * Returns an {@link InvalidKeyException} corresponding to the provided 675ad9ba10ecda10c14e46d00f40fc3e431cc2d9bc2Alex Klyubin * {@link KeyStoreException}. 676ad9ba10ecda10c14e46d00f40fc3e431cc2d9bc2Alex Klyubin */ 677dcdaf87ed0aa99073638bcfe645949f130f0c7adAlex Klyubin public InvalidKeyException getInvalidKeyException( 678dcdaf87ed0aa99073638bcfe645949f130f0c7adAlex Klyubin String keystoreKeyAlias, KeyStoreException e) { 679b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin switch (e.getErrorCode()) { 6805418393c58d1d80fe37a209ab931f6d56bd46a86Alex Klyubin case LOCKED: 6815418393c58d1d80fe37a209ab931f6d56bd46a86Alex Klyubin return new UserNotAuthenticatedException(); 682b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin case KeymasterDefs.KM_ERROR_KEY_EXPIRED: 683b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin return new KeyExpiredException(); 684b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin case KeymasterDefs.KM_ERROR_KEY_NOT_YET_VALID: 685b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin return new KeyNotYetValidException(); 686b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin case KeymasterDefs.KM_ERROR_KEY_USER_NOT_AUTHENTICATED: 687058de02073a129301d391c22b050f2d65adadb0fAlex Klyubin case OP_AUTH_NEEDED: 688708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubin { 689708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubin // We now need to determine whether the key/operation can become usable if user 690708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubin // authentication is performed, or whether it can never become usable again. 691708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubin // User authentication requirements are contained in the key's characteristics. We 692708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubin // need to check whether these requirements can be be satisfied by asking the user 693708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubin // to authenticate. 694708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubin KeyCharacteristics keyCharacteristics = new KeyCharacteristics(); 695708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubin int getKeyCharacteristicsErrorCode = 696708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubin getKeyCharacteristics(keystoreKeyAlias, null, null, keyCharacteristics); 697708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubin if (getKeyCharacteristicsErrorCode != NO_ERROR) { 698708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubin return new InvalidKeyException( 699708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubin "Failed to obtained key characteristics", 700708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubin getKeyStoreException(getKeyCharacteristicsErrorCode)); 701708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubin } 702708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubin List<Long> keySids = 703708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubin keyCharacteristics.getLongs(KeymasterDefs.KM_TAG_USER_SECURE_ID); 704708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubin if (keySids.isEmpty()) { 705708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubin // Key is not bound to any SIDs -- no amount of authentication will help here. 706708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubin return new KeyPermanentlyInvalidatedException(); 707708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubin } 708708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubin long rootSid = GateKeeper.getSecureUserId(); 709708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubin if ((rootSid != 0) && (keySids.contains(Long.valueOf(rootSid)))) { 710708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubin // One of the key's SIDs is the current root SID -- user can be authenticated 711708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubin // against that SID. 712708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubin return new UserNotAuthenticatedException(); 713708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubin } 714708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubin 715708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubin long fingerprintOnlySid = getFingerprintOnlySid(); 716708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubin if ((fingerprintOnlySid != 0) 717708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubin && (keySids.contains(Long.valueOf(fingerprintOnlySid)))) { 718708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubin // One of the key's SIDs is the current fingerprint SID -- user can be 719708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubin // authenticated against that SID. 720708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubin return new UserNotAuthenticatedException(); 721708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubin } 722708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubin 723708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubin // None of the key's SIDs can ever be authenticated 724708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubin return new KeyPermanentlyInvalidatedException(); 725708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubin } 726b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin default: 727ad9ba10ecda10c14e46d00f40fc3e431cc2d9bc2Alex Klyubin return new InvalidKeyException("Keystore operation failed", e); 728b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin } 729b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin } 730b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin 7312d7a85cd2b2ab4dbbe09354c6ae1668bff51a514Alex Klyubin private long getFingerprintOnlySid() { 7322d7a85cd2b2ab4dbbe09354c6ae1668bff51a514Alex Klyubin FingerprintManager fingerprintManager = 7332d7a85cd2b2ab4dbbe09354c6ae1668bff51a514Alex Klyubin mContext.getSystemService(FingerprintManager.class); 7342d7a85cd2b2ab4dbbe09354c6ae1668bff51a514Alex Klyubin if (fingerprintManager == null) { 735708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubin return 0; 736708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubin } 737708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubin 7382d7a85cd2b2ab4dbbe09354c6ae1668bff51a514Alex Klyubin if (!fingerprintManager.isHardwareDetected()) { 7392d7a85cd2b2ab4dbbe09354c6ae1668bff51a514Alex Klyubin return 0; 740708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubin } 741708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubin 7422d7a85cd2b2ab4dbbe09354c6ae1668bff51a514Alex Klyubin return fingerprintManager.getAuthenticatorId(); 7432dac95d03399bb9fa59999e4964d7f8bcd485c38Svetoslav } 7442dac95d03399bb9fa59999e4964d7f8bcd485c38Svetoslav 745ad9ba10ecda10c14e46d00f40fc3e431cc2d9bc2Alex Klyubin /** 746ad9ba10ecda10c14e46d00f40fc3e431cc2d9bc2Alex Klyubin * Returns an {@link InvalidKeyException} corresponding to the provided keystore/keymaster error 747ad9ba10ecda10c14e46d00f40fc3e431cc2d9bc2Alex Klyubin * code. 748ad9ba10ecda10c14e46d00f40fc3e431cc2d9bc2Alex Klyubin */ 749dcdaf87ed0aa99073638bcfe645949f130f0c7adAlex Klyubin public InvalidKeyException getInvalidKeyException(String keystoreKeyAlias, int errorCode) { 750708fc9404501ac42b6cac925fe3e10801b5f633bAlex Klyubin return getInvalidKeyException(keystoreKeyAlias, getKeyStoreException(errorCode)); 751b4834ae3fa09e8013f7ab743a12def063ae999e3Alex Klyubin } 75244039172627d1c15737ea73836ad375559d76211Chia-chi Yeh} 753