From 72e260da48c79027f61f9ceb38d2fe903333d08f Mon Sep 17 00:00:00 2001 From: Fred Gylys-Colwell Date: Sun, 1 Jul 2018 21:18:33 -0700 Subject: [PATCH] Clean merge of Client ID code This CL cleans up some bad merges of client ID code, entitlement keys, and concurrent session access. After this CL, core cdm code on android should match that on widevine at the commit 2f916720 on branch master. CLs merged here are based on: http://go/wvgerrit/50483 Protect sessions from concurrent access http://go/wvgerrit/48860 Remove duplicate information from client identification http://go/wvgerrit/49040 Revert revertion of Client ID Expansion http://go/wvgerrit/46448 Test Entitlement Licenses Test: tested as part of http://go/ag/4674759 Change-Id: I45854d6b034c247b16073a96d6ff3ea953ded3ae --- .../core/include/certificate_provisioning.h | 3 - .../cdm/core/src/cdm_session_map.cpp | 10 +-- .../cdm/core/src/certificate_provisioning.cpp | 80 ++++--------------- .../cdm/core/src/crypto_session.cpp | 19 ++++- 4 files changed, 34 insertions(+), 78 deletions(-) diff --git a/libwvdrmengine/cdm/core/include/certificate_provisioning.h b/libwvdrmengine/cdm/core/include/certificate_provisioning.h index 6f3b00ea..219a9d99 100644 --- a/libwvdrmengine/cdm/core/include/certificate_provisioning.h +++ b/libwvdrmengine/cdm/core/include/certificate_provisioning.h @@ -53,9 +53,6 @@ class CertificateProvisioning { video_widevine::SignedProvisioningMessage::ProtocolVersion GetProtocolVersion(); - bool GetProvisioningTokenType( - video_widevine::ClientIdentification::TokenType* token_type); - CryptoSession crypto_session_; CdmCertificateType cert_type_; scoped_ptr service_certificate_; diff --git a/libwvdrmengine/cdm/core/src/cdm_session_map.cpp b/libwvdrmengine/cdm/core/src/cdm_session_map.cpp index 8f8b2bf0..e94a3173 100644 --- a/libwvdrmengine/cdm/core/src/cdm_session_map.cpp +++ b/libwvdrmengine/cdm/core/src/cdm_session_map.cpp @@ -12,7 +12,10 @@ namespace wvcdm { CdmSessionMap::~CdmSessionMap() { - AutoLock lock(lock_); + Terminate(); +} + +void CdmSessionMap::Terminate() { for (CdmIdToSessionMap::iterator i = sessions_.begin(); i != sessions_.end(); ++i) { i->second->Close(); @@ -22,12 +25,10 @@ CdmSessionMap::~CdmSessionMap() { } void CdmSessionMap::Add(const std::string& id, CdmSession* session) { - AutoLock lock(lock_); sessions_[id].reset(session); } bool CdmSessionMap::CloseSession(const std::string& id) { - AutoLock lock(lock_); shared_ptr session; if (!FindSessionNoLock(id, &session)) { return false; @@ -38,13 +39,11 @@ bool CdmSessionMap::CloseSession(const std::string& id) { } bool CdmSessionMap::Exists(const std::string& id) { - AutoLock lock(lock_); return sessions_.find(id) != sessions_.end(); } bool CdmSessionMap::FindSession(const CdmSessionId& id, shared_ptr* session) { - AutoLock lock(lock_); return FindSessionNoLock(id, session); } @@ -61,7 +60,6 @@ bool CdmSessionMap::FindSessionNoLock(const CdmSessionId& session_id, void CdmSessionMap::GetSessionList(CdmSessionList& sessions) { sessions.clear(); - AutoLock lock(lock_); for (CdmIdToSessionMap::iterator iter = sessions_.begin(); iter != sessions_.end(); ++iter) { if (!(iter->second)->IsClosed()) { diff --git a/libwvdrmengine/cdm/core/src/certificate_provisioning.cpp b/libwvdrmengine/cdm/core/src/certificate_provisioning.cpp index 487ee7fc..0d3345b6 100644 --- a/libwvdrmengine/cdm/core/src/certificate_provisioning.cpp +++ b/libwvdrmengine/cdm/core/src/certificate_provisioning.cpp @@ -15,8 +15,6 @@ namespace { -const std::string kKeyBuildInfo = "build_info"; - // URL for Google Provisioning Server. // The provisioning server supplies the certificate that is needed // to communicate with the License Server. @@ -194,12 +192,6 @@ CdmResponseType CertificateProvisioning::GetProvisioningRequest( // Prepare device provisioning request. ProvisioningRequest provisioning_request; - video_widevine::ClientIdentification::TokenType token_type; - if (!GetProvisioningTokenType(&token_type)) { - LOGE("GetProvisioningRequest: failure getting provisioning token type"); - return CLIENT_IDENTIFICATION_TOKEN_ERROR_1; - } - wvcdm::ClientIdentification id; status = id.Init(&crypto_session_); if (status != NO_ERROR) return status; @@ -207,47 +199,23 @@ CdmResponseType CertificateProvisioning::GetProvisioningRequest( video_widevine::ClientIdentification* client_id = provisioning_request.mutable_client_id(); - if (token_type == video_widevine::ClientIdentification::KEYBOX) { - CdmAppParameterMap app_parameter; - status = id.Prepare(app_parameter, client_id); - if (status != NO_ERROR) return status; + CdmAppParameterMap app_parameter; + status = id.Prepare(app_parameter, client_id); + if (status != NO_ERROR) return status; - if (!service_certificate_->has_certificate()) { - LOGE("CertificateProvisioning::GetProvisioningRequest: Service " - "Certificate not staged"); - return CERT_PROVISIONING_EMPTY_SERVICE_CERTIFICATE; - } - - // Encrypt client identification - EncryptedClientIdentification* encrypted_client_id = - provisioning_request.mutable_encrypted_client_id(); - status = service_certificate_->EncryptClientId(&crypto_session_, client_id, - encrypted_client_id); - provisioning_request.clear_client_id(); - } else { - // TODO(rfrias,juce,b/78303730) provide encrypted client identification - // for devices whose root of trust is OEM_DEVICE_CERTIFICATES. - // Prerequisite is that apps need to transition to sending the - // provisioning request in the HTTP POST body. - client_id->set_type(token_type); - - std::string token; - if (!crypto_session_.GetProvisioningToken(&token)) { - LOGE("GetProvisioningRequest: failure getting provisioning token"); - return CLIENT_IDENTIFICATION_TOKEN_ERROR_2; - } - client_id->set_token(token); - - std::string value; - if (Properties::GetBuildInfo(&value)) { - ClientIdentification_NameValue* client_info; - - client_info = client_id->add_client_info(); - client_info->set_name(kKeyBuildInfo); - client_info->set_value(value); - } + if (!service_certificate_->has_certificate()) { + LOGE("CertificateProvisioning::GetProvisioningRequest: Service " + "Certificate not staged"); + return CERT_PROVISIONING_EMPTY_SERVICE_CERTIFICATE; } + // Encrypt client identification + EncryptedClientIdentification* encrypted_client_id = + provisioning_request.mutable_encrypted_client_id(); + status = service_certificate_->EncryptClientId(&crypto_session_, client_id, + encrypted_client_id); + provisioning_request.clear_client_id(); + uint32_t nonce; if (!crypto_session_.GenerateNonce(&nonce)) { LOGE("GetProvisioningRequest: fails to generate a nonce"); @@ -435,24 +403,4 @@ CdmResponseType CertificateProvisioning::HandleProvisioningResponse( return NO_ERROR; } -bool CertificateProvisioning::GetProvisioningTokenType( - video_widevine::ClientIdentification::TokenType* token_type) { - CdmClientTokenType token = crypto_session_.GetPreProvisionTokenType(); - switch (token) { - case kClientTokenKeybox: - *token_type = video_widevine::ClientIdentification::KEYBOX; - return true; - case kClientTokenOemCert: - *token_type = - video_widevine::ClientIdentification::OEM_DEVICE_CERTIFICATE; - return true; - case kClientTokenDrmCert: - default: - // shouldn't happen - LOGE("CertificateProvisioning::GetProvisioningTokenType: unexpected " - "provisioning type: %d", token); - return false; - } -} - } // namespace wvcdm diff --git a/libwvdrmengine/cdm/core/src/crypto_session.cpp b/libwvdrmengine/cdm/core/src/crypto_session.cpp index aeecca26..8b3351e6 100644 --- a/libwvdrmengine/cdm/core/src/crypto_session.cpp +++ b/libwvdrmengine/cdm/core/src/crypto_session.cpp @@ -875,9 +875,22 @@ CdmResponseType CryptoSession::LoadKeys( CdmResponseType CryptoSession::LoadEntitledContentKeys( const std::vector& key_array) { - // TODO(jfore): Handle and return errors. - /*OEMCryptoResult status =*/ key_session_->LoadEntitledContentKeys(key_array); - return KEY_ADDED; + LOGV("CryptoSession::LoadEntitledContentKeys: Lock"); + AutoLock auto_lock(crypto_lock_); + + OEMCryptoResult sts = key_session_->LoadEntitledContentKeys(key_array); + + if (OEMCrypto_SUCCESS == sts) { + return KEY_ADDED; + } else if (OEMCrypto_ERROR_INSUFFICIENT_RESOURCES == sts) { + return INSUFFICIENT_CRYPTO_RESOURCES_6; + } else if (OEMCrypto_ERROR_INVALID_CONTEXT == sts) { + return NOT_AN_ENTITLEMENT_SESSION; + } else if (OEMCrypto_KEY_NOT_ENTITLED == sts) { + return NO_MATCHING_ENTITLEMENT_KEY; + } else { + return LOAD_ENTITLED_CONTENT_KEYS_ERROR; + } } bool CryptoSession::LoadCertificatePrivateKey(std::string& wrapped_key) {