From 8513b71499532c5eb20e5d4e6f842b1873a67b1f Mon Sep 17 00:00:00 2001 From: "John W. Bruce" Date: Tue, 11 Apr 2017 11:57:57 -0700 Subject: [PATCH] Hash OEM Certificate (This is a merge of wvgerrit/25582) Provisioning 3.0 devices that do not use SPOIDs have been returning their full OEM Public Certificate as their device ID. While this is not a security concern, (it is a PUBLIC cert) the cert is many times larger than applications are likely expecting. (several kilobytes vs. just a few bytes) This patch hashes the OEM Public Certificate to produce a smaller value, but only when it is being provided out of the CDM to a caller. Bug: 34716264 Test: run_all_unit_tests.sh Change-Id: Ib82cf7a174a8bf02ff606edd0394ada13842224c --- .../cdm/core/include/crypto_session.h | 3 +- libwvdrmengine/cdm/core/src/cdm_engine.cpp | 2 +- .../cdm/core/src/certificate_provisioning.cpp | 2 +- .../cdm/core/src/crypto_session.cpp | 28 +++++++++++++++++-- libwvdrmengine/cdm/core/src/license.cpp | 2 +- 5 files changed, 30 insertions(+), 7 deletions(-) diff --git a/libwvdrmengine/cdm/core/include/crypto_session.h b/libwvdrmengine/cdm/core/include/crypto_session.h index 22f3c2e9..b61ddc05 100644 --- a/libwvdrmengine/cdm/core/include/crypto_session.h +++ b/libwvdrmengine/cdm/core/include/crypto_session.h @@ -43,7 +43,8 @@ class CryptoSession { return pre_provision_token_type_; } virtual CdmSecurityLevel GetSecurityLevel(); - virtual bool GetDeviceUniqueId(std::string* device_id); + virtual bool GetInternalDeviceUniqueId(std::string* device_id); + virtual bool GetExternalDeviceUniqueId(std::string* device_id); virtual bool GetApiVersion(uint32_t* version); virtual bool GetSystemId(uint32_t* system_id); virtual bool GetProvisioningId(std::string* provisioning_id); diff --git a/libwvdrmengine/cdm/core/src/cdm_engine.cpp b/libwvdrmengine/cdm/core/src/cdm_engine.cpp index 19291f9b..fc08e865 100644 --- a/libwvdrmengine/cdm/core/src/cdm_engine.cpp +++ b/libwvdrmengine/cdm/core/src/cdm_engine.cpp @@ -540,7 +540,7 @@ CdmResponseType CdmEngine::QueryStatus(SecurityLevel security_level, std::string deviceId; bool got_id; M_TIME( - got_id = crypto_session.GetDeviceUniqueId( + got_id = crypto_session.GetExternalDeviceUniqueId( &deviceId), &metrics_, crypto_session_get_device_unique_id_, diff --git a/libwvdrmengine/cdm/core/src/certificate_provisioning.cpp b/libwvdrmengine/cdm/core/src/certificate_provisioning.cpp index e0f3608f..e32b8f63 100644 --- a/libwvdrmengine/cdm/core/src/certificate_provisioning.cpp +++ b/libwvdrmengine/cdm/core/src/certificate_provisioning.cpp @@ -97,7 +97,7 @@ bool CertificateProvisioning::FillStableIdField( } else if (origin != EMPTY_ORIGIN) { // Legacy behavior - Concatenate Unique ID with Origin std::string device_unique_id; - if (!crypto_session_.GetDeviceUniqueId(&device_unique_id)) { + if (!crypto_session_.GetInternalDeviceUniqueId(&device_unique_id)) { LOGE("CryptoSession::GetStableIdField: Failure to get device unique ID"); return false; } diff --git a/libwvdrmengine/cdm/core/src/crypto_session.cpp b/libwvdrmengine/cdm/core/src/crypto_session.cpp index 80cab2e6..4962d870 100644 --- a/libwvdrmengine/cdm/core/src/crypto_session.cpp +++ b/libwvdrmengine/cdm/core/src/crypto_session.cpp @@ -13,6 +13,7 @@ #include "crypto_key.h" #include "log.h" #include "metrics_front_end.h" +#include "openssl/sha.h" #include "properties.h" #include "pst_report.h" #include "string_conversions.h" @@ -242,13 +243,14 @@ CdmSecurityLevel CryptoSession::GetSecurityLevel() { return kSecurityLevelUnknown; } -bool CryptoSession::GetDeviceUniqueId(std::string* device_id) { +bool CryptoSession::GetInternalDeviceUniqueId(std::string* device_id) { if (!device_id) { - LOGE("CryptoSession::GetDeviceUniqueId : No buffer passed to method."); + LOGE("CryptoSession::GetInternalDeviceUniqueId : No buffer passed to " + "method."); return false; } - LOGV("CryptoSession::GetDeviceUniqueId: Lock"); + LOGV("CryptoSession::GetInternalDeviceUniqueId: Lock"); AutoLock auto_lock(crypto_lock_); if (!initialized_) { return false; @@ -281,6 +283,26 @@ bool CryptoSession::GetDeviceUniqueId(std::string* device_id) { } } +bool CryptoSession::GetExternalDeviceUniqueId(std::string* device_id) { + std::string temp; + if (!GetInternalDeviceUniqueId(&temp)) return false; + + if (pre_provision_token_type_ == kClientTokenOemCert) { + // To keep the size of the value passed back to the application down, hash + // the large OEM Public Cert to a smaller value. + uint8_t hash[SHA256_DIGEST_LENGTH]; + SHA256_CTX ctx; + SHA256_Init(&ctx); + SHA256_Update(&ctx, temp.data(), temp.length()); + SHA256_Final(hash, &ctx); + + temp.assign(reinterpret_cast(hash), SHA256_DIGEST_LENGTH); + } + + *device_id = temp; + return true; +} + bool CryptoSession::GetApiVersion(uint32_t* version) { if (!version) { LOGE("CryptoSession::GetApiVersion: No buffer passed to method."); diff --git a/libwvdrmengine/cdm/core/src/license.cpp b/libwvdrmengine/cdm/core/src/license.cpp index 46f11615..276369bb 100644 --- a/libwvdrmengine/cdm/core/src/license.cpp +++ b/libwvdrmengine/cdm/core/src/license.cpp @@ -918,7 +918,7 @@ CdmResponseType CdmLicense::PrepareClientId( client_info->set_name(kBuildInfoKey); client_info->set_value(value); } - if (crypto_session_->GetDeviceUniqueId(&value)) { + if (crypto_session_->GetInternalDeviceUniqueId(&value)) { client_info = client_id->add_client_info(); client_info->set_name(kDeviceIdKey); client_info->set_value(value);