Skip to content

Commit 28ab6fd

Browse files
committed
Added the 'Callbacks' struct, as a simple generic implementation of the 'FapiCallbacks' trait.
1 parent fcf6a14 commit 28ab6fd

File tree

6 files changed

+123
-42
lines changed

6 files changed

+123
-42
lines changed

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,16 @@ All notable changes to this project will be documented in this file.
44

55
The format is based on [Keep a Changelog](http://keepachangelog.com/).
66

7+
## [0.10.0] - 2026-01-21
8+
9+
### Added
10+
11+
- Added the `Callbacks` struct, as a simple generic implementation of the `FapiCallbacks` trait.
12+
13+
### Changed
14+
15+
- The `FapiCallbacks` trait **no** longer has the `Debug` trait bound.
16+
717
## [0.9.0] - 2026-01-20
818

919
### Added

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "tss2-fapi-rs"
3-
version = "0.9.0"
3+
version = "0.10.0"
44
edition = "2024"
55
rust-version = "1.85"
66
description = "Provides a Rust interface to the TSS2.0 Feature API (FAPI)"

examples/3_auth_callback.rs

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
use env_logger::Builder as EnvLogger;
88
use log::{LevelFilter, debug, info, warn};
99
use std::borrow::Cow;
10-
use tss2_fapi_rs::{AuthCbParam, BaseErrorCode, ErrorCode, FapiCallbacks, FapiContext, KeyFlags};
10+
use tss2_fapi_rs::{BaseErrorCode, Callbacks, ErrorCode, FapiContext, KeyFlags};
1111

1212
const MY_KEYFLAG: &[KeyFlags] = &[KeyFlags::Sign, KeyFlags::NoDA];
1313
const MY_KEYPATH: &str = "HS/SRK/myTestKey";
@@ -44,7 +44,8 @@ fn main() {
4444
info!("FAPI context created. ({})", context);
4545

4646
// Add authorization callback function
47-
match context.set_callbacks(MyCallbacks { password: MY_AUTHVAL }) {
47+
// Will be called by the FAPI in order to request authorization values!
48+
match context.set_callbacks(Callbacks::with_auth(|_| Some(Cow::Borrowed(MY_AUTHVAL)))) {
4849
Ok(_) => info!("Success."),
4950
Err(error) => panic!("Failed to set up AUTH callback function: {:?}", error),
5051
}
@@ -82,19 +83,3 @@ fn main() {
8283
// Exit
8384
info!("Shutting down...");
8485
}
85-
86-
/// Struct to implement our application-defined callback functions
87-
#[derive(Debug)]
88-
struct MyCallbacks {
89-
password: &'static str,
90-
}
91-
92-
impl FapiCallbacks for MyCallbacks {
93-
/// This function will be called by FAPI in order to request authorization values from the application.
94-
///
95-
/// *Note:* For simplicity, in this example, the callback function always returns our password, regardless of the requested object path.
96-
fn auth_cb(&self, param: AuthCbParam) -> Option<Cow<'static, str>> {
97-
info!("Authorization for object at {:?} has been requested.", param.object_path);
98-
Some(Cow::from(self.password))
99-
}
100-
}

src/callback.rs

Lines changed: 101 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -129,14 +129,17 @@ impl<T: Any> AsAny for T {
129129

130130
/// Represents the set of application-defined callback functions that the FAPI invokes.
131131
///
132+
/// An implementation is **not** required to override *all* callback functions, as the trait provides “blank” default implementations.
133+
///
134+
/// Generally, an application overrides only the callback functions that it actually needs.
135+
///
132136
/// Implementations of this trait are registered with a FAPI context via the [**`FapiContext::set_callbacks()`**](crate::FapiContext::set_callbacks) function.
133137
///
134138
/// ### Example
135139
///
136140
/// Applications shall implement this trait as follows:
137141
///
138142
/// ```
139-
/// #[derive(Debug)]
140143
/// pub struct MyCallbacks;
141144
///
142145
/// impl FapiCallbacks for MyCallbacks {
@@ -157,7 +160,7 @@ impl<T: Any> AsAny for T {
157160
/// }
158161
/// }
159162
/// ```
160-
pub trait FapiCallbacks: AsAny + Send + Debug + 'static {
163+
pub trait FapiCallbacks: AsAny + Send + 'static {
161164
/// A callback function that allows the FAPI to request authorization values.
162165
///
163166
/// The default implementation of this function returns `None`. Please override the function as needed!
@@ -201,11 +204,96 @@ pub trait FapiCallbacks: AsAny + Send + Debug + 'static {
201204
}
202205
}
203206

207+
// ==========================================================================
208+
// Callbacks implementation
209+
// ==========================================================================
210+
211+
/// Provides a simple implementation of the [`FapiCallbacks`](crate::FapiCallbacks) trait.
212+
#[allow(clippy::type_complexity)]
213+
pub struct Callbacks {
214+
auth_fn: Box<dyn Fn(AuthCbParam) -> Option<Cow<'static, str>> + Send>,
215+
sign_fn: Box<dyn Fn(SignCbParam) -> Option<Vec<u8>> + Send>,
216+
branch_fn: Box<dyn Fn(BranchCbParam) -> Option<usize> + Send>,
217+
policy_action_fn: Box<dyn Fn(PolicyActionCbParam) -> bool + Send>,
218+
}
219+
220+
impl Callbacks {
221+
/// Creates a new `Callbacks` instance with application-defined callback functions.
222+
///
223+
/// Instances of this struct are registered with a FAPI context via the [**`FapiContext::set_callbacks()`**](crate::FapiContext::set_callbacks) function.
224+
pub fn new<AuthFn, SignFn, BranchFn, PolicyActionFn>(auth_fn: AuthFn, sign_fn: SignFn, branch_fn: BranchFn, policy_action_fn: PolicyActionFn) -> Self
225+
where
226+
AuthFn: Fn(AuthCbParam) -> Option<Cow<'static, str>> + Send + 'static,
227+
SignFn: Fn(SignCbParam) -> Option<Vec<u8>> + Send + 'static,
228+
BranchFn: Fn(BranchCbParam) -> Option<usize> + Send + 'static,
229+
PolicyActionFn: Fn(PolicyActionCbParam) -> bool + Send + 'static,
230+
{
231+
Self { auth_fn: Box::new(auth_fn), sign_fn: Box::new(sign_fn), branch_fn: Box::new(branch_fn), policy_action_fn: Box::new(policy_action_fn) }
232+
}
233+
234+
/// Creates a `Callbacks` instance with an application-defined [`auth_cb`](crate::FapiCallbacks::auth_cb) callback function.
235+
///
236+
/// All other callback functions will use the default implementation.
237+
pub fn with_auth<F>(auth_fn: F) -> Self
238+
where
239+
F: Fn(AuthCbParam) -> Option<Cow<'static, str>> + Send + 'static,
240+
{
241+
Self::new(auth_fn, |_| None, |_| None, |_| false)
242+
}
243+
244+
/// Creates a `Callbacks` instance with an application-defined [`sign_cb`](crate::FapiCallbacks::sign_cb) callback function.
245+
///
246+
/// All other callback functions will use the default implementation.
247+
pub fn with_sign<F>(sign_fn: F) -> Self
248+
where
249+
F: Fn(SignCbParam) -> Option<Vec<u8>> + Send + 'static,
250+
{
251+
Self::new(|_| None, sign_fn, |_| None, |_| false)
252+
}
253+
254+
/// Creates a `Callbacks` instance with an application-defined [`branch_cb`](crate::FapiCallbacks::branch_cb) callback function.
255+
///
256+
/// All other callback functions will use the default implementation.
257+
pub fn with_branch<F>(branch_fn: F) -> Self
258+
where
259+
F: Fn(BranchCbParam) -> Option<usize> + Send + 'static,
260+
{
261+
Self::new(|_| None, |_| None, branch_fn, |_| false)
262+
}
263+
264+
/// Creates a `Callbacks` instance with an application-defined [`policy_action_cb`](crate::FapiCallbacks::policy_action_cb) callback function.
265+
///
266+
/// All other callback functions will use the default implementation.
267+
pub fn with_policy_action<F>(policy_action_fn: F) -> Self
268+
where
269+
F: Fn(PolicyActionCbParam) -> bool + Send + 'static,
270+
{
271+
Self::new(|_| None, |_| None, |_| None, policy_action_fn)
272+
}
273+
}
274+
275+
impl FapiCallbacks for Callbacks {
276+
fn auth_cb(&self, param: AuthCbParam) -> Option<Cow<'static, str>> {
277+
(self.auth_fn)(param)
278+
}
279+
280+
fn sign_cb(&self, param: SignCbParam) -> Option<Vec<u8>> {
281+
(self.sign_fn)(param)
282+
}
283+
284+
fn branch_cb(&self, param: BranchCbParam) -> Option<usize> {
285+
(self.branch_fn)(param)
286+
}
287+
288+
fn policy_action_cb(&self, param: PolicyActionCbParam) -> bool {
289+
(self.policy_action_fn)(param)
290+
}
291+
}
292+
204293
// ==========================================================================
205294
// Callbacks manager
206295
// ==========================================================================
207296

208-
#[derive(Debug)]
209297
pub struct CallbackManager {
210298
inner: Box<dyn FapiCallbacks>,
211299
auth_value: Option<CStringHolder>,
@@ -283,6 +371,16 @@ impl CallbackManager {
283371
}
284372
}
285373

374+
impl Debug for CallbackManager {
375+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
376+
f.debug_struct("CallbackManager")
377+
.field("inner", &self.inner.as_any().type_id())
378+
.field("auth_value", &self.auth_value)
379+
.field("sign_data", &self.sign_data)
380+
.finish()
381+
}
382+
}
383+
286384
// ==========================================================================
287385
// Unit tests
288386
// ==========================================================================

src/lib.rs

Lines changed: 7 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -66,41 +66,29 @@
6666
//! ```rust no_run
6767
//! use log::info;
6868
//! use std::borrow::Cow;
69-
//! use tss2_fapi_rs::{AuthCbParam, FapiCallbacks, FapiContext};
69+
//! use tss2_fapi_rs::{Callbacks, FapiContext};
7070
//!
7171
//! fn main() {
7272
//! // Create a new FAPI context
7373
//! let mut context = FapiContext::new().expect("Failed to create context!");
7474
//!
75-
//! // Add callback functions
76-
//! match context.set_callbacks(MyCallbacks { password: "my_password" }) {
75+
//! // Register "auth" callback function
76+
//! match context.set_callbacks(Callbacks::with_auth(|_| Some(Cow::from("my_password")))) {
7777
//! Ok(_) => info!("Success."),
7878
//! Err(error) => panic!("Failed to set up AUTH callback function: {:?}", error),
7979
//! }
8080
//! }
81-
//!
82-
//! /// Application-defined callback functions
83-
//! #[derive(Debug)]
84-
//! struct MyCallbacks {
85-
//! password: &'static str,
86-
//! }
87-
//!
88-
//! impl FapiCallbacks for MyCallbacks {
89-
//! /// Function that will be called by the FAPI to request authorization values
90-
//! fn auth_cb(&self, param: AuthCbParam) -> Option<Cow<'static, str>> {
91-
//! info!("Authorization for object at {:?} requested.", param.object_path);
92-
//! Some(Cow::from(self.password))
93-
//! }
94-
//! }
9581
//! ```
9682
//!
83+
//! Please see the **[`FapiCallbacks`]** documentation for more details!
84+
//!
9785
//! ### Usage instructions
9886
//!
9987
//! In order to use the **`tss2-fapi-rs`** library in your Rust project, simply add it to your `Cargo.toml` file:
10088
//!
10189
//! ```toml
10290
//! [dependencies]
103-
//! tss2-fapi-rs = "0.9.0"
91+
//! tss2-fapi-rs = "0.10.0"
10492
//! ```
10593
//!
10694
//! **Note:** Please also consider the [prerequisites](#prerequisites) that are required to use the `tss2-fapi-rs` library!
@@ -451,7 +439,7 @@ mod types;
451439
mod version;
452440

453441
pub use algorithm_id::HashAlgorithm;
454-
pub use callback::{AsAny, AuthCbParam, BranchCbParam, FapiCallbacks, PolicyActionCbParam, SignCbParam};
442+
pub use callback::{AsAny, AuthCbParam, BranchCbParam, Callbacks, FapiCallbacks, PolicyActionCbParam, SignCbParam};
455443
pub use context::FapiContext;
456444
pub use error::{BaseErrorCode, ErrorCode, InternalError, Tpm2ErrFmt0, Tpm2ErrFmt1, Tpm2ErrorCode, Tpm2Warning};
457445
pub use flags::{BlobType, KeyFlags, NvFlags, PaddingFlags, QuoteFlags, SealFlags};

0 commit comments

Comments
 (0)