Support Keybox, DRM Cert, and OEM Cert for Client ID
[ Merge of http://go/wvgerrit/22900 ] Add GetClientToken(), GetProvisioningToken(), GetPreProvisionTokenType() to CryptoSession. They return the correct token bytes and token type for preparing the ClientIdentification message for provisioning and license server transactions. Also refactor service certificate handling. OEM certs are introduced in Provisioning 3.0 b/30811184 * Address build breaks [ Merge of http://go/wvgerrit/23162 ] This addresses issues introduced by http://go/wvgerrit/22900 b/30811184 * When http://go/wvgerrit/18012 was merged (ag/1446934) some changes were not merged for mapErrors-inl.h. These changes are included in this CL. * When ag/1678104 was reverse merged to http//go/wvgerrit/21981/ a variable was renamed and some comments were added to add clarity in cdm_engine.cpp. These changes are included in this CL. Test: All unittests other than some oemcrypto, request_license_test passed. Those tests failed with or without this CL. Change-Id: Ie0215509f2f985f2a610f5a4c865db47edec8662
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
|
||||
#include "crypto_session.h"
|
||||
#include "oemcrypto_adapter.h"
|
||||
#include "service_certificate.h"
|
||||
#include "wv_cdm_types.h"
|
||||
|
||||
namespace wvcdm {
|
||||
@@ -16,7 +17,9 @@ class FileSystem;
|
||||
|
||||
class CertificateProvisioning {
|
||||
public:
|
||||
CertificateProvisioning() : cert_type_(kCertificateWidevine) {};
|
||||
CertificateProvisioning() :
|
||||
cert_type_(kCertificateWidevine),
|
||||
service_certificate_(NULL) {};
|
||||
~CertificateProvisioning() {};
|
||||
|
||||
// Provisioning related methods
|
||||
@@ -33,6 +36,12 @@ class CertificateProvisioning {
|
||||
std::string* wrapped_key);
|
||||
|
||||
private:
|
||||
bool GetProvisioningTokenType(
|
||||
video_widevine::ClientIdentification::TokenType* token_type);
|
||||
|
||||
video_widevine::SignedProvisioningMessage::ProtocolVersion
|
||||
GetProtocolVersion();
|
||||
|
||||
void ComposeJsonRequestAsQueryString(const std::string& message,
|
||||
CdmProvisioningRequest* request);
|
||||
bool ParseJsonResponse(const CdmProvisioningResponse& json_str,
|
||||
@@ -40,9 +49,11 @@ class CertificateProvisioning {
|
||||
const std::string& end_substr, std::string* result);
|
||||
CryptoSession crypto_session_;
|
||||
CdmCertificateType cert_type_;
|
||||
ServiceCertificate* service_certificate_;
|
||||
|
||||
CORE_DISALLOW_COPY_AND_ASSIGN(CertificateProvisioning);
|
||||
};
|
||||
|
||||
} // namespace wvcdm
|
||||
|
||||
#endif // WVCDM_CORE_CERTIFICATE_PROVISIONING_H_
|
||||
|
||||
@@ -29,8 +29,11 @@ class CryptoSession {
|
||||
CryptoSession();
|
||||
virtual ~CryptoSession();
|
||||
|
||||
virtual bool ValidateKeybox();
|
||||
virtual bool GetToken(std::string* token);
|
||||
virtual bool GetClientToken(std::string* client_token);
|
||||
virtual bool GetProvisioningToken(std::string* client_token);
|
||||
virtual CdmClientTokenType GetPreProvisionTokenType() {
|
||||
return pre_provision_token_type_;
|
||||
}
|
||||
virtual CdmSecurityLevel GetSecurityLevel();
|
||||
virtual bool GetDeviceUniqueId(std::string* device_id);
|
||||
virtual bool GetApiVersion(uint32_t* version);
|
||||
@@ -124,8 +127,11 @@ class CryptoSession {
|
||||
const std::string& signature);
|
||||
|
||||
private:
|
||||
bool GetProvisioningMethod(CdmClientTokenType* token_type);
|
||||
void Init();
|
||||
void Terminate();
|
||||
bool GetTokenFromKeybox(std::string* token);
|
||||
bool GetTokenFromOemCert(std::string* token);
|
||||
void GenerateMacContext(const std::string& input_context,
|
||||
std::string* deriv_context);
|
||||
void GenerateEncryptContext(const std::string& input_context,
|
||||
@@ -163,6 +169,7 @@ class CryptoSession {
|
||||
static int session_count_;
|
||||
|
||||
bool open_;
|
||||
CdmClientTokenType pre_provision_token_type_;
|
||||
bool update_usage_table_after_close_session_;
|
||||
CryptoSessionId oec_session_id_;
|
||||
|
||||
|
||||
@@ -6,7 +6,9 @@
|
||||
#include <set>
|
||||
|
||||
#include "initialization_data.h"
|
||||
#include "license_protocol.pb.h"
|
||||
#include "scoped_ptr.h"
|
||||
#include "service_certificate.h"
|
||||
#include "wv_cdm_types.h"
|
||||
|
||||
namespace video_widevine {
|
||||
@@ -25,11 +27,12 @@ class CdmLicense {
|
||||
CdmLicense(const CdmSessionId& session_id);
|
||||
virtual ~CdmLicense();
|
||||
|
||||
virtual bool Init(const std::string& token, CryptoSession* session,
|
||||
PolicyEngine* policy_engine);
|
||||
virtual bool Init(
|
||||
const std::string& client_token, CdmClientTokenType client_token_type,
|
||||
CryptoSession* session, PolicyEngine* policy_engine);
|
||||
|
||||
virtual CdmResponseType PrepareKeyRequest(
|
||||
const InitializationData& init_data, const CdmLicenseType license_type,
|
||||
const InitializationData& init_data, CdmLicenseType license_type,
|
||||
const CdmAppParameterMap& app_parameters, CdmKeyMessage* signed_request,
|
||||
std::string* server_url);
|
||||
virtual CdmResponseType PrepareKeyUpdateRequest(
|
||||
@@ -59,33 +62,32 @@ class CdmLicense {
|
||||
return is_offline_;
|
||||
}
|
||||
|
||||
static CdmResponseType VerifySignedServiceCertificate(
|
||||
const std::string& signed_service_certificate);
|
||||
|
||||
private:
|
||||
bool PrepareServiceCertificateRequest(CdmKeyMessage* signed_request,
|
||||
std::string* server_url);
|
||||
|
||||
CdmResponseType HandleKeyErrorResponse(
|
||||
const video_widevine::SignedMessage& signed_message);
|
||||
|
||||
bool GetClientTokenType(
|
||||
video_widevine::ClientIdentification::TokenType* token_type);
|
||||
|
||||
CdmResponseType PrepareClientId(
|
||||
bool encrypt, const std::string& certificate,
|
||||
const CdmAppParameterMap& app_parameters,
|
||||
video_widevine::LicenseRequest* license_request);
|
||||
|
||||
CdmResponseType PrepareContentId(
|
||||
const InitializationData& init_data, CdmLicenseType license_type,
|
||||
const std::string& request_id,
|
||||
video_widevine::LicenseRequest* license_request);
|
||||
|
||||
template <typename T>
|
||||
bool PrepareContentId(const CdmLicenseType license_type,
|
||||
const std::string& request_id, T* content_id);
|
||||
bool SetTypeAndId(CdmLicenseType license_type,
|
||||
const std::string& request_id, T* content_id);
|
||||
|
||||
static CdmResponseType VerifyAndExtractSignedServiceCertificate(
|
||||
const std::string& signed_service_certificate,
|
||||
std::string* service_certificate);
|
||||
bool GetServiceCertificate(std::string* service_certificate);
|
||||
|
||||
CryptoSession* session_;
|
||||
CryptoSession* crypto_session_;
|
||||
PolicyEngine* policy_engine_;
|
||||
std::string server_url_;
|
||||
std::string token_;
|
||||
std::string client_token_;
|
||||
CdmClientTokenType client_token_type_;
|
||||
const CdmSessionId session_id_;
|
||||
scoped_ptr<InitializationData> stored_init_data_;
|
||||
bool initialized_;
|
||||
@@ -94,6 +96,9 @@ class CdmLicense {
|
||||
bool renew_with_client_id_;
|
||||
bool is_offline_;
|
||||
|
||||
// Used to encrypt ClientIdentification message
|
||||
scoped_ptr<ServiceCertificate> service_certificate_;
|
||||
|
||||
// Used for certificate based licensing
|
||||
CdmKeyMessage key_request_;
|
||||
|
||||
|
||||
@@ -95,6 +95,7 @@ class Properties {
|
||||
}
|
||||
|
||||
#if defined(UNIT_TEST)
|
||||
FRIEND_TEST(CdmSessionTest, InitWithBuiltInCertificate);
|
||||
FRIEND_TEST(CdmSessionTest, InitWithCertificate);
|
||||
FRIEND_TEST(CdmSessionTest, InitWithKeybox);
|
||||
FRIEND_TEST(CdmSessionTest, ReInitFail);
|
||||
|
||||
81
libwvdrmengine/cdm/core/include/service_certificate.h
Normal file
81
libwvdrmengine/cdm/core/include/service_certificate.h
Normal file
@@ -0,0 +1,81 @@
|
||||
// Copyright 2017 Google Inc. All Rights Reserved.
|
||||
//
|
||||
#ifndef WVCDM_CORE_SERVICE_CERTIFICATE_H_
|
||||
#define WVCDM_CORE_SERVICE_CERTIFICATE_H_
|
||||
|
||||
// Service Certificates are used to encrypt the ClientIdentification message
|
||||
// that is part of Device Provisioning, License, Renewal, and Release requests.
|
||||
// They may be supplied by the application, or a default certificate may be
|
||||
// configured into the CDM, or the CDM may send a Service Certificate Request
|
||||
// to the target server to get one. Separate certificates are maintained for
|
||||
// the License and Provisioning Servers (the default service certificates
|
||||
// are currently identical for both servers). Once the Service Certificates are
|
||||
// established for the session, they should not change.
|
||||
|
||||
#include "license_protocol.pb.h"
|
||||
#include "wv_cdm_types.h"
|
||||
|
||||
namespace video_widevine {
|
||||
class SignedMessage;
|
||||
class LicenseRequest;
|
||||
} // namespace video_widevine
|
||||
|
||||
namespace wvcdm {
|
||||
|
||||
class CryptoSession;
|
||||
|
||||
class ServiceCertificate {
|
||||
public:
|
||||
ServiceCertificate();
|
||||
virtual ~ServiceCertificate();
|
||||
|
||||
virtual bool Init(const CdmSessionId& session_id, CryptoSession* session);
|
||||
|
||||
virtual bool IsRequired();
|
||||
virtual bool IsAvailable();
|
||||
virtual bool PrepareServiceCertificateRequest(CdmKeyMessage* signed_request);
|
||||
|
||||
virtual CdmResponseType VerifyAndSet(
|
||||
const std::string& signed_service_certificate);
|
||||
|
||||
virtual CdmResponseType EncryptClientId(
|
||||
const video_widevine::ClientIdentification* clear_client_id,
|
||||
video_widevine::EncryptedClientIdentification* encrypted_client_id);
|
||||
|
||||
static CdmResponseType VerifySignedServiceCertificate(
|
||||
const std::string& signed_certificate) {
|
||||
bool has_provider_id;
|
||||
return VerifyAndExtractFromSignedCertificate(signed_certificate, NULL,
|
||||
&has_provider_id, NULL);
|
||||
}
|
||||
|
||||
private:
|
||||
// Take a signed certificate, parse it, and verify it.
|
||||
// If a pointer to a string object is passed in, the certificate
|
||||
// will be copied to it.
|
||||
static CdmResponseType VerifyAndExtractFromSignedCertificate(
|
||||
const std::string& signed_service_certificate,
|
||||
std::string* service_certificate, bool* has_provider_id,
|
||||
std::string* provider_id);
|
||||
|
||||
virtual bool SetupServiceCertificate();
|
||||
|
||||
CryptoSession* crypto_session_;
|
||||
CdmSessionId session_id_;
|
||||
bool privacy_mode_enabled_;
|
||||
bool valid_;
|
||||
bool initialized_;
|
||||
|
||||
// Certificate, verified and extracted from signed message.
|
||||
std::string certificate_;
|
||||
|
||||
// Provider ID, extracted from certificate message.
|
||||
bool has_provider_id_;
|
||||
std::string provider_id_;
|
||||
|
||||
CORE_DISALLOW_COPY_AND_ASSIGN(ServiceCertificate);
|
||||
};
|
||||
|
||||
} // namespace wvcdm
|
||||
|
||||
#endif // WVCDM_CORE_SERVICE_CERTIFICATE_H_
|
||||
@@ -14,6 +14,10 @@ static const size_t KEY_SIZE = 16;
|
||||
static const size_t MAC_KEY_SIZE = 32;
|
||||
static const size_t KEYBOX_KEY_DATA_SIZE = 72;
|
||||
|
||||
// Initial estimate of certificate size. Code that
|
||||
// uses this estimate should be able to adapt to a larger or smaller size.
|
||||
static const size_t CERTIFICATE_DATA_SIZE = 4 * 1024;
|
||||
|
||||
// Use 0 to represent never expired license as specified in EME spec
|
||||
// (NaN in JS translates to 0 in unix timestamp).
|
||||
static const int64_t NEVER_EXPIRES = 0;
|
||||
|
||||
@@ -151,9 +151,9 @@ enum CdmResponseType {
|
||||
LICENSE_RENEWAL_SIGNING_ERROR,
|
||||
UNUSED_4, /* previously RESTORE_OFFLINE_LICENSE_ERROR_1 */
|
||||
RESTORE_OFFLINE_LICENSE_ERROR_2,
|
||||
UNUSED_5, /* SESSION_INIT_ERROR_1 */
|
||||
SESSION_INIT_ERROR_1,
|
||||
SESSION_INIT_ERROR_2, /* 115 */
|
||||
SESSION_INIT_GET_KEYBOX_ERROR,
|
||||
UNUSED_5, /* previously SESSION_INIT_GET_KEYBOX_ERROR */
|
||||
SESSION_NOT_FOUND_1,
|
||||
SESSION_NOT_FOUND_2,
|
||||
SESSION_NOT_FOUND_3,
|
||||
@@ -245,6 +245,10 @@ enum CdmResponseType {
|
||||
INVALID_PARAMETERS_ENG_14, /* 205 */
|
||||
INVALID_PARAMETERS_ENG_15,
|
||||
INVALID_PARAMETERS_ENG_16,
|
||||
DEVICE_CERTIFICATE_ERROR_5,
|
||||
CERT_PROVISIONING_CLIENT_TOKEN_ERROR_1,
|
||||
CERT_PROVISIONING_CLIENT_TOKEN_ERROR_2,
|
||||
LICENSING_CLIENT_TOKEN_ERROR_1,
|
||||
};
|
||||
|
||||
enum CdmKeyStatus {
|
||||
@@ -311,6 +315,12 @@ enum CdmSigningAlgorithm {
|
||||
kSigningAlgorithmHmacSha256
|
||||
};
|
||||
|
||||
enum CdmClientTokenType {
|
||||
kClientTokenKeybox,
|
||||
kClientTokenDrmCert,
|
||||
kClientTokenOemCert
|
||||
};
|
||||
|
||||
class CdmKeyAllowedUsage {
|
||||
public:
|
||||
CdmKeyAllowedUsage() {
|
||||
|
||||
Reference in New Issue
Block a user