KeyStore.java revision e66769ad5194cb4533d1087416a2e804ac384285
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 byte[] get(String key) {
78        try {
79            return mBinder.get(key);
80        } catch (RemoteException e) {
81            Log.w(TAG, "Cannot connect to keystore", e);
82            return null;
83        }
84    }
85
86    public boolean put(String key, byte[] value) {
87        try {
88            return mBinder.insert(key, value) == NO_ERROR;
89        } catch (RemoteException e) {
90            Log.w(TAG, "Cannot connect to keystore", e);
91            return false;
92        }
93    }
94
95    public boolean delete(String key) {
96        try {
97            return mBinder.del(key) == NO_ERROR;
98        } catch (RemoteException e) {
99            Log.w(TAG, "Cannot connect to keystore", e);
100            return false;
101        }
102    }
103
104    public boolean contains(String key) {
105        try {
106            return mBinder.exist(key) == NO_ERROR;
107        } catch (RemoteException e) {
108            Log.w(TAG, "Cannot connect to keystore", e);
109            return false;
110        }
111    }
112
113    public String[] saw(String prefix) {
114        try {
115            return mBinder.saw(prefix);
116        } catch (RemoteException e) {
117            Log.w(TAG, "Cannot connect to keystore", e);
118            return null;
119        }
120    }
121
122    public boolean reset() {
123        try {
124            return mBinder.reset() == NO_ERROR;
125        } catch (RemoteException e) {
126            Log.w(TAG, "Cannot connect to keystore", e);
127            return false;
128        }
129    }
130
131    public boolean password(String password) {
132        try {
133            return mBinder.password(password) == NO_ERROR;
134        } catch (RemoteException e) {
135            Log.w(TAG, "Cannot connect to keystore", e);
136            return false;
137        }
138    }
139
140    public boolean lock() {
141        try {
142            return mBinder.lock() == NO_ERROR;
143        } catch (RemoteException e) {
144            Log.w(TAG, "Cannot connect to keystore", e);
145            return false;
146        }
147    }
148
149    public boolean unlock(String password) {
150        try {
151            mError = mBinder.unlock(password);
152            return mError == NO_ERROR;
153        } catch (RemoteException e) {
154            Log.w(TAG, "Cannot connect to keystore", e);
155            return false;
156        }
157    }
158
159    public boolean isEmpty() {
160        try {
161            return mBinder.zero() == KEY_NOT_FOUND;
162        } catch (RemoteException e) {
163            Log.w(TAG, "Cannot connect to keystore", e);
164            return false;
165        }
166    }
167
168    public boolean generate(String key) {
169        try {
170            return mBinder.generate(key) == NO_ERROR;
171        } catch (RemoteException e) {
172            Log.w(TAG, "Cannot connect to keystore", e);
173            return false;
174        }
175    }
176
177    public boolean importKey(String keyName, byte[] key) {
178        try {
179            return mBinder.import_key(keyName, key) == NO_ERROR;
180        } catch (RemoteException e) {
181            Log.w(TAG, "Cannot connect to keystore", e);
182            return false;
183        }
184    }
185
186    public byte[] getPubkey(String key) {
187        try {
188            return mBinder.get_pubkey(key);
189        } catch (RemoteException e) {
190            Log.w(TAG, "Cannot connect to keystore", e);
191            return null;
192        }
193    }
194
195    public boolean delKey(String key) {
196        try {
197            return mBinder.del_key(key) == NO_ERROR;
198        } catch (RemoteException e) {
199            Log.w(TAG, "Cannot connect to keystore", e);
200            return false;
201        }
202    }
203
204    public byte[] sign(String key, byte[] data) {
205        try {
206            return mBinder.sign(key, data);
207        } catch (RemoteException e) {
208            Log.w(TAG, "Cannot connect to keystore", e);
209            return null;
210        }
211    }
212
213    public boolean verify(String key, byte[] data, byte[] signature) {
214        try {
215            return mBinder.verify(key, data, signature) == NO_ERROR;
216        } catch (RemoteException e) {
217            Log.w(TAG, "Cannot connect to keystore", e);
218            return false;
219        }
220    }
221
222    public boolean grant(String key, int uid) {
223        try {
224            return mBinder.grant(key, uid) == NO_ERROR;
225        } catch (RemoteException e) {
226            Log.w(TAG, "Cannot connect to keystore", e);
227            return false;
228        }
229    }
230
231    public boolean ungrant(String key, int uid) {
232        try {
233            return mBinder.ungrant(key, uid) == NO_ERROR;
234        } catch (RemoteException e) {
235            Log.w(TAG, "Cannot connect to keystore", e);
236            return false;
237        }
238    }
239
240    /**
241     * Returns the last modification time of the key in milliseconds since the
242     * epoch. Will return -1L if the key could not be found or other error.
243     */
244    public long getmtime(String key) {
245        try {
246            final long millis = mBinder.getmtime(key);
247            if (millis == -1L) {
248                return -1L;
249            }
250
251            return millis * 1000L;
252        } catch (RemoteException e) {
253            Log.w(TAG, "Cannot connect to keystore", e);
254            return -1L;
255        }
256    }
257
258    public int getLastError() {
259        return mError;
260    }
261}
262