• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "VtsIdentityTestUtils.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 = {3000};
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 =
342             support::cborPrettyPrint(proofOfProvisioning.value(), 32, {"readerCertificate"});
343     EXPECT_EQ(
344             "[\n"
345             "  'ProofOfProvisioning',\n"
346             "  'org.iso.18013-5.2019.mdl',\n"
347             "  [\n"
348             "    {\n"
349             "      'id' : 1,\n"
350             "      'readerCertificate' : <not printed>,\n"
351             "      'userAuthenticationRequired' : true,\n"
352             "      'timeoutMillis' : 1,\n"
353             "    },\n"
354             "  ],\n"
355             "  {\n"
356             "    'Name Space' : [\n"
357             "      {\n"
358             "        'name' : 'Last name',\n"
359             "        'value' : 'Turing',\n"
360             "        'accessControlProfiles' : [1, ],\n"
361             "      },\n"
362             "    ],\n"
363             "  },\n"
364             "  false,\n"
365             "]",
366             cborPretty);
367 
368     optional<vector<uint8_t>> credentialPubKey = support::certificateChainGetTopMostKey(
369             attData.attestationCertificate[0].encodedCertificate);
370     ASSERT_TRUE(credentialPubKey);
371     EXPECT_TRUE(support::coseCheckEcDsaSignature(proofOfProvisioningSignature,
372                                                  {},  // Additional data
373                                                  credentialPubKey.value()));
374 }
375 
TEST_P(IdentityCredentialTests,verifyManyProfilesAndEntriesPass)376 TEST_P(IdentityCredentialTests, verifyManyProfilesAndEntriesPass) {
377     Status result;
378 
379     HardwareInformation hwInfo;
380     ASSERT_TRUE(credentialStore_->getHardwareInformation(&hwInfo).isOk());
381 
382     sp<IWritableIdentityCredential> writableCredential;
383     ASSERT_TRUE(test_utils::setupWritableCredential(writableCredential, credentialStore_,
384                                                     false /* testCredential */));
385 
386     string challenge = "NotSoRandomChallenge";
387     test_utils::AttestationData attData(writableCredential, challenge,
388                                         {} /* atteestationApplicationId */);
389     EXPECT_TRUE(attData.result.isOk())
390             << attData.result.exceptionCode() << "; " << attData.result.exceptionMessage() << endl;
391 
392     optional<vector<uint8_t>> readerCertificate1 = test_utils::generateReaderCertificate("123456");
393     ASSERT_TRUE(readerCertificate1);
394 
395     optional<vector<uint8_t>> readerCertificate2 = test_utils::generateReaderCertificate("1256");
396     ASSERT_TRUE(readerCertificate2);
397 
398     const vector<test_utils::TestProfile> testProfiles = {
399             {1, readerCertificate1.value(), true, 1},
400             {2, readerCertificate2.value(), true, 2},
401     };
402     const vector<int32_t> entryCounts = {1u, 3u, 1u, 1u, 2u};
403     size_t expectedPoPSize =
404             525021 + readerCertificate1.value().size() + readerCertificate2.value().size();
405     // OK to fail, not available in v1 HAL
406     writableCredential->setExpectedProofOfProvisioningSize(expectedPoPSize);
407     result = writableCredential->startPersonalization(testProfiles.size(), entryCounts);
408     ASSERT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage()
409                                << endl;
410 
411     optional<vector<SecureAccessControlProfile>> secureProfiles =
412             test_utils::addAccessControlProfiles(writableCredential, testProfiles);
413     ASSERT_TRUE(secureProfiles);
414 
415     vector<uint8_t> portraitImage1;
416     test_utils::setImageData(portraitImage1);
417 
418     vector<uint8_t> portraitImage2;
419     test_utils::setImageData(portraitImage2);
420 
421     const vector<test_utils::TestEntryData> testEntries1 = {
422             {"Name Space 1", "Last name", string("Turing"), vector<int32_t>{1, 2}},
423             {"Name Space2", "Home address", string("Maida Vale, London, England"),
424              vector<int32_t>{1}},
425             {"Name Space2", "Work address", string("Maida Vale2, London, England"),
426              vector<int32_t>{2}},
427             {"Name Space2", "Trailer address", string("Maida, London, England"),
428              vector<int32_t>{1}},
429             {"Image", "Portrait image", portraitImage1, vector<int32_t>{1}},
430             {"Image2", "Work image", portraitImage2, vector<int32_t>{1, 2}},
431             {"Name Space3", "xyzw", string("random stuff"), vector<int32_t>{1, 2}},
432             {"Name Space3", "Something", string("Some string"), vector<int32_t>{2}},
433     };
434 
435     map<const test_utils::TestEntryData*, vector<vector<uint8_t>>> encryptedBlobs;
436     for (const auto& entry : testEntries1) {
437         EXPECT_TRUE(test_utils::addEntry(writableCredential, entry, hwInfo.dataChunkSize,
438                                          encryptedBlobs, true));
439     }
440 
441     vector<uint8_t> credentialData;
442     vector<uint8_t> proofOfProvisioningSignature;
443     result =
444             writableCredential->finishAddingEntries(&credentialData, &proofOfProvisioningSignature);
445 
446     EXPECT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage()
447                                << endl;
448 
449     optional<vector<uint8_t>> proofOfProvisioning =
450             support::coseSignGetPayload(proofOfProvisioningSignature);
451     ASSERT_TRUE(proofOfProvisioning);
452     string cborPretty = support::cborPrettyPrint(proofOfProvisioning.value(),
453                                                  32,  //
454                                                  {"readerCertificate"});
455     EXPECT_EQ(
456             "[\n"
457             "  'ProofOfProvisioning',\n"
458             "  'org.iso.18013-5.2019.mdl',\n"
459             "  [\n"
460             "    {\n"
461             "      'id' : 1,\n"
462             "      'readerCertificate' : <not printed>,\n"
463             "      'userAuthenticationRequired' : true,\n"
464             "      'timeoutMillis' : 1,\n"
465             "    },\n"
466             "    {\n"
467             "      'id' : 2,\n"
468             "      'readerCertificate' : <not printed>,\n"
469             "      'userAuthenticationRequired' : true,\n"
470             "      'timeoutMillis' : 2,\n"
471             "    },\n"
472             "  ],\n"
473             "  {\n"
474             "    'Name Space 1' : [\n"
475             "      {\n"
476             "        'name' : 'Last name',\n"
477             "        'value' : 'Turing',\n"
478             "        'accessControlProfiles' : [1, 2, ],\n"
479             "      },\n"
480             "    ],\n"
481             "    'Name Space2' : [\n"
482             "      {\n"
483             "        'name' : 'Home address',\n"
484             "        'value' : 'Maida Vale, London, England',\n"
485             "        'accessControlProfiles' : [1, ],\n"
486             "      },\n"
487             "      {\n"
488             "        'name' : 'Work address',\n"
489             "        'value' : 'Maida Vale2, London, England',\n"
490             "        'accessControlProfiles' : [2, ],\n"
491             "      },\n"
492             "      {\n"
493             "        'name' : 'Trailer address',\n"
494             "        'value' : 'Maida, London, England',\n"
495             "        'accessControlProfiles' : [1, ],\n"
496             "      },\n"
497             "    ],\n"
498             "    'Image' : [\n"
499             "      {\n"
500             "        'name' : 'Portrait image',\n"
501             "        'value' : <bstr size=262134 sha1=941e372f654d86c32d88fae9e41b706afbfd02bb>,\n"
502             "        'accessControlProfiles' : [1, ],\n"
503             "      },\n"
504             "    ],\n"
505             "    'Image2' : [\n"
506             "      {\n"
507             "        'name' : 'Work image',\n"
508             "        'value' : <bstr size=262134 sha1=941e372f654d86c32d88fae9e41b706afbfd02bb>,\n"
509             "        'accessControlProfiles' : [1, 2, ],\n"
510             "      },\n"
511             "    ],\n"
512             "    'Name Space3' : [\n"
513             "      {\n"
514             "        'name' : 'xyzw',\n"
515             "        'value' : 'random stuff',\n"
516             "        'accessControlProfiles' : [1, 2, ],\n"
517             "      },\n"
518             "      {\n"
519             "        'name' : 'Something',\n"
520             "        'value' : 'Some string',\n"
521             "        'accessControlProfiles' : [2, ],\n"
522             "      },\n"
523             "    ],\n"
524             "  },\n"
525             "  false,\n"
526             "]",
527             cborPretty);
528 
529     optional<vector<uint8_t>> credentialPubKey = support::certificateChainGetTopMostKey(
530             attData.attestationCertificate[0].encodedCertificate);
531     ASSERT_TRUE(credentialPubKey);
532     EXPECT_TRUE(support::coseCheckEcDsaSignature(proofOfProvisioningSignature,
533                                                  {},  // Additional data
534                                                  credentialPubKey.value()));
535 }
536 
TEST_P(IdentityCredentialTests,verifyEmptyNameSpaceMixedWithNonEmptyWorks)537 TEST_P(IdentityCredentialTests, verifyEmptyNameSpaceMixedWithNonEmptyWorks) {
538     Status result;
539 
540     HardwareInformation hwInfo;
541     ASSERT_TRUE(credentialStore_->getHardwareInformation(&hwInfo).isOk());
542 
543     sp<IWritableIdentityCredential> writableCredential;
544     ASSERT_TRUE(test_utils::setupWritableCredential(writableCredential, credentialStore_,
545                                                     false /* testCredential */));
546 
547     string challenge = "NotSoRandomChallenge";
548     test_utils::AttestationData attData(writableCredential, challenge,
549                                         {} /* atteestationApplicationId */);
550     ASSERT_TRUE(attData.result.isOk())
551             << attData.result.exceptionCode() << "; " << attData.result.exceptionMessage() << endl;
552 
553     optional<vector<uint8_t>> readerCertificate1 = test_utils::generateReaderCertificate("123456");
554     ASSERT_TRUE(readerCertificate1);
555 
556     optional<vector<uint8_t>> readerCertificate2 =
557             test_utils::generateReaderCertificate("123456987987987987987987");
558     ASSERT_TRUE(readerCertificate2);
559 
560     const vector<int32_t> entryCounts = {2u, 2u};
561     size_t expectedPoPSize =
562             377 + readerCertificate1.value().size() + readerCertificate2.value().size();
563     ;
564     // OK to fail, not available in v1 HAL
565     writableCredential->setExpectedProofOfProvisioningSize(expectedPoPSize);
566     result = writableCredential->startPersonalization(3, entryCounts);
567     ASSERT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage()
568                                << endl;
569 
570     const vector<test_utils::TestProfile> testProfiles = {{0, readerCertificate1.value(), false, 0},
571                                                           {1, readerCertificate2.value(), true, 1},
572                                                           {2, {}, false, 0}};
573 
574     optional<vector<SecureAccessControlProfile>> secureProfiles =
575             test_utils::addAccessControlProfiles(writableCredential, testProfiles);
576     ASSERT_TRUE(secureProfiles);
577 
578     const vector<test_utils::TestEntryData> testEntries1 = {
579             // test empty name space
580             {"", "t name", string("Turing"), vector<int32_t>{2}},
581             {"", "Birth", string("19120623"), vector<int32_t>{2}},
582             {"Name Space", "Last name", string("Turing"), vector<int32_t>{0, 1}},
583             {"Name Space", "Birth date", string("19120623"), vector<int32_t>{0, 1}},
584     };
585 
586     map<const test_utils::TestEntryData*, vector<vector<uint8_t>>> encryptedBlobs;
587     for (const auto& entry : testEntries1) {
588         EXPECT_TRUE(test_utils::addEntry(writableCredential, entry, hwInfo.dataChunkSize,
589                                          encryptedBlobs, true));
590     }
591 
592     vector<uint8_t> credentialData;
593     vector<uint8_t> proofOfProvisioningSignature;
594     result =
595             writableCredential->finishAddingEntries(&credentialData, &proofOfProvisioningSignature);
596 
597     EXPECT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage()
598                                << endl;
599 }
600 
TEST_P(IdentityCredentialTests,verifyInterleavingEntryNameSpaceOrderingFails)601 TEST_P(IdentityCredentialTests, verifyInterleavingEntryNameSpaceOrderingFails) {
602     Status result;
603 
604     HardwareInformation hwInfo;
605     ASSERT_TRUE(credentialStore_->getHardwareInformation(&hwInfo).isOk());
606 
607     sp<IWritableIdentityCredential> writableCredential;
608     ASSERT_TRUE(test_utils::setupWritableCredential(writableCredential, credentialStore_,
609                                                     false /* testCredential */));
610 
611     string challenge = "NotSoRandomChallenge";
612     test_utils::AttestationData attData(writableCredential, challenge,
613                                         {} /* atteestationApplicationId */);
614     ASSERT_TRUE(attData.result.isOk())
615             << attData.result.exceptionCode() << "; " << attData.result.exceptionMessage() << endl;
616 
617     // Enter mismatched entry and profile numbers.
618     // Technically the 2nd name space of "Name Space" occurs intermittently, 2
619     // before "Image" and 2 after image, which is not correct.  All of same name
620     // space should occur together.  Let's see if this fails.
621     const vector<int32_t> entryCounts = {2u, 1u, 2u};
622     writableCredential->setExpectedProofOfProvisioningSize(123456);
623     result = writableCredential->startPersonalization(3, entryCounts);
624     ASSERT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage()
625                                << endl;
626 
627     optional<vector<uint8_t>> readerCertificate1 = test_utils::generateReaderCertificate("123456");
628     ASSERT_TRUE(readerCertificate1);
629 
630     optional<vector<uint8_t>> readerCertificate2 =
631             test_utils::generateReaderCertificate("123456987987987987987987");
632     ASSERT_TRUE(readerCertificate2);
633 
634     const vector<test_utils::TestProfile> testProfiles = {{0, readerCertificate1.value(), false, 0},
635                                                           {1, readerCertificate2.value(), true, 1},
636                                                           {2, {}, false, 0}};
637 
638     optional<vector<SecureAccessControlProfile>> secureProfiles =
639             test_utils::addAccessControlProfiles(writableCredential, testProfiles);
640     ASSERT_TRUE(secureProfiles);
641 
642     const vector<test_utils::TestEntryData> testEntries1 = {
643             // test empty name space
644             {"Name Space", "Last name", string("Turing"), vector<int32_t>{0, 1}},
645             {"Name Space", "Birth date", string("19120623"), vector<int32_t>{0, 1}},
646     };
647 
648     map<const test_utils::TestEntryData*, vector<vector<uint8_t>>> encryptedBlobs;
649     for (const auto& entry : testEntries1) {
650         EXPECT_TRUE(test_utils::addEntry(writableCredential, entry, hwInfo.dataChunkSize,
651                                          encryptedBlobs, true));
652     }
653     const test_utils::TestEntryData testEntry2 = {"Image", "Portrait image", string("asdfs"),
654                                                   vector<int32_t>{0, 1}};
655 
656     EXPECT_TRUE(test_utils::addEntry(writableCredential, testEntry2, hwInfo.dataChunkSize,
657                                      encryptedBlobs, true));
658 
659     // We expect this to fail because the namespace is out of order, all "Name Space"
660     // should have been called together
661     const vector<test_utils::TestEntryData> testEntries3 = {
662             {"Name Space", "First name", string("Alan"), vector<int32_t>{0, 1}},
663             {"Name Space", "Home address", string("Maida Vale, London, England"),
664              vector<int32_t>{0}},
665     };
666 
667     for (const auto& entry : testEntries3) {
668         EXPECT_FALSE(test_utils::addEntry(writableCredential, entry, hwInfo.dataChunkSize,
669                                           encryptedBlobs, false));
670     }
671 
672     vector<uint8_t> credentialData;
673     vector<uint8_t> proofOfProvisioningSignature;
674     result =
675             writableCredential->finishAddingEntries(&credentialData, &proofOfProvisioningSignature);
676 
677     // should fail because test_utils::addEntry should have failed earlier.
678     EXPECT_FALSE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage()
679                                 << endl;
680     EXPECT_EQ(binder::Status::EX_SERVICE_SPECIFIC, result.exceptionCode());
681     EXPECT_EQ(IIdentityCredentialStore::STATUS_INVALID_DATA, result.serviceSpecificErrorCode());
682 }
683 
TEST_P(IdentityCredentialTests,verifyAccessControlProfileIdOutOfRange)684 TEST_P(IdentityCredentialTests, verifyAccessControlProfileIdOutOfRange) {
685     sp<IWritableIdentityCredential> writableCredential;
686     ASSERT_TRUE(test_utils::setupWritableCredential(writableCredential, credentialStore_,
687                                                     false /* testCredential */));
688 
689     const vector<int32_t> entryCounts = {1};
690     writableCredential->setExpectedProofOfProvisioningSize(123456);
691     Status result = writableCredential->startPersonalization(1, entryCounts);
692     ASSERT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage()
693                                << endl;
694 
695     SecureAccessControlProfile profile;
696 
697     // This should fail because the id is >= 32
698     result = writableCredential->addAccessControlProfile(32,     // id
699                                                          {},     // readerCertificate
700                                                          false,  // userAuthenticationRequired
701                                                          0,      // timeoutMillis
702                                                          42,     // secureUserId
703                                                          &profile);
704     ASSERT_FALSE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage();
705     ASSERT_EQ(binder::Status::EX_SERVICE_SPECIFIC, result.exceptionCode());
706     ASSERT_EQ(IIdentityCredentialStore::STATUS_INVALID_DATA, result.serviceSpecificErrorCode());
707 
708     // This should fail because the id is < 0
709     result = writableCredential->addAccessControlProfile(-1,     // id
710                                                          {},     // readerCertificate
711                                                          false,  // userAuthenticationRequired
712                                                          0,      // timeoutMillis
713                                                          42,     // secureUserId
714                                                          &profile);
715     ASSERT_FALSE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage();
716     ASSERT_EQ(binder::Status::EX_SERVICE_SPECIFIC, result.exceptionCode());
717     ASSERT_EQ(IIdentityCredentialStore::STATUS_INVALID_DATA, result.serviceSpecificErrorCode());
718 }
719 
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