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