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