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