Always insert attestation material in the store
This commit is contained in:
@@ -12,10 +12,13 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
pub const AAGUID: &[u8; 16] = include_bytes!(concat!(env!("OUT_DIR"), "/opensk_aaguid.bin"));
|
||||
pub const ATTESTATION_PRIVATE_KEY_LENGTH: usize = 32;
|
||||
pub const AAGUID_LENGTH: usize = 16;
|
||||
|
||||
pub const AAGUID: &[u8; AAGUID_LENGTH] = include_bytes!(concat!(env!("OUT_DIR"), "/opensk_aaguid.bin"));
|
||||
|
||||
pub const ATTESTATION_CERTIFICATE: &[u8] =
|
||||
include_bytes!(concat!(env!("OUT_DIR"), "/opensk_cert.bin"));
|
||||
|
||||
pub const ATTESTATION_PRIVATE_KEY: &[u8; 32] =
|
||||
pub const ATTESTATION_PRIVATE_KEY: &[u8; ATTESTATION_PRIVATE_KEY_LENGTH] =
|
||||
include_bytes!(concat!(env!("OUT_DIR"), "/opensk_pkey.bin"));
|
||||
|
||||
@@ -15,9 +15,9 @@
|
||||
#[cfg(feature = "with_ctap2_1")]
|
||||
use crate::ctap::data_formats::{extract_array, extract_text_string};
|
||||
use crate::ctap::data_formats::{CredentialProtectionPolicy, PublicKeyCredentialSource};
|
||||
use crate::ctap::key_material;
|
||||
use crate::ctap::pin_protocol_v1::PIN_AUTH_LENGTH;
|
||||
use crate::ctap::status_code::Ctap2StatusCode;
|
||||
use crate::ctap::{key_material, USE_BATCH_ATTESTATION};
|
||||
use crate::embedded_flash::{self, StoreConfig, StoreEntry, StoreError};
|
||||
use alloc::string::String;
|
||||
#[cfg(any(test, feature = "ram_storage", feature = "with_ctap2_1"))]
|
||||
@@ -76,8 +76,6 @@ const MIN_PIN_LENGTH_RP_IDS: usize = 9;
|
||||
const NUM_TAGS: usize = 10;
|
||||
|
||||
const MAX_PIN_RETRIES: u8 = 8;
|
||||
const ATTESTATION_PRIVATE_KEY_LENGTH: usize = 32;
|
||||
const AAGUID_LENGTH: usize = 16;
|
||||
#[cfg(feature = "with_ctap2_1")]
|
||||
const DEFAULT_MIN_PIN_LENGTH: u8 = 4;
|
||||
// TODO(kaczmarczyck) use this for the minPinLength extension
|
||||
@@ -231,17 +229,16 @@ impl PersistentStore {
|
||||
})
|
||||
.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() {
|
||||
self.set_attestation_private_key(key_material::ATTESTATION_PRIVATE_KEY)
|
||||
.unwrap();
|
||||
}
|
||||
if self.store.find_one(&Key::AttestationCertificate).is_none() {
|
||||
self.set_attestation_certificate(key_material::ATTESTATION_CERTIFICATE)
|
||||
.unwrap();
|
||||
}
|
||||
// The following 2 entries are meant to be written by vendor-specific commands.
|
||||
if self.store.find_one(&Key::AttestationPrivateKey).is_none() {
|
||||
self.set_attestation_private_key(key_material::ATTESTATION_PRIVATE_KEY)
|
||||
.unwrap();
|
||||
}
|
||||
if self.store.find_one(&Key::AttestationCertificate).is_none() {
|
||||
self.set_attestation_certificate(key_material::ATTESTATION_CERTIFICATE)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
if self.store.find_one(&Key::Aaguid).is_none() {
|
||||
self.set_aaguid(key_material::AAGUID).unwrap();
|
||||
}
|
||||
@@ -525,20 +522,24 @@ impl PersistentStore {
|
||||
|
||||
pub fn attestation_private_key(
|
||||
&self,
|
||||
) -> Result<Option<&[u8; ATTESTATION_PRIVATE_KEY_LENGTH]>, Ctap2StatusCode> {
|
||||
) -> Result<Option<&[u8; key_material::ATTESTATION_PRIVATE_KEY_LENGTH]>, Ctap2StatusCode> {
|
||||
let data = match self.store.find_one(&Key::AttestationPrivateKey) {
|
||||
None => return Ok(None),
|
||||
Some((_, entry)) => entry.data,
|
||||
};
|
||||
if data.len() != ATTESTATION_PRIVATE_KEY_LENGTH {
|
||||
if data.len() != key_material::ATTESTATION_PRIVATE_KEY_LENGTH {
|
||||
return Err(Ctap2StatusCode::CTAP2_ERR_VENDOR_INTERNAL_ERROR);
|
||||
}
|
||||
Ok(Some(array_ref!(data, 0, ATTESTATION_PRIVATE_KEY_LENGTH)))
|
||||
Ok(Some(array_ref!(
|
||||
data,
|
||||
0,
|
||||
key_material::ATTESTATION_PRIVATE_KEY_LENGTH
|
||||
)))
|
||||
}
|
||||
|
||||
pub fn set_attestation_private_key(
|
||||
&mut self,
|
||||
attestation_private_key: &[u8; ATTESTATION_PRIVATE_KEY_LENGTH],
|
||||
attestation_private_key: &[u8; key_material::ATTESTATION_PRIVATE_KEY_LENGTH],
|
||||
) -> Result<(), Ctap2StatusCode> {
|
||||
let entry = StoreEntry {
|
||||
tag: ATTESTATION_PRIVATE_KEY,
|
||||
@@ -576,19 +577,22 @@ impl PersistentStore {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn aaguid(&self) -> Result<[u8; AAGUID_LENGTH], Ctap2StatusCode> {
|
||||
pub fn aaguid(&self) -> Result<[u8; key_material::AAGUID_LENGTH], Ctap2StatusCode> {
|
||||
let (_, entry) = self
|
||||
.store
|
||||
.find_one(&Key::Aaguid)
|
||||
.ok_or(Ctap2StatusCode::CTAP2_ERR_VENDOR_INTERNAL_ERROR)?;
|
||||
let data = entry.data;
|
||||
if data.len() != AAGUID_LENGTH {
|
||||
if data.len() != key_material::AAGUID_LENGTH {
|
||||
return Err(Ctap2StatusCode::CTAP2_ERR_VENDOR_INTERNAL_ERROR);
|
||||
}
|
||||
Ok(*array_ref![data, 0, AAGUID_LENGTH])
|
||||
Ok(*array_ref![data, 0, key_material::AAGUID_LENGTH])
|
||||
}
|
||||
|
||||
pub fn set_aaguid(&mut self, aaguid: &[u8; AAGUID_LENGTH]) -> Result<(), Ctap2StatusCode> {
|
||||
pub fn set_aaguid(
|
||||
&mut self,
|
||||
aaguid: &[u8; key_material::AAGUID_LENGTH],
|
||||
) -> Result<(), Ctap2StatusCode> {
|
||||
let entry = StoreEntry {
|
||||
tag: AAGUID,
|
||||
data: aaguid,
|
||||
@@ -996,23 +1000,6 @@ mod test {
|
||||
let mut rng = ThreadRng256 {};
|
||||
let mut persistent_store = PersistentStore::new(&mut rng);
|
||||
|
||||
// Make sure the attestation are absent. There is no batch attestation in tests.
|
||||
assert!(persistent_store
|
||||
.attestation_private_key()
|
||||
.unwrap()
|
||||
.is_none());
|
||||
assert!(persistent_store
|
||||
.attestation_certificate()
|
||||
.unwrap()
|
||||
.is_none());
|
||||
|
||||
// Make sure the persistent keys are initialized.
|
||||
persistent_store
|
||||
.set_attestation_private_key(key_material::ATTESTATION_PRIVATE_KEY)
|
||||
.unwrap();
|
||||
persistent_store
|
||||
.set_attestation_certificate(key_material::ATTESTATION_CERTIFICATE)
|
||||
.unwrap();
|
||||
assert_eq!(&persistent_store.aaguid().unwrap(), key_material::AAGUID);
|
||||
|
||||
// The persistent keys stay initialized and preserve their value after a reset.
|
||||
|
||||
Reference in New Issue
Block a user