Revert^2 "[rkpd_client] Add Error type to rkpd_client"
This reverts commit f84c46c3b3cad3ea4908ab44c361f637c7fcdb09.
Reason for revert: Reland the original cl aosp/2821995
with an adjustment about the Timeout error type in order
to maintain the original ResponseCode.
Test: atest RkpdAppIntegrationTests
Bug: 310139666
Change-Id: Id4ee05eb616c125f9d28b25f4668ca3071ccb26c
diff --git a/keystore2/src/error.rs b/keystore2/src/error.rs
index 1a048b6..ac5ba4c 100644
--- a/keystore2/src/error.rs
+++ b/keystore2/src/error.rs
@@ -27,7 +27,9 @@
//! Keystore functions should use `anyhow::Result` to return error conditions, and context should
//! be added every time an error is forwarded.
+use crate::rkpd_client::Error as RkpdError;
pub use android_hardware_security_keymint::aidl::android::hardware::security::keymint::ErrorCode::ErrorCode;
+use android_security_rkp_aidl::aidl::android::security::rkp::IGetKeyCallback::ErrorCode::ErrorCode as GetKeyErrorCode;
pub use android_system_keystore2::aidl::android::system::keystore2::ResponseCode::ResponseCode;
use android_system_keystore2::binder::{
ExceptionCode, Result as BinderResult, Status as BinderStatus, StatusCode,
@@ -66,6 +68,49 @@
}
}
+impl From<RkpdError> for Error {
+ fn from(e: RkpdError) -> Self {
+ match e {
+ RkpdError::RequestCancelled | RkpdError::GetRegistrationFailed => {
+ Error::Rc(ResponseCode::OUT_OF_KEYS_TRANSIENT_ERROR)
+ }
+ RkpdError::GetKeyFailed(e) => {
+ let response_code = match e {
+ GetKeyErrorCode::ERROR_UNKNOWN => ResponseCode::OUT_OF_KEYS_TRANSIENT_ERROR,
+ GetKeyErrorCode::ERROR_PERMANENT => ResponseCode::OUT_OF_KEYS_PERMANENT_ERROR,
+ GetKeyErrorCode::ERROR_PENDING_INTERNET_CONNECTIVITY => {
+ ResponseCode::OUT_OF_KEYS_PENDING_INTERNET_CONNECTIVITY
+ }
+ GetKeyErrorCode::ERROR_REQUIRES_SECURITY_PATCH => {
+ ResponseCode::OUT_OF_KEYS_REQUIRES_SYSTEM_UPGRADE
+ }
+ _ => {
+ log::error!("Unexpected get key error from rkpd: {e:?}");
+ ResponseCode::OUT_OF_KEYS_TRANSIENT_ERROR
+ }
+ };
+ Error::Rc(response_code)
+ }
+ RkpdError::RetryableTimeout => Error::Rc(ResponseCode::OUT_OF_KEYS_TRANSIENT_ERROR),
+ RkpdError::StoreUpgradedKeyFailed | RkpdError::Timeout => {
+ Error::Rc(ResponseCode::SYSTEM_ERROR)
+ }
+ RkpdError::BinderTransaction(s) => Error::BinderTransaction(s),
+ }
+ }
+}
+
+/// Maps an `rkpd_client::Error` that is wrapped with an `anyhow::Error` to a keystore2 `Error`.
+pub fn wrapped_rkpd_error_to_ks_error(e: &anyhow::Error) -> Error {
+ match e.downcast_ref::<RkpdError>() {
+ Some(e) => Error::from(*e),
+ None => {
+ log::error!("Failed to downcast the anyhow::Error to rkpd_client::Error: {e:?}");
+ Error::Rc(ResponseCode::SYSTEM_ERROR)
+ }
+ }
+}
+
/// Helper function to map the binder status we get from calls into KeyMint
/// to a Keystore Error. We don't create an anyhow error here to make
/// it easier to evaluate KeyMint errors, which we must do in some cases, e.g.,
@@ -409,4 +454,35 @@
expected_error_string
);
}
+
+ #[test]
+ fn rkpd_error_is_in_sync_with_response_code() {
+ let error_mapping = [
+ (RkpdError::RequestCancelled, ResponseCode::OUT_OF_KEYS_TRANSIENT_ERROR),
+ (RkpdError::GetRegistrationFailed, ResponseCode::OUT_OF_KEYS_TRANSIENT_ERROR),
+ (
+ RkpdError::GetKeyFailed(GetKeyErrorCode::ERROR_UNKNOWN),
+ ResponseCode::OUT_OF_KEYS_TRANSIENT_ERROR,
+ ),
+ (
+ RkpdError::GetKeyFailed(GetKeyErrorCode::ERROR_PERMANENT),
+ ResponseCode::OUT_OF_KEYS_PERMANENT_ERROR,
+ ),
+ (
+ RkpdError::GetKeyFailed(GetKeyErrorCode::ERROR_PENDING_INTERNET_CONNECTIVITY),
+ ResponseCode::OUT_OF_KEYS_PENDING_INTERNET_CONNECTIVITY,
+ ),
+ (
+ RkpdError::GetKeyFailed(GetKeyErrorCode::ERROR_REQUIRES_SECURITY_PATCH),
+ ResponseCode::OUT_OF_KEYS_REQUIRES_SYSTEM_UPGRADE,
+ ),
+ (RkpdError::StoreUpgradedKeyFailed, ResponseCode::SYSTEM_ERROR),
+ (RkpdError::RetryableTimeout, ResponseCode::OUT_OF_KEYS_TRANSIENT_ERROR),
+ (RkpdError::Timeout, ResponseCode::SYSTEM_ERROR),
+ ];
+ for (rkpd_error, expected_response_code) in error_mapping {
+ let e: Error = rkpd_error.into();
+ assert_eq!(e, Error::Rc(expected_response_code));
+ }
+ }
} // mod tests