Only write attestation if compiled with batch attestation
This commit is contained in:
@@ -531,19 +531,25 @@ where
|
|||||||
|
|
||||||
let mut signature_data = auth_data.clone();
|
let mut signature_data = auth_data.clone();
|
||||||
signature_data.extend(client_data_hash);
|
signature_data.extend(client_data_hash);
|
||||||
let (signature, x5c) = if USE_BATCH_ATTESTATION {
|
// We currently use the presence of the attestation private key in the persistent storage to
|
||||||
|
// decide whether batch attestation is needed.
|
||||||
|
let (signature, x5c) = match self.persistent_store.attestation_private_key()? {
|
||||||
|
Some(attestation_private_key) => {
|
||||||
let attestation_key =
|
let attestation_key =
|
||||||
crypto::ecdsa::SecKey::from_bytes(self.persistent_store.attestation_private_key()?)
|
crypto::ecdsa::SecKey::from_bytes(attestation_private_key).unwrap();
|
||||||
.unwrap();
|
let attestation_certificate = self
|
||||||
|
.persistent_store
|
||||||
|
.attestation_certificate()?
|
||||||
|
.ok_or(Ctap2StatusCode::CTAP2_ERR_VENDOR_INTERNAL_ERROR)?;
|
||||||
(
|
(
|
||||||
attestation_key.sign_rfc6979::<crypto::sha256::Sha256>(&signature_data),
|
attestation_key.sign_rfc6979::<crypto::sha256::Sha256>(&signature_data),
|
||||||
Some(vec![self.persistent_store.attestation_certificate()?]),
|
Some(vec![attestation_certificate]),
|
||||||
)
|
)
|
||||||
} else {
|
}
|
||||||
(
|
None => (
|
||||||
sk.sign_rfc6979::<crypto::sha256::Sha256>(&signature_data),
|
sk.sign_rfc6979::<crypto::sha256::Sha256>(&signature_data),
|
||||||
None,
|
None,
|
||||||
)
|
),
|
||||||
};
|
};
|
||||||
let attestation_statement = PackedAttestationStatement {
|
let attestation_statement = PackedAttestationStatement {
|
||||||
alg: SignatureAlgorithm::ES256 as i64,
|
alg: SignatureAlgorithm::ES256 as i64,
|
||||||
|
|||||||
@@ -14,9 +14,8 @@
|
|||||||
|
|
||||||
use crate::crypto::rng256::Rng256;
|
use crate::crypto::rng256::Rng256;
|
||||||
use crate::ctap::data_formats::PublicKeyCredentialSource;
|
use crate::ctap::data_formats::PublicKeyCredentialSource;
|
||||||
use crate::ctap::key_material;
|
|
||||||
use crate::ctap::status_code::Ctap2StatusCode;
|
use crate::ctap::status_code::Ctap2StatusCode;
|
||||||
use crate::ctap::PIN_AUTH_LENGTH;
|
use crate::ctap::{key_material, PIN_AUTH_LENGTH, USE_BATCH_ATTESTATION};
|
||||||
use alloc::string::String;
|
use alloc::string::String;
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
use core::convert::TryInto;
|
use core::convert::TryInto;
|
||||||
@@ -223,6 +222,8 @@ impl PersistentStore {
|
|||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
// The following 3 entries are meant to be written by vendor-specific commands.
|
||||||
|
if USE_BATCH_ATTESTATION {
|
||||||
if self.store.find_one(&Key::AttestationPrivateKey).is_none() {
|
if self.store.find_one(&Key::AttestationPrivateKey).is_none() {
|
||||||
self.store
|
self.store
|
||||||
.insert(StoreEntry {
|
.insert(StoreEntry {
|
||||||
@@ -241,6 +242,7 @@ impl PersistentStore {
|
|||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if self.store.find_one(&Key::Aaguid).is_none() {
|
if self.store.find_one(&Key::Aaguid).is_none() {
|
||||||
self.store
|
self.store
|
||||||
.insert(StoreEntry {
|
.insert(StoreEntry {
|
||||||
@@ -435,24 +437,23 @@ impl PersistentStore {
|
|||||||
|
|
||||||
pub fn attestation_private_key(
|
pub fn attestation_private_key(
|
||||||
&self,
|
&self,
|
||||||
) -> Result<&[u8; ATTESTATION_PRIVATE_KEY_LENGTH], Ctap2StatusCode> {
|
) -> Result<Option<&[u8; ATTESTATION_PRIVATE_KEY_LENGTH]>, Ctap2StatusCode> {
|
||||||
let (_, entry) = self
|
let data = match self.store.find_one(&Key::AttestationPrivateKey) {
|
||||||
.store
|
None => return Ok(None),
|
||||||
.find_one(&Key::AttestationPrivateKey)
|
Some((_, entry)) => entry.data,
|
||||||
.ok_or(Ctap2StatusCode::CTAP2_ERR_VENDOR_INTERNAL_ERROR)?;
|
};
|
||||||
let data = entry.data;
|
|
||||||
if data.len() != ATTESTATION_PRIVATE_KEY_LENGTH {
|
if data.len() != ATTESTATION_PRIVATE_KEY_LENGTH {
|
||||||
return Err(Ctap2StatusCode::CTAP2_ERR_VENDOR_INTERNAL_ERROR);
|
return Err(Ctap2StatusCode::CTAP2_ERR_VENDOR_INTERNAL_ERROR);
|
||||||
}
|
}
|
||||||
Ok(array_ref!(data, 0, ATTESTATION_PRIVATE_KEY_LENGTH))
|
Ok(Some(array_ref!(data, 0, ATTESTATION_PRIVATE_KEY_LENGTH)))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn attestation_certificate(&self) -> Result<Vec<u8>, Ctap2StatusCode> {
|
pub fn attestation_certificate(&self) -> Result<Option<Vec<u8>>, Ctap2StatusCode> {
|
||||||
let (_, entry) = self
|
let data = match self.store.find_one(&Key::AttestationCertificate) {
|
||||||
.store
|
None => return Ok(None),
|
||||||
.find_one(&Key::AttestationCertificate)
|
Some((_, entry)) => entry.data,
|
||||||
.ok_or(Ctap2StatusCode::CTAP2_ERR_VENDOR_INTERNAL_ERROR)?;
|
};
|
||||||
Ok(entry.data.to_vec())
|
Ok(Some(data.to_vec()))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn aaguid(&self) -> Result<&[u8; AAGUID_LENGTH], Ctap2StatusCode> {
|
pub fn aaguid(&self) -> Result<&[u8; AAGUID_LENGTH], Ctap2StatusCode> {
|
||||||
|
|||||||
Reference in New Issue
Block a user