Merges to android Pi release (part 8)
These are a set of CLs merged from the wv cdm repo to the android repo. * Android build fixes Author: Rahul Frias <rfrias@google.com> [ Merge of http://go/wvgerrit/36322 ] * Address android compilation errors and warnings Author: Rahul Frias <rfrias@google.com> [ Merge of http://go/wvgerrit/36300 ] * Gyp cleanup and OpenSSL v10.1 support. Author: Gene Morgan <gmorgan@google.com> [ Merge of http://go/wvgerrit/36001 ] OpenSSL 10.1 has a small number of incompatible changes. A desktop system upgrade exposed some issue in the build scripts. Specifically, the linux build was using both third_party/protobufs (2.6.1) and the version installed on the system (3.0 in this case). The linux cdm.gyp depended on cdm/cdm.gyp which caused that plus some additional issues. These changes are necessary to support g++ version: g++ (Debian 6.3.0-18) 6.3.0 20170516 Also did some cosmetic rework on run_current_tests to make it easier to figure out what is going on when something fails. Also tweaked some of the compiler settings for g++ support (revisit this later). * Refactored Service Certificate encryption to allow encryption of arbitrary data. Author: Thomas Inskip <tinskip@google.com> [ Merge of http://go/wvgerrit/36141 ] * Send cdm test requests to UAT. Author: Jeff Fore <jfore@google.com> [ Merge of http://go/wvgerrit/36221 ] This change resolves the all of the CdmDecryptTest/CdmTestWithDecryptParam.DecryptToClearBuffer tests. The license servers will return different keys and keyids. Sending the request to staging returned key ids and keys that were not matching what was expected in the unit tests. * Fix for building L3 OEMCrypto with clang and libc++ Author: yucliu <yucliu@google.com> [ Merge of http://go/wvgerrit/35740 ] 1. Include <time.h> for time(time_t*). 2. Create endian check union on stack. Clang may create const union somewhere else, which may cause crash. * Remove error result when a sublicense session does not exist. This is not considered an error. Author: Jeff Fore <jfore@google.com> [ Merge of http://go/wvgerrit/36080 ] * Set default mock handler for GetSupportedCertificateTypes for all unit tests and removed the use of StrictMock from MockCryptoSession. Author: Jeff Fore <jfore@google.com> [ Merge of http://go/wvgerrit/35922 ] The handler for this was only set for one test and resulted in a number of failures. * Set default handler for GetHdcpCapabilities. For now the default action is to call the real GetHdcpCapabilities of crypto_session. Author: Jeff Fore <jfore@google.com> [ Merge of http://go/wvgerrit/36140 ] I also changed the mock to a NiceMock to silence responses to unexpected calls to GetHdcpCapabilities. The default handler can be overridden as needed in the individual tests. This resolves the policy engine test failures. * Finalize merge of cdm_partner_3.4 to master. Author: Gene Morgan <gmorgan@google.com> [ Merge of http://go/wvgerrit/35360 ] This is the final set of updates to merge all v3.4.1 changes into master. * Embedded license: Sublicense rotation. Author: Jeff Fore <jfore@google.com> [ Merge of http://go/wvgerrit/35360 ] Handle sublicense rotation event. * Embedded license: Initial license phase. Author: Jeff Fore <jfore@google.com> [ Merge of http://go/wvgerrit/34280 ] Initial license phase - key loading subsession. * Embedded license: generate session data. Author: Jeff Fore <jfore@google.com> [ Merge of http://go/wvgerrit/33722 ] Generate session data and add it to the license request for any embedded license material. * Resolve missing symbol when building cd-cdm Author: Jeff Fore <jfore@google.com> [ Merge of http://go/wvgerrit/35840 ] * C++11: Replace OVERRIDE def with override keyword Author: Gene Morgan <gmorgan@google.com> [ Merge of http://go/wvgerrit/35400 ] BUG: 71650075 Test: Not currently passing. Will be addressed in a subsequent commit in the chain. Change-Id: I37d0cb17f255ac6389030047d616ad69f895748c
This commit is contained in:
@@ -245,7 +245,7 @@ CdmResponseType CdmEngine::OpenKeySetSession(
|
||||
}
|
||||
|
||||
CdmResponseType CdmEngine::CloseSession(const CdmSessionId& session_id) {
|
||||
LOGI("CdmEngine::CloseSession");
|
||||
LOGV("CdmEngine::CloseSession: %s", session_id.c_str());
|
||||
if (!session_map_.CloseSession(session_id)) {
|
||||
LOGE("CdmEngine::CloseSession: session not found = %s", session_id.c_str());
|
||||
return SESSION_NOT_FOUND_1;
|
||||
|
||||
@@ -363,6 +363,8 @@ CdmResponseType CdmSession::GenerateKeyRequest(
|
||||
case kLicenseTypeRelease:
|
||||
is_release_ = true;
|
||||
break;
|
||||
case kLicenseTypeSubSession:
|
||||
return license_parser_->HandleSubLicense(init_data);
|
||||
default:
|
||||
LOGE("CdmSession::GenerateKeyRequest: unrecognized license type: %ld",
|
||||
license_type);
|
||||
@@ -390,6 +392,17 @@ CdmResponseType CdmSession::GenerateKeyRequest(
|
||||
return KEY_REQUEST_ERROR_1;
|
||||
}
|
||||
|
||||
std::vector<video_widevine::SubLicense> embedded_key_data =
|
||||
init_data.ExtractEmbeddedKeys();
|
||||
for (size_t i = 0; i < embedded_key_data.size(); ++i) {
|
||||
CdmResponseType sts = crypto_session_->AddSubSession(
|
||||
embedded_key_data[i].sub_session_key_id());
|
||||
if (NO_ERROR != sts) {
|
||||
LOGE("CdmSession::GenerateKeyRequest: Unable to generate sub session");
|
||||
return sts;
|
||||
}
|
||||
}
|
||||
|
||||
app_parameters_ = app_parameters;
|
||||
CdmResponseType status = license_parser_->PrepareKeyRequest(
|
||||
init_data, license_type,
|
||||
@@ -450,12 +463,13 @@ CdmResponseType CdmSession::AddKey(const CdmKeyResponse& key_response) {
|
||||
!provider_session_token.empty() &&
|
||||
usage_table_header_ != nullptr) {
|
||||
if (sts != KEY_ADDED) {
|
||||
CdmResponseType sts =
|
||||
CdmResponseType delete_sts =
|
||||
usage_table_header_->DeleteEntry(usage_entry_number_,
|
||||
file_handle_.get(),
|
||||
crypto_metrics_);
|
||||
if (sts != NO_ERROR) {
|
||||
LOGW("CdmSession::AddKey: Delete usage entry failed = %d", sts);
|
||||
if (delete_sts != NO_ERROR) {
|
||||
LOGW("CdmSession::AddKey: Delete usage entry failed = %d",
|
||||
delete_sts);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -891,8 +905,11 @@ CdmResponseType CdmSession::UpdateUsageEntryInformation() {
|
||||
if (usage_support_type_ != kUsageEntrySupport ||
|
||||
!has_provider_session_token() ||
|
||||
usage_table_header_ == nullptr) {
|
||||
LOGE("CdmSession::UpdateUsageEntryInformation: Unexpected usage type "
|
||||
"supported: %d", usage_support_type_);
|
||||
LOGE("CdmSession::UpdateUsageEntryInformation: Unexpected state, "
|
||||
"usage support type: %d, PST present: %s, usage table header available"
|
||||
": %s", usage_support_type_,
|
||||
has_provider_session_token() ? "yes" : "no",
|
||||
usage_table_header_ == nullptr ? "no" : "yes");
|
||||
return INCORRECT_USAGE_SUPPORT_TYPE_2;
|
||||
}
|
||||
|
||||
|
||||
@@ -83,7 +83,8 @@ using video_widevine::SignedProvisioningMessage;
|
||||
*/
|
||||
bool CertificateProvisioning::GetProvisioningTokenType(
|
||||
ClientIdentification::TokenType* token_type) {
|
||||
switch (crypto_session_.GetPreProvisionTokenType()) {
|
||||
CdmClientTokenType token = crypto_session_.GetPreProvisionTokenType();
|
||||
switch (token) {
|
||||
case kClientTokenKeybox:
|
||||
*token_type = ClientIdentification::KEYBOX;
|
||||
return true;
|
||||
@@ -93,6 +94,8 @@ bool CertificateProvisioning::GetProvisioningTokenType(
|
||||
case kClientTokenDrmCert:
|
||||
default:
|
||||
// shouldn't happen
|
||||
LOGE("CertificateProvisioning::GetProvisioningTokenType: unexpected "
|
||||
"provisioning type: %d", token);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -107,7 +110,7 @@ bool CertificateProvisioning::SetSpoidParameter(
|
||||
const std::string& origin, const std::string& spoid,
|
||||
ProvisioningRequest* request) {
|
||||
if (!request) {
|
||||
LOGE("CertificateProvisioning::SetSpoidParameter : No request buffer "
|
||||
LOGE("CertificateProvisioning::SetSpoidParameter: No request buffer "
|
||||
"passed to method.");
|
||||
return false;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -14,10 +14,6 @@
|
||||
|
||||
namespace {
|
||||
const char kKeyFormatVersionsSeparator = '/';
|
||||
const char kColon = ':';
|
||||
const char kDoubleQuote = '\"';
|
||||
const char kLeftBracket = '[';
|
||||
const char kRightBracket = ']';
|
||||
const std::string kBase64String = "base64,";
|
||||
const uint32_t kFourCcCbc1 = 0x63626331;
|
||||
const uint32_t kFourCcCbcs = 0x63626373;
|
||||
|
||||
@@ -36,7 +36,6 @@ const uint32_t kFourCcCbcs = 0x63626373;
|
||||
const uint32_t kFourCcLittleEndianCbc1 = 0x31636263;
|
||||
const uint32_t kFourCcLittleEndianCbcs = 0x73636263;
|
||||
const uint32_t kFourCcCenc = 0x63656e63;
|
||||
const uint32_t kFourCcCens = 0x63656e73;
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -49,17 +48,41 @@ using video_widevine::ClientIdentification_NameValue;
|
||||
using video_widevine::DrmDeviceCertificate;
|
||||
using video_widevine::EncryptedClientIdentification;
|
||||
using video_widevine::License;
|
||||
using video_widevine::License_KeyContainer;
|
||||
using video_widevine::LicenseError;
|
||||
using video_widevine::LicenseIdentification;
|
||||
using video_widevine::LicenseRequest;
|
||||
using video_widevine::LicenseRequest_ContentIdentification;
|
||||
using video_widevine::LicenseRequest_ContentIdentification_CencDeprecated;
|
||||
using video_widevine::LicenseRequest_ContentIdentification_WebmDeprecated;
|
||||
using video_widevine::LicenseRequest_ContentIdentification_ExistingLicense;
|
||||
using video_widevine::LicenseRequest_ContentIdentification_WebmDeprecated;
|
||||
using video_widevine::License_KeyContainer;
|
||||
using video_widevine::SignedDrmDeviceCertificate;
|
||||
using video_widevine::SignedMessage;
|
||||
|
||||
static std::vector<CryptoKey> ExtractSubSessionKeys(const License& license) {
|
||||
std::vector<CryptoKey> key_array;
|
||||
|
||||
// Extract sub session key(s)
|
||||
for (int i = 0; i < license.key_size(); ++i) {
|
||||
CryptoKey key;
|
||||
switch (license.key(i).type()) {
|
||||
case License_KeyContainer::SUB_SESSION:
|
||||
key.set_key_data(license.key(i).key());
|
||||
key.set_key_data_iv(license.key(i).iv());
|
||||
key.set_key_id(license.key(i).id());
|
||||
key.set_track_label(license.key(i).track_label());
|
||||
key_array.push_back(key);
|
||||
break;
|
||||
|
||||
default:
|
||||
// Ignore all but SUB_SESSION key types.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return key_array;
|
||||
}
|
||||
|
||||
static std::vector<CryptoKey> ExtractContentKeys(const License& license) {
|
||||
std::vector<CryptoKey> key_array;
|
||||
|
||||
@@ -88,6 +111,7 @@ static std::vector<CryptoKey> ExtractContentKeys(const License& license) {
|
||||
if (license.has_protection_scheme()) {
|
||||
four_cc = license.protection_scheme();
|
||||
}
|
||||
key.set_track_label(license.key(i).track_label());
|
||||
switch (four_cc) {
|
||||
// b/30713238: Android N assumed that the "protection scheme" Four
|
||||
// CC code, after being extracted from the protobuf, was host byte
|
||||
@@ -116,11 +140,28 @@ static std::vector<CryptoKey> ExtractContentKeys(const License& license) {
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// Ignore SIGNING key types as they are not content related
|
||||
// Ignore SIGNING and SUB_SESSION key types as they are not content
|
||||
// related.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<CryptoKey> sub_session_keys = ExtractSubSessionKeys(license);
|
||||
// Match the track label from the key arrays and add sub_license_key_id to
|
||||
// the content key array.
|
||||
LOGV("Received %d subsession keys", sub_session_keys.size());
|
||||
if (!sub_session_keys.empty()) {
|
||||
for (size_t i = 0; i < key_array.size(); ++i) {
|
||||
if (key_array[i].track_label().empty()) continue;
|
||||
for (size_t x = 0; x < sub_session_keys.size(); ++x) {
|
||||
if (sub_session_keys[x].track_label() == key_array[i].track_label()) {
|
||||
key_array[i].set_sub_session_key_id(sub_session_keys[x].key_id());
|
||||
key_array[i].set_sub_session_key(sub_session_keys[x].key_data());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return key_array;
|
||||
}
|
||||
|
||||
@@ -222,8 +263,8 @@ CdmResponseType CdmLicense::PrepareKeyRequest(
|
||||
status = PrepareClientId(app_parameters, &license_request);
|
||||
if (NO_ERROR != status) return status;
|
||||
|
||||
status = PrepareContentId(init_data, license_type, request_id,
|
||||
&license_request);
|
||||
status =
|
||||
PrepareContentId(init_data, license_type, request_id, &license_request);
|
||||
if (NO_ERROR != status) return status;
|
||||
|
||||
license_request.set_type(LicenseRequest::NEW);
|
||||
@@ -238,6 +279,37 @@ CdmResponseType CdmLicense::PrepareKeyRequest(
|
||||
}
|
||||
license_request.set_key_control_nonce(nonce);
|
||||
LOGD("PrepareKeyRequest: nonce=%u", nonce);
|
||||
|
||||
// Prepare the request for any embedded keys that may exist in the
|
||||
// initialization data.
|
||||
std::vector<video_widevine::SubLicense> embedded_key_data =
|
||||
init_data.ExtractEmbeddedKeys();
|
||||
for (size_t i = 0; i < embedded_key_data.size(); ++i) {
|
||||
bool exists = false;
|
||||
if (!crypto_session_->GenerateSubSessionNonce(
|
||||
embedded_key_data[i].sub_session_key_id(), &exists, &nonce)) {
|
||||
if (exists) {
|
||||
return LICENSE_REQUEST_NONCE_GENERATION_ERROR;
|
||||
}
|
||||
}
|
||||
SignedMessage signed_sub_license;
|
||||
License_KeyContainer keyc;
|
||||
|
||||
// Parse the sub license for this track to extract the label.
|
||||
if (!signed_sub_license.ParseFromString(embedded_key_data[i].key_msg()) ||
|
||||
!keyc.ParseFromString(signed_sub_license.msg()) ||
|
||||
keyc.track_label().empty()) {
|
||||
return LICENSE_REQUEST_INVALID_SUBLICENSE;
|
||||
}
|
||||
|
||||
LicenseRequest::SubSessionData* sub_session_data =
|
||||
license_request.add_sub_session_data();
|
||||
sub_session_data->set_sub_session_key_id(
|
||||
embedded_key_data[i].sub_session_key_id());
|
||||
sub_session_data->set_nonce(nonce);
|
||||
sub_session_data->set_track_label(keyc.track_label());
|
||||
}
|
||||
|
||||
license_request.set_protocol_version(video_widevine::VERSION_2_1);
|
||||
|
||||
// License request is complete. Serialize it.
|
||||
@@ -333,7 +405,8 @@ CdmResponseType CdmLicense::PrepareKeyUpdateRequest(
|
||||
}
|
||||
|
||||
// TODO(rfrias): Refactor to avoid needing to call CdmSession
|
||||
if (cdm_session) {
|
||||
if (cdm_session &&
|
||||
cdm_session->get_usage_support_type() == kUsageEntrySupport) {
|
||||
CdmResponseType status = cdm_session->UpdateUsageEntryInformation();
|
||||
if (NO_ERROR != status) return status;
|
||||
}
|
||||
@@ -446,7 +519,6 @@ CdmResponseType CdmLicense::HandleKeyResponse(
|
||||
LOGE("CdmLicense::HandleKeyResponse: no session keys present");
|
||||
return SESSION_KEYS_NOT_FOUND;
|
||||
}
|
||||
|
||||
if (!crypto_session_->GenerateDerivedKeys(key_request_,
|
||||
signed_response.session_key()))
|
||||
return GENERATE_DERIVED_KEYS_ERROR;
|
||||
@@ -595,6 +667,48 @@ CdmResponseType CdmLicense::HandleKeyUpdateResponse(
|
||||
}
|
||||
}
|
||||
|
||||
CdmResponseType CdmLicense::HandleSubLicense(
|
||||
const InitializationData& init_data) {
|
||||
std::vector<video_widevine::SubLicense> subkeys =
|
||||
init_data.ExtractEmbeddedKeys();
|
||||
std::set<KeyId> loaded_keys;
|
||||
// Build a license with the rotated keys.
|
||||
License license;
|
||||
for (size_t i = 0; i < subkeys.size(); ++i) {
|
||||
SignedMessage sm;
|
||||
if (!sm.ParseFromString(subkeys[i].key_msg())) {
|
||||
return LICENSE_REQUEST_INVALID_SUBLICENSE;
|
||||
}
|
||||
License_KeyContainer keyc;
|
||||
if (!keyc.ParseFromString(sm.msg())) {
|
||||
return LICENSE_REQUEST_INVALID_SUBLICENSE;
|
||||
}
|
||||
std::vector<CryptoKey> keys;
|
||||
keys.resize(1);
|
||||
keys[0].set_key_id(keyc.id());
|
||||
keys[0].set_key_data(keyc.key());
|
||||
keys[0].set_key_data_iv(keyc.iv());
|
||||
keys[0].set_key_control(keyc.key_control().key_control_block());
|
||||
keys[0].set_key_control_iv(keyc.key_control().iv());
|
||||
keys[0].set_track_label(keyc.track_label());
|
||||
//TODO: passing empty cipher_mode and srm_req params - OK?
|
||||
CdmResponseType result = crypto_session_->LoadKeys(
|
||||
sm.msg(), sm.signature(), std::string(), std::string(), keys,
|
||||
std::string(), std::string());
|
||||
if (result != KEY_ADDED) {
|
||||
LOGE("CdmLicense::HandleSubLicense: LoadKeys() call failed, result=%d",
|
||||
result);
|
||||
return result;
|
||||
}
|
||||
loaded_keys.insert(keyc.id());
|
||||
*license.add_key() = keyc;
|
||||
}
|
||||
loaded_keys_.swap(loaded_keys);
|
||||
policy_engine_->UpdateLicenseKeys(license);
|
||||
|
||||
return KEY_MESSAGE;
|
||||
}
|
||||
|
||||
bool CdmLicense::RestoreOfflineLicense(
|
||||
const CdmKeyMessage& license_request,
|
||||
const CdmKeyResponse& license_response,
|
||||
@@ -642,7 +756,8 @@ bool CdmLicense::RestoreOfflineLicense(
|
||||
}
|
||||
|
||||
if (!provider_session_token_.empty()) {
|
||||
if (cdm_session) {
|
||||
if (cdm_session &&
|
||||
cdm_session->get_usage_support_type() == kUsageEntrySupport) {
|
||||
CdmResponseType status = cdm_session->UpdateUsageEntryInformation();
|
||||
if (NO_ERROR != status) return false;
|
||||
}
|
||||
@@ -1067,8 +1182,7 @@ CdmResponseType CdmLicense::PrepareContentId(
|
||||
|
||||
template <typename T>
|
||||
bool CdmLicense::SetTypeAndId(CdmLicenseType license_type,
|
||||
const std::string& request_id,
|
||||
T* content_id) {
|
||||
const std::string& request_id, T* content_id) {
|
||||
switch (license_type) {
|
||||
case kLicenseTypeOffline:
|
||||
content_id->set_license_type(video_widevine::OFFLINE);
|
||||
|
||||
@@ -18,7 +18,6 @@ namespace {
|
||||
|
||||
const int kCdmPolicyTimerDurationSeconds = 1;
|
||||
const int kClockSkewDelta = 5; // seconds
|
||||
const int64_t kHdcpCheckInterval = 10;
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -169,6 +168,14 @@ void PolicyEngine::SetLicense(const License& license) {
|
||||
UpdateLicense(license);
|
||||
}
|
||||
|
||||
void PolicyEngine::UpdateLicenseKeys(const video_widevine::License& license) {
|
||||
// Use the current policy and set the new keys.
|
||||
video_widevine::License loadable = license;
|
||||
loadable.mutable_policy()->CopyFrom(policy_);
|
||||
license_keys_->SetFromLicense(loadable);
|
||||
NotifyKeysChange(kKeyStatusUsable);
|
||||
}
|
||||
|
||||
void PolicyEngine::SetLicenseForRelease(const License& license) {
|
||||
license_id_.Clear();
|
||||
license_id_.CopyFrom(license.id());
|
||||
|
||||
@@ -88,38 +88,60 @@ bool AesCbcKey::Encrypt(const std::string& in, std::string* out,
|
||||
return false;
|
||||
}
|
||||
|
||||
EVP_CIPHER_CTX ctx;
|
||||
if (EVP_EncryptInit(&ctx, EVP_aes_128_cbc(),
|
||||
#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
|
||||
EVP_CIPHER_CTX ctx_struct;
|
||||
EVP_CIPHER_CTX* evp_cipher_ctx = &ctx_struct;
|
||||
#else
|
||||
EVP_CIPHER_CTX* evp_cipher_ctx = EVP_CIPHER_CTX_new();
|
||||
#endif
|
||||
if (EVP_EncryptInit(evp_cipher_ctx, EVP_aes_128_cbc(),
|
||||
reinterpret_cast<uint8_t*>(&key_[0]),
|
||||
reinterpret_cast<uint8_t*>(&(*iv)[0])) == 0) {
|
||||
LOGE("AesCbcKey::Encrypt: AES CBC setup failure: %s",
|
||||
ERR_error_string(ERR_get_error(), NULL));
|
||||
EVP_CIPHER_CTX_cleanup(&ctx);
|
||||
#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
|
||||
EVP_CIPHER_CTX_cleanup(evp_cipher_ctx);
|
||||
#else
|
||||
EVP_CIPHER_CTX_free(evp_cipher_ctx);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
out->resize(in.size() + AES_BLOCK_SIZE);
|
||||
int out_length = out->size();
|
||||
if (EVP_EncryptUpdate(
|
||||
&ctx, reinterpret_cast<uint8_t*>(&(*out)[0]), &out_length,
|
||||
evp_cipher_ctx, reinterpret_cast<uint8_t*>(&(*out)[0]), &out_length,
|
||||
reinterpret_cast<uint8_t*>(const_cast<char*>(in.data())),
|
||||
in.size()) == 0) {
|
||||
LOGE("AesCbcKey::Encrypt: encryption failure: %s",
|
||||
ERR_error_string(ERR_get_error(), NULL));
|
||||
EVP_CIPHER_CTX_cleanup(&ctx);
|
||||
#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
|
||||
EVP_CIPHER_CTX_cleanup(evp_cipher_ctx);
|
||||
#else
|
||||
EVP_CIPHER_CTX_free(evp_cipher_ctx);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
int padding = 0;
|
||||
if (EVP_EncryptFinal_ex(&ctx, reinterpret_cast<uint8_t*>(&(*out)[out_length]),
|
||||
if (EVP_EncryptFinal_ex(evp_cipher_ctx,
|
||||
reinterpret_cast<uint8_t*>(&(*out)[out_length]),
|
||||
&padding) == 0) {
|
||||
LOGE("AesCbcKey::Encrypt: PKCS7 padding failure: %s",
|
||||
ERR_error_string(ERR_get_error(), NULL));
|
||||
EVP_CIPHER_CTX_cleanup(&ctx);
|
||||
#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
|
||||
EVP_CIPHER_CTX_cleanup(evp_cipher_ctx);
|
||||
#else
|
||||
EVP_CIPHER_CTX_free(evp_cipher_ctx);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
EVP_CIPHER_CTX_cleanup(&ctx);
|
||||
|
||||
#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
|
||||
EVP_CIPHER_CTX_cleanup(evp_cipher_ctx);
|
||||
#else
|
||||
EVP_CIPHER_CTX_free(evp_cipher_ctx);
|
||||
#endif
|
||||
out->resize(out_length + padding);
|
||||
return true;
|
||||
}
|
||||
@@ -195,11 +217,16 @@ static int LogOpenSSLError(const char* msg, size_t /* len */, void* /* ctx */) {
|
||||
|
||||
static bool VerifyPSSSignature(EVP_PKEY *pkey, const std::string &message,
|
||||
const std::string &signature) {
|
||||
EVP_MD_CTX ctx;
|
||||
EVP_MD_CTX_init(&ctx);
|
||||
#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
|
||||
EVP_MD_CTX ctx_struct;
|
||||
EVP_MD_CTX* evp_md_ctx = &ctx_struct;
|
||||
EVP_MD_CTX_init(evp_md_ctx);
|
||||
#else
|
||||
EVP_MD_CTX* evp_md_ctx = EVP_MD_CTX_new();
|
||||
#endif
|
||||
EVP_PKEY_CTX *pctx = NULL;
|
||||
|
||||
if (EVP_DigestVerifyInit(&ctx, &pctx, EVP_sha1(), NULL /* no ENGINE */,
|
||||
if (EVP_DigestVerifyInit(evp_md_ctx, &pctx, EVP_sha1(), NULL /* no ENGINE */,
|
||||
pkey) != 1) {
|
||||
LOGE("EVP_DigestVerifyInit failed in VerifyPSSSignature");
|
||||
goto err;
|
||||
@@ -221,13 +248,13 @@ static bool VerifyPSSSignature(EVP_PKEY *pkey, const std::string &message,
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (EVP_DigestVerifyUpdate(&ctx, message.data(), message.size()) != 1) {
|
||||
if (EVP_DigestVerifyUpdate(evp_md_ctx, message.data(), message.size()) != 1) {
|
||||
LOGE("EVP_DigestVerifyUpdate failed in VerifyPSSSignature");
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (EVP_DigestVerifyFinal(
|
||||
&ctx, const_cast<uint8_t *>(
|
||||
evp_md_ctx, const_cast<uint8_t *>(
|
||||
reinterpret_cast<const uint8_t *>(signature.data())),
|
||||
signature.size()) != 1) {
|
||||
LOGE(
|
||||
@@ -236,12 +263,20 @@ static bool VerifyPSSSignature(EVP_PKEY *pkey, const std::string &message,
|
||||
goto err;
|
||||
}
|
||||
|
||||
EVP_MD_CTX_cleanup(&ctx);
|
||||
#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
|
||||
EVP_MD_CTX_cleanup(evp_md_ctx);
|
||||
#else
|
||||
EVP_MD_CTX_free(evp_md_ctx);
|
||||
#endif
|
||||
return true;
|
||||
|
||||
err:
|
||||
ERR_print_errors_cb(LogOpenSSLError, NULL);
|
||||
EVP_MD_CTX_cleanup(&ctx);
|
||||
#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
|
||||
EVP_MD_CTX_cleanup(evp_md_ctx);
|
||||
#else
|
||||
EVP_MD_CTX_free(evp_md_ctx);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -200,14 +200,22 @@ CdmResponseType ServiceCertificate::VerifySignedMessage(
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
CdmResponseType ServiceCertificate::EncryptClientId(
|
||||
CryptoSession* crypto_session, const ClientIdentification* clear_client_id,
|
||||
EncryptedClientIdentification* encrypted_client_id) {
|
||||
CdmResponseType ServiceCertificate::EncryptRsaOaep(const std::string& plaintext,
|
||||
std::string* ciphertext) {
|
||||
if (!public_key_) {
|
||||
LOGE("Service certificate not set.");
|
||||
return DEVICE_CERTIFICATE_ERROR_4;
|
||||
}
|
||||
|
||||
if (!public_key_->Encrypt(plaintext, ciphertext))
|
||||
return CLIENT_ID_RSA_ENCRYPT_ERROR;
|
||||
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
CdmResponseType ServiceCertificate::EncryptClientId(
|
||||
CryptoSession* crypto_session, const ClientIdentification* clear_client_id,
|
||||
EncryptedClientIdentification* encrypted_client_id) {
|
||||
encrypted_client_id->set_provider_id(provider_id_);
|
||||
encrypted_client_id->set_service_certificate_serial_number(serial_number_);
|
||||
|
||||
@@ -227,8 +235,9 @@ CdmResponseType ServiceCertificate::EncryptClientId(
|
||||
if (!aes.Init(key)) return CLIENT_ID_AES_INIT_ERROR;
|
||||
if (!aes.Encrypt(id, &enc_id, &iv)) return CLIENT_ID_AES_ENCRYPT_ERROR;
|
||||
|
||||
if (!public_key_->Encrypt(key, &enc_key))
|
||||
return CLIENT_ID_RSA_ENCRYPT_ERROR;
|
||||
CdmResponseType encrypt_result = EncryptRsaOaep(key, &enc_key);
|
||||
if (encrypt_result != NO_ERROR)
|
||||
return encrypt_result;
|
||||
|
||||
encrypted_client_id->set_encrypted_client_id_iv(iv);
|
||||
encrypted_client_id->set_encrypted_privacy_key(enc_key);
|
||||
|
||||
Reference in New Issue
Block a user