Provisioning 3.0: Changes to Provisioning and Service Certs.
[ Merge of http://go/wvgerrit/23360 ] Service Certificates are used in two places, provisioning and licensing. The service certificate code depended on a session_id to get and set the service certificate properties, but the session_id was not available in the provisioning path. This patch pulls out the property lookup by session_id dependency, and passes the CdmImpl's property_set into the provisioning code, so the service certificate can be read and written there. Bug: 62972441 Test: WV unit/integration tests. This introduces three test failures * WvCdmRequestLicenseTest.PrivacyModeWithServiceCertificateTest * Cdm/WvCdmStreamingLicenseRenewalTest.WithClientId/4 * Cdm/WvCdmOfflineLicenseReleaseTest.WithClientId/3 Change-Id: I6e9d4e23a9e7e81a63a994db8ec0b443893449a6
This commit is contained in:
@@ -17,10 +17,6 @@ class CdmClientPropertySet {
|
|||||||
virtual bool use_privacy_mode() const = 0;
|
virtual bool use_privacy_mode() const = 0;
|
||||||
virtual const std::string& service_certificate() const = 0;
|
virtual const std::string& service_certificate() const = 0;
|
||||||
virtual void set_service_certificate(const std::string& cert) = 0;
|
virtual void set_service_certificate(const std::string& cert) = 0;
|
||||||
virtual const std::string& device_provisioning_service_certificate() const
|
|
||||||
= 0;
|
|
||||||
virtual void set_device_provisioning_service_certificate(
|
|
||||||
const std::string& cert) = 0;
|
|
||||||
virtual bool is_session_sharing_enabled() const = 0;
|
virtual bool is_session_sharing_enabled() const = 0;
|
||||||
virtual uint32_t session_sharing_id() const = 0;
|
virtual uint32_t session_sharing_id() const = 0;
|
||||||
virtual void set_session_sharing_id(uint32_t id) = 0;
|
virtual void set_session_sharing_id(uint32_t id) = 0;
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
#include "oemcrypto_adapter.h"
|
#include "oemcrypto_adapter.h"
|
||||||
#include "scoped_ptr.h"
|
#include "scoped_ptr.h"
|
||||||
#include "timer_metric.h"
|
#include "timer_metric.h"
|
||||||
|
#include "service_certificate.h"
|
||||||
#include "wv_cdm_constants.h"
|
#include "wv_cdm_constants.h"
|
||||||
#include "wv_cdm_types.h"
|
#include "wv_cdm_types.h"
|
||||||
|
|
||||||
@@ -38,21 +39,31 @@ class CdmEngine {
|
|||||||
CdmEngine(FileSystem* file_system, const std::string& spoid = EMPTY_SPOID);
|
CdmEngine(FileSystem* file_system, const std::string& spoid = EMPTY_SPOID);
|
||||||
virtual ~CdmEngine();
|
virtual ~CdmEngine();
|
||||||
|
|
||||||
|
// Set service certificate for all sessions under this CDM/CdmEngine.
|
||||||
|
// Setting to the empty string is OK. If the License Service certificate is
|
||||||
|
// empty and privacy mode is true, the certificate will be fetched from
|
||||||
|
// the server before the first license request.
|
||||||
|
virtual CdmResponseType SetServiceCertificate(
|
||||||
|
const std::string& certificate);
|
||||||
|
|
||||||
// Session related methods
|
// Session related methods
|
||||||
virtual CdmResponseType OpenSession(const CdmKeySystem& key_system,
|
virtual CdmResponseType OpenSession(
|
||||||
CdmClientPropertySet* property_set,
|
const CdmKeySystem& key_system, CdmClientPropertySet* property_set,
|
||||||
const CdmSessionId& forced_session_id,
|
const CdmSessionId& forced_session_id,
|
||||||
WvCdmEventListener* event_listener);
|
WvCdmEventListener* event_listener);
|
||||||
virtual CdmResponseType OpenSession(const CdmKeySystem& key_system,
|
|
||||||
CdmClientPropertySet* property_set,
|
virtual CdmResponseType OpenSession(
|
||||||
WvCdmEventListener* event_listener,
|
const CdmKeySystem& key_system, CdmClientPropertySet* property_set,
|
||||||
CdmSessionId* session_id);
|
WvCdmEventListener* event_listener, CdmSessionId* session_id);
|
||||||
|
|
||||||
virtual CdmResponseType CloseSession(const CdmSessionId& session_id);
|
virtual CdmResponseType CloseSession(const CdmSessionId& session_id);
|
||||||
|
|
||||||
virtual bool IsOpenSession(const CdmSessionId& session_id);
|
virtual bool IsOpenSession(const CdmSessionId& session_id);
|
||||||
|
|
||||||
virtual CdmResponseType OpenKeySetSession(const CdmKeySetId& key_set_id,
|
virtual CdmResponseType OpenKeySetSession(
|
||||||
CdmClientPropertySet* property_set,
|
const CdmKeySetId& key_set_id, CdmClientPropertySet* property_set,
|
||||||
WvCdmEventListener* event_listener);
|
WvCdmEventListener* event_listener);
|
||||||
|
|
||||||
virtual CdmResponseType CloseKeySetSession(const CdmKeySetId& key_set_id);
|
virtual CdmResponseType CloseKeySetSession(const CdmKeySetId& key_set_id);
|
||||||
|
|
||||||
// License related methods
|
// License related methods
|
||||||
@@ -249,10 +260,9 @@ class CdmEngine {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
// private methods
|
// private methods
|
||||||
CdmResponseType OpenSession(const CdmKeySystem& key_system,
|
CdmResponseType OpenSession(
|
||||||
CdmClientPropertySet* property_set,
|
const CdmKeySystem& key_system, CdmClientPropertySet* property_set,
|
||||||
WvCdmEventListener* event_listener,
|
WvCdmEventListener* event_listener, const CdmSessionId* forced_session_id,
|
||||||
const CdmSessionId* forced_session_id,
|
|
||||||
CdmSessionId* session_id);
|
CdmSessionId* session_id);
|
||||||
|
|
||||||
void DeleteAllUsageReportsUponFactoryReset();
|
void DeleteAllUsageReportsUponFactoryReset();
|
||||||
@@ -290,6 +300,12 @@ class CdmEngine {
|
|||||||
|
|
||||||
static bool seeded_;
|
static bool seeded_;
|
||||||
|
|
||||||
|
// Service certificate for license server and provisioning server.
|
||||||
|
// It is initially empty. If left empty, the operations that
|
||||||
|
// require them (getting provider_id, encrypting ClientIdentification)
|
||||||
|
// are not performed.
|
||||||
|
ServiceCertificate service_certificate_;
|
||||||
|
|
||||||
// usage related variables
|
// usage related variables
|
||||||
scoped_ptr<CdmSession> usage_session_;
|
scoped_ptr<CdmSession> usage_session_;
|
||||||
scoped_ptr<UsagePropertySet> usage_property_set_;
|
scoped_ptr<UsagePropertySet> usage_property_set_;
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
namespace wvcdm {
|
namespace wvcdm {
|
||||||
|
|
||||||
class CdmClientPropertySet;
|
class CdmClientPropertySet;
|
||||||
|
class ServiceCertificate;
|
||||||
class WvCdmEventListener;
|
class WvCdmEventListener;
|
||||||
class UsageTableHeader;
|
class UsageTableHeader;
|
||||||
|
|
||||||
@@ -45,7 +46,8 @@ class CdmSession {
|
|||||||
// |forced_session_id| is caller owned and may be null.
|
// |forced_session_id| is caller owned and may be null.
|
||||||
// |event_listener| is caller owned, may be null, but must be in scope
|
// |event_listener| is caller owned, may be null, but must be in scope
|
||||||
// as long as the session is in scope.
|
// as long as the session is in scope.
|
||||||
virtual CdmResponseType Init(CdmClientPropertySet* cdm_client_property_set,
|
virtual CdmResponseType Init(ServiceCertificate* service_certificate,
|
||||||
|
CdmClientPropertySet* cdm_client_property_set,
|
||||||
const CdmSessionId* forced_session_id,
|
const CdmSessionId* forced_session_id,
|
||||||
WvCdmEventListener* event_listener);
|
WvCdmEventListener* event_listener);
|
||||||
|
|
||||||
|
|||||||
@@ -7,31 +7,37 @@
|
|||||||
|
|
||||||
#include "crypto_session.h"
|
#include "crypto_session.h"
|
||||||
#include "metrics_collections.h"
|
#include "metrics_collections.h"
|
||||||
|
#include "license_protocol.pb.h"
|
||||||
#include "oemcrypto_adapter.h"
|
#include "oemcrypto_adapter.h"
|
||||||
#include "service_certificate.h"
|
#include "scoped_ptr.h"
|
||||||
#include "wv_cdm_types.h"
|
#include "wv_cdm_types.h"
|
||||||
|
|
||||||
namespace wvcdm {
|
namespace wvcdm {
|
||||||
|
|
||||||
|
class CdmClientPropertySet;
|
||||||
class CdmSession;
|
class CdmSession;
|
||||||
class FileSystem;
|
class FileSystem;
|
||||||
|
class ServiceCertificate;
|
||||||
|
|
||||||
class CertificateProvisioning {
|
class CertificateProvisioning {
|
||||||
public:
|
public:
|
||||||
CertificateProvisioning(metrics::CryptoMetrics* metrics) :
|
explicit CertificateProvisioning(metrics::CryptoMetrics* metrics,
|
||||||
|
ServiceCertificate* service_certificate) :
|
||||||
crypto_session_(metrics),
|
crypto_session_(metrics),
|
||||||
cert_type_(kCertificateWidevine),
|
cert_type_(kCertificateWidevine),
|
||||||
service_certificate_(NULL) {};
|
service_certificate_(service_certificate) {}
|
||||||
|
|
||||||
~CertificateProvisioning() {};
|
~CertificateProvisioning() {};
|
||||||
|
|
||||||
// Provisioning related methods
|
// Construct a valid provisioning request.
|
||||||
CdmResponseType GetProvisioningRequest(SecurityLevel requested_security_level,
|
// The request will be sent to the provisioning server.
|
||||||
CdmCertificateType cert_type,
|
CdmResponseType GetProvisioningRequest(
|
||||||
const std::string& cert_authority,
|
SecurityLevel requested_security_level, CdmCertificateType cert_type,
|
||||||
const std::string& origin,
|
const std::string& cert_authority, const std::string& origin,
|
||||||
const std::string& spoid,
|
const std::string& spoid, CdmProvisioningRequest* request,
|
||||||
CdmProvisioningRequest* request,
|
|
||||||
std::string* default_url);
|
std::string* default_url);
|
||||||
|
|
||||||
|
// Process the provisioning response.
|
||||||
CdmResponseType HandleProvisioningResponse(
|
CdmResponseType HandleProvisioningResponse(
|
||||||
FileSystem* file_system,
|
FileSystem* file_system,
|
||||||
const CdmProvisioningResponse& response,
|
const CdmProvisioningResponse& response,
|
||||||
@@ -53,6 +59,7 @@ class CertificateProvisioning {
|
|||||||
bool ParseJsonResponse(const CdmProvisioningResponse& json_str,
|
bool ParseJsonResponse(const CdmProvisioningResponse& json_str,
|
||||||
const std::string& start_substr,
|
const std::string& start_substr,
|
||||||
const std::string& end_substr, std::string* result);
|
const std::string& end_substr, std::string* result);
|
||||||
|
|
||||||
CryptoSession crypto_session_;
|
CryptoSession crypto_session_;
|
||||||
CdmCertificateType cert_type_;
|
CdmCertificateType cert_type_;
|
||||||
ServiceCertificate* service_certificate_;
|
ServiceCertificate* service_certificate_;
|
||||||
|
|||||||
@@ -8,7 +8,6 @@
|
|||||||
#include "initialization_data.h"
|
#include "initialization_data.h"
|
||||||
#include "license_protocol.pb.h"
|
#include "license_protocol.pb.h"
|
||||||
#include "scoped_ptr.h"
|
#include "scoped_ptr.h"
|
||||||
#include "service_certificate.h"
|
|
||||||
#include "wv_cdm_types.h"
|
#include "wv_cdm_types.h"
|
||||||
|
|
||||||
namespace video_widevine {
|
namespace video_widevine {
|
||||||
@@ -22,6 +21,7 @@ class Clock;
|
|||||||
class CryptoSession;
|
class CryptoSession;
|
||||||
class PolicyEngine;
|
class PolicyEngine;
|
||||||
class CdmSession;
|
class CdmSession;
|
||||||
|
class ServiceCertificate;
|
||||||
|
|
||||||
class CdmLicense {
|
class CdmLicense {
|
||||||
public:
|
public:
|
||||||
@@ -29,8 +29,9 @@ class CdmLicense {
|
|||||||
virtual ~CdmLicense();
|
virtual ~CdmLicense();
|
||||||
|
|
||||||
virtual bool Init(
|
virtual bool Init(
|
||||||
const std::string& client_token, CdmClientTokenType client_token_type,
|
ServiceCertificate* service_certificate, const std::string& client_token,
|
||||||
CryptoSession* session, PolicyEngine* policy_engine);
|
CdmClientTokenType client_token_type, CryptoSession* session,
|
||||||
|
PolicyEngine* policy_engine);
|
||||||
|
|
||||||
virtual CdmResponseType PrepareKeyRequest(
|
virtual CdmResponseType PrepareKeyRequest(
|
||||||
const InitializationData& init_data, CdmLicenseType license_type,
|
const InitializationData& init_data, CdmLicenseType license_type,
|
||||||
@@ -103,7 +104,7 @@ class CdmLicense {
|
|||||||
bool is_offline_;
|
bool is_offline_;
|
||||||
|
|
||||||
// Used to encrypt ClientIdentification message
|
// Used to encrypt ClientIdentification message
|
||||||
scoped_ptr<ServiceCertificate> service_certificate_;
|
ServiceCertificate* service_certificate_;
|
||||||
|
|
||||||
// Used for certificate based licensing
|
// Used for certificate based licensing
|
||||||
CdmKeyMessage key_request_;
|
CdmKeyMessage key_request_;
|
||||||
|
|||||||
@@ -5,12 +5,11 @@
|
|||||||
|
|
||||||
// Service Certificates are used to encrypt the ClientIdentification message
|
// Service Certificates are used to encrypt the ClientIdentification message
|
||||||
// that is part of Device Provisioning, License, Renewal, and Release requests.
|
// that is part of Device Provisioning, License, Renewal, and Release requests.
|
||||||
// They may be supplied by the application, or a default certificate may be
|
// It also supplies a provider_id setting used in device provisioning.
|
||||||
// configured into the CDM, or the CDM may send a Service Certificate Request
|
// Service Certificates are typically supplied by the application. If one
|
||||||
// to the target server to get one. Separate certificates are maintained for
|
// is not supplied and privacy mode is enabled, the CDM will send a Service
|
||||||
// the License and Provisioning Servers (the default service certificates
|
// Certificate Request to the target server to get one. Once the Service
|
||||||
// are currently identical for both servers). Once the Service Certificates are
|
// Certificate is established for the session, it should not change.
|
||||||
// established for the session, they should not change.
|
|
||||||
|
|
||||||
#include "license_protocol.pb.h"
|
#include "license_protocol.pb.h"
|
||||||
#include "wv_cdm_types.h"
|
#include "wv_cdm_types.h"
|
||||||
@@ -26,51 +25,56 @@ class CryptoSession;
|
|||||||
|
|
||||||
class ServiceCertificate {
|
class ServiceCertificate {
|
||||||
public:
|
public:
|
||||||
ServiceCertificate();
|
ServiceCertificate() {}
|
||||||
virtual ~ServiceCertificate();
|
virtual ~ServiceCertificate() {}
|
||||||
|
|
||||||
virtual bool Init(const CdmSessionId& session_id, CryptoSession* session);
|
// Set up a new service certificate.
|
||||||
|
// Accept a serialized video_widevine::SignedDrmDeviceCertificate message.
|
||||||
|
virtual CdmResponseType Init(const std::string& signed_certificate);
|
||||||
|
|
||||||
virtual bool IsRequired();
|
// Initialize the service certificate.
|
||||||
virtual bool IsAvailable();
|
// Set the certificate with no certificate and provider ID.
|
||||||
virtual bool PrepareServiceCertificateRequest(CdmKeyMessage* signed_request);
|
virtual void Clear();
|
||||||
|
|
||||||
virtual CdmResponseType VerifyAndSet(
|
// Current state of certificate.
|
||||||
const std::string& signed_service_certificate);
|
// If !HasCertificate() and privacy mode is enabled, then should call
|
||||||
|
// PrepareRequest() and pass the request to the license server.
|
||||||
|
virtual bool HasCertificate() { return !certificate_.empty(); }
|
||||||
|
virtual bool HasProviderId() { return !provider_id_.empty(); }
|
||||||
|
virtual const std::string& provider_id() { return provider_id_; }
|
||||||
|
|
||||||
|
// Encrypt the ClientIdentification message for a provisioning or
|
||||||
|
// licensing request. Encryption is performed using the current
|
||||||
|
// service certificate. Return a failure if the service certificate is
|
||||||
|
// not present, not valid, or if some other error occurs.
|
||||||
|
// The routine should not be called if privacy mode is off or if the
|
||||||
|
// certificate is empty.
|
||||||
virtual CdmResponseType EncryptClientId(
|
virtual CdmResponseType EncryptClientId(
|
||||||
|
CryptoSession* crypto_session,
|
||||||
const video_widevine::ClientIdentification* clear_client_id,
|
const video_widevine::ClientIdentification* clear_client_id,
|
||||||
video_widevine::EncryptedClientIdentification* encrypted_client_id);
|
video_widevine::EncryptedClientIdentification* encrypted_client_id);
|
||||||
|
|
||||||
static CdmResponseType VerifySignedServiceCertificate(
|
// Construct service certificate request.
|
||||||
const std::string& signed_certificate) {
|
virtual bool PrepareRequest(CdmKeyMessage* signed_request);
|
||||||
bool has_provider_id;
|
|
||||||
return VerifyAndExtractFromSignedCertificate(signed_certificate, NULL,
|
// Parse service certificate response and make it usable.
|
||||||
&has_provider_id, NULL);
|
virtual CdmResponseType HandleResponse(
|
||||||
}
|
const std::string& signed_respnse);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Take a signed certificate, parse it, and verify it.
|
// Verify the signature on the signed service certificate.
|
||||||
// If a pointer to a string object is passed in, the certificate
|
// Extract and save the certificate and provider_id.
|
||||||
// will be copied to it.
|
// Expected format: serialized video_widevine::SignedDrmDeviceCertificate.
|
||||||
static CdmResponseType VerifyAndExtractFromSignedCertificate(
|
virtual CdmResponseType VerifyAndExtract(
|
||||||
const std::string& signed_service_certificate,
|
const std::string& raw_certificate);
|
||||||
std::string* service_certificate, bool* has_provider_id,
|
|
||||||
std::string* provider_id);
|
|
||||||
|
|
||||||
virtual bool SetupServiceCertificate();
|
// True while waiting for response to service certificate request.
|
||||||
|
bool fetch_in_progress_;
|
||||||
CryptoSession* crypto_session_;
|
|
||||||
CdmSessionId session_id_;
|
|
||||||
bool privacy_mode_enabled_;
|
|
||||||
bool valid_;
|
|
||||||
bool initialized_;
|
|
||||||
|
|
||||||
// Certificate, verified and extracted from signed message.
|
// Certificate, verified and extracted from signed message.
|
||||||
std::string certificate_;
|
std::string certificate_;
|
||||||
|
|
||||||
// Provider ID, extracted from certificate message.
|
// Provider ID, extracted from certificate message.
|
||||||
bool has_provider_id_;
|
|
||||||
std::string provider_id_;
|
std::string provider_id_;
|
||||||
|
|
||||||
CORE_DISALLOW_COPY_AND_ASSIGN(ServiceCertificate);
|
CORE_DISALLOW_COPY_AND_ASSIGN(ServiceCertificate);
|
||||||
|
|||||||
@@ -247,7 +247,7 @@ enum CdmResponseType {
|
|||||||
INVALID_PARAMETERS_ENG_14,
|
INVALID_PARAMETERS_ENG_14,
|
||||||
INVALID_PARAMETERS_ENG_15, /* 205 */
|
INVALID_PARAMETERS_ENG_15, /* 205 */
|
||||||
INVALID_PARAMETERS_ENG_16,
|
INVALID_PARAMETERS_ENG_16,
|
||||||
DEVICE_CERTIFICATE_ERROR_5,
|
UNUSED_7, /* previously DEVICE_CERTIFICATE_ERROR_5 */
|
||||||
CERT_PROVISIONING_CLIENT_TOKEN_ERROR_1,
|
CERT_PROVISIONING_CLIENT_TOKEN_ERROR_1,
|
||||||
CERT_PROVISIONING_CLIENT_TOKEN_ERROR_2,
|
CERT_PROVISIONING_CLIENT_TOKEN_ERROR_2,
|
||||||
LICENSING_CLIENT_TOKEN_ERROR_1, /* 210 */
|
LICENSING_CLIENT_TOKEN_ERROR_1, /* 210 */
|
||||||
|
|||||||
@@ -42,11 +42,6 @@ class UsagePropertySet : public CdmClientPropertySet {
|
|||||||
virtual bool use_privacy_mode() const { return false; }
|
virtual bool use_privacy_mode() const { return false; }
|
||||||
virtual const std::string& service_certificate() const { return empty_; }
|
virtual const std::string& service_certificate() const { return empty_; }
|
||||||
virtual void set_service_certificate(const std::string&) {}
|
virtual void set_service_certificate(const std::string&) {}
|
||||||
virtual const std::string& device_provisioning_service_certificate() const {
|
|
||||||
return empty_;
|
|
||||||
}
|
|
||||||
virtual void set_device_provisioning_service_certificate(const std::string&) {
|
|
||||||
}
|
|
||||||
virtual bool is_session_sharing_enabled() const { return false; }
|
virtual bool is_session_sharing_enabled() const { return false; }
|
||||||
virtual uint32_t session_sharing_id() const { return 0; }
|
virtual uint32_t session_sharing_id() const { return 0; }
|
||||||
virtual void set_session_sharing_id(uint32_t /* id */) {}
|
virtual void set_session_sharing_id(uint32_t /* id */) {}
|
||||||
@@ -102,26 +97,27 @@ CdmEngine::~CdmEngine() {
|
|||||||
M_RECORD(&metrics_, cdm_engine_life_span_, life_span_.AsMs());
|
M_RECORD(&metrics_, cdm_engine_life_span_, life_span_.AsMs());
|
||||||
}
|
}
|
||||||
|
|
||||||
CdmResponseType CdmEngine::OpenSession(const CdmKeySystem& key_system,
|
CdmResponseType CdmEngine::SetServiceCertificate(
|
||||||
CdmClientPropertySet* property_set,
|
const std::string& certificate) {
|
||||||
const CdmSessionId& forced_session_id,
|
return service_certificate_.Init(certificate);
|
||||||
WvCdmEventListener* event_listener) {
|
}
|
||||||
|
|
||||||
|
CdmResponseType CdmEngine::OpenSession(
|
||||||
|
const CdmKeySystem& key_system, CdmClientPropertySet* property_set,
|
||||||
|
const CdmSessionId& forced_session_id, WvCdmEventListener* event_listener) {
|
||||||
return OpenSession(key_system, property_set, event_listener,
|
return OpenSession(key_system, property_set, event_listener,
|
||||||
&forced_session_id, NULL);
|
&forced_session_id, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
CdmResponseType CdmEngine::OpenSession(const CdmKeySystem& key_system,
|
CdmResponseType CdmEngine::OpenSession(
|
||||||
CdmClientPropertySet* property_set,
|
const CdmKeySystem& key_system, CdmClientPropertySet* property_set,
|
||||||
WvCdmEventListener* event_listener,
|
WvCdmEventListener* event_listener, CdmSessionId* session_id) {
|
||||||
CdmSessionId* session_id) {
|
return OpenSession(key_system, property_set, event_listener, NULL, session_id);
|
||||||
return OpenSession(key_system, property_set, event_listener, NULL,
|
|
||||||
session_id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CdmResponseType CdmEngine::OpenSession(const CdmKeySystem& key_system,
|
CdmResponseType CdmEngine::OpenSession(
|
||||||
CdmClientPropertySet* property_set,
|
const CdmKeySystem& key_system, CdmClientPropertySet* property_set,
|
||||||
WvCdmEventListener* event_listener,
|
WvCdmEventListener* event_listener, const CdmSessionId* forced_session_id,
|
||||||
const CdmSessionId* forced_session_id,
|
|
||||||
CdmSessionId* session_id) {
|
CdmSessionId* session_id) {
|
||||||
LOGI("CdmEngine::OpenSession");
|
LOGI("CdmEngine::OpenSession");
|
||||||
|
|
||||||
@@ -145,8 +141,8 @@ CdmResponseType CdmEngine::OpenSession(const CdmKeySystem& key_system,
|
|||||||
|
|
||||||
scoped_ptr<CdmSession> new_session(new CdmSession(file_system_,
|
scoped_ptr<CdmSession> new_session(new CdmSession(file_system_,
|
||||||
metrics_.AddSession()));
|
metrics_.AddSession()));
|
||||||
CdmResponseType sts = new_session->Init(property_set, forced_session_id,
|
CdmResponseType sts = new_session->Init(&service_certificate_, property_set,
|
||||||
event_listener);
|
forced_session_id, event_listener);
|
||||||
if (sts != NO_ERROR) {
|
if (sts != NO_ERROR) {
|
||||||
if (sts == NEED_PROVISIONING) {
|
if (sts == NEED_PROVISIONING) {
|
||||||
cert_provisioning_requested_security_level_ =
|
cert_provisioning_requested_security_level_ =
|
||||||
@@ -547,6 +543,8 @@ CdmResponseType CdmEngine::QueryStatus(SecurityLevel security_level,
|
|||||||
return UNKNOWN_ERROR;
|
return UNKNOWN_ERROR;
|
||||||
}
|
}
|
||||||
} else if (query_token == QUERY_KEY_DEVICE_ID) {
|
} else if (query_token == QUERY_KEY_DEVICE_ID) {
|
||||||
|
// TODO(gmorgan): this should not be performed before device is provisioned
|
||||||
|
// (except if keybox provisioned).
|
||||||
std::string deviceId;
|
std::string deviceId;
|
||||||
bool got_id = crypto_session.GetExternalDeviceUniqueId(&deviceId);
|
bool got_id = crypto_session.GetExternalDeviceUniqueId(&deviceId);
|
||||||
metrics_.GetCryptoMetrics()->crypto_session_get_device_unique_id_
|
metrics_.GetCryptoMetrics()->crypto_session_get_device_unique_id_
|
||||||
@@ -558,6 +556,8 @@ CdmResponseType CdmEngine::QueryStatus(SecurityLevel security_level,
|
|||||||
|
|
||||||
*query_response = deviceId;
|
*query_response = deviceId;
|
||||||
} else if (query_token == QUERY_KEY_SYSTEM_ID) {
|
} else if (query_token == QUERY_KEY_SYSTEM_ID) {
|
||||||
|
// TODO(gmorgan): this should not be performed before device is provisioned
|
||||||
|
// (except if keybox provisioned).
|
||||||
uint32_t system_id;
|
uint32_t system_id;
|
||||||
bool got_id = crypto_session.GetSystemId(&system_id);
|
bool got_id = crypto_session.GetSystemId(&system_id);
|
||||||
if (!got_id) {
|
if (!got_id) {
|
||||||
@@ -569,6 +569,8 @@ CdmResponseType CdmEngine::QueryStatus(SecurityLevel security_level,
|
|||||||
system_id_stream << system_id;
|
system_id_stream << system_id;
|
||||||
*query_response = system_id_stream.str();
|
*query_response = system_id_stream.str();
|
||||||
} else if (query_token == QUERY_KEY_PROVISIONING_ID) {
|
} else if (query_token == QUERY_KEY_PROVISIONING_ID) {
|
||||||
|
// TODO(gmorgan): this should not be performed before device is provisioned
|
||||||
|
// (except if keybox provisioned).
|
||||||
std::string provisioning_id;
|
std::string provisioning_id;
|
||||||
if (!crypto_session.GetProvisioningId(&provisioning_id)) {
|
if (!crypto_session.GetProvisioningId(&provisioning_id)) {
|
||||||
LOGW("CdmEngine::QueryStatus: GetProvisioningId failed");
|
LOGW("CdmEngine::QueryStatus: GetProvisioningId failed");
|
||||||
@@ -798,7 +800,8 @@ CdmResponseType CdmEngine::GetProvisioningRequest(
|
|||||||
|
|
||||||
if (NULL == cert_provisioning_.get()) {
|
if (NULL == cert_provisioning_.get()) {
|
||||||
cert_provisioning_.reset(
|
cert_provisioning_.reset(
|
||||||
new CertificateProvisioning(metrics_.GetCryptoMetrics()));
|
new CertificateProvisioning(metrics_.GetCryptoMetrics(),
|
||||||
|
&service_certificate_));
|
||||||
}
|
}
|
||||||
CdmResponseType ret = cert_provisioning_->GetProvisioningRequest(
|
CdmResponseType ret = cert_provisioning_->GetProvisioningRequest(
|
||||||
cert_provisioning_requested_security_level_, cert_type, cert_authority,
|
cert_provisioning_requested_security_level_, cert_type, cert_authority,
|
||||||
@@ -824,14 +827,14 @@ CdmResponseType CdmEngine::HandleProvisioningResponse(
|
|||||||
cert_provisioning_.reset(NULL);
|
cert_provisioning_.reset(NULL);
|
||||||
return EMPTY_PROVISIONING_RESPONSE;
|
return EMPTY_PROVISIONING_RESPONSE;
|
||||||
}
|
}
|
||||||
if (NULL == cert) {
|
if (cert == NULL) {
|
||||||
LOGE(
|
LOGE(
|
||||||
"CdmEngine::HandleProvisioningResponse: invalid certificate "
|
"CdmEngine::HandleProvisioningResponse: invalid certificate "
|
||||||
"destination");
|
"destination");
|
||||||
cert_provisioning_.reset(NULL);
|
cert_provisioning_.reset(NULL);
|
||||||
return INVALID_PROVISIONING_PARAMETERS_1;
|
return INVALID_PROVISIONING_PARAMETERS_1;
|
||||||
}
|
}
|
||||||
if (NULL == wrapped_key) {
|
if (wrapped_key == NULL) {
|
||||||
LOGE("CdmEngine::HandleProvisioningResponse: invalid wrapped key "
|
LOGE("CdmEngine::HandleProvisioningResponse: invalid wrapped key "
|
||||||
"destination");
|
"destination");
|
||||||
cert_provisioning_.reset(NULL);
|
cert_provisioning_.reset(NULL);
|
||||||
|
|||||||
@@ -65,12 +65,13 @@ CdmSession::~CdmSession() {
|
|||||||
|
|
||||||
CdmResponseType CdmSession::Init(
|
CdmResponseType CdmSession::Init(
|
||||||
CdmClientPropertySet* cdm_client_property_set) {
|
CdmClientPropertySet* cdm_client_property_set) {
|
||||||
return Init(cdm_client_property_set, NULL, NULL);
|
return Init(NULL, cdm_client_property_set, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
CdmResponseType CdmSession::Init(CdmClientPropertySet* cdm_client_property_set,
|
CdmResponseType CdmSession::Init(
|
||||||
const CdmSessionId* forced_session_id,
|
ServiceCertificate* service_certificate,
|
||||||
WvCdmEventListener* event_listener) {
|
CdmClientPropertySet* cdm_client_property_set,
|
||||||
|
const CdmSessionId* forced_session_id, WvCdmEventListener* event_listener) {
|
||||||
if (initialized_) {
|
if (initialized_) {
|
||||||
LOGE("CdmSession::Init: Failed due to previous initialization");
|
LOGE("CdmSession::Init: Failed due to previous initialization");
|
||||||
return SESSION_INIT_ERROR_2;
|
return SESSION_INIT_ERROR_2;
|
||||||
@@ -112,11 +113,13 @@ CdmResponseType CdmSession::Init(CdmClientPropertySet* cdm_client_property_set,
|
|||||||
// Otherwise, try to fetch device certificate. If not successful and
|
// Otherwise, try to fetch device certificate. If not successful and
|
||||||
// provisioning is supported, return NEED_PROVISIONING. Otherwise, return
|
// provisioning is supported, return NEED_PROVISIONING. Otherwise, return
|
||||||
// an error.
|
// an error.
|
||||||
|
// client_token and client_token_type are determined here; they are needed
|
||||||
|
// to initialize the license parser.
|
||||||
std::string client_token;
|
std::string client_token;
|
||||||
CdmClientTokenType client_token_type =
|
CdmClientTokenType client_token_type =
|
||||||
crypto_session_->GetPreProvisionTokenType();
|
crypto_session_->GetPreProvisionTokenType();
|
||||||
if ((client_token_type == kClientTokenKeybox) &&
|
if ((client_token_type == kClientTokenKeybox) &&
|
||||||
(!Properties::use_certificates_as_identification())) {
|
!Properties::use_certificates_as_identification()) {
|
||||||
// Keybox is client token.
|
// Keybox is client token.
|
||||||
LOGW("CdmSession::Init: Properties::use_certificates_as_identification() "
|
LOGW("CdmSession::Init: Properties::use_certificates_as_identification() "
|
||||||
"is not set - using Keybox for license requests (not recommended).");
|
"is not set - using Keybox for license requests (not recommended).");
|
||||||
@@ -147,6 +150,9 @@ CdmResponseType CdmSession::Init(CdmClientPropertySet* cdm_client_property_set,
|
|||||||
client_token_type = kClientTokenDrmCert;
|
client_token_type = kClientTokenDrmCert;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Session is provisioned with certificate needed to construct
|
||||||
|
// license request (or with keybox).
|
||||||
|
|
||||||
if (forced_session_id) {
|
if (forced_session_id) {
|
||||||
key_set_id_ = *forced_session_id;
|
key_set_id_ = *forced_session_id;
|
||||||
} else {
|
} else {
|
||||||
@@ -172,7 +178,8 @@ CdmResponseType CdmSession::Init(CdmClientPropertySet* cdm_client_property_set,
|
|||||||
policy_engine_.reset(new PolicyEngine(
|
policy_engine_.reset(new PolicyEngine(
|
||||||
session_id_, event_listener, crypto_session_.get()));
|
session_id_, event_listener, crypto_session_.get()));
|
||||||
|
|
||||||
if (!license_parser_->Init(client_token, client_token_type,
|
if (!license_parser_->Init(
|
||||||
|
service_certificate, client_token, client_token_type,
|
||||||
crypto_session_.get(), policy_engine_.get()))
|
crypto_session_.get(), policy_engine_.get()))
|
||||||
return LICENSE_PARSER_INIT_ERROR;
|
return LICENSE_PARSER_INIT_ERROR;
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
#include "license_protocol.pb.h"
|
#include "license_protocol.pb.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "properties.h"
|
#include "properties.h"
|
||||||
|
#include "service_certificate.h"
|
||||||
#include "string_conversions.h"
|
#include "string_conversions.h"
|
||||||
#include "wv_cdm_constants.h"
|
#include "wv_cdm_constants.h"
|
||||||
|
|
||||||
@@ -86,16 +87,17 @@ bool CertificateProvisioning::SetSpoidParameter(
|
|||||||
"passed to method.");
|
"passed to method.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!spoid.empty()) {
|
if (!spoid.empty()) {
|
||||||
// Use the SPOID that has been pre-provided
|
// Use the SPOID that has been pre-provided
|
||||||
request->set_spoid(spoid);
|
request->set_spoid(spoid);
|
||||||
} else if (Properties::UseProviderIdInProvisioningRequest() &&
|
} else if (Properties::UseProviderIdInProvisioningRequest()) {
|
||||||
false /* TODO(gmorgan): use provider ID. */) {
|
if (service_certificate_->HasProviderId()) {
|
||||||
// Use the provider ID from the service certificate
|
request->set_provider_id(service_certificate_->provider_id());
|
||||||
|
} else {
|
||||||
// TODO(gmorgan): use provider ID.
|
LOGE("CertificateProvisioning::SetSpoidParameter: Failure getting "
|
||||||
// request->set_provider_id(???);
|
"provider ID");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
} else if (origin != EMPTY_ORIGIN) {
|
} else if (origin != EMPTY_ORIGIN) {
|
||||||
// Legacy behavior - Concatenate Unique ID with Origin
|
// Legacy behavior - Concatenate Unique ID with Origin
|
||||||
std::string device_unique_id;
|
std::string device_unique_id;
|
||||||
@@ -130,8 +132,8 @@ SignedProvisioningMessage::ProtocolVersion
|
|||||||
CdmResponseType CertificateProvisioning::GetProvisioningRequest(
|
CdmResponseType CertificateProvisioning::GetProvisioningRequest(
|
||||||
SecurityLevel requested_security_level, CdmCertificateType cert_type,
|
SecurityLevel requested_security_level, CdmCertificateType cert_type,
|
||||||
const std::string& cert_authority, const std::string& origin,
|
const std::string& cert_authority, const std::string& origin,
|
||||||
const std::string& spoid,
|
const std::string& spoid, CdmProvisioningRequest* request,
|
||||||
CdmProvisioningRequest* request, std::string* default_url) {
|
std::string* default_url) {
|
||||||
if (!default_url) {
|
if (!default_url) {
|
||||||
LOGE("GetProvisioningRequest: pointer for returning URL is NULL");
|
LOGE("GetProvisioningRequest: pointer for returning URL is NULL");
|
||||||
return CERT_PROVISIONING_REQUEST_ERROR_1;
|
return CERT_PROVISIONING_REQUEST_ERROR_1;
|
||||||
@@ -139,13 +141,13 @@ CdmResponseType CertificateProvisioning::GetProvisioningRequest(
|
|||||||
|
|
||||||
default_url->assign(kProvisioningServerUrl);
|
default_url->assign(kProvisioningServerUrl);
|
||||||
|
|
||||||
CdmResponseType sts = crypto_session_.Open(requested_security_level);
|
CdmResponseType status = crypto_session_.Open(requested_security_level);
|
||||||
if (NO_ERROR != sts) {
|
if (NO_ERROR != status) {
|
||||||
LOGE("GetProvisioningRequest: fails to create a crypto session");
|
LOGE("GetProvisioningRequest: fails to create a crypto session");
|
||||||
return sts;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prepares device provisioning request.
|
// Prepare device provisioning request.
|
||||||
ProvisioningRequest provisioning_request;
|
ProvisioningRequest provisioning_request;
|
||||||
std::string token;
|
std::string token;
|
||||||
ClientIdentification* client_id = provisioning_request.mutable_client_id();
|
ClientIdentification* client_id = provisioning_request.mutable_client_id();
|
||||||
|
|||||||
@@ -292,6 +292,8 @@ bool CryptoSession::GetInternalDeviceUniqueId(std::string* device_id) {
|
|||||||
if (pre_provision_token_type_ == kClientTokenOemCert) {
|
if (pre_provision_token_type_ == kClientTokenOemCert) {
|
||||||
return GetTokenFromOemCert(device_id);
|
return GetTokenFromOemCert(device_id);
|
||||||
} else {
|
} else {
|
||||||
|
// Device's authentication root is a keybox.
|
||||||
|
// Or not. If no keybox, let the OEMCrypto call fail.
|
||||||
std::vector<uint8_t> id;
|
std::vector<uint8_t> id;
|
||||||
size_t id_length = 32;
|
size_t id_length = 32;
|
||||||
id.resize(id_length);
|
id.resize(id_length);
|
||||||
@@ -348,6 +350,8 @@ bool CryptoSession::GetApiVersion(uint32_t* version) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool CryptoSession::GetSystemId(uint32_t* system_id) {
|
bool CryptoSession::GetSystemId(uint32_t* system_id) {
|
||||||
|
// TODO(gmorgan): if Prov 3.0, get system ID from DRM Device Cert. If
|
||||||
|
// DRM Device Cert is not available (e.g., not yet provisioned), return false.
|
||||||
if (!system_id) {
|
if (!system_id) {
|
||||||
LOGE("CryptoSession::GetSystemId: No buffer passed to method.");
|
LOGE("CryptoSession::GetSystemId: No buffer passed to method.");
|
||||||
return false;
|
return false;
|
||||||
@@ -496,6 +500,7 @@ bool CryptoSession::ExtractSystemIdFromOemCert(const std::string& oem_cert,
|
|||||||
|
|
||||||
|
|
||||||
bool CryptoSession::GetProvisioningId(std::string* provisioning_id) {
|
bool CryptoSession::GetProvisioningId(std::string* provisioning_id) {
|
||||||
|
// TODO(gmorgan): if Prov 3.0, return false (no "provisioning ID" available).
|
||||||
if (!provisioning_id) {
|
if (!provisioning_id) {
|
||||||
LOGE("CryptoSession::GetProvisioningId : No buffer passed to method.");
|
LOGE("CryptoSession::GetProvisioningId : No buffer passed to method.");
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
#include "policy_engine.h"
|
#include "policy_engine.h"
|
||||||
#include "privacy_crypto.h"
|
#include "privacy_crypto.h"
|
||||||
#include "properties.h"
|
#include "properties.h"
|
||||||
|
#include "service_certificate.h"
|
||||||
#include "string_conversions.h"
|
#include "string_conversions.h"
|
||||||
#include "wv_cdm_constants.h"
|
#include "wv_cdm_constants.h"
|
||||||
|
|
||||||
@@ -145,8 +146,9 @@ CdmLicense::CdmLicense(const CdmSessionId& session_id, Clock* clock)
|
|||||||
CdmLicense::~CdmLicense() {}
|
CdmLicense::~CdmLicense() {}
|
||||||
|
|
||||||
bool CdmLicense::Init(
|
bool CdmLicense::Init(
|
||||||
const std::string& client_token, CdmClientTokenType client_token_type,
|
ServiceCertificate* service_certificate, const std::string& client_token,
|
||||||
CryptoSession* session, PolicyEngine* policy_engine) {
|
CdmClientTokenType client_token_type, CryptoSession* session,
|
||||||
|
PolicyEngine* policy_engine) {
|
||||||
if (clock_.get() == NULL) {
|
if (clock_.get() == NULL) {
|
||||||
LOGE("CdmLicense::Init: clock parameter not provided");
|
LOGE("CdmLicense::Init: clock parameter not provided");
|
||||||
return false;
|
return false;
|
||||||
@@ -168,19 +170,11 @@ bool CdmLicense::Init(
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
service_certificate_ = service_certificate;
|
||||||
client_token_ = client_token;
|
client_token_ = client_token;
|
||||||
client_token_type_ = client_token_type;
|
client_token_type_ = client_token_type;
|
||||||
crypto_session_ = session;
|
crypto_session_ = session;
|
||||||
policy_engine_ = policy_engine;
|
policy_engine_ = policy_engine;
|
||||||
service_certificate_.reset(new ServiceCertificate());
|
|
||||||
if (service_certificate_.get() == NULL) {
|
|
||||||
LOGE("CdmLicense::Init: creation of service_certificate failed");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!service_certificate_->Init(session_id_, crypto_session_)) {
|
|
||||||
LOGE("CdmLicense::Init: init of service_certificate failed");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
initialized_ = true;
|
initialized_ = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -217,13 +211,15 @@ CdmResponseType CdmLicense::PrepareKeyRequest(
|
|||||||
return INVALID_PARAMETERS_LIC_7;
|
return INVALID_PARAMETERS_LIC_7;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (service_certificate_->IsRequired() &&
|
// If privacy mode and no service certificate, initiate a
|
||||||
!service_certificate_->IsAvailable()) {
|
// service certificate request.
|
||||||
|
if (Properties::UsePrivacyMode(session_id_) &&
|
||||||
|
!service_certificate_->HasCertificate()) {
|
||||||
stored_init_data_.reset(new InitializationData(init_data));
|
stored_init_data_.reset(new InitializationData(init_data));
|
||||||
*server_url = server_url_;
|
*server_url = server_url_;
|
||||||
if (service_certificate_->PrepareServiceCertificateRequest(signed_request))
|
if (service_certificate_->PrepareRequest(signed_request)) {
|
||||||
return KEY_MESSAGE;
|
return KEY_MESSAGE;
|
||||||
else
|
}
|
||||||
return LICENSE_REQUEST_SERVICE_CERTIFICATE_GENERATION_ERROR;
|
return LICENSE_REQUEST_SERVICE_CERTIFICATE_GENERATION_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -309,13 +305,12 @@ CdmResponseType CdmLicense::PrepareKeyUpdateRequest(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (renew_with_client_id_) {
|
if (renew_with_client_id_) {
|
||||||
if (service_certificate_->IsRequired() &&
|
if (Properties::UsePrivacyMode(session_id_) &&
|
||||||
!service_certificate_->IsAvailable()) {
|
!service_certificate_->HasCertificate()) {
|
||||||
*server_url = server_url_;
|
*server_url = server_url_;
|
||||||
if (service_certificate_->
|
if (service_certificate_->PrepareRequest(signed_request)) {
|
||||||
PrepareServiceCertificateRequest(signed_request))
|
|
||||||
return KEY_MESSAGE;
|
return KEY_MESSAGE;
|
||||||
else
|
}
|
||||||
return LICENSE_RENEWAL_SERVICE_CERTIFICATE_GENERATION_ERROR;
|
return LICENSE_RENEWAL_SERVICE_CERTIFICATE_GENERATION_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -439,8 +434,8 @@ CdmResponseType CdmLicense::HandleKeyResponse(
|
|||||||
case SignedMessage::LICENSE:
|
case SignedMessage::LICENSE:
|
||||||
break;
|
break;
|
||||||
case SignedMessage::SERVICE_CERTIFICATE: {
|
case SignedMessage::SERVICE_CERTIFICATE: {
|
||||||
CdmResponseType status =
|
CdmResponseType status;
|
||||||
service_certificate_->VerifyAndSet(signed_response.msg());
|
status = service_certificate_->HandleResponse(signed_response.msg());
|
||||||
if (status != NO_ERROR) {
|
if (status != NO_ERROR) {
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
@@ -558,8 +553,8 @@ CdmResponseType CdmLicense::HandleKeyUpdateResponse(
|
|||||||
case SignedMessage::LICENSE:
|
case SignedMessage::LICENSE:
|
||||||
break;
|
break;
|
||||||
case SignedMessage::SERVICE_CERTIFICATE: {
|
case SignedMessage::SERVICE_CERTIFICATE: {
|
||||||
CdmResponseType status =
|
CdmResponseType status;
|
||||||
service_certificate_->VerifyAndSet(signed_response.msg());
|
status = service_certificate_->HandleResponse(signed_response.msg());
|
||||||
if (status != NO_ERROR) {
|
if (status != NO_ERROR) {
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
@@ -1027,16 +1022,15 @@ CdmResponseType CdmLicense::PrepareClientId(
|
|||||||
if (crypto_session_->GetSrmVersion(&srm_version))
|
if (crypto_session_->GetSrmVersion(&srm_version))
|
||||||
client_capabilities->set_srm_version(srm_version);
|
client_capabilities->set_srm_version(srm_version);
|
||||||
|
|
||||||
if (service_certificate_->IsRequired()) {
|
if (Properties::UsePrivacyMode(session_id_)) {
|
||||||
if (!service_certificate_->IsAvailable()) {
|
if (!service_certificate_->HasCertificate()) {
|
||||||
LOGE("CdmLicense::PrepareClientId: Service Certificate not staged");
|
LOGE("CdmLicense::PrepareClientId: Service Certificate not staged");
|
||||||
return LICENSE_REQUEST_SERVICE_CERTIFICATE_GENERATION_ERROR;
|
return LICENSE_REQUEST_SERVICE_CERTIFICATE_GENERATION_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
EncryptedClientIdentification* encrypted_client_id =
|
EncryptedClientIdentification* encrypted_client_id =
|
||||||
license_request->mutable_encrypted_client_id();
|
license_request->mutable_encrypted_client_id();
|
||||||
CdmResponseType status;
|
CdmResponseType status;
|
||||||
status = service_certificate_->EncryptClientId(client_id,
|
status = service_certificate_->EncryptClientId(crypto_session_, client_id,
|
||||||
encrypted_client_id);
|
encrypted_client_id);
|
||||||
if (NO_ERROR == status) {
|
if (NO_ERROR == status) {
|
||||||
license_request->clear_client_id();
|
license_request->clear_client_id();
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ bool Properties::GetServiceCertificate(const CdmSessionId& session_id,
|
|||||||
std::string* service_certificate) {
|
std::string* service_certificate) {
|
||||||
const CdmClientPropertySet* property_set =
|
const CdmClientPropertySet* property_set =
|
||||||
GetCdmClientPropertySet(session_id);
|
GetCdmClientPropertySet(session_id);
|
||||||
if (NULL == property_set) {
|
if (property_set == NULL) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
*service_certificate = property_set->service_certificate();
|
*service_certificate = property_set->service_certificate();
|
||||||
@@ -73,35 +73,13 @@ bool Properties::SetServiceCertificate(const CdmSessionId& session_id,
|
|||||||
const std::string& service_certificate) {
|
const std::string& service_certificate) {
|
||||||
CdmClientPropertySet* property_set =
|
CdmClientPropertySet* property_set =
|
||||||
GetCdmClientPropertySet(session_id);
|
GetCdmClientPropertySet(session_id);
|
||||||
if (NULL == property_set) {
|
if (property_set == NULL) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
property_set->set_service_certificate(service_certificate);
|
property_set->set_service_certificate(service_certificate);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Properties::GetDeviceProvisioningServiceCertificate(
|
|
||||||
const CdmSessionId& session_id, std::string* service_certificate) {
|
|
||||||
const CdmClientPropertySet* property_set =
|
|
||||||
GetCdmClientPropertySet(session_id);
|
|
||||||
if (NULL == property_set) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
*service_certificate = property_set->device_provisioning_service_certificate();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Properties::SetDeviceProvisioningServiceCertificate(
|
|
||||||
const CdmSessionId& session_id, const std::string& service_certificate) {
|
|
||||||
CdmClientPropertySet* property_set =
|
|
||||||
GetCdmClientPropertySet(session_id);
|
|
||||||
if (NULL == property_set) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
property_set->set_device_provisioning_service_certificate(service_certificate);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Properties::UsePrivacyMode(const CdmSessionId& session_id) {
|
bool Properties::UsePrivacyMode(const CdmSessionId& session_id) {
|
||||||
const CdmClientPropertySet* property_set =
|
const CdmClientPropertySet* property_set =
|
||||||
GetCdmClientPropertySet(session_id);
|
GetCdmClientPropertySet(session_id);
|
||||||
|
|||||||
@@ -57,148 +57,26 @@ using video_widevine::EncryptedClientIdentification;
|
|||||||
using video_widevine::SignedDrmDeviceCertificate;
|
using video_widevine::SignedDrmDeviceCertificate;
|
||||||
using video_widevine::SignedMessage;
|
using video_widevine::SignedMessage;
|
||||||
|
|
||||||
ServiceCertificate::ServiceCertificate()
|
void ServiceCertificate::Clear() {
|
||||||
: crypto_session_(NULL),
|
fetch_in_progress_ = false;
|
||||||
valid_(false),
|
|
||||||
initialized_(false) {
|
|
||||||
certificate_.clear();
|
certificate_.clear();
|
||||||
|
provider_id_.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
ServiceCertificate::~ServiceCertificate() {}
|
CdmResponseType ServiceCertificate::Init(const std::string& raw_certificate) {
|
||||||
|
return VerifyAndExtract(raw_certificate);
|
||||||
bool ServiceCertificate::Init(const CdmSessionId& session_id,
|
|
||||||
CryptoSession* session) {
|
|
||||||
if (session_id.empty()) {
|
|
||||||
LOGE("ServiceCertificate::Init: empty session id provided");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (session == NULL) {
|
|
||||||
LOGE("ServiceCertificate::Init: crypto session not provided");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
session_id_.assign(session_id);
|
|
||||||
crypto_session_ = session;
|
|
||||||
privacy_mode_enabled_ = Properties::UsePrivacyMode(session_id_);
|
|
||||||
SetupServiceCertificate();
|
|
||||||
initialized_ = true;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ServiceCertificate::IsRequired() {
|
|
||||||
return privacy_mode_enabled_;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ServiceCertificate::IsAvailable() {
|
|
||||||
return valid_;
|
|
||||||
}
|
|
||||||
|
|
||||||
CdmResponseType ServiceCertificate::VerifyAndSet(
|
|
||||||
const std::string& signed_service_certificate) {
|
|
||||||
CdmResponseType status;
|
|
||||||
bool has_provider_id;
|
|
||||||
status = VerifyAndExtractFromSignedCertificate(signed_service_certificate,
|
|
||||||
&certificate_,
|
|
||||||
&has_provider_id,
|
|
||||||
NULL);
|
|
||||||
if (status != NO_ERROR) {
|
|
||||||
LOGE("ServiceCertificate::VerifyAndSet: verify and extract failed with "
|
|
||||||
"status %d", status);
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
Properties::SetServiceCertificate(session_id_, signed_service_certificate);
|
|
||||||
valid_ = true;
|
|
||||||
return NO_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ServiceCertificate::PrepareServiceCertificateRequest(
|
|
||||||
CdmKeyMessage* signed_request) {
|
|
||||||
if (!initialized_) {
|
|
||||||
LOGE("ServiceCertificate::PrepareServiceCertificateRequest: "
|
|
||||||
"not initialized");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!signed_request) {
|
|
||||||
LOGE("ServiceCertificate::PrepareServiceCertificateRequest: "
|
|
||||||
"no signed request provided");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
SignedMessage signed_message;
|
|
||||||
signed_message.set_type(SignedMessage::SERVICE_CERTIFICATE_REQUEST);
|
|
||||||
signed_message.SerializeToString(signed_request);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
CdmResponseType ServiceCertificate::VerifyAndExtractFromSignedCertificate(
|
|
||||||
const std::string& signed_certificate, std::string* certificate,
|
|
||||||
bool* /* has_provider_id */, std::string* /* provider_id */) {
|
|
||||||
SignedDrmDeviceCertificate signed_service_certificate;
|
|
||||||
if (!signed_service_certificate.ParseFromString(signed_certificate)) {
|
|
||||||
LOGE(
|
|
||||||
"ServiceCertificate::VerifyAndExtractFromSignedCertificate: "
|
|
||||||
"unable to parse signed service certificate");
|
|
||||||
return DEVICE_CERTIFICATE_ERROR_1;
|
|
||||||
}
|
|
||||||
|
|
||||||
RsaPublicKey root_ca_key;
|
|
||||||
std::string ca_public_key(
|
|
||||||
reinterpret_cast<const char*>(&kServiceCertificateCAPublicKey[0]),
|
|
||||||
sizeof(kServiceCertificateCAPublicKey));
|
|
||||||
if (!root_ca_key.Init(ca_public_key)) {
|
|
||||||
LOGE(
|
|
||||||
"ServiceCertificate::VerifyAndExtractFromSignedCertificate: public key "
|
|
||||||
"initialization failed");
|
|
||||||
return DEVICE_CERTIFICATE_ERROR_2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!root_ca_key.VerifySignature(
|
|
||||||
signed_service_certificate.drm_certificate(),
|
|
||||||
signed_service_certificate.signature())) {
|
|
||||||
LOGE(
|
|
||||||
"ServiceCertificate::VerifyAndExtractFromSignedCertificate: service "
|
|
||||||
"certificate verification failed");
|
|
||||||
return DEVICE_CERTIFICATE_ERROR_3;
|
|
||||||
}
|
|
||||||
|
|
||||||
DrmDeviceCertificate service_certificate;
|
|
||||||
if (!service_certificate.ParseFromString(
|
|
||||||
signed_service_certificate.drm_certificate())) {
|
|
||||||
LOGE(
|
|
||||||
"ServiceCertificate::VerifyAndExtractFromSignedCertificate: unable to "
|
|
||||||
"parse retrieved service certificate");
|
|
||||||
return DEVICE_CERTIFICATE_ERROR_4;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (service_certificate.type() !=
|
|
||||||
video_widevine::DrmDeviceCertificate_CertificateType_SERVICE) {
|
|
||||||
LOGE(
|
|
||||||
"ServiceCertificate::VerifyAndExtractFromSignedCertificate: "
|
|
||||||
"certificate not of type service, %d", service_certificate.type());
|
|
||||||
return INVALID_DEVICE_CERTIFICATE_TYPE;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0 // TODO(gmorgan): service cert has no provider_id
|
|
||||||
*has_provider_id = service_certificate.has_provider_id();
|
|
||||||
if (*has_provider_id && provider_id != NULL) {
|
|
||||||
*provider_id = service_certificate.provider_id();
|
|
||||||
} else {
|
|
||||||
return DEVICE_CERTIFICATE_ERROR_5;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (certificate != NULL &&
|
|
||||||
!signed_service_certificate.drm_certificate().empty()) {
|
|
||||||
*certificate = signed_service_certificate.drm_certificate();
|
|
||||||
}
|
|
||||||
return NO_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CdmResponseType ServiceCertificate::EncryptClientId(
|
CdmResponseType ServiceCertificate::EncryptClientId(
|
||||||
const ClientIdentification* clear_client_id,
|
CryptoSession* crypto_session, const ClientIdentification* clear_client_id,
|
||||||
EncryptedClientIdentification* encrypted_client_id) {
|
EncryptedClientIdentification* encrypted_client_id) {
|
||||||
DrmDeviceCertificate service_certificate;
|
DrmDeviceCertificate service_certificate;
|
||||||
|
|
||||||
|
if (certificate_.empty()) {
|
||||||
|
LOGE("ServiceCertificate::EncryptClientId: "
|
||||||
|
"service certificate is not properly initialized");
|
||||||
|
return UNKNOWN_ERROR;
|
||||||
|
}
|
||||||
if (!service_certificate.ParseFromString(certificate_)) {
|
if (!service_certificate.ParseFromString(certificate_)) {
|
||||||
LOGE("ServiceCertificate::EncryptClientId: unable to parse retrieved "
|
LOGE("ServiceCertificate::EncryptClientId: unable to parse retrieved "
|
||||||
"service certificate");
|
"service certificate");
|
||||||
@@ -215,13 +93,13 @@ CdmResponseType ServiceCertificate::EncryptClientId(
|
|||||||
encrypted_client_id->set_service_certificate_serial_number(
|
encrypted_client_id->set_service_certificate_serial_number(
|
||||||
service_certificate.serial_number());
|
service_certificate.serial_number());
|
||||||
|
|
||||||
std::string iv(KEY_IV_SIZE, 0); // TODO(gmorgan) randomize
|
std::string iv(KEY_IV_SIZE, 0);
|
||||||
std::string key(KEY_SIZE, 0);
|
std::string key(KEY_SIZE, 0);
|
||||||
|
|
||||||
if (!crypto_session_->GetRandom(key.size(),
|
if (!crypto_session->GetRandom(key.size(),
|
||||||
reinterpret_cast<uint8_t*>(&key[0])))
|
reinterpret_cast<uint8_t*>(&key[0])))
|
||||||
return CLIENT_ID_GENERATE_RANDOM_ERROR;
|
return CLIENT_ID_GENERATE_RANDOM_ERROR;
|
||||||
if (!crypto_session_->GetRandom(iv.size(),
|
if (!crypto_session->GetRandom(iv.size(),
|
||||||
reinterpret_cast<uint8_t*>(&iv[0])))
|
reinterpret_cast<uint8_t*>(&iv[0])))
|
||||||
return CLIENT_ID_GENERATE_RANDOM_ERROR;
|
return CLIENT_ID_GENERATE_RANDOM_ERROR;
|
||||||
std::string id, enc_id, enc_key;
|
std::string id, enc_id, enc_key;
|
||||||
@@ -242,38 +120,97 @@ CdmResponseType ServiceCertificate::EncryptClientId(
|
|||||||
return NO_ERROR;
|
return NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ServiceCertificate::SetupServiceCertificate() {
|
bool ServiceCertificate::PrepareRequest(CdmKeyMessage* signed_request) {
|
||||||
std::string signed_certificate;
|
if (!signed_request) {
|
||||||
|
LOGE("ServiceCertificate::PrepareRequest: no signed request provided");
|
||||||
valid_ = false;
|
|
||||||
certificate_.clear();
|
|
||||||
|
|
||||||
if (!Properties::GetServiceCertificate(session_id_, &signed_certificate)) {
|
|
||||||
LOGV("ServiceCertificate::SetupServiceCertificate: no signed service "
|
|
||||||
"certificate set");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (signed_certificate.empty()) {
|
|
||||||
LOGV("ServiceCertificate::SetupServiceCertificate: service certificate "
|
|
||||||
"empty");
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
SignedMessage signed_message;
|
||||||
|
signed_message.set_type(SignedMessage::SERVICE_CERTIFICATE_REQUEST);
|
||||||
|
signed_message.SerializeToString(signed_request);
|
||||||
|
|
||||||
std::string extracted_certificate;
|
fetch_in_progress_ = true;
|
||||||
std::string extracted_provider_id;
|
|
||||||
bool has_provider_id;
|
|
||||||
if (NO_ERROR != VerifyAndExtractFromSignedCertificate(
|
|
||||||
signed_certificate, &extracted_certificate,
|
|
||||||
&has_provider_id, &extracted_provider_id)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
has_provider_id_ = has_provider_id;
|
|
||||||
if (has_provider_id_) {
|
|
||||||
provider_id_ = extracted_provider_id;
|
|
||||||
}
|
|
||||||
certificate_ = extracted_certificate;
|
|
||||||
valid_ = true;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CdmResponseType ServiceCertificate::HandleResponse(
|
||||||
|
const std::string& signed_response) {
|
||||||
|
if (!fetch_in_progress_) {
|
||||||
|
LOGE("ServiceCertificate::HandleResponse: unexpected service "
|
||||||
|
"certificate response.");
|
||||||
|
return UNKNOWN_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
fetch_in_progress_ = false;
|
||||||
|
CdmResponseType status = VerifyAndExtract(signed_response);
|
||||||
|
if (status != NO_ERROR) {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
return NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
CdmResponseType ServiceCertificate::VerifyAndExtract(
|
||||||
|
const std::string& raw_certificate) {
|
||||||
|
if (raw_certificate.empty()) {
|
||||||
|
Clear();
|
||||||
|
return NO_ERROR;
|
||||||
|
}
|
||||||
|
// Deserialize and parse raw certificate.
|
||||||
|
SignedDrmDeviceCertificate signed_service_certificate;
|
||||||
|
if (!signed_service_certificate.ParseFromString(raw_certificate)) {
|
||||||
|
LOGE(
|
||||||
|
"ServiceCertificate::VerifyAndExtract: unable to parse signed "
|
||||||
|
"service certificate");
|
||||||
|
return DEVICE_CERTIFICATE_ERROR_1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set up root key (for verifying signature).
|
||||||
|
RsaPublicKey root_ca_key;
|
||||||
|
std::string ca_public_key(
|
||||||
|
reinterpret_cast<const char*>(&kServiceCertificateCAPublicKey[0]),
|
||||||
|
sizeof(kServiceCertificateCAPublicKey));
|
||||||
|
if (!root_ca_key.Init(ca_public_key)) {
|
||||||
|
LOGE(
|
||||||
|
"ServiceCertificate::VerifyAndExtract: public key initialization "
|
||||||
|
"failed");
|
||||||
|
return DEVICE_CERTIFICATE_ERROR_2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify the signature.
|
||||||
|
if (!root_ca_key.VerifySignature(
|
||||||
|
signed_service_certificate.drm_certificate(),
|
||||||
|
signed_service_certificate.signature())) {
|
||||||
|
LOGE(
|
||||||
|
"ServiceCertificate::VerifyAndExtract: service certificate "
|
||||||
|
"verification failed");
|
||||||
|
return DEVICE_CERTIFICATE_ERROR_3;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deserialize and parse actual certificate.
|
||||||
|
DrmDeviceCertificate service_certificate;
|
||||||
|
if (!service_certificate.ParseFromString(
|
||||||
|
signed_service_certificate.drm_certificate())) {
|
||||||
|
LOGE(
|
||||||
|
"ServiceCertificate::VerifyAndExtract: unable to parse retrieved "
|
||||||
|
"service certificate");
|
||||||
|
return DEVICE_CERTIFICATE_ERROR_4;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify, extract needed fields.
|
||||||
|
if (service_certificate.type() !=
|
||||||
|
video_widevine::DrmDeviceCertificate_CertificateType_SERVICE) {
|
||||||
|
LOGE(
|
||||||
|
"ServiceCertificate::VerifyAndExtract: certificate not of type "
|
||||||
|
"service, %d", service_certificate.type());
|
||||||
|
return INVALID_DEVICE_CERTIFICATE_TYPE;
|
||||||
|
}
|
||||||
|
if (service_certificate.has_provider_id()) {
|
||||||
|
provider_id_.assign(service_certificate.provider_id());
|
||||||
|
} else {
|
||||||
|
provider_id_.clear();
|
||||||
|
}
|
||||||
|
certificate_.assign(signed_service_certificate.drm_certificate());
|
||||||
|
return NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace wvcdm
|
} // namespace wvcdm
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
#include "cdm_engine.h"
|
#include "cdm_engine.h"
|
||||||
#include "config_test_env.h"
|
#include "config_test_env.h"
|
||||||
|
#include "default_service_certificate.h"
|
||||||
#include "initialization_data.h"
|
#include "initialization_data.h"
|
||||||
#include "license_request.h"
|
#include "license_request.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
@@ -80,6 +81,8 @@ class WvCdmEngineTest : public testing::Test {
|
|||||||
CdmCertificateType cert_type = kCertificateWidevine;
|
CdmCertificateType cert_type = kCertificateWidevine;
|
||||||
std::string cert_authority;
|
std::string cert_authority;
|
||||||
std::string cert, wrapped_key;
|
std::string cert, wrapped_key;
|
||||||
|
ASSERT_EQ(NO_ERROR, cdm_engine_.SetServiceCertificate(
|
||||||
|
kDefaultServiceCertificate));
|
||||||
CdmResponseType result = NO_ERROR;
|
CdmResponseType result = NO_ERROR;
|
||||||
for (int i = 0; i < 2; i++) { // Retry once if there is a nonce problem.
|
for (int i = 0; i < 2; i++) { // Retry once if there is a nonce problem.
|
||||||
result = cdm_engine_.GetProvisioningRequest(
|
result = cdm_engine_.GetProvisioningRequest(
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
#include "crypto_key.h"
|
#include "crypto_key.h"
|
||||||
#include "properties.h"
|
#include "properties.h"
|
||||||
#include "scoped_ptr.h"
|
#include "scoped_ptr.h"
|
||||||
|
#include "service_certificate.h"
|
||||||
#include "string_conversions.h"
|
#include "string_conversions.h"
|
||||||
#include "test_printers.h"
|
#include "test_printers.h"
|
||||||
#include "wv_cdm_constants.h"
|
#include "wv_cdm_constants.h"
|
||||||
@@ -122,8 +123,8 @@ class MockCdmLicense : public CdmLicense {
|
|||||||
MockCdmLicense(const CdmSessionId& session_id)
|
MockCdmLicense(const CdmSessionId& session_id)
|
||||||
: CdmLicense(session_id) {}
|
: CdmLicense(session_id) {}
|
||||||
|
|
||||||
MOCK_METHOD4(Init, bool(const std::string&, CdmClientTokenType,
|
MOCK_METHOD5(Init, bool(ServiceCertificate*, const std::string&,
|
||||||
CryptoSession*, PolicyEngine*));
|
CdmClientTokenType, CryptoSession*, PolicyEngine*));
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
@@ -140,6 +141,7 @@ using ::testing::StrEq;
|
|||||||
class CdmSessionTest : public ::testing::Test {
|
class CdmSessionTest : public ::testing::Test {
|
||||||
protected:
|
protected:
|
||||||
virtual void SetUp() {
|
virtual void SetUp() {
|
||||||
|
service_cert_ = new ServiceCertificate;
|
||||||
cdm_session_.reset(new CdmSession(NULL, &metrics_));
|
cdm_session_.reset(new CdmSession(NULL, &metrics_));
|
||||||
// Inject testing mocks.
|
// Inject testing mocks.
|
||||||
license_parser_ = new MockCdmLicense(cdm_session_->session_id());
|
license_parser_ = new MockCdmLicense(cdm_session_->session_id());
|
||||||
@@ -165,6 +167,7 @@ class CdmSessionTest : public ::testing::Test {
|
|||||||
MockCryptoSession* crypto_session_;
|
MockCryptoSession* crypto_session_;
|
||||||
MockPolicyEngine* policy_engine_;
|
MockPolicyEngine* policy_engine_;
|
||||||
MockDeviceFiles* file_handle_;
|
MockDeviceFiles* file_handle_;
|
||||||
|
ServiceCertificate* service_cert_;
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_F(CdmSessionTest, InitWithBuiltInCertificate) {
|
TEST_F(CdmSessionTest, InitWithBuiltInCertificate) {
|
||||||
@@ -186,7 +189,7 @@ TEST_F(CdmSessionTest, InitWithBuiltInCertificate) {
|
|||||||
.WillOnce(Return(true));
|
.WillOnce(Return(true));
|
||||||
EXPECT_CALL(*file_handle_, Init(Eq(level))).WillOnce(Return(true));
|
EXPECT_CALL(*file_handle_, Init(Eq(level))).WillOnce(Return(true));
|
||||||
EXPECT_CALL(*license_parser_,
|
EXPECT_CALL(*license_parser_,
|
||||||
Init(Eq(kToken), Eq(kClientTokenDrmCert),
|
Init(NULL, Eq(kToken), Eq(kClientTokenDrmCert),
|
||||||
Eq(crypto_session_), Eq(policy_engine_)))
|
Eq(crypto_session_), Eq(policy_engine_)))
|
||||||
.WillOnce(Return(true));
|
.WillOnce(Return(true));
|
||||||
|
|
||||||
@@ -214,7 +217,7 @@ TEST_F(CdmSessionTest, InitWithCertificate) {
|
|||||||
.InSequence(crypto_session_seq)
|
.InSequence(crypto_session_seq)
|
||||||
.WillOnce(Return(true));
|
.WillOnce(Return(true));
|
||||||
EXPECT_CALL(*license_parser_,
|
EXPECT_CALL(*license_parser_,
|
||||||
Init(Eq(kToken), Eq(kClientTokenDrmCert),
|
Init(NULL, Eq(kToken), Eq(kClientTokenDrmCert),
|
||||||
Eq(crypto_session_), Eq(policy_engine_)))
|
Eq(crypto_session_), Eq(policy_engine_)))
|
||||||
.WillOnce(Return(true));
|
.WillOnce(Return(true));
|
||||||
|
|
||||||
@@ -239,7 +242,7 @@ TEST_F(CdmSessionTest, InitWithKeybox) {
|
|||||||
.WillOnce(Return(kClientTokenKeybox));
|
.WillOnce(Return(kClientTokenKeybox));
|
||||||
EXPECT_CALL(*file_handle_, Init(Eq(level))).WillOnce(Return(true));
|
EXPECT_CALL(*file_handle_, Init(Eq(level))).WillOnce(Return(true));
|
||||||
EXPECT_CALL(*license_parser_,
|
EXPECT_CALL(*license_parser_,
|
||||||
Init(Eq(kToken), Eq(kClientTokenKeybox),
|
Init(NULL, Eq(kToken), Eq(kClientTokenKeybox),
|
||||||
Eq(crypto_session_), Eq(policy_engine_)))
|
Eq(crypto_session_), Eq(policy_engine_)))
|
||||||
.WillOnce(Return(true));
|
.WillOnce(Return(true));
|
||||||
|
|
||||||
@@ -267,7 +270,7 @@ TEST_F(CdmSessionTest, ReInitFail) {
|
|||||||
.InSequence(crypto_session_seq)
|
.InSequence(crypto_session_seq)
|
||||||
.WillOnce(Return(true));
|
.WillOnce(Return(true));
|
||||||
EXPECT_CALL(*license_parser_,
|
EXPECT_CALL(*license_parser_,
|
||||||
Init(Eq(kToken), Eq(kClientTokenDrmCert),
|
Init(NULL, Eq(kToken), Eq(kClientTokenDrmCert),
|
||||||
Eq(crypto_session_), Eq(policy_engine_)))
|
Eq(crypto_session_), Eq(policy_engine_)))
|
||||||
.WillOnce(Return(true));
|
.WillOnce(Return(true));
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
#include "cdm_engine.h"
|
#include "cdm_engine.h"
|
||||||
|
|
||||||
|
#include "default_service_certificate.h"
|
||||||
#include "license_request.h"
|
#include "license_request.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "oec_session_util.h"
|
#include "oec_session_util.h"
|
||||||
@@ -163,6 +164,7 @@ class WvGenericOperationsTest : public testing::Test {
|
|||||||
CdmCertificateType cert_type = kCertificateWidevine;
|
CdmCertificateType cert_type = kCertificateWidevine;
|
||||||
std::string cert_authority;
|
std::string cert_authority;
|
||||||
std::string cert, wrapped_key;
|
std::string cert, wrapped_key;
|
||||||
|
cdm_engine_->SetServiceCertificate(kDefaultServiceCertificate);
|
||||||
ASSERT_EQ(NO_ERROR,
|
ASSERT_EQ(NO_ERROR,
|
||||||
cdm_engine_->GetProvisioningRequest(
|
cdm_engine_->GetProvisioningRequest(
|
||||||
cert_type, cert_authority, &prov_request,
|
cert_type, cert_authority, &prov_request,
|
||||||
|
|||||||
@@ -5,10 +5,12 @@
|
|||||||
|
|
||||||
#include "clock.h"
|
#include "clock.h"
|
||||||
#include "crypto_session.h"
|
#include "crypto_session.h"
|
||||||
|
#include "default_service_certificate.h"
|
||||||
#include "initialization_data.h"
|
#include "initialization_data.h"
|
||||||
#include "license.h"
|
#include "license.h"
|
||||||
#include "policy_engine.h"
|
#include "policy_engine.h"
|
||||||
#include "properties.h"
|
#include "properties.h"
|
||||||
|
#include "service_certificate.h"
|
||||||
#include "string_conversions.h"
|
#include "string_conversions.h"
|
||||||
#include "wv_cdm_constants.h"
|
#include "wv_cdm_constants.h"
|
||||||
|
|
||||||
@@ -155,25 +157,26 @@ class CdmLicenseTest : public ::testing::Test {
|
|||||||
MockCryptoSession* crypto_session_;
|
MockCryptoSession* crypto_session_;
|
||||||
MockInitializationData* init_data_;
|
MockInitializationData* init_data_;
|
||||||
MockPolicyEngine* policy_engine_;
|
MockPolicyEngine* policy_engine_;
|
||||||
|
ServiceCertificate service_cert_;
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_F(CdmLicenseTest, InitSuccess) {
|
TEST_F(CdmLicenseTest, InitSuccess) {
|
||||||
EXPECT_CALL(*crypto_session_, IsOpen()).WillOnce(Return(true));
|
EXPECT_CALL(*crypto_session_, IsOpen()).WillOnce(Return(true));
|
||||||
|
|
||||||
CreateCdmLicense();
|
CreateCdmLicense();
|
||||||
EXPECT_TRUE(cdm_license_->Init(kToken, kClientTokenDrmCert,
|
EXPECT_TRUE(cdm_license_->Init(&service_cert_, kToken, kClientTokenDrmCert,
|
||||||
crypto_session_, policy_engine_));
|
crypto_session_, policy_engine_));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(CdmLicenseTest, InitFail_EmptyToken) {
|
TEST_F(CdmLicenseTest, InitFail_EmptyToken) {
|
||||||
CreateCdmLicense();
|
CreateCdmLicense();
|
||||||
EXPECT_FALSE(cdm_license_->Init("", kClientTokenDrmCert,
|
EXPECT_FALSE(cdm_license_->Init(&service_cert_, "", kClientTokenDrmCert,
|
||||||
crypto_session_, policy_engine_));
|
crypto_session_, policy_engine_));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(CdmLicenseTest, InitFail_CryptoSessionNull) {
|
TEST_F(CdmLicenseTest, InitFail_CryptoSessionNull) {
|
||||||
CreateCdmLicense();
|
CreateCdmLicense();
|
||||||
EXPECT_FALSE(cdm_license_->Init(kToken, kClientTokenDrmCert,
|
EXPECT_FALSE(cdm_license_->Init(&service_cert_, kToken, kClientTokenDrmCert,
|
||||||
NULL, policy_engine_));
|
NULL, policy_engine_));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -181,10 +184,18 @@ TEST_F(CdmLicenseTest, InitFail_PolicyEngineNull) {
|
|||||||
EXPECT_CALL(*crypto_session_, IsOpen()).WillOnce(Return(true));
|
EXPECT_CALL(*crypto_session_, IsOpen()).WillOnce(Return(true));
|
||||||
|
|
||||||
CreateCdmLicense();
|
CreateCdmLicense();
|
||||||
EXPECT_FALSE(cdm_license_->Init(kToken, kClientTokenDrmCert,
|
EXPECT_FALSE(cdm_license_->Init(&service_cert_, kToken, kClientTokenDrmCert,
|
||||||
crypto_session_, NULL));
|
crypto_session_, NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(CdmLicenseTest, InitWithNullServiceCert) {
|
||||||
|
EXPECT_CALL(*crypto_session_, IsOpen()).WillOnce(Return(true));
|
||||||
|
|
||||||
|
CreateCdmLicense();
|
||||||
|
EXPECT_TRUE(cdm_license_->Init(NULL, kToken, kClientTokenDrmCert,
|
||||||
|
crypto_session_, policy_engine_));
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(CdmLicenseTest, PrepareKeyRequestValidation) {
|
TEST_F(CdmLicenseTest, PrepareKeyRequestValidation) {
|
||||||
bool usage_information_support = true;
|
bool usage_information_support = true;
|
||||||
CryptoSession::HdcpCapability current_hdcp_version = HDCP_NO_DIGITAL_OUTPUT;
|
CryptoSession::HdcpCapability current_hdcp_version = HDCP_NO_DIGITAL_OUTPUT;
|
||||||
@@ -219,16 +230,17 @@ TEST_F(CdmLicenseTest, PrepareKeyRequestValidation) {
|
|||||||
DoAll(SetArgPointee<2>(kLicenseRequestSignature), Return(true)));
|
DoAll(SetArgPointee<2>(kLicenseRequestSignature), Return(true)));
|
||||||
|
|
||||||
CreateCdmLicense();
|
CreateCdmLicense();
|
||||||
EXPECT_TRUE(cdm_license_->Init(kToken, kClientTokenDrmCert,
|
service_cert_.Init(kDefaultServiceCertificate);
|
||||||
|
EXPECT_TRUE(cdm_license_->Init(&service_cert_, kToken, kClientTokenDrmCert,
|
||||||
crypto_session_, policy_engine_));
|
crypto_session_, policy_engine_));
|
||||||
|
|
||||||
CdmAppParameterMap app_parameters;
|
CdmAppParameterMap app_parameters;
|
||||||
CdmKeyMessage signed_request;
|
CdmKeyMessage signed_request;
|
||||||
Properties::set_use_certificates_as_identification(true);
|
Properties::set_use_certificates_as_identification(true);
|
||||||
std::string server_url;
|
std::string server_url;
|
||||||
EXPECT_TRUE(cdm_license_->PrepareKeyRequest(
|
EXPECT_EQ(cdm_license_->PrepareKeyRequest(
|
||||||
*init_data_, kLicenseTypeStreaming, app_parameters,
|
*init_data_, kLicenseTypeStreaming, app_parameters,
|
||||||
&signed_request, &server_url));
|
&signed_request, &server_url), KEY_MESSAGE);
|
||||||
|
|
||||||
EXPECT_TRUE(!signed_request.empty());
|
EXPECT_TRUE(!signed_request.empty());
|
||||||
|
|
||||||
@@ -287,7 +299,7 @@ TEST_F(CdmLicenseTest, PrepareKeyRequestValidation) {
|
|||||||
// Verify Content Identification
|
// Verify Content Identification
|
||||||
const LicenseRequest_ContentIdentification& content_id =
|
const LicenseRequest_ContentIdentification& content_id =
|
||||||
license_request.content_id();
|
license_request.content_id();
|
||||||
EXPECT_TRUE(content_id.has_cenc_id_deprecated());
|
ASSERT_TRUE(content_id.has_cenc_id_deprecated());
|
||||||
EXPECT_FALSE(content_id.has_webm_id_deprecated());
|
EXPECT_FALSE(content_id.has_webm_id_deprecated());
|
||||||
EXPECT_FALSE(content_id.has_existing_license());
|
EXPECT_FALSE(content_id.has_existing_license());
|
||||||
|
|
||||||
|
|||||||
@@ -89,14 +89,6 @@ class StubCdmClientPropertySet : public CdmClientPropertySet {
|
|||||||
service_certificate_ = cert;
|
service_certificate_ = cert;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual const std::string& device_provisioning_service_certificate() const {
|
|
||||||
return device_provisioning_service_certificate_;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void set_device_provisioning_service_certificate(
|
|
||||||
const std::string& cert) {
|
|
||||||
device_provisioning_service_certificate_ = cert;
|
|
||||||
}
|
|
||||||
virtual bool is_session_sharing_enabled() const {
|
virtual bool is_session_sharing_enabled() const {
|
||||||
return is_session_sharing_enabled_;
|
return is_session_sharing_enabled_;
|
||||||
}
|
}
|
||||||
@@ -112,7 +104,6 @@ class StubCdmClientPropertySet : public CdmClientPropertySet {
|
|||||||
private:
|
private:
|
||||||
std::string security_level_;
|
std::string security_level_;
|
||||||
std::string service_certificate_;
|
std::string service_certificate_;
|
||||||
std::string device_provisioning_service_certificate_;
|
|
||||||
bool use_privacy_mode_;
|
bool use_privacy_mode_;
|
||||||
bool is_session_sharing_enabled_;
|
bool is_session_sharing_enabled_;
|
||||||
uint32_t session_sharing_id_;
|
uint32_t session_sharing_id_;
|
||||||
@@ -123,9 +114,8 @@ TEST_F(ServiceCertificateTest, InitSuccess) {
|
|||||||
MockCryptoSession crypto_session(&crypto_metrics_);
|
MockCryptoSession crypto_session(&crypto_metrics_);
|
||||||
|
|
||||||
CreateServiceCertificate();
|
CreateServiceCertificate();
|
||||||
service_certificate_->Init(kTestSessionId1, &crypto_session);
|
service_certificate_->Init(kTestSessionId1);
|
||||||
EXPECT_FALSE(service_certificate_->IsRequired());
|
EXPECT_FALSE(service_certificate_->HasCertificate());
|
||||||
EXPECT_FALSE(service_certificate_->IsAvailable());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ServiceCertificateTest, InitPrivacyModeRequired) {
|
TEST_F(ServiceCertificateTest, InitPrivacyModeRequired) {
|
||||||
@@ -138,9 +128,8 @@ TEST_F(ServiceCertificateTest, InitPrivacyModeRequired) {
|
|||||||
Properties::AddSessionPropertySet(kTestSessionId1, &property_set);
|
Properties::AddSessionPropertySet(kTestSessionId1, &property_set);
|
||||||
|
|
||||||
CreateServiceCertificate();
|
CreateServiceCertificate();
|
||||||
service_certificate_->Init(kTestSessionId1, &crypto_session);
|
service_certificate_->Init(kTestSessionId1);
|
||||||
EXPECT_TRUE(service_certificate_->IsRequired());
|
EXPECT_FALSE(service_certificate_->HasCertificate());
|
||||||
EXPECT_FALSE(service_certificate_->IsAvailable());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ServiceCertificateTest, InitServiceCertificatePresent) {
|
TEST_F(ServiceCertificateTest, InitServiceCertificatePresent) {
|
||||||
@@ -154,9 +143,12 @@ TEST_F(ServiceCertificateTest, InitServiceCertificatePresent) {
|
|||||||
Properties::AddSessionPropertySet(kTestSessionId1, &property_set);
|
Properties::AddSessionPropertySet(kTestSessionId1, &property_set);
|
||||||
|
|
||||||
CreateServiceCertificate();
|
CreateServiceCertificate();
|
||||||
service_certificate_->Init(kTestSessionId1, &crypto_session);
|
std::string raw_service_certificate;
|
||||||
EXPECT_TRUE(service_certificate_->IsRequired());
|
EXPECT_TRUE(Properties::GetServiceCertificate(kTestSessionId1,
|
||||||
EXPECT_TRUE(service_certificate_->IsAvailable());
|
&raw_service_certificate));
|
||||||
|
EXPECT_EQ(NO_ERROR,
|
||||||
|
service_certificate_->Init(raw_service_certificate));
|
||||||
|
EXPECT_TRUE(service_certificate_->HasCertificate());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ServiceCertificateTest, SetServiceCertificate) {
|
TEST_F(ServiceCertificateTest, SetServiceCertificate) {
|
||||||
@@ -169,13 +161,8 @@ TEST_F(ServiceCertificateTest, SetServiceCertificate) {
|
|||||||
Properties::AddSessionPropertySet(kTestSessionId1, &property_set);
|
Properties::AddSessionPropertySet(kTestSessionId1, &property_set);
|
||||||
|
|
||||||
CreateServiceCertificate();
|
CreateServiceCertificate();
|
||||||
service_certificate_->Init(kTestSessionId1, &crypto_session);
|
EXPECT_EQ(NO_ERROR, service_certificate_->Init(kTestSignedCertificate));
|
||||||
EXPECT_TRUE(service_certificate_->IsRequired());
|
EXPECT_TRUE(service_certificate_->HasCertificate());
|
||||||
EXPECT_FALSE(service_certificate_->IsAvailable());
|
}
|
||||||
|
|
||||||
EXPECT_EQ(NO_ERROR,
|
|
||||||
service_certificate_->VerifyAndSet(kTestSignedCertificate));
|
|
||||||
EXPECT_TRUE(service_certificate_->IsRequired());
|
|
||||||
EXPECT_TRUE(service_certificate_->IsAvailable());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -95,8 +95,6 @@ void PrintTo(const enum CdmResponseType& value, ::std::ostream* os) {
|
|||||||
break;
|
break;
|
||||||
case DEVICE_CERTIFICATE_ERROR_4: *os << "DEVICE_CERTIFICATE_ERROR_4";
|
case DEVICE_CERTIFICATE_ERROR_4: *os << "DEVICE_CERTIFICATE_ERROR_4";
|
||||||
break;
|
break;
|
||||||
case DEVICE_CERTIFICATE_ERROR_5: *os << "DEVICE_CERTIFICATE_ERROR_5";
|
|
||||||
break;
|
|
||||||
case EMPTY_KEY_DATA_1: *os << "EMPTY_KEY_DATA_1";
|
case EMPTY_KEY_DATA_1: *os << "EMPTY_KEY_DATA_1";
|
||||||
break;
|
break;
|
||||||
case EMPTY_KEY_DATA_2: *os << "EMPTY_KEY_DATA_2";
|
case EMPTY_KEY_DATA_2: *os << "EMPTY_KEY_DATA_2";
|
||||||
|
|||||||
@@ -353,8 +353,10 @@ void WvContentDecryptionModule::NotifyResolution(const CdmSessionId& session_id,
|
|||||||
|
|
||||||
bool WvContentDecryptionModule::IsValidServiceCertificate(
|
bool WvContentDecryptionModule::IsValidServiceCertificate(
|
||||||
const std::string& certificate) {
|
const std::string& certificate) {
|
||||||
return ServiceCertificate::VerifySignedServiceCertificate(certificate) ==
|
ServiceCertificate cert;
|
||||||
NO_ERROR;
|
CdmResponseType status = cert.Init(certificate);
|
||||||
|
if (status != NO_ERROR) return false;
|
||||||
|
return cert.HasCertificate();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WvContentDecryptionModule::GetSerializedMetrics(
|
void WvContentDecryptionModule::GetSerializedMetrics(
|
||||||
|
|||||||
@@ -213,13 +213,6 @@ class TestWvCdmClientPropertySet : public CdmClientPropertySet {
|
|||||||
virtual void set_service_certificate(const std::string& cert) {
|
virtual void set_service_certificate(const std::string& cert) {
|
||||||
service_certificate_ = cert;
|
service_certificate_ = cert;
|
||||||
}
|
}
|
||||||
virtual const std::string& device_provisioning_service_certificate() const {
|
|
||||||
return device_provisioning_service_certificate_;
|
|
||||||
}
|
|
||||||
virtual void set_device_provisioning_service_certificate(
|
|
||||||
const std::string& cert) {
|
|
||||||
device_provisioning_service_certificate_ = cert;
|
|
||||||
}
|
|
||||||
virtual bool use_privacy_mode() const { return use_privacy_mode_; }
|
virtual bool use_privacy_mode() const { return use_privacy_mode_; }
|
||||||
virtual bool is_session_sharing_enabled() const {
|
virtual bool is_session_sharing_enabled() const {
|
||||||
return is_session_sharing_enabled_;
|
return is_session_sharing_enabled_;
|
||||||
@@ -245,7 +238,6 @@ class TestWvCdmClientPropertySet : public CdmClientPropertySet {
|
|||||||
std::string app_id_;
|
std::string app_id_;
|
||||||
std::string security_level_;
|
std::string security_level_;
|
||||||
std::string service_certificate_;
|
std::string service_certificate_;
|
||||||
std::string device_provisioning_service_certificate_;
|
|
||||||
bool use_privacy_mode_;
|
bool use_privacy_mode_;
|
||||||
bool is_session_sharing_enabled_;
|
bool is_session_sharing_enabled_;
|
||||||
uint32_t session_sharing_id_;
|
uint32_t session_sharing_id_;
|
||||||
|
|||||||
@@ -894,13 +894,6 @@ class TestWvCdmClientPropertySet : public CdmClientPropertySet {
|
|||||||
virtual void set_service_certificate(const std::string& cert) {
|
virtual void set_service_certificate(const std::string& cert) {
|
||||||
service_certificate_ = cert;
|
service_certificate_ = cert;
|
||||||
}
|
}
|
||||||
virtual const std::string& device_provisioning_service_certificate() const {
|
|
||||||
return device_provisioning_service_certificate_;
|
|
||||||
}
|
|
||||||
virtual void set_device_provisioning_service_certificate(
|
|
||||||
const std::string& cert) {
|
|
||||||
device_provisioning_service_certificate_ = cert;
|
|
||||||
}
|
|
||||||
virtual bool use_privacy_mode() const { return use_privacy_mode_; }
|
virtual bool use_privacy_mode() const { return use_privacy_mode_; }
|
||||||
virtual bool is_session_sharing_enabled() const {
|
virtual bool is_session_sharing_enabled() const {
|
||||||
return is_session_sharing_enabled_;
|
return is_session_sharing_enabled_;
|
||||||
@@ -926,7 +919,6 @@ class TestWvCdmClientPropertySet : public CdmClientPropertySet {
|
|||||||
std::string app_id_;
|
std::string app_id_;
|
||||||
std::string security_level_;
|
std::string security_level_;
|
||||||
std::string service_certificate_;
|
std::string service_certificate_;
|
||||||
std::string device_provisioning_service_certificate_;
|
|
||||||
bool use_privacy_mode_;
|
bool use_privacy_mode_;
|
||||||
bool is_session_sharing_enabled_;
|
bool is_session_sharing_enabled_;
|
||||||
uint32_t session_sharing_id_;
|
uint32_t session_sharing_id_;
|
||||||
@@ -1652,6 +1644,7 @@ TEST_F(WvCdmRequestLicenseTest, PrivacyModeWithServiceCertificateTest) {
|
|||||||
|
|
||||||
property_set.set_use_privacy_mode(true);
|
property_set.set_use_privacy_mode(true);
|
||||||
property_set.set_service_certificate(a2bs_hex(g_service_certificate));
|
property_set.set_service_certificate(a2bs_hex(g_service_certificate));
|
||||||
|
// TODO: pass g_service_certificate into CdmEngine::SetServiceCertificate()
|
||||||
decryptor_.OpenSession(g_key_system, &property_set, kDefaultCdmIdentifier,
|
decryptor_.OpenSession(g_key_system, &property_set, kDefaultCdmIdentifier,
|
||||||
NULL, &session_id_);
|
NULL, &session_id_);
|
||||||
GenerateKeyRequest(g_key_id, kLicenseTypeStreaming);
|
GenerateKeyRequest(g_key_id, kLicenseTypeStreaming);
|
||||||
@@ -2181,6 +2174,7 @@ TEST_P(WvCdmStreamingLicenseRenewalTest, WithClientId) {
|
|||||||
if (config->specify_service_certificate)
|
if (config->specify_service_certificate)
|
||||||
property_set.set_service_certificate(a2bs_hex(g_service_certificate));
|
property_set.set_service_certificate(a2bs_hex(g_service_certificate));
|
||||||
}
|
}
|
||||||
|
// TODO: pass g_service_certificate into CdmEngine::SetServiceCertificate()
|
||||||
decryptor_.OpenSession(g_key_system, &property_set, kDefaultCdmIdentifier,
|
decryptor_.OpenSession(g_key_system, &property_set, kDefaultCdmIdentifier,
|
||||||
NULL, &session_id_);
|
NULL, &session_id_);
|
||||||
GenerateKeyRequest(key_id, app_parameters, kLicenseTypeStreaming,
|
GenerateKeyRequest(key_id, app_parameters, kLicenseTypeStreaming,
|
||||||
@@ -2311,6 +2305,7 @@ TEST_P(WvCdmOfflineLicenseReleaseTest, WithClientId) {
|
|||||||
if (config->specify_service_certificate)
|
if (config->specify_service_certificate)
|
||||||
property_set.set_service_certificate(a2bs_hex(g_service_certificate));
|
property_set.set_service_certificate(a2bs_hex(g_service_certificate));
|
||||||
}
|
}
|
||||||
|
// TODO: pass g_service_certificate into CdmEngine::SetServiceCertificate()
|
||||||
decryptor_.OpenSession(g_key_system, &property_set, kDefaultCdmIdentifier,
|
decryptor_.OpenSession(g_key_system, &property_set, kDefaultCdmIdentifier,
|
||||||
NULL, &session_id_);
|
NULL, &session_id_);
|
||||||
GenerateKeyRequest(key_id, app_parameters, kLicenseTypeOffline, NULL);
|
GenerateKeyRequest(key_id, app_parameters, kLicenseTypeOffline, NULL);
|
||||||
|
|||||||
@@ -212,7 +212,6 @@ enum {
|
|||||||
kInvalidParametersEng14 = ERROR_DRM_VENDOR_MIN + 199,
|
kInvalidParametersEng14 = ERROR_DRM_VENDOR_MIN + 199,
|
||||||
kInvalidParametersEng15 = ERROR_DRM_VENDOR_MIN + 200,
|
kInvalidParametersEng15 = ERROR_DRM_VENDOR_MIN + 200,
|
||||||
kInvalidParametersEng16 = ERROR_DRM_VENDOR_MIN + 201,
|
kInvalidParametersEng16 = ERROR_DRM_VENDOR_MIN + 201,
|
||||||
kDeviceCertificateError5 = ERROR_DRM_VENDOR_MIN + 202,
|
|
||||||
kCertProvisioningClientTokenError1 = ERROR_DRM_VENDOR_MIN + 203,
|
kCertProvisioningClientTokenError1 = ERROR_DRM_VENDOR_MIN + 203,
|
||||||
kCertProvisioningClientTokenError2 = ERROR_DRM_VENDOR_MIN + 204,
|
kCertProvisioningClientTokenError2 = ERROR_DRM_VENDOR_MIN + 204,
|
||||||
kLicensingClientTokenError1 = ERROR_DRM_VENDOR_MIN + 205,
|
kLicensingClientTokenError1 = ERROR_DRM_VENDOR_MIN + 205,
|
||||||
|
|||||||
@@ -81,8 +81,6 @@ static android::status_t mapCdmResponseType(wvcdm::CdmResponseType res) {
|
|||||||
return kDeviceCertificateError3;
|
return kDeviceCertificateError3;
|
||||||
case wvcdm::DEVICE_CERTIFICATE_ERROR_4:
|
case wvcdm::DEVICE_CERTIFICATE_ERROR_4:
|
||||||
return kDeviceCertificateError4;
|
return kDeviceCertificateError4;
|
||||||
case wvcdm::DEVICE_CERTIFICATE_ERROR_5:
|
|
||||||
return kDeviceCertificateError5;
|
|
||||||
case wvcdm::EMPTY_KEY_DATA_1:
|
case wvcdm::EMPTY_KEY_DATA_1:
|
||||||
return kEmptyKeyData1;
|
return kEmptyKeyData1;
|
||||||
case wvcdm::EMPTY_KEY_DATA_2:
|
case wvcdm::EMPTY_KEY_DATA_2:
|
||||||
@@ -542,6 +540,7 @@ static android::status_t mapCdmResponseType(wvcdm::CdmResponseType res) {
|
|||||||
case wvcdm::UNUSED_4:
|
case wvcdm::UNUSED_4:
|
||||||
case wvcdm::UNUSED_5:
|
case wvcdm::UNUSED_5:
|
||||||
case wvcdm::UNUSED_6:
|
case wvcdm::UNUSED_6:
|
||||||
|
case wvcdm::UNUSED_7:
|
||||||
return android::UNKNOWN_ERROR;
|
return android::UNKNOWN_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -242,7 +242,6 @@ static Status mapCdmResponseType(wvcdm::CdmResponseType res) {
|
|||||||
case wvcdm::INVALID_PARAMETERS_ENG_14:
|
case wvcdm::INVALID_PARAMETERS_ENG_14:
|
||||||
case wvcdm::INVALID_PARAMETERS_ENG_15:
|
case wvcdm::INVALID_PARAMETERS_ENG_15:
|
||||||
case wvcdm::INVALID_PARAMETERS_ENG_16:
|
case wvcdm::INVALID_PARAMETERS_ENG_16:
|
||||||
case wvcdm::DEVICE_CERTIFICATE_ERROR_5:
|
|
||||||
case wvcdm::CERT_PROVISIONING_CLIENT_TOKEN_ERROR_1:
|
case wvcdm::CERT_PROVISIONING_CLIENT_TOKEN_ERROR_1:
|
||||||
case wvcdm::CERT_PROVISIONING_CLIENT_TOKEN_ERROR_2:
|
case wvcdm::CERT_PROVISIONING_CLIENT_TOKEN_ERROR_2:
|
||||||
case wvcdm::LICENSING_CLIENT_TOKEN_ERROR_1:
|
case wvcdm::LICENSING_CLIENT_TOKEN_ERROR_1:
|
||||||
|
|||||||
@@ -217,16 +217,6 @@ class WVDrmPlugin : public android::DrmPlugin,
|
|||||||
mServiceCertificate = serviceCertificate;
|
mServiceCertificate = serviceCertificate;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual const std::string& device_provisioning_service_certificate() const {
|
|
||||||
// Android does not support service certificates for provisioning.
|
|
||||||
return mEmptyString;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void set_device_provisioning_service_certificate(
|
|
||||||
const std::string& ) {
|
|
||||||
// Ignore. Android does not support service certificates for provisioning
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool is_session_sharing_enabled() const {
|
virtual bool is_session_sharing_enabled() const {
|
||||||
return mShareKeys;
|
return mShareKeys;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -81,8 +81,11 @@ class UsageTableEntry {
|
|||||||
|
|
||||||
class UsageTable {
|
class UsageTable {
|
||||||
public:
|
public:
|
||||||
explicit UsageTable(CryptoEngine* ce)
|
UsageTable(CryptoEngine* ce, wvcdm::FileSystem* /* file_system */)
|
||||||
: ce_(ce), header_loaded_(false), old_table_(NULL){};
|
: ce_(ce),
|
||||||
|
/* TODO: unused: file_system_(file_system), */
|
||||||
|
header_loaded_(false),
|
||||||
|
old_table_(NULL){};
|
||||||
~UsageTable();
|
~UsageTable();
|
||||||
|
|
||||||
OEMCryptoResult CreateNewUsageEntry(SessionContext* session,
|
OEMCryptoResult CreateNewUsageEntry(SessionContext* session,
|
||||||
@@ -125,6 +128,7 @@ class UsageTable {
|
|||||||
bool LoadGenerationNumber(bool or_make_new_one);
|
bool LoadGenerationNumber(bool or_make_new_one);
|
||||||
|
|
||||||
CryptoEngine* ce_;
|
CryptoEngine* ce_;
|
||||||
|
/* TODO: unused: wvcdm::FileSystem* file_system_; */
|
||||||
bool header_loaded_;
|
bool header_loaded_;
|
||||||
int64_t master_generation_number_;
|
int64_t master_generation_number_;
|
||||||
std::vector<int64_t> generation_numbers_;
|
std::vector<int64_t> generation_numbers_;
|
||||||
|
|||||||
Reference in New Issue
Block a user