mirror of
https://github.com/trussed-dev/piv-authenticator.git
synced 2026-06-20 04:16:15 -07:00
Add reading of large data objects
This commit is contained in:
+1
-1
@@ -74,7 +74,7 @@ log-warn = []
|
||||
log-error = []
|
||||
|
||||
[patch.crates-io]
|
||||
trussed = { git = "https://github.com/Nitrokey/trussed", tag = "v0.1.0-nitrokey.8"}
|
||||
trussed = { git = "https://github.com/sosthene-nitrokey/trussed", rev = "25ae084251b76bacfa8919eb8"}
|
||||
trussed-auth = { git = "https://github.com/trussed-dev/trussed-auth", tag = "v0.2.1"}
|
||||
littlefs2 = { git = "https://github.com/Nitrokey/littlefs2", tag = "v0.3.2-nitrokey-2" }
|
||||
|
||||
|
||||
+9
-4
@@ -910,10 +910,15 @@ impl<'a, T: trussed::Client + AuthClient + trussed::client::Ed255> LoadedAuthent
|
||||
let offset = reply.len();
|
||||
match container {
|
||||
Container::KeyHistoryObject => self.get_key_history_object(reply.lend())?,
|
||||
_ => match ContainerStorage(container).load(self.trussed, self.options.storage)? {
|
||||
Some(data) => reply.expand(&data)?,
|
||||
None => return Err(Status::NotFound),
|
||||
},
|
||||
_ => {
|
||||
if !ContainerStorage(container).load(
|
||||
self.trussed,
|
||||
self.options.storage,
|
||||
reply.lend(),
|
||||
)? {
|
||||
return Err(Status::NotFound);
|
||||
}
|
||||
}
|
||||
}
|
||||
reply.prepend_len(offset)?;
|
||||
|
||||
|
||||
+62
-4
@@ -8,6 +8,7 @@ use flexiber::EncodableHeapless;
|
||||
use heapless::Vec;
|
||||
use heapless_bytes::Bytes;
|
||||
use iso7816::Status;
|
||||
use trussed::types::OpenSeekFrom;
|
||||
use trussed::{
|
||||
api::reply::Metadata,
|
||||
config::MAX_MESSAGE_LENGTH,
|
||||
@@ -17,6 +18,7 @@ use trussed::{
|
||||
use trussed_auth::AuthClient;
|
||||
|
||||
use crate::piv_types::CardHolderUniqueIdentifier;
|
||||
use crate::reply::Reply;
|
||||
use crate::{constants::*, piv_types::AsymmetricAlgorithms};
|
||||
use crate::{
|
||||
container::{AsymmetricKeyReference, Container, ReadAccessRule, SecurityCondition},
|
||||
@@ -617,6 +619,53 @@ fn load_if_exists(
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns false if the file does not exist
|
||||
fn load_if_exists_streaming<const R: usize>(
|
||||
client: &mut impl trussed::Client,
|
||||
location: Location,
|
||||
path: &PathBuf,
|
||||
mut buffer: Reply<'_, R>,
|
||||
) -> Result<bool, Status> {
|
||||
let mut read_len = 0;
|
||||
let file_len;
|
||||
match try_syscall!(client.read_file_chunk(location, path.clone(), OpenSeekFrom::Start(0))) {
|
||||
Ok(r) => {
|
||||
read_len += r.data.len();
|
||||
file_len = r.len;
|
||||
buffer.expand(&r.data)?;
|
||||
}
|
||||
Err(_) => match try_syscall!(client.entry_metadata(location, path.clone())) {
|
||||
Ok(Metadata { metadata: None }) => return Ok(false),
|
||||
Ok(Metadata {
|
||||
metadata: Some(_metadata),
|
||||
}) => {
|
||||
error!("File {path} exists but couldn't be read: {_metadata:?}");
|
||||
return Err(Status::UnspecifiedPersistentExecutionError);
|
||||
}
|
||||
Err(_err) => {
|
||||
error!("File {path} couldn't be read: {_err:?}");
|
||||
return Err(Status::UnspecifiedPersistentExecutionError);
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
while read_len < file_len {
|
||||
match try_syscall!(client.read_file_chunk(
|
||||
location,
|
||||
path.clone(),
|
||||
OpenSeekFrom::Start(read_len as u32)
|
||||
)) {
|
||||
Ok(r) => {
|
||||
read_len += r.data.len();
|
||||
buffer.expand(&r.data)?;
|
||||
}
|
||||
Err(_err) => error!("Failed to read chunk: {:?}", _err),
|
||||
}
|
||||
}
|
||||
|
||||
Ok(true)
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct ContainerStorage(pub Container);
|
||||
|
||||
@@ -703,13 +752,22 @@ impl ContainerStorage {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn load(
|
||||
pub fn load<const R: usize>(
|
||||
self,
|
||||
client: &mut impl trussed::Client,
|
||||
storage: Location,
|
||||
) -> Result<Option<Bytes<MAX_MESSAGE_LENGTH>>, Status> {
|
||||
load_if_exists(client, storage, &self.path())
|
||||
.map(|data| data.or_else(|| self.default().map(Bytes::from)))
|
||||
mut reply: Reply<'_, R>,
|
||||
) -> Result<bool, Status> {
|
||||
if load_if_exists_streaming(client, storage, &self.path(), reply.lend())? {
|
||||
return Ok(true);
|
||||
}
|
||||
|
||||
if let Some(data) = self.default() {
|
||||
reply.expand(&data)?;
|
||||
Ok(true)
|
||||
} else {
|
||||
Ok(false)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn save(
|
||||
|
||||
Reference in New Issue
Block a user