Merge "Switch keystore to binder"

This commit is contained in:
Kenny Root
2012-11-14 14:17:27 -08:00
committed by Gerrit Code Review
3 changed files with 639 additions and 220 deletions

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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));
try {
return mBinder.getmtime(key);
} catch (RemoteException e) {
Log.w(TAG, "Cannot connect to keystore", e);
return -1L;
}
}
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);
}
}
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);
}
}