From 1af09a5139fa378e2c90a3b949b9162d30e1531e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sosth=C3=A8ne=20Gu=C3=A9don?= Date: Tue, 14 Nov 2023 15:50:16 +0100 Subject: [PATCH 1/4] Add support for full device factory reset We preserve all certificates, counters, and keys that have an id lower than 255. These IDs are the `Special` ids as defined by trussed --- Cargo.lock | 22 ++++-- Cargo.toml | 11 +-- components/apps/Cargo.toml | 12 +-- components/apps/src/dispatch.rs | 133 ++++++++++++++++++++++---------- components/apps/src/lib.rs | 17 +++- 5 files changed, 134 insertions(+), 61 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 24b63f7a..f8e917fe 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5,7 +5,7 @@ version = 3 [[package]] name = "admin-app" version = "0.1.0" -source = "git+https://github.com/Nitrokey/admin-app?tag=v0.1.0-nitrokey.6#b67c3647b7b6ec3ce8c453e9ffbf9327dfd5c813" +source = "git+https://github.com/Nitrokey/admin-app.git?rev=1adbce18ca884d35a3a4b80a7c5dd8fca9e4bae0#1adbce18ca884d35a3a4b80a7c5dd8fca9e4bae0" dependencies = [ "apdu-dispatch", "cbor-smol", @@ -18,6 +18,7 @@ dependencies = [ "strum_macros", "trussed", "trussed-se050-backend", + "trussed-staging", ] [[package]] @@ -113,6 +114,8 @@ dependencies = [ "embedded-hal", "fido-authenticator", "hex", + "if_chain", + "littlefs2", "ndef-app", "opcard", "piv-authenticator", @@ -1657,6 +1660,12 @@ dependencies = [ "unicode-normalization", ] +[[package]] +name = "if_chain" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb56e1aa765b4b4f3aadfab769793b7087bb03a4ea4920644a6d238e2df5b9ed" + [[package]] name = "indexmap" version = "1.9.3" @@ -1777,8 +1786,7 @@ checksum = "9afa463f5405ee81cdb9cc2baf37e08ec7e4c8209442b5d72c04cfb2cd6e6286" [[package]] name = "littlefs2" version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95c72bdf63e7ad35f391e60c48e4c32560038f1d3a0dd97f90a2891ce09160bf" +source = "git+https://github.com/trussed-dev/littlefs2?rev=e6c46e7ba5ae19129e457a2182e40a439c0322fe#e6c46e7ba5ae19129e457a2182e40a439c0322fe" dependencies = [ "bitflags 1.3.2", "cstr_core", @@ -3250,7 +3258,7 @@ dependencies = [ [[package]] name = "trussed" version = "0.1.0" -source = "git+https://github.com/Nitrokey/trussed.git?rev=v0.1.0-nitrokey.14#30a4764ddca80fd5f23eff6db1c53770f84c2c2f" +source = "git+https://github.com/trussed-dev/trussed.git?rev=d97c64d0bc5f83ce22b0e0ed034a2b451616b3f9#d97c64d0bc5f83ce22b0e0ed034a2b451616b3f9" dependencies = [ "aes", "bitflags 2.4.1", @@ -3287,7 +3295,7 @@ dependencies = [ [[package]] name = "trussed-auth" version = "0.2.2" -source = "git+https://github.com/Nitrokey/trussed-auth?tag=v0.2.2-nitrokey.1#203a90dd13a7378f596b3099cd986a8da6185137" +source = "git+https://github.com/trussed-dev/trussed-auth?rev=62235294bd63977bbb88eb01e7ac44b8010eb450#62235294bd63977bbb88eb01e7ac44b8010eb450" dependencies = [ "chacha20poly1305", "hkdf", @@ -3303,7 +3311,7 @@ dependencies = [ [[package]] name = "trussed-rsa-alloc" version = "0.1.0" -source = "git+https://github.com/Nitrokey/trussed-rsa-backend.git?tag=v0.1.0#a72ce195a4495a8db26debfb0240a4dc712d8dbe" +source = "git+https://github.com/trussed-dev/trussed-rsa-backend.git?rev=2f51478f0861ff8db19fdd5290f023ab6f4c2fb9#2f51478f0861ff8db19fdd5290f023ab6f4c2fb9" dependencies = [ "delog", "heapless-bytes 0.3.0", @@ -3338,7 +3346,7 @@ dependencies = [ [[package]] name = "trussed-staging" version = "0.1.0" -source = "git+https://github.com/trussed-dev/trussed-staging.git?branch=hmacsha256p256#1b54bf8703d515688a58f2f605c3efa0f2f60ced" +source = "git+https://github.com/nitrokey/trussed-staging.git?branch=hmacsha256p256-rebased#edb966aba4a3c211b6453d6f01259823e82b932b" dependencies = [ "chacha20poly1305", "delog", diff --git a/Cargo.toml b/Cargo.toml index e2ee896e..daa5d90d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,7 @@ version = "1.6.0-rc.1" [patch.crates-io] # forked -admin-app = { git = "https://github.com/Nitrokey/admin-app", tag = "v0.1.0-nitrokey.6" } +admin-app = { git = "https://github.com/Nitrokey/admin-app.git", rev = "1adbce18ca884d35a3a4b80a7c5dd8fca9e4bae0" } ctap-types = { git = "https://github.com/Nitrokey/ctap-types", tag = "v0.1.2-nitrokey.4" } fido-authenticator = { git = "https://github.com/Nitrokey/fido-authenticator.git", tag = "v0.1.1-nitrokey.8" } flexiber = { git = "https://github.com/Nitrokey/flexiber", tag = "0.1.1.nitrokey" } @@ -23,9 +23,10 @@ serde-indexed = { git = "https://github.com/nitrokey/serde-indexed.git", tag = " apdu-dispatch = { git = "https://github.com/Nitrokey/apdu-dispatch.git", tag = "v0.1.2-nitrokey.2" } ctaphid-dispatch = { git = "https://github.com/Nitrokey/ctaphid-dispatch.git", tag = "v0.1.1-nitrokey.3" } iso7816 = { git = "https://github.com/Nitrokey/iso7816.git", tag = "v0.1.1-nitrokey.2"} -trussed = { git = "https://github.com/Nitrokey/trussed.git", rev = "v0.1.0-nitrokey.14" } +trussed = { git = "https://github.com/trussed-dev/trussed.git", rev = "d97c64d0bc5f83ce22b0e0ed034a2b451616b3f9" } usbd-ctaphid = { git = "https://github.com/Nitrokey/usbd-ctaphid.git", tag = "v0.1.0-nitrokey.2" } usbd-ccid = { git = "https://github.com/Nitrokey/usbd-ccid", tag = "v0.2.0-nitrokey.1" } +littlefs2 = { git = "https://github.com/trussed-dev/littlefs2", rev = "e6c46e7ba5ae19129e457a2182e40a439c0322fe" } # unreleased crates secrets-app = { git = "https://github.com/Nitrokey/trussed-secrets-app", tag = "v0.13.0-rc2" } @@ -33,9 +34,9 @@ webcrypt = { git = "https://github.com/nitrokey/nitrokey-websmartcard-rust", tag opcard = { git = "https://github.com/Nitrokey/opcard-rs", tag = "v1.2.0" } piv-authenticator = { git = "https://github.com/Nitrokey/piv-authenticator", tag = "v0.3.3" } se05x = { git = "https://github.com/Nitrokey/se05x.git", tag = "v0.1.0"} -trussed-auth = { git = "https://github.com/Nitrokey/trussed-auth", tag = "v0.2.2-nitrokey.1" } -trussed-rsa-alloc = { git = "https://github.com/Nitrokey/trussed-rsa-backend.git", tag = "v0.1.0"} -trussed-staging = { git = "https://github.com/trussed-dev/trussed-staging.git", branch = "hmacsha256p256" } +trussed-auth = { git = "https://github.com/trussed-dev/trussed-auth", rev = "62235294bd63977bbb88eb01e7ac44b8010eb450" } +trussed-rsa-alloc = { git = "https://github.com/trussed-dev/trussed-rsa-backend.git", rev = "2f51478f0861ff8db19fdd5290f023ab6f4c2fb9" } +trussed-staging = { git = "https://github.com/nitrokey/trussed-staging.git", branch = "hmacsha256p256-rebased" } trussed-usbip = { git = "https://github.com/Nitrokey/pc-usbip-runner.git", tag = "v0.0.1-nitrokey.3" } trussed-se050-backend = { git = "https://github.com/Nitrokey/trussed-se050-backend.git", tag = "v0.1.0-test-driver" } diff --git a/components/apps/Cargo.toml b/components/apps/Cargo.toml index af2f5790..95675645 100644 --- a/components/apps/Cargo.toml +++ b/components/apps/Cargo.toml @@ -11,11 +11,13 @@ trussed = { version = "0.1", features = ["serde-extensions"]} trussed-usbip = { version = "0.0.1", default-features = false, features = ["ctaphid"], optional = true } usbd-ctaphid = { version = "0.1", optional = true } utils = { path = "../utils" } +if_chain = "1.0.2" +littlefs2 = { version = "0.4" } # Backends trussed-auth = { version = "0.2.2", optional = true } trussed-rsa-alloc = { version = "0.1.0", optional = true } -trussed-staging = { version = "0.1.0", features = ["wrap-key-to-file", "chunked", "encrypted-chunked"], optional = true } +trussed-staging = { version = "0.1.0", features = ["wrap-key-to-file", "chunked", "encrypted-chunked", "manage"] } # apps admin-app = "0.1.0" @@ -41,17 +43,17 @@ provisioner = ["provisioner-app", "trussed/clients-5"] # apps secrets-app = ["dep:secrets-app", "backend-auth"] -webcrypt = ["dep:webcrypt", "backend-auth", "backend-rsa", "backend-staging", "trussed-staging/hmacsha256p256"] +backend-staging-hmacsha256p256 = ["trussed-staging/hmacsha256p256"] +webcrypt = ["dep:webcrypt", "backend-auth", "backend-rsa", "backend-staging-hmacsha256p256"] fido-authenticator = ["dep:fido-authenticator", "usbd-ctaphid"] -opcard = ["dep:opcard", "backend-rsa", "backend-auth", "backend-staging"] -piv-authenticator = ["dep:piv-authenticator", "backend-rsa", "backend-auth", "backend-staging"] +opcard = ["dep:opcard", "backend-rsa", "backend-auth"] +piv-authenticator = ["dep:piv-authenticator", "backend-rsa", "backend-auth"] se050-test-app = ["se050", "admin-app/se050"] se050 = ["trussed-se050-backend", "dep:se05x"] # backends backend-auth = ["trussed-auth"] backend-rsa = ["trussed-rsa-alloc"] -backend-staging = ["trussed-staging"] log-all = ["admin-app/log-all", "fido-authenticator?/log-all", "secrets-app?/log-all", "webcrypt?/log-all", "opcard?/log-all", "provisioner-app?/log-all"] diff --git a/components/apps/src/dispatch.rs b/components/apps/src/dispatch.rs index 27bf144b..d1e98e9e 100644 --- a/components/apps/src/dispatch.rs +++ b/components/apps/src/dispatch.rs @@ -9,11 +9,9 @@ use trussed::{ Platform, }; -#[cfg(any( - feature = "backend-auth", - feature = "backend-rsa", - feature = "backend-staging" -))] +use littlefs2::{path, path::Path}; + +use if_chain::if_chain; use trussed::{ api::{reply, request}, backend::Backend as _, @@ -26,7 +24,9 @@ use embedded_hal::blocking::delay::DelayUs; #[cfg(feature = "se050")] use se05x::{se05x::Se05X, t1::I2CForT1}; #[cfg(feature = "se050")] -use trussed_se050_backend::{manage::ManageExtension, Context as Se050Context, Se050Backend}; +use trussed_se050_backend::{ + manage::ManageExtension as Se050ManageExtension, Context as Se050Context, Se050Backend, +}; #[cfg(feature = "backend-auth")] use trussed_auth::{AuthBackend, AuthContext, AuthExtension, MAX_HW_KEY_LEN}; @@ -34,19 +34,17 @@ use trussed_auth::{AuthBackend, AuthContext, AuthExtension, MAX_HW_KEY_LEN}; #[cfg(feature = "backend-rsa")] use trussed_rsa_alloc::SoftwareRsa; -#[cfg(feature = "backend-staging")] use trussed_staging::{ - streaming::ChunkedExtension, wrap_key_to_file::WrapKeyToFileExtension, StagingBackend, - StagingContext, + manage::ManageExtension, streaming::ChunkedExtension, wrap_key_to_file::WrapKeyToFileExtension, + StagingBackend, StagingContext, }; -#[cfg(all(feature = "webcrypt", feature = "backend-staging"))] +#[cfg(feature = "webcrypt")] use trussed_staging::hmacsha256p256::HmacSha256P256Extension; pub struct Dispatch { #[cfg(feature = "backend-auth")] auth: AuthBackend, - #[cfg(feature = "backend-staging")] staging: StagingBackend, #[cfg(feature = "se050")] se050: Option>, @@ -58,12 +56,39 @@ pub struct Dispatch { pub struct DispatchContext { #[cfg(feature = "backend-auth")] auth: AuthContext, - #[cfg(feature = "backend-staging")] staging: StagingContext, #[cfg(feature = "se050")] se050: Se050Context, } +fn should_preserve_file(file: &Path) -> bool { + // We save all "special" objects, with an ID that is representable by a `u8` + + const DIRS: &[&Path] = &[path!("x5c"), path!("ctr"), path!("sec"), path!("pub")]; + + let mut components = file.iter(); + if_chain! { + if components.next() == Some("/".into()); + if components.next().is_some(); + if let Some(intermediary) = components.next(); + if DIRS.contains(&&*intermediary); + if let Some(file_name) = components.next(); + if components.next().is_none(); + if file_name.as_ref().len() <=2; + then { + true + } else { + false + } + } +} + +fn build_staging_backend() -> StagingBackend { + let mut backend = StagingBackend::new(); + backend.manage.should_preserve_file = |file, _location| should_preserve_file(file); + backend +} + impl Dispatch { pub fn new( auth_location: Location, @@ -74,8 +99,7 @@ impl Dispatch { Self { #[cfg(feature = "backend-auth")] auth: AuthBackend::new(auth_location), - #[cfg(feature = "backend-staging")] - staging: StagingBackend::new(), + staging: build_staging_backend(), #[cfg(feature = "se050")] se050: se050.map(trussed_se050_backend::Se050Backend::new), #[cfg(not(feature = "se050"))] @@ -91,8 +115,7 @@ impl Dispatch { ) -> Self { Self { auth: AuthBackend::with_hw_key(auth_location, hw_key), - #[cfg(feature = "backend-staging")] - staging: StagingBackend::new(), + staging: build_staging_backend(), #[cfg(feature = "se050")] se050: se050.map(trussed_se050_backend::Se050Backend::new), #[cfg(not(feature = "se050"))] @@ -142,11 +165,11 @@ impl ExtensionDispatch for Dispatch { } #[cfg(feature = "backend-rsa")] Backend::SoftwareRsa => SoftwareRsa.request(&mut ctx.core, &mut (), request, resources), - #[cfg(feature = "backend-staging")] Backend::Staging => { self.staging .request(&mut ctx.core, &mut ctx.backends.staging, request, resources) } + Backend::StagingManage => Err(TrussedError::RequestNotAvailable), #[cfg(feature = "se050")] Backend::Se050 => self .se050 @@ -179,7 +202,6 @@ impl ExtensionDispatch for Dispatch { }, #[cfg(feature = "backend-rsa")] Backend::SoftwareRsa => Err(TrussedError::RequestNotAvailable), - #[cfg(feature = "backend-staging")] Backend::Staging => match extension { Extension::Chunked => { ExtensionImpl::::extension_request_serialized( @@ -199,7 +221,7 @@ impl ExtensionDispatch for Dispatch { resources, ) } - #[cfg(feature = "webcrypt")] + #[cfg(feature = "backend-staging-hmacsha256p256")] Extension::HmacShaP256 => { ExtensionImpl::::extension_request_serialized( &mut self.staging, @@ -212,19 +234,31 @@ impl ExtensionDispatch for Dispatch { #[allow(unreachable_patterns)] _ => Err(TrussedError::RequestNotAvailable), }, - #[cfg(feature = "se050")] - Backend::Se050 => match extension { - Extension::Se050Manage => { + Backend::StagingManage => match extension { + Extension::Manage => { ExtensionImpl::::extension_request_serialized( - self.se050.as_mut().ok_or(TrussedError::GeneralError)?, + &mut self.staging, &mut ctx.core, - &mut ctx.backends.se050, + &mut ctx.backends.staging, request, resources, ) } _ => Err(TrussedError::RequestNotAvailable), }, + #[cfg(feature = "se050")] + Backend::Se050 => match extension { + Extension::Se050Manage => ExtensionImpl::< + trussed_se050_backend::manage::ManageExtension, + >::extension_request_serialized( + self.se050.as_mut().ok_or(TrussedError::GeneralError)?, + &mut ctx.core, + &mut ctx.backends.se050, + request, + resources, + ), + _ => Err(TrussedError::RequestNotAvailable), + }, _ => Err(TrussedError::RequestNotAvailable), } } @@ -236,8 +270,8 @@ pub enum Backend { Auth, #[cfg(feature = "backend-rsa")] SoftwareRsa, - #[cfg(feature = "backend-staging")] Staging, + StagingManage, #[cfg(feature = "se050")] Se050, } @@ -246,11 +280,10 @@ pub enum Backend { pub enum Extension { #[cfg(feature = "backend-auth")] Auth, - #[cfg(feature = "backend-staging")] Chunked, - #[cfg(feature = "backend-staging")] WrapKeyToFile, - #[cfg(feature = "backend-staging")] + Manage, + #[cfg(feature = "backend-staging-hmacsha256p256")] HmacShaP256, #[cfg(feature = "se050")] Se050Manage, @@ -261,14 +294,13 @@ impl From for u8 { match extension { #[cfg(feature = "backend-auth")] Extension::Auth => 0, - #[cfg(feature = "backend-staging")] Extension::Chunked => 1, - #[cfg(feature = "backend-staging")] Extension::WrapKeyToFile => 2, - #[cfg(feature = "backend-staging")] - Extension::HmacShaP256 => 3, + Extension::Manage => 3, + #[cfg(feature = "backend-staging-hmacsha256p256")] + Extension::HmacShaP256 => 4, #[cfg(feature = "se050")] - Extension::Se050Manage => 4, + Extension::Se050Manage => 5, } } } @@ -280,14 +312,13 @@ impl TryFrom for Extension { match id { #[cfg(feature = "backend-auth")] 0 => Ok(Extension::Auth), - #[cfg(feature = "backend-staging")] 1 => Ok(Extension::Chunked), - #[cfg(feature = "backend-staging")] 2 => Ok(Extension::WrapKeyToFile), - #[cfg(feature = "backend-staging")] - 3 => Ok(Extension::HmacShaP256), + 3 => Ok(Extension::Manage), + #[cfg(feature = "backend-staging-hmacsha256p256")] + 4 => Ok(Extension::HmacShaP256), #[cfg(feature = "se050")] - 4 => Ok(Extension::Se050Manage), + 5 => Ok(Extension::Se050Manage), _ => Err(TrussedError::InternalError), } } @@ -300,30 +331,48 @@ impl ExtensionId for Dispatch { const ID: Self::Id = Self::Id::Auth; } -#[cfg(feature = "backend-staging")] impl ExtensionId for Dispatch { type Id = Extension; const ID: Self::Id = Self::Id::Chunked; } -#[cfg(feature = "backend-staging")] impl ExtensionId for Dispatch { type Id = Extension; const ID: Self::Id = Self::Id::WrapKeyToFile; } -#[cfg(all(feature = "backend-staging", feature = "webcrypt"))] +#[cfg(feature = "backend-staging-hmacsha256p256")] impl ExtensionId for Dispatch { type Id = Extension; const ID: Self::Id = Self::Id::HmacShaP256; } -#[cfg(feature = "se050")] impl ExtensionId for Dispatch { type Id = Extension; + const ID: Self::Id = Self::Id::Manage; +} + +#[cfg(feature = "se050")] +impl ExtensionId for Dispatch { + type Id = Extension; + const ID: Self::Id = Self::Id::Se050Manage; } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn file_preserve() { + assert!(should_preserve_file(path!("/fido/sec/00"))); + assert!(should_preserve_file(path!("/fido/x5c/00"))); + assert!(should_preserve_file(path!("/fido/sec/01"))); + assert!(should_preserve_file(path!("/fido/x5c/01"))); + assert!(!should_preserve_file(path!("/fido/dat/sec/00"))); + } +} diff --git a/components/apps/src/lib.rs b/components/apps/src/lib.rs index ee671a72..d3035c17 100644 --- a/components/apps/src/lib.rs +++ b/components/apps/src/lib.rs @@ -15,11 +15,11 @@ use embedded_hal::blocking::delay::DelayUs; use serde::{Deserialize, Serialize}; use trussed::{ backend::BackendId, client::ClientBuilder, interrupt::InterruptFlag, platform::Syscall, - store::filestore::ClientFilestore, ClientImplementation, Platform, Service, + store::filestore::ClientFilestore, types::Path, ClientImplementation, Platform, Service, }; -use admin_app::ConfigValueMut; pub use admin_app::Reboot; +use admin_app::{ConfigValueMut, ResetSignalAllocation}; use trussed::types::Location; #[cfg(feature = "webcrypt")] @@ -47,6 +47,18 @@ impl admin_app::Config for Config { _ => None, } } + + fn reset_client_id(&self, _key: &str) -> Option<&'static Path> { + None + } + + fn reset_signal(&self, _key: &str) -> Option<&'static ResetSignalAllocation> { + None + } + + fn can_reset(&self, _client: &str) -> Option<&'static ResetSignalAllocation> { + None + } } #[derive(Debug, Default, PartialEq, Deserialize, Serialize)] @@ -422,6 +434,7 @@ impl App for AdminApp { fn backends(runner: &R, _config: &()) -> &'static [BackendId] { const BACKENDS_ADMIN: &[BackendId] = &[ + BackendId::Custom(Backend::StagingManage), #[cfg(feature = "se050-test-app")] BackendId::Custom(Backend::Se050), BackendId::Core, From b176bf88cb5c08774ec423bc82dab3c3596cd907 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sosth=C3=A8ne=20Gu=C3=A9don?= Date: Wed, 15 Nov 2023 18:06:41 +0100 Subject: [PATCH 2/4] Allow factory-resetting opcard from admin-app --- Cargo.lock | 5 +++-- Cargo.toml | 4 ++-- components/apps/Cargo.toml | 2 +- components/apps/src/dispatch.rs | 2 +- components/apps/src/lib.rs | 22 ++++++++++++---------- 5 files changed, 19 insertions(+), 16 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f8e917fe..31622bba 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5,7 +5,7 @@ version = 3 [[package]] name = "admin-app" version = "0.1.0" -source = "git+https://github.com/Nitrokey/admin-app.git?rev=1adbce18ca884d35a3a4b80a7c5dd8fca9e4bae0#1adbce18ca884d35a3a4b80a7c5dd8fca9e4bae0" +source = "git+https://github.com/Nitrokey/admin-app.git?rev=410899311ae7b194360366ff477f74d4d278e056#410899311ae7b194360366ff477f74d4d278e056" dependencies = [ "apdu-dispatch", "cbor-smol", @@ -2176,8 +2176,9 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "opcard" version = "1.2.0" -source = "git+https://github.com/Nitrokey/opcard-rs?tag=v1.2.0#ad61078c4653d0daa0512bf1a8466bbba7039edc" +source = "git+https://github.com/Nitrokey/opcard-rs?rev=6dfe4c1112443e337591f59c0b74ece79a2e2c30#6dfe4c1112443e337591f59c0b74ece79a2e2c30" dependencies = [ + "admin-app", "apdu-dispatch", "delog", "heapless 0.7.16", diff --git a/Cargo.toml b/Cargo.toml index daa5d90d..e50c0dc6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,7 @@ version = "1.6.0-rc.1" [patch.crates-io] # forked -admin-app = { git = "https://github.com/Nitrokey/admin-app.git", rev = "1adbce18ca884d35a3a4b80a7c5dd8fca9e4bae0" } +admin-app = { git = "https://github.com/Nitrokey/admin-app.git", rev = "410899311ae7b194360366ff477f74d4d278e056" } ctap-types = { git = "https://github.com/Nitrokey/ctap-types", tag = "v0.1.2-nitrokey.4" } fido-authenticator = { git = "https://github.com/Nitrokey/fido-authenticator.git", tag = "v0.1.1-nitrokey.8" } flexiber = { git = "https://github.com/Nitrokey/flexiber", tag = "0.1.1.nitrokey" } @@ -31,7 +31,7 @@ littlefs2 = { git = "https://github.com/trussed-dev/littlefs2", rev = "e6c46e7ba # unreleased crates secrets-app = { git = "https://github.com/Nitrokey/trussed-secrets-app", tag = "v0.13.0-rc2" } webcrypt = { git = "https://github.com/nitrokey/nitrokey-websmartcard-rust", tag = "v0.8.0-rc4"} -opcard = { git = "https://github.com/Nitrokey/opcard-rs", tag = "v1.2.0" } +opcard = { git = "https://github.com/Nitrokey/opcard-rs", rev = "6dfe4c1112443e337591f59c0b74ece79a2e2c30" } piv-authenticator = { git = "https://github.com/Nitrokey/piv-authenticator", tag = "v0.3.3" } se05x = { git = "https://github.com/Nitrokey/se05x.git", tag = "v0.1.0"} trussed-auth = { git = "https://github.com/trussed-dev/trussed-auth", rev = "62235294bd63977bbb88eb01e7ac44b8010eb450" } diff --git a/components/apps/Cargo.toml b/components/apps/Cargo.toml index 95675645..40f4b6d0 100644 --- a/components/apps/Cargo.toml +++ b/components/apps/Cargo.toml @@ -25,7 +25,7 @@ fido-authenticator = { version = "0.1.1", features = ["dispatch"], optional = tr ndef-app = { path = "../ndef-app", optional = true } webcrypt = { version = "0.8.0", optional = true } secrets-app = { version = "0.13.0", features = ["apdu-dispatch", "ctaphid"], optional = true } -opcard = { version = "1.1.1", features = ["apdu-dispatch", "delog", "rsa2048-gen", "rsa4096"], optional = true } +opcard = { version = "1.1.1", features = ["apdu-dispatch", "delog", "rsa2048-gen", "rsa4096", "admin-app"], optional = true } piv-authenticator = { version = "0.3.1", features = ["apdu-dispatch", "delog"], optional = true } provisioner-app = { path = "../provisioner-app", optional = true } se05x = { version = "0.0.1", optional = true} diff --git a/components/apps/src/dispatch.rs b/components/apps/src/dispatch.rs index d1e98e9e..37111d8c 100644 --- a/components/apps/src/dispatch.rs +++ b/components/apps/src/dispatch.rs @@ -47,7 +47,7 @@ pub struct Dispatch { auth: AuthBackend, staging: StagingBackend, #[cfg(feature = "se050")] - se050: Option>, + se050: Option>, #[cfg(not(feature = "se050"))] __: PhantomData<(T, D)>, } diff --git a/components/apps/src/lib.rs b/components/apps/src/lib.rs index d3035c17..601e4a96 100644 --- a/components/apps/src/lib.rs +++ b/components/apps/src/lib.rs @@ -12,6 +12,7 @@ use core::marker::PhantomData; use ctaphid_dispatch::app::App as CtaphidApp; #[cfg(feature = "se050")] use embedded_hal::blocking::delay::DelayUs; +use littlefs2::path; use serde::{Deserialize, Serialize}; use trussed::{ backend::BackendId, client::ClientBuilder, interrupt::InterruptFlag, platform::Syscall, @@ -48,16 +49,14 @@ impl admin_app::Config for Config { } } - fn reset_client_id(&self, _key: &str) -> Option<&'static Path> { - None - } - - fn reset_signal(&self, _key: &str) -> Option<&'static ResetSignalAllocation> { - None - } - - fn can_reset(&self, _client: &str) -> Option<&'static ResetSignalAllocation> { - None + fn reset_client_id( + &self, + key: &str, + ) -> Option<(&'static Path, &'static ResetSignalAllocation)> { + match key { + "opcard" => Some((path!("opcard"), &OPCARD_RESET_SIGNAL)), + _ => None, + } } } @@ -533,6 +532,8 @@ impl App for SecretsApp { } } +static OPCARD_RESET_SIGNAL: ResetSignalAllocation = ResetSignalAllocation::new(); + #[cfg(feature = "opcard")] impl App for OpcardApp { const CLIENT_ID: &'static str = "opcard"; @@ -548,6 +549,7 @@ impl App for OpcardApp { options.manufacturer = 0x000Fu16.to_be_bytes(); options.serial = [uuid[0], uuid[1], uuid[2], uuid[3]]; options.storage = trussed::types::Location::External; + options.reset_signal = Some(&OPCARD_RESET_SIGNAL); Self::new(trussed, options) } fn backends(runner: &R, _: &()) -> &'static [BackendId] { From fc1047cb48c5811899b89b01c948b6ca00aff892 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sosth=C3=A8ne=20Gu=C3=A9don?= Date: Mon, 20 Nov 2023 11:02:21 +0100 Subject: [PATCH 3/4] Add tests for the preservation of the trussed certificate --- Cargo.lock | 2 +- Cargo.toml | 2 +- components/apps/src/dispatch.rs | 7 +++++++ 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 31622bba..0b10f9b4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2176,7 +2176,7 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "opcard" version = "1.2.0" -source = "git+https://github.com/Nitrokey/opcard-rs?rev=6dfe4c1112443e337591f59c0b74ece79a2e2c30#6dfe4c1112443e337591f59c0b74ece79a2e2c30" +source = "git+https://github.com/Nitrokey/opcard-rs?rev=a824c6473ce1b88b45b32de21089401fc9f7f683#a824c6473ce1b88b45b32de21089401fc9f7f683" dependencies = [ "admin-app", "apdu-dispatch", diff --git a/Cargo.toml b/Cargo.toml index e50c0dc6..0f4a9fc7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,7 +31,7 @@ littlefs2 = { git = "https://github.com/trussed-dev/littlefs2", rev = "e6c46e7ba # unreleased crates secrets-app = { git = "https://github.com/Nitrokey/trussed-secrets-app", tag = "v0.13.0-rc2" } webcrypt = { git = "https://github.com/nitrokey/nitrokey-websmartcard-rust", tag = "v0.8.0-rc4"} -opcard = { git = "https://github.com/Nitrokey/opcard-rs", rev = "6dfe4c1112443e337591f59c0b74ece79a2e2c30" } +opcard = { git = "https://github.com/Nitrokey/opcard-rs", rev = "a824c6473ce1b88b45b32de21089401fc9f7f683" } piv-authenticator = { git = "https://github.com/Nitrokey/piv-authenticator", tag = "v0.3.3" } se05x = { git = "https://github.com/Nitrokey/se05x.git", tag = "v0.1.0"} trussed-auth = { git = "https://github.com/trussed-dev/trussed-auth", rev = "62235294bd63977bbb88eb01e7ac44b8010eb450" } diff --git a/components/apps/src/dispatch.rs b/components/apps/src/dispatch.rs index 37111d8c..fd4270ac 100644 --- a/components/apps/src/dispatch.rs +++ b/components/apps/src/dispatch.rs @@ -373,6 +373,13 @@ mod tests { assert!(should_preserve_file(path!("/fido/x5c/00"))); assert!(should_preserve_file(path!("/fido/sec/01"))); assert!(should_preserve_file(path!("/fido/x5c/01"))); + assert!(should_preserve_file(path!("/attn/pub/00"))); + assert!(should_preserve_file(path!("/attn/sec/01"))); + assert!(should_preserve_file(path!("/attn/sec/02"))); + assert!(should_preserve_file(path!("/attn/sec/03"))); + assert!(should_preserve_file(path!("/attn/x5c/01"))); + assert!(should_preserve_file(path!("/attn/x5c/02"))); + assert!(should_preserve_file(path!("/attn/x5c/03"))); assert!(!should_preserve_file(path!("/fido/dat/sec/00"))); } } From 19e168a53411b0a470c0c65e742d943a7466e4f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sosth=C3=A8ne=20Gu=C3=A9don?= Date: Mon, 20 Nov 2023 11:14:19 +0100 Subject: [PATCH 4/4] Document Separate manage backend ID --- components/apps/src/dispatch.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/components/apps/src/dispatch.rs b/components/apps/src/dispatch.rs index fd4270ac..96cb8f08 100644 --- a/components/apps/src/dispatch.rs +++ b/components/apps/src/dispatch.rs @@ -271,6 +271,7 @@ pub enum Backend { #[cfg(feature = "backend-rsa")] SoftwareRsa, Staging, + /// Separate BackendId to prevent non-priviledged apps from accessing the manage Extension StagingManage, #[cfg(feature = "se050")] Se050,