Add largeBlobKey support to make_credential

This patch adds support for the largeBlobKey extension to
make_credential.  This means that we have to generate a 32-bit key and
store it together with the credential if requested by the platform.
This commit is contained in:
Robin Krahl
2023-11-21 12:46:00 +01:00
parent 71d14ff073
commit c43da04a26
2 changed files with 28 additions and 1 deletions
+4
View File
@@ -226,6 +226,8 @@ pub struct CredentialData {
pub hmac_secret: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub cred_protect: Option<CredentialProtectionPolicy>,
#[serde(skip_serializing_if = "Option::is_none")]
pub large_blob_key: Option<Bytes<32>>,
// TODO: add `sig_counter: Option<CounterId>`,
// and grant RKs a per-credential sig-counter.
@@ -327,6 +329,7 @@ impl FullCredential {
timestamp: u32,
hmac_secret: Option<bool>,
cred_protect: Option<CredentialProtectionPolicy>,
large_blob_key: Option<Bytes<32>>,
nonce: [u8; 12],
) -> Self {
info!("credential for algorithm {}", algorithm);
@@ -341,6 +344,7 @@ impl FullCredential {
hmac_secret,
cred_protect,
large_blob_key,
use_short_id: Some(true),
};
+24 -1
View File
@@ -234,6 +234,7 @@ impl<UP: UserPresence, T: TrussedRequirements> Authenticator for crate::Authenti
let mut hmac_secret_requested = None;
// let mut cred_protect_requested = CredentialProtectionPolicy::Optional;
let mut cred_protect_requested = None;
let mut large_blob_key_requested = false;
if let Some(extensions) = &parameters.extensions {
hmac_secret_requested = extensions.hmac_secret;
@@ -241,6 +242,21 @@ impl<UP: UserPresence, T: TrussedRequirements> Authenticator for crate::Authenti
cred_protect_requested =
Some(credential::CredentialProtectionPolicy::try_from(*policy)?);
}
if self.config.supports_large_blobs() {
if let Some(large_blob_key) = extensions.large_blob_key {
if large_blob_key {
if !rk_requested {
// the largeBlobKey extension is only available for resident keys
return Err(Error::InvalidOption);
}
large_blob_key_requested = true;
} else {
// large_blob_key must be Some(true) or omitted, Some(false) is invalid
return Err(Error::InvalidOption);
}
}
}
}
// debug_now!("hmac-secret = {:?}, credProtect = {:?}", hmac_secret_requested, cred_protect_requested);
@@ -343,6 +359,12 @@ impl<UP: UserPresence, T: TrussedRequirements> Authenticator for crate::Authenti
// store it.
// TODO: overwrite, error handling with KeyStoreFull
let large_blob_key = if large_blob_key_requested {
Some(Bytes::from_slice(&syscall!(self.trussed.random_bytes(32)).bytes).unwrap())
} else {
None
};
let credential = FullCredential::new(
credential::CtapVersion::Fido21Pre,
&parameters.rp,
@@ -352,6 +374,7 @@ impl<UP: UserPresence, T: TrussedRequirements> Authenticator for crate::Authenti
self.state.persistent.timestamp(&mut self.trussed)?,
hmac_secret_requested,
cred_protect_requested,
large_blob_key.clone(),
nonce,
);
@@ -559,7 +582,7 @@ impl<UP: UserPresence, T: TrussedRequirements> Authenticator for crate::Authenti
auth_data: serialized_auth_data,
att_stmt,
ep_att: None,
large_blob_key: None,
large_blob_key,
};
Ok(attestation_object)