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