You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1361 lines
52 KiB
1361 lines
52 KiB
/* |
|
** |
|
** Copyright 2008, 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. |
|
*/ |
|
|
|
#include <stdint.h> |
|
#include <sys/limits.h> |
|
#include <sys/types.h> |
|
|
|
#include <algorithm> |
|
#include <limits> |
|
|
|
#define LOG_TAG "KeystoreService" |
|
#include <utils/Log.h> |
|
|
|
#include <binder/IPCThreadState.h> |
|
#include <binder/IServiceManager.h> |
|
#include <binder/Parcel.h> |
|
|
|
#include <keystore/IKeystoreService.h> |
|
#include <keystore/keystore_hidl_support.h> |
|
|
|
#include "keystore_aidl_hidl_marshalling_utils.h" |
|
|
|
namespace android { |
|
using namespace ::keystore; |
|
|
|
const ssize_t MAX_GENERATE_ARGS = 3; |
|
|
|
KeystoreArg::KeystoreArg(const void* data, size_t len) : mData(data), mSize(len) {} |
|
|
|
KeystoreArg::~KeystoreArg() {} |
|
|
|
const void* KeystoreArg::data() const { |
|
return mData; |
|
} |
|
|
|
size_t KeystoreArg::size() const { |
|
return mSize; |
|
} |
|
|
|
OperationResult::OperationResult() : resultCode(), token(), handle(0), inputConsumed(0), data() {} |
|
|
|
OperationResult::~OperationResult() {} |
|
|
|
status_t OperationResult::readFromParcel(const Parcel* inn) { |
|
const Parcel& in = *inn; |
|
resultCode = ErrorCode(in.readInt32()); |
|
token = in.readStrongBinder(); |
|
handle = static_cast<uint64_t>(in.readInt64()); |
|
inputConsumed = in.readInt32(); |
|
data = readKeymasterBlob(in); |
|
outParams = readParamSetFromParcel(in); |
|
return OK; |
|
} |
|
|
|
status_t OperationResult::writeToParcel(Parcel* out) const { |
|
out->writeInt32(resultCode); |
|
out->writeStrongBinder(token); |
|
out->writeInt64(handle); |
|
out->writeInt32(inputConsumed); |
|
writeKeymasterBlob(data, out); |
|
writeParamSetToParcel(outParams, out); |
|
return OK; |
|
} |
|
|
|
ExportResult::ExportResult() : resultCode() {} |
|
|
|
ExportResult::~ExportResult() {} |
|
|
|
status_t ExportResult::readFromParcel(const Parcel* inn) { |
|
const Parcel& in = *inn; |
|
resultCode = ErrorCode(in.readInt32()); |
|
exportData = readKeymasterBlob(in); |
|
return OK; |
|
} |
|
|
|
status_t ExportResult::writeToParcel(Parcel* out) const { |
|
out->writeInt32(resultCode); |
|
writeKeymasterBlob(exportData, out); |
|
return OK; |
|
} |
|
|
|
/** |
|
* Read a byte array from in. The data at *data is still owned by the parcel |
|
*/ |
|
static void readByteArray(const Parcel& in, const uint8_t** data, size_t* length) { |
|
ssize_t slength = in.readInt32(); |
|
if (slength > 0) { |
|
*data = reinterpret_cast<const uint8_t*>(in.readInplace(slength)); |
|
if (*data) { |
|
*length = static_cast<size_t>(slength); |
|
} else { |
|
*length = 0; |
|
} |
|
} else { |
|
*data = NULL; |
|
*length = 0; |
|
} |
|
} |
|
|
|
class BpKeystoreService : public BpInterface<IKeystoreService> { |
|
public: |
|
explicit BpKeystoreService(const sp<IBinder>& impl) : BpInterface<IKeystoreService>(impl) {} |
|
|
|
// test ping |
|
KeyStoreServiceReturnCode getState(int32_t userId) override { |
|
Parcel data, reply; |
|
data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor()); |
|
data.writeInt32(userId); |
|
status_t status = remote()->transact(BnKeystoreService::GET_STATE, data, &reply); |
|
if (status != NO_ERROR) { |
|
ALOGD("getState() could not contact remote: %d\n", status); |
|
return ResponseCode::SYSTEM_ERROR; |
|
} |
|
int32_t err = reply.readExceptionCode(); |
|
ResponseCode ret = ResponseCode(reply.readInt32()); |
|
if (err < 0) { |
|
ALOGD("getState() caught exception %d\n", err); |
|
return ResponseCode::SYSTEM_ERROR; |
|
} |
|
return ret; |
|
} |
|
|
|
KeyStoreServiceReturnCode get(const String16& name, int32_t uid, |
|
hidl_vec<uint8_t>* item) override { |
|
Parcel data, reply; |
|
data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor()); |
|
data.writeString16(name); |
|
data.writeInt32(uid); |
|
status_t status = remote()->transact(BnKeystoreService::GET, data, &reply); |
|
if (status != NO_ERROR) { |
|
ALOGD("get() could not contact remote: %d\n", status); |
|
return ResponseCode::SYSTEM_ERROR; |
|
} |
|
int32_t err = reply.readExceptionCode(); |
|
if (err < 0) { |
|
ALOGD("get() caught exception %d\n", err); |
|
return ResponseCode::SYSTEM_ERROR; |
|
} |
|
auto resultItem = readBlobAsByteArray(reply); |
|
if (item) *item = resultItem.value(); |
|
return ResponseCode(reply.readInt32()); |
|
} |
|
|
|
KeyStoreServiceReturnCode insert(const String16& name, const hidl_vec<uint8_t>& item, int uid, |
|
int32_t flags) override { |
|
Parcel data, reply; |
|
data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor()); |
|
data.writeString16(name); |
|
writeBlobAsByteArray(item, &data); |
|
data.writeInt32(uid); |
|
data.writeInt32(flags); |
|
status_t status = remote()->transact(BnKeystoreService::INSERT, data, &reply); |
|
if (status != NO_ERROR) { |
|
ALOGD("import() could not contact remote: %d\n", status); |
|
return ResponseCode::SYSTEM_ERROR; |
|
} |
|
int32_t err = reply.readExceptionCode(); |
|
if (err < 0) { |
|
ALOGD("import() caught exception %d\n", err); |
|
return ResponseCode::SYSTEM_ERROR; |
|
} |
|
return ResponseCode(reply.readInt32()); |
|
} |
|
|
|
KeyStoreServiceReturnCode del(const String16& name, int uid) override { |
|
Parcel data, reply; |
|
data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor()); |
|
data.writeString16(name); |
|
data.writeInt32(uid); |
|
status_t status = remote()->transact(BnKeystoreService::DEL, data, &reply); |
|
if (status != NO_ERROR) { |
|
ALOGD("del() could not contact remote: %d\n", status); |
|
return ResponseCode::SYSTEM_ERROR; |
|
} |
|
int32_t err = reply.readExceptionCode(); |
|
if (err < 0) { |
|
ALOGD("del() caught exception %d\n", err); |
|
return ResponseCode::SYSTEM_ERROR; |
|
} |
|
return ResponseCode(reply.readInt32()); |
|
} |
|
|
|
KeyStoreServiceReturnCode exist(const String16& name, int uid) override { |
|
Parcel data, reply; |
|
data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor()); |
|
data.writeString16(name); |
|
data.writeInt32(uid); |
|
status_t status = remote()->transact(BnKeystoreService::EXIST, data, &reply); |
|
if (status != NO_ERROR) { |
|
ALOGD("exist() could not contact remote: %d\n", status); |
|
return ResponseCode::SYSTEM_ERROR; |
|
} |
|
int32_t err = reply.readExceptionCode(); |
|
if (err < 0) { |
|
ALOGD("exist() caught exception %d\n", err); |
|
return ResponseCode::SYSTEM_ERROR; |
|
} |
|
return ResponseCode(reply.readInt32()); |
|
} |
|
|
|
KeyStoreServiceReturnCode list(const String16& prefix, int uid, |
|
Vector<String16>* matches) override { |
|
Parcel data, reply; |
|
data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor()); |
|
data.writeString16(prefix); |
|
data.writeInt32(uid); |
|
status_t status = remote()->transact(BnKeystoreService::LIST, data, &reply); |
|
if (status != NO_ERROR) { |
|
ALOGD("list() could not contact remote: %d\n", status); |
|
return ResponseCode::SYSTEM_ERROR; |
|
} |
|
int32_t err = reply.readExceptionCode(); |
|
int32_t numMatches = reply.readInt32(); |
|
for (int32_t i = 0; i < numMatches; i++) { |
|
matches->push(reply.readString16()); |
|
} |
|
if (err < 0) { |
|
ALOGD("list() caught exception %d\n", err); |
|
return ResponseCode::SYSTEM_ERROR; |
|
} |
|
return ResponseCode(reply.readInt32()); |
|
} |
|
|
|
KeyStoreServiceReturnCode reset() override { |
|
Parcel data, reply; |
|
data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor()); |
|
status_t status = remote()->transact(BnKeystoreService::RESET, data, &reply); |
|
if (status != NO_ERROR) { |
|
ALOGD("reset() could not contact remote: %d\n", status); |
|
return ResponseCode::SYSTEM_ERROR; |
|
} |
|
int32_t err = reply.readExceptionCode(); |
|
if (err < 0) { |
|
ALOGD("reset() caught exception %d\n", err); |
|
return ResponseCode::SYSTEM_ERROR; |
|
} |
|
return ResponseCode(reply.readInt32()); |
|
} |
|
|
|
KeyStoreServiceReturnCode onUserPasswordChanged(int32_t userId, |
|
const String16& password) override { |
|
Parcel data, reply; |
|
data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor()); |
|
data.writeInt32(userId); |
|
data.writeString16(password); |
|
status_t status = |
|
remote()->transact(BnKeystoreService::ON_USER_PASSWORD_CHANGED, data, &reply); |
|
if (status != NO_ERROR) { |
|
ALOGD("onUserPasswordChanged() could not contact remote: %d\n", status); |
|
return ResponseCode::SYSTEM_ERROR; |
|
} |
|
int32_t err = reply.readExceptionCode(); |
|
if (err < 0) { |
|
ALOGD("onUserPasswordChanged() caught exception %d\n", err); |
|
return ResponseCode::SYSTEM_ERROR; |
|
} |
|
return ResponseCode(reply.readInt32()); |
|
} |
|
|
|
KeyStoreServiceReturnCode lock(int32_t userId) override { |
|
Parcel data, reply; |
|
data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor()); |
|
data.writeInt32(userId); |
|
status_t status = remote()->transact(BnKeystoreService::LOCK, data, &reply); |
|
if (status != NO_ERROR) { |
|
ALOGD("lock() could not contact remote: %d\n", status); |
|
return ResponseCode::SYSTEM_ERROR; |
|
} |
|
int32_t err = reply.readExceptionCode(); |
|
if (err < 0) { |
|
ALOGD("lock() caught exception %d\n", err); |
|
return ResponseCode::SYSTEM_ERROR; |
|
} |
|
return ResponseCode(reply.readInt32()); |
|
} |
|
|
|
KeyStoreServiceReturnCode unlock(int32_t userId, const String16& password) override { |
|
Parcel data, reply; |
|
data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor()); |
|
data.writeInt32(userId); |
|
data.writeString16(password); |
|
status_t status = remote()->transact(BnKeystoreService::UNLOCK, data, &reply); |
|
if (status != NO_ERROR) { |
|
ALOGD("unlock() could not contact remote: %d\n", status); |
|
return ResponseCode::SYSTEM_ERROR; |
|
} |
|
int32_t err = reply.readExceptionCode(); |
|
if (err < 0) { |
|
ALOGD("unlock() caught exception %d\n", err); |
|
return ResponseCode::SYSTEM_ERROR; |
|
} |
|
return ResponseCode(reply.readInt32()); |
|
} |
|
|
|
bool isEmpty(int32_t userId) override { |
|
Parcel data, reply; |
|
data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor()); |
|
data.writeInt32(userId); |
|
status_t status = remote()->transact(BnKeystoreService::IS_EMPTY, data, &reply); |
|
if (status != NO_ERROR) { |
|
ALOGD("isEmpty() could not contact remote: %d\n", status); |
|
return false; |
|
} |
|
int32_t err = reply.readExceptionCode(); |
|
if (err < 0) { |
|
ALOGD("isEmpty() caught exception %d\n", err); |
|
return false; |
|
} |
|
return reply.readInt32() != 0; |
|
} |
|
|
|
KeyStoreServiceReturnCode generate(const String16& name, int32_t uid, int32_t keyType, |
|
int32_t keySize, int32_t flags, |
|
Vector<sp<KeystoreArg>>* args) override { |
|
Parcel data, reply; |
|
data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor()); |
|
data.writeString16(name); |
|
data.writeInt32(uid); |
|
data.writeInt32(keyType); |
|
data.writeInt32(keySize); |
|
data.writeInt32(flags); |
|
data.writeInt32(1); |
|
data.writeInt32(args->size()); |
|
for (Vector<sp<KeystoreArg>>::iterator it = args->begin(); it != args->end(); ++it) { |
|
sp<KeystoreArg> item = *it; |
|
size_t keyLength = item->size(); |
|
data.writeInt32(keyLength); |
|
void* buf = data.writeInplace(keyLength); |
|
memcpy(buf, item->data(), keyLength); |
|
} |
|
status_t status = remote()->transact(BnKeystoreService::GENERATE, data, &reply); |
|
if (status != NO_ERROR) { |
|
ALOGD("generate() could not contact remote: %d\n", status); |
|
return ResponseCode::SYSTEM_ERROR; |
|
} |
|
int32_t err = reply.readExceptionCode(); |
|
if (err < 0) { |
|
ALOGD("generate() caught exception %d\n", err); |
|
return ResponseCode::SYSTEM_ERROR; |
|
} |
|
return ResponseCode(reply.readInt32()); |
|
} |
|
|
|
KeyStoreServiceReturnCode import(const String16& name, const hidl_vec<uint8_t>& key, int uid, |
|
int flags) override { |
|
Parcel data, reply; |
|
data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor()); |
|
data.writeString16(name); |
|
writeBlobAsByteArray(key, &data); |
|
data.writeInt32(uid); |
|
data.writeInt32(flags); |
|
status_t status = remote()->transact(BnKeystoreService::IMPORT, data, &reply); |
|
if (status != NO_ERROR) { |
|
ALOGD("import() could not contact remote: %d\n", status); |
|
return ResponseCode::SYSTEM_ERROR; |
|
} |
|
int32_t err = reply.readExceptionCode(); |
|
if (err < 0) { |
|
ALOGD("import() caught exception %d\n", err); |
|
return ResponseCode::SYSTEM_ERROR; |
|
} |
|
return ResponseCode(reply.readInt32()); |
|
} |
|
|
|
KeyStoreServiceReturnCode sign(const String16& name, const hidl_vec<uint8_t>& in, |
|
hidl_vec<uint8_t>* out) override { |
|
Parcel data, reply; |
|
data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor()); |
|
data.writeString16(name); |
|
writeBlobAsByteArray(in, &data); |
|
status_t status = remote()->transact(BnKeystoreService::SIGN, data, &reply); |
|
if (status != NO_ERROR) { |
|
ALOGD("import() could not contact remote: %d\n", status); |
|
return ResponseCode::SYSTEM_ERROR; |
|
} |
|
int32_t err = reply.readExceptionCode(); |
|
if (err < 0) { |
|
ALOGD("import() caught exception %d\n", err); |
|
return ResponseCode::SYSTEM_ERROR; |
|
} |
|
auto outBlob = readBlobAsByteArray(reply); |
|
if (out) { |
|
// don't need to check outBlob.isOk() |
|
// if !outBlob.isOk() the wrapped value is default constructed and therefore empty, |
|
// as expected. |
|
*out = outBlob.value(); |
|
} |
|
return ResponseCode(reply.readInt32()); |
|
} |
|
|
|
KeyStoreServiceReturnCode verify(const String16& name, const hidl_vec<uint8_t>& in, |
|
const hidl_vec<uint8_t>& signature) override { |
|
Parcel data, reply; |
|
|
|
data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor()); |
|
data.writeString16(name); |
|
writeBlobAsByteArray(in, &data); |
|
writeBlobAsByteArray(signature, &data); |
|
status_t status = remote()->transact(BnKeystoreService::VERIFY, data, &reply); |
|
if (status != NO_ERROR) { |
|
ALOGD("verify() could not contact remote: %d\n", status); |
|
return ResponseCode::SYSTEM_ERROR; |
|
} |
|
int32_t err = reply.readExceptionCode(); |
|
if (err < 0) { |
|
ALOGD("verify() caught exception %d\n", err); |
|
return ResponseCode::SYSTEM_ERROR; |
|
} |
|
return ResponseCode(reply.readInt32()); |
|
} |
|
|
|
KeyStoreServiceReturnCode get_pubkey(const String16& name, hidl_vec<uint8_t>* pubkey) override { |
|
Parcel data, reply; |
|
data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor()); |
|
data.writeString16(name); |
|
status_t status = remote()->transact(BnKeystoreService::GET_PUBKEY, data, &reply); |
|
if (status != NO_ERROR) { |
|
ALOGD("get_pubkey() could not contact remote: %d\n", status); |
|
return ResponseCode::SYSTEM_ERROR; |
|
} |
|
int32_t err = reply.readExceptionCode(); |
|
if (err < 0) { |
|
ALOGD("get_pubkey() caught exception %d\n", err); |
|
return ResponseCode::SYSTEM_ERROR; |
|
} |
|
auto resultKey = readBlobAsByteArray(reply); |
|
if (pubkey) *pubkey = resultKey.value(); |
|
return ResponseCode(reply.readInt32()); |
|
} |
|
|
|
String16 grant(const String16& name, int32_t granteeUid) override { |
|
Parcel data, reply; |
|
data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor()); |
|
data.writeString16(name); |
|
data.writeInt32(granteeUid); |
|
status_t status = remote()->transact(BnKeystoreService::GRANT, data, &reply); |
|
if (status != NO_ERROR) { |
|
ALOGD("grant() could not contact remote: %d\n", status); |
|
return String16(); |
|
} |
|
int32_t err = reply.readExceptionCode(); |
|
if (err < 0) { |
|
ALOGD("grant() caught exception %d\n", err); |
|
return String16(); |
|
} |
|
return reply.readString16(); |
|
} |
|
|
|
KeyStoreServiceReturnCode ungrant(const String16& name, int32_t granteeUid) override { |
|
Parcel data, reply; |
|
data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor()); |
|
data.writeString16(name); |
|
data.writeInt32(granteeUid); |
|
status_t status = remote()->transact(BnKeystoreService::UNGRANT, data, &reply); |
|
if (status != NO_ERROR) { |
|
ALOGD("ungrant() could not contact remote: %d\n", status); |
|
return ResponseCode::SYSTEM_ERROR; |
|
} |
|
int32_t err = reply.readExceptionCode(); |
|
if (err < 0) { |
|
ALOGD("ungrant() caught exception %d\n", err); |
|
return ResponseCode::SYSTEM_ERROR; |
|
} |
|
return ResponseCode(reply.readInt32()); |
|
} |
|
|
|
int64_t getmtime(const String16& name, int32_t uid) override { |
|
Parcel data, reply; |
|
data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor()); |
|
data.writeString16(name); |
|
data.writeInt32(uid); |
|
status_t status = remote()->transact(BnKeystoreService::GETMTIME, data, &reply); |
|
if (status != NO_ERROR) { |
|
ALOGD("getmtime() could not contact remote: %d\n", status); |
|
return -1; |
|
} |
|
int32_t err = reply.readExceptionCode(); |
|
if (err < 0) { |
|
ALOGD("getmtime() caught exception %d\n", err); |
|
return -1; |
|
} |
|
return reply.readInt64(); |
|
} |
|
|
|
KeyStoreServiceReturnCode duplicate(const String16& srcKey, int32_t srcUid, |
|
const String16& destKey, int32_t destUid) override { |
|
Parcel data, reply; |
|
data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor()); |
|
data.writeString16(srcKey); |
|
data.writeInt32(srcUid); |
|
data.writeString16(destKey); |
|
data.writeInt32(destUid); |
|
status_t status = remote()->transact(BnKeystoreService::DUPLICATE, data, &reply); |
|
if (status != NO_ERROR) { |
|
ALOGD("duplicate() could not contact remote: %d\n", status); |
|
return ResponseCode::SYSTEM_ERROR; |
|
} |
|
int32_t err = reply.readExceptionCode(); |
|
if (err < 0) { |
|
ALOGD("duplicate() caught exception %d\n", err); |
|
return ResponseCode::SYSTEM_ERROR; |
|
} |
|
return ResponseCode(reply.readInt32()); |
|
} |
|
|
|
int32_t is_hardware_backed(const String16& keyType) override { |
|
Parcel data, reply; |
|
data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor()); |
|
data.writeString16(keyType); |
|
status_t status = remote()->transact(BnKeystoreService::IS_HARDWARE_BACKED, data, &reply); |
|
if (status != NO_ERROR) { |
|
ALOGD("is_hardware_backed() could not contact remote: %d\n", status); |
|
return -1; |
|
} |
|
int32_t err = reply.readExceptionCode(); |
|
if (err < 0) { |
|
ALOGD("is_hardware_backed() caught exception %d\n", err); |
|
return -1; |
|
} |
|
return reply.readInt32(); |
|
} |
|
|
|
KeyStoreServiceReturnCode clear_uid(int64_t uid) override { |
|
Parcel data, reply; |
|
data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor()); |
|
data.writeInt64(uid); |
|
status_t status = remote()->transact(BnKeystoreService::CLEAR_UID, data, &reply); |
|
if (status != NO_ERROR) { |
|
ALOGD("clear_uid() could not contact remote: %d\n", status); |
|
return ResponseCode::SYSTEM_ERROR; |
|
} |
|
int32_t err = reply.readExceptionCode(); |
|
if (err < 0) { |
|
ALOGD("clear_uid() caught exception %d\n", err); |
|
return ResponseCode::SYSTEM_ERROR; |
|
} |
|
return ResponseCode(reply.readInt32()); |
|
} |
|
|
|
KeyStoreServiceReturnCode addRngEntropy(const hidl_vec<uint8_t>& entropy) override { |
|
Parcel data, reply; |
|
data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor()); |
|
writeBlobAsByteArray(entropy, &data); |
|
status_t status = remote()->transact(BnKeystoreService::ADD_RNG_ENTROPY, data, &reply); |
|
if (status != NO_ERROR) { |
|
ALOGD("addRngEntropy() could not contact remote: %d\n", status); |
|
return ResponseCode::SYSTEM_ERROR; |
|
} |
|
int32_t err = reply.readExceptionCode(); |
|
if (err < 0) { |
|
ALOGD("addRngEntropy() caught exception %d\n", err); |
|
return ResponseCode::SYSTEM_ERROR; |
|
} |
|
return ResponseCode(reply.readInt32()); |
|
}; |
|
|
|
KeyStoreServiceReturnCode generateKey(const String16& name, |
|
const hidl_vec<KeyParameter>& params, |
|
const hidl_vec<uint8_t>& entropy, int uid, int flags, |
|
KeyCharacteristics* outCharacteristics) override { |
|
Parcel data, reply; |
|
data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor()); |
|
data.writeString16(name); |
|
nullable(writeParamSetToParcel, params, &data); |
|
writeBlobAsByteArray(entropy, &data); |
|
data.writeInt32(uid); |
|
data.writeInt32(flags); |
|
status_t status = remote()->transact(BnKeystoreService::GENERATE_KEY, data, &reply); |
|
if (status != NO_ERROR) { |
|
ALOGD("generateKey() could not contact remote: %d\n", status); |
|
return ResponseCode::SYSTEM_ERROR; |
|
} |
|
int32_t err = reply.readExceptionCode(); |
|
ResponseCode ret = ResponseCode(reply.readInt32()); |
|
if (err < 0) { |
|
ALOGD("generateKey() caught exception %d\n", err); |
|
return ResponseCode::SYSTEM_ERROR; |
|
} |
|
if (outCharacteristics) { |
|
*outCharacteristics = nullable(readKeyCharacteristicsFromParcel, reply).value(); |
|
} |
|
return ret; |
|
} |
|
KeyStoreServiceReturnCode |
|
getKeyCharacteristics(const String16& name, const hidl_vec<uint8_t>& clientId, |
|
const hidl_vec<uint8_t>& appData, int32_t uid, |
|
KeyCharacteristics* outCharacteristics) override { |
|
Parcel data, reply; |
|
data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor()); |
|
data.writeString16(name); |
|
writeBlobAsByteArray(clientId, &data); |
|
writeBlobAsByteArray(appData, &data); |
|
data.writeInt32(uid); |
|
status_t status = |
|
remote()->transact(BnKeystoreService::GET_KEY_CHARACTERISTICS, data, &reply); |
|
if (status != NO_ERROR) { |
|
ALOGD("getKeyCharacteristics() could not contact remote: %d\n", status); |
|
return ResponseCode::SYSTEM_ERROR; |
|
} |
|
int32_t err = reply.readExceptionCode(); |
|
ResponseCode ret = ResponseCode(reply.readInt32()); |
|
if (err < 0) { |
|
ALOGD("getKeyCharacteristics() caught exception %d\n", err); |
|
return ResponseCode::SYSTEM_ERROR; |
|
} |
|
if (outCharacteristics) { |
|
*outCharacteristics = nullable(readKeyCharacteristicsFromParcel, reply).value(); |
|
} |
|
return ret; |
|
} |
|
KeyStoreServiceReturnCode importKey(const String16& name, const hidl_vec<KeyParameter>& params, |
|
KeyFormat format, const hidl_vec<uint8_t>& keyData, int uid, |
|
int flags, |
|
KeyCharacteristics* outCharacteristics) override { |
|
Parcel data, reply; |
|
data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor()); |
|
data.writeString16(name); |
|
nullable(writeParamSetToParcel, params, &data); |
|
data.writeInt32(uint32_t(format)); |
|
writeBlobAsByteArray(keyData, &data); |
|
data.writeInt32(uid); |
|
data.writeInt32(flags); |
|
status_t status = remote()->transact(BnKeystoreService::IMPORT_KEY, data, &reply); |
|
if (status != NO_ERROR) { |
|
ALOGD("importKey() could not contact remote: %d\n", status); |
|
return ResponseCode::SYSTEM_ERROR; |
|
} |
|
int32_t err = reply.readExceptionCode(); |
|
ResponseCode ret = ResponseCode(reply.readInt32()); |
|
if (err < 0) { |
|
ALOGD("importKey() caught exception %d\n", err); |
|
return ResponseCode::SYSTEM_ERROR; |
|
} |
|
if (outCharacteristics) { |
|
*outCharacteristics = nullable(readKeyCharacteristicsFromParcel, reply).value(); |
|
} |
|
return ret; |
|
} |
|
|
|
void exportKey(const String16& name, KeyFormat format, const hidl_vec<uint8_t>& clientId, |
|
const hidl_vec<uint8_t>& appData, int32_t uid, ExportResult* result) override { |
|
if (!result) { |
|
return; |
|
} |
|
|
|
Parcel data, reply; |
|
data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor()); |
|
data.writeString16(name); |
|
data.writeInt32(int32_t(format)); |
|
writeBlobAsByteArray(clientId, &data); |
|
writeBlobAsByteArray(appData, &data); |
|
data.writeInt32(uid); |
|
status_t status = remote()->transact(BnKeystoreService::EXPORT_KEY, data, &reply); |
|
if (status != NO_ERROR) { |
|
ALOGD("exportKey() could not contact remote: %d\n", status); |
|
result->resultCode = ResponseCode::SYSTEM_ERROR; |
|
return; |
|
} |
|
int32_t err = reply.readExceptionCode(); |
|
if (err < 0) { |
|
ALOGD("exportKey() caught exception %d\n", err); |
|
result->resultCode = ResponseCode::SYSTEM_ERROR; |
|
return; |
|
} |
|
|
|
reply.readParcelable(result); |
|
} |
|
|
|
void begin(const sp<IBinder>& appToken, const String16& name, KeyPurpose purpose, |
|
bool pruneable, const hidl_vec<KeyParameter>& params, |
|
const hidl_vec<uint8_t>& entropy, int32_t uid, OperationResult* result) override { |
|
if (!result) { |
|
return; |
|
} |
|
Parcel data, reply; |
|
data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor()); |
|
data.writeStrongBinder(appToken); |
|
data.writeString16(name); |
|
data.writeInt32(int32_t(purpose)); |
|
data.writeInt32(pruneable ? 1 : 0); |
|
nullable(writeParamSetToParcel, params, &data); |
|
writeBlobAsByteArray(entropy, &data); |
|
data.writeInt32(uid); |
|
status_t status = remote()->transact(BnKeystoreService::BEGIN, data, &reply); |
|
if (status != NO_ERROR) { |
|
ALOGD("begin() could not contact remote: %d\n", status); |
|
result->resultCode = ResponseCode::SYSTEM_ERROR; |
|
return; |
|
} |
|
int32_t err = reply.readExceptionCode(); |
|
if (err < 0) { |
|
ALOGD("begin() caught exception %d\n", err); |
|
result->resultCode = ResponseCode::SYSTEM_ERROR; |
|
return; |
|
} |
|
|
|
reply.readParcelable(result); |
|
} |
|
|
|
void update(const sp<IBinder>& token, const hidl_vec<KeyParameter>& params, |
|
const hidl_vec<uint8_t>& opData, OperationResult* result) override { |
|
if (!result) { |
|
return; |
|
} |
|
Parcel data, reply; |
|
data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor()); |
|
data.writeStrongBinder(token); |
|
nullable(writeParamSetToParcel, params, &data); |
|
writeBlobAsByteArray(opData, &data); |
|
status_t status = remote()->transact(BnKeystoreService::UPDATE, data, &reply); |
|
if (status != NO_ERROR) { |
|
ALOGD("update() could not contact remote: %d\n", status); |
|
result->resultCode = ResponseCode::SYSTEM_ERROR; |
|
return; |
|
} |
|
int32_t err = reply.readExceptionCode(); |
|
if (err < 0) { |
|
ALOGD("update() caught exception %d\n", err); |
|
result->resultCode = ResponseCode::SYSTEM_ERROR; |
|
return; |
|
} |
|
|
|
reply.readParcelable(result); |
|
} |
|
|
|
void finish(const sp<IBinder>& token, const hidl_vec<KeyParameter>& params, |
|
const hidl_vec<uint8_t>& signature, const hidl_vec<uint8_t>& entropy, |
|
OperationResult* result) override { |
|
if (!result) { |
|
return; |
|
} |
|
Parcel data, reply; |
|
data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor()); |
|
data.writeStrongBinder(token); |
|
nullable(writeParamSetToParcel, params, &data); |
|
writeBlobAsByteArray(signature, &data); |
|
writeBlobAsByteArray(entropy, &data); |
|
status_t status = remote()->transact(BnKeystoreService::FINISH, data, &reply); |
|
if (status != NO_ERROR) { |
|
ALOGD("finish() could not contact remote: %d\n", status); |
|
result->resultCode = ResponseCode::SYSTEM_ERROR; |
|
return; |
|
} |
|
int32_t err = reply.readExceptionCode(); |
|
if (err < 0) { |
|
ALOGD("finish() caught exception %d\n", err); |
|
result->resultCode = ResponseCode::SYSTEM_ERROR; |
|
return; |
|
} |
|
|
|
reply.readParcelable(result); |
|
} |
|
|
|
KeyStoreServiceReturnCode abort(const sp<IBinder>& token) override { |
|
Parcel data, reply; |
|
data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor()); |
|
data.writeStrongBinder(token); |
|
status_t status = remote()->transact(BnKeystoreService::ABORT, data, &reply); |
|
if (status != NO_ERROR) { |
|
ALOGD("abort() could not contact remote: %d\n", status); |
|
return ResponseCode::SYSTEM_ERROR; |
|
} |
|
int32_t err = reply.readExceptionCode(); |
|
if (err < 0) { |
|
ALOGD("abort() caught exception %d\n", err); |
|
return ResponseCode::SYSTEM_ERROR; |
|
} |
|
return ResponseCode(reply.readInt32()); |
|
} |
|
|
|
bool isOperationAuthorized(const sp<IBinder>& token) override { |
|
Parcel data, reply; |
|
data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor()); |
|
data.writeStrongBinder(token); |
|
status_t status = |
|
remote()->transact(BnKeystoreService::IS_OPERATION_AUTHORIZED, data, &reply); |
|
if (status != NO_ERROR) { |
|
ALOGD("isOperationAuthorized() could not contact remote: %d\n", status); |
|
return false; |
|
} |
|
int32_t err = reply.readExceptionCode(); |
|
if (err < 0) { |
|
ALOGD("isOperationAuthorized() caught exception %d\n", err); |
|
return false; |
|
} |
|
return reply.readInt32() == 1; |
|
} |
|
|
|
KeyStoreServiceReturnCode addAuthToken(const uint8_t* token, size_t length) override { |
|
Parcel data, reply; |
|
data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor()); |
|
data.writeByteArray(length, token); |
|
status_t status = remote()->transact(BnKeystoreService::ADD_AUTH_TOKEN, data, &reply); |
|
if (status != NO_ERROR) { |
|
ALOGD("addAuthToken() could not contact remote: %d\n", status); |
|
return ResponseCode::SYSTEM_ERROR; |
|
} |
|
int32_t err = reply.readExceptionCode(); |
|
if (err < 0) { |
|
ALOGD("addAuthToken() caught exception %d\n", err); |
|
return ResponseCode::SYSTEM_ERROR; |
|
} |
|
return ResponseCode(reply.readInt32()); |
|
}; |
|
|
|
KeyStoreServiceReturnCode onUserAdded(int32_t userId, int32_t parentId) override { |
|
Parcel data, reply; |
|
data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor()); |
|
data.writeInt32(userId); |
|
data.writeInt32(parentId); |
|
status_t status = remote()->transact(BnKeystoreService::ON_USER_ADDED, data, &reply); |
|
if (status != NO_ERROR) { |
|
ALOGD("onUserAdded() could not contact remote: %d\n", status); |
|
return ResponseCode::SYSTEM_ERROR; |
|
} |
|
int32_t err = reply.readExceptionCode(); |
|
if (err < 0) { |
|
ALOGD("onUserAdded() caught exception %d\n", err); |
|
return ResponseCode::SYSTEM_ERROR; |
|
} |
|
return ResponseCode(reply.readInt32()); |
|
} |
|
|
|
KeyStoreServiceReturnCode onUserRemoved(int32_t userId) override { |
|
Parcel data, reply; |
|
data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor()); |
|
data.writeInt32(userId); |
|
status_t status = remote()->transact(BnKeystoreService::ON_USER_REMOVED, data, &reply); |
|
if (status != NO_ERROR) { |
|
ALOGD("onUserRemoved() could not contact remote: %d\n", status); |
|
return ResponseCode::SYSTEM_ERROR; |
|
} |
|
int32_t err = reply.readExceptionCode(); |
|
if (err < 0) { |
|
ALOGD("onUserRemoved() caught exception %d\n", err); |
|
return ResponseCode::SYSTEM_ERROR; |
|
} |
|
return ResponseCode(reply.readInt32()); |
|
} |
|
|
|
KeyStoreServiceReturnCode attestKey(const String16& name, const hidl_vec<KeyParameter>& params, |
|
hidl_vec<hidl_vec<uint8_t>>* outChain) override { |
|
if (!outChain) return ErrorCode::OUTPUT_PARAMETER_NULL; |
|
|
|
Parcel data, reply; |
|
data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor()); |
|
data.writeString16(name); |
|
nullable(writeParamSetToParcel, params, &data); |
|
|
|
status_t status = remote()->transact(BnKeystoreService::ATTEST_KEY, data, &reply); |
|
if (status != NO_ERROR) { |
|
ALOGD("attestkey() count not contact remote: %d\n", status); |
|
return ResponseCode::SYSTEM_ERROR; |
|
} |
|
int32_t err = reply.readExceptionCode(); |
|
ResponseCode ret = ResponseCode(reply.readInt32()); |
|
if (err < 0) { |
|
ALOGD("attestKey() caught exception %d\n", err); |
|
return ResponseCode::SYSTEM_ERROR; |
|
} |
|
if (reply.readInt32() != 0) { |
|
*outChain = readCertificateChainFromParcel(reply); |
|
} |
|
return ret; |
|
} |
|
|
|
KeyStoreServiceReturnCode attestDeviceIds(const hidl_vec<KeyParameter>& params, |
|
hidl_vec<hidl_vec<uint8_t>>* outChain) override { |
|
if (!outChain) return ErrorCode::OUTPUT_PARAMETER_NULL; |
|
|
|
Parcel data, reply; |
|
data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor()); |
|
nullable(writeParamSetToParcel, params, &data); |
|
|
|
status_t status = remote()->transact(BnKeystoreService::ATTEST_DEVICE_IDS, data, &reply); |
|
if (status != NO_ERROR) { |
|
ALOGD("attestDeviceIds() count not contact remote: %d\n", status); |
|
return ResponseCode::SYSTEM_ERROR; |
|
} |
|
int32_t err = reply.readExceptionCode(); |
|
ResponseCode ret = ResponseCode(reply.readInt32()); |
|
if (err < 0) { |
|
ALOGD("attestDeviceIds() caught exception %d\n", err); |
|
return ResponseCode::SYSTEM_ERROR; |
|
} |
|
if (reply.readInt32() != 0) { |
|
*outChain = readCertificateChainFromParcel(reply); |
|
} |
|
return ret; |
|
} |
|
|
|
KeyStoreServiceReturnCode onDeviceOffBody() override { |
|
Parcel data, reply; |
|
data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor()); |
|
status_t status = remote()->transact(BnKeystoreService::ON_DEVICE_OFF_BODY, data, &reply); |
|
if (status != NO_ERROR) { |
|
ALOGD("onDeviceOffBody() could not contact remote: %d\n", status); |
|
return ResponseCode::SYSTEM_ERROR; |
|
} |
|
int32_t err = reply.readExceptionCode(); |
|
if (err < 0) { |
|
ALOGD("onDeviceOffBody() caught exception %d\n", err); |
|
return ResponseCode::SYSTEM_ERROR; |
|
} |
|
return ResponseCode(reply.readInt32()); |
|
} |
|
}; |
|
|
|
IMPLEMENT_META_INTERFACE(KeystoreService, "android.security.IKeystoreService"); |
|
|
|
// ---------------------------------------------------------------------- |
|
|
|
status_t BnKeystoreService::onTransact(uint32_t code, const Parcel& data, Parcel* reply, |
|
uint32_t flags) { |
|
switch (code) { |
|
case GET_STATE: { |
|
CHECK_INTERFACE(IKeystoreService, data, reply); |
|
int32_t userId = data.readInt32(); |
|
int32_t ret = getState(userId); |
|
reply->writeNoException(); |
|
reply->writeInt32(ret); |
|
return NO_ERROR; |
|
} break; |
|
case GET: { |
|
CHECK_INTERFACE(IKeystoreService, data, reply); |
|
String16 name = data.readString16(); |
|
int32_t uid = data.readInt32(); |
|
hidl_vec<uint8_t> out; |
|
auto ret = get(name, uid, &out); |
|
reply->writeNoException(); |
|
if (ret.isOk()) { |
|
writeBlobAsByteArray(out, reply); |
|
} else { |
|
reply->writeInt32(-1); |
|
} |
|
reply->writeInt32(ret); |
|
return NO_ERROR; |
|
} break; |
|
case INSERT: { |
|
CHECK_INTERFACE(IKeystoreService, data, reply); |
|
String16 name = data.readString16(); |
|
auto in = readBlobAsByteArray(data); |
|
int uid = data.readInt32(); |
|
int32_t flags = data.readInt32(); |
|
int32_t ret = insert(name, in.value(), uid, flags); |
|
reply->writeNoException(); |
|
reply->writeInt32(ret); |
|
return NO_ERROR; |
|
} break; |
|
case DEL: { |
|
CHECK_INTERFACE(IKeystoreService, data, reply); |
|
String16 name = data.readString16(); |
|
int uid = data.readInt32(); |
|
int32_t ret = del(name, uid); |
|
reply->writeNoException(); |
|
reply->writeInt32(ret); |
|
return NO_ERROR; |
|
} break; |
|
case EXIST: { |
|
CHECK_INTERFACE(IKeystoreService, data, reply); |
|
String16 name = data.readString16(); |
|
int uid = data.readInt32(); |
|
int32_t ret = exist(name, uid); |
|
reply->writeNoException(); |
|
reply->writeInt32(ret); |
|
return NO_ERROR; |
|
} break; |
|
case LIST: { |
|
CHECK_INTERFACE(IKeystoreService, data, reply); |
|
String16 prefix = data.readString16(); |
|
int uid = data.readInt32(); |
|
Vector<String16> matches; |
|
int32_t ret = list(prefix, uid, &matches); |
|
reply->writeNoException(); |
|
reply->writeInt32(matches.size()); |
|
Vector<String16>::const_iterator it = matches.begin(); |
|
for (; it != matches.end(); ++it) { |
|
reply->writeString16(*it); |
|
} |
|
reply->writeInt32(ret); |
|
return NO_ERROR; |
|
} break; |
|
case RESET: { |
|
CHECK_INTERFACE(IKeystoreService, data, reply); |
|
int32_t ret = reset(); |
|
reply->writeNoException(); |
|
reply->writeInt32(ret); |
|
return NO_ERROR; |
|
} break; |
|
case ON_USER_PASSWORD_CHANGED: { |
|
CHECK_INTERFACE(IKeystoreService, data, reply); |
|
int32_t userId = data.readInt32(); |
|
String16 pass = data.readString16(); |
|
int32_t ret = onUserPasswordChanged(userId, pass); |
|
reply->writeNoException(); |
|
reply->writeInt32(ret); |
|
return NO_ERROR; |
|
} break; |
|
case LOCK: { |
|
CHECK_INTERFACE(IKeystoreService, data, reply); |
|
int32_t userId = data.readInt32(); |
|
int32_t ret = lock(userId); |
|
reply->writeNoException(); |
|
reply->writeInt32(ret); |
|
return NO_ERROR; |
|
} break; |
|
case UNLOCK: { |
|
CHECK_INTERFACE(IKeystoreService, data, reply); |
|
int32_t userId = data.readInt32(); |
|
String16 pass = data.readString16(); |
|
int32_t ret = unlock(userId, pass); |
|
reply->writeNoException(); |
|
reply->writeInt32(ret); |
|
return NO_ERROR; |
|
} break; |
|
case IS_EMPTY: { |
|
CHECK_INTERFACE(IKeystoreService, data, reply); |
|
int32_t userId = data.readInt32(); |
|
bool ret = isEmpty(userId); |
|
reply->writeNoException(); |
|
reply->writeInt32(ret ? 1 : 0); |
|
return NO_ERROR; |
|
} break; |
|
case GENERATE: { |
|
CHECK_INTERFACE(IKeystoreService, data, reply); |
|
String16 name = data.readString16(); |
|
int32_t uid = data.readInt32(); |
|
int32_t keyType = data.readInt32(); |
|
int32_t keySize = data.readInt32(); |
|
int32_t flags = data.readInt32(); |
|
Vector<sp<KeystoreArg>> args; |
|
int32_t argsPresent = data.readInt32(); |
|
if (argsPresent == 1) { |
|
ssize_t numArgs = data.readInt32(); |
|
if (numArgs > MAX_GENERATE_ARGS) { |
|
return BAD_VALUE; |
|
} |
|
if (numArgs > 0) { |
|
for (size_t i = 0; i < (size_t)numArgs; i++) { |
|
ssize_t inSize = data.readInt32(); |
|
if (inSize >= 0 && (size_t)inSize <= data.dataAvail()) { |
|
sp<KeystoreArg> arg = new KeystoreArg(data.readInplace(inSize), inSize); |
|
args.push_back(arg); |
|
} else { |
|
args.push_back(NULL); |
|
} |
|
} |
|
} |
|
} |
|
int32_t ret = generate(name, uid, keyType, keySize, flags, &args); |
|
reply->writeNoException(); |
|
reply->writeInt32(ret); |
|
return NO_ERROR; |
|
} break; |
|
case IMPORT: { |
|
CHECK_INTERFACE(IKeystoreService, data, reply); |
|
String16 name = data.readString16(); |
|
auto in = readBlobAsByteArray(data); |
|
int uid = data.readInt32(); |
|
int32_t flags = data.readInt32(); |
|
auto ret = import(name, in.value(), uid, flags); |
|
reply->writeNoException(); |
|
reply->writeInt32(ret); |
|
return NO_ERROR; |
|
} break; |
|
case SIGN: { |
|
CHECK_INTERFACE(IKeystoreService, data, reply); |
|
String16 name = data.readString16(); |
|
auto in = readBlobAsByteArray(data); |
|
hidl_vec<uint8_t> out; |
|
auto ret = sign(name, in.value(), &out); |
|
reply->writeNoException(); |
|
writeBlobAsByteArray(out, reply); |
|
reply->writeInt32(ret); |
|
return NO_ERROR; |
|
} break; |
|
case VERIFY: { |
|
CHECK_INTERFACE(IKeystoreService, data, reply); |
|
String16 name = data.readString16(); |
|
auto in = readBlobAsByteArray(data); |
|
auto signature = readBlobAsByteArray(data); |
|
auto ret = verify(name, in.value(), signature.value()); |
|
reply->writeNoException(); |
|
reply->writeInt32(ret); |
|
return NO_ERROR; |
|
} break; |
|
case GET_PUBKEY: { |
|
CHECK_INTERFACE(IKeystoreService, data, reply); |
|
String16 name = data.readString16(); |
|
hidl_vec<uint8_t> out; |
|
auto ret = get_pubkey(name, &out); |
|
reply->writeNoException(); |
|
writeBlobAsByteArray(out, reply); |
|
reply->writeInt32(ret); |
|
return NO_ERROR; |
|
} break; |
|
case GRANT: { |
|
CHECK_INTERFACE(IKeystoreService, data, reply); |
|
String16 name = data.readString16(); |
|
int32_t granteeUid = data.readInt32(); |
|
String16 ret = grant(name, granteeUid); |
|
reply->writeNoException(); |
|
reply->writeString16(ret); |
|
return NO_ERROR; |
|
} break; |
|
case UNGRANT: { |
|
CHECK_INTERFACE(IKeystoreService, data, reply); |
|
String16 name = data.readString16(); |
|
int32_t granteeUid = data.readInt32(); |
|
int32_t ret = ungrant(name, granteeUid); |
|
reply->writeNoException(); |
|
reply->writeInt32(ret); |
|
return NO_ERROR; |
|
} break; |
|
case GETMTIME: { |
|
CHECK_INTERFACE(IKeystoreService, data, reply); |
|
String16 name = data.readString16(); |
|
int32_t uid = data.readInt32(); |
|
int64_t ret = getmtime(name, uid); |
|
reply->writeNoException(); |
|
reply->writeInt64(ret); |
|
return NO_ERROR; |
|
} break; |
|
case DUPLICATE: { |
|
CHECK_INTERFACE(IKeystoreService, data, reply); |
|
String16 srcKey = data.readString16(); |
|
int32_t srcUid = data.readInt32(); |
|
String16 destKey = data.readString16(); |
|
int32_t destUid = data.readInt32(); |
|
int32_t ret = duplicate(srcKey, srcUid, destKey, destUid); |
|
reply->writeNoException(); |
|
reply->writeInt32(ret); |
|
return NO_ERROR; |
|
} break; |
|
case IS_HARDWARE_BACKED: { |
|
CHECK_INTERFACE(IKeystoreService, data, reply); |
|
String16 keyType = data.readString16(); |
|
int32_t ret = is_hardware_backed(keyType); |
|
reply->writeNoException(); |
|
reply->writeInt32(ret); |
|
return NO_ERROR; |
|
} |
|
case CLEAR_UID: { |
|
CHECK_INTERFACE(IKeystoreService, data, reply); |
|
int64_t uid = data.readInt64(); |
|
int32_t ret = clear_uid(uid); |
|
reply->writeNoException(); |
|
reply->writeInt32(ret); |
|
return NO_ERROR; |
|
} |
|
case ADD_RNG_ENTROPY: { |
|
CHECK_INTERFACE(IKeystoreService, data, reply); |
|
auto entropy = readBlobAsByteArray(data); |
|
auto ret = addRngEntropy(entropy.value()); |
|
reply->writeNoException(); |
|
reply->writeInt32(ret); |
|
return NO_ERROR; |
|
} |
|
case GENERATE_KEY: { |
|
CHECK_INTERFACE(IKeystoreService, data, reply); |
|
String16 name = data.readString16(); |
|
auto params = nullable(readParamSetFromParcel, data); |
|
auto entropy = readBlobAsByteArray(data); |
|
int32_t uid = data.readInt32(); |
|
int32_t flags = data.readInt32(); |
|
KeyCharacteristics outCharacteristics; |
|
int32_t ret = |
|
generateKey(name, params.value(), entropy.value(), uid, flags, &outCharacteristics); |
|
reply->writeNoException(); |
|
reply->writeInt32(ret); |
|
nullable(writeKeyCharacteristicsToParcel, outCharacteristics, reply); |
|
return NO_ERROR; |
|
} |
|
case GET_KEY_CHARACTERISTICS: { |
|
CHECK_INTERFACE(IKeystoreService, data, reply); |
|
String16 name = data.readString16(); |
|
auto clientId = nullable(readKeymasterBlob, data, true); |
|
auto appData = nullable(readKeymasterBlob, data, true); |
|
int32_t uid = data.readInt32(); |
|
KeyCharacteristics outCharacteristics; |
|
int ret = getKeyCharacteristics(name, clientId.value(), appData.value(), uid, |
|
&outCharacteristics); |
|
reply->writeNoException(); |
|
reply->writeInt32(ret); |
|
nullable(writeKeyCharacteristicsToParcel, outCharacteristics, reply); |
|
return NO_ERROR; |
|
} |
|
case IMPORT_KEY: { |
|
CHECK_INTERFACE(IKeystoreService, data, reply); |
|
String16 name = data.readString16(); |
|
auto args = nullable(readParamSetFromParcel, data); |
|
KeyFormat format = static_cast<KeyFormat>(data.readInt32()); |
|
auto keyData = readBlobAsByteArray(data); |
|
int32_t uid = data.readInt32(); |
|
int32_t flags = data.readInt32(); |
|
KeyCharacteristics outCharacteristics; |
|
int32_t ret = |
|
importKey(name, args.value(), format, keyData.value(), uid, flags, &outCharacteristics); |
|
reply->writeNoException(); |
|
reply->writeInt32(ret); |
|
nullable(writeKeyCharacteristicsToParcel, outCharacteristics, reply); |
|
return NO_ERROR; |
|
} |
|
case EXPORT_KEY: { |
|
CHECK_INTERFACE(IKeystoreService, data, reply); |
|
String16 name = data.readString16(); |
|
KeyFormat format = static_cast<KeyFormat>(data.readInt32()); |
|
auto clientId = nullable(readKeymasterBlob, data, true); |
|
auto appData = nullable(readKeymasterBlob, data, true); |
|
int32_t uid = data.readInt32(); |
|
ExportResult result; |
|
exportKey(name, format, clientId.value(), appData.value(), uid, &result); |
|
reply->writeNoException(); |
|
reply->writeParcelable(result); |
|
|
|
return NO_ERROR; |
|
} |
|
case BEGIN: { |
|
CHECK_INTERFACE(IKeystoreService, data, reply); |
|
sp<IBinder> token = data.readStrongBinder(); |
|
String16 name = data.readString16(); |
|
KeyPurpose purpose = static_cast<KeyPurpose>(data.readInt32()); |
|
bool pruneable = data.readInt32() != 0; |
|
auto args = nullable(readParamSetFromParcel, data); |
|
auto entropy = readBlobAsByteArray(data); |
|
int32_t uid = data.readInt32(); |
|
OperationResult result; |
|
begin(token, name, purpose, pruneable, args.value(), entropy.value(), uid, &result); |
|
reply->writeNoException(); |
|
reply->writeParcelable(result); |
|
|
|
return NO_ERROR; |
|
} |
|
case UPDATE: { |
|
CHECK_INTERFACE(IKeystoreService, data, reply); |
|
sp<IBinder> token = data.readStrongBinder(); |
|
auto args = nullable(readParamSetFromParcel, data); |
|
auto buf = readBlobAsByteArray(data); |
|
OperationResult result; |
|
update(token, args.value(), buf.value(), &result); |
|
reply->writeNoException(); |
|
reply->writeParcelable(result); |
|
|
|
return NO_ERROR; |
|
} |
|
case FINISH: { |
|
CHECK_INTERFACE(IKeystoreService, data, reply); |
|
sp<IBinder> token = data.readStrongBinder(); |
|
auto args = nullable(readParamSetFromParcel, data); |
|
auto signature = readBlobAsByteArray(data); |
|
auto entropy = readBlobAsByteArray(data); |
|
OperationResult result; |
|
finish(token, args.value(), signature.value(), entropy.value(), &result); |
|
reply->writeNoException(); |
|
reply->writeParcelable(result); |
|
|
|
return NO_ERROR; |
|
} |
|
case ABORT: { |
|
CHECK_INTERFACE(IKeystoreService, data, reply); |
|
sp<IBinder> token = data.readStrongBinder(); |
|
int32_t result = abort(token); |
|
reply->writeNoException(); |
|
reply->writeInt32(result); |
|
|
|
return NO_ERROR; |
|
} |
|
case IS_OPERATION_AUTHORIZED: { |
|
CHECK_INTERFACE(IKeystoreService, data, reply); |
|
sp<IBinder> token = data.readStrongBinder(); |
|
bool result = isOperationAuthorized(token); |
|
reply->writeNoException(); |
|
reply->writeInt32(result ? 1 : 0); |
|
|
|
return NO_ERROR; |
|
} |
|
case ADD_AUTH_TOKEN: { |
|
CHECK_INTERFACE(IKeystoreService, data, reply); |
|
const uint8_t* token_bytes = NULL; |
|
size_t size = 0; |
|
readByteArray(data, &token_bytes, &size); |
|
int32_t result = addAuthToken(token_bytes, size); |
|
reply->writeNoException(); |
|
reply->writeInt32(result); |
|
|
|
return NO_ERROR; |
|
} |
|
case ON_USER_ADDED: { |
|
CHECK_INTERFACE(IKeystoreService, data, reply); |
|
int32_t userId = data.readInt32(); |
|
int32_t parentId = data.readInt32(); |
|
int32_t result = onUserAdded(userId, parentId); |
|
reply->writeNoException(); |
|
reply->writeInt32(result); |
|
|
|
return NO_ERROR; |
|
} |
|
case ON_USER_REMOVED: { |
|
CHECK_INTERFACE(IKeystoreService, data, reply); |
|
int32_t userId = data.readInt32(); |
|
int32_t result = onUserRemoved(userId); |
|
reply->writeNoException(); |
|
reply->writeInt32(result); |
|
|
|
return NO_ERROR; |
|
} |
|
case ATTEST_KEY: { |
|
CHECK_INTERFACE(IKeystoreService, data, reply); |
|
String16 name = data.readString16(); |
|
auto params = nullable(readParamSetFromParcel, data); |
|
hidl_vec<hidl_vec<uint8_t>> chain; |
|
int ret = attestKey(name, params.value(), &chain); |
|
reply->writeNoException(); |
|
reply->writeInt32(ret); |
|
nullable(writeCertificateChainToParcel, chain, reply); |
|
|
|
return NO_ERROR; |
|
} |
|
|
|
case ATTEST_DEVICE_IDS: { |
|
CHECK_INTERFACE(IKeystoreService, data, reply); |
|
auto params = nullable(readParamSetFromParcel, data); |
|
hidl_vec<hidl_vec<uint8_t>> chain; |
|
int ret = attestDeviceIds(params.value(), &chain); |
|
reply->writeNoException(); |
|
reply->writeInt32(ret); |
|
nullable(writeCertificateChainToParcel, chain, reply); |
|
|
|
return NO_ERROR; |
|
} |
|
|
|
case ON_DEVICE_OFF_BODY: { |
|
CHECK_INTERFACE(IKeystoreService, data, reply); |
|
int32_t ret = onDeviceOffBody(); |
|
reply->writeNoException(); |
|
reply->writeInt32(ret); |
|
|
|
return NO_ERROR; |
|
} |
|
default: |
|
return BBinder::onTransact(code, data, reply, flags); |
|
} |
|
} |
|
|
|
// ---------------------------------------------------------------------------- |
|
|
|
}; // namespace android
|
|
|