diff --git a/Cargo.toml b/Cargo.toml index e3a43cf..70480db 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,6 +11,7 @@ repository = "https://github.com/trussed-dev/ctap-types" arbitrary = { version = "1.3.2", features = ["derive"], optional = true } bitflags = "1.3" cbor-smol = { version = "0.5", features = ["heapless-bytes-v0-3"] } +cfg-if = "1.0" cosey = "0.3.1" delog = "0.1" heapless = { version = "0.7", default-features = false, features = ["serde"] } @@ -36,6 +37,10 @@ get-info-full = [] large-blobs = [] third-party-payment = [] +backend-dilithium2 = [] +backend-dilithium3 = [] +backend-dilithium5 = [] + log-all = [] log-none = [] log-info = [] diff --git a/src/ctap1.rs b/src/ctap1.rs index 0fc6153..dd6216c 100644 --- a/src/ctap1.rs +++ b/src/ctap1.rs @@ -30,6 +30,7 @@ pub mod authenticate { pub mod register { use super::Bytes; + use crate::sizes::{MAX_CREDENTIAL_ID_LENGTH, MAX_MESSAGE_LENGTH}; #[derive(Clone, Debug, Eq, PartialEq)] pub struct Request<'a> { @@ -41,8 +42,8 @@ pub mod register { pub struct Response { pub header_byte: u8, pub public_key: Bytes<65>, - pub key_handle: Bytes<255>, - pub attestation_certificate: Bytes<1024>, + pub key_handle: Bytes, + pub attestation_certificate: Bytes, pub signature: Bytes<72>, } @@ -50,9 +51,9 @@ pub mod register { pub fn new( header_byte: u8, public_key: &cosey::EcdhEsHkdf256PublicKey, - key_handle: Bytes<255>, + key_handle: Bytes, signature: Bytes<72>, - attestation_certificate: Bytes<1024>, + attestation_certificate: Bytes, ) -> Self { let mut public_key_bytes = Bytes::new(); public_key_bytes.push(0x04).unwrap(); diff --git a/src/ctap2.rs b/src/ctap2.rs index 8136be2..efc70d2 100644 --- a/src/ctap2.rs +++ b/src/ctap2.rs @@ -6,6 +6,7 @@ use bitflags::bitflags; use cbor_smol::cbor_deserialize; use serde::{Deserialize, Serialize}; +use crate::sizes::MAX_MESSAGE_LENGTH; use crate::{sizes::*, Bytes, TryFromStrError, Vec}; pub use crate::operation::{Operation, VendorOperation}; @@ -301,7 +302,7 @@ pub struct PackedAttestationStatement { pub alg: i32, pub sig: Bytes, #[serde(skip_serializing_if = "Option::is_none")] - pub x5c: Option, 1>>, + pub x5c: Option, 1>>, } #[derive(Clone, Debug, Default, Eq, PartialEq)] diff --git a/src/sizes.rs b/src/sizes.rs index 3f36595..68395dd 100644 --- a/src/sizes.rs +++ b/src/sizes.rs @@ -1,13 +1,10 @@ -pub const AUTHENTICATOR_DATA_LENGTH: usize = 676; // pub const AUTHENTICATOR_DATA_LENGTH_BYTES: usize = 512; -pub const ASN1_SIGNATURE_LENGTH: usize = 77; // pub const ASN1_SIGNATURE_LENGTH_BYTES: usize = 72; pub const COSE_KEY_LENGTH: usize = 256; // pub const COSE_KEY_LENGTH_BYTES: usize = 256; -pub const MAX_CREDENTIAL_ID_LENGTH: usize = 255; pub const MAX_CREDENTIAL_ID_LENGTH_PLUS_256: usize = 767; pub const MAX_CREDENTIAL_COUNT_IN_LIST: usize = 10; @@ -30,3 +27,30 @@ pub const THEORETICAL_MAX_MESSAGE_SIZE: usize = PACKET_SIZE - 7 + 128 * (PACKET_ pub const LARGE_BLOB_MAX_FRAGMENT_LENGTH: usize = 0; #[cfg(feature = "large-blobs")] pub const LARGE_BLOB_MAX_FRAGMENT_LENGTH: usize = 3008; + +// TODO: update these, and grab them from a common crate? +cfg_if::cfg_if! { + if #[cfg(feature = "backend-dilithium5")] { + pub const MAX_MESSAGE_LENGTH: usize = MAX_COMMITTMENT_LENGTH; + pub const MAX_CREDENTIAL_ID_LENGTH: usize = 7523 + 57 + 30 + 37; + pub const AUTHENTICATOR_DATA_LENGTH: usize = MAX_CREDENTIAL_ID_LENGTH + 2031; // TODO: this will have to be larger + pub const ASN1_SIGNATURE_LENGTH: usize = 4627; + } else if #[cfg(feature = "backend-dilithium3")] { + pub const MAX_MESSAGE_LENGTH: usize = MAX_COMMITTMENT_LENGTH; + pub const MAX_CREDENTIAL_ID_LENGTH: usize = 6019 + 57 + 30 + 37; + pub const AUTHENTICATOR_DATA_LENGTH: usize = MAX_CREDENTIAL_ID_LENGTH + 2031; + pub const ASN1_SIGNATURE_LENGTH: usize = 3309; + } else if #[cfg(feature = "backend-dilithium2")] { + pub const MAX_MESSAGE_LENGTH: usize = MAX_COMMITTMENT_LENGTH; + pub const MAX_CREDENTIAL_ID_LENGTH: usize = 3907 + 57 + 30 + 37; + pub const AUTHENTICATOR_DATA_LENGTH: usize = MAX_CREDENTIAL_ID_LENGTH + 2031; // TODO: this can be smaller + pub const ASN1_SIGNATURE_LENGTH: usize = 2420; + } else { + pub const MAX_MESSAGE_LENGTH: usize = 1024; + pub const MAX_CREDENTIAL_ID_LENGTH: usize = 255; + pub const AUTHENTICATOR_DATA_LENGTH: usize = 676; + pub const ASN1_SIGNATURE_LENGTH: usize = 77; + } +} + +pub const MAX_COMMITTMENT_LENGTH: usize = AUTHENTICATOR_DATA_LENGTH + 32; diff --git a/src/webauthn.rs b/src/webauthn.rs index 48d4dc6..072b929 100644 --- a/src/webauthn.rs +++ b/src/webauthn.rs @@ -158,9 +158,40 @@ pub enum UnknownPKCredentialParam { pub const ES256: i32 = -7; /// EdDSA pub const ED_DSA: i32 = -8; - -pub const COUNT_KNOWN_ALGS: usize = 2; -pub const KNOWN_ALGS: [i32; COUNT_KNOWN_ALGS] = [ES256, ED_DSA]; +/// Dilithium2 +#[cfg(feature = "backend-dilithium2")] +pub const DILITHIUM2: i32 = -87; +#[cfg(feature = "backend-dilithium3")] +pub const DILITHIUM3: i32 = -88; +#[cfg(feature = "backend-dilithium5")] +pub const DILITHIUM5: i32 = -89; + +// Dynamically calculate the number of different known algorithms +pub const COUNT_KNOWN_ALGS: usize = + 2 + (if cfg!(feature = "backend-dilithium2") { + 1 + } else { + 0 + }) + (if cfg!(feature = "backend-dilithium3") { + 1 + } else { + 0 + }) + (if cfg!(feature = "backend-dilithium5") { + 1 + } else { + 0 + }); + +pub const KNOWN_ALGS: [i32; COUNT_KNOWN_ALGS] = [ + ES256, + ED_DSA, + #[cfg(feature = "backend-dilithium2")] + DILITHIUM2, + #[cfg(feature = "backend-dilithium3")] + DILITHIUM3, + #[cfg(feature = "backend-dilithium5")] + DILITHIUM5, +]; impl TryFrom for KnownPublicKeyCredentialParameters { type Error = UnknownPKCredentialParam;