Source release 14.1.0

This commit is contained in:
John W. Bruce
2018-06-29 15:59:47 -07:00
parent 3ab70cec4e
commit afa11a48a0
1941 changed files with 557780 additions and 105547 deletions

View File

@@ -1,4 +1,6 @@
// Copyright 2015 Google Inc. All Rights Reserved.
// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
// source code may only be used and distributed under the Widevine Master
// License Agreement.
#include "cdm.h"
#include <assert.h>
@@ -125,6 +127,11 @@ class CdmImpl : public Cdm,
virtual bool isProvisioned() OVERRIDE;
virtual Status getProvisioningRequest(std::string* request) OVERRIDE;
virtual Status handleProvisioningResponse(
const std::string& response) OVERRIDE;
virtual Status removeProvisioning() OVERRIDE;
virtual Status removeUsageTable() OVERRIDE;
@@ -184,6 +191,8 @@ class CdmImpl : public Cdm,
virtual Status remove(const std::string& session_id) OVERRIDE;
virtual Status forceRemove(const std::string& session_id) OVERRIDE;
virtual Status decrypt(const InputBuffer& input,
const OutputBuffer& output) OVERRIDE;
@@ -297,7 +306,7 @@ Cdm::Status CdmImpl::setServiceCertificate(const std::string& certificate) {
// Verify that the certificate is properly signed and well-formed.
CdmResponseType status =
cdm_engine_.SetProvisioningServiceCertificate(certificate);
cdm_engine_.ValidateServiceCertificate(certificate);
if (status != NO_ERROR) {
LOGE("Invalid service certificate! Error code = %d", status);
return kTypeError;
@@ -339,6 +348,37 @@ bool CdmImpl::isProvisioned() {
return cdm_engine_.IsProvisioned(kSecurityLevelL1);
}
Cdm::Status CdmImpl::getProvisioningRequest(std::string* request) {
std::string empty_authority;
std::string ignored_base_url;
CdmResponseType result = cdm_engine_.GetProvisioningRequest(
kCertificateWidevine, empty_authority,
property_set_.service_certificate(), request, &ignored_base_url);
if (result == CERT_PROVISIONING_NONCE_GENERATION_ERROR) {
LOGE("Nonce quota exceeded");
return kQuotaExceeded;
}
if (result != NO_ERROR) {
LOGE("Unexpected error %d", result);
return kUnexpectedError;
}
return kSuccess;
}
Cdm::Status CdmImpl::handleProvisioningResponse(const std::string& response) {
std::string ignored_cert;
std::string ignored_wrapped_key;
CdmResponseType result = cdm_engine_.HandleProvisioningResponse(
response, &ignored_cert, &ignored_wrapped_key);
if (result != NO_ERROR) {
LOGE("Unexpected error %d", result);
return kUnexpectedError;
}
return kSuccess;
}
Cdm::Status CdmImpl::removeProvisioning() {
if (cdm_engine_.Unprovision(kSecurityLevelL1) != NO_ERROR) {
return kUnexpectedError;
@@ -370,8 +410,8 @@ Cdm::Status CdmImpl::listUsageRecords(std::vector<std::string>* ksids) {
LOGE("Missing vector parameter to receive KSIDs.");
return kTypeError;
}
if (cdm_engine_.ListUsageRecords(
property_set_.app_id(), kSecurityLevelL1, ksids) != NO_ERROR) {
if (cdm_engine_.ListUsageIds(
property_set_.app_id(), kSecurityLevelL1, ksids, NULL) != NO_ERROR) {
return kUnexpectedError;
}
return kSuccess;
@@ -713,16 +753,10 @@ Cdm::Status CdmImpl::load(const std::string& session_id,
Cdm::Status CdmImpl::update(const std::string& session_id,
const std::string& response) {
if (provision_request_sent_) {
std::string ignored_cert;
std::string ignored_wrapped_key;
provision_request_sent_ = false;
CdmResponseType result = cdm_engine_.HandleProvisioningResponse(
response, &ignored_cert, &ignored_wrapped_key);
if (result != NO_ERROR) {
LOGE("Unexpected error %d", result);
return kUnexpectedError;
}
const Status status = handleProvisioningResponse(response);
if (status != kSuccess)
return status;
}
// Check to see if any sessions have been waiting for provisioning.
@@ -1010,6 +1044,37 @@ Cdm::Status CdmImpl::remove(const std::string& session_id) {
return kSuccess;
}
Cdm::Status CdmImpl::forceRemove(const std::string& session_id) {
if (!cdm_engine_.IsOpenSession(session_id)) {
LOGE("No such session: %s", session_id.c_str());
return kSessionNotFound;
}
if (!sessions_[session_id].callable) {
LOGE("Request not yet generated: %s", session_id.c_str());
return kInvalidState;
}
if (sessions_[session_id].type == kTemporary) {
LOGE("Not a persistent session: %s", session_id.c_str());
return kRangeError;
}
CdmResponseType result = cdm_engine_.RemoveLicense(session_id);
if (result != NO_ERROR) {
LOGE("Unexpected error %d", result);
return kUnexpectedError;
}
sessions_.erase(session_id);
cdm_engine_.CloseSession(session_id);
listener_->onRemoveComplete(session_id);
LOGI("A session has been forcibly deleted.");
return kSuccess;
}
Cdm::Status CdmImpl::decrypt(const InputBuffer& input,
const OutputBuffer& output) {
const bool is_encrypted = (input.encryption_scheme != kClear);
@@ -1273,8 +1338,8 @@ void CdmImpl::OnSessionKeysChange(const CdmSessionId& session_id,
void CdmImpl::OnExpirationUpdate(const CdmSessionId& session_id,
int64_t new_expiry_time_seconds) {
// "Never expires" in core is LLONG_MAX. In the CDM API, it's -1.
if (new_expiry_time_seconds == LLONG_MAX) {
// "Never expires" in core is NEVER_EXPIRES. In the CDM API, it's -1.
if (new_expiry_time_seconds == NEVER_EXPIRES) {
sessions_[session_id].expiration = -1;
} else {
sessions_[session_id].expiration = new_expiry_time_seconds * 1000;
@@ -1295,20 +1360,11 @@ Cdm::KeyAllowedUsageFlags CdmImpl::KeyAllowedFlags(
Cdm::Status CdmImpl::SendProvisioningRequest(const std::string& session_id) {
// Generate a provisioning request.
std::string empty_authority;
std::string ignored_base_url;
std::string signed_request;
CdmResponseType result = cdm_engine_.GetProvisioningRequest(
kCertificateWidevine, empty_authority, &signed_request,
&ignored_base_url);
if (result == CERT_PROVISIONING_NONCE_GENERATION_ERROR) {
LOGE("Nonce quota exceeded");
return kQuotaExceeded;
}
if (result != NO_ERROR) {
LOGE("Unexpected error %d", result);
return kUnexpectedError;
}
const Status status = getProvisioningRequest(&signed_request);
if (status != kSuccess)
return status;
listener_->onDirectIndividualizationRequest(session_id, signed_request);
provision_request_sent_ = true;
return kSuccess;