Source release 17.1.2
This commit is contained in:
@@ -11,9 +11,13 @@
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include <gmock/gmock.h>
|
||||
#include <gtest/gtest.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/rsa.h>
|
||||
#include <openssl/x509.h>
|
||||
|
||||
#include "OEMCryptoCENC.h"
|
||||
#include "cdm.h"
|
||||
@@ -204,6 +208,12 @@ const std::string kNewValue = "A New Value";
|
||||
const std::string kParamName = "PARAM";
|
||||
const std::string kParamName2 = "PARAM2";
|
||||
|
||||
const std::string kFakeCastMessage = a2bs_hex(
|
||||
// ASN.1 SHA-1 identifier
|
||||
"3021300906052b0e03021a05000414"
|
||||
// Fake SHA-1 digest (actually just random bytes)
|
||||
"96b34d11727bb41089e989ea51588666f924a40e");
|
||||
|
||||
class CdmTest : public WvCdmTestBase, public Cdm::IEventListener {
|
||||
public:
|
||||
CdmTest() {}
|
||||
@@ -2431,6 +2441,33 @@ TEST_F(CdmTest, EncryptedPlaybackWithoutALicense) {
|
||||
EXPECT_EQ(Cdm::kNoKey, status);
|
||||
}
|
||||
|
||||
TEST_F(CdmTest, CheckInitDataEmbeddedKeys) {
|
||||
bool contains_embedded_keys;
|
||||
|
||||
// WebM (cannot contain embedded keys)
|
||||
EXPECT_EQ(cdm_->initDataContainsEmbeddedKeys(Cdm::kWebM, kWebMInitData,
|
||||
&contains_embedded_keys),
|
||||
Cdm::kSuccess);
|
||||
EXPECT_FALSE(contains_embedded_keys);
|
||||
|
||||
// PSSH without embedded keys
|
||||
EXPECT_EQ(cdm_->initDataContainsEmbeddedKeys(Cdm::kCenc, kCencInitData,
|
||||
&contains_embedded_keys),
|
||||
Cdm::kSuccess);
|
||||
EXPECT_FALSE(contains_embedded_keys);
|
||||
|
||||
// PSSH with embedded keys
|
||||
EXPECT_EQ(cdm_->initDataContainsEmbeddedKeys(
|
||||
Cdm::kCenc, kCencEntitlementInitData1, &contains_embedded_keys),
|
||||
Cdm::kSuccess);
|
||||
EXPECT_TRUE(contains_embedded_keys);
|
||||
|
||||
// Null out pointer
|
||||
EXPECT_NE(
|
||||
cdm_->initDataContainsEmbeddedKeys(Cdm::kCenc, kCencInitData, nullptr),
|
||||
Cdm::kSuccess);
|
||||
}
|
||||
|
||||
TEST_F(CdmTest, GetEmptyMetrics) {
|
||||
std::string metrics;
|
||||
Cdm::Status status = cdm_->getMetrics(&metrics);
|
||||
@@ -2691,6 +2728,72 @@ TEST_F(CdmIndividualizationTest, NoLoadWithoutProvisioning) {
|
||||
EXPECT_EQ(Cdm::kNeedsDeviceCertificate, cdm_->load(kBogusSessionId));
|
||||
}
|
||||
|
||||
TEST_F(CdmIndividualizationTest, CastReceiverProvisionAndSign) {
|
||||
if (!CheckProvisioningSupport()) {
|
||||
GTEST_SKIP() << "OEMCrypto does not support provisioning";
|
||||
}
|
||||
if (!wvoec::global_features.cast_receiver) {
|
||||
GTEST_SKIP() << "OEMCrypto does not support Cast Receiver functionality";
|
||||
}
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(ProvisionDevice());
|
||||
|
||||
// Perform Cast provisioning and store the public cert and wrapped private key
|
||||
// for use later in the test
|
||||
std::string cast_prov_request;
|
||||
ASSERT_EQ(cdm_->getCastProvisioningRequest(&cast_prov_request),
|
||||
Cdm::kSuccess);
|
||||
|
||||
const std::string cast_prov_response =
|
||||
GetProvisioningResponse(cast_prov_request);
|
||||
ASSERT_FALSE(cast_prov_response.empty());
|
||||
|
||||
std::string cert;
|
||||
std::string wrapped_key;
|
||||
ASSERT_EQ(cdm_->handleCastProvisioningResponse(cast_prov_response, &cert,
|
||||
&wrapped_key),
|
||||
Cdm::kSuccess);
|
||||
EXPECT_FALSE(cert.empty());
|
||||
ASSERT_FALSE(wrapped_key.empty());
|
||||
|
||||
// Perform cast signing using the wrapped private key
|
||||
std::string signature;
|
||||
ASSERT_EQ(cdm_->castSign(wrapped_key, kFakeCastMessage, &signature),
|
||||
Cdm::kSuccess);
|
||||
|
||||
// Verify the signature against the public key
|
||||
//
|
||||
// 1) Load the public key into an RSA struct
|
||||
std::unique_ptr<BIO, void (*)(BIO*)> bio(BIO_new(BIO_s_mem()), BIO_free_all);
|
||||
ASSERT_NE(bio, nullptr);
|
||||
ASSERT_EQ(BIO_write(bio.get(), cert.data(), static_cast<int>(cert.size())),
|
||||
static_cast<int>(cert.size()));
|
||||
|
||||
std::unique_ptr<X509, void (*)(X509*)> x509(
|
||||
PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr), X509_free);
|
||||
ASSERT_NE(x509, nullptr);
|
||||
|
||||
std::unique_ptr<EVP_PKEY, void (*)(EVP_PKEY*)> pubkey(
|
||||
X509_get_pubkey(x509.get()), EVP_PKEY_free);
|
||||
ASSERT_NE(pubkey, nullptr);
|
||||
|
||||
// Not a std::unique_ptr because "get0" returns a non-owning pointer.
|
||||
RSA* const rsa = EVP_PKEY_get0_RSA(pubkey.get());
|
||||
ASSERT_NE(rsa, nullptr);
|
||||
|
||||
// 2) Decrypt the signature
|
||||
std::string decrypted_digest(RSA_size(rsa), 0);
|
||||
const int decrypted_length = RSA_public_decrypt(
|
||||
static_cast<int>(signature.size()),
|
||||
reinterpret_cast<const uint8_t*>(signature.data()),
|
||||
reinterpret_cast<uint8_t*>(&decrypted_digest[0]), rsa, RSA_PKCS1_PADDING);
|
||||
ASSERT_GT(decrypted_length, 0);
|
||||
|
||||
// 3) Compare the digests
|
||||
decrypted_digest.resize(decrypted_length);
|
||||
EXPECT_EQ(decrypted_digest, kFakeCastMessage);
|
||||
}
|
||||
|
||||
class CdmProv40IndividualizationTest : public CdmTest {};
|
||||
|
||||
TEST_F(CdmProv40IndividualizationTest, NeedsOemCertProvisioning) {
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
int argc = 1;
|
||||
testing::InitGoogleTest(&argc, argv);
|
||||
|
||||
XCTAssertEqual(widevine::PerfTestMain(&widevine::Cdm::initialize, &widevine::Cdm::create, cert), 0);
|
||||
XCTAssertEqual(widevine::PerfTestMain(&widevine::Cdm::initialize, &widevine::Cdm::create, ""), 0);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
Reference in New Issue
Block a user