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.
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.
///
/// # Invariant
@@ -256,6 +265,8 @@ mod test {
} else {
assert!(ENTERPRISE_RP_ID_LIST.is_empty());
}
assert!(MAX_MSG_SIZE >= 1024);
assert!(MAX_MSG_SIZE <= 7609);
assert!(MAX_PIN_RETRIES <= 8);
assert!(MAX_CRED_BLOB_LENGTH >= 32);
if let Some(count) = MAX_CREDENTIAL_COUNT_IN_LIST {

View File

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

View File

@@ -14,6 +14,7 @@
use super::client_pin::{ClientPin, PinPermission};
use super::command::AuthenticatorLargeBlobsParameters;
use super::customization::MAX_MSG_SIZE;
use super::response::{AuthenticatorLargeBlobsResponse, ResponseData};
use super::status_code::Ctap2StatusCode;
use super::storage::PersistentStore;
@@ -23,10 +24,6 @@ use byteorder::{ByteOrder, LittleEndian};
use crypto::sha256::Sha256;
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.
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::customization::{
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,
};
use self::data_formats::{
@@ -52,7 +52,7 @@ use self::data_formats::{
PublicKeyCredentialType, PublicKeyCredentialUserEntity, SignatureAlgorithm,
};
use self::hid::ChannelID;
use self::large_blobs::{LargeBlobs, MAX_MSG_SIZE};
use self::large_blobs::LargeBlobs;
use self::response::{
AuthenticatorGetAssertionResponse, AuthenticatorGetInfoResponse,
AuthenticatorMakeCredentialResponse, AuthenticatorVendorResponse, ResponseData,