/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#define LOG_TAG "VtsIWritableIdentityCredentialTests"

#include <aidl/Gtest.h>
#include <aidl/Vintf.h>
#include <aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.h>
#include <aidl/android/hardware/security/keymint/MacedPublicKey.h>
#include <android-base/logging.h>
#include <android/hardware/identity/IIdentityCredentialStore.h>
#include <android/hardware/identity/support/IdentityCredentialSupport.h>
#include <binder/IServiceManager.h>
#include <binder/ProcessState.h>
#include <cppbor.h>
#include <cppbor_parse.h>
#include <gtest/gtest.h>
#include <future>
#include <map>

#include "Util.h"

namespace android::hardware::identity {

using std::endl;
using std::map;
using std::optional;
using std::string;
using std::vector;

using ::android::sp;
using ::android::String16;
using ::android::binder::Status;
using ::android::hardware::security::keymint::IRemotelyProvisionedComponent;
using ::android::hardware::security::keymint::MacedPublicKey;

class IdentityCredentialTests : public testing::TestWithParam<string> {
  public:
    virtual void SetUp() override {
        credentialStore_ = android::waitForDeclaredService<IIdentityCredentialStore>(
                String16(GetParam().c_str()));
        ASSERT_NE(credentialStore_, nullptr);
    }

    sp<IIdentityCredentialStore> credentialStore_;
};

TEST_P(IdentityCredentialTests, verifyAttestationWithEmptyChallenge) {
    Status result;

    HardwareInformation hwInfo;
    ASSERT_TRUE(credentialStore_->getHardwareInformation(&hwInfo).isOk());

    sp<IWritableIdentityCredential> writableCredential;
    ASSERT_TRUE(test_utils::setupWritableCredential(writableCredential, credentialStore_,
                                                    false /* testCredential */));

    vector<uint8_t> attestationChallenge;
    vector<Certificate> attestationCertificate;
    vector<uint8_t> attestationApplicationId = {};
    result = writableCredential->getAttestationCertificate(
            attestationApplicationId, attestationChallenge, &attestationCertificate);

    EXPECT_FALSE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage()
                                << endl;
    EXPECT_EQ(binder::Status::EX_SERVICE_SPECIFIC, result.exceptionCode());
    EXPECT_EQ(IIdentityCredentialStore::STATUS_INVALID_DATA, result.serviceSpecificErrorCode());
}

TEST_P(IdentityCredentialTests, verifyAttestationSuccessWithChallenge) {
    Status result;

    HardwareInformation hwInfo;
    ASSERT_TRUE(credentialStore_->getHardwareInformation(&hwInfo).isOk());

    sp<IWritableIdentityCredential> writableCredential;
    ASSERT_TRUE(test_utils::setupWritableCredential(writableCredential, credentialStore_,
                                                    false /* testCredential */));

    string challenge = "NotSoRandomChallenge1NotSoRandomChallenge1NotSoRandomChallenge1";
    vector<uint8_t> attestationChallenge(challenge.begin(), challenge.end());
    vector<Certificate> attestationCertificate;
    vector<uint8_t> attestationApplicationId = {1};

    result = writableCredential->getAttestationCertificate(
            attestationApplicationId, attestationChallenge, &attestationCertificate);

    EXPECT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage()
                               << endl;

    test_utils::validateAttestationCertificate(attestationCertificate, attestationChallenge,
                                               attestationApplicationId, false);
}

TEST_P(IdentityCredentialTests, verifyAttestationSuccessWithRemoteProvisioning) {
    HardwareInformation hwInfo;
    ASSERT_TRUE(credentialStore_->getHardwareInformation(&hwInfo).isOk());

    if (!hwInfo.isRemoteKeyProvisioningSupported) {
        GTEST_SKIP() << "Remote provisioning is not supported";
    }

    Status result;

    sp<IWritableIdentityCredential> writableCredential;
    ASSERT_TRUE(test_utils::setupWritableCredential(writableCredential, credentialStore_,
                                                    false /* testCredential */));

    sp<IRemotelyProvisionedComponent> rpc;
    result = credentialStore_->getRemotelyProvisionedComponent(&rpc);
    ASSERT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage();

    MacedPublicKey macedPublicKey;
    std::vector<uint8_t> attestationKey;
    // Start by RPC version 3, we don't support testMode=true. So just verify testMode=false here.
    result = rpc->generateEcdsaP256KeyPair(/*testMode=*/false, &macedPublicKey, &attestationKey);
    ASSERT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage();

    optional<vector<vector<uint8_t>>> remotelyProvisionedCertChain =
            test_utils::createFakeRemotelyProvisionedCertificateChain(macedPublicKey);
    ASSERT_TRUE(remotelyProvisionedCertChain);

    vector<uint8_t> concatenatedCerts;
    for (const vector<uint8_t>& cert : *remotelyProvisionedCertChain) {
        concatenatedCerts.insert(concatenatedCerts.end(), cert.begin(), cert.end());
    }
    result = writableCredential->setRemotelyProvisionedAttestationKey(attestationKey,
                                                                      concatenatedCerts);
    ASSERT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage();

    string challenge = "NotSoRandomChallenge1NotSoRandomChallenge1NotSoRandomChallenge1";
    vector<uint8_t> attestationChallenge(challenge.begin(), challenge.end());
    vector<Certificate> attestationCertificate;
    vector<uint8_t> attestationApplicationId = {1};

    result = writableCredential->getAttestationCertificate(
            attestationApplicationId, attestationChallenge, &attestationCertificate);

    ASSERT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage();

    test_utils::validateAttestationCertificate(attestationCertificate, attestationChallenge,
                                               attestationApplicationId, false);

    ASSERT_EQ(remotelyProvisionedCertChain->size() + 1, attestationCertificate.size());
    for (size_t i = 0; i < remotelyProvisionedCertChain->size(); ++i) {
        ASSERT_EQ(remotelyProvisionedCertChain->at(i),
                  attestationCertificate[i + 1].encodedCertificate)
                << "Certificate mismatch (cert index " << i + 1 << " out of "
                << attestationCertificate.size() << " total certs)";
    }
}

TEST_P(IdentityCredentialTests, verifyRemotelyProvisionedKeyMayOnlyBeSetOnce) {
    HardwareInformation hwInfo;
    ASSERT_TRUE(credentialStore_->getHardwareInformation(&hwInfo).isOk());

    if (!hwInfo.isRemoteKeyProvisioningSupported) {
        GTEST_SKIP() << "Remote provisioning is not supported";
    }

    sp<IRemotelyProvisionedComponent> rpc;
    Status result = credentialStore_->getRemotelyProvisionedComponent(&rpc);
    ASSERT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage();

    MacedPublicKey macedPublicKey;
    std::vector<uint8_t> attestationKey;
    // Start by RPC version 3, we don't support testMode=true. So just verify testMode=false here.
    result = rpc->generateEcdsaP256KeyPair(/*testMode=*/false, &macedPublicKey, &attestationKey);
    ASSERT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage();

    optional<vector<vector<uint8_t>>> remotelyProvisionedCertChain =
            test_utils::createFakeRemotelyProvisionedCertificateChain(macedPublicKey);
    ASSERT_TRUE(remotelyProvisionedCertChain);

    vector<uint8_t> concatenatedCerts;
    for (const vector<uint8_t>& cert : *remotelyProvisionedCertChain) {
        concatenatedCerts.insert(concatenatedCerts.end(), cert.begin(), cert.end());
    }

    sp<IWritableIdentityCredential> writableCredential;
    ASSERT_TRUE(test_utils::setupWritableCredential(writableCredential, credentialStore_,
                                                    /*testCredential=*/false));

    result = writableCredential->setRemotelyProvisionedAttestationKey(attestationKey,
                                                                      concatenatedCerts);
    ASSERT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage();

    // Now try again, and verify that the implementation rejects it.
    result = writableCredential->setRemotelyProvisionedAttestationKey(attestationKey,
                                                                      concatenatedCerts);
    EXPECT_FALSE(result.isOk());
}

TEST_P(IdentityCredentialTests, verifyAttestationDoubleCallFails) {
    Status result;

    sp<IWritableIdentityCredential> writableCredential;
    ASSERT_TRUE(test_utils::setupWritableCredential(writableCredential, credentialStore_,
                                                    false /* testCredential */));

    string challenge = "NotSoRandomChallenge1";
    test_utils::AttestationData attData(writableCredential, challenge,
                                        {1} /* atteestationApplicationId */);
    test_utils::validateAttestationCertificate(attData.attestationCertificate,
                                               attData.attestationChallenge,
                                               attData.attestationApplicationId, false);

    string challenge2 = "NotSoRandomChallenge2";
    test_utils::AttestationData attData2(writableCredential, challenge2,
                                         {} /* atteestationApplicationId */);
    EXPECT_FALSE(attData2.result.isOk()) << attData2.result.exceptionCode() << "; "
                                         << attData2.result.exceptionMessage() << endl;
    EXPECT_EQ(binder::Status::EX_SERVICE_SPECIFIC, attData2.result.exceptionCode());
    EXPECT_EQ(IIdentityCredentialStore::STATUS_FAILED, attData2.result.serviceSpecificErrorCode());
}

TEST_P(IdentityCredentialTests, verifyStartPersonalization) {
    Status result;
    sp<IWritableIdentityCredential> writableCredential;
    ASSERT_TRUE(test_utils::setupWritableCredential(writableCredential, credentialStore_,
                                                    false /* testCredential */));

    // First call should go through
    const vector<int32_t> entryCounts = {2, 4};
    writableCredential->setExpectedProofOfProvisioningSize(123456);
    result = writableCredential->startPersonalization(5, entryCounts);
    ASSERT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage()
                               << endl;

    // Call personalization again to check if repeat call is allowed.
    result = writableCredential->startPersonalization(7, entryCounts);

    // Second call to startPersonalization should have failed.
    EXPECT_FALSE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage()
                                << endl;
    EXPECT_EQ(binder::Status::EX_SERVICE_SPECIFIC, result.exceptionCode());
    EXPECT_EQ(IIdentityCredentialStore::STATUS_FAILED, result.serviceSpecificErrorCode());
}

TEST_P(IdentityCredentialTests, verifyStartPersonalizationMin) {
    Status result;
    sp<IWritableIdentityCredential> writableCredential;
    ASSERT_TRUE(test_utils::setupWritableCredential(writableCredential, credentialStore_,
                                                    false /* testCredential */));

    // Verify minimal number of profile count and entry count
    const vector<int32_t> entryCounts = {1, 1};
    writableCredential->setExpectedProofOfProvisioningSize(123456);
    result = writableCredential->startPersonalization(1, entryCounts);
    EXPECT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage()
                               << endl;
}

TEST_P(IdentityCredentialTests, verifyStartPersonalizationOne) {
    Status result;
    sp<IWritableIdentityCredential> writableCredential;
    ASSERT_TRUE(test_utils::setupWritableCredential(writableCredential, credentialStore_,
                                                    false /* testCredential */));

    // Verify minimal number of profile count and entry count
    const vector<int32_t> entryCounts = {1};
    writableCredential->setExpectedProofOfProvisioningSize(123456);
    result = writableCredential->startPersonalization(1, entryCounts);
    EXPECT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage()
                               << endl;
}

TEST_P(IdentityCredentialTests, verifyStartPersonalizationLarge) {
    Status result;
    sp<IWritableIdentityCredential> writableCredential;
    ASSERT_TRUE(test_utils::setupWritableCredential(writableCredential, credentialStore_,
                                                    false /* testCredential */));

    // Verify set a large number of profile count and entry count is ok
    const vector<int32_t> entryCounts = {255};
    writableCredential->setExpectedProofOfProvisioningSize(123456);
    result = writableCredential->startPersonalization(25, entryCounts);
    EXPECT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage()
                               << endl;
}

TEST_P(IdentityCredentialTests, verifyProfileNumberMismatchShouldFail) {
    Status result;
    sp<IWritableIdentityCredential> writableCredential;
    ASSERT_TRUE(test_utils::setupWritableCredential(writableCredential, credentialStore_,
                                                    false /* testCredential */));

    // Enter mismatched entry and profile numbers
    const vector<int32_t> entryCounts = {5, 6};
    writableCredential->setExpectedProofOfProvisioningSize(123456);
    result = writableCredential->startPersonalization(5, entryCounts);
    ASSERT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage()
                               << endl;

    optional<vector<uint8_t>> readerCertificate = test_utils::generateReaderCertificate("12345");
    ASSERT_TRUE(readerCertificate);

    const vector<test_utils::TestProfile> testProfiles = {// Profile 0 (reader authentication)
                                                          {1, readerCertificate.value(), false, 0},
                                                          {2, readerCertificate.value(), true, 1},
                                                          // Profile 4 (no authentication)
                                                          {4, {}, false, 0}};

    optional<vector<SecureAccessControlProfile>> secureProfiles =
            test_utils::addAccessControlProfiles(writableCredential, testProfiles);
    ASSERT_TRUE(secureProfiles);

    vector<uint8_t> credentialData;
    vector<uint8_t> proofOfProvisioningSignature;
    result =
            writableCredential->finishAddingEntries(&credentialData, &proofOfProvisioningSignature);

    // finishAddingEntries should fail because the number of addAccessControlProfile mismatched with
    // startPersonalization, and begintest_utils::addEntry was not called.
    EXPECT_FALSE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage()
                                << endl;
    EXPECT_EQ(binder::Status::EX_SERVICE_SPECIFIC, result.exceptionCode());
    EXPECT_EQ(IIdentityCredentialStore::STATUS_INVALID_DATA, result.serviceSpecificErrorCode());
}

TEST_P(IdentityCredentialTests, verifyDuplicateProfileId) {
    Status result;
    sp<IWritableIdentityCredential> writableCredential;
    ASSERT_TRUE(test_utils::setupWritableCredential(writableCredential, credentialStore_,
                                                    false /* testCredential */));

    const vector<int32_t> entryCounts = {3, 6};
    writableCredential->setExpectedProofOfProvisioningSize(123456);
    result = writableCredential->startPersonalization(3, entryCounts);
    ASSERT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage()
                               << endl;

    const vector<test_utils::TestProfile> testProfiles = {// first profile should go though
                                                          {1, {}, true, 2},
                                                          // same id, different
                                                          // authentication requirement
                                                          {1, {}, true, 1},
                                                          // same id, different certificate
                                                          {1, {}, false, 0}};

    bool expectOk = true;
    for (const auto& testProfile : testProfiles) {
        SecureAccessControlProfile profile;
        Certificate cert;
        cert.encodedCertificate = testProfile.readerCertificate;
        int64_t secureUserId = testProfile.userAuthenticationRequired ? 66 : 0;
        result = writableCredential->addAccessControlProfile(
                testProfile.id, cert, testProfile.userAuthenticationRequired,
                testProfile.timeoutMillis, secureUserId, &profile);

        if (expectOk) {
            expectOk = false;
            // for profile should be allowed though as there are no duplications
            // yet.
            ASSERT_TRUE(result.isOk())
                    << result.exceptionCode() << "; " << result.exceptionMessage()
                    << "test profile id = " << testProfile.id << endl;

            ASSERT_EQ(testProfile.id, profile.id);
            ASSERT_EQ(testProfile.readerCertificate, profile.readerCertificate.encodedCertificate);
            ASSERT_EQ(testProfile.userAuthenticationRequired, profile.userAuthenticationRequired);
            ASSERT_EQ(testProfile.timeoutMillis, profile.timeoutMillis);
            ASSERT_EQ(support::kAesGcmTagSize + support::kAesGcmIvSize, profile.mac.size());
        } else {
            // should not allow duplicate id profiles.
            ASSERT_FALSE(result.isOk())
                    << result.exceptionCode() << "; " << result.exceptionMessage()
                    << ". Test profile id = " << testProfile.id
                    << ", timeout=" << testProfile.timeoutMillis << endl;
            ASSERT_EQ(binder::Status::EX_SERVICE_SPECIFIC, result.exceptionCode());
            ASSERT_EQ(IIdentityCredentialStore::STATUS_INVALID_DATA,
                      result.serviceSpecificErrorCode());
        }
    }
}

TEST_P(IdentityCredentialTests, verifyOneProfileAndEntryPass) {
    Status result;

    HardwareInformation hwInfo;
    ASSERT_TRUE(credentialStore_->getHardwareInformation(&hwInfo).isOk());

    sp<IWritableIdentityCredential> writableCredential;
    ASSERT_TRUE(test_utils::setupWritableCredential(writableCredential, credentialStore_,
                                                    false /* testCredential */));

    string challenge = "NotSoRandomChallenge1";
    test_utils::AttestationData attData(writableCredential, challenge,
                                        {} /* atteestationApplicationId */);
    EXPECT_TRUE(attData.result.isOk())
            << attData.result.exceptionCode() << "; " << attData.result.exceptionMessage() << endl;

    optional<vector<uint8_t>> readerCertificate1 = test_utils::generateReaderCertificate("123456");
    ASSERT_TRUE(readerCertificate1);

    const vector<int32_t> entryCounts = {1u};
    size_t expectedPoPSize = 185 + readerCertificate1.value().size();
    // OK to fail, not available in v1 HAL
    writableCredential->setExpectedProofOfProvisioningSize(expectedPoPSize);
    result = writableCredential->startPersonalization(1, entryCounts);
    ASSERT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage()
                               << endl;

    const vector<test_utils::TestProfile> testProfiles = {{1, readerCertificate1.value(), true, 1}};

    optional<vector<SecureAccessControlProfile>> secureProfiles =
            test_utils::addAccessControlProfiles(writableCredential, testProfiles);
    ASSERT_TRUE(secureProfiles);

    const vector<test_utils::TestEntryData> testEntries1 = {
            {"Name Space", "Last name", string("Turing"), vector<int32_t>{1}},
    };

    map<const test_utils::TestEntryData*, vector<vector<uint8_t>>> encryptedBlobs;
    for (const auto& entry : testEntries1) {
        ASSERT_TRUE(test_utils::addEntry(writableCredential, entry, hwInfo.dataChunkSize,
                                         encryptedBlobs, true));
    }

    vector<uint8_t> credentialData;
    vector<uint8_t> proofOfProvisioningSignature;
    result =
            writableCredential->finishAddingEntries(&credentialData, &proofOfProvisioningSignature);

    EXPECT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage()
                               << endl;

    optional<vector<uint8_t>> proofOfProvisioning =
            support::coseSignGetPayload(proofOfProvisioningSignature);
    ASSERT_TRUE(proofOfProvisioning);
    string cborPretty = cppbor::prettyPrint(proofOfProvisioning.value(), 32, {"readerCertificate"});
    EXPECT_EQ(
            "[\n"
            "  'ProofOfProvisioning',\n"
            "  'org.iso.18013-5.2019.mdl',\n"
            "  [\n"
            "    {\n"
            "      'id' : 1,\n"
            "      'readerCertificate' : <not printed>,\n"
            "      'userAuthenticationRequired' : true,\n"
            "      'timeoutMillis' : 1,\n"
            "    },\n"
            "  ],\n"
            "  {\n"
            "    'Name Space' : [\n"
            "      {\n"
            "        'name' : 'Last name',\n"
            "        'value' : 'Turing',\n"
            "        'accessControlProfiles' : [1, ],\n"
            "      },\n"
            "    ],\n"
            "  },\n"
            "  false,\n"
            "]",
            cborPretty);

    optional<vector<uint8_t>> credentialPubKey = support::certificateChainGetTopMostKey(
            attData.attestationCertificate[0].encodedCertificate);
    ASSERT_TRUE(credentialPubKey);
    EXPECT_TRUE(support::coseCheckEcDsaSignature(proofOfProvisioningSignature,
                                                 {},  // Additional data
                                                 credentialPubKey.value()));
}

TEST_P(IdentityCredentialTests, verifyManyProfilesAndEntriesPass) {
    Status result;

    HardwareInformation hwInfo;
    ASSERT_TRUE(credentialStore_->getHardwareInformation(&hwInfo).isOk());

    sp<IWritableIdentityCredential> writableCredential;
    ASSERT_TRUE(test_utils::setupWritableCredential(writableCredential, credentialStore_,
                                                    false /* testCredential */));

    string challenge = "NotSoRandomChallenge";
    test_utils::AttestationData attData(writableCredential, challenge,
                                        {} /* atteestationApplicationId */);
    EXPECT_TRUE(attData.result.isOk())
            << attData.result.exceptionCode() << "; " << attData.result.exceptionMessage() << endl;

    optional<vector<uint8_t>> readerCertificate1 = test_utils::generateReaderCertificate("123456");
    ASSERT_TRUE(readerCertificate1);

    optional<vector<uint8_t>> readerCertificate2 = test_utils::generateReaderCertificate("1256");
    ASSERT_TRUE(readerCertificate2);

    const vector<test_utils::TestProfile> testProfiles = {
            {1, readerCertificate1.value(), true, 1},
            {2, readerCertificate2.value(), true, 2},
    };
    const vector<int32_t> entryCounts = {1u, 3u, 1u, 1u, 2u};
    size_t expectedPoPSize =
            525021 + readerCertificate1.value().size() + readerCertificate2.value().size();
    // OK to fail, not available in v1 HAL
    writableCredential->setExpectedProofOfProvisioningSize(expectedPoPSize);
    result = writableCredential->startPersonalization(testProfiles.size(), entryCounts);
    ASSERT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage()
                               << endl;

    optional<vector<SecureAccessControlProfile>> secureProfiles =
            test_utils::addAccessControlProfiles(writableCredential, testProfiles);
    ASSERT_TRUE(secureProfiles);

    vector<uint8_t> portraitImage1;
    test_utils::setImageData(portraitImage1);

    vector<uint8_t> portraitImage2;
    test_utils::setImageData(portraitImage2);

    const vector<test_utils::TestEntryData> testEntries1 = {
            {"Name Space 1", "Last name", string("Turing"), vector<int32_t>{1, 2}},
            {"Name Space2", "Home address", string("Maida Vale, London, England"),
             vector<int32_t>{1}},
            {"Name Space2", "Work address", string("Maida Vale2, London, England"),
             vector<int32_t>{2}},
            {"Name Space2", "Trailer address", string("Maida, London, England"),
             vector<int32_t>{1}},
            {"Image", "Portrait image", portraitImage1, vector<int32_t>{1}},
            {"Image2", "Work image", portraitImage2, vector<int32_t>{1, 2}},
            {"Name Space3", "xyzw", string("random stuff"), vector<int32_t>{1, 2}},
            {"Name Space3", "Something", string("Some string"), vector<int32_t>{2}},
    };

    map<const test_utils::TestEntryData*, vector<vector<uint8_t>>> encryptedBlobs;
    for (const auto& entry : testEntries1) {
        EXPECT_TRUE(test_utils::addEntry(writableCredential, entry, hwInfo.dataChunkSize,
                                         encryptedBlobs, true));
    }

    vector<uint8_t> credentialData;
    vector<uint8_t> proofOfProvisioningSignature;
    result =
            writableCredential->finishAddingEntries(&credentialData, &proofOfProvisioningSignature);

    EXPECT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage()
                               << endl;

    optional<vector<uint8_t>> proofOfProvisioning =
            support::coseSignGetPayload(proofOfProvisioningSignature);
    ASSERT_TRUE(proofOfProvisioning);
    string cborPretty = cppbor::prettyPrint(proofOfProvisioning.value(),
                                            32,  //
                                            {"readerCertificate"});
    EXPECT_EQ(
            "[\n"
            "  'ProofOfProvisioning',\n"
            "  'org.iso.18013-5.2019.mdl',\n"
            "  [\n"
            "    {\n"
            "      'id' : 1,\n"
            "      'readerCertificate' : <not printed>,\n"
            "      'userAuthenticationRequired' : true,\n"
            "      'timeoutMillis' : 1,\n"
            "    },\n"
            "    {\n"
            "      'id' : 2,\n"
            "      'readerCertificate' : <not printed>,\n"
            "      'userAuthenticationRequired' : true,\n"
            "      'timeoutMillis' : 2,\n"
            "    },\n"
            "  ],\n"
            "  {\n"
            "    'Name Space 1' : [\n"
            "      {\n"
            "        'name' : 'Last name',\n"
            "        'value' : 'Turing',\n"
            "        'accessControlProfiles' : [1, 2, ],\n"
            "      },\n"
            "    ],\n"
            "    'Name Space2' : [\n"
            "      {\n"
            "        'name' : 'Home address',\n"
            "        'value' : 'Maida Vale, London, England',\n"
            "        'accessControlProfiles' : [1, ],\n"
            "      },\n"
            "      {\n"
            "        'name' : 'Work address',\n"
            "        'value' : 'Maida Vale2, London, England',\n"
            "        'accessControlProfiles' : [2, ],\n"
            "      },\n"
            "      {\n"
            "        'name' : 'Trailer address',\n"
            "        'value' : 'Maida, London, England',\n"
            "        'accessControlProfiles' : [1, ],\n"
            "      },\n"
            "    ],\n"
            "    'Image' : [\n"
            "      {\n"
            "        'name' : 'Portrait image',\n"
            "        'value' : <bstr size=262134 sha1=941e372f654d86c32d88fae9e41b706afbfd02bb>,\n"
            "        'accessControlProfiles' : [1, ],\n"
            "      },\n"
            "    ],\n"
            "    'Image2' : [\n"
            "      {\n"
            "        'name' : 'Work image',\n"
            "        'value' : <bstr size=262134 sha1=941e372f654d86c32d88fae9e41b706afbfd02bb>,\n"
            "        'accessControlProfiles' : [1, 2, ],\n"
            "      },\n"
            "    ],\n"
            "    'Name Space3' : [\n"
            "      {\n"
            "        'name' : 'xyzw',\n"
            "        'value' : 'random stuff',\n"
            "        'accessControlProfiles' : [1, 2, ],\n"
            "      },\n"
            "      {\n"
            "        'name' : 'Something',\n"
            "        'value' : 'Some string',\n"
            "        'accessControlProfiles' : [2, ],\n"
            "      },\n"
            "    ],\n"
            "  },\n"
            "  false,\n"
            "]",
            cborPretty);

    optional<vector<uint8_t>> credentialPubKey = support::certificateChainGetTopMostKey(
            attData.attestationCertificate[0].encodedCertificate);
    ASSERT_TRUE(credentialPubKey);
    EXPECT_TRUE(support::coseCheckEcDsaSignature(proofOfProvisioningSignature,
                                                 {},  // Additional data
                                                 credentialPubKey.value()));
}

TEST_P(IdentityCredentialTests, verifyEmptyNameSpaceMixedWithNonEmptyWorks) {
    Status result;

    HardwareInformation hwInfo;
    ASSERT_TRUE(credentialStore_->getHardwareInformation(&hwInfo).isOk());

    sp<IWritableIdentityCredential> writableCredential;
    ASSERT_TRUE(test_utils::setupWritableCredential(writableCredential, credentialStore_,
                                                    false /* testCredential */));

    string challenge = "NotSoRandomChallenge";
    test_utils::AttestationData attData(writableCredential, challenge,
                                        {} /* atteestationApplicationId */);
    ASSERT_TRUE(attData.result.isOk())
            << attData.result.exceptionCode() << "; " << attData.result.exceptionMessage() << endl;

    optional<vector<uint8_t>> readerCertificate1 = test_utils::generateReaderCertificate("123456");
    ASSERT_TRUE(readerCertificate1);

    optional<vector<uint8_t>> readerCertificate2 =
            test_utils::generateReaderCertificate("123456987987987987987987");
    ASSERT_TRUE(readerCertificate2);

    const vector<int32_t> entryCounts = {2u, 2u};
    size_t expectedPoPSize =
            377 + readerCertificate1.value().size() + readerCertificate2.value().size();
    ;
    // OK to fail, not available in v1 HAL
    writableCredential->setExpectedProofOfProvisioningSize(expectedPoPSize);
    result = writableCredential->startPersonalization(3, entryCounts);
    ASSERT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage()
                               << endl;

    const vector<test_utils::TestProfile> testProfiles = {{0, readerCertificate1.value(), false, 0},
                                                          {1, readerCertificate2.value(), true, 1},
                                                          {2, {}, false, 0}};

    optional<vector<SecureAccessControlProfile>> secureProfiles =
            test_utils::addAccessControlProfiles(writableCredential, testProfiles);
    ASSERT_TRUE(secureProfiles);

    const vector<test_utils::TestEntryData> testEntries1 = {
            // test empty name space
            {"", "t name", string("Turing"), vector<int32_t>{2}},
            {"", "Birth", string("19120623"), vector<int32_t>{2}},
            {"Name Space", "Last name", string("Turing"), vector<int32_t>{0, 1}},
            {"Name Space", "Birth date", string("19120623"), vector<int32_t>{0, 1}},
    };

    map<const test_utils::TestEntryData*, vector<vector<uint8_t>>> encryptedBlobs;
    for (const auto& entry : testEntries1) {
        EXPECT_TRUE(test_utils::addEntry(writableCredential, entry, hwInfo.dataChunkSize,
                                         encryptedBlobs, true));
    }

    vector<uint8_t> credentialData;
    vector<uint8_t> proofOfProvisioningSignature;
    result =
            writableCredential->finishAddingEntries(&credentialData, &proofOfProvisioningSignature);

    EXPECT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage()
                               << endl;
}

TEST_P(IdentityCredentialTests, verifyInterleavingEntryNameSpaceOrderingFails) {
    Status result;

    HardwareInformation hwInfo;
    ASSERT_TRUE(credentialStore_->getHardwareInformation(&hwInfo).isOk());

    sp<IWritableIdentityCredential> writableCredential;
    ASSERT_TRUE(test_utils::setupWritableCredential(writableCredential, credentialStore_,
                                                    false /* testCredential */));

    string challenge = "NotSoRandomChallenge";
    test_utils::AttestationData attData(writableCredential, challenge,
                                        {} /* atteestationApplicationId */);
    ASSERT_TRUE(attData.result.isOk())
            << attData.result.exceptionCode() << "; " << attData.result.exceptionMessage() << endl;

    // Enter mismatched entry and profile numbers.
    // Technically the 2nd name space of "Name Space" occurs intermittently, 2
    // before "Image" and 2 after image, which is not correct.  All of same name
    // space should occur together.  Let's see if this fails.
    const vector<int32_t> entryCounts = {2u, 1u, 2u};
    writableCredential->setExpectedProofOfProvisioningSize(123456);
    result = writableCredential->startPersonalization(3, entryCounts);
    ASSERT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage()
                               << endl;

    optional<vector<uint8_t>> readerCertificate1 = test_utils::generateReaderCertificate("123456");
    ASSERT_TRUE(readerCertificate1);

    optional<vector<uint8_t>> readerCertificate2 =
            test_utils::generateReaderCertificate("123456987987987987987987");
    ASSERT_TRUE(readerCertificate2);

    const vector<test_utils::TestProfile> testProfiles = {{0, readerCertificate1.value(), false, 0},
                                                          {1, readerCertificate2.value(), true, 1},
                                                          {2, {}, false, 0}};

    optional<vector<SecureAccessControlProfile>> secureProfiles =
            test_utils::addAccessControlProfiles(writableCredential, testProfiles);
    ASSERT_TRUE(secureProfiles);

    const vector<test_utils::TestEntryData> testEntries1 = {
            // test empty name space
            {"Name Space", "Last name", string("Turing"), vector<int32_t>{0, 1}},
            {"Name Space", "Birth date", string("19120623"), vector<int32_t>{0, 1}},
    };

    map<const test_utils::TestEntryData*, vector<vector<uint8_t>>> encryptedBlobs;
    for (const auto& entry : testEntries1) {
        EXPECT_TRUE(test_utils::addEntry(writableCredential, entry, hwInfo.dataChunkSize,
                                         encryptedBlobs, true));
    }
    const test_utils::TestEntryData testEntry2 = {"Image", "Portrait image", string("asdfs"),
                                                  vector<int32_t>{0, 1}};

    EXPECT_TRUE(test_utils::addEntry(writableCredential, testEntry2, hwInfo.dataChunkSize,
                                     encryptedBlobs, true));

    // We expect this to fail because the namespace is out of order, all "Name Space"
    // should have been called together
    const vector<test_utils::TestEntryData> testEntries3 = {
            {"Name Space", "First name", string("Alan"), vector<int32_t>{0, 1}},
            {"Name Space", "Home address", string("Maida Vale, London, England"),
             vector<int32_t>{0}},
    };

    for (const auto& entry : testEntries3) {
        EXPECT_FALSE(test_utils::addEntry(writableCredential, entry, hwInfo.dataChunkSize,
                                          encryptedBlobs, false));
    }

    vector<uint8_t> credentialData;
    vector<uint8_t> proofOfProvisioningSignature;
    result =
            writableCredential->finishAddingEntries(&credentialData, &proofOfProvisioningSignature);

    // should fail because test_utils::addEntry should have failed earlier.
    EXPECT_FALSE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage()
                                << endl;
    EXPECT_EQ(binder::Status::EX_SERVICE_SPECIFIC, result.exceptionCode());
    EXPECT_EQ(IIdentityCredentialStore::STATUS_INVALID_DATA, result.serviceSpecificErrorCode());
}

TEST_P(IdentityCredentialTests, verifyAccessControlProfileIdOutOfRange) {
    sp<IWritableIdentityCredential> writableCredential;
    ASSERT_TRUE(test_utils::setupWritableCredential(writableCredential, credentialStore_,
                                                    false /* testCredential */));

    const vector<int32_t> entryCounts = {1};
    writableCredential->setExpectedProofOfProvisioningSize(123456);
    Status result = writableCredential->startPersonalization(1, entryCounts);
    ASSERT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage()
                               << endl;

    SecureAccessControlProfile profile;

    // This should fail because the id is >= 32
    result = writableCredential->addAccessControlProfile(32,     // id
                                                         {},     // readerCertificate
                                                         false,  // userAuthenticationRequired
                                                         0,      // timeoutMillis
                                                         42,     // secureUserId
                                                         &profile);
    ASSERT_FALSE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage();
    ASSERT_EQ(binder::Status::EX_SERVICE_SPECIFIC, result.exceptionCode());
    ASSERT_EQ(IIdentityCredentialStore::STATUS_INVALID_DATA, result.serviceSpecificErrorCode());

    // This should fail because the id is < 0
    result = writableCredential->addAccessControlProfile(-1,     // id
                                                         {},     // readerCertificate
                                                         false,  // userAuthenticationRequired
                                                         0,      // timeoutMillis
                                                         42,     // secureUserId
                                                         &profile);
    ASSERT_FALSE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage();
    ASSERT_EQ(binder::Status::EX_SERVICE_SPECIFIC, result.exceptionCode());
    ASSERT_EQ(IIdentityCredentialStore::STATUS_INVALID_DATA, result.serviceSpecificErrorCode());
}

GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(IdentityCredentialTests);
INSTANTIATE_TEST_SUITE_P(
        Identity, IdentityCredentialTests,
        testing::ValuesIn(android::getAidlHalInstanceNames(IIdentityCredentialStore::descriptor)),
        android::PrintInstanceNameToString);

}  // namespace android::hardware::identity
