From 6d196d84960081ff9fafede01bdad3fb87c7ae44 Mon Sep 17 00:00:00 2001 From: Srujan Gaddam Date: Wed, 29 May 2019 17:10:41 -0700 Subject: [PATCH] Change prov retry test to use prov models Bug: b/133641240 Tests: ProvisioningInterspersedRetryTest L3 & modmock Merge of http://go/wvgerrit/80164 The ProvisioningInterspersedRetryTest tests that the response tied to the provisioning request before the latest fails to be handled. This is only true for provisioning 2.0 where we use derived keys. In provisioning 3.0, the number of requests allowed to be handled is tied to the number of nonces, which from OEMCrypto v15.2 onwards, is exactly 4. This CL modifies the test to handle that behavior. Change-Id: I9f4e555acab145487d6e409779afe7b9b63fd4af --- .../cdm/test/request_license_test.cpp | 105 ++++++++++++------ 1 file changed, 72 insertions(+), 33 deletions(-) diff --git a/libwvdrmengine/cdm/test/request_license_test.cpp b/libwvdrmengine/cdm/test/request_license_test.cpp index a4823b68..df94a2a7 100644 --- a/libwvdrmengine/cdm/test/request_license_test.cpp +++ b/libwvdrmengine/cdm/test/request_license_test.cpp @@ -69,6 +69,9 @@ const wvcdm::CdmIdentifier kAlternateCdmIdentifier1 = { const std::string kEmptyServiceCertificate; const std::string kComma = ","; +// From OEMCrypto v15.2 onwards, we require the nonce table to be size 4. +const size_t kNonceTableSize = 4; + // Protobuf generated classes using video_widevine::LicenseIdentification; using video_widevine::LicenseRequest_ContentIdentification; @@ -2267,46 +2270,82 @@ TEST_F(WvCdmRequestLicenseTest, ProvisioningInterposedRetryTest) { } TEST_F(WvCdmRequestLicenseTest, ProvisioningInterspersedRetryTest) { - decryptor_->OpenSession(config_.key_system(), NULL, kDefaultCdmIdentifier, NULL, - &session_id_); + decryptor_->OpenSession(config_.key_system(), NULL, kDefaultCdmIdentifier, + NULL, &session_id_); std::string provisioning_server; CdmCertificateType cert_type = kCertificateWidevine; std::string cert_authority, cert, wrapped_key; - std::string key_msg1, key_msg2; - EXPECT_EQ(wvcdm::NO_ERROR, decryptor_->GetProvisioningRequest( - cert_type, cert_authority, - kDefaultCdmIdentifier, - kEmptyServiceCertificate, &key_msg1, - &provisioning_server)); - EXPECT_EQ(provisioning_server, config_.provisioning_server()); + std::string provisioning_model; + EXPECT_EQ(wvcdm::NO_ERROR, + decryptor_->QueryStatus(kLevelDefault, + wvcdm::QUERY_KEY_PROVISIONING_MODEL, + &provisioning_model)); - EXPECT_EQ(wvcdm::NO_ERROR, decryptor_->GetProvisioningRequest( - cert_type, cert_authority, - kDefaultCdmIdentifier, - kEmptyServiceCertificate, &key_msg2, - &provisioning_server)); - EXPECT_EQ(provisioning_server, config_.provisioning_server()); + std::string value; + EXPECT_EQ(wvcdm::NO_ERROR, + decryptor_->QueryStatus( + kLevelDefault, wvcdm::QUERY_KEY_OEMCRYPTO_API_VERSION, &value)); + std::istringstream ss(value); + uint32_t api_version; + ss >> api_version; + ASSERT_FALSE(ss.fail()); + EXPECT_TRUE(ss.eof()); - key_msg_ = key_msg1; - std::string response = - GetCertRequestResponse(config_.provisioning_server()); - EXPECT_NE(0, static_cast(response.size())); - EXPECT_EQ(wvcdm::REWRAP_DEVICE_RSA_KEY_ERROR, - decryptor_->HandleProvisioningResponse(kDefaultCdmIdentifier, - response, &cert, - &wrapped_key)); - EXPECT_EQ(0, static_cast(cert.size())); - EXPECT_EQ(0, static_cast(wrapped_key.size())); + if (provisioning_model == wvcdm::QUERY_VALUE_KEYBOX || + (provisioning_model == wvcdm::QUERY_VALUE_OEM_CERTIFICATE && + api_version >= 15)) { + // From OEMCrypto v15.2 onwards, the nonce table size is fixed. We can't + // test this for API versions before that if they use OEM certificates. + std::vector key_msgs; - key_msg_ = key_msg2; - response = GetCertRequestResponse(config_.provisioning_server()); - EXPECT_NE(0, static_cast(response.size())); - EXPECT_EQ(wvcdm::NO_ERROR, decryptor_->HandleProvisioningResponse( - kDefaultCdmIdentifier, response, &cert, - &wrapped_key)); - EXPECT_EQ(0, static_cast(cert.size())); - EXPECT_EQ(0, static_cast(wrapped_key.size())); + wvcdm::CdmResponseType first_request_error; + if (provisioning_model == wvcdm::QUERY_VALUE_KEYBOX) { + // For keyboxes we use derived keys as part of the provisioning request. + // These get updated each request, therefore any request before the latest + // fails, so we only need 2 requests. + key_msgs.resize(2); + first_request_error = wvcdm::REWRAP_DEVICE_RSA_KEY_ERROR; + } else { + // For OEM certificates, we don't use derived keys, so any request is + // valid as long as its corresponding nonce is contained in the nonce + // table. This is why we need the size to be fixed. + // We need kNonceTableSize + 1 requests here to check that the first + // of these fails and the one after that succeeds. + key_msgs.resize(kNonceTableSize + 1); + first_request_error = wvcdm::REWRAP_DEVICE_RSA_KEY_30_ERROR; + } + + for (size_t i = 0; i < key_msgs.size(); i++) { + EXPECT_EQ( + wvcdm::NO_ERROR, + decryptor_->GetProvisioningRequest( + cert_type, cert_authority, kDefaultCdmIdentifier, + kEmptyServiceCertificate, &key_msgs[i], &provisioning_server)); + EXPECT_EQ(provisioning_server, config_.provisioning_server()); + } + + // First request that we expect to fail. + key_msg_ = key_msgs[0]; + std::string response = + GetCertRequestResponse(config_.provisioning_server()); + EXPECT_NE(0, static_cast(response.size())); + EXPECT_EQ(first_request_error, + decryptor_->HandleProvisioningResponse( + kDefaultCdmIdentifier, response, &cert, &wrapped_key)); + EXPECT_EQ(0, static_cast(cert.size())); + EXPECT_EQ(0, static_cast(wrapped_key.size())); + + // Second request that we expect to succeed. + key_msg_ = key_msgs[1]; + response = GetCertRequestResponse(config_.provisioning_server()); + EXPECT_NE(0, static_cast(response.size())); + EXPECT_EQ(wvcdm::NO_ERROR, + decryptor_->HandleProvisioningResponse( + kDefaultCdmIdentifier, response, &cert, &wrapped_key)); + EXPECT_EQ(0, static_cast(cert.size())); + EXPECT_EQ(0, static_cast(wrapped_key.size())); + } decryptor_->CloseSession(session_id_); }