move MAX_MSG_SIZE to customization and use it in HID (#302)

This commit is contained in:
kaczmarczyck
2021-04-09 07:40:11 +02:00
committed by GitHub
parent 6216a3214d
commit 054e303d11
5 changed files with 30 additions and 15 deletions

View File

@@ -119,6 +119,15 @@ pub const ENTERPRISE_ATTESTATION_MODE: Option<EnterpriseAttestationMode> = None;
/// VendorFacilitated. /// VendorFacilitated.
pub const ENTERPRISE_RP_ID_LIST: &[&str] = &[]; pub const ENTERPRISE_RP_ID_LIST: &[&str] = &[];
/// Maximum message size send for CTAP commands.
///
/// The maximum value is 7609, as HID packets can not encode longer messages.
/// 1024 is the default mentioned in the authenticatorLargeBlobs commands.
/// Larger values are preferred, as that allows more parameters in commands.
/// If long commands are too unreliable on your hardware, consider decreasing
/// this value.
pub const MAX_MSG_SIZE: usize = 7609;
/// Sets the number of consecutive failed PINs before blocking interaction. /// Sets the number of consecutive failed PINs before blocking interaction.
/// ///
/// # Invariant /// # Invariant
@@ -256,6 +265,8 @@ mod test {
} else { } else {
assert!(ENTERPRISE_RP_ID_LIST.is_empty()); assert!(ENTERPRISE_RP_ID_LIST.is_empty());
} }
assert!(MAX_MSG_SIZE >= 1024);
assert!(MAX_MSG_SIZE <= 7609);
assert!(MAX_PIN_RETRIES <= 8); assert!(MAX_PIN_RETRIES <= 8);
assert!(MAX_CRED_BLOB_LENGTH >= 32); assert!(MAX_CRED_BLOB_LENGTH >= 32);
if let Some(count) = MAX_CREDENTIAL_COUNT_IN_LIST { if let Some(count) = MAX_CREDENTIAL_COUNT_IN_LIST {

View File

@@ -322,6 +322,9 @@ impl CtapHid {
receive::Error::UnexpectedSeq => { receive::Error::UnexpectedSeq => {
CtapHid::error_message(cid, CtapHid::ERR_INVALID_SEQ) CtapHid::error_message(cid, CtapHid::ERR_INVALID_SEQ)
} }
receive::Error::UnexpectedLen => {
CtapHid::error_message(cid, CtapHid::ERR_INVALID_LEN)
}
receive::Error::Timeout => { receive::Error::Timeout => {
CtapHid::error_message(cid, CtapHid::ERR_MSG_TIMEOUT) CtapHid::error_message(cid, CtapHid::ERR_MSG_TIMEOUT)
} }

View File

@@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
use super::super::customization::MAX_MSG_SIZE;
use super::{ChannelID, CtapHid, HidPacket, Message, ProcessedPacket}; use super::{ChannelID, CtapHid, HidPacket, Message, ProcessedPacket};
use alloc::vec::Vec; use alloc::vec::Vec;
use core::mem::swap; use core::mem::swap;
@@ -45,6 +46,8 @@ pub enum Error {
UnexpectedContinuation, UnexpectedContinuation,
// Expected a continuation packet with a specific sequence number, got another sequence number. // Expected a continuation packet with a specific sequence number, got another sequence number.
UnexpectedSeq, UnexpectedSeq,
// The length of a message is too big.
UnexpectedLen,
// This packet arrived after a timeout. // This packet arrived after a timeout.
Timeout, Timeout,
} }
@@ -107,7 +110,7 @@ impl MessageAssembler {
// Expecting an initialization packet. // Expecting an initialization packet.
match processed_packet { match processed_packet {
ProcessedPacket::InitPacket { cmd, len, data } => { ProcessedPacket::InitPacket { cmd, len, data } => {
Ok(self.accept_init_packet(*cid, cmd, len, data, timestamp)) self.parse_init_packet(*cid, cmd, len, data, timestamp)
} }
ProcessedPacket::ContinuationPacket { .. } => { ProcessedPacket::ContinuationPacket { .. } => {
// CTAP specification (version 20190130) section 8.1.5.4 // CTAP specification (version 20190130) section 8.1.5.4
@@ -129,7 +132,7 @@ impl MessageAssembler {
ProcessedPacket::InitPacket { cmd, len, data } => { ProcessedPacket::InitPacket { cmd, len, data } => {
self.reset(); self.reset();
if cmd == CtapHid::COMMAND_INIT { if cmd == CtapHid::COMMAND_INIT {
Ok(self.accept_init_packet(*cid, cmd, len, data, timestamp)) self.parse_init_packet(*cid, cmd, len, data, timestamp)
} else { } else {
Err((*cid, Error::UnexpectedInit)) Err((*cid, Error::UnexpectedInit))
} }
@@ -151,24 +154,25 @@ impl MessageAssembler {
} }
} }
fn accept_init_packet( fn parse_init_packet(
&mut self, &mut self,
cid: ChannelID, cid: ChannelID,
cmd: u8, cmd: u8,
len: usize, len: usize,
data: &[u8], data: &[u8],
timestamp: Timestamp<isize>, timestamp: Timestamp<isize>,
) -> Option<Message> { ) -> Result<Option<Message>, (ChannelID, Error)> {
// TODO: Should invalid commands/payload lengths be rejected early, i.e. as soon as the // Reject invalid lengths early to reduce the risk of running out of memory.
// initialization packet is received, or should we build a message and then catch the // TODO: also reject invalid commands early?
// error? if len > MAX_MSG_SIZE {
// The specification (version 20190130) isn't clear on this point. return Err((cid, Error::UnexpectedLen));
}
self.cid = cid; self.cid = cid;
self.last_timestamp = timestamp; self.last_timestamp = timestamp;
self.cmd = cmd; self.cmd = cmd;
self.seq = 0; self.seq = 0;
self.remaining_payload_len = len; self.remaining_payload_len = len;
self.append_payload(data) Ok(self.append_payload(data))
} }
fn append_payload(&mut self, data: &[u8]) -> Option<Message> { fn append_payload(&mut self, data: &[u8]) -> Option<Message> {

View File

@@ -14,6 +14,7 @@
use super::client_pin::{ClientPin, PinPermission}; use super::client_pin::{ClientPin, PinPermission};
use super::command::AuthenticatorLargeBlobsParameters; use super::command::AuthenticatorLargeBlobsParameters;
use super::customization::MAX_MSG_SIZE;
use super::response::{AuthenticatorLargeBlobsResponse, ResponseData}; use super::response::{AuthenticatorLargeBlobsResponse, ResponseData};
use super::status_code::Ctap2StatusCode; use super::status_code::Ctap2StatusCode;
use super::storage::PersistentStore; use super::storage::PersistentStore;
@@ -23,10 +24,6 @@ use byteorder::{ByteOrder, LittleEndian};
use crypto::sha256::Sha256; use crypto::sha256::Sha256;
use crypto::Hash256; use crypto::Hash256;
/// This is maximum message size supported by the authenticator. 1024 is the default.
/// Increasing this values can speed up commands with longer responses, but lead to
/// packets dropping or unexpected failures.
pub const MAX_MSG_SIZE: usize = 1024;
/// The length of the truncated hash that as appended to the large blob data. /// The length of the truncated hash that as appended to the large blob data.
const TRUNCATED_HASH_LEN: usize = 16; const TRUNCATED_HASH_LEN: usize = 16;

View File

@@ -42,7 +42,7 @@ use self::credential_management::process_credential_management;
use self::crypto_wrapper::{aes256_cbc_decrypt, aes256_cbc_encrypt}; use self::crypto_wrapper::{aes256_cbc_decrypt, aes256_cbc_encrypt};
use self::customization::{ use self::customization::{
DEFAULT_CRED_PROTECT, ENTERPRISE_ATTESTATION_MODE, ENTERPRISE_RP_ID_LIST, DEFAULT_CRED_PROTECT, ENTERPRISE_ATTESTATION_MODE, ENTERPRISE_RP_ID_LIST,
MAX_CREDENTIAL_COUNT_IN_LIST, MAX_CRED_BLOB_LENGTH, MAX_LARGE_BLOB_ARRAY_SIZE, MAX_CREDENTIAL_COUNT_IN_LIST, MAX_CRED_BLOB_LENGTH, MAX_LARGE_BLOB_ARRAY_SIZE, MAX_MSG_SIZE,
MAX_RP_IDS_LENGTH, USE_BATCH_ATTESTATION, USE_SIGNATURE_COUNTER, MAX_RP_IDS_LENGTH, USE_BATCH_ATTESTATION, USE_SIGNATURE_COUNTER,
}; };
use self::data_formats::{ use self::data_formats::{
@@ -52,7 +52,7 @@ use self::data_formats::{
PublicKeyCredentialType, PublicKeyCredentialUserEntity, SignatureAlgorithm, PublicKeyCredentialType, PublicKeyCredentialUserEntity, SignatureAlgorithm,
}; };
use self::hid::ChannelID; use self::hid::ChannelID;
use self::large_blobs::{LargeBlobs, MAX_MSG_SIZE}; use self::large_blobs::LargeBlobs;
use self::response::{ use self::response::{
AuthenticatorGetAssertionResponse, AuthenticatorGetInfoResponse, AuthenticatorGetAssertionResponse, AuthenticatorGetInfoResponse,
AuthenticatorMakeCredentialResponse, AuthenticatorVendorResponse, ResponseData, AuthenticatorMakeCredentialResponse, AuthenticatorVendorResponse, ResponseData,