Note that this version does not have Widevine Provisioning 4.0 support. It is only suitable for device upgrades. A new patch with provisioning 4.0 support will be made later.
211 lines
6.9 KiB
C++
211 lines
6.9 KiB
C++
// 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 WIDEVINE_CAS_LICENSE_KEY_STATUS_H_
|
|
#define WIDEVINE_CAS_LICENSE_KEY_STATUS_H_
|
|
|
|
#include <map>
|
|
|
|
#include "crypto_session.h"
|
|
#include "license_protocol.pb.h"
|
|
|
|
namespace wvcas {
|
|
|
|
class LicenseKeyStatus;
|
|
|
|
using video_widevine::WidevinePsshData_EntitledKey;
|
|
|
|
// Policy engine HDCP enforcement
|
|
static constexpr uint32_t HDCP_UNSPECIFIED_VIDEO_RESOLUTION = 0;
|
|
static constexpr int64_t HDCP_DEVICE_CHECK_INTERVAL = 10;
|
|
|
|
enum KeySecurityLevel {
|
|
kKeySecurityLevelUnset,
|
|
kSoftwareSecureCrypto,
|
|
kSoftwareSecureDecode,
|
|
kHardwareSecureCrypto,
|
|
kHardwareSecureDecode,
|
|
kHardwareSecureAll,
|
|
kKeySecurityLevelUnknown,
|
|
};
|
|
|
|
class KeyAllowedUsage {
|
|
public:
|
|
KeyAllowedUsage() { Clear(); }
|
|
|
|
bool Valid() const { return valid_; }
|
|
void SetValid() { valid_ = true; }
|
|
|
|
void Clear() {
|
|
decrypt_to_clear_buffer = false;
|
|
decrypt_to_secure_buffer = false;
|
|
generic_encrypt = false;
|
|
generic_decrypt = false;
|
|
generic_sign = false;
|
|
generic_verify = false;
|
|
key_security_level_ = kKeySecurityLevelUnset;
|
|
valid_ = false;
|
|
}
|
|
|
|
bool Equals(const KeyAllowedUsage& other) {
|
|
if (!valid_ || !other.Valid() ||
|
|
decrypt_to_clear_buffer != other.decrypt_to_clear_buffer ||
|
|
decrypt_to_secure_buffer != other.decrypt_to_secure_buffer ||
|
|
generic_encrypt != other.generic_encrypt ||
|
|
generic_decrypt != other.generic_decrypt ||
|
|
generic_sign != other.generic_sign ||
|
|
generic_verify != other.generic_verify ||
|
|
key_security_level_ != other.key_security_level_) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool decrypt_to_clear_buffer;
|
|
bool decrypt_to_secure_buffer;
|
|
bool generic_encrypt;
|
|
bool generic_decrypt;
|
|
bool generic_sign;
|
|
bool generic_verify;
|
|
KeySecurityLevel key_security_level_;
|
|
|
|
private:
|
|
bool valid_;
|
|
};
|
|
|
|
// Holds all content and operator session keys for a session.
|
|
class LicenseKeys {
|
|
public:
|
|
LicenseKeys() {}
|
|
virtual ~LicenseKeys() { Clear(); }
|
|
|
|
virtual bool Empty() { return key_statuses_.empty(); }
|
|
|
|
// Returns true if the key is a content key (not an operator session key)
|
|
virtual bool IsContentKey(const KeyId& key_id);
|
|
|
|
// Returns true if the key is currently usable for content decryption.
|
|
virtual bool CanDecryptContent(const KeyId& key_id);
|
|
|
|
// Returns the allowed usages for a key.
|
|
virtual bool GetAllowedUsage(const KeyId& key_id,
|
|
KeyAllowedUsage* allowed_usage);
|
|
|
|
// Applies a new status to each content key.
|
|
// Returns true if any statuses changed, and sets new_usable_keys to
|
|
// true if the status changes resulted in keys becoming usable.
|
|
virtual bool ApplyStatusChange(KeyStatus new_status, bool* new_usable_keys);
|
|
|
|
// Returns current KeyStatus for the given key.
|
|
// Returns kKeyStatusKeyUnknown if key_id not found.
|
|
virtual KeyStatus GetKeyStatus(const KeyId& key_id);
|
|
|
|
// Populates a KeyStatusMap with the current content keys.
|
|
virtual void ExtractKeyStatuses(KeyStatusMap* content_keys);
|
|
|
|
// Determines whether the specified key can be used under the current
|
|
// resolution and/or hdcp constraints. If no constraints have been applied
|
|
// to the key, returns true.
|
|
virtual bool MeetsConstraints(const KeyId& key_id);
|
|
|
|
// Applies a resolution and/or hdcp change to each key, updating their
|
|
// useability under their constraints.
|
|
virtual void ApplyConstraints(uint32_t new_resolution,
|
|
HdcpCapability new_hdcp_level);
|
|
|
|
// Extracts the keys from a license and makes them available for
|
|
// querying usage and constraint settings.
|
|
virtual void SetFromLicense(const video_widevine::License& license);
|
|
|
|
// Sets the keys from the input entitled key data.
|
|
virtual void SetEntitledKeys(
|
|
const std::vector<WidevinePsshData_EntitledKey>& keys);
|
|
|
|
LicenseKeys(const LicenseKeys&) = delete;
|
|
LicenseKeys& operator=(const LicenseKeys&) = delete;
|
|
|
|
private:
|
|
typedef ::video_widevine::License::KeyContainer KeyContainer;
|
|
typedef std::map<KeyId, LicenseKeyStatus*>::const_iterator
|
|
LicenseKeyStatusIterator;
|
|
|
|
void Clear();
|
|
|
|
bool is_initialized_;
|
|
// |key_statuses_| can hold either content key statuses, or entitlement key
|
|
// statuses.
|
|
std::map<KeyId, LicenseKeyStatus*> key_statuses_;
|
|
// |content_keyid_to_entitlement_key_id_| maps a content key id to an
|
|
// entitlement_key_id. The resulting key id can be used to obtain the current
|
|
// key status from |key_statuses_| when using entitlement key licensing.
|
|
std::map<KeyId, KeyId> content_keyid_to_entitlement_key_id_;
|
|
};
|
|
|
|
// Holds the current license status of a key.
|
|
class LicenseKeyStatus {
|
|
friend class LicenseKeys;
|
|
|
|
public:
|
|
// Returns true if the key is a content key (not an operator session key)
|
|
virtual bool IsContentKey() { return is_content_key_; }
|
|
|
|
// Returns true if the key is currently usable for content decryption
|
|
virtual bool CanDecryptContent();
|
|
|
|
// Returns the usages allowed for this key.
|
|
virtual bool GetAllowedUsage(KeyAllowedUsage* allowed_usage);
|
|
|
|
// Returns the current status of the key.
|
|
virtual KeyStatus GetKeyStatus() const { return key_status_; }
|
|
|
|
// Applies a new status to this key.
|
|
// Returns true if the status changed, and sets new_usable_keys to
|
|
// true if the status changes resulted in the key becoming usable.
|
|
virtual bool ApplyStatusChange(KeyStatus new_status, bool* new_usable_keys);
|
|
|
|
// Returns the current constraint status of this key. The result
|
|
// may change due to calls to ApplyConstraints().
|
|
// Note: this will return true until the first call to ApplyConstraints().
|
|
virtual bool MeetsConstraints() const { return meets_constraints_; }
|
|
|
|
// Applies the given changes in resolution or HDCP settings.
|
|
virtual void ApplyConstraints(uint32_t new_resolution,
|
|
HdcpCapability new_hdcp_level);
|
|
|
|
LicenseKeyStatus(const LicenseKeyStatus&) = delete;
|
|
LicenseKeyStatus& operator=(const LicenseKeyStatus&) = delete;
|
|
|
|
protected:
|
|
typedef ::video_widevine::License::KeyContainer KeyContainer;
|
|
typedef KeyContainer::OperatorSessionKeyPermissions
|
|
OperatorSessionKeyPermissions;
|
|
typedef KeyContainer::OutputProtection OutputProtection;
|
|
typedef KeyContainer::VideoResolutionConstraint VideoResolutionConstraint;
|
|
typedef ::google::protobuf::RepeatedPtrField<VideoResolutionConstraint>
|
|
ConstraintList;
|
|
|
|
LicenseKeyStatus(const KeyContainer& key);
|
|
|
|
virtual ~LicenseKeyStatus() {}
|
|
|
|
private:
|
|
void ParseContentKey(const KeyContainer& key);
|
|
void ParseOperatorSessionKey(const KeyContainer& key);
|
|
|
|
bool HasConstraints() { return is_content_key_ && constraints_.size() != 0; }
|
|
|
|
void SetConstraints(const ConstraintList& constraints);
|
|
|
|
bool is_content_key_;
|
|
KeyStatus key_status_;
|
|
bool meets_constraints_;
|
|
KeyAllowedUsage allowed_usage_;
|
|
HdcpCapability default_hdcp_level_;
|
|
ConstraintList constraints_;
|
|
};
|
|
|
|
} // namespace wvcas
|
|
|
|
#endif // WIDEVINE_CAS_LICENSE_KEY_STATUS_H_
|