move MAX_MSG_SIZE to customization and use it in HID (#302)
This commit is contained in:
@@ -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 {
|
||||||
|
|||||||
@@ -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)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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> {
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
Reference in New Issue
Block a user