• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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