Skip to content

Commit

Permalink
Addresses comments with different parameter typing
Browse files Browse the repository at this point in the history
  • Loading branch information
kaczmarczyck committed Apr 8, 2024
1 parent 87be49e commit 3fd77a9
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 27 deletions.
26 changes: 14 additions & 12 deletions libraries/opensk/src/api/persist.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use crate::api::crypto::EC_FIELD_SIZE;
use crate::ctap::secret::Secret;
use crate::ctap::status_code::{Ctap2StatusCode, CtapResult};
use crate::ctap::PIN_AUTH_LENGTH;
use alloc::borrow::Cow;
use alloc::boxed::Box;
use alloc::vec::Vec;
use core::cmp;
Expand All @@ -27,6 +28,7 @@ use enum_iterator::IntoEnumIterator;

pub type PersistIter<'a> = Box<dyn Iterator<Item = CtapResult<usize>> + 'a>;
pub type PersistCredentialIter<'a> = Box<dyn Iterator<Item = CtapResult<(usize, Vec<u8>)>> + 'a>;
pub type LargeBlobBuffer = Vec<u8>;

/// Stores data that persists across reboots.
///
Expand Down Expand Up @@ -235,7 +237,7 @@ pub trait Persist {
/// Prepares writing a new large blob.
///
/// Returns a buffer that is returned to other API calls for potential usage.
fn init_large_blob(&mut self, expected_length: usize) -> CtapResult<Vec<u8>> {
fn init_large_blob(&mut self, expected_length: usize) -> CtapResult<LargeBlobBuffer> {
Ok(Vec::with_capacity(expected_length))
}

Expand All @@ -245,14 +247,14 @@ pub trait Persist {
fn write_large_blob_chunk(
&mut self,
offset: usize,
chunk: &mut Vec<u8>,
buffer: &mut Vec<u8>,
chunk: &[u8],
buffer: &mut LargeBlobBuffer,
) -> CtapResult<()> {
if buffer.len() != offset {
// This should be caught on CTAP level.
return Err(Ctap2StatusCode::CTAP2_ERR_VENDOR_INTERNAL_ERROR);
}
buffer.append(chunk);
buffer.extend_from_slice(chunk);
Ok(())
}

Expand All @@ -262,17 +264,17 @@ pub trait Persist {
/// available. This includes cases of offset being beyond the stored array.
///
/// The buffer is passed in when writing is in process.
fn get_large_blob(
&self,
fn get_large_blob<'a>(
&'a self,
mut offset: usize,
byte_count: usize,
buffer: Option<&Vec<u8>>,
) -> CtapResult<Option<Vec<u8>>> {
buffer: Option<&'a LargeBlobBuffer>,
) -> CtapResult<Option<Cow<[u8]>>> {
if let Some(buffer) = buffer {
let start = cmp::min(offset, buffer.len());
let end = offset.saturating_add(byte_count);
let end = cmp::min(end, buffer.len());
return Ok(Some(buffer[start..end].to_vec()));
return Ok(Some(Cow::from(&buffer[start..end])));
}
let mut result = Vec::with_capacity(byte_count);
for key in keys::LARGE_BLOB_SHARDS {
Expand All @@ -288,16 +290,16 @@ pub trait Persist {
}
let end = cmp::min(end, value.len());
if end < offset {
return Ok(Some(result));
return Ok(Some(Cow::from(result)));
}
result.extend(&value[offset..end]);
offset = offset.saturating_sub(VALUE_LENGTH);
}
Ok(Some(result))
Ok(Some(Cow::from(result)))
}

/// Sets a byte vector as the serialized large blobs array.
fn commit_large_blob_array(&mut self, buffer: &Vec<u8>) -> CtapResult<()> {
fn commit_large_blob_array(&mut self, buffer: &LargeBlobBuffer) -> CtapResult<()> {
debug_assert!(buffer.len() <= keys::LARGE_BLOB_SHARDS.len() * VALUE_LENGTH);
let mut offset = 0;
for key in keys::LARGE_BLOB_SHARDS {
Expand Down
31 changes: 17 additions & 14 deletions libraries/opensk/src/ctap/large_blobs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ impl LargeBlobState {
)));
}

if let Some(mut set) = set {
if let Some(set) = set {
if set.len() > max_fragment_size {
return Err(Ctap2StatusCode::CTAP1_ERR_INVALID_LENGTH);
}
Expand Down Expand Up @@ -112,7 +112,7 @@ impl LargeBlobState {
}
let received_length = set.len();
env.persist()
.write_large_blob_chunk(offset, &mut set, &mut self.buffer)?;
.write_large_blob_chunk(offset, &set, &mut self.buffer)?;
self.expected_next_offset += received_length;
if self.expected_next_offset == self.expected_length {
const CHUNK_SIZE: usize = 1024;
Expand All @@ -132,7 +132,7 @@ impl LargeBlobState {
.persist()
.get_large_blob(buffer_hash_index, TRUNCATED_HASH_LEN, Some(&self.buffer))?
.ok_or(Ctap2StatusCode::CTAP2_ERR_VENDOR_INTERNAL_ERROR)?;
if computed_hash[..TRUNCATED_HASH_LEN] != written_hash {
if computed_hash[..TRUNCATED_HASH_LEN] != written_hash[..] {
return Err(Ctap2StatusCode::CTAP2_ERR_INTEGRITY_FAILURE);
}
env.persist().commit_large_blob_array(&self.buffer)?;
Expand Down Expand Up @@ -163,17 +163,20 @@ fn get_large_blob_array(
byte_count: usize,
) -> CtapResult<Vec<u8>> {
let output = env.persist().get_large_blob(offset, byte_count, None)?;
Ok(output.unwrap_or_else(|| {
const EMPTY_LARGE_BLOB: [u8; 17] = [
0x80, 0x76, 0xBE, 0x8B, 0x52, 0x8D, 0x00, 0x75, 0xF7, 0xAA, 0xE9, 0x8D, 0x6F, 0xA5,
0x7A, 0x6D, 0x3C,
];
let last_index = cmp::min(EMPTY_LARGE_BLOB.len(), offset.saturating_add(byte_count));
EMPTY_LARGE_BLOB
.get(offset..last_index)
.unwrap_or_default()
.to_vec()
}))
Ok(match output {
Some(data) => data.into(),
None => {
const EMPTY_LARGE_BLOB: [u8; 17] = [
0x80, 0x76, 0xBE, 0x8B, 0x52, 0x8D, 0x00, 0x75, 0xF7, 0xAA, 0xE9, 0x8D, 0x6F, 0xA5,
0x7A, 0x6D, 0x3C,
];
let last_index = cmp::min(EMPTY_LARGE_BLOB.len(), offset.saturating_add(byte_count));
EMPTY_LARGE_BLOB
.get(offset..last_index)
.unwrap_or_default()
.to_vec()
}
})
}

#[cfg(test)]
Expand Down
2 changes: 1 addition & 1 deletion libraries/opensk/src/ctap/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -561,7 +561,7 @@ impl<E: Env> StatefulPermission<E> {
channel,
);
}
if let Some(StatefulCommand::LargeBlob(ref mut large_blob_state)) = &mut self.command_type {
if let Some(StatefulCommand::LargeBlob(large_blob_state)) = &mut self.command_type {
large_blob_state
} else {
unreachable!();
Expand Down

0 comments on commit 3fd77a9

Please sign in to comment.