Merge "First-stage Provisioning 4.0 client ID encryption" into tm-dev am: 7d78ce9ac8 am: 22d2ba8bf1 am: 8db98d1bc9

Original change: https://googleplex-android-review.googlesource.com/c/platform/vendor/widevine/+/17949160

Change-Id: Ib97df795cd954fde73758d6fdc2747eb18c26672
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
John Bruce
2022-04-29 18:44:34 +00:00
committed by Automerger Merge Worker
4 changed files with 34 additions and 23 deletions

View File

@@ -86,7 +86,8 @@ class CertificateProvisioning {
std::string* default_url); std::string* default_url);
CdmResponseType FillEncryptedClientId( CdmResponseType FillEncryptedClientId(
const std::string& client_token, const std::string& client_token,
video_widevine::ProvisioningRequest& provisioning_request); video_widevine::ProvisioningRequest& provisioning_request,
const ServiceCertificate& service_certificate);
CdmResponseType HandleProvisioning40Response( CdmResponseType HandleProvisioning40Response(
wvutil::FileSystem* file_system, const std::string& response_message); wvutil::FileSystem* file_system, const std::string& response_message);

View File

@@ -38,8 +38,8 @@ class ServiceCertificate {
const std::string& provider_id() const { return provider_id_; } const std::string& provider_id() const { return provider_id_; }
// Verify the signature for a message. // Verify the signature for a message.
virtual CdmResponseType VerifySignedMessage(const std::string& message, virtual CdmResponseType VerifySignedMessage(
const std::string& signature); const std::string& message, const std::string& signature) const;
// Encrypt the ClientIdentification message for a provisioning or // Encrypt the ClientIdentification message for a provisioning or
// licensing request. Encryption is performed using the current // licensing request. Encryption is performed using the current
@@ -50,7 +50,7 @@ class ServiceCertificate {
virtual CdmResponseType EncryptClientId( virtual CdmResponseType EncryptClientId(
CryptoSession* crypto_session, CryptoSession* crypto_session,
const video_widevine::ClientIdentification* clear_client_id, const video_widevine::ClientIdentification* clear_client_id,
video_widevine::EncryptedClientIdentification* encrypted_client_id); video_widevine::EncryptedClientIdentification* encrypted_client_id) const;
// Helper methods // Helper methods
static bool GetRequest(CdmKeyMessage* request); static bool GetRequest(CdmKeyMessage* request);
@@ -63,7 +63,7 @@ class ServiceCertificate {
// string to contain the decrypted data on return, and may not be null. // string to contain the decrypted data on return, and may not be null.
// returns NO_ERROR if successful or an appropriate error code otherwise. // returns NO_ERROR if successful or an appropriate error code otherwise.
virtual CdmResponseType EncryptRsaOaep(const std::string& plaintext, virtual CdmResponseType EncryptRsaOaep(const std::string& plaintext,
std::string* ciphertext); std::string* ciphertext) const;
// Track whether object holds valid certificate // Track whether object holds valid certificate
bool has_certificate_; bool has_certificate_;

View File

@@ -218,7 +218,8 @@ CdmResponseType CertificateProvisioning::GetProvisioningRequestInternal(
// Prepare device provisioning request. // Prepare device provisioning request.
ProvisioningRequest provisioning_request; ProvisioningRequest provisioning_request;
status = FillEncryptedClientId(/*client_token=*/"", provisioning_request); status = FillEncryptedClientId(/*client_token=*/"", provisioning_request,
*service_certificate_);
if (status != NO_ERROR) return status; if (status != NO_ERROR) return status;
uint32_t nonce; uint32_t nonce;
@@ -339,24 +340,33 @@ CdmResponseType CertificateProvisioning::GetProvisioning40RequestInternal(
} }
} }
CdmResponseType status = NO_ERROR;
if (stored_oem_cert.empty()) { if (stored_oem_cert.empty()) {
// This is the first stage provisioning. // This is the first stage provisioning.
default_url->assign(kProvisioningServerUrl + default_url->assign(kProvisioningServerUrl +
kProv40FirstStageServerUrlSuffix); kProv40FirstStageServerUrlSuffix);
// First-stage provisioning always uses the WV production service cert for
// encryption.
ServiceCertificate wv_service_cert;
status = wv_service_cert.Init(kCpProductionServiceCertificate);
if (status != NO_ERROR) return status;
// Since |stored_oem_cert| is empty, the client identification token will be
// retrieved from OEMCrypto, which is the BCC in this case.
status = FillEncryptedClientId(stored_oem_cert, provisioning_request,
wv_service_cert);
if (status != NO_ERROR) return status;
} else { } else {
// This is the second stage provisioning. // This is the second stage provisioning.
default_url->assign(kProvisioningServerUrl); default_url->assign(kProvisioningServerUrl);
// Since |stored_oem_cert| is non-empty, it will be used as the client
// identification token.
status = FillEncryptedClientId(stored_oem_cert, provisioning_request,
*service_certificate_);
if (status != NO_ERROR) return status;
} }
// If this is the first stage, |stored_oem_cert| remains empty. In this case,
// the client identification token will be retrieved from OEMCrypto, which is
// the BCC in this case.
// If this is the second stage, |stored_oem_cert| is non-empty and will be
// used as the client identification token.
CdmResponseType status =
FillEncryptedClientId(stored_oem_cert, provisioning_request);
if (status != NO_ERROR) return status;
std::string public_key; std::string public_key;
std::string public_key_signature; std::string public_key_signature;
provisioning_40_wrapped_private_key_.clear(); provisioning_40_wrapped_private_key_.clear();
@@ -396,8 +406,8 @@ CdmResponseType CertificateProvisioning::GetProvisioning40RequestInternal(
} }
CdmResponseType CertificateProvisioning::FillEncryptedClientId( CdmResponseType CertificateProvisioning::FillEncryptedClientId(
const std::string& client_token, const std::string& client_token, ProvisioningRequest& provisioning_request,
ProvisioningRequest& provisioning_request) { const ServiceCertificate& service_certificate) {
if (!crypto_session_->IsOpen()) { if (!crypto_session_->IsOpen()) {
return UNKNOWN_ERROR; return UNKNOWN_ERROR;
} }
@@ -412,13 +422,13 @@ CdmResponseType CertificateProvisioning::FillEncryptedClientId(
status = id.Prepare(app_parameter, kEmptyString, &client_id); status = id.Prepare(app_parameter, kEmptyString, &client_id);
if (status != NO_ERROR) return status; if (status != NO_ERROR) return status;
if (!service_certificate_->has_certificate()) { if (!service_certificate.has_certificate()) {
LOGE("Service certificate not staged"); LOGE("Service certificate not staged");
return CERT_PROVISIONING_EMPTY_SERVICE_CERTIFICATE; return CERT_PROVISIONING_EMPTY_SERVICE_CERTIFICATE;
} }
// Encrypt client identification // Encrypt client identification
return service_certificate_->EncryptClientId( return service_certificate.EncryptClientId(
crypto_session_.get(), &client_id, crypto_session_.get(), &client_id,
provisioning_request.mutable_encrypted_client_id()); provisioning_request.mutable_encrypted_client_id());
} }

View File

@@ -206,7 +206,7 @@ CdmResponseType ServiceCertificate::Init(const std::string& certificate) {
} }
CdmResponseType ServiceCertificate::VerifySignedMessage( CdmResponseType ServiceCertificate::VerifySignedMessage(
const std::string& message, const std::string& signature) { const std::string& message, const std::string& signature) const {
if (!public_key_) { if (!public_key_) {
LOGE("Service certificate not set"); LOGE("Service certificate not set");
return DEVICE_CERTIFICATE_ERROR_4; return DEVICE_CERTIFICATE_ERROR_4;
@@ -218,8 +218,8 @@ CdmResponseType ServiceCertificate::VerifySignedMessage(
return NO_ERROR; return NO_ERROR;
} }
CdmResponseType ServiceCertificate::EncryptRsaOaep(const std::string& plaintext, CdmResponseType ServiceCertificate::EncryptRsaOaep(
std::string* ciphertext) { const std::string& plaintext, std::string* ciphertext) const {
if (!public_key_) { if (!public_key_) {
LOGE("Service certificate not set"); LOGE("Service certificate not set");
return DEVICE_CERTIFICATE_ERROR_4; return DEVICE_CERTIFICATE_ERROR_4;
@@ -233,7 +233,7 @@ CdmResponseType ServiceCertificate::EncryptRsaOaep(const std::string& plaintext,
CdmResponseType ServiceCertificate::EncryptClientId( CdmResponseType ServiceCertificate::EncryptClientId(
CryptoSession* crypto_session, const ClientIdentification* clear_client_id, CryptoSession* crypto_session, const ClientIdentification* clear_client_id,
EncryptedClientIdentification* encrypted_client_id) { EncryptedClientIdentification* encrypted_client_id) const {
encrypted_client_id->set_provider_id(provider_id_); encrypted_client_id->set_provider_id(provider_id_);
encrypted_client_id->set_service_certificate_serial_number(serial_number_); encrypted_client_id->set_service_certificate_serial_number(serial_number_);