Skip to content

Commit

Permalink
Update dependencies for trussed-core and ctaphid-app
Browse files Browse the repository at this point in the history
  • Loading branch information
robin-nitrokey committed Jan 8, 2025
1 parent 0ac88d4 commit d61a9ac
Show file tree
Hide file tree
Showing 16 changed files with 179 additions and 146 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Support CTAP 2.1
- Serialize PIN hash with `serde-bytes` ([#52][])
- Reduce the space taken by credential serializaiton ([#59][])
- Update dependencies:
- Replace `trussed` dependency with `trussed-core`
- Replace `ctaphid-dispatch` dependeny with `ctaphid-app`

[#26]: https://github.com/solokeys/fido-authenticator/issues/26
[#28]: https://github.com/solokeys/fido-authenticator/issues/28
Expand Down
30 changes: 14 additions & 16 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,32 +15,30 @@ name = "usbip"
required-features = ["dispatch"]

[dependencies]
cbor-smol = { version = "0.5" }
ctap-types = { version = "0.3.1", features = ["get-info-full", "large-blobs", "third-party-payment"] }
cosey = "0.3"
delog = "0.1.0"
heapless = "0.7"
heapless-bytes = "0.3"
littlefs2-core = "0.1"
serde = { version = "1.0", default-features = false }
serde_bytes = { version = "0.11.14", default-features = false }
serde-indexed = "0.1.0"
sha2 = { version = "0.10", default-features = false }
trussed = "0.1"
trussed-core = "0.1"
trussed-core = { version = "0.1.0-rc.1", features = ["aes256-cbc", "certificate-client", "chacha8-poly1305", "crypto-client", "ed255", "filesystem-client", "hmac-sha256", "management-client", "p256", "sha256", "ui-client"] }
trussed-fs-info = "0.1.0"
trussed-hkdf = { version = "0.2.0" }
trussed-chunked = { version = "0.1.0", optional = true }

apdu-app = { version = "0.1", optional = true }
ctaphid-dispatch = { version = "0.1", optional = true }
ctaphid-app = { version = "0.1.0-rc.1", optional = true }
iso7816 = { version = "0.1.2", optional = true }

# This dependency is used indirectly via Trussed. We only want to make sure that we use at least
# 0.4.1 so that the persistent state is deserialized correctly.
cbor-smol = { version = ">= 0.4.1" }

[features]
dispatch = ["apdu-dispatch", "ctaphid-dispatch", "iso7816"]
apdu-dispatch = ["dep:apdu-app"]
ctaphid-dispatch = ["dep:ctaphid-app"]
disable-reset-time-window = []

# enables support for a large-blob array longer than 1024 bytes
Expand All @@ -60,6 +58,7 @@ ciborium = { version = "0.2.2" }
ciborium-io = "0.2.2"
cipher = "0.4.4"
ctaphid = { version = "0.3.1", default-features = false }
ctaphid-dispatch = "0.1"
delog = { version = "0.1.6", features = ["std-log"] }
env_logger = "0.11.0"
hex-literal = "0.4.1"
Expand All @@ -82,12 +81,11 @@ x509-parser = "0.16.0"
features = ["dispatch"]

[patch.crates-io]
ctaphid-dispatch = { git = "https://github.com/trussed-dev/ctaphid-dispatch.git", rev = "57cb3317878a8593847595319aa03ef17c29ec5b" }
trussed = { git = "https://github.com/trussed-dev/trussed.git", rev = "eadd27cda0f457caae609e7fa972277e46695bd3" }
trussed-core = { git = "https://github.com/trussed-dev/trussed.git", rev = "eadd27cda0f457caae609e7fa972277e46695bd3" }
trussed-chunked = { git = "https://github.com/trussed-dev/trussed-staging.git", tag = "chunked-v0.1.0" }
trussed-fs-info = { git = "https://github.com/trussed-dev/trussed-staging.git", rev = "fs-info-v0.1.0" }
trussed-hkdf = { git = "https://github.com/trussed-dev/trussed-staging.git", tag = "hkdf-v0.2.0" }
trussed-staging = { git = "https://github.com/trussed-dev/trussed-staging.git", rev = "53eba84d2cd0bcacc3a7096d4b7a2490dcf6f069" }
trussed-usbip = { git = "https://github.com/Nitrokey/pc-usbip-runner.git", tag = "v0.0.1-nitrokey.5" }
usbd-ctaphid = { git = "https://github.com/trussed-dev/usbd-ctaphid.git", rev = "dcff9009c3cd1ef9e5b09f8f307aca998fc9a8c8" }
ctaphid-dispatch = { git = "https://github.com/trussed-dev/ctaphid-dispatch.git", rev = "5a2864c76fea6785d9ffe4c7b6596237d8378755" }
trussed = { git = "https://github.com/trussed-dev/trussed.git", rev = "6bba8fde36d05c0227769eb63345744e87d84b2b" }
trussed-chunked = { git = "https://github.com/trussed-dev/trussed-staging.git", rev = "9355f700831c1a278c334f76382fbf98d82aedcd" }
trussed-fs-info = { git = "https://github.com/trussed-dev/trussed-staging.git", rev = "9355f700831c1a278c334f76382fbf98d82aedcd" }
trussed-hkdf = { git = "https://github.com/trussed-dev/trussed-staging.git", rev = "9355f700831c1a278c334f76382fbf98d82aedcd" }
trussed-staging = { git = "https://github.com/trussed-dev/trussed-staging.git", rev = "9355f700831c1a278c334f76382fbf98d82aedcd" }
trussed-usbip = { git = "https://github.com/trussed-dev/pc-usbip-runner.git", rev = "60c58eb80685f72d80850b850800fc6a660fe50a" }
usbd-ctaphid = { git = "https://github.com/trussed-dev/usbd-ctaphid.git", rev = "96bf04e97cfc8077b4d9b6b97b3e34ec3ca3e2fc" }
7 changes: 6 additions & 1 deletion examples/usbip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,12 @@ impl<S: StoreProvider> trussed_usbip::Apps<'static, S, Dispatcher> for FidoApp {

fn with_ctaphid_apps<T>(
&mut self,
f: impl FnOnce(&mut [&mut dyn ctaphid_dispatch::app::App<'static>]) -> T,
f: impl FnOnce(
&mut [&mut dyn ctaphid_dispatch::app::App<
'static,
{ ctaphid_dispatch::types::MESSAGE_SIZE },
>],
) -> T,
) -> T {
f(&mut [&mut self.fido])
}
Expand Down
12 changes: 6 additions & 6 deletions fuzz/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ cargo-fuzz = true
[dependencies]
ctap-types = { version = "0.3.0", features = ["arbitrary"] }
libfuzzer-sys = "0.4"
trussed = { version = "0.1", features = ["clients-1", "certificate-client", "crypto-client", "filesystem-client", "management-client", "aes256-cbc", "ed255", "p256", "sha256"] }
trussed-staging = { version = "0.3.0", features = ["chunked", "hkdf", "virt", "fs-info"] }

[dependencies.fido-authenticator]
Expand All @@ -23,9 +24,8 @@ doc = false
bench = false

[patch.crates-io]
trussed = { git = "https://github.com/trussed-dev/trussed.git", rev = "eadd27cda0f457caae609e7fa972277e46695bd3" }
trussed-core = { git = "https://github.com/trussed-dev/trussed.git", rev = "eadd27cda0f457caae609e7fa972277e46695bd3" }
trussed-chunked = { git = "https://github.com/trussed-dev/trussed-staging.git", tag = "chunked-v0.1.0" }
trussed-hkdf = { git = "https://github.com/trussed-dev/trussed-staging.git", tag = "hkdf-v0.2.0" }
trussed-fs-info = { git = "https://github.com/trussed-dev/trussed-staging.git", rev = "fs-info-v0.1.0" }
trussed-staging = { git = "https://github.com/trussed-dev/trussed-staging.git", rev = "53eba84d2cd0bcacc3a7096d4b7a2490dcf6f069" }
trussed = { git = "https://github.com/trussed-dev/trussed.git", rev = "6bba8fde36d05c0227769eb63345744e87d84b2b" }
trussed-chunked = { git = "https://github.com/trussed-dev/trussed-staging.git", rev = "9355f700831c1a278c334f76382fbf98d82aedcd" }
trussed-fs-info = { git = "https://github.com/trussed-dev/trussed-staging.git", rev = "9355f700831c1a278c334f76382fbf98d82aedcd" }
trussed-hkdf = { git = "https://github.com/trussed-dev/trussed-staging.git", rev = "9355f700831c1a278c334f76382fbf98d82aedcd" }
trussed-staging = { git = "https://github.com/trussed-dev/trussed-staging.git", rev = "9355f700831c1a278c334f76382fbf98d82aedcd" }
2 changes: 1 addition & 1 deletion src/constants.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Constants.
use trussed::types::{CertId, KeyId};
use trussed_core::types::{CertId, KeyId};

pub const FIDO2_UP_TIMEOUT: u32 = 30_000;
pub const U2F_UP_TIMEOUT: u32 = 250;
Expand Down
50 changes: 32 additions & 18 deletions src/credential.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,12 @@ use core::cmp::Ordering;

use serde::Serialize;
use serde_bytes::ByteArray;
use trussed::{client, syscall, try_syscall, types::KeyId};
use trussed_core::types::EncryptedData;
use trussed_core::{
mechanisms::{Chacha8Poly1305, Sha256},
syscall, try_syscall,
types::{EncryptedData, KeyId},
CryptoClient, FilesystemClient,
};

pub(crate) use ctap_types::{
// authenticator::{ctap1, ctap2, Error, Request, Response},
Expand Down Expand Up @@ -36,15 +40,16 @@ pub enum CtapVersion {
pub struct CredentialId(pub Bytes<MAX_CREDENTIAL_ID_LENGTH>);

impl CredentialId {
fn new<T: client::Chacha8Poly1305 + client::Sha256, C: Serialize>(
fn new<T: Chacha8Poly1305, C: Serialize>(
trussed: &mut T,
credential: &C,
key_encryption_key: KeyId,
rp_id_hash: &[u8; 32],
nonce: &[u8; 12],
) -> Result<Self> {
let serialized_credential: SerializedCredential =
trussed::cbor_serialize_bytes(credential).map_err(|_| Error::Other)?;
let mut serialized_credential = SerializedCredential::new();
cbor_smol::cbor_serialize_to(credential, &mut serialized_credential)
.map_err(|_| Error::Other)?;
let message = &serialized_credential;
// info!("serialized cred = {:?}", message).ok();
let associated_data = &rp_id_hash[..];
Expand All @@ -54,24 +59,28 @@ impl CredentialId {
associated_data,
Some(nonce)
));
trussed::cbor_serialize_bytes(&EncryptedData::from(encrypted_serialized_credential))
.map(Self)
.map_err(|_| Error::RequestTooLarge)
let mut credential_id = Bytes::new();
cbor_smol::cbor_serialize_to(
&EncryptedData::from(encrypted_serialized_credential),
&mut credential_id,
)
.map_err(|_| Error::RequestTooLarge)?;
Ok(Self(credential_id))
}
}

struct CredentialIdRef<'a>(&'a [u8]);

impl CredentialIdRef<'_> {
fn deserialize(&self) -> Result<EncryptedData> {
ctap_types::serde::cbor_deserialize(self.0).map_err(|_| Error::InvalidCredential)
cbor_smol::cbor_deserialize(self.0).map_err(|_| Error::InvalidCredential)
}
}

// TODO: how to determine necessary size?
// pub type SerializedCredential = Bytes<512>;
// pub type SerializedCredential = Bytes<256>;
pub(crate) type SerializedCredential = trussed::types::Message;
pub(crate) type SerializedCredential = trussed_core::types::Message;

/// Credential keys can either be "discoverable" or not.
///
Expand Down Expand Up @@ -101,15 +110,18 @@ pub enum Credential {
}

impl Credential {
pub fn try_from<UP: UserPresence, T: client::Client + client::Chacha8Poly1305>(
pub fn try_from<UP: UserPresence, T: CryptoClient + Chacha8Poly1305 + FilesystemClient>(
authnr: &mut Authenticator<UP, T>,
rp_id_hash: &[u8; 32],
descriptor: &PublicKeyCredentialDescriptorRef,
) -> Result<Self> {
Self::try_from_bytes(authnr, rp_id_hash, descriptor.id)
}

pub fn try_from_bytes<UP: UserPresence, T: client::Client + client::Chacha8Poly1305>(
pub fn try_from_bytes<
UP: UserPresence,
T: CryptoClient + Chacha8Poly1305 + FilesystemClient,
>(
authnr: &mut Authenticator<UP, T>,
rp_id_hash: &[u8; 32],
id: &[u8],
Expand Down Expand Up @@ -140,7 +152,7 @@ impl Credential {
.map_err(|_| Error::InvalidCredential)
}

pub fn id<T: client::Chacha8Poly1305 + client::Sha256>(
pub fn id<T: Chacha8Poly1305 + Sha256>(
&self,
trussed: &mut T,
key_encryption_key: KeyId,
Expand Down Expand Up @@ -639,7 +651,7 @@ impl FullCredential {
// the ID will stay below 255 bytes.
//
// Existing keyhandles can still be decoded
pub fn id<T: client::Chacha8Poly1305 + client::Sha256>(
pub fn id<T: Chacha8Poly1305 + Sha256>(
&self,
trussed: &mut T,
key_encryption_key: KeyId,
Expand Down Expand Up @@ -669,11 +681,13 @@ impl FullCredential {
}

pub fn serialize(&self) -> Result<SerializedCredential> {
trussed::cbor_serialize_bytes(self).map_err(|_| Error::Other)
let mut serialized_credential = SerializedCredential::new();
cbor_smol::cbor_serialize_to(self, &mut serialized_credential).map_err(|_| Error::Other)?;
Ok(serialized_credential)
}

pub fn deserialize(bytes: &SerializedCredential) -> Result<Self> {
match ctap_types::serde::cbor_deserialize(bytes) {
match cbor_smol::cbor_deserialize(bytes) {
Ok(s) => Ok(s),
Err(_) => {
info_now!("could not deserialize {:?}", bytes);
Expand Down Expand Up @@ -724,7 +738,7 @@ pub struct StrippedCredential {

impl StrippedCredential {
fn deserialize(bytes: &SerializedCredential) -> Result<Self> {
match ctap_types::serde::cbor_deserialize(bytes) {
match cbor_smol::cbor_deserialize(bytes) {
Ok(s) => Ok(s),
Err(_) => {
info_now!("could not deserialize {:?}", bytes);
Expand All @@ -733,7 +747,7 @@ impl StrippedCredential {
}
}

pub fn id<T: client::Chacha8Poly1305 + client::Sha256>(
pub fn id<T: Chacha8Poly1305>(
&self,
trussed: &mut T,
key_encryption_key: KeyId,
Expand Down
4 changes: 2 additions & 2 deletions src/ctap1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use ctap_types::{
};
use serde_bytes::ByteArray;

use trussed::{
use trussed_core::{
syscall,
types::{KeySerialization, Location, Mechanism, SignatureSerialization},
};
Expand Down Expand Up @@ -52,7 +52,7 @@ impl<UP: UserPresence, T: TrussedRequirements> Authenticator for crate::Authenti
.serialized_key;
syscall!(self.trussed.delete(public_key));
let cose_key: cosey::EcdhEsHkdf256PublicKey =
trussed::cbor_deserialize(&serialized_cose_public_key).unwrap();
cbor_smol::cbor_deserialize(&serialized_cose_public_key).unwrap();

let wrapping_key = self
.state
Expand Down
10 changes: 5 additions & 5 deletions src/ctap2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@ use ctap_types::{
webauthn::PublicKeyCredentialUserEntity,
ByteArray, Error,
};
use littlefs2_core::path;
use littlefs2_core::{path, Path, PathBuf};
use sha2::{Digest as _, Sha256};

use trussed::{
use trussed_core::{
syscall, try_syscall,
types::{
KeyId, KeySerialization, Location, Mechanism, MediumData, Message, Path, PathBuf,
SignatureSerialization,
KeyId, KeySerialization, Location, Mechanism, MediumData, Message, SignatureSerialization,
StorageAttributes,
},
};

Expand Down Expand Up @@ -1517,7 +1517,7 @@ impl<UP: UserPresence, T: TrussedRequirements> crate::Authenticator<UP, T> {
Mechanism::HmacSha256,
credential_key,
Some(Bytes::from_slice(&[get_assertion_state.uv_performed as u8]).unwrap()),
trussed::types::StorageAttributes::new().set_persistence(Location::Volatile)
StorageAttributes::new().set_persistence(Location::Volatile)
))
.key;

Expand Down
7 changes: 4 additions & 3 deletions src/ctap2/credential_management.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
use core::{cmp, convert::TryFrom};

use trussed::{
use littlefs2_core::{Path, PathBuf};
use trussed_core::{
syscall, try_syscall,
types::{DirEntry, Location, Path, PathBuf},
types::{DirEntry, Location},
};

use cosey::PublicKey;
Expand Down Expand Up @@ -414,7 +415,7 @@ where
};

use crate::SigningAlgorithm;
use trussed::types::{KeySerialization, Mechanism};
use trussed_core::types::{KeySerialization, Mechanism};

let algorithm = SigningAlgorithm::try_from(credential.algorithm)?;
let cose_public_key = match algorithm {
Expand Down
21 changes: 12 additions & 9 deletions src/ctap2/large_blobs.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
use ctap_types::{sizes::LARGE_BLOB_MAX_FRAGMENT_LENGTH, Error};
use littlefs2_core::path;
use trussed::{
use littlefs2_core::{path, Path, PathBuf};
use trussed_core::{
config::MAX_MESSAGE_LENGTH,
try_syscall,
types::{Bytes, Location, Message, Path, PathBuf},
types::{Bytes, Location, Message},
FilesystemClient,
};

#[cfg(feature = "chunked")]
use trussed_chunked::ChunkedClient;
#[cfg(not(feature = "chunked"))]
use trussed::{syscall, types::Mechanism};
use trussed_core::{mechanisms::Sha256, syscall, types::Mechanism, CryptoClient};

use crate::{Result, TrussedRequirements};

Expand Down Expand Up @@ -51,7 +54,7 @@ impl Config {
}
}

pub fn size<C: TrussedRequirements>(client: &mut C, location: Location) -> Result<usize> {
pub fn size<C: FilesystemClient>(client: &mut C, location: Location) -> Result<usize> {
Ok(
try_syscall!(client.entry_metadata(location, PathBuf::from(FILENAME)))
.map_err(|_| Error::Other)?
Expand Down Expand Up @@ -82,7 +85,7 @@ pub fn write_chunk<C: TrussedRequirements>(
write_impl::<_, SelectedStorage>(client, state, location, data)
}

pub fn reset<C: TrussedRequirements>(client: &mut C) {
pub fn reset<C: FilesystemClient>(client: &mut C) {
for location in [Location::Internal, Location::External, Location::Volatile] {
try_syscall!(client.remove_file(location, PathBuf::from(FILENAME))).ok();
}
Expand Down Expand Up @@ -161,7 +164,7 @@ struct SimpleStorage {
}

#[cfg(not(feature = "chunked"))]
impl<C: TrussedRequirements> Storage<C> for SimpleStorage {
impl<C: CryptoClient + FilesystemClient + Sha256> Storage<C> for SimpleStorage {
fn read(client: &mut C, location: Location, offset: usize, length: usize) -> Result<Chunk> {
let result = try_syscall!(client.read_file(location, PathBuf::from(FILENAME)));
let data = if let Ok(reply) = &result {
Expand Down Expand Up @@ -248,7 +251,7 @@ struct ChunkedStorage {
}

#[cfg(feature = "chunked")]
impl<C: TrussedRequirements> Storage<C> for ChunkedStorage {
impl<C: ChunkedClient + FilesystemClient> Storage<C> for ChunkedStorage {
fn read(client: &mut C, location: Location, offset: usize, length: usize) -> Result<Chunk> {
debug!("ChunkedStorage::read: offset = {offset}, length = {length}");
let mut chunk = Chunk::new();
Expand Down Expand Up @@ -307,7 +310,7 @@ impl<C: TrussedRequirements> Storage<C> for ChunkedStorage {
fn extend_buffer(&mut self, client: &mut C, data: &[u8]) -> Result<usize> {
debug!("ChunkedStorage::extend_buffer: |data| = {}", data.len());
let mut n = 0;
for chunk in data.chunks(trussed::config::MAX_MESSAGE_LENGTH) {
for chunk in data.chunks(trussed_core::config::MAX_MESSAGE_LENGTH) {
trace!("Writing {} bytes", chunk.len());
let path = PathBuf::from(FILENAME_TMP);
let mut message = Message::new();
Expand Down
Loading

0 comments on commit d61a9ac

Please sign in to comment.