KeyStore.java revision bd79419ef84ae31f3765721b50aa413fa462d1d1
1/*
2 * Copyright (C) 2009 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.security;
18
19import android.os.RemoteException;
20import android.os.ServiceManager;
21import android.util.Log;
22
23/**
24 * @hide This should not be made public in its present form because it
25 * assumes that private and secret key bytes are available and would
26 * preclude the use of hardware crypto.
27 */
28public class KeyStore {
29    private static final String TAG = "KeyStore";
30
31    // ResponseCodes
32    public static final int NO_ERROR = 1;
33    public static final int LOCKED = 2;
34    public static final int UNINITIALIZED = 3;
35    public static final int SYSTEM_ERROR = 4;
36    public static final int PROTOCOL_ERROR = 5;
37    public static final int PERMISSION_DENIED = 6;
38    public static final int KEY_NOT_FOUND = 7;
39    public static final int VALUE_CORRUPTED = 8;
40    public static final int UNDEFINED_ACTION = 9;
41    public static final int WRONG_PASSWORD = 10;
42
43    // States
44    public enum State { UNLOCKED, LOCKED, UNINITIALIZED };
45
46    private int mError = NO_ERROR;
47
48    private final IKeystoreService mBinder;
49
50    private KeyStore(IKeystoreService binder) {
51        mBinder = binder;
52    }
53
54    public static KeyStore getInstance() {
55        IKeystoreService keystore = IKeystoreService.Stub.asInterface(ServiceManager
56                .getService("android.security.keystore"));
57        return new KeyStore(keystore);
58    }
59
60    public State state() {
61        final int ret;
62        try {
63            ret = mBinder.test();
64        } catch (RemoteException e) {
65            Log.w(TAG, "Cannot connect to keystore", e);
66            throw new AssertionError(e);
67        }
68
69        switch (ret) {
70            case NO_ERROR: return State.UNLOCKED;
71            case LOCKED: return State.LOCKED;
72            case UNINITIALIZED: return State.UNINITIALIZED;
73            default: throw new AssertionError(mError);
74        }
75    }
76
77    public boolean isUnlocked() {
78        return state() == State.UNLOCKED;
79    }
80
81    public byte[] get(String key) {
82        try {
83            return mBinder.get(key);
84        } catch (RemoteException e) {
85            Log.w(TAG, "Cannot connect to keystore", e);
86            return null;
87        }
88    }
89
90    public boolean put(String key, byte[] value, int uid) {
91        try {
92            return mBinder.insert(key, value, uid) == NO_ERROR;
93        } catch (RemoteException e) {
94            Log.w(TAG, "Cannot connect to keystore", e);
95            return false;
96        }
97    }
98
99    public boolean put(String key, byte[] value) {
100        return put(key, value, -1);
101    }
102
103    public boolean delete(String key, int uid) {
104        try {
105            return mBinder.del(key, uid) == NO_ERROR;
106        } catch (RemoteException e) {
107            Log.w(TAG, "Cannot connect to keystore", e);
108            return false;
109        }
110    }
111
112    public boolean delete(String key) {
113        return delete(key, -1);
114    }
115
116    public boolean contains(String key, int uid) {
117        try {
118            return mBinder.exist(key, uid) == NO_ERROR;
119        } catch (RemoteException e) {
120            Log.w(TAG, "Cannot connect to keystore", e);
121            return false;
122        }
123    }
124
125    public boolean contains(String key) {
126        return contains(key, -1);
127    }
128
129    public String[] saw(String prefix, int uid) {
130        try {
131            return mBinder.saw(prefix, uid);
132        } catch (RemoteException e) {
133            Log.w(TAG, "Cannot connect to keystore", e);
134            return null;
135        }
136    }
137
138    public String[] saw(String prefix) {
139        return saw(prefix, -1);
140    }
141
142    public boolean reset() {
143        try {
144            return mBinder.reset() == NO_ERROR;
145        } catch (RemoteException e) {
146            Log.w(TAG, "Cannot connect to keystore", e);
147            return false;
148        }
149    }
150
151    public boolean password(String password) {
152        try {
153            return mBinder.password(password) == NO_ERROR;
154        } catch (RemoteException e) {
155            Log.w(TAG, "Cannot connect to keystore", e);
156            return false;
157        }
158    }
159
160    public boolean lock() {
161        try {
162            return mBinder.lock() == NO_ERROR;
163        } catch (RemoteException e) {
164            Log.w(TAG, "Cannot connect to keystore", e);
165            return false;
166        }
167    }
168
169    public boolean unlock(String password) {
170        try {
171            mError = mBinder.unlock(password);
172            return mError == NO_ERROR;
173        } catch (RemoteException e) {
174            Log.w(TAG, "Cannot connect to keystore", e);
175            return false;
176        }
177    }
178
179    public boolean isEmpty() {
180        try {
181            return mBinder.zero() == KEY_NOT_FOUND;
182        } catch (RemoteException e) {
183            Log.w(TAG, "Cannot connect to keystore", e);
184            return false;
185        }
186    }
187
188    public boolean generate(String key, int uid) {
189        try {
190            return mBinder.generate(key, uid) == NO_ERROR;
191        } catch (RemoteException e) {
192            Log.w(TAG, "Cannot connect to keystore", e);
193            return false;
194        }
195    }
196
197    public boolean generate(String key) {
198        return generate(key, -1);
199    }
200
201    public boolean importKey(String keyName, byte[] key, int uid) {
202        try {
203            return mBinder.import_key(keyName, key, uid) == NO_ERROR;
204        } catch (RemoteException e) {
205            Log.w(TAG, "Cannot connect to keystore", e);
206            return false;
207        }
208    }
209
210    public boolean importKey(String keyName, byte[] key) {
211        return importKey(keyName, key, -1);
212    }
213
214    public byte[] getPubkey(String key) {
215        try {
216            return mBinder.get_pubkey(key);
217        } catch (RemoteException e) {
218            Log.w(TAG, "Cannot connect to keystore", e);
219            return null;
220        }
221    }
222
223    public boolean delKey(String key, int uid) {
224        try {
225            return mBinder.del_key(key, uid) == NO_ERROR;
226        } catch (RemoteException e) {
227            Log.w(TAG, "Cannot connect to keystore", e);
228            return false;
229        }
230    }
231
232    public boolean delKey(String key) {
233        return delKey(key, -1);
234    }
235
236    public byte[] sign(String key, byte[] data) {
237        try {
238            return mBinder.sign(key, data);
239        } catch (RemoteException e) {
240            Log.w(TAG, "Cannot connect to keystore", e);
241            return null;
242        }
243    }
244
245    public boolean verify(String key, byte[] data, byte[] signature) {
246        try {
247            return mBinder.verify(key, data, signature) == NO_ERROR;
248        } catch (RemoteException e) {
249            Log.w(TAG, "Cannot connect to keystore", e);
250            return false;
251        }
252    }
253
254    public boolean grant(String key, int uid) {
255        try {
256            return mBinder.grant(key, uid) == NO_ERROR;
257        } catch (RemoteException e) {
258            Log.w(TAG, "Cannot connect to keystore", e);
259            return false;
260        }
261    }
262
263    public boolean ungrant(String key, int uid) {
264        try {
265            return mBinder.ungrant(key, uid) == NO_ERROR;
266        } catch (RemoteException e) {
267            Log.w(TAG, "Cannot connect to keystore", e);
268            return false;
269        }
270    }
271
272    /**
273     * Returns the last modification time of the key in milliseconds since the
274     * epoch. Will return -1L if the key could not be found or other error.
275     */
276    public long getmtime(String key) {
277        try {
278            final long millis = mBinder.getmtime(key);
279            if (millis == -1L) {
280                return -1L;
281            }
282
283            return millis * 1000L;
284        } catch (RemoteException e) {
285            Log.w(TAG, "Cannot connect to keystore", e);
286            return -1L;
287        }
288    }
289
290    public boolean migrate(String key, int uid) {
291        try {
292            return mBinder.migrate(key, uid) == NO_ERROR;
293        } catch (RemoteException e) {
294            Log.w(TAG, "Cannot connect to keystore", e);
295            return false;
296        }
297    }
298
299    public int getLastError() {
300        return mError;
301    }
302}
303