summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cmds/servicemanager/service_manager.c1
-rw-r--r--core/java/android/security/IKeystoreService.java505
-rw-r--r--keystore/java/android/security/KeyStore.java353
3 files changed, 639 insertions, 220 deletions
diff --git a/cmds/servicemanager/service_manager.c b/cmds/servicemanager/service_manager.c
index 71e840e..c563a82 100644
--- a/cmds/servicemanager/service_manager.c
+++ b/cmds/servicemanager/service_manager.c
@@ -47,6 +47,7 @@ static struct {
{ AID_RADIO, "simphonebook" },
{ AID_MEDIA, "common_time.clock" },
{ AID_MEDIA, "common_time.config" },
+ { AID_KEYSTORE, "android.security.keystore" },
};
void *svcmgr_handle;
diff --git a/core/java/android/security/IKeystoreService.java b/core/java/android/security/IKeystoreService.java
new file mode 100644
index 0000000..f8a49e6
--- /dev/null
+++ b/core/java/android/security/IKeystoreService.java
@@ -0,0 +1,505 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security;
+
+import android.os.Binder;
+import android.os.IBinder;
+import android.os.IInterface;
+import android.os.Parcel;
+import android.os.RemoteException;
+
+/**
+ * This must be kept manually in sync with system/security/keystore until AIDL
+ * can generate both Java and C++ bindings.
+ *
+ * @hide
+ */
+public interface IKeystoreService extends IInterface {
+ public static abstract class Stub extends Binder implements IKeystoreService {
+ private static class Proxy implements IKeystoreService {
+ private final IBinder mRemote;
+
+ Proxy(IBinder remote) {
+ mRemote = remote;
+ }
+
+ public IBinder asBinder() {
+ return mRemote;
+ }
+
+ public String getInterfaceDescriptor() {
+ return DESCRIPTOR;
+ }
+
+ public int test() throws RemoteException {
+ Parcel _data = Parcel.obtain();
+ Parcel _reply = Parcel.obtain();
+ int _result;
+ try {
+ _data.writeInterfaceToken(DESCRIPTOR);
+ mRemote.transact(Stub.TRANSACTION_test, _data, _reply, 0);
+ _reply.readException();
+ _result = _reply.readInt();
+ } finally {
+ _reply.recycle();
+ _data.recycle();
+ }
+ return _result;
+ }
+
+ public byte[] get(String name) throws RemoteException {
+ Parcel _data = Parcel.obtain();
+ Parcel _reply = Parcel.obtain();
+ byte[] _result;
+ try {
+ _data.writeInterfaceToken(DESCRIPTOR);
+ _data.writeString(name);
+ mRemote.transact(Stub.TRANSACTION_get, _data, _reply, 0);
+ _reply.readException();
+ _result = _reply.createByteArray();
+ } finally {
+ _reply.recycle();
+ _data.recycle();
+ }
+ return _result;
+ }
+
+ public int insert(String name, byte[] item) throws RemoteException {
+ Parcel _data = Parcel.obtain();
+ Parcel _reply = Parcel.obtain();
+ int _result;
+ try {
+ _data.writeInterfaceToken(DESCRIPTOR);
+ _data.writeString(name);
+ _data.writeByteArray(item);
+ mRemote.transact(Stub.TRANSACTION_insert, _data, _reply, 0);
+ _reply.readException();
+ _result = _reply.readInt();
+ } finally {
+ _reply.recycle();
+ _data.recycle();
+ }
+ return _result;
+ }
+
+ public int del(String name) throws RemoteException {
+ Parcel _data = Parcel.obtain();
+ Parcel _reply = Parcel.obtain();
+ int _result;
+ try {
+ _data.writeInterfaceToken(DESCRIPTOR);
+ _data.writeString(name);
+ mRemote.transact(Stub.TRANSACTION_del, _data, _reply, 0);
+ _reply.readException();
+ _result = _reply.readInt();
+ } finally {
+ _reply.recycle();
+ _data.recycle();
+ }
+ return _result;
+ }
+
+ public int exist(String name) throws RemoteException {
+ Parcel _data = Parcel.obtain();
+ Parcel _reply = Parcel.obtain();
+ int _result;
+ try {
+ _data.writeInterfaceToken(DESCRIPTOR);
+ _data.writeString(name);
+ mRemote.transact(Stub.TRANSACTION_exist, _data, _reply, 0);
+ _reply.readException();
+ _result = _reply.readInt();
+ } finally {
+ _reply.recycle();
+ _data.recycle();
+ }
+ return _result;
+ }
+
+ public String[] saw(String name) throws RemoteException {
+ Parcel _data = Parcel.obtain();
+ Parcel _reply = Parcel.obtain();
+ String[] _result;
+ try {
+ _data.writeInterfaceToken(DESCRIPTOR);
+ _data.writeString(name);
+ mRemote.transact(Stub.TRANSACTION_saw, _data, _reply, 0);
+ _reply.readException();
+ int size = _reply.readInt();
+ _result = new String[size];
+ for (int i = 0; i < size; i++) {
+ _result[i] = _reply.readString();
+ }
+ } finally {
+ _reply.recycle();
+ _data.recycle();
+ }
+ return _result;
+ }
+
+ @Override
+ public int reset() throws RemoteException {
+ Parcel _data = Parcel.obtain();
+ Parcel _reply = Parcel.obtain();
+ int _result;
+ try {
+ _data.writeInterfaceToken(DESCRIPTOR);
+ mRemote.transact(Stub.TRANSACTION_reset, _data, _reply, 0);
+ _reply.readException();
+ _result = _reply.readInt();
+ } finally {
+ _reply.recycle();
+ _data.recycle();
+ }
+ return _result;
+ }
+
+ public int password(String password) throws RemoteException {
+ Parcel _data = Parcel.obtain();
+ Parcel _reply = Parcel.obtain();
+ int _result;
+ try {
+ _data.writeInterfaceToken(DESCRIPTOR);
+ _data.writeString(password);
+ mRemote.transact(Stub.TRANSACTION_password, _data, _reply, 0);
+ _reply.readException();
+ _result = _reply.readInt();
+ } finally {
+ _reply.recycle();
+ _data.recycle();
+ }
+ return _result;
+ }
+
+ public int lock() throws RemoteException {
+ Parcel _data = Parcel.obtain();
+ Parcel _reply = Parcel.obtain();
+ int _result;
+ try {
+ _data.writeInterfaceToken(DESCRIPTOR);
+ mRemote.transact(Stub.TRANSACTION_lock, _data, _reply, 0);
+ _reply.readException();
+ _result = _reply.readInt();
+ } finally {
+ _reply.recycle();
+ _data.recycle();
+ }
+ return _result;
+ }
+
+ public int unlock(String password) throws RemoteException {
+ Parcel _data = Parcel.obtain();
+ Parcel _reply = Parcel.obtain();
+ int _result;
+ try {
+ _data.writeInterfaceToken(DESCRIPTOR);
+ _data.writeString(password);
+ mRemote.transact(Stub.TRANSACTION_unlock, _data, _reply, 0);
+ _reply.readException();
+ _result = _reply.readInt();
+ } finally {
+ _reply.recycle();
+ _data.recycle();
+ }
+ return _result;
+ }
+
+ @Override
+ public int zero() throws RemoteException {
+ Parcel _data = Parcel.obtain();
+ Parcel _reply = Parcel.obtain();
+ int _result;
+ try {
+ _data.writeInterfaceToken(DESCRIPTOR);
+ mRemote.transact(Stub.TRANSACTION_zero, _data, _reply, 0);
+ _reply.readException();
+ _result = _reply.readInt();
+ } finally {
+ _reply.recycle();
+ _data.recycle();
+ }
+ return _result;
+ }
+
+ public int generate(String name) throws RemoteException {
+ Parcel _data = Parcel.obtain();
+ Parcel _reply = Parcel.obtain();
+ int _result;
+ try {
+ _data.writeInterfaceToken(DESCRIPTOR);
+ _data.writeString(name);
+ mRemote.transact(Stub.TRANSACTION_generate, _data, _reply, 0);
+ _reply.readException();
+ _result = _reply.readInt();
+ } finally {
+ _reply.recycle();
+ _data.recycle();
+ }
+ return _result;
+ }
+
+ public int import_key(String name, byte[] data) throws RemoteException {
+ Parcel _data = Parcel.obtain();
+ Parcel _reply = Parcel.obtain();
+ int _result;
+ try {
+ _data.writeInterfaceToken(DESCRIPTOR);
+ _data.writeString(name);
+ _data.writeByteArray(data);
+ mRemote.transact(Stub.TRANSACTION_import, _data, _reply, 0);
+ _reply.readException();
+ _result = _reply.readInt();
+ } finally {
+ _reply.recycle();
+ _data.recycle();
+ }
+ return _result;
+ }
+
+ public byte[] sign(String name, byte[] data) throws RemoteException {
+ Parcel _data = Parcel.obtain();
+ Parcel _reply = Parcel.obtain();
+ byte[] _result;
+ try {
+ _data.writeInterfaceToken(DESCRIPTOR);
+ _data.writeString(name);
+ _data.writeByteArray(data);
+ mRemote.transact(Stub.TRANSACTION_sign, _data, _reply, 0);
+ _reply.readException();
+ _result = _reply.createByteArray();
+ } finally {
+ _reply.recycle();
+ _data.recycle();
+ }
+ return _result;
+ }
+
+ public int verify(String name, byte[] data, byte[] signature) throws RemoteException {
+ Parcel _data = Parcel.obtain();
+ Parcel _reply = Parcel.obtain();
+ int _result;
+ try {
+ _data.writeInterfaceToken(DESCRIPTOR);
+ _data.writeString(name);
+ _data.writeByteArray(data);
+ _data.writeByteArray(signature);
+ mRemote.transact(Stub.TRANSACTION_verify, _data, _reply, 0);
+ _reply.readException();
+ _result = _reply.readInt();
+ } finally {
+ _reply.recycle();
+ _data.recycle();
+ }
+ return _result;
+ }
+
+ public byte[] get_pubkey(String name) throws RemoteException {
+ Parcel _data = Parcel.obtain();
+ Parcel _reply = Parcel.obtain();
+ byte[] _result;
+ try {
+ _data.writeInterfaceToken(DESCRIPTOR);
+ _data.writeString(name);
+ mRemote.transact(Stub.TRANSACTION_get_pubkey, _data, _reply, 0);
+ _reply.readException();
+ _result = _reply.createByteArray();
+ } finally {
+ _reply.recycle();
+ _data.recycle();
+ }
+ return _result;
+ }
+
+ public int del_key(String name) throws RemoteException {
+ Parcel _data = Parcel.obtain();
+ Parcel _reply = Parcel.obtain();
+ int _result;
+ try {
+ _data.writeInterfaceToken(DESCRIPTOR);
+ _data.writeString(name);
+ mRemote.transact(Stub.TRANSACTION_del_key, _data, _reply, 0);
+ _reply.readException();
+ _result = _reply.readInt();
+ } finally {
+ _reply.recycle();
+ _data.recycle();
+ }
+ return _result;
+ }
+
+ public int grant(String name, int granteeUid) throws RemoteException {
+ Parcel _data = Parcel.obtain();
+ Parcel _reply = Parcel.obtain();
+ int _result;
+ try {
+ _data.writeInterfaceToken(DESCRIPTOR);
+ _data.writeString(name);
+ _data.writeInt(granteeUid);
+ mRemote.transact(Stub.TRANSACTION_grant, _data, _reply, 0);
+ _reply.readException();
+ _result = _reply.readInt();
+ } finally {
+ _reply.recycle();
+ _data.recycle();
+ }
+ return _result;
+ }
+
+ public int ungrant(String name, int granteeUid) throws RemoteException {
+ Parcel _data = Parcel.obtain();
+ Parcel _reply = Parcel.obtain();
+ int _result;
+ try {
+ _data.writeInterfaceToken(DESCRIPTOR);
+ _data.writeString(name);
+ _data.writeInt(granteeUid);
+ mRemote.transact(Stub.TRANSACTION_ungrant, _data, _reply, 0);
+ _reply.readException();
+ _result = _reply.readInt();
+ } finally {
+ _reply.recycle();
+ _data.recycle();
+ }
+ return _result;
+ }
+
+ @Override
+ public long getmtime(String name) throws RemoteException {
+ Parcel _data = Parcel.obtain();
+ Parcel _reply = Parcel.obtain();
+ long _result;
+ try {
+ _data.writeInterfaceToken(DESCRIPTOR);
+ _data.writeString(name);
+ mRemote.transact(Stub.TRANSACTION_getmtime, _data, _reply, 0);
+ _reply.readException();
+ _result = _reply.readLong();
+ } finally {
+ _reply.recycle();
+ _data.recycle();
+ }
+ return _result;
+ }
+ }
+
+ private static final String DESCRIPTOR = "android.security.keystore";
+
+ static final int TRANSACTION_test = IBinder.FIRST_CALL_TRANSACTION + 0;
+ static final int TRANSACTION_get = IBinder.FIRST_CALL_TRANSACTION + 1;
+ static final int TRANSACTION_insert = IBinder.FIRST_CALL_TRANSACTION + 2;
+ static final int TRANSACTION_del = IBinder.FIRST_CALL_TRANSACTION + 3;
+ static final int TRANSACTION_exist = IBinder.FIRST_CALL_TRANSACTION + 4;
+ static final int TRANSACTION_saw = IBinder.FIRST_CALL_TRANSACTION + 5;
+ static final int TRANSACTION_reset = IBinder.FIRST_CALL_TRANSACTION + 6;
+ static final int TRANSACTION_password = IBinder.FIRST_CALL_TRANSACTION + 7;
+ static final int TRANSACTION_lock = IBinder.FIRST_CALL_TRANSACTION + 8;
+ static final int TRANSACTION_unlock = IBinder.FIRST_CALL_TRANSACTION + 9;
+ static final int TRANSACTION_zero = IBinder.FIRST_CALL_TRANSACTION + 10;
+ static final int TRANSACTION_generate = IBinder.FIRST_CALL_TRANSACTION + 11;
+ static final int TRANSACTION_import = IBinder.FIRST_CALL_TRANSACTION + 12;
+ static final int TRANSACTION_sign = IBinder.FIRST_CALL_TRANSACTION + 13;
+ static final int TRANSACTION_verify = IBinder.FIRST_CALL_TRANSACTION + 14;
+ static final int TRANSACTION_get_pubkey = IBinder.FIRST_CALL_TRANSACTION + 15;
+ static final int TRANSACTION_del_key = IBinder.FIRST_CALL_TRANSACTION + 16;
+ static final int TRANSACTION_grant = IBinder.FIRST_CALL_TRANSACTION + 17;
+ static final int TRANSACTION_ungrant = IBinder.FIRST_CALL_TRANSACTION + 18;
+ static final int TRANSACTION_getmtime = IBinder.FIRST_CALL_TRANSACTION + 19;
+
+ /**
+ * Cast an IBinder object into an IKeystoreService interface, generating
+ * a proxy if needed.
+ */
+ public static IKeystoreService asInterface(IBinder obj) {
+ if (obj == null) {
+ return null;
+ }
+ IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
+ if (iin != null && iin instanceof IKeystoreService) {
+ return (IKeystoreService) iin;
+ }
+ return new IKeystoreService.Stub.Proxy(obj);
+ }
+
+ /** Construct the stub at attach it to the interface. */
+ public Stub() {
+ attachInterface(this, DESCRIPTOR);
+ }
+
+ public IBinder asBinder() {
+ return this;
+ }
+
+ @Override
+ public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
+ throws RemoteException {
+ switch (code) {
+ case INTERFACE_TRANSACTION: {
+ reply.writeString(DESCRIPTOR);
+ return true;
+ }
+ case TRANSACTION_test: {
+ data.enforceInterface(DESCRIPTOR);
+ int resultCode = test();
+ reply.writeNoException();
+ reply.writeInt(resultCode);
+ return true;
+ }
+ }
+ return super.onTransact(code, data, reply, flags);
+ }
+ }
+
+ public int test() throws RemoteException;
+
+ public byte[] get(String name) throws RemoteException;
+
+ public int insert(String name, byte[] item) throws RemoteException;
+
+ public int del(String name) throws RemoteException;
+
+ public int exist(String name) throws RemoteException;
+
+ public String[] saw(String name) throws RemoteException;
+
+ public int reset() throws RemoteException;
+
+ public int password(String password) throws RemoteException;
+
+ public int lock() throws RemoteException;
+
+ public int unlock(String password) throws RemoteException;
+
+ public int zero() throws RemoteException;
+
+ public int generate(String name) throws RemoteException;
+
+ public int import_key(String name, byte[] data) throws RemoteException;
+
+ public byte[] sign(String name, byte[] data) throws RemoteException;
+
+ public int verify(String name, byte[] data, byte[] signature) throws RemoteException;
+
+ public byte[] get_pubkey(String name) throws RemoteException;
+
+ public int del_key(String name) throws RemoteException;
+
+ public int grant(String name, int granteeUid) throws RemoteException;
+
+ public int ungrant(String name, int granteeUid) throws RemoteException;
+
+ public long getmtime(String name) throws RemoteException;
+}
diff --git a/keystore/java/android/security/KeyStore.java b/keystore/java/android/security/KeyStore.java
index 4637991..44be804 100644
--- a/keystore/java/android/security/KeyStore.java
+++ b/keystore/java/android/security/KeyStore.java
@@ -16,17 +16,9 @@
package android.security;
-import android.net.LocalSocketAddress;
-import android.net.LocalSocket;
-
-import java.io.InputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.UTFDataFormatException;
-import java.nio.charset.Charsets;
-import java.nio.charset.ModifiedUtf8;
-import java.util.ArrayList;
-import java.util.Date;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.util.Log;
/**
* @hide This should not be made public in its present form because it
@@ -34,6 +26,7 @@ import java.util.Date;
* preclude the use of hardware crypto.
*/
public class KeyStore {
+ private static final String TAG = "KeyStore";
// ResponseCodes
public static final int NO_ERROR = 1;
@@ -50,20 +43,30 @@ public class KeyStore {
// States
public enum State { UNLOCKED, LOCKED, UNINITIALIZED };
- private static final LocalSocketAddress sAddress = new LocalSocketAddress(
- "keystore", LocalSocketAddress.Namespace.RESERVED);
-
private int mError = NO_ERROR;
- private KeyStore() {}
+ private final IKeystoreService mBinder;
+
+ private KeyStore(IKeystoreService binder) {
+ mBinder = binder;
+ }
public static KeyStore getInstance() {
- return new KeyStore();
+ IKeystoreService keystore = IKeystoreService.Stub.asInterface(ServiceManager
+ .getService("android.security.keystore"));
+ return new KeyStore(keystore);
}
public State state() {
- execute('t');
- switch (mError) {
+ final int ret;
+ try {
+ ret = mBinder.test();
+ } catch (RemoteException e) {
+ Log.w(TAG, "Cannot connect to keystore", e);
+ throw new AssertionError(e);
+ }
+
+ switch (ret) {
case NO_ERROR: return State.UNLOCKED;
case LOCKED: return State.LOCKED;
case UNINITIALIZED: return State.UNINITIALIZED;
@@ -71,171 +74,167 @@ public class KeyStore {
}
}
- private byte[] get(byte[] key) {
- ArrayList<byte[]> values = execute('g', key);
- return (values == null || values.isEmpty()) ? null : values.get(0);
- }
-
public byte[] get(String key) {
- return get(getKeyBytes(key));
- }
-
- private boolean put(byte[] key, byte[] value) {
- execute('i', key, value);
- return mError == NO_ERROR;
+ try {
+ return mBinder.get(key);
+ } catch (RemoteException e) {
+ Log.w(TAG, "Cannot connect to keystore", e);
+ return null;
+ }
}
public boolean put(String key, byte[] value) {
- return put(getKeyBytes(key), value);
- }
-
- private boolean delete(byte[] key) {
- execute('d', key);
- return mError == NO_ERROR;
+ try {
+ return mBinder.insert(key, value) == NO_ERROR;
+ } catch (RemoteException e) {
+ Log.w(TAG, "Cannot connect to keystore", e);
+ return false;
+ }
}
public boolean delete(String key) {
- return delete(getKeyBytes(key));
- }
-
- private boolean contains(byte[] key) {
- execute('e', key);
- return mError == NO_ERROR;
+ try {
+ return mBinder.del(key) == NO_ERROR;
+ } catch (RemoteException e) {
+ Log.w(TAG, "Cannot connect to keystore", e);
+ return false;
+ }
}
public boolean contains(String key) {
- return contains(getKeyBytes(key));
- }
-
- public byte[][] saw(byte[] prefix) {
- ArrayList<byte[]> values = execute('s', prefix);
- return (values == null) ? null : values.toArray(new byte[values.size()][]);
+ try {
+ return mBinder.exist(key) == NO_ERROR;
+ } catch (RemoteException e) {
+ Log.w(TAG, "Cannot connect to keystore", e);
+ return false;
+ }
}
public String[] saw(String prefix) {
- byte[][] values = saw(getKeyBytes(prefix));
- if (values == null) {
+ try {
+ return mBinder.saw(prefix);
+ } catch (RemoteException e) {
+ Log.w(TAG, "Cannot connect to keystore", e);
return null;
}
- String[] strings = new String[values.length];
- for (int i = 0; i < values.length; ++i) {
- strings[i] = toKeyString(values[i]);
- }
- return strings;
}
public boolean reset() {
- execute('r');
- return mError == NO_ERROR;
- }
-
- private boolean password(byte[] password) {
- execute('p', password);
- return mError == NO_ERROR;
+ try {
+ return mBinder.reset() == NO_ERROR;
+ } catch (RemoteException e) {
+ Log.w(TAG, "Cannot connect to keystore", e);
+ return false;
+ }
}
public boolean password(String password) {
- return password(getPasswordBytes(password));
+ try {
+ return mBinder.password(password) == NO_ERROR;
+ } catch (RemoteException e) {
+ Log.w(TAG, "Cannot connect to keystore", e);
+ return false;
+ }
}
public boolean lock() {
- execute('l');
- return mError == NO_ERROR;
- }
-
- private boolean unlock(byte[] password) {
- execute('u', password);
- return mError == NO_ERROR;
+ try {
+ return mBinder.lock() == NO_ERROR;
+ } catch (RemoteException e) {
+ Log.w(TAG, "Cannot connect to keystore", e);
+ return false;
+ }
}
public boolean unlock(String password) {
- return unlock(getPasswordBytes(password));
+ try {
+ mError = mBinder.unlock(password);
+ return mError == NO_ERROR;
+ } catch (RemoteException e) {
+ Log.w(TAG, "Cannot connect to keystore", e);
+ return false;
+ }
}
public boolean isEmpty() {
- execute('z');
- return mError == KEY_NOT_FOUND;
- }
-
- private boolean generate(byte[] key) {
- execute('a', key);
- return mError == NO_ERROR;
+ try {
+ return mBinder.zero() == KEY_NOT_FOUND;
+ } catch (RemoteException e) {
+ Log.w(TAG, "Cannot connect to keystore", e);
+ return false;
+ }
}
public boolean generate(String key) {
- return generate(getKeyBytes(key));
- }
-
- private boolean importKey(byte[] keyName, byte[] key) {
- execute('m', keyName, key);
- return mError == NO_ERROR;
+ try {
+ return mBinder.generate(key) == NO_ERROR;
+ } catch (RemoteException e) {
+ Log.w(TAG, "Cannot connect to keystore", e);
+ return false;
+ }
}
public boolean importKey(String keyName, byte[] key) {
- return importKey(getKeyBytes(keyName), key);
- }
-
- private byte[] getPubkey(byte[] key) {
- ArrayList<byte[]> values = execute('b', key);
- return (values == null || values.isEmpty()) ? null : values.get(0);
+ try {
+ return mBinder.import_key(keyName, key) == NO_ERROR;
+ } catch (RemoteException e) {
+ Log.w(TAG, "Cannot connect to keystore", e);
+ return false;
+ }
}
public byte[] getPubkey(String key) {
- return getPubkey(getKeyBytes(key));
- }
-
- private boolean delKey(byte[] key) {
- execute('k', key);
- return mError == NO_ERROR;
+ try {
+ return mBinder.get_pubkey(key);
+ } catch (RemoteException e) {
+ Log.w(TAG, "Cannot connect to keystore", e);
+ return null;
+ }
}
public boolean delKey(String key) {
- return delKey(getKeyBytes(key));
- }
-
- private byte[] sign(byte[] keyName, byte[] data) {
- final ArrayList<byte[]> values = execute('n', keyName, data);
- return (values == null || values.isEmpty()) ? null : values.get(0);
+ try {
+ return mBinder.del_key(key) == NO_ERROR;
+ } catch (RemoteException e) {
+ Log.w(TAG, "Cannot connect to keystore", e);
+ return false;
+ }
}
public byte[] sign(String key, byte[] data) {
- return sign(getKeyBytes(key), data);
- }
-
- private boolean verify(byte[] keyName, byte[] data, byte[] signature) {
- execute('v', keyName, data, signature);
- return mError == NO_ERROR;
+ try {
+ return mBinder.sign(key, data);
+ } catch (RemoteException e) {
+ Log.w(TAG, "Cannot connect to keystore", e);
+ return null;
+ }
}
public boolean verify(String key, byte[] data, byte[] signature) {
- return verify(getKeyBytes(key), data, signature);
- }
-
- private boolean grant(byte[] key, byte[] uid) {
- execute('x', key, uid);
- return mError == NO_ERROR;
+ try {
+ return mBinder.verify(key, data, signature) == NO_ERROR;
+ } catch (RemoteException e) {
+ Log.w(TAG, "Cannot connect to keystore", e);
+ return false;
+ }
}
public boolean grant(String key, int uid) {
- return grant(getKeyBytes(key), getUidBytes(uid));
- }
-
- private boolean ungrant(byte[] key, byte[] uid) {
- execute('y', key, uid);
- return mError == NO_ERROR;
+ try {
+ return mBinder.grant(key, uid) == NO_ERROR;
+ } catch (RemoteException e) {
+ Log.w(TAG, "Cannot connect to keystore", e);
+ return false;
+ }
}
public boolean ungrant(String key, int uid) {
- return ungrant(getKeyBytes(key), getUidBytes(uid));
- }
-
- private long getmtime(byte[] key) {
- final ArrayList<byte[]> values = execute('c', key);
- if (values == null || values.isEmpty()) {
- return -1L;
+ try {
+ return mBinder.ungrant(key, uid) == NO_ERROR;
+ } catch (RemoteException e) {
+ Log.w(TAG, "Cannot connect to keystore", e);
+ return false;
}
-
- return Long.parseLong(new String(values.get(0))) * 1000L;
}
/**
@@ -243,101 +242,15 @@ public class KeyStore {
* epoch. Will return -1L if the key could not be found or other error.
*/
public long getmtime(String key) {
- return getmtime(getKeyBytes(key));
- }
-
- public int getLastError() {
- return mError;
- }
-
- private ArrayList<byte[]> execute(int code, byte[]... parameters) {
- mError = PROTOCOL_ERROR;
-
- for (byte[] parameter : parameters) {
- if (parameter == null || parameter.length > 65535) {
- return null;
- }
- }
-
- LocalSocket socket = new LocalSocket();
- try {
- socket.connect(sAddress);
-
- OutputStream out = socket.getOutputStream();
- out.write(code);
- for (byte[] parameter : parameters) {
- out.write(parameter.length >> 8);
- out.write(parameter.length);
- out.write(parameter);
- }
- out.flush();
- socket.shutdownOutput();
-
- InputStream in = socket.getInputStream();
- if ((code = in.read()) != NO_ERROR) {
- if (code != -1) {
- mError = code;
- }
- return null;
- }
-
- ArrayList<byte[]> values = new ArrayList<byte[]>();
- while (true) {
- int i, j;
- if ((i = in.read()) == -1) {
- break;
- }
- if ((j = in.read()) == -1) {
- return null;
- }
- byte[] value = new byte[i << 8 | j];
- for (i = 0; i < value.length; i += j) {
- if ((j = in.read(value, i, value.length - i)) == -1) {
- return null;
- }
- }
- values.add(value);
- }
- mError = NO_ERROR;
- return values;
- } catch (IOException e) {
- // ignore
- } finally {
- try {
- socket.close();
- } catch (IOException e) {}
- }
- return null;
- }
-
- /**
- * ModifiedUtf8 is used for key encoding to match the
- * implementation of NativeCrypto.ENGINE_load_private_key.
- */
- private static byte[] getKeyBytes(String string) {
try {
- int utfCount = (int) ModifiedUtf8.countBytes(string, false);
- byte[] result = new byte[utfCount];
- ModifiedUtf8.encode(result, 0, string);
- return result;
- } catch (UTFDataFormatException e) {
- throw new RuntimeException(e);
- }
- }
-
- private static String toKeyString(byte[] bytes) {
- try {
- return ModifiedUtf8.decode(bytes, new char[bytes.length], 0, bytes.length);
- } catch (UTFDataFormatException e) {
- throw new RuntimeException(e);
+ return mBinder.getmtime(key);
+ } catch (RemoteException e) {
+ Log.w(TAG, "Cannot connect to keystore", e);
+ return -1L;
}
}
- private static byte[] getPasswordBytes(String password) {
- return password.getBytes(Charsets.UTF_8);
- }
-
- private static byte[] getUidBytes(int uid) {
- return Integer.toString(uid).getBytes(Charsets.UTF_8);
+ public int getLastError() {
+ return mError;
}
}