OSDN Git Service

original
[gb-231r1-is01/Gingerbread_2.3.3_r1_IS01.git] / frameworks / base / keystore / java / android / security / KeyStore.java
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.io.UnsupportedEncodingException;
26 import java.util.ArrayList;
27
28 /**
29  * {@hide}
30  */
31 public class KeyStore {
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     private static final LocalSocketAddress sAddress = new LocalSocketAddress(
44             "keystore", LocalSocketAddress.Namespace.RESERVED);
45
46     private int mError = NO_ERROR;
47
48     private KeyStore() {}
49
50     public static KeyStore getInstance() {
51         return new KeyStore();
52     }
53
54     public int test() {
55         execute('t');
56         return mError;
57     }
58
59     public byte[] get(byte[] key) {
60         ArrayList<byte[]> values = execute('g', key);
61         return (values == null || values.isEmpty()) ? null : values.get(0);
62     }
63
64     public String get(String key) {
65         byte[] value = get(getBytes(key));
66         return (value == null) ? null : toString(value);
67     }
68
69     public boolean put(byte[] key, byte[] value) {
70         execute('i', key, value);
71         return mError == NO_ERROR;
72     }
73
74     public boolean put(String key, String value) {
75         return put(getBytes(key), getBytes(value));
76     }
77
78     public boolean delete(byte[] key) {
79         execute('d', key);
80         return mError == NO_ERROR;
81     }
82
83     public boolean delete(String key) {
84         return delete(getBytes(key));
85     }
86
87     public boolean contains(byte[] key) {
88         execute('e', key);
89         return mError == NO_ERROR;
90     }
91
92     public boolean contains(String key) {
93         return contains(getBytes(key));
94     }
95
96     public byte[][] saw(byte[] prefix) {
97         ArrayList<byte[]> values = execute('s', prefix);
98         return (values == null) ? null : values.toArray(new byte[values.size()][]);
99     }
100
101     public String[] saw(String prefix) {
102         byte[][] values = saw(getBytes(prefix));
103         if (values == null) {
104             return null;
105         }
106         String[] strings = new String[values.length];
107         for (int i = 0; i < values.length; ++i) {
108             strings[i] = toString(values[i]);
109         }
110         return strings;
111     }
112
113     public boolean reset() {
114         execute('r');
115         return mError == NO_ERROR;
116     }
117
118     public boolean password(byte[] oldPassword, byte[] newPassword) {
119         execute('p', oldPassword, newPassword);
120         return mError == NO_ERROR;
121     }
122
123     public boolean password(String oldPassword, String newPassword) {
124         return password(getBytes(oldPassword), getBytes(newPassword));
125     }
126
127     public boolean password(byte[] password) {
128         return password(password, password);
129     }
130
131     public boolean password(String password) {
132         return password(getBytes(password));
133     }
134
135     public boolean lock() {
136         execute('l');
137         return mError == NO_ERROR;
138     }
139
140     public boolean unlock(byte[] password) {
141         execute('u', password);
142         return mError == NO_ERROR;
143     }
144
145     public boolean unlock(String password) {
146         return unlock(getBytes(password));
147     }
148
149     public int getLastError() {
150         return mError;
151     }
152
153     private ArrayList<byte[]> execute(int code, byte[]... parameters) {
154         mError = PROTOCOL_ERROR;
155
156         for (byte[] parameter : parameters) {
157             if (parameter == null || parameter.length > 65535) {
158                 return null;
159             }
160         }
161
162         LocalSocket socket = new LocalSocket();
163         try {
164             socket.connect(sAddress);
165
166             OutputStream out = socket.getOutputStream();
167             out.write(code);
168             for (byte[] parameter : parameters) {
169                 out.write(parameter.length >> 8);
170                 out.write(parameter.length);
171                 out.write(parameter);
172             }
173             out.flush();
174             socket.shutdownOutput();
175
176             InputStream in = socket.getInputStream();
177             if ((code = in.read()) != NO_ERROR) {
178                 if (code != -1) {
179                     mError = code;
180                 }
181                 return null;
182             }
183
184             ArrayList<byte[]> values = new ArrayList<byte[]>();
185             while (true) {
186                 int i, j;
187                 if ((i = in.read()) == -1) {
188                     break;
189                 }
190                 if ((j = in.read()) == -1) {
191                     return null;
192                 }
193                 byte[] value = new byte[i << 8 | j];
194                 for (i = 0; i < value.length; i += j) {
195                     if ((j = in.read(value, i, value.length - i)) == -1) {
196                         return null;
197                     }
198                 }
199                 values.add(value);
200             }
201             mError = NO_ERROR;
202             return values;
203         } catch (IOException e) {
204             // ignore
205         } finally {
206             try {
207                 socket.close();
208             } catch (IOException e) {}
209         }
210         return null;
211     }
212
213     private static byte[] getBytes(String string) {
214         try {
215             return string.getBytes("UTF-8");
216         } catch (UnsupportedEncodingException e) {
217             // will never happen
218             throw new RuntimeException(e);
219         }
220     }
221
222     private static String toString(byte[] bytes) {
223         try {
224             return new String(bytes, "UTF-8");
225         } catch (UnsupportedEncodingException e) {
226             // will never happen
227             throw new RuntimeException(e);
228         }
229     }
230 }