Add Provisioning 4 support

Widevine provisioning 4 support is added in this patch.
This commit is contained in:
Lu Chen
2025-02-25 13:49:37 -08:00
parent 5f209e6980
commit 41829ca1e5
37 changed files with 2915 additions and 356 deletions

View File

@@ -13,8 +13,10 @@
#include "cas_status.h"
#include "cas_util.h"
#include "device_files.pb.h"
#include "file_util.h"
#include "license_protocol.pb.h"
#include "mock_crypto_session.h"
#include "mock_file.h"
#include "string_conversions.h"
namespace wvcas {
@@ -22,6 +24,8 @@ namespace {
using ::testing::_;
using ::testing::AllOf;
using ::testing::AtLeast;
using ::testing::ByMove;
using ::testing::DoAll;
using ::testing::Eq;
using ::testing::Invoke;
@@ -32,6 +36,7 @@ using ::testing::Return;
using ::testing::ReturnRef;
using ::testing::SetArgPointee;
using ::testing::SetArgReferee;
using ::testing::SetArrayArgument;
using ::testing::StrictMock;
using wvutil::Base64Decode;
@@ -41,6 +46,7 @@ using wvutil::Base64SafeEncodeNoPad;
using video_widevine_client::sdk::DeviceCertificate;
using video_widevine_client::sdk::File;
using video_widevine_client::sdk::HashedFile;
using video_widevine_client::sdk::OemCertificate;
static constexpr char kKeyboxToken[] = "KeyBoxToken";
static constexpr char kExpectedRenewalRequest[] = "ExpectedRenewalRequest";
@@ -76,6 +82,14 @@ static constexpr char kKeyOemCryptoSecurityPatchLevel[] =
"oem_crypto_security_patch_level";
static constexpr char kRenewalSereverURL[] = "ExpectedRenewalURL";
static constexpr char kCoreMessage[] = "CoreMessage";
constexpr char kOemCertificateFilePath[] =
"/data/vendor/mediacas/IDM/widevine/oemcert.bin";
constexpr char kBccToken[] = "Bcc token";
constexpr char kPublicKeyToCertify[] = "public_key_to_certify";
constexpr char kOemCertificate[] = "oem cert";
constexpr char kOemCertPrivateKey[] = "wrapped_private_key";
constexpr char kDrmCertificateFilePath[] =
"/data/vendor/mediacas/IDM/widevine/cert.bin";
typedef StrictMock<MockCryptoSession> StrictMockCryptoSession;
@@ -93,13 +107,17 @@ class MockPolicyEngine : public wvcas::PolicyEngine {
MOCK_CONST_METHOD0(IsExpired, bool());
MOCK_CONST_METHOD0(CanPersist, bool());
MOCK_CONST_METHOD0(always_include_client_id, bool());
MOCK_METHOD(void, RestorePlaybackTimes,
(int64_t playback_start_time, int64_t last_playback_time,
int64_t grace_period_end_time),
(override));
};
typedef StrictMock<MockPolicyEngine> StrictMockPolicyEngine;
class TestCasLicense : public wvcas::CasLicense {
public:
explicit TestCasLicense() {}
~TestCasLicense() override{};
~TestCasLicense() override {};
std::unique_ptr<wvcas::PolicyEngine> GetPolicyEngine() override {
policy_engine_ = pass_thru_.get();
return std::move(pass_thru_);
@@ -124,6 +142,8 @@ class CasLicenseTest : public ::testing::TestWithParam<bool> {
std::shared_ptr<StrictMockCryptoSession> strict_mock_;
std::string wrapped_rsa_key_;
std::string device_certificate_;
wvutil::FileSystem file_system_;
CryptoWrappedKey wrapped_private_key_;
};
std::string CasLicenseTest::CreateProvisioningResponse() {
@@ -138,9 +158,14 @@ std::string CasLicenseTest::CreateProvisioningResponse() {
response.set_device_rsa_key(kDeviceRsaKey);
response.set_device_rsa_key_iv(kDeviceRsaKeyIV);
video_widevine::SignedDrmCertificate signed_device_cert;
video_widevine::DrmCertificate device_cert;
device_cert.set_serial_number("serial_number");
device_cert.SerializeToString(signed_device_cert.mutable_drm_certificate());
signed_device_cert.SerializeToString(response.mutable_device_certificate());
response.SerializeToString(signed_message.mutable_message());
std::vector<uint8_t> b64_message(signed_message.ByteSize());
std::vector<uint8_t> b64_message(signed_message.ByteSizeLong());
signed_message.SerializeToArray(&b64_message[0], b64_message.size());
return kJsonStartSubstr + Base64SafeEncodeNoPad(b64_message) + kJsonEndSubstr;
@@ -207,6 +232,21 @@ std::string CreateLicenseFileData() {
return hashed_file.SerializeAsString();
}
std::string CreateOemCertFileData() {
File file;
file.set_type(File::OEM_CERTIFICATE);
OemCertificate* oem_certificate = file.mutable_oem_certificate();
oem_certificate->set_certificate(kOemCertificate);
oem_certificate->set_wrapped_private_key(kOemCertPrivateKey);
oem_certificate->set_key_type(OemCertificate::ECC);
HashedFile hashed_file;
file.SerializeToString(hashed_file.mutable_file());
Hash(hashed_file.file(), hashed_file.mutable_hash());
return hashed_file.SerializeAsString();
}
TEST_F(CasLicenseTest, GenerateDeviceProvisioningRequest) {
strict_mock_ = std::make_shared<StrictMockCryptoSession>();
TestCasLicense cas_license;
@@ -238,7 +278,7 @@ TEST_F(CasLicenseTest, GenerateDeviceProvisioningRequest) {
.WillOnce(Return(wvcas::CasStatusCode::kNoError));
wvcas::CasStatus status = cas_license.GenerateDeviceProvisioningRequest(
&serialized_provisioning_request);
file_system_, &serialized_provisioning_request);
EXPECT_EQ(wvcas::CasStatusCode::kNoError, status.status_code());
// Verify the provisioning request.
@@ -263,6 +303,127 @@ TEST_F(CasLicenseTest, GenerateDeviceProvisioningRequest) {
provisioning_request.nonce().data()));
}
TEST_F(CasLicenseTest, GenerateDeviceProvisioning4FirstStageRequest) {
strict_mock_ = std::make_shared<StrictMockCryptoSession>();
TestCasLicense cas_license;
EXPECT_CALL(*cas_license.policy_engine_, initialize(_, _));
EXPECT_EQ(cas_license.initialize(strict_mock_, nullptr).status_code(),
wvcas::CasStatusCode::kNoError);
EXPECT_CALL(*strict_mock_, provisioning_method())
.WillRepeatedly(Return(wvcas::BootCertificateChain));
EXPECT_CALL(*strict_mock_, GetBootCertificateChain(NotNull(), NotNull()))
.WillOnce(
DoAll(SetArgPointee<0>(kBccToken), Return(CasStatusCode::kNoError)));
EXPECT_CALL(*strict_mock_, APIVersion(NotNull()))
.WillRepeatedly(
DoAll(SetArgPointee<0>(18), Return(CasStatusCode::kNoError)));
EXPECT_CALL(*strict_mock_, GetSecurityPatchLevel()).WillOnce(Return(1));
EXPECT_CALL(*strict_mock_, GetBuildInformation(NotNull()))
.WillOnce(DoAll(SetArgPointee<0>("build info"), Return(true)));
EXPECT_CALL(*strict_mock_, GenerateCertificateKeyPair)
.WillOnce(DoAll(SetArgPointee<0>(kPublicKeyToCertify),
SetArgPointee<1>("public_key_signature"),
SetArgPointee<2>("wrapped_private_key"),
SetArgPointee<3>(CryptoWrappedKey::kEcc),
Return(wvcas::CasStatusCode::kNoError)));
EXPECT_CALL(*strict_mock_,
PrepareAndSignProvisioningRequest(_, NotNull(), NotNull(), _, _))
.WillOnce(DoAll(SetArgPointee<1>("core message"),
SetArgPointee<2>(kExpectedSignature),
SetArgReferee<3>(false),
Return(wvcas::CasStatusCode::kNoError)));
std::string serialized_provisioning_request;
wvcas::CasStatus status = cas_license.GenerateDeviceProvisioningRequest(
file_system_, &serialized_provisioning_request);
EXPECT_EQ(status.status_code(), wvcas::CasStatusCode::kNoError);
// Verify the provisioning request.
video_widevine::SignedProvisioningMessage signed_message;
auto data = Base64SafeDecode(serialized_provisioning_request);
EXPECT_TRUE(signed_message.ParseFromArray(&data[0], data.size()));
EXPECT_EQ(signed_message.signature(), kExpectedSignature);
EXPECT_EQ(signed_message.protocol_version(),
video_widevine::SignedProvisioningMessage::PROVISIONING_40);
video_widevine::ProvisioningRequest provisioning_request;
EXPECT_TRUE(provisioning_request.ParseFromString(signed_message.message()));
EXPECT_TRUE(provisioning_request.has_encrypted_client_id());
EXPECT_EQ(provisioning_request.certificate_public_key().public_key(),
kPublicKeyToCertify);
EXPECT_EQ(provisioning_request.certificate_public_key().key_type(),
video_widevine::PublicKeyToCertify::ECC);
}
TEST_F(CasLicenseTest, GenerateDeviceProvisioning4SecondStageRequest) {
strict_mock_ = std::make_shared<StrictMockCryptoSession>();
TestCasLicense cas_license;
EXPECT_CALL(*cas_license.policy_engine_, initialize(_, _));
EXPECT_EQ(cas_license.initialize(strict_mock_, nullptr).status_code(),
wvcas::CasStatusCode::kNoError);
// Setup the test OEM certificate.
const std::string data = CreateOemCertFileData();
const int data_size = data.size();
auto file = std::make_unique<wvutil::MockFile>();
EXPECT_CALL(*file, Read(NotNull(), Eq(data_size)))
.Times(1)
.WillOnce(DoAll(SetArrayArgument<0>(data.begin(), data.end()),
Return(data_size)));
wvutil::MockFileSystem file_system;
EXPECT_CALL(file_system, Exists(std::string(kOemCertificateFilePath)))
.Times(AtLeast(1))
.WillRepeatedly(Return(true));
EXPECT_CALL(file_system, FileSize(std::string(kOemCertificateFilePath)))
.Times(AtLeast(1))
.WillOnce(Return(data_size));
EXPECT_CALL(file_system, Open(std::string(kOemCertificateFilePath), _))
.WillOnce(Return(ByMove(std::move(file))));
EXPECT_CALL(*strict_mock_, provisioning_method())
.WillRepeatedly(Return(wvcas::BootCertificateChain));
EXPECT_CALL(*strict_mock_, GetBootCertificateChain).Times(0);
EXPECT_CALL(*strict_mock_, GetSecurityPatchLevel()).WillOnce(Return(1));
EXPECT_CALL(*strict_mock_, GetBuildInformation(NotNull()))
.WillOnce(DoAll(SetArgPointee<0>("build info"), Return(true)));
EXPECT_CALL(*strict_mock_, APIVersion(NotNull()))
.WillRepeatedly(
DoAll(SetArgPointee<0>(18), Return(CasStatusCode::kNoError)));
EXPECT_CALL(*strict_mock_, GenerateCertificateKeyPair)
.WillOnce(DoAll(SetArgPointee<0>(kPublicKeyToCertify),
SetArgPointee<1>("public_key_signature"),
SetArgPointee<2>("wrapped_private_key"),
SetArgPointee<3>(CryptoWrappedKey::kEcc),
Return(wvcas::CasStatusCode::kNoError)));
EXPECT_CALL(*strict_mock_,
PrepareAndSignProvisioningRequest(_, NotNull(), NotNull(), _, _))
.WillOnce(DoAll(SetArgPointee<1>("core message"),
SetArgPointee<2>(kExpectedSignature),
SetArgReferee<3>(false),
Return(wvcas::CasStatusCode::kNoError)));
EXPECT_CALL(*strict_mock_, LoadOemCertificatePrivateKey)
.WillOnce(Return(wvcas::CasStatusCode::kNoError));
std::string serialized_provisioning_request;
wvcas::CasStatus status = cas_license.GenerateDeviceProvisioningRequest(
file_system, &serialized_provisioning_request);
EXPECT_EQ(status.status_code(), wvcas::CasStatusCode::kNoError);
// Verify the provisioning request.
video_widevine::SignedProvisioningMessage signed_message;
auto decoded_provisioning_request =
Base64SafeDecode(serialized_provisioning_request);
EXPECT_TRUE(signed_message.ParseFromArray(
&decoded_provisioning_request[0], decoded_provisioning_request.size()));
EXPECT_EQ(signed_message.signature(), kExpectedSignature);
EXPECT_EQ(signed_message.protocol_version(),
video_widevine::SignedProvisioningMessage::PROVISIONING_40);
video_widevine::ProvisioningRequest provisioning_request;
EXPECT_TRUE(provisioning_request.ParseFromString(signed_message.message()));
EXPECT_TRUE(provisioning_request.has_encrypted_client_id());
EXPECT_EQ(provisioning_request.certificate_public_key().public_key(),
kPublicKeyToCertify);
EXPECT_EQ(provisioning_request.certificate_public_key().key_type(),
video_widevine::PublicKeyToCertify::ECC);
}
TEST_F(CasLicenseTest, HandleProvisioningResponse) {
const std::string provisioning_response = CreateProvisioningResponse();
@@ -274,47 +435,34 @@ TEST_F(CasLicenseTest, HandleProvisioningResponse) {
EXPECT_CALL(*strict_mock_, reset())
.WillOnce(Return(wvcas::CasStatusCode::kNoError));
EXPECT_CALL(*strict_mock_, LoadProvisioning(_, _, _, _));
EXPECT_CALL(*strict_mock_, LoadProvisioning(_, _, _, _))
.WillOnce(DoAll(SetArgPointee<3>("private_key"),
Return(wvcas::CasStatusCode::kNoError)));
auto file = std::make_unique<wvutil::MockFile>();
EXPECT_CALL(*file, Write(NotNull(), _))
.Times(1)
.WillOnce([&](const char*, size_t data_size) { return data_size; });
wvutil::MockFileSystem file_system;
EXPECT_CALL(file_system, Open(std::string(kDrmCertificateFilePath), _))
.WillOnce(Return(ByMove(std::move(file))));
wvcas::CasStatus status = cas_license.HandleDeviceProvisioningResponse(
provisioning_response, &device_certificate_, &wrapped_rsa_key_, nullptr);
&file_system, provisioning_response, &device_certificate_,
&wrapped_private_key_);
EXPECT_EQ(wvcas::CasStatusCode::kNoError, status.status_code());
}
TEST_F(CasLicenseTest, HandleProvisioningResponseWithDeviceFileOutput) {
const std::string provisioning_response = CreateProvisioningResponse();
strict_mock_ = std::make_shared<StrictMockCryptoSession>();
TestCasLicense cas_license;
EXPECT_CALL(*cas_license.policy_engine_, initialize(_, _));
EXPECT_EQ(wvcas::CasStatusCode::kNoError,
cas_license.initialize(strict_mock_, nullptr).status_code());
EXPECT_CALL(*strict_mock_, reset())
.WillOnce(Return(wvcas::CasStatusCode::kNoError));
EXPECT_CALL(*strict_mock_, LoadProvisioning(_, _, _, _));
std::string device_cert_file;
wvcas::CasStatus status = cas_license.HandleDeviceProvisioningResponse(
provisioning_response, &device_certificate_, &wrapped_rsa_key_,
&device_cert_file);
EXPECT_EQ(wvcas::CasStatusCode::kNoError, status.status_code());
EXPECT_FALSE(device_cert_file.empty());
}
TEST_F(CasLicenseTest, GenerateEntitlementRequest) {
strict_mock_ = std::make_shared<StrictMockCryptoSession>();
TestCasLicense cas_license;
EXPECT_CALL(*cas_license.policy_engine_, initialize(_, _));
EXPECT_EQ(wvcas::CasStatusCode::kNoError,
cas_license.initialize(strict_mock_, nullptr).status_code());
EXPECT_CALL(*strict_mock_, GetOEMPublicCertificate(_, _))
.WillOnce(Return(wvcas::CasStatusCode::kCryptoSessionError));
EXPECT_CALL(*strict_mock_, GetSecurityPatchLevel()).WillOnce(Return(1));
EXPECT_CALL(*strict_mock_, GetBuildInformation(NotNull()))
.WillOnce(DoAll(SetArgPointee<0>("build info"), Return(true)));
EXPECT_CALL(*strict_mock_, APIVersion(_))
.WillOnce(Return(wvcas::CasStatusCode::kNoError));
EXPECT_CALL(*strict_mock_, GenerateNonce(_))
.WillOnce(Return(wvcas::CasStatusCode::kNoError));
EXPECT_CALL(*strict_mock_,
@@ -322,11 +470,11 @@ TEST_F(CasLicenseTest, GenerateEntitlementRequest) {
.WillOnce(DoAll(SetArgPointee<2>(kExpectedSignature),
SetArgReferee<3>(false),
Return(wvcas::CasStatusCode::kNoError)));
EXPECT_CALL(*strict_mock_, LoadDeviceRSAKey(_, _));
EXPECT_CALL(*strict_mock_, LoadCertificatePrivateKey);
std::string serialized_entitlement_request;
wvcas::CasStatus status = cas_license.GenerateEntitlementRequest(
kInitializationData, device_certificate_, wrapped_rsa_key_,
kInitializationData, device_certificate_, wrapped_private_key_,
wvcas::LicenseType::kStreaming, &serialized_entitlement_request);
EXPECT_EQ(wvcas::CasStatusCode::kNoError, status.status_code());
}
@@ -338,12 +486,11 @@ TEST_F(CasLicenseTest, HandleEntitlementResponse) {
EXPECT_CALL(*cas_license.policy_engine_, initialize(_, _));
EXPECT_EQ(wvcas::CasStatusCode::kNoError,
cas_license.initialize(strict_mock_, nullptr).status_code());
EXPECT_CALL(*strict_mock_, GetOEMPublicCertificate(_, _))
.WillOnce(Return(wvcas::CasStatusCode::kCryptoSessionError));
EXPECT_CALL(*strict_mock_, GetSecurityPatchLevel()).WillOnce(Return(1));
EXPECT_CALL(*strict_mock_, GetBuildInformation(NotNull()))
.WillOnce(DoAll(SetArgPointee<0>("build info"), Return(true)));
EXPECT_CALL(*strict_mock_, APIVersion(_))
.WillOnce(Return(wvcas::CasStatusCode::kNoError));
EXPECT_CALL(*strict_mock_, GenerateNonce(_))
.WillOnce(Return(wvcas::CasStatusCode::kNoError));
EXPECT_CALL(*strict_mock_,
@@ -351,11 +498,11 @@ TEST_F(CasLicenseTest, HandleEntitlementResponse) {
.WillOnce(DoAll(SetArgPointee<2>(kExpectedSignature),
SetArgReferee<3>(false),
Return(wvcas::CasStatusCode::kNoError)));
EXPECT_CALL(*strict_mock_, LoadDeviceRSAKey(_, _));
EXPECT_CALL(*strict_mock_, LoadCertificatePrivateKey);
std::string serialized_entitlement_request;
wvcas::CasStatus status = cas_license.GenerateEntitlementRequest(
kInitializationData, device_certificate_, wrapped_rsa_key_,
kInitializationData, device_certificate_, wrapped_private_key_,
wvcas::LicenseType::kStreaming, &serialized_entitlement_request);
EXPECT_EQ(wvcas::CasStatusCode::kNoError, status.status_code());
@@ -592,7 +739,7 @@ TEST_F(CasLicenseTest, RestoreLicense) {
cas_license.initialize(strict_mock_, nullptr).status_code());
std::string license_file_data = CreateLicenseFileData();
EXPECT_CALL(*strict_mock_, LoadDeviceRSAKey(_, _));
EXPECT_CALL(*strict_mock_, LoadCertificatePrivateKey);
EXPECT_CALL(*strict_mock_, DeriveKeysFromSessionKey(_, _, _, _, _, _))
.WillRepeatedly(Return(wvcas::CasStatusCode::kNoError));
EXPECT_CALL(*strict_mock_, LoadLicense(_, _, _))
@@ -601,9 +748,11 @@ TEST_F(CasLicenseTest, RestoreLicense) {
.WillRepeatedly(Return(wvcas::CasStatusCode::kNoError));
EXPECT_CALL(*cas_license.policy_engine_, SetLicense(_));
EXPECT_CALL(*cas_license.policy_engine_, UpdateLicense(_));
EXPECT_EQ(wvcas::CasStatusCode::kNoError,
cas_license.HandleStoredLicense(wrapped_rsa_key_, license_file_data)
.status_code());
EXPECT_CALL(*cas_license.policy_engine_, RestorePlaybackTimes);
EXPECT_EQ(
wvcas::CasStatusCode::kNoError,
cas_license.HandleStoredLicense(wrapped_private_key_, license_file_data)
.status_code());
}
TEST_F(CasLicenseTest, HandleMultiContentEntitlementResponse) {
@@ -612,8 +761,9 @@ TEST_F(CasLicenseTest, HandleMultiContentEntitlementResponse) {
EXPECT_CALL(*cas_license.policy_engine_, initialize(_, _));
EXPECT_EQ(wvcas::CasStatusCode::kNoError,
cas_license.initialize(strict_mock_, nullptr).status_code());
EXPECT_CALL(*strict_mock_, GetOEMPublicCertificate(_, _))
.WillOnce(Return(wvcas::CasStatusCode::kCryptoSessionError));
EXPECT_CALL(*strict_mock_, GetSecurityPatchLevel()).WillOnce(Return(1));
EXPECT_CALL(*strict_mock_, GetBuildInformation(NotNull()))
.WillOnce(DoAll(SetArgPointee<0>("build info"), Return(true)));
EXPECT_CALL(*strict_mock_, APIVersion(_))
.WillOnce(Return(wvcas::CasStatusCode::kNoError));
EXPECT_CALL(*strict_mock_, GenerateNonce(_))
@@ -623,11 +773,11 @@ TEST_F(CasLicenseTest, HandleMultiContentEntitlementResponse) {
.WillOnce(DoAll(SetArgPointee<2>(kExpectedSignature),
SetArgReferee<3>(false),
Return(wvcas::CasStatusCode::kNoError)));
EXPECT_CALL(*strict_mock_, LoadDeviceRSAKey(_, _));
EXPECT_CALL(*strict_mock_, LoadCertificatePrivateKey);
std::string serialized_entitlement_request;
wvcas::CasStatus status = cas_license.GenerateEntitlementRequest(
kInitializationData, device_certificate_, wrapped_rsa_key_,
kInitializationData, device_certificate_, wrapped_private_key_,
wvcas::LicenseType::kStreaming, &serialized_entitlement_request);
EXPECT_EQ(wvcas::CasStatusCode::kNoError, status.status_code());

View File

@@ -666,7 +666,8 @@ TEST_F(CryptoSessionTest, PrepareAndSignProvisioningRequest) {
DoAll(SetArgPointee<0>(kOemcSessionId), Return(OEMCrypto_SUCCESS)));
EXPECT_EQ(wvcas::CasStatusCode::kNoError,
crypto_session.initialize().status_code());
EXPECT_CALL(nice_oemcrypto_interface_, OEMCrypto_GetProvisioningMethod())
.WillRepeatedly(Return(OEMCrypto_BootCertificateChain));
const std::string message = "message";
std::string core_message;
std::string signature;
@@ -688,6 +689,10 @@ TEST_F(CryptoSessionTest, PrepareAndSignProvisioningRequest) {
.WillOnce(DoAll(
Invoke(this, &CryptoSessionTest::SetOutputCoreMessageAndSignature),
Return(OEMCrypto_SUCCESS)));
EXPECT_CALL(nice_oemcrypto_interface_,
OEMCrypto_GetSignatureHashAlgorithm(kOemcSessionId, NotNull()))
.WillOnce(DoAll(SetArgPointee<1>(OEMCrypto_SHA2_256),
Return(OEMCrypto_SUCCESS)));
EXPECT_EQ(wvcas::CasStatusCode::kNoError,
crypto_session
.PrepareAndSignProvisioningRequest(
@@ -696,7 +701,7 @@ TEST_F(CryptoSessionTest, PrepareAndSignProvisioningRequest) {
.status_code());
EXPECT_EQ(core_message, std::string(kExpectedCoreMessage));
EXPECT_EQ(signature, std::string(kExpectedSignature));
EXPECT_FALSE(should_specify_algorithm);
EXPECT_TRUE(should_specify_algorithm);
}
TEST_F(CryptoSessionTest, LoadProvisioning) {
@@ -785,7 +790,7 @@ TEST_F(CryptoSessionTest, GetOEMPublicCertificate) {
EXPECT_EQ(cert_size, public_cert_length);
}
TEST_F(CryptoSessionTest, LoadDeviceRSAKey) {
TEST_F(CryptoSessionTest, LoadCertificatePrivateKey) {
TestCryptoSession<NiceMock<MockedOEMCrypto> > crypto_session(
nice_oemcrypto_interface_);
EXPECT_CALL(nice_oemcrypto_interface_, OEMCrypto_OpenSession(_))
@@ -795,18 +800,16 @@ TEST_F(CryptoSessionTest, LoadDeviceRSAKey) {
crypto_session.initialize().status_code());
// Test data for use in handling the expected calls.
uint8_t wrapped_rsa_key = 0;
size_t wrapped_rsa_key_length = 75;
std::string key = "key";
CryptoWrappedKey wrapped_key;
wrapped_key.set_key(key);
EXPECT_CALL(
nice_oemcrypto_interface_,
OEMCrypto_LoadDRMPrivateKey(kOemcSessionId, OEMCrypto_RSA_Private_Key,
&wrapped_rsa_key, wrapped_rsa_key_length))
EXPECT_CALL(nice_oemcrypto_interface_,
OEMCrypto_LoadDRMPrivateKey(
kOemcSessionId, OEMCrypto_RSA_Private_Key, _, key.size()))
.WillOnce(Return(OEMCrypto_SUCCESS));
EXPECT_EQ(
wvcas::CasStatusCode::kNoError,
crypto_session.LoadDeviceRSAKey(&wrapped_rsa_key, wrapped_rsa_key_length)
.status_code());
EXPECT_EQ(crypto_session.LoadCertificatePrivateKey(wrapped_key).status_code(),
wvcas::CasStatusCode::kNoError);
}
TEST_F(CryptoSessionTest, GenerateRSASignature) {

View File

@@ -9,6 +9,7 @@
#include <gtest/gtest.h>
#include "crypto_session.h"
#include "crypto_wrapped_key.h"
class MockCryptoSession : public wvcas::CryptoSession {
public:
@@ -30,21 +31,19 @@ class MockCryptoSession : public wvcas::CryptoSession {
const uint8_t* enc_key_context,
uint32_t enc_key_context_length));
MOCK_METHOD5(PrepareAndSignLicenseRequest,
wvcas::CasStatus(const std::string& message,
std::string* core_message,
std::string* signature, bool&,
OEMCrypto_SignatureHashAlgorithm&)
);
wvcas::CasStatus(const std::string& message,
std::string* core_message,
std::string* signature, bool&,
OEMCrypto_SignatureHashAlgorithm&));
MOCK_METHOD3(PrepareAndSignRenewalRequest,
wvcas::CasStatus(const std::string& message,
std::string* core_message,
std::string* signature));
MOCK_METHOD5(PrepareAndSignProvisioningRequest,
wvcas::CasStatus(const std::string& message,
std::string* core_message,
std::string* signature, bool&,
OEMCrypto_SignatureHashAlgorithm&)
);
wvcas::CasStatus(const std::string& message,
std::string* core_message,
std::string* signature, bool&,
OEMCrypto_SignatureHashAlgorithm&));
MOCK_METHOD4(LoadProvisioning,
wvcas::CasStatus(const std::string& signed_message,
const std::string& core_message,
@@ -88,6 +87,18 @@ class MockCryptoSession : public wvcas::CryptoSession {
MOCK_METHOD(wvcas::CasStatus, GetOEMKeyToken,
(OEMCrypto_SESSION entitled_key_session_id,
std::vector<uint8_t>& token));
MOCK_METHOD(wvcas::CasStatus, GetBootCertificateChain,
(std::string * bcc, std::string* additional_signature));
MOCK_METHOD(wvcas::CasStatus, GenerateCertificateKeyPair,
(std::string * public_key, std::string* public_key_signature,
std::string* wrapped_private_key,
wvcas::CryptoWrappedKey::Type* key_type));
MOCK_METHOD(wvcas::CasStatus, LoadOemCertificatePrivateKey,
(const wvcas::CryptoWrappedKey& private_key));
MOCK_METHOD(wvcas::CasStatus, LoadCertificatePrivateKey,
(const wvcas::CryptoWrappedKey& private_key));
MOCK_METHOD(uint8_t, GetSecurityPatchLevel, ());
MOCK_METHOD(bool, GetBuildInformation, (std::string * info));
};
#endif // MOCK_CRYPTO_SESSION_H

41
tests/src/mock_file.h Normal file
View File

@@ -0,0 +1,41 @@
// Copyright 2021 Google LLC. All Rights Reserved. This file and proprietary
// source code may only be used and distributed under the Widevine Master
// License Agreement.
#ifndef WIDEVINE_CAS_MOCK_FILE_H
#define WIDEVINE_CAS_MOCK_FILE_H
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include "file_store.h"
namespace wvutil {
class MockFile : public File {
public:
MockFile() {}
~MockFile() override {}
MOCK_METHOD(ssize_t, Read, (char*, size_t), (override));
MOCK_METHOD(ssize_t, Write, (const char*, size_t), (override));
};
class MockFileSystem : public wvutil::FileSystem {
public:
MockFileSystem() {}
~MockFileSystem() override {}
MOCK_METHOD(std::unique_ptr<File>, Open, (const std::string&, int flags),
(override));
MOCK_METHOD(bool, Exists, (const std::string&), (override));
MOCK_METHOD(bool, Exists, (const std::string&, int*), (override));
MOCK_METHOD(bool, Remove, (const std::string&), (override));
MOCK_METHOD(ssize_t, FileSize, (const std::string&), (override));
MOCK_METHOD(bool, List, (const std::string&, std::vector<std::string>*),
(override));
};
} // namespace wvutil
#endif // MOCK_ECM_PARSER_H

View File

@@ -11,6 +11,7 @@ static constexpr char kGenericModelName[] = "www";
static constexpr char kProductName[] = "WidevineCasTests";
static constexpr char kKeyArchitectureName[] = "architecture_name";
static constexpr char kKeyDeviceName[] = "device_name";
static constexpr char kBuildInfo[] = "build_info";
static constexpr char kOemcPath[] = "cas_oemc_path.so";
namespace wvcas {
@@ -55,6 +56,14 @@ bool Properties::GetDeviceName(std::string* device_name) {
return true;
}
bool Properties::GetBuildInfo(std::string* build_info) {
if (build_info == nullptr) {
return false;
}
*build_info = kBuildInfo;
return true;
}
bool Properties::GetOEMCryptoPath(std::string* path) {
if (path == nullptr) {
return false;

View File

@@ -56,14 +56,15 @@ class MockLicense : public wvcas::CasLicense {
~MockLicense() override {}
MOCK_CONST_METHOD0(IsExpired, bool());
MOCK_METHOD5(GenerateEntitlementRequest,
wvcas::CasStatus(const std::string& init_data,
const std::string& device_certificate,
const std::string& wrapped_rsa_key,
wvcas::LicenseType license_type,
std::string* signed_license_request));
MOCK_METHOD(wvcas::CasStatus, GenerateEntitlementRequest,
(const std::string& init_data,
const std::string& device_certificate,
const CryptoWrappedKey& private_key, LicenseType license_type,
std::string* signed_license_request),
(override));
MOCK_METHOD(wvcas::CasStatus, HandleStoredLicense,
(const std::string&, const std::string&), (override));
(const CryptoWrappedKey& wrapped_private_key, const std::string&),
(override));
MOCK_METHOD2(GenerateEntitlementRenewalRequest,
wvcas::CasStatus(const std::string& device_certificate,
std::string* signed_renewal_request));