KeyStore.java revision 613fcc850686dfe71cec9809c3694be9cf02cdc7
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.net.LocalSocketAddress; 20import android.net.LocalSocket; 21 22import java.io.InputStream; 23import java.io.IOException; 24import java.io.OutputStream; 25import java.util.ArrayList; 26 27/** 28 * {@hide} 29 */ 30public class KeyStore { 31 public static int NO_ERROR = 1; 32 public static int LOCKED = 2; 33 public static int UNINITIALIZED = 3; 34 public static int SYSTEM_ERROR = 4; 35 public static int PROTOCOL_ERROR = 5; 36 public static int PERMISSION_DENIED = 6; 37 public static int KEY_NOT_FOUND = 7; 38 public static int VALUE_CORRUPTED = 8; 39 public static int UNDEFINED_ACTION = 9; 40 public static int WRONG_PASSWORD = 10; 41 42 private static final LocalSocketAddress sAddress = new LocalSocketAddress( 43 "keystore", LocalSocketAddress.Namespace.RESERVED); 44 45 private int mError = NO_ERROR; 46 47 private KeyStore() {} 48 49 public static KeyStore getInstance() { 50 return new KeyStore(); 51 } 52 53 public int test() { 54 execute('t'); 55 return mError; 56 } 57 58 public byte[] get(byte[] key) { 59 byte[][] values = execute('g', key); 60 return (values == null) ? null : values[0]; 61 } 62 63 public String get(String key) { 64 byte[] value = get(key.getBytes()); 65 return (value == null) ? null : new String(value); 66 } 67 68 public boolean put(byte[] key, byte[] value) { 69 execute('i', key, value); 70 return mError == NO_ERROR; 71 } 72 73 public boolean put(String key, String value) { 74 return put(key.getBytes(), value.getBytes()); 75 } 76 77 public boolean delete(byte[] key) { 78 execute('d', key); 79 return mError == NO_ERROR; 80 } 81 82 public boolean delete(String key) { 83 return delete(key.getBytes()); 84 } 85 86 public boolean contains(byte[] key) { 87 execute('e', key); 88 return mError == NO_ERROR; 89 } 90 91 public boolean contains(String key) { 92 return contains(key.getBytes()); 93 } 94 95 public byte[][] saw(byte[] prefix) { 96 return execute('s', prefix); 97 } 98 99 public String[] saw(String prefix) { 100 byte[][] values = saw(prefix.getBytes()); 101 if (values == null) { 102 return null; 103 } 104 String[] strings = new String[values.length]; 105 for (int i = 0; i < values.length; ++i) { 106 strings[i] = new String(values[i]); 107 } 108 return strings; 109 } 110 111 public boolean reset() { 112 execute('r'); 113 return mError == NO_ERROR; 114 } 115 116 public boolean password(byte[] oldPassword, byte[] newPassword) { 117 execute('p', oldPassword, newPassword); 118 return mError == NO_ERROR; 119 } 120 121 public boolean password(String oldPassword, String newPassword) { 122 return password(oldPassword.getBytes(), newPassword.getBytes()); 123 } 124 125 public boolean password(byte[] password) { 126 return password(password, password); 127 } 128 129 public boolean password(String password) { 130 return password(password.getBytes()); 131 } 132 133 public boolean lock() { 134 execute('l'); 135 return mError == NO_ERROR; 136 } 137 138 public boolean unlock(byte[] password) { 139 execute('u', password); 140 return mError == NO_ERROR; 141 } 142 143 public boolean unlock(String password) { 144 return unlock(password.getBytes()); 145 } 146 147 public int getLastError() { 148 return mError; 149 } 150 151 private byte[][] execute(int code, byte[]... parameters) { 152 mError = PROTOCOL_ERROR; 153 154 for (byte[] parameter : parameters) { 155 if (parameter == null || parameter.length > 65535) { 156 return null; 157 } 158 } 159 160 LocalSocket socket = new LocalSocket(); 161 try { 162 socket.connect(sAddress); 163 164 OutputStream out = socket.getOutputStream(); 165 out.write(code); 166 for (byte[] parameter : parameters) { 167 out.write(parameter.length >> 8); 168 out.write(parameter.length); 169 out.write(parameter); 170 } 171 out.flush(); 172 socket.shutdownOutput(); 173 174 InputStream in = socket.getInputStream(); 175 code = in.read(); 176 if (code == -1) { 177 return null; 178 } 179 180 ArrayList<byte[]> results = new ArrayList<byte[]>(); 181 while (true) { 182 int i, j; 183 if ((i = in.read()) == -1) { 184 break; 185 } 186 if ((j = in.read()) == -1) { 187 return null; 188 } 189 byte[] result = new byte[i << 8 | j]; 190 for (i = 0; i < result.length; i += j) { 191 if ((j = in.read(result, i, result.length - i)) == -1) { 192 return null; 193 } 194 } 195 results.add(result); 196 } 197 mError = code; 198 return results.toArray(new byte[results.size()][]); 199 } catch (IOException e) { 200 // ignore 201 } finally { 202 try { 203 socket.close(); 204 } catch (IOException e) {} 205 } 206 return null; 207 } 208} 209