Skip to content

Commit ebae887

Browse files
committed
Added the 'AsAny' trait to allow casting from 'FapiCallback' to the concrete type, even in older Rust versions.
1 parent 71600b3 commit ebae887

File tree

6 files changed

+53
-25
lines changed

6 files changed

+53
-25
lines changed

.github/workflows/cargo-workflow.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ on:
55
TOOLCHAIN_MIN:
66
required: false
77
type: string
8-
default: "1.86.0"
8+
default: "1.85.0"
99
TOOLCHAIN_MAX:
1010
required: false
1111
type: string

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
name = "tss2-fapi-rs"
33
version = "0.9.0"
44
edition = "2024"
5-
rust-version = "1.86"
5+
rust-version = "1.85"
66
description = "Provides a Rust interface to the TSS2.0 Feature API (FAPI)"
77
license = "BSD-3-Clause"
88
authors = ["Daniel Trick <daniel.trick@sit.fraunhofer.de>"]

src/callback.rs

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -100,16 +100,41 @@ impl<'a> PolicyActionCbParam<'a> {
100100
}
101101
}
102102

103+
// ==========================================================================
104+
// AsAny trait
105+
// ==========================================================================
106+
107+
/// Helper trait that provides the [`as_any()`](AsAny::as_any) and [`as_mut_any()`](AsAny::as_mut_any) functions.
108+
pub trait AsAny {
109+
/// A helper function that returns the implementation as a [`&dyn Any`](std::any::Any) reference.
110+
fn as_any(&self) -> &dyn Any;
111+
112+
/// A helper function that returns the implementation as a [`&mut dyn Any`](std::any::Any) reference.
113+
fn as_mut_any(&mut self) -> &mut dyn Any;
114+
}
115+
116+
impl<T: Any> AsAny for T {
117+
fn as_any(&self) -> &dyn Any {
118+
self
119+
}
120+
121+
fn as_mut_any(&mut self) -> &mut dyn Any {
122+
self
123+
}
124+
}
125+
103126
// ==========================================================================
104127
// Callbacks trait
105128
// ==========================================================================
106129

107130
/// Represents the set of application-defined callback functions that the FAPI invokes.
108131
///
109-
/// Implementations of this trait can be registered with a FAPI context via the [`FapiContext::set_callbacks()`](crate::FapiContext::set_callbacks) function.
132+
/// Implementations of this trait are registered with a FAPI context via the [**`FapiContext::set_callbacks()`**](crate::FapiContext::set_callbacks) function.
110133
///
111134
/// ### Example
112135
///
136+
/// Applications shall implement this trait as follows:
137+
///
113138
/// ```
114139
/// #[derive(Debug)]
115140
/// pub struct MyCallbacks;
@@ -132,10 +157,10 @@ impl<'a> PolicyActionCbParam<'a> {
132157
/// }
133158
/// }
134159
/// ```
135-
pub trait FapiCallbacks: Any + Send + Debug {
160+
pub trait FapiCallbacks: AsAny + Send + Debug + 'static {
136161
/// A callback function that allows the FAPI to request authorization values.
137162
///
138-
/// The default implementation of this function returns `None`. Please override as needed!
163+
/// The default implementation of this function returns `None`. Please override the function as needed!
139164
///
140165
/// *See also:* [`Fapi_SetAuthCB()`](https://tpm2-tss.readthedocs.io/en/stable/group___fapi___set_auth_c_b.html)
141166
fn auth_cb(&self, _param: AuthCbParam) -> Option<Cow<'static, str>> {
@@ -146,7 +171,7 @@ pub trait FapiCallbacks: Any + Send + Debug {
146171
///
147172
/// Signatures are requested for authorizing TPM objects.
148173
///
149-
/// The default implementation of this function returns `None`. Please override as needed!
174+
/// The default implementation of this function returns `None`. Please override the function as needed!
150175
///
151176
/// *See also:* [`Fapi_SetSignCB()`](https://tpm2-tss.readthedocs.io/en/stable/group___fapi___set_sign_c_b.html)
152177
fn sign_cb(&self, _param: SignCbParam) -> Option<Vec<u8>> {
@@ -157,7 +182,7 @@ pub trait FapiCallbacks: Any + Send + Debug {
157182
///
158183
/// It is usually called during policy evaluation.
159184
///
160-
/// The default implementation of this function returns `None`. Please override as needed!
185+
/// The default implementation of this function returns `None`. Please override the function as needed!
161186
///
162187
/// *See also:* [`Fapi_SetBranchCB()`](https://tpm2-tss.readthedocs.io/en/stable/group___fapi___set_sign_c_b.html)
163188
fn branch_cb(&self, _param: BranchCbParam) -> Option<usize> {
@@ -168,7 +193,7 @@ pub trait FapiCallbacks: Any + Send + Debug {
168193
///
169194
/// It is usually called to announce policy actions.
170195
///
171-
/// The default implementation of this function returns `false`. Please override as needed!
196+
/// The default implementation of this function returns `false`. Please override the function as needed!
172197
///
173198
/// *See also:* [`Fapi_SetPolicyActionCB()`](https://tpm2-tss.readthedocs.io/en/stable/group___fapi___set_sign_c_b.html)
174199
fn policy_action_cb(&self, _param: PolicyActionCbParam) -> bool {

src/context.rs

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -148,18 +148,18 @@ impl FapiContext {
148148
// Callback setters
149149
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
150150

151-
/// This function registers application-defined callback functions with the FAPI context, replacing any previously registered callbacks.
151+
/// Registers application-defined callback functions with the FAPI context, replacing the previously registered callbacks.
152152
///
153-
/// The callback functions are implemented via the [`FapiCallbacks`](crate::FapiCallbacks) trait.
153+
/// Please see the [**`FapiCallbacks`**](crate::FapiCallbacks) trait for details!
154154
///
155-
/// If successful, the function retruns the previously registered callback functions, which may be `None`.
155+
/// If successful, the function retruns an option containing the previously registered `FapiCallbacks`, which may be `None`.
156156
///
157157
/// *See also:*
158158
/// - [`Fapi_SetAuthCB()`](https://tpm2-tss.readthedocs.io/en/stable/group___fapi___set_auth_c_b.html)
159159
/// - [`Fapi_SetSignCB()`](https://tpm2-tss.readthedocs.io/en/stable/group___fapi___set_sign_c_b.html)
160160
/// - [`Fapi_SetBranchCB()`](https://tpm2-tss.readthedocs.io/en/stable/group___fapi___set_sign_c_b.html)
161161
/// - [`Fapi_SetPolicyActionCB()`](https://tpm2-tss.readthedocs.io/en/stable/group___fapi___set_sign_c_b.html)
162-
pub fn set_callbacks(&mut self, callbacks: impl FapiCallbacks + 'static) -> Result<Option<Box<dyn FapiCallbacks>>, ErrorCode> {
162+
pub fn set_callbacks(&mut self, callbacks: impl FapiCallbacks) -> Result<Option<Box<dyn FapiCallbacks + 'static>>, ErrorCode> {
163163
let previous = self.callbacks.replace(CallbackManager::new(callbacks));
164164
let callbacks_ptr = self.callbacks.as_mut().unwrap() as *mut CallbackManager as *mut c_void;
165165
let results = [
@@ -171,10 +171,16 @@ impl FapiContext {
171171
results.iter().try_fold(previous.map(|cb| cb.into_inner()), |acc, ret| ret.map(|_| acc))
172172
}
173173

174-
/// This function un-registers the application-defined callback functions that have been registers via [`set_callbacks()`](FapiContext::set_callbacks).
174+
/// Un-registers the application-defined callback functions that have been registers via [`set_callbacks()`](FapiContext::set_callbacks).
175175
///
176-
/// If successful, the function retruns the previously registered callback functions, which may be `None`.
177-
pub fn clear_callbacks(&mut self) -> Result<Option<Box<dyn FapiCallbacks>>, ErrorCode> {
176+
/// If successful, the function retruns an option containing the previously registered `FapiCallbacks`, which may be `None`.
177+
///
178+
/// *See also:*
179+
/// - [`Fapi_SetAuthCB()`](https://tpm2-tss.readthedocs.io/en/stable/group___fapi___set_auth_c_b.html)
180+
/// - [`Fapi_SetSignCB()`](https://tpm2-tss.readthedocs.io/en/stable/group___fapi___set_sign_c_b.html)
181+
/// - [`Fapi_SetBranchCB()`](https://tpm2-tss.readthedocs.io/en/stable/group___fapi___set_sign_c_b.html)
182+
/// - [`Fapi_SetPolicyActionCB()`](https://tpm2-tss.readthedocs.io/en/stable/group___fapi___set_sign_c_b.html)
183+
pub fn clear_callbacks(&mut self) -> Result<Option<Box<dyn FapiCallbacks + 'static>>, ErrorCode> {
178184
let previous = self.callbacks.take();
179185
let results = [
180186
self.fapi_call(false, |context| unsafe { fapi_sys::Fapi_SetAuthCB(context, None, ptr::null_mut()) }),

src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -451,7 +451,7 @@ mod types;
451451
mod version;
452452

453453
pub use algorithm_id::HashAlgorithm;
454-
pub use callback::{AuthCbParam, BranchCbParam, FapiCallbacks, PolicyActionCbParam, SignCbParam};
454+
pub use callback::{AsAny, AuthCbParam, BranchCbParam, FapiCallbacks, PolicyActionCbParam, SignCbParam};
455455
pub use context::FapiContext;
456456
pub use error::{BaseErrorCode, ErrorCode, InternalError, Tpm2ErrFmt0, Tpm2ErrFmt1, Tpm2ErrorCode, Tpm2Warning};
457457
pub use flags::{BlobType, KeyFlags, NvFlags, PaddingFlags, QuoteFlags, SealFlags};

tests/09_policy_test.rs

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ use rand::SeedableRng;
2020
use rand_chacha::ChaChaRng;
2121
use serial_test::serial;
2222
use sha2::{Digest, Sha256};
23-
use std::{any::Any, fs, path::Path};
24-
use tss2_fapi_rs::{FapiContext, ImportData, KeyFlags, json::JsonValue};
23+
use std::{fs, path::Path};
24+
use tss2_fapi_rs::{FapiCallbacks, FapiContext, ImportData, KeyFlags, json::JsonValue};
2525

2626
const KEY_FLAGS_SIGN: &[KeyFlags] = &[KeyFlags::NoDA, KeyFlags::Sign];
2727

@@ -188,7 +188,8 @@ fn test_policy_or() {
188188
};
189189

190190
// Check retrieved branches
191-
let callbacks: Box<MyCallbacks> = downcast(context.clear_callbacks().expect("Failed to clear!").expect("No callbacks!")).expect("Downcast has failed!");
191+
let callbacks: Box<dyn FapiCallbacks> = context.clear_callbacks().expect("Failed to clear callbacks!").expect("No callbacks!");
192+
let callbacks: &MyCallbacks = callbacks.as_any().downcast_ref().expect("Downcast has failed!");
192193
let branches = callbacks.get_branches();
193194
assert_eq!(branches.len(), 2);
194195
assert!(branches[0].eq_ignore_ascii_case("#0,PolicySignedRSA"));
@@ -245,7 +246,8 @@ fn test_policy_action() {
245246
};
246247

247248
// Check retrieved actions
248-
let callbacks: Box<MyCallbacks> = downcast(context.clear_callbacks().expect("Failed to clear!").expect("No callbacks!")).expect("Downcast has failed!");
249+
let callbacks: Box<dyn FapiCallbacks> = context.clear_callbacks().expect("Failed to clear callbacks!").expect("No callbacks!");
250+
let callbacks: &MyCallbacks = callbacks.as_any().downcast_ref().expect("Downcast has failed!");
249251
let actions = callbacks.get_actions();
250252
assert!(!actions.is_empty());
251253
assert!(actions[0].eq_ignore_ascii_case("myaction"));
@@ -267,8 +269,3 @@ fn read_private_key(data_path: &Path, key_type: KeyType, key_name: &str) -> Opti
267269
let pem_file = data_path.join("keys").join(format!("{}.pem", key_name));
268270
fs::read_to_string(pem_file).ok().and_then(|pem_data| load_private_key(&pem_data[..], key_type))
269271
}
270-
271-
/// Downcast helper
272-
fn downcast<T: 'static>(boxed: Box<dyn Any>) -> Option<Box<T>> {
273-
boxed.downcast().ok()
274-
}

0 commit comments

Comments
 (0)