Skip to content

Commit

Permalink
Use upstream trussed and wrap_key_to_file as extension
Browse files Browse the repository at this point in the history
  • Loading branch information
sosthene-nitrokey committed Apr 25, 2023
1 parent d2ed9c4 commit be1adc6
Show file tree
Hide file tree
Showing 14 changed files with 233 additions and 217 deletions.
7 changes: 4 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ serde = { version = "1.0", default-features = false }
subtle = { version = "2.4.1", default-features = false }
trussed = "0.1.0"
trussed-rsa-alloc = { version = "0.1.0", optional = true }
trussed-staging = { version = "0.1.0", features = ["wrap-key-to-file"]}
serde_repr = "0.1"
hex-literal = "0.3.4"
trussed-auth = "0.2.1"
Expand Down Expand Up @@ -85,11 +86,11 @@ log-warn = []
log-error = []

[patch.crates-io]
littlefs2 = { git = "https://github.com/Nitrokey/littlefs2", tag = "v0.3.2-nitrokey-2" }
p256-cortex-m4 = { git = "https://github.com/Nitrokey/p256-cortex-m4", tag = "v0.1.0-alpha.6-nitrokey-1" }
trussed = { git = "https://github.com/Nitrokey/trussed" , tag = "v0.1.0-nitrokey.9" }
trussed-auth = { git = "https://github.com/trussed-dev/trussed-auth.git", tag= "v0.2.1"}
trussed = { git = "https://github.com/trussed-dev/trussed" , rev = "55ea391367fce4bf5093ff2d3c79041d7aef0485" }
trussed-auth = { git = "https://github.com/trussed-dev/trussed-auth.git", branch = "core-context"}
trussed-rsa-alloc = { git = "https://github.com/Nitrokey/trussed-rsa-backend", tag = "v0.1.0" }
trussed-staging = { git = "https://github.com/Nitrokey/trussed-staging", branch = "main" }

[package.metadata.docs.rs]
all-features = true
Expand Down
9 changes: 4 additions & 5 deletions src/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,30 +5,29 @@
//!
//! As this crate is designed to be usable on any platform, it cannot rely on a specific data
//! storage and cryptography implementation. Instead, a [`Card`][`crate::Card`] has to be provided
//! with a Backend wrapping a [`trussed::Client`][trussed::Client]
//! with a Backend wrapping a [`crate::card::Client`][crate::card::Client]

use core::fmt::Debug;

use trussed::try_syscall;
use trussed_auth::AuthClient;

use crate::error::Error;

/// Backend that provides data storage and cryptography operations.
/// Mostly a wrapper around a trussed client
#[derive(Clone)]
pub struct Backend<T: trussed::Client + AuthClient> {
pub struct Backend<T: crate::card::Client> {
client: T,
}

impl<T: trussed::Client + AuthClient> Debug for Backend<T> {
impl<T: crate::card::Client> Debug for Backend<T> {
fn fmt(&self, fmt: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
let Self { client: _client } = self;
fmt.debug_struct("Backend").finish()
}
}

impl<T: trussed::Client + AuthClient> Backend<T> {
impl<T: crate::card::Client> Backend<T> {
/// Create new backend from a trussed client
pub fn new(client: T) -> Self {
Self { client }
Expand Down
26 changes: 15 additions & 11 deletions src/card.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,13 @@ pub const PGP_SMARTCARD_VERSION: [u8; 2] = [3, 4];
/// This is the main entry point for this crate. It takes care of the command handling and state
/// management.
#[derive(Clone, Debug)]
pub struct Card<T: trussed::Client + AuthClient> {
pub struct Card<T: Client> {
backend: Backend<T>,
options: Options,
state: State,
}

impl<T: trussed::Client + AuthClient> Card<T> {
impl<T: Client> Card<T> {
/// Creates a new OpenPGP card with the given backend and options.
pub fn new(client: T, options: Options) -> Self {
let state = State::default();
Expand Down Expand Up @@ -73,23 +73,21 @@ impl<T: trussed::Client + AuthClient> Card<T> {
}
}

impl<T: trussed::Client + AuthClient> Drop for Card<T> {
impl<T: Client> Drop for Card<T> {
fn drop(&mut self) {
self.reset()
}
}

impl<T: trussed::Client + AuthClient> iso7816::App for Card<T> {
impl<T: Client> iso7816::App for Card<T> {
fn aid(&self) -> iso7816::Aid {
// TODO: check truncation length
iso7816::Aid::new_truncatable(&self.options.aid(), RID.len())
}
}

#[cfg(feature = "apdu-dispatch")]
impl<T: trussed::Client + AuthClient, const C: usize, const R: usize> apdu_dispatch::App<C, R>
for Card<T>
{
impl<T: Client, const C: usize, const R: usize> apdu_dispatch::App<C, R> for Card<T> {
fn select(
&mut self,
command: &iso7816::Command<C>,
Expand Down Expand Up @@ -172,15 +170,15 @@ impl Default for Options {
}

#[derive(Debug)]
pub struct Context<'a, const R: usize, T: trussed::Client + AuthClient> {
pub struct Context<'a, const R: usize, T: Client> {
pub backend: &'a mut Backend<T>,
pub options: &'a Options,
pub state: &'a mut State,
pub data: &'a [u8],
pub reply: Reply<'a, R>,
}

impl<'a, const R: usize, T: trussed::Client + AuthClient> Context<'a, R, T> {
impl<'a, const R: usize, T: Client> Context<'a, R, T> {
pub fn load_state(&mut self) -> Result<LoadedContext<'_, R, T>, Status> {
Ok(LoadedContext {
state: self
Expand Down Expand Up @@ -211,15 +209,15 @@ impl<'a, const R: usize, T: trussed::Client + AuthClient> Context<'a, R, T> {

#[derive(Debug)]
/// Context with the persistent state loaded from flash
pub struct LoadedContext<'a, const R: usize, T: trussed::Client + AuthClient> {
pub struct LoadedContext<'a, const R: usize, T: Client> {
pub backend: &'a mut Backend<T>,
pub options: &'a Options,
pub state: LoadedState<'a>,
pub data: &'a [u8],
pub reply: Reply<'a, R>,
}

impl<'a, const R: usize, T: trussed::Client + AuthClient> LoadedContext<'a, R, T> {
impl<'a, const R: usize, T: Client> LoadedContext<'a, R, T> {
/// Lend the context
///
/// The resulting `LoadedContext` has a shorter lifetime than the original one, meaning that it
Expand Down Expand Up @@ -248,3 +246,9 @@ mod tests {
)
}
}

use trussed_staging::wrap_key_to_file::WrapKeyToFileClient;

/// Super trait with all trussed extensions required by opcard
pub trait Client: trussed::Client + AuthClient + WrapKeyToFileClient {}
impl<C: trussed::Client + WrapKeyToFileClient + AuthClient> Client for C {}
30 changes: 15 additions & 15 deletions src/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ mod pso;

use hex_literal::hex;
use iso7816::Status;
use trussed_auth::{AuthClient, PinId};
use trussed_auth::PinId;

use crate::card::{Context, LoadedContext, RID};
use crate::error::Error;
Expand Down Expand Up @@ -55,7 +55,7 @@ impl Command {
}
}

pub fn exec<const R: usize, T: trussed::Client + AuthClient>(
pub fn exec<const R: usize, T: crate::card::Client>(
&self,
mut ctx: Context<'_, R, T>,
) -> Result<(), Status> {
Expand Down Expand Up @@ -336,7 +336,7 @@ impl TryFrom<u8> for ManageSecurityEnvironmentMode {
}

// § 7.2.1
fn select<const R: usize, T: trussed::Client + AuthClient>(
fn select<const R: usize, T: crate::card::Client>(
context: Context<'_, R, T>,
) -> Result<(), Status> {
if context.data.starts_with(&RID) {
Expand All @@ -350,7 +350,7 @@ fn select<const R: usize, T: trussed::Client + AuthClient>(
}

// § 7.2.2
fn verify<const R: usize, T: trussed::Client + AuthClient>(
fn verify<const R: usize, T: crate::card::Client>(
mut ctx: LoadedContext<'_, R, T>,
mode: VerifyMode,
password: PasswordMode,
Expand Down Expand Up @@ -401,7 +401,7 @@ fn verify<const R: usize, T: trussed::Client + AuthClient>(
}

// § 7.2.3
fn change_reference_data<const R: usize, T: trussed::Client + AuthClient>(
fn change_reference_data<const R: usize, T: crate::card::Client>(
mut ctx: LoadedContext<'_, R, T>,
password: Password,
) -> Result<(), Status> {
Expand Down Expand Up @@ -438,7 +438,7 @@ fn change_reference_data<const R: usize, T: trussed::Client + AuthClient>(
}

// § 7.2.14
fn gen_keypair<const R: usize, T: trussed::Client + AuthClient>(
fn gen_keypair<const R: usize, T: crate::card::Client>(
context: LoadedContext<'_, R, T>,
mode: GenerateAsymmetricKeyPairMode,
) -> Result<(), Status> {
Expand All @@ -464,7 +464,7 @@ fn gen_keypair<const R: usize, T: trussed::Client + AuthClient>(
}

// § 7.2.16
fn terminate_df<const R: usize, T: trussed::Client + AuthClient>(
fn terminate_df<const R: usize, T: crate::card::Client>(
mut ctx: Context<'_, R, T>,
) -> Result<(), Status> {
if let Ok(ctx) = ctx.load_state() {
Expand All @@ -490,7 +490,7 @@ fn unspecified_delete_error<E: core::fmt::Debug>(_err: E) -> Status {
Status::UnspecifiedPersistentExecutionError
}

fn factory_reset<const R: usize, T: trussed::Client + AuthClient>(
fn factory_reset<const R: usize, T: crate::card::Client>(
ctx: Context<'_, R, T>,
) -> Result<(), Status> {
ctx.state.volatile.clear(ctx.backend.client_mut());
Expand Down Expand Up @@ -521,7 +521,7 @@ fn factory_reset<const R: usize, T: trussed::Client + AuthClient>(
}

// § 7.2.17
fn activate_file<const R: usize, T: trussed::Client + AuthClient>(
fn activate_file<const R: usize, T: crate::card::Client>(
mut ctx: Context<'_, R, T>,
) -> Result<(), Status> {
if State::lifecycle(ctx.backend.client_mut(), ctx.options.storage) == LifeCycle::Operational {
Expand All @@ -542,7 +542,7 @@ fn activate_file<const R: usize, T: trussed::Client + AuthClient>(
}

// § 7.2.4
fn reset_retry_conter<const R: usize, T: trussed::Client + AuthClient>(
fn reset_retry_conter<const R: usize, T: crate::card::Client>(
ctx: LoadedContext<'_, R, T>,
mode: ResetRetryCounterMode,
) -> Result<(), Status> {
Expand All @@ -552,7 +552,7 @@ fn reset_retry_conter<const R: usize, T: trussed::Client + AuthClient>(
}
}

fn reset_retry_conter_with_p3<const R: usize, T: trussed::Client + AuthClient>(
fn reset_retry_conter_with_p3<const R: usize, T: crate::card::Client>(
mut ctx: LoadedContext<'_, R, T>,
) -> Result<(), Status> {
if ctx.data.len() < MIN_LENGTH_USER_PIN || ctx.data.len() > MAX_PIN_LENGTH {
Expand All @@ -575,7 +575,7 @@ fn reset_retry_conter_with_p3<const R: usize, T: trussed::Client + AuthClient>(
})
}

fn reset_retry_conter_with_code<const R: usize, T: trussed::Client + AuthClient>(
fn reset_retry_conter_with_code<const R: usize, T: crate::card::Client>(
mut ctx: LoadedContext<'_, R, T>,
) -> Result<(), Status> {
let code_len = ctx.state.persistent.reset_code_len().ok_or_else(|| {
Expand Down Expand Up @@ -626,7 +626,7 @@ fn reset_retry_conter_with_code<const R: usize, T: trussed::Client + AuthClient>
}

// § 7.2.5
fn select_data<const R: usize, T: trussed::Client + AuthClient>(
fn select_data<const R: usize, T: crate::card::Client>(
ctx: Context<'_, R, T>,
occurrence: Occurrence,
) -> Result<(), Status> {
Expand All @@ -643,7 +643,7 @@ fn select_data<const R: usize, T: trussed::Client + AuthClient>(
}

// § 7.2.15
fn get_challenge<const R: usize, T: trussed::Client + AuthClient>(
fn get_challenge<const R: usize, T: crate::card::Client>(
mut ctx: Context<'_, R, T>,
expected: usize,
) -> Result<(), Status> {
Expand All @@ -665,7 +665,7 @@ fn get_challenge<const R: usize, T: trussed::Client + AuthClient>(
}

// § 7.2.18
fn manage_security_environment<const R: usize, T: trussed::Client + AuthClient>(
fn manage_security_environment<const R: usize, T: crate::card::Client>(
ctx: Context<'_, R, T>,
mode: ManageSecurityEnvironmentMode,
) -> Result<(), Status> {
Expand Down
Loading

0 comments on commit be1adc6

Please sign in to comment.