Merge "Change error.rs to use generated types." am: 5061b81606

Original change: https://android-review.googlesource.com/c/platform/system/security/+/1398873

Change-Id: If8b97c7b5f1ca304fe629fc4d0bf3b663592e388
diff --git a/keystore2/Android.bp b/keystore2/Android.bp
index 7016d06..338f37e 100644
--- a/keystore2/Android.bp
+++ b/keystore2/Android.bp
@@ -18,9 +18,10 @@
     srcs: ["src/lib.rs"],
 
     rustlibs: [
+        "libandroid_hardware_keymint",
         "libandroid_security_keystore2",
         "libanyhow",
-        "libandroid_hardware_keymint",
+        "libbinder_rs",
         "libkeystore_aidl_generated",
         "libkeystore2_selinux",
         "liblazy_static",
@@ -40,9 +41,10 @@
     auto_gen_config: true,
     rustlibs: [
         "libandroid_logger",
+        "libandroid_hardware_keymint",
         "libandroid_security_keystore2",
         "libanyhow",
-        "libandroid_hardware_keymint",
+        "libbinder_rs",
         "libkeystore_aidl_generated",
         "libkeystore2_selinux",
         "liblazy_static",
diff --git a/keystore2/src/error.rs b/keystore2/src/error.rs
index a285bda..f4da749 100644
--- a/keystore2/src/error.rs
+++ b/keystore2/src/error.rs
@@ -31,35 +31,16 @@
 //! context should be added every time an error is forwarded.
 
 use std::cmp::PartialEq;
-use std::convert::From;
 
-use keystore_aidl_generated as aidl;
-use keystore_aidl_generated::ResponseCode as AidlRc;
+pub use android_hardware_keymint::aidl::android::hardware::keymint::ErrorCode as Ec;
+pub use android_security_keystore2::aidl::android::security::keystore2::ResponseCode as Rc;
+
+use android_hardware_keymint::aidl::android::hardware::keymint::ErrorCode::ErrorCode;
+use android_security_keystore2::aidl::android::security::keystore2::ResponseCode::ResponseCode;
 
 use keystore2_selinux as selinux;
 
-pub use aidl::ResponseCode;
-
-/// AidlResult wraps the `android.security.keystore2.Result` generated from AIDL
-#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
-pub struct AidlResult(aidl::Result);
-
-impl AidlResult {
-    /// Creates an instance of AidlResult indicating no error has occurred.
-    pub fn ok() -> Self {
-        Self(aidl::Result { rc: AidlRc::Ok, km_error_code: 0 })
-    }
-
-    /// Creates an instance of AidlResult indicating the given ResponseCode.
-    pub fn rc(rc: AidlRc) -> Self {
-        Self(aidl::Result { rc, km_error_code: 0 })
-    }
-
-    /// Creates an instance of AidlResult indicating the given KM ErrorCode.
-    pub fn ec(ec: aidl::ErrorCode) -> Self {
-        Self(aidl::Result { rc: AidlRc::KeymintErrorCode, km_error_code: ec })
-    }
-}
+use android_security_keystore2::binder::{Result as BinderResult, Status as BinderStatus};
 
 /// This is the main Keystore error type. It wraps the Keystore `ResponseCode` generated
 /// from AIDL in the `Rc` variant and Keymint `ErrorCode` in the Km variant.
@@ -67,35 +48,21 @@
 pub enum Error {
     /// Wraps a Keystore `ResponseCode` as defined by the Keystore AIDL interface specification.
     #[error("Error::Rc({0:?})")]
-    Rc(AidlRc),
+    Rc(ResponseCode),
     /// Wraps a Keymint `ErrorCode` as defined by the Keymint AIDL interface specification.
     #[error("Error::Km({0:?})")]
-    Km(aidl::ErrorCode), // TODO Keymint ErrorCode is a generated AIDL type.
+    Km(ErrorCode),
 }
 
 impl Error {
     /// Short hand for `Error::Rc(ResponseCode::SystemError)`
     pub fn sys() -> Self {
-        Error::Rc(AidlRc::SystemError)
+        Error::Rc(Rc::SystemError)
     }
 
     /// Short hand for `Error::Rc(ResponseCode::PermissionDenied`
     pub fn perm() -> Self {
-        Error::Rc(AidlRc::PermissionDenied)
-    }
-}
-
-impl From<anyhow::Error> for AidlResult {
-    fn from(error: anyhow::Error) -> Self {
-        let root_cause = error.root_cause();
-        match root_cause.downcast_ref::<Error>() {
-            Some(Error::Rc(rcode)) => AidlResult::rc(*rcode),
-            Some(Error::Km(ec)) => AidlResult::ec(*ec),
-            None => match root_cause.downcast_ref::<selinux::Error>() {
-                Some(selinux::Error::PermissionDenied) => AidlResult::rc(AidlRc::PermissionDenied),
-                _ => AidlResult::rc(AidlRc::SystemError),
-            },
-        }
+        Error::Rc(Rc::PermissionDenied)
     }
 }
 
@@ -129,14 +96,23 @@
 ///
 /// aidl_result_ = map_or_log_err(loadKey(), |r| { some_side_effect(); AidlResult::rc(r) });
 /// ```
-pub fn map_or_log_err<T>(
-    result: anyhow::Result<T>,
-    handle_ok: impl FnOnce(T) -> AidlResult,
-) -> AidlResult {
+pub fn map_or_log_err<T, U, F>(result: anyhow::Result<U>, handle_ok: F) -> BinderResult<T>
+where
+    F: FnOnce(U) -> BinderResult<T>,
+{
     result.map_or_else(
         |e| {
             log::error!("{:?}", e);
-            e.into()
+            let root_cause = e.root_cause();
+            let rc = match root_cause.downcast_ref::<Error>() {
+                Some(Error::Rc(rcode)) => *rcode,
+                Some(Error::Km(ec)) => *ec,
+                None => match root_cause.downcast_ref::<selinux::Error>() {
+                    Some(selinux::Error::PermissionDenied) => Rc::PermissionDenied,
+                    _ => Rc::SystemError,
+                },
+            };
+            Err(BinderStatus::new_service_specific_error(rc, None))
         },
         handle_ok,
     )
@@ -145,16 +121,14 @@
 #[cfg(test)]
 pub mod tests {
 
-    use anyhow::{anyhow, Context, Result};
-
-    use super::aidl::ErrorCode;
     use super::*;
+    use anyhow::{anyhow, Context};
 
-    fn nested_nested_rc(rc: AidlRc) -> anyhow::Result<()> {
+    fn nested_nested_rc(rc: ResponseCode) -> anyhow::Result<()> {
         Err(anyhow!(Error::Rc(rc))).context("nested nested rc")
     }
 
-    fn nested_rc(rc: AidlRc) -> anyhow::Result<()> {
+    fn nested_rc(rc: ResponseCode) -> anyhow::Result<()> {
         nested_nested_rc(rc).context("nested rc")
     }
 
@@ -166,11 +140,11 @@
         nested_nested_ec(ec).context("nested ec")
     }
 
-    fn nested_nested_ok(rc: AidlRc) -> anyhow::Result<AidlRc> {
+    fn nested_nested_ok(rc: ResponseCode) -> anyhow::Result<ResponseCode> {
         Ok(rc)
     }
 
-    fn nested_ok(rc: AidlRc) -> anyhow::Result<AidlRc> {
+    fn nested_ok(rc: ResponseCode) -> anyhow::Result<ResponseCode> {
         nested_nested_ok(rc).context("nested ok")
     }
 
@@ -203,90 +177,52 @@
                 .with_tag("keystore_error_tests")
                 .with_min_level(log::Level::Debug),
         );
-        // All Error::Rc(x) get mapped on aidl::Result{x, 0}
+        // All Error::Rc(x) get mapped on a service specific error
+        // code of x.
+        for rc in Rc::Ok..Rc::BackendBusy {
+            assert_eq!(
+                Result::<(), i32>::Err(rc),
+                map_or_log_err(nested_rc(rc), |_| Err(BinderStatus::ok()))
+                    .map_err(|s| s.service_specific_error())
+            );
+        }
+
+        // All KeystoreKerror::Km(x) get mapped on a service
+        // specific error of x.
+        for ec in Ec::UNKNOWN_ERROR..Ec::ROOT_OF_TRUST_ALREADY_SET {
+            assert_eq!(
+                Result::<(), i32>::Err(ec),
+                map_or_log_err(nested_ec(ec), |_| Err(BinderStatus::ok()))
+                    .map_err(|s| s.service_specific_error())
+            );
+        }
+
+        // selinux::Error::Perm() needs to be mapped to Rc::PermissionDenied
         assert_eq!(
-            AidlResult::rc(AidlRc::Ok),
-            map_or_log_err(nested_rc(AidlRc::Ok), |_| AidlResult::ec(0))
-        );
-        assert_eq!(
-            AidlResult::rc(AidlRc::Locked),
-            map_or_log_err(nested_rc(AidlRc::Locked), |_| AidlResult::ec(0))
-        );
-        assert_eq!(
-            AidlResult::rc(AidlRc::Uninitialized),
-            map_or_log_err(nested_rc(AidlRc::Uninitialized), |_| AidlResult::ec(0))
-        );
-        assert_eq!(
-            AidlResult::rc(AidlRc::SystemError),
-            map_or_log_err(nested_rc(AidlRc::SystemError), |_| AidlResult::ec(0))
-        );
-        assert_eq!(
-            AidlResult::rc(AidlRc::PermissionDenied),
-            map_or_log_err(nested_rc(AidlRc::PermissionDenied), |_| AidlResult::ec(0))
-        );
-        assert_eq!(
-            AidlResult::rc(AidlRc::KeyNotFound),
-            map_or_log_err(nested_rc(AidlRc::KeyNotFound), |_| AidlResult::ec(0))
-        );
-        assert_eq!(
-            AidlResult::rc(AidlRc::ValueCorrupted),
-            map_or_log_err(nested_rc(AidlRc::ValueCorrupted), |_| AidlResult::ec(0))
-        );
-        assert_eq!(
-            AidlResult::rc(AidlRc::WrongPassword),
-            map_or_log_err(nested_rc(AidlRc::WrongPassword), |_| AidlResult::ec(0))
-        );
-        assert_eq!(
-            AidlResult::rc(AidlRc::OpAuthNeeded),
-            map_or_log_err(nested_rc(AidlRc::OpAuthNeeded), |_| AidlResult::ec(0))
-        );
-        assert_eq!(
-            AidlResult::rc(AidlRc::KeyPermanentlyInvalidated),
-            map_or_log_err(nested_rc(AidlRc::KeyPermanentlyInvalidated), |_| AidlResult::ec(0))
-        );
-        assert_eq!(
-            AidlResult::rc(AidlRc::NoSuchSecurityLevel),
-            map_or_log_err(nested_rc(AidlRc::NoSuchSecurityLevel), |_| AidlResult::ec(0))
-        );
-        assert_eq!(
-            AidlResult::rc(AidlRc::KeymintErrorCode),
-            map_or_log_err(nested_rc(AidlRc::KeymintErrorCode), |_| AidlResult::ec(0))
-        );
-        assert_eq!(
-            AidlResult::rc(AidlRc::BackendBusy),
-            map_or_log_err(nested_rc(AidlRc::BackendBusy), |_| AidlResult::ec(0))
+            Result::<(), i32>::Err(Rc::PermissionDenied),
+            map_or_log_err(nested_selinux_perm(), |_| Err(BinderStatus::ok()))
+                .map_err(|s| s.service_specific_error())
         );
 
-        // All KeystoreKerror::Km(x) get mapped on
-        // aidl::Result{AidlRc::KeymintErrorCode, x}
+        // All other errors get mapped on System Error.
         assert_eq!(
-            AidlResult::ec(-7),
-            map_or_log_err(nested_ec(-7), |_| AidlResult::rc(AidlRc::SystemError))
-        );
-
-        // All other get mapped on System Error.
-        assert_eq!(
-            AidlResult::rc(AidlRc::SystemError),
-            map_or_log_err(nested_other_error(), |_| AidlResult::ec(0))
+            Result::<(), i32>::Err(Rc::SystemError),
+            map_or_log_err(nested_other_error(), |_| Err(BinderStatus::ok()))
+                .map_err(|s| s.service_specific_error())
         );
 
         // Result::Ok variants get passed to the ok handler.
-        assert_eq!(
-            AidlResult::rc(AidlRc::OpAuthNeeded),
-            map_or_log_err(nested_ok(AidlRc::OpAuthNeeded), AidlResult::rc)
-        );
-        assert_eq!(AidlResult::ok(), map_or_log_err(nested_ok(AidlRc::Ok), AidlResult::rc));
+        assert_eq!(Ok(Rc::OpAuthNeeded), map_or_log_err(nested_ok(Rc::OpAuthNeeded), Ok));
+        assert_eq!(Ok(Rc::Ok), map_or_log_err(nested_ok(Rc::Ok), Ok));
 
-        // selinux::Error::Perm() needs to be mapped to AidlRc::PermissionDenied
-        assert_eq!(
-            AidlResult::rc(AidlRc::PermissionDenied),
-            map_or_log_err(nested_selinux_perm(), |_| AidlResult::ec(0))
-        );
         Ok(())
     }
 
     //Helper function to test whether error cases are handled as expected.
-    pub fn check_result_contains_error_string<T>(result: Result<T>, expected_error_string: &str) {
+    pub fn check_result_contains_error_string<T>(
+        result: anyhow::Result<T>,
+        expected_error_string: &str,
+    ) {
         let error_str = format!(
             "{:#?}",
             result.err().unwrap_or_else(|| panic!("Expected the error: {}", expected_error_string))
diff --git a/keystore2/src/key_parameter.rs b/keystore2/src/key_parameter.rs
index 1eb5d41..5266c28 100644
--- a/keystore2/src/key_parameter.rs
+++ b/keystore2/src/key_parameter.rs
@@ -17,7 +17,7 @@
 //! and the methods to work with KeyParameter.
 
 use crate::error::Error as KeystoreError;
-use crate::error::ResponseCode;
+use crate::error::Rc;
 pub use android_hardware_keymint::aidl::android::hardware::keymint::{
     Algorithm, Algorithm::Algorithm as AlgorithmType, BlockMode,
     BlockMode::BlockMode as BlockModeType, Digest, Digest::Digest as DigestType, EcCurve,
@@ -354,14 +354,14 @@
             Tag::PURPOSE => {
                 let key_purpose: KeyPurposeType = data
                     .get()
-                    .map_err(|_| KeystoreError::Rc(ResponseCode::ValueCorrupted))
+                    .map_err(|_| KeystoreError::Rc(Rc::ValueCorrupted))
                     .context("Failed to read sql data for tag: PURPOSE.")?;
                 KeyParameterValue::KeyPurpose(key_purpose)
             }
             Tag::ALGORITHM => {
                 let algorithm: AlgorithmType = data
                     .get()
-                    .map_err(|_| KeystoreError::Rc(ResponseCode::ValueCorrupted))
+                    .map_err(|_| KeystoreError::Rc(Rc::ValueCorrupted))
                     .context("Failed to read sql data for tag: ALGORITHM.")?;
                 KeyParameterValue::Algorithm(algorithm)
             }
@@ -373,21 +373,21 @@
             Tag::BLOCK_MODE => {
                 let block_mode: BlockModeType = data
                     .get()
-                    .map_err(|_| KeystoreError::Rc(ResponseCode::ValueCorrupted))
+                    .map_err(|_| KeystoreError::Rc(Rc::ValueCorrupted))
                     .context("Failed to read sql data for tag: BLOCK_MODE.")?;
                 KeyParameterValue::BlockMode(block_mode)
             }
             Tag::DIGEST => {
                 let digest: DigestType = data
                     .get()
-                    .map_err(|_| KeystoreError::Rc(ResponseCode::ValueCorrupted))
+                    .map_err(|_| KeystoreError::Rc(Rc::ValueCorrupted))
                     .context("Failed to read sql data for tag: DIGEST.")?;
                 KeyParameterValue::Digest(digest)
             }
             Tag::PADDING => {
                 let padding: PaddingModeType = data
                     .get()
-                    .map_err(|_| KeystoreError::Rc(ResponseCode::ValueCorrupted))
+                    .map_err(|_| KeystoreError::Rc(Rc::ValueCorrupted))
                     .context("Failed to read sql data for tag: PADDING.")?;
                 KeyParameterValue::PaddingMode(padding)
             }
@@ -400,7 +400,7 @@
             Tag::EC_CURVE => {
                 let ec_curve: EcCurveType = data
                     .get()
-                    .map_err(|_| KeystoreError::Rc(ResponseCode::ValueCorrupted))
+                    .map_err(|_| KeystoreError::Rc(Rc::ValueCorrupted))
                     .context("Failed to read sql data for tag: EC_CURVE.")?;
                 KeyParameterValue::EcCurve(ec_curve)
             }
@@ -455,7 +455,7 @@
             Tag::USER_AUTH_TYPE => {
                 let user_auth_type: HardwareAuthenticatorTypeType = data
                     .get()
-                    .map_err(|_| KeystoreError::Rc(ResponseCode::ValueCorrupted))
+                    .map_err(|_| KeystoreError::Rc(Rc::ValueCorrupted))
                     .context("Failed to read sql data for tag: USER_AUTH_TYPE.")?;
                 KeyParameterValue::HardwareAuthenticatorType(user_auth_type)
             }
@@ -486,7 +486,7 @@
             Tag::ORIGIN => {
                 let origin: KeyOriginType = data
                     .get()
-                    .map_err(|_| KeystoreError::Rc(ResponseCode::ValueCorrupted))
+                    .map_err(|_| KeystoreError::Rc(Rc::ValueCorrupted))
                     .context("Failed to read sql data for tag: ORIGIN.")?;
                 KeyParameterValue::KeyOrigin(origin)
             }
@@ -598,7 +598,7 @@
                 KeyParameterValue::ConfirmationToken(confirmation_token)
             }
             _ => {
-                return Err(KeystoreError::Rc(ResponseCode::ValueCorrupted))
+                return Err(KeystoreError::Rc(Rc::ValueCorrupted))
                     .context("Failed to decode Tag enum from value.")?
             }
         };