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