Only write attestation if compiled with batch attestation

This commit is contained in:
Julien Cretin
2020-06-02 11:00:26 +02:00
parent a195cfec02
commit 5f8cb116a5
2 changed files with 50 additions and 43 deletions

View File

@@ -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,

View File

@@ -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> {