Skip to content

Commit 43c0cf1

Browse files
msirringhausjschanck
authored andcommitted
Address feedback
1 parent d62d602 commit 43c0cf1

File tree

1 file changed

+29
-10
lines changed

1 file changed

+29
-10
lines changed

src/ctap2/commands/large_blobs.rs

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::{
22
crypto::{PinUvAuthParam, PinUvAuthToken},
33
ctap2::server::UserVerificationRequirement,
4-
errors::AuthenticatorError,
4+
errors::{AuthenticatorError, UnsupportedOption},
55
transport::errors::HIDError,
66
FidoDevice,
77
};
@@ -69,6 +69,10 @@ impl PinUvAuthCommand for LargeBlobs {
6969
fn get_rp_id(&self) -> Option<&String> {
7070
None
7171
}
72+
73+
fn hmac_requested(&self) -> bool {
74+
false
75+
}
7276
}
7377

7478
impl Serialize for LargeBlobs {
@@ -132,16 +136,17 @@ impl RequestCtap2 for LargeBlobs {
132136
}
133137

134138
let status: StatusCode = input[0].into();
135-
let payload = &input[1..];
136139
if status.is_ok() {
137-
if payload.len() > 1 {
140+
if input.len() > 1 {
141+
let payload = &input[1..];
138142
Ok(payload.to_vec())
139143
} else {
140144
// Some subcommands return only an OK-status without any data
141145
Ok(Vec::new())
142146
}
143147
} else {
144148
let data: Option<Value> = if input.len() > 1 {
149+
let payload = &input[1..];
145150
Some(from_slice(payload).map_err(CommandError::Deserializing)?)
146151
} else {
147152
None
@@ -314,7 +319,7 @@ impl<'de> Deserialize<'de> for LargeBlobsResponse {
314319

315320
let byte_len = large_blob.len() as u64;
316321
let large_blob_array: Vec<LargeBlobArrayElement> =
317-
from_slice(large_blob).unwrap();
322+
from_slice(large_blob).map_err(M::Error::custom)?;
318323
let mut hash = [0u8; 16];
319324
hash.copy_from_slice(hash_slice);
320325
response = Some(LargeBlobsResponse {
@@ -354,11 +359,18 @@ where
354359
// Spec:
355360
// A per-authenticator constant, maxFragmentLength, is here defined as the value of maxMsgSize (from the authenticatorGetInfo response) minus 64.
356361
// If no maxMsgSize is given in the authenticatorGetInfo response) then it defaults to 1024, leaving maxFragmentLength to default to 960.
357-
let max_fragment_length = dev
362+
//
363+
// In the highly unlikely case of a max_msg_size smaller than 65 (leaving zero-byte fragment-length), we error out, saying that largeBlobs is unsupported.
364+
let max_msg_size = dev
358365
.get_authenticator_info()
359366
.and_then(|i| i.max_msg_size)
360-
.unwrap_or(1024)
361-
- 64;
367+
.unwrap_or(1024);
368+
if max_msg_size <= 64 {
369+
return Err(AuthenticatorError::UnsupportedOption(
370+
UnsupportedOption::LargeBlobs,
371+
));
372+
}
373+
let max_fragment_length = max_msg_size - 64;
362374
let mut bytes = vec![];
363375
let mut offset = 0;
364376
loop {
@@ -404,11 +416,18 @@ where
404416
// Spec:
405417
// A per-authenticator constant, maxFragmentLength, is here defined as the value of maxMsgSize (from the authenticatorGetInfo response) minus 64.
406418
// If no maxMsgSize is given in the authenticatorGetInfo response) then it defaults to 1024, leaving maxFragmentLength to default to 960.
407-
let max_fragment_length = dev
419+
//
420+
// In the highly unlikely case of a max_msg_size smaller than 65 (leaving zero-byte fragment-length), we error out, saying that largeBlobs is unsupported.
421+
let max_msg_size = dev
408422
.get_authenticator_info()
409423
.and_then(|i| i.max_msg_size)
410-
.unwrap_or(1024)
411-
- 64;
424+
.unwrap_or(1024);
425+
if max_msg_size <= 64 {
426+
return Err(AuthenticatorError::UnsupportedOption(
427+
UnsupportedOption::LargeBlobs,
428+
));
429+
}
430+
let max_fragment_length = max_msg_size - 64;
412431
let total_length = bytes.len();
413432
let mut offset = initial_offset;
414433
for chunk in bytes.chunks(max_fragment_length) {

0 commit comments

Comments
 (0)