OSDN Git Service

Generate IKeystoreService using aidl
[android-x86/frameworks-base.git] / keystore / java / android / security / KeyStore.java
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
17 package android.security;
18
19 import com.android.org.conscrypt.NativeCrypto;
20
21 import android.os.RemoteException;
22 import android.os.ServiceManager;
23 import android.util.Log;
24
25 import java.util.Locale;
26
27 /**
28  * @hide This should not be made public in its present form because it
29  * assumes that private and secret key bytes are available and would
30  * preclude the use of hardware crypto.
31  */
32 public class KeyStore {
33     private static final String TAG = "KeyStore";
34
35     // ResponseCodes
36     public static final int NO_ERROR = 1;
37     public static final int LOCKED = 2;
38     public static final int UNINITIALIZED = 3;
39     public static final int SYSTEM_ERROR = 4;
40     public static final int PROTOCOL_ERROR = 5;
41     public static final int PERMISSION_DENIED = 6;
42     public static final int KEY_NOT_FOUND = 7;
43     public static final int VALUE_CORRUPTED = 8;
44     public static final int UNDEFINED_ACTION = 9;
45     public static final int WRONG_PASSWORD = 10;
46
47     // Used for UID field to indicate the calling UID.
48     public static final int UID_SELF = -1;
49
50     // Flags for "put" "import" and "generate"
51     public static final int FLAG_NONE = 0;
52     public static final int FLAG_ENCRYPTED = 1;
53
54     // States
55     public enum State { UNLOCKED, LOCKED, UNINITIALIZED };
56
57     private int mError = NO_ERROR;
58
59     private final IKeystoreService mBinder;
60
61     private KeyStore(IKeystoreService binder) {
62         mBinder = binder;
63     }
64
65     public static KeyStore getInstance() {
66         IKeystoreService keystore = IKeystoreService.Stub.asInterface(ServiceManager
67                 .getService("android.security.keystore"));
68         return new KeyStore(keystore);
69     }
70
71     static int getKeyTypeForAlgorithm(String keyType) throws IllegalArgumentException {
72         if ("RSA".equalsIgnoreCase(keyType)) {
73             return NativeCrypto.EVP_PKEY_RSA;
74         } else if ("EC".equalsIgnoreCase(keyType)) {
75             return NativeCrypto.EVP_PKEY_EC;
76         } else {
77             throw new IllegalArgumentException("Unsupported key type: " + keyType);
78         }
79     }
80
81     public State state() {
82         final int ret;
83         try {
84             ret = mBinder.test();
85         } catch (RemoteException e) {
86             Log.w(TAG, "Cannot connect to keystore", e);
87             throw new AssertionError(e);
88         }
89
90         switch (ret) {
91             case NO_ERROR: return State.UNLOCKED;
92             case LOCKED: return State.LOCKED;
93             case UNINITIALIZED: return State.UNINITIALIZED;
94             default: throw new AssertionError(mError);
95         }
96     }
97
98     public boolean isUnlocked() {
99         return state() == State.UNLOCKED;
100     }
101
102     public byte[] get(String key) {
103         try {
104             return mBinder.get(key);
105         } catch (RemoteException e) {
106             Log.w(TAG, "Cannot connect to keystore", e);
107             return null;
108         }
109     }
110
111     public boolean put(String key, byte[] value, int uid, int flags) {
112         try {
113             return mBinder.insert(key, value, uid, flags) == NO_ERROR;
114         } catch (RemoteException e) {
115             Log.w(TAG, "Cannot connect to keystore", e);
116             return false;
117         }
118     }
119
120     public boolean delete(String key, int uid) {
121         try {
122             return mBinder.del(key, uid) == NO_ERROR;
123         } catch (RemoteException e) {
124             Log.w(TAG, "Cannot connect to keystore", e);
125             return false;
126         }
127     }
128
129     public boolean delete(String key) {
130         return delete(key, UID_SELF);
131     }
132
133     public boolean contains(String key, int uid) {
134         try {
135             return mBinder.exist(key, uid) == NO_ERROR;
136         } catch (RemoteException e) {
137             Log.w(TAG, "Cannot connect to keystore", e);
138             return false;
139         }
140     }
141
142     public boolean contains(String key) {
143         return contains(key, UID_SELF);
144     }
145
146     public String[] saw(String prefix, int uid) {
147         try {
148             return mBinder.saw(prefix, uid);
149         } catch (RemoteException e) {
150             Log.w(TAG, "Cannot connect to keystore", e);
151             return null;
152         }
153     }
154
155     public String[] saw(String prefix) {
156         return saw(prefix, UID_SELF);
157     }
158
159     public boolean reset() {
160         try {
161             return mBinder.reset() == NO_ERROR;
162         } catch (RemoteException e) {
163             Log.w(TAG, "Cannot connect to keystore", e);
164             return false;
165         }
166     }
167
168     public boolean password(String password) {
169         try {
170             return mBinder.password(password) == NO_ERROR;
171         } catch (RemoteException e) {
172             Log.w(TAG, "Cannot connect to keystore", e);
173             return false;
174         }
175     }
176
177     public boolean lock() {
178         try {
179             return mBinder.lock() == NO_ERROR;
180         } catch (RemoteException e) {
181             Log.w(TAG, "Cannot connect to keystore", e);
182             return false;
183         }
184     }
185
186     public boolean unlock(String password) {
187         try {
188             mError = mBinder.unlock(password);
189             return mError == NO_ERROR;
190         } catch (RemoteException e) {
191             Log.w(TAG, "Cannot connect to keystore", e);
192             return false;
193         }
194     }
195
196     public boolean isEmpty() {
197         try {
198             return mBinder.zero() == KEY_NOT_FOUND;
199         } catch (RemoteException e) {
200             Log.w(TAG, "Cannot connect to keystore", e);
201             return false;
202         }
203     }
204
205     public boolean generate(String key, int uid, int keyType, int keySize, int flags,
206             byte[][] args) {
207         try {
208             return mBinder.generate(key, uid, keyType, keySize, flags,
209                     new KeystoreArguments(args)) == NO_ERROR;
210         } catch (RemoteException e) {
211             Log.w(TAG, "Cannot connect to keystore", e);
212             return false;
213         }
214     }
215
216     public boolean importKey(String keyName, byte[] key, int uid, int flags) {
217         try {
218             return mBinder.import_key(keyName, key, uid, flags) == NO_ERROR;
219         } catch (RemoteException e) {
220             Log.w(TAG, "Cannot connect to keystore", e);
221             return false;
222         }
223     }
224
225     public byte[] getPubkey(String key) {
226         try {
227             return mBinder.get_pubkey(key);
228         } catch (RemoteException e) {
229             Log.w(TAG, "Cannot connect to keystore", e);
230             return null;
231         }
232     }
233
234     public boolean delKey(String key, int uid) {
235         try {
236             return mBinder.del_key(key, uid) == NO_ERROR;
237         } catch (RemoteException e) {
238             Log.w(TAG, "Cannot connect to keystore", e);
239             return false;
240         }
241     }
242
243     public boolean delKey(String key) {
244         return delKey(key, UID_SELF);
245     }
246
247     public byte[] sign(String key, byte[] data) {
248         try {
249             return mBinder.sign(key, data);
250         } catch (RemoteException e) {
251             Log.w(TAG, "Cannot connect to keystore", e);
252             return null;
253         }
254     }
255
256     public boolean verify(String key, byte[] data, byte[] signature) {
257         try {
258             return mBinder.verify(key, data, signature) == NO_ERROR;
259         } catch (RemoteException e) {
260             Log.w(TAG, "Cannot connect to keystore", e);
261             return false;
262         }
263     }
264
265     public boolean grant(String key, int uid) {
266         try {
267             return mBinder.grant(key, uid) == NO_ERROR;
268         } catch (RemoteException e) {
269             Log.w(TAG, "Cannot connect to keystore", e);
270             return false;
271         }
272     }
273
274     public boolean ungrant(String key, int uid) {
275         try {
276             return mBinder.ungrant(key, uid) == NO_ERROR;
277         } catch (RemoteException e) {
278             Log.w(TAG, "Cannot connect to keystore", e);
279             return false;
280         }
281     }
282
283     /**
284      * Returns the last modification time of the key in milliseconds since the
285      * epoch. Will return -1L if the key could not be found or other error.
286      */
287     public long getmtime(String key) {
288         try {
289             final long millis = mBinder.getmtime(key);
290             if (millis == -1L) {
291                 return -1L;
292             }
293
294             return millis * 1000L;
295         } catch (RemoteException e) {
296             Log.w(TAG, "Cannot connect to keystore", e);
297             return -1L;
298         }
299     }
300
301     public boolean duplicate(String srcKey, int srcUid, String destKey, int destUid) {
302         try {
303             return mBinder.duplicate(srcKey, srcUid, destKey, destUid) == NO_ERROR;
304         } catch (RemoteException e) {
305             Log.w(TAG, "Cannot connect to keystore", e);
306             return false;
307         }
308     }
309
310     // TODO remove this when it's removed from Settings
311     public boolean isHardwareBacked() {
312         return isHardwareBacked("RSA");
313     }
314
315     public boolean isHardwareBacked(String keyType) {
316         try {
317             return mBinder.is_hardware_backed(keyType.toUpperCase(Locale.US)) == NO_ERROR;
318         } catch (RemoteException e) {
319             Log.w(TAG, "Cannot connect to keystore", e);
320             return false;
321         }
322     }
323
324     public boolean clearUid(int uid) {
325         try {
326             return mBinder.clear_uid(uid) == NO_ERROR;
327         } catch (RemoteException e) {
328             Log.w(TAG, "Cannot connect to keystore", e);
329             return false;
330         }
331     }
332
333     public boolean resetUid(int uid) {
334         try {
335             mError = mBinder.reset_uid(uid);
336             return mError == NO_ERROR;
337         } catch (RemoteException e) {
338             Log.w(TAG, "Cannot connect to keystore", e);
339             return false;
340         }
341     }
342
343     public boolean syncUid(int sourceUid, int targetUid) {
344         try {
345             mError = mBinder.sync_uid(sourceUid, targetUid);
346             return mError == NO_ERROR;
347         } catch (RemoteException e) {
348             Log.w(TAG, "Cannot connect to keystore", e);
349             return false;
350         }
351     }
352
353     public boolean passwordUid(String password, int uid) {
354         try {
355             mError = mBinder.password_uid(password, uid);
356             return mError == NO_ERROR;
357         } catch (RemoteException e) {
358             Log.w(TAG, "Cannot connect to keystore", e);
359             return false;
360         }
361     }
362
363     public int getLastError() {
364         return mError;
365     }
366 }