Move system ID extraction outside of CryptoSession.

[ Merge of http://go/wvgerrit/151391 ]

This CL moves the logic for extracting the system ID from keybox or
OEM certificate (from OEMCrypto or device files) to a dedicated
SystemIdExtractor.

Before Provisioning 4.0, the system ID could only be found from data
returned by OEMCrypto.  However, with provisioning 4.0, the system ID
can now be found in the OEM certificate that is stored on the device
files.

Bug: 232020319
Test: system_id_extractor_unittest
Test: Forest L37800000954493485
Change-Id: Ie1b7987906e2e4fef015cd659a947b6dbb7594b1
This commit is contained in:
Alex Dale
2022-05-09 16:51:39 -07:00
parent 8ac7ca3f46
commit 9d169a00bb
12 changed files with 945 additions and 431 deletions

View File

@@ -82,12 +82,28 @@ class CryptoSession {
static void DisableDelayedTermination();
virtual CdmResponseType GetProvisioningToken(
RequestedSecurityLevel requested_security_level, std::string* token,
std::string* additional_token);
// Must be called after session is open.
virtual CdmResponseType GetProvisioningToken(std::string* token,
std::string* additional_token);
virtual CdmClientTokenType GetPreProvisionTokenType() {
return pre_provision_token_type_;
}
// Retrieves the key data portion of the OEMCrypto keybox.
// Only valid for keybox-based based devices.
// May return NEED_PROVISIONING if the device is keybox-based, but
// OTA keybox provisioning is required.
virtual CdmResponseType GetTokenFromKeybox(
RequestedSecurityLevel requested_security_level, std::string* key_data);
// Retrieves the public OEM certificate chain from OEMCrypto.
// Only valid for OEM certificate-based based devices.
virtual CdmResponseType GetTokenFromOemCert(
RequestedSecurityLevel requested_security_level, std::string* oem_cert);
// The overloaded methods with |requested_level| may be called
// without a preceding call to Open. The other method must call Open first.
virtual CdmSecurityLevel GetSecurityLevel();
@@ -114,10 +130,15 @@ class CryptoSession {
// - that does not implement |OEMCrypto_GetDeviceID|: the 32 byte hash
// of the OEM public certificate.
virtual CdmResponseType GetExternalDeviceUniqueId(std::string* device_id);
virtual bool GetSystemId(uint32_t* system_id);
virtual CdmResponseType GetProvisioningId(std::string* provisioning_id);
virtual uint8_t GetSecurityPatchLevel();
virtual bool GetCachedSystemId(uint32_t* system_id);
// With provisioning 4.0, the system ID cannot reliably be found within
// OEMCrypto. The system ID can be assigned to the CryptoSession instance
// after the ID has been determined.
virtual void SetSystemId(uint32_t system_id);
virtual CdmResponseType Open() { return Open(kLevelDefault); }
virtual CdmResponseType Open(RequestedSecurityLevel requested_security_level);
virtual void Close();
@@ -179,6 +200,9 @@ class CryptoSession {
std::string* wrapped_private_key);
virtual CdmResponseType LoadCertificatePrivateKey(
const CryptoWrappedKey& private_key);
virtual CdmResponseType GetBootCertificateChain(
RequestedSecurityLevel requested_security_level, std::string* bcc,
std::string* additional_signature);
virtual CdmResponseType GetBootCertificateChain(
std::string* bcc, std::string* additional_signature);
virtual CdmResponseType GenerateCertificateKeyPair(
@@ -377,11 +401,6 @@ class CryptoSession {
// Note: This function will lock the global static field lock in write mode.
bool SetUpUsageTableHeader(RequestedSecurityLevel requested_security_level);
CdmResponseType GetTokenFromKeybox(std::string* token);
CdmResponseType GetTokenFromOemCert(std::string* token);
static bool ExtractSystemIdFromOemCert(const std::string& oem_cert,
uint32_t* system_id);
CdmResponseType GetSystemIdInternal(uint32_t* system_id);
CdmResponseType GenerateRsaSignature(const std::string& message,
std::string* signature);
size_t GetMaxSubsampleRegionSize();

View File

@@ -0,0 +1,68 @@
// Copyright 2022 Google LLC. All Rights Reserved. This file and proprietary
// source code may only be used and distributed under the Widevine License
// Agreement.
#ifndef WVCDM_CORE_SYSTEM_ID_EXTRACTOR_H_
#define WVCDM_CORE_SYSTEM_ID_EXTRACTOR_H_
#include <stdint.h>
#include "wv_cdm_types.h"
namespace wvutil {
class FileSystem;
} // namespace wvutil
namespace wvcdm {
class CryptoSession;
class DeviceFiles;
// System ID extractor will find and extract the system ID of the device.
// Handles the different cases where the system ID may be found in
// different place.
class SystemIdExtractor {
public:
SystemIdExtractor(RequestedSecurityLevel security_level,
CryptoSession* crypto_session, wvutil::FileSystem* fs);
virtual ~SystemIdExtractor() {}
// Disallow copy and move.
SystemIdExtractor(const SystemIdExtractor&) = delete;
SystemIdExtractor(SystemIdExtractor&&) = delete;
SystemIdExtractor& operator=(const SystemIdExtractor&) = delete;
SystemIdExtractor& operator=(SystemIdExtractor&&) = delete;
virtual bool ExtractSystemId(uint32_t* system_id);
// Extracts the system ID from a keybox key data (aka CA token).
static bool ExtractSystemIdFromKeyboxData(const std::string& key_data,
uint32_t* system_id);
// Extracts the system ID from a serialized OEM certificate.
static bool ExtractSystemIdFromOemCert(const std::string& oem_cert,
uint32_t* system_id);
void SetDeviceFilesForTesting(DeviceFiles* device_files) {
test_device_files_ = device_files;
}
private:
// Extracts the system ID from keybox-based OEMCrypto implementations.
// System ID is expected to be found in the keybox data. Devices
// which require OTA keybox provisioning will return a null system ID.
bool ExtractSystemIdProv20(uint32_t* system_id);
// Extracts the system ID from OEM certificate-based OEMCrypto
// implementations. System ID is expected to be in the manufacturers
// intermediate X.509 certificate.
bool ExtractSystemIdProv30(uint32_t* system_id);
// Extracts the system ID from BCC-based OEMCrypto implementations.
// System ID is expected to be found in the stored OEM certificate
// for the provided origin-identifier, after BCC provisioning.
// Clients which have not performed BCC provisioning will return
// a null system ID.
bool ExtractSystemIdProv40(uint32_t* system_id);
RequestedSecurityLevel security_level_ = kLevelDefault;
CryptoSession* crypto_session_ = nullptr;
wvutil::FileSystem* fs_ = nullptr;
DeviceFiles* test_device_files_ = nullptr;
};
} // namespace wvcdm
#endif // WVCDM_CORE_SYSTEM_ID_EXTRACTOR_H_

View File

@@ -5,6 +5,7 @@
#ifndef WVCDM_CORE_WV_CDM_CONSTANTS_H_
#define WVCDM_CORE_WV_CDM_CONSTANTS_H_
#include <limits>
#include <string>
namespace wvcdm {
@@ -28,6 +29,11 @@ static const int64_t NEVER_EXPIRES = 0;
static const int64_t UNLIMITED_DURATION = 0;
static const int64_t INVALID_TIME = -1;
// Not a valid system ID. Used as a placeholder for systems without an ID.
// Will not be accepted for DRM provisioning requests or license requests.
static constexpr uint32_t NULL_SYSTEM_ID =
static_cast<uint32_t>(std::numeric_limits<int>::max());
// This is the lower limit. For OEMCrypto v16+ one can query and find how many
// are supported
static constexpr size_t kMinimumUsageTableEntriesSupported = 200;