diff --git a/libwvdrmengine/build_all_unit_tests.sh b/libwvdrmengine/build_all_unit_tests.sh index 3506e636..1daa8cde 100755 --- a/libwvdrmengine/build_all_unit_tests.sh +++ b/libwvdrmengine/build_all_unit_tests.sh @@ -73,6 +73,7 @@ WV_UNITTESTS="base64_test \ request_license_test \ rw_lock_test \ service_certificate_unittest \ + system_id_extractor_unittest \ timer_unittest \ usage_table_header_unittest \ value_metric_unittest \ diff --git a/libwvdrmengine/cdm/Android.bp b/libwvdrmengine/cdm/Android.bp index a03c47ec..dae4e43e 100644 --- a/libwvdrmengine/cdm/Android.bp +++ b/libwvdrmengine/cdm/Android.bp @@ -63,6 +63,7 @@ cc_library_static { CORE_SRC_DIR + "/policy_timers_v16.cpp", CORE_SRC_DIR + "/privacy_crypto_boringssl.cpp", CORE_SRC_DIR + "/service_certificate.cpp", + CORE_SRC_DIR + "/system_id_extractor.cpp", CORE_SRC_DIR + "/usage_table_header.cpp", CORE_SRC_DIR + "/wv_cdm_types.cpp", SRC_DIR + "/wv_content_decryption_module.cpp", diff --git a/libwvdrmengine/cdm/core/include/crypto_session.h b/libwvdrmengine/cdm/core/include/crypto_session.h index 15ce3278..20421510 100644 --- a/libwvdrmengine/cdm/core/include/crypto_session.h +++ b/libwvdrmengine/cdm/core/include/crypto_session.h @@ -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(); diff --git a/libwvdrmengine/cdm/core/include/system_id_extractor.h b/libwvdrmengine/cdm/core/include/system_id_extractor.h new file mode 100644 index 00000000..e98f03b8 --- /dev/null +++ b/libwvdrmengine/cdm/core/include/system_id_extractor.h @@ -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 + +#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_ diff --git a/libwvdrmengine/cdm/core/include/wv_cdm_constants.h b/libwvdrmengine/cdm/core/include/wv_cdm_constants.h index fba47372..dc6cf694 100644 --- a/libwvdrmengine/cdm/core/include/wv_cdm_constants.h +++ b/libwvdrmengine/cdm/core/include/wv_cdm_constants.h @@ -5,6 +5,7 @@ #ifndef WVCDM_CORE_WV_CDM_CONSTANTS_H_ #define WVCDM_CORE_WV_CDM_CONSTANTS_H_ +#include #include 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(std::numeric_limits::max()); + // This is the lower limit. For OEMCrypto v16+ one can query and find how many // are supported static constexpr size_t kMinimumUsageTableEntriesSupported = 200; diff --git a/libwvdrmengine/cdm/core/src/cdm_engine.cpp b/libwvdrmengine/cdm/core/src/cdm_engine.cpp index b422978b..d7d4bb58 100644 --- a/libwvdrmengine/cdm/core/src/cdm_engine.cpp +++ b/libwvdrmengine/cdm/core/src/cdm_engine.cpp @@ -25,6 +25,7 @@ #include "ota_keybox_provisioner.h" #include "properties.h" #include "string_conversions.h" +#include "system_id_extractor.h" #include "wv_cdm_constants.h" #include "wv_cdm_event_listener.h" @@ -839,6 +840,17 @@ CdmResponseType CdmEngine::QueryStatus(RequestedSecurityLevel security_level, } return NO_ERROR; } + if (query_token == QUERY_KEY_SYSTEM_ID) { + SystemIdExtractor extractor(security_level, crypto_session.get(), + file_system_); + uint32_t system_id; + if (!extractor.ExtractSystemId(&system_id)) { + LOGW("ExtractSystemId failed"); + return UNKNOWN_ERROR; + } + *query_response = std::to_string(system_id); + return NO_ERROR; + } CdmResponseType status; M_TIME(status = crypto_session->Open(security_level), @@ -857,16 +869,6 @@ CdmResponseType CdmEngine::QueryStatus(RequestedSecurityLevel security_level, *query_response = device_id; return NO_ERROR; } - if (query_token == QUERY_KEY_SYSTEM_ID) { - uint32_t system_id; - const bool got_id = crypto_session->GetSystemId(&system_id); - if (!got_id) { - LOGW("QUERY_KEY_SYSTEM_ID unknown failure"); - return UNKNOWN_ERROR; - } - *query_response = std::to_string(system_id); - return NO_ERROR; - } if (query_token == QUERY_KEY_PROVISIONING_ID) { std::string provisioning_id; status = crypto_session->GetProvisioningId(&provisioning_id); diff --git a/libwvdrmengine/cdm/core/src/crypto_session.cpp b/libwvdrmengine/cdm/core/src/crypto_session.cpp index f431986e..4c649010 100644 --- a/libwvdrmengine/cdm/core/src/crypto_session.cpp +++ b/libwvdrmengine/cdm/core/src/crypto_session.cpp @@ -72,8 +72,6 @@ constexpr uint32_t kRsaSignatureLength = 256; constexpr size_t kEstimatedInitialUsageTableHeader = 40; const size_t kAes128BlockSize = 16; -// Constants and utility objects relating to OEM Certificates -constexpr const char* kWidevineSystemIdExtensionOid = "1.3.6.1.4.1.11129.4.1.1"; constexpr int kMaxTerminateCountDown = 5; const std::string kStringNotAvailable = "NA"; @@ -100,11 +98,6 @@ static_assert(wvutil::ArraySize(kMaxSubsampleRegionSizes) == constexpr size_t kDefaultMaxSubsampleRegionSize = kMaxSubsampleRegionSizes[0]; -// 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. -constexpr uint32_t kNullSystemId = - static_cast(std::numeric_limits::max()); - constexpr size_t kMaxExternalDeviceIdLength = 64; // This maps a few common OEMCryptoResult to CdmResponseType. Many mappings @@ -269,7 +262,7 @@ OEMCryptoCipherMode ToOEMCryptoCipherMode(CdmCipherMode cipher_mode) { CryptoSession::CryptoSession(metrics::CryptoMetrics* metrics) : metrics_(metrics), - system_id_(-1), + system_id_(NULL_SYSTEM_ID), open_(false), pre_provision_token_type_(kClientTokenUninitialized), update_usage_table_after_close_session_(false), @@ -525,76 +518,102 @@ bool CryptoSession::SetUpUsageTableHeader( return true; } -CdmResponseType CryptoSession::GetTokenFromKeybox(std::string* token) { +CdmResponseType CryptoSession::GetTokenFromKeybox( + RequestedSecurityLevel requested_security_level, std::string* key_data) { RETURN_IF_UNINITIALIZED(CRYPTO_SESSION_NOT_INITIALIZED); - RETURN_IF_NULL(token, PARAMETER_NULL); - std::string temp_buffer(KEYBOX_KEY_DATA_SIZE, '\0'); - size_t buf_size = temp_buffer.size(); - uint8_t* buf = reinterpret_cast(&temp_buffer[0]); + RETURN_IF_NULL(key_data, PARAMETER_NULL); + LOGV("requested_security_level = %s", + RequestedSecurityLevelToString(requested_security_level)); + // Devices with an invalid L1 keybox which support OTA keybox + // provisioning don't have keybox data. + const bool keybox_provisioning_required = WithStaticFieldReadLock( + "GetTokenFromKeybox - keybox_provisioning_required", [&] { + if (requested_security_level_ != kLevelDefault) return false; + return needs_keybox_provisioning_; + }); + if (keybox_provisioning_required) return NEED_PROVISIONING; + size_t key_data_length = KEYBOX_KEY_DATA_SIZE; + key_data->assign(key_data_length, '\0'); OEMCryptoResult status; WithOecReadLock("GetTokenFromKeybox", [&] { - M_TIME(status = - OEMCrypto_GetKeyData(buf, &buf_size, requested_security_level_), + M_TIME(status = OEMCrypto_GetKeyData( + reinterpret_cast(&key_data->front()), &key_data_length, + requested_security_level), metrics_, oemcrypto_get_key_data_, status, - metrics::Pow2Bucket(buf_size)); + metrics::Pow2Bucket(key_data_length)); }); - if (OEMCrypto_SUCCESS == status) { - token->swap(temp_buffer); + key_data->resize(key_data_length); + return NO_ERROR; } - + key_data->clear(); return MapOEMCryptoResult(status, GET_TOKEN_FROM_KEYBOX_ERROR, "GetTokenFromKeybox"); } -CdmResponseType CryptoSession::GetTokenFromOemCert(std::string* token) { +CdmResponseType CryptoSession::GetTokenFromOemCert( + RequestedSecurityLevel requested_security_level, std::string* oem_cert) { RETURN_IF_UNINITIALIZED(CRYPTO_SESSION_NOT_INITIALIZED); - RETURN_IF_NULL(token, PARAMETER_NULL); + RETURN_IF_NULL(oem_cert, PARAMETER_NULL); + LOGV("requested_security_level = %s", + RequestedSecurityLevelToString(requested_security_level)); - OEMCryptoResult status; - if (!oem_token_.empty()) { - token->assign(oem_token_); - return NO_ERROR; - } + const bool cache_success = + WithOecSessionLock("GetTokenFromOemCert - check cached", [&] { + if (oem_token_.empty()) { + return false; + } + oem_cert->assign(oem_token_); + return true; + }); + if (cache_success) return NO_ERROR; - std::string temp_buffer(CERTIFICATE_DATA_SIZE, '\0'); - bool retrying = false; - while (true) { - size_t buf_size = temp_buffer.size(); - uint8_t* buf = reinterpret_cast(&temp_buffer[0]); - WithOecSessionLock("GetTokenFromOemCert", [&] { - status = OEMCrypto_GetOEMPublicCertificate(buf, &buf_size, - requested_security_level_); + size_t oem_cert_length = CERTIFICATE_DATA_SIZE; + oem_cert->assign(oem_cert_length, '\0'); + OEMCryptoResult status = + WithOecReadLock("GetTokenFromOemCert - attempt 1", [&] { + return OEMCrypto_GetOEMPublicCertificate( + reinterpret_cast(&oem_cert->front()), &oem_cert_length, + requested_security_level); + }); + metrics_->oemcrypto_get_oem_public_certificate_.Increment(status); + if (status == OEMCrypto_ERROR_SHORT_BUFFER) { + oem_cert->assign(oem_cert_length, '\0'); + status = WithOecReadLock("GetTokenFromOemCert - attempt 2", [&] { + return OEMCrypto_GetOEMPublicCertificate( + reinterpret_cast(&oem_cert->front()), &oem_cert_length, + requested_security_level); }); metrics_->oemcrypto_get_oem_public_certificate_.Increment(status); - - if (OEMCrypto_SUCCESS == status) { - temp_buffer.resize(buf_size); - oem_token_.assign(temp_buffer); - token->assign(temp_buffer); - return NO_ERROR; - } - - if (status == OEMCrypto_ERROR_SHORT_BUFFER && !retrying) { - temp_buffer.resize(buf_size); - retrying = true; - continue; - } - - return MapOEMCryptoResult(status, GET_TOKEN_FROM_OEM_CERT_ERROR, - "GetTokenFromOemCert"); } + + if (status == OEMCrypto_SUCCESS) { + oem_cert->resize(oem_cert_length); + WithOecSessionLock("GetTokenFromOemCert - set cache", + [&] { oem_token_ = *oem_cert; }); + return NO_ERROR; + } + oem_cert->clear(); + return MapOEMCryptoResult(status, GET_TOKEN_FROM_OEM_CERT_ERROR, + "GetTokenFromOemCert"); } CdmResponseType CryptoSession::GetProvisioningToken( std::string* token, std::string* additional_token) { + RETURN_IF_NOT_OPEN(CRYPTO_SESSION_NOT_OPEN); + return GetProvisioningToken(requested_security_level_, token, + additional_token); +} + +CdmResponseType CryptoSession::GetProvisioningToken( + RequestedSecurityLevel requested_security_level, std::string* token, + std::string* additional_token) { if (token == nullptr || additional_token == nullptr) { metrics_->crypto_session_get_token_.Increment(PARAMETER_NULL); RETURN_IF_NULL(token, PARAMETER_NULL); RETURN_IF_NULL(additional_token, PARAMETER_NULL); } - if (!IsInitialized()) { metrics_->crypto_session_get_token_.Increment( CRYPTO_SESSION_NOT_INITIALIZED); @@ -603,11 +622,12 @@ CdmResponseType CryptoSession::GetProvisioningToken( CdmResponseType status = UNKNOWN_CLIENT_TOKEN_TYPE; if (pre_provision_token_type_ == kClientTokenKeybox) { - status = GetTokenFromKeybox(token); + status = GetTokenFromKeybox(requested_security_level, token); } else if (pre_provision_token_type_ == kClientTokenOemCert) { - status = GetTokenFromOemCert(token); + status = GetTokenFromOemCert(requested_security_level, token); } else if (pre_provision_token_type_ == kClientTokenBootCertChain) { - status = GetBootCertificateChain(token, additional_token); + status = GetBootCertificateChain(requested_security_level, token, + additional_token); } metrics_->crypto_session_get_token_.Increment(status); return status; @@ -689,7 +709,7 @@ CdmResponseType CryptoSession::GetInternalDeviceUniqueId( if (sts == OEMCrypto_ERROR_NOT_IMPLEMENTED && pre_provision_token_type_ == kClientTokenOemCert) { - return GetTokenFromOemCert(device_id); + return GetTokenFromOemCert(requested_security_level_, device_id); } const bool use_null_device_id = WithStaticFieldReadLock( @@ -772,84 +792,23 @@ bool CryptoSession::GetApiMinorVersion(RequestedSecurityLevel security_level, return true; } -bool CryptoSession::GetSystemId(uint32_t* system_id) { +bool CryptoSession::GetCachedSystemId(uint32_t* system_id) { RETURN_IF_NULL(system_id, false); - RETURN_IF_UNINITIALIZED(false); RETURN_IF_NOT_OPEN(false); + if (system_id_ == NULL_SYSTEM_ID) return false; *system_id = system_id_; return true; } -// This method gets the system id from the keybox key data. -// This method assumes that OEMCrypto has been initialized before making this -// call. -CdmResponseType CryptoSession::GetSystemIdInternal(uint32_t* system_id) { - RETURN_IF_NULL(system_id, PARAMETER_NULL); - - if (pre_provision_token_type_ == kClientTokenKeybox) { - const bool use_null_system_id = WithStaticFieldReadLock( - "GetSystemIdInternal() use_null_system_id", [&] { - // Devices with an invalid L1 keybox which support OTA keybox - // provisioning require a placeholder system ID while waiting for - // keybox. - if (requested_security_level_ != kLevelDefault) return false; - return needs_keybox_provisioning_; - }); - if (use_null_system_id) { - LOGD("Using null system ID"); - *system_id = kNullSystemId; - return NO_ERROR; - } - std::string token; - const CdmResponseType status = GetTokenFromKeybox(&token); - if (status != NO_ERROR) return status; - if (token.size() < 2 * sizeof(uint32_t)) { - LOGE("Keybox token size too small: token_size = %zu", token.size()); - return KEYBOX_TOKEN_TOO_SHORT; - } - - // Decode 32-bit int encoded as network-byte-order byte array starting at - // index 4. - const uint32_t* id = reinterpret_cast(&token[4]); - *system_id = ntohl(*id); - return NO_ERROR; - } - if (pre_provision_token_type_ == kClientTokenOemCert) { - // Get the OEM Cert - std::string oem_cert; - CdmResponseType status = GetTokenFromOemCert(&oem_cert); - - if (status != NO_ERROR) return status; - - if (!ExtractSystemIdFromOemCert(oem_cert, system_id)) - return EXTRACT_SYSTEM_ID_FROM_OEM_CERT_ERROR; - - return NO_ERROR; - } - if (pre_provision_token_type_ == kClientTokenDrmCert) { - // TODO(blueeyes): Support loading the system id from a pre-provisioned - // Drm certificate. - return NO_ERROR; - } - if (pre_provision_token_type_ == kClientTokenBootCertChain) { - // A system id can not be inferred from BCC. If the provisioning process has - // come to the second stage, we may read system id from the stored OEM cert. - return NO_ERROR; - } - LOGE("Unsupported pre-provision token type: %d", - static_cast(pre_provision_token_type_)); - return UNKNOWN_CLIENT_TOKEN_TYPE; -} - -bool CryptoSession::ExtractSystemIdFromOemCert(const std::string& oem_cert, - uint32_t* system_id) { - return ExtractExtensionValueFromCertificate( - oem_cert, kWidevineSystemIdExtensionOid, /* cert_index */ 1, system_id); +void CryptoSession::SetSystemId(uint32_t system_id) { + if (!IsOpen()) return; // Ignore silently. + system_id_ = system_id; + metrics_->crypto_session_system_id_.Record(system_id_); } CdmResponseType CryptoSession::GetProvisioningId(std::string* provisioning_id) { RETURN_IF_NULL(provisioning_id, PARAMETER_NULL); - RETURN_IF_UNINITIALIZED(CRYPTO_SESSION_NOT_INITIALIZED); + RETURN_IF_NOT_OPEN(CRYPTO_SESSION_NOT_OPEN); if (pre_provision_token_type_ == kClientTokenOemCert) { // OEM Cert devices have no provisioning-unique ID embedded in them, so we @@ -868,7 +827,8 @@ CdmResponseType CryptoSession::GetProvisioningId(std::string* provisioning_id) { } if (pre_provision_token_type_ == kClientTokenKeybox) { std::string token; - CdmResponseType status = GetTokenFromKeybox(&token); + CdmResponseType status = + GetTokenFromKeybox(requested_security_level_, &token); if (status != NO_ERROR) return status; @@ -940,16 +900,6 @@ CdmResponseType CryptoSession::Open( LOGV("Opened session: id = %u", oec_session_id_); open_ = true; - // Get System ID and save it. - result = GetSystemIdInternal(&system_id_); - if (result == NO_ERROR) { - metrics_->crypto_session_system_id_.Record(system_id_); - } else { - LOGE("Failed to fetch system ID"); - metrics_->crypto_session_system_id_.SetError(result); - return result; - } - // Set up request ID uint64_t request_id_base; OEMCryptoResult random_sts; @@ -989,6 +939,8 @@ void CryptoSession::Close() { // Clear cached values. has_usage_info_support_ = kBooleanUnset; oem_token_.clear(); + system_id_ = NULL_SYSTEM_ID; + pre_provision_token_type_ = kClientTokenUninitialized; if (close_sts != OEMCrypto_SUCCESS) { LOGW("OEMCrypto_CloseSession failed: status = %d", @@ -1412,13 +1364,26 @@ CdmResponseType CryptoSession::LoadCertificatePrivateKey( CdmResponseType CryptoSession::GetBootCertificateChain( std::string* bcc, std::string* additional_signature) { + RETURN_IF_NOT_OPEN(CRYPTO_SESSION_NOT_OPEN); + return GetBootCertificateChain(requested_security_level_, bcc, + additional_signature); +} + +CdmResponseType CryptoSession::GetBootCertificateChain( + RequestedSecurityLevel requested_security_level, std::string* bcc, + std::string* additional_signature) { RETURN_IF_NULL(bcc, PARAMETER_NULL); RETURN_IF_NULL(additional_signature, PARAMETER_NULL); RETURN_IF_UNINITIALIZED(CRYPTO_SESSION_NOT_INITIALIZED); - LOGV("GetBootCertificateChain"); + LOGV("requested_security_level = %s", + RequestedSecurityLevelToString(requested_security_level)); if (pre_provision_token_type_ != kClientTokenBootCertChain) { return PROVISIONING_TYPE_IS_NOT_BOOT_CERTIFICATE_CHAIN_ERROR; } + if (requested_security_level != kLevelDefault) { + LOGE("CDM only supports L1 BCC"); + return NOT_IMPLEMENTED_ERROR; + } size_t bcc_length = 0; size_t additional_signature_length = 0; @@ -3346,12 +3311,6 @@ CdmResponseType CryptoSession::LoadOtaProvisioning( WithOecWriteLock("LoadOtaProvisioning", [&] { needs_keybox_provisioning_ = false; }); } - CdmResponseType result = GetSystemIdInternal(&system_id_); - if (result == NO_ERROR) { - LOGD("New system id is %d", system_id_); - } else { - LOGE("Failed to fetch system ID"); - } return MapOEMCryptoResult(status, UNKNOWN_ERROR, "LoadOtaProvisioning"); } diff --git a/libwvdrmengine/cdm/core/src/system_id_extractor.cpp b/libwvdrmengine/cdm/core/src/system_id_extractor.cpp new file mode 100644 index 00000000..85d0859f --- /dev/null +++ b/libwvdrmengine/cdm/core/src/system_id_extractor.cpp @@ -0,0 +1,190 @@ +// Copyright 2022 Google LLC. All Rights Reserved. This file and proprietary +// source code may only be used and distributed under the Widevine License +// Agreement. +#include "system_id_extractor.h" + +#include + +#include "crypto_session.h" +#include "device_files.h" +#include "privacy_crypto.h" +#include "wv_cdm_constants.h" +#include "wv_cdm_types.h" + +namespace wvcdm { +namespace { +// Offset within the keybox data where the device ID is stored. +constexpr size_t kKeyboxSystemIdOffset = 4; +// Index of certificate within cerificate chain which contains the +// system ID (0 = leaf/device cert, 1 = intermediate/device family cert). +constexpr size_t kOemCertSystemIdIndex = 1; +// OID of X.509 certificate extension containing the Widevine system ID. +const std::string kWidevineSystemIdExtensionOid = "1.3.6.1.4.1.11129.4.1.1"; + +constexpr size_t kSystemIdLength = sizeof(uint32_t); + +constexpr bool IsSupportedSecurityLevel(CdmSecurityLevel security_level) { + return security_level == kSecurityLevelL1 || + security_level == kSecurityLevelL2 || + security_level == kSecurityLevelL3; +} +} // namespace + +SystemIdExtractor::SystemIdExtractor(RequestedSecurityLevel security_level, + CryptoSession* crypto_session, + wvutil::FileSystem* fs) + : security_level_(security_level), + crypto_session_(crypto_session), + fs_(fs) { + assert(crypto_session != nullptr); + assert(fs != nullptr); +} + +bool SystemIdExtractor::ExtractSystemId(uint32_t* system_id) { + if (system_id == nullptr) { + LOGE("Output |system_id| is null"); + return false; + } + if (crypto_session_->GetCachedSystemId(system_id)) { + return true; + } + CdmClientTokenType type = kClientTokenUninitialized; + const CdmResponseType status = + crypto_session_->GetProvisioningMethod(security_level_, &type); + if (status != NO_ERROR) { + LOGE("Failed to get provisioning method: security_level = %s, status = %d", + RequestedSecurityLevelToString(security_level_), + static_cast(status)); + return false; + } + bool success = false; + switch (type) { + case kClientTokenDrmCert: + LOGE("Cannot get a system ID from a DRM certificate"); + return false; + case kClientTokenKeybox: + success = ExtractSystemIdProv20(system_id); + break; + case kClientTokenOemCert: + success = ExtractSystemIdProv30(system_id); + break; + case kClientTokenBootCertChain: + success = ExtractSystemIdProv40(system_id); + break; + case kClientTokenUninitialized: + default: + LOGE("Unexpected token type: %d", type); + return false; + } + if (success && *system_id != NULL_SYSTEM_ID) { + crypto_session_->SetSystemId(*system_id); + } + return success; +} + +// static +bool SystemIdExtractor::ExtractSystemIdFromKeyboxData( + const std::string& key_data, uint32_t* system_id) { + if (system_id == nullptr) return false; + if (key_data.size() < (kKeyboxSystemIdOffset + kSystemIdLength)) { + LOGE("Keybox data does not contain system ID: key_data_size = %zu", + key_data.size()); + return false; + } + uint32_t system_id_nbo = 0; + memcpy(&system_id_nbo, &key_data[kKeyboxSystemIdOffset], + sizeof(system_id_nbo)); + *system_id = ntohl(system_id_nbo); + return true; +} + +// static +bool SystemIdExtractor::ExtractSystemIdFromOemCert(const std::string& oem_cert, + uint32_t* system_id) { + if (system_id == nullptr) return false; + return ExtractExtensionValueFromCertificate(oem_cert, + kWidevineSystemIdExtensionOid, + kOemCertSystemIdIndex, system_id); +} + +bool SystemIdExtractor::ExtractSystemIdProv20(uint32_t* system_id) { + std::string key_data; + const CdmResponseType status = + crypto_session_->GetTokenFromKeybox(security_level_, &key_data); + if (status == NEED_PROVISIONING) { + LOGD("Keybox provisioning required, using null system ID"); + *system_id = NULL_SYSTEM_ID; + return true; + } + if (status != NO_ERROR) { + LOGE("Failed to get keybox data: security_level = %s, status = %d", + RequestedSecurityLevelToString(security_level_), + static_cast(status)); + return false; + } + if (!ExtractSystemIdFromKeyboxData(key_data, system_id)) { + LOGE("Failed to extract system ID from keybox data"); + return false; + } + return true; +} + +bool SystemIdExtractor::ExtractSystemIdProv30(uint32_t* system_id) { + std::string oem_cert; + const CdmResponseType status = + crypto_session_->GetTokenFromOemCert(security_level_, &oem_cert); + if (status != NO_ERROR) { + LOGE("Failed to get OEM certificate: security_level = %s, status = %d", + RequestedSecurityLevelToString(security_level_), + static_cast(status)); + return false; + } + if (!ExtractSystemIdFromOemCert(oem_cert, system_id)) { + LOGE("Failed to extract system ID from OEM certificate"); + return false; + } + return true; +} + +bool SystemIdExtractor::ExtractSystemIdProv40(uint32_t* system_id) { + const CdmSecurityLevel security_level = + crypto_session_->GetSecurityLevel(security_level_); + if (!IsSupportedSecurityLevel(security_level)) { + LOGE("Unsupported security level: %s", + CdmSecurityLevelToString(security_level)); + return false; + } + DeviceFiles real_device_files(fs_); + // Mock DeviceFiles for testing. + DeviceFiles& device_files = + (test_device_files_ ? *test_device_files_ : real_device_files); + if (!device_files.Init(security_level)) { + LOGE("Failed to initialize device files: security_level = %s", + CdmSecurityLevelToString(security_level)); + return false; + } + std::string oem_cert; + CryptoWrappedKey wrapped_private_key_unused; + const DeviceFiles::CertificateState cert_state = + device_files.RetrieveOemCertificate(&oem_cert, + &wrapped_private_key_unused); + if (cert_state == DeviceFiles::kCertificateNotFound) { + LOGD("No OEM certificate available, using null system ID"); + *system_id = NULL_SYSTEM_ID; + return true; + } + if (cert_state != DeviceFiles::kCertificateValid) { + LOGE( + "Failed to retrieve OEM certificate: " + "security_level = %s, cert_state = %s", + CdmSecurityLevelToString(security_level), + DeviceFiles::CertificateStateToString(cert_state)); + return false; + } + if (!ExtractSystemIdFromOemCert(oem_cert, system_id)) { + LOGE("Failed to extract system ID from OEM certificate"); + return false; + } + return true; +} +} // namespace wvcdm diff --git a/libwvdrmengine/cdm/core/test/crypto_session_unittest.cpp b/libwvdrmengine/cdm/core/test/crypto_session_unittest.cpp index a3ead761..a49a39e1 100644 --- a/libwvdrmengine/cdm/core/test/crypto_session_unittest.cpp +++ b/libwvdrmengine/cdm/core/test/crypto_session_unittest.cpp @@ -24,233 +24,9 @@ using ::testing::AllOf; using ::testing::Ge; using ::testing::Le; -namespace { -const uint8_t kOemCert[] = { - 0x30, 0x82, 0x09, 0xf7, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, - 0x01, 0x07, 0x02, 0xa0, 0x82, 0x09, 0xe8, 0x30, 0x82, 0x09, 0xe4, 0x02, - 0x01, 0x01, 0x31, 0x00, 0x30, 0x0f, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, - 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x02, 0x04, 0x00, 0xa0, 0x82, 0x09, - 0xc8, 0x30, 0x82, 0x04, 0x1a, 0x30, 0x82, 0x03, 0x02, 0xa0, 0x03, 0x02, - 0x01, 0x02, 0x02, 0x11, 0x00, 0xf2, 0xa1, 0x08, 0xdf, 0x12, 0x84, 0xb9, - 0x73, 0x6c, 0x23, 0x73, 0xe1, 0x1f, 0xf3, 0xac, 0x7a, 0x30, 0x0d, 0x06, - 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, - 0x30, 0x81, 0x8b, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, - 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, - 0x08, 0x0c, 0x0a, 0x57, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x74, 0x6f, - 0x6e, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x08, - 0x4b, 0x69, 0x72, 0x6b, 0x6c, 0x61, 0x6e, 0x64, 0x31, 0x0f, 0x30, 0x0d, - 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x06, 0x47, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x08, - 0x57, 0x69, 0x64, 0x65, 0x76, 0x69, 0x6e, 0x65, 0x31, 0x30, 0x30, 0x2e, - 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x27, 0x47, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x20, 0x4f, 0x45, 0x4d, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x44, - 0x65, 0x76, 0x69, 0x63, 0x65, 0x3b, 0x20, 0x73, 0x79, 0x73, 0x74, 0x65, - 0x6d, 0x20, 0x69, 0x64, 0x3a, 0x20, 0x37, 0x33, 0x34, 0x36, 0x30, 0x1e, - 0x17, 0x0d, 0x31, 0x37, 0x30, 0x33, 0x31, 0x33, 0x30, 0x30, 0x30, 0x30, - 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x31, 0x39, 0x31, 0x32, 0x30, 0x38, 0x30, - 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x6d, 0x31, 0x12, 0x30, 0x10, - 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x09, 0x37, 0x33, 0x34, 0x36, 0x2d, - 0x6c, 0x65, 0x61, 0x66, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, - 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, - 0x04, 0x08, 0x0c, 0x0a, 0x57, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x74, - 0x6f, 0x6e, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, - 0x08, 0x4b, 0x69, 0x72, 0x6b, 0x6c, 0x61, 0x6e, 0x64, 0x31, 0x0f, 0x30, - 0x0d, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x06, 0x47, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, - 0x08, 0x57, 0x69, 0x64, 0x65, 0x76, 0x69, 0x6e, 0x65, 0x30, 0x82, 0x01, - 0xa2, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, - 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x8f, 0x00, 0x30, 0x82, 0x01, - 0x8a, 0x02, 0x82, 0x01, 0x81, 0x00, 0xf5, 0x09, 0x64, 0x4a, 0x26, 0xfe, - 0xc0, 0x98, 0x55, 0x6a, 0x1d, 0x5d, 0x1c, 0xc7, 0x38, 0xaf, 0xfd, 0x49, - 0x9e, 0x85, 0x3f, 0xd6, 0x45, 0x0e, 0x99, 0x09, 0x85, 0x69, 0x84, 0x3c, - 0xfe, 0x72, 0xa5, 0x56, 0xfa, 0x11, 0x4f, 0x6b, 0x7d, 0x32, 0x2b, 0x0c, - 0xbf, 0x8f, 0xac, 0x47, 0x96, 0x22, 0x82, 0x3d, 0xf5, 0x64, 0x74, 0x7e, - 0x62, 0x68, 0x74, 0xcd, 0x0a, 0xec, 0x84, 0xc5, 0x15, 0x06, 0x0e, 0x5a, - 0x2f, 0x20, 0xe3, 0xc9, 0x67, 0xcd, 0xdd, 0x01, 0xb8, 0xb3, 0x18, 0x87, - 0x8c, 0xa9, 0x58, 0x86, 0x0f, 0xb6, 0xc3, 0x42, 0x7e, 0x87, 0x48, 0x5e, - 0x10, 0x49, 0xc7, 0xd7, 0xb7, 0xb8, 0xa6, 0x34, 0x08, 0x0c, 0x94, 0xf4, - 0xbb, 0x2a, 0x06, 0xa4, 0x4f, 0xec, 0xbc, 0xc4, 0x37, 0xbe, 0x99, 0x10, - 0x23, 0x37, 0x24, 0xb1, 0xdf, 0xcb, 0xe6, 0x3f, 0xc1, 0xf0, 0x0f, 0x04, - 0x03, 0xc8, 0xb0, 0x1e, 0xd6, 0xb8, 0xae, 0x77, 0xe1, 0x4d, 0x6d, 0x97, - 0x69, 0x6d, 0x8a, 0x73, 0x66, 0x32, 0x57, 0x6f, 0xcf, 0xea, 0x1e, 0x7b, - 0x87, 0x03, 0x75, 0xb1, 0xef, 0x83, 0x64, 0x26, 0xf1, 0x3f, 0xbf, 0xe6, - 0x28, 0x03, 0x72, 0x57, 0xbf, 0x47, 0x29, 0x99, 0x8f, 0x74, 0x1d, 0x01, - 0x16, 0xad, 0xb2, 0xdf, 0x80, 0xa4, 0xd3, 0x8b, 0xeb, 0x61, 0xd1, 0x40, - 0x68, 0xb9, 0xa2, 0xa5, 0xef, 0x2b, 0xe5, 0x78, 0xe8, 0x28, 0x88, 0x87, - 0xb7, 0x53, 0x49, 0xbb, 0xe4, 0xea, 0x0d, 0x5e, 0x96, 0xa5, 0xdd, 0x1f, - 0x0b, 0x25, 0x8b, 0xb5, 0x95, 0x46, 0xe7, 0xba, 0xb8, 0xc4, 0x0a, 0x36, - 0xb1, 0x89, 0xeb, 0x27, 0x5d, 0xd9, 0x97, 0x24, 0x59, 0xa3, 0x9b, 0xb0, - 0x23, 0x0b, 0xd2, 0xec, 0x65, 0x91, 0xf9, 0xf0, 0xa0, 0x74, 0x5f, 0xb4, - 0xce, 0x22, 0x27, 0x18, 0x37, 0xe2, 0x4b, 0xfc, 0x91, 0xf9, 0x09, 0x15, - 0xe6, 0xdb, 0x06, 0x9b, 0x4d, 0x82, 0xdc, 0x36, 0x14, 0x48, 0xc6, 0xd5, - 0x87, 0xca, 0xec, 0x5a, 0xa2, 0x29, 0x33, 0xef, 0x22, 0x0c, 0x4b, 0xbf, - 0xe7, 0x2f, 0x95, 0xe1, 0xd3, 0xa5, 0xd8, 0xaa, 0x44, 0x77, 0x29, 0xa3, - 0x20, 0x33, 0xd2, 0x51, 0xa2, 0xf9, 0x4a, 0x6f, 0xf7, 0x3e, 0xf7, 0x0b, - 0x8a, 0xec, 0xc1, 0x99, 0x1d, 0x47, 0xf3, 0x74, 0x02, 0x04, 0xab, 0x8e, - 0x62, 0x4c, 0x9e, 0x00, 0xc2, 0x84, 0xd7, 0xd0, 0xf8, 0xe4, 0x1c, 0x9d, - 0x98, 0x15, 0xa8, 0x8f, 0x08, 0x98, 0x4e, 0x5a, 0xfa, 0xd6, 0x60, 0x87, - 0x12, 0xdc, 0x8e, 0xfd, 0xcb, 0xb3, 0x13, 0x97, 0x7a, 0xa8, 0x8c, 0x56, - 0x2e, 0x49, 0x26, 0x60, 0xe9, 0x4a, 0xdc, 0xec, 0x3f, 0xf0, 0x94, 0xcd, - 0x90, 0x8e, 0x7c, 0x21, 0x3f, 0x80, 0x14, 0x33, 0xdd, 0xb0, 0x00, 0xe2, - 0x09, 0x37, 0x06, 0xdd, 0x17, 0x69, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, - 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, - 0xd6, 0x79, 0x04, 0x01, 0x01, 0x04, 0x04, 0x02, 0x02, 0x1c, 0xb2, 0x30, - 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, - 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x8e, 0x2d, 0x13, 0x1e, 0x60, - 0xaa, 0xda, 0x52, 0x53, 0x55, 0x64, 0x3a, 0xdc, 0xb6, 0x7a, 0xc0, 0xba, - 0xfa, 0xeb, 0x20, 0xab, 0xb6, 0x63, 0xcf, 0xcd, 0x9b, 0xdb, 0x71, 0xf3, - 0xa0, 0xd6, 0x91, 0xbf, 0x0c, 0xc1, 0xae, 0x8f, 0x02, 0x18, 0x00, 0x54, - 0xfb, 0x49, 0x03, 0x34, 0x8d, 0x92, 0x9d, 0x5d, 0x8d, 0xa8, 0x1c, 0x20, - 0x0f, 0x85, 0x60, 0xf9, 0xf6, 0x8b, 0xbb, 0x2b, 0x82, 0xce, 0xb3, 0xe2, - 0x91, 0xe7, 0xbd, 0x91, 0x61, 0x52, 0x36, 0x40, 0x9f, 0x2f, 0x5e, 0xa6, - 0x5d, 0x2f, 0xb3, 0x81, 0xe7, 0xf1, 0x87, 0xbe, 0xc5, 0x9d, 0x67, 0x5a, - 0xf7, 0x41, 0x1e, 0x73, 0xb0, 0x1e, 0xdc, 0x4f, 0x8d, 0x53, 0x21, 0x38, - 0x1b, 0xfd, 0x92, 0x43, 0x68, 0x83, 0x03, 0xd0, 0x9a, 0xca, 0x92, 0x14, - 0x73, 0x04, 0x94, 0x2a, 0x93, 0x22, 0x60, 0x5e, 0xee, 0xb6, 0xec, 0x0f, - 0xb0, 0xc8, 0x92, 0x97, 0xfb, 0x5d, 0xed, 0x1f, 0xa0, 0x5f, 0xe4, 0x98, - 0x2f, 0xf6, 0x13, 0x78, 0x99, 0xec, 0xb3, 0xf1, 0x0d, 0x27, 0xaa, 0x19, - 0x95, 0x39, 0xdb, 0xb0, 0x7b, 0x96, 0x74, 0x03, 0x5e, 0x51, 0xf5, 0x15, - 0x27, 0xce, 0xca, 0x0b, 0x2a, 0x0d, 0x43, 0xb3, 0x68, 0x17, 0x1e, 0x11, - 0x60, 0xd9, 0x84, 0x9b, 0xc3, 0x53, 0xce, 0xbd, 0xf4, 0x61, 0x51, 0x4b, - 0x41, 0x00, 0x7e, 0xe1, 0x5f, 0x69, 0xb3, 0x4a, 0x89, 0x7e, 0x47, 0x67, - 0xfd, 0x76, 0xf8, 0x94, 0x2f, 0x72, 0xb6, 0x14, 0x08, 0x2c, 0x16, 0x4e, - 0x9d, 0x37, 0x62, 0xbf, 0x11, 0x67, 0xc0, 0x70, 0x71, 0xec, 0x55, 0x51, - 0x4e, 0x46, 0x76, 0xb4, 0xc3, 0xeb, 0x52, 0x06, 0x17, 0x06, 0xce, 0x61, - 0x43, 0xce, 0x26, 0x80, 0x68, 0xb6, 0x2d, 0x57, 0xba, 0x8c, 0x7d, 0xb7, - 0xc5, 0x05, 0x2c, 0xf8, 0xa3, 0x69, 0xf8, 0x96, 0xad, 0xac, 0xd1, 0x30, - 0x82, 0x05, 0xa6, 0x30, 0x82, 0x03, 0x8e, 0xa0, 0x03, 0x02, 0x01, 0x02, - 0x02, 0x10, 0x73, 0xd1, 0xe1, 0x1d, 0xa9, 0x75, 0xfd, 0x0c, 0xda, 0x7f, - 0xfa, 0x43, 0x3c, 0x26, 0xbd, 0x3d, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, - 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x7e, 0x31, - 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, - 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a, 0x57, - 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x74, 0x6f, 0x6e, 0x31, 0x11, 0x30, - 0x0f, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x08, 0x4b, 0x69, 0x72, 0x6b, - 0x6c, 0x61, 0x6e, 0x64, 0x31, 0x0f, 0x30, 0x0d, 0x06, 0x03, 0x55, 0x04, - 0x0a, 0x0c, 0x06, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x31, 0x11, 0x30, - 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x08, 0x57, 0x69, 0x64, 0x65, - 0x76, 0x69, 0x6e, 0x65, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, - 0x03, 0x0c, 0x1a, 0x77, 0x69, 0x64, 0x65, 0x76, 0x69, 0x6e, 0x65, 0x2e, - 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x65, 0x6d, 0x2d, 0x72, 0x6f, 0x6f, 0x74, - 0x2d, 0x70, 0x72, 0x6f, 0x64, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x37, 0x30, - 0x33, 0x31, 0x34, 0x30, 0x33, 0x30, 0x32, 0x34, 0x31, 0x5a, 0x17, 0x0d, - 0x32, 0x37, 0x30, 0x33, 0x31, 0x34, 0x30, 0x33, 0x30, 0x32, 0x34, 0x31, - 0x5a, 0x30, 0x81, 0x8b, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, - 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, - 0x04, 0x08, 0x0c, 0x0a, 0x57, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x74, - 0x6f, 0x6e, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, - 0x08, 0x4b, 0x69, 0x72, 0x6b, 0x6c, 0x61, 0x6e, 0x64, 0x31, 0x0f, 0x30, - 0x0d, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x06, 0x47, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, - 0x08, 0x57, 0x69, 0x64, 0x65, 0x76, 0x69, 0x6e, 0x65, 0x31, 0x30, 0x30, - 0x2e, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x27, 0x47, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x20, 0x4f, 0x45, 0x4d, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, - 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x3b, 0x20, 0x73, 0x79, 0x73, 0x74, - 0x65, 0x6d, 0x20, 0x69, 0x64, 0x3a, 0x20, 0x37, 0x33, 0x34, 0x36, 0x30, - 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, - 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, - 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xa5, 0x45, 0x13, 0xf2, - 0xb2, 0xcb, 0x4b, 0x0f, 0xb4, 0x44, 0x25, 0x9c, 0x8a, 0x68, 0x54, 0xd5, - 0x45, 0x1e, 0x15, 0x89, 0x5b, 0xb8, 0xce, 0xda, 0x5a, 0x42, 0xe6, 0x9a, - 0x8c, 0xc1, 0xcb, 0xe8, 0xc5, 0xf5, 0x8f, 0x49, 0x0e, 0x02, 0xef, 0x5e, - 0x97, 0x1a, 0x91, 0xa4, 0x94, 0xc3, 0x50, 0x13, 0xe5, 0x13, 0xb7, 0x7f, - 0x26, 0x53, 0x19, 0xb0, 0x37, 0xa5, 0xef, 0xe6, 0x2a, 0x39, 0xdc, 0x93, - 0x37, 0xe2, 0x3d, 0x7f, 0xcb, 0x4b, 0x93, 0xa2, 0xc3, 0x69, 0x78, 0xc9, - 0x01, 0xfa, 0x68, 0x3b, 0xe0, 0xe2, 0x22, 0x6c, 0xeb, 0xe4, 0x8a, 0xa8, - 0x3e, 0xf5, 0x20, 0x82, 0xa8, 0x62, 0x68, 0x59, 0x78, 0x24, 0xde, 0xef, - 0x47, 0x43, 0xb1, 0x6c, 0x38, 0x29, 0xd3, 0x69, 0x3f, 0xae, 0x35, 0x57, - 0x75, 0x80, 0xc9, 0x21, 0xe7, 0x01, 0xb9, 0x54, 0x8b, 0x6e, 0x4e, 0x2e, - 0x5a, 0x5b, 0x77, 0xa4, 0x22, 0xc2, 0x7b, 0x95, 0xb9, 0x39, 0x2c, 0xbd, - 0xc2, 0x1e, 0x02, 0xa6, 0xb2, 0xbc, 0x0f, 0x7a, 0xcb, 0xdc, 0xbc, 0xbc, - 0x90, 0x66, 0xe3, 0xca, 0x46, 0x53, 0x3e, 0x98, 0xff, 0x2e, 0x78, 0x9f, - 0xd3, 0xa1, 0x12, 0x93, 0x66, 0x7d, 0xcc, 0x94, 0x6b, 0xec, 0x19, 0x0e, - 0x20, 0x45, 0x22, 0x57, 0x6d, 0x9e, 0xd0, 0x89, 0xf2, 0xa9, 0x34, 0xdc, - 0xab, 0xa5, 0x73, 0x47, 0x38, 0xe3, 0x7f, 0x98, 0x3a, 0x61, 0xae, 0x6c, - 0x4d, 0xf2, 0x31, 0x90, 0xcb, 0x83, 0xc1, 0xee, 0xb4, 0xf2, 0x9a, 0x28, - 0x5f, 0xbb, 0x7d, 0x89, 0xdf, 0xa2, 0x31, 0xb6, 0x1d, 0x39, 0x2b, 0x70, - 0xbf, 0x1e, 0xad, 0xe1, 0x74, 0x94, 0x1d, 0xf8, 0xc5, 0x1a, 0x8d, 0x13, - 0x45, 0xf0, 0x6a, 0x80, 0x0c, 0x5d, 0xbb, 0x46, 0x8a, 0x43, 0xd0, 0xff, - 0x21, 0x39, 0x57, 0x53, 0x5b, 0x51, 0xf8, 0xa2, 0x8f, 0x7f, 0x27, 0xc7, - 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x10, 0x30, 0x82, 0x01, - 0x0c, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, - 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x0e, 0x06, - 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x02, - 0x04, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, - 0xe8, 0xe9, 0xac, 0x16, 0x5c, 0x5e, 0xb2, 0xe8, 0xeb, 0xff, 0x57, 0x27, - 0x20, 0x08, 0x72, 0x63, 0x9b, 0xe5, 0xb5, 0x16, 0x30, 0x81, 0xb2, 0x06, - 0x03, 0x55, 0x1d, 0x23, 0x04, 0x81, 0xaa, 0x30, 0x81, 0xa7, 0x80, 0x14, - 0x04, 0x94, 0x66, 0xaa, 0xf9, 0x61, 0x89, 0xb6, 0xdb, 0xb5, 0xf7, 0x13, - 0x38, 0x3d, 0x62, 0x84, 0xb8, 0x18, 0x0a, 0x8f, 0xa1, 0x81, 0x83, 0xa4, - 0x81, 0x80, 0x30, 0x7e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, - 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, - 0x04, 0x08, 0x0c, 0x0a, 0x57, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x74, - 0x6f, 0x6e, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, - 0x08, 0x4b, 0x69, 0x72, 0x6b, 0x6c, 0x61, 0x6e, 0x64, 0x31, 0x0f, 0x30, - 0x0d, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x06, 0x47, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, - 0x08, 0x57, 0x69, 0x64, 0x65, 0x76, 0x69, 0x6e, 0x65, 0x31, 0x23, 0x30, - 0x21, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x1a, 0x77, 0x69, 0x64, 0x65, - 0x76, 0x69, 0x6e, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x65, 0x6d, - 0x2d, 0x72, 0x6f, 0x6f, 0x74, 0x2d, 0x70, 0x72, 0x6f, 0x64, 0x82, 0x09, - 0x00, 0xdf, 0x86, 0x05, 0x31, 0x01, 0xbe, 0x9a, 0x9a, 0x30, 0x12, 0x06, - 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0xd6, 0x79, 0x04, 0x01, 0x01, 0x04, - 0x04, 0x02, 0x02, 0x1c, 0xb2, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, - 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x02, 0x01, - 0x00, 0x25, 0xce, 0xd2, 0x02, 0x48, 0xbb, 0xbe, 0xfc, 0xb6, 0xa4, 0x87, - 0x87, 0xe0, 0x21, 0x7d, 0xfa, 0x23, 0xc3, 0x0d, 0x73, 0x8f, 0x46, 0xe7, - 0x09, 0x59, 0xda, 0x2e, 0x55, 0x59, 0xff, 0x3c, 0x1b, 0xf6, 0xf8, 0x9a, - 0xc4, 0x1c, 0xf7, 0xac, 0xca, 0xe7, 0x63, 0xf2, 0xc7, 0xd6, 0x0c, 0x2d, - 0xa6, 0xad, 0x55, 0xf4, 0x10, 0x0e, 0xa8, 0x82, 0x0f, 0x88, 0xb5, 0x44, - 0xe8, 0x8e, 0x84, 0x08, 0xf7, 0xdd, 0xe7, 0x10, 0xce, 0x71, 0x56, 0x57, - 0x3f, 0xed, 0x48, 0xee, 0xe2, 0x5d, 0x08, 0x0a, 0x58, 0xe4, 0xfe, 0xbc, - 0x8c, 0x27, 0x1a, 0x46, 0x3f, 0xd5, 0x2d, 0xdb, 0x0b, 0x71, 0x73, 0xd1, - 0x49, 0xf3, 0x5c, 0x86, 0x4d, 0x0a, 0xe1, 0xeb, 0x53, 0x21, 0x38, 0x4f, - 0xec, 0x1e, 0xc2, 0x68, 0x1f, 0x7d, 0xa6, 0x33, 0xe9, 0xa5, 0x37, 0x2a, - 0xef, 0xcd, 0x78, 0x56, 0xb3, 0x39, 0x60, 0xf4, 0xa5, 0xf9, 0x2b, 0x85, - 0xcf, 0xe6, 0x1c, 0x7c, 0x8a, 0x5d, 0xe8, 0x26, 0x02, 0xcf, 0x7a, 0x56, - 0x1f, 0xae, 0x0d, 0x71, 0x20, 0xee, 0xec, 0x3b, 0xae, 0x95, 0x25, 0x15, - 0xc8, 0xf6, 0x92, 0x5d, 0xb8, 0x9b, 0xc2, 0xb4, 0x95, 0x33, 0x13, 0x76, - 0x45, 0xbe, 0x21, 0xe2, 0x3a, 0x69, 0x66, 0xd7, 0xff, 0x22, 0x00, 0x89, - 0xc9, 0x44, 0xb6, 0x54, 0x38, 0x1f, 0x33, 0xe4, 0xda, 0x7b, 0x87, 0xf3, - 0x23, 0xed, 0xf5, 0x16, 0x08, 0xbe, 0x4b, 0xea, 0x91, 0x8f, 0x91, 0x8b, - 0x4e, 0xd1, 0x02, 0x06, 0xa2, 0x77, 0x15, 0x03, 0x46, 0x11, 0x7d, 0x5b, - 0xea, 0x7a, 0xf6, 0x86, 0x7d, 0x96, 0xb7, 0x73, 0x9b, 0x5b, 0x32, 0xc3, - 0xf8, 0x92, 0x36, 0xe3, 0xe3, 0x2f, 0xe8, 0xf1, 0x72, 0xec, 0x0d, 0x50, - 0xd4, 0x86, 0xc5, 0x62, 0x83, 0xf1, 0x2a, 0x4c, 0xd1, 0xbf, 0x76, 0x62, - 0xd4, 0x21, 0x11, 0x68, 0xb2, 0xd6, 0x8d, 0xc4, 0xf8, 0xe4, 0x70, 0x85, - 0x19, 0xa7, 0x82, 0x27, 0x2c, 0x24, 0x21, 0x7a, 0x3b, 0xad, 0x8a, 0xd3, - 0xae, 0xda, 0x78, 0x3c, 0x6c, 0xab, 0xa2, 0xaa, 0x36, 0xf0, 0x1c, 0x58, - 0xd4, 0x72, 0x5e, 0xe8, 0x8b, 0x41, 0x08, 0xf5, 0x85, 0xdd, 0xee, 0x99, - 0x12, 0xf4, 0xd6, 0x41, 0x83, 0x69, 0xe7, 0x79, 0x19, 0xa3, 0x74, 0xc4, - 0x34, 0x2a, 0x8a, 0x7e, 0x4d, 0xbb, 0x2c, 0x49, 0x19, 0xf7, 0x98, 0x98, - 0xfc, 0x81, 0xf7, 0x9b, 0x7f, 0xff, 0xd9, 0x66, 0xf4, 0x51, 0x14, 0x29, - 0x2a, 0x14, 0x1d, 0x4f, 0xbd, 0x91, 0xba, 0x6f, 0x32, 0x34, 0x3c, 0x40, - 0x28, 0x6c, 0x97, 0xf8, 0x6d, 0x38, 0xcd, 0xa3, 0x7b, 0x18, 0xc8, 0x77, - 0x58, 0x4d, 0x53, 0x30, 0x7f, 0x4d, 0x89, 0xca, 0x95, 0x6e, 0xb5, 0xb8, - 0x8e, 0xc8, 0x2d, 0x18, 0x2f, 0x52, 0x2a, 0xde, 0xac, 0x56, 0x8d, 0x8c, - 0x67, 0x14, 0xf6, 0xb9, 0xf1, 0x65, 0xd3, 0x22, 0x43, 0xa3, 0x98, 0x42, - 0x20, 0x43, 0x4c, 0xdf, 0xf2, 0xeb, 0x31, 0x8c, 0x0e, 0x53, 0x5b, 0x99, - 0x82, 0xc3, 0x48, 0x04, 0x53, 0xad, 0x96, 0xb6, 0x9f, 0x52, 0xcc, 0x01, - 0xc8, 0xb3, 0x87, 0x6b, 0x9e, 0xea, 0xa9, 0xeb, 0xda, 0xac, 0xf9, 0x6f, - 0xde, 0xa1, 0x44, 0x32, 0x52, 0x49, 0x47, 0xff, 0x65, 0x79, 0x1e, 0xc5, - 0x73, 0x17, 0xb3, 0x36, 0xfc, 0x45, 0xca, 0x90, 0x37, 0x59, 0x1e, 0x16, - 0xab, 0x09, 0x69, 0xcf, 0xda, 0x56, 0x51, 0xfd, 0xeb, 0xcf, 0xcb, 0x8f, - 0xb1, 0xc3, 0x45, 0x2b, 0x7c, 0x0a, 0xa5, 0x9c, 0x0d, 0x2c, 0xad, 0x1c, - 0xd3, 0x33, 0xdd, 0xfe, 0x93, 0x69, 0xa2, 0x4b, 0x4b, 0xcf, 0x1d, 0x20, - 0x98, 0x4a, 0x4f, 0x5b, 0xe9, 0x24, 0xca, 0xfa, 0x18, 0x11, 0x81, 0x8b, - 0x7a, 0xb4, 0x5a, 0xc8, 0xdf, 0x6f, 0x5f, 0x21, 0x07, 0x31, 0x00}; - -const uint32_t kOemCertSystemId = 7346; - -constexpr uint32_t kNullSystemId = - static_cast(std::numeric_limits::max()); -} // namespace - namespace wvcdm { - class CryptoSessionForTest : public TestCryptoSession, public WvCdmTestBase { public: - using CryptoSession::ExtractSystemIdFromOemCert; CryptoSessionForTest() : TestCryptoSession(metrics_.GetCryptoMetrics()) {} void SetUp() override {} @@ -263,26 +39,17 @@ class CryptoSessionForTest : public TestCryptoSession, public WvCdmTestBase { metrics::SessionMetrics CryptoSessionForTest::metrics_; -TEST(CryptoSessionTest, CanExtractSystemIdFromOemCertificate) { - std::string oem_cert(reinterpret_cast(kOemCert), - sizeof(kOemCert)); - uint32_t system_id; - ASSERT_TRUE( - CryptoSessionForTest::ExtractSystemIdFromOemCert(oem_cert, &system_id)); - ASSERT_EQ(kOemCertSystemId, system_id); -} - class CryptoSessionMetricsTest : public WvCdmTestBase { protected: uint32_t FindKeyboxSystemID() { if (CryptoSession::needs_keybox_provisioning()) { - return kNullSystemId; + return NULL_SYSTEM_ID; } uint8_t key_data[256]; size_t key_data_len = sizeof(key_data); const OEMCryptoResult sts = OEMCrypto_GetKeyData(key_data, &key_data_len, kLevelDefault); - if (sts != OEMCrypto_SUCCESS) return kNullSystemId; + if (sts != OEMCrypto_SUCCESS) return NULL_SYSTEM_ID; const uint32_t* data = reinterpret_cast(key_data); return htonl(data[1]); } @@ -321,30 +88,11 @@ TEST_F(CryptoSessionMetricsTest, OpenSessionValidMetrics) { CdmClientTokenType token_type = session->GetPreProvisionTokenType(); if (token_type == kClientTokenKeybox) { - const uint32_t expected_system_id = FindKeyboxSystemID(); - const uint32_t recorded_system_id = static_cast( - metrics_proto.crypto_session_system_id().int_value()); - EXPECT_EQ(expected_system_id, recorded_system_id); EXPECT_EQ(OEMCrypto_Keybox, metrics_proto.oemcrypto_provisioning_method().int_value()); - if (recorded_system_id != kNullSystemId) { - // Devices with a null system ID don't actually call into the - // TEE for the keybox. - EXPECT_EQ(1, metrics_proto.oemcrypto_get_key_data_time_us().size()); - } } else if (token_type == kClientTokenOemCert) { - // Recent devices all have a system id between 1k and 6 or 7k. Errors - // we are trying to catch are 0, byte swapped 32 bit numbers, or - // garbage. These errors will most likely be outside the range of 1000 - // to 2^16. - EXPECT_LE(1000, metrics_proto.crypto_session_system_id().int_value()); - EXPECT_GT(0x10000, metrics_proto.crypto_session_system_id().int_value()); - EXPECT_EQ(OEMCrypto_OEMCertificate, metrics_proto.oemcrypto_provisioning_method().int_value()); - ASSERT_EQ(1, metrics_proto.oemcrypto_get_oem_public_certificate().size()); - EXPECT_THAT(metrics_proto.oemcrypto_get_oem_public_certificate(0).count(), - AllOf(Ge(1), Le(2))); } else if (token_type == kClientTokenDrmCert) { // TODO(blueeyes): Add support for getting the system id from a // pre-installed DRM certificate.. @@ -376,32 +124,19 @@ TEST_F(CryptoSessionMetricsTest, GetProvisioningTokenValidMetrics) { crypto_metrics.Serialize(&metrics_proto); if (token_type == kClientTokenKeybox) { - ASSERT_EQ(1, metrics_proto.crypto_session_get_token().size()); - EXPECT_EQ(1, metrics_proto.crypto_session_get_token(0).count()); - - const uint32_t expected_system_id = FindKeyboxSystemID(); - const uint32_t recorded_system_id = static_cast( - metrics_proto.crypto_session_system_id().int_value()); - EXPECT_EQ(expected_system_id, recorded_system_id); - if (recorded_system_id != kNullSystemId) { - EXPECT_EQ(1, metrics_proto.oemcrypto_get_key_data_time_us().size()); - } + EXPECT_EQ(OEMCrypto_Keybox, + metrics_proto.oemcrypto_provisioning_method().int_value()); + ASSERT_GE(metrics_proto.crypto_session_get_token().size(), 1); + EXPECT_GE(metrics_proto.crypto_session_get_token(0).count(), 1); } else if (token_type == kClientTokenOemCert) { - // Recent devices all have a system id between 1k and 6 or 7k. Errors - // we are trying to catch are 0, byte swapped 32 bit numbers, or - // garbage. These errors will most likely be outside the range of 1000 - // to 2^16. - EXPECT_LE(1000, metrics_proto.crypto_session_system_id().int_value()); - EXPECT_GT(0X10000, metrics_proto.crypto_session_system_id().int_value()); - EXPECT_EQ(OEMCrypto_OEMCertificate, metrics_proto.oemcrypto_provisioning_method().int_value()); - ASSERT_EQ(1, metrics_proto.oemcrypto_get_oem_public_certificate().size()); + ASSERT_GE(metrics_proto.oemcrypto_get_oem_public_certificate().size(), 1); EXPECT_THAT(metrics_proto.oemcrypto_get_oem_public_certificate(0).count(), AllOf(Ge(1), Le(2))); - ASSERT_EQ(1, metrics_proto.crypto_session_get_token().size()); - EXPECT_EQ(1, metrics_proto.crypto_session_get_token(0).count()); + ASSERT_GE(metrics_proto.crypto_session_get_token().size(), 1); + EXPECT_GE(metrics_proto.crypto_session_get_token(0).count(), 1); } else { ASSERT_EQ(0, metrics_proto.crypto_session_get_token().size()); } diff --git a/libwvdrmengine/cdm/core/test/system_id_extractor_unittest.cpp b/libwvdrmengine/cdm/core/test/system_id_extractor_unittest.cpp new file mode 100644 index 00000000..e08ff529 --- /dev/null +++ b/libwvdrmengine/cdm/core/test/system_id_extractor_unittest.cpp @@ -0,0 +1,528 @@ +// Copyright 2022 Google LLC. All Rights Reserved. This file and proprietary +// source code may only be used and distributed under the Widevine License +// Agreement. +#include +#include +#include + +#include +#include + +#include "cdm_random.h" +#include "crypto_session.h" +#include "device_files.h" +#include "file_store.h" +#include "system_id_extractor.h" +#include "test_base.h" +#include "wv_cdm_types.h" + +namespace wvcdm { +using ::testing::_; +using ::testing::DoAll; +using ::testing::NotNull; +using ::testing::Return; +using ::testing::SetArgPointee; + +namespace { +const uint8_t kOemCert[] = { + 0x30, 0x82, 0x09, 0xf7, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, + 0x01, 0x07, 0x02, 0xa0, 0x82, 0x09, 0xe8, 0x30, 0x82, 0x09, 0xe4, 0x02, + 0x01, 0x01, 0x31, 0x00, 0x30, 0x0f, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, + 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x02, 0x04, 0x00, 0xa0, 0x82, 0x09, + 0xc8, 0x30, 0x82, 0x04, 0x1a, 0x30, 0x82, 0x03, 0x02, 0xa0, 0x03, 0x02, + 0x01, 0x02, 0x02, 0x11, 0x00, 0xf2, 0xa1, 0x08, 0xdf, 0x12, 0x84, 0xb9, + 0x73, 0x6c, 0x23, 0x73, 0xe1, 0x1f, 0xf3, 0xac, 0x7a, 0x30, 0x0d, 0x06, + 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, + 0x30, 0x81, 0x8b, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x0c, 0x0a, 0x57, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x74, 0x6f, + 0x6e, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x08, + 0x4b, 0x69, 0x72, 0x6b, 0x6c, 0x61, 0x6e, 0x64, 0x31, 0x0f, 0x30, 0x0d, + 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x06, 0x47, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x08, + 0x57, 0x69, 0x64, 0x65, 0x76, 0x69, 0x6e, 0x65, 0x31, 0x30, 0x30, 0x2e, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x27, 0x47, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x20, 0x4f, 0x45, 0x4d, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x44, + 0x65, 0x76, 0x69, 0x63, 0x65, 0x3b, 0x20, 0x73, 0x79, 0x73, 0x74, 0x65, + 0x6d, 0x20, 0x69, 0x64, 0x3a, 0x20, 0x37, 0x33, 0x34, 0x36, 0x30, 0x1e, + 0x17, 0x0d, 0x31, 0x37, 0x30, 0x33, 0x31, 0x33, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x31, 0x39, 0x31, 0x32, 0x30, 0x38, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x6d, 0x31, 0x12, 0x30, 0x10, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x09, 0x37, 0x33, 0x34, 0x36, 0x2d, + 0x6c, 0x65, 0x61, 0x66, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, + 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, + 0x04, 0x08, 0x0c, 0x0a, 0x57, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x74, + 0x6f, 0x6e, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, + 0x08, 0x4b, 0x69, 0x72, 0x6b, 0x6c, 0x61, 0x6e, 0x64, 0x31, 0x0f, 0x30, + 0x0d, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x06, 0x47, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, + 0x08, 0x57, 0x69, 0x64, 0x65, 0x76, 0x69, 0x6e, 0x65, 0x30, 0x82, 0x01, + 0xa2, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, + 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x8f, 0x00, 0x30, 0x82, 0x01, + 0x8a, 0x02, 0x82, 0x01, 0x81, 0x00, 0xf5, 0x09, 0x64, 0x4a, 0x26, 0xfe, + 0xc0, 0x98, 0x55, 0x6a, 0x1d, 0x5d, 0x1c, 0xc7, 0x38, 0xaf, 0xfd, 0x49, + 0x9e, 0x85, 0x3f, 0xd6, 0x45, 0x0e, 0x99, 0x09, 0x85, 0x69, 0x84, 0x3c, + 0xfe, 0x72, 0xa5, 0x56, 0xfa, 0x11, 0x4f, 0x6b, 0x7d, 0x32, 0x2b, 0x0c, + 0xbf, 0x8f, 0xac, 0x47, 0x96, 0x22, 0x82, 0x3d, 0xf5, 0x64, 0x74, 0x7e, + 0x62, 0x68, 0x74, 0xcd, 0x0a, 0xec, 0x84, 0xc5, 0x15, 0x06, 0x0e, 0x5a, + 0x2f, 0x20, 0xe3, 0xc9, 0x67, 0xcd, 0xdd, 0x01, 0xb8, 0xb3, 0x18, 0x87, + 0x8c, 0xa9, 0x58, 0x86, 0x0f, 0xb6, 0xc3, 0x42, 0x7e, 0x87, 0x48, 0x5e, + 0x10, 0x49, 0xc7, 0xd7, 0xb7, 0xb8, 0xa6, 0x34, 0x08, 0x0c, 0x94, 0xf4, + 0xbb, 0x2a, 0x06, 0xa4, 0x4f, 0xec, 0xbc, 0xc4, 0x37, 0xbe, 0x99, 0x10, + 0x23, 0x37, 0x24, 0xb1, 0xdf, 0xcb, 0xe6, 0x3f, 0xc1, 0xf0, 0x0f, 0x04, + 0x03, 0xc8, 0xb0, 0x1e, 0xd6, 0xb8, 0xae, 0x77, 0xe1, 0x4d, 0x6d, 0x97, + 0x69, 0x6d, 0x8a, 0x73, 0x66, 0x32, 0x57, 0x6f, 0xcf, 0xea, 0x1e, 0x7b, + 0x87, 0x03, 0x75, 0xb1, 0xef, 0x83, 0x64, 0x26, 0xf1, 0x3f, 0xbf, 0xe6, + 0x28, 0x03, 0x72, 0x57, 0xbf, 0x47, 0x29, 0x99, 0x8f, 0x74, 0x1d, 0x01, + 0x16, 0xad, 0xb2, 0xdf, 0x80, 0xa4, 0xd3, 0x8b, 0xeb, 0x61, 0xd1, 0x40, + 0x68, 0xb9, 0xa2, 0xa5, 0xef, 0x2b, 0xe5, 0x78, 0xe8, 0x28, 0x88, 0x87, + 0xb7, 0x53, 0x49, 0xbb, 0xe4, 0xea, 0x0d, 0x5e, 0x96, 0xa5, 0xdd, 0x1f, + 0x0b, 0x25, 0x8b, 0xb5, 0x95, 0x46, 0xe7, 0xba, 0xb8, 0xc4, 0x0a, 0x36, + 0xb1, 0x89, 0xeb, 0x27, 0x5d, 0xd9, 0x97, 0x24, 0x59, 0xa3, 0x9b, 0xb0, + 0x23, 0x0b, 0xd2, 0xec, 0x65, 0x91, 0xf9, 0xf0, 0xa0, 0x74, 0x5f, 0xb4, + 0xce, 0x22, 0x27, 0x18, 0x37, 0xe2, 0x4b, 0xfc, 0x91, 0xf9, 0x09, 0x15, + 0xe6, 0xdb, 0x06, 0x9b, 0x4d, 0x82, 0xdc, 0x36, 0x14, 0x48, 0xc6, 0xd5, + 0x87, 0xca, 0xec, 0x5a, 0xa2, 0x29, 0x33, 0xef, 0x22, 0x0c, 0x4b, 0xbf, + 0xe7, 0x2f, 0x95, 0xe1, 0xd3, 0xa5, 0xd8, 0xaa, 0x44, 0x77, 0x29, 0xa3, + 0x20, 0x33, 0xd2, 0x51, 0xa2, 0xf9, 0x4a, 0x6f, 0xf7, 0x3e, 0xf7, 0x0b, + 0x8a, 0xec, 0xc1, 0x99, 0x1d, 0x47, 0xf3, 0x74, 0x02, 0x04, 0xab, 0x8e, + 0x62, 0x4c, 0x9e, 0x00, 0xc2, 0x84, 0xd7, 0xd0, 0xf8, 0xe4, 0x1c, 0x9d, + 0x98, 0x15, 0xa8, 0x8f, 0x08, 0x98, 0x4e, 0x5a, 0xfa, 0xd6, 0x60, 0x87, + 0x12, 0xdc, 0x8e, 0xfd, 0xcb, 0xb3, 0x13, 0x97, 0x7a, 0xa8, 0x8c, 0x56, + 0x2e, 0x49, 0x26, 0x60, 0xe9, 0x4a, 0xdc, 0xec, 0x3f, 0xf0, 0x94, 0xcd, + 0x90, 0x8e, 0x7c, 0x21, 0x3f, 0x80, 0x14, 0x33, 0xdd, 0xb0, 0x00, 0xe2, + 0x09, 0x37, 0x06, 0xdd, 0x17, 0x69, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, + 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, + 0xd6, 0x79, 0x04, 0x01, 0x01, 0x04, 0x04, 0x02, 0x02, 0x1c, 0xb2, 0x30, + 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, + 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x8e, 0x2d, 0x13, 0x1e, 0x60, + 0xaa, 0xda, 0x52, 0x53, 0x55, 0x64, 0x3a, 0xdc, 0xb6, 0x7a, 0xc0, 0xba, + 0xfa, 0xeb, 0x20, 0xab, 0xb6, 0x63, 0xcf, 0xcd, 0x9b, 0xdb, 0x71, 0xf3, + 0xa0, 0xd6, 0x91, 0xbf, 0x0c, 0xc1, 0xae, 0x8f, 0x02, 0x18, 0x00, 0x54, + 0xfb, 0x49, 0x03, 0x34, 0x8d, 0x92, 0x9d, 0x5d, 0x8d, 0xa8, 0x1c, 0x20, + 0x0f, 0x85, 0x60, 0xf9, 0xf6, 0x8b, 0xbb, 0x2b, 0x82, 0xce, 0xb3, 0xe2, + 0x91, 0xe7, 0xbd, 0x91, 0x61, 0x52, 0x36, 0x40, 0x9f, 0x2f, 0x5e, 0xa6, + 0x5d, 0x2f, 0xb3, 0x81, 0xe7, 0xf1, 0x87, 0xbe, 0xc5, 0x9d, 0x67, 0x5a, + 0xf7, 0x41, 0x1e, 0x73, 0xb0, 0x1e, 0xdc, 0x4f, 0x8d, 0x53, 0x21, 0x38, + 0x1b, 0xfd, 0x92, 0x43, 0x68, 0x83, 0x03, 0xd0, 0x9a, 0xca, 0x92, 0x14, + 0x73, 0x04, 0x94, 0x2a, 0x93, 0x22, 0x60, 0x5e, 0xee, 0xb6, 0xec, 0x0f, + 0xb0, 0xc8, 0x92, 0x97, 0xfb, 0x5d, 0xed, 0x1f, 0xa0, 0x5f, 0xe4, 0x98, + 0x2f, 0xf6, 0x13, 0x78, 0x99, 0xec, 0xb3, 0xf1, 0x0d, 0x27, 0xaa, 0x19, + 0x95, 0x39, 0xdb, 0xb0, 0x7b, 0x96, 0x74, 0x03, 0x5e, 0x51, 0xf5, 0x15, + 0x27, 0xce, 0xca, 0x0b, 0x2a, 0x0d, 0x43, 0xb3, 0x68, 0x17, 0x1e, 0x11, + 0x60, 0xd9, 0x84, 0x9b, 0xc3, 0x53, 0xce, 0xbd, 0xf4, 0x61, 0x51, 0x4b, + 0x41, 0x00, 0x7e, 0xe1, 0x5f, 0x69, 0xb3, 0x4a, 0x89, 0x7e, 0x47, 0x67, + 0xfd, 0x76, 0xf8, 0x94, 0x2f, 0x72, 0xb6, 0x14, 0x08, 0x2c, 0x16, 0x4e, + 0x9d, 0x37, 0x62, 0xbf, 0x11, 0x67, 0xc0, 0x70, 0x71, 0xec, 0x55, 0x51, + 0x4e, 0x46, 0x76, 0xb4, 0xc3, 0xeb, 0x52, 0x06, 0x17, 0x06, 0xce, 0x61, + 0x43, 0xce, 0x26, 0x80, 0x68, 0xb6, 0x2d, 0x57, 0xba, 0x8c, 0x7d, 0xb7, + 0xc5, 0x05, 0x2c, 0xf8, 0xa3, 0x69, 0xf8, 0x96, 0xad, 0xac, 0xd1, 0x30, + 0x82, 0x05, 0xa6, 0x30, 0x82, 0x03, 0x8e, 0xa0, 0x03, 0x02, 0x01, 0x02, + 0x02, 0x10, 0x73, 0xd1, 0xe1, 0x1d, 0xa9, 0x75, 0xfd, 0x0c, 0xda, 0x7f, + 0xfa, 0x43, 0x3c, 0x26, 0xbd, 0x3d, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x7e, 0x31, + 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, + 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a, 0x57, + 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x74, 0x6f, 0x6e, 0x31, 0x11, 0x30, + 0x0f, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x08, 0x4b, 0x69, 0x72, 0x6b, + 0x6c, 0x61, 0x6e, 0x64, 0x31, 0x0f, 0x30, 0x0d, 0x06, 0x03, 0x55, 0x04, + 0x0a, 0x0c, 0x06, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x31, 0x11, 0x30, + 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x08, 0x57, 0x69, 0x64, 0x65, + 0x76, 0x69, 0x6e, 0x65, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x0c, 0x1a, 0x77, 0x69, 0x64, 0x65, 0x76, 0x69, 0x6e, 0x65, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x65, 0x6d, 0x2d, 0x72, 0x6f, 0x6f, 0x74, + 0x2d, 0x70, 0x72, 0x6f, 0x64, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x37, 0x30, + 0x33, 0x31, 0x34, 0x30, 0x33, 0x30, 0x32, 0x34, 0x31, 0x5a, 0x17, 0x0d, + 0x32, 0x37, 0x30, 0x33, 0x31, 0x34, 0x30, 0x33, 0x30, 0x32, 0x34, 0x31, + 0x5a, 0x30, 0x81, 0x8b, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, + 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, + 0x04, 0x08, 0x0c, 0x0a, 0x57, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x74, + 0x6f, 0x6e, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, + 0x08, 0x4b, 0x69, 0x72, 0x6b, 0x6c, 0x61, 0x6e, 0x64, 0x31, 0x0f, 0x30, + 0x0d, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x06, 0x47, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, + 0x08, 0x57, 0x69, 0x64, 0x65, 0x76, 0x69, 0x6e, 0x65, 0x31, 0x30, 0x30, + 0x2e, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x27, 0x47, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x20, 0x4f, 0x45, 0x4d, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, + 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x3b, 0x20, 0x73, 0x79, 0x73, 0x74, + 0x65, 0x6d, 0x20, 0x69, 0x64, 0x3a, 0x20, 0x37, 0x33, 0x34, 0x36, 0x30, + 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, + 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xa5, 0x45, 0x13, 0xf2, + 0xb2, 0xcb, 0x4b, 0x0f, 0xb4, 0x44, 0x25, 0x9c, 0x8a, 0x68, 0x54, 0xd5, + 0x45, 0x1e, 0x15, 0x89, 0x5b, 0xb8, 0xce, 0xda, 0x5a, 0x42, 0xe6, 0x9a, + 0x8c, 0xc1, 0xcb, 0xe8, 0xc5, 0xf5, 0x8f, 0x49, 0x0e, 0x02, 0xef, 0x5e, + 0x97, 0x1a, 0x91, 0xa4, 0x94, 0xc3, 0x50, 0x13, 0xe5, 0x13, 0xb7, 0x7f, + 0x26, 0x53, 0x19, 0xb0, 0x37, 0xa5, 0xef, 0xe6, 0x2a, 0x39, 0xdc, 0x93, + 0x37, 0xe2, 0x3d, 0x7f, 0xcb, 0x4b, 0x93, 0xa2, 0xc3, 0x69, 0x78, 0xc9, + 0x01, 0xfa, 0x68, 0x3b, 0xe0, 0xe2, 0x22, 0x6c, 0xeb, 0xe4, 0x8a, 0xa8, + 0x3e, 0xf5, 0x20, 0x82, 0xa8, 0x62, 0x68, 0x59, 0x78, 0x24, 0xde, 0xef, + 0x47, 0x43, 0xb1, 0x6c, 0x38, 0x29, 0xd3, 0x69, 0x3f, 0xae, 0x35, 0x57, + 0x75, 0x80, 0xc9, 0x21, 0xe7, 0x01, 0xb9, 0x54, 0x8b, 0x6e, 0x4e, 0x2e, + 0x5a, 0x5b, 0x77, 0xa4, 0x22, 0xc2, 0x7b, 0x95, 0xb9, 0x39, 0x2c, 0xbd, + 0xc2, 0x1e, 0x02, 0xa6, 0xb2, 0xbc, 0x0f, 0x7a, 0xcb, 0xdc, 0xbc, 0xbc, + 0x90, 0x66, 0xe3, 0xca, 0x46, 0x53, 0x3e, 0x98, 0xff, 0x2e, 0x78, 0x9f, + 0xd3, 0xa1, 0x12, 0x93, 0x66, 0x7d, 0xcc, 0x94, 0x6b, 0xec, 0x19, 0x0e, + 0x20, 0x45, 0x22, 0x57, 0x6d, 0x9e, 0xd0, 0x89, 0xf2, 0xa9, 0x34, 0xdc, + 0xab, 0xa5, 0x73, 0x47, 0x38, 0xe3, 0x7f, 0x98, 0x3a, 0x61, 0xae, 0x6c, + 0x4d, 0xf2, 0x31, 0x90, 0xcb, 0x83, 0xc1, 0xee, 0xb4, 0xf2, 0x9a, 0x28, + 0x5f, 0xbb, 0x7d, 0x89, 0xdf, 0xa2, 0x31, 0xb6, 0x1d, 0x39, 0x2b, 0x70, + 0xbf, 0x1e, 0xad, 0xe1, 0x74, 0x94, 0x1d, 0xf8, 0xc5, 0x1a, 0x8d, 0x13, + 0x45, 0xf0, 0x6a, 0x80, 0x0c, 0x5d, 0xbb, 0x46, 0x8a, 0x43, 0xd0, 0xff, + 0x21, 0x39, 0x57, 0x53, 0x5b, 0x51, 0xf8, 0xa2, 0x8f, 0x7f, 0x27, 0xc7, + 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x10, 0x30, 0x82, 0x01, + 0x0c, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, + 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x0e, 0x06, + 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x02, + 0x04, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, + 0xe8, 0xe9, 0xac, 0x16, 0x5c, 0x5e, 0xb2, 0xe8, 0xeb, 0xff, 0x57, 0x27, + 0x20, 0x08, 0x72, 0x63, 0x9b, 0xe5, 0xb5, 0x16, 0x30, 0x81, 0xb2, 0x06, + 0x03, 0x55, 0x1d, 0x23, 0x04, 0x81, 0xaa, 0x30, 0x81, 0xa7, 0x80, 0x14, + 0x04, 0x94, 0x66, 0xaa, 0xf9, 0x61, 0x89, 0xb6, 0xdb, 0xb5, 0xf7, 0x13, + 0x38, 0x3d, 0x62, 0x84, 0xb8, 0x18, 0x0a, 0x8f, 0xa1, 0x81, 0x83, 0xa4, + 0x81, 0x80, 0x30, 0x7e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, + 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, + 0x04, 0x08, 0x0c, 0x0a, 0x57, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x74, + 0x6f, 0x6e, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, + 0x08, 0x4b, 0x69, 0x72, 0x6b, 0x6c, 0x61, 0x6e, 0x64, 0x31, 0x0f, 0x30, + 0x0d, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x06, 0x47, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, + 0x08, 0x57, 0x69, 0x64, 0x65, 0x76, 0x69, 0x6e, 0x65, 0x31, 0x23, 0x30, + 0x21, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x1a, 0x77, 0x69, 0x64, 0x65, + 0x76, 0x69, 0x6e, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x65, 0x6d, + 0x2d, 0x72, 0x6f, 0x6f, 0x74, 0x2d, 0x70, 0x72, 0x6f, 0x64, 0x82, 0x09, + 0x00, 0xdf, 0x86, 0x05, 0x31, 0x01, 0xbe, 0x9a, 0x9a, 0x30, 0x12, 0x06, + 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0xd6, 0x79, 0x04, 0x01, 0x01, 0x04, + 0x04, 0x02, 0x02, 0x1c, 0xb2, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, + 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x02, 0x01, + 0x00, 0x25, 0xce, 0xd2, 0x02, 0x48, 0xbb, 0xbe, 0xfc, 0xb6, 0xa4, 0x87, + 0x87, 0xe0, 0x21, 0x7d, 0xfa, 0x23, 0xc3, 0x0d, 0x73, 0x8f, 0x46, 0xe7, + 0x09, 0x59, 0xda, 0x2e, 0x55, 0x59, 0xff, 0x3c, 0x1b, 0xf6, 0xf8, 0x9a, + 0xc4, 0x1c, 0xf7, 0xac, 0xca, 0xe7, 0x63, 0xf2, 0xc7, 0xd6, 0x0c, 0x2d, + 0xa6, 0xad, 0x55, 0xf4, 0x10, 0x0e, 0xa8, 0x82, 0x0f, 0x88, 0xb5, 0x44, + 0xe8, 0x8e, 0x84, 0x08, 0xf7, 0xdd, 0xe7, 0x10, 0xce, 0x71, 0x56, 0x57, + 0x3f, 0xed, 0x48, 0xee, 0xe2, 0x5d, 0x08, 0x0a, 0x58, 0xe4, 0xfe, 0xbc, + 0x8c, 0x27, 0x1a, 0x46, 0x3f, 0xd5, 0x2d, 0xdb, 0x0b, 0x71, 0x73, 0xd1, + 0x49, 0xf3, 0x5c, 0x86, 0x4d, 0x0a, 0xe1, 0xeb, 0x53, 0x21, 0x38, 0x4f, + 0xec, 0x1e, 0xc2, 0x68, 0x1f, 0x7d, 0xa6, 0x33, 0xe9, 0xa5, 0x37, 0x2a, + 0xef, 0xcd, 0x78, 0x56, 0xb3, 0x39, 0x60, 0xf4, 0xa5, 0xf9, 0x2b, 0x85, + 0xcf, 0xe6, 0x1c, 0x7c, 0x8a, 0x5d, 0xe8, 0x26, 0x02, 0xcf, 0x7a, 0x56, + 0x1f, 0xae, 0x0d, 0x71, 0x20, 0xee, 0xec, 0x3b, 0xae, 0x95, 0x25, 0x15, + 0xc8, 0xf6, 0x92, 0x5d, 0xb8, 0x9b, 0xc2, 0xb4, 0x95, 0x33, 0x13, 0x76, + 0x45, 0xbe, 0x21, 0xe2, 0x3a, 0x69, 0x66, 0xd7, 0xff, 0x22, 0x00, 0x89, + 0xc9, 0x44, 0xb6, 0x54, 0x38, 0x1f, 0x33, 0xe4, 0xda, 0x7b, 0x87, 0xf3, + 0x23, 0xed, 0xf5, 0x16, 0x08, 0xbe, 0x4b, 0xea, 0x91, 0x8f, 0x91, 0x8b, + 0x4e, 0xd1, 0x02, 0x06, 0xa2, 0x77, 0x15, 0x03, 0x46, 0x11, 0x7d, 0x5b, + 0xea, 0x7a, 0xf6, 0x86, 0x7d, 0x96, 0xb7, 0x73, 0x9b, 0x5b, 0x32, 0xc3, + 0xf8, 0x92, 0x36, 0xe3, 0xe3, 0x2f, 0xe8, 0xf1, 0x72, 0xec, 0x0d, 0x50, + 0xd4, 0x86, 0xc5, 0x62, 0x83, 0xf1, 0x2a, 0x4c, 0xd1, 0xbf, 0x76, 0x62, + 0xd4, 0x21, 0x11, 0x68, 0xb2, 0xd6, 0x8d, 0xc4, 0xf8, 0xe4, 0x70, 0x85, + 0x19, 0xa7, 0x82, 0x27, 0x2c, 0x24, 0x21, 0x7a, 0x3b, 0xad, 0x8a, 0xd3, + 0xae, 0xda, 0x78, 0x3c, 0x6c, 0xab, 0xa2, 0xaa, 0x36, 0xf0, 0x1c, 0x58, + 0xd4, 0x72, 0x5e, 0xe8, 0x8b, 0x41, 0x08, 0xf5, 0x85, 0xdd, 0xee, 0x99, + 0x12, 0xf4, 0xd6, 0x41, 0x83, 0x69, 0xe7, 0x79, 0x19, 0xa3, 0x74, 0xc4, + 0x34, 0x2a, 0x8a, 0x7e, 0x4d, 0xbb, 0x2c, 0x49, 0x19, 0xf7, 0x98, 0x98, + 0xfc, 0x81, 0xf7, 0x9b, 0x7f, 0xff, 0xd9, 0x66, 0xf4, 0x51, 0x14, 0x29, + 0x2a, 0x14, 0x1d, 0x4f, 0xbd, 0x91, 0xba, 0x6f, 0x32, 0x34, 0x3c, 0x40, + 0x28, 0x6c, 0x97, 0xf8, 0x6d, 0x38, 0xcd, 0xa3, 0x7b, 0x18, 0xc8, 0x77, + 0x58, 0x4d, 0x53, 0x30, 0x7f, 0x4d, 0x89, 0xca, 0x95, 0x6e, 0xb5, 0xb8, + 0x8e, 0xc8, 0x2d, 0x18, 0x2f, 0x52, 0x2a, 0xde, 0xac, 0x56, 0x8d, 0x8c, + 0x67, 0x14, 0xf6, 0xb9, 0xf1, 0x65, 0xd3, 0x22, 0x43, 0xa3, 0x98, 0x42, + 0x20, 0x43, 0x4c, 0xdf, 0xf2, 0xeb, 0x31, 0x8c, 0x0e, 0x53, 0x5b, 0x99, + 0x82, 0xc3, 0x48, 0x04, 0x53, 0xad, 0x96, 0xb6, 0x9f, 0x52, 0xcc, 0x01, + 0xc8, 0xb3, 0x87, 0x6b, 0x9e, 0xea, 0xa9, 0xeb, 0xda, 0xac, 0xf9, 0x6f, + 0xde, 0xa1, 0x44, 0x32, 0x52, 0x49, 0x47, 0xff, 0x65, 0x79, 0x1e, 0xc5, + 0x73, 0x17, 0xb3, 0x36, 0xfc, 0x45, 0xca, 0x90, 0x37, 0x59, 0x1e, 0x16, + 0xab, 0x09, 0x69, 0xcf, 0xda, 0x56, 0x51, 0xfd, 0xeb, 0xcf, 0xcb, 0x8f, + 0xb1, 0xc3, 0x45, 0x2b, 0x7c, 0x0a, 0xa5, 0x9c, 0x0d, 0x2c, 0xad, 0x1c, + 0xd3, 0x33, 0xdd, 0xfe, 0x93, 0x69, 0xa2, 0x4b, 0x4b, 0xcf, 0x1d, 0x20, + 0x98, 0x4a, 0x4f, 0x5b, 0xe9, 0x24, 0xca, 0xfa, 0x18, 0x11, 0x81, 0x8b, + 0x7a, 0xb4, 0x5a, 0xc8, 0xdf, 0x6f, 0x5f, 0x21, 0x07, 0x31, 0x00}; + +const std::string kOemCertStr(kOemCert, kOemCert + sizeof(kOemCert)); + +const uint32_t kOemCertSystemId = 7346; + +// clang-format off +const uint8_t kKeyboxData[72] = { + // Version = 1 - 4 bytes + 0x00, 0x00, 0x00, 0x01, + // System ID = 1337 - 4 bytes + 0x00, 0x00, 0x05, 0x39, + // Encrypted info = arbitrary - 64 bytes + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, + 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, + 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, + 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, + 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, + 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, + 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, +}; +// clang-format on + +const uint32_t kKeyboxSystemId = 1337; +const std::string kKeyboxDataStr(kKeyboxData, + kKeyboxData + sizeof(kKeyboxData)); + +class MockCryptoSession : public CryptoSession { + public: + MockCryptoSession(metrics::CryptoMetrics* metrics) : CryptoSession(metrics) {} + // ~MockCryptoSession() override {} + + bool IsOpen() override { return true; } + CdmSecurityLevel GetSecurityLevel() override { return kSecurityLevelL1; } + CdmSecurityLevel GetSecurityLevel( + RequestedSecurityLevel security_level) override { + return security_level == kLevelDefault ? kSecurityLevelL1 + : kSecurityLevelL3; + } + + MOCK_METHOD(bool, GetCachedSystemId, (uint32_t*), (override)); + MOCK_METHOD(void, SetSystemId, (uint32_t), (override)); + + void SetSystemIdBase(uint32_t system_id) { + CryptoSession::SetSystemId(system_id); + } + + MOCK_METHOD(CdmResponseType, GetProvisioningMethod, + (RequestedSecurityLevel, CdmClientTokenType*), (override)); + MOCK_METHOD(CdmResponseType, GetTokenFromKeybox, + (RequestedSecurityLevel, std::string*), (override)); + MOCK_METHOD(CdmResponseType, GetTokenFromOemCert, + (RequestedSecurityLevel, std::string*), (override)); +}; + +class MockDeviceFiles : public DeviceFiles { + public: + MockDeviceFiles(wvutil::FileSystem* fs) : DeviceFiles(fs) {} + // ~MockDeviceFiles() override {} + + MOCK_METHOD(bool, Init, (CdmSecurityLevel), (override)); + MOCK_METHOD(DeviceFiles::CertificateState, RetrieveOemCertificate, + (std::string*, CryptoWrappedKey*), (override)); +}; +} // namespace + +class SystemIdExtractorTest : public WvCdmTestBase { + protected: + void SetUp() override { + WvCdmTestBase::SetUp(); + crypto_session_.reset(new MockCryptoSession(&crypto_metrics_)); + ASSERT_TRUE(crypto_session_); + device_files_.reset(new MockDeviceFiles(&fs_)); + ASSERT_TRUE(device_files_); + } + + void TearDown() override { + device_files_.reset(); + crypto_session_.reset(); + WvCdmTestBase::TearDown(); + } + + std::unique_ptr CreateExtractor( + RequestedSecurityLevel security_level) { + std::unique_ptr extractor( + new SystemIdExtractor(security_level, crypto_session_.get(), &fs_)); + extractor->SetDeviceFilesForTesting(device_files_.get()); + return extractor; + } + + void ExpectProvisioningType(CdmClientTokenType type) { + EXPECT_CALL(*crypto_session_, GetCachedSystemId).WillOnce(Return(false)); + EXPECT_CALL(*crypto_session_, GetProvisioningMethod(_, NotNull())) + .WillOnce(DoAll(SetArgPointee<1>(type), Return(NO_ERROR))); + } + + void ExpectSet(uint32_t system_id) { + EXPECT_CALL(*crypto_session_, SetSystemId(system_id)); + } + + std::unique_ptr crypto_session_ = nullptr; + std::unique_ptr device_files_ = nullptr; + wvutil::FileSystem fs_; + metrics::CryptoMetrics crypto_metrics_; +}; + +TEST_F(SystemIdExtractorTest, ExtractSystemIdFromOemCert) { + uint32_t system_id = 0; + EXPECT_TRUE( + SystemIdExtractor::ExtractSystemIdFromOemCert(kOemCertStr, &system_id)); + EXPECT_EQ(system_id, kOemCertSystemId); +} + +TEST_F(SystemIdExtractorTest, ExtractSystemIdFromKeyboxData) { + uint32_t system_id = 0; + EXPECT_TRUE(SystemIdExtractor::ExtractSystemIdFromKeyboxData(kKeyboxDataStr, + &system_id)); + EXPECT_EQ(system_id, kKeyboxSystemId); +} + +TEST_F(SystemIdExtractorTest, CachedSystemId) { + const uint32_t kCachedSystemId = 1234; + EXPECT_CALL(*crypto_session_, GetCachedSystemId(NotNull())) + .WillOnce(DoAll(SetArgPointee<0>(kCachedSystemId), Return(true))); + auto extractor = CreateExtractor(kLevelDefault); + ASSERT_TRUE(extractor); + uint32_t system_id; + EXPECT_TRUE(extractor->ExtractSystemId(&system_id)); + EXPECT_EQ(system_id, kCachedSystemId); +} + +TEST_F(SystemIdExtractorTest, SetSystemIdMetrics) { + const uint32_t kSystemId = 4321; + crypto_session_->SetSystemIdBase(kSystemId); + drm_metrics::WvCdmMetrics::CryptoMetrics metrics_proto; + crypto_metrics_.Serialize(&metrics_proto); + const uint32_t recorded_system_id = static_cast( + metrics_proto.crypto_session_system_id().int_value()); + EXPECT_EQ(recorded_system_id, kSystemId); +} + +TEST_F(SystemIdExtractorTest, GetProvisioningMethod_Failed) { + EXPECT_CALL(*crypto_session_, GetCachedSystemId).WillOnce(Return(false)); + EXPECT_CALL(*crypto_session_, GetProvisioningMethod(_, NotNull())) + .WillOnce(Return(UNKNOWN_ERROR)); + auto extractor = CreateExtractor(kLevelDefault); + ASSERT_TRUE(extractor); + uint32_t system_id; + EXPECT_FALSE(extractor->ExtractSystemId(&system_id)); +} + +TEST_F(SystemIdExtractorTest, GetProvisioningMethod_Unsupported) { + ExpectProvisioningType(kClientTokenDrmCert); + auto extractor = CreateExtractor(kLevelDefault); + ASSERT_TRUE(extractor); + uint32_t system_id; + EXPECT_FALSE(extractor->ExtractSystemId(&system_id)); +} + +TEST_F(SystemIdExtractorTest, KeyboxDevice_Success) { + ExpectProvisioningType(kClientTokenKeybox); + EXPECT_CALL(*crypto_session_, GetTokenFromKeybox(kLevelDefault, NotNull())) + .WillOnce(DoAll(SetArgPointee<1>(kKeyboxDataStr), Return(NO_ERROR))); + ExpectSet(kKeyboxSystemId); + auto extractor = CreateExtractor(kLevelDefault); + ASSERT_TRUE(extractor); + uint32_t system_id; + EXPECT_TRUE(extractor->ExtractSystemId(&system_id)); + EXPECT_EQ(system_id, kKeyboxSystemId); +} + +TEST_F(SystemIdExtractorTest, KeyboxDevice_NeedsOtaKeyboxProvisioning) { + ExpectProvisioningType(kClientTokenKeybox); + EXPECT_CALL(*crypto_session_, GetTokenFromKeybox(kLevelDefault, NotNull())) + .WillOnce(Return(NEED_PROVISIONING)); + auto extractor = CreateExtractor(kLevelDefault); + ASSERT_TRUE(extractor); + uint32_t system_id; + EXPECT_TRUE(extractor->ExtractSystemId(&system_id)); + EXPECT_EQ(system_id, NULL_SYSTEM_ID); +} + +TEST_F(SystemIdExtractorTest, KeyboxDevice_FailedToGetKeyboxData) { + ExpectProvisioningType(kClientTokenKeybox); + EXPECT_CALL(*crypto_session_, GetTokenFromKeybox(kLevel3, NotNull())) + .WillOnce(Return(UNKNOWN_ERROR)); + auto extractor = CreateExtractor(kLevel3); + ASSERT_TRUE(extractor); + uint32_t system_id; + EXPECT_FALSE(extractor->ExtractSystemId(&system_id)); +} + +TEST_F(SystemIdExtractorTest, KeyboxDevice_FailedToParse) { + const std::string kShortKeyData = "123456"; + ExpectProvisioningType(kClientTokenKeybox); + EXPECT_CALL(*crypto_session_, GetTokenFromKeybox(kLevel3, NotNull())) + .WillOnce(DoAll(SetArgPointee<1>(kShortKeyData), Return(NO_ERROR))); + auto extractor = CreateExtractor(kLevel3); + ASSERT_TRUE(extractor); + uint32_t system_id; + EXPECT_FALSE(extractor->ExtractSystemId(&system_id)); +} + +TEST_F(SystemIdExtractorTest, OemCertDevice_Success) { + ExpectProvisioningType(kClientTokenOemCert); + EXPECT_CALL(*crypto_session_, GetTokenFromOemCert(kLevel3, NotNull())) + .WillOnce(DoAll(SetArgPointee<1>(kOemCertStr), Return(NO_ERROR))); + ExpectSet(kOemCertSystemId); + auto extractor = CreateExtractor(kLevel3); + ASSERT_TRUE(extractor); + uint32_t system_id; + EXPECT_TRUE(extractor->ExtractSystemId(&system_id)); + EXPECT_EQ(system_id, kOemCertSystemId); +} + +TEST_F(SystemIdExtractorTest, OemCertDevice_FailedToGetCert) { + ExpectProvisioningType(kClientTokenOemCert); + EXPECT_CALL(*crypto_session_, GetTokenFromOemCert(kLevelDefault, NotNull())) + .WillOnce(Return(UNKNOWN_ERROR)); + auto extractor = CreateExtractor(kLevelDefault); + ASSERT_TRUE(extractor); + uint32_t system_id; + EXPECT_FALSE(extractor->ExtractSystemId(&system_id)); +} + +TEST_F(SystemIdExtractorTest, OemCertDevice_FailedToParse) { + const std::string kNotACertChain = + wvutil::CdmRandom::RandomData(kOemCertStr.size()); + ExpectProvisioningType(kClientTokenOemCert); + EXPECT_CALL(*crypto_session_, GetTokenFromOemCert(kLevelDefault, NotNull())) + .WillOnce(DoAll(SetArgPointee<1>(kNotACertChain), Return(NO_ERROR))); + auto extractor = CreateExtractor(kLevelDefault); + ASSERT_TRUE(extractor); + uint32_t system_id; + EXPECT_FALSE(extractor->ExtractSystemId(&system_id)); +} + +TEST_F(SystemIdExtractorTest, BccDevice_Success) { + ExpectProvisioningType(kClientTokenBootCertChain); + EXPECT_CALL(*device_files_, Init(kSecurityLevelL1)).WillOnce(Return(true)); + EXPECT_CALL(*device_files_, RetrieveOemCertificate(NotNull(), NotNull())) + .WillOnce(DoAll(SetArgPointee<0>(kOemCertStr), + Return(DeviceFiles::kCertificateValid))); + ExpectSet(kOemCertSystemId); + auto extractor = CreateExtractor(kLevelDefault); + ASSERT_TRUE(extractor); + uint32_t system_id; + EXPECT_TRUE(extractor->ExtractSystemId(&system_id)); + EXPECT_EQ(system_id, kOemCertSystemId); +} + +TEST_F(SystemIdExtractorTest, BccDevice_NotAvailable) { + ExpectProvisioningType(kClientTokenBootCertChain); + EXPECT_CALL(*device_files_, Init(kSecurityLevelL1)).WillOnce(Return(true)); + EXPECT_CALL(*device_files_, RetrieveOemCertificate(NotNull(), NotNull())) + .WillOnce(Return(DeviceFiles::kCertificateNotFound)); + auto extractor = CreateExtractor(kLevelDefault); + ASSERT_TRUE(extractor); + uint32_t system_id; + EXPECT_TRUE(extractor->ExtractSystemId(&system_id)); + EXPECT_EQ(system_id, NULL_SYSTEM_ID); +} + +TEST_F(SystemIdExtractorTest, BccDevice_FailedToRetrieve) { + ExpectProvisioningType(kClientTokenBootCertChain); + EXPECT_CALL(*device_files_, Init(kSecurityLevelL1)).WillOnce(Return(true)); + EXPECT_CALL(*device_files_, RetrieveOemCertificate(NotNull(), NotNull())) + .WillOnce(Return(DeviceFiles::kCertificateInvalid)); + auto extractor = CreateExtractor(kLevelDefault); + ASSERT_TRUE(extractor); + uint32_t system_id; + EXPECT_FALSE(extractor->ExtractSystemId(&system_id)); +} + +TEST_F(SystemIdExtractorTest, BccDevice_FailedToParse) { + const std::string kNotACertChain = + wvutil::CdmRandom::RandomData(kOemCertStr.size()); + ExpectProvisioningType(kClientTokenBootCertChain); + EXPECT_CALL(*device_files_, Init(kSecurityLevelL1)).WillOnce(Return(true)); + EXPECT_CALL(*device_files_, RetrieveOemCertificate(NotNull(), NotNull())) + .WillOnce(DoAll(SetArgPointee<0>(kNotACertChain), + Return(DeviceFiles::kCertificateValid))); + auto extractor = CreateExtractor(kLevelDefault); + ASSERT_TRUE(extractor); + uint32_t system_id; + EXPECT_FALSE(extractor->ExtractSystemId(&system_id)); +} +} // namespace wvcdm diff --git a/libwvdrmengine/cdm/test/Android.mk b/libwvdrmengine/cdm/test/Android.mk index 5bb1c3fd..80945a91 100644 --- a/libwvdrmengine/cdm/test/Android.mk +++ b/libwvdrmengine/cdm/test/Android.mk @@ -161,6 +161,10 @@ test_name := service_certificate_unittest test_src_dir := ../core/test include $(LOCAL_PATH)/unit-test.mk +test_name := system_id_extractor_unittest +test_src_dir := ../core/test +include $(LOCAL_PATH)/integration-test.mk + test_name := timer_unittest test_src_dir := . include $(LOCAL_PATH)/unit-test.mk diff --git a/libwvdrmengine/run_all_unit_tests.sh b/libwvdrmengine/run_all_unit_tests.sh index 8a669ff1..bda1f1e3 100755 --- a/libwvdrmengine/run_all_unit_tests.sh +++ b/libwvdrmengine/run_all_unit_tests.sh @@ -123,6 +123,7 @@ adb_shell_run policy_engine_unittest adb_shell_run policy_integration_test adb_shell_run rw_lock_test adb_shell_run service_certificate_unittest +adb_shell_run system_id_extractor_unittest adb_shell_run timer_unittest adb_shell_run usage_table_header_unittest adb_shell_run value_metric_unittest