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
This commit is contained in:
Fred Gylys-Colwell
2018-07-01 21:18:33 -07:00
parent bbb89c2d7f
commit 72e260da48
4 changed files with 34 additions and 78 deletions

View File

@@ -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<ServiceCertificate> service_certificate_;

View File

@@ -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<CdmSession> 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<CdmSession>* 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()) {

View File

@@ -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

View File

@@ -875,9 +875,22 @@ CdmResponseType CryptoSession::LoadKeys(
CdmResponseType CryptoSession::LoadEntitledContentKeys(
const std::vector<CryptoKey>& 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) {