KeyStore.java revision a39859889b7de0ad3190386cc732fa4bdcbe5504
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
2544039172627d1c15737ea73836ad375559d76211Chia-chi Yeh/**
2646703b099516c383a6882815bcf9cd4df0ec538dBrian Carlstrom * @hide This should not be made public in its present form because it
2746703b099516c383a6882815bcf9cd4df0ec538dBrian Carlstrom * assumes that private and secret key bytes are available and would
2846703b099516c383a6882815bcf9cd4df0ec538dBrian Carlstrom * preclude the use of hardware crypto.
2944039172627d1c15737ea73836ad375559d76211Chia-chi Yeh */
3044039172627d1c15737ea73836ad375559d76211Chia-chi Yehpublic class KeyStore {
316b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root    private static final String TAG = "KeyStore";
325cfee3fabb3482c6a6df1c8b6f21e843cf214527Brian Carlstrom
335cfee3fabb3482c6a6df1c8b6f21e843cf214527Brian Carlstrom    // ResponseCodes
347e4b1a488dd02c4bf6156379e36834e9e01c5b1bBrian Carlstrom    public static final int NO_ERROR = 1;
357e4b1a488dd02c4bf6156379e36834e9e01c5b1bBrian Carlstrom    public static final int LOCKED = 2;
367e4b1a488dd02c4bf6156379e36834e9e01c5b1bBrian Carlstrom    public static final int UNINITIALIZED = 3;
377e4b1a488dd02c4bf6156379e36834e9e01c5b1bBrian Carlstrom    public static final int SYSTEM_ERROR = 4;
387e4b1a488dd02c4bf6156379e36834e9e01c5b1bBrian Carlstrom    public static final int PROTOCOL_ERROR = 5;
397e4b1a488dd02c4bf6156379e36834e9e01c5b1bBrian Carlstrom    public static final int PERMISSION_DENIED = 6;
407e4b1a488dd02c4bf6156379e36834e9e01c5b1bBrian Carlstrom    public static final int KEY_NOT_FOUND = 7;
417e4b1a488dd02c4bf6156379e36834e9e01c5b1bBrian Carlstrom    public static final int VALUE_CORRUPTED = 8;
427e4b1a488dd02c4bf6156379e36834e9e01c5b1bBrian Carlstrom    public static final int UNDEFINED_ACTION = 9;
437e4b1a488dd02c4bf6156379e36834e9e01c5b1bBrian Carlstrom    public static final int WRONG_PASSWORD = 10;
445cfee3fabb3482c6a6df1c8b6f21e843cf214527Brian Carlstrom
452eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root    // Used for UID field to indicate the calling UID.
462eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root    public static final int UID_SELF = -1;
472eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root
482eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root    // Flags for "put" "import" and "generate"
492eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root    public static final int FLAG_NONE = 0;
50a3788b00bb221e20abdd42f747d2af419e0a088cKenny Root    public static final int FLAG_ENCRYPTED = 1;
51a3788b00bb221e20abdd42f747d2af419e0a088cKenny Root
525cfee3fabb3482c6a6df1c8b6f21e843cf214527Brian Carlstrom    // States
535cfee3fabb3482c6a6df1c8b6f21e843cf214527Brian Carlstrom    public enum State { UNLOCKED, LOCKED, UNINITIALIZED };
5444039172627d1c15737ea73836ad375559d76211Chia-chi Yeh
5544039172627d1c15737ea73836ad375559d76211Chia-chi Yeh    private int mError = NO_ERROR;
5644039172627d1c15737ea73836ad375559d76211Chia-chi Yeh
576b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root    private final IKeystoreService mBinder;
586b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root
596b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root    private KeyStore(IKeystoreService binder) {
606b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        mBinder = binder;
616b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root    }
6244039172627d1c15737ea73836ad375559d76211Chia-chi Yeh
6344039172627d1c15737ea73836ad375559d76211Chia-chi Yeh    public static KeyStore getInstance() {
646b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        IKeystoreService keystore = IKeystoreService.Stub.asInterface(ServiceManager
656b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root                .getService("android.security.keystore"));
666b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        return new KeyStore(keystore);
6744039172627d1c15737ea73836ad375559d76211Chia-chi Yeh    }
6844039172627d1c15737ea73836ad375559d76211Chia-chi Yeh
69a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root    static int getKeyTypeForAlgorithm(String keyType) throws IllegalArgumentException {
70a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root        if ("RSA".equalsIgnoreCase(keyType)) {
71a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root            return NativeCrypto.EVP_PKEY_RSA;
72a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root        } else if ("DSA".equalsIgnoreCase(keyType)) {
73a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root            return NativeCrypto.EVP_PKEY_DSA;
74a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root        } else if ("EC".equalsIgnoreCase(keyType)) {
75a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root            return NativeCrypto.EVP_PKEY_EC;
76a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root        } else {
77a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root            throw new IllegalArgumentException("Unsupported key type: " + keyType);
78a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root        }
79a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root    }
80a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root
815cfee3fabb3482c6a6df1c8b6f21e843cf214527Brian Carlstrom    public State state() {
826b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        final int ret;
836b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        try {
846b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            ret = mBinder.test();
856b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        } catch (RemoteException e) {
866b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            Log.w(TAG, "Cannot connect to keystore", e);
876b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            throw new AssertionError(e);
886b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        }
896b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root
906b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        switch (ret) {
915cfee3fabb3482c6a6df1c8b6f21e843cf214527Brian Carlstrom            case NO_ERROR: return State.UNLOCKED;
925cfee3fabb3482c6a6df1c8b6f21e843cf214527Brian Carlstrom            case LOCKED: return State.LOCKED;
935cfee3fabb3482c6a6df1c8b6f21e843cf214527Brian Carlstrom            case UNINITIALIZED: return State.UNINITIALIZED;
945cfee3fabb3482c6a6df1c8b6f21e843cf214527Brian Carlstrom            default: throw new AssertionError(mError);
955cfee3fabb3482c6a6df1c8b6f21e843cf214527Brian Carlstrom        }
96b9594ce9ebb3f5f303a280f04312ae5754ce3560Kenny Root    }
97b9594ce9ebb3f5f303a280f04312ae5754ce3560Kenny Root
98b9594ce9ebb3f5f303a280f04312ae5754ce3560Kenny Root    public boolean isUnlocked() {
99b9594ce9ebb3f5f303a280f04312ae5754ce3560Kenny Root        return state() == State.UNLOCKED;
10044039172627d1c15737ea73836ad375559d76211Chia-chi Yeh    }
10144039172627d1c15737ea73836ad375559d76211Chia-chi Yeh
1025cfee3fabb3482c6a6df1c8b6f21e843cf214527Brian Carlstrom    public byte[] get(String key) {
1036b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        try {
1046b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            return mBinder.get(key);
1056b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        } catch (RemoteException e) {
1066b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            Log.w(TAG, "Cannot connect to keystore", e);
1076b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            return null;
1086b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        }
10944039172627d1c15737ea73836ad375559d76211Chia-chi Yeh    }
11044039172627d1c15737ea73836ad375559d76211Chia-chi Yeh
111a3788b00bb221e20abdd42f747d2af419e0a088cKenny Root    public boolean put(String key, byte[] value, int uid, int flags) {
1126b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        try {
113a3788b00bb221e20abdd42f747d2af419e0a088cKenny Root            return mBinder.insert(key, value, uid, flags) == NO_ERROR;
1146b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        } catch (RemoteException e) {
1156b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            Log.w(TAG, "Cannot connect to keystore", e);
1166b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            return false;
1176b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        }
11844039172627d1c15737ea73836ad375559d76211Chia-chi Yeh    }
11944039172627d1c15737ea73836ad375559d76211Chia-chi Yeh
12078ad849163a7b01073b46fbd7d818392720005d1Kenny Root    public boolean delete(String key, int uid) {
1216b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        try {
12278ad849163a7b01073b46fbd7d818392720005d1Kenny Root            return mBinder.del(key, uid) == NO_ERROR;
1236b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        } catch (RemoteException e) {
1246b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            Log.w(TAG, "Cannot connect to keystore", e);
1256b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            return false;
1266b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        }
12744039172627d1c15737ea73836ad375559d76211Chia-chi Yeh    }
12844039172627d1c15737ea73836ad375559d76211Chia-chi Yeh
12978ad849163a7b01073b46fbd7d818392720005d1Kenny Root    public boolean delete(String key) {
1302eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root        return delete(key, UID_SELF);
13178ad849163a7b01073b46fbd7d818392720005d1Kenny Root    }
13278ad849163a7b01073b46fbd7d818392720005d1Kenny Root
13378ad849163a7b01073b46fbd7d818392720005d1Kenny Root    public boolean contains(String key, int uid) {
1346b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        try {
13578ad849163a7b01073b46fbd7d818392720005d1Kenny Root            return mBinder.exist(key, uid) == NO_ERROR;
1366b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        } catch (RemoteException e) {
1376b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            Log.w(TAG, "Cannot connect to keystore", e);
1386b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            return false;
1396b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        }
14044039172627d1c15737ea73836ad375559d76211Chia-chi Yeh    }
14144039172627d1c15737ea73836ad375559d76211Chia-chi Yeh
14278ad849163a7b01073b46fbd7d818392720005d1Kenny Root    public boolean contains(String key) {
1432eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root        return contains(key, UID_SELF);
14478ad849163a7b01073b46fbd7d818392720005d1Kenny Root    }
14578ad849163a7b01073b46fbd7d818392720005d1Kenny Root
14678ad849163a7b01073b46fbd7d818392720005d1Kenny Root    public String[] saw(String prefix, int uid) {
1476b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        try {
14878ad849163a7b01073b46fbd7d818392720005d1Kenny Root            return mBinder.saw(prefix, uid);
1496b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        } catch (RemoteException e) {
1506b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            Log.w(TAG, "Cannot connect to keystore", e);
15144039172627d1c15737ea73836ad375559d76211Chia-chi Yeh            return null;
15244039172627d1c15737ea73836ad375559d76211Chia-chi Yeh        }
15344039172627d1c15737ea73836ad375559d76211Chia-chi Yeh    }
15444039172627d1c15737ea73836ad375559d76211Chia-chi Yeh
15578ad849163a7b01073b46fbd7d818392720005d1Kenny Root    public String[] saw(String prefix) {
1562eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root        return saw(prefix, UID_SELF);
15778ad849163a7b01073b46fbd7d818392720005d1Kenny Root    }
15878ad849163a7b01073b46fbd7d818392720005d1Kenny Root
15944039172627d1c15737ea73836ad375559d76211Chia-chi Yeh    public boolean reset() {
1606b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        try {
1616b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            return mBinder.reset() == NO_ERROR;
1626b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        } catch (RemoteException e) {
1636b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            Log.w(TAG, "Cannot connect to keystore", e);
1646b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            return false;
1656b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        }
16644039172627d1c15737ea73836ad375559d76211Chia-chi Yeh    }
16744039172627d1c15737ea73836ad375559d76211Chia-chi Yeh
16844039172627d1c15737ea73836ad375559d76211Chia-chi Yeh    public boolean password(String password) {
1696b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        try {
1706b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            return mBinder.password(password) == NO_ERROR;
1716b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        } catch (RemoteException e) {
1726b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            Log.w(TAG, "Cannot connect to keystore", e);
1736b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            return false;
1746b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        }
17544039172627d1c15737ea73836ad375559d76211Chia-chi Yeh    }
17644039172627d1c15737ea73836ad375559d76211Chia-chi Yeh
17744039172627d1c15737ea73836ad375559d76211Chia-chi Yeh    public boolean lock() {
1786b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        try {
1796b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            return mBinder.lock() == NO_ERROR;
1806b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        } catch (RemoteException e) {
1816b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            Log.w(TAG, "Cannot connect to keystore", e);
1826b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            return false;
1836b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        }
18444039172627d1c15737ea73836ad375559d76211Chia-chi Yeh    }
18544039172627d1c15737ea73836ad375559d76211Chia-chi Yeh
18644039172627d1c15737ea73836ad375559d76211Chia-chi Yeh    public boolean unlock(String password) {
1876b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        try {
1886b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            mError = mBinder.unlock(password);
1896b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            return mError == NO_ERROR;
1906b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        } catch (RemoteException e) {
1916b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            Log.w(TAG, "Cannot connect to keystore", e);
1926b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            return false;
1936b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        }
19444039172627d1c15737ea73836ad375559d76211Chia-chi Yeh    }
19544039172627d1c15737ea73836ad375559d76211Chia-chi Yeh
1965cfee3fabb3482c6a6df1c8b6f21e843cf214527Brian Carlstrom    public boolean isEmpty() {
1976b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        try {
1986b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            return mBinder.zero() == KEY_NOT_FOUND;
1996b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        } catch (RemoteException e) {
2006b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            Log.w(TAG, "Cannot connect to keystore", e);
2016b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            return false;
2026b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        }
2035423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root    }
2045423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root
205a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root    public boolean generate(String key, int uid, int keyType, int keySize, int flags,
206a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root            byte[][] args) {
2076b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        try {
208a39859889b7de0ad3190386cc732fa4bdcbe5504Kenny Root            return mBinder.generate(key, uid, keyType, keySize, flags, args) == NO_ERROR;
2096b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        } catch (RemoteException e) {
2106b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            Log.w(TAG, "Cannot connect to keystore", e);
2116b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            return false;
2126b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        }
2135423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root    }
2145423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root
215a3788b00bb221e20abdd42f747d2af419e0a088cKenny Root    public boolean importKey(String keyName, byte[] key, int uid, int flags) {
2166b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        try {
217a3788b00bb221e20abdd42f747d2af419e0a088cKenny Root            return mBinder.import_key(keyName, key, uid, flags) == NO_ERROR;
2186b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        } catch (RemoteException e) {
2196b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            Log.w(TAG, "Cannot connect to keystore", e);
2206b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            return false;
2216b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        }
2225423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root    }
2235423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root
2245423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root    public byte[] getPubkey(String key) {
2256b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        try {
2266b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            return mBinder.get_pubkey(key);
2276b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        } catch (RemoteException e) {
2286b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            Log.w(TAG, "Cannot connect to keystore", e);
2296b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            return null;
2306b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        }
2315423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root    }
2325423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root
23378ad849163a7b01073b46fbd7d818392720005d1Kenny Root    public boolean delKey(String key, int uid) {
2346b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        try {
23578ad849163a7b01073b46fbd7d818392720005d1Kenny Root            return mBinder.del_key(key, uid) == NO_ERROR;
2366b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        } catch (RemoteException e) {
2376b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            Log.w(TAG, "Cannot connect to keystore", e);
2386b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            return false;
2396b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        }
2405423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root    }
2415423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root
24278ad849163a7b01073b46fbd7d818392720005d1Kenny Root    public boolean delKey(String key) {
2432eeda7286f3c7cb79f7eb71ae6464cad213d12a3Kenny Root        return delKey(key, UID_SELF);
24478ad849163a7b01073b46fbd7d818392720005d1Kenny Root    }
24578ad849163a7b01073b46fbd7d818392720005d1Kenny Root
2465423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root    public byte[] sign(String key, byte[] data) {
2476b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        try {
2486b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            return mBinder.sign(key, data);
2496b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        } catch (RemoteException e) {
2506b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            Log.w(TAG, "Cannot connect to keystore", e);
2516b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            return null;
2526b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        }
2535423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root    }
2545423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root
2555423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root    public boolean verify(String key, byte[] data, byte[] signature) {
2566b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        try {
2576b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            return mBinder.verify(key, data, signature) == NO_ERROR;
2586b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        } catch (RemoteException e) {
2596b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            Log.w(TAG, "Cannot connect to keystore", e);
2606b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            return false;
2616b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        }
2625423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root    }
2635423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root
2645423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root    public boolean grant(String key, int uid) {
2656b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        try {
2666b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            return mBinder.grant(key, uid) == NO_ERROR;
2676b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        } catch (RemoteException e) {
2686b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            Log.w(TAG, "Cannot connect to keystore", e);
2696b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            return false;
2706b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        }
2715423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root    }
2725423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root
2735423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root    public boolean ungrant(String key, int uid) {
2746b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        try {
2756b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            return mBinder.ungrant(key, uid) == NO_ERROR;
2766b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        } catch (RemoteException e) {
2776b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            Log.w(TAG, "Cannot connect to keystore", e);
2786b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            return false;
279473c712b19bad992ab4eafcd43175fdce77b913dKenny Root        }
280473c712b19bad992ab4eafcd43175fdce77b913dKenny Root    }
281473c712b19bad992ab4eafcd43175fdce77b913dKenny Root
282473c712b19bad992ab4eafcd43175fdce77b913dKenny Root    /**
283473c712b19bad992ab4eafcd43175fdce77b913dKenny Root     * Returns the last modification time of the key in milliseconds since the
284473c712b19bad992ab4eafcd43175fdce77b913dKenny Root     * epoch. Will return -1L if the key could not be found or other error.
285473c712b19bad992ab4eafcd43175fdce77b913dKenny Root     */
286473c712b19bad992ab4eafcd43175fdce77b913dKenny Root    public long getmtime(String key) {
2875b1f037829bff93877a6257db69f4e7723a27e20Brian Carlstrom        try {
288e66769ad5194cb4533d1087416a2e804ac384285Kenny Root            final long millis = mBinder.getmtime(key);
289e66769ad5194cb4533d1087416a2e804ac384285Kenny Root            if (millis == -1L) {
290e66769ad5194cb4533d1087416a2e804ac384285Kenny Root                return -1L;
291e66769ad5194cb4533d1087416a2e804ac384285Kenny Root            }
292e66769ad5194cb4533d1087416a2e804ac384285Kenny Root
293e66769ad5194cb4533d1087416a2e804ac384285Kenny Root            return millis * 1000L;
2946b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        } catch (RemoteException e) {
2956b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            Log.w(TAG, "Cannot connect to keystore", e);
2966b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            return -1L;
2975b1f037829bff93877a6257db69f4e7723a27e20Brian Carlstrom        }
2985b1f037829bff93877a6257db69f4e7723a27e20Brian Carlstrom    }
2995b1f037829bff93877a6257db69f4e7723a27e20Brian Carlstrom
3005f1d965f7d7e1df50981ffed8faa11fbcc17ca22Kenny Root    public boolean duplicate(String srcKey, int srcUid, String destKey, int destUid) {
301bd79419ef84ae31f3765721b50aa413fa462d1d1Kenny Root        try {
3025f1d965f7d7e1df50981ffed8faa11fbcc17ca22Kenny Root            return mBinder.duplicate(srcKey, srcUid, destKey, destUid) == NO_ERROR;
303bd79419ef84ae31f3765721b50aa413fa462d1d1Kenny Root        } catch (RemoteException e) {
304bd79419ef84ae31f3765721b50aa413fa462d1d1Kenny Root            Log.w(TAG, "Cannot connect to keystore", e);
305bd79419ef84ae31f3765721b50aa413fa462d1d1Kenny Root            return false;
306bd79419ef84ae31f3765721b50aa413fa462d1d1Kenny Root        }
307bd79419ef84ae31f3765721b50aa413fa462d1d1Kenny Root    }
308bd79419ef84ae31f3765721b50aa413fa462d1d1Kenny Root
3095cb5cec6a4a4d5432d4ce6468c12de9508db1633Kenny Root    public boolean isHardwareBacked() {
3105cb5cec6a4a4d5432d4ce6468c12de9508db1633Kenny Root        try {
3115cb5cec6a4a4d5432d4ce6468c12de9508db1633Kenny Root            return mBinder.is_hardware_backed() == NO_ERROR;
3125cb5cec6a4a4d5432d4ce6468c12de9508db1633Kenny Root        } catch (RemoteException e) {
3135cb5cec6a4a4d5432d4ce6468c12de9508db1633Kenny Root            Log.w(TAG, "Cannot connect to keystore", e);
3145cb5cec6a4a4d5432d4ce6468c12de9508db1633Kenny Root            return false;
3155cb5cec6a4a4d5432d4ce6468c12de9508db1633Kenny Root        }
3165cb5cec6a4a4d5432d4ce6468c12de9508db1633Kenny Root    }
3175cb5cec6a4a4d5432d4ce6468c12de9508db1633Kenny Root
318d72317abd79ddf95d48c8f35bf1070900ff55b5eKenny Root    public boolean clearUid(int uid) {
319d72317abd79ddf95d48c8f35bf1070900ff55b5eKenny Root        try {
320d72317abd79ddf95d48c8f35bf1070900ff55b5eKenny Root            return mBinder.clear_uid(uid) == NO_ERROR;
321d72317abd79ddf95d48c8f35bf1070900ff55b5eKenny Root        } catch (RemoteException e) {
322d72317abd79ddf95d48c8f35bf1070900ff55b5eKenny Root            Log.w(TAG, "Cannot connect to keystore", e);
323d72317abd79ddf95d48c8f35bf1070900ff55b5eKenny Root            return false;
324d72317abd79ddf95d48c8f35bf1070900ff55b5eKenny Root        }
325d72317abd79ddf95d48c8f35bf1070900ff55b5eKenny Root    }
326d72317abd79ddf95d48c8f35bf1070900ff55b5eKenny Root
3276b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root    public int getLastError() {
3286b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        return mError;
32934c47c855815d731e6deb55748ff690b0ec7b53fNick Kralevich    }
33044039172627d1c15737ea73836ad375559d76211Chia-chi Yeh}
331