Source release 14.1.0

This commit is contained in:
John W. Bruce
2018-06-29 15:59:47 -07:00
parent 3ab70cec4e
commit afa11a48a0
1941 changed files with 557780 additions and 105547 deletions

View File

@@ -1,7 +1,9 @@
# Copyright 2015 Google Inc. All Rights Reserved.
# 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.
#
# Refer to the distribution package's integration guide
# (Widevine_CE_CDM_IntegrationGuide_v3.2.x.pdf) for information about
# (Widevine_CE_CDM_IntegrationGuide_x.x.x.pdf) for information about
# setting up your system, performing the build, and using/testing
# the build targets.
@@ -106,12 +108,14 @@
'../metrics/include',
'../oemcrypto/include',
'../third_party/jsmn',
'../util/include',
],
'direct_dependent_settings': {
'include_dirs': [
'../core/include',
'../metrics/include',
'../oemcrypto/include',
'../util/include',
],
},
'sources': [
@@ -138,6 +142,7 @@
'target_name': 'widevine_ce_cdm_static',
'type': 'static_library',
'standalone_static_library': 1,
'hard_dependency': 1,
'dependencies': [
'widevine_cdm_core',
'device_files',

View File

@@ -1,11 +1,22 @@
# Copyright 2015 Google Inc. All Rights Reserved.
# 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.
#
# Builds under the CDM ./build.py (target platform) build system
# Refer to the distribution package's README for details.
{
'variables': {
'oemcrypto_stubs%': '',
# Label as 'static' or 'dynamic' to use the respective OEMCrypto adapter.
'oemcrypto_adapter%': 'static',
# Choose type of OEMCrypto library to compile in (ref, level3, vendor).
# Production Level 1 systems should use vendor.
'oemcrypto_lib%': 'ref',
# Override this for the location to the BoringSSL gyp file.
'boringssl_dependency%': '../third_party/boringssl/boringssl.gyp:legacy_ssl',
# Directory where OEMCrypto header, test, and reference files lives.
'oemcrypto_dir%': '../oemcrypto',
# Directory where widevine utilities live.
'util_dir%': '../util',
'metrics_target%': 'cdm.gyp:metrics_proto',
'device_files_target%': 'cdm.gyp:device_files',
},
@@ -23,7 +34,7 @@
'test/test_host.h',
],
'includes': [
'oemcrypto_unittests.gypi',
'../oemcrypto/test/oemcrypto_unittests.gypi',
'core_unittests.gypi',
'cdm_unittests.gypi',
],
@@ -36,39 +47,47 @@
'../third_party/gmock.gyp:gtest',
],
'conditions': [
['oemcrypto_stubs!=""', {
['oemcrypto_lib=="ref"', {
'dependencies': [
'../oemcrypto/stubs/stubs.gyp:oec_stubs_v14',
'oec_ref_shared',
],
}, {
'conditions': [
['oemcrypto_lib=="mock"', {
'dependencies': [
'../oemcrypto/mock/oec_mock.gyp:oec_mock_shared',
],
}],
['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_ce_test_factory.cpp',
],
'conditions': [
['oemcrypto_adapter=="static"', {
'dependencies': [
}],
['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_ce_test_factory.cpp',
],
'conditions': [
['oemcrypto_adapter=="static"', {
'dependencies': [
'../oemcrypto/level3/oec_level3.gyp:oec_level3_static',
],
}, {
'dependencies': [
],
}, {
'dependencies': [
'../oemcrypto/level3/oec_level3.gyp:oec_level3_dynamic',
],
}],
],
}],
],
],
}],
],
}],
],
},
{
'target_name': 'oec_ref',
'type': 'static_library',
'standalone_static_library': 1,
'includes': [
'../oemcrypto/ref/oec_ref.gypi',
],
},
{
'target_name': 'oec_ref_shared',
'type': 'shared_library',
'dependencies': [
'oec_ref'
],
},
],
}

View File

@@ -1,4 +1,6 @@
# Copyright 2015 Google Inc. All Rights Reserved.
# 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.
#
# Include this in any custom unit test targets.
# Does not include the device certificate or the test runner main.

View File

@@ -1,4 +1,6 @@
# Copyright 2017 Google Inc. All Rights Reserved.
# 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.
#
# Include this in any custom unit test targets.
# Does not include the test runner main.
@@ -12,26 +14,21 @@
'../core/include/cdm_session_map.h',
'../core/include/certificate_provisioning.h',
'../core/include/client_identification.h',
'../core/include/clock.h',
'../core/include/content_key_session.h',
'../core/include/crypto_key.h',
'../core/include/crypto_session.h',
'../core/include/device_files.h',
'../core/include/entitlement_key_session.h',
'../core/include/file_store.h',
'../core/include/initialization_data.h',
'../core/include/key_session.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/sublicense_key_session.h',
'../core/include/wv_cdm_constants.h',
'../core/include/wv_cdm_event_listener.h',
@@ -53,9 +50,14 @@
'../core/src/policy_engine.cpp',
'../core/src/properties.cpp',
'../core/src/service_certificate.cpp',
'../core/src/string_conversions.cpp',
'../core/src/sublicense_key_session.cpp',
'../core/src/usage_table_header.cpp',
'../util/include/clock.h',
'../util/include/file_store.h',
'../util/include/lock.h',
'../util/include/log.h',
'../util/include/string_conversions.h',
'../util/src/string_conversions.cpp',
'../metrics/src/attribute_handler.cpp',
'../metrics/src/counter_metric.cpp',
'../metrics/src/distribution.cpp',

View File

@@ -1,4 +1,6 @@
# Copyright 2015 Google Inc. All Rights Reserved.
# 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.
#
# Include this in any custom unit test targets.
# Does not include the test runner main.
@@ -35,6 +37,7 @@
'../core/include',
'../core/test',
'../metrics/include',
'../util/include',
],
'defines': [
'UNIT_TEST',

View File

@@ -1,4 +1,6 @@
// Copyright 2015 Google Inc. All Rights Reserved.
// 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.
// Based on the EME draft spec from 2016 June 10.
// http://www.w3.org/TR/2016/WD-encrypted-media-20160610/"
#ifndef WVCDM_CDM_CDM_H_
@@ -318,7 +320,9 @@ class CDM_EXPORT Cdm : public ITimerClient {
};
// Initialize the CDM library and provide access to platform services.
// All platform interfaces are required.
// All platform interfaces are required. It is the responsibility of the host
// platform to ensure that the objects passed into this method remain valid
// for the lifetime of the CDM library.
// Logging is controlled by |verbosity|.
// Must be called and must return kSuccess before create() is called.
static Status initialize(
@@ -337,9 +341,9 @@ class CDM_EXPORT Cdm : public ITimerClient {
// instance may be constructed.
// The CDM may notify of events at any time via the provided |listener|,
// which may not be NULL.
// |storage| defines the storage to use for this instance. This can be used
// to provide per-origin storage. Passing NULL will use the storage passed
// to initialize().
// |storage| defines the storage to use for this instance. By providing
// different objects here for different origins, this parameter can be used to
// provide per-origin storage. It may not be NULL.
// If |privacy_mode| is true, server certificates are required and will be
// used to encrypt messages to the license server.
// By using server certificates to encrypt communication with the license
@@ -387,6 +391,15 @@ class CDM_EXPORT Cdm : public ITimerClient {
// dertermined by the CDM's current IStorage object.
virtual bool isProvisioned() = 0;
// Creates a Provisioning Request message.
// This is used to provision the device. The request should be sent to the
// provisioning server and the response given to handleProvisioningResponse().
virtual Status getProvisioningRequest(std::string* request) = 0;
// Handles a provisioning response and provisions the device. If this returns
// success, the device will now be provisioned.
virtual Status handleProvisioningResponse(const std::string& response) = 0;
// Remove the device's Device Certificate (for the current origin).
// The Device Certificate is origin-specific, and the origin is
// determined by the CDM's current IStorage object.
@@ -485,6 +498,21 @@ class CDM_EXPORT Cdm : public ITimerClient {
// session is fully removed.
virtual Status remove(const std::string& session_id) = 0;
// Removes stored session data associated with the session.
// The session must be loaded before it can be removed.
// Unlike remove(), this method does not generate a release message. The
// stored data is removed immediately. The session is closed if this function
// returns successfully.
// Generally, callers should not use this method, as it prevents usage data
// from being gathered and it does not allow the license's release to be
// tracked by the server. Most callers will want to use remove(), which
// generates a release request. However, this method is provided for
// applications that have a specific need to release licenses without a server
// roundtrip and are aware of the costs of doing so.
// There is no EME equivalent to this method. EME specifies that removal
// should require a release request, as is done by the remove() method.
virtual Status forceRemove(const std::string& session_id) = 0;
// Describes a repeating pattern as defined by the CENC 3.0 standard. A
// CENC 3.0 pattern consists of a number of encrypted blocks followed by a
// number of clear blocks, after which it repeats.

View File

@@ -1,3 +1,3 @@
// Widevine CE CDM Version
#define CDM_VERSION "14.0.0"
#define CDM_VERSION "14.1.0"
#define EME_VERSION "https://www.w3.org/TR/2017/REC-encrypted-media-20170918"

View File

@@ -1,4 +1,6 @@
// Copyright 2015 Google Inc. All Rights Reserved.
// 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.
#ifndef WVCDM_CDM_PROPERTIES_CE_H_
#define WVCDM_CDM_PROPERTIES_CE_H_

View File

@@ -1,35 +0,0 @@
# Copyright 2015 Google Inc. All Rights Reserved.
#
# 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',
],
'dependencies': [
'<(boringssl_dependency)',
],
}

View File

@@ -1,4 +1,6 @@
// Copyright 2015 Google Inc. All Rights Reserved.
// 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.
#include "cdm.h"
#include <assert.h>
@@ -125,6 +127,11 @@ class CdmImpl : public Cdm,
virtual bool isProvisioned() OVERRIDE;
virtual Status getProvisioningRequest(std::string* request) OVERRIDE;
virtual Status handleProvisioningResponse(
const std::string& response) OVERRIDE;
virtual Status removeProvisioning() OVERRIDE;
virtual Status removeUsageTable() OVERRIDE;
@@ -184,6 +191,8 @@ class CdmImpl : public Cdm,
virtual Status remove(const std::string& session_id) OVERRIDE;
virtual Status forceRemove(const std::string& session_id) OVERRIDE;
virtual Status decrypt(const InputBuffer& input,
const OutputBuffer& output) OVERRIDE;
@@ -297,7 +306,7 @@ Cdm::Status CdmImpl::setServiceCertificate(const std::string& certificate) {
// Verify that the certificate is properly signed and well-formed.
CdmResponseType status =
cdm_engine_.SetProvisioningServiceCertificate(certificate);
cdm_engine_.ValidateServiceCertificate(certificate);
if (status != NO_ERROR) {
LOGE("Invalid service certificate! Error code = %d", status);
return kTypeError;
@@ -339,6 +348,37 @@ bool CdmImpl::isProvisioned() {
return cdm_engine_.IsProvisioned(kSecurityLevelL1);
}
Cdm::Status CdmImpl::getProvisioningRequest(std::string* request) {
std::string empty_authority;
std::string ignored_base_url;
CdmResponseType result = cdm_engine_.GetProvisioningRequest(
kCertificateWidevine, empty_authority,
property_set_.service_certificate(), request, &ignored_base_url);
if (result == CERT_PROVISIONING_NONCE_GENERATION_ERROR) {
LOGE("Nonce quota exceeded");
return kQuotaExceeded;
}
if (result != NO_ERROR) {
LOGE("Unexpected error %d", result);
return kUnexpectedError;
}
return kSuccess;
}
Cdm::Status CdmImpl::handleProvisioningResponse(const std::string& response) {
std::string ignored_cert;
std::string ignored_wrapped_key;
CdmResponseType result = cdm_engine_.HandleProvisioningResponse(
response, &ignored_cert, &ignored_wrapped_key);
if (result != NO_ERROR) {
LOGE("Unexpected error %d", result);
return kUnexpectedError;
}
return kSuccess;
}
Cdm::Status CdmImpl::removeProvisioning() {
if (cdm_engine_.Unprovision(kSecurityLevelL1) != NO_ERROR) {
return kUnexpectedError;
@@ -370,8 +410,8 @@ Cdm::Status CdmImpl::listUsageRecords(std::vector<std::string>* ksids) {
LOGE("Missing vector parameter to receive KSIDs.");
return kTypeError;
}
if (cdm_engine_.ListUsageRecords(
property_set_.app_id(), kSecurityLevelL1, ksids) != NO_ERROR) {
if (cdm_engine_.ListUsageIds(
property_set_.app_id(), kSecurityLevelL1, ksids, NULL) != NO_ERROR) {
return kUnexpectedError;
}
return kSuccess;
@@ -713,16 +753,10 @@ Cdm::Status CdmImpl::load(const std::string& session_id,
Cdm::Status CdmImpl::update(const std::string& session_id,
const std::string& response) {
if (provision_request_sent_) {
std::string ignored_cert;
std::string ignored_wrapped_key;
provision_request_sent_ = false;
CdmResponseType result = cdm_engine_.HandleProvisioningResponse(
response, &ignored_cert, &ignored_wrapped_key);
if (result != NO_ERROR) {
LOGE("Unexpected error %d", result);
return kUnexpectedError;
}
const Status status = handleProvisioningResponse(response);
if (status != kSuccess)
return status;
}
// Check to see if any sessions have been waiting for provisioning.
@@ -1010,6 +1044,37 @@ Cdm::Status CdmImpl::remove(const std::string& session_id) {
return kSuccess;
}
Cdm::Status CdmImpl::forceRemove(const std::string& session_id) {
if (!cdm_engine_.IsOpenSession(session_id)) {
LOGE("No such session: %s", session_id.c_str());
return kSessionNotFound;
}
if (!sessions_[session_id].callable) {
LOGE("Request not yet generated: %s", session_id.c_str());
return kInvalidState;
}
if (sessions_[session_id].type == kTemporary) {
LOGE("Not a persistent session: %s", session_id.c_str());
return kRangeError;
}
CdmResponseType result = cdm_engine_.RemoveLicense(session_id);
if (result != NO_ERROR) {
LOGE("Unexpected error %d", result);
return kUnexpectedError;
}
sessions_.erase(session_id);
cdm_engine_.CloseSession(session_id);
listener_->onRemoveComplete(session_id);
LOGI("A session has been forcibly deleted.");
return kSuccess;
}
Cdm::Status CdmImpl::decrypt(const InputBuffer& input,
const OutputBuffer& output) {
const bool is_encrypted = (input.encryption_scheme != kClear);
@@ -1273,8 +1338,8 @@ void CdmImpl::OnSessionKeysChange(const CdmSessionId& session_id,
void CdmImpl::OnExpirationUpdate(const CdmSessionId& session_id,
int64_t new_expiry_time_seconds) {
// "Never expires" in core is LLONG_MAX. In the CDM API, it's -1.
if (new_expiry_time_seconds == LLONG_MAX) {
// "Never expires" in core is NEVER_EXPIRES. In the CDM API, it's -1.
if (new_expiry_time_seconds == NEVER_EXPIRES) {
sessions_[session_id].expiration = -1;
} else {
sessions_[session_id].expiration = new_expiry_time_seconds * 1000;
@@ -1295,20 +1360,11 @@ Cdm::KeyAllowedUsageFlags CdmImpl::KeyAllowedFlags(
Cdm::Status CdmImpl::SendProvisioningRequest(const std::string& session_id) {
// Generate a provisioning request.
std::string empty_authority;
std::string ignored_base_url;
std::string signed_request;
CdmResponseType result = cdm_engine_.GetProvisioningRequest(
kCertificateWidevine, empty_authority, &signed_request,
&ignored_base_url);
if (result == CERT_PROVISIONING_NONCE_GENERATION_ERROR) {
LOGE("Nonce quota exceeded");
return kQuotaExceeded;
}
if (result != NO_ERROR) {
LOGE("Unexpected error %d", result);
return kUnexpectedError;
}
const Status status = getProvisioningRequest(&signed_request);
if (status != kSuccess)
return status;
listener_->onDirectIndividualizationRequest(session_id, signed_request);
provision_request_sent_ = true;
return kSuccess;

View File

@@ -1,4 +1,6 @@
// Copyright 2015 Google Inc. All Rights Reserved.
// 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.
//
// Lock class - provides a simple mutex implementation.

View File

@@ -1,4 +1,6 @@
// Copyright 2015 Google Inc. All Rights Reserved.
// 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.
//
// Log - implemented using stderr.

View File

@@ -1,4 +1,6 @@
// Copyright 2015 Google Inc. All Rights Reserved.
// 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.
#include "properties.h"
#include "properties_ce.h"

View File

@@ -1,4 +1,6 @@
// Copyright 2015 Google Inc. All Rights Reserved.
// 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.
//
// This source file provides a basic set of unit tests for the Content
// Decryption Module (CDM).
@@ -943,8 +945,7 @@ TEST_F(CdmTest, LoadTemporary) {
EXPECT_EQ(Cdm::kSessionNotFound, status);
}
// TODO(fredgc,rfrias): turn this on after big usage tables work.
TEST_F(CdmTest, DISABLED_LoadPersistent) {
TEST_F(CdmTest, LoadPersistent) {
std::string session_id;
std::string response;
Cdm::Status status;
@@ -983,8 +984,7 @@ TEST_F(CdmTest, DISABLED_LoadPersistent) {
Mock::VerifyAndClear(this);
}
// TODO(fredgc,rfrias): turn this on after big usage tables work.
TEST_F(CdmTest, DISABLED_LoadWillFireExpiration) {
TEST_F(CdmTest, 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;
@@ -1005,7 +1005,7 @@ TEST_F(CdmTest, DISABLED_LoadWillFireExpiration) {
Mock::VerifyAndClear(this);
}
// TODO(fredgc,rfrias): turn this on after big usage tables work.
// TODO(b/110802394): Fix this test or remove auto-provisioning.
TEST_F(CdmTest, DISABLED_PerOriginLoadPersistent) {
std::string session_id;
std::string response;
@@ -1038,7 +1038,7 @@ TEST_F(CdmTest, DISABLED_PerOriginLoadPersistent) {
Mock::VerifyAndClear(this);
}
// TODO(fredgc,rfrias): turn this on after big usage tables work.
// TODO(b/34949512): Fix this test so it can be re-enabled.
TEST_F(CdmTest, DISABLED_LoadUsageRecord) {
std::string session_id;
std::string response;
@@ -1082,7 +1082,7 @@ TEST_F(CdmTest, DISABLED_LoadUsageRecord) {
Mock::VerifyAndClear(this);
}
// TODO(gmorgan): temporarily disabled - pending cdm_partner_3.2 merges
// TODO(b/109897011): Temporarily Disabled
TEST_F(CdmTest, DISABLED_DestroyUsageRecord) {
std::string session_id;
std::string response;
@@ -1117,7 +1117,7 @@ TEST_F(CdmTest, DISABLED_DestroyUsageRecord) {
Mock::VerifyAndClear(this);
}
// TODO(gmorgan): temporarily disabled - pending cdm_partner_3.2 merges
// TODO(b/109897011): Temporarily Disabled
TEST_F(CdmTest, DISABLED_DestroyAllUsageRecords) {
std::string session_id;
std::string response;
@@ -1152,7 +1152,7 @@ TEST_F(CdmTest, DISABLED_DestroyAllUsageRecords) {
Mock::VerifyAndClear(this);
}
// TODO(gmorgan): temporarily disabled - pending cdm_partner_3.2 merges
// TODO(b/109897011): Temporarily Disabled
TEST_F(CdmTest, DISABLED_ListUsageRecords) {
std::string session_id;
std::string response;
@@ -1267,8 +1267,7 @@ TEST_F(CdmTest, GetExpiration) {
ASSERT_EQ(Cdm::kSessionNotFound, status);
}
// TODO(fredgc,rfrias): turn this on after big usage tables work.
TEST_F(CdmTest, DISABLED_Remove) {
TEST_F(CdmTest, Remove) {
std::string session_id;
ASSERT_NO_FATAL_FAILURE(CreateSessionAndUpdate(
Cdm::kPersistentLicense, Cdm::kCenc, &session_id));
@@ -1322,8 +1321,43 @@ TEST_F(CdmTest, DISABLED_Remove) {
EXPECT_EQ(Cdm::kRangeError, status);
}
// TODO(fredgc,rfrias): turn this on after big usage tables work.
TEST_F(CdmTest, DISABLED_RemoveUsageRecord) {
TEST_F(CdmTest, ForceRemove) {
std::string session_id;
ASSERT_NO_FATAL_FAILURE(CreateSessionAndUpdate(
Cdm::kPersistentLicense, Cdm::kCenc, &session_id));
// Forcibly remove the session. This should immediately trigger a removal
// callback and should *not* cause a release message to be generated.
EXPECT_CALL(*this, onRemoveComplete(session_id)).Times(1);
EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRelease, _)).Times(0);
Cdm::Status status = cdm_->forceRemove(session_id);
ASSERT_EQ(Cdm::kSuccess, status);
Mock::VerifyAndClear(this);
// The session is now completely gone.
status = cdm_->close(session_id);
ASSERT_EQ(Cdm::kSessionNotFound, status);
status = cdm_->load(session_id);
ASSERT_EQ(Cdm::kSessionNotFound, status);
// Try a bogus session ID.
status = cdm_->forceRemove(kBogusSessionId);
EXPECT_EQ(Cdm::kSessionNotFound, status);
// Try a new session.
status = cdm_->createSession(Cdm::kPersistentLicense, &session_id);
ASSERT_EQ(Cdm::kSuccess, status);
status = cdm_->forceRemove(session_id);
EXPECT_EQ(Cdm::kInvalidState, status);
// Try a temporary session.
ASSERT_NO_FATAL_FAILURE(CreateSessionAndUpdate(
Cdm::kTemporary, Cdm::kCenc, &session_id));
status = cdm_->forceRemove(session_id);
EXPECT_EQ(Cdm::kRangeError, status);
}
TEST_F(CdmTest, RemoveUsageRecord) {
std::string session_id;
ASSERT_NO_FATAL_FAILURE(CreateSessionAndUpdate(
Cdm::kPersistentUsageRecord, Cdm::kCenc, &session_id));
@@ -1359,8 +1393,7 @@ TEST_F(CdmTest, DISABLED_RemoveUsageRecord) {
ASSERT_EQ(Cdm::kSessionNotFound, status);
}
// TODO(fredgc,rfrias): turn this on after big usage tables work.
TEST_F(CdmTest, DISABLED_RemoveIncomplete) {
TEST_F(CdmTest, RemoveIncomplete) {
std::string session_id;
ASSERT_NO_FATAL_FAILURE(CreateSessionAndUpdate(
Cdm::kPersistentLicense, Cdm::kCenc, &session_id));
@@ -1423,8 +1456,7 @@ TEST_F(CdmTest, DISABLED_RemoveIncomplete) {
ASSERT_EQ(Cdm::kSessionNotFound, status);
}
// TODO(fredgc,rfrias): turn this on after big usage tables work.
TEST_F(CdmTest, DISABLED_RemoveUsageRecordIncomplete) {
TEST_F(CdmTest, RemoveUsageRecordIncomplete) {
std::string session_id;
ASSERT_NO_FATAL_FAILURE(CreateSessionAndUpdate(
Cdm::kPersistentUsageRecord, Cdm::kCenc, &session_id));
@@ -1487,8 +1519,7 @@ TEST_F(CdmTest, DISABLED_RemoveUsageRecordIncomplete) {
ASSERT_EQ(Cdm::kSessionNotFound, status);
}
// TODO(fredgc,rfrias): turn this on after big usage tables work.
TEST_F(CdmTest, DISABLED_RemoveNotLoaded) {
TEST_F(CdmTest, RemoveNotLoaded) {
// Create a persistent session and then close it.
std::string session_id;
ASSERT_NO_FATAL_FAILURE(CreateSessionAndUpdate(
@@ -1523,7 +1554,7 @@ TEST_F(CdmTest, RequestPersistentLicenseWithWrongInitData) {
FetchLicenseFailure(message, 500);
}
// TODO(fredgc,rfrias): turn this on after big usage tables work.
// TODO(b/34949512): Fix this test so it can be re-enabled.
TEST_F(CdmTest, DISABLED_RequestTemporaryLicenseWithWrongInitData) {
// Generate a request for a temporary license using persistent init data.
std::string session_id;
@@ -1790,6 +1821,14 @@ TEST_F(CdmTest, HandlesKeyRotationWithOnlyOneLicenseRequest) {
input.iv_length = kIvEntitlement2.size();
ASSERT_EQ(Cdm::kSuccess, cdm_->decrypt(input, output));
EXPECT_EQ(kOutputEntitlement2, output_buffer);
// Attempt decrypt with a key from the first license again.
input.key_id = kKeyIdEntitlement1.data();
input.key_id_length = kKeyIdEntitlement1.size();
input.iv = kIvEntitlement1.data();
input.iv_length = kIvEntitlement1.size();
ASSERT_EQ(Cdm::kSuccess, cdm_->decrypt(input, output));
EXPECT_EQ(kOutputEntitlement1, output_buffer);
}
// TODO(http://b/37286053): Fix this test.
@@ -1892,32 +1931,22 @@ TEST_F(CdmIndividualizationTest, BasicFlow) {
// Clear any existing certificates.
g_host->remove("cert.bin");
// Creating a session should succeed.
std::string session_id;
Cdm::Status status;
status = cdm_->setServiceCertificate(g_license_service_certificate);
// Provision the device
Cdm::Status status =
cdm_->setServiceCertificate(g_provisioning_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 = generateRequestWithRetry(session_id, Cdm::kCenc, kCencInitData);
status = cdm_->getProvisioningRequest(&message);
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 = updateWithRetry(session_id, reply);
ASSERT_EQ(Cdm::kSuccess, status);
Mock::VerifyAndClear(this);
status = cdm_->handleProvisioningResponse(reply);
EXPECT_EQ(Cdm::kSuccess, status);
// We should now be able to create a session and generate a request.
std::string session_id;
status = cdm_->setServiceCertificate(g_license_service_certificate);
EXPECT_EQ(Cdm::kSuccess, status);
ASSERT_NO_FATAL_FAILURE(CreateSessionAndGenerateRequest(
Cdm::kTemporary, Cdm::kCenc, &session_id, &message));
@@ -1938,27 +1967,17 @@ TEST_F(CdmIndividualizationTest, IsProvisioned) {
EXPECT_FALSE(cdm_->isProvisioned());
// Creating a session should succeed.
std::string session_id;
Cdm::Status status = cdm_->createSession(Cdm::kTemporary, &session_id);
// Provision the device
Cdm::Status status =
cdm_->setServiceCertificate(g_provisioning_service_certificate);
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 = generateRequestWithRetry(session_id, Cdm::kCenc, kCencInitData);
status = cdm_->getProvisioningRequest(&message);
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 = updateWithRetry(session_id, reply);
ASSERT_EQ(Cdm::kSuccess, status);
Mock::VerifyAndClear(this);
status = cdm_->handleProvisioningResponse(reply);
EXPECT_EQ(Cdm::kSuccess, status);
EXPECT_TRUE(cdm_->isProvisioned());
}
@@ -1972,27 +1991,17 @@ TEST_F(CdmIndividualizationTest, RemoveProvisioning) {
EXPECT_FALSE(cdm_->isProvisioned());
// Creating a session should succeed.
std::string session_id;
Cdm::Status status = cdm_->createSession(Cdm::kTemporary, &session_id);
// Provision the device
Cdm::Status status =
cdm_->setServiceCertificate(g_provisioning_service_certificate);
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 = generateRequestWithRetry(session_id, Cdm::kCenc, kCencInitData);
status = cdm_->getProvisioningRequest(&message);
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 = updateWithRetry(session_id, reply);
ASSERT_EQ(Cdm::kSuccess, status);
Mock::VerifyAndClear(this);
status = cdm_->handleProvisioningResponse(reply);
EXPECT_EQ(Cdm::kSuccess, status);
EXPECT_TRUE(cdm_->isProvisioned());
@@ -2001,6 +2010,49 @@ TEST_F(CdmIndividualizationTest, RemoveProvisioning) {
EXPECT_FALSE(cdm_->isProvisioned());
}
TEST_F(CdmIndividualizationTest, HandlesAutomaticProvisioning) {
if (!CheckProvisioningSupport()) return;
// Clear any existing certificates.
g_host->remove("cert.bin");
// Creating a session should succeed.
std::string session_id;
Cdm::Status status =
cdm_->setServiceCertificate(g_provisioning_service_certificate);
EXPECT_EQ(Cdm::kSuccess, status);
ASSERT_EQ(Cdm::kSuccess, cdm_->createSession(Cdm::kTemporary, &session_id));
// Should get an individualization request when we generate request.
std::string message;
EXPECT_CALL(*this, onDirectIndividualizationRequest(session_id, _))
.WillOnce(SaveArg<1>(&message));
ASSERT_EQ(Cdm::kSuccess,
generateRequestWithRetry(session_id, Cdm::kCenc, kCencInitData));
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_EQ(Cdm::kSuccess, updateWithRetry(session_id, reply));
Mock::VerifyAndClear(this);
// We should now be able to create a session and generate a request.
status = cdm_->setServiceCertificate(g_license_service_certificate);
EXPECT_EQ(Cdm::kSuccess, status);
ASSERT_NO_FATAL_FAILURE(CreateSessionAndGenerateRequest(
Cdm::kTemporary, Cdm::kCenc, &session_id, &message));
// Acquire a license and update the session.
ASSERT_NO_FATAL_FAILURE(FetchLicense(
g_license_server, message, &reply));
EXPECT_CALL(*this, onKeyStatusesChange(session_id, true));
status = updateWithRetry(session_id, reply);
EXPECT_EQ(Cdm::kSuccess, status);
Mock::VerifyAndClear(this);
}
TEST_F(CdmIndividualizationTest, WillNotSendRequestTwice) {
if (!CheckProvisioningSupport()) return;
@@ -2008,6 +2060,9 @@ TEST_F(CdmIndividualizationTest, WillNotSendRequestTwice) {
g_host->remove("cert.bin");
// Creating a session should succeed.
Cdm::Status status =
cdm_->setServiceCertificate(g_provisioning_service_certificate);
EXPECT_EQ(Cdm::kSuccess, status);
std::string session_id;
ASSERT_EQ(Cdm::kSuccess, cdm_->createSession(Cdm::kTemporary, &session_id));
@@ -2048,6 +2103,9 @@ TEST_F(CdmIndividualizationTest,
g_host->remove("cert.bin");
// Creating a session should succeed.
Cdm::Status status =
cdm_->setServiceCertificate(g_provisioning_service_certificate);
EXPECT_EQ(Cdm::kSuccess, status);
std::string session_id;
ASSERT_EQ(Cdm::kSuccess, cdm_->createSession(Cdm::kTemporary, &session_id));
@@ -2074,6 +2132,8 @@ TEST_F(CdmIndividualizationTest,
Mock::VerifyAndClear(this);
// We should get a license message for the second session.
status = cdm_->setServiceCertificate(g_license_service_certificate);
EXPECT_EQ(Cdm::kSuccess, status);
EXPECT_CALL(*this, onMessage(session_id2, Cdm::kLicenseRequest, _)).Times(1);
ASSERT_EQ(Cdm::kSuccess,
generateRequestWithRetry(session_id2, Cdm::kCenc, kCencInitData));
@@ -2087,6 +2147,9 @@ TEST_F(CdmIndividualizationTest, PropagatesErrorsInUpdate) {
g_host->remove("cert.bin");
// Creating a session should succeed.
Cdm::Status status =
cdm_->setServiceCertificate(g_provisioning_service_certificate);
EXPECT_EQ(Cdm::kSuccess, status);
std::string session_id;
ASSERT_EQ(Cdm::kSuccess, cdm_->createSession(Cdm::kTemporary, &session_id));
@@ -2114,6 +2177,9 @@ TEST_F(CdmIndividualizationTest, OnlyPropagatesErrorsForThisSession) {
g_host->remove("cert.bin");
// Creating a session should succeed.
Cdm::Status status =
cdm_->setServiceCertificate(g_provisioning_service_certificate);
EXPECT_EQ(Cdm::kSuccess, status);
std::string session_id;
ASSERT_EQ(Cdm::kSuccess, cdm_->createSession(Cdm::kTemporary, &session_id));
@@ -2143,7 +2209,7 @@ TEST_F(CdmIndividualizationTest, OnlyPropagatesErrorsForThisSession) {
Mock::VerifyAndClear(this);
}
// TODO(fredgc,rfrias): turn this on after big usage tables work.
// TODO(b/34949512): Fix this test so it can be re-enabled.
TEST_F(CdmIndividualizationTest, DISABLED_WorksWithLoad) {
if (!CheckProvisioningSupport()) return;
@@ -2189,6 +2255,9 @@ TEST_F(CdmIndividualizationTest, WillResendOnProvisioningError) {
g_host->remove("cert.bin");
// Creating a session should succeed.
Cdm::Status status =
cdm_->setServiceCertificate(g_provisioning_service_certificate);
EXPECT_EQ(Cdm::kSuccess, status);
std::string session_id;
ASSERT_EQ(Cdm::kSuccess, cdm_->createSession(Cdm::kTemporary, &session_id));

View File

@@ -1,4 +1,6 @@
// Copyright 2015 Google Inc. All Rights Reserved.
// 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.
#include <assert.h>
#include <getopt.h>

View File

@@ -1,4 +1,6 @@
// Copyright 2015 Google Inc. All Rights Reserved.
// 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.
#include "cdm_test_printers.h"

View File

@@ -1,4 +1,6 @@
// Copyright 2015 Google Inc. All Rights Reserved.
// 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.
// This file adds some print methods so that when unit tests fail, the
// will print the name of an enumeration instead of the numeric value.

View File

@@ -1,4 +1,6 @@
// Copyright 2016 Google Inc. All Rights Reserved.
// 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.
//
// This source file contains the test data used to verify decryption behavior
// in cdm_test.cpp.

View File

@@ -1,4 +1,6 @@
// Copyright 2014 Google Inc. All Rights Reserved.
// 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.
#include "device_cert.h"
@@ -334,4 +336,3 @@ const uint8_t kDeviceCert[] = {
};
const size_t kDeviceCertSize = sizeof(kDeviceCert);

View File

@@ -1,4 +1,6 @@
// Copyright 2014 Google Inc. All Rights Reserved.
// 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.
#ifndef WVCDM_CDM_TEST_DEVICE_CERT_H_
#define WVCDM_CDM_TEST_DEVICE_CERT_H_

View File

@@ -1,4 +1,6 @@
// Copyright 2017 Google Inc. All Rights Reserved
// 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.
/*********************************************************************
* level3_file_system_ce_test.h
@@ -32,4 +34,4 @@ class OEMCrypto_Level3CETestFileSystem : public OEMCrypto_Level3FileSystem {
} // namespace wvoec3
#endif
#endif

View File

@@ -1,4 +1,6 @@
// Copyright 2015 Google Inc. All Rights Reserved.
// 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.
#include "test_host.h"
#include <gtest/gtest.h>

View File

@@ -1,4 +1,6 @@
// Copyright 2015 Google Inc. All Rights Reserved.
// 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.
#ifndef WVCDM_CDM_TEST_TEST_HOST_H_
#define WVCDM_CDM_TEST_TEST_HOST_H_