You've already forked fido-authenticator
mirror of
https://github.com/trussed-dev/fido-authenticator.git
synced 2026-03-11 16:36:21 -07:00
Clippy round
This commit is contained in:
committed by
Nicolas Stalder
parent
9e4b7e806a
commit
c4e4b79502
@@ -41,3 +41,6 @@ log-error = []
|
||||
[dev-dependencies]
|
||||
# quickcheck = "1"
|
||||
rand = "0.8.4"
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
features = ["dispatch"]
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
use trussed::types::{CertId, KeyId};
|
||||
|
||||
pub const FIDO2_UP_TIMEOUT: u32 = 30_000;
|
||||
pub const U2F_UP_TIMEOUT: u32 = 0_250;
|
||||
pub const U2F_UP_TIMEOUT: u32 = 250;
|
||||
|
||||
pub const ATTESTATION_CERT_ID: CertId = CertId::from_special(0);
|
||||
pub const ATTESTATION_KEY_ID: KeyId = KeyId::from_special(0);
|
||||
|
||||
@@ -175,10 +175,10 @@ impl PartialOrd<&Credential> for Credential {
|
||||
// Bad idea - huge stack
|
||||
// pub(crate) type CredentialList = Vec<Credential, {ctap_types::sizes::MAX_CREDENTIAL_COUNT_IN_LIST}>;
|
||||
|
||||
impl Into<PublicKeyCredentialDescriptor> for CredentialId {
|
||||
fn into(self) -> PublicKeyCredentialDescriptor {
|
||||
impl From<CredentialId> for PublicKeyCredentialDescriptor {
|
||||
fn from(id: CredentialId) -> PublicKeyCredentialDescriptor {
|
||||
PublicKeyCredentialDescriptor {
|
||||
id: self.0,
|
||||
id: id.0,
|
||||
key_type: {
|
||||
let mut key_type = String::new();
|
||||
key_type.push_str("public-key").unwrap();
|
||||
@@ -189,6 +189,7 @@ impl Into<PublicKeyCredentialDescriptor> for CredentialId {
|
||||
}
|
||||
|
||||
impl Credential {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn new(
|
||||
ctap: CtapVersion,
|
||||
// parameters: &ctap2::make_credential::Parameters,
|
||||
@@ -210,7 +211,7 @@ impl Credential {
|
||||
|
||||
creation_time: timestamp,
|
||||
use_counter: true,
|
||||
algorithm: algorithm,
|
||||
algorithm,
|
||||
key,
|
||||
|
||||
hmac_secret,
|
||||
@@ -237,7 +238,7 @@ impl Credential {
|
||||
// the ID will stay below 255 bytes.
|
||||
//
|
||||
// Existing keyhandles can still be decoded
|
||||
pub fn id<'a, T: client::Chacha8Poly1305 + client::Sha256>(
|
||||
pub fn id<T: client::Chacha8Poly1305 + client::Sha256>(
|
||||
&self,
|
||||
trussed: &mut T,
|
||||
key_encryption_key: KeyId,
|
||||
@@ -252,7 +253,7 @@ impl Credential {
|
||||
let rp_id_hash: Bytes<32> = if let Some(hash) = rp_id_hash {
|
||||
hash.clone()
|
||||
} else {
|
||||
syscall!(trussed.hash_sha256(&self.rp.id.as_ref()))
|
||||
syscall!(trussed.hash_sha256(self.rp.id.as_ref()))
|
||||
.hash
|
||||
.to_bytes().map_err(|_| Error::Other)?
|
||||
};
|
||||
@@ -268,7 +269,7 @@ impl Credential {
|
||||
}
|
||||
|
||||
pub fn serialize(&self) -> Result<SerializedCredential> {
|
||||
Ok(trussed::cbor_serialize_bytes(self).map_err(|_| Error::Other)?)
|
||||
trussed::cbor_serialize_bytes(self).map_err(|_| Error::Other)
|
||||
}
|
||||
|
||||
pub fn deserialize(bytes: &SerializedCredential) -> Result<Self> {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//! The `ctap1::Authenticator` trait and its implementation.
|
||||
//! The `ctap_types::ctap1::Authenticator` implementation.
|
||||
|
||||
use ctap_types::{
|
||||
ctap1::{
|
||||
|
||||
72
src/ctap2.rs
72
src/ctap2.rs
@@ -1,4 +1,4 @@
|
||||
//! The `ctap2::Authenticator` trait and its implementation.
|
||||
//! The `ctap_types::ctap2::Authenticator` implementation.
|
||||
|
||||
use ctap_types::{
|
||||
heapless::{String, Vec},
|
||||
@@ -158,7 +158,7 @@ impl<UP: UserPresence, T: TrussedRequirements> Authenticator for crate::Authenti
|
||||
#[inline(never)]
|
||||
fn make_credential(&mut self, parameters: &ctap2::make_credential::Request) -> Result<ctap2::make_credential::Response> {
|
||||
|
||||
let rp_id_hash = self.hash(¶meters.rp.id.as_ref());
|
||||
let rp_id_hash = self.hash(parameters.rp.id.as_ref());
|
||||
|
||||
// 1-4.
|
||||
if let Some(options) = parameters.options.as_ref() {
|
||||
@@ -169,7 +169,7 @@ impl<UP: UserPresence, T: TrussedRequirements> Authenticator for crate::Authenti
|
||||
}
|
||||
let uv_performed = self.pin_prechecks(
|
||||
¶meters.options, ¶meters.pin_auth, ¶meters.pin_protocol,
|
||||
¶meters.client_data_hash.as_ref(),
|
||||
parameters.client_data_hash.as_ref(),
|
||||
)?;
|
||||
|
||||
// 5. "persist credProtect value for this credential"
|
||||
@@ -183,7 +183,7 @@ impl<UP: UserPresence, T: TrussedRequirements> Authenticator for crate::Authenti
|
||||
if let Ok(excluded_cred) = result {
|
||||
use credential::CredentialProtectionPolicy;
|
||||
// If UV is not performed, than CredProtectRequired credentials should not be visibile.
|
||||
if !(excluded_cred.cred_protect == Some(CredentialProtectionPolicy::Required) && !uv_performed) {
|
||||
if !(excluded_cred.cred_protect == Some(CredentialProtectionPolicy::Required)) || uv_performed {
|
||||
info_now!("Excluded!");
|
||||
self.up.user_present(&mut self.trussed, constants::FIDO2_UP_TIMEOUT)?;
|
||||
return Err(Error::CredentialExcluded);
|
||||
@@ -261,7 +261,7 @@ impl<UP: UserPresence, T: TrussedRequirements> Authenticator for crate::Authenti
|
||||
private_key = syscall!(self.trussed.generate_p256_private_key(location)).key;
|
||||
public_key = syscall!(self.trussed.derive_p256_public_key(private_key, Location::Volatile)).key;
|
||||
cose_public_key = syscall!(self.trussed.serialize_key(
|
||||
Mechanism::P256, public_key.clone(), KeySerialization::Cose
|
||||
Mechanism::P256, public_key, KeySerialization::Cose
|
||||
)).serialized_key;
|
||||
let _success = syscall!(self.trussed.delete(public_key)).success;
|
||||
info_now!("deleted public P256 key: {}", _success);
|
||||
@@ -270,7 +270,7 @@ impl<UP: UserPresence, T: TrussedRequirements> Authenticator for crate::Authenti
|
||||
private_key = syscall!(self.trussed.generate_ed255_private_key(location)).key;
|
||||
public_key = syscall!(self.trussed.derive_ed255_public_key(private_key, Location::Volatile)).key;
|
||||
cose_public_key = syscall!(self.trussed.serialize_key(
|
||||
Mechanism::Ed255, public_key.clone(), KeySerialization::Cose
|
||||
Mechanism::Ed255, public_key, KeySerialization::Cose
|
||||
)).serialized_key;
|
||||
let _success = syscall!(self.trussed.delete(public_key)).success;
|
||||
info_now!("deleted public Ed25519 key: {}", _success);
|
||||
@@ -330,7 +330,7 @@ impl<UP: UserPresence, T: TrussedRequirements> Authenticator for crate::Authenti
|
||||
algorithm as i32,
|
||||
key_parameter,
|
||||
self.state.persistent.timestamp(&mut self.trussed)?,
|
||||
hmac_secret_requested.clone(),
|
||||
hmac_secret_requested,
|
||||
cred_protect_requested,
|
||||
nonce,
|
||||
);
|
||||
@@ -346,11 +346,11 @@ impl<UP: UserPresence, T: TrussedRequirements> Authenticator for crate::Authenti
|
||||
self.delete_resident_key_by_user_id(&rp_id_hash, &credential.user.id).ok();
|
||||
|
||||
// then store key, making it resident
|
||||
let credential_id_hash = self.hash(&credential_id.0.as_ref());
|
||||
let credential_id_hash = self.hash(credential_id.0.as_ref());
|
||||
try_syscall!(self.trussed.write_file(
|
||||
Location::Internal,
|
||||
rk_path(&rp_id_hash, &credential_id_hash),
|
||||
serialized_credential.clone(),
|
||||
serialized_credential,
|
||||
// user attribute for later easy lookup
|
||||
// Some(rp_id_hash.clone()),
|
||||
None,
|
||||
@@ -398,8 +398,8 @@ impl<UP: UserPresence, T: TrussedRequirements> Authenticator for crate::Authenti
|
||||
extensions: {
|
||||
if hmac_secret_requested.is_some() || cred_protect_requested.is_some() {
|
||||
Some(ctap2::make_credential::Extensions {
|
||||
cred_protect: parameters.extensions.as_ref().unwrap().cred_protect.clone(),
|
||||
hmac_secret: parameters.extensions.as_ref().unwrap().hmac_secret.clone(),
|
||||
cred_protect: parameters.extensions.as_ref().unwrap().cred_protect,
|
||||
hmac_secret: parameters.extensions.as_ref().unwrap().hmac_secret,
|
||||
})
|
||||
|
||||
} else {
|
||||
@@ -567,7 +567,7 @@ impl<UP: UserPresence, T: TrussedRequirements> Authenticator for crate::Authenti
|
||||
let private_key = self.state.runtime.key_agreement_key(&mut self.trussed);
|
||||
let public_key = syscall!(self.trussed.derive_p256_public_key(private_key, Location::Volatile)).key;
|
||||
let serialized_cose_key = syscall!(self.trussed.serialize_key(
|
||||
Mechanism::P256, public_key.clone(), KeySerialization::EcdhEsHkdf256)).serialized_key;
|
||||
Mechanism::P256, public_key, KeySerialization::EcdhEsHkdf256)).serialized_key;
|
||||
let cose_key = trussed::cbor_deserialize(&serialized_cose_key).unwrap();
|
||||
|
||||
syscall!(self.trussed.delete(public_key));
|
||||
@@ -663,7 +663,7 @@ impl<UP: UserPresence, T: TrussedRequirements> Authenticator for crate::Authenti
|
||||
self.state.decrement_retries(&mut self.trussed)?;
|
||||
|
||||
// 6. decrypt pinHashEnc, compare with stored
|
||||
self.decrypt_pin_hash_and_maybe_escalate(shared_secret, &pin_hash_enc)?;
|
||||
self.decrypt_pin_hash_and_maybe_escalate(shared_secret, pin_hash_enc)?;
|
||||
|
||||
// 7. reset retries
|
||||
self.state.reset_retries(&mut self.trussed)?;
|
||||
@@ -706,7 +706,7 @@ impl<UP: UserPresence, T: TrussedRequirements> Authenticator for crate::Authenti
|
||||
self.state.decrement_retries(&mut self.trussed)?;
|
||||
|
||||
// 5. decrypt and verify pinHashEnc
|
||||
self.decrypt_pin_hash_and_maybe_escalate(shared_secret, &pin_hash_enc)?;
|
||||
self.decrypt_pin_hash_and_maybe_escalate(shared_secret, pin_hash_enc)?;
|
||||
|
||||
// 6. reset retries
|
||||
self.state.reset_retries(&mut self.trussed)?;
|
||||
@@ -749,7 +749,7 @@ impl<UP: UserPresence, T: TrussedRequirements> Authenticator for crate::Authenti
|
||||
use credential_management as cm;
|
||||
|
||||
// TODO: I see "failed pinauth" output, but then still continuation...
|
||||
self.verify_pin_auth_using_token(¶meters)?;
|
||||
self.verify_pin_auth_using_token(parameters)?;
|
||||
|
||||
let mut cred_mgmt = cm::CredentialManagement::new(self);
|
||||
let sub_parameters = ¶meters.sub_command_params;
|
||||
@@ -813,12 +813,12 @@ impl<UP: UserPresence, T: TrussedRequirements> Authenticator for crate::Authenti
|
||||
|
||||
debug_now!("remaining stack size: {} bytes", msp() - 0x2000_0000);
|
||||
|
||||
let rp_id_hash = self.hash(¶meters.rp_id.as_ref());
|
||||
let rp_id_hash = self.hash(parameters.rp_id.as_ref());
|
||||
|
||||
// 1-4.
|
||||
let uv_performed = match self.pin_prechecks(
|
||||
¶meters.options, ¶meters.pin_auth, ¶meters.pin_protocol,
|
||||
¶meters.client_data_hash.as_ref(),
|
||||
parameters.client_data_hash.as_ref(),
|
||||
) {
|
||||
Ok(b) => b,
|
||||
Err(Error::PinRequired) => {
|
||||
@@ -909,7 +909,7 @@ impl<UP: UserPresence, T: TrussedRequirements> crate::Authenticator<UP, T>
|
||||
} {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
true
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
@@ -941,7 +941,7 @@ impl<UP: UserPresence, T: TrussedRequirements> crate::Authenticator<UP, T>
|
||||
// <https://fidoalliance.org/specs/fido-v2.1-ps-20210615/fido-client-to-authenticator-protocol-v2.1-ps-20210615.html#:~:text=A%20platform%20MUST%20NOT%20send%20an%20empty%20allowList%E2%80%94if%20it%20would%20be%20empty%20it%20MUST%20be%20omitted>
|
||||
// but some still do (and CTAP 2.0 does not rule it out).
|
||||
// they probably meant to send None.
|
||||
if allow_list.len() > 0 {
|
||||
if !allow_list.is_empty() {
|
||||
for credential_id in allow_list {
|
||||
let credential = match Credential::try_from(self, rp_id_hash, credential_id) {
|
||||
Ok(credential) => credential,
|
||||
@@ -965,7 +965,7 @@ impl<UP: UserPresence, T: TrussedRequirements> crate::Authenticator<UP, T>
|
||||
|
||||
let mut maybe_path = syscall!(self.trussed.read_dir_first(
|
||||
Location::Internal,
|
||||
rp_rk_dir(&rp_id_hash),
|
||||
rp_rk_dir(rp_id_hash),
|
||||
None,
|
||||
)).entry.map(|entry| PathBuf::try_from(entry.path()).unwrap());
|
||||
|
||||
@@ -983,7 +983,7 @@ impl<UP: UserPresence, T: TrussedRequirements> crate::Authenticator<UP, T>
|
||||
if self.check_credential_applicable(&credential, false, uv_performed) {
|
||||
self.state.runtime.push_credential(CachedCredential {
|
||||
timestamp: credential.creation_time,
|
||||
path: String::from_str(&path.as_str_ref_with_trailing_nul()).ok()?,
|
||||
path: String::from_str(path.as_str_ref_with_trailing_nul()).ok()?,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1007,7 +1007,7 @@ impl<UP: UserPresence, T: TrussedRequirements> crate::Authenticator<UP, T>
|
||||
None => { return Err(Error::PinNotSet); }
|
||||
};
|
||||
|
||||
if &pin_hash != &stored_pin_hash {
|
||||
if pin_hash != stored_pin_hash {
|
||||
// I) generate new KEK
|
||||
self.state.runtime.rotate_key_agreement_key(&mut self.trussed);
|
||||
if self.state.persistent.retries() == 0 {
|
||||
@@ -1023,7 +1023,7 @@ impl<UP: UserPresence, T: TrussedRequirements> crate::Authenticator<UP, T>
|
||||
}
|
||||
|
||||
fn hash_store_pin(&mut self, pin: &Message) -> Result<()> {
|
||||
let pin_hash_32 = syscall!(self.trussed.hash_sha256(&pin)).hash;
|
||||
let pin_hash_32 = syscall!(self.trussed.hash_sha256(pin)).hash;
|
||||
let pin_hash: [u8; 16] = pin_hash_32[..16].try_into().unwrap();
|
||||
self.state.persistent.set_pin_hash(&mut self.trussed, pin_hash).unwrap();
|
||||
|
||||
@@ -1038,7 +1038,7 @@ impl<UP: UserPresence, T: TrussedRequirements> crate::Authenticator<UP, T>
|
||||
}
|
||||
|
||||
let mut pin = syscall!(self.trussed.decrypt_aes256cbc(
|
||||
shared_secret, &pin_enc)).plaintext.ok_or(Error::Other)?;
|
||||
shared_secret, pin_enc)).plaintext.ok_or(Error::Other)?;
|
||||
|
||||
// // temp
|
||||
// let pin_length = pin.iter().position(|&b| b == b'\0').unwrap_or(pin.len());
|
||||
@@ -1046,7 +1046,7 @@ impl<UP: UserPresence, T: TrussedRequirements> crate::Authenticator<UP, T>
|
||||
// pin.len(), pin_length, &pin);
|
||||
// chop off null bytes
|
||||
let pin_length = pin.iter().position(|&b| b == b'\0').unwrap_or(pin.len());
|
||||
if pin_length < 4 || pin_length >= 64 {
|
||||
if !(4..64).contains(&pin_length) {
|
||||
return Err(Error::PinPolicyViolation);
|
||||
}
|
||||
|
||||
@@ -1072,7 +1072,7 @@ impl<UP: UserPresence, T: TrussedRequirements> crate::Authenticator<UP, T>
|
||||
{
|
||||
let expected_pin_auth = syscall!(self.trussed.sign_hmacsha256(shared_secret, data)).signature;
|
||||
|
||||
if &expected_pin_auth[..16] == &pin_auth[..] {
|
||||
if expected_pin_auth[..16] == pin_auth[..] {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(Error::PinAuthInvalid)
|
||||
@@ -1130,7 +1130,7 @@ impl<UP: UserPresence, T: TrussedRequirements> crate::Authenticator<UP, T>
|
||||
let pin_auth = parameters
|
||||
.pin_auth.as_ref().ok_or(Error::MissingParameter)?;
|
||||
|
||||
if &expected_pin_auth[..16] == &pin_auth[..] {
|
||||
if expected_pin_auth[..16] == pin_auth[..] {
|
||||
info_now!("passed pinauth");
|
||||
Ok(())
|
||||
} else {
|
||||
@@ -1252,8 +1252,8 @@ impl<UP: UserPresence, T: TrussedRequirements> crate::Authenticator<UP, T>
|
||||
Key::ResidentKey(key) => {
|
||||
debug_now!("checking if ResidentKey {:?} exists", key);
|
||||
match alg {
|
||||
-7 => syscall!(self.trussed.exists(Mechanism::P256, key.clone())).exists,
|
||||
-8 => syscall!(self.trussed.exists(Mechanism::Ed255, key.clone())).exists,
|
||||
-7 => syscall!(self.trussed.exists(Mechanism::P256, *key)).exists,
|
||||
-8 => syscall!(self.trussed.exists(Mechanism::Ed255, *key)).exists,
|
||||
// -9 => {
|
||||
// let exists = syscall!(self.trussed.exists(Mechanism::Totp, key)).exists;
|
||||
// info_now!("found it");
|
||||
@@ -1369,7 +1369,7 @@ impl<UP: UserPresence, T: TrussedRequirements> crate::Authenticator<UP, T>
|
||||
|
||||
// 8. process any extensions present
|
||||
let extensions_output = if let Some(extensions) = &data.extensions {
|
||||
self.process_assertion_extensions(&data, &extensions, &credential, key)?
|
||||
self.process_assertion_extensions(&data, extensions, &credential, key)?
|
||||
} else {
|
||||
None
|
||||
};
|
||||
@@ -1385,7 +1385,7 @@ impl<UP: UserPresence, T: TrussedRequirements> crate::Authenticator<UP, T>
|
||||
let sig_count = self.state.persistent.timestamp(&mut self.trussed)?;
|
||||
|
||||
let authenticator_data = ctap2::get_assertion::AuthenticatorData {
|
||||
rp_id_hash: rp_id_hash,
|
||||
rp_id_hash,
|
||||
|
||||
flags: {
|
||||
let mut flags = Flags::EMPTY;
|
||||
@@ -1426,7 +1426,7 @@ impl<UP: UserPresence, T: TrussedRequirements> crate::Authenticator<UP, T>
|
||||
// info_now!("TOTP with timestamp {:?}", ×tamp);
|
||||
// syscall!(self.trussed.sign_totp(key, timestamp)).signature.to_bytes().unwrap()
|
||||
// }
|
||||
_ => syscall!(self.trussed.sign(mechanism, key.clone(), &commitment, serialization)).signature
|
||||
_ => syscall!(self.trussed.sign(mechanism, key, &commitment, serialization)).signature
|
||||
.to_bytes().unwrap(),
|
||||
};
|
||||
|
||||
@@ -1466,10 +1466,10 @@ impl<UP: UserPresence, T: TrussedRequirements> crate::Authenticator<UP, T>
|
||||
) -> Result<()> {
|
||||
|
||||
// Prepare to iterate over all credentials associated to RP.
|
||||
let rp_path = rp_rk_dir(&rp_id_hash);
|
||||
let rp_path = rp_rk_dir(rp_id_hash);
|
||||
let mut entry = syscall!(self.trussed.read_dir_first(
|
||||
Location::Internal,
|
||||
rp_path.clone(),
|
||||
rp_path,
|
||||
None,
|
||||
)).entry;
|
||||
|
||||
@@ -1485,7 +1485,7 @@ impl<UP: UserPresence, T: TrussedRequirements> crate::Authenticator<UP, T>
|
||||
info_now!("checking RK {:?} for userId ", &rk_path);
|
||||
let credential_data = syscall!(self.trussed.read_file(
|
||||
Location::Internal,
|
||||
PathBuf::from(rk_path.clone()),
|
||||
rk_path.clone(),
|
||||
)).data;
|
||||
let credential_maybe = Credential::deserialize(&credential_data);
|
||||
|
||||
@@ -1502,7 +1502,7 @@ impl<UP: UserPresence, T: TrussedRequirements> crate::Authenticator<UP, T>
|
||||
}
|
||||
syscall!(self.trussed.remove_file(
|
||||
Location::Internal,
|
||||
PathBuf::from(rk_path),
|
||||
rk_path,
|
||||
));
|
||||
|
||||
info_now!("Overwriting previous rk tied to this userId.");
|
||||
|
||||
@@ -46,7 +46,7 @@ where UP: UserPresence,
|
||||
{
|
||||
type Target = Authenticator<UP, T>;
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.authnr
|
||||
self.authnr
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ impl<UP, T> core::ops::DerefMut for CredentialManagement<'_, UP, T>
|
||||
where UP: UserPresence,
|
||||
{
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
&mut self.authnr
|
||||
self.authnr
|
||||
}
|
||||
}
|
||||
|
||||
@@ -178,7 +178,7 @@ where UP: UserPresence,
|
||||
|
||||
let rp = credential.data.rp;
|
||||
|
||||
response.rp_id_hash = Some(self.hash(&rp.id.as_ref()));
|
||||
response.rp_id_hash = Some(self.hash(rp.id.as_ref()));
|
||||
response.rp = Some(rp);
|
||||
|
||||
}
|
||||
@@ -206,7 +206,7 @@ where UP: UserPresence,
|
||||
let CredentialManagementEnumerateRps {
|
||||
remaining,
|
||||
rp_id_hash: last_rp_id_hash,
|
||||
} = self.state.runtime.cached_rp.clone().ok_or_else(|| Error::NotAllowed)?;
|
||||
} = self.state.runtime.cached_rp.clone().ok_or(Error::NotAllowed)?;
|
||||
|
||||
let dir = PathBuf::from(b"rk");
|
||||
|
||||
@@ -251,7 +251,7 @@ where UP: UserPresence,
|
||||
|
||||
let rp = credential.data.rp;
|
||||
|
||||
response.rp_id_hash = Some(self.hash(&rp.id.as_ref()));
|
||||
response.rp_id_hash = Some(self.hash(rp.id.as_ref()));
|
||||
response.rp = Some(rp);
|
||||
|
||||
// cache state for next call
|
||||
@@ -395,16 +395,12 @@ where UP: UserPresence,
|
||||
.map_err(|_| Error::InvalidCredential)?;
|
||||
|
||||
// now fill response
|
||||
let mut response: Response = Default::default();
|
||||
|
||||
response.user = Some(credential.data.user.clone());
|
||||
|
||||
// why these contortions to get kek. sheesh
|
||||
let authnr = &mut self.authnr;
|
||||
let kek = authnr.state.persistent.key_encryption_key(&mut authnr.trussed)?;
|
||||
|
||||
let credential_id = credential.id(&mut self.trussed, kek, None)?;
|
||||
response.credential_id = Some(credential_id.into());
|
||||
let credential_id = credential.id(&mut self.trussed, kek, None)?;
|
||||
|
||||
use crate::credential::Key;
|
||||
let private_key = match credential.key {
|
||||
@@ -420,7 +416,7 @@ where UP: UserPresence,
|
||||
SigningAlgorithm::P256 => {
|
||||
let public_key = syscall!(self.trussed.derive_p256_public_key(private_key, Location::Volatile)).key;
|
||||
let cose_public_key = syscall!(self.trussed.serialize_key(
|
||||
Mechanism::P256, public_key.clone(),
|
||||
Mechanism::P256, public_key,
|
||||
// KeySerialization::EcdhEsHkdf256
|
||||
KeySerialization::Cose,
|
||||
)).serialized_key;
|
||||
@@ -444,12 +440,19 @@ where UP: UserPresence,
|
||||
// PublicKey::TotpKey(Default::default())
|
||||
// }
|
||||
};
|
||||
response.public_key = Some(cose_public_key);
|
||||
response.cred_protect = match credential.cred_protect {
|
||||
let cred_protect = match credential.cred_protect {
|
||||
Some(x) => Some(x),
|
||||
None => Some(CredentialProtectionPolicy::Optional),
|
||||
};
|
||||
|
||||
let response = Response {
|
||||
user: Some(credential.data.user),
|
||||
credential_id: Some(credential_id.into()),
|
||||
public_key: Some(cose_public_key),
|
||||
cred_protect,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
Ok(response)
|
||||
}
|
||||
|
||||
@@ -467,7 +470,7 @@ where UP: UserPresence,
|
||||
|
||||
let rk_path = syscall!(self.trussed.locate_file(
|
||||
Location::Internal,
|
||||
Some(dir.clone()),
|
||||
Some(dir),
|
||||
filename,
|
||||
)).path.ok_or(Error::InvalidCredential)?;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//! Dispatch of incoming requests over CTAPHID or NFC APDUs into CTAP1 and CTAP2.
|
||||
|
||||
pub mod apdu;
|
||||
pub mod ctaphid;
|
||||
mod apdu;
|
||||
mod ctaphid;
|
||||
|
||||
use crate::{Authenticator, TrussedRequirements, UserPresence};
|
||||
#[allow(unused_imports)]
|
||||
|
||||
26
src/lib.rs
26
src/lib.rs
@@ -2,8 +2,11 @@
|
||||
//!
|
||||
//! The core structure is [`Authenticator`], a Trussed® application.
|
||||
//!
|
||||
//! It implements [`ctap1::Authenticator`] and [`ctap2::Authenticator`] traits,
|
||||
//! It implements the [`ctap_types::ctap1::Authenticator`] and [`ctap_types::ctap2::Authenticator`] traits,
|
||||
//! which express the interface defined in the CTAP specification.
|
||||
//!
|
||||
//! With feature `dispatch` activated, it also implements the `App` traits
|
||||
//! of [`apdu_dispatch`] and [`ctaphid_dispatch`].
|
||||
|
||||
#![cfg_attr(not(test), no_std)]
|
||||
// #![warn(missing_docs)]
|
||||
@@ -28,11 +31,11 @@ use ctap_types::{
|
||||
/// Re-export of `ctap-types` authenticator errors.
|
||||
pub use ctap_types::Error;
|
||||
|
||||
pub mod ctap1;
|
||||
pub mod ctap2;
|
||||
mod ctap1;
|
||||
mod ctap2;
|
||||
|
||||
#[cfg(feature="dispatch")]
|
||||
pub mod dispatch;
|
||||
mod dispatch;
|
||||
|
||||
pub mod constants;
|
||||
pub mod credential;
|
||||
@@ -72,6 +75,7 @@ where T:
|
||||
{}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||
/// Externally defined configuration.
|
||||
pub struct Config {
|
||||
/// Typically determined by surrounding USB-level decoder.
|
||||
/// For Solo 2, this is usbd-ctaphid (and its buffer size).
|
||||
@@ -92,7 +96,7 @@ pub struct Config {
|
||||
|
||||
/// Trussed® app implementing a FIDO authenticator.
|
||||
///
|
||||
/// It implements [`ctap1::Authenticator`] and [`ctap2::Authenticator`] traits,
|
||||
/// It implements the [`ctap_types::ctap1::Authenticator`] and [`ctap_types::ctap2::Authenticator`] traits,
|
||||
/// which, in turn, express the interfaces defined in the CTAP specification.
|
||||
///
|
||||
/// The type parameter `T` selects a Trussed® client implementation, which
|
||||
@@ -136,7 +140,7 @@ fn format_hex(data: &[u8], mut buffer: &mut [u8]) {
|
||||
|
||||
#[inline]
|
||||
#[allow(dead_code)]
|
||||
pub(crate) fn msp() -> u32 { 0x2000_000 }
|
||||
pub(crate) fn msp() -> u32 { 0x2000_0000 }
|
||||
|
||||
/// Currently Ed25519 and P256.
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||
@@ -169,6 +173,7 @@ pub trait UserPresence: Copy {
|
||||
}
|
||||
|
||||
#[deprecated(note="use `Silent` directly`")]
|
||||
#[doc(hidden)]
|
||||
pub type SilentAuthenticator = Silent;
|
||||
|
||||
/// No user presence verification.
|
||||
@@ -182,6 +187,7 @@ impl UserPresence for Silent {
|
||||
}
|
||||
|
||||
#[deprecated(note="use `Conforming` directly")]
|
||||
#[doc(hidden)]
|
||||
pub type NonSilentAuthenticator = Conforming;
|
||||
|
||||
/// User presence verification via Trussed.
|
||||
@@ -200,7 +206,7 @@ impl UserPresence for Conforming {
|
||||
}
|
||||
|
||||
fn cbor_serialize_message<T: serde::Serialize>(object: &T) -> core::result::Result<Message, ctap_types::serde::Error> {
|
||||
Ok(trussed::cbor_serialize_bytes(object)?)
|
||||
trussed::cbor_serialize_bytes(object)
|
||||
}
|
||||
|
||||
impl<UP, T> Authenticator<UP, T>
|
||||
@@ -210,9 +216,7 @@ where UP: UserPresence,
|
||||
pub fn new(trussed: T, up: UP, config: Config) -> Self {
|
||||
|
||||
let state = state::State::new();
|
||||
let authenticator = Self { trussed, state, up, config };
|
||||
|
||||
authenticator
|
||||
Self { trussed, state, up, config }
|
||||
}
|
||||
|
||||
pub fn call(&mut self, request: &Request) -> Result<Response> {
|
||||
@@ -235,7 +239,7 @@ where UP: UserPresence,
|
||||
}
|
||||
|
||||
fn hash(&mut self, data: &[u8]) -> Bytes<32> {
|
||||
let hash = syscall!(self.trussed.hash_sha256(&data)).hash;
|
||||
let hash = syscall!(self.trussed.hash_sha256(data)).hash;
|
||||
hash.to_bytes().expect("hash should fit")
|
||||
}
|
||||
}
|
||||
|
||||
18
src/state.rs
18
src/state.rs
@@ -68,7 +68,7 @@ impl<const N: usize> CredentialCacheGeneric<N> {
|
||||
self.0.len() as u32
|
||||
}
|
||||
|
||||
pub fn is_empty(&mut self) -> bool {
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.0.is_empty()
|
||||
}
|
||||
|
||||
@@ -88,6 +88,12 @@ pub struct State {
|
||||
pub runtime: RuntimeState,
|
||||
}
|
||||
|
||||
impl Default for State {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl State {
|
||||
|
||||
// pub fn new(trussed: &mut TrussedClient) -> Self {
|
||||
@@ -169,9 +175,7 @@ impl Identity {
|
||||
cert_reader = &cert_reader[aaguid_start_sequence.len()..];
|
||||
|
||||
let mut aaguid = [0u8; 16];
|
||||
for i in 0 .. 16 {
|
||||
aaguid[i] = cert_reader[i]
|
||||
}
|
||||
aaguid[..16].clone_from_slice(&cert_reader[..16]);
|
||||
Some(aaguid)
|
||||
}
|
||||
|
||||
@@ -187,7 +191,7 @@ impl Identity {
|
||||
crate::constants::ATTESTATION_CERT_ID
|
||||
)).der;
|
||||
|
||||
let mut aaguid = self.yank_aaguid(&cert.as_slice());
|
||||
let mut aaguid = self.yank_aaguid(cert.as_slice());
|
||||
|
||||
if aaguid.is_none() {
|
||||
// Provide a default
|
||||
@@ -308,9 +312,7 @@ impl PersistentState {
|
||||
return Err(Error::Other);
|
||||
}
|
||||
|
||||
let previous_state = result.map_err(|_| Error::Other);
|
||||
|
||||
previous_state
|
||||
result.map_err(|_| Error::Other)
|
||||
}
|
||||
|
||||
pub fn save<T: TrussedClient>(&self, trussed: &mut T) -> Result<()> {
|
||||
|
||||
Reference in New Issue
Block a user