KeyStore.java revision b9594ce9ebb3f5f303a280f04312ae5754ce3560
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
196b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Rootimport android.os.RemoteException;
206b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Rootimport android.os.ServiceManager;
216b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Rootimport android.util.Log;
2244039172627d1c15737ea73836ad375559d76211Chia-chi Yeh
2344039172627d1c15737ea73836ad375559d76211Chia-chi Yeh/**
2446703b099516c383a6882815bcf9cd4df0ec538dBrian Carlstrom * @hide This should not be made public in its present form because it
2546703b099516c383a6882815bcf9cd4df0ec538dBrian Carlstrom * assumes that private and secret key bytes are available and would
2646703b099516c383a6882815bcf9cd4df0ec538dBrian Carlstrom * preclude the use of hardware crypto.
2744039172627d1c15737ea73836ad375559d76211Chia-chi Yeh */
2844039172627d1c15737ea73836ad375559d76211Chia-chi Yehpublic class KeyStore {
296b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root    private static final String TAG = "KeyStore";
305cfee3fabb3482c6a6df1c8b6f21e843cf214527Brian Carlstrom
315cfee3fabb3482c6a6df1c8b6f21e843cf214527Brian Carlstrom    // ResponseCodes
327e4b1a488dd02c4bf6156379e36834e9e01c5b1bBrian Carlstrom    public static final int NO_ERROR = 1;
337e4b1a488dd02c4bf6156379e36834e9e01c5b1bBrian Carlstrom    public static final int LOCKED = 2;
347e4b1a488dd02c4bf6156379e36834e9e01c5b1bBrian Carlstrom    public static final int UNINITIALIZED = 3;
357e4b1a488dd02c4bf6156379e36834e9e01c5b1bBrian Carlstrom    public static final int SYSTEM_ERROR = 4;
367e4b1a488dd02c4bf6156379e36834e9e01c5b1bBrian Carlstrom    public static final int PROTOCOL_ERROR = 5;
377e4b1a488dd02c4bf6156379e36834e9e01c5b1bBrian Carlstrom    public static final int PERMISSION_DENIED = 6;
387e4b1a488dd02c4bf6156379e36834e9e01c5b1bBrian Carlstrom    public static final int KEY_NOT_FOUND = 7;
397e4b1a488dd02c4bf6156379e36834e9e01c5b1bBrian Carlstrom    public static final int VALUE_CORRUPTED = 8;
407e4b1a488dd02c4bf6156379e36834e9e01c5b1bBrian Carlstrom    public static final int UNDEFINED_ACTION = 9;
417e4b1a488dd02c4bf6156379e36834e9e01c5b1bBrian Carlstrom    public static final int WRONG_PASSWORD = 10;
425cfee3fabb3482c6a6df1c8b6f21e843cf214527Brian Carlstrom
435cfee3fabb3482c6a6df1c8b6f21e843cf214527Brian Carlstrom    // States
445cfee3fabb3482c6a6df1c8b6f21e843cf214527Brian Carlstrom    public enum State { UNLOCKED, LOCKED, UNINITIALIZED };
4544039172627d1c15737ea73836ad375559d76211Chia-chi Yeh
4644039172627d1c15737ea73836ad375559d76211Chia-chi Yeh    private int mError = NO_ERROR;
4744039172627d1c15737ea73836ad375559d76211Chia-chi Yeh
486b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root    private final IKeystoreService mBinder;
496b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root
506b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root    private KeyStore(IKeystoreService binder) {
516b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        mBinder = binder;
526b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root    }
5344039172627d1c15737ea73836ad375559d76211Chia-chi Yeh
5444039172627d1c15737ea73836ad375559d76211Chia-chi Yeh    public static KeyStore getInstance() {
556b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        IKeystoreService keystore = IKeystoreService.Stub.asInterface(ServiceManager
566b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root                .getService("android.security.keystore"));
576b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        return new KeyStore(keystore);
5844039172627d1c15737ea73836ad375559d76211Chia-chi Yeh    }
5944039172627d1c15737ea73836ad375559d76211Chia-chi Yeh
605cfee3fabb3482c6a6df1c8b6f21e843cf214527Brian Carlstrom    public State state() {
616b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        final int ret;
626b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        try {
636b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            ret = mBinder.test();
646b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        } catch (RemoteException e) {
656b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            Log.w(TAG, "Cannot connect to keystore", e);
666b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            throw new AssertionError(e);
676b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        }
686b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root
696b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        switch (ret) {
705cfee3fabb3482c6a6df1c8b6f21e843cf214527Brian Carlstrom            case NO_ERROR: return State.UNLOCKED;
715cfee3fabb3482c6a6df1c8b6f21e843cf214527Brian Carlstrom            case LOCKED: return State.LOCKED;
725cfee3fabb3482c6a6df1c8b6f21e843cf214527Brian Carlstrom            case UNINITIALIZED: return State.UNINITIALIZED;
735cfee3fabb3482c6a6df1c8b6f21e843cf214527Brian Carlstrom            default: throw new AssertionError(mError);
745cfee3fabb3482c6a6df1c8b6f21e843cf214527Brian Carlstrom        }
75b9594ce9ebb3f5f303a280f04312ae5754ce3560Kenny Root    }
76b9594ce9ebb3f5f303a280f04312ae5754ce3560Kenny Root
77b9594ce9ebb3f5f303a280f04312ae5754ce3560Kenny Root    public boolean isUnlocked() {
78b9594ce9ebb3f5f303a280f04312ae5754ce3560Kenny Root        return state() == State.UNLOCKED;
7944039172627d1c15737ea73836ad375559d76211Chia-chi Yeh    }
8044039172627d1c15737ea73836ad375559d76211Chia-chi Yeh
815cfee3fabb3482c6a6df1c8b6f21e843cf214527Brian Carlstrom    public byte[] get(String key) {
826b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        try {
836b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            return mBinder.get(key);
846b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        } catch (RemoteException e) {
856b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            Log.w(TAG, "Cannot connect to keystore", e);
866b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            return null;
876b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        }
8844039172627d1c15737ea73836ad375559d76211Chia-chi Yeh    }
8944039172627d1c15737ea73836ad375559d76211Chia-chi Yeh
905cfee3fabb3482c6a6df1c8b6f21e843cf214527Brian Carlstrom    public boolean put(String key, byte[] value) {
916b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        try {
92e151f281d527f4bea5cbdf4219d5e0507a6668b0Kenny Root            return mBinder.insert(key, value, -1) == NO_ERROR;
936b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        } catch (RemoteException e) {
946b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            Log.w(TAG, "Cannot connect to keystore", e);
956b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            return false;
966b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        }
9744039172627d1c15737ea73836ad375559d76211Chia-chi Yeh    }
9844039172627d1c15737ea73836ad375559d76211Chia-chi Yeh
9944039172627d1c15737ea73836ad375559d76211Chia-chi Yeh    public boolean delete(String key) {
1006b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        try {
101e151f281d527f4bea5cbdf4219d5e0507a6668b0Kenny Root            return mBinder.del(key, -1) == NO_ERROR;
1026b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        } catch (RemoteException e) {
1036b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            Log.w(TAG, "Cannot connect to keystore", e);
1046b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            return false;
1056b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        }
10644039172627d1c15737ea73836ad375559d76211Chia-chi Yeh    }
10744039172627d1c15737ea73836ad375559d76211Chia-chi Yeh
10844039172627d1c15737ea73836ad375559d76211Chia-chi Yeh    public boolean contains(String key) {
1096b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        try {
110e151f281d527f4bea5cbdf4219d5e0507a6668b0Kenny Root            return mBinder.exist(key, -1) == NO_ERROR;
1116b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        } catch (RemoteException e) {
1126b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            Log.w(TAG, "Cannot connect to keystore", e);
1136b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            return false;
1146b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        }
11544039172627d1c15737ea73836ad375559d76211Chia-chi Yeh    }
11644039172627d1c15737ea73836ad375559d76211Chia-chi Yeh
117613fcc850686dfe71cec9809c3694be9cf02cdc7Chia-chi Yeh    public String[] saw(String prefix) {
1186b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        try {
119e151f281d527f4bea5cbdf4219d5e0507a6668b0Kenny Root            return mBinder.saw(prefix, -1);
1206b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        } catch (RemoteException e) {
1216b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            Log.w(TAG, "Cannot connect to keystore", e);
12244039172627d1c15737ea73836ad375559d76211Chia-chi Yeh            return null;
12344039172627d1c15737ea73836ad375559d76211Chia-chi Yeh        }
12444039172627d1c15737ea73836ad375559d76211Chia-chi Yeh    }
12544039172627d1c15737ea73836ad375559d76211Chia-chi Yeh
12644039172627d1c15737ea73836ad375559d76211Chia-chi Yeh    public boolean reset() {
1276b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        try {
1286b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            return mBinder.reset() == NO_ERROR;
1296b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        } catch (RemoteException e) {
1306b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            Log.w(TAG, "Cannot connect to keystore", e);
1316b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            return false;
1326b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        }
13344039172627d1c15737ea73836ad375559d76211Chia-chi Yeh    }
13444039172627d1c15737ea73836ad375559d76211Chia-chi Yeh
13544039172627d1c15737ea73836ad375559d76211Chia-chi Yeh    public boolean password(String password) {
1366b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        try {
1376b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            return mBinder.password(password) == 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
14444039172627d1c15737ea73836ad375559d76211Chia-chi Yeh    public boolean lock() {
1456b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        try {
1466b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            return mBinder.lock() == NO_ERROR;
1476b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        } catch (RemoteException e) {
1486b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            Log.w(TAG, "Cannot connect to keystore", e);
1496b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            return false;
1506b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        }
15144039172627d1c15737ea73836ad375559d76211Chia-chi Yeh    }
15244039172627d1c15737ea73836ad375559d76211Chia-chi Yeh
15344039172627d1c15737ea73836ad375559d76211Chia-chi Yeh    public boolean unlock(String password) {
1546b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        try {
1556b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            mError = mBinder.unlock(password);
1566b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            return mError == NO_ERROR;
1576b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        } catch (RemoteException e) {
1586b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            Log.w(TAG, "Cannot connect to keystore", e);
1596b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            return false;
1606b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        }
16144039172627d1c15737ea73836ad375559d76211Chia-chi Yeh    }
16244039172627d1c15737ea73836ad375559d76211Chia-chi Yeh
1635cfee3fabb3482c6a6df1c8b6f21e843cf214527Brian Carlstrom    public boolean isEmpty() {
1646b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        try {
1656b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            return mBinder.zero() == KEY_NOT_FOUND;
1666b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        } catch (RemoteException e) {
1676b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            Log.w(TAG, "Cannot connect to keystore", e);
1686b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            return false;
1696b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        }
1705423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root    }
1715423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root
1725423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root    public boolean generate(String key) {
1736b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        try {
174e151f281d527f4bea5cbdf4219d5e0507a6668b0Kenny Root            return mBinder.generate(key, -1) == NO_ERROR;
1756b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        } catch (RemoteException e) {
1766b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            Log.w(TAG, "Cannot connect to keystore", e);
1776b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            return false;
1786b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        }
1795423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root    }
1805423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root
1815423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root    public boolean importKey(String keyName, byte[] key) {
1826b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        try {
183e151f281d527f4bea5cbdf4219d5e0507a6668b0Kenny Root            return mBinder.import_key(keyName, key, -1) == NO_ERROR;
1846b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        } catch (RemoteException e) {
1856b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            Log.w(TAG, "Cannot connect to keystore", e);
1866b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            return false;
1876b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        }
1885423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root    }
1895423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root
1905423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root    public byte[] getPubkey(String key) {
1916b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        try {
1926b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            return mBinder.get_pubkey(key);
1936b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        } catch (RemoteException e) {
1946b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            Log.w(TAG, "Cannot connect to keystore", e);
1956b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            return null;
1966b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        }
1975423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root    }
1985423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root
1995423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root    public boolean delKey(String key) {
2006b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        try {
201e151f281d527f4bea5cbdf4219d5e0507a6668b0Kenny Root            return mBinder.del_key(key, -1) == NO_ERROR;
2026b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        } catch (RemoteException e) {
2036b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            Log.w(TAG, "Cannot connect to keystore", e);
2046b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            return false;
2056b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        }
2065423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root    }
2075423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root
2085423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root    public byte[] sign(String key, byte[] data) {
2096b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        try {
2106b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            return mBinder.sign(key, data);
2116b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        } catch (RemoteException e) {
2126b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            Log.w(TAG, "Cannot connect to keystore", e);
2136b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            return null;
2146b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        }
2155423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root    }
2165423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root
2175423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root    public boolean verify(String key, byte[] data, byte[] signature) {
2186b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        try {
2196b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            return mBinder.verify(key, data, signature) == 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 boolean grant(String key, int uid) {
2276b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        try {
2286b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            return mBinder.grant(key, uid) == NO_ERROR;
2296b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        } catch (RemoteException e) {
2306b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            Log.w(TAG, "Cannot connect to keystore", e);
2316b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            return false;
2326b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        }
2335423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root    }
2345423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root
2355423e68d5dbe048ec6f042cce52a33f94184e9fbKenny Root    public boolean ungrant(String key, int uid) {
2366b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        try {
2376b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            return mBinder.ungrant(key, uid) == NO_ERROR;
2386b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        } catch (RemoteException e) {
2396b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            Log.w(TAG, "Cannot connect to keystore", e);
2406b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            return false;
241473c712b19bad992ab4eafcd43175fdce77b913dKenny Root        }
242473c712b19bad992ab4eafcd43175fdce77b913dKenny Root    }
243473c712b19bad992ab4eafcd43175fdce77b913dKenny Root
244473c712b19bad992ab4eafcd43175fdce77b913dKenny Root    /**
245473c712b19bad992ab4eafcd43175fdce77b913dKenny Root     * Returns the last modification time of the key in milliseconds since the
246473c712b19bad992ab4eafcd43175fdce77b913dKenny Root     * epoch. Will return -1L if the key could not be found or other error.
247473c712b19bad992ab4eafcd43175fdce77b913dKenny Root     */
248473c712b19bad992ab4eafcd43175fdce77b913dKenny Root    public long getmtime(String key) {
2495b1f037829bff93877a6257db69f4e7723a27e20Brian Carlstrom        try {
250e66769ad5194cb4533d1087416a2e804ac384285Kenny Root            final long millis = mBinder.getmtime(key);
251e66769ad5194cb4533d1087416a2e804ac384285Kenny Root            if (millis == -1L) {
252e66769ad5194cb4533d1087416a2e804ac384285Kenny Root                return -1L;
253e66769ad5194cb4533d1087416a2e804ac384285Kenny Root            }
254e66769ad5194cb4533d1087416a2e804ac384285Kenny Root
255e66769ad5194cb4533d1087416a2e804ac384285Kenny Root            return millis * 1000L;
2566b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        } catch (RemoteException e) {
2576b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            Log.w(TAG, "Cannot connect to keystore", e);
2586b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root            return -1L;
2595b1f037829bff93877a6257db69f4e7723a27e20Brian Carlstrom        }
2605b1f037829bff93877a6257db69f4e7723a27e20Brian Carlstrom    }
2615b1f037829bff93877a6257db69f4e7723a27e20Brian Carlstrom
2626b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root    public int getLastError() {
2636b77645aa9ac51ce33ea67adba226aaf1a6e8846Kenny Root        return mError;
26434c47c855815d731e6deb55748ff690b0ec7b53fNick Kralevich    }
26544039172627d1c15737ea73836ad375559d76211Chia-chi Yeh}
266