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.net.LocalSocketAddress; 20 import android.net.LocalSocket; 21 22 import java.io.InputStream; 23 import java.io.IOException; 24 import java.io.OutputStream; 25 import java.util.ArrayList; 26 27 /** 28 * {@hide} 29 */ 30 public 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 KeyStore()47 private KeyStore() {} 48 getInstance()49 public static KeyStore getInstance() { 50 return new KeyStore(); 51 } 52 test()53 public int test() { 54 execute('t'); 55 return mError; 56 } 57 get(byte[] key)58 public byte[] get(byte[] key) { 59 byte[][] values = execute('g', key); 60 return (values == null) ? null : values[0]; 61 } 62 get(String key)63 public String get(String key) { 64 byte[] value = get(key.getBytes()); 65 return (value == null) ? null : new String(value); 66 } 67 put(byte[] key, byte[] value)68 public boolean put(byte[] key, byte[] value) { 69 execute('i', key, value); 70 return mError == NO_ERROR; 71 } 72 put(String key, String value)73 public boolean put(String key, String value) { 74 return put(key.getBytes(), value.getBytes()); 75 } 76 delete(byte[] key)77 public boolean delete(byte[] key) { 78 execute('d', key); 79 return mError == NO_ERROR; 80 } 81 delete(String key)82 public boolean delete(String key) { 83 return delete(key.getBytes()); 84 } 85 contains(byte[] key)86 public boolean contains(byte[] key) { 87 execute('e', key); 88 return mError == NO_ERROR; 89 } 90 contains(String key)91 public boolean contains(String key) { 92 return contains(key.getBytes()); 93 } 94 saw(byte[] prefix)95 public byte[][] saw(byte[] prefix) { 96 return execute('s', prefix); 97 } 98 saw(String prefix)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 reset()111 public boolean reset() { 112 execute('r'); 113 return mError == NO_ERROR; 114 } 115 password(byte[] oldPassword, byte[] newPassword)116 public boolean password(byte[] oldPassword, byte[] newPassword) { 117 execute('p', oldPassword, newPassword); 118 return mError == NO_ERROR; 119 } 120 password(String oldPassword, String newPassword)121 public boolean password(String oldPassword, String newPassword) { 122 return password(oldPassword.getBytes(), newPassword.getBytes()); 123 } 124 password(byte[] password)125 public boolean password(byte[] password) { 126 return password(password, password); 127 } 128 password(String password)129 public boolean password(String password) { 130 return password(password.getBytes()); 131 } 132 lock()133 public boolean lock() { 134 execute('l'); 135 return mError == NO_ERROR; 136 } 137 unlock(byte[] password)138 public boolean unlock(byte[] password) { 139 execute('u', password); 140 return mError == NO_ERROR; 141 } 142 unlock(String password)143 public boolean unlock(String password) { 144 return unlock(password.getBytes()); 145 } 146 getLastError()147 public int getLastError() { 148 return mError; 149 } 150 execute(int code, byte[]... parameters)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 if ((code = in.read()) != NO_ERROR) { 176 if (code != -1) { 177 mError = code; 178 } 179 return null; 180 } 181 182 ArrayList<byte[]> results = new ArrayList<byte[]>(); 183 while (true) { 184 int i, j; 185 if ((i = in.read()) == -1) { 186 break; 187 } 188 if ((j = in.read()) == -1) { 189 return null; 190 } 191 byte[] result = new byte[i << 8 | j]; 192 for (i = 0; i < result.length; i += j) { 193 if ((j = in.read(result, i, result.length - i)) == -1) { 194 return null; 195 } 196 } 197 results.add(result); 198 } 199 mError = NO_ERROR; 200 return results.toArray(new byte[results.size()][]); 201 } catch (IOException e) { 202 // ignore 203 } finally { 204 try { 205 socket.close(); 206 } catch (IOException e) {} 207 } 208 return null; 209 } 210 } 211