chio_kernel_core/receipts.rs
1//! Portable receipt signing.
2//!
3//! Wraps `chio_core_types::ChioReceipt::sign_with_backend` so the kernel core
4//! can produce signed receipts without depending on the `chio-kernel` full
5//! crate's keypair-based helper. Using the `SigningBackend` trait keeps
6//! the FIPS-capable signing path available on every adapter.
7
8use alloc::string::ToString;
9
10use chio_core_types::crypto::SigningBackend;
11use chio_core_types::receipt::{ChioReceipt, ChioReceiptBody};
12
13/// Errors raised by [`sign_receipt`].
14#[derive(Debug, Clone, PartialEq, Eq)]
15pub enum ReceiptSigningError {
16 /// The receipt body's `kernel_key` does not match the signing backend's
17 /// public key. Signing would succeed but verification against the
18 /// embedded `kernel_key` would then fail; we fail early to catch
19 /// config drift.
20 KernelKeyMismatch,
21 /// The canonical-JSON signing pipeline raised an error (bubbled up
22 /// from `chio-core-types::crypto::sign_canonical_with_backend`).
23 SigningFailed(alloc::string::String),
24}
25
26/// Sign a receipt body using the given [`SigningBackend`].
27///
28/// This mirrors the pre-existing `chio_kernel::kernel::responses::build_and_sign_receipt`
29/// but accepts an abstract signing backend rather than the `Keypair`
30/// concrete type. `chio-kernel` delegates to this function for the pure
31/// signing step; adapters on WASM / mobile route to their platform's
32/// signing backend (ed25519-dalek in WASM today, AWS LC or system keystores
33/// in FIPS deployments) through the same trait.
34///
35/// The `body.kernel_key` must equal `backend.public_key()`; otherwise we
36/// fail fast with [`ReceiptSigningError::KernelKeyMismatch`] so the caller
37/// doesn't produce a receipt whose signature cannot be verified.
38pub fn sign_receipt(
39 body: ChioReceiptBody,
40 backend: &dyn SigningBackend,
41) -> Result<ChioReceipt, ReceiptSigningError> {
42 if body.kernel_key != backend.public_key() {
43 return Err(ReceiptSigningError::KernelKeyMismatch);
44 }
45
46 ChioReceipt::sign_with_backend(body, backend)
47 .map_err(|error| ReceiptSigningError::SigningFailed(error.to_string()))
48}