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 "ReaderAuthTests"
18
19 #include <aidl/Gtest.h>
20 #include <aidl/Vintf.h>
21 #include <aidl/android/hardware/keymaster/HardwareAuthToken.h>
22 #include <aidl/android/hardware/keymaster/VerificationToken.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 #include <utility>
34
35 #include "VtsIdentityTestUtils.h"
36
37 namespace android::hardware::identity {
38
39 using std::endl;
40 using std::make_pair;
41 using std::map;
42 using std::optional;
43 using std::pair;
44 using std::string;
45 using std::tie;
46 using std::vector;
47
48 using ::android::sp;
49 using ::android::String16;
50 using ::android::binder::Status;
51
52 using ::android::hardware::keymaster::HardwareAuthToken;
53 using ::android::hardware::keymaster::VerificationToken;
54
55 class ReaderAuthTests : public testing::TestWithParam<string> {
56 public:
SetUp()57 virtual void SetUp() override {
58 credentialStore_ = android::waitForDeclaredService<IIdentityCredentialStore>(
59 String16(GetParam().c_str()));
60 ASSERT_NE(credentialStore_, nullptr);
61 }
62
63 void provisionData();
64 void retrieveData(const vector<uint8_t>& readerPrivateKey,
65 const vector<vector<uint8_t>>& readerCertChain, bool expectSuccess,
66 bool leaveOutAccessibleToAllFromRequestMessage);
67
68 // Set by provisionData
69 vector<uint8_t> readerPublicKey_;
70 vector<uint8_t> readerPrivateKey_;
71 vector<uint8_t> intermediateAPublicKey_;
72 vector<uint8_t> intermediateAPrivateKey_;
73 vector<uint8_t> intermediateBPublicKey_;
74 vector<uint8_t> intermediateBPrivateKey_;
75 vector<uint8_t> intermediateCPublicKey_;
76 vector<uint8_t> intermediateCPrivateKey_;
77
78 vector<uint8_t> cert_A_SelfSigned_;
79
80 vector<uint8_t> cert_B_SelfSigned_;
81
82 vector<uint8_t> cert_B_SignedBy_C_;
83
84 vector<uint8_t> cert_C_SelfSigned_;
85
86 vector<uint8_t> cert_reader_SelfSigned_;
87 vector<uint8_t> cert_reader_SignedBy_A_;
88 vector<uint8_t> cert_reader_SignedBy_B_;
89
90 SecureAccessControlProfile sacp0_;
91 SecureAccessControlProfile sacp1_;
92 SecureAccessControlProfile sacp2_;
93 SecureAccessControlProfile sacp3_;
94
95 vector<uint8_t> encContentAccessibleByA_;
96 vector<uint8_t> encContentAccessibleByAorB_;
97 vector<uint8_t> encContentAccessibleByB_;
98 vector<uint8_t> encContentAccessibleByC_;
99 vector<uint8_t> encContentAccessibleByAll_;
100 vector<uint8_t> encContentAccessibleByNone_;
101
102 vector<uint8_t> credentialData_;
103
104 // Set by retrieveData()
105 bool canGetAccessibleByA_;
106 bool canGetAccessibleByAorB_;
107 bool canGetAccessibleByB_;
108 bool canGetAccessibleByC_;
109 bool canGetAccessibleByAll_;
110 bool canGetAccessibleByNone_;
111
112 sp<IIdentityCredentialStore> credentialStore_;
113 };
114
generateReaderKey()115 pair<vector<uint8_t>, vector<uint8_t>> generateReaderKey() {
116 optional<vector<uint8_t>> keyPKCS8 = support::createEcKeyPair();
117 optional<vector<uint8_t>> publicKey = support::ecKeyPairGetPublicKey(keyPKCS8.value());
118 optional<vector<uint8_t>> privateKey = support::ecKeyPairGetPrivateKey(keyPKCS8.value());
119 return make_pair(publicKey.value(), privateKey.value());
120 }
121
generateReaderCert(const vector<uint8_t> & publicKey,const vector<uint8_t> & signingKey)122 vector<uint8_t> generateReaderCert(const vector<uint8_t>& publicKey,
123 const vector<uint8_t>& signingKey) {
124 time_t validityNotBefore = 0;
125 time_t validityNotAfter = 0xffffffff;
126 optional<vector<uint8_t>> cert =
127 support::ecPublicKeyGenerateCertificate(publicKey, signingKey, "24601", "Issuer",
128 "Subject", validityNotBefore, validityNotAfter);
129 return cert.value();
130 }
131
provisionData()132 void ReaderAuthTests::provisionData() {
133 // Keys and certificates for intermediates.
134 tie(intermediateAPublicKey_, intermediateAPrivateKey_) = generateReaderKey();
135 tie(intermediateBPublicKey_, intermediateBPrivateKey_) = generateReaderKey();
136 tie(intermediateCPublicKey_, intermediateCPrivateKey_) = generateReaderKey();
137
138 cert_A_SelfSigned_ = generateReaderCert(intermediateAPublicKey_, intermediateAPrivateKey_);
139
140 cert_B_SelfSigned_ = generateReaderCert(intermediateBPublicKey_, intermediateBPrivateKey_);
141
142 cert_B_SignedBy_C_ = generateReaderCert(intermediateBPublicKey_, intermediateCPrivateKey_);
143
144 cert_C_SelfSigned_ = generateReaderCert(intermediateCPublicKey_, intermediateCPrivateKey_);
145
146 // Key and self-signed certificate reader
147 tie(readerPublicKey_, readerPrivateKey_) = generateReaderKey();
148 cert_reader_SelfSigned_ = generateReaderCert(readerPublicKey_, readerPrivateKey_);
149
150 // Certificate for reader signed by intermediates
151 cert_reader_SignedBy_A_ = generateReaderCert(readerPublicKey_, intermediateAPrivateKey_);
152 cert_reader_SignedBy_B_ = generateReaderCert(readerPublicKey_, intermediateBPrivateKey_);
153
154 string docType = "org.iso.18013-5.2019.mdl";
155 bool testCredential = true;
156 sp<IWritableIdentityCredential> wc;
157 ASSERT_TRUE(credentialStore_->createCredential(docType, testCredential, &wc).isOk());
158
159 vector<uint8_t> attestationApplicationId = {};
160 vector<uint8_t> attestationChallenge = {1};
161 vector<Certificate> certChain;
162 ASSERT_TRUE(wc->getAttestationCertificate(attestationApplicationId, attestationChallenge,
163 &certChain)
164 .isOk());
165
166 size_t proofOfProvisioningSize =
167 465 + cert_A_SelfSigned_.size() + cert_B_SelfSigned_.size() + cert_C_SelfSigned_.size();
168 ASSERT_TRUE(wc->setExpectedProofOfProvisioningSize(proofOfProvisioningSize).isOk());
169
170 // Not in v1 HAL, may fail
171 wc->startPersonalization(4 /* numAccessControlProfiles */,
172 {6} /* numDataElementsPerNamespace */);
173
174 // AIDL expects certificates wrapped in the Certificate type...
175 Certificate cert_A;
176 Certificate cert_B;
177 Certificate cert_C;
178 cert_A.encodedCertificate = cert_A_SelfSigned_;
179 cert_B.encodedCertificate = cert_B_SelfSigned_;
180 cert_C.encodedCertificate = cert_C_SelfSigned_;
181
182 // Access control profile 0: accessible by A
183 ASSERT_TRUE(wc->addAccessControlProfile(0, cert_A, false, 0, 0, &sacp0_).isOk());
184
185 // Access control profile 1: accessible by B
186 ASSERT_TRUE(wc->addAccessControlProfile(1, cert_B, false, 0, 0, &sacp1_).isOk());
187
188 // Access control profile 2: accessible by C
189 ASSERT_TRUE(wc->addAccessControlProfile(2, cert_C, false, 0, 0, &sacp2_).isOk());
190
191 // Access control profile 3: open access
192 ASSERT_TRUE(wc->addAccessControlProfile(3, {}, false, 0, 0, &sacp3_).isOk());
193
194 // Data Element: "Accessible by A"
195 ASSERT_TRUE(wc->beginAddEntry({0}, "ns", "Accessible by A", 1).isOk());
196 ASSERT_TRUE(wc->addEntryValue({9}, &encContentAccessibleByA_).isOk());
197
198 // Data Element: "Accessible by A or B"
199 ASSERT_TRUE(wc->beginAddEntry({0, 1}, "ns", "Accessible by A or B", 1).isOk());
200 ASSERT_TRUE(wc->addEntryValue({9}, &encContentAccessibleByAorB_).isOk());
201
202 // Data Element: "Accessible by B"
203 ASSERT_TRUE(wc->beginAddEntry({1}, "ns", "Accessible by B", 1).isOk());
204 ASSERT_TRUE(wc->addEntryValue({9}, &encContentAccessibleByB_).isOk());
205
206 // Data Element: "Accessible by C"
207 ASSERT_TRUE(wc->beginAddEntry({2}, "ns", "Accessible by C", 1).isOk());
208 ASSERT_TRUE(wc->addEntryValue({9}, &encContentAccessibleByC_).isOk());
209
210 // Data Element: "Accessible by All"
211 ASSERT_TRUE(wc->beginAddEntry({3}, "ns", "Accessible by All", 1).isOk());
212 ASSERT_TRUE(wc->addEntryValue({9}, &encContentAccessibleByAll_).isOk());
213
214 // Data Element: "Accessible by None"
215 ASSERT_TRUE(wc->beginAddEntry({}, "ns", "Accessible by None", 1).isOk());
216 ASSERT_TRUE(wc->addEntryValue({9}, &encContentAccessibleByNone_).isOk());
217
218 vector<uint8_t> proofOfProvisioningSignature;
219 ASSERT_TRUE(wc->finishAddingEntries(&credentialData_, &proofOfProvisioningSignature).isOk());
220 }
221
buildRequestDataItem(const string & name,size_t size,vector<int32_t> accessControlProfileIds)222 RequestDataItem buildRequestDataItem(const string& name, size_t size,
223 vector<int32_t> accessControlProfileIds) {
224 RequestDataItem item;
225 item.name = name;
226 item.size = size;
227 item.accessControlProfileIds = accessControlProfileIds;
228 return item;
229 }
230
retrieveData(const vector<uint8_t> & readerPrivateKey,const vector<vector<uint8_t>> & readerCertChain,bool expectSuccess,bool leaveOutAccessibleToAllFromRequestMessage)231 void ReaderAuthTests::retrieveData(const vector<uint8_t>& readerPrivateKey,
232 const vector<vector<uint8_t>>& readerCertChain,
233 bool expectSuccess,
234 bool leaveOutAccessibleToAllFromRequestMessage) {
235 canGetAccessibleByA_ = false;
236 canGetAccessibleByAorB_ = false;
237 canGetAccessibleByB_ = false;
238 canGetAccessibleByC_ = false;
239 canGetAccessibleByAll_ = false;
240 canGetAccessibleByNone_ = false;
241
242 sp<IIdentityCredential> c;
243 ASSERT_TRUE(credentialStore_
244 ->getCredential(
245 CipherSuite::CIPHERSUITE_ECDHE_HKDF_ECDSA_WITH_AES_256_GCM_SHA256,
246 credentialData_, &c)
247 .isOk());
248
249 optional<vector<uint8_t>> readerEKeyPair = support::createEcKeyPair();
250 optional<vector<uint8_t>> readerEPublicKey =
251 support::ecKeyPairGetPublicKey(readerEKeyPair.value());
252 ASSERT_TRUE(c->setReaderEphemeralPublicKey(readerEPublicKey.value()).isOk());
253
254 vector<uint8_t> eKeyPair;
255 ASSERT_TRUE(c->createEphemeralKeyPair(&eKeyPair).isOk());
256 optional<vector<uint8_t>> ePublicKey = support::ecKeyPairGetPublicKey(eKeyPair);
257
258 // Calculate requestData field and sign it with the reader key.
259 auto [getXYSuccess, ephX, ephY] = support::ecPublicKeyGetXandY(ePublicKey.value());
260 ASSERT_TRUE(getXYSuccess);
261 cppbor::Map deviceEngagement = cppbor::Map().add("ephX", ephX).add("ephY", ephY);
262 vector<uint8_t> deviceEngagementBytes = deviceEngagement.encode();
263 vector<uint8_t> eReaderPubBytes = cppbor::Tstr("ignored").encode();
264 cppbor::Array sessionTranscript = cppbor::Array()
265 .add(cppbor::Semantic(24, deviceEngagementBytes))
266 .add(cppbor::Semantic(24, eReaderPubBytes));
267 vector<uint8_t> sessionTranscriptBytes = sessionTranscript.encode();
268
269 vector<uint8_t> itemsRequestBytes;
270 if (leaveOutAccessibleToAllFromRequestMessage) {
271 itemsRequestBytes =
272 cppbor::Map("nameSpaces",
273 cppbor::Map().add("ns", cppbor::Map()
274 .add("Accessible by A", false)
275 .add("Accessible by A or B", false)
276 .add("Accessible by B", false)
277 .add("Accessible by C", false)
278 .add("Accessible by None", false)))
279 .encode();
280 } else {
281 itemsRequestBytes =
282 cppbor::Map("nameSpaces",
283 cppbor::Map().add("ns", cppbor::Map()
284 .add("Accessible by A", false)
285 .add("Accessible by A or B", false)
286 .add("Accessible by B", false)
287 .add("Accessible by C", false)
288 .add("Accessible by All", false)
289 .add("Accessible by None", false)))
290 .encode();
291 }
292 vector<uint8_t> encodedReaderAuthentication =
293 cppbor::Array()
294 .add("ReaderAuthentication")
295 .add(sessionTranscript.clone())
296 .add(cppbor::Semantic(24, itemsRequestBytes))
297 .encode();
298 vector<uint8_t> encodedReaderAuthenticationBytes =
299 cppbor::Semantic(24, encodedReaderAuthentication).encode();
300
301 optional<vector<uint8_t>> readerSignature =
302 support::coseSignEcDsa(readerPrivateKey, // private key for reader
303 {}, // content
304 encodedReaderAuthenticationBytes, // detached content
305 support::certificateChainJoin(readerCertChain));
306 ASSERT_TRUE(readerSignature);
307
308 // Generate the key that will be used to sign AuthenticatedData.
309 vector<uint8_t> signingKeyBlob;
310 Certificate signingKeyCertificate;
311 ASSERT_TRUE(c->generateSigningKeyPair(&signingKeyBlob, &signingKeyCertificate).isOk());
312
313 RequestNamespace rns;
314 rns.namespaceName = "ns";
315 rns.items.push_back(buildRequestDataItem("Accessible by A", 1, {0}));
316 rns.items.push_back(buildRequestDataItem("Accessible by A or B", 1, {0, 1}));
317 rns.items.push_back(buildRequestDataItem("Accessible by B", 1, {1}));
318 rns.items.push_back(buildRequestDataItem("Accessible by C", 1, {2}));
319 rns.items.push_back(buildRequestDataItem("Accessible by All", 1, {3}));
320 rns.items.push_back(buildRequestDataItem("Accessible by None", 1, {}));
321 // OK to fail, not available in v1 HAL
322 c->setRequestedNamespaces({rns}).isOk();
323
324 // It doesn't matter since no user auth is needed in this particular test,
325 // but for good measure, clear out the tokens we pass to the HAL.
326 HardwareAuthToken authToken;
327 VerificationToken verificationToken;
328 authToken.challenge = 0;
329 authToken.userId = 0;
330 authToken.authenticatorId = 0;
331 authToken.authenticatorType = ::android::hardware::keymaster::HardwareAuthenticatorType::NONE;
332 authToken.timestamp.milliSeconds = 0;
333 authToken.mac.clear();
334 verificationToken.challenge = 0;
335 verificationToken.timestamp.milliSeconds = 0;
336 verificationToken.securityLevel = ::android::hardware::keymaster::SecurityLevel::SOFTWARE;
337 verificationToken.mac.clear();
338 // OK to fail, not available in v1 HAL
339 c->setVerificationToken(verificationToken);
340
341 Status status = c->startRetrieval(
342 {sacp0_, sacp1_, sacp2_, sacp3_}, authToken, itemsRequestBytes, signingKeyBlob,
343 sessionTranscriptBytes, readerSignature.value(), {6 /* numDataElementsPerNamespace */});
344 if (expectSuccess) {
345 ASSERT_TRUE(status.isOk());
346 } else {
347 ASSERT_FALSE(status.isOk());
348 return;
349 }
350
351 vector<uint8_t> decrypted;
352
353 status = c->startRetrieveEntryValue("ns", "Accessible by A", 1, {0});
354 if (status.isOk()) {
355 canGetAccessibleByA_ = true;
356 ASSERT_TRUE(c->retrieveEntryValue(encContentAccessibleByA_, &decrypted).isOk());
357 }
358
359 status = c->startRetrieveEntryValue("ns", "Accessible by A or B", 1, {0, 1});
360 if (status.isOk()) {
361 canGetAccessibleByAorB_ = true;
362 ASSERT_TRUE(c->retrieveEntryValue(encContentAccessibleByAorB_, &decrypted).isOk());
363 }
364
365 status = c->startRetrieveEntryValue("ns", "Accessible by B", 1, {1});
366 if (status.isOk()) {
367 canGetAccessibleByB_ = true;
368 ASSERT_TRUE(c->retrieveEntryValue(encContentAccessibleByB_, &decrypted).isOk());
369 }
370
371 status = c->startRetrieveEntryValue("ns", "Accessible by C", 1, {2});
372 if (status.isOk()) {
373 canGetAccessibleByC_ = true;
374 ASSERT_TRUE(c->retrieveEntryValue(encContentAccessibleByC_, &decrypted).isOk());
375 }
376
377 status = c->startRetrieveEntryValue("ns", "Accessible by All", 1, {3});
378 if (status.isOk()) {
379 canGetAccessibleByAll_ = true;
380 ASSERT_TRUE(c->retrieveEntryValue(encContentAccessibleByAll_, &decrypted).isOk());
381 }
382
383 status = c->startRetrieveEntryValue("ns", "Accessible by None", 1, {});
384 if (status.isOk()) {
385 canGetAccessibleByNone_ = true;
386 ASSERT_TRUE(c->retrieveEntryValue(encContentAccessibleByNone_, &decrypted).isOk());
387 }
388
389 vector<uint8_t> mac;
390 vector<uint8_t> deviceNameSpaces;
391 ASSERT_TRUE(c->finishRetrieval(&mac, &deviceNameSpaces).isOk());
392 }
393
TEST_P(ReaderAuthTests,presentingChain_Reader)394 TEST_P(ReaderAuthTests, presentingChain_Reader) {
395 provisionData();
396 retrieveData(readerPrivateKey_, {cert_reader_SelfSigned_}, true /* expectSuccess */,
397 false /* leaveOutAccessibleToAllFromRequestMessage */);
398 EXPECT_FALSE(canGetAccessibleByA_);
399 EXPECT_FALSE(canGetAccessibleByAorB_);
400 EXPECT_FALSE(canGetAccessibleByB_);
401 EXPECT_FALSE(canGetAccessibleByC_);
402 EXPECT_TRUE(canGetAccessibleByAll_);
403 EXPECT_FALSE(canGetAccessibleByNone_);
404 }
405
TEST_P(ReaderAuthTests,presentingChain_Reader_A)406 TEST_P(ReaderAuthTests, presentingChain_Reader_A) {
407 provisionData();
408 retrieveData(readerPrivateKey_, {cert_reader_SignedBy_A_, cert_A_SelfSigned_},
409 true /* expectSuccess */, false /* leaveOutAccessibleToAllFromRequestMessage */);
410 EXPECT_TRUE(canGetAccessibleByA_);
411 EXPECT_TRUE(canGetAccessibleByAorB_);
412 EXPECT_FALSE(canGetAccessibleByB_);
413 EXPECT_FALSE(canGetAccessibleByC_);
414 EXPECT_TRUE(canGetAccessibleByAll_);
415 EXPECT_FALSE(canGetAccessibleByNone_);
416 }
417
TEST_P(ReaderAuthTests,presentingChain_Reader_B)418 TEST_P(ReaderAuthTests, presentingChain_Reader_B) {
419 provisionData();
420 retrieveData(readerPrivateKey_, {cert_reader_SignedBy_B_, cert_B_SelfSigned_},
421 true /* expectSuccess */, false /* leaveOutAccessibleToAllFromRequestMessage */);
422 EXPECT_FALSE(canGetAccessibleByA_);
423 EXPECT_TRUE(canGetAccessibleByAorB_);
424 EXPECT_TRUE(canGetAccessibleByB_);
425 EXPECT_FALSE(canGetAccessibleByC_);
426 EXPECT_TRUE(canGetAccessibleByAll_);
427 EXPECT_FALSE(canGetAccessibleByNone_);
428 }
429
430 // This test proves that for the purpose of determining inclusion of an ACP certificate
431 // in a presented reader chain, certificate equality is done by comparing public keys,
432 // not bitwise comparison of the certificates.
433 //
434 // Specifically for this test, the ACP is configured with cert_B_SelfSigned_ and the
435 // reader is presenting cert_B_SignedBy_C_. Both certificates have the same public
436 // key - intermediateBPublicKey_ - but they are signed by different keys.
437 //
TEST_P(ReaderAuthTests,presentingChain_Reader_B_C)438 TEST_P(ReaderAuthTests, presentingChain_Reader_B_C) {
439 provisionData();
440 retrieveData(readerPrivateKey_,
441 {cert_reader_SignedBy_B_, cert_B_SignedBy_C_, cert_C_SelfSigned_},
442 true /* expectSuccess */, false /* leaveOutAccessibleToAllFromRequestMessage */);
443 EXPECT_FALSE(canGetAccessibleByA_);
444 EXPECT_TRUE(canGetAccessibleByAorB_);
445 EXPECT_TRUE(canGetAccessibleByB_);
446 EXPECT_TRUE(canGetAccessibleByC_);
447 EXPECT_TRUE(canGetAccessibleByAll_);
448 EXPECT_FALSE(canGetAccessibleByNone_);
449 }
450
451 // This test presents a reader chain where the chain is invalid because
452 // the 2nd certificate in the chain isn't signed by the 3rd one.
453 //
TEST_P(ReaderAuthTests,presentingInvalidChain)454 TEST_P(ReaderAuthTests, presentingInvalidChain) {
455 provisionData();
456 retrieveData(readerPrivateKey_,
457 {cert_reader_SignedBy_B_, cert_B_SelfSigned_, cert_C_SelfSigned_},
458 false /* expectSuccess */, false /* leaveOutAccessibleToAllFromRequestMessage */);
459 }
460
461 // This tests presents a valid reader chain but where requestMessage isn't
462 // signed by the private key corresponding to the public key in the top-level
463 // certificate.
464 //
TEST_P(ReaderAuthTests,presentingMessageSignedNotByTopLevel)465 TEST_P(ReaderAuthTests, presentingMessageSignedNotByTopLevel) {
466 provisionData();
467 retrieveData(intermediateBPrivateKey_,
468 {cert_reader_SignedBy_B_, cert_B_SignedBy_C_, cert_C_SelfSigned_},
469 false /* expectSuccess */, false /* leaveOutAccessibleToAllFromRequestMessage */);
470 }
471
472 // This test leaves out "Accessible by All" data element from the signed request
473 // message (the CBOR from the reader) while still including this data element at
474 // the API level. The call on the API level for said element will fail with
475 // STATUS_NOT_IN_REQUEST_MESSAGE but this doesn't prevent the other elements
476 // from being returned (if authorized, of course).
477 //
478 // This test verifies that.
479 //
TEST_P(ReaderAuthTests,limitedMessage)480 TEST_P(ReaderAuthTests, limitedMessage) {
481 provisionData();
482 retrieveData(readerPrivateKey_, {cert_reader_SelfSigned_}, true /* expectSuccess */,
483 true /* leaveOutAccessibleToAllFromRequestMessage */);
484 EXPECT_FALSE(canGetAccessibleByA_);
485 EXPECT_FALSE(canGetAccessibleByAorB_);
486 EXPECT_FALSE(canGetAccessibleByB_);
487 EXPECT_FALSE(canGetAccessibleByC_);
488 EXPECT_FALSE(canGetAccessibleByAll_);
489 EXPECT_FALSE(canGetAccessibleByNone_);
490 }
491
TEST_P(ReaderAuthTests,ephemeralKeyNotInSessionTranscript)492 TEST_P(ReaderAuthTests, ephemeralKeyNotInSessionTranscript) {
493 provisionData();
494
495 sp<IIdentityCredential> c;
496 ASSERT_TRUE(credentialStore_
497 ->getCredential(
498 CipherSuite::CIPHERSUITE_ECDHE_HKDF_ECDSA_WITH_AES_256_GCM_SHA256,
499 credentialData_, &c)
500 .isOk());
501
502 optional<vector<uint8_t>> readerEKeyPair = support::createEcKeyPair();
503 optional<vector<uint8_t>> readerEPublicKey =
504 support::ecKeyPairGetPublicKey(readerEKeyPair.value());
505 ASSERT_TRUE(c->setReaderEphemeralPublicKey(readerEPublicKey.value()).isOk());
506
507 vector<uint8_t> eKeyPair;
508 ASSERT_TRUE(c->createEphemeralKeyPair(&eKeyPair).isOk());
509 optional<vector<uint8_t>> ePublicKey = support::ecKeyPairGetPublicKey(eKeyPair);
510
511 // Calculate requestData field and sign it with the reader key.
512 auto [getXYSuccess, ephX, ephY] = support::ecPublicKeyGetXandY(ePublicKey.value());
513 ASSERT_TRUE(getXYSuccess);
514 // Instead of include the X and Y coordinates (|ephX| and |ephY|), add NUL bytes instead.
515 vector<uint8_t> nulls(32);
516 cppbor::Map deviceEngagement = cppbor::Map().add("ephX", nulls).add("ephY", nulls);
517 vector<uint8_t> deviceEngagementBytes = deviceEngagement.encode();
518 vector<uint8_t> eReaderPubBytes = cppbor::Tstr("ignored").encode();
519 cppbor::Array sessionTranscript = cppbor::Array()
520 .add(cppbor::Semantic(24, deviceEngagementBytes))
521 .add(cppbor::Semantic(24, eReaderPubBytes));
522 vector<uint8_t> sessionTranscriptBytes = sessionTranscript.encode();
523
524 vector<uint8_t> itemsRequestBytes;
525 itemsRequestBytes =
526 cppbor::Map("nameSpaces",
527 cppbor::Map().add("ns", cppbor::Map()
528 .add("Accessible by A", false)
529 .add("Accessible by A or B", false)
530 .add("Accessible by B", false)
531 .add("Accessible by C", false)
532 .add("Accessible by None", false)))
533 .encode();
534 vector<uint8_t> encodedReaderAuthentication =
535 cppbor::Array()
536 .add("ReaderAuthentication")
537 .add(sessionTranscript.clone())
538 .add(cppbor::Semantic(24, itemsRequestBytes))
539 .encode();
540 vector<uint8_t> encodedReaderAuthenticationBytes =
541 cppbor::Semantic(24, encodedReaderAuthentication).encode();
542
543 vector<vector<uint8_t>> readerCertChain = {cert_reader_SelfSigned_};
544 optional<vector<uint8_t>> readerSignature =
545 support::coseSignEcDsa(readerPrivateKey_, // private key for reader
546 {}, // content
547 encodedReaderAuthenticationBytes, // detached content
548 support::certificateChainJoin(readerCertChain));
549 ASSERT_TRUE(readerSignature);
550
551 // Generate the key that will be used to sign AuthenticatedData.
552 vector<uint8_t> signingKeyBlob;
553 Certificate signingKeyCertificate;
554 ASSERT_TRUE(c->generateSigningKeyPair(&signingKeyBlob, &signingKeyCertificate).isOk());
555
556 RequestNamespace rns;
557 rns.namespaceName = "ns";
558 rns.items.push_back(buildRequestDataItem("Accessible by A", 1, {0}));
559 rns.items.push_back(buildRequestDataItem("Accessible by A or B", 1, {0, 1}));
560 rns.items.push_back(buildRequestDataItem("Accessible by B", 1, {1}));
561 rns.items.push_back(buildRequestDataItem("Accessible by C", 1, {2}));
562 rns.items.push_back(buildRequestDataItem("Accessible by All", 1, {3}));
563 rns.items.push_back(buildRequestDataItem("Accessible by None", 1, {}));
564 // OK to fail, not available in v1 HAL
565 c->setRequestedNamespaces({rns}).isOk();
566
567 // It doesn't matter since no user auth is needed in this particular test,
568 // but for good measure, clear out the tokens we pass to the HAL.
569 HardwareAuthToken authToken;
570 VerificationToken verificationToken;
571 authToken.challenge = 0;
572 authToken.userId = 0;
573 authToken.authenticatorId = 0;
574 authToken.authenticatorType = ::android::hardware::keymaster::HardwareAuthenticatorType::NONE;
575 authToken.timestamp.milliSeconds = 0;
576 authToken.mac.clear();
577 verificationToken.challenge = 0;
578 verificationToken.timestamp.milliSeconds = 0;
579 verificationToken.securityLevel =
580 ::android::hardware::keymaster::SecurityLevel::TRUSTED_ENVIRONMENT;
581 verificationToken.mac.clear();
582 // OK to fail, not available in v1 HAL
583 c->setVerificationToken(verificationToken);
584
585 // Finally check that STATUS_EPHEMERAL_PUBLIC_KEY_NOT_FOUND is returned.
586 // This proves that the TA checked for X and Y coordinatets and didn't find
587 // them.
588 Status status = c->startRetrieval(
589 {sacp0_, sacp1_, sacp2_, sacp3_}, authToken, itemsRequestBytes, signingKeyBlob,
590 sessionTranscriptBytes, readerSignature.value(), {6 /* numDataElementsPerNamespace */});
591 ASSERT_FALSE(status.isOk());
592 ASSERT_EQ(binder::Status::EX_SERVICE_SPECIFIC, status.exceptionCode());
593 ASSERT_EQ(IIdentityCredentialStore::STATUS_EPHEMERAL_PUBLIC_KEY_NOT_FOUND,
594 status.serviceSpecificErrorCode());
595 }
596
597 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ReaderAuthTests);
598 INSTANTIATE_TEST_SUITE_P(
599 Identity, ReaderAuthTests,
600 testing::ValuesIn(android::getAidlHalInstanceNames(IIdentityCredentialStore::descriptor)),
601 android::PrintInstanceNameToString);
602
603 } // namespace android::hardware::identity
604