blob: b68fbb54f115b1d73ac7cdc1f8965da178d2d4fa [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
282 const vector<int32_t> entryCounts = {1u};
283 writableCredential->startPersonalization(1, entryCounts);
284 ASSERT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage()
285 << endl;
286
287 optional<vector<uint8_t>> readerCertificate1 = test_utils::GenerateReaderCertificate("123456");
288 ASSERT_TRUE(readerCertificate1);
289
290 const vector<test_utils::TestProfile> testProfiles = {{1, readerCertificate1.value(), true, 1}};
291
292 optional<vector<SecureAccessControlProfile>> secureProfiles =
293 test_utils::AddAccessControlProfiles(writableCredential, testProfiles);
294 ASSERT_TRUE(secureProfiles);
295
296 const vector<test_utils::TestEntryData> testEntries1 = {
297 {"Name Space", "Last name", string("Turing"), vector<int32_t>{0, 1}},
298 };
299
300 map<const test_utils::TestEntryData*, vector<vector<uint8_t>>> encryptedBlobs;
301 for (const auto& entry : testEntries1) {
302 ASSERT_TRUE(test_utils::AddEntry(writableCredential, entry, hwInfo.dataChunkSize,
303 encryptedBlobs, true));
304 }
305
306 vector<uint8_t> credentialData;
307 vector<uint8_t> proofOfProvisioningSignature;
308 result =
309 writableCredential->finishAddingEntries(&credentialData, &proofOfProvisioningSignature);
310
311 EXPECT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage()
312 << endl;
313
314 optional<vector<uint8_t>> proofOfProvisioning =
315 support::coseSignGetPayload(proofOfProvisioningSignature);
316 ASSERT_TRUE(proofOfProvisioning);
317 string cborPretty =
318 support::cborPrettyPrint(proofOfProvisioning.value(), 32, {"readerCertificate"});
319 EXPECT_EQ(
320 "[\n"
321 " 'ProofOfProvisioning',\n"
322 " 'org.iso.18013-5.2019.mdl',\n"
323 " [\n"
324 " {\n"
325 " 'id' : 1,\n"
326 " 'readerCertificate' : <not printed>,\n"
327 " 'userAuthenticationRequired' : true,\n"
328 " 'timeoutMillis' : 1,\n"
329 " },\n"
330 " ],\n"
331 " {\n"
332 " 'Name Space' : [\n"
333 " {\n"
334 " 'name' : 'Last name',\n"
335 " 'value' : 'Turing',\n"
336 " 'accessControlProfiles' : [0, 1, ],\n"
337 " },\n"
338 " ],\n"
339 " },\n"
340 " true,\n"
341 "]",
342 cborPretty);
343
344 optional<vector<uint8_t>> credentialPubKey = support::certificateChainGetTopMostKey(
345 attData.attestationCertificate[0].encodedCertificate);
346 ASSERT_TRUE(credentialPubKey);
347 EXPECT_TRUE(support::coseCheckEcDsaSignature(proofOfProvisioningSignature,
348 {}, // Additional data
349 credentialPubKey.value()));
350}
351
352TEST_P(IdentityCredentialTests, verifyManyProfilesAndEntriesPass) {
353 Status result;
354
355 HardwareInformation hwInfo;
356 ASSERT_TRUE(credentialStore_->getHardwareInformation(&hwInfo).isOk());
357
358 sp<IWritableIdentityCredential> writableCredential;
359 ASSERT_TRUE(test_utils::SetupWritableCredential(writableCredential, credentialStore_));
360
361 string challenge = "NotSoRandomChallenge";
362 test_utils::AttestationData attData(writableCredential, challenge, {});
363 EXPECT_TRUE(attData.result.isOk())
364 << attData.result.exceptionCode() << "; " << attData.result.exceptionMessage() << endl;
365
366 optional<vector<uint8_t>> readerCertificate1 = test_utils::GenerateReaderCertificate("123456");
367 ASSERT_TRUE(readerCertificate1);
368
369 optional<vector<uint8_t>> readerCertificate2 = test_utils::GenerateReaderCertificate("1256");
370 ASSERT_TRUE(readerCertificate2);
371
372 const vector<test_utils::TestProfile> testProfiles = {
373 {1, readerCertificate1.value(), true, 1},
374 {2, readerCertificate2.value(), true, 2},
375 };
376 const vector<int32_t> entryCounts = {1u, 3u, 1u, 1u, 2u};
377 writableCredential->startPersonalization(testProfiles.size(), entryCounts);
378 ASSERT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage()
379 << endl;
380
381 optional<vector<SecureAccessControlProfile>> secureProfiles =
382 test_utils::AddAccessControlProfiles(writableCredential, testProfiles);
383 ASSERT_TRUE(secureProfiles);
384
385 vector<uint8_t> portraitImage1;
386 test_utils::SetImageData(portraitImage1);
387
388 vector<uint8_t> portraitImage2;
389 test_utils::SetImageData(portraitImage2);
390
391 const vector<test_utils::TestEntryData> testEntries1 = {
392 {"Name Space 1", "Last name", string("Turing"), vector<int32_t>{1, 2}},
393 {"Name Space2", "Home address", string("Maida Vale, London, England"),
394 vector<int32_t>{1}},
395 {"Name Space2", "Work address", string("Maida Vale2, London, England"),
396 vector<int32_t>{2}},
397 {"Name Space2", "Trailer address", string("Maida, London, England"),
398 vector<int32_t>{1}},
399 {"Image", "Portrait image", portraitImage1, vector<int32_t>{1}},
400 {"Image2", "Work image", portraitImage2, vector<int32_t>{1, 2}},
401 {"Name Space3", "xyzw", string("random stuff"), vector<int32_t>{1, 2}},
402 {"Name Space3", "Something", string("Some string"), vector<int32_t>{2}},
403 };
404
405 map<const test_utils::TestEntryData*, vector<vector<uint8_t>>> encryptedBlobs;
406 for (const auto& entry : testEntries1) {
407 EXPECT_TRUE(test_utils::AddEntry(writableCredential, entry, hwInfo.dataChunkSize,
408 encryptedBlobs, true));
409 }
410
411 vector<uint8_t> credentialData;
412 vector<uint8_t> proofOfProvisioningSignature;
413 result =
414 writableCredential->finishAddingEntries(&credentialData, &proofOfProvisioningSignature);
415
416 EXPECT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage()
417 << endl;
418
419 optional<vector<uint8_t>> proofOfProvisioning =
420 support::coseSignGetPayload(proofOfProvisioningSignature);
421 ASSERT_TRUE(proofOfProvisioning);
422 string cborPretty = support::cborPrettyPrint(proofOfProvisioning.value(),
423 32, //
424 {"readerCertificate"});
425 EXPECT_EQ(
426 "[\n"
427 " 'ProofOfProvisioning',\n"
428 " 'org.iso.18013-5.2019.mdl',\n"
429 " [\n"
430 " {\n"
431 " 'id' : 1,\n"
432 " 'readerCertificate' : <not printed>,\n"
433 " 'userAuthenticationRequired' : true,\n"
434 " 'timeoutMillis' : 1,\n"
435 " },\n"
436 " {\n"
437 " 'id' : 2,\n"
438 " 'readerCertificate' : <not printed>,\n"
439 " 'userAuthenticationRequired' : true,\n"
440 " 'timeoutMillis' : 2,\n"
441 " },\n"
442 " ],\n"
443 " {\n"
444 " 'Name Space 1' : [\n"
445 " {\n"
446 " 'name' : 'Last name',\n"
447 " 'value' : 'Turing',\n"
448 " 'accessControlProfiles' : [1, 2, ],\n"
449 " },\n"
450 " ],\n"
451 " 'Name Space2' : [\n"
452 " {\n"
453 " 'name' : 'Home address',\n"
454 " 'value' : 'Maida Vale, London, England',\n"
455 " 'accessControlProfiles' : [1, ],\n"
456 " },\n"
457 " {\n"
458 " 'name' : 'Work address',\n"
459 " 'value' : 'Maida Vale2, London, England',\n"
460 " 'accessControlProfiles' : [2, ],\n"
461 " },\n"
462 " {\n"
463 " 'name' : 'Trailer address',\n"
464 " 'value' : 'Maida, London, England',\n"
465 " 'accessControlProfiles' : [1, ],\n"
466 " },\n"
467 " ],\n"
468 " 'Image' : [\n"
469 " {\n"
470 " 'name' : 'Portrait image',\n"
471 " 'value' : <bstr size=262134 sha1=941e372f654d86c32d88fae9e41b706afbfd02bb>,\n"
472 " 'accessControlProfiles' : [1, ],\n"
473 " },\n"
474 " ],\n"
475 " 'Image2' : [\n"
476 " {\n"
477 " 'name' : 'Work image',\n"
478 " 'value' : <bstr size=262134 sha1=941e372f654d86c32d88fae9e41b706afbfd02bb>,\n"
479 " 'accessControlProfiles' : [1, 2, ],\n"
480 " },\n"
481 " ],\n"
482 " 'Name Space3' : [\n"
483 " {\n"
484 " 'name' : 'xyzw',\n"
485 " 'value' : 'random stuff',\n"
486 " 'accessControlProfiles' : [1, 2, ],\n"
487 " },\n"
488 " {\n"
489 " 'name' : 'Something',\n"
490 " 'value' : 'Some string',\n"
491 " 'accessControlProfiles' : [2, ],\n"
492 " },\n"
493 " ],\n"
494 " },\n"
495 " true,\n"
496 "]",
497 cborPretty);
498
499 optional<vector<uint8_t>> credentialPubKey = support::certificateChainGetTopMostKey(
500 attData.attestationCertificate[0].encodedCertificate);
501 ASSERT_TRUE(credentialPubKey);
502 EXPECT_TRUE(support::coseCheckEcDsaSignature(proofOfProvisioningSignature,
503 {}, // Additional data
504 credentialPubKey.value()));
505}
506
507TEST_P(IdentityCredentialTests, verifyEmptyNameSpaceMixedWithNonEmptyWorks) {
508 Status result;
509
510 HardwareInformation hwInfo;
511 ASSERT_TRUE(credentialStore_->getHardwareInformation(&hwInfo).isOk());
512
513 sp<IWritableIdentityCredential> writableCredential;
514 ASSERT_TRUE(test_utils::SetupWritableCredential(writableCredential, credentialStore_));
515
516 string challenge = "NotSoRandomChallenge";
517 test_utils::AttestationData attData(writableCredential, challenge, {});
518 ASSERT_TRUE(attData.result.isOk())
519 << attData.result.exceptionCode() << "; " << attData.result.exceptionMessage() << endl;
520
521 const vector<int32_t> entryCounts = {2u, 2u};
522 writableCredential->startPersonalization(3, entryCounts);
523 ASSERT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage()
524 << endl;
525
526 optional<vector<uint8_t>> readerCertificate1 = test_utils::GenerateReaderCertificate("123456");
527 ASSERT_TRUE(readerCertificate1);
528
529 optional<vector<uint8_t>> readerCertificate2 =
530 test_utils::GenerateReaderCertificate("123456987987987987987987");
531 ASSERT_TRUE(readerCertificate2);
532
533 const vector<test_utils::TestProfile> testProfiles = {{0, readerCertificate1.value(), false, 0},
534 {1, readerCertificate2.value(), true, 1},
535 {2, {}, false, 0}};
536
537 optional<vector<SecureAccessControlProfile>> secureProfiles =
538 test_utils::AddAccessControlProfiles(writableCredential, testProfiles);
539 ASSERT_TRUE(secureProfiles);
540
541 const vector<test_utils::TestEntryData> testEntries1 = {
542 // test empty name space
543 {"", "t name", string("Turing"), vector<int32_t>{2}},
544 {"", "Birth", string("19120623"), vector<int32_t>{2}},
545 {"Name Space", "Last name", string("Turing"), vector<int32_t>{0, 1}},
546 {"Name Space", "Birth date", string("19120623"), vector<int32_t>{0, 1}},
547 };
548
549 map<const test_utils::TestEntryData*, vector<vector<uint8_t>>> encryptedBlobs;
550 for (const auto& entry : testEntries1) {
551 EXPECT_TRUE(test_utils::AddEntry(writableCredential, entry, hwInfo.dataChunkSize,
552 encryptedBlobs, true));
553 }
554
555 vector<uint8_t> credentialData;
556 vector<uint8_t> proofOfProvisioningSignature;
557 result =
558 writableCredential->finishAddingEntries(&credentialData, &proofOfProvisioningSignature);
559
560 EXPECT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage()
561 << endl;
562}
563
564TEST_P(IdentityCredentialTests, verifyInterleavingEntryNameSpaceOrderingFails) {
565 Status result;
566
567 HardwareInformation hwInfo;
568 ASSERT_TRUE(credentialStore_->getHardwareInformation(&hwInfo).isOk());
569
570 sp<IWritableIdentityCredential> writableCredential;
571 ASSERT_TRUE(test_utils::SetupWritableCredential(writableCredential, credentialStore_));
572
573 string challenge = "NotSoRandomChallenge";
574 test_utils::AttestationData attData(writableCredential, challenge, {});
575 ASSERT_TRUE(attData.result.isOk())
576 << attData.result.exceptionCode() << "; " << attData.result.exceptionMessage() << endl;
577
578 // Enter mismatched entry and profile numbers.
579 // Technically the 2nd name space of "Name Space" occurs intermittently, 2
580 // before "Image" and 2 after image, which is not correct. All of same name
581 // space should occur together. Let's see if this fails.
582 const vector<int32_t> entryCounts = {2u, 1u, 2u};
583 writableCredential->startPersonalization(3, entryCounts);
584 ASSERT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage()
585 << endl;
586
587 optional<vector<uint8_t>> readerCertificate1 = test_utils::GenerateReaderCertificate("123456");
588 ASSERT_TRUE(readerCertificate1);
589
590 optional<vector<uint8_t>> readerCertificate2 =
591 test_utils::GenerateReaderCertificate("123456987987987987987987");
592 ASSERT_TRUE(readerCertificate2);
593
594 const vector<test_utils::TestProfile> testProfiles = {{0, readerCertificate1.value(), false, 0},
595 {1, readerCertificate2.value(), true, 1},
596 {2, {}, false, 0}};
597
598 optional<vector<SecureAccessControlProfile>> secureProfiles =
599 test_utils::AddAccessControlProfiles(writableCredential, testProfiles);
600 ASSERT_TRUE(secureProfiles);
601
602 const vector<test_utils::TestEntryData> testEntries1 = {
603 // test empty name space
604 {"Name Space", "Last name", string("Turing"), vector<int32_t>{0, 1}},
605 {"Name Space", "Birth date", string("19120623"), vector<int32_t>{0, 1}},
606 };
607
608 map<const test_utils::TestEntryData*, vector<vector<uint8_t>>> encryptedBlobs;
609 for (const auto& entry : testEntries1) {
610 EXPECT_TRUE(test_utils::AddEntry(writableCredential, entry, hwInfo.dataChunkSize,
611 encryptedBlobs, true));
612 }
613 const test_utils::TestEntryData testEntry2 = {"Image", "Portrait image", string("asdfs"),
614 vector<int32_t>{0, 1}};
615
616 EXPECT_TRUE(test_utils::AddEntry(writableCredential, testEntry2, hwInfo.dataChunkSize,
617 encryptedBlobs, true));
618
619 // We expect this to fail because the namespace is out of order, all "Name Space"
620 // should have been called together
621 const vector<test_utils::TestEntryData> testEntries3 = {
622 {"Name Space", "First name", string("Alan"), vector<int32_t>{0, 1}},
623 {"Name Space", "Home address", string("Maida Vale, London, England"),
624 vector<int32_t>{0}},
625 };
626
627 for (const auto& entry : testEntries3) {
628 EXPECT_FALSE(test_utils::AddEntry(writableCredential, entry, hwInfo.dataChunkSize,
629 encryptedBlobs, false));
630 }
631
632 vector<uint8_t> credentialData;
633 vector<uint8_t> proofOfProvisioningSignature;
634 result =
635 writableCredential->finishAddingEntries(&credentialData, &proofOfProvisioningSignature);
636
637 // should fail because test_utils::AddEntry should have failed earlier.
638 EXPECT_FALSE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage()
639 << endl;
640 EXPECT_EQ(binder::Status::EX_SERVICE_SPECIFIC, result.exceptionCode());
641 EXPECT_EQ(IIdentityCredentialStore::STATUS_INVALID_DATA, result.serviceSpecificErrorCode());
642}
643
David Zeuthena0796e92020-04-27 15:24:55 -0400644TEST_P(IdentityCredentialTests, verifyAccessControlProfileIdOutOfRange) {
645 sp<IWritableIdentityCredential> writableCredential;
646 ASSERT_TRUE(test_utils::SetupWritableCredential(writableCredential, credentialStore_));
647
648 const vector<int32_t> entryCounts = {1};
649 Status result = writableCredential->startPersonalization(1, entryCounts);
650 ASSERT_TRUE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage()
651 << endl;
652
653 SecureAccessControlProfile profile;
654
655 // This should fail because the id is >= 32
656 result = writableCredential->addAccessControlProfile(32, // id
657 {}, // readerCertificate
658 false, // userAuthenticationRequired
659 0, // timeoutMillis
660 42, // secureUserId
661 &profile);
662 ASSERT_FALSE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage();
663 ASSERT_EQ(binder::Status::EX_SERVICE_SPECIFIC, result.exceptionCode());
664 ASSERT_EQ(IIdentityCredentialStore::STATUS_INVALID_DATA, result.serviceSpecificErrorCode());
665
666 // This should fail because the id is < 0
667 result = writableCredential->addAccessControlProfile(-1, // id
668 {}, // readerCertificate
669 false, // userAuthenticationRequired
670 0, // timeoutMillis
671 42, // secureUserId
672 &profile);
673 ASSERT_FALSE(result.isOk()) << result.exceptionCode() << "; " << result.exceptionMessage();
674 ASSERT_EQ(binder::Status::EX_SERVICE_SPECIFIC, result.exceptionCode());
675 ASSERT_EQ(IIdentityCredentialStore::STATUS_INVALID_DATA, result.serviceSpecificErrorCode());
676}
677
Selene Huang92b61d62020-03-04 02:24:16 -0800678INSTANTIATE_TEST_SUITE_P(
679 Identity, IdentityCredentialTests,
680 testing::ValuesIn(android::getAidlHalInstanceNames(IIdentityCredentialStore::descriptor)),
681 android::PrintInstanceNameToString);
682
683} // namespace android::hardware::identity