Merge "keystore2: Use libbinder_rs Strong references for Binder objects"

This commit is contained in:
Matthew Maurer 2021-02-10 19:06:53 +00:00 committed by Gerrit Code Review
commit 84a668248f
12 changed files with 50 additions and 45 deletions

View file

@ -28,7 +28,7 @@ use android_security_apc::aidl::android::security::apc::{
ResponseCode::ResponseCode,
};
use android_security_apc::binder::{
ExceptionCode, Interface, Result as BinderResult, SpIBinder, Status as BinderStatus,
ExceptionCode, Interface, Result as BinderResult, SpIBinder, Status as BinderStatus, Strong,
};
use anyhow::{Context, Result};
use binder::{IBinder, ThreadState};
@ -202,7 +202,7 @@ impl ApcManager {
/// Create a new instance of the Android Protected Confirmation service.
pub fn new_native_binder(
confirmation_token_sender: Sender<Vec<u8>>,
) -> Result<impl IProtectedConfirmation> {
) -> Result<Strong<dyn IProtectedConfirmation>> {
let result = BnProtectedConfirmation::new_binder(Self {
state: Arc::new(Mutex::new(ApcState::new(confirmation_token_sender))),
});

View file

@ -25,8 +25,8 @@ use android_hardware_security_keymint::aidl::android::hardware::security::keymin
use android_hardware_security_secureclock::aidl::android::hardware::security::secureclock::{
Timestamp::Timestamp,
};
use android_security_authorization::binder::{Interface, Result as BinderResult};
use android_security_authorization:: aidl::android::security::authorization::IKeystoreAuthorization::{
use android_security_authorization::binder::{Interface, Result as BinderResult, Strong};
use android_security_authorization::aidl::android::security::authorization::IKeystoreAuthorization::{
BnKeystoreAuthorization, IKeystoreAuthorization,
};
use android_security_authorization:: aidl::android::security::authorization::LockScreenEvent::LockScreenEvent;
@ -40,7 +40,7 @@ pub struct AuthorizationManager;
impl AuthorizationManager {
/// Create a new instance of Keystore Authorization service.
pub fn new_native_binder() -> Result<impl IKeystoreAuthorization> {
pub fn new_native_binder() -> Result<Strong<dyn IKeystoreAuthorization>> {
let result = BnKeystoreAuthorization::new_binder(Self);
result.as_binder().set_requesting_sid(true);
Ok(result)

View file

@ -30,6 +30,7 @@ use android_hardware_security_secureclock::aidl::android::hardware::security::se
ISecureClock::ISecureClock, TimeStampToken::TimeStampToken,
};
use android_system_keystore2::aidl::android::system::keystore2::OperationChallenge::OperationChallenge;
use android_system_keystore2::binder::Strong;
use anyhow::{Context, Result};
use std::sync::{
mpsc::{channel, Receiver, Sender},
@ -202,7 +203,7 @@ impl TokenReceiver {
}
fn get_timestamp_token(challenge: i64) -> Result<TimeStampToken, Error> {
let dev: Box<dyn ISecureClock> = get_timestamp_service()
let dev: Strong<dyn ISecureClock> = get_timestamp_service()
.expect(concat!(
"Secure Clock service must be present ",
"if TimeStampTokens are required."

View file

@ -21,6 +21,7 @@
use crate::globals::{get_keymint_dev_by_uuid, DB};
use crate::{error::map_km_error, globals::ASYNC_TASK};
use android_hardware_security_keymint::aidl::android::hardware::security::keymint::IKeyMintDevice::IKeyMintDevice;
use android_hardware_security_keymint::binder::Strong;
use anyhow::Result;
#[derive(Clone, Copy)]
@ -41,7 +42,7 @@ impl Gc {
let mut db = db.borrow_mut();
if let Some((key_id, mut key_entry)) = db.get_unreferenced_key()? {
if let Some(blob) = key_entry.take_km_blob() {
let km_dev: Box<dyn IKeyMintDevice> =
let km_dev: Strong<dyn IKeyMintDevice> =
get_keymint_dev_by_uuid(key_entry.km_uuid())
.map(|(dev, _)| dev)?
.get_interface()?;

View file

@ -30,7 +30,7 @@ use crate::{enforcements::Enforcements, error::map_km_error};
use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
KeyMintHardwareInfo::KeyMintHardwareInfo, SecurityLevel::SecurityLevel,
};
use android_hardware_security_keymint::binder::StatusCode;
use android_hardware_security_keymint::binder::{StatusCode, Strong};
use android_security_compat::aidl::android::security::compat::IKeystoreCompatService::IKeystoreCompatService;
use anyhow::{Context, Result};
use lazy_static::lazy_static;
@ -152,7 +152,7 @@ fn connect_keymint(security_level: &SecurityLevel) -> Result<(Asp, KeyMintHardwa
// This is a no-op if it was called before.
keystore2_km_compat::add_keymint_device_service();
let keystore_compat_service: Box<dyn IKeystoreCompatService> =
let keystore_compat_service: Strong<dyn IKeystoreCompatService> =
map_binder_status_code(binder::get_interface("android.security.compat"))
.context("In connect_keymint: Trying to connect to compat service.")?;
map_binder_status(keystore_compat_service.getKeyMintDevice(*security_level))
@ -218,7 +218,7 @@ fn connect_secureclock() -> Result<Asp> {
// This is a no-op if it was called before.
keystore2_km_compat::add_keymint_device_service();
let keystore_compat_service: Box<dyn IKeystoreCompatService> =
let keystore_compat_service: Strong<dyn IKeystoreCompatService> =
map_binder_status_code(binder::get_interface("android.security.compat"))
.context(
"In connect_secureclock: Trying to connect to compat service.",

View file

@ -14,7 +14,6 @@
//! This crate implements the Keystore 2.0 service entry point.
use binder::Interface;
use keystore2::apc::ApcManager;
use keystore2::authorization::AuthorizationManager;
use keystore2::globals::ENFORCEMENTS;

View file

@ -34,14 +34,14 @@ mod tests {
KeyParameterArray::KeyParameterArray, KeyParameterValue::KeyParameterValue,
KeyPurpose::KeyPurpose, PaddingMode::PaddingMode, SecurityLevel::SecurityLevel, Tag::Tag,
};
use android_hardware_security_keymint::binder;
use android_hardware_security_keymint::binder::{self, Strong};
use android_security_compat::aidl::android::security::compat::IKeystoreCompatService::IKeystoreCompatService;
static COMPAT_NAME: &str = "android.security.compat";
fn get_device() -> Option<Box<dyn IKeyMintDevice>> {
fn get_device() -> Option<Strong<dyn IKeyMintDevice>> {
add_keymint_device_service();
let compat_service: Box<dyn IKeystoreCompatService> =
let compat_service: Strong<dyn IKeystoreCompatService> =
binder::get_interface(COMPAT_NAME).ok()?;
compat_service.getKeyMintDevice(SecurityLevel::TRUSTED_ENVIRONMENT).ok()
}
@ -321,7 +321,7 @@ mod tests {
#[test]
fn test_secure_clock() {
add_keymint_device_service();
let compat_service: Box<dyn IKeystoreCompatService> =
let compat_service: binder::Strong<dyn IKeystoreCompatService> =
binder::get_interface(COMPAT_NAME).unwrap();
let secure_clock = compat_service.getSecureClock().unwrap();
@ -336,7 +336,7 @@ mod tests {
#[test]
fn test_shared_secret() {
add_keymint_device_service();
let compat_service: Box<dyn IKeystoreCompatService> =
let compat_service: binder::Strong<dyn IKeystoreCompatService> =
binder::get_interface(COMPAT_NAME).unwrap();
let shared_secret =
compat_service.getSharedSecret(SecurityLevel::TRUSTED_ENVIRONMENT).unwrap();

View file

@ -137,7 +137,7 @@ use android_system_keystore2::aidl::android::system::keystore2::{
IKeystoreOperation::BnKeystoreOperation, IKeystoreOperation::IKeystoreOperation,
};
use anyhow::{anyhow, Context, Result};
use binder::{IBinder, Interface};
use binder::IBinder;
use std::{
collections::HashMap,
sync::{Arc, Mutex, MutexGuard, Weak},
@ -184,7 +184,7 @@ impl Operation {
/// Constructor
pub fn new(
index: usize,
km_op: Box<dyn IKeyMintOperation>,
km_op: binder::Strong<dyn IKeyMintOperation>,
owner: u32,
auth_info: AuthInfo,
) -> Self {
@ -247,13 +247,14 @@ impl Operation {
}
*locked_outcome = Outcome::Pruned;
let km_op: Box<dyn IKeyMintOperation> = match self.km_op.get_interface() {
Ok(km_op) => km_op,
Err(e) => {
log::error!("In prune: Failed to get KeyMintOperation interface.\n {:?}", e);
return Err(Error::sys());
}
};
let km_op: binder::public_api::Strong<dyn IKeyMintOperation> =
match self.km_op.get_interface() {
Ok(km_op) => km_op,
Err(e) => {
log::error!("In prune: Failed to get KeyMintOperation interface.\n {:?}", e);
return Err(Error::sys());
}
};
// We abort the operation. If there was an error we log it but ignore it.
if let Err(e) = map_km_error(km_op.abort()) {
@ -334,7 +335,7 @@ impl Operation {
let mut out_params: Option<KeyParameterArray> = None;
let mut output: Option<ByteArray> = None;
let km_op: Box<dyn IKeyMintOperation> =
let km_op: binder::public_api::Strong<dyn IKeyMintOperation> =
self.km_op.get_interface().context("In update: Failed to get KeyMintOperation.")?;
let (hat, tst) = self
@ -369,7 +370,7 @@ impl Operation {
let mut out_params: Option<KeyParameterArray> = None;
let km_op: Box<dyn IKeyMintOperation> =
let km_op: binder::public_api::Strong<dyn IKeyMintOperation> =
self.km_op.get_interface().context("In update: Failed to get KeyMintOperation.")?;
let (hat, tst) = self
@ -426,7 +427,7 @@ impl Operation {
let mut out_params: Option<KeyParameterArray> = None;
let km_op: Box<dyn IKeyMintOperation> =
let km_op: binder::public_api::Strong<dyn IKeyMintOperation> =
self.km_op.get_interface().context("In finish: Failed to get KeyMintOperation.")?;
let (hat, tst, confirmation_token) = self
@ -475,7 +476,7 @@ impl Operation {
fn abort(&self, outcome: Outcome) -> Result<()> {
let mut locked_outcome = self.check_active().context("In abort")?;
*locked_outcome = outcome;
let km_op: Box<dyn IKeyMintOperation> =
let km_op: binder::public_api::Strong<dyn IKeyMintOperation> =
self.km_op.get_interface().context("In abort: Failed to get KeyMintOperation.")?;
map_km_error(km_op.abort()).context("In abort: KeyMint::abort failed.")
@ -514,7 +515,7 @@ impl OperationDb {
/// owner uid and returns a new Operation wrapped in a `std::sync::Arc`.
pub fn create_operation(
&self,
km_op: Box<dyn IKeyMintOperation>,
km_op: binder::public_api::Strong<dyn IKeyMintOperation>,
owner: u32,
auth_info: AuthInfo,
) -> Arc<Operation> {
@ -770,7 +771,9 @@ impl KeystoreOperation {
/// BnKeystoreOperation proxy object. It also
/// calls `IBinder::set_requesting_sid` on the new interface, because
/// we need it for checking Keystore permissions.
pub fn new_native_binder(operation: Arc<Operation>) -> impl IKeystoreOperation + Send {
pub fn new_native_binder(
operation: Arc<Operation>,
) -> binder::public_api::Strong<dyn IKeystoreOperation> {
let result =
BnKeystoreOperation::new_binder(Self { operation: Mutex::new(Some(operation)) });
result.as_binder().set_requesting_sid(true);

View file

@ -25,6 +25,7 @@ use android_security_remoteprovisioning::aidl::android::security::remoteprovisio
AttestationPoolStatus::AttestationPoolStatus, IRemoteProvisioning::BnRemoteProvisioning,
IRemoteProvisioning::IRemoteProvisioning,
};
use android_security_remoteprovisioning::binder::Strong;
use anyhow::Result;
use crate::error::map_or_log_err;
@ -37,7 +38,7 @@ pub struct RemoteProvisioningService {
impl RemoteProvisioningService {
/// Creates a new instance of the remote provisioning service
pub fn new_native_binder() -> Result<impl IRemoteProvisioning> {
pub fn new_native_binder() -> Result<Strong<dyn IRemoteProvisioning>> {
let result = BnRemoteProvisioning::new_binder(Self {});
Ok(result)
}

View file

@ -53,7 +53,7 @@ use crate::{
utils::key_characteristics_to_internal,
};
use anyhow::{anyhow, Context, Result};
use binder::{IBinder, Interface, ThreadState};
use binder::{IBinder, Strong, ThreadState};
/// Implementation of the IKeystoreSecurityLevel Interface.
pub struct KeystoreSecurityLevel {
@ -79,7 +79,7 @@ impl KeystoreSecurityLevel {
/// we need it for checking keystore permissions.
pub fn new_native_binder(
security_level: SecurityLevel,
) -> Result<(impl IKeystoreSecurityLevel + Send, Uuid)> {
) -> Result<(Strong<dyn IKeystoreSecurityLevel>, Uuid)> {
let (dev, hw_info, km_uuid) = get_keymint_device(&security_level)
.context("In KeystoreSecurityLevel::new_native_binder.")?;
let result = BnKeystoreSecurityLevel::new_binder(Self {
@ -256,7 +256,7 @@ impl KeystoreSecurityLevel {
let immediate_hat = immediate_hat.unwrap_or_default();
let km_dev: Box<dyn IKeyMintDevice> = self
let km_dev: Strong<dyn IKeyMintDevice> = self
.keymint
.get_interface()
.context("In create_operation: Failed to get KeyMint device")?;
@ -293,7 +293,7 @@ impl KeystoreSecurityLevel {
None => return Err(Error::sys()).context("In create_operation: Begin operation returned successfully, but did not return a valid operation."),
};
let op_binder: Box<dyn IKeystoreOperation> =
let op_binder: binder::public_api::Strong<dyn IKeystoreOperation> =
KeystoreOperation::new_native_binder(operation)
.as_binder()
.into_interface()
@ -386,7 +386,7 @@ impl KeystoreSecurityLevel {
let params = Self::add_certificate_parameters(caller_uid, params, &key)
.context("In generate_key: Trying to get aaid.")?;
let km_dev: Box<dyn IKeyMintDevice> = self.keymint.get_interface()?;
let km_dev: Strong<dyn IKeyMintDevice> = self.keymint.get_interface()?;
map_km_error(km_dev.addRngEntropy(entropy))
.context("In generate_key: Trying to add entropy.")?;
let creation_result = map_km_error(km_dev.generateKey(&params))
@ -442,7 +442,7 @@ impl KeystoreSecurityLevel {
})
.context("In import_key.")?;
let km_dev: Box<dyn IKeyMintDevice> =
let km_dev: Strong<dyn IKeyMintDevice> =
self.keymint.get_interface().context("In import_key: Trying to get the KM device")?;
let creation_result = map_km_error(km_dev.importKey(&params, format, key_data))
.context("In import_key: Trying to call importKey")?;
@ -544,7 +544,7 @@ impl KeystoreSecurityLevel {
let masking_key = masking_key.unwrap_or(ZERO_BLOB_32);
let km_dev: Box<dyn IKeyMintDevice> = self.keymint.get_interface()?;
let km_dev: Strong<dyn IKeyMintDevice> = self.keymint.get_interface()?;
let (creation_result, _) = self
.upgrade_keyblob_if_required_with(
&*km_dev,

View file

@ -43,7 +43,7 @@ use android_system_keystore2::aidl::android::system::keystore2::{
KeyDescriptor::KeyDescriptor, KeyEntryResponse::KeyEntryResponse, KeyMetadata::KeyMetadata,
};
use anyhow::{Context, Result};
use binder::{IBinder, Interface, ThreadState};
use binder::{IBinder, Strong, ThreadState};
use error::Error;
use keystore2_selinux as selinux;
@ -56,7 +56,7 @@ pub struct KeystoreService {
impl KeystoreService {
/// Create a new instance of the Keystore 2.0 service.
pub fn new_native_binder() -> Result<impl IKeystoreService> {
pub fn new_native_binder() -> Result<Strong<dyn IKeystoreService>> {
let mut result: Self = Default::default();
let (dev, uuid) =
KeystoreSecurityLevel::new_native_binder(SecurityLevel::TRUSTED_ENVIRONMENT)
@ -89,7 +89,7 @@ impl KeystoreService {
.unwrap_or(SecurityLevel::SOFTWARE)
}
fn get_i_sec_level_by_uuid(&self, uuid: &Uuid) -> Result<Box<dyn IKeystoreSecurityLevel>> {
fn get_i_sec_level_by_uuid(&self, uuid: &Uuid) -> Result<Strong<dyn IKeystoreSecurityLevel>> {
if let Some(dev) = self.i_sec_level_by_uuid.get(uuid) {
dev.get_interface().context("In get_i_sec_level_by_uuid.")
} else {
@ -101,7 +101,7 @@ impl KeystoreService {
fn get_security_level(
&self,
sec_level: SecurityLevel,
) -> Result<Box<dyn IKeystoreSecurityLevel>> {
) -> Result<Strong<dyn IKeystoreSecurityLevel>> {
if let Some(dev) = self
.uuid_by_sec_level
.get(&sec_level)
@ -318,7 +318,7 @@ impl IKeystoreService for KeystoreService {
fn getSecurityLevel(
&self,
security_level: SecurityLevel,
) -> binder::public_api::Result<Box<dyn IKeystoreSecurityLevel>> {
) -> binder::public_api::Result<Strong<dyn IKeystoreSecurityLevel>> {
map_or_log_err(self.get_security_level(security_level), Ok)
}
fn getKeyEntry(&self, key: &KeyDescriptor) -> binder::public_api::Result<KeyEntryResponse> {

View file

@ -103,7 +103,7 @@ impl Asp {
}
/// Clones the owned SpIBinder and attempts to convert it into the requested interface.
pub fn get_interface<T: FromIBinder + ?Sized>(&self) -> anyhow::Result<Box<T>> {
pub fn get_interface<T: FromIBinder + ?Sized>(&self) -> anyhow::Result<binder::Strong<T>> {
// We can use unwrap here because we never panic when locked, so the mutex
// can never be poisoned.
let lock = self.0.lock().unwrap();