From cc35c647572d1efaf3cdb11cc4616a511f8980fd Mon Sep 17 00:00:00 2001 From: Alex Dale Date: Fri, 15 Apr 2022 20:14:51 -0700 Subject: [PATCH 1/3] Specify DRM certificate duration in tests. [ Merge of http://go/wvgerrit/150350 ] Certain integration tests were depending on the provisioning server only sending short duration (~2 minute) certificates when testing the CDM's ability to enforce expiration periods. This behavior of the server was not reliable, resulting in device test failures from server behavior changes. The DRM certificate provisioning server allows the requester to optionally provide a desired certificate duration in the request URL. The tests which test the CDM's ability to enforce certificate durations will now explicitly specify the certificate duration required by the test. Bug: 228547158 Test: request_license_test Change-Id: Ib9ebfdba1451104be0e59baca0b2f23a94cd51e6 --- .../include/wv_content_decryption_module.h | 2 +- .../cdm/src/wv_content_decryption_module.cpp | 2 +- .../cdm/test/request_license_test.cpp | 92 ++++++++++++++----- .../mediadrm/test/WVDrmPlugin_test.cpp | 2 +- 4 files changed, 71 insertions(+), 27 deletions(-) diff --git a/libwvdrmengine/cdm/include/wv_content_decryption_module.h b/libwvdrmengine/cdm/include/wv_content_decryption_module.h index 511a88bf..bc6145f8 100644 --- a/libwvdrmengine/cdm/include/wv_content_decryption_module.h +++ b/libwvdrmengine/cdm/include/wv_content_decryption_module.h @@ -92,7 +92,7 @@ class WvContentDecryptionModule : public android::RefBase, public TimerHandler { CdmProvisioningRequest* request, std::string* default_url); virtual CdmResponseType HandleProvisioningResponse( - const CdmIdentifier& identifier, CdmProvisioningResponse& response, + const CdmIdentifier& identifier, const CdmProvisioningResponse& response, RequestedSecurityLevel requested_security_level, std::string* cert, std::string* wrapped_key); diff --git a/libwvdrmengine/cdm/src/wv_content_decryption_module.cpp b/libwvdrmengine/cdm/src/wv_content_decryption_module.cpp index 2ff88768..a0f6edae 100644 --- a/libwvdrmengine/cdm/src/wv_content_decryption_module.cpp +++ b/libwvdrmengine/cdm/src/wv_content_decryption_module.cpp @@ -227,7 +227,7 @@ CdmResponseType WvContentDecryptionModule::GetProvisioningRequest( } CdmResponseType WvContentDecryptionModule::HandleProvisioningResponse( - const CdmIdentifier& identifier, CdmProvisioningResponse& response, + const CdmIdentifier& identifier, const CdmProvisioningResponse& response, RequestedSecurityLevel requested_security_level, std::string* cert, std::string* wrapped_key) { CdmEngine* cdm_engine = EnsureCdmForIdentifier(identifier); diff --git a/libwvdrmengine/cdm/test/request_license_test.cpp b/libwvdrmengine/cdm/test/request_license_test.cpp index 21cff53d..b960cbcb 100644 --- a/libwvdrmengine/cdm/test/request_license_test.cpp +++ b/libwvdrmengine/cdm/test/request_license_test.cpp @@ -52,7 +52,11 @@ namespace { // HTTP response codes. const int kHttpOk = 200; -const int kDrmCertificateExpiryPeriod = 150; + +// For tests checking functionality of expiring. +constexpr uint32_t kDrmCertificateExpiryPeriod = 120; +constexpr uint32_t kDrmCertificateExpirySleepPeriod = + kDrmCertificateExpiryPeriod + 30; const wvcdm::CdmIdentifier kExampleIdentifier = { wvcdm::EMPTY_SPOID, "com.example", "com.example", 7, 9}; @@ -1868,11 +1872,26 @@ class WvCdmRequestLicenseTest : public WvCdmTestBase { // Post a request and extract the signed provisioning message from // the HTTP response. - std::string GetCertRequestResponse(const std::string& server_url) { + // Setting a non-zero value to |duration_seconds| will request a + // limited duration DRM certificate. + std::string GetCertRequestResponse(const std::string& server_url, + uint32_t duration_seconds = 0) { // Use secure connection and chunk transfer coding. - UrlRequest url_request(server_url); + std::string actual_url = server_url; + if (duration_seconds > 0) { + const auto query_start = actual_url.find('?'); + if (query_start == std::string::npos) { + actual_url.push_back('?'); + } else { + actual_url.push_back('&'); + } + actual_url.append("options.expiration_delta_seconds="); + actual_url.append(std::to_string(duration_seconds)); + } + + UrlRequest url_request(actual_url); EXPECT_TRUE(url_request.is_connected()) - << "Fail to connect to " << server_url; + << "Fail to connect to " << actual_url; url_request.PostCertRequestInQueryString(key_msg_); std::string message; EXPECT_TRUE(url_request.GetResponse(&message)); @@ -2573,6 +2592,10 @@ TEST_F(WvCdmRequestLicenseTest, ProvisioningRevocationTest) { } } +// Test checks that the CDM correctly reports provisioning status when +// a certificate has expired. It is expected that the CDM reports that +// the specified CDM engine is provisioned only during the certificate's +// validity period. TEST_F(WvCdmRequestLicenseTest, ProvisioningWithExpiringCertTest) { EXPECT_EQ(NO_ERROR, decryptor_->Unprovision(kSecurityLevelL1, kExampleIdentifier)); @@ -2584,7 +2607,7 @@ TEST_F(WvCdmRequestLicenseTest, ProvisioningWithExpiringCertTest) { // Provision std::string provisioning_server; - CdmCertificateType cert_type = kCertificateWidevine; + const CdmCertificateType cert_type = kCertificateWidevine; std::string cert_authority, cert, wrapped_key; EXPECT_EQ(wvcdm::NO_ERROR, decryptor_->GetProvisioningRequest( @@ -2592,18 +2615,19 @@ TEST_F(WvCdmRequestLicenseTest, ProvisioningWithExpiringCertTest) { kEmptyServiceCertificate, kLevelDefault, &key_msg_, &provisioning_server)); - std::string response = GetCertRequestResponse(config.provisioning_server()); - EXPECT_NE(0, static_cast(response.size())); + const std::string response = GetCertRequestResponse( + config.provisioning_server(), kDrmCertificateExpiryPeriod); + EXPECT_FALSE(response.empty()) << "Failed to get DRM provisioning response"; EXPECT_EQ(wvcdm::NO_ERROR, decryptor_->HandleProvisioningResponse( kExampleIdentifier, response, kLevelDefault, &cert, &wrapped_key)); - EXPECT_EQ(0, static_cast(cert.size())); - EXPECT_EQ(0, static_cast(wrapped_key.size())); - decryptor_->CloseSession(session_id_); + EXPECT_TRUE(cert.empty()) << "Widevine certs should not be returned"; + EXPECT_TRUE(wrapped_key.empty()) + << "Keys from Widevine certs should not be returned"; // Make sure it is provisioned, then wait for certificate expiry period EXPECT_TRUE(IsProvisioned(kExampleIdentifier, kLevelDefault)); - sleep(kDrmCertificateExpiryPeriod); + sleep(kDrmCertificateExpirySleepPeriod); // Verify that it is no longer provisioned after the certificate expires EXPECT_FALSE(IsProvisioned(kExampleIdentifier, kLevelDefault)); @@ -2781,6 +2805,8 @@ TEST_F(WvCdmRequestLicenseTest, AddStreamingKeyTest) { decryptor_->CloseSession(session_id_); } +// Test checks that the CDM does not allow key request generations +// if the DRM certificate is expired. TEST_F(WvCdmRequestLicenseTest, StreamingWithExpiringCertTest) { EXPECT_EQ(NO_ERROR, decryptor_->Unprovision(kSecurityLevelL1, kExampleIdentifier)); @@ -2800,13 +2826,15 @@ TEST_F(WvCdmRequestLicenseTest, StreamingWithExpiringCertTest) { kEmptyServiceCertificate, kLevelDefault, &key_msg_, &provisioning_server)); - std::string response = GetCertRequestResponse(config.provisioning_server()); - EXPECT_NE(0, static_cast(response.size())); + const std::string response = GetCertRequestResponse( + config.provisioning_server(), kDrmCertificateExpiryPeriod); + EXPECT_FALSE(response.empty()) << "Failed to get DRM provisioning response"; EXPECT_EQ(wvcdm::NO_ERROR, decryptor_->HandleProvisioningResponse( kExampleIdentifier, response, kLevelDefault, &cert, &wrapped_key)); - EXPECT_EQ(0, static_cast(cert.size())); - EXPECT_EQ(0, static_cast(wrapped_key.size())); + EXPECT_TRUE(cert.empty()) << "Widevine certs should not be returned"; + EXPECT_TRUE(wrapped_key.empty()) + << "Keys from Widevine certs should not be returned"; EXPECT_TRUE(IsProvisioned(kExampleIdentifier, kLevelDefault)); @@ -2821,6 +2849,17 @@ TEST_F(WvCdmRequestLicenseTest, StreamingWithExpiringCertTest) { nullptr); VerifyKeyRequestResponse(config_.license_server(), config_.client_auth()); decryptor_->CloseSession(session_id_); + + sleep(kDrmCertificateExpirySleepPeriod); + + // Fetch another stream license, after expiry. + EXPECT_EQ(NO_ERROR, + decryptor_->OpenSession(config_.key_system(), nullptr, + kExampleIdentifier, nullptr, &session_id_)); + GenerateKeyRequest(NEED_PROVISIONING, ISO_BMFF_VIDEO_MIME_TYPE, + binary_key_id(), app_parameters, kLicenseTypeStreaming, + kExampleIdentifier, nullptr); + decryptor_->CloseSession(session_id_); } TEST_F(WvCdmRequestLicenseTest, AddKeyOfflineTest) { @@ -2864,6 +2903,8 @@ TEST_F(WvCdmRequestLicenseTest, RestoreOfflineKeyTest) { decryptor_->CloseSession(session_id_); } +// Test checks that the CDM allows reloading of previously acquired offline +// licenses even if the DRM certificate has expired. TEST_F(WvCdmRequestLicenseTest, RestoreOfflineKeysWithExpiringCertTest) { EXPECT_EQ(NO_ERROR, decryptor_->Unprovision(kSecurityLevelL1, kExampleIdentifier)); @@ -2875,7 +2916,7 @@ TEST_F(WvCdmRequestLicenseTest, RestoreOfflineKeysWithExpiringCertTest) { // Provision std::string provisioning_server; - CdmCertificateType cert_type = kCertificateWidevine; + const CdmCertificateType cert_type = kCertificateWidevine; std::string cert_authority, cert, wrapped_key; EXPECT_EQ(wvcdm::NO_ERROR, decryptor_->GetProvisioningRequest( @@ -2883,13 +2924,15 @@ TEST_F(WvCdmRequestLicenseTest, RestoreOfflineKeysWithExpiringCertTest) { kEmptyServiceCertificate, kLevelDefault, &key_msg_, &provisioning_server)); - std::string response = GetCertRequestResponse(config.provisioning_server()); - EXPECT_NE(0, static_cast(response.size())); + const std::string response = GetCertRequestResponse( + config.provisioning_server(), kDrmCertificateExpiryPeriod); + EXPECT_FALSE(response.empty()) << "Failed to get DRM provisioning response"; EXPECT_EQ(wvcdm::NO_ERROR, decryptor_->HandleProvisioningResponse( kExampleIdentifier, response, kLevelDefault, &cert, &wrapped_key)); - EXPECT_EQ(0, static_cast(cert.size())); - EXPECT_EQ(0, static_cast(wrapped_key.size())); + EXPECT_TRUE(cert.empty()) << "Widevine certs should not be returned"; + EXPECT_TRUE(wrapped_key.empty()) + << "Keys from Widevine certs should not be returned"; EXPECT_TRUE(IsProvisioned(kExampleIdentifier, kLevelDefault)); @@ -2908,19 +2951,20 @@ TEST_F(WvCdmRequestLicenseTest, RestoreOfflineKeysWithExpiringCertTest) { nullptr); VerifyKeyRequestResponse(config_.license_server(), client_auth); - CdmKeySetId key_set_id = key_set_id_; + const CdmKeySetId key_set_id = key_set_id_; EXPECT_FALSE(key_set_id_.empty()); decryptor_->CloseSession(session_id_); session_id_.clear(); // Wait till certificate expires - sleep(kDrmCertificateExpiryPeriod); + sleep(kDrmCertificateExpirySleepPeriod); - // Make sure the certificate has expired and the device is not provisioned + // Make sure the certificate has expired and the device is not provisioned. EXPECT_FALSE(IsProvisioned(kExampleIdentifier, kLevelDefault)); - // Restore offline license + // Restore offline license. Key restoration should not be prevented + // by the expired DRM certificate. decryptor_->OpenSession(config_.key_system(), nullptr, kExampleIdentifier, nullptr, &session_id_); EXPECT_EQ(wvcdm::KEY_ADDED, decryptor_->RestoreKey(session_id_, key_set_id)); diff --git a/libwvdrmengine/mediadrm/test/WVDrmPlugin_test.cpp b/libwvdrmengine/mediadrm/test/WVDrmPlugin_test.cpp index 8e567b32..b74ad900 100644 --- a/libwvdrmengine/mediadrm/test/WVDrmPlugin_test.cpp +++ b/libwvdrmengine/mediadrm/test/WVDrmPlugin_test.cpp @@ -194,7 +194,7 @@ class MockCDM : public WvContentDecryptionModule { std::string*), (override)); MOCK_METHOD(CdmResponseType, HandleProvisioningResponse, - (const CdmIdentifier&, CdmProvisioningResponse&, + (const CdmIdentifier&, const CdmProvisioningResponse&, wvcdm::RequestedSecurityLevel, std::string*, std::string*), (override)); MOCK_METHOD(CdmResponseType, Unprovision, (CdmSecurityLevel, From a80a9fef26b7e695e4072293aad8f6b7bdce613d Mon Sep 17 00:00:00 2001 From: Alex Dale Date: Fri, 22 Apr 2022 13:53:11 -0700 Subject: [PATCH 2/3] Added mutex for reserved_license_ids_. [ Merge of http://go/wvgerrit/150630 ] DeviceFiles uses a static variable for tracking license IDs which have been reserved by a CDM session before officially storing the license on the device. This variable was not protected by a mutex, and a rare race condition would arise, either crashing the service or getting it stuck in a loop. This CL adds a mutex for protecting the set of reserved IDs. Bug: 226555704 Test: device_files_unittest Change-Id: Icdea88673c76c267b4b7db79697ec52ae8e2581e --- libwvdrmengine/cdm/core/include/device_files.h | 2 ++ libwvdrmengine/cdm/core/src/device_files.cpp | 7 +++++++ 2 files changed, 9 insertions(+) diff --git a/libwvdrmengine/cdm/core/include/device_files.h b/libwvdrmengine/cdm/core/include/device_files.h index d23a5d45..8b3926ef 100644 --- a/libwvdrmengine/cdm/core/include/device_files.h +++ b/libwvdrmengine/cdm/core/include/device_files.h @@ -5,6 +5,7 @@ #ifndef WVCDM_CORE_DEVICE_FILES_H_ #define WVCDM_CORE_DEVICE_FILES_H_ +#include #include #include #include @@ -369,6 +370,7 @@ class DeviceFiles { #endif static std::set reserved_license_ids_; + static std::mutex reserved_license_ids_mutex_; wvutil::FileSystem* file_system_; CdmSecurityLevel security_level_; diff --git a/libwvdrmengine/cdm/core/src/device_files.cpp b/libwvdrmengine/cdm/core/src/device_files.cpp index 2602171b..e18fac0a 100644 --- a/libwvdrmengine/cdm/core/src/device_files.cpp +++ b/libwvdrmengine/cdm/core/src/device_files.cpp @@ -87,6 +87,8 @@ using video_widevine_client::sdk:: } namespace wvcdm { +using UniqueLock = std::unique_lock; + namespace { const char kEmptyFileName[] = ""; const char kFalse[] = "false"; @@ -364,6 +366,7 @@ const char* DeviceFiles::ResponseTypeToString(ResponseType type) { // static std::set DeviceFiles::reserved_license_ids_; +std::mutex DeviceFiles::reserved_license_ids_mutex_; DeviceFiles::DeviceFiles(wvutil::FileSystem* file_system) : file_system_(file_system), @@ -847,6 +850,7 @@ bool DeviceFiles::StoreLicense(const CdmLicenseData& license_data, std::string serialized_file; file.SerializeToString(&serialized_file); + UniqueLock lock(reserved_license_ids_mutex_); reserved_license_ids_.erase(license_data.key_set_id); *result = StoreFileWithHash(license_data.key_set_id + kLicenseFileNameExt, serialized_file); @@ -984,18 +988,21 @@ bool DeviceFiles::DeleteAllFiles() { bool DeviceFiles::LicenseExists(const std::string& key_set_id) { RETURN_FALSE_IF_UNINITIALIZED(); + UniqueLock lock(reserved_license_ids_mutex_); return reserved_license_ids_.count(key_set_id) || FileExists(key_set_id + kLicenseFileNameExt); } bool DeviceFiles::ReserveLicenseId(const std::string& key_set_id) { RETURN_FALSE_IF_UNINITIALIZED(); + UniqueLock lock(reserved_license_ids_mutex_); reserved_license_ids_.insert(key_set_id); return true; } bool DeviceFiles::UnreserveLicenseId(const std::string& key_set_id) { RETURN_FALSE_IF_UNINITIALIZED(); + UniqueLock lock(reserved_license_ids_mutex_); reserved_license_ids_.erase(key_set_id); return true; } From c823a85e7d3e541ad6dfce15b9be49ba15dfe904 Mon Sep 17 00:00:00 2001 From: "John \"Juce\" Bruce" Date: Wed, 20 Apr 2022 14:10:20 -0700 Subject: [PATCH 3/3] First-stage Provisioning 4.0 client ID encryption (This is a merge of http://go/wvgerrit/150131 to the Android repo.) This patch changes the code path in the CDM so that the first-stage provisioning request for Provisioning 4.0 is always encrypted with the Widevine service certificate instead of the client-set service certificate, reflecting that the first-stage provisioning is always handled by Widevine. This patch also makes several methods on the ServiceCertificate class const. This has no impact on their behavior. Bug: 221443151 Test: prov40 tests Change-Id: Ide4c3927afadcd45ae7fb629b99e2f55cc29d56e --- .../core/include/certificate_provisioning.h | 3 +- .../cdm/core/include/service_certificate.h | 8 ++-- .../cdm/core/src/certificate_provisioning.cpp | 38 ++++++++++++------- .../cdm/core/src/service_certificate.cpp | 8 ++-- 4 files changed, 34 insertions(+), 23 deletions(-) diff --git a/libwvdrmengine/cdm/core/include/certificate_provisioning.h b/libwvdrmengine/cdm/core/include/certificate_provisioning.h index 097a8006..05c0cad5 100644 --- a/libwvdrmengine/cdm/core/include/certificate_provisioning.h +++ b/libwvdrmengine/cdm/core/include/certificate_provisioning.h @@ -86,7 +86,8 @@ class CertificateProvisioning { std::string* default_url); CdmResponseType FillEncryptedClientId( const std::string& client_token, - video_widevine::ProvisioningRequest& provisioning_request); + video_widevine::ProvisioningRequest& provisioning_request, + const ServiceCertificate& service_certificate); CdmResponseType HandleProvisioning40Response( wvutil::FileSystem* file_system, const std::string& response_message); diff --git a/libwvdrmengine/cdm/core/include/service_certificate.h b/libwvdrmengine/cdm/core/include/service_certificate.h index 7bd80b26..ced4f4c1 100644 --- a/libwvdrmengine/cdm/core/include/service_certificate.h +++ b/libwvdrmengine/cdm/core/include/service_certificate.h @@ -38,8 +38,8 @@ class ServiceCertificate { const std::string& provider_id() const { return provider_id_; } // Verify the signature for a message. - virtual CdmResponseType VerifySignedMessage(const std::string& message, - const std::string& signature); + virtual CdmResponseType VerifySignedMessage( + const std::string& message, const std::string& signature) const; // Encrypt the ClientIdentification message for a provisioning or // licensing request. Encryption is performed using the current @@ -50,7 +50,7 @@ class ServiceCertificate { virtual CdmResponseType EncryptClientId( CryptoSession* crypto_session, const video_widevine::ClientIdentification* clear_client_id, - video_widevine::EncryptedClientIdentification* encrypted_client_id); + video_widevine::EncryptedClientIdentification* encrypted_client_id) const; // Helper methods static bool GetRequest(CdmKeyMessage* request); @@ -63,7 +63,7 @@ class ServiceCertificate { // string to contain the decrypted data on return, and may not be null. // returns NO_ERROR if successful or an appropriate error code otherwise. virtual CdmResponseType EncryptRsaOaep(const std::string& plaintext, - std::string* ciphertext); + std::string* ciphertext) const; // Track whether object holds valid certificate bool has_certificate_; diff --git a/libwvdrmengine/cdm/core/src/certificate_provisioning.cpp b/libwvdrmengine/cdm/core/src/certificate_provisioning.cpp index 77e20747..2f2f2339 100644 --- a/libwvdrmengine/cdm/core/src/certificate_provisioning.cpp +++ b/libwvdrmengine/cdm/core/src/certificate_provisioning.cpp @@ -218,7 +218,8 @@ CdmResponseType CertificateProvisioning::GetProvisioningRequestInternal( // Prepare device 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; uint32_t nonce; @@ -339,24 +340,33 @@ CdmResponseType CertificateProvisioning::GetProvisioning40RequestInternal( } } + CdmResponseType status = NO_ERROR; if (stored_oem_cert.empty()) { // This is the first stage provisioning. default_url->assign(kProvisioningServerUrl + 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 { // This is the second stage provisioning. 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_signature; provisioning_40_wrapped_private_key_.clear(); @@ -396,8 +406,8 @@ CdmResponseType CertificateProvisioning::GetProvisioning40RequestInternal( } CdmResponseType CertificateProvisioning::FillEncryptedClientId( - const std::string& client_token, - ProvisioningRequest& provisioning_request) { + const std::string& client_token, ProvisioningRequest& provisioning_request, + const ServiceCertificate& service_certificate) { if (!crypto_session_->IsOpen()) { return UNKNOWN_ERROR; } @@ -412,13 +422,13 @@ CdmResponseType CertificateProvisioning::FillEncryptedClientId( status = id.Prepare(app_parameter, kEmptyString, &client_id); if (status != NO_ERROR) return status; - if (!service_certificate_->has_certificate()) { + if (!service_certificate.has_certificate()) { LOGE("Service certificate not staged"); return CERT_PROVISIONING_EMPTY_SERVICE_CERTIFICATE; } // Encrypt client identification - return service_certificate_->EncryptClientId( + return service_certificate.EncryptClientId( crypto_session_.get(), &client_id, provisioning_request.mutable_encrypted_client_id()); } diff --git a/libwvdrmengine/cdm/core/src/service_certificate.cpp b/libwvdrmengine/cdm/core/src/service_certificate.cpp index 47625a7a..2d2947bf 100644 --- a/libwvdrmengine/cdm/core/src/service_certificate.cpp +++ b/libwvdrmengine/cdm/core/src/service_certificate.cpp @@ -206,7 +206,7 @@ CdmResponseType ServiceCertificate::Init(const std::string& certificate) { } CdmResponseType ServiceCertificate::VerifySignedMessage( - const std::string& message, const std::string& signature) { + const std::string& message, const std::string& signature) const { if (!public_key_) { LOGE("Service certificate not set"); return DEVICE_CERTIFICATE_ERROR_4; @@ -218,8 +218,8 @@ CdmResponseType ServiceCertificate::VerifySignedMessage( return NO_ERROR; } -CdmResponseType ServiceCertificate::EncryptRsaOaep(const std::string& plaintext, - std::string* ciphertext) { +CdmResponseType ServiceCertificate::EncryptRsaOaep( + const std::string& plaintext, std::string* ciphertext) const { if (!public_key_) { LOGE("Service certificate not set"); return DEVICE_CERTIFICATE_ERROR_4; @@ -233,7 +233,7 @@ CdmResponseType ServiceCertificate::EncryptRsaOaep(const std::string& plaintext, CdmResponseType ServiceCertificate::EncryptClientId( 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_service_certificate_serial_number(serial_number_);