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