Merge "Port credstore to IdentityCredential AIDL." am: c092adeb2b
Change-Id: Ie497c7c1f9e38a88411ba7acab83f4ee85ddbb84
This commit is contained in:
commit
4718a821b3
13 changed files with 224 additions and 303 deletions
|
@ -27,8 +27,6 @@ cc_binary {
|
|||
],
|
||||
init_rc: ["credstore.rc"],
|
||||
shared_libs: [
|
||||
"android.hardware.identity@1.0",
|
||||
"android.hardware.keymaster@4.0",
|
||||
"libbase",
|
||||
"libbinder",
|
||||
"libkeystore_aidl",
|
||||
|
@ -40,6 +38,8 @@ cc_binary {
|
|||
"libkeystore-attestation-application-id",
|
||||
],
|
||||
static_libs: [
|
||||
"android.hardware.identity-cpp",
|
||||
"android.hardware.keymaster-cpp",
|
||||
"libcppbor",
|
||||
]
|
||||
}
|
||||
|
|
|
@ -42,21 +42,17 @@ using std::optional;
|
|||
|
||||
using android::security::keystore::IKeystoreService;
|
||||
|
||||
using ::android::hardware::hidl_vec;
|
||||
|
||||
using ::android::hardware::identity::V1_0::Result;
|
||||
using ::android::hardware::identity::V1_0::ResultCode;
|
||||
using ::android::hardware::identity::V1_0::SecureAccessControlProfile;
|
||||
|
||||
using ::android::hardware::identity::support::ecKeyPairGetPkcs12;
|
||||
using ::android::hardware::identity::support::ecKeyPairGetPrivateKey;
|
||||
using ::android::hardware::identity::support::ecKeyPairGetPublicKey;
|
||||
using ::android::hardware::identity::support::sha256;
|
||||
|
||||
using android::hardware::keymaster::V4_0::HardwareAuthToken;
|
||||
using AidlHardwareAuthToken = android::hardware::keymaster::HardwareAuthToken;
|
||||
|
||||
Credential::Credential(const std::string& dataPath, const std::string& credentialName)
|
||||
: dataPath_(dataPath), credentialName_(credentialName) {}
|
||||
Credential::Credential(CipherSuite cipherSuite, const std::string& dataPath,
|
||||
const std::string& credentialName)
|
||||
: cipherSuite_(cipherSuite), dataPath_(dataPath), credentialName_(credentialName) {}
|
||||
|
||||
Credential::~Credential() {}
|
||||
|
||||
|
@ -71,15 +67,16 @@ Status Credential::loadCredential(sp<IIdentityCredentialStore> halStoreBinder) {
|
|||
|
||||
data_ = data;
|
||||
|
||||
Result result;
|
||||
sp<IIdentityCredential> halBinder;
|
||||
halStoreBinder->getCredential(
|
||||
data_->getCredentialData(),
|
||||
[&](const Result& _result, const sp<IIdentityCredential>& _halBinder) {
|
||||
result = _result;
|
||||
halBinder = _halBinder;
|
||||
});
|
||||
if (result.code != ResultCode::OK) {
|
||||
Status status =
|
||||
halStoreBinder->getCredential(cipherSuite_, data_->getCredentialData(), &halBinder);
|
||||
if (!status.isOk() && status.exceptionCode() == binder::Status::EX_SERVICE_SPECIFIC) {
|
||||
int code = status.serviceSpecificErrorCode();
|
||||
if (code == IIdentityCredentialStore::STATUS_CIPHER_SUITE_NOT_SUPPORTED) {
|
||||
return halStatusToError(status, ICredentialStore::ERROR_CIPHER_SUITE_NOT_SUPPORTED);
|
||||
}
|
||||
}
|
||||
if (!status.isOk()) {
|
||||
LOG(ERROR) << "Error getting HAL binder";
|
||||
return Status::fromServiceSpecificError(ICredentialStore::ERROR_GENERIC);
|
||||
}
|
||||
|
@ -104,16 +101,10 @@ Status Credential::selectAuthKey(bool allowUsingExhaustedKeys, int64_t* _aidl_re
|
|||
"No suitable authentication key available");
|
||||
}
|
||||
|
||||
Result result;
|
||||
uint64_t challenge;
|
||||
halBinder_->createAuthChallenge([&](const Result& _result, uint64_t _challenge) {
|
||||
result = _result;
|
||||
challenge = _challenge;
|
||||
});
|
||||
if (result.code != ResultCode::OK) {
|
||||
LOG(ERROR) << "createAuthChallenge() failed " << ((int)result.code) << ": "
|
||||
<< result.message;
|
||||
return halResultToGenericError(result);
|
||||
int64_t challenge;
|
||||
Status status = halBinder_->createAuthChallenge(&challenge);
|
||||
if (!status.isOk()) {
|
||||
return halStatusToGenericError(status);
|
||||
}
|
||||
if (challenge == 0) {
|
||||
return Status::fromServiceSpecificError(ICredentialStore::ERROR_GENERIC,
|
||||
|
@ -160,7 +151,7 @@ Status Credential::getEntries(const vector<uint8_t>& requestMessage,
|
|||
//
|
||||
// Also go through and figure out which access control profiles to include
|
||||
// in the startRetrieval() call.
|
||||
vector<uint16_t> requestCounts;
|
||||
vector<int32_t> requestCounts;
|
||||
const vector<SecureAccessControlProfile>& allProfiles = data_->getSecureAccessControlProfiles();
|
||||
vector<bool> includeProfile(allProfiles.size());
|
||||
for (const RequestNamespaceParcel& rns : requestNamespaces) {
|
||||
|
@ -172,8 +163,8 @@ Status Credential::getEntries(const vector<uint8_t>& requestMessage,
|
|||
|
||||
optional<EntryData> data = data_->getEntryData(rns.namespaceName, rep.name);
|
||||
if (data) {
|
||||
for (uint16_t id : data.value().accessControlProfileIds) {
|
||||
if (id >= includeProfile.size()) {
|
||||
for (int32_t id : data.value().accessControlProfileIds) {
|
||||
if (id >= int32_t(includeProfile.size())) {
|
||||
LOG(ERROR) << "Invalid accessControlProfileId " << id << " for "
|
||||
<< rns.namespaceName << ": " << rep.name;
|
||||
return Status::fromServiceSpecificError(
|
||||
|
@ -227,7 +218,7 @@ Status Credential::getEntries(const vector<uint8_t>& requestMessage,
|
|||
}
|
||||
|
||||
// Only get an authToken if it's actually needed.
|
||||
HardwareAuthToken authToken;
|
||||
AidlHardwareAuthToken aidlAuthToken;
|
||||
if (userAuthNeeded) {
|
||||
vector<uint8_t> authTokenBytes;
|
||||
if (!getAuthTokenFromKeystore(selectedChallenge_, data_->getSecureUserId(),
|
||||
|
@ -237,34 +228,36 @@ Status Credential::getEntries(const vector<uint8_t>& requestMessage,
|
|||
"Error getting auth token from keystore");
|
||||
}
|
||||
if (authTokenBytes.size() > 0) {
|
||||
authToken =
|
||||
HardwareAuthToken authToken =
|
||||
android::hardware::keymaster::V4_0::support::hidlVec2AuthToken(authTokenBytes);
|
||||
// Convert from HIDL to AIDL...
|
||||
aidlAuthToken.challenge = int64_t(authToken.challenge);
|
||||
aidlAuthToken.userId = int64_t(authToken.userId);
|
||||
aidlAuthToken.authenticatorId = int64_t(authToken.authenticatorId);
|
||||
aidlAuthToken.authenticatorType =
|
||||
::android::hardware::keymaster::HardwareAuthenticatorType(
|
||||
int32_t(authToken.authenticatorType));
|
||||
aidlAuthToken.timestamp.milliSeconds = int64_t(authToken.timestamp);
|
||||
aidlAuthToken.mac = authToken.mac;
|
||||
}
|
||||
}
|
||||
|
||||
Result result;
|
||||
halBinder_->startRetrieval(selectedProfiles, authToken, requestMessage, sessionTranscript,
|
||||
readerSignature, requestCounts,
|
||||
[&](const Result& _result) { result = _result; });
|
||||
if (result.code == ResultCode::EPHEMERAL_PUBLIC_KEY_NOT_FOUND) {
|
||||
LOG(ERROR) << "startRetrieval() failed " << ((int)result.code) << ": " << result.message;
|
||||
return Status::fromServiceSpecificError(
|
||||
ICredentialStore::ERROR_EPHEMERAL_PUBLIC_KEY_NOT_FOUND, result.message.c_str());
|
||||
} else if (result.code == ResultCode::READER_SIGNATURE_CHECK_FAILED) {
|
||||
LOG(ERROR) << "startRetrieval() failed " << ((int)result.code) << ": " << result.message;
|
||||
return Status::fromServiceSpecificError(ICredentialStore::ERROR_INVALID_READER_SIGNATURE,
|
||||
result.message.c_str());
|
||||
} else if (result.code == ResultCode::INVALID_ITEMS_REQUEST_MESSAGE) {
|
||||
LOG(ERROR) << "startRetrieval() failed " << ((int)result.code) << ": " << result.message;
|
||||
return Status::fromServiceSpecificError(
|
||||
ICredentialStore::ERROR_INVALID_ITEMS_REQUEST_MESSAGE, result.message.c_str());
|
||||
} else if (result.code == ResultCode::SESSION_TRANSCRIPT_MISMATCH) {
|
||||
LOG(ERROR) << "startRetrieval() failed " << ((int)result.code) << ": " << result.message;
|
||||
return Status::fromServiceSpecificError(ICredentialStore::ERROR_SESSION_TRANSCRIPT_MISMATCH,
|
||||
result.message.c_str());
|
||||
} else if (result.code != ResultCode::OK) {
|
||||
LOG(ERROR) << "startRetrieval() failed " << ((int)result.code) << ": " << result.message;
|
||||
return halResultToGenericError(result);
|
||||
Status status = halBinder_->startRetrieval(selectedProfiles, aidlAuthToken, requestMessage,
|
||||
sessionTranscript, readerSignature, requestCounts);
|
||||
if (!status.isOk() && status.exceptionCode() == binder::Status::EX_SERVICE_SPECIFIC) {
|
||||
int code = status.serviceSpecificErrorCode();
|
||||
if (code == IIdentityCredentialStore::STATUS_EPHEMERAL_PUBLIC_KEY_NOT_FOUND) {
|
||||
return halStatusToError(status, ICredentialStore::ERROR_EPHEMERAL_PUBLIC_KEY_NOT_FOUND);
|
||||
} else if (code == IIdentityCredentialStore::STATUS_READER_SIGNATURE_CHECK_FAILED) {
|
||||
return halStatusToError(status, ICredentialStore::ERROR_INVALID_READER_SIGNATURE);
|
||||
} else if (code == IIdentityCredentialStore::STATUS_INVALID_ITEMS_REQUEST_MESSAGE) {
|
||||
return halStatusToError(status, ICredentialStore::ERROR_INVALID_ITEMS_REQUEST_MESSAGE);
|
||||
} else if (code == IIdentityCredentialStore::STATUS_SESSION_TRANSCRIPT_MISMATCH) {
|
||||
return halStatusToError(status, ICredentialStore::ERROR_SESSION_TRANSCRIPT_MISMATCH);
|
||||
}
|
||||
}
|
||||
if (!status.isOk()) {
|
||||
return halStatusToGenericError(status);
|
||||
}
|
||||
|
||||
for (const RequestNamespaceParcel& rns : requestNamespaces) {
|
||||
|
@ -282,43 +275,41 @@ Status Credential::getEntries(const vector<uint8_t>& requestMessage,
|
|||
continue;
|
||||
}
|
||||
|
||||
halBinder_->startRetrieveEntryValue(rns.namespaceName, rep.name, data.value().size,
|
||||
data.value().accessControlProfileIds,
|
||||
[&](const Result& _result) { result = _result; });
|
||||
if (result.code == ResultCode::USER_AUTHENTICATION_FAILED) {
|
||||
resultEntryParcel.status = STATUS_USER_AUTHENTICATION_FAILED;
|
||||
resultNamespaceParcel.entries.push_back(resultEntryParcel);
|
||||
continue;
|
||||
} else if (result.code == ResultCode::READER_AUTHENTICATION_FAILED) {
|
||||
resultEntryParcel.status = STATUS_READER_AUTHENTICATION_FAILED;
|
||||
resultNamespaceParcel.entries.push_back(resultEntryParcel);
|
||||
continue;
|
||||
} else if (result.code == ResultCode::NOT_IN_REQUEST_MESSAGE) {
|
||||
resultEntryParcel.status = STATUS_NOT_IN_REQUEST_MESSAGE;
|
||||
resultNamespaceParcel.entries.push_back(resultEntryParcel);
|
||||
continue;
|
||||
} else if (result.code == ResultCode::NO_ACCESS_CONTROL_PROFILES) {
|
||||
resultEntryParcel.status = STATUS_NO_ACCESS_CONTROL_PROFILES;
|
||||
resultNamespaceParcel.entries.push_back(resultEntryParcel);
|
||||
continue;
|
||||
} else if (result.code != ResultCode::OK) {
|
||||
LOG(ERROR) << "startRetrieveEntryValue() failed " << ((int)result.code) << ": "
|
||||
<< result.message;
|
||||
return halResultToGenericError(result);
|
||||
status =
|
||||
halBinder_->startRetrieveEntryValue(rns.namespaceName, rep.name, data.value().size,
|
||||
data.value().accessControlProfileIds);
|
||||
if (!status.isOk() && status.exceptionCode() == binder::Status::EX_SERVICE_SPECIFIC) {
|
||||
int code = status.serviceSpecificErrorCode();
|
||||
if (code == IIdentityCredentialStore::STATUS_USER_AUTHENTICATION_FAILED) {
|
||||
resultEntryParcel.status = STATUS_USER_AUTHENTICATION_FAILED;
|
||||
resultNamespaceParcel.entries.push_back(resultEntryParcel);
|
||||
continue;
|
||||
} else if (code == IIdentityCredentialStore::STATUS_READER_AUTHENTICATION_FAILED) {
|
||||
resultEntryParcel.status = STATUS_READER_AUTHENTICATION_FAILED;
|
||||
resultNamespaceParcel.entries.push_back(resultEntryParcel);
|
||||
continue;
|
||||
} else if (code == IIdentityCredentialStore::STATUS_NOT_IN_REQUEST_MESSAGE) {
|
||||
resultEntryParcel.status = STATUS_NOT_IN_REQUEST_MESSAGE;
|
||||
resultNamespaceParcel.entries.push_back(resultEntryParcel);
|
||||
continue;
|
||||
} else if (code == IIdentityCredentialStore::STATUS_NO_ACCESS_CONTROL_PROFILES) {
|
||||
resultEntryParcel.status = STATUS_NO_ACCESS_CONTROL_PROFILES;
|
||||
resultNamespaceParcel.entries.push_back(resultEntryParcel);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (!status.isOk()) {
|
||||
return halStatusToGenericError(status);
|
||||
}
|
||||
|
||||
vector<uint8_t> value;
|
||||
for (const auto& encryptedChunk : data.value().encryptedChunks) {
|
||||
halBinder_->retrieveEntryValue(
|
||||
encryptedChunk, [&](const Result& _result, const hidl_vec<uint8_t>& chunk) {
|
||||
result = _result;
|
||||
value.insert(value.end(), chunk.begin(), chunk.end());
|
||||
});
|
||||
if (result.code != ResultCode::OK) {
|
||||
LOG(ERROR) << "retrieveEntryValue failed() " << ((int)result.code) << ": "
|
||||
<< result.message;
|
||||
return halResultToGenericError(result);
|
||||
vector<uint8_t> chunk;
|
||||
status = halBinder_->retrieveEntryValue(encryptedChunk, &chunk);
|
||||
if (!status.isOk()) {
|
||||
return halStatusToGenericError(status);
|
||||
}
|
||||
value.insert(value.end(), chunk.begin(), chunk.end());
|
||||
}
|
||||
|
||||
resultEntryParcel.status = STATUS_OK;
|
||||
|
@ -347,19 +338,12 @@ Status Credential::getEntries(const vector<uint8_t>& requestMessage,
|
|||
if (authKey != nullptr) {
|
||||
signingKeyBlob = authKey->keyBlob;
|
||||
}
|
||||
halBinder_->finishRetrieval(signingKeyBlob, [&](const Result& _result,
|
||||
const hidl_vec<uint8_t>& _mac,
|
||||
const hidl_vec<uint8_t>& _deviceNameSpaces) {
|
||||
result = _result;
|
||||
ret.mac = _mac;
|
||||
ret.deviceNameSpaces = _deviceNameSpaces;
|
||||
if (authKey != nullptr) {
|
||||
ret.staticAuthenticationData = authKey->staticAuthenticationData;
|
||||
}
|
||||
});
|
||||
if (result.code != ResultCode::OK) {
|
||||
LOG(ERROR) << "finishRetrieval failed() " << ((int)result.code) << ": " << result.message;
|
||||
return halResultToGenericError(result);
|
||||
status = halBinder_->finishRetrieval(signingKeyBlob, &ret.mac, &ret.deviceNameSpaces);
|
||||
if (!status.isOk()) {
|
||||
return halStatusToGenericError(status);
|
||||
}
|
||||
if (authKey != nullptr) {
|
||||
ret.staticAuthenticationData = authKey->staticAuthenticationData;
|
||||
}
|
||||
|
||||
// Ensure useCount is updated on disk.
|
||||
|
@ -375,36 +359,24 @@ Status Credential::getEntries(const vector<uint8_t>& requestMessage,
|
|||
}
|
||||
|
||||
Status Credential::deleteCredential(vector<uint8_t>* _aidl_return) {
|
||||
Result result;
|
||||
halBinder_->deleteCredential(
|
||||
[&](const Result& _result, const hidl_vec<uint8_t>& _proofOfDeletionSignature) {
|
||||
result = _result;
|
||||
*_aidl_return = _proofOfDeletionSignature;
|
||||
});
|
||||
if (result.code != ResultCode::OK) {
|
||||
LOG(ERROR) << "deleteCredential failed() " << ((int)result.code) << ": " << result.message;
|
||||
return halResultToGenericError(result);
|
||||
vector<uint8_t> proofOfDeletionSignature;
|
||||
Status status = halBinder_->deleteCredential(&proofOfDeletionSignature);
|
||||
if (!status.isOk()) {
|
||||
return halStatusToGenericError(status);
|
||||
}
|
||||
if (!data_->deleteCredential()) {
|
||||
return Status::fromServiceSpecificError(ICredentialStore::ERROR_GENERIC,
|
||||
"Error deleting credential data on disk");
|
||||
}
|
||||
*_aidl_return = proofOfDeletionSignature;
|
||||
return Status::ok();
|
||||
}
|
||||
|
||||
Status Credential::createEphemeralKeyPair(vector<uint8_t>* _aidl_return) {
|
||||
Result result;
|
||||
|
||||
vector<uint8_t> keyPair;
|
||||
halBinder_->createEphemeralKeyPair(
|
||||
[&](const Result& _result, const hidl_vec<uint8_t>& _keyPair) {
|
||||
result = _result;
|
||||
keyPair = _keyPair;
|
||||
});
|
||||
if (result.code != ResultCode::OK) {
|
||||
LOG(ERROR) << "createEphemeralKeyPair failed() " << ((int)result.code) << ": "
|
||||
<< result.message;
|
||||
return halResultToGenericError(result);
|
||||
Status status = halBinder_->createEphemeralKeyPair(&keyPair);
|
||||
if (!status.isOk()) {
|
||||
return halStatusToGenericError(status);
|
||||
}
|
||||
|
||||
optional<vector<uint8_t>> pkcs12Bytes = ecKeyPairGetPkcs12(keyPair,
|
||||
|
@ -423,13 +395,9 @@ Status Credential::createEphemeralKeyPair(vector<uint8_t>* _aidl_return) {
|
|||
}
|
||||
|
||||
Status Credential::setReaderEphemeralPublicKey(const vector<uint8_t>& publicKey) {
|
||||
Result result;
|
||||
halBinder_->setReaderEphemeralPublicKey(publicKey,
|
||||
[&](const Result& _result) { result = _result; });
|
||||
if (result.code != ResultCode::OK) {
|
||||
LOG(ERROR) << "setReaderEphemeralPublicKey failed() " << ((int)result.code) << ": "
|
||||
<< result.message;
|
||||
return halResultToGenericError(result);
|
||||
Status status = halBinder_->setReaderEphemeralPublicKey(publicKey);
|
||||
if (!status.isOk()) {
|
||||
return halStatusToGenericError(status);
|
||||
}
|
||||
return Status::ok();
|
||||
}
|
||||
|
|
|
@ -22,8 +22,7 @@
|
|||
|
||||
#include <android/security/identity/BnCredential.h>
|
||||
|
||||
#include <android/hardware/identity/1.0/IIdentityCredentialStore.h>
|
||||
#include <android/hardware/identity/1.0/types.h>
|
||||
#include <android/hardware/identity/IIdentityCredentialStore.h>
|
||||
|
||||
#include "CredentialData.h"
|
||||
|
||||
|
@ -36,12 +35,13 @@ using ::android::binder::Status;
|
|||
using ::std::string;
|
||||
using ::std::vector;
|
||||
|
||||
using ::android::hardware::identity::V1_0::IIdentityCredential;
|
||||
using ::android::hardware::identity::V1_0::IIdentityCredentialStore;
|
||||
using ::android::hardware::identity::CipherSuite;
|
||||
using ::android::hardware::identity::IIdentityCredential;
|
||||
using ::android::hardware::identity::IIdentityCredentialStore;
|
||||
|
||||
class Credential : public BnCredential {
|
||||
public:
|
||||
Credential(const string& dataPath, const string& credentialName);
|
||||
Credential(CipherSuite cipherSuite, const string& dataPath, const string& credentialName);
|
||||
~Credential();
|
||||
|
||||
Status loadCredential(sp<IIdentityCredentialStore> halStoreBinder);
|
||||
|
@ -70,6 +70,7 @@ class Credential : public BnCredential {
|
|||
Status getAuthenticationDataUsageCount(vector<int32_t>* _aidl_return) override;
|
||||
|
||||
private:
|
||||
CipherSuite cipherSuite_;
|
||||
string dataPath_;
|
||||
string credentialName_;
|
||||
|
||||
|
|
|
@ -37,8 +37,6 @@ namespace android {
|
|||
namespace security {
|
||||
namespace identity {
|
||||
|
||||
using android::hardware::identity::V1_0::Result;
|
||||
using android::hardware::identity::V1_0::ResultCode;
|
||||
using std::optional;
|
||||
|
||||
string CredentialData::calculateCredentialFileName(const string& dataPath, uid_t ownerUid,
|
||||
|
@ -88,7 +86,7 @@ bool CredentialData::saveToDisk() const {
|
|||
for (const SecureAccessControlProfile& sacp : secureAccessControlProfiles_) {
|
||||
cppbor::Array array;
|
||||
array.add(sacp.id);
|
||||
array.add((const vector<uint8_t>&)sacp.readerCertificate);
|
||||
array.add(sacp.readerCertificate.encodedCertificate);
|
||||
array.add(sacp.userAuthenticationRequired);
|
||||
array.add(sacp.timeoutMillis);
|
||||
array.add(sacp.secureUserId);
|
||||
|
@ -107,7 +105,7 @@ bool CredentialData::saveToDisk() const {
|
|||
cppbor::Array entryDataArray;
|
||||
entryDataArray.add(entryData.size);
|
||||
cppbor::Array idsArray;
|
||||
for (uint16_t id : entryData.accessControlProfileIds) {
|
||||
for (int32_t id : entryData.accessControlProfileIds) {
|
||||
idsArray.add(id);
|
||||
}
|
||||
entryDataArray.add(std::move(idsArray));
|
||||
|
@ -159,7 +157,7 @@ optional<SecureAccessControlProfile> parseSacp(const cppbor::Item& item) {
|
|||
}
|
||||
SecureAccessControlProfile sacp;
|
||||
sacp.id = itemId->value();
|
||||
sacp.readerCertificate = itemReaderCertificate->value();
|
||||
sacp.readerCertificate.encodedCertificate = itemReaderCertificate->value();
|
||||
sacp.userAuthenticationRequired = itemUserAuthenticationRequired->value();
|
||||
sacp.timeoutMillis = itemTimeoutMillis->value();
|
||||
sacp.secureUserId = itesecureUserId_->value();
|
||||
|
@ -195,14 +193,14 @@ optional<AuthKeyData> parseAuthKeyData(const cppbor::Item& item) {
|
|||
return authKeyData;
|
||||
}
|
||||
|
||||
vector<uint16_t> parseAccessControlProfileIds(const cppbor::Item& item) {
|
||||
vector<int32_t> parseAccessControlProfileIds(const cppbor::Item& item) {
|
||||
const cppbor::Array* array = item.asArray();
|
||||
if (array == nullptr) {
|
||||
LOG(ERROR) << "The accessControlProfileIds member is not an array";
|
||||
return {};
|
||||
}
|
||||
|
||||
vector<uint16_t> accessControlProfileIds;
|
||||
vector<int32_t> accessControlProfileIds;
|
||||
for (size_t n = 0; n < array->size(); n++) {
|
||||
const cppbor::Int* itemInt = ((*array)[n])->asInt();
|
||||
if (itemInt == nullptr) {
|
||||
|
@ -336,7 +334,7 @@ bool CredentialData::loadFromDisk() {
|
|||
}
|
||||
uint64_t entrySize = ecEntrySizeItem->value();
|
||||
|
||||
optional<vector<uint16_t>> accessControlProfileIds =
|
||||
optional<vector<int32_t>> accessControlProfileIds =
|
||||
parseAccessControlProfileIds(*(*ecEntryArrayItem)[1]);
|
||||
if (!accessControlProfileIds) {
|
||||
LOG(ERROR) << "Error parsing access control profile ids";
|
||||
|
@ -391,8 +389,13 @@ bool CredentialData::loadFromDisk() {
|
|||
}
|
||||
}
|
||||
|
||||
if (credentialData_.size() == 0 || attestationCertificate_.size() == 0) {
|
||||
LOG(ERROR) << "Missing credentialData or attestationCertificate";
|
||||
if (credentialData_.size() == 0) {
|
||||
LOG(ERROR) << "Missing credentialData";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (attestationCertificate_.size() == 0) {
|
||||
LOG(ERROR) << "Missing attestationCertificate";
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -511,8 +514,8 @@ const AuthKeyData* CredentialData::selectAuthKey(bool allowUsingExhaustedKeys) {
|
|||
return candidate;
|
||||
}
|
||||
|
||||
optional<vector<vector<uint8_t>>> CredentialData::getAuthKeysNeedingCertification(
|
||||
const sp<android::hardware::identity::V1_0::IIdentityCredential>& halBinder) {
|
||||
optional<vector<vector<uint8_t>>>
|
||||
CredentialData::getAuthKeysNeedingCertification(const sp<IIdentityCredential>& halBinder) {
|
||||
|
||||
vector<vector<uint8_t>> keysNeedingCert;
|
||||
|
||||
|
@ -520,22 +523,14 @@ optional<vector<vector<uint8_t>>> CredentialData::getAuthKeysNeedingCertificatio
|
|||
bool newKeyNeeded = (data.certificate.size() == 0) || (data.useCount >= maxUsesPerKey_);
|
||||
bool certificationPending = (data.pendingCertificate.size() > 0);
|
||||
if (newKeyNeeded && !certificationPending) {
|
||||
Result result;
|
||||
vector<uint8_t> signingKeyBlob;
|
||||
vector<uint8_t> signingKeyCertificate;
|
||||
halBinder->generateSigningKeyPair(
|
||||
[&](const Result& _result,
|
||||
const android::hardware::hidl_vec<uint8_t> _signingKeyBlob,
|
||||
const android::hardware::hidl_vec<uint8_t> _signingKeyCertificate) {
|
||||
result = _result;
|
||||
signingKeyBlob = _signingKeyBlob;
|
||||
signingKeyCertificate = _signingKeyCertificate;
|
||||
});
|
||||
if (result.code != ResultCode::OK) {
|
||||
Certificate signingKeyCertificate;
|
||||
if (!halBinder->generateSigningKeyPair(&signingKeyBlob, &signingKeyCertificate)
|
||||
.isOk()) {
|
||||
LOG(ERROR) << "Error generating signing key-pair";
|
||||
return {};
|
||||
}
|
||||
data.pendingCertificate = signingKeyCertificate;
|
||||
data.pendingCertificate = signingKeyCertificate.encodedCertificate;
|
||||
data.pendingKeyBlob = signingKeyBlob;
|
||||
certificationPending = true;
|
||||
}
|
||||
|
|
|
@ -25,14 +25,16 @@
|
|||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include <android/hardware/identity/1.0/IIdentityCredential.h>
|
||||
#include <android/hardware/identity/1.0/types.h>
|
||||
#include <android/hardware/identity/IIdentityCredential.h>
|
||||
#include <android/hardware/identity/SecureAccessControlProfile.h>
|
||||
|
||||
namespace android {
|
||||
namespace security {
|
||||
namespace identity {
|
||||
|
||||
using ::android::hardware::identity::V1_0::SecureAccessControlProfile;
|
||||
using ::android::hardware::identity::Certificate;
|
||||
using ::android::hardware::identity::IIdentityCredential;
|
||||
using ::android::hardware::identity::SecureAccessControlProfile;
|
||||
using ::std::map;
|
||||
using ::std::optional;
|
||||
using ::std::pair;
|
||||
|
@ -44,7 +46,7 @@ struct EntryData {
|
|||
EntryData() {}
|
||||
|
||||
uint64_t size = 0;
|
||||
vector<uint16_t> accessControlProfileIds;
|
||||
vector<int32_t> accessControlProfileIds;
|
||||
vector<vector<uint8_t>> encryptedChunks;
|
||||
};
|
||||
|
||||
|
@ -108,8 +110,8 @@ class CredentialData : public RefBase {
|
|||
// the authentication and increases its use-count.
|
||||
const AuthKeyData* selectAuthKey(bool allowUsingExhaustedKeys);
|
||||
|
||||
optional<vector<vector<uint8_t>>> getAuthKeysNeedingCertification(
|
||||
const sp<android::hardware::identity::V1_0::IIdentityCredential>& halBinder);
|
||||
optional<vector<vector<uint8_t>>>
|
||||
getAuthKeysNeedingCertification(const sp<IIdentityCredential>& halBinder);
|
||||
|
||||
bool storeStaticAuthenticationData(const vector<uint8_t>& authenticationKey,
|
||||
const vector<uint8_t>& staticAuthData);
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include <binder/IPCThreadState.h>
|
||||
|
||||
#include "Credential.h"
|
||||
#include "CredentialData.h"
|
||||
#include "CredentialStore.h"
|
||||
#include "Util.h"
|
||||
#include "WritableCredential.h"
|
||||
|
@ -31,39 +32,20 @@ namespace android {
|
|||
namespace security {
|
||||
namespace identity {
|
||||
|
||||
using ::android::hardware::hidl_string;
|
||||
using ::android::hardware::hidl_vec;
|
||||
using ::android::hardware::identity::V1_0::Result;
|
||||
using ::android::hardware::identity::V1_0::ResultCode;
|
||||
|
||||
using ::android::hardware::identity::V1_0::IWritableIdentityCredential;
|
||||
|
||||
CredentialStore::CredentialStore(const std::string& dataPath, sp<IIdentityCredentialStore> hal)
|
||||
: dataPath_(dataPath), hal_(hal) {}
|
||||
|
||||
bool CredentialStore::init() {
|
||||
Result result;
|
||||
hal_->getHardwareInformation([&](const Result& _result, const hidl_string& credentialStoreName,
|
||||
const hidl_string& credentialStoreAuthorName,
|
||||
uint32_t _dataChunkSize, bool _isDirectAccess,
|
||||
const hidl_vec<hidl_string>& _supportedDocTypes) {
|
||||
result = _result;
|
||||
dataChunkSize_ = _dataChunkSize;
|
||||
isDirectAccess_ = _isDirectAccess;
|
||||
supportedDocTypes_.clear();
|
||||
for (auto& docType : _supportedDocTypes) {
|
||||
supportedDocTypes_.push_back(docType);
|
||||
}
|
||||
LOG(INFO) << "Connected to Identity Credential HAL with name '" << credentialStoreName
|
||||
<< "' authored by '" << credentialStoreAuthorName << "' with chunk size "
|
||||
<< _dataChunkSize << " and directoAccess set to "
|
||||
<< (_isDirectAccess ? "true" : "false");
|
||||
});
|
||||
if (result.code != ResultCode::OK) {
|
||||
LOG(ERROR) << "Error getting hardware information: " << (int)result.code << ": "
|
||||
<< result.message;
|
||||
Status status = hal_->getHardwareInformation(&hwInfo_);
|
||||
if (!status.isOk()) {
|
||||
LOG(ERROR) << "Error getting hardware information: " << status.toString8();
|
||||
return false;
|
||||
}
|
||||
|
||||
LOG(INFO) << "Connected to Identity Credential HAL with name '" << hwInfo_.credentialStoreName
|
||||
<< "' authored by '" << hwInfo_.credentialStoreAuthorName << "' with chunk size "
|
||||
<< hwInfo_.dataChunkSize << " and directoAccess set to "
|
||||
<< (hwInfo_.isDirectAccess ? "true" : "false");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -71,8 +53,8 @@ CredentialStore::~CredentialStore() {}
|
|||
|
||||
Status CredentialStore::getSecurityHardwareInfo(SecurityHardwareInfoParcel* _aidl_return) {
|
||||
SecurityHardwareInfoParcel info;
|
||||
info.directAccess = isDirectAccess_;
|
||||
info.supportedDocTypes = supportedDocTypes_;
|
||||
info.directAccess = hwInfo_.isDirectAccess;
|
||||
info.supportedDocTypes = hwInfo_.supportedDocTypes;
|
||||
*_aidl_return = info;
|
||||
return Status::ok();
|
||||
};
|
||||
|
@ -92,37 +74,26 @@ Status CredentialStore::createCredential(const std::string& credentialName,
|
|||
"Credential with given name already exists");
|
||||
}
|
||||
|
||||
if (supportedDocTypes_.size() > 0) {
|
||||
if (std::find(supportedDocTypes_.begin(), supportedDocTypes_.end(), docType) ==
|
||||
supportedDocTypes_.end()) {
|
||||
if (hwInfo_.supportedDocTypes.size() > 0) {
|
||||
if (std::find(hwInfo_.supportedDocTypes.begin(), hwInfo_.supportedDocTypes.end(),
|
||||
docType) == hwInfo_.supportedDocTypes.end()) {
|
||||
return Status::fromServiceSpecificError(ERROR_DOCUMENT_TYPE_NOT_SUPPORTED,
|
||||
"No support for given document type");
|
||||
}
|
||||
}
|
||||
|
||||
Result result;
|
||||
sp<IWritableIdentityCredential> halWritableCredential;
|
||||
hal_->createCredential(
|
||||
docType, false,
|
||||
[&](const Result& _result, const sp<IWritableIdentityCredential>& _halWritableCredential) {
|
||||
result = _result;
|
||||
halWritableCredential = _halWritableCredential;
|
||||
});
|
||||
if (result.code != ResultCode::OK) {
|
||||
return halResultToGenericError(result);
|
||||
Status status = hal_->createCredential(docType, false, &halWritableCredential);
|
||||
if (!status.isOk()) {
|
||||
return halStatusToGenericError(status);
|
||||
}
|
||||
|
||||
sp<IWritableCredential> writableCredential = new WritableCredential(
|
||||
dataPath_, credentialName, docType, dataChunkSize_, halWritableCredential);
|
||||
dataPath_, credentialName, docType, hwInfo_.dataChunkSize, halWritableCredential);
|
||||
*_aidl_return = writableCredential;
|
||||
return Status::ok();
|
||||
}
|
||||
|
||||
// Keep in sync with IdentityCredentialStore.java
|
||||
//
|
||||
|
||||
const int CIPHERSUITE_ECDHE_HKDF_ECDSA_WITH_AES_256_GCM_SHA256 = 1;
|
||||
|
||||
Status CredentialStore::getCredentialByName(const std::string& credentialName, int32_t cipherSuite,
|
||||
sp<ICredential>* _aidl_return) {
|
||||
*_aidl_return = nullptr;
|
||||
|
@ -139,13 +110,9 @@ Status CredentialStore::getCredentialByName(const std::string& credentialName, i
|
|||
"Credential with given name doesn't exist");
|
||||
}
|
||||
|
||||
// We only support a single cipher-suite right now.
|
||||
if (cipherSuite != CIPHERSUITE_ECDHE_HKDF_ECDSA_WITH_AES_256_GCM_SHA256) {
|
||||
return Status::fromServiceSpecificError(ERROR_CIPHER_SUITE_NOT_SUPPORTED,
|
||||
"Cipher suite not supported");
|
||||
}
|
||||
|
||||
sp<Credential> credential = new Credential(dataPath_, credentialName);
|
||||
// Note: IdentityCredentialStore.java's CipherSuite enumeration and CipherSuite from the
|
||||
// HAL is manually kept in sync. So this cast is safe.
|
||||
sp<Credential> credential = new Credential(CipherSuite(cipherSuite), dataPath_, credentialName);
|
||||
|
||||
Status loadStatus = credential->loadCredential(hal_);
|
||||
if (!loadStatus.isOk()) {
|
||||
|
|
|
@ -20,8 +20,7 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <android/hardware/identity/1.0/IIdentityCredentialStore.h>
|
||||
#include <android/hardware/identity/1.0/types.h>
|
||||
#include <android/hardware/identity/IIdentityCredentialStore.h>
|
||||
|
||||
#include <android/security/identity/BnCredentialStore.h>
|
||||
|
||||
|
@ -35,7 +34,8 @@ using ::std::string;
|
|||
using ::std::unique_ptr;
|
||||
using ::std::vector;
|
||||
|
||||
using ::android::hardware::identity::V1_0::IIdentityCredentialStore;
|
||||
using ::android::hardware::identity::HardwareInformation;
|
||||
using ::android::hardware::identity::IIdentityCredentialStore;
|
||||
|
||||
class CredentialStore : public BnCredentialStore {
|
||||
public:
|
||||
|
@ -58,9 +58,7 @@ class CredentialStore : public BnCredentialStore {
|
|||
|
||||
sp<IIdentityCredentialStore> hal_;
|
||||
|
||||
bool isDirectAccess_;
|
||||
vector<string> supportedDocTypes_;
|
||||
size_t dataChunkSize_;
|
||||
HardwareInformation hwInfo_;
|
||||
};
|
||||
|
||||
} // namespace identity
|
||||
|
|
|
@ -19,28 +19,29 @@
|
|||
#include <android-base/logging.h>
|
||||
|
||||
#include <binder/IPCThreadState.h>
|
||||
#include <binder/IServiceManager.h>
|
||||
|
||||
#include "CredentialStore.h"
|
||||
//#include "CredentialStore.h"
|
||||
#include "CredentialStoreFactory.h"
|
||||
|
||||
namespace android {
|
||||
namespace security {
|
||||
namespace identity {
|
||||
|
||||
using ::android::hardware::hidl_string;
|
||||
using ::android::hardware::hidl_vec;
|
||||
using ::android::hardware::identity::V1_0::IIdentityCredentialStore;
|
||||
using ::android::hardware::identity::V1_0::Result;
|
||||
using ::android::hardware::identity::V1_0::ResultCode;
|
||||
using ::android::hardware::identity::IIdentityCredentialStore;
|
||||
|
||||
CredentialStoreFactory::CredentialStoreFactory(const std::string& dataPath) : dataPath_(dataPath) {}
|
||||
|
||||
CredentialStoreFactory::~CredentialStoreFactory() {}
|
||||
|
||||
CredentialStore* CredentialStoreFactory::createCredentialStore(const string& serviceName) {
|
||||
sp<IIdentityCredentialStore> hal = IIdentityCredentialStore::tryGetService(serviceName);
|
||||
CredentialStore* CredentialStoreFactory::createCredentialStore(const string& instanceName) {
|
||||
String16 serviceName =
|
||||
IIdentityCredentialStore::descriptor + String16("/") + String16(instanceName.c_str());
|
||||
sp<IIdentityCredentialStore> hal =
|
||||
android::waitForDeclaredService<IIdentityCredentialStore>(serviceName);
|
||||
if (hal.get() == nullptr) {
|
||||
LOG(ERROR) << "Error get hal for store with service name '" << serviceName << "'";
|
||||
LOG(ERROR) << "Error getting HAL for IdentityCredentialStore store with service name '"
|
||||
<< serviceName << "'";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -51,7 +52,6 @@ CredentialStore* CredentialStoreFactory::createCredentialStore(const string& ser
|
|||
delete store;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return store;
|
||||
}
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ class CredentialStoreFactory : public BnCredentialStoreFactory {
|
|||
sp<ICredentialStore>* _aidl_return) override;
|
||||
|
||||
private:
|
||||
CredentialStore* createCredentialStore(const string& serviceName);
|
||||
CredentialStore* createCredentialStore(const string& instanceName);
|
||||
|
||||
string dataPath_;
|
||||
|
||||
|
|
|
@ -35,10 +35,16 @@ namespace identity {
|
|||
|
||||
using ::android::base::StringPrintf;
|
||||
|
||||
Status halResultToGenericError(const Result& result) {
|
||||
string message =
|
||||
StringPrintf("HAL failed with code %d: %s", int(result.code), result.message.c_str());
|
||||
return Status::fromServiceSpecificError(ICredentialStore::ERROR_GENERIC, message.c_str());
|
||||
Status halStatusToError(const Status& halStatus, int credStoreError) {
|
||||
string message = StringPrintf(
|
||||
"HAL failed with exception code %d (%s), service-specific error code %d, message '%s'",
|
||||
halStatus.exceptionCode(), Status::exceptionToString(halStatus.exceptionCode()).c_str(),
|
||||
halStatus.serviceSpecificErrorCode(), halStatus.exceptionMessage().c_str());
|
||||
return Status::fromServiceSpecificError(credStoreError, message.c_str());
|
||||
}
|
||||
|
||||
Status halStatusToGenericError(const Status& halStatus) {
|
||||
return halStatusToError(halStatus, ICredentialStore::ERROR_GENERIC);
|
||||
}
|
||||
|
||||
optional<vector<uint8_t>> fileGetContents(const string& path) {
|
||||
|
|
|
@ -20,8 +20,6 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <android/hardware/identity/1.0/IIdentityCredentialStore.h>
|
||||
#include <android/hardware/identity/1.0/types.h>
|
||||
#include <binder/Status.h>
|
||||
|
||||
namespace android {
|
||||
|
@ -33,9 +31,13 @@ using ::std::string;
|
|||
using ::std::vector;
|
||||
|
||||
using ::android::binder::Status;
|
||||
using ::android::hardware::identity::V1_0::Result;
|
||||
|
||||
Status halResultToGenericError(const Result& result);
|
||||
// Converts a HAL status to a credstore service-specific error with code
|
||||
// ICredentialStore::ERROR_GENERIC.
|
||||
Status halStatusToGenericError(const Status& halStatus);
|
||||
|
||||
// Converts a HAL status to a credstore service-specific error of a given value
|
||||
Status halStatusToError(const Status& halStatus, int credStoreError);
|
||||
|
||||
// Helper function to atomically write |data| into file at |path|.
|
||||
//
|
||||
|
|
|
@ -34,11 +34,7 @@ namespace identity {
|
|||
|
||||
using ::std::pair;
|
||||
|
||||
using ::android::hardware::hidl_vec;
|
||||
|
||||
using ::android::hardware::identity::V1_0::Result;
|
||||
using ::android::hardware::identity::V1_0::ResultCode;
|
||||
using ::android::hardware::identity::V1_0::SecureAccessControlProfile;
|
||||
using ::android::hardware::identity::SecureAccessControlProfile;
|
||||
|
||||
using ::android::hardware::identity::support::chunkVector;
|
||||
|
||||
|
@ -51,8 +47,6 @@ WritableCredential::WritableCredential(const string& dataPath, const string& cre
|
|||
WritableCredential::~WritableCredential() {}
|
||||
|
||||
Status WritableCredential::ensureAttestationCertificateExists(const vector<uint8_t>& challenge) {
|
||||
vector<uint8_t> attestationCertificate;
|
||||
|
||||
if (!attestationCertificate_.empty()) {
|
||||
return Status::ok();
|
||||
}
|
||||
|
@ -65,21 +59,21 @@ Status WritableCredential::ensureAttestationCertificateExists(const vector<uint8
|
|||
"Failed gathering AttestionApplicationId");
|
||||
}
|
||||
|
||||
Result result;
|
||||
halBinder_->getAttestationCertificate(
|
||||
asn1AttestationId.value(), challenge,
|
||||
[&](const Result& _result, const hidl_vec<hidl_vec<uint8_t>>& _splitCerts) {
|
||||
result = _result;
|
||||
vector<vector<uint8_t>> splitCerts;
|
||||
std::copy(_splitCerts.begin(), _splitCerts.end(), std::back_inserter(splitCerts));
|
||||
attestationCertificate =
|
||||
::android::hardware::identity::support::certificateChainJoin(splitCerts);
|
||||
});
|
||||
if (result.code != ResultCode::OK) {
|
||||
vector<Certificate> certificateChain;
|
||||
Status status = halBinder_->getAttestationCertificate(asn1AttestationId.value(), challenge,
|
||||
&certificateChain);
|
||||
if (!status.isOk()) {
|
||||
LOG(ERROR) << "Error calling getAttestationCertificate()";
|
||||
return halResultToGenericError(result);
|
||||
return halStatusToGenericError(status);
|
||||
}
|
||||
attestationCertificate_ = attestationCertificate;
|
||||
|
||||
vector<vector<uint8_t>> splitCerts;
|
||||
for (const auto& cert : certificateChain) {
|
||||
splitCerts.push_back(cert.encodedCertificate);
|
||||
}
|
||||
attestationCertificate_ =
|
||||
::android::hardware::identity::support::certificateChainJoin(splitCerts);
|
||||
|
||||
return Status::ok();
|
||||
}
|
||||
|
||||
|
@ -114,56 +108,51 @@ WritableCredential::personalize(const vector<AccessControlProfileParcel>& access
|
|||
|
||||
data.setAttestationCertificate(attestationCertificate_);
|
||||
|
||||
vector<uint16_t> entryCounts;
|
||||
vector<int32_t> entryCounts;
|
||||
for (const EntryNamespaceParcel& ensParcel : entryNamespaces) {
|
||||
entryCounts.push_back(ensParcel.entries.size());
|
||||
}
|
||||
|
||||
Result result;
|
||||
halBinder_->startPersonalization(accessControlProfiles.size(), entryCounts,
|
||||
[&](const Result& _result) { result = _result; });
|
||||
if (result.code != ResultCode::OK) {
|
||||
return halResultToGenericError(result);
|
||||
Status status = halBinder_->startPersonalization(accessControlProfiles.size(), entryCounts);
|
||||
if (!status.isOk()) {
|
||||
return halStatusToGenericError(status);
|
||||
}
|
||||
|
||||
for (const AccessControlProfileParcel& acpParcel : accessControlProfiles) {
|
||||
halBinder_->addAccessControlProfile(
|
||||
acpParcel.id, acpParcel.readerCertificate, acpParcel.userAuthenticationRequired,
|
||||
acpParcel.userAuthenticationTimeoutMillis, secureUserId,
|
||||
[&](const Result& _result, const SecureAccessControlProfile& profile) {
|
||||
data.addSecureAccessControlProfile(profile);
|
||||
result = _result;
|
||||
});
|
||||
if (result.code != ResultCode::OK) {
|
||||
return halResultToGenericError(result);
|
||||
Certificate certificate;
|
||||
certificate.encodedCertificate = acpParcel.readerCertificate;
|
||||
SecureAccessControlProfile profile;
|
||||
status = halBinder_->addAccessControlProfile(
|
||||
acpParcel.id, certificate, acpParcel.userAuthenticationRequired,
|
||||
acpParcel.userAuthenticationTimeoutMillis, secureUserId, &profile);
|
||||
if (!status.isOk()) {
|
||||
return halStatusToGenericError(status);
|
||||
}
|
||||
data.addSecureAccessControlProfile(profile);
|
||||
}
|
||||
|
||||
for (const EntryNamespaceParcel& ensParcel : entryNamespaces) {
|
||||
for (const EntryParcel& eParcel : ensParcel.entries) {
|
||||
vector<vector<uint8_t>> chunks = chunkVector(eParcel.value, dataChunkSize_);
|
||||
|
||||
vector<uint16_t> ids;
|
||||
vector<int32_t> ids;
|
||||
std::copy(eParcel.accessControlProfileIds.begin(),
|
||||
eParcel.accessControlProfileIds.end(), std::back_inserter(ids));
|
||||
|
||||
halBinder_->beginAddEntry(ids, ensParcel.namespaceName, eParcel.name,
|
||||
eParcel.value.size(),
|
||||
[&](const Result& _result) { result = _result; });
|
||||
if (result.code != ResultCode::OK) {
|
||||
return halResultToGenericError(result);
|
||||
status = halBinder_->beginAddEntry(ids, ensParcel.namespaceName, eParcel.name,
|
||||
eParcel.value.size());
|
||||
if (!status.isOk()) {
|
||||
return halStatusToGenericError(status);
|
||||
}
|
||||
|
||||
vector<vector<uint8_t>> encryptedChunks;
|
||||
for (const auto& chunk : chunks) {
|
||||
halBinder_->addEntryValue(
|
||||
chunk, [&](const Result& _result, const hidl_vec<uint8_t>& encryptedContent) {
|
||||
result = _result;
|
||||
encryptedChunks.push_back(encryptedContent);
|
||||
});
|
||||
if (result.code != ResultCode::OK) {
|
||||
return halResultToGenericError(result);
|
||||
vector<uint8_t> encryptedChunk;
|
||||
status = halBinder_->addEntryValue(chunk, &encryptedChunk);
|
||||
if (!status.isOk()) {
|
||||
return halStatusToGenericError(status);
|
||||
}
|
||||
encryptedChunks.push_back(encryptedChunk);
|
||||
}
|
||||
EntryData eData;
|
||||
eData.size = eParcel.value.size();
|
||||
|
@ -175,17 +164,11 @@ WritableCredential::personalize(const vector<AccessControlProfileParcel>& access
|
|||
|
||||
vector<uint8_t> credentialData;
|
||||
vector<uint8_t> proofOfProvisioningSignature;
|
||||
halBinder_->finishAddingEntries([&](const Result& _result,
|
||||
const hidl_vec<uint8_t>& _credentialData,
|
||||
const hidl_vec<uint8_t>& _proofOfProvisioningSignature) {
|
||||
data.setCredentialData(_credentialData);
|
||||
result = _result;
|
||||
credentialData = _credentialData;
|
||||
proofOfProvisioningSignature = _proofOfProvisioningSignature;
|
||||
});
|
||||
if (result.code != ResultCode::OK) {
|
||||
return halResultToGenericError(result);
|
||||
status = halBinder_->finishAddingEntries(&credentialData, &proofOfProvisioningSignature);
|
||||
if (!status.isOk()) {
|
||||
return halStatusToGenericError(status);
|
||||
}
|
||||
data.setCredentialData(credentialData);
|
||||
|
||||
if (!data.saveToDisk()) {
|
||||
return Status::fromServiceSpecificError(ICredentialStore::ERROR_GENERIC,
|
||||
|
|
|
@ -22,15 +22,14 @@
|
|||
|
||||
#include <android/security/identity/BnWritableCredential.h>
|
||||
|
||||
#include <android/hardware/identity/1.0/IIdentityCredentialStore.h>
|
||||
#include <android/hardware/identity/1.0/types.h>
|
||||
#include <android/hardware/identity/IIdentityCredentialStore.h>
|
||||
|
||||
namespace android {
|
||||
namespace security {
|
||||
namespace identity {
|
||||
|
||||
using ::android::binder::Status;
|
||||
using ::android::hardware::identity::V1_0::IWritableIdentityCredential;
|
||||
using ::android::hardware::identity::IWritableIdentityCredential;
|
||||
using ::std::string;
|
||||
using ::std::vector;
|
||||
|
||||
|
|
Loading…
Reference in a new issue