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 "Util.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 = support::ecPublicKeyGenerateCertificate( 127 publicKey, signingKey, "24601", "Issuer", "Subject", validityNotBefore, 128 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::SemanticTag(24, deviceEngagementBytes)) 266 .add(cppbor::SemanticTag(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::SemanticTag(24, itemsRequestBytes)) 297 .encode(); 298 vector<uint8_t> encodedReaderAuthenticationBytes = 299 cppbor::SemanticTag(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::SemanticTag(24, deviceEngagementBytes)) 521 .add(cppbor::SemanticTag(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::SemanticTag(24, itemsRequestBytes)) 539 .encode(); 540 vector<uint8_t> encodedReaderAuthenticationBytes = 541 cppbor::SemanticTag(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