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
diff --git a/identity/aidl/default/IdentityCredential.cpp b/identity/aidl/default/IdentityCredential.cpp
index 381eb84..4e9e0e6 100644
--- a/identity/aidl/default/IdentityCredential.cpp
+++ b/identity/aidl/default/IdentityCredential.cpp
@@ -164,6 +164,7 @@
     }
 
     *outChallenge = challenge;
+    authChallenge_ = challenge;
     return ndk::ScopedAStatus::ok();
 }
 
@@ -223,7 +224,8 @@
         }
 
         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 @@
     //
     // 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 @@
                     "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 @@
     }
 
     // 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"));