These are a set of CLs merged from the wv cdm repo to the android repo. * Level3 cleanup for SHA + field provision headers Author: Srujan Gaddam <srujzs@google.com> [ Merge of http://go/wvgerrit/37581 ] Moved some redundant macro and struct definitions out of hmac.cpp and sha.cpp into a separate header file to make the build easier and cleaner. Also cleaned up unnecessary includes and method signatures in field_provision.h. * Address CDM_All_Tests failures Author: Rahul Frias <rfrias@google.com> [ Merge of http://go/wvgerrit/37580 ] CDM engine tests for CE CDM occasionally fails when CDM_All_Tests is run by the build server. The failures are due to a nonce generation error. If provisioning fails due to a nonce generation error, a delay followed by a retry will be attempted. * Update OEMCrypto version to 13 in cdm.gyp Author: Gene Morgan <gmorgan@google.com> [ Merge of http://go/wvgerrit/37520 ] * Use per-session service certificates for licensing Author: Rahul Frias <rfrias@google.com> [ Merge of http://go/wvgerrit/37260 ] These changes allow for service certificates to be specified on a per-session basis rather than use one common to a CdmEngine instance. This also allows for a service certificate request and response handling when allowed on the platform, when privacy mode is enabled and a service certificate is not provided. Request license tests accept a service certificate command line parameter in hex (ascii). Earlier it expected it in binary. Bug: 68328352 * Refactor service certificate parsing Author: Rahul Frias <rfrias@google.com> [ Merge of http://go/wvgerrit/37060 ] Service certificates may still be set in CdmEngine but service certificate requests and responses have been moved from CdmEngine to ServiceCertificate. This allows them to be called from lower in the heirarchy (a class that CdmEngine depends on). Bug: 68328352 * Revert "C++11: Replace OVERRIDE def with override keyword" Author: Gene Morgan <gmorgan@google.com> [ Merge of http://go/wvgerrit/37020 ] This reverts commit 2d3fb5c4c8f4cf5c986ee43723914a23cf76e8f0. * Modified scripts/makefiles for L3 build Author: Srujan Gaddam <srujzs@google.com> [ Merge of http://go/wvgerrit/37220 ] Changed build-android-haystack.sh and make_fastball_libwvlevel3.sh to build using the new liboemcrypto.cpp file. Also changed makefiles to build using the new file. Renamed liboemcrypto.cc to liboemcrypto.cpp to make it consistent across android and CE CDM. Added static libraries that were rebuilt using this change. * Added android implementations for Level3 Author: Srujan Gaddam <srujzs@google.com> [ Merge of http://go/wvgerrit/37181 ] Moved getUniqueID and added Level3FileSystem implementations for android. Also deleted redundant and unnecessary methods from anroid_keybox.cpp. * Refactored getUniqueID and updated libl3oemcrypto.cc Author: Srujan Gaddam <srujzs@google.com> [ Merge of http://go/wvgerrit/37160 ] Renamed getUniqueID header and added comments to make it clear what the function is doing. Also removed obfuscation of the method name since it is implemented by the partner. Updated the libl3oemcrypto.cc file to reflect the change as well as be obfuscated. * Moved clear_cache function out of entry_points Author: Srujan Gaddam <srujzs@google.com> [ Merge of http://go/wvgerrit/37040 ] clear_cache function is unobfuscated and relies on compiler flags to work properly, and therefore should be removed from the libl3oemcrypto.cpp file and linked during the final build. * Minor gyp changes and added L3 build file Author: Srujan Gaddam <srujzs@google.com> [ Merge of http://go/wvgerrit/36480 ] Gyp changes to cdm_unittests.gyp to make the test Level3FileSystem build only on a level3 build and to oec_level3.gyp to be compatible with the changes to the x86-64 platform settings changes (and to use -Wno-unused to catch all unused warnings the libl3oemcrypto.cc might cause). This change also includes an x86-64 libl3oemcrypto.cc so a Level3 OEMCrypto can build. * Merge CE & Linux file system/factory + dynamic adapter changes Author: Srujan Gaddam <srujzs@google.com> [ Merge of http://go/wvgerrit/36220 ] This CL merges the changes from I27f5037e4fcea94abd84181f55053843b68f3e8d - it adds the CE implementation for the file system, as well as the factory methods needed to build the file system (and their implementations for both CE and linux). As part of the merge, since the Linux build relies on the dynamic adapter, that was fixed and gyp changes were made to reflect the change. * Cherry pick change to retrieve/save provisioning cert Author: Srujan Gaddam <srujzs@google.com> [ Merge of http://go/wvgerrit/30000 ] This is cherry pick from level3-dev-3.3 of a merge of I4f5dc5c216fa916e0bca0631c4ceda68859baf1d to save the certificate for future tests with the current test host setup. * Merged changes of usage/linux impl of L3FileSystem Author: Srujan Gaddam <srujzs@google.com> [ Merge of http://go/wvgerrit/35541 ] This is a merge of change I15d38b3c36933d061d168e0ec30bcefd0182f32d. It also adds a similar change in usage of L3FileSystem write for a line in usage_table.cpp. * Add cdm build changes for new Level3 build Author: Srujan Gaddam <srujzs@google.com> [ Merge of http://go/wvgerrit/34600 ] Original CL: Ib611cf8a8589afa5cd25d6dc5b0aa43922cfda1e Adds level3 oemcrypto library for static adapter. Includes changes to gyp files to choose between oemcrypto libraries. Also includes changes to the dynamic adapter, level3 headers, and entry_points to be compatible with the function signature differences when using the static adapter. * Merge OEMCrypto Level3FileSystem interface Author: Srujan Gaddam <srujzs@google.com> [ Merge of http://go/wvgerrit/34541 ] This merges in the interface for the Level3FileSystem object from level3_dev_3.3 as well as the linux implementation. Furthermore, this merge includes changes in properties and gyp files to allow compilation. The associated changes are I3f1c58f0e3782de0669a96725a38673a26cc1a49, I9fb2d10b0f966896bea685166c6b6b2e33c995dd, and I4c87a5412a8a022fa9cfba43f33bd4d683e61536. * Merged misc. changes to Level3 files Author: Srujan Gaddam <srujzs@google.com> [ Merge of http://go/wvgerrit/33303 ] Continuation of I03d3aa1a308f2f010dcb6f5e15f927e81e42925b. These changes are miscellaneous changes from level3-dev-3.3 involving include statements, Caligo compatibility, and new Level3 signatures from changes Ibc5befd492b295970e839f3481e2b512b52dcb08 and If599e62c72b5eb40c53633cd72a4d20dc859ee52. * Merged change involving getUniqueId() Author: Srujan Gaddam <srujzs@google.com> [ Merge of http://go/wvgerrit/33302 ] This is a merge from level3-dev-3.3. This change (Ibc5befd492b295970e839f3481e2b512b52dcb08) involves separating out the method getUniqueId() from the linux_ and android_keybox.cpp. This was done so that clients can supply the necessary implementation for the method. * Merged needle file changes from level3-dev-3.3 Author: Srujan Gaddam <srujzs@google.com> [ Merge of http://go/wvgerrit/33301 ] Continuation of I3dbf34bab526945720280f819dd3212ae982d2f7. These are changes (Ibc5befd492b295970e839f3481e2b512b52dcb08) involving the compiled needles for Haystack. Major changes include function signature changes, adding non-state needles automatically, and include statements. * Merged keybox/usage table access and function sigs Author: Srujan Gaddam <srujzs@google.com> [ Merge of http://go/wvgerrit/33300 ] These are changes from level3-dev-3.3. They involve changing function signatures/include files for the new Haystack runtime (Ibc5befd492b295970e839f3481e2b512b52dcb08). They are also related to change I0285e6d85e80b06b7df1ed298cd1145a6c9c4842. Keybox and usage table file names are replaced with constant needles. Furthermore, a state needle was added that removes the OldUsageTable file. In addition, this CL includes removals of method references that are now stale due to the introduction of change I9fb2d10b0f966896bea685166c6b6b2e33c995dd. * Android unit test build fixes Author: Srujan Gaddam <srujzs@google.com> [ Merge of http://go/wvgerrit/37380 ] Removed crypto_session_unittest from build script (introduced in http://go/wvgerrit/32824), since crypto_session.cpp requires some changes to be merged over from oc-mr1-dev (b/64456400). Added oemcrypto_session_tests_helper.cpp to the oemcrypto test makefile so the oemcrypto unit tests can link in the methods from the refactor in http://go/wvgerrit/36562. BUG: 71650075 Test: Not currently passing. Will be addressed in a subsequent commit in the chain. Change-Id: I7e45901a151e51da96d192d359edddc5fe74946e
346 lines
15 KiB
C++
346 lines
15 KiB
C++
// Copyright 2013 Google Inc. All Rights Reserved.
|
|
|
|
#ifndef WVCDM_CORE_CDM_ENGINE_H_
|
|
#define WVCDM_CORE_CDM_ENGINE_H_
|
|
|
|
#include <memory>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include "cdm_session_map.h"
|
|
#include "certificate_provisioning.h"
|
|
#include "clock.h"
|
|
#include "crypto_session.h"
|
|
#include "file_store.h"
|
|
#include "initialization_data.h"
|
|
#include "lock.h"
|
|
#include "metrics_collections.h"
|
|
#include "oemcrypto_adapter.h"
|
|
#include "scoped_ptr.h"
|
|
#include "service_certificate.h"
|
|
#include "timer_metric.h"
|
|
#include "wv_cdm_constants.h"
|
|
#include "wv_cdm_types.h"
|
|
|
|
namespace wvcdm {
|
|
|
|
class CdmClientPropertySet;
|
|
class CdmSession;
|
|
class CryptoEngine;
|
|
class UsagePropertySet;
|
|
class WvCdmEventListener;
|
|
|
|
// Keep expiration time for each key set
|
|
typedef std::map<CdmKeySetId,
|
|
std::pair<CdmSessionId, int64_t> > CdmReleaseKeySetMap;
|
|
|
|
class CdmEngine {
|
|
public:
|
|
CdmEngine(FileSystem* file_system, const std::string& spoid = EMPTY_SPOID);
|
|
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);
|
|
|
|
// Report whether the service certificate has been set.
|
|
virtual bool HasServiceCertificate();
|
|
|
|
// Session related methods
|
|
virtual CdmResponseType OpenSession(
|
|
const CdmKeySystem& key_system, CdmClientPropertySet* property_set,
|
|
const CdmSessionId& forced_session_id,
|
|
WvCdmEventListener* event_listener);
|
|
|
|
virtual CdmResponseType OpenSession(
|
|
const CdmKeySystem& key_system, CdmClientPropertySet* property_set,
|
|
WvCdmEventListener* event_listener, CdmSessionId* session_id);
|
|
|
|
virtual CdmResponseType CloseSession(const CdmSessionId& session_id);
|
|
|
|
virtual bool IsOpenSession(const CdmSessionId& session_id);
|
|
|
|
virtual CdmResponseType OpenKeySetSession(
|
|
const CdmKeySetId& key_set_id, CdmClientPropertySet* property_set,
|
|
WvCdmEventListener* event_listener);
|
|
|
|
virtual CdmResponseType CloseKeySetSession(const CdmKeySetId& key_set_id);
|
|
|
|
// License related methods
|
|
|
|
// Construct a valid license request. The arguments are used as follows:
|
|
// session_id: The Session ID of the session the request is being generated
|
|
// for. This is ignored for license release requests.
|
|
// key_set_id: The Key Set ID of the key set the request is being generated
|
|
// for. This is ignored except for license release requests.
|
|
// init_data: The initialization data from the media file, which is used to
|
|
// build the key request. This is ignored for release and renewal
|
|
// requests.
|
|
// license_type: The type of license being requested. Never ignored.
|
|
// app_parameters: Additional, application-specific parameters that factor
|
|
// into the request generation. This is ignored for release
|
|
// and renewal requests.
|
|
// key_request: This must be non-null and point to a CdmKeyRequest. The
|
|
// message field will be filled with the key request, the
|
|
// type field will be filled with the key request type,
|
|
// whether it is an initial request, renewal request,
|
|
// release request, etc. The url field will be filled with
|
|
// the default URL (if one is known) to send this key
|
|
// request to.
|
|
virtual CdmResponseType GenerateKeyRequest(
|
|
const CdmSessionId& session_id, const CdmKeySetId& key_set_id,
|
|
const InitializationData& init_data, const CdmLicenseType license_type,
|
|
CdmAppParameterMap& app_parameters, CdmKeyRequest* key_request);
|
|
// This API may
|
|
// (a) accept license response, extract key info and load keys.
|
|
// (b) accept a renewal response and update license policy information.
|
|
// (c) accept a release response and release an offline license or secure
|
|
// stop.
|
|
// (d) accept a service certificate and cache that information for the
|
|
// the lifetime of the session.
|
|
//
|
|
// |session_id| identifies the session that generated the request and can
|
|
// process the response. Should be empty if a release response.
|
|
// |key_data| is the license, renewal, release response or service
|
|
// certificate response.
|
|
// |key_set_id| should be non-null and specified if license release.
|
|
// If offline license or streaming license associated with
|
|
// a secure stop, |key_set_id| should be non-null and will
|
|
// be filled in on return. Use the |key_set_id| with
|
|
// RestoreKeys (to reload offline session) or
|
|
// GenerateKeyRequest (to release offline session/secure stop).
|
|
// |key_set_id| will be cleared if release or streaming
|
|
// (not associated with a secure stop).
|
|
virtual CdmResponseType AddKey(const CdmSessionId& session_id,
|
|
const CdmKeyResponse& key_data,
|
|
CdmKeySetId* key_set_id);
|
|
|
|
virtual CdmResponseType RestoreKey(const CdmSessionId& session_id,
|
|
const CdmKeySetId& key_set_id);
|
|
|
|
virtual CdmResponseType RemoveKeys(const CdmSessionId& session_id);
|
|
|
|
// Construct valid renewal request for the current session keys.
|
|
virtual CdmResponseType GenerateRenewalRequest(
|
|
const CdmSessionId& session_id, CdmKeyRequest* key_request);
|
|
|
|
// Accept renewal response and update key info.
|
|
virtual CdmResponseType RenewKey(const CdmSessionId& session_id,
|
|
const CdmKeyResponse& key_data);
|
|
|
|
// Query system information
|
|
virtual CdmResponseType QueryStatus(SecurityLevel security_level,
|
|
const std::string& query_token,
|
|
std::string* query_response);
|
|
|
|
// Query session information
|
|
virtual CdmResponseType QuerySessionStatus(const CdmSessionId& session_id,
|
|
CdmQueryMap* query_response);
|
|
virtual bool IsReleaseSession(const CdmSessionId& session_id);
|
|
virtual bool IsOfflineSession(const CdmSessionId& session_id);
|
|
|
|
// Query license information
|
|
virtual CdmResponseType QueryKeyStatus(const CdmSessionId& session_id,
|
|
CdmQueryMap* query_response);
|
|
|
|
// Query the types of usage permitted for the specified key.
|
|
virtual CdmResponseType QueryKeyAllowedUsage(const CdmSessionId& session_id,
|
|
const std::string& key_id,
|
|
CdmKeyAllowedUsage* key_usage);
|
|
|
|
// Query the types of usage permitted for the specified key.
|
|
// Apply the query across all sessions. If the key is found in more than
|
|
// one session, return the allowed usage settings only if the usage settings
|
|
// are identical for each instance of the key. Otherwise, clear the settings
|
|
// and return KEY_CONFLICT_1.
|
|
virtual CdmResponseType QueryKeyAllowedUsage(const std::string& key_id,
|
|
CdmKeyAllowedUsage* key_usage);
|
|
|
|
// Query OEMCrypto session ID
|
|
virtual CdmResponseType QueryOemCryptoSessionId(
|
|
const CdmSessionId& session_id, CdmQueryMap* query_response);
|
|
|
|
// Generate and return a valid provisioning request.
|
|
virtual CdmResponseType GetProvisioningRequest(
|
|
CdmCertificateType cert_type, const std::string& cert_authority,
|
|
CdmProvisioningRequest* request, std::string* default_url);
|
|
|
|
// Verify and process a provisioning response.
|
|
virtual CdmResponseType HandleProvisioningResponse(
|
|
const CdmProvisioningResponse& response, std::string* cert,
|
|
std::string* wrapped_key);
|
|
|
|
// Return true if there is a device certificate on the current
|
|
// (origin-specific) file system.
|
|
virtual bool IsProvisioned(CdmSecurityLevel security_level);
|
|
|
|
// Remove device DRM certificate from the current (origin-specific) file
|
|
// system. This will force the device to reprovision itself.
|
|
virtual CdmResponseType Unprovision(CdmSecurityLevel security_level);
|
|
|
|
// Delete OEMCrypto usage tables. Used by Unprovision().
|
|
virtual CdmResponseType DeleteUsageTable(CdmSecurityLevel security_level);
|
|
|
|
// Return the list of key_set_ids stored on the current (origin-specific)
|
|
// file system.
|
|
virtual CdmResponseType ListStoredLicenses(
|
|
CdmSecurityLevel security_level, std::vector<std::string>* key_set_ids);
|
|
|
|
// Return the list of key_set_ids stored as usage records on the
|
|
// current (origin-specific) file system.
|
|
virtual CdmResponseType ListUsageRecords(
|
|
const std::string& app_id, CdmSecurityLevel security_level,
|
|
std::vector<std::string>* ksids);
|
|
|
|
// Delete the usage record for the given key_set_id. This removes the
|
|
// usage record in the file system and the OEMCrypto usage record.
|
|
virtual CdmResponseType DeleteUsageRecord(const std::string& app_id,
|
|
CdmSecurityLevel security_level,
|
|
const std::string& key_set_id);
|
|
|
|
// Usage related methods for streaming licenses
|
|
// Retrieve a random usage info from the list of all usage infos for this app
|
|
// id.
|
|
virtual CdmResponseType GetUsageInfo(const std::string& app_id,
|
|
CdmUsageInfo* usage_info);
|
|
|
|
// Retrieve the usage info for the specified pst.
|
|
// Returns UNKNOWN_ERROR if no usage info was found.
|
|
virtual CdmResponseType GetUsageInfo(const std::string& app_id,
|
|
const CdmSecureStopId& ssid,
|
|
CdmUsageInfo* usage_info);
|
|
|
|
// Release all usage records for the current origin.
|
|
virtual CdmResponseType ReleaseAllUsageInfo(const std::string& app_id,
|
|
CdmSecurityLevel security_level);
|
|
|
|
// Release all usage records for the current origin. Span all
|
|
// security levels.
|
|
virtual CdmResponseType ReleaseAllUsageInfo(const std::string& app_id);
|
|
|
|
virtual CdmResponseType ReleaseUsageInfo(
|
|
const CdmUsageInfoReleaseMessage& message);
|
|
virtual CdmResponseType LoadUsageSession(const CdmKeySetId& key_set_id,
|
|
CdmKeyMessage* release_message);
|
|
|
|
// Decryption and key related methods
|
|
// Accept encrypted buffer and return decrypted data.
|
|
virtual CdmResponseType Decrypt(const CdmSessionId& session_id,
|
|
const CdmDecryptionParameters& parameters);
|
|
|
|
// Generic crypto operations - provides basic crypto operations that an
|
|
// application can use outside of content stream processing
|
|
|
|
// Encrypts a buffer of app-level data.
|
|
virtual CdmResponseType GenericEncrypt(
|
|
const std::string& session_id, const std::string& in_buffer,
|
|
const std::string& key_id, const std::string& iv,
|
|
CdmEncryptionAlgorithm algorithm, std::string* out_buffer);
|
|
|
|
// Decrypts a buffer of app-level data.
|
|
virtual CdmResponseType GenericDecrypt(
|
|
const std::string& session_id, const std::string& in_buffer,
|
|
const std::string& key_id, const std::string& iv,
|
|
CdmEncryptionAlgorithm algorithm, std::string* out_buffer);
|
|
|
|
// Computes the signature for a message.
|
|
virtual CdmResponseType GenericSign(const std::string& session_id,
|
|
const std::string& message,
|
|
const std::string& key_id,
|
|
CdmSigningAlgorithm algorithm,
|
|
std::string* signature);
|
|
|
|
// Verifies the signature on a buffer of app-level data.
|
|
virtual CdmResponseType GenericVerify(const std::string& session_id,
|
|
const std::string& message,
|
|
const std::string& key_id,
|
|
CdmSigningAlgorithm algorithm,
|
|
const std::string& signature);
|
|
|
|
virtual size_t SessionSize() const { return session_map_.Size(); }
|
|
|
|
// Is the key known to any session?
|
|
virtual bool IsKeyLoaded(const KeyId& key_id);
|
|
virtual bool FindSessionForKey(const KeyId& key_id, CdmSessionId* sessionId);
|
|
|
|
// Used for notifying the Max-Res Engine of resolution changes.
|
|
// Return false if no match is found for session_id.
|
|
virtual bool NotifyResolution(const CdmSessionId& session_id, uint32_t width,
|
|
uint32_t height);
|
|
|
|
// Timer expiration method. This method is not re-entrant -- there can be
|
|
// only one timer.
|
|
// This method triggers appropriate event callbacks from |event_listener_|,
|
|
// which is assumed to be asynchronous -- i.e. an event should be dispatched
|
|
// to another thread which does the actual work. In particular, if a
|
|
// synchronous listener calls OpenSession or CloseSession, the thread will
|
|
// dead lock.
|
|
virtual void OnTimerEvent();
|
|
|
|
virtual metrics::EngineMetrics* GetMetrics() { return &metrics_; }
|
|
|
|
private:
|
|
// private methods
|
|
CdmResponseType OpenSession(
|
|
const CdmKeySystem& key_system, CdmClientPropertySet* property_set,
|
|
WvCdmEventListener* event_listener, const CdmSessionId* forced_session_id,
|
|
CdmSessionId* session_id);
|
|
|
|
void DeleteAllUsageReportsUponFactoryReset();
|
|
bool ValidateKeySystem(const CdmKeySystem& key_system);
|
|
CdmResponseType GetUsageInfo(const std::string& app_id,
|
|
SecurityLevel requested_security_level,
|
|
CdmUsageInfo* usage_info);
|
|
|
|
void OnKeyReleaseEvent(const CdmKeySetId& key_set_id);
|
|
|
|
std::string MapHdcpVersion(CryptoSession::HdcpCapability version);
|
|
|
|
void CloseExpiredReleaseSessions();
|
|
|
|
// instance variables
|
|
|
|
/*
|
|
* The metrics group must be the first variable declared to ensure
|
|
* that it is the last member destroyed so that no child members
|
|
* try to use a reference to it after it is destroyed. This will
|
|
* ensure that all data has been properly recorded in the group before
|
|
* it is published.
|
|
*/
|
|
metrics::EngineMetrics metrics_;
|
|
metrics::TimerMetric life_span_;
|
|
|
|
CdmSessionMap session_map_;
|
|
CdmReleaseKeySetMap release_key_sets_;
|
|
scoped_ptr<CertificateProvisioning> cert_provisioning_;
|
|
SecurityLevel cert_provisioning_requested_security_level_;
|
|
FileSystem* file_system_;
|
|
Clock clock_;
|
|
std::string spoid_;
|
|
|
|
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
|
|
scoped_ptr<CdmSession> usage_session_;
|
|
scoped_ptr<UsagePropertySet> usage_property_set_;
|
|
int64_t last_usage_information_update_time_;
|
|
|
|
// Protect release_key_sets_ from non-thread-safe operations.
|
|
Lock release_key_sets_lock_;
|
|
|
|
CORE_DISALLOW_COPY_AND_ASSIGN(CdmEngine);
|
|
};
|
|
|
|
} // namespace wvcdm
|
|
|
|
#endif // WVCDM_CORE_CDM_ENGINE_H_
|