Source release 17.1.0

This commit is contained in:
John "Juce" Bruce
2022-07-07 17:14:31 -07:00
parent 8c17574083
commit 694cf6fb25
2233 changed files with 272026 additions and 223371 deletions

View File

@@ -1,14 +1,16 @@
// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
// source code may only be used and distributed under the Widevine Master
// License Agreement.
// source code may only be used and distributed under the Widevine License
// Agreement.
#include <memory>
#include "cdm_session.h"
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include "cdm_session.h"
#include <memory>
#include "crypto_key.h"
#include "crypto_wrapped_key.h"
#include "properties.h"
#include "service_certificate.h"
#include "string_conversions.h"
@@ -35,7 +37,7 @@ namespace {
const std::string kEmptyString;
const std::string kToken = a2bs_hex(
const std::string kToken = wvutil::a2bs_hex(
"0AAE02080212107E0A892DEEB021E7AF696B938BB1D5B1188B85AD9D05228E023082010A02"
"82010100DBEDF2BFB0EC98213766E65049B9AB176FA4B1FBFBB2A0C96C87D9F2B895E0ED77"
"93BDA057E6BC3E0CA2348BC6831E03609445CA4D418CB98EAC98FFC87AB2364CE76BA26BEE"
@@ -71,7 +73,7 @@ const std::string kToken = a2bs_hex(
"8CD5A9DF6E3D3A99B806F6D60991358C5BE77117D4F3168F3348E9A048539F892F4D783152"
"C7A8095224AA56B78C5CF7BD1AB1B179C0C0D11E3C3BAC84C141A00191321E3ACC17242E68"
"3C");
const std::string kWrappedKey = a2bs_hex(
const std::string kWrappedKeyData = wvutil::a2bs_hex(
"3B84252DD84F1A710365014A114507FFFA3DD404625D61D1EEC7C3A39D72CB8D9318ADE9DA"
"05D69F9776DAFDA49A97BC30E84CA275925DFD98CA04F7DB23465103A224852192DE232902"
"99FF82024F5CCA7716ACA9BE0B56348BA16B9E3136D73789C842CB2ECA4820DDAAF59CCB9B"
@@ -108,47 +110,52 @@ const std::string kWrappedKey = a2bs_hex(
"33EF70621A98184DDAB5E14BC971CF98CF6C91A37FFA83B00AD3BCABBAAB2DEF1C52F43003"
"E74C92B44F9205D22262FB47948654229DE1920F8EDF96A19A88A1CA1552F8856FB4CBF83B"
"AA3348419159D207F65FCE9C1A500C6818");
const CryptoWrappedKey kWrappedKey = {CryptoWrappedKey::kRsa, kWrappedKeyData};
class MockDeviceFiles : public DeviceFiles {
public:
MockDeviceFiles() : DeviceFiles(nullptr) {}
MOCK_METHOD1(Init, bool(CdmSecurityLevel));
MOCK_METHOD5(RetrieveCertificate,
bool(bool, std::string*, std::string*, std::string*, uint32_t*));
MOCK_METHOD(bool, Init, (CdmSecurityLevel), (override));
MOCK_METHOD(DeviceFiles::CertificateState, RetrieveCertificate,
(bool, std::string*, CryptoWrappedKey*, std::string*, uint32_t*),
(override));
MOCK_METHOD(bool, HasCertificate, (bool), (override));
};
class MockUsageTableHeader : public UsageTableHeader {
public:
MockUsageTableHeader() : UsageTableHeader() {}
MOCK_METHOD3(UpdateEntry, CdmResponseType(uint32_t usage_entry_number,
CryptoSession* crypto_session,
CdmUsageEntry* usage_entry));
MOCK_METHOD(CdmResponseType, UpdateEntry,
(uint32_t usage_entry_number, CryptoSession* crypto_session,
CdmUsageEntry* usage_entry),
(override));
};
class MockCryptoSession : public TestCryptoSession {
public:
MockCryptoSession(metrics::CryptoMetrics* crypto_metrics)
: TestCryptoSession(crypto_metrics) {
// By default, call the concrete implementation of GetUsageSupportType.
ON_CALL(*this, GetUsageSupportType(_))
// By default, call the concrete implementation of HasUsageInfoSupport.
ON_CALL(*this, HasUsageInfoSupport(_))
.WillByDefault(
Invoke(this, &MockCryptoSession::BaseGetUsageSupportType));
Invoke(this, &MockCryptoSession::BaseHasUsageInfoSupport));
}
MOCK_METHOD1(GetClientToken, bool(std::string*));
MOCK_METHOD1(GetProvisioningToken, CdmResponseType(std::string*));
MOCK_METHOD0(GetPreProvisionTokenType, CdmClientTokenType());
MOCK_METHOD0(GetSecurityLevel, CdmSecurityLevel());
MOCK_METHOD0(Open, CdmResponseType());
MOCK_METHOD1(Open, CdmResponseType(SecurityLevel));
MOCK_METHOD1(LoadCertificatePrivateKey, CdmResponseType(const std::string&));
MOCK_METHOD0(DeleteAllUsageReports, CdmResponseType());
MOCK_METHOD1(GetUsageSupportType, CdmResponseType(CdmUsageSupportType* type));
MOCK_METHOD0(GetUsageTableHeader, UsageTableHeader*());
MOCK_METHOD(CdmResponseType, GetProvisioningToken,
(std::string*, std::string*), (override));
MOCK_METHOD(CdmClientTokenType, GetPreProvisionTokenType, (), (override));
MOCK_METHOD(CdmSecurityLevel, GetSecurityLevel, (), (override));
MOCK_METHOD(CdmResponseType, Open, (), (override));
MOCK_METHOD(CdmResponseType, Open, (wvcdm::RequestedSecurityLevel),
(override));
MOCK_METHOD(CdmResponseType, LoadCertificatePrivateKey,
(const CryptoWrappedKey&), (override));
MOCK_METHOD(bool, HasUsageInfoSupport, (bool*), (override));
MOCK_METHOD(UsageTableHeader*, GetUsageTableHeader, (), (override));
CdmResponseType BaseGetUsageSupportType(CdmUsageSupportType* type) {
return CryptoSession::GetUsageSupportType(type);
bool BaseHasUsageInfoSupport(bool* has_support) {
return CryptoSession::HasUsageInfoSupport(has_support);
}
};
@@ -164,10 +171,10 @@ class MockCdmLicense : public CdmLicense {
public:
MockCdmLicense(const CdmSessionId& session_id) : CdmLicense(session_id) {}
MOCK_METHOD7(Init,
bool(const std::string&, CdmClientTokenType, const std::string&,
bool, const std::string&, CryptoSession*, PolicyEngine*));
MOCK_METHOD0(provider_session_token, std::string());
MOCK_METHOD(bool, Init,
(bool, const std::string&, CryptoSession*, PolicyEngine*),
(override));
MOCK_METHOD(std::string, provider_session_token, (), (override));
};
} // namespace
@@ -214,20 +221,13 @@ TEST_F(CdmSessionTest, InitWithBuiltInCertificate) {
EXPECT_CALL(*crypto_session_, GetSecurityLevel())
.InSequence(crypto_session_seq)
.WillOnce(Return(level));
EXPECT_CALL(*crypto_session_, GetPreProvisionTokenType())
.WillOnce(Return(kClientTokenDrmCert));
EXPECT_CALL(*file_handle_,
RetrieveCertificate(false, NotNull(), NotNull(), NotNull(), _))
.WillOnce(DoAll(SetArgPointee<1>(kToken), SetArgPointee<2>(kWrappedKey),
Return(true)));
EXPECT_CALL(*crypto_session_, LoadCertificatePrivateKey(StrEq(kWrappedKey)))
.InSequence(crypto_session_seq)
.WillOnce(Return(NO_ERROR));
EXPECT_CALL(*file_handle_, Init(Eq(level))).WillOnce(Return(true));
EXPECT_CALL(*license_parser_,
Init(Eq(kToken), Eq(kClientTokenDrmCert), Eq(kEmptyString), false,
Eq(kEmptyString), Eq(crypto_session_), Eq(policy_engine_)))
EXPECT_CALL(*file_handle_, HasCertificate(false)).WillOnce(Return(true));
EXPECT_CALL(*license_parser_, Init(false, Eq(kEmptyString),
Eq(crypto_session_), Eq(policy_engine_)))
.WillOnce(Return(true));
EXPECT_CALL(*license_parser_, provider_session_token())
.WillRepeatedly(Return("Mock provider session token"));
ASSERT_EQ(NO_ERROR, cdm_session_->Init(nullptr));
}
@@ -241,20 +241,13 @@ TEST_F(CdmSessionTest, InitWithCertificate) {
EXPECT_CALL(*crypto_session_, GetSecurityLevel())
.InSequence(crypto_session_seq)
.WillOnce(Return(level));
EXPECT_CALL(*crypto_session_, GetPreProvisionTokenType())
.WillOnce(Return(kClientTokenKeybox));
EXPECT_CALL(*file_handle_, Init(Eq(level))).WillOnce(Return(true));
EXPECT_CALL(*file_handle_,
RetrieveCertificate(false, NotNull(), NotNull(), NotNull(), _))
.WillOnce(DoAll(SetArgPointee<1>(kToken), SetArgPointee<2>(kWrappedKey),
Return(true)));
EXPECT_CALL(*crypto_session_, LoadCertificatePrivateKey(StrEq(kWrappedKey)))
.InSequence(crypto_session_seq)
.WillOnce(Return(NO_ERROR));
EXPECT_CALL(*license_parser_,
Init(Eq(kToken), Eq(kClientTokenDrmCert), Eq(kEmptyString), false,
Eq(kEmptyString), Eq(crypto_session_), Eq(policy_engine_)))
EXPECT_CALL(*file_handle_, HasCertificate(false)).WillOnce(Return(true));
EXPECT_CALL(*license_parser_, Init(false, Eq(kEmptyString),
Eq(crypto_session_), Eq(policy_engine_)))
.WillOnce(Return(true));
EXPECT_CALL(*license_parser_, provider_session_token())
.WillRepeatedly(Return("Mock provider session token"));
ASSERT_EQ(NO_ERROR, cdm_session_->Init(nullptr));
}
@@ -268,20 +261,13 @@ TEST_F(CdmSessionTest, ReInitFail) {
EXPECT_CALL(*crypto_session_, GetSecurityLevel())
.InSequence(crypto_session_seq)
.WillOnce(Return(level));
EXPECT_CALL(*crypto_session_, GetPreProvisionTokenType())
.WillOnce(Return(kClientTokenKeybox));
EXPECT_CALL(*file_handle_, Init(Eq(level))).WillOnce(Return(true));
EXPECT_CALL(*file_handle_,
RetrieveCertificate(false, NotNull(), NotNull(), NotNull(), _))
.WillOnce(DoAll(SetArgPointee<1>(kToken), SetArgPointee<2>(kWrappedKey),
Return(true)));
EXPECT_CALL(*crypto_session_, LoadCertificatePrivateKey(StrEq(kWrappedKey)))
.InSequence(crypto_session_seq)
.WillOnce(Return(NO_ERROR));
EXPECT_CALL(*license_parser_,
Init(Eq(kToken), Eq(kClientTokenDrmCert), Eq(kEmptyString), false,
Eq(kEmptyString), Eq(crypto_session_), Eq(policy_engine_)))
EXPECT_CALL(*file_handle_, HasCertificate(false)).WillOnce(Return(true));
EXPECT_CALL(*license_parser_, Init(false, Eq(kEmptyString),
Eq(crypto_session_), Eq(policy_engine_)))
.WillOnce(Return(true));
EXPECT_CALL(*license_parser_, provider_session_token())
.WillRepeatedly(Return("Mock provider session token"));
ASSERT_EQ(NO_ERROR, cdm_session_->Init(nullptr));
ASSERT_NE(NO_ERROR, cdm_session_->Init(nullptr));
@@ -290,29 +276,12 @@ TEST_F(CdmSessionTest, ReInitFail) {
TEST_F(CdmSessionTest, InitFailCryptoError) {
EXPECT_CALL(*crypto_session_, Open(Eq(kLevelDefault)))
.WillOnce(Return(UNKNOWN_ERROR));
EXPECT_CALL(*license_parser_, provider_session_token())
.WillRepeatedly(Return("Mock provider session token"));
ASSERT_EQ(UNKNOWN_ERROR, cdm_session_->Init(nullptr));
}
TEST_F(CdmSessionTest, InitNeedsProvisioning) {
Sequence crypto_session_seq;
CdmSecurityLevel level = kSecurityLevelL1;
EXPECT_CALL(*crypto_session_, Open(Eq(kLevelDefault)))
.InSequence(crypto_session_seq)
.WillOnce(Return(NO_ERROR));
EXPECT_CALL(*crypto_session_, GetSecurityLevel())
.InSequence(crypto_session_seq)
.WillOnce(Return(level));
EXPECT_CALL(*crypto_session_, GetPreProvisionTokenType())
.WillOnce(Return(kClientTokenKeybox));
EXPECT_CALL(*file_handle_, Init(Eq(level))).WillOnce(Return(true));
EXPECT_CALL(*file_handle_,
RetrieveCertificate(false, NotNull(), NotNull(), NotNull(), _))
.WillOnce(Return(false));
ASSERT_EQ(NEED_PROVISIONING, cdm_session_->Init(nullptr));
}
TEST_F(CdmSessionTest, UpdateUsageEntry) {
// Setup common expectations for initializing the CdmSession object.
Sequence crypto_session_seq;
@@ -323,35 +292,24 @@ TEST_F(CdmSessionTest, UpdateUsageEntry) {
EXPECT_CALL(*crypto_session_, GetSecurityLevel())
.InSequence(crypto_session_seq)
.WillOnce(Return(level));
EXPECT_CALL(*crypto_session_, GetPreProvisionTokenType())
.WillOnce(Return(kClientTokenKeybox));
EXPECT_CALL(*file_handle_, Init(Eq(level))).WillOnce(Return(true));
EXPECT_CALL(*file_handle_,
RetrieveCertificate(false, NotNull(), NotNull(), NotNull(), _))
.WillOnce(DoAll(SetArgPointee<1>(kToken), SetArgPointee<2>(kWrappedKey),
Return(true)));
EXPECT_CALL(*crypto_session_, LoadCertificatePrivateKey(StrEq(kWrappedKey)))
.InSequence(crypto_session_seq)
.WillOnce(Return(NO_ERROR));
EXPECT_CALL(*file_handle_, HasCertificate(false)).WillOnce(Return(true));
EXPECT_CALL(*crypto_session_, GetUsageTableHeader())
.WillOnce(Return(&usage_table_header_));
EXPECT_CALL(*license_parser_,
Init(Eq(kToken), Eq(kClientTokenDrmCert), Eq(kEmptyString), false,
Eq(kEmptyString), Eq(crypto_session_), Eq(policy_engine_)))
EXPECT_CALL(*license_parser_, Init(false, Eq(kEmptyString),
Eq(crypto_session_), Eq(policy_engine_)))
.WillOnce(Return(true));
// Set up mocks and expectations for the UpdateUsageEntryInformation call.
EXPECT_CALL(*crypto_session_, GetUsageSupportType(_))
.WillRepeatedly(
DoAll(SetArgPointee<0>(kUsageEntrySupport), Return(NO_ERROR)));
EXPECT_CALL(*crypto_session_, HasUsageInfoSupport(_))
.WillRepeatedly(DoAll(SetArgPointee<0>(true), Return(true)));
EXPECT_CALL(*license_parser_, provider_session_token())
.WillRepeatedly(Return("Mock provider session token"));
EXPECT_CALL(usage_table_header_, UpdateEntry(_, NotNull(), NotNull()))
.WillRepeatedly(Return(NO_ERROR));
EXPECT_EQ(NO_ERROR, cdm_session_->Init(nullptr));
EXPECT_EQ(kUsageEntrySupport, cdm_session_->get_usage_support_type())
<< "Usage support type: " << cdm_session_->get_usage_support_type();
EXPECT_TRUE(cdm_session_->supports_usage_info());
EXPECT_EQ(NO_ERROR, cdm_session_->UpdateUsageEntryInformation());
// Verify the UsageEntry metric is set.
@@ -363,7 +321,7 @@ TEST_F(CdmSessionTest, UpdateUsageEntry) {
metrics.crypto_metrics().usage_table_header_update_entry_time_us().size(),
0)
<< "Missing update usage entry metric. Metrics: "
<< wvcdm::b2a_hex(serialized_metrics);
<< wvutil::b2a_hex(serialized_metrics);
}
} // namespace wvcdm