Source release 15.0.0

This commit is contained in:
John W. Bruce
2019-02-28 16:25:30 -08:00
parent f51edaba5a
commit 66628486b5
2672 changed files with 260431 additions and 762489 deletions

View File

@@ -6,33 +6,26 @@
#ifndef WVCDM_CDM_CDM_H_
#define WVCDM_CDM_CDM_H_
#if defined(_MSC_VER)
typedef unsigned char uint8_t;
typedef unsigned int uint32_t;
typedef int int32_t;
typedef __int64 int64_t;
#else
# include <stdint.h>
#endif
#include <stdint.h>
#include <map>
#include <string>
#include <vector>
// Define CDM_EXPORT to export functionality across shared library boundaries.
#if defined(WIN32)
#if defined(_WIN32)
# if defined(CDM_IMPLEMENTATION)
# define CDM_EXPORT __declspec(dllexport)
# else
# define CDM_EXPORT __declspec(dllimport)
# endif // defined(CDM_IMPLEMENTATION)
#else // defined(WIN32)
#else // defined(_WIN32)
# if defined(CDM_IMPLEMENTATION)
# define CDM_EXPORT __attribute__((visibility("default")))
# else
# define CDM_EXPORT
# endif
#endif // defined(WIN32)
#endif // defined(_WIN32)
namespace widevine {
@@ -63,8 +56,6 @@ class CDM_EXPORT Cdm : public ITimerClient {
kLicenseRelease = 2,
kIndividualizationRequest = 3, // Not used. Direct Individualization
// is used instead of App-Assisted
kLicenseSub = 4 // Used in loading sub licenses from
// embedded key data.
} MessageType;
// Status codes returned by CDM functions.
@@ -93,10 +84,6 @@ class CDM_EXPORT Cdm : public ITimerClient {
kKeyUsageBlockedByPolicy = 105,
kRangeError = 106,
// The action could not be completed yet but has been scheduled to be done
// later. A call to |event_listener.onDeferredComplete| will be made once
// the action is complete.
kDeferred = 99998,
// This covers errors that we do not expect (see logs for details):
kUnexpectedError = 99999,
} Status;
@@ -181,6 +168,16 @@ class CDM_EXPORT Cdm : public ITimerClient {
kVerbose = 4,
} LogLevel;
// Types of service defined by Widevine.
// The service certificate installation methods - Cdm::setServiceCertificate()
// and Cdm::parseAndLoadServiceCertificateResponse() - use these to identify
// which service the certificate is intended for.
typedef enum {
kAllServices = 0,
kProvisioningService = 1,
kLicensingService = 2,
} ServiceRole;
// A map of key statuses.
// See Cdm::getKeyStatuses().
typedef std::map<std::string, KeyStatus> KeyStatusMap;
@@ -209,10 +206,6 @@ class CDM_EXPORT Cdm : public ITimerClient {
virtual void onDeferredComplete(const std::string& session_id,
Status result) = 0;
// Called when the CDM requires a new device certificate
virtual void onDirectIndividualizationRequest(
const std::string& session_id, const std::string& request) = 0;
protected:
IEventListener() {}
virtual ~IEventListener() {}
@@ -235,10 +228,8 @@ class CDM_EXPORT Cdm : public ITimerClient {
// See http://www.w3.org/TR/encrypted-media/#privacy-storedinfo.
class IStorage {
public:
virtual bool read(const std::string& name,
std::string* data) = 0;
virtual bool write(const std::string& name,
const std::string& data) = 0;
virtual bool read(const std::string& name, std::string* data) = 0;
virtual bool write(const std::string& name, const std::string& data) = 0;
virtual bool exists(const std::string& name) = 0;
virtual bool remove(const std::string& name) = 0;
virtual int32_t size(const std::string& name) = 0;
@@ -282,12 +273,11 @@ class CDM_EXPORT Cdm : public ITimerClient {
typedef ITimerClient IClient;
// Call |client->onTimerExpired(context)| after a delay of |delay_ms| ms.
virtual void setTimeout(int64_t delay_ms,
IClient* client,
virtual void setTimeout(int64_t delay_ms, IClient* client,
void* context) = 0;
// Cancel the timer associated with |client|.
virtual void cancel(IClient *client) = 0;
virtual void cancel(IClient* client) = 0;
protected:
ITimer() {}
@@ -332,13 +322,9 @@ class CDM_EXPORT Cdm : public ITimerClient {
// 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(
SecureOutputType secure_output_type,
const ClientInfo& client_info,
IStorage* storage,
IClock* clock,
ITimer* timer,
LogLevel verbosity);
static Status initialize(SecureOutputType secure_output_type,
const ClientInfo& client_info, IStorage* storage,
IClock* clock, ITimer* timer, LogLevel verbosity);
// Query the CDM library version.
static const char* version();
@@ -359,28 +345,33 @@ class CDM_EXPORT Cdm : public ITimerClient {
// the server.
// This is particularly useful for browser environments, but is recommended
// for use whenever possible.
static Cdm* create(IEventListener* listener,
IStorage* storage,
static Cdm* create(IEventListener* listener, IStorage* storage,
bool privacy_mode);
virtual ~Cdm() {}
// The following three methods relate to service certificates. The service
// certificate holds the RSA public key for the server and other fields needed
// for provisioning. It is mandatory if privacy mode is turned on, as it
// is used to encrypt portions of outgoing messages.
// If a certificate has not been installed before generating a provisioning
// request, a default certificate that only works with the Widevine-hosted
// provisioning service will be used.
// It is an error to generate a license request while privacy mode is turned
// on without installing a service certificate first.
// The following three methods relate to service certificates. A service
// certificate holds the RSA public key for a server, as well as other fields
// needed for provisioning. Service certificates are mandatory if privacy mode
// is turned on, as they are used to encrypt portions of outgoing messages to
// the provisioning and licensing servers.
// If a provisioning service certificate has not been installed before
// generating a provisioning request, a default certificate that only works
// with the Widevine-hosted provisioning service will be used.
// It is an error to generate a licensing request while privacy mode is
// turned on without installing a service certificate for the licensing
// service first.
// Installs a service certificate from a data buffer.
// This is used when the system or application already knows the certificate
// of the service it wishes to communicate with, either because it is baked
// into the software or because it was previously cached after a call to
// parseServiceCertificateResponse().
virtual Status setServiceCertificate(const std::string& certificate) = 0;
// Cdm::parseAndLoadServiceCertificateResponse().
// The certificate is installed only for the service given by |role|. If the
// role |ServiceRole::kAllServices| is given, it is installed for all
// services.
virtual Status setServiceCertificate(ServiceRole role,
const std::string& certificate) = 0;
// Generate a Service Certificate Request message.
// This is used to fetch a service certificate from the license server.
@@ -397,9 +388,13 @@ class CDM_EXPORT Cdm : public ITimerClient {
// The service certificate is installed if no error is returned. The returned
// certificate string may be used in future sessions as the input to
// setServiceCertificate(), to avoid needing to make a call to the license
// server to get the certificate.
virtual Status parseServiceCertificateResponse(const std::string& response,
std::string* certificate) = 0;
// server to get the certificate. The |certificate| argument may be NULL.
// The certificate is installed only for the service given by |role|. If the
// role |ServiceRole::kAllServices| is given, it is installed for all
// services.
virtual Status parseAndLoadServiceCertificateResponse(
ServiceRole role, const std::string& response,
std::string* certificate) = 0;
// Determine if the device has a Device Certificate (for the current origin).
// The Device Certificate is origin-specific, and the origin is
@@ -452,7 +447,7 @@ class CDM_EXPORT Cdm : public ITimerClient {
// Creates a new session.
// Do not use this to load an existing persistent session (use load()).
// If successful, the session_id is returned via |sessionId|.
// If successful, the session ID is returned via |session_id|.
virtual Status createSession(SessionType session_type,
std::string* session_id) = 0;
@@ -467,17 +462,19 @@ class CDM_EXPORT Cdm : public ITimerClient {
// Loads an existing persisted session from storage.
virtual Status load(const std::string& session_id) = 0;
// Loads a new sublicense as specified in init_data.
virtual Status load(const std::string& session_id,
InitDataType init_data_type,
const std::string& init_data) = 0;
// Provides messages, including licenses, to the CDM.
// If the message is a successful response to a release message, stored
// session data will be removed for the session.
virtual Status update(const std::string& session_id,
const std::string& response) = 0;
// Loads the entitled keys embedded in |init_data| into the session identified
// by |session_id|. This function is only used when using entitlement
// licenses for key rotation.
virtual Status loadEmbeddedKeys(const std::string& session_id,
InitDataType init_data_type,
const std::string& init_data) = 0;
// The time, in milliseconds since 1970 UTC, after which the key(s) in the
// session will no longer be usable to decrypt media data, or -1 if no such
// time exists.
@@ -533,13 +530,10 @@ class CDM_EXPORT Cdm : public ITimerClient {
// number of clear blocks, after which it repeats.
struct Pattern {
public:
Pattern()
: encrypted_blocks(0),
clear_blocks(0) {}
Pattern() : encrypted_blocks(0), clear_blocks(0) {}
Pattern(uint32_t encrypt, uint32_t clear)
: encrypted_blocks(encrypt),
clear_blocks(clear) {}
: encrypted_blocks(encrypt), clear_blocks(clear) {}
// The number of crypto blocks that are encrypted and therefore need to be
// decrypted.
@@ -553,18 +547,18 @@ class CDM_EXPORT Cdm : public ITimerClient {
struct InputBuffer {
public:
InputBuffer()
: key_id(NULL),
key_id_length(0),
iv(NULL),
iv_length(0),
pattern(),
data(NULL),
data_length(0),
block_offset(0),
encryption_scheme(kAesCtr),
is_video(true),
first_subsample(true),
last_subsample(true) {}
: key_id(nullptr),
key_id_length(0),
iv(nullptr),
iv_length(0),
pattern(),
data(nullptr),
data_length(0),
block_offset(0),
encryption_scheme(kAesCtr),
is_video(true),
first_subsample(true),
last_subsample(true) {}
const uint8_t* key_id;
uint32_t key_id_length;
@@ -611,10 +605,7 @@ class CDM_EXPORT Cdm : public ITimerClient {
struct OutputBuffer {
OutputBuffer()
: data(NULL),
data_length(0),
data_offset(0),
is_secure(false) {}
: data(nullptr), data_length(0), data_offset(0), is_secure(false) {}
// If |is_secure| is false or the secure output type is kNoSecureOutput,
// this is a memory address in main memory.
@@ -642,10 +633,20 @@ class CDM_EXPORT Cdm : public ITimerClient {
};
// Decrypt the input as described by |input| and pass the output as described
// in |output|.
// in |output|. The |key_id| field of |input| must refer to a key that is
// already loaded in some session.
virtual Status decrypt(const InputBuffer& input,
const OutputBuffer& output) = 0;
// Decrypt the input as described by |input| and pass the output as described
// in |output|. Decryption will be attempted in the session identified by
// |session_id|, regardless of whether the |key_id| field of |input| refers to
// a key loaded in that session. This overload may be useful on platforms that
// need to play clear content through the secure path before a key is loaded.
virtual Status decrypt(const std::string& session_id,
const InputBuffer& input,
const OutputBuffer& output) = 0;
// Sets a value in the custom app settings. These are settings
// that are sent with any message to the license server. These methods
// should only be used by advanced users maintaining existing systems.
@@ -681,36 +682,44 @@ class CDM_EXPORT Cdm : public ITimerClient {
} GenericSigningAlgorithmType;
// Encrypts a buffer of app-level data.
virtual Status genericEncrypt(
const std::string& session_id, const std::string& in_buffer,
const std::string& key_id, const std::string& iv,
GenericEncryptionAlgorithmType algorithm, std::string* out_buffer) = 0;
virtual Status genericEncrypt(const std::string& session_id,
const std::string& in_buffer,
const std::string& key_id,
const std::string& iv,
GenericEncryptionAlgorithmType algorithm,
std::string* out_buffer) = 0;
// Decrypts a buffer of app-level data.
virtual Status genericDecrypt(
const std::string& session_id, const std::string& in_buffer,
const std::string& key_id, const std::string& iv,
GenericEncryptionAlgorithmType algorithm, std::string* out_buffer) = 0;
virtual Status genericDecrypt(const std::string& session_id,
const std::string& in_buffer,
const std::string& key_id,
const std::string& iv,
GenericEncryptionAlgorithmType algorithm,
std::string* out_buffer) = 0;
// Signs a buffer of app-level data.
virtual Status genericSign(
const std::string& session_id, const std::string& message,
const std::string& key_id, GenericSigningAlgorithmType algorithm,
std::string* signature) = 0;
virtual Status genericSign(const std::string& session_id,
const std::string& message,
const std::string& key_id,
GenericSigningAlgorithmType algorithm,
std::string* signature) = 0;
// Verifies the signature on a buffer of app-level data.
// Returns kSuccess if signature is verified, otherwise returns kDecryptError.
virtual Status genericVerify(
const std::string& session_id, const std::string& message,
const std::string& key_id, GenericSigningAlgorithmType algorithm,
const std::string& signature) = 0;
virtual Status genericVerify(const std::string& session_id,
const std::string& message,
const std::string& key_id,
GenericSigningAlgorithmType algorithm,
const std::string& signature) = 0;
// Enable enforcement of Video Resolution Constraints.
// This function should be called during session startup and any time
// the video resolution changes.
// Video resolution in license policy is a 32-bit value representing pixels.
// If the product of width and height is greater than or equal to 1^32,
// return kRangeError.
// the resolution of the video stream changes. The resolution passed in should
// be the resolution of the content being played, not the output resolution of
// the device.
// Video resolutions in the license policy are stored as 32-bit values
// representing the total number of pixels. If the product of |width| and
// |height| is greater than or equal to 2^32, this will return kRangeError.
virtual Status setVideoResolution(const std::string& session_id,
uint32_t width, uint32_t height) = 0;