Make change and version bump to AV1A.240704.001
Snap for 12047203 from b282ec92b6 to vic-widevine-partner-release
Change-Id: I5b2680f1f99d29c2ab4d24a9b6c80e1a282d97bd
This commit is contained in:
@@ -12,6 +12,7 @@ namespace wvutil {
|
|||||||
class FileSystem;
|
class FileSystem;
|
||||||
} // namespace wvutil
|
} // namespace wvutil
|
||||||
namespace wvcdm {
|
namespace wvcdm {
|
||||||
|
// Forward declarations.
|
||||||
class CryptoSession;
|
class CryptoSession;
|
||||||
class DeviceFiles;
|
class DeviceFiles;
|
||||||
|
|
||||||
@@ -20,6 +21,22 @@ class DeviceFiles;
|
|||||||
// different place.
|
// different place.
|
||||||
class SystemIdExtractor {
|
class SystemIdExtractor {
|
||||||
public:
|
public:
|
||||||
|
// The constructor should be provided all the parameters necessary
|
||||||
|
// to find the system ID. Although certain provisioning methods
|
||||||
|
// may not use all parameters, this class must behave in a way which
|
||||||
|
// makes it as easy as possible to obtain the system ID, all
|
||||||
|
// parameters are required.
|
||||||
|
//
|
||||||
|
// Parameters:
|
||||||
|
// |security_level|
|
||||||
|
// - Requested security level, uses the |crypto_session| handle
|
||||||
|
// to convert to a concrete security level.
|
||||||
|
// |crypto_session|
|
||||||
|
// - Handle into the OEMCrypto platform. If handle is open,
|
||||||
|
// then the session's real security level should match
|
||||||
|
// |security_level|.
|
||||||
|
// |fs|
|
||||||
|
// - File system handle to the global file system.
|
||||||
SystemIdExtractor(RequestedSecurityLevel security_level,
|
SystemIdExtractor(RequestedSecurityLevel security_level,
|
||||||
CryptoSession* crypto_session, wvutil::FileSystem* fs);
|
CryptoSession* crypto_session, wvutil::FileSystem* fs);
|
||||||
virtual ~SystemIdExtractor() {}
|
virtual ~SystemIdExtractor() {}
|
||||||
@@ -30,12 +47,17 @@ class SystemIdExtractor {
|
|||||||
SystemIdExtractor& operator=(const SystemIdExtractor&) = delete;
|
SystemIdExtractor& operator=(const SystemIdExtractor&) = delete;
|
||||||
SystemIdExtractor& operator=(SystemIdExtractor&&) = delete;
|
SystemIdExtractor& operator=(SystemIdExtractor&&) = delete;
|
||||||
|
|
||||||
|
// Extracts the system ID from the appropriate source.
|
||||||
virtual bool ExtractSystemId(uint32_t* system_id);
|
virtual bool ExtractSystemId(uint32_t* system_id);
|
||||||
|
|
||||||
// Extracts the system ID from a keybox key data (aka CA token).
|
// Extracts the system ID from a keybox key data (aka CA token).
|
||||||
static bool ExtractSystemIdFromKeyboxData(const std::string& key_data,
|
static bool ExtractSystemIdFromKeyboxData(const std::string& key_data,
|
||||||
uint32_t* system_id);
|
uint32_t* system_id);
|
||||||
// Extracts the system ID from a serialized OEM certificate.
|
// Extracts the system ID from a serialized OEM certificate.
|
||||||
|
// System ID is expected to be in the manufacturer's intermediate
|
||||||
|
// X.509 certificate from the Widevine-defined X.509 v3
|
||||||
|
// Extension found in the TBSCertificate "extensions" attribute.
|
||||||
|
// See RFC 5280 for X.509 certificate structure.
|
||||||
static bool ExtractSystemIdFromOemCert(const std::string& oem_cert,
|
static bool ExtractSystemIdFromOemCert(const std::string& oem_cert,
|
||||||
uint32_t* system_id);
|
uint32_t* system_id);
|
||||||
|
|
||||||
@@ -44,13 +66,15 @@ class SystemIdExtractor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
// Note: All the internal ExtractSystemId*() methods assume
|
||||||
|
// |system_id| is not null.
|
||||||
|
|
||||||
// Extracts the system ID from keybox-based OEMCrypto implementations.
|
// Extracts the system ID from keybox-based OEMCrypto implementations.
|
||||||
// System ID is expected to be found in the keybox data. Devices
|
// System ID is expected to be found in the keybox data. Devices
|
||||||
// which require OTA keybox provisioning will return a null system ID.
|
// which require OTA keybox provisioning will return a null system ID.
|
||||||
bool ExtractSystemIdProv20(uint32_t* system_id);
|
bool ExtractSystemIdProv20(uint32_t* system_id);
|
||||||
// Extracts the system ID from OEM certificate-based OEMCrypto
|
// Extracts the system ID from OEM certificate-based OEMCrypto
|
||||||
// implementations. System ID is expected to be in the manufacturers
|
// implementations.
|
||||||
// intermediate X.509 certificate.
|
|
||||||
bool ExtractSystemIdProv30(uint32_t* system_id);
|
bool ExtractSystemIdProv30(uint32_t* system_id);
|
||||||
// Extracts the system ID from BCC-based OEMCrypto implementations.
|
// Extracts the system ID from BCC-based OEMCrypto implementations.
|
||||||
// System ID is expected to be found in the stored OEM certificate
|
// System ID is expected to be found in the stored OEM certificate
|
||||||
@@ -59,9 +83,20 @@ class SystemIdExtractor {
|
|||||||
// a null system ID.
|
// a null system ID.
|
||||||
bool ExtractSystemIdProv40(uint32_t* system_id);
|
bool ExtractSystemIdProv40(uint32_t* system_id);
|
||||||
|
|
||||||
|
// Add future extraction methods here.
|
||||||
|
|
||||||
|
// Verifies that if |crypto_session_| is opened, that the
|
||||||
|
// security level is matches the instances |security_level_|.
|
||||||
|
// If unopened, verifies that |security_level_| is a defined
|
||||||
|
// value.
|
||||||
|
// Returns true if security level is valid, false otherwise.
|
||||||
|
bool VerifySecurityLevelExpectations();
|
||||||
|
|
||||||
RequestedSecurityLevel security_level_ = kLevelDefault;
|
RequestedSecurityLevel security_level_ = kLevelDefault;
|
||||||
CryptoSession* crypto_session_ = nullptr;
|
CryptoSession* crypto_session_ = nullptr;
|
||||||
wvutil::FileSystem* fs_ = nullptr;
|
wvutil::FileSystem* fs_ = nullptr;
|
||||||
|
// Test only handle to DeviceFiles. When not null, |fs_| will be
|
||||||
|
// ignored.
|
||||||
DeviceFiles* test_device_files_ = nullptr;
|
DeviceFiles* test_device_files_ = nullptr;
|
||||||
};
|
};
|
||||||
} // namespace wvcdm
|
} // namespace wvcdm
|
||||||
|
|||||||
@@ -18,16 +18,22 @@ constexpr size_t kKeyboxSystemIdOffset = 4;
|
|||||||
// Index of certificate within cerificate chain which contains the
|
// Index of certificate within cerificate chain which contains the
|
||||||
// system ID (0 = leaf/device cert, 1 = intermediate/device family cert).
|
// system ID (0 = leaf/device cert, 1 = intermediate/device family cert).
|
||||||
constexpr size_t kOemCertSystemIdIndex = 1;
|
constexpr size_t kOemCertSystemIdIndex = 1;
|
||||||
// OID of X.509 certificate extension containing the Widevine system ID.
|
// OID of X.509 TBSCertificate extension containing the Widevine
|
||||||
|
// system ID.
|
||||||
const char kWidevineSystemIdExtensionOid[] = "1.3.6.1.4.1.11129.4.1.1";
|
const char kWidevineSystemIdExtensionOid[] = "1.3.6.1.4.1.11129.4.1.1";
|
||||||
|
|
||||||
constexpr size_t kSystemIdLength = sizeof(uint32_t);
|
constexpr size_t kSystemIdLength = sizeof(uint32_t);
|
||||||
|
|
||||||
constexpr bool IsSupportedSecurityLevel(CdmSecurityLevel security_level) {
|
constexpr bool IsSupportedCdmSecurityLevel(CdmSecurityLevel security_level) {
|
||||||
return security_level == kSecurityLevelL1 ||
|
return security_level == kSecurityLevelL1 ||
|
||||||
security_level == kSecurityLevelL2 ||
|
security_level == kSecurityLevelL2 ||
|
||||||
security_level == kSecurityLevelL3;
|
security_level == kSecurityLevelL3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
constexpr bool IsSupportedRequestedSecurityLevel(
|
||||||
|
RequestedSecurityLevel security_level) {
|
||||||
|
return security_level == kLevelDefault || security_level == kLevel3;
|
||||||
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
SystemIdExtractor::SystemIdExtractor(RequestedSecurityLevel security_level,
|
SystemIdExtractor::SystemIdExtractor(RequestedSecurityLevel security_level,
|
||||||
@@ -45,15 +51,21 @@ bool SystemIdExtractor::ExtractSystemId(uint32_t* system_id) {
|
|||||||
LOGE("Output |system_id| is null");
|
LOGE("Output |system_id| is null");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (crypto_session_->GetCachedSystemId(system_id)) {
|
if (!VerifySecurityLevelExpectations()) {
|
||||||
|
// VerifySecurityLevelExpectations() will log details.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (crypto_session_->IsOpen() &&
|
||||||
|
crypto_session_->GetCachedSystemId(system_id)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
CdmClientTokenType type = kClientTokenUninitialized;
|
CdmClientTokenType type = kClientTokenUninitialized;
|
||||||
const CdmResponseType status =
|
const CdmResponseType status =
|
||||||
crypto_session_->GetProvisioningMethod(security_level_, &type);
|
crypto_session_->GetProvisioningMethod(security_level_, &type);
|
||||||
if (status != NO_ERROR) {
|
if (status != NO_ERROR) {
|
||||||
LOGE("Failed to get provisioning method: security_level = %s, status = %d",
|
LOGE("Failed to get provisioning method: security_level = %s, status = %s",
|
||||||
RequestedSecurityLevelToString(security_level_), status.ToInt());
|
RequestedSecurityLevelToString(security_level_),
|
||||||
|
status.ToString().c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
bool success = false;
|
bool success = false;
|
||||||
@@ -90,7 +102,10 @@ bool SystemIdExtractor::ExtractSystemId(uint32_t* system_id) {
|
|||||||
// static
|
// static
|
||||||
bool SystemIdExtractor::ExtractSystemIdFromKeyboxData(
|
bool SystemIdExtractor::ExtractSystemIdFromKeyboxData(
|
||||||
const std::string& key_data, uint32_t* system_id) {
|
const std::string& key_data, uint32_t* system_id) {
|
||||||
if (system_id == nullptr) return false;
|
if (system_id == nullptr) {
|
||||||
|
LOGE("Output |system_id| is null");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (key_data.size() < (kKeyboxSystemIdOffset + kSystemIdLength)) {
|
if (key_data.size() < (kKeyboxSystemIdOffset + kSystemIdLength)) {
|
||||||
LOGE("Keybox data does not contain system ID: key_data_size = %zu",
|
LOGE("Keybox data does not contain system ID: key_data_size = %zu",
|
||||||
key_data.size());
|
key_data.size());
|
||||||
@@ -106,7 +121,10 @@ bool SystemIdExtractor::ExtractSystemIdFromKeyboxData(
|
|||||||
// static
|
// static
|
||||||
bool SystemIdExtractor::ExtractSystemIdFromOemCert(const std::string& oem_cert,
|
bool SystemIdExtractor::ExtractSystemIdFromOemCert(const std::string& oem_cert,
|
||||||
uint32_t* system_id) {
|
uint32_t* system_id) {
|
||||||
if (system_id == nullptr) return false;
|
if (system_id == nullptr) {
|
||||||
|
LOGE("Output |system_id| is null");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
return ExtractExtensionValueFromCertificate(oem_cert,
|
return ExtractExtensionValueFromCertificate(oem_cert,
|
||||||
kWidevineSystemIdExtensionOid,
|
kWidevineSystemIdExtensionOid,
|
||||||
kOemCertSystemIdIndex, system_id);
|
kOemCertSystemIdIndex, system_id);
|
||||||
@@ -122,8 +140,9 @@ bool SystemIdExtractor::ExtractSystemIdProv20(uint32_t* system_id) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (status != NO_ERROR) {
|
if (status != NO_ERROR) {
|
||||||
LOGE("Failed to get keybox data: security_level = %s, status = %d",
|
LOGE("Failed to get keybox data: security_level = %s, status = %s",
|
||||||
RequestedSecurityLevelToString(security_level_), status.ToInt());
|
RequestedSecurityLevelToString(security_level_),
|
||||||
|
status.ToString().c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!ExtractSystemIdFromKeyboxData(key_data, system_id)) {
|
if (!ExtractSystemIdFromKeyboxData(key_data, system_id)) {
|
||||||
@@ -138,8 +157,9 @@ bool SystemIdExtractor::ExtractSystemIdProv30(uint32_t* system_id) {
|
|||||||
const CdmResponseType status =
|
const CdmResponseType status =
|
||||||
crypto_session_->GetTokenFromOemCert(security_level_, &oem_cert);
|
crypto_session_->GetTokenFromOemCert(security_level_, &oem_cert);
|
||||||
if (status != NO_ERROR) {
|
if (status != NO_ERROR) {
|
||||||
LOGE("Failed to get OEM certificate: security_level = %s, status = %d",
|
LOGE("Failed to get OEM certificate: security_level = %s, status = %s",
|
||||||
RequestedSecurityLevelToString(security_level_), status.ToInt());
|
RequestedSecurityLevelToString(security_level_),
|
||||||
|
status.ToString().c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!ExtractSystemIdFromOemCert(oem_cert, system_id)) {
|
if (!ExtractSystemIdFromOemCert(oem_cert, system_id)) {
|
||||||
@@ -152,7 +172,7 @@ bool SystemIdExtractor::ExtractSystemIdProv30(uint32_t* system_id) {
|
|||||||
bool SystemIdExtractor::ExtractSystemIdProv40(uint32_t* system_id) {
|
bool SystemIdExtractor::ExtractSystemIdProv40(uint32_t* system_id) {
|
||||||
const CdmSecurityLevel security_level =
|
const CdmSecurityLevel security_level =
|
||||||
crypto_session_->GetSecurityLevel(security_level_);
|
crypto_session_->GetSecurityLevel(security_level_);
|
||||||
if (!IsSupportedSecurityLevel(security_level)) {
|
if (!IsSupportedCdmSecurityLevel(security_level)) {
|
||||||
LOGE("Unsupported security level: %s",
|
LOGE("Unsupported security level: %s",
|
||||||
CdmSecurityLevelToString(security_level));
|
CdmSecurityLevelToString(security_level));
|
||||||
return false;
|
return false;
|
||||||
@@ -160,7 +180,7 @@ bool SystemIdExtractor::ExtractSystemIdProv40(uint32_t* system_id) {
|
|||||||
DeviceFiles real_device_files(fs_);
|
DeviceFiles real_device_files(fs_);
|
||||||
// Mock DeviceFiles for testing.
|
// Mock DeviceFiles for testing.
|
||||||
DeviceFiles& device_files =
|
DeviceFiles& device_files =
|
||||||
(test_device_files_ ? *test_device_files_ : real_device_files);
|
(test_device_files_ != nullptr ? *test_device_files_ : real_device_files);
|
||||||
if (!device_files.Init(security_level)) {
|
if (!device_files.Init(security_level)) {
|
||||||
LOGE("Failed to initialize device files: security_level = %s",
|
LOGE("Failed to initialize device files: security_level = %s",
|
||||||
CdmSecurityLevelToString(security_level));
|
CdmSecurityLevelToString(security_level));
|
||||||
@@ -190,4 +210,48 @@ bool SystemIdExtractor::ExtractSystemIdProv40(uint32_t* system_id) {
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SystemIdExtractor::VerifySecurityLevelExpectations() {
|
||||||
|
if (!IsSupportedRequestedSecurityLevel(security_level_)) {
|
||||||
|
LOGE("Unsupported requested extractor security level: %d",
|
||||||
|
static_cast<int>(security_level_));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!crypto_session_->IsOpen()) {
|
||||||
|
// Any other issues with the security level should be caught and
|
||||||
|
// handled by the respective extractor methods.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// The SystemIdExtractor is intended to work with unopened
|
||||||
|
// CryptoSessions, but does not restrict this.
|
||||||
|
// If the crypto session is open, it is already tied to a
|
||||||
|
// security level; for the extractor work as expected the
|
||||||
|
// session's security level must be the same as extractor's
|
||||||
|
// requested security level.
|
||||||
|
const CdmSecurityLevel session_security_level =
|
||||||
|
crypto_session_->GetSecurityLevel();
|
||||||
|
if (!IsSupportedCdmSecurityLevel(session_security_level)) {
|
||||||
|
LOGE("Failed to get session security level: %s",
|
||||||
|
CdmSecurityLevelToString(session_security_level));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const CdmSecurityLevel extractor_security_level =
|
||||||
|
crypto_session_->GetSecurityLevel(security_level_);
|
||||||
|
if (!IsSupportedCdmSecurityLevel(extractor_security_level)) {
|
||||||
|
LOGE("Failed to get extractor security level: %s",
|
||||||
|
CdmSecurityLevelToString(extractor_security_level));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (session_security_level != extractor_security_level) {
|
||||||
|
LOGE(
|
||||||
|
"Extractor and session security levels do not match: "
|
||||||
|
"session_security_level = %s, extractor_security_level = %s, "
|
||||||
|
"requested_security_level = %s",
|
||||||
|
CdmSecurityLevelToString(session_security_level),
|
||||||
|
CdmSecurityLevelToString(extractor_security_level),
|
||||||
|
RequestedSecurityLevelToString(security_level_));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
} // namespace wvcdm
|
} // namespace wvcdm
|
||||||
|
|||||||
@@ -270,11 +270,13 @@ class MockCryptoSession : public CryptoSession {
|
|||||||
MockCryptoSession(metrics::CryptoMetrics* metrics) : CryptoSession(metrics) {}
|
MockCryptoSession(metrics::CryptoMetrics* metrics) : CryptoSession(metrics) {}
|
||||||
// ~MockCryptoSession() override {}
|
// ~MockCryptoSession() override {}
|
||||||
|
|
||||||
bool IsOpen() override { return true; }
|
bool IsOpen() override { return is_open_; }
|
||||||
CdmSecurityLevel GetSecurityLevel() override { return kSecurityLevelL1; }
|
CdmSecurityLevel GetSecurityLevel() override {
|
||||||
|
return is_open_ ? open_security_level_ : kSecurityLevelUninitialized;
|
||||||
|
}
|
||||||
CdmSecurityLevel GetSecurityLevel(
|
CdmSecurityLevel GetSecurityLevel(
|
||||||
RequestedSecurityLevel security_level) override {
|
RequestedSecurityLevel security_level) override {
|
||||||
return security_level == kLevelDefault ? kSecurityLevelL1
|
return security_level == kLevelDefault ? default_security_level_
|
||||||
: kSecurityLevelL3;
|
: kSecurityLevelL3;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -291,6 +293,16 @@ class MockCryptoSession : public CryptoSession {
|
|||||||
(RequestedSecurityLevel, std::string*), (override));
|
(RequestedSecurityLevel, std::string*), (override));
|
||||||
MOCK_METHOD(CdmResponseType, GetTokenFromOemCert,
|
MOCK_METHOD(CdmResponseType, GetTokenFromOemCert,
|
||||||
(RequestedSecurityLevel, std::string*), (override));
|
(RequestedSecurityLevel, std::string*), (override));
|
||||||
|
|
||||||
|
// These default values should represent good values of a
|
||||||
|
// CryptoSession used for system ID extractions.
|
||||||
|
// Test cases should modify them if needing to test edge cases.
|
||||||
|
|
||||||
|
bool is_open_ = false;
|
||||||
|
// Security level which is returned if the session is opened.
|
||||||
|
CdmSecurityLevel open_security_level_ = kSecurityLevelL1;
|
||||||
|
// Security level of the underlying default OEMCrypto engine.
|
||||||
|
CdmSecurityLevel default_security_level_ = kSecurityLevelL1;
|
||||||
};
|
};
|
||||||
|
|
||||||
class MockDeviceFiles : public DeviceFiles {
|
class MockDeviceFiles : public DeviceFiles {
|
||||||
@@ -328,13 +340,27 @@ class SystemIdExtractorTest : public WvCdmTestBase {
|
|||||||
return extractor;
|
return extractor;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExpectProvisioningType(CdmClientTokenType type) {
|
void ExpectProvisioningType(CdmClientTokenType type, bool is_open = false) {
|
||||||
EXPECT_CALL(*crypto_session_, GetCachedSystemId).WillOnce(Return(false));
|
crypto_session_->is_open_ = is_open;
|
||||||
|
if (is_open) {
|
||||||
|
// Extractor should only call GetCachedSystemId if session
|
||||||
|
// is opened.
|
||||||
|
EXPECT_CALL(*crypto_session_, GetCachedSystemId).WillOnce(Return(false));
|
||||||
|
} else {
|
||||||
|
EXPECT_CALL(*crypto_session_, GetCachedSystemId).Times(0);
|
||||||
|
}
|
||||||
|
|
||||||
EXPECT_CALL(*crypto_session_, GetProvisioningMethod(_, NotNull()))
|
EXPECT_CALL(*crypto_session_, GetProvisioningMethod(_, NotNull()))
|
||||||
.WillOnce(
|
.WillOnce(
|
||||||
DoAll(SetArgPointee<1>(type), Return(CdmResponseType(NO_ERROR))));
|
DoAll(SetArgPointee<1>(type), Return(CdmResponseType(NO_ERROR))));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ExpectFromCached(uint32_t system_id) {
|
||||||
|
crypto_session_->is_open_ = true;
|
||||||
|
EXPECT_CALL(*crypto_session_, GetCachedSystemId(NotNull()))
|
||||||
|
.WillOnce(DoAll(SetArgPointee<0>(system_id), Return(true)));
|
||||||
|
}
|
||||||
|
|
||||||
void ExpectSet(uint32_t system_id) {
|
void ExpectSet(uint32_t system_id) {
|
||||||
EXPECT_CALL(*crypto_session_, SetSystemId(system_id));
|
EXPECT_CALL(*crypto_session_, SetSystemId(system_id));
|
||||||
}
|
}
|
||||||
@@ -361,8 +387,7 @@ TEST_F(SystemIdExtractorTest, ExtractSystemIdFromKeyboxData) {
|
|||||||
|
|
||||||
TEST_F(SystemIdExtractorTest, CachedSystemId) {
|
TEST_F(SystemIdExtractorTest, CachedSystemId) {
|
||||||
const uint32_t kCachedSystemId = 1234;
|
const uint32_t kCachedSystemId = 1234;
|
||||||
EXPECT_CALL(*crypto_session_, GetCachedSystemId(NotNull()))
|
ExpectFromCached(kCachedSystemId);
|
||||||
.WillOnce(DoAll(SetArgPointee<0>(kCachedSystemId), Return(true)));
|
|
||||||
auto extractor = CreateExtractor(kLevelDefault);
|
auto extractor = CreateExtractor(kLevelDefault);
|
||||||
ASSERT_TRUE(extractor);
|
ASSERT_TRUE(extractor);
|
||||||
uint32_t system_id;
|
uint32_t system_id;
|
||||||
@@ -372,6 +397,7 @@ TEST_F(SystemIdExtractorTest, CachedSystemId) {
|
|||||||
|
|
||||||
TEST_F(SystemIdExtractorTest, SetSystemIdMetrics) {
|
TEST_F(SystemIdExtractorTest, SetSystemIdMetrics) {
|
||||||
const uint32_t kSystemId = 4321;
|
const uint32_t kSystemId = 4321;
|
||||||
|
crypto_session_->is_open_ = true; // Must be open to set system ID.
|
||||||
crypto_session_->SetSystemIdBase(kSystemId);
|
crypto_session_->SetSystemIdBase(kSystemId);
|
||||||
drm_metrics::WvCdmMetrics::CryptoMetrics metrics_proto;
|
drm_metrics::WvCdmMetrics::CryptoMetrics metrics_proto;
|
||||||
crypto_metrics_.Serialize(&metrics_proto);
|
crypto_metrics_.Serialize(&metrics_proto);
|
||||||
@@ -380,8 +406,54 @@ TEST_F(SystemIdExtractorTest, SetSystemIdMetrics) {
|
|||||||
EXPECT_EQ(recorded_system_id, kSystemId);
|
EXPECT_EQ(recorded_system_id, kSystemId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(SystemIdExtractorTest,
|
||||||
|
BadSecurityLevelExpectations_InvalidRequestedSecurityLevel) {
|
||||||
|
// Extractor caller is using an invalid requested security level.
|
||||||
|
const RequestedSecurityLevel kBadRequestedSecurityLevel =
|
||||||
|
static_cast<RequestedSecurityLevel>(9999);
|
||||||
|
auto extractor = CreateExtractor(kBadRequestedSecurityLevel);
|
||||||
|
uint32_t system_id;
|
||||||
|
EXPECT_FALSE(extractor->ExtractSystemId(&system_id));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(SystemIdExtractorTest,
|
||||||
|
BadSecurityLevelExpectations_UnexpectedSessionSecurityLevel) {
|
||||||
|
// CryptoSession is returning an unexpected result for its security
|
||||||
|
// level.
|
||||||
|
crypto_session_->is_open_ = true;
|
||||||
|
crypto_session_->open_security_level_ = kSecurityLevelUnknown;
|
||||||
|
auto extractor = CreateExtractor(kLevelDefault);
|
||||||
|
uint32_t system_id;
|
||||||
|
EXPECT_FALSE(extractor->ExtractSystemId(&system_id));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(SystemIdExtractorTest,
|
||||||
|
BadSecurityLevelExpectations_UnexpectedExtractorSecurityLevel) {
|
||||||
|
// OEMCrypto (via session-less CryptoSession) is returning an
|
||||||
|
// unexpected result for the default security level.
|
||||||
|
crypto_session_->is_open_ = true;
|
||||||
|
crypto_session_->default_security_level_ = kSecurityLevelUnknown;
|
||||||
|
auto extractor = CreateExtractor(kLevelDefault);
|
||||||
|
uint32_t system_id;
|
||||||
|
EXPECT_FALSE(extractor->ExtractSystemId(&system_id));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(SystemIdExtractorTest,
|
||||||
|
BadSecurityLevelExpectations_MismatchedSessionSecurityLevel) {
|
||||||
|
// CryptoSession and Extractor are different security levels.
|
||||||
|
crypto_session_->is_open_ = true;
|
||||||
|
// Case 1: Session L3, extractor L1
|
||||||
|
crypto_session_->open_security_level_ = kSecurityLevelL3;
|
||||||
|
auto extractor = CreateExtractor(kLevelDefault);
|
||||||
|
uint32_t system_id;
|
||||||
|
EXPECT_FALSE(extractor->ExtractSystemId(&system_id));
|
||||||
|
// Case 2: Session L1, extractor L3
|
||||||
|
crypto_session_->open_security_level_ = kSecurityLevelL1;
|
||||||
|
extractor = CreateExtractor(kLevel3);
|
||||||
|
EXPECT_FALSE(extractor->ExtractSystemId(&system_id));
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(SystemIdExtractorTest, GetProvisioningMethod_Failed) {
|
TEST_F(SystemIdExtractorTest, GetProvisioningMethod_Failed) {
|
||||||
EXPECT_CALL(*crypto_session_, GetCachedSystemId).WillOnce(Return(false));
|
|
||||||
EXPECT_CALL(*crypto_session_, GetProvisioningMethod(_, NotNull()))
|
EXPECT_CALL(*crypto_session_, GetProvisioningMethod(_, NotNull()))
|
||||||
.WillOnce(Return(CdmResponseType(UNKNOWN_ERROR)));
|
.WillOnce(Return(CdmResponseType(UNKNOWN_ERROR)));
|
||||||
auto extractor = CreateExtractor(kLevelDefault);
|
auto extractor = CreateExtractor(kLevelDefault);
|
||||||
@@ -420,6 +492,19 @@ TEST_F(SystemIdExtractorTest, KeyboxDevice_Success) {
|
|||||||
EXPECT_EQ(system_id, kKeyboxSystemId);
|
EXPECT_EQ(system_id, kKeyboxSystemId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(SystemIdExtractorTest, KeyboxDevice_Success_WithCallToGetCached) {
|
||||||
|
ExpectProvisioningType(kClientTokenKeybox, /* is_open = */ true);
|
||||||
|
EXPECT_CALL(*crypto_session_, GetTokenFromKeybox(kLevelDefault, NotNull()))
|
||||||
|
.WillOnce(DoAll(SetArgPointee<1>(kKeyboxDataStr),
|
||||||
|
Return(CdmResponseType(NO_ERROR))));
|
||||||
|
ExpectSet(kKeyboxSystemId);
|
||||||
|
auto extractor = CreateExtractor(kLevelDefault);
|
||||||
|
ASSERT_TRUE(extractor);
|
||||||
|
uint32_t system_id;
|
||||||
|
EXPECT_TRUE(extractor->ExtractSystemId(&system_id));
|
||||||
|
EXPECT_EQ(system_id, kKeyboxSystemId);
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(SystemIdExtractorTest, KeyboxDevice_NeedsOtaKeyboxProvisioning) {
|
TEST_F(SystemIdExtractorTest, KeyboxDevice_NeedsOtaKeyboxProvisioning) {
|
||||||
ExpectProvisioningType(kClientTokenKeybox);
|
ExpectProvisioningType(kClientTokenKeybox);
|
||||||
EXPECT_CALL(*crypto_session_, GetTokenFromKeybox(kLevelDefault, NotNull()))
|
EXPECT_CALL(*crypto_session_, GetTokenFromKeybox(kLevelDefault, NotNull()))
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
AV1A.240629.001
|
AV1A.240704.001
|
||||||
|
|||||||
Reference in New Issue
Block a user