xref: /aosp_15_r20/hardware/interfaces/identity/aidl/vts/VtsIWritableIdentityCredentialTests.cpp (revision 4d7e907c777eeecc4c5bd7cf640a754fac206ff7)
1 /*
2  * Copyright (C) 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define LOG_TAG "VtsIWritableIdentityCredentialTests"
18 
19 #include <aidl/Gtest.h>
20 #include <aidl/Vintf.h>
21 #include <aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.h>
22 #include <aidl/android/hardware/security/keymint/MacedPublicKey.h>
23 #include <android-base/logging.h>
24 #include <android/hardware/identity/IIdentityCredentialStore.h>
25 #include <android/hardware/identity/support/IdentityCredentialSupport.h>
26 #include <binder/IServiceManager.h>
27 #include <binder/ProcessState.h>
28 #include <cppbor.h>
29 #include <cppbor_parse.h>
30 #include <gtest/gtest.h>
31 #include <future>
32 #include <map>
33 
34 #include "Util.h"
35 
36 namespace android::hardware::identity {
37 
38 using std::endl;
39 using std::map;
40 using std::optional;
41 using std::string;
42 using std::vector;
43 
44 using ::android::sp;
45 using ::android::String16;
46 using ::android::binder::Status;
47 using ::android::hardware::security::keymint::IRemotelyProvisionedComponent;
48 using ::android::hardware::security::keymint::MacedPublicKey;
49 
50 class IdentityCredentialTests : public testing::TestWithParam<string> {
51   public:
SetUp()52     virtual void SetUp() override {
53         credentialStore_ = android::waitForDeclaredService<IIdentityCredentialStore>(
54                 String16(GetParam().c_str()));
55         ASSERT_NE(credentialStore_, nullptr);
56     }
57 
58     sp<IIdentityCredentialStore> credentialStore_;
59 };
60 
TEST_P(IdentityCredentialTests,verifyAttestationWithEmptyChallenge)61 TEST_P(IdentityCredentialTests, verifyAttestationWithEmptyChallenge) {
62     Status result;
63 
64     HardwareInformation hwInfo;
65     ASSERT_TRUE(credentialStore_->getHardwareInformation(&hwInfo).isOk());
66 
67     sp<IWritableIdentityCredential> writableCredential;
68     ASSERT_TRUE(test_utils::setupWritableCredential(writableCredential, credentialStore_,
69                                                     false /* testCredential */));
70 
71     vector<uint8_t> attestationChallenge;
72     vector<Certificate> attestationCertificate;
73     vector<uint8_t> attestationApplicationId = {};
74     result = writableCredential->getAttestationCertificate(
75             attestationApplicationId, attestationChallenge, &attestationCertificate);
76 
77     EXPECT_FALSE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage()
78                                 << endl;
79     EXPECT_EQ(binder::Status::EX_SERVICE_SPECIFIC, result.exceptionCode());
80     EXPECT_EQ(IIdentityCredentialStore::STATUS_INVALID_DATA, result.serviceSpecificErrorCode());
81 }
82 
TEST_P(IdentityCredentialTests,verifyAttestationSuccessWithChallenge)83 TEST_P(IdentityCredentialTests, verifyAttestationSuccessWithChallenge) {
84     Status result;
85 
86     HardwareInformation hwInfo;
87     ASSERT_TRUE(credentialStore_->getHardwareInformation(&hwInfo).isOk());
88 
89     sp<IWritableIdentityCredential> writableCredential;
90     ASSERT_TRUE(test_utils::setupWritableCredential(writableCredential, credentialStore_,
91                                                     false /* testCredential */));
92 
93     string challenge = "NotSoRandomChallenge1NotSoRandomChallenge1NotSoRandomChallenge1";
94     vector<uint8_t> attestationChallenge(challenge.begin(), challenge.end());
95     vector<Certificate> attestationCertificate;
96     vector<uint8_t> attestationApplicationId = {1};
97 
98     result = writableCredential->getAttestationCertificate(
99             attestationApplicationId, attestationChallenge, &attestationCertificate);
100 
101     EXPECT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage()
102                                << endl;
103 
104     test_utils::validateAttestationCertificate(attestationCertificate, attestationChallenge,
105                                                attestationApplicationId, false);
106 }
107 
TEST_P(IdentityCredentialTests,verifyAttestationSuccessWithRemoteProvisioning)108 TEST_P(IdentityCredentialTests, verifyAttestationSuccessWithRemoteProvisioning) {
109     HardwareInformation hwInfo;
110     ASSERT_TRUE(credentialStore_->getHardwareInformation(&hwInfo).isOk());
111 
112     if (!hwInfo.isRemoteKeyProvisioningSupported) {
113         GTEST_SKIP() << "Remote provisioning is not supported";
114     }
115 
116     Status result;
117 
118     sp<IWritableIdentityCredential> writableCredential;
119     ASSERT_TRUE(test_utils::setupWritableCredential(writableCredential, credentialStore_,
120                                                     false /* testCredential */));
121 
122     sp<IRemotelyProvisionedComponent> rpc;
123     result = credentialStore_->getRemotelyProvisionedComponent(&rpc);
124     ASSERT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage();
125 
126     MacedPublicKey macedPublicKey;
127     std::vector<uint8_t> attestationKey;
128     // Start by RPC version 3, we don't support testMode=true. So just verify testMode=false here.
129     result = rpc->generateEcdsaP256KeyPair(/*testMode=*/false, &macedPublicKey, &attestationKey);
130     ASSERT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage();
131 
132     optional<vector<vector<uint8_t>>> remotelyProvisionedCertChain =
133             test_utils::createFakeRemotelyProvisionedCertificateChain(macedPublicKey);
134     ASSERT_TRUE(remotelyProvisionedCertChain);
135 
136     vector<uint8_t> concatenatedCerts;
137     for (const vector<uint8_t>& cert : *remotelyProvisionedCertChain) {
138         concatenatedCerts.insert(concatenatedCerts.end(), cert.begin(), cert.end());
139     }
140     result = writableCredential->setRemotelyProvisionedAttestationKey(attestationKey,
141                                                                       concatenatedCerts);
142     ASSERT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage();
143 
144     string challenge = "NotSoRandomChallenge1NotSoRandomChallenge1NotSoRandomChallenge1";
145     vector<uint8_t> attestationChallenge(challenge.begin(), challenge.end());
146     vector<Certificate> attestationCertificate;
147     vector<uint8_t> attestationApplicationId = {1};
148 
149     result = writableCredential->getAttestationCertificate(
150             attestationApplicationId, attestationChallenge, &attestationCertificate);
151 
152     ASSERT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage();
153 
154     test_utils::validateAttestationCertificate(attestationCertificate, attestationChallenge,
155                                                attestationApplicationId, false);
156 
157     ASSERT_EQ(remotelyProvisionedCertChain->size() + 1, attestationCertificate.size());
158     for (size_t i = 0; i < remotelyProvisionedCertChain->size(); ++i) {
159         ASSERT_EQ(remotelyProvisionedCertChain->at(i),
160                   attestationCertificate[i + 1].encodedCertificate)
161                 << "Certificate mismatch (cert index " << i + 1 << " out of "
162                 << attestationCertificate.size() << " total certs)";
163     }
164 }
165 
TEST_P(IdentityCredentialTests,verifyRemotelyProvisionedKeyMayOnlyBeSetOnce)166 TEST_P(IdentityCredentialTests, verifyRemotelyProvisionedKeyMayOnlyBeSetOnce) {
167     HardwareInformation hwInfo;
168     ASSERT_TRUE(credentialStore_->getHardwareInformation(&hwInfo).isOk());
169 
170     if (!hwInfo.isRemoteKeyProvisioningSupported) {
171         GTEST_SKIP() << "Remote provisioning is not supported";
172     }
173 
174     sp<IRemotelyProvisionedComponent> rpc;
175     Status result = credentialStore_->getRemotelyProvisionedComponent(&rpc);
176     ASSERT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage();
177 
178     MacedPublicKey macedPublicKey;
179     std::vector<uint8_t> attestationKey;
180     // Start by RPC version 3, we don't support testMode=true. So just verify testMode=false here.
181     result = rpc->generateEcdsaP256KeyPair(/*testMode=*/false, &macedPublicKey, &attestationKey);
182     ASSERT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage();
183 
184     optional<vector<vector<uint8_t>>> remotelyProvisionedCertChain =
185             test_utils::createFakeRemotelyProvisionedCertificateChain(macedPublicKey);
186     ASSERT_TRUE(remotelyProvisionedCertChain);
187 
188     vector<uint8_t> concatenatedCerts;
189     for (const vector<uint8_t>& cert : *remotelyProvisionedCertChain) {
190         concatenatedCerts.insert(concatenatedCerts.end(), cert.begin(), cert.end());
191     }
192 
193     sp<IWritableIdentityCredential> writableCredential;
194     ASSERT_TRUE(test_utils::setupWritableCredential(writableCredential, credentialStore_,
195                                                     /*testCredential=*/false));
196 
197     result = writableCredential->setRemotelyProvisionedAttestationKey(attestationKey,
198                                                                       concatenatedCerts);
199     ASSERT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage();
200 
201     // Now try again, and verify that the implementation rejects it.
202     result = writableCredential->setRemotelyProvisionedAttestationKey(attestationKey,
203                                                                       concatenatedCerts);
204     EXPECT_FALSE(result.isOk());
205 }
206 
TEST_P(IdentityCredentialTests,verifyAttestationDoubleCallFails)207 TEST_P(IdentityCredentialTests, verifyAttestationDoubleCallFails) {
208     Status result;
209 
210     sp<IWritableIdentityCredential> writableCredential;
211     ASSERT_TRUE(test_utils::setupWritableCredential(writableCredential, credentialStore_,
212                                                     false /* testCredential */));
213 
214     string challenge = "NotSoRandomChallenge1";
215     test_utils::AttestationData attData(writableCredential, challenge,
216                                         {1} /* atteestationApplicationId */);
217     test_utils::validateAttestationCertificate(attData.attestationCertificate,
218                                                attData.attestationChallenge,
219                                                attData.attestationApplicationId, false);
220 
221     string challenge2 = "NotSoRandomChallenge2";
222     test_utils::AttestationData attData2(writableCredential, challenge2,
223                                          {} /* atteestationApplicationId */);
224     EXPECT_FALSE(attData2.result.isOk()) << attData2.result.exceptionCode() << "; "
225                                          << attData2.result.exceptionMessage() << endl;
226     EXPECT_EQ(binder::Status::EX_SERVICE_SPECIFIC, attData2.result.exceptionCode());
227     EXPECT_EQ(IIdentityCredentialStore::STATUS_FAILED, attData2.result.serviceSpecificErrorCode());
228 }
229 
TEST_P(IdentityCredentialTests,verifyStartPersonalization)230 TEST_P(IdentityCredentialTests, verifyStartPersonalization) {
231     Status result;
232     sp<IWritableIdentityCredential> writableCredential;
233     ASSERT_TRUE(test_utils::setupWritableCredential(writableCredential, credentialStore_,
234                                                     false /* testCredential */));
235 
236     // First call should go through
237     const vector<int32_t> entryCounts = {2, 4};
238     writableCredential->setExpectedProofOfProvisioningSize(123456);
239     result = writableCredential->startPersonalization(5, entryCounts);
240     ASSERT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage()
241                                << endl;
242 
243     // Call personalization again to check if repeat call is allowed.
244     result = writableCredential->startPersonalization(7, entryCounts);
245 
246     // Second call to startPersonalization should have failed.
247     EXPECT_FALSE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage()
248                                 << endl;
249     EXPECT_EQ(binder::Status::EX_SERVICE_SPECIFIC, result.exceptionCode());
250     EXPECT_EQ(IIdentityCredentialStore::STATUS_FAILED, result.serviceSpecificErrorCode());
251 }
252 
TEST_P(IdentityCredentialTests,verifyStartPersonalizationMin)253 TEST_P(IdentityCredentialTests, verifyStartPersonalizationMin) {
254     Status result;
255     sp<IWritableIdentityCredential> writableCredential;
256     ASSERT_TRUE(test_utils::setupWritableCredential(writableCredential, credentialStore_,
257                                                     false /* testCredential */));
258 
259     // Verify minimal number of profile count and entry count
260     const vector<int32_t> entryCounts = {1, 1};
261     writableCredential->setExpectedProofOfProvisioningSize(123456);
262     result = writableCredential->startPersonalization(1, entryCounts);
263     EXPECT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage()
264                                << endl;
265 }
266 
TEST_P(IdentityCredentialTests,verifyStartPersonalizationOne)267 TEST_P(IdentityCredentialTests, verifyStartPersonalizationOne) {
268     Status result;
269     sp<IWritableIdentityCredential> writableCredential;
270     ASSERT_TRUE(test_utils::setupWritableCredential(writableCredential, credentialStore_,
271                                                     false /* testCredential */));
272 
273     // Verify minimal number of profile count and entry count
274     const vector<int32_t> entryCounts = {1};
275     writableCredential->setExpectedProofOfProvisioningSize(123456);
276     result = writableCredential->startPersonalization(1, entryCounts);
277     EXPECT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage()
278                                << endl;
279 }
280 
TEST_P(IdentityCredentialTests,verifyStartPersonalizationLarge)281 TEST_P(IdentityCredentialTests, verifyStartPersonalizationLarge) {
282     Status result;
283     sp<IWritableIdentityCredential> writableCredential;
284     ASSERT_TRUE(test_utils::setupWritableCredential(writableCredential, credentialStore_,
285                                                     false /* testCredential */));
286 
287     // Verify set a large number of profile count and entry count is ok
288     const vector<int32_t> entryCounts = {255};
289     writableCredential->setExpectedProofOfProvisioningSize(123456);
290     result = writableCredential->startPersonalization(25, entryCounts);
291     EXPECT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage()
292                                << endl;
293 }
294 
TEST_P(IdentityCredentialTests,verifyProfileNumberMismatchShouldFail)295 TEST_P(IdentityCredentialTests, verifyProfileNumberMismatchShouldFail) {
296     Status result;
297     sp<IWritableIdentityCredential> writableCredential;
298     ASSERT_TRUE(test_utils::setupWritableCredential(writableCredential, credentialStore_,
299                                                     false /* testCredential */));
300 
301     // Enter mismatched entry and profile numbers
302     const vector<int32_t> entryCounts = {5, 6};
303     writableCredential->setExpectedProofOfProvisioningSize(123456);
304     result = writableCredential->startPersonalization(5, entryCounts);
305     ASSERT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage()
306                                << endl;
307 
308     optional<vector<uint8_t>> readerCertificate = test_utils::generateReaderCertificate("12345");
309     ASSERT_TRUE(readerCertificate);
310 
311     const vector<test_utils::TestProfile> testProfiles = {// Profile 0 (reader authentication)
312                                                           {1, readerCertificate.value(), false, 0},
313                                                           {2, readerCertificate.value(), true, 1},
314                                                           // Profile 4 (no authentication)
315                                                           {4, {}, false, 0}};
316 
317     optional<vector<SecureAccessControlProfile>> secureProfiles =
318             test_utils::addAccessControlProfiles(writableCredential, testProfiles);
319     ASSERT_TRUE(secureProfiles);
320 
321     vector<uint8_t> credentialData;
322     vector<uint8_t> proofOfProvisioningSignature;
323     result =
324             writableCredential->finishAddingEntries(&credentialData, &proofOfProvisioningSignature);
325 
326     // finishAddingEntries should fail because the number of addAccessControlProfile mismatched with
327     // startPersonalization, and begintest_utils::addEntry was not called.
328     EXPECT_FALSE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage()
329                                 << endl;
330     EXPECT_EQ(binder::Status::EX_SERVICE_SPECIFIC, result.exceptionCode());
331     EXPECT_EQ(IIdentityCredentialStore::STATUS_INVALID_DATA, result.serviceSpecificErrorCode());
332 }
333 
TEST_P(IdentityCredentialTests,verifyDuplicateProfileId)334 TEST_P(IdentityCredentialTests, verifyDuplicateProfileId) {
335     Status result;
336     sp<IWritableIdentityCredential> writableCredential;
337     ASSERT_TRUE(test_utils::setupWritableCredential(writableCredential, credentialStore_,
338                                                     false /* testCredential */));
339 
340     const vector<int32_t> entryCounts = {3, 6};
341     writableCredential->setExpectedProofOfProvisioningSize(123456);
342     result = writableCredential->startPersonalization(3, entryCounts);
343     ASSERT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage()
344                                << endl;
345 
346     const vector<test_utils::TestProfile> testProfiles = {// first profile should go though
347                                                           {1, {}, true, 2},
348                                                           // same id, different
349                                                           // authentication requirement
350                                                           {1, {}, true, 1},
351                                                           // same id, different certificate
352                                                           {1, {}, false, 0}};
353 
354     bool expectOk = true;
355     for (const auto& testProfile : testProfiles) {
356         SecureAccessControlProfile profile;
357         Certificate cert;
358         cert.encodedCertificate = testProfile.readerCertificate;
359         int64_t secureUserId = testProfile.userAuthenticationRequired ? 66 : 0;
360         result = writableCredential->addAccessControlProfile(
361                 testProfile.id, cert, testProfile.userAuthenticationRequired,
362                 testProfile.timeoutMillis, secureUserId, &profile);
363 
364         if (expectOk) {
365             expectOk = false;
366             // for profile should be allowed though as there are no duplications
367             // yet.
368             ASSERT_TRUE(result.isOk())
369                     << result.exceptionCode() << "; " << result.exceptionMessage()
370                     << "test profile id = " << testProfile.id << endl;
371 
372             ASSERT_EQ(testProfile.id, profile.id);
373             ASSERT_EQ(testProfile.readerCertificate, profile.readerCertificate.encodedCertificate);
374             ASSERT_EQ(testProfile.userAuthenticationRequired, profile.userAuthenticationRequired);
375             ASSERT_EQ(testProfile.timeoutMillis, profile.timeoutMillis);
376             ASSERT_EQ(support::kAesGcmTagSize + support::kAesGcmIvSize, profile.mac.size());
377         } else {
378             // should not allow duplicate id profiles.
379             ASSERT_FALSE(result.isOk())
380                     << result.exceptionCode() << "; " << result.exceptionMessage()
381                     << ". Test profile id = " << testProfile.id
382                     << ", timeout=" << testProfile.timeoutMillis << endl;
383             ASSERT_EQ(binder::Status::EX_SERVICE_SPECIFIC, result.exceptionCode());
384             ASSERT_EQ(IIdentityCredentialStore::STATUS_INVALID_DATA,
385                       result.serviceSpecificErrorCode());
386         }
387     }
388 }
389 
TEST_P(IdentityCredentialTests,verifyOneProfileAndEntryPass)390 TEST_P(IdentityCredentialTests, verifyOneProfileAndEntryPass) {
391     Status result;
392 
393     HardwareInformation hwInfo;
394     ASSERT_TRUE(credentialStore_->getHardwareInformation(&hwInfo).isOk());
395 
396     sp<IWritableIdentityCredential> writableCredential;
397     ASSERT_TRUE(test_utils::setupWritableCredential(writableCredential, credentialStore_,
398                                                     false /* testCredential */));
399 
400     string challenge = "NotSoRandomChallenge1";
401     test_utils::AttestationData attData(writableCredential, challenge,
402                                         {} /* atteestationApplicationId */);
403     EXPECT_TRUE(attData.result.isOk())
404             << attData.result.exceptionCode() << "; " << attData.result.exceptionMessage() << endl;
405 
406     optional<vector<uint8_t>> readerCertificate1 = test_utils::generateReaderCertificate("123456");
407     ASSERT_TRUE(readerCertificate1);
408 
409     const vector<int32_t> entryCounts = {1u};
410     size_t expectedPoPSize = 185 + readerCertificate1.value().size();
411     // OK to fail, not available in v1 HAL
412     writableCredential->setExpectedProofOfProvisioningSize(expectedPoPSize);
413     result = writableCredential->startPersonalization(1, entryCounts);
414     ASSERT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage()
415                                << endl;
416 
417     const vector<test_utils::TestProfile> testProfiles = {{1, readerCertificate1.value(), true, 1}};
418 
419     optional<vector<SecureAccessControlProfile>> secureProfiles =
420             test_utils::addAccessControlProfiles(writableCredential, testProfiles);
421     ASSERT_TRUE(secureProfiles);
422 
423     const vector<test_utils::TestEntryData> testEntries1 = {
424             {"Name Space", "Last name", string("Turing"), vector<int32_t>{1}},
425     };
426 
427     map<const test_utils::TestEntryData*, vector<vector<uint8_t>>> encryptedBlobs;
428     for (const auto& entry : testEntries1) {
429         ASSERT_TRUE(test_utils::addEntry(writableCredential, entry, hwInfo.dataChunkSize,
430                                          encryptedBlobs, true));
431     }
432 
433     vector<uint8_t> credentialData;
434     vector<uint8_t> proofOfProvisioningSignature;
435     result =
436             writableCredential->finishAddingEntries(&credentialData, &proofOfProvisioningSignature);
437 
438     EXPECT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage()
439                                << endl;
440 
441     optional<vector<uint8_t>> proofOfProvisioning =
442             support::coseSignGetPayload(proofOfProvisioningSignature);
443     ASSERT_TRUE(proofOfProvisioning);
444     string cborPretty = cppbor::prettyPrint(proofOfProvisioning.value(), 32, {"readerCertificate"});
445     EXPECT_EQ(
446             "[\n"
447             "  'ProofOfProvisioning',\n"
448             "  'org.iso.18013-5.2019.mdl',\n"
449             "  [\n"
450             "    {\n"
451             "      'id' : 1,\n"
452             "      'readerCertificate' : <not printed>,\n"
453             "      'userAuthenticationRequired' : true,\n"
454             "      'timeoutMillis' : 1,\n"
455             "    },\n"
456             "  ],\n"
457             "  {\n"
458             "    'Name Space' : [\n"
459             "      {\n"
460             "        'name' : 'Last name',\n"
461             "        'value' : 'Turing',\n"
462             "        'accessControlProfiles' : [1, ],\n"
463             "      },\n"
464             "    ],\n"
465             "  },\n"
466             "  false,\n"
467             "]",
468             cborPretty);
469 
470     optional<vector<uint8_t>> credentialPubKey = support::certificateChainGetTopMostKey(
471             attData.attestationCertificate[0].encodedCertificate);
472     ASSERT_TRUE(credentialPubKey);
473     EXPECT_TRUE(support::coseCheckEcDsaSignature(proofOfProvisioningSignature,
474                                                  {},  // Additional data
475                                                  credentialPubKey.value()));
476 }
477 
TEST_P(IdentityCredentialTests,verifyManyProfilesAndEntriesPass)478 TEST_P(IdentityCredentialTests, verifyManyProfilesAndEntriesPass) {
479     Status result;
480 
481     HardwareInformation hwInfo;
482     ASSERT_TRUE(credentialStore_->getHardwareInformation(&hwInfo).isOk());
483 
484     sp<IWritableIdentityCredential> writableCredential;
485     ASSERT_TRUE(test_utils::setupWritableCredential(writableCredential, credentialStore_,
486                                                     false /* testCredential */));
487 
488     string challenge = "NotSoRandomChallenge";
489     test_utils::AttestationData attData(writableCredential, challenge,
490                                         {} /* atteestationApplicationId */);
491     EXPECT_TRUE(attData.result.isOk())
492             << attData.result.exceptionCode() << "; " << attData.result.exceptionMessage() << endl;
493 
494     optional<vector<uint8_t>> readerCertificate1 = test_utils::generateReaderCertificate("123456");
495     ASSERT_TRUE(readerCertificate1);
496 
497     optional<vector<uint8_t>> readerCertificate2 = test_utils::generateReaderCertificate("1256");
498     ASSERT_TRUE(readerCertificate2);
499 
500     const vector<test_utils::TestProfile> testProfiles = {
501             {1, readerCertificate1.value(), true, 1},
502             {2, readerCertificate2.value(), true, 2},
503     };
504     const vector<int32_t> entryCounts = {1u, 3u, 1u, 1u, 2u};
505     size_t expectedPoPSize =
506             525021 + readerCertificate1.value().size() + readerCertificate2.value().size();
507     // OK to fail, not available in v1 HAL
508     writableCredential->setExpectedProofOfProvisioningSize(expectedPoPSize);
509     result = writableCredential->startPersonalization(testProfiles.size(), entryCounts);
510     ASSERT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage()
511                                << endl;
512 
513     optional<vector<SecureAccessControlProfile>> secureProfiles =
514             test_utils::addAccessControlProfiles(writableCredential, testProfiles);
515     ASSERT_TRUE(secureProfiles);
516 
517     vector<uint8_t> portraitImage1;
518     test_utils::setImageData(portraitImage1);
519 
520     vector<uint8_t> portraitImage2;
521     test_utils::setImageData(portraitImage2);
522 
523     const vector<test_utils::TestEntryData> testEntries1 = {
524             {"Name Space 1", "Last name", string("Turing"), vector<int32_t>{1, 2}},
525             {"Name Space2", "Home address", string("Maida Vale, London, England"),
526              vector<int32_t>{1}},
527             {"Name Space2", "Work address", string("Maida Vale2, London, England"),
528              vector<int32_t>{2}},
529             {"Name Space2", "Trailer address", string("Maida, London, England"),
530              vector<int32_t>{1}},
531             {"Image", "Portrait image", portraitImage1, vector<int32_t>{1}},
532             {"Image2", "Work image", portraitImage2, vector<int32_t>{1, 2}},
533             {"Name Space3", "xyzw", string("random stuff"), vector<int32_t>{1, 2}},
534             {"Name Space3", "Something", string("Some string"), vector<int32_t>{2}},
535     };
536 
537     map<const test_utils::TestEntryData*, vector<vector<uint8_t>>> encryptedBlobs;
538     for (const auto& entry : testEntries1) {
539         EXPECT_TRUE(test_utils::addEntry(writableCredential, entry, hwInfo.dataChunkSize,
540                                          encryptedBlobs, true));
541     }
542 
543     vector<uint8_t> credentialData;
544     vector<uint8_t> proofOfProvisioningSignature;
545     result =
546             writableCredential->finishAddingEntries(&credentialData, &proofOfProvisioningSignature);
547 
548     EXPECT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage()
549                                << endl;
550 
551     optional<vector<uint8_t>> proofOfProvisioning =
552             support::coseSignGetPayload(proofOfProvisioningSignature);
553     ASSERT_TRUE(proofOfProvisioning);
554     string cborPretty = cppbor::prettyPrint(proofOfProvisioning.value(),
555                                             32,  //
556                                             {"readerCertificate"});
557     EXPECT_EQ(
558             "[\n"
559             "  'ProofOfProvisioning',\n"
560             "  'org.iso.18013-5.2019.mdl',\n"
561             "  [\n"
562             "    {\n"
563             "      'id' : 1,\n"
564             "      'readerCertificate' : <not printed>,\n"
565             "      'userAuthenticationRequired' : true,\n"
566             "      'timeoutMillis' : 1,\n"
567             "    },\n"
568             "    {\n"
569             "      'id' : 2,\n"
570             "      'readerCertificate' : <not printed>,\n"
571             "      'userAuthenticationRequired' : true,\n"
572             "      'timeoutMillis' : 2,\n"
573             "    },\n"
574             "  ],\n"
575             "  {\n"
576             "    'Name Space 1' : [\n"
577             "      {\n"
578             "        'name' : 'Last name',\n"
579             "        'value' : 'Turing',\n"
580             "        'accessControlProfiles' : [1, 2, ],\n"
581             "      },\n"
582             "    ],\n"
583             "    'Name Space2' : [\n"
584             "      {\n"
585             "        'name' : 'Home address',\n"
586             "        'value' : 'Maida Vale, London, England',\n"
587             "        'accessControlProfiles' : [1, ],\n"
588             "      },\n"
589             "      {\n"
590             "        'name' : 'Work address',\n"
591             "        'value' : 'Maida Vale2, London, England',\n"
592             "        'accessControlProfiles' : [2, ],\n"
593             "      },\n"
594             "      {\n"
595             "        'name' : 'Trailer address',\n"
596             "        'value' : 'Maida, London, England',\n"
597             "        'accessControlProfiles' : [1, ],\n"
598             "      },\n"
599             "    ],\n"
600             "    'Image' : [\n"
601             "      {\n"
602             "        'name' : 'Portrait image',\n"
603             "        'value' : <bstr size=262134 sha1=941e372f654d86c32d88fae9e41b706afbfd02bb>,\n"
604             "        'accessControlProfiles' : [1, ],\n"
605             "      },\n"
606             "    ],\n"
607             "    'Image2' : [\n"
608             "      {\n"
609             "        'name' : 'Work image',\n"
610             "        'value' : <bstr size=262134 sha1=941e372f654d86c32d88fae9e41b706afbfd02bb>,\n"
611             "        'accessControlProfiles' : [1, 2, ],\n"
612             "      },\n"
613             "    ],\n"
614             "    'Name Space3' : [\n"
615             "      {\n"
616             "        'name' : 'xyzw',\n"
617             "        'value' : 'random stuff',\n"
618             "        'accessControlProfiles' : [1, 2, ],\n"
619             "      },\n"
620             "      {\n"
621             "        'name' : 'Something',\n"
622             "        'value' : 'Some string',\n"
623             "        'accessControlProfiles' : [2, ],\n"
624             "      },\n"
625             "    ],\n"
626             "  },\n"
627             "  false,\n"
628             "]",
629             cborPretty);
630 
631     optional<vector<uint8_t>> credentialPubKey = support::certificateChainGetTopMostKey(
632             attData.attestationCertificate[0].encodedCertificate);
633     ASSERT_TRUE(credentialPubKey);
634     EXPECT_TRUE(support::coseCheckEcDsaSignature(proofOfProvisioningSignature,
635                                                  {},  // Additional data
636                                                  credentialPubKey.value()));
637 }
638 
TEST_P(IdentityCredentialTests,verifyEmptyNameSpaceMixedWithNonEmptyWorks)639 TEST_P(IdentityCredentialTests, verifyEmptyNameSpaceMixedWithNonEmptyWorks) {
640     Status result;
641 
642     HardwareInformation hwInfo;
643     ASSERT_TRUE(credentialStore_->getHardwareInformation(&hwInfo).isOk());
644 
645     sp<IWritableIdentityCredential> writableCredential;
646     ASSERT_TRUE(test_utils::setupWritableCredential(writableCredential, credentialStore_,
647                                                     false /* testCredential */));
648 
649     string challenge = "NotSoRandomChallenge";
650     test_utils::AttestationData attData(writableCredential, challenge,
651                                         {} /* atteestationApplicationId */);
652     ASSERT_TRUE(attData.result.isOk())
653             << attData.result.exceptionCode() << "; " << attData.result.exceptionMessage() << endl;
654 
655     optional<vector<uint8_t>> readerCertificate1 = test_utils::generateReaderCertificate("123456");
656     ASSERT_TRUE(readerCertificate1);
657 
658     optional<vector<uint8_t>> readerCertificate2 =
659             test_utils::generateReaderCertificate("123456987987987987987987");
660     ASSERT_TRUE(readerCertificate2);
661 
662     const vector<int32_t> entryCounts = {2u, 2u};
663     size_t expectedPoPSize =
664             377 + readerCertificate1.value().size() + readerCertificate2.value().size();
665     ;
666     // OK to fail, not available in v1 HAL
667     writableCredential->setExpectedProofOfProvisioningSize(expectedPoPSize);
668     result = writableCredential->startPersonalization(3, entryCounts);
669     ASSERT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage()
670                                << endl;
671 
672     const vector<test_utils::TestProfile> testProfiles = {{0, readerCertificate1.value(), false, 0},
673                                                           {1, readerCertificate2.value(), true, 1},
674                                                           {2, {}, false, 0}};
675 
676     optional<vector<SecureAccessControlProfile>> secureProfiles =
677             test_utils::addAccessControlProfiles(writableCredential, testProfiles);
678     ASSERT_TRUE(secureProfiles);
679 
680     const vector<test_utils::TestEntryData> testEntries1 = {
681             // test empty name space
682             {"", "t name", string("Turing"), vector<int32_t>{2}},
683             {"", "Birth", string("19120623"), vector<int32_t>{2}},
684             {"Name Space", "Last name", string("Turing"), vector<int32_t>{0, 1}},
685             {"Name Space", "Birth date", string("19120623"), vector<int32_t>{0, 1}},
686     };
687 
688     map<const test_utils::TestEntryData*, vector<vector<uint8_t>>> encryptedBlobs;
689     for (const auto& entry : testEntries1) {
690         EXPECT_TRUE(test_utils::addEntry(writableCredential, entry, hwInfo.dataChunkSize,
691                                          encryptedBlobs, true));
692     }
693 
694     vector<uint8_t> credentialData;
695     vector<uint8_t> proofOfProvisioningSignature;
696     result =
697             writableCredential->finishAddingEntries(&credentialData, &proofOfProvisioningSignature);
698 
699     EXPECT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage()
700                                << endl;
701 }
702 
TEST_P(IdentityCredentialTests,verifyInterleavingEntryNameSpaceOrderingFails)703 TEST_P(IdentityCredentialTests, verifyInterleavingEntryNameSpaceOrderingFails) {
704     Status result;
705 
706     HardwareInformation hwInfo;
707     ASSERT_TRUE(credentialStore_->getHardwareInformation(&hwInfo).isOk());
708 
709     sp<IWritableIdentityCredential> writableCredential;
710     ASSERT_TRUE(test_utils::setupWritableCredential(writableCredential, credentialStore_,
711                                                     false /* testCredential */));
712 
713     string challenge = "NotSoRandomChallenge";
714     test_utils::AttestationData attData(writableCredential, challenge,
715                                         {} /* atteestationApplicationId */);
716     ASSERT_TRUE(attData.result.isOk())
717             << attData.result.exceptionCode() << "; " << attData.result.exceptionMessage() << endl;
718 
719     // Enter mismatched entry and profile numbers.
720     // Technically the 2nd name space of "Name Space" occurs intermittently, 2
721     // before "Image" and 2 after image, which is not correct.  All of same name
722     // space should occur together.  Let's see if this fails.
723     const vector<int32_t> entryCounts = {2u, 1u, 2u};
724     writableCredential->setExpectedProofOfProvisioningSize(123456);
725     result = writableCredential->startPersonalization(3, entryCounts);
726     ASSERT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage()
727                                << endl;
728 
729     optional<vector<uint8_t>> readerCertificate1 = test_utils::generateReaderCertificate("123456");
730     ASSERT_TRUE(readerCertificate1);
731 
732     optional<vector<uint8_t>> readerCertificate2 =
733             test_utils::generateReaderCertificate("123456987987987987987987");
734     ASSERT_TRUE(readerCertificate2);
735 
736     const vector<test_utils::TestProfile> testProfiles = {{0, readerCertificate1.value(), false, 0},
737                                                           {1, readerCertificate2.value(), true, 1},
738                                                           {2, {}, false, 0}};
739 
740     optional<vector<SecureAccessControlProfile>> secureProfiles =
741             test_utils::addAccessControlProfiles(writableCredential, testProfiles);
742     ASSERT_TRUE(secureProfiles);
743 
744     const vector<test_utils::TestEntryData> testEntries1 = {
745             // test empty name space
746             {"Name Space", "Last name", string("Turing"), vector<int32_t>{0, 1}},
747             {"Name Space", "Birth date", string("19120623"), vector<int32_t>{0, 1}},
748     };
749 
750     map<const test_utils::TestEntryData*, vector<vector<uint8_t>>> encryptedBlobs;
751     for (const auto& entry : testEntries1) {
752         EXPECT_TRUE(test_utils::addEntry(writableCredential, entry, hwInfo.dataChunkSize,
753                                          encryptedBlobs, true));
754     }
755     const test_utils::TestEntryData testEntry2 = {"Image", "Portrait image", string("asdfs"),
756                                                   vector<int32_t>{0, 1}};
757 
758     EXPECT_TRUE(test_utils::addEntry(writableCredential, testEntry2, hwInfo.dataChunkSize,
759                                      encryptedBlobs, true));
760 
761     // We expect this to fail because the namespace is out of order, all "Name Space"
762     // should have been called together
763     const vector<test_utils::TestEntryData> testEntries3 = {
764             {"Name Space", "First name", string("Alan"), vector<int32_t>{0, 1}},
765             {"Name Space", "Home address", string("Maida Vale, London, England"),
766              vector<int32_t>{0}},
767     };
768 
769     for (const auto& entry : testEntries3) {
770         EXPECT_FALSE(test_utils::addEntry(writableCredential, entry, hwInfo.dataChunkSize,
771                                           encryptedBlobs, false));
772     }
773 
774     vector<uint8_t> credentialData;
775     vector<uint8_t> proofOfProvisioningSignature;
776     result =
777             writableCredential->finishAddingEntries(&credentialData, &proofOfProvisioningSignature);
778 
779     // should fail because test_utils::addEntry should have failed earlier.
780     EXPECT_FALSE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage()
781                                 << endl;
782     EXPECT_EQ(binder::Status::EX_SERVICE_SPECIFIC, result.exceptionCode());
783     EXPECT_EQ(IIdentityCredentialStore::STATUS_INVALID_DATA, result.serviceSpecificErrorCode());
784 }
785 
TEST_P(IdentityCredentialTests,verifyAccessControlProfileIdOutOfRange)786 TEST_P(IdentityCredentialTests, verifyAccessControlProfileIdOutOfRange) {
787     sp<IWritableIdentityCredential> writableCredential;
788     ASSERT_TRUE(test_utils::setupWritableCredential(writableCredential, credentialStore_,
789                                                     false /* testCredential */));
790 
791     const vector<int32_t> entryCounts = {1};
792     writableCredential->setExpectedProofOfProvisioningSize(123456);
793     Status result = writableCredential->startPersonalization(1, entryCounts);
794     ASSERT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage()
795                                << endl;
796 
797     SecureAccessControlProfile profile;
798 
799     // This should fail because the id is >= 32
800     result = writableCredential->addAccessControlProfile(32,     // id
801                                                          {},     // readerCertificate
802                                                          false,  // userAuthenticationRequired
803                                                          0,      // timeoutMillis
804                                                          42,     // secureUserId
805                                                          &profile);
806     ASSERT_FALSE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage();
807     ASSERT_EQ(binder::Status::EX_SERVICE_SPECIFIC, result.exceptionCode());
808     ASSERT_EQ(IIdentityCredentialStore::STATUS_INVALID_DATA, result.serviceSpecificErrorCode());
809 
810     // This should fail because the id is < 0
811     result = writableCredential->addAccessControlProfile(-1,     // id
812                                                          {},     // readerCertificate
813                                                          false,  // userAuthenticationRequired
814                                                          0,      // timeoutMillis
815                                                          42,     // secureUserId
816                                                          &profile);
817     ASSERT_FALSE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage();
818     ASSERT_EQ(binder::Status::EX_SERVICE_SPECIFIC, result.exceptionCode());
819     ASSERT_EQ(IIdentityCredentialStore::STATUS_INVALID_DATA, result.serviceSpecificErrorCode());
820 }
821 
822 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(IdentityCredentialTests);
823 INSTANTIATE_TEST_SUITE_P(
824         Identity, IdentityCredentialTests,
825         testing::ValuesIn(android::getAidlHalInstanceNames(IIdentityCredentialStore::descriptor)),
826         android::PrintInstanceNameToString);
827 
828 }  // namespace android::hardware::identity
829