Support CTAP 2.1

This commit is contained in:
Robin Krahl
2024-03-01 19:24:42 +01:00
parent 079edd84c9
commit 4e30470232
5 changed files with 16 additions and 25 deletions
+1
View File
@@ -23,6 +23,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Implement PIN protocol 2 ([#63][])
- Implement PIN token permissions ([#63][])
- Implement UpdateUserInformation subcommand for CredentialManagement
- Support CTAP 2.1
[#26]: https://github.com/solokeys/fido-authenticator/issues/26
[#28]: https://github.com/solokeys/fido-authenticator/issues/28
-1
View File
@@ -33,7 +33,6 @@ iso7816 = { version = "0.1", optional = true }
[features]
dispatch = ["apdu-dispatch", "ctaphid-dispatch", "iso7816"]
disable-reset-time-window = []
enable-fido-pre = []
# enables support for a large-blob array longer than 1024 bytes
chunked = ["trussed-staging/chunked"]
+12 -23
View File
@@ -49,13 +49,11 @@ impl<UP: UserPresence, T: TrussedRequirements> Authenticator for crate::Authenti
versions
.push(String::from_str("FIDO_2_0").unwrap())
.unwrap();
// #[cfg(feature = "enable-fido-pre")]
versions
.push(String::from_str("FIDO_2_1_PRE").unwrap())
.push(String::from_str("FIDO_2_1").unwrap())
.unwrap();
let mut extensions = Vec::<String<13>, 4>::new();
// extensions.push(String::from_str("credProtect").unwrap()).unwrap();
extensions
.push(String::from_str("credProtect").unwrap())
.unwrap();
@@ -84,25 +82,15 @@ impl<UP: UserPresence, T: TrussedRequirements> Authenticator for crate::Authenti
true => Some(true),
false => Some(false),
},
credential_mgmt_preview: Some(true),
large_blobs: Some(self.config.supports_large_blobs()),
pin_uv_auth_token: Some(true),
..Default::default()
};
// options.rk = true;
// options.up = true;
// options.uv = None; // "uv" here refers to "in itself", e.g. biometric
// options.plat = Some(false);
// options.cred_mgmt = Some(true);
// options.credential_mgmt_preview = Some(true);
// // options.client_pin = None; // not capable of PIN
// options.client_pin = match self.state.persistent.pin_is_set() {
// true => Some(true),
// false => Some(false),
// };
let mut transports = Vec::new();
transports.push(String::from("nfc")).unwrap();
if self.config.nfc_transport {
transports.push(String::from("nfc")).unwrap();
}
transports.push(String::from("usb")).unwrap();
let (_, aaguid) = self.state.identity.attestation(&mut self.trussed);
@@ -170,6 +158,9 @@ impl<UP: UserPresence, T: TrussedRequirements> Authenticator for crate::Authenti
return Err(Error::InvalidOption);
}
}
if parameters.enterprise_attestation.is_some() {
return Err(Error::InvalidParameter);
}
let uv_performed = self.pin_prechecks(
&parameters.options,
parameters.pin_auth.map(AsRef::as_ref),
@@ -1553,18 +1544,16 @@ impl<UP: UserPresence, T: TrussedRequirements> crate::Authenticator<UP, T> {
&hmac_secret.salt_auth,
)?;
if hmac_secret.salt_enc.len() != 32
&& (hmac_secret.salt_enc.len() != 64 || hmac_secret.salt_enc.len() == 80)
{
debug_now!("invalid hmac-secret length");
return Err(Error::InvalidLength);
}
// decrypt input salt_enc to get salt1 or (salt1 || salt2)
let salts = shared_secret
.decrypt(&mut self.trussed, &hmac_secret.salt_enc)
.ok_or(Error::InvalidOption)?;
if salts.len() != 32 && salts.len() != 64 {
debug_now!("invalid hmac-secret length");
return Err(Error::InvalidLength);
}
let mut salt_output: Bytes<64> = Bytes::new();
// output1 = hmac_sha256(credRandom, salt1)
+1 -1
View File
@@ -406,7 +406,7 @@ impl SharedSecret {
data.split_at(16)
}
};
try_syscall!(trussed.decrypt(Mechanism::Aes256Cbc, key_id, data, iv, b"", b""))
try_syscall!(trussed.decrypt(Mechanism::Aes256Cbc, key_id, data, b"", iv, b""))
.ok()
.and_then(|response| response.plaintext)
}
+2
View File
@@ -103,6 +103,8 @@ pub struct Config {
///
/// If this is `None`, the extension and the command are disabled.
pub large_blobs: Option<ctap2::large_blobs::Config>,
/// Whether the authenticator supports the NFC transport.
pub nfc_transport: bool,
}
impl Config {