// Copyright 2020, The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! This module implements utility functions used by the Keystore 2.0 service
//! implementation.

use crate::error::{map_binder_status, map_km_error, Error, ErrorCode};
use crate::key_parameter::KeyParameter;
use crate::ks_err;
use crate::permission;
use crate::permission::{KeyPerm, KeyPermSet, KeystorePerm};
pub use crate::watchdog_helper::watchdog;
use crate::{
    database::{KeyType, KeystoreDB},
    globals::LEGACY_IMPORTER,
    km_compat,
    raw_device::KeyMintDevice,
};
use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
    Algorithm::Algorithm, IKeyMintDevice::IKeyMintDevice, KeyCharacteristics::KeyCharacteristics,
    KeyParameter::KeyParameter as KmKeyParameter, KeyParameterValue::KeyParameterValue, Tag::Tag,
};
use android_os_permissions_aidl::aidl::android::os::IPermissionController;
use android_security_apc::aidl::android::security::apc::{
    IProtectedConfirmation::{FLAG_UI_OPTION_INVERTED, FLAG_UI_OPTION_MAGNIFIED},
    ResponseCode::ResponseCode as ApcResponseCode,
};
use android_system_keystore2::aidl::android::system::keystore2::{
    Authorization::Authorization, Domain::Domain, KeyDescriptor::KeyDescriptor,
    ResponseCode::ResponseCode,
};
use anyhow::{Context, Result};
use binder::{FromIBinder, StatusCode, Strong, ThreadState};
use keystore2_apc_compat::{
    ApcCompatUiOptions, APC_COMPAT_ERROR_ABORTED, APC_COMPAT_ERROR_CANCELLED,
    APC_COMPAT_ERROR_IGNORED, APC_COMPAT_ERROR_OK, APC_COMPAT_ERROR_OPERATION_PENDING,
    APC_COMPAT_ERROR_SYSTEM_ERROR,
};
use keystore2_crypto::{aes_gcm_decrypt, aes_gcm_encrypt, ZVec};
use log::{info, warn};
use std::iter::IntoIterator;
use std::thread::sleep;
use std::time::Duration;

#[cfg(test)]
mod tests;

/// Per RFC 5280 4.1.2.5, an undefined expiration (not-after) field should be set to GeneralizedTime
/// 999912312359559, which is 253402300799000 ms from Jan 1, 1970.
pub const UNDEFINED_NOT_AFTER: i64 = 253402300799000i64;

/// This function uses its namesake in the permission module and in
/// combination with with_calling_sid from the binder crate to check
/// if the caller has the given keystore permission.
pub fn check_keystore_permission(perm: KeystorePerm) -> anyhow::Result<()> {
    ThreadState::with_calling_sid(|calling_sid| {
        permission::check_keystore_permission(
            calling_sid
                .ok_or_else(Error::sys)
                .context(ks_err!("Cannot check permission without calling_sid."))?,
            perm,
        )
    })
}

/// This function uses its namesake in the permission module and in
/// combination with with_calling_sid from the binder crate to check
/// if the caller has the given grant permission.
pub fn check_grant_permission(access_vec: KeyPermSet, key: &KeyDescriptor) -> anyhow::Result<()> {
    ThreadState::with_calling_sid(|calling_sid| {
        permission::check_grant_permission(
            calling_sid
                .ok_or_else(Error::sys)
                .context(ks_err!("Cannot check permission without calling_sid."))?,
            access_vec,
            key,
        )
    })
}

/// This function uses its namesake in the permission module and in
/// combination with with_calling_sid from the binder crate to check
/// if the caller has the given key permission.
pub fn check_key_permission(
    perm: KeyPerm,
    key: &KeyDescriptor,
    access_vector: &Option<KeyPermSet>,
) -> anyhow::Result<()> {
    ThreadState::with_calling_sid(|calling_sid| {
        permission::check_key_permission(
            ThreadState::get_calling_uid(),
            calling_sid
                .ok_or_else(Error::sys)
                .context(ks_err!("Cannot check permission without calling_sid."))?,
            perm,
            key,
            access_vector,
        )
    })
}

/// This function checks whether a given tag corresponds to the access of device identifiers.
pub fn is_device_id_attestation_tag(tag: Tag) -> bool {
    matches!(
        tag,
        Tag::ATTESTATION_ID_IMEI
            | Tag::ATTESTATION_ID_MEID
            | Tag::ATTESTATION_ID_SERIAL
            | Tag::DEVICE_UNIQUE_ATTESTATION
            | Tag::ATTESTATION_ID_SECOND_IMEI
    )
}

/// This function checks whether the calling app has the Android permissions needed to attest device
/// identifiers. It throws an error if the permissions cannot be verified or if the caller doesn't
/// have the right permissions. Otherwise it returns silently.
pub fn check_device_attestation_permissions() -> anyhow::Result<()> {
    check_android_permission(
        "android.permission.READ_PRIVILEGED_PHONE_STATE",
        Error::Km(ErrorCode::CANNOT_ATTEST_IDS),
    )
}

/// This function checks whether the calling app has the Android permissions needed to attest the
/// device-unique identifier. It throws an error if the permissions cannot be verified or if the
/// caller doesn't have the right permissions. Otherwise it returns silently.
pub fn check_unique_id_attestation_permissions() -> anyhow::Result<()> {
    check_android_permission(
        "android.permission.REQUEST_UNIQUE_ID_ATTESTATION",
        Error::Km(ErrorCode::CANNOT_ATTEST_IDS),
    )
}

/// This function checks whether the calling app has the Android permissions needed to manage
/// users. Only callers that can manage users are allowed to get a list of apps affected
/// by a user's SID changing.
/// It throws an error if the permissions cannot be verified or if the caller doesn't
/// have the right permissions. Otherwise it returns silently.
pub fn check_get_app_uids_affected_by_sid_permissions() -> anyhow::Result<()> {
    check_android_permission(
        "android.permission.MANAGE_USERS",
        Error::Km(ErrorCode::CANNOT_ATTEST_IDS),
    )
}

/// This function checks whether the calling app has the Android permission needed to dump
/// Keystore state to logcat.
pub fn check_dump_permission() -> anyhow::Result<()> {
    check_android_permission("android.permission.DUMP", Error::Rc(ResponseCode::PERMISSION_DENIED))
}

fn check_android_permission(permission: &str, err: Error) -> anyhow::Result<()> {
    let permission_controller: Strong<dyn IPermissionController::IPermissionController> =
        binder::get_interface("permission")?;

    let binder_result = {
        let _wp = watchdog::watch("check_android_permission: calling checkPermission");
        permission_controller.checkPermission(
            permission,
            ThreadState::get_calling_pid(),
            ThreadState::get_calling_uid() as i32,
        )
    };
    let has_permissions =
        map_binder_status(binder_result).context(ks_err!("checkPermission failed"))?;
    match has_permissions {
        true => Ok(()),
        false => Err(err).context(ks_err!("caller does not have the '{permission}' permission")),
    }
}

/// Converts a set of key characteristics as returned from KeyMint into the internal
/// representation of the keystore service.
pub fn key_characteristics_to_internal(
    key_characteristics: Vec<KeyCharacteristics>,
) -> Vec<KeyParameter> {
    key_characteristics
        .into_iter()
        .flat_map(|aidl_key_char| {
            let sec_level = aidl_key_char.securityLevel;
            aidl_key_char
                .authorizations
                .into_iter()
                .map(move |aidl_kp| KeyParameter::new(aidl_kp.into(), sec_level))
        })
        .collect()
}

/// Import a keyblob that is of the format used by the software C++ KeyMint implementation.  After
/// successful import, invoke both the `new_blob_handler` and `km_op` closures. On success a tuple
/// of the `km_op`s result and the optional upgraded blob is returned.
fn import_keyblob_and_perform_op<T, KmOp, NewBlobHandler>(
    km_dev: &dyn IKeyMintDevice,
    inner_keyblob: &[u8],
    upgrade_params: &[KmKeyParameter],
    km_op: KmOp,
    new_blob_handler: NewBlobHandler,
) -> Result<(T, Option<Vec<u8>>)>
where
    KmOp: Fn(&[u8]) -> Result<T, Error>,
    NewBlobHandler: FnOnce(&[u8]) -> Result<()>,
{
    let (format, key_material, mut chars) =
        crate::sw_keyblob::export_key(inner_keyblob, upgrade_params)?;
    log::debug!(
        "importing {:?} key material (len={}) with original chars={:?}",
        format,
        key_material.len(),
        chars
    );
    let asymmetric = chars.iter().any(|kp| {
        kp.tag == Tag::ALGORITHM
            && (kp.value == KeyParameterValue::Algorithm(Algorithm::RSA)
                || (kp.value == KeyParameterValue::Algorithm(Algorithm::EC)))
    });

    // Combine the characteristics of the previous keyblob with the upgrade parameters (which might
    // include special things like APPLICATION_ID / APPLICATION_DATA).
    chars.extend_from_slice(upgrade_params);

    // Now filter out values from the existing keyblob that shouldn't be set on import, either
    // because they are per-operation parameter or because they are auto-added by KeyMint itself.
    let mut import_params: Vec<KmKeyParameter> = chars
        .into_iter()
        .filter(|kp| {
            !matches!(
                kp.tag,
                Tag::ORIGIN
                    | Tag::ROOT_OF_TRUST
                    | Tag::OS_VERSION
                    | Tag::OS_PATCHLEVEL
                    | Tag::UNIQUE_ID
                    | Tag::ATTESTATION_CHALLENGE
                    | Tag::ATTESTATION_APPLICATION_ID
                    | Tag::ATTESTATION_ID_BRAND
                    | Tag::ATTESTATION_ID_DEVICE
                    | Tag::ATTESTATION_ID_PRODUCT
                    | Tag::ATTESTATION_ID_SERIAL
                    | Tag::ATTESTATION_ID_IMEI
                    | Tag::ATTESTATION_ID_MEID
                    | Tag::ATTESTATION_ID_MANUFACTURER
                    | Tag::ATTESTATION_ID_MODEL
                    | Tag::VENDOR_PATCHLEVEL
                    | Tag::BOOT_PATCHLEVEL
                    | Tag::DEVICE_UNIQUE_ATTESTATION
                    | Tag::ATTESTATION_ID_SECOND_IMEI
                    | Tag::NONCE
                    | Tag::MAC_LENGTH
                    | Tag::CERTIFICATE_SERIAL
                    | Tag::CERTIFICATE_SUBJECT
                    | Tag::CERTIFICATE_NOT_BEFORE
                    | Tag::CERTIFICATE_NOT_AFTER
            )
        })
        .collect();

    // Now that any previous values have been removed, add any additional parameters that needed for
    // import. In particular, if we are generating/importing an asymmetric key, we need to make sure
    // that NOT_BEFORE and NOT_AFTER are present.
    if asymmetric {
        import_params.push(KmKeyParameter {
            tag: Tag::CERTIFICATE_NOT_BEFORE,
            value: KeyParameterValue::DateTime(0),
        });
        import_params.push(KmKeyParameter {
            tag: Tag::CERTIFICATE_NOT_AFTER,
            value: KeyParameterValue::DateTime(UNDEFINED_NOT_AFTER),
        });
    }
    log::debug!("import parameters={import_params:?}");

    let creation_result = {
        let _wp = watchdog::watch(
            "utils::import_keyblob_and_perform_op: calling IKeyMintDevice::importKey",
        );
        map_km_error(km_dev.importKey(&import_params, format, &key_material, None))
    }
    .context(ks_err!("Upgrade failed."))?;

    // Note that the importKey operation will produce key characteristics that may be different
    // than are already stored in Keystore's SQL database.  In particular, the KeyMint
    // implementation will now mark the key as `Origin::IMPORTED` not `Origin::GENERATED`, and
    // the security level for characteristics will now be `TRUSTED_ENVIRONMENT` not `SOFTWARE`.
    //
    // However, the DB metadata still accurately reflects the original origin of the key, and
    // so we leave the values as-is (and so any `KeyInfo` retrieved in the Java layer will get the
    // same results before and after import).
    //
    // Note that this also applies to the `USAGE_COUNT_LIMIT` parameter -- if the key has already
    // been used, then the DB version of the parameter will be (and will continue to be) lower
    // than the original count bound to the keyblob. This means that Keystore's policing of
    // usage counts will continue where it left off.

    new_blob_handler(&creation_result.keyBlob).context(ks_err!("calling new_blob_handler."))?;

    km_op(&creation_result.keyBlob)
        .map(|v| (v, Some(creation_result.keyBlob)))
        .context(ks_err!("Calling km_op after upgrade."))
}

/// Upgrade a keyblob then invoke both the `new_blob_handler` and the `km_op` closures.  On success
/// a tuple of the `km_op`s result and the optional upgraded blob is returned.
fn upgrade_keyblob_and_perform_op<T, KmOp, NewBlobHandler>(
    km_dev: &dyn IKeyMintDevice,
    key_blob: &[u8],
    upgrade_params: &[KmKeyParameter],
    km_op: KmOp,
    new_blob_handler: NewBlobHandler,
) -> Result<(T, Option<Vec<u8>>)>
where
    KmOp: Fn(&[u8]) -> Result<T, Error>,
    NewBlobHandler: FnOnce(&[u8]) -> Result<()>,
{
    let upgraded_blob = {
        let _wp = watchdog::watch(
            "utils::upgrade_keyblob_and_perform_op: calling IKeyMintDevice::upgradeKey.",
        );
        map_km_error(km_dev.upgradeKey(key_blob, upgrade_params))
    }
    .context(ks_err!("Upgrade failed."))?;

    new_blob_handler(&upgraded_blob).context(ks_err!("calling new_blob_handler."))?;

    km_op(&upgraded_blob)
        .map(|v| (v, Some(upgraded_blob)))
        .context(ks_err!("Calling km_op after upgrade."))
}

/// This function can be used to upgrade key blobs on demand. The return value of
/// `km_op` is inspected and if ErrorCode::KEY_REQUIRES_UPGRADE is encountered,
/// an attempt is made to upgrade the key blob. On success `new_blob_handler` is called
/// with the upgraded blob as argument. Then `km_op` is called a second time with the
/// upgraded blob as argument. On success a tuple of the `km_op`s result and the
/// optional upgraded blob is returned.
pub fn upgrade_keyblob_if_required_with<T, KmOp, NewBlobHandler>(
    km_dev: &dyn IKeyMintDevice,
    km_dev_version: i32,
    key_blob: &[u8],
    upgrade_params: &[KmKeyParameter],
    km_op: KmOp,
    new_blob_handler: NewBlobHandler,
) -> Result<(T, Option<Vec<u8>>)>
where
    KmOp: Fn(&[u8]) -> Result<T, Error>,
    NewBlobHandler: FnOnce(&[u8]) -> Result<()>,
{
    match km_op(key_blob) {
        Err(Error::Km(ErrorCode::KEY_REQUIRES_UPGRADE)) => upgrade_keyblob_and_perform_op(
            km_dev,
            key_blob,
            upgrade_params,
            km_op,
            new_blob_handler,
        ),
        Err(Error::Km(ErrorCode::INVALID_KEY_BLOB))
            if km_dev_version >= KeyMintDevice::KEY_MINT_V1 =>
        {
            // A KeyMint (not Keymaster via km_compat) device says that this is an invalid keyblob.
            //
            // This may be because the keyblob was created before an Android upgrade, and as part of
            // the device upgrade the underlying Keymaster/KeyMint implementation has been upgraded.
            //
            // If that's the case, there are three possible scenarios:
            if key_blob.starts_with(km_compat::KEYMASTER_BLOB_HW_PREFIX) {
                // 1) The keyblob was created in hardware by the km_compat C++ code, using a prior
                //    Keymaster implementation, and wrapped.
                //
                //    In this case, the keyblob will have the km_compat magic prefix, including the
                //    marker that indicates that this was a hardware-backed key.
                //
                //    The inner keyblob should still be recognized by the hardware implementation, so
                //    strip the prefix and attempt a key upgrade.
                log::info!(
                    "found apparent km_compat(Keymaster) HW blob, attempt strip-and-upgrade"
                );
                let inner_keyblob = &key_blob[km_compat::KEYMASTER_BLOB_HW_PREFIX.len()..];
                upgrade_keyblob_and_perform_op(
                    km_dev,
                    inner_keyblob,
                    upgrade_params,
                    km_op,
                    new_blob_handler,
                )
            } else if keystore2_flags::import_previously_emulated_keys()
                && key_blob.starts_with(km_compat::KEYMASTER_BLOB_SW_PREFIX)
            {
                // 2) The keyblob was created in software by the km_compat C++ code because a prior
                //    Keymaster implementation did not support ECDH (which was only added in KeyMint).
                //
                //    In this case, the keyblob with have the km_compat magic prefix, but with the
                //    marker that indicates that this was a software-emulated key.
                //
                //    The inner keyblob should be in the format produced by the C++ reference
                //    implementation of KeyMint.  Extract the key material and import it into the
                //    current KeyMint device.
                log::info!("found apparent km_compat(Keymaster) SW blob, attempt strip-and-import");
                let inner_keyblob = &key_blob[km_compat::KEYMASTER_BLOB_SW_PREFIX.len()..];
                import_keyblob_and_perform_op(
                    km_dev,
                    inner_keyblob,
                    upgrade_params,
                    km_op,
                    new_blob_handler,
                )
            } else if let (true, km_compat::KeyBlob::Wrapped(inner_keyblob)) = (
                keystore2_flags::import_previously_emulated_keys(),
                km_compat::unwrap_keyblob(key_blob),
            ) {
                // 3) The keyblob was created in software by km_compat.rs because a prior KeyMint
                //    implementation did not support a feature present in the current KeyMint spec.
                //    (For example, a curve 25519 key created when the device only supported KeyMint
                //    v1).
                //
                //    In this case, the keyblob with have the km_compat.rs wrapper around it to
                //    indicate that this was a software-emulated key.
                //
                //    The inner keyblob should be in the format produced by the C++ reference
                //    implementation of KeyMint.  Extract the key material and import it into the
                //    current KeyMint device.
                log::info!(
                    "found apparent km_compat.rs(KeyMint) SW blob, attempt strip-and-import"
                );
                import_keyblob_and_perform_op(
                    km_dev,
                    inner_keyblob,
                    upgrade_params,
                    km_op,
                    new_blob_handler,
                )
            } else {
                Err(Error::Km(ErrorCode::INVALID_KEY_BLOB)).context(ks_err!("Calling km_op"))
            }
        }
        r => r.map(|v| (v, None)).context(ks_err!("Calling km_op.")),
    }
}

/// Converts a set of key characteristics from the internal representation into a set of
/// Authorizations as they are used to convey key characteristics to the clients of keystore.
pub fn key_parameters_to_authorizations(
    parameters: Vec<crate::key_parameter::KeyParameter>,
) -> Vec<Authorization> {
    parameters.into_iter().map(|p| p.into_authorization()).collect()
}

#[allow(clippy::unnecessary_cast)]
/// This returns the current time (in milliseconds) as an instance of a monotonic clock,
/// by invoking the system call since Rust does not support getting monotonic time instance
/// as an integer.
pub fn get_current_time_in_milliseconds() -> i64 {
    let mut current_time = libc::timespec { tv_sec: 0, tv_nsec: 0 };
    // SAFETY: The pointer is valid because it comes from a reference, and clock_gettime doesn't
    // retain it beyond the call.
    unsafe { libc::clock_gettime(libc::CLOCK_BOOTTIME, &mut current_time) };
    current_time.tv_sec as i64 * 1000 + (current_time.tv_nsec as i64 / 1_000_000)
}

/// Converts a response code as returned by the Android Protected Confirmation HIDL compatibility
/// module (keystore2_apc_compat) into a ResponseCode as defined by the APC AIDL
/// (android.security.apc) spec.
pub fn compat_2_response_code(rc: u32) -> ApcResponseCode {
    match rc {
        APC_COMPAT_ERROR_OK => ApcResponseCode::OK,
        APC_COMPAT_ERROR_CANCELLED => ApcResponseCode::CANCELLED,
        APC_COMPAT_ERROR_ABORTED => ApcResponseCode::ABORTED,
        APC_COMPAT_ERROR_OPERATION_PENDING => ApcResponseCode::OPERATION_PENDING,
        APC_COMPAT_ERROR_IGNORED => ApcResponseCode::IGNORED,
        APC_COMPAT_ERROR_SYSTEM_ERROR => ApcResponseCode::SYSTEM_ERROR,
        _ => ApcResponseCode::SYSTEM_ERROR,
    }
}

/// Converts the UI Options flags as defined by the APC AIDL (android.security.apc) spec into
/// UI Options flags as defined by the Android Protected Confirmation HIDL compatibility
/// module (keystore2_apc_compat).
pub fn ui_opts_2_compat(opt: i32) -> ApcCompatUiOptions {
    ApcCompatUiOptions {
        inverted: (opt & FLAG_UI_OPTION_INVERTED) != 0,
        magnified: (opt & FLAG_UI_OPTION_MAGNIFIED) != 0,
    }
}

/// AID offset for uid space partitioning.
pub const AID_USER_OFFSET: u32 = rustutils::users::AID_USER_OFFSET;

/// AID of the keystore process itself, used for keys that
/// keystore generates for its own use.
pub const AID_KEYSTORE: u32 = rustutils::users::AID_KEYSTORE;

/// Extracts the android user from the given uid.
pub fn uid_to_android_user(uid: u32) -> u32 {
    rustutils::users::multiuser_get_user_id(uid)
}

/// Merges and filters two lists of key descriptors. The first input list, legacy_descriptors,
/// is assumed to not be sorted or filtered. As such, all key descriptors in that list whose
/// alias is less than, or equal to, start_past_alias (if provided) will be removed.
/// This list will then be merged with the second list, db_descriptors. The db_descriptors list
/// is assumed to be sorted and filtered so the output list will be sorted prior to returning.
/// The returned value is a list of KeyDescriptor objects whose alias is greater than
/// start_past_alias, sorted and de-duplicated.
fn merge_and_filter_key_entry_lists(
    legacy_descriptors: &[KeyDescriptor],
    db_descriptors: &[KeyDescriptor],
    start_past_alias: Option<&str>,
) -> Vec<KeyDescriptor> {
    let mut result: Vec<KeyDescriptor> =
        match start_past_alias {
            Some(past_alias) => legacy_descriptors
                .iter()
                .filter(|kd| {
                    if let Some(alias) = &kd.alias {
                        alias.as_str() > past_alias
                    } else {
                        false
                    }
                })
                .cloned()
                .collect(),
            None => legacy_descriptors.to_vec(),
        };

    result.extend_from_slice(db_descriptors);
    result.sort_unstable();
    result.dedup();
    result
}

pub(crate) fn estimate_safe_amount_to_return(
    domain: Domain,
    namespace: i64,
    key_descriptors: &[KeyDescriptor],
    response_size_limit: usize,
) -> usize {
    let mut items_to_return = 0;
    let mut returned_bytes: usize = 0;
    // Estimate the transaction size to avoid returning more items than what
    // could fit in a binder transaction.
    for kd in key_descriptors.iter() {
        // 4 bytes for the Domain enum
        // 8 bytes for the Namespace long.
        returned_bytes += 4 + 8;
        // Size of the alias string. Includes 4 bytes for length encoding.
        if let Some(alias) = &kd.alias {
            returned_bytes += 4 + alias.len();
        }
        // Size of the blob. Includes 4 bytes for length encoding.
        if let Some(blob) = &kd.blob {
            returned_bytes += 4 + blob.len();
        }
        // The binder transaction size limit is 1M. Empirical measurements show
        // that the binder overhead is 60% (to be confirmed). So break after
        // 350KB and return a partial list.
        if returned_bytes > response_size_limit {
            log::warn!(
                "{domain:?}:{namespace}: Key descriptors list ({} items) may exceed binder \
                       size, returning {items_to_return} items est {returned_bytes} bytes.",
                key_descriptors.len(),
            );
            break;
        }
        items_to_return += 1;
    }
    items_to_return
}

/// Estimate for maximum size of a Binder response in bytes.
pub(crate) const RESPONSE_SIZE_LIMIT: usize = 358400;

/// List all key aliases for a given domain + namespace. whose alias is greater
/// than start_past_alias (if provided).
pub fn list_key_entries(
    db: &mut KeystoreDB,
    domain: Domain,
    namespace: i64,
    start_past_alias: Option<&str>,
) -> Result<Vec<KeyDescriptor>> {
    let legacy_key_descriptors: Vec<KeyDescriptor> = LEGACY_IMPORTER
        .list_uid(domain, namespace)
        .context(ks_err!("Trying to list legacy keys."))?;

    // The results from the database will be sorted and unique
    let db_key_descriptors: Vec<KeyDescriptor> = db
        .list_past_alias(domain, namespace, KeyType::Client, start_past_alias)
        .context(ks_err!("Trying to list keystore database past alias."))?;

    let merged_key_entries = merge_and_filter_key_entry_lists(
        &legacy_key_descriptors,
        &db_key_descriptors,
        start_past_alias,
    );

    let safe_amount_to_return =
        estimate_safe_amount_to_return(domain, namespace, &merged_key_entries, RESPONSE_SIZE_LIMIT);
    Ok(merged_key_entries[..safe_amount_to_return].to_vec())
}

/// Count all key aliases for a given domain + namespace.
pub fn count_key_entries(db: &mut KeystoreDB, domain: Domain, namespace: i64) -> Result<i32> {
    let legacy_keys = LEGACY_IMPORTER
        .list_uid(domain, namespace)
        .context(ks_err!("Trying to list legacy keys."))?;

    let num_keys_in_db = db.count_keys(domain, namespace, KeyType::Client)?;

    Ok((legacy_keys.len() + num_keys_in_db) as i32)
}

/// For params remove sensitive data before returning a string for logging
pub fn log_security_safe_params(params: &[KmKeyParameter]) -> Vec<KmKeyParameter> {
    params
        .iter()
        .filter(|kp| (kp.tag != Tag::APPLICATION_ID && kp.tag != Tag::APPLICATION_DATA))
        .cloned()
        .collect::<Vec<KmKeyParameter>>()
}

/// Trait implemented by objects that can be used to decrypt cipher text using AES-GCM.
pub trait AesGcm {
    /// Deciphers `data` using the initialization vector `iv` and AEAD tag `tag`
    /// and AES-GCM. The implementation provides the key material and selects
    /// the implementation variant, e.g., AES128 or AES265.
    fn decrypt(&self, data: &[u8], iv: &[u8], tag: &[u8]) -> Result<ZVec>;

    /// Encrypts `data` and returns the ciphertext, the initialization vector `iv`
    /// and AEAD tag `tag`. The implementation provides the key material and selects
    /// the implementation variant, e.g., AES128 or AES265.
    fn encrypt(&self, plaintext: &[u8]) -> Result<(Vec<u8>, Vec<u8>, Vec<u8>)>;
}

/// Marks an object as AES-GCM key.
pub trait AesGcmKey {
    /// Provides access to the raw key material.
    fn key(&self) -> &[u8];
}

impl<T: AesGcmKey> AesGcm for T {
    fn decrypt(&self, data: &[u8], iv: &[u8], tag: &[u8]) -> Result<ZVec> {
        aes_gcm_decrypt(data, iv, tag, self.key()).context(ks_err!("Decryption failed"))
    }

    fn encrypt(&self, plaintext: &[u8]) -> Result<(Vec<u8>, Vec<u8>, Vec<u8>)> {
        aes_gcm_encrypt(plaintext, self.key()).context(ks_err!("Encryption failed."))
    }
}

pub(crate) fn retry_get_interface<T: FromIBinder + ?Sized>(
    name: &str,
) -> Result<Strong<T>, StatusCode> {
    let retry_count = if cfg!(early_vm) { 5 } else { 1 };

    let mut wait_time = Duration::from_secs(5);
    for i in 1..retry_count {
        match binder::get_interface(name) {
            Ok(res) => return Ok(res),
            Err(e) => {
                warn!("failed to get interface {name}. Retry {i}/{retry_count}: {e:?}");
                sleep(wait_time);
                wait_time *= 2;
            }
        }
    }
    if retry_count > 1 {
        info!("{retry_count}-th (last) retry to get interface: {name}");
    }
    binder::get_interface(name)
}
