diff --git a/CHANGELOG.md b/CHANGELOG.md index d7a2768..4ff5e5e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,10 +2,27 @@ ## [Unreleased][] -[Unreleased]: https://github.com/trussed-dev/piv-authenticator/compare/v0.5.3...HEAD +[Unreleased]: https://github.com/trussed-dev/piv-authenticator/compare/v0.6.0...HEAD + +- + +## [v0.6.0][] (2026-03-25) + +[v0.6.0]: https://github.com/trussed-dev/piv-authenticator/releases/tag/v0.6.0 - Replace `trussed-rsa-alloc` dependency with `trussed-rsa-types` for most use cases. (Only the `virt` feature still requires `trussed-rsa-alloc`.) +- Update dependencies: + - `apdu-app` v0.2 + - `cbor-smol` v0.5 + - `flexiber` v0.2 + - `heapless` v0.9 + - `heapless-bytes` v0.5 + - `iso7816` v0.2 + - `trussed-chunked` v0.3 + - `trussed-core` v0.2 + - `trussed-hpke` v0.3 + - `trussed-wrap-key-to-file` v0.3 ## [v0.5.3][] (2025-07-31) diff --git a/Cargo.toml b/Cargo.toml index 3fdb6e2..3e461fb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "piv-authenticator" -version = "0.5.3" +version = "0.6.0" authors = ["Nicolas Stalder ", "Nitrokey GmbH"] edition = "2021" license = "Apache-2.0 OR MIT" @@ -12,30 +12,30 @@ name = "vpicc" required-features = ["vpicc"] [dependencies] -apdu-app = { version = "0.1", optional = true } -cbor-smol = { version = "0.5", features = ["heapless-bytes-v0-3"] } +apdu-app = { version = "0.2", optional = true } +cbor-smol = { version = "0.5", features = ["heapless-bytes-v0-5"] } delog = { version = "0.1.5", optional = true } -flexiber = { version = "0.1", features = ["derive", "heapless"] } -heapless = "0.7" +flexiber = { version = "0.2", features = ["derive", "heapless"] } +heapless = "0.9.1" hex-literal = "0.3" -iso7816 = "0.1.3" +iso7816 = "0.2.0" serde = { version = "1", default-features = false, features = ["derive"] } trussed = { version = "0.1", default-features = false, features = ["aes256-cbc", "chacha8-poly1305", "crypto-client", "ed255", "filesystem-client", "p256", "p384", "shared-secret", "serde-extensions", "tdes", "x255"], optional = true } -trussed-auth = "0.4" +trussed-auth = "0.5" trussed-auth-backend = { version = "0.1.0", optional = true } untrusted = "0.9" vpicc = { version = "0.1.0", optional = true } log = "0.4" -heapless-bytes = "0.3.0" +heapless-bytes = "0.5.0" subtle = { version = "2", default-features = false } # TODO: only enable rsa features when needed -trussed-core = { version = "0.1.0-rc.1", features = ["aes256-cbc", "chacha8-poly1305", "crypto-client", "ed255", "filesystem-client", "p256", "p384", "rsa2048", "rsa3072", "rsa4096", "shared-secret", "tdes", "x255"] } -trussed-rsa-types = { version = "0.1", optional = true } -trussed-rsa-alloc = { version = "0.3", features = ["raw"], optional = true } -trussed-chunked = "0.2.0" -trussed-hpke = "0.2.0" -trussed-wrap-key-to-file = "0.2.0" -trussed-staging = { version = "0.3.2", features = ["chunked", "hpke", "wrap-key-to-file"], default-features = false, optional = true } +trussed-core = { version = "0.2", features = ["aes256-cbc", "chacha8-poly1305", "crypto-client", "ed255", "filesystem-client", "p256", "p384", "rsa2048", "rsa3072", "rsa4096", "shared-secret", "tdes", "x255"] } +trussed-rsa-types = { version = "0.2", optional = true } +trussed-rsa-alloc = { version = "0.4", features = ["raw"], optional = true } +trussed-chunked = "0.3.0" +trussed-hpke = "0.3.0" +trussed-wrap-key-to-file = "0.3.0" +trussed-staging = { version = "0.4", features = ["chunked", "hpke", "wrap-key-to-file"], default-features = false, optional = true } littlefs2-core = "0.1.0" cfg-if = "1.0.0" @@ -52,7 +52,7 @@ des = "0.8" aes = "0.8.2" stoppable_thread = "0.2.1" expectrl = "0.7.0" -iso7816 = { version = "0.1.2", features = ["std"] } +iso7816 = { version = "0.2", features = ["std"] } # Examples # usbip @@ -83,10 +83,10 @@ log-error = [] dangerous-test-real-card = [] [patch.crates-io] -trussed = { git = "https://github.com/trussed-dev/trussed", rev = "6bba8fde36d05c0227769eb63345744e87d84b2b" } -trussed-rsa-alloc = { git = "https://github.com/trussed-dev/trussed-rsa-backend.git", tag = "v0.3.0" } -trussed-staging = { git = "https://github.com/trussed-dev/trussed-staging.git", rev = "1e1ca03a3a62ea9b802f4070ea4bce002eeb4bec" } -trussed-auth-backend = { git = "https://github.com/trussed-dev/trussed-auth", tag = "v0.4.0" } +trussed = { git = "https://github.com/trussed-dev/trussed", rev = "0f8df68be879acdde1f8cf428c11e5d29692a47b" } +trussed-auth-backend = { git = "https://github.com/trussed-dev/trussed-auth", tag = "backend-v0.1.0" } +trussed-rsa-alloc = { git = "https://github.com/trussed-dev/trussed-rsa-backend.git", tag = "v0.4.0" } +trussed-staging = { git = "https://github.com/trussed-dev/trussed-staging.git", tag = "v0.4.0" } [profile.dev.package.rsa] opt-level = 2 diff --git a/src/dispatch.rs b/src/dispatch.rs index b8bd0b0..eab8230 100644 --- a/src/dispatch.rs +++ b/src/dispatch.rs @@ -1,10 +1,11 @@ use crate::{reply::Reply, Authenticator, /*constants::PIV_AID,*/ Result}; -use apdu_app::{App, CommandView, Data}; +use apdu_app::{App, CommandView}; +use heapless::VecView; use iso7816::{Interface, Status}; #[cfg(feature = "apdu-dispatch")] -impl App for Authenticator +impl App for Authenticator where T: crate::Client, { @@ -12,7 +13,7 @@ where &mut self, interface: Interface, _apdu: CommandView<'_>, - reply: &mut Data, + reply: &mut VecView, ) -> Result { if interface != Interface::Contact { return Err(Status::ConditionsOfUseNotSatisfied); @@ -24,7 +25,12 @@ where self.deselect() } - fn call(&mut self, interface: Interface, apdu: CommandView<'_>, reply: &mut Data) -> Result { + fn call( + &mut self, + interface: Interface, + apdu: CommandView<'_>, + reply: &mut VecView, + ) -> Result { if interface != Interface::Contact { return Err(Status::ConditionsOfUseNotSatisfied); } diff --git a/src/lib.rs b/src/lib.rs index 83331aa..7e7b65f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -21,6 +21,7 @@ mod reply; pub mod state; mod tlv; +use heapless::VecView; pub use piv_types::{AsymmetricAlgorithms, Pin, Puk}; use trussed_chunked::ChunkedClient; use trussed_hpke::HpkeClient; @@ -35,7 +36,7 @@ use core::convert::TryInto; use flexiber::EncodableHeapless; use heapless_bytes::Bytes; -use iso7816::{Data, Status}; +use iso7816::Status; use trussed_auth::AuthClient; use trussed_core::mechanisms::Tdes; use trussed_core::types::{KeySerialization, Location, Mechanism, PathBuf, StorageAttributes}; @@ -136,7 +137,7 @@ where // The way apdu-dispatch currently works, this would deselect, resetting security indicators. pub fn deselect(&mut self) {} - pub fn select(&mut self, mut reply: Reply<'_, R>) -> Result { + pub fn select(&mut self, mut reply: Reply<'_>) -> Result { use piv_types::Algorithms::*; info!("selecting PIV maybe"); @@ -154,10 +155,10 @@ where Ok(()) } - pub fn respond( + pub fn respond( &mut self, command: iso7816::command::CommandView<'_>, - reply: &mut Data, + reply: &mut VecView, ) -> Result { let just_verified = self.state.volatile.app_security_status.pin_just_verified; self.state.volatile.app_security_status.pin_just_verified = false; @@ -192,11 +193,11 @@ where } } - pub fn yubico_piv_extension( + pub fn yubico_piv_extension( &mut self, data: &[u8], instruction: YubicoPivExtension, - mut reply: Reply<'_, R>, + mut reply: Reply<'_>, ) -> Result { info!("yubico extension: {:?}", &instruction); match instruction { @@ -256,11 +257,11 @@ where } impl LoadedAuthenticator<'_, T> { - pub fn yubico_set_administration_key( + pub fn yubico_set_administration_key( &mut self, data: &[u8], _touch_policy: TouchPolicy, - _reply: Reply<'_, R>, + _reply: Reply<'_>, ) -> Result { // cmd := apdu{ // instruction: insSetMGMKey, @@ -424,12 +425,12 @@ impl LoadedAuthenticator<'_, T> { // - 9000, 61XX for success // - 6982 security status // - 6A80, 6A86 for data, P1/P2 issue - pub fn general_authenticate( + pub fn general_authenticate( &mut self, auth: GeneralAuthenticate, data: &[u8], just_verified: bool, - mut reply: Reply<'_, R>, + mut reply: Reply<'_>, ) -> Result { // For "SSH", we need implement A.4.2 in SP-800-73-4 Part 2, ECDSA signatures // @@ -562,11 +563,7 @@ impl LoadedAuthenticator<'_, T> { Ok(self.state.persistent.keys.administration) } - fn single_auth_1( - &mut self, - auth: GeneralAuthenticate, - mut reply: Reply<'_, R>, - ) -> Result { + fn single_auth_1(&mut self, auth: GeneralAuthenticate, mut reply: Reply<'_>) -> Result { info!("Single auth 1"); let key = self.validate_auth_management(auth)?; let plaintext = syscall!(self.trussed.random_bytes(key.alg.challenge_length())).bytes; @@ -576,7 +573,7 @@ impl LoadedAuthenticator<'_, T> { .encrypt(key.alg.mechanism(), key.id, &plaintext, &[], None)) .ciphertext; self.state.volatile.command_cache = Some(CommandCache::SingleAuthChallengeReference( - Bytes::from_slice(&ciphertext).unwrap(), + Bytes::try_from(&*ciphertext).unwrap(), )); reply.expand(&[0x7C])?; @@ -619,11 +616,7 @@ impl LoadedAuthenticator<'_, T> { Ok(()) } - fn mutual_auth_1( - &mut self, - auth: GeneralAuthenticate, - mut reply: Reply<'_, R>, - ) -> Result { + fn mutual_auth_1(&mut self, auth: GeneralAuthenticate, mut reply: Reply<'_>) -> Result { info!("Mutual auth 1"); let key = self.validate_auth_management(auth)?; let plaintext = syscall!(self.trussed.random_bytes(key.alg.challenge_length())).bytes; @@ -635,7 +628,7 @@ impl LoadedAuthenticator<'_, T> { .ciphertext; self.state.volatile.command_cache = Some(CommandCache::MutualAuthWitnessReference( - Bytes::from_slice(&plaintext).unwrap(), + Bytes::try_from(&*plaintext).unwrap(), )); reply.expand(&[0x7C])?; @@ -649,12 +642,12 @@ impl LoadedAuthenticator<'_, T> { Ok(()) } - fn mutual_auth_2( + fn mutual_auth_2( &mut self, auth: GeneralAuthenticate, response: &[u8], challenge: &[u8], - mut reply: Reply<'_, R>, + mut reply: Reply<'_>, ) -> Result { use subtle::ConstantTimeEq; @@ -703,12 +696,12 @@ impl LoadedAuthenticator<'_, T> { } // Sign a message. For RSA, since the key is exposed as a raw key, so it can also be used for decryption - fn sign( + fn sign( &mut self, auth: GeneralAuthenticate, message: &[u8], just_verified: bool, - mut reply: Reply<'_, R>, + mut reply: Reply<'_>, ) -> Result { debug!("Request for sign, data length: {}, data:", message.len()); // error!("{}", delog::hexstr!(message)); @@ -754,11 +747,11 @@ impl LoadedAuthenticator<'_, T> { ) } - fn key_agreement( + fn key_agreement( &mut self, auth: GeneralAuthenticate, data: &[u8], - mut reply: Reply<'_, R>, + mut reply: Reply<'_>, just_verified: bool, ) -> Result { info!("Request for exponentiation"); @@ -839,11 +832,11 @@ impl LoadedAuthenticator<'_, T> { ) } - pub fn generate_asymmetric_keypair( + pub fn generate_asymmetric_keypair( &mut self, reference: GenerateKeyReference, data: &[u8], - mut reply: Reply<'_, R>, + mut reply: Reply<'_>, ) -> Result { if !self .state @@ -967,11 +960,7 @@ impl LoadedAuthenticator<'_, T> { Ok(()) } - fn get_data( - &mut self, - container: Container, - mut reply: Reply<'_, R>, - ) -> Result { + fn get_data(&mut self, container: Container, mut reply: Reply<'_>) -> Result { let read_valid = self.state .volatile @@ -1045,7 +1034,7 @@ impl LoadedAuthenticator<'_, T> { Ok(()) } - fn get_key_history_object(&mut self, mut reply: Reply<'_, R>) -> Result { + fn get_key_history_object(&mut self, mut reply: Reply<'_>) -> Result { use state::ContainerStorage; let mut num_certs = 0; @@ -1063,12 +1052,12 @@ impl LoadedAuthenticator<'_, T> { Ok(()) } - fn import_asymmetric_key( + fn import_asymmetric_key( &mut self, algo: AsymmetricAlgorithms, key: AsymmetricKeyReference, #[cfg_attr(not(feature = "rsa"), allow(unused))] data: &[u8], - mut _reply: Reply<'_, R>, + mut _reply: Reply<'_>, ) -> Result { if !self .state diff --git a/src/reply.rs b/src/reply.rs index ebca2a3..33509d8 100644 --- a/src/reply.rs +++ b/src/reply.rs @@ -3,22 +3,22 @@ use iso7816::Status; use core::ops::{Deref, DerefMut}; #[derive(Debug)] -pub struct Reply<'v, const R: usize>(pub &'v mut heapless::Vec); +pub struct Reply<'v>(pub &'v mut heapless::VecView); -impl<'v, const R: usize> Deref for Reply<'v, R> { - type Target = &'v mut heapless::Vec; +impl<'v> Deref for Reply<'v> { + type Target = &'v mut heapless::VecView; fn deref(&self) -> &Self::Target { &self.0 } } -impl DerefMut for Reply<'_, R> { +impl DerefMut for Reply<'_> { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0 } } -impl Reply<'_, R> { +impl Reply<'_> { /// Extend the reply and return an error otherwise /// The MoreAvailable and GET RESPONSE mechanisms are handled by adpu_dispatch /// @@ -82,7 +82,7 @@ impl Reply<'_, R> { }) } - pub fn lend(&mut self) -> Reply<'_, R> { + pub fn lend(&mut self) -> Reply<'_> { Reply(self.0) } } diff --git a/src/state.rs b/src/state.rs index d7567b2..ca6643c 100644 --- a/src/state.rs +++ b/src/state.rs @@ -200,8 +200,8 @@ impl Keys { storage, user_public_key, new.id, - Bytes::from_slice(key.name().as_str().as_bytes()).unwrap(), - Bytes::from_slice(HPKE_SEALKEY_REFERENCE_INFO).unwrap(), + Bytes::try_from(key.name().as_str().as_bytes()).unwrap(), + Bytes::try_from(HPKE_SEALKEY_REFERENCE_INFO).unwrap(), )); KeyOrEncryptedWithAlg::Encrypted(match key { @@ -382,8 +382,8 @@ impl LoadedState<'_> { key.name().into(), options.storage, Location::Volatile, - Bytes::from_slice(key.name().as_str().as_bytes()).unwrap(), - Bytes::from_slice(HPKE_SEALKEY_REFERENCE_INFO).unwrap(), + Bytes::try_from(key.name().as_str().as_bytes()).unwrap(), + Bytes::try_from(HPKE_SEALKEY_REFERENCE_INFO).unwrap(), )) .map_err(|_err| { error!("Failed to unseal key: {_err:?}"); @@ -460,7 +460,7 @@ impl Volatile { client: &mut T, ) -> &'this mut PinVerified { self.clear_pin_verified(client); - let pin = Bytes::from_slice(&value.0).expect("Convertion of static array"); + let pin = Bytes::from(&value.0); let syscall_res = try_syscall!(client.get_pin_key(PinType::UserPin, pin)); let pin_key = match syscall_res { Err(_err) => { @@ -532,8 +532,8 @@ impl Volatile { data_encryption_sealed_key_path, options.storage, Location::Volatile, - Bytes::from_slice(ContainerStorage(container).path_key_str().as_bytes()).unwrap(), - Bytes::from_slice(HPKE_SEALKEY_CONTAINER_INFO).unwrap(), + Bytes::try_from(ContainerStorage(container).path_key_str().as_bytes()).unwrap(), + Bytes::try_from(HPKE_SEALKEY_CONTAINER_INFO).unwrap(), )) else { return Ok(ReadValid::EncryptedNotFound); }; @@ -680,7 +680,7 @@ impl Persistent { value: &Puk, client: &mut T, ) -> Result, Status> { - let puk = Bytes::from_slice(&value.0).expect("Convertion of static array"); + let puk = Bytes::from(&value.0); try_syscall!(client.get_pin_key(PinType::Puk, puk)) .map(|r| r.result) .map_err(|_err| { @@ -695,8 +695,8 @@ impl Persistent { new_value: &Pin, client: &mut T, ) -> bool { - let old_pin = Bytes::from_slice(&old_value.0).expect("Convertion of static array"); - let new_pin = Bytes::from_slice(&new_value.0).expect("Convertion of static array"); + let old_pin = Bytes::from(&old_value.0); + let new_pin = Bytes::from(&new_value.0); try_syscall!(client.change_pin(PinType::UserPin, old_pin, new_pin)) .map(|r| r.success) .unwrap_or(false) @@ -708,8 +708,8 @@ impl Persistent { new_value: &Puk, client: &mut T, ) -> bool { - let old_puk = Bytes::from_slice(&old_value.0).expect("Convertion of static array"); - let new_puk = Bytes::from_slice(&new_value.0).expect("Convertion of static array"); + let old_puk = Bytes::from(&old_value.0); + let new_puk = Bytes::from(&new_value.0); try_syscall!(client.change_pin(PinType::Puk, old_puk, new_puk)) .map(|r| r.success) .unwrap_or(false) @@ -721,7 +721,7 @@ impl Persistent { old_key: KeyId, client: &mut T, ) -> Result<(), Status> { - let new_pin = Bytes::from_slice(&new_pin.0).expect("Convertion of static array"); + let new_pin = Bytes::from(&new_pin.0); try_syscall!(client.set_pin_with_key( PinType::UserPin, new_pin, @@ -740,7 +740,7 @@ impl Persistent { new_puk: Puk, client: &mut T, ) -> Result<(), Status> { - let new_puk = Bytes::from_slice(&new_puk.0).expect("Convertion of static array"); + let new_puk = Bytes::from(&new_puk.0); try_syscall!(client.set_pin(PinType::Puk, new_puk, Some(Self::PUK_RETRIES_DEFAULT), true)) .map_err(|_err| { error!("Failed to set puk"); @@ -858,8 +858,7 @@ impl Persistent { } fn init_pins(client: &mut T, options: &crate::Options) -> Result<(), Status> { - let default_pin = - Bytes::from_slice(&Self::DEFAULT_PIN.0).expect("Convertion of static array"); + let default_pin = Bytes::from(&Self::DEFAULT_PIN.0); try_syscall!(client.set_pin( PinType::UserPin, default_pin.clone(), @@ -870,8 +869,7 @@ impl Persistent { error!("Failed to set pin"); Status::UnspecifiedPersistentExecutionError })?; - let default_puk = - Bytes::from_slice(&Self::DEFAULT_PUK.0).expect("Convertion of static array"); + let default_puk = Bytes::from(&Self::DEFAULT_PUK.0); try_syscall!(client.set_pin( PinType::Puk, default_puk.clone(), @@ -933,7 +931,7 @@ impl Persistent { syscall!(client.write_file( options.storage, PathBuf::from(USER_PUBLIC_KEY), - Bytes::from_slice(&key).unwrap(), + Bytes::try_from(&*key).unwrap(), None )); @@ -1068,11 +1066,11 @@ fn load_if_exists( } /// Returns false if the file does not exist -fn load_if_exists_streaming( +fn load_if_exists_streaming( client: &mut impl crate::Client, location: Location, path: &PathBuf, - mut buffer: Reply<'_, R>, + mut buffer: Reply<'_>, encryption: Option, ) -> Result { let offset = buffer.len(); @@ -1218,11 +1216,11 @@ impl ContainerStorage { } // Write the length of the file and write - pub fn load( + pub fn load( self, client: &mut impl crate::Client, storage: Location, - mut reply: Reply<'_, R>, + mut reply: Reply<'_>, read_valid: ReadValid, ) -> Result { let encryption = match read_valid { @@ -1292,8 +1290,8 @@ impl ContainerStorage { storage, user_public_key, key_to_seal, - Bytes::from_slice(self.path_key_str().as_bytes()).unwrap(), - Bytes::from_slice(HPKE_SEALKEY_CONTAINER_INFO).unwrap(), + Bytes::try_from(self.path_key_str().as_bytes()).unwrap(), + Bytes::try_from(HPKE_SEALKEY_CONTAINER_INFO).unwrap(), )); syscall!(client.delete(user_public_key)); diff --git a/src/virt.rs b/src/virt.rs index 87a57e8..6d1de19 100644 --- a/src/virt.rs +++ b/src/virt.rs @@ -213,23 +213,22 @@ pub mod dispatch { use std::path::PathBuf; use trussed::{ types::Bytes, - virt::{self, Client, Filesystem, Ram, StoreProvider}, + virt::{self, Client, StorageConfig, StoreConfig}, }; /// Client type using a dispatcher with the backends required by opcard -pub type VirtClient = Client; +pub type VirtClient<'a> = Client<'a, dispatch::Dispatch>; /// Run a client using a provided store -pub fn with_client(store: S, client_id: &str, f: F) -> R +pub fn with_client(store: StoreConfig, client_id: &str, f: F) -> R where - F: FnOnce(VirtClient) -> R, - S: StoreProvider, + F: FnOnce(VirtClient<'_>) -> R, { #[allow(clippy::unwrap_used)] virt::with_platform(store, |platform| { platform.run_client_with_backends( client_id, - dispatch::Dispatch::with_hw_key(Bytes::from_slice(b"some bytes").unwrap()), + dispatch::Dispatch::with_hw_key(Bytes::from(b"some bytes")), dispatch::BACKENDS, f, ) @@ -240,17 +239,22 @@ where /// using storage backed by a file pub fn with_fs_client(internal: P, client_id: &str, f: F) -> R where - F: FnOnce(VirtClient) -> R, + F: FnOnce(VirtClient<'_>) -> R, P: Into, { - with_client(Filesystem::new(internal), client_id, f) + let store = StoreConfig { + internal: StorageConfig::filesystem(internal.into()), + external: StorageConfig::ram(), + volatile: StorageConfig::ram(), + }; + with_client(store, client_id, f) } /// Run the backend with the extensions required by opcard /// using a RAM file storage pub fn with_ram_client(client_id: &str, f: F) -> R where - F: FnOnce(VirtClient) -> R, + F: FnOnce(VirtClient<'_>) -> R, { - with_client(Ram::default(), client_id, f) + with_client(StoreConfig::ram(), client_id, f) } diff --git a/src/vpicc.rs b/src/vpicc.rs index 63ff199..781174a 100644 --- a/src/vpicc.rs +++ b/src/vpicc.rs @@ -1,5 +1,4 @@ use iso7816::{command::FromSliceError, Command, Status}; -use trussed::virt::Ram; use crate::virt::VirtClient; @@ -14,15 +13,15 @@ const RESPONSE_LEN: usize = 7609; /// /// This struct provides a vpicc PIV smart card implementation that can be used with /// `vpicc-rs` and [`vsmartcard`](https://frankmorgner.github.io/vsmartcard/) to emulate the card. -pub struct VpiccCard { +pub struct VpiccCard<'a> { request_buffer: RequestBuffer, response_buffer: ResponseBuffer, - card: Authenticator>, + card: Authenticator>, } -impl VpiccCard { +impl<'a> VpiccCard<'a> { /// Creates a new virtual smart card from the given card. - pub fn new(card: Authenticator>) -> Self { + pub fn new(card: Authenticator>) -> Self { Self { request_buffer: Default::default(), response_buffer: Default::default(), @@ -46,7 +45,7 @@ impl VpiccCard { } } -impl vpicc::VSmartCard for VpiccCard { +impl vpicc::VSmartCard for VpiccCard<'_> { fn power_on(&mut self) {} fn power_off(&mut self) { diff --git a/tests/setup/mod.rs b/tests/setup/mod.rs index 875f8a8..9cf26aa 100644 --- a/tests/setup/mod.rs +++ b/tests/setup/mod.rs @@ -12,13 +12,12 @@ use piv_authenticator::{ virt::{with_ram_client, VirtClient}, Authenticator, Options, }; -use trussed::virt::Ram; -pub type Piv = piv_authenticator::Authenticator>; +pub type Piv<'a> = piv_authenticator::Authenticator>; pub const WITHOUT_UUID: Options = Options::new(); -pub fn piv(options: Options, test: impl FnOnce(&mut Piv) -> R) -> R { +pub fn piv(options: Options, test: impl FnOnce(&mut Piv<'_>) -> R) -> R { with_ram_client("test", |client| { let mut piv_app = Authenticator::new(client, options); test(&mut piv_app)