From c171d024d950dbee30112f7424359a691fadafc6 Mon Sep 17 00:00:00 2001 From: Rahul Frias Date: Wed, 4 Apr 2018 23:29:16 -0700 Subject: [PATCH] Enable encryption of client ID for provisioning [ Merge of http://go/wvgerrit/46760 ] This enables encryption of client ID for provisioning requests for devices with keyboxes as root of trust. Client ID will not be provided for those devices with OEM device certificates as root of trust. That will be addressed in b/78303730. Bug: 77607585 Test: WV unit/integration tests. Tests with L3 using OEM certs Change-Id: Id9bd697aa049bd5659ab80714e141dbc50408f6a --- .../core/include/certificate_provisioning.h | 3 + .../cdm/core/src/certificate_provisioning.cpp | 73 ++++++++++++++----- 2 files changed, 59 insertions(+), 17 deletions(-) diff --git a/libwvdrmengine/cdm/core/include/certificate_provisioning.h b/libwvdrmengine/cdm/core/include/certificate_provisioning.h index 4a825dc8..edf8a737 100644 --- a/libwvdrmengine/cdm/core/include/certificate_provisioning.h +++ b/libwvdrmengine/cdm/core/include/certificate_provisioning.h @@ -52,6 +52,9 @@ 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/certificate_provisioning.cpp b/libwvdrmengine/cdm/core/src/certificate_provisioning.cpp index 7b5387d8..cc9ac0d1 100644 --- a/libwvdrmengine/cdm/core/src/certificate_provisioning.cpp +++ b/libwvdrmengine/cdm/core/src/certificate_provisioning.cpp @@ -192,32 +192,51 @@ 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; video_widevine::ClientIdentification* client_id = provisioning_request.mutable_client_id(); - 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; + if (token_type == video_widevine::ClientIdentification::KEYBOX) { + 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); } - // TODO(rfrias): Uncomment when b/69427217 is addressed - /* - EncryptedClientIdentification* encrypted_client_id = - provisioning_request->mutable_encrypted_client_id(); - CdmResponseType 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"); @@ -405,4 +424,24 @@ 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