diff options
author | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2020-02-19 23:18:16 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2020-02-19 23:18:16 +0000 |
commit | 6391867773044f284a6f53dae9b91129af00f337 (patch) | |
tree | 0363bcaae57f05c64095ff6460c5161492b1fe30 | |
parent | 8210743f1277a47ab88070e18b8b3c33ee5f554c (diff) | |
parent | 10938d3e263445c48ca5e48e05544603bcb96f79 (diff) | |
download | security-6391867773044f284a6f53dae9b91129af00f337.tar.gz |
Merge "Port credstore to IdentityCredential AIDL." am: c092adeb2b am: 4718a821b3 am: 10938d3e26
Change-Id: I3c8857252d86fdacdbe8ab0d762f5c1f3db797ff
-rw-r--r-- | identity/Android.bp | 4 | ||||
-rw-r--r-- | identity/Credential.cpp | 220 | ||||
-rw-r--r-- | identity/Credential.h | 11 | ||||
-rw-r--r-- | identity/CredentialData.cpp | 43 | ||||
-rw-r--r-- | identity/CredentialData.h | 14 | ||||
-rw-r--r-- | identity/CredentialStore.cpp | 75 | ||||
-rw-r--r-- | identity/CredentialStore.h | 10 | ||||
-rw-r--r-- | identity/CredentialStoreFactory.cpp | 20 | ||||
-rw-r--r-- | identity/CredentialStoreFactory.h | 2 | ||||
-rw-r--r-- | identity/Util.cpp | 14 | ||||
-rw-r--r-- | identity/Util.h | 10 | ||||
-rw-r--r-- | identity/WritableCredential.cpp | 99 | ||||
-rw-r--r-- | identity/WritableCredential.h | 5 |
13 files changed, 224 insertions, 303 deletions
diff --git a/identity/Android.bp b/identity/Android.bp index ad9bd72d..c0f16359 100644 --- a/identity/Android.bp +++ b/identity/Android.bp @@ -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", ] } diff --git a/identity/Credential.cpp b/identity/Credential.cpp index 6b033099..604d2621 100644 --- a/identity/Credential.cpp +++ b/identity/Credential.cpp @@ -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(); } diff --git a/identity/Credential.h b/identity/Credential.h index 356d75f1..a0d90634 100644 --- a/identity/Credential.h +++ b/identity/Credential.h @@ -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_; diff --git a/identity/CredentialData.cpp b/identity/CredentialData.cpp index 99dd04bb..b4e6641d 100644 --- a/identity/CredentialData.cpp +++ b/identity/CredentialData.cpp @@ -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; } diff --git a/identity/CredentialData.h b/identity/CredentialData.h index 39e41f89..79958281 100644 --- a/identity/CredentialData.h +++ b/identity/CredentialData.h @@ -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); diff --git a/identity/CredentialStore.cpp b/identity/CredentialStore.cpp index b13a7b08..e3a825ba 100644 --- a/identity/CredentialStore.cpp +++ b/identity/CredentialStore.cpp @@ -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()) { diff --git a/identity/CredentialStore.h b/identity/CredentialStore.h index 8d679a2e..24b2b4db 100644 --- a/identity/CredentialStore.h +++ b/identity/CredentialStore.h @@ -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 diff --git a/identity/CredentialStoreFactory.cpp b/identity/CredentialStoreFactory.cpp index 947adf37..5c3bf36c 100644 --- a/identity/CredentialStoreFactory.cpp +++ b/identity/CredentialStoreFactory.cpp @@ -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; } diff --git a/identity/CredentialStoreFactory.h b/identity/CredentialStoreFactory.h index 3aef6188..b944b264 100644 --- a/identity/CredentialStoreFactory.h +++ b/identity/CredentialStoreFactory.h @@ -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_; diff --git a/identity/Util.cpp b/identity/Util.cpp index 70e7105d..a962dc32 100644 --- a/identity/Util.cpp +++ b/identity/Util.cpp @@ -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) { diff --git a/identity/Util.h b/identity/Util.h index bb0e275e..12953f73 100644 --- a/identity/Util.h +++ b/identity/Util.h @@ -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|. // diff --git a/identity/WritableCredential.cpp b/identity/WritableCredential.cpp index 86c604d2..dec95a6a 100644 --- a/identity/WritableCredential.cpp +++ b/identity/WritableCredential.cpp @@ -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, diff --git a/identity/WritableCredential.h b/identity/WritableCredential.h index 47987cef..8b5e19e2 100644 --- a/identity/WritableCredential.h +++ b/identity/WritableCredential.h @@ -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; |