Add recoverable errors

[ Merge of http://go/wvgerrit/71326 ]

Nonce flood, frame size, session and system invalidation errors
will now bubble up to the app. OEMCrypto v15 returns
OEMCrypto_ERROR_BUFFER_TOO_LARGE, OEMCrypto_ERROR_SESSION_LOST_STATE,
OEMCrypto_ERROR_SYSTEM_INVALIDATED and a variety of nonce errors.
These will be reported to HIDL as OUTPUT_TOO_LARGE_ERROR,
ERROR_DRM_SESSION_LOST_STATE, ERROR_DRM_INVALID_STATE and
ERROR_DRM_RESOURCE_CONTENTION.

Bug: 120572706
Test: Unit/Integration tests
Change-Id: Ida177300046327ce81592a273028ef6c3a0d9fd9
This commit is contained in:
Rahul Frias
2019-01-30 02:15:52 -08:00
parent 54104c7a22
commit 272e60db27
27 changed files with 977 additions and 648 deletions

View File

@@ -122,13 +122,13 @@ CdmResponseType CertificateProvisioning::Init(
* server for determining a unique per origin ID for the device.
* It is also valid (though deprecated) to leave the settings unset.
*/
bool CertificateProvisioning::SetSpoidParameter(
CdmResponseType CertificateProvisioning::SetSpoidParameter(
const std::string& origin, const std::string& spoid,
ProvisioningRequest* request) {
if (!request) {
LOGE("CertificateProvisioning::SetSpoidParameter: No request buffer "
"passed to method.");
return false;
return PARAMETER_NULL;
}
if (!spoid.empty()) {
// Use the SPOID that has been pre-provided
@@ -139,19 +139,22 @@ bool CertificateProvisioning::SetSpoidParameter(
} else {
LOGE("CertificateProvisioning::SetSpoidParameter: Failure getting "
"provider ID");
return false;
return SERVICE_CERTIFICATE_PROVIDER_ID_EMPTY;
}
} else if (origin != EMPTY_ORIGIN) {
// Legacy behavior - Concatenate Unique ID with Origin
std::string device_unique_id;
if (!crypto_session_->GetInternalDeviceUniqueId(&device_unique_id)) {
CdmResponseType status =
crypto_session_->GetInternalDeviceUniqueId(&device_unique_id);
if (status != NO_ERROR) {
LOGE("CertificateProvisioning::SetSpoidParameter: Failure getting "
"device unique ID");
return false;
return status;
}
request->set_stable_id(device_unique_id + origin);
} // No else clause, by design. It is valid to do nothing.
return true;
return NO_ERROR;
}
/*
@@ -219,9 +222,12 @@ CdmResponseType CertificateProvisioning::GetProvisioningRequest(
provisioning_request.clear_client_id();
uint32_t nonce;
if (!crypto_session_->GenerateNonce(&nonce)) {
LOGE("GetProvisioningRequest: fails to generate a nonce");
return CERT_PROVISIONING_NONCE_GENERATION_ERROR;
status = crypto_session_->GenerateNonce(&nonce);
if (status != NO_ERROR) {
LOGE("GetProvisioningRequest: fails to generate a nonce: %d", status);
return status == NONCE_GENERATION_ERROR ?
CERT_PROVISIONING_NONCE_GENERATION_ERROR : status;
}
// The provisioning server does not convert the nonce to uint32_t, it just
@@ -247,20 +253,22 @@ CdmResponseType CertificateProvisioning::GetProvisioningRequest(
cert_type_ = cert_type;
options->set_certificate_authority(cert_authority);
if (!SetSpoidParameter(origin, spoid, &provisioning_request)) {
return CERT_PROVISIONING_GET_KEYBOX_ERROR_2;
}
status = SetSpoidParameter(origin, spoid, &provisioning_request);
if (status != NO_ERROR) return status;
std::string serialized_message;
provisioning_request.SerializeToString(&serialized_message);
// Derives signing and encryption keys and constructs signature.
std::string request_signature;
if (!crypto_session_->PrepareRequest(serialized_message, true,
&request_signature)) {
status = crypto_session_->PrepareRequest(serialized_message, true,
&request_signature);
if (status != NO_ERROR) {
LOGE("GetProvisioningRequest: fails to prepare request");
return CERT_PROVISIONING_REQUEST_ERROR_3;
return status;
}
if (request_signature.empty()) {
LOGE("GetProvisioningRequest: request signature is empty");
return CERT_PROVISIONING_REQUEST_ERROR_4;
@@ -371,11 +379,14 @@ CdmResponseType CertificateProvisioning::HandleProvisioningResponse(
std::string wrapped_private_key;
if (!crypto_session_->RewrapCertificate(signed_message, signature, nonce,
CdmResponseType status =
crypto_session_->RewrapCertificate(signed_message, signature, nonce,
new_private_key, iv, wrapping_key,
&wrapped_private_key)) {
&wrapped_private_key);
if (status != NO_ERROR) {
LOGE("HandleProvisioningResponse: RewrapCertificate fails");
return CERT_PROVISIONING_RESPONSE_ERROR_6;
return status;
}
CdmSecurityLevel security_level = crypto_session_->GetSecurityLevel();