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 android.os.RemoteException; 20 import android.os.ServiceManager; 21 import 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 */ 28 public 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 // Used for UID field to indicate the calling UID. 44 public static final int UID_SELF = -1; 45 46 // Flags for "put" "import" and "generate" 47 public static final int FLAG_NONE = 0; 48 public static final int FLAG_ENCRYPTED = 1; 49 50 // States 51 public enum State { UNLOCKED, LOCKED, UNINITIALIZED }; 52 53 private int mError = NO_ERROR; 54 55 private final IKeystoreService mBinder; 56 57 private KeyStore(IKeystoreService binder) { 58 mBinder = binder; 59 } 60 61 public static KeyStore getInstance() { 62 IKeystoreService keystore = IKeystoreService.Stub.asInterface(ServiceManager 63 .getService("android.security.keystore")); 64 return new KeyStore(keystore); 65 } 66 67 public State state() { 68 final int ret; 69 try { 70 ret = mBinder.test(); 71 } catch (RemoteException e) { 72 Log.w(TAG, "Cannot connect to keystore", e); 73 throw new AssertionError(e); 74 } 75 76 switch (ret) { 77 case NO_ERROR: return State.UNLOCKED; 78 case LOCKED: return State.LOCKED; 79 case UNINITIALIZED: return State.UNINITIALIZED; 80 default: throw new AssertionError(mError); 81 } 82 } 83 84 public boolean isUnlocked() { 85 return state() == State.UNLOCKED; 86 } 87 88 public byte[] get(String key) { 89 try { 90 return mBinder.get(key); 91 } catch (RemoteException e) { 92 Log.w(TAG, "Cannot connect to keystore", e); 93 return null; 94 } 95 } 96 97 public boolean put(String key, byte[] value, int uid, int flags) { 98 try { 99 return mBinder.insert(key, value, uid, flags) == NO_ERROR; 100 } catch (RemoteException e) { 101 Log.w(TAG, "Cannot connect to keystore", e); 102 return false; 103 } 104 } 105 106 public boolean delete(String key, int uid) { 107 try { 108 return mBinder.del(key, uid) == NO_ERROR; 109 } catch (RemoteException e) { 110 Log.w(TAG, "Cannot connect to keystore", e); 111 return false; 112 } 113 } 114 115 public boolean delete(String key) { 116 return delete(key, UID_SELF); 117 } 118 119 public boolean contains(String key, int uid) { 120 try { 121 return mBinder.exist(key, uid) == NO_ERROR; 122 } catch (RemoteException e) { 123 Log.w(TAG, "Cannot connect to keystore", e); 124 return false; 125 } 126 } 127 128 public boolean contains(String key) { 129 return contains(key, UID_SELF); 130 } 131 132 public String[] saw(String prefix, int uid) { 133 try { 134 return mBinder.saw(prefix, uid); 135 } catch (RemoteException e) { 136 Log.w(TAG, "Cannot connect to keystore", e); 137 return null; 138 } 139 } 140 141 public String[] saw(String prefix) { 142 return saw(prefix, UID_SELF); 143 } 144 145 public boolean reset() { 146 try { 147 return mBinder.reset() == NO_ERROR; 148 } catch (RemoteException e) { 149 Log.w(TAG, "Cannot connect to keystore", e); 150 return false; 151 } 152 } 153 154 public boolean password(String password) { 155 try { 156 return mBinder.password(password) == NO_ERROR; 157 } catch (RemoteException e) { 158 Log.w(TAG, "Cannot connect to keystore", e); 159 return false; 160 } 161 } 162 163 public boolean lock() { 164 try { 165 return mBinder.lock() == NO_ERROR; 166 } catch (RemoteException e) { 167 Log.w(TAG, "Cannot connect to keystore", e); 168 return false; 169 } 170 } 171 172 public boolean unlock(String password) { 173 try { 174 mError = mBinder.unlock(password); 175 return mError == NO_ERROR; 176 } catch (RemoteException e) { 177 Log.w(TAG, "Cannot connect to keystore", e); 178 return false; 179 } 180 } 181 182 public boolean isEmpty() { 183 try { 184 return mBinder.zero() == KEY_NOT_FOUND; 185 } catch (RemoteException e) { 186 Log.w(TAG, "Cannot connect to keystore", e); 187 return false; 188 } 189 } 190 191 public boolean generate(String key, int uid, int flags) { 192 try { 193 return mBinder.generate(key, uid, flags) == NO_ERROR; 194 } catch (RemoteException e) { 195 Log.w(TAG, "Cannot connect to keystore", e); 196 return false; 197 } 198 } 199 200 public boolean importKey(String keyName, byte[] key, int uid, int flags) { 201 try { 202 return mBinder.import_key(keyName, key, uid, flags) == NO_ERROR; 203 } catch (RemoteException e) { 204 Log.w(TAG, "Cannot connect to keystore", e); 205 return false; 206 } 207 } 208 209 public byte[] getPubkey(String key) { 210 try { 211 return mBinder.get_pubkey(key); 212 } catch (RemoteException e) { 213 Log.w(TAG, "Cannot connect to keystore", e); 214 return null; 215 } 216 } 217 218 public boolean delKey(String key, int uid) { 219 try { 220 return mBinder.del_key(key, uid) == NO_ERROR; 221 } catch (RemoteException e) { 222 Log.w(TAG, "Cannot connect to keystore", e); 223 return false; 224 } 225 } 226 227 public boolean delKey(String key) { 228 return delKey(key, UID_SELF); 229 } 230 231 public byte[] sign(String key, byte[] data) { 232 try { 233 return mBinder.sign(key, data); 234 } catch (RemoteException e) { 235 Log.w(TAG, "Cannot connect to keystore", e); 236 return null; 237 } 238 } 239 240 public boolean verify(String key, byte[] data, byte[] signature) { 241 try { 242 return mBinder.verify(key, data, signature) == NO_ERROR; 243 } catch (RemoteException e) { 244 Log.w(TAG, "Cannot connect to keystore", e); 245 return false; 246 } 247 } 248 249 public boolean grant(String key, int uid) { 250 try { 251 return mBinder.grant(key, uid) == NO_ERROR; 252 } catch (RemoteException e) { 253 Log.w(TAG, "Cannot connect to keystore", e); 254 return false; 255 } 256 } 257 258 public boolean ungrant(String key, int uid) { 259 try { 260 return mBinder.ungrant(key, uid) == NO_ERROR; 261 } catch (RemoteException e) { 262 Log.w(TAG, "Cannot connect to keystore", e); 263 return false; 264 } 265 } 266 267 /** 268 * Returns the last modification time of the key in milliseconds since the 269 * epoch. Will return -1L if the key could not be found or other error. 270 */ 271 public long getmtime(String key) { 272 try { 273 final long millis = mBinder.getmtime(key); 274 if (millis == -1L) { 275 return -1L; 276 } 277 278 return millis * 1000L; 279 } catch (RemoteException e) { 280 Log.w(TAG, "Cannot connect to keystore", e); 281 return -1L; 282 } 283 } 284 285 public boolean duplicate(String srcKey, int srcUid, String destKey, int destUid) { 286 try { 287 return mBinder.duplicate(srcKey, srcUid, destKey, destUid) == NO_ERROR; 288 } catch (RemoteException e) { 289 Log.w(TAG, "Cannot connect to keystore", e); 290 return false; 291 } 292 } 293 294 public boolean isHardwareBacked() { 295 try { 296 return mBinder.is_hardware_backed() == NO_ERROR; 297 } catch (RemoteException e) { 298 Log.w(TAG, "Cannot connect to keystore", e); 299 return false; 300 } 301 } 302 303 public boolean clearUid(int uid) { 304 try { 305 return mBinder.clear_uid(uid) == NO_ERROR; 306 } catch (RemoteException e) { 307 Log.w(TAG, "Cannot connect to keystore", e); 308 return false; 309 } 310 } 311 312 public int getLastError() { 313 return mError; 314 } 315 } 316