Source release 19.4.0
This commit is contained in:
@@ -62,39 +62,256 @@ class CdmLicense {
|
||||
|
||||
// == License Restoring API ==
|
||||
|
||||
// Restores an offline license for continued use.
|
||||
//
|
||||
// Parameters:
|
||||
// |client_token|
|
||||
// Client's DRM certificate used as the "token" when
|
||||
// authenticating the device and client with the license
|
||||
// server.
|
||||
// |license_request|
|
||||
// Original license request generated by this device.
|
||||
// Expected to be a serialized SignedMessage, with type
|
||||
// LICENSE_REQUEST.
|
||||
// |license_response|
|
||||
// Original license response generated by the license
|
||||
// server, associated with the |license_response|.
|
||||
// Expected to be a serialized SignedMessage, with type
|
||||
// LICENSE.
|
||||
// |license_renewal_response|
|
||||
// Last renewal response received from the renewal license
|
||||
// server.
|
||||
// Expected to be a serialized SignedMessage, with type
|
||||
// LICENSE.
|
||||
// |playback_start_time|, |last_playback_time|, |grace_period_end_time|
|
||||
// License timers from the CDM, not necessarily secure timers.
|
||||
//
|
||||
// Important Results:
|
||||
// NO_ERROR
|
||||
// Successfully restored license for playback.
|
||||
virtual CdmResponseType RestoreOfflineLicense(
|
||||
const std::string& client_token, const CdmKeyMessage& license_request,
|
||||
const CdmKeyResponse& license_response,
|
||||
const CdmKeyResponse& license_renewal_response,
|
||||
int64_t playback_start_time, int64_t last_playback_time,
|
||||
int64_t grace_period_end_time, CdmSession* cdm_session);
|
||||
|
||||
// Restores an offline license for release.
|
||||
//
|
||||
// License is loaded into OEMCrypto with the intention of
|
||||
// generating a release request.
|
||||
// Attempting playback will cause undefined behavior.
|
||||
//
|
||||
// Parameters:
|
||||
// |client_token|
|
||||
// Client's DRM certificate used as the "token" when
|
||||
// authenticating the device and client with the license
|
||||
// server.
|
||||
// |license_request|
|
||||
// Original license request generated by this device.
|
||||
// Expected to be a serialized SignedMessage, with type
|
||||
// LICENSE_REQUEST.
|
||||
// |license_response|
|
||||
// Original license response generated by the license
|
||||
// server, associated with the |license_response|.
|
||||
// Expected to be a serialized SignedMessage, with type
|
||||
// LICENSE.
|
||||
//
|
||||
// Important Results:
|
||||
// NO_ERROR
|
||||
// Successfully restored license for release.
|
||||
virtual CdmResponseType RestoreLicenseForRelease(
|
||||
const std::string& client_token, const CdmKeyMessage& license_request,
|
||||
const CdmKeyResponse& license_response);
|
||||
|
||||
// == Request/Response API ==
|
||||
|
||||
// Generates a license or service certificate request.
|
||||
//
|
||||
// If the license does not have a service certificate, then the
|
||||
// first time calling this method on a newly initialized instance
|
||||
// will generate a service certificate request.
|
||||
//
|
||||
// Parameters:
|
||||
// |init_data|
|
||||
// App provided initialization data. Should be of a supported
|
||||
// format.
|
||||
// |client_token|
|
||||
// Client's DRM certificate used as the "token" when
|
||||
// authenticating the device and client with the license
|
||||
// server.
|
||||
// |license_type|
|
||||
// Type of license to be requested, used in the generation
|
||||
// of the content ID.
|
||||
// |app_parameters|
|
||||
// Optional key-value pair of parameters to be inserted into
|
||||
// the client ID of the license request.
|
||||
// Note: Certain key's are reserved for Widevine use and
|
||||
// cannot be specified by the app.
|
||||
// |signed_request| (out)
|
||||
// Serialized license request to be sent to the server.
|
||||
// Only set if generating license is successful.
|
||||
// This message is a serialized SignedMessage, with type
|
||||
// NEW.
|
||||
// |server_url| (out)
|
||||
// Server URL, never specified by the CDM for new licenses.
|
||||
// Legacy field for older revisions.
|
||||
//
|
||||
// Important Results:
|
||||
// KEY_MESSAGE
|
||||
// Successfully generated a request.
|
||||
// PRIVACY_MODE_ERROR_1
|
||||
// Privacy mode is enabled, but no service certificate has
|
||||
// been provided, and requesting service certificates are
|
||||
// forbidden.
|
||||
// GENERATE_SIGNATURE_ERROR (legacy name)
|
||||
// OEMCrypto was unable to sign the request.
|
||||
virtual CdmResponseType PrepareKeyRequest(
|
||||
const InitializationData& init_data, const std::string& client_token,
|
||||
CdmLicenseType license_type, const CdmAppParameterMap& app_parameters,
|
||||
CdmKeyMessage* signed_request, std::string* server_url);
|
||||
|
||||
// Generates a license renewal or release request.
|
||||
//
|
||||
// For license renewals (|is_renewal| = true), will attempt to
|
||||
// generate a renewal request using the policies specified in the
|
||||
// original license. Playback will continue to be allowed so
|
||||
// long as the policy timers have not expired.
|
||||
//
|
||||
// For license release (|is_renewal| = false), will attempt to
|
||||
// generate a release request using the policies specified in the
|
||||
// original license. Playback will be halted, and not allowed to
|
||||
// resume. For licenses with a usage entry, OEMCrypto will enforce
|
||||
// playback halting, and a usage report will be generated to be
|
||||
// sent with the release.
|
||||
//
|
||||
// Parameters:
|
||||
// |is_renewal|
|
||||
// Flag to indicate whether the generated request is a
|
||||
// renewal (true) or a release (false).
|
||||
// |app_parameters|
|
||||
// Optional key-value pair of parameters to be inserted into
|
||||
// the client ID of the license request.
|
||||
// Note: Certain key's are reserved for Widevine use and
|
||||
// cannot be specified by the app.
|
||||
// |cdm_session|
|
||||
// Handle to the calling CdmSession to allow for usage
|
||||
// reporting.
|
||||
// |signed_request| (out)
|
||||
// Serialized renewal or release request to be sent to the
|
||||
// server. Only set if generating license is successful.
|
||||
// This message is a serialized SignedMessage, with type
|
||||
// RENEWAL or RELEASE.
|
||||
// |server_url| (out)
|
||||
// Server URL to be used for sending renewals. The value
|
||||
// provided is extracted from the license policy received
|
||||
// in the original license response.
|
||||
//
|
||||
// Important Results:
|
||||
// KEY_MESSAGE
|
||||
// Successfully generated a renewal or release request.
|
||||
// LICENSE_RENEWAL_PROHIBITED
|
||||
// License policy forbids license renewals.
|
||||
// GENERATE_SIGNATURE_ERROR (legacy name)
|
||||
// OEMCrypto was unable to sign the request.
|
||||
virtual CdmResponseType PrepareKeyUpdateRequest(
|
||||
bool is_renewal, const CdmAppParameterMap& app_parameters,
|
||||
CdmSession* cdm_session, CdmKeyMessage* signed_request,
|
||||
std::string* server_url);
|
||||
|
||||
// Parses and loads license or service certificate response,
|
||||
// or handles license errors.
|
||||
//
|
||||
// For license response, the content of the license is parsed;
|
||||
// extracting and verifying keys, initializing the license's
|
||||
// policy engine, and updating other policy rules. If license
|
||||
// contains entitlement keys, changes the license type
|
||||
// to entitlement.
|
||||
//
|
||||
// For service certificate response, the service certificate
|
||||
// is parsed and loaded into the |service_certificate_|
|
||||
// field for next call to generate request.
|
||||
//
|
||||
// For error response, parses the error message, producing logs
|
||||
// and returning an appropriate error.
|
||||
//
|
||||
// Parameters:
|
||||
// |license_response|
|
||||
// Serialized license response.
|
||||
// Expected to be a serialized SignedMessage, with type
|
||||
// LICENSE.
|
||||
//
|
||||
// Important Results:
|
||||
// KEY_ADDED
|
||||
// Successfully loaded license.
|
||||
// NEED_KEY
|
||||
// Successfully loaded service certificate, and signals
|
||||
// to the app that another request is required to generate
|
||||
// a license request.
|
||||
// NO_CONTENT_KEY
|
||||
// License was received, but did not contain any content
|
||||
// or operator session keys.
|
||||
// LOAD_LICENSE_ERROR
|
||||
// OEMCrypto rejected the license, see logs for details.
|
||||
virtual CdmResponseType HandleKeyResponse(
|
||||
bool is_restore, const CdmKeyResponse& license_response);
|
||||
const CdmKeyResponse& license_response) {
|
||||
return HandleKeyResponseInternal(/* is_restore = */ false,
|
||||
license_response);
|
||||
}
|
||||
|
||||
// Parses and loads renewal response, or handles license
|
||||
// errors.
|
||||
//
|
||||
// For license renewal response, the content of the renewal is
|
||||
// parsed; updating policy timers and other license policy
|
||||
// variables.
|
||||
//
|
||||
// For error response, parses the error message, producing logs
|
||||
// and returning an appropriate error.
|
||||
//
|
||||
// Parameters:
|
||||
// |license_response|
|
||||
// Serialized license renewal response.
|
||||
// Expected to be a serialized SignedMessage, with type
|
||||
// LICENSE.
|
||||
//
|
||||
// Important Results:
|
||||
// KEY_ADDED
|
||||
// Successfully loaded renewal.
|
||||
// NO_CONTENT_KEY
|
||||
// License was received, but did not contain any content
|
||||
// or operator session keys.
|
||||
// LOAD_LICENSE_ERROR
|
||||
// OEMCrypto rejected the license, see logs for details.
|
||||
virtual CdmResponseType HandleKeyUpdateResponse(
|
||||
bool is_renewal, bool is_restore, const CdmKeyResponse& license_response);
|
||||
bool is_renewal, const CdmKeyResponse& license_response) {
|
||||
return HandleKeyUpdateResponseInternal(is_renewal, /* is_restore = */ false,
|
||||
license_response);
|
||||
}
|
||||
|
||||
// Parses and loads new embedded keys.
|
||||
//
|
||||
// Updates the license's key session with new entitled keys
|
||||
// for which the license has entitlement keys for. Storing
|
||||
// those keys internally as new content keys.
|
||||
//
|
||||
// Used exclusively for entitlement licenses.
|
||||
//
|
||||
// Parameters:
|
||||
// |init_data|
|
||||
// Initialization data containing entitled keys within
|
||||
// the PSSH data.
|
||||
//
|
||||
// Important Results:
|
||||
// KEY_ADDED
|
||||
// Successfully loaded new entitled keys.
|
||||
virtual CdmResponseType HandleEmbeddedKeyData(
|
||||
const InitializationData& init_data);
|
||||
|
||||
// == Utilities ==
|
||||
|
||||
// Utility method for extracting the provider session token
|
||||
// from the license response.
|
||||
static bool ExtractProviderSessionToken(
|
||||
const CdmKeyResponse& license_response,
|
||||
std::string* provider_session_token);
|
||||
@@ -110,11 +327,22 @@ class CdmLicense {
|
||||
policy_engine_ = policy_engine;
|
||||
}
|
||||
|
||||
private:
|
||||
protected:
|
||||
// Test Constructor.
|
||||
// CdmLicense takes ownership of the clock.
|
||||
CdmLicense(const CdmSessionId& session_id, wvutil::Clock* clock);
|
||||
|
||||
// Inserts an entitlement key ID from test data.
|
||||
void InsertEntitlementKeyIdForTest(const KeyId& entitlement_key_id) {
|
||||
entitlement_key_ids_.insert(entitlement_key_id);
|
||||
}
|
||||
|
||||
CdmResponseType HandleNewEntitledKeysForTest(
|
||||
const std::vector<PsshEntitledKey>& packaged_entitled_keys) {
|
||||
return HandleNewEntitledKeysInternal(packaged_entitled_keys);
|
||||
}
|
||||
|
||||
private:
|
||||
// == Internal Request/Response API ==
|
||||
|
||||
// Prepare to reload a key update message. Some special code is needed to work
|
||||
@@ -122,9 +350,25 @@ class CdmLicense {
|
||||
// TODO(b/166007195): Remove this.
|
||||
CdmResponseType PrepareKeyUpdateReload(CdmSession* cdm_session);
|
||||
|
||||
// Used internally to handle license responses for both newly acquired
|
||||
// licenses and for restoring of offline licenses.
|
||||
CdmResponseType HandleKeyResponseInternal(
|
||||
bool is_restore, const CdmKeyResponse& license_response);
|
||||
|
||||
// Used internally to handle renewal responses for both newly acquired
|
||||
// renewals and for restoring of offline licenses which had received
|
||||
// renewals.
|
||||
CdmResponseType HandleKeyUpdateResponseInternal(
|
||||
bool is_renewal, bool is_restore, const CdmKeyResponse& license_response);
|
||||
|
||||
// Used internally to handle license error responses for both
|
||||
// license requests and renewal requests. Maps the error code
|
||||
// from the license protocol to a CDM error code.
|
||||
CdmResponseType HandleKeyErrorResponse(
|
||||
const video_widevine::SignedMessage& signed_message);
|
||||
|
||||
// Used internally to load the content license into OEMCrypto
|
||||
// and update the license data if successful.
|
||||
CdmResponseType HandleContentKeyResponse(
|
||||
bool is_restore, const std::string& session_key, const std::string& msg,
|
||||
const std::string& core_message, const std::string& signature,
|
||||
@@ -142,7 +386,9 @@ class CdmLicense {
|
||||
const std::vector<CryptoKey>& license_keys,
|
||||
const video_widevine::License& license);
|
||||
|
||||
CdmResponseType HandleNewEntitledKeys(
|
||||
// Used internally to load the entitlement keys from
|
||||
// outside the license into the CryptoSession.
|
||||
CdmResponseType HandleNewEntitledKeysInternal(
|
||||
const std::vector<PsshEntitledKey>& packaged_entitled_keys);
|
||||
|
||||
// == Internal Utilities ==
|
||||
@@ -163,60 +409,116 @@ class CdmLicense {
|
||||
|
||||
// == Creation-time Variables ==
|
||||
|
||||
// CDM session ID associated with this license. CdmLicense should
|
||||
// only be associated with a single CDM session.
|
||||
const CdmSessionId session_id_;
|
||||
// Internal clock used to get REE system-time.
|
||||
// For production, uses the default Clock implementation;
|
||||
// for testing, uses a MockClock.
|
||||
std::unique_ptr<wvutil::Clock> clock_;
|
||||
|
||||
// == Initialization-time Variables ==
|
||||
|
||||
// Flag to indicate that the CdmLicense has been initialized
|
||||
// correctly via a call to Init().
|
||||
bool initialized_ = false;
|
||||
// License's crypto session, owned by the CdmSession which owns
|
||||
// this instance.
|
||||
CryptoSession* crypto_session_ = nullptr;
|
||||
// License's policy engine, owned by the CdmSession which owns
|
||||
// this instance.
|
||||
PolicyEngine* policy_engine_ = nullptr;
|
||||
|
||||
// Associated with ClientIdentification encryption
|
||||
// The flag |use_privacy_mode_| is used to determine whether
|
||||
// the client identification field should be encrypted when
|
||||
// generating license / renewal request.
|
||||
bool use_privacy_mode_ = false;
|
||||
// The service certificate used to encrypt client
|
||||
// identification. Must be initialized if |use_privacy_mode_|
|
||||
// is true.
|
||||
ServiceCertificate service_certificate_;
|
||||
|
||||
// Assume the latest, and downgrade later.
|
||||
// May be downgraded based on the OEMCrypto level, or the
|
||||
// license response.
|
||||
video_widevine::ProtocolVersion protocol_version_ =
|
||||
video_widevine::VERSION_2_2;
|
||||
|
||||
// == License Request/Response variables ==
|
||||
|
||||
// Device-side token used to authenticate the license request
|
||||
// with the license server.
|
||||
// Always contains a serialized DRM certificate associated
|
||||
// with the client.
|
||||
std::string client_token_;
|
||||
|
||||
// Contains the initialization data that was provided by the app
|
||||
// when making the first request.
|
||||
// Used for certain devices which may perform a service certificate
|
||||
// request. The app will only provided the license init data on
|
||||
// the first request, but may not provide initialization data on
|
||||
// the follow up request.
|
||||
std::unique_ptr<InitializationData> stored_init_data_;
|
||||
|
||||
// The nonce used in the original license request.
|
||||
uint32_t license_nonce_ = 0;
|
||||
|
||||
// Serialized LicenseRequest proto.
|
||||
// Either originates internally from a license request generated
|
||||
// since the opening of this session; or provided while restoring
|
||||
// of a license.
|
||||
CdmKeyMessage license_request_;
|
||||
|
||||
// For entitlement key licensing. This holds the keys from the init_data.
|
||||
// These keys are extracted from the PSSH when we generate a license request.
|
||||
// It is used to load content keys after we have received a license and
|
||||
// entitlement keys. It is also used in updating the key status info.
|
||||
// These are extracted from the PSSH from the initialization data.
|
||||
// They are used to load entitled content keys after the license
|
||||
// has been received. It is also used in updating the key status
|
||||
// info.
|
||||
// Used exclusively for entitlement key licensing.
|
||||
// These entitled keys are extracted at license request time.
|
||||
std::vector<PsshEntitledKey> request_entitled_keys_;
|
||||
|
||||
// Content-provider token for identifying a client's device across
|
||||
// multiple sessions/licenses.
|
||||
std::string provider_client_token_;
|
||||
// Content-provider token for identifying a client's session for
|
||||
// a single persistent license, and potentially across multiple
|
||||
// restores.
|
||||
std::string provider_session_token_;
|
||||
|
||||
// Flag to indicate that a renewal request requires a client ID.
|
||||
// This is specified in the license.
|
||||
bool renew_with_client_id_ = false;
|
||||
|
||||
// Server URL which the client app should use when requesting
|
||||
// a renewal.
|
||||
std::string renewal_server_url_;
|
||||
|
||||
// This is the latest version info extracted from the SignedMessage in
|
||||
// HandleKeyResponse
|
||||
// This is the latest version info extracted from the SignedMessage
|
||||
// when loading a received license.
|
||||
video_widevine::VersionInfo latest_service_version_;
|
||||
|
||||
// == License Life-Time Variables ==
|
||||
|
||||
// A license is assumed to be content type until the license
|
||||
// response changes that.
|
||||
CdmLicenseKeyType license_key_type_ = kLicenseKeyTypeContent;
|
||||
|
||||
// Flag to indicate that the license is offline.
|
||||
// A license is assumed to be streaming/online until a response is
|
||||
// received. This flag is determined by the license
|
||||
// type (OFFLINE) and the policy's "can persist" flag.
|
||||
bool is_offline_ = false;
|
||||
|
||||
// A list of content keys (either basic content keys, or entitled
|
||||
// content keys) which have been received.
|
||||
// Note: for entitlement licenses, this is updated when new entitled
|
||||
// content keys are received.
|
||||
std::set<KeyId> content_key_ids_;
|
||||
std::set<KeyId> entitlement_key_ids_;
|
||||
|
||||
#if defined(UNIT_TEST)
|
||||
friend class CdmLicenseTestPeer;
|
||||
#endif
|
||||
// A list of entitlement key IDs from the license. Used to filter
|
||||
// out the any entitled keys tied to an entitlement key which are
|
||||
// not specified in the license response.
|
||||
std::set<KeyId> entitlement_key_ids_;
|
||||
}; // class CdmLicense
|
||||
} // namespace wvcdm
|
||||
#endif // WVCDM_CORE_LICENSE_H_
|
||||
|
||||
Reference in New Issue
Block a user