diff options
author | David Zeuthen <zeuthen@google.com> | 2020-06-03 13:24:52 -0400 |
---|---|---|
committer | David Zeuthen <zeuthen@google.com> | 2020-06-04 16:46:54 -0400 |
commit | ef7395127f2166dfd0a2bd5cfbb334f3695f2c96 (patch) | |
tree | fe189542607488b2207c5ceff3e8d1ff4ef0aea7 /identity/aidl/default/IdentityCredential.cpp | |
parent | a2a6a33ea94633d8ab75414e571ae0a71cc6a761 (diff) |
Update Identity Credential VTS tests.
These updates are based on input/experiences implementing this
HAL. There are no API changes.
- Specify that the validity for credentialKey certificate shall be
from current time and expire at the same time as the attestation
batch certificate.
- Require challenge passed to getAttestationCertificate() is
non-empty.
- Fix bug in VTS tests where the startPersonlization() result was not
checked.
- Remove verifyStartPersonalizationZero test since it cannot be
completed.
- Ensure secureUserId is non-zero if user authentication is needed.
- Specify format for signingKeyBlob in generateSigningKeyPair() same
way we do for credentialData in finishAddingEntries().
- Modify EndToEndTest to decrypt/unpack credentialData to obtain
credentialPrivKey and storageKey and do cross-checks on these.
- Modify EndToEndTest to decrypt/unpack signingKeyBlob to obtain
signingKeyPriv and check it matches the public key in the returned
certificate.
- Add new VTS tests for user and reader authentication.
- Relax unnecessary requirements about SessionTranscript structure -
just require it has X and Y of the ephemeral key created earlier.
- Allow calls in VTS tests to v2 HAL to fail - this should allow
these VTS tests to pass on a compliant v1 HAL.
Bug: 156911917
Bug: 158107945
Test: atest VtsHalIdentityTargetTest
Test: atest android.security.identity.cts
Change-Id: I11b79dbd57b1830609c70301fea9c99f9e5080cb
Diffstat (limited to 'identity/aidl/default/IdentityCredential.cpp')
-rw-r--r-- | identity/aidl/default/IdentityCredential.cpp | 35 |
1 files changed, 9 insertions, 26 deletions
diff --git a/identity/aidl/default/IdentityCredential.cpp b/identity/aidl/default/IdentityCredential.cpp index 381eb8426f..4e9e0e698c 100644 --- a/identity/aidl/default/IdentityCredential.cpp +++ b/identity/aidl/default/IdentityCredential.cpp @@ -164,6 +164,7 @@ ndk::ScopedAStatus IdentityCredential::createAuthChallenge(int64_t* outChallenge } *outChallenge = challenge; + authChallenge_ = challenge; return ndk::ScopedAStatus::ok(); } @@ -223,7 +224,8 @@ bool checkUserAuthentication(const SecureAccessControlProfile& profile, } if (authToken.challenge != int64_t(authChallenge)) { - LOG(ERROR) << "Challenge in authToken doesn't match the challenge we created"; + LOG(ERROR) << "Challenge in authToken (" << uint64_t(authToken.challenge) << ") " + << "doesn't match the challenge we created (" << authChallenge << ")"; return false; } return true; @@ -337,28 +339,6 @@ ndk::ScopedAStatus IdentityCredential::startRetrieval( // // We do this by just searching for the X and Y coordinates. if (sessionTranscript.size() > 0) { - const cppbor::Array* array = sessionTranscriptItem_->asArray(); - if (array == nullptr || array->size() != 2) { - return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( - IIdentityCredentialStore::STATUS_EPHEMERAL_PUBLIC_KEY_NOT_FOUND, - "SessionTranscript is not an array with two items")); - } - const cppbor::Semantic* taggedEncodedDE = (*array)[0]->asSemantic(); - if (taggedEncodedDE == nullptr || taggedEncodedDE->value() != 24) { - return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( - IIdentityCredentialStore::STATUS_EPHEMERAL_PUBLIC_KEY_NOT_FOUND, - "First item in SessionTranscript array is not a " - "semantic with value 24")); - } - const cppbor::Bstr* encodedDE = (taggedEncodedDE->child())->asBstr(); - if (encodedDE == nullptr) { - return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( - IIdentityCredentialStore::STATUS_EPHEMERAL_PUBLIC_KEY_NOT_FOUND, - "Child of semantic in first item in SessionTranscript " - "array is not a bstr")); - } - const vector<uint8_t>& bytesDE = encodedDE->value(); - auto [getXYSuccess, ePubX, ePubY] = support::ecPublicKeyGetXandY(ephemeralPublicKey_); if (!getXYSuccess) { return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( @@ -366,8 +346,10 @@ ndk::ScopedAStatus IdentityCredential::startRetrieval( "Error extracting X and Y from ePub")); } if (sessionTranscript.size() > 0 && - !(memmem(bytesDE.data(), bytesDE.size(), ePubX.data(), ePubX.size()) != nullptr && - memmem(bytesDE.data(), bytesDE.size(), ePubY.data(), ePubY.size()) != nullptr)) { + !(memmem(sessionTranscript.data(), sessionTranscript.size(), ePubX.data(), + ePubX.size()) != nullptr && + memmem(sessionTranscript.data(), sessionTranscript.size(), ePubY.data(), + ePubY.size()) != nullptr)) { return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( IIdentityCredentialStore::STATUS_EPHEMERAL_PUBLIC_KEY_NOT_FOUND, "Did not find ephemeral public key's X and Y coordinates in " @@ -474,9 +456,10 @@ ndk::ScopedAStatus IdentityCredential::startRetrieval( } // Validate all the access control profiles in the requestData. - bool haveAuthToken = (authToken.mac.size() > 0); + bool haveAuthToken = (authToken.timestamp.milliSeconds != int64_t(0)); for (const auto& profile : accessControlProfiles) { if (!secureAccessControlProfileCheckMac(profile, storageKey_)) { + LOG(ERROR) << "Error checking MAC for profile"; return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage( IIdentityCredentialStore::STATUS_INVALID_DATA, "Error checking MAC for profile")); |