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
19a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Rootimport com.android.org.conscrypt.NativeCrypto;
20a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root
216b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Rootimport android.os.RemoteException;
226b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Rootimport android.os.ServiceManager;
236b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Rootimport android.util.Log;
2444039172627d1c15737ea73836ad375559d76211Chia-chi Yeh
25b91773bce1126d28a93f73fbef18f3a79245f24eKenny Rootimport java.util.Locale;
26b91773bce1126d28a93f73fbef18f3a79245f24eKenny Root
2744039172627d1c15737ea73836ad375559d76211Chia-chi Yeh/**
2846703b099516c383a6882815bcf9cd4df0ec538dBrian Carlstrom * @hide This should not be made public in its present form because it
2946703b099516c383a6882815bcf9cd4df0ec538dBrian Carlstrom * assumes that private and secret key bytes are available and would
3046703b099516c383a6882815bcf9cd4df0ec538dBrian Carlstrom * preclude the use of hardware crypto.
3144039172627d1c15737ea73836ad375559d76211Chia-chi Yeh */
3244039172627d1c15737ea73836ad375559d76211Chia-chi Yehpublic class KeyStore {
336b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root    private static final String TAG = "KeyStore";
345cfee3fabb3482c6a6df1c8b6f21e843cf214527Brian Carlstrom
355cfee3fabb3482c6a6df1c8b6f21e843cf214527Brian Carlstrom    // ResponseCodes
367e4b1a488dd02c4bf6156379e36834e9e01c5b1bBrian Carlstrom    public static final int NO_ERROR = 1;
377e4b1a488dd02c4bf6156379e36834e9e01c5b1bBrian Carlstrom    public static final int LOCKED = 2;
387e4b1a488dd02c4bf6156379e36834e9e01c5b1bBrian Carlstrom    public static final int UNINITIALIZED = 3;
397e4b1a488dd02c4bf6156379e36834e9e01c5b1bBrian Carlstrom    public static final int SYSTEM_ERROR = 4;
407e4b1a488dd02c4bf6156379e36834e9e01c5b1bBrian Carlstrom    public static final int PROTOCOL_ERROR = 5;
417e4b1a488dd02c4bf6156379e36834e9e01c5b1bBrian Carlstrom    public static final int PERMISSION_DENIED = 6;
427e4b1a488dd02c4bf6156379e36834e9e01c5b1bBrian Carlstrom    public static final int KEY_NOT_FOUND = 7;
437e4b1a488dd02c4bf6156379e36834e9e01c5b1bBrian Carlstrom    public static final int VALUE_CORRUPTED = 8;
447e4b1a488dd02c4bf6156379e36834e9e01c5b1bBrian Carlstrom    public static final int UNDEFINED_ACTION = 9;
457e4b1a488dd02c4bf6156379e36834e9e01c5b1bBrian Carlstrom    public static final int WRONG_PASSWORD = 10;
465cfee3fabb3482c6a6df1c8b6f21e843cf214527Brian Carlstrom
472eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root    // Used for UID field to indicate the calling UID.
482eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root    public static final int UID_SELF = -1;
492eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root
502eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root    // Flags for "put" "import" and "generate"
512eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root    public static final int FLAG_NONE = 0;
52a3788b00bb221e20abdd42f747d2af419e0a088cKenny Root    public static final int FLAG_ENCRYPTED = 1;
53a3788b00bb221e20abdd42f747d2af419e0a088cKenny Root
545cfee3fabb3482c6a6df1c8b6f21e843cf214527Brian Carlstrom    // States
555cfee3fabb3482c6a6df1c8b6f21e843cf214527Brian Carlstrom    public enum State { UNLOCKED, LOCKED, UNINITIALIZED };
5644039172627d1c15737ea73836ad375559d76211Chia-chi Yeh
5744039172627d1c15737ea73836ad375559d76211Chia-chi Yeh    private int mError = NO_ERROR;
5844039172627d1c15737ea73836ad375559d76211Chia-chi Yeh
596b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root    private final IKeystoreService mBinder;
606b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root
616b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root    private KeyStore(IKeystoreService binder) {
626b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        mBinder = binder;
636b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root    }
6444039172627d1c15737ea73836ad375559d76211Chia-chi Yeh
6544039172627d1c15737ea73836ad375559d76211Chia-chi Yeh    public static KeyStore getInstance() {
666b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        IKeystoreService keystore = IKeystoreService.Stub.asInterface(ServiceManager
676b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root                .getService("android.security.keystore"));
686b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        return new KeyStore(keystore);
6944039172627d1c15737ea73836ad375559d76211Chia-chi Yeh    }
7044039172627d1c15737ea73836ad375559d76211Chia-chi Yeh
71a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root    static int getKeyTypeForAlgorithm(String keyType) throws IllegalArgumentException {
72a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root        if ("RSA".equalsIgnoreCase(keyType)) {
73a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root            return NativeCrypto.EVP_PKEY_RSA;
74a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root        } else if ("DSA".equalsIgnoreCase(keyType)) {
75a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root            return NativeCrypto.EVP_PKEY_DSA;
76a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root        } else if ("EC".equalsIgnoreCase(keyType)) {
77a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root            return NativeCrypto.EVP_PKEY_EC;
78a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root        } else {
79a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root            throw new IllegalArgumentException("Unsupported key type: " + keyType);
80a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root        }
81a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root    }
82a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root
835cfee3fabb3482c6a6df1c8b6f21e843cf214527Brian Carlstrom    public State state() {
846b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        final int ret;
856b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        try {
866b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            ret = mBinder.test();
876b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        } catch (RemoteException e) {
886b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            Log.w(TAG, "Cannot connect to keystore", e);
896b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            throw new AssertionError(e);
906b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        }
916b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root
926b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        switch (ret) {
935cfee3fabb3482c6a6df1c8b6f21e843cf214527Brian Carlstrom            case NO_ERROR: return State.UNLOCKED;
945cfee3fabb3482c6a6df1c8b6f21e843cf214527Brian Carlstrom            case LOCKED: return State.LOCKED;
955cfee3fabb3482c6a6df1c8b6f21e843cf214527Brian Carlstrom            case UNINITIALIZED: return State.UNINITIALIZED;
965cfee3fabb3482c6a6df1c8b6f21e843cf214527Brian Carlstrom            default: throw new AssertionError(mError);
975cfee3fabb3482c6a6df1c8b6f21e843cf214527Brian Carlstrom        }
98b9594ce9ebb3f5f303a280f04312ae5754ce3560Kenny Root    }
99b9594ce9ebb3f5f303a280f04312ae5754ce3560Kenny Root
100b9594ce9ebb3f5f303a280f04312ae5754ce3560Kenny Root    public boolean isUnlocked() {
101b9594ce9ebb3f5f303a280f04312ae5754ce3560Kenny Root        return state() == State.UNLOCKED;
10244039172627d1c15737ea73836ad375559d76211Chia-chi Yeh    }
10344039172627d1c15737ea73836ad375559d76211Chia-chi Yeh
1045cfee3fabb3482c6a6df1c8b6f21e843cf214527Brian Carlstrom    public byte[] get(String key) {
1056b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        try {
1066b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            return mBinder.get(key);
1076b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        } catch (RemoteException e) {
1086b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            Log.w(TAG, "Cannot connect to keystore", e);
1096b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            return null;
1106b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        }
11144039172627d1c15737ea73836ad375559d76211Chia-chi Yeh    }
11244039172627d1c15737ea73836ad375559d76211Chia-chi Yeh
113a3788b00bb221e20abdd42f747d2af419e0a088cKenny Root    public boolean put(String key, byte[] value, int uid, int flags) {
1146b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        try {
115a3788b00bb221e20abdd42f747d2af419e0a088cKenny Root            return mBinder.insert(key, value, uid, flags) == NO_ERROR;
1166b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        } catch (RemoteException e) {
1176b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            Log.w(TAG, "Cannot connect to keystore", e);
1186b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            return false;
1196b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        }
12044039172627d1c15737ea73836ad375559d76211Chia-chi Yeh    }
12144039172627d1c15737ea73836ad375559d76211Chia-chi Yeh
12278ad849163a7b01073b46fbd7d818392720005d1Kenny Root    public boolean delete(String key, int uid) {
1236b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        try {
12478ad849163a7b01073b46fbd7d818392720005d1Kenny Root            return mBinder.del(key, uid) == NO_ERROR;
1256b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        } catch (RemoteException e) {
1266b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            Log.w(TAG, "Cannot connect to keystore", e);
1276b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            return false;
1286b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        }
12944039172627d1c15737ea73836ad375559d76211Chia-chi Yeh    }
13044039172627d1c15737ea73836ad375559d76211Chia-chi Yeh
13178ad849163a7b01073b46fbd7d818392720005d1Kenny Root    public boolean delete(String key) {
1322eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root        return delete(key, UID_SELF);
13378ad849163a7b01073b46fbd7d818392720005d1Kenny Root    }
13478ad849163a7b01073b46fbd7d818392720005d1Kenny Root
13578ad849163a7b01073b46fbd7d818392720005d1Kenny Root    public boolean contains(String key, int uid) {
1366b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        try {
13778ad849163a7b01073b46fbd7d818392720005d1Kenny Root            return mBinder.exist(key, uid) == NO_ERROR;
1386b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        } catch (RemoteException e) {
1396b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            Log.w(TAG, "Cannot connect to keystore", e);
1406b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            return false;
1416b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        }
14244039172627d1c15737ea73836ad375559d76211Chia-chi Yeh    }
14344039172627d1c15737ea73836ad375559d76211Chia-chi Yeh
14478ad849163a7b01073b46fbd7d818392720005d1Kenny Root    public boolean contains(String key) {
1452eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root        return contains(key, UID_SELF);
14678ad849163a7b01073b46fbd7d818392720005d1Kenny Root    }
14778ad849163a7b01073b46fbd7d818392720005d1Kenny Root
14878ad849163a7b01073b46fbd7d818392720005d1Kenny Root    public String[] saw(String prefix, int uid) {
1496b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        try {
15078ad849163a7b01073b46fbd7d818392720005d1Kenny Root            return mBinder.saw(prefix, uid);
1516b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        } catch (RemoteException e) {
1526b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            Log.w(TAG, "Cannot connect to keystore", e);
15344039172627d1c15737ea73836ad375559d76211Chia-chi Yeh            return null;
15444039172627d1c15737ea73836ad375559d76211Chia-chi Yeh        }
15544039172627d1c15737ea73836ad375559d76211Chia-chi Yeh    }
15644039172627d1c15737ea73836ad375559d76211Chia-chi Yeh
15778ad849163a7b01073b46fbd7d818392720005d1Kenny Root    public String[] saw(String prefix) {
1582eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root        return saw(prefix, UID_SELF);
15978ad849163a7b01073b46fbd7d818392720005d1Kenny Root    }
16078ad849163a7b01073b46fbd7d818392720005d1Kenny Root
16144039172627d1c15737ea73836ad375559d76211Chia-chi Yeh    public boolean reset() {
1626b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        try {
1636b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            return mBinder.reset() == NO_ERROR;
1646b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        } catch (RemoteException e) {
1656b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            Log.w(TAG, "Cannot connect to keystore", e);
1666b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            return false;
1676b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        }
16844039172627d1c15737ea73836ad375559d76211Chia-chi Yeh    }
16944039172627d1c15737ea73836ad375559d76211Chia-chi Yeh
17044039172627d1c15737ea73836ad375559d76211Chia-chi Yeh    public boolean password(String password) {
1716b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        try {
1726b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            return mBinder.password(password) == NO_ERROR;
1736b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        } catch (RemoteException e) {
1746b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            Log.w(TAG, "Cannot connect to keystore", e);
1756b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            return false;
1766b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        }
17744039172627d1c15737ea73836ad375559d76211Chia-chi Yeh    }
17844039172627d1c15737ea73836ad375559d76211Chia-chi Yeh
17944039172627d1c15737ea73836ad375559d76211Chia-chi Yeh    public boolean lock() {
1806b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        try {
1816b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            return mBinder.lock() == 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
18844039172627d1c15737ea73836ad375559d76211Chia-chi Yeh    public boolean unlock(String password) {
1896b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        try {
1906b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            mError = mBinder.unlock(password);
1916b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            return mError == NO_ERROR;
1926b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        } catch (RemoteException e) {
1936b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            Log.w(TAG, "Cannot connect to keystore", e);
1946b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            return false;
1956b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        }
19644039172627d1c15737ea73836ad375559d76211Chia-chi Yeh    }
19744039172627d1c15737ea73836ad375559d76211Chia-chi Yeh
1985cfee3fabb3482c6a6df1c8b6f21e843cf214527Brian Carlstrom    public boolean isEmpty() {
1996b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        try {
2006b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            return mBinder.zero() == KEY_NOT_FOUND;
2016b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        } catch (RemoteException e) {
2026b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            Log.w(TAG, "Cannot connect to keystore", e);
2036b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            return false;
2046b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        }
2055423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root    }
2065423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root
207a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root    public boolean generate(String key, int uid, int keyType, int keySize, int flags,
208a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root            byte[][] args) {
2096b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        try {
210a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root            return mBinder.generate(key, uid, keyType, keySize, flags, args) == NO_ERROR;
2116b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        } catch (RemoteException e) {
2126b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            Log.w(TAG, "Cannot connect to keystore", e);
2136b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            return false;
2146b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        }
2155423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root    }
2165423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root
217a3788b00bb221e20abdd42f747d2af419e0a088cKenny Root    public boolean importKey(String keyName, byte[] key, int uid, int flags) {
2186b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        try {
219a3788b00bb221e20abdd42f747d2af419e0a088cKenny Root            return mBinder.import_key(keyName, key, uid, flags) == NO_ERROR;
2206b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        } catch (RemoteException e) {
2216b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            Log.w(TAG, "Cannot connect to keystore", e);
2226b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            return false;
2236b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        }
2245423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root    }
2255423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root
2265423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root    public byte[] getPubkey(String key) {
2276b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        try {
2286b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            return mBinder.get_pubkey(key);
2296b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        } catch (RemoteException e) {
2306b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            Log.w(TAG, "Cannot connect to keystore", e);
2316b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            return null;
2326b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        }
2335423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root    }
2345423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root
23578ad849163a7b01073b46fbd7d818392720005d1Kenny Root    public boolean delKey(String key, int uid) {
2366b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        try {
23778ad849163a7b01073b46fbd7d818392720005d1Kenny Root            return mBinder.del_key(key, uid) == NO_ERROR;
2386b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        } catch (RemoteException e) {
2396b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            Log.w(TAG, "Cannot connect to keystore", e);
2406b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            return false;
2416b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        }
2425423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root    }
2435423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root
24478ad849163a7b01073b46fbd7d818392720005d1Kenny Root    public boolean delKey(String key) {
2452eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root        return delKey(key, UID_SELF);
24678ad849163a7b01073b46fbd7d818392720005d1Kenny Root    }
24778ad849163a7b01073b46fbd7d818392720005d1Kenny Root
2485423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root    public byte[] sign(String key, byte[] data) {
2496b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        try {
2506b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            return mBinder.sign(key, data);
2516b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        } catch (RemoteException e) {
2526b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            Log.w(TAG, "Cannot connect to keystore", e);
2536b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            return null;
2546b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        }
2555423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root    }
2565423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root
2575423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root    public boolean verify(String key, byte[] data, byte[] signature) {
2586b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        try {
2596b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            return mBinder.verify(key, data, signature) == NO_ERROR;
2606b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        } catch (RemoteException e) {
2616b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            Log.w(TAG, "Cannot connect to keystore", e);
2626b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            return false;
2636b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        }
2645423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root    }
2655423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root
2665423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root    public boolean grant(String key, int uid) {
2676b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        try {
2686b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            return mBinder.grant(key, uid) == NO_ERROR;
2696b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        } catch (RemoteException e) {
2706b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            Log.w(TAG, "Cannot connect to keystore", e);
2716b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            return false;
2726b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        }
2735423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root    }
2745423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root
2755423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root    public boolean ungrant(String key, int uid) {
2766b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        try {
2776b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            return mBinder.ungrant(key, uid) == NO_ERROR;
2786b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        } catch (RemoteException e) {
2796b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            Log.w(TAG, "Cannot connect to keystore", e);
2806b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            return false;
281473c712b19bad992ab4eafcd43175fdce77b913dKenny Root        }
282473c712b19bad992ab4eafcd43175fdce77b913dKenny Root    }
283473c712b19bad992ab4eafcd43175fdce77b913dKenny Root
284473c712b19bad992ab4eafcd43175fdce77b913dKenny Root    /**
285473c712b19bad992ab4eafcd43175fdce77b913dKenny Root     * Returns the last modification time of the key in milliseconds since the
286473c712b19bad992ab4eafcd43175fdce77b913dKenny Root     * epoch. Will return -1L if the key could not be found or other error.
287473c712b19bad992ab4eafcd43175fdce77b913dKenny Root     */
288473c712b19bad992ab4eafcd43175fdce77b913dKenny Root    public long getmtime(String key) {
2895b1f037829bff93877a6257db69f4e7723a27e20Brian Carlstrom        try {
290e66769ad5194cb4533d1087416a2e804ac384285Kenny Root            final long millis = mBinder.getmtime(key);
291e66769ad5194cb4533d1087416a2e804ac384285Kenny Root            if (millis == -1L) {
292e66769ad5194cb4533d1087416a2e804ac384285Kenny Root                return -1L;
293e66769ad5194cb4533d1087416a2e804ac384285Kenny Root            }
294e66769ad5194cb4533d1087416a2e804ac384285Kenny Root
295e66769ad5194cb4533d1087416a2e804ac384285Kenny Root            return millis * 1000L;
2966b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        } catch (RemoteException e) {
2976b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            Log.w(TAG, "Cannot connect to keystore", e);
2986b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            return -1L;
2995b1f037829bff93877a6257db69f4e7723a27e20Brian Carlstrom        }
3005b1f037829bff93877a6257db69f4e7723a27e20Brian Carlstrom    }
3015b1f037829bff93877a6257db69f4e7723a27e20Brian Carlstrom
3025f1d965f7d7e1df50981ffed8faa11fbcc17ca22Kenny Root    public boolean duplicate(String srcKey, int srcUid, String destKey, int destUid) {
303bd79419ef84ae31f3765721b50aa413fa462d1d1Kenny Root        try {
3045f1d965f7d7e1df50981ffed8faa11fbcc17ca22Kenny Root            return mBinder.duplicate(srcKey, srcUid, destKey, destUid) == NO_ERROR;
305bd79419ef84ae31f3765721b50aa413fa462d1d1Kenny Root        } catch (RemoteException e) {
306bd79419ef84ae31f3765721b50aa413fa462d1d1Kenny Root            Log.w(TAG, "Cannot connect to keystore", e);
307bd79419ef84ae31f3765721b50aa413fa462d1d1Kenny Root            return false;
308bd79419ef84ae31f3765721b50aa413fa462d1d1Kenny Root        }
309bd79419ef84ae31f3765721b50aa413fa462d1d1Kenny Root    }
310bd79419ef84ae31f3765721b50aa413fa462d1d1Kenny Root
311b91773bce1126d28a93f73fbef18f3a79245f24eKenny Root    // TODO remove this when it's removed from Settings
3125cb5cec6a4a4d5432d4ce6468c12de9508db1633Kenny Root    public boolean isHardwareBacked() {
313b91773bce1126d28a93f73fbef18f3a79245f24eKenny Root        return isHardwareBacked("RSA");
314b91773bce1126d28a93f73fbef18f3a79245f24eKenny Root    }
315b91773bce1126d28a93f73fbef18f3a79245f24eKenny Root
316b91773bce1126d28a93f73fbef18f3a79245f24eKenny Root    public boolean isHardwareBacked(String keyType) {
3175cb5cec6a4a4d5432d4ce6468c12de9508db1633Kenny Root        try {
318b91773bce1126d28a93f73fbef18f3a79245f24eKenny Root            return mBinder.is_hardware_backed(keyType.toUpperCase(Locale.US)) == NO_ERROR;
3195cb5cec6a4a4d5432d4ce6468c12de9508db1633Kenny Root        } catch (RemoteException e) {
3205cb5cec6a4a4d5432d4ce6468c12de9508db1633Kenny Root            Log.w(TAG, "Cannot connect to keystore", e);
3215cb5cec6a4a4d5432d4ce6468c12de9508db1633Kenny Root            return false;
3225cb5cec6a4a4d5432d4ce6468c12de9508db1633Kenny Root        }
3235cb5cec6a4a4d5432d4ce6468c12de9508db1633Kenny Root    }
3245cb5cec6a4a4d5432d4ce6468c12de9508db1633Kenny Root
325d72317abd79ddf95d48c8f35bf1070900ff55b5eKenny Root    public boolean clearUid(int uid) {
326d72317abd79ddf95d48c8f35bf1070900ff55b5eKenny Root        try {
327d72317abd79ddf95d48c8f35bf1070900ff55b5eKenny Root            return mBinder.clear_uid(uid) == NO_ERROR;
328d72317abd79ddf95d48c8f35bf1070900ff55b5eKenny Root        } catch (RemoteException e) {
329d72317abd79ddf95d48c8f35bf1070900ff55b5eKenny Root            Log.w(TAG, "Cannot connect to keystore", e);
330d72317abd79ddf95d48c8f35bf1070900ff55b5eKenny Root            return false;
331d72317abd79ddf95d48c8f35bf1070900ff55b5eKenny Root        }
332d72317abd79ddf95d48c8f35bf1070900ff55b5eKenny Root    }
333d72317abd79ddf95d48c8f35bf1070900ff55b5eKenny Root
3346b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root    public int getLastError() {
3356b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        return mError;
33634c47c855815d731e6deb55748ff690b0ec7b53fNick Kralevich    }
33744039172627d1c15737ea73836ad375559d76211Chia-chi Yeh}
338