Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor service and remove clients-? features #194

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Added `init_raw` constructor for types generated by the `store!` macro.
- Added `FilesystemClient::entry_metadata` syscall.
- Added `FilesystemClient::rename` syscall.
- Added `Syscall` implementation for `Service`.
- Added `Syscall::try_into_new_client` service.
- Added serializable flag to `StorageAttributes` for key agreement.
- Added virtual platform in `virt` module.
- Added methods for creating the client stores to `ServiceResources`.
Expand All @@ -25,7 +23,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Changed

- Set `config::MAX_SERVICE_CLIENTS` based on the clients-? feature.
- Made `StorageAttributes` non-exhaustive.
- Changed `KeyStore<P: Platform>` to `KeyStore<S: Store>`.
- Replaced the client ID with a `ClientContext` struct.
Expand Down Expand Up @@ -56,6 +53,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Put all client traits, requests, replies and implementations behind feature flags.
- Put all mechanisms behind feature flags.
- Move `CryptoClient::attest` into new `AttestationClient`.
- Pass endpoints to `Service::process` instead of storing them in the service.
- Added support for non-static channels:
- Added lifetimes to `ClientImplementation` and `ServiceEndpoints`.
- Added the `pipe::TrussedChannel` type.

### Fixed

Expand All @@ -71,6 +72,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Removed unused items:
- `config`: `MAX_APPLICATION_NAME_LENGTH`, `MAX_LABEL_LENGTH`, `MAX_LONG_DATA_LENGTH`, `MAX_OBJECT_HANDLES`, `MAX_PATH_LENGTH`
- `types`: `Attributes`, `CertificateType` `DataAttributes`, `KeyAttributes`, `Letters`, `LongData`, `ObjectType`
- Removed the `Syscall` implementations for `Service` and the `Syscall::try_as_new_client` and `Syscall::try_new_client` methods.
- Removed `TrussedInterchange` and `TRUSSED_INTERCHANGE` from `pipe`.
- Removed the `clients-?` features.

[#64]: https://github.com/trussed-dev/trussed/issues/64
[#65]: https://github.com/trussed-dev/trussed/issues/65
Expand Down
15 changes: 1 addition & 14 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ trussed-derive = { path = "derive" }
# rand_core = { version = "0.5", features = ["getrandom"] }

[features]
default = ["all-clients", "default-mechanisms", "clients-5"]
default = ["all-clients", "default-mechanisms"]
serde-extensions = ["trussed-core/serde-extensions"]
std = []
verbose-tests = ["littlefs2/ll-assertions"]
Expand Down Expand Up @@ -150,19 +150,6 @@ filesystem-client = ["trussed-core/filesystem-client"]
management-client = ["trussed-core/management-client"]
ui-client = ["trussed-core/ui-client"]

clients-1 = []
clients-2 = []
clients-3 = []
clients-4 = []
clients-5 = []
clients-6 = []
clients-7 = []
clients-8 = []
clients-9 = []
clients-10 = []
clients-11 = []
clients-12 = []

test-attestation-cert-ids = []

[[test]]
Expand Down
7 changes: 3 additions & 4 deletions src/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
//! Trussed provides a default implementation for all [`Request`][]s, the core backend. Runners
//! can add custom [`Backend`][] implementations using the [`Dispatch`][] trait that can override
//! the implementation of one or more requests. The backends used to execute a request can be
//! selected per client when constructing a client using
//! [`ClientBuilder::backends`][`crate::client::ClientBuilder::backends`].
//! selected per client when constructing the [`ServiceEndpoint`][`crate::pipe::ServiceEndpoint`].
//!
//! Backends can also implement API extensions to provide additional syscalls (see the
//! [`serde_extensions`][`crate::serde_extensions`] module).
Expand Down Expand Up @@ -50,8 +49,8 @@ pub trait Backend {
///
/// If a runner does not support custom backends, it can use the [`CoreOnly`][] dispatch.
/// Otherwise it can provide an implementation of this trait that defines which backends are
/// supported. The backends that are used to execute a request can be selected when constructing a
/// client using [`ClientBuilder::backends`][`crate::client::ClientBuilder::backends`].
/// supported. The backends that are used to execute a request can be selected when constructing
/// the [`ServiceEndpoint`][`crate::pipe::ServiceEndpoint`] for the client.
pub trait Dispatch {
/// The ID type for the custom backends used by this dispatch implementation.
type BackendId: 'static;
Expand Down
128 changes: 14 additions & 114 deletions src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,12 +78,10 @@
use core::{marker::PhantomData, task::Poll};

use crate::api::{Reply, RequestVariant};
use crate::backend::{BackendId, CoreOnly, Dispatch};
use crate::backend::CoreOnly;
use crate::error::{Error, Result};
use crate::interrupt::InterruptFlag;
use crate::pipe::{TrussedRequester, TRUSSED_INTERCHANGE};
use crate::service::Service;
use crate::types::{PathBuf, Platform};
use crate::pipe::TrussedRequester;

pub use crate::platform::Syscall;

Expand Down Expand Up @@ -117,15 +115,15 @@ pub trait Client:
}

#[cfg(feature = "all-clients")]
impl<S: Syscall, E> Client for ClientImplementation<S, E> {}
impl<S: Syscall, E> Client for ClientImplementation<'_, S, E> {}

/// The client implementation client applications actually receive.
pub struct ClientImplementation<S, D = CoreOnly> {
pub struct ClientImplementation<'a, S, D = CoreOnly> {
// raw: RawClient<Client<S>>,
syscall: S,

// RawClient:
pub(crate) interchange: TrussedRequester,
pub(crate) interchange: TrussedRequester<'a>,
pub(crate) interrupt: Option<&'static InterruptFlag>,
// pending: Option<Discriminant<Request>>,
pending: Option<u8>,
Expand All @@ -140,12 +138,12 @@ pub struct ClientImplementation<S, D = CoreOnly> {
// }
// }

impl<S, E> ClientImplementation<S, E>
impl<'a, S, E> ClientImplementation<'a, S, E>
where
S: Syscall,
{
pub fn new(
interchange: TrussedRequester,
interchange: TrussedRequester<'a>,
syscall: S,
interrupt: Option<&'static InterruptFlag>,
) -> Self {
Expand All @@ -159,7 +157,7 @@ where
}
}

impl<S, E> PollClient for ClientImplementation<S, E>
impl<S, E> PollClient for ClientImplementation<'_, S, E>
where
S: Syscall,
{
Expand Down Expand Up @@ -225,112 +223,14 @@ where
}

#[cfg(feature = "certificate-client")]
impl<S: Syscall, E> CertificateClient for ClientImplementation<S, E> {}
impl<S: Syscall, E> CertificateClient for ClientImplementation<'_, S, E> {}
#[cfg(feature = "crypto-client")]
impl<S: Syscall, E> CryptoClient for ClientImplementation<S, E> {}
impl<S: Syscall, E> CryptoClient for ClientImplementation<'_, S, E> {}
#[cfg(feature = "counter-client")]
impl<S: Syscall, E> CounterClient for ClientImplementation<S, E> {}
impl<S: Syscall, E> CounterClient for ClientImplementation<'_, S, E> {}
#[cfg(feature = "filesystem-client")]
impl<S: Syscall, E> FilesystemClient for ClientImplementation<S, E> {}
impl<S: Syscall, E> FilesystemClient for ClientImplementation<'_, S, E> {}
#[cfg(feature = "management-client")]
impl<S: Syscall, E> ManagementClient for ClientImplementation<S, E> {}
impl<S: Syscall, E> ManagementClient for ClientImplementation<'_, S, E> {}
#[cfg(feature = "ui-client")]
impl<S: Syscall, E> UiClient for ClientImplementation<S, E> {}

/// Builder for [`ClientImplementation`][].
///
/// This builder can be used to select the backends used for the client. If no backends are used,
/// [`Service::try_new_client`][], [`Service::try_as_new_client`][] and
/// [`Service::try_into_new_client`][] can be used directly.
///
/// The maximum number of clients that can be created is defined by the `clients-?` features. If
/// this number is exceeded, [`Error::ClientCountExceeded`][] is returned.
pub struct ClientBuilder<D: Dispatch = CoreOnly> {
id: PathBuf,
backends: &'static [BackendId<D::BackendId>],
interrupt: Option<&'static InterruptFlag>,
}

impl ClientBuilder {
/// Creates a new client builder using the given client ID.
///
/// Per default, the client does not support backends and always uses the Trussed core
/// implementation to execute requests.
pub fn new(id: impl Into<PathBuf>) -> Self {
Self {
id: id.into(),
backends: &[],
interrupt: None,
}
}
}

impl<D: Dispatch> ClientBuilder<D> {
/// Selects the backends to use for this client.
///
/// If `backends` is empty, the Trussed core implementation is always used.
pub fn backends<E: Dispatch>(
self,
backends: &'static [BackendId<E::BackendId>],
) -> ClientBuilder<E> {
ClientBuilder {
id: self.id,
backends,
interrupt: self.interrupt,
}
}

pub fn interrupt(self, interrupt: Option<&'static InterruptFlag>) -> Self {
Self { interrupt, ..self }
}

fn create_endpoint<P: Platform>(
self,
service: &mut Service<P, D>,
) -> Result<TrussedRequester, Error> {
let (requester, responder) = TRUSSED_INTERCHANGE
.claim()
.ok_or(Error::ClientCountExceeded)?;
service.add_endpoint(responder, self.id, self.backends, self.interrupt)?;
Ok(requester)
}

/// Prepare a client using the given service.
///
/// This allocates a [`TrussedInterchange`][`crate::pipe::TrussedInterchange`] and a
/// [`ServiceEndpoint`][`crate::service::ServiceEndpoint`].
pub fn prepare<P: Platform>(
self,
service: &mut Service<P, D>,
) -> Result<PreparedClient<D>, Error> {
let interrupt = self.interrupt;
self.create_endpoint(service)
.map(|requester| PreparedClient::new(requester, interrupt))
}
}

/// An intermediate step of the [`ClientBuilder`][].
///
/// This struct already has an allocated [`TrussedInterchange`][`crate::pipe::TrussedInterchange`] and
/// [`ServiceEndpoint`][`crate::service::ServiceEndpoint`] but still needs a [`Syscall`][]
/// implementation.
pub struct PreparedClient<D> {
requester: TrussedRequester,
interrupt: Option<&'static InterruptFlag>,
_marker: PhantomData<D>,
}

impl<D> PreparedClient<D> {
fn new(requester: TrussedRequester, interrupt: Option<&'static InterruptFlag>) -> Self {
Self {
requester,
interrupt,
_marker: Default::default(),
}
}

/// Builds the client using the given syscall implementation.
pub fn build<S: Syscall>(self, syscall: S) -> ClientImplementation<S, D> {
ClientImplementation::new(self.requester, syscall, self.interrupt)
}
}
impl<S: Syscall, E> UiClient for ClientImplementation<'_, S, E> {}
28 changes: 14 additions & 14 deletions src/client/mechanisms.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,43 +4,43 @@ use crate::platform::Syscall;
pub use trussed_core::mechanisms::*;

#[cfg(feature = "aes256-cbc")]
impl<S: Syscall, E> Aes256Cbc for ClientImplementation<S, E> {}
impl<S: Syscall, E> Aes256Cbc for ClientImplementation<'_, S, E> {}

#[cfg(feature = "chacha8-poly1305")]
impl<S: Syscall, E> Chacha8Poly1305 for ClientImplementation<S, E> {}
impl<S: Syscall, E> Chacha8Poly1305 for ClientImplementation<'_, S, E> {}

#[cfg(feature = "hmac-blake2s")]
impl<S: Syscall, E> HmacBlake2s for ClientImplementation<S, E> {}
impl<S: Syscall, E> HmacBlake2s for ClientImplementation<'_, S, E> {}

#[cfg(feature = "hmac-sha1")]
impl<S: Syscall, E> HmacSha1 for ClientImplementation<S, E> {}
impl<S: Syscall, E> HmacSha1 for ClientImplementation<'_, S, E> {}

#[cfg(feature = "hmac-sha256")]
impl<S: Syscall, E> HmacSha256 for ClientImplementation<S, E> {}
impl<S: Syscall, E> HmacSha256 for ClientImplementation<'_, S, E> {}

#[cfg(feature = "hmac-sha512")]
impl<S: Syscall, E> HmacSha512 for ClientImplementation<S, E> {}
impl<S: Syscall, E> HmacSha512 for ClientImplementation<'_, S, E> {}

#[cfg(feature = "ed255")]
impl<S: Syscall, E> Ed255 for ClientImplementation<S, E> {}
impl<S: Syscall, E> Ed255 for ClientImplementation<'_, S, E> {}

#[cfg(feature = "p256")]
impl<S: Syscall, E> P256 for ClientImplementation<S, E> {}
impl<S: Syscall, E> P256 for ClientImplementation<'_, S, E> {}

#[cfg(feature = "p384")]
impl<S: Syscall, E> P384 for ClientImplementation<S, E> {}
impl<S: Syscall, E> P384 for ClientImplementation<'_, S, E> {}

#[cfg(feature = "p521")]
impl<S: Syscall, E> P521 for ClientImplementation<S, E> {}
impl<S: Syscall, E> P521 for ClientImplementation<'_, S, E> {}

#[cfg(feature = "sha256")]
impl<S: Syscall, E> Sha256 for ClientImplementation<S, E> {}
impl<S: Syscall, E> Sha256 for ClientImplementation<'_, S, E> {}

#[cfg(feature = "tdes")]
impl<S: Syscall, E> Tdes for ClientImplementation<S, E> {}
impl<S: Syscall, E> Tdes for ClientImplementation<'_, S, E> {}

#[cfg(feature = "totp")]
impl<S: Syscall, E> Totp for ClientImplementation<S, E> {}
impl<S: Syscall, E> Totp for ClientImplementation<'_, S, E> {}

#[cfg(feature = "x255")]
impl<S: Syscall, E> X255 for ClientImplementation<S, E> {}
impl<S: Syscall, E> X255 for ClientImplementation<'_, S, E> {}
32 changes: 0 additions & 32 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,38 +7,6 @@ pub use trussed_core::config::{
SERDE_EXTENSION_REQUEST_LENGTH,
};

cfg_if::cfg_if! {
if #[cfg(test)] {
pub const MAX_SERVICE_CLIENTS: usize = 6;
} else if #[cfg(feature = "clients-12")] {
pub const MAX_SERVICE_CLIENTS: usize = 12;
} else if #[cfg(feature = "clients-11")] {
pub const MAX_SERVICE_CLIENTS: usize = 11;
} else if #[cfg(feature = "clients-10")] {
pub const MAX_SERVICE_CLIENTS: usize = 10;
} else if #[cfg(feature = "clients-9")] {
pub const MAX_SERVICE_CLIENTS: usize = 9;
} else if #[cfg(feature = "clients-8")] {
pub const MAX_SERVICE_CLIENTS: usize = 8;
} else if #[cfg(feature = "clients-7")] {
pub const MAX_SERVICE_CLIENTS: usize = 7;
} else if #[cfg(feature = "clients-6")] {
pub const MAX_SERVICE_CLIENTS: usize = 6;
} else if #[cfg(feature = "clients-5")] {
pub const MAX_SERVICE_CLIENTS: usize = 5;
} else if #[cfg(feature = "clients-4")] {
pub const MAX_SERVICE_CLIENTS: usize = 4;
} else if #[cfg(feature = "clients-3")] {
pub const MAX_SERVICE_CLIENTS: usize = 3;
} else if #[cfg(feature = "clients-2")] {
pub const MAX_SERVICE_CLIENTS: usize = 2;
} else if #[cfg(feature = "clients-1")] {
pub const MAX_SERVICE_CLIENTS: usize = 1;
} else {
pub const MAX_SERVICE_CLIENTS: usize = 0;
}
}

// must be MAX_KEY_MATERIAL_LENGTH + 4
pub const MAX_SERIALIZED_KEY_LENGTH: usize = MAX_KEY_MATERIAL_LENGTH + 4;

Expand Down
Loading
Loading