Source release v3.5.0
This commit is contained in:
74
cdm/cdm.gyp
74
cdm/cdm.gyp
@@ -8,7 +8,7 @@
|
||||
{
|
||||
'variables': {
|
||||
# Override if you intend to link against a different OEMCrypto API version.
|
||||
'oemcrypto_version%': 12,
|
||||
'oemcrypto_version%': 13,
|
||||
|
||||
# Override if you can't depend on OpenSSL for privacy features.
|
||||
# If set to 'dummy', privacy mode in the CDM will fail.
|
||||
@@ -42,11 +42,11 @@
|
||||
# 3) protobuf_config == 'source' (default)
|
||||
# Build protobuf and protoc from source.
|
||||
# Specify the path to the protobuf source in protobuf_source.
|
||||
# Make sure that a valid config.h for your target is in the source tree.
|
||||
'protobuf_config%': 'source',
|
||||
'protobuf_source%': '../third_party/protobuf',
|
||||
'protoc_host_target%': 'dummy',
|
||||
}, # variables
|
||||
'includes': ['core.gypi'], # Get list of core source files.
|
||||
'conditions': [
|
||||
['protobuf_config=="source"', {
|
||||
# Include protobuf targets used by protobuf_config=='source'
|
||||
@@ -58,23 +58,33 @@
|
||||
'target_name': 'license_protocol',
|
||||
'type': 'static_library',
|
||||
'standalone_static_library': 1,
|
||||
'includes': ['../third_party/protoc.gypi'],
|
||||
'sources': [
|
||||
'../core/src/license_protocol.proto',
|
||||
],
|
||||
'variables': {
|
||||
'proto_in_dir': '../core/src',
|
||||
},
|
||||
'includes': ['../third_party/protoc.gypi'],
|
||||
},
|
||||
{
|
||||
'target_name': 'device_files',
|
||||
'type': 'static_library',
|
||||
'standalone_static_library': 1,
|
||||
'includes': ['../third_party/protoc.gypi'],
|
||||
'sources': ['../core/src/device_files.proto',],
|
||||
'variables': {
|
||||
'proto_in_dir': '../core/src',
|
||||
},
|
||||
},
|
||||
{
|
||||
'target_name': 'metrics_proto',
|
||||
'type': 'static_library',
|
||||
'standalone_static_library': 1,
|
||||
'includes': ['../third_party/protoc.gypi'],
|
||||
'sources': ['../metrics/src/metrics.proto',],
|
||||
'variables': {
|
||||
'proto_in_dir': '../metrics/src',
|
||||
},
|
||||
},
|
||||
{
|
||||
'target_name': 'widevine_cdm_core',
|
||||
@@ -83,71 +93,29 @@
|
||||
'dependencies': [
|
||||
'device_files',
|
||||
'license_protocol',
|
||||
'metrics_proto',
|
||||
],
|
||||
'include_dirs': [
|
||||
'../core/include',
|
||||
'../metrics/include',
|
||||
'../oemcrypto/include',
|
||||
'../third_party/jsmn',
|
||||
],
|
||||
'direct_dependent_settings': {
|
||||
'include_dirs': [
|
||||
'../core/include',
|
||||
'../metrics/include',
|
||||
'../oemcrypto/include',
|
||||
],
|
||||
},
|
||||
'sources': [
|
||||
'../core/include/buffer_reader.h',
|
||||
'../core/include/cdm_client_property_set.h',
|
||||
'../core/include/cdm_engine.h',
|
||||
'../core/include/cdm_session.h',
|
||||
'../core/include/cdm_session_map.h',
|
||||
'../core/include/certificate_provisioning.h',
|
||||
'../core/include/clock.h',
|
||||
'../core/include/crypto_key.h',
|
||||
'../core/include/crypto_session.h',
|
||||
'../core/include/device_files.h',
|
||||
'../core/include/file_store.h',
|
||||
'../core/include/initialization_data.h',
|
||||
'../core/include/license_key_status.h',
|
||||
'../core/include/license.h',
|
||||
'../core/include/lock.h',
|
||||
'../core/include/log.h',
|
||||
'../core/include/oemcrypto_adapter.h',
|
||||
'../core/include/policy_engine.h',
|
||||
'../core/include/privacy_crypto.h',
|
||||
'../core/include/properties.h',
|
||||
'../core/include/scoped_ptr.h',
|
||||
'../core/include/service_certificate.h',
|
||||
'../core/include/string_conversions.h',
|
||||
'../core/include/wv_cdm_constants.h',
|
||||
'../core/include/wv_cdm_event_listener.h',
|
||||
'../core/include/wv_cdm_types.h',
|
||||
'../core/src/buffer_reader.cpp',
|
||||
'../core/src/cdm_engine.cpp',
|
||||
'../core/src/cdm_session.cpp',
|
||||
'../core/src/cdm_session_map.cpp',
|
||||
'../core/src/certificate_provisioning.cpp',
|
||||
'../core/src/crypto_session.cpp',
|
||||
'../core/src/device_files.cpp',
|
||||
'../core/src/initialization_data.cpp',
|
||||
'../core/src/license_key_status.cpp',
|
||||
'../core/src/license.cpp',
|
||||
'<@(wvcdm_sources)',
|
||||
'../core/src/oemcrypto_adapter_static.cpp',
|
||||
'../core/src/policy_engine.cpp',
|
||||
'../core/src/privacy_crypto_<(privacy_crypto_impl).cpp',
|
||||
'../core/src/properties.cpp',
|
||||
'../core/src/service_certificate.cpp',
|
||||
'../core/src/string_conversions.cpp',
|
||||
'../third_party/jsmn/jsmn.h',
|
||||
'../third_party/jsmn/jsmn.c',
|
||||
],
|
||||
'conditions': [
|
||||
['oemcrypto_version < 9', {
|
||||
'sources': [
|
||||
# Include APIs introduced in v9.
|
||||
'../core/src/oemcrypto_adapter_static_v9.cpp',
|
||||
],
|
||||
}],
|
||||
['oemcrypto_version < 10', {
|
||||
'sources': [
|
||||
# Include APIs introduced in v10.
|
||||
@@ -166,6 +134,12 @@
|
||||
'../core/src/oemcrypto_adapter_static_v12.cpp',
|
||||
],
|
||||
}],
|
||||
['oemcrypto_version < 13', {
|
||||
'sources': [
|
||||
# Include APIs introduced in v13.
|
||||
'../core/src/oemcrypto_adapter_static_v13.cpp',
|
||||
],
|
||||
}],
|
||||
['privacy_crypto_impl=="openssl"', {
|
||||
'conditions': [
|
||||
['openssl_config == "target"', {
|
||||
@@ -192,12 +166,14 @@
|
||||
'widevine_cdm_core',
|
||||
'device_files',
|
||||
'license_protocol',
|
||||
'metrics_proto',
|
||||
],
|
||||
# Without this, library deps do not propagate from the protocol targets
|
||||
# up to the shared lib or executable above.
|
||||
'export_dependent_settings': [
|
||||
'device_files',
|
||||
'license_protocol',
|
||||
'metrics_proto',
|
||||
],
|
||||
'defines': ['CDM_IMPLEMENTATION'],
|
||||
'include_dirs': [
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
# Refer to the distribution package's README for details.
|
||||
{
|
||||
'variables': {
|
||||
'oemcrypto_lib%': '',
|
||||
'oemcrypto_stubs%': '',
|
||||
'openssl_config%': 'system',
|
||||
'openssl_target%': '',
|
||||
@@ -22,9 +21,6 @@
|
||||
'test/test_host.cpp',
|
||||
'test/test_host.h',
|
||||
],
|
||||
'variables': {
|
||||
'cdm_dir': '..',
|
||||
},
|
||||
'includes': [
|
||||
'oemcrypto_unittests.gypi',
|
||||
'core_unittests.gypi',
|
||||
@@ -35,6 +31,7 @@
|
||||
],
|
||||
'dependencies': [
|
||||
'cdm.gyp:widevine_ce_cdm_shared',
|
||||
'cdm.gyp:widevine_cdm_core',
|
||||
'../third_party/gmock.gyp:gmock',
|
||||
'../third_party/gmock.gyp:gtest',
|
||||
],
|
||||
@@ -45,13 +42,28 @@
|
||||
],
|
||||
}, {
|
||||
'conditions': [
|
||||
['oemcrypto_lib==""', {
|
||||
['oemcrypto_lib=="mock"', {
|
||||
'dependencies': [
|
||||
'../oemcrypto/mock/oec_mock.gyp:oec_mock',
|
||||
],
|
||||
}, {
|
||||
'libraries': [
|
||||
'<(oemcrypto_lib)',
|
||||
}],
|
||||
['oemcrypto_lib=="level3"', {
|
||||
'sources': [
|
||||
# The test impl of OEMCrypto_Level3FileSystem and its factory.
|
||||
'test/level3_file_system_ce_test.h',
|
||||
'test/level3_file_system_ce_test.cpp',
|
||||
'test/level3_file_system_test_factory.cpp',
|
||||
],
|
||||
'conditions': [
|
||||
['oemcrypto_adapter=="static"', {
|
||||
'dependencies': [
|
||||
'../oemcrypto/level3/oec_level3.gyp:oec_level3_static',
|
||||
],
|
||||
}, {
|
||||
'dependencies': [
|
||||
'../oemcrypto/level3/oec_level3.gyp:oec_level3_dynamic',
|
||||
],
|
||||
}],
|
||||
],
|
||||
}],
|
||||
],
|
||||
|
||||
@@ -3,6 +3,9 @@
|
||||
# Include this in any custom unit test targets.
|
||||
# Does not include the device certificate or the test runner main.
|
||||
{
|
||||
'cflags_cc+': [
|
||||
'-Wno-inconsistent-missing-override',
|
||||
],
|
||||
'sources': [
|
||||
'../core/test/http_socket.cpp',
|
||||
'../core/test/license_request.cpp',
|
||||
|
||||
59
cdm/core.gypi
Normal file
59
cdm/core.gypi
Normal file
@@ -0,0 +1,59 @@
|
||||
# Copyright 2017 Google Inc. All Rights Reserved.
|
||||
#
|
||||
# Include this in any custom unit test targets.
|
||||
# Does not include the test runner main.
|
||||
{
|
||||
'variables': {
|
||||
'wvcdm_sources': [
|
||||
'../core/include/buffer_reader.h',
|
||||
'../core/include/cdm_client_property_set.h',
|
||||
'../core/include/cdm_engine.h',
|
||||
'../core/include/cdm_session.h',
|
||||
'../core/include/cdm_session_map.h',
|
||||
'../core/include/certificate_provisioning.h',
|
||||
'../core/include/clock.h',
|
||||
'../core/include/crypto_key.h',
|
||||
'../core/include/crypto_session.h',
|
||||
'../core/include/device_files.h',
|
||||
'../core/include/file_store.h',
|
||||
'../core/include/initialization_data.h',
|
||||
'../core/include/license_key_status.h',
|
||||
'../core/include/license.h',
|
||||
'../core/include/lock.h',
|
||||
'../core/include/log.h',
|
||||
'../core/include/oemcrypto_adapter.h',
|
||||
'../core/include/policy_engine.h',
|
||||
'../core/include/privacy_crypto.h',
|
||||
'../core/include/properties.h',
|
||||
'../core/include/scoped_ptr.h',
|
||||
'../core/include/service_certificate.h',
|
||||
'../core/include/string_conversions.h',
|
||||
'../core/include/wv_cdm_constants.h',
|
||||
'../core/include/wv_cdm_event_listener.h',
|
||||
'../core/include/wv_cdm_types.h',
|
||||
'../core/include/usage_table_header.h',
|
||||
'../core/src/buffer_reader.cpp',
|
||||
'../core/src/cdm_engine.cpp',
|
||||
'../core/src/cdm_session.cpp',
|
||||
'../core/src/cdm_session_map.cpp',
|
||||
'../core/src/certificate_provisioning.cpp',
|
||||
'../core/src/crypto_session.cpp',
|
||||
'../core/src/device_files.cpp',
|
||||
'../core/src/initialization_data.cpp',
|
||||
'../core/src/license.cpp',
|
||||
'../core/src/license_key_status.cpp',
|
||||
'../core/src/policy_engine.cpp',
|
||||
'../core/src/privacy_crypto_openssl.cpp',
|
||||
'../core/src/properties.cpp',
|
||||
'../core/src/service_certificate.cpp',
|
||||
'../core/src/string_conversions.cpp',
|
||||
'../core/src/usage_table_header.cpp',
|
||||
'../metrics/src/counter_metric.cpp',
|
||||
'../metrics/src/distribution.cpp',
|
||||
'../metrics/src/event_metric.cpp',
|
||||
'../metrics/src/metrics_collections.cpp',
|
||||
'../metrics/src/timer_metric.cpp',
|
||||
'../metrics/src/value_metric.cpp',
|
||||
],
|
||||
},
|
||||
}
|
||||
@@ -5,6 +5,7 @@
|
||||
{
|
||||
'sources': [
|
||||
'../core/test/base64_test.cpp',
|
||||
'../core/test/buffer_reader_test.cpp',
|
||||
'../core/test/cdm_engine_test.cpp',
|
||||
'../core/test/cdm_session_unittest.cpp',
|
||||
'../core/test/config_test_env.cpp',
|
||||
@@ -12,28 +13,34 @@
|
||||
# '../core/test/generic_crypto_unittest.cpp', # currently keybox only
|
||||
'../core/test/http_socket.cpp',
|
||||
'../core/test/initialization_data_unittest.cpp',
|
||||
'../core/test/license_keys_unittest.cpp',
|
||||
'../core/test/license_request.cpp',
|
||||
'../core/test/license_unittest.cpp',
|
||||
'../core/test/license_keys_unittest.cpp',
|
||||
'../core/test/policy_engine_unittest.cpp',
|
||||
'../core/test/policy_engine_constraints_unittest.cpp',
|
||||
'../core/test/policy_engine_unittest.cpp',
|
||||
'../core/test/service_certificate_unittest.cpp',
|
||||
'../core/test/shared_ptr_test.cpp',
|
||||
'../core/test/test_printers.cpp',
|
||||
'../core/test/url_request.cpp',
|
||||
'../core/test/usage_table_header_unittest.cpp',
|
||||
'../metrics/test/counter_metric_unittest.cpp',
|
||||
'../metrics/test/distribution_unittest.cpp',
|
||||
'../metrics/test/event_metric_unittest.cpp',
|
||||
'../metrics/test/value_metric_unittest.cpp',
|
||||
],
|
||||
'include_dirs': [
|
||||
'../cdm/include',
|
||||
'../core/include',
|
||||
'../core/test',
|
||||
'../metrics/include',
|
||||
],
|
||||
'defines': [
|
||||
'UNIT_TEST',
|
||||
'CORE_TESTS',
|
||||
],
|
||||
'dependencies': [
|
||||
# This gypi may be included from outside this folder, and dependencies in
|
||||
# a gypi are relative to the gyp file doing the including.
|
||||
# cdm_dir is a variable the including file must set to help us find the
|
||||
# correct path.
|
||||
'<(cdm_dir)/cdm/cdm.gyp:license_protocol',
|
||||
'cdm.gyp:metrics_proto',
|
||||
'cdm.gyp:device_files',
|
||||
],
|
||||
'conditions': [
|
||||
# OpenSSL needed for http_socket
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
// Widevine CE CDM Version
|
||||
#define CDM_VERSION "v3.4.1-0-gb429ebdf-ce"
|
||||
#define CDM_VERSION "v3.5.0-0-gc0ea5d51-ce"
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
// Copyright 2015 Google Inc. All Rights Reserved.
|
||||
// TODO: Import to core/, use everywhere.
|
||||
#ifndef WVCDM_CDM_OVERRIDE_H_
|
||||
#define WVCDM_CDM_OVERRIDE_H_
|
||||
|
||||
#define GCC_HAS_OVERRIDE ( \
|
||||
(__GNUC__ > 4) || \
|
||||
(__GNUC__ == 4 && __GNUC_MINOR__ >= 7) \
|
||||
)
|
||||
|
||||
#if !defined(DISABLE_CPP_11) && \
|
||||
(defined(COMPILER_MSVC) || defined(__clang__) || GCC_HAS_OVERRIDE)
|
||||
#define OVERRIDE override
|
||||
#else
|
||||
#define OVERRIDE
|
||||
#endif
|
||||
|
||||
#endif // WVCDM_CDM_OVERRIDE_H_
|
||||
@@ -3,16 +3,28 @@
|
||||
# Include this in any custom unit test targets.
|
||||
# Does not include the test runner main.
|
||||
{
|
||||
'variables': {
|
||||
# Label as 'static' or 'dynamic' to use the respective OEMCrypto adapter.
|
||||
'oemcrypto_adapter%': 'static',
|
||||
# Choose OEMCrypto library to compile in (mock, level3, vendor).
|
||||
'oemcrypto_lib%': 'mock',
|
||||
},
|
||||
'sources': [
|
||||
'../oemcrypto/test/oec_device_features.cpp',
|
||||
'../oemcrypto/test/oec_session_util.cpp',
|
||||
'../oemcrypto/test/oemcrypto_session_tests_helper.cpp',
|
||||
'../oemcrypto/test/oemcrypto_test.cpp',
|
||||
'../test/auth/test_keybox.cpp',
|
||||
'../test/auth/test_rsa_key.cpp',
|
||||
'../test/auth/test_oem_cert.cpp',
|
||||
'../test/auth/test_service_cert.cpp',
|
||||
],
|
||||
'include_dirs': [
|
||||
'../core/include', # log.h
|
||||
'../oemcrypto/include',
|
||||
'../oemcrypto/mock/src', # oemcrypto_key_mock.h
|
||||
'../oemcrypto/test',
|
||||
'../test/auth',
|
||||
],
|
||||
'defines': [
|
||||
'OEMCRYPTO_TESTS',
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "license.h"
|
||||
#include "log.h"
|
||||
#include "properties.h"
|
||||
#include "service_certificate.h"
|
||||
#include "string_conversions.h"
|
||||
#include "wv_cdm_constants.h"
|
||||
#include "wv_cdm_event_listener.h"
|
||||
@@ -212,7 +213,7 @@ class CdmImpl : public Cdm,
|
||||
|
||||
virtual void OnSessionKeysChange(const CdmSessionId& session_id,
|
||||
const CdmKeyStatusMap& keys_status,
|
||||
bool has_new_usable_key) OVERRIDE;
|
||||
bool /* has_new_usable_key */) OVERRIDE;
|
||||
|
||||
virtual void OnExpirationUpdate(const CdmSessionId& session_id,
|
||||
int64_t new_expiry_time_seconds) OVERRIDE;
|
||||
@@ -285,13 +286,16 @@ Cdm::Status CdmImpl::setServiceCertificate(const std::string& certificate) {
|
||||
return kTypeError;
|
||||
}
|
||||
|
||||
// Check for properly signed and well-formed certificate.
|
||||
// Keep results. NOTE: an empty certificate should be accepted here.
|
||||
CdmResponseType status = cdm_engine_.SetServiceCertificate(certificate);
|
||||
// Verify that the certificate is properly signed and well-formed.
|
||||
ServiceCertificate service_certificate;
|
||||
CdmResponseType status = service_certificate.Init(certificate);
|
||||
if (status != NO_ERROR) {
|
||||
LOGE("Invalid service certificate! Error code = %d", status);
|
||||
return kTypeError;
|
||||
}
|
||||
// TODO(gmorgan): remove when provisioning service certificate is added
|
||||
cdm_engine_.SetServiceCertificate(certificate);
|
||||
property_set_.set_service_certificate(certificate);
|
||||
return kSuccess;
|
||||
}
|
||||
|
||||
@@ -301,8 +305,7 @@ Cdm::Status CdmImpl::getServiceCertificateRequest(std::string* message) {
|
||||
"string return parameter not supplied");
|
||||
return kTypeError;
|
||||
}
|
||||
CdmKeyMessage request_message;
|
||||
if (!cdm_engine_.GetServiceCertificateRequest(message)) {
|
||||
if (!ServiceCertificate::GetRequest(message)) {
|
||||
LOGE("Unable to return service certificate request!");
|
||||
message->clear();
|
||||
return kTypeError;
|
||||
@@ -317,13 +320,12 @@ Cdm::Status CdmImpl::parseServiceCertificateResponse(
|
||||
"string return parameter not supplied");
|
||||
return kTypeError;
|
||||
}
|
||||
if (cdm_engine_.ParseServiceCertificateResponse(response, certificate) !=
|
||||
NO_ERROR) {
|
||||
if (ServiceCertificate::ParseResponse(response, certificate) != NO_ERROR) {
|
||||
LOGE("Failure parsing service certificate response!");
|
||||
certificate->clear();
|
||||
return kTypeError;
|
||||
}
|
||||
return kSuccess;
|
||||
return setServiceCertificate(*certificate);
|
||||
}
|
||||
|
||||
bool CdmImpl::isProvisioned() {
|
||||
@@ -1017,7 +1019,7 @@ Cdm::Status CdmImpl::genericEncrypt(
|
||||
LOGE("No such session: %s", session_id.c_str());
|
||||
return kSessionNotFound;
|
||||
}
|
||||
if (result == KEY_NOT_FOUND_3 || result == KEY_ERROR_1) {
|
||||
if (result == KEY_NOT_FOUND_3 || result == NEED_KEY) {
|
||||
LOGE("Key Error: %s", session_id.c_str());
|
||||
return kNoKey;
|
||||
}
|
||||
@@ -1045,7 +1047,7 @@ Cdm::Status CdmImpl::genericDecrypt(
|
||||
LOGE("No such session: %s", session_id.c_str());
|
||||
return kSessionNotFound;
|
||||
}
|
||||
if (result == KEY_NOT_FOUND_4 || result == KEY_ERROR_2) {
|
||||
if (result == KEY_NOT_FOUND_4 || result == NEED_KEY) {
|
||||
LOGE("Key Error: %s", session_id.c_str());
|
||||
return kNoKey;
|
||||
}
|
||||
@@ -1073,7 +1075,7 @@ Cdm::Status CdmImpl::genericSign(
|
||||
LOGE("No such session: %s", session_id.c_str());
|
||||
return kSessionNotFound;
|
||||
}
|
||||
if (result == KEY_NOT_FOUND_5 || result == KEY_ERROR_3) {
|
||||
if (result == KEY_NOT_FOUND_5 || result == NEED_KEY) {
|
||||
LOGE("Key Error: %s", session_id.c_str());
|
||||
return kNoKey;
|
||||
}
|
||||
@@ -1101,7 +1103,7 @@ Cdm::Status CdmImpl::genericVerify(
|
||||
LOGE("No such session: %s", session_id.c_str());
|
||||
return kSessionNotFound;
|
||||
}
|
||||
if (result == KEY_NOT_FOUND_6 || result == KEY_ERROR_4) {
|
||||
if (result == KEY_NOT_FOUND_6 || result == NEED_KEY) {
|
||||
LOGE("Key Error: %s", session_id.c_str());
|
||||
return kNoKey;
|
||||
}
|
||||
@@ -1151,7 +1153,8 @@ void CdmImpl::OnSessionRenewalNeeded(const CdmSessionId& session_id) {
|
||||
}
|
||||
|
||||
void CdmImpl::OnSessionKeysChange(const CdmSessionId& session_id,
|
||||
const CdmKeyStatusMap& keys_status, bool) {
|
||||
const CdmKeyStatusMap& keys_status,
|
||||
bool /* has_new_usable_key */) {
|
||||
KeyStatusMap& map = sessions_[session_id].key_statuses;
|
||||
|
||||
CdmKeyStatusMap::const_iterator it;
|
||||
@@ -1250,7 +1253,7 @@ CdmSigningAlgorithm CdmImpl::ConvertSigningAlgorithm(
|
||||
}
|
||||
|
||||
bool VerifyL1() {
|
||||
CryptoSession cs;
|
||||
CryptoSession cs(NULL);
|
||||
return cs.GetSecurityLevel() == kSecurityLevelL1;
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,8 @@ LogPriority g_cutoff = LOG_WARN;
|
||||
|
||||
void InitLogging() {}
|
||||
|
||||
void Log(const char* file, int line, LogPriority level, const char* fmt, ...) {
|
||||
void Log(const char* file, const char* function, int line, LogPriority level,
|
||||
const char* fmt, ...) {
|
||||
const char* severities[] = { "ERROR", "WARN", "INFO", "DEBUG", "VERBOSE" };
|
||||
if (level >= sizeof(severities) / sizeof(*severities)) {
|
||||
fprintf(stderr, "[FATAL:%s(%d)] Invalid log priority level: %d\n",
|
||||
@@ -24,7 +25,7 @@ void Log(const char* file, int line, LogPriority level, const char* fmt, ...) {
|
||||
}
|
||||
if (level > g_cutoff) return;
|
||||
|
||||
fprintf(stderr, "[%s:%s(%d)] ", severities[level], file, line);
|
||||
fprintf(stderr, "[%s:%s(%d):%s] ", severities[level], file, line, function);
|
||||
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
|
||||
@@ -84,9 +84,9 @@ void Properties::Init() {
|
||||
oem_crypto_use_secure_buffers_ = use_secure_buffers_;
|
||||
oem_crypto_use_fifo_ = use_fifo_;
|
||||
oem_crypto_use_userspace_buffers_ = use_userspace_buffers_;
|
||||
use_certificates_as_identification_ = true;
|
||||
provisioning_messages_are_binary_ = set_provisioning_messages_to_binary_;
|
||||
security_level_path_backward_compatibility_support_ = false;
|
||||
allow_service_certificate_requests_ = false;
|
||||
session_property_set_.reset(new CdmClientPropertySetMap());
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "override.h"
|
||||
#include "properties_ce.h"
|
||||
#include "scoped_ptr.h"
|
||||
#include "service_certificate.h"
|
||||
#include "string_conversions.h"
|
||||
#include "test_host.h"
|
||||
#include "url_request.h"
|
||||
@@ -130,7 +131,7 @@ class CdmTest : public Test, public Cdm::IEventListener {
|
||||
protected:
|
||||
virtual void SetUp() OVERRIDE {
|
||||
|
||||
ConfigTestEnv config(kContentProtectionStagingPlusProv30);
|
||||
ConfigTestEnv config(kContentProtectionUatServer);
|
||||
|
||||
g_provisioning_service_certificate.assign(
|
||||
config.provisioning_service_certificate());
|
||||
@@ -143,7 +144,7 @@ class CdmTest : public Test, public Cdm::IEventListener {
|
||||
|
||||
// Clear anything stored by OEMCrypto.
|
||||
ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_Initialize());
|
||||
int result = OEMCrypto_DeleteUsageTable();
|
||||
int result = OEMCrypto_DeleteOldUsageTable(); // TODO(fredgc): update this.
|
||||
// Don't fault OEMCrypto implementations without usage tables:
|
||||
if (result != OEMCrypto_ERROR_NOT_IMPLEMENTED) {
|
||||
EXPECT_EQ(OEMCrypto_SUCCESS, result);
|
||||
@@ -227,7 +228,28 @@ class CdmTest : public Test, public Cdm::IEventListener {
|
||||
int status_code;
|
||||
bool ok = Fetch(url, "", response, &status_code);
|
||||
ASSERT_TRUE(ok);
|
||||
if (ok) ASSERT_EQ(kHttpOk, status_code);
|
||||
if (ok) ASSERT_EQ(kHttpOk, status_code)
|
||||
<< "Error response: " << *response << "\n"
|
||||
<< "url: " << url;
|
||||
}
|
||||
|
||||
bool FetchServiceCertificate(const std::string& url,
|
||||
std::string* response) {
|
||||
std::string request;
|
||||
int status;
|
||||
if (!ServiceCertificate::GetRequest(&request)) {
|
||||
LOGE("FAILED to generate service certificate request.");
|
||||
return false;
|
||||
}
|
||||
if (!Fetch (url, request, response, &status)) {
|
||||
LOGE("FAILED to get service certificate response: sts=%d", status);
|
||||
return false;
|
||||
}
|
||||
LOGV("Reply body(hex): \n%s\n", b2a_hex(*response).c_str());
|
||||
LOGV("Reply body(b64): \n%s\n",
|
||||
Base64SafeEncode(std::vector<uint8_t>(response->begin(),
|
||||
response->end())).c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
void FetchLicense(const std::string& license_server,
|
||||
@@ -236,7 +258,9 @@ class CdmTest : public Test, public Cdm::IEventListener {
|
||||
int status_code;
|
||||
bool ok = Fetch(license_server, message, response, &status_code);
|
||||
ASSERT_TRUE(ok);
|
||||
if (ok) ASSERT_EQ(kHttpOk, status_code);
|
||||
if (ok) ASSERT_EQ(kHttpOk, status_code)
|
||||
<< "Error response: " << *response << "\n"
|
||||
<< "license_server: " << license_server;
|
||||
}
|
||||
|
||||
void FetchLicenseFailure(const std::string& message,
|
||||
@@ -324,6 +348,24 @@ class CdmTest : public Test, public Cdm::IEventListener {
|
||||
Mock::VerifyAndClear(this);
|
||||
}
|
||||
|
||||
std::string GetProvisioningResponse(const std::string& message) {
|
||||
std::string reply;
|
||||
std::string uri = g_provisioning_server;
|
||||
|
||||
LOGV("GetProvisioningResponse: URI: %s", uri.c_str());
|
||||
LOGV("GetProvisioningResponse: message:\n%s\n", b2a_hex(message).c_str());
|
||||
|
||||
uri += "&signedRequest=" + message;
|
||||
FetchCertificate(uri, &reply);
|
||||
if (HasFatalFailure()) {
|
||||
LOGE("GetProvisioningResponse: Failed.");
|
||||
return "";
|
||||
}
|
||||
|
||||
LOGV("GetProvisioningResponse: response:\n%s\n", reply.c_str());
|
||||
return reply;
|
||||
}
|
||||
|
||||
scoped_ptr<Cdm> cdm_;
|
||||
};
|
||||
|
||||
@@ -487,6 +529,51 @@ TEST_F(CdmTest, GetServiceCertificateRequest) {
|
||||
EXPECT_EQ(Cdm::kSuccess, status);
|
||||
}
|
||||
|
||||
TEST_F(CdmTest, ServiceCertificateRequestResponseUat) {
|
||||
ConfigTestEnv uat_config(kContentProtectionUatServer);
|
||||
|
||||
std::string response;
|
||||
ASSERT_TRUE(FetchServiceCertificate(uat_config.license_server(), &response));
|
||||
LOGV("response size=%d", response.size());
|
||||
#if 0 // enable to extract the service certificate in byte form
|
||||
size_t done = 0;
|
||||
while (done < response.size()) {
|
||||
for (int i = 0; i < 12; i++) {
|
||||
if (done >= response.size()) {
|
||||
break;
|
||||
}
|
||||
uint32_t x = static_cast<uint8_t>(response.data()[done]);
|
||||
printf("0x%02x, ", x);
|
||||
done++;
|
||||
}
|
||||
printf ("\n");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST_F(CdmTest, ServiceCertificateRequestResponseStaging) {
|
||||
ConfigTestEnv staging_config(kContentProtectionStagingServer);
|
||||
|
||||
std::string response;
|
||||
ASSERT_TRUE(FetchServiceCertificate(staging_config.license_server(),
|
||||
&response));
|
||||
LOGV("response size=%d", response.size());
|
||||
#if 0 // enable to extract the service certificate in byte form
|
||||
size_t done = 0;
|
||||
while (done < response.size()) {
|
||||
for (int i = 0; i < 12; i++) {
|
||||
if (done >= response.size()) {
|
||||
break;
|
||||
}
|
||||
uint32_t x = static_cast<uint8_t>(response.data()[done]);
|
||||
printf("0x%02x, ", x);
|
||||
done++;
|
||||
}
|
||||
printf ("\n");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST_F(CdmTest, SetServiceCertificate) {
|
||||
// Set a server certificate with privacy mode disabled - should work.
|
||||
ASSERT_NO_FATAL_FAILURE(RecreateCdm(false /* privacy_mode */));
|
||||
@@ -504,6 +591,37 @@ TEST_F(CdmTest, SetServiceCertificate) {
|
||||
EXPECT_EQ(Cdm::kTypeError, status);
|
||||
}
|
||||
|
||||
TEST_F(CdmTest, Provision) {
|
||||
// Clear any existing certificates.
|
||||
g_host->remove("cert.bin");
|
||||
g_host->SaveProvisioningInformation();
|
||||
|
||||
// Creating a session should succeed.
|
||||
std::string session_id;
|
||||
Cdm::Status status;
|
||||
status = cdm_->setServiceCertificate(g_license_service_certificate);
|
||||
EXPECT_EQ(Cdm::kSuccess, status);
|
||||
status = cdm_->createSession(Cdm::kTemporary, &session_id);
|
||||
EXPECT_EQ(Cdm::kSuccess, status);
|
||||
|
||||
// Should get an individualization request when we generate request.
|
||||
std::string message;
|
||||
EXPECT_CALL(*this, onDirectIndividualizationRequest(session_id, _))
|
||||
.WillOnce(SaveArg<1>(&message));
|
||||
status = cdm_->generateRequest(session_id, Cdm::kCenc, kCencInitData);
|
||||
EXPECT_EQ(Cdm::kSuccess, status);
|
||||
Mock::VerifyAndClear(this);
|
||||
|
||||
// Complete the provisioning request.
|
||||
std::string reply = GetProvisioningResponse(message);
|
||||
ASSERT_FALSE(reply.empty());
|
||||
EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRequest, _)).Times(1);
|
||||
EXPECT_CALL(*this, onDeferredComplete(_, _)).Times(0);
|
||||
status = cdm_->update(session_id, reply);
|
||||
ASSERT_EQ(Cdm::kSuccess, status);
|
||||
Mock::VerifyAndClear(this);
|
||||
}
|
||||
|
||||
TEST_F(CdmTest, CreateSession) {
|
||||
// Create a temporary session.
|
||||
std::string session_id;
|
||||
@@ -709,7 +827,8 @@ TEST_F(CdmTest, LoadTemporary) {
|
||||
EXPECT_EQ(Cdm::kSessionNotFound, status);
|
||||
}
|
||||
|
||||
TEST_F(CdmTest, LoadPersistent) {
|
||||
// TODO(fredgc,rfrias): turn this on after big usage tables work.
|
||||
TEST_F(CdmTest, DISABLED_LoadPersistent) {
|
||||
std::string session_id;
|
||||
std::string response;
|
||||
Cdm::Status status;
|
||||
@@ -748,7 +867,8 @@ TEST_F(CdmTest, LoadPersistent) {
|
||||
Mock::VerifyAndClear(this);
|
||||
}
|
||||
|
||||
TEST_F(CdmTest, LoadWillFireExpiration) {
|
||||
// TODO(fredgc,rfrias): turn this on after big usage tables work.
|
||||
TEST_F(CdmTest, DISABLED_LoadWillFireExpiration) {
|
||||
// There was a bug where calling load() would not start the PolicyEngine timer
|
||||
// because it was only started in update().
|
||||
std::string session_id;
|
||||
@@ -769,7 +889,8 @@ TEST_F(CdmTest, LoadWillFireExpiration) {
|
||||
Mock::VerifyAndClear(this);
|
||||
}
|
||||
|
||||
TEST_F(CdmTest, PerOriginLoadPersistent) {
|
||||
// TODO(fredgc,rfrias): turn this on after big usage tables work.
|
||||
TEST_F(CdmTest, DISABLED_PerOriginLoadPersistent) {
|
||||
std::string session_id;
|
||||
std::string response;
|
||||
ASSERT_NO_FATAL_FAILURE(CreateSessionAndFetchLicense(
|
||||
@@ -801,7 +922,8 @@ TEST_F(CdmTest, PerOriginLoadPersistent) {
|
||||
Mock::VerifyAndClear(this);
|
||||
}
|
||||
|
||||
TEST_F(CdmTest, LoadUsageRecord) {
|
||||
// TODO(fredgc,rfrias): turn this on after big usage tables work.
|
||||
TEST_F(CdmTest, DISABLED_LoadUsageRecord) {
|
||||
std::string session_id;
|
||||
std::string response;
|
||||
|
||||
@@ -844,7 +966,8 @@ TEST_F(CdmTest, LoadUsageRecord) {
|
||||
Mock::VerifyAndClear(this);
|
||||
}
|
||||
|
||||
TEST_F(CdmTest, DestroyUsageRecord) {
|
||||
// TODO(gmorgan): temporarily disabled - pending cdm_partner_3.2 merges
|
||||
TEST_F(CdmTest, DISABLED_DestroyUsageRecord) {
|
||||
std::string session_id;
|
||||
std::string response;
|
||||
ASSERT_NO_FATAL_FAILURE(CreateSessionAndFetchLicense(
|
||||
@@ -878,7 +1001,8 @@ TEST_F(CdmTest, DestroyUsageRecord) {
|
||||
Mock::VerifyAndClear(this);
|
||||
}
|
||||
|
||||
TEST_F(CdmTest, DestroyAllUsageRecords) {
|
||||
// TODO(gmorgan): temporarily disabled - pending cdm_partner_3.2 merges
|
||||
TEST_F(CdmTest, DISABLED_DestroyAllUsageRecords) {
|
||||
std::string session_id;
|
||||
std::string response;
|
||||
ASSERT_NO_FATAL_FAILURE(CreateSessionAndFetchLicense(
|
||||
@@ -912,7 +1036,8 @@ TEST_F(CdmTest, DestroyAllUsageRecords) {
|
||||
Mock::VerifyAndClear(this);
|
||||
}
|
||||
|
||||
TEST_F(CdmTest, ListUsageRecords) {
|
||||
// TODO(gmorgan): temporarily disabled - pending cdm_partner_3.2 merges
|
||||
TEST_F(CdmTest, DISABLED_ListUsageRecords) {
|
||||
std::string session_id;
|
||||
std::string response;
|
||||
ASSERT_NO_FATAL_FAILURE(CreateSessionAndFetchLicense(
|
||||
@@ -1026,7 +1151,8 @@ TEST_F(CdmTest, GetExpiration) {
|
||||
ASSERT_EQ(Cdm::kSessionNotFound, status);
|
||||
}
|
||||
|
||||
TEST_F(CdmTest, Remove) {
|
||||
// TODO(fredgc,rfrias): turn this on after big usage tables work.
|
||||
TEST_F(CdmTest, DISABLED_Remove) {
|
||||
std::string session_id;
|
||||
ASSERT_NO_FATAL_FAILURE(CreateSessionAndUpdate(
|
||||
Cdm::kPersistentLicense, Cdm::kCenc, &session_id));
|
||||
@@ -1080,7 +1206,8 @@ TEST_F(CdmTest, Remove) {
|
||||
EXPECT_EQ(Cdm::kRangeError, status);
|
||||
}
|
||||
|
||||
TEST_F(CdmTest, RemoveUsageRecord) {
|
||||
// TODO(fredgc,rfrias): turn this on after big usage tables work.
|
||||
TEST_F(CdmTest, DISABLED_RemoveUsageRecord) {
|
||||
std::string session_id;
|
||||
ASSERT_NO_FATAL_FAILURE(CreateSessionAndUpdate(
|
||||
Cdm::kPersistentUsageRecord, Cdm::kCenc, &session_id));
|
||||
@@ -1116,7 +1243,8 @@ TEST_F(CdmTest, RemoveUsageRecord) {
|
||||
ASSERT_EQ(Cdm::kSessionNotFound, status);
|
||||
}
|
||||
|
||||
TEST_F(CdmTest, RemoveIncomplete) {
|
||||
// TODO(fredgc,rfrias): turn this on after big usage tables work.
|
||||
TEST_F(CdmTest, DISABLED_RemoveIncomplete) {
|
||||
std::string session_id;
|
||||
ASSERT_NO_FATAL_FAILURE(CreateSessionAndUpdate(
|
||||
Cdm::kPersistentLicense, Cdm::kCenc, &session_id));
|
||||
@@ -1179,15 +1307,8 @@ TEST_F(CdmTest, RemoveIncomplete) {
|
||||
ASSERT_EQ(Cdm::kSessionNotFound, status);
|
||||
}
|
||||
|
||||
TEST_F(CdmTest, RemoveUsageTable) {
|
||||
Cdm::Status status;
|
||||
status = cdm_->removeUsageTable();
|
||||
ASSERT_EQ(Cdm::kSuccess, status);
|
||||
status = cdm_->removeUsageTable();
|
||||
ASSERT_EQ(Cdm::kSuccess, status);
|
||||
}
|
||||
|
||||
TEST_F(CdmTest, RemoveUsageRecordIncomplete) {
|
||||
// TODO(fredgc,rfrias): turn this on after big usage tables work.
|
||||
TEST_F(CdmTest, DISABLED_RemoveUsageRecordIncomplete) {
|
||||
std::string session_id;
|
||||
ASSERT_NO_FATAL_FAILURE(CreateSessionAndUpdate(
|
||||
Cdm::kPersistentUsageRecord, Cdm::kCenc, &session_id));
|
||||
@@ -1250,7 +1371,8 @@ TEST_F(CdmTest, RemoveUsageRecordIncomplete) {
|
||||
ASSERT_EQ(Cdm::kSessionNotFound, status);
|
||||
}
|
||||
|
||||
TEST_F(CdmTest, RemoveNotLoaded) {
|
||||
// TODO(fredgc,rfrias): turn this on after big usage tables work.
|
||||
TEST_F(CdmTest, DISABLED_RemoveNotLoaded) {
|
||||
// Create a persistent session and then close it.
|
||||
std::string session_id;
|
||||
ASSERT_NO_FATAL_FAILURE(CreateSessionAndUpdate(
|
||||
@@ -1285,7 +1407,8 @@ TEST_F(CdmTest, RequestPersistentLicenseWithWrongInitData) {
|
||||
FetchLicenseFailure(message, 500);
|
||||
}
|
||||
|
||||
TEST_F(CdmTest, RequestTemporaryLicenseWithWrongInitData) {
|
||||
// TODO(fredgc,rfrias): turn this on after big usage tables work.
|
||||
TEST_F(CdmTest, DISABLED_RequestTemporaryLicenseWithWrongInitData) {
|
||||
// Generate a request for a temporary license using persistent init data.
|
||||
std::string session_id;
|
||||
Cdm::Status status;
|
||||
@@ -1460,6 +1583,7 @@ TEST_F(CdmTest, SetVideoResolutionOverflow) {
|
||||
cdm_->close(session_id);
|
||||
}
|
||||
|
||||
// TODO(http://b/37286053): Fix this test.
|
||||
TEST_P(CdmTestWithDecryptParam, DecryptToClearBuffer) {
|
||||
DecryptParam param = GetParam();
|
||||
|
||||
@@ -1630,6 +1754,7 @@ TEST_F(CdmIndividualizationTest, IsProvisioned) {
|
||||
EXPECT_TRUE(cdm_->isProvisioned());
|
||||
}
|
||||
|
||||
// TODO(fredgc,rfrias): turn this on after big usage tables work.
|
||||
TEST_F(CdmIndividualizationTest, RemoveProvisioning) {
|
||||
if (!CheckProvisioningSupport()) return;
|
||||
|
||||
@@ -1810,7 +1935,8 @@ TEST_F(CdmIndividualizationTest, OnlyPropagatesErrorsForThisSession) {
|
||||
Mock::VerifyAndClear(this);
|
||||
}
|
||||
|
||||
TEST_F(CdmIndividualizationTest, WorksWithLoad) {
|
||||
// TODO(fredgc,rfrias): turn this on after big usage tables work.
|
||||
TEST_F(CdmIndividualizationTest, DISABLED_WorksWithLoad) {
|
||||
if (!CheckProvisioningSupport()) return;
|
||||
|
||||
// Create an offline session to load.
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <getopt.h>
|
||||
#include <gtest/gtest.h>
|
||||
#include <time.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#if defined(__linux__)
|
||||
#include <sys/utsname.h>
|
||||
@@ -13,6 +14,7 @@
|
||||
#include "device_cert.h"
|
||||
#include "override.h"
|
||||
#include "test_host.h"
|
||||
#include "test_keybox.h"
|
||||
|
||||
#if defined(OEMCRYPTO_TESTS)
|
||||
# include "oec_device_features.h"
|
||||
@@ -45,6 +47,23 @@ int main(int argc, char** argv) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
{
|
||||
FILE* outfile;
|
||||
outfile = fopen("danger_do_not_use.bin", "w");
|
||||
if (outfile == NULL) { return 0; }
|
||||
if (fwrite(wvcdm_test_auth::kKeybox, 1,
|
||||
wvcdm_test_auth::kKeyboxSize, outfile) != 128) {
|
||||
fclose(outfile);
|
||||
return 0;
|
||||
}
|
||||
if (fwrite(wvcdm_test_auth::kKeyboxValid02, 1,
|
||||
wvcdm_test_auth::kKeyboxSize, outfile) != 128) {
|
||||
fclose(outfile);
|
||||
return 0;
|
||||
}
|
||||
fclose(outfile);
|
||||
}
|
||||
|
||||
// Set up a Host so that tests and initialize the library. This makes these
|
||||
// services available to the tests. We would do this in the test suite
|
||||
// itself, but the core & OEMCrypto tests don't know they depend on this
|
||||
@@ -76,7 +95,6 @@ int main(int argc, char** argv) {
|
||||
|
||||
#if defined(OEMCRYPTO_TESTS)
|
||||
// Set up the OEMCrypto test harness.
|
||||
// NOTE: This creates a temporary OEMCrypto "instance".
|
||||
wvoec::global_features.Initialize(false /* is_cast_receiver */,
|
||||
false /* force_load_test_keybox */);
|
||||
::testing::GTEST_FLAG(filter)
|
||||
|
||||
44
cdm/test/level3_file_system_ce_test.cpp
Normal file
44
cdm/test/level3_file_system_ce_test.cpp
Normal file
@@ -0,0 +1,44 @@
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#include "level3_file_system_ce_test.h"
|
||||
|
||||
namespace wvoec3 {
|
||||
|
||||
std::map<std::string, std::string> OEMCrypto_Level3CETestFileSystem::files_;
|
||||
|
||||
ssize_t OEMCrypto_Level3CETestFileSystem::Read(const char *filename,
|
||||
void *buffer, size_t size) {
|
||||
if (!Exists(filename)) return 0;
|
||||
std::string data = files_[std::string(filename)];
|
||||
size_t bytes_read = std::min(size, data.size());
|
||||
memcpy(buffer, data.data(), bytes_read);
|
||||
return bytes_read;
|
||||
}
|
||||
|
||||
ssize_t OEMCrypto_Level3CETestFileSystem::Write(const char *filename,
|
||||
const void *buffer,
|
||||
size_t size) {
|
||||
std::string data(static_cast<const char*>(buffer), size);
|
||||
files_[std::string(filename)] = data;
|
||||
return size;
|
||||
}
|
||||
|
||||
bool OEMCrypto_Level3CETestFileSystem::Exists(const char *filename) {
|
||||
return files_.find(std::string(filename)) != files_.end();
|
||||
}
|
||||
|
||||
ssize_t OEMCrypto_Level3CETestFileSystem::FileSize(const char *filename) {
|
||||
if (!Exists(filename)) return -1;
|
||||
return files_[std::string(filename)].size();
|
||||
}
|
||||
|
||||
bool OEMCrypto_Level3CETestFileSystem::Remove(const char *filename) {
|
||||
if (!Exists(filename)) return false;
|
||||
files_.erase(std::string(filename));
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace wvoec3
|
||||
34
cdm/test/level3_file_system_ce_test.h
Normal file
34
cdm/test/level3_file_system_ce_test.h
Normal file
@@ -0,0 +1,34 @@
|
||||
// Copyright 2017 Google Inc. All Rights Reserved
|
||||
|
||||
/*********************************************************************
|
||||
* level3_file_system_ce_test.h
|
||||
*
|
||||
* Test file system for CE CDM for OEMCrypto Level3 File Operations.
|
||||
*********************************************************************/
|
||||
|
||||
#ifndef LEVEL3_FILE_SYSTEM_CE_TEST_H_
|
||||
#define LEVEL3_FILE_SYSTEM_CE_TEST_H_
|
||||
|
||||
#include "cdm.h"
|
||||
#include "file_store.h"
|
||||
#include "level3_file_system.h"
|
||||
|
||||
namespace wvoec3 {
|
||||
|
||||
class OEMCrypto_Level3CETestFileSystem : public OEMCrypto_Level3FileSystem {
|
||||
public:
|
||||
OEMCrypto_Level3CETestFileSystem() {};
|
||||
~OEMCrypto_Level3CETestFileSystem() override {};
|
||||
ssize_t Read(const char *filename, void *buffer, size_t size) override;
|
||||
ssize_t Write(const char *filename, const void *buffer, size_t size) override;
|
||||
bool Exists(const char *filename) override;
|
||||
ssize_t FileSize(const char *filename) override;
|
||||
bool Remove(const char *filename) override;
|
||||
|
||||
private:
|
||||
static std::map<std::string, std::string> files_;
|
||||
};
|
||||
|
||||
} // namespace wvoec3
|
||||
|
||||
#endif
|
||||
16
cdm/test/level3_file_system_test_factory.cpp
Normal file
16
cdm/test/level3_file_system_test_factory.cpp
Normal file
@@ -0,0 +1,16 @@
|
||||
#include "level3_file_system_ce_test.h"
|
||||
#include "level3_file_system_factory.h"
|
||||
|
||||
namespace wvoec3 {
|
||||
|
||||
OEMCrypto_Level3FileSystem* createLevel3FileSystem() {
|
||||
return new OEMCrypto_Level3CETestFileSystem();
|
||||
}
|
||||
|
||||
void deleteLevel3FileSystem(OEMCrypto_Level3FileSystem* file_system) {
|
||||
if (file_system) {
|
||||
delete file_system;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -9,6 +9,10 @@
|
||||
|
||||
using namespace widevine;
|
||||
|
||||
namespace {
|
||||
const std::string kCertificateFilename = "cert.bin";
|
||||
} // namespace
|
||||
|
||||
TestHost::TestHost() {
|
||||
Reset();
|
||||
}
|
||||
@@ -19,14 +23,17 @@ void TestHost::Reset() {
|
||||
gettimeofday(&tv, NULL);
|
||||
now_ = (tv.tv_sec * 1000LL) + (tv.tv_usec / 1000LL);
|
||||
|
||||
save_device_cert_ = false;
|
||||
|
||||
// Surprisingly, std::priority_queue has no clear().
|
||||
while (!timers_.empty()) {
|
||||
timers_.pop();
|
||||
}
|
||||
|
||||
files_.clear();
|
||||
files_["cert.bin"] =
|
||||
std::string((const char*)kDeviceCert, kDeviceCertSize);
|
||||
files_[kCertificateFilename.c_str()] = (device_cert_.size() > 0)
|
||||
? device_cert_
|
||||
: std::string((const char*)kDeviceCert, kDeviceCertSize);
|
||||
}
|
||||
|
||||
void TestHost::ElapseTime(int64_t milliseconds) {
|
||||
@@ -37,9 +44,9 @@ void TestHost::ElapseTime(int64_t milliseconds) {
|
||||
} else {
|
||||
Timer t = timers_.top();
|
||||
timers_.pop();
|
||||
ASSERT_GE(t.expiry_time, now_);
|
||||
now_ = t.expiry_time;
|
||||
t.client->onTimerExpired(t.context);
|
||||
ASSERT_GE(t.expiry_time(), now_);
|
||||
now_ = t.expiry_time();
|
||||
t.client()->onTimerExpired(t.context());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -60,6 +67,10 @@ bool TestHost::write(const std::string& name,
|
||||
const std::string& data) {
|
||||
LOGD("write file: %s", name.c_str());
|
||||
files_[name] = data;
|
||||
if (save_device_cert_ && kCertificateFilename.compare(name) == 0) {
|
||||
device_cert_ = data;
|
||||
save_device_cert_ = false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -114,7 +125,7 @@ void TestHost::cancel(IClient* client) {
|
||||
Timer t = timers_.top();
|
||||
timers_.pop();
|
||||
|
||||
if (t.client != client) {
|
||||
if (t.client() != client) {
|
||||
others.push(t);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,8 @@ class TestHost : public widevine::Cdm::IStorage,
|
||||
void ElapseTime(int64_t milliseconds);
|
||||
int NumTimers() const;
|
||||
|
||||
void SaveProvisioningInformation() { save_device_cert_ = true; }
|
||||
|
||||
virtual bool read(const std::string& name,
|
||||
std::string* data) OVERRIDE;
|
||||
virtual bool write(const std::string& name,
|
||||
@@ -36,23 +38,31 @@ class TestHost : public widevine::Cdm::IStorage,
|
||||
|
||||
private:
|
||||
struct Timer {
|
||||
Timer(int64_t expiry_time_, IClient* client_, void* context_)
|
||||
: expiry_time(expiry_time_), client(client_), context(context_) {}
|
||||
Timer(int64_t expiry_time, IClient* client, void* context)
|
||||
: expiry_time_(expiry_time), client_(client), context_(context) {}
|
||||
|
||||
bool operator<(const Timer& other) const {
|
||||
// We want to reverse the order so that the smallest expiry times go to
|
||||
// the top of the priority queue.
|
||||
return expiry_time > other.expiry_time;
|
||||
return expiry_time_ > other.expiry_time_;
|
||||
}
|
||||
|
||||
int64_t expiry_time;
|
||||
IClient* client;
|
||||
void* context;
|
||||
int64_t expiry_time() { return expiry_time_; }
|
||||
IClient* client() { return client_; }
|
||||
void* context() { return context_; }
|
||||
|
||||
private:
|
||||
int64_t expiry_time_;
|
||||
IClient* client_;
|
||||
void* context_;
|
||||
};
|
||||
|
||||
int64_t now_;
|
||||
std::priority_queue<Timer> timers_;
|
||||
|
||||
std::string device_cert_;
|
||||
bool save_device_cert_;
|
||||
|
||||
typedef std::map<std::string, std::string> StorageMap;
|
||||
StorageMap files_;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user