Add setter functions and fix tests
This commit is contained in:
@@ -225,32 +225,16 @@ impl PersistentStore {
|
|||||||
// The following 3 entries are meant to be written by vendor-specific commands.
|
// The following 3 entries are meant to be written by vendor-specific commands.
|
||||||
if USE_BATCH_ATTESTATION {
|
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.set_attestation_private_key(key_material::ATTESTATION_PRIVATE_KEY)
|
||||||
.insert(StoreEntry {
|
|
||||||
tag: ATTESTATION_PRIVATE_KEY,
|
|
||||||
data: key_material::ATTESTATION_PRIVATE_KEY,
|
|
||||||
sensitive: false,
|
|
||||||
})
|
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
if self.store.find_one(&Key::AttestationCertificate).is_none() {
|
if self.store.find_one(&Key::AttestationCertificate).is_none() {
|
||||||
self.store
|
self.set_attestation_certificate(key_material::ATTESTATION_CERTIFICATE)
|
||||||
.insert(StoreEntry {
|
|
||||||
tag: ATTESTATION_CERTIFICATE,
|
|
||||||
data: key_material::ATTESTATION_CERTIFICATE,
|
|
||||||
sensitive: false,
|
|
||||||
})
|
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if self.store.find_one(&Key::Aaguid).is_none() {
|
if self.store.find_one(&Key::Aaguid).is_none() {
|
||||||
self.store
|
self.set_aaguid(key_material::AAGUID).unwrap();
|
||||||
.insert(StoreEntry {
|
|
||||||
tag: AAGUID,
|
|
||||||
data: key_material::AAGUID,
|
|
||||||
sensitive: false,
|
|
||||||
})
|
|
||||||
.unwrap();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -448,6 +432,22 @@ impl PersistentStore {
|
|||||||
Ok(Some(array_ref!(data, 0, ATTESTATION_PRIVATE_KEY_LENGTH)))
|
Ok(Some(array_ref!(data, 0, ATTESTATION_PRIVATE_KEY_LENGTH)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_attestation_private_key(
|
||||||
|
&mut self,
|
||||||
|
attestation_private_key: &[u8; ATTESTATION_PRIVATE_KEY_LENGTH],
|
||||||
|
) -> Result<(), Ctap2StatusCode> {
|
||||||
|
let entry = StoreEntry {
|
||||||
|
tag: ATTESTATION_PRIVATE_KEY,
|
||||||
|
data: attestation_private_key,
|
||||||
|
sensitive: false,
|
||||||
|
};
|
||||||
|
match self.store.find_one(&Key::AttestationPrivateKey) {
|
||||||
|
None => self.store.insert(entry)?,
|
||||||
|
Some((index, _)) => self.store.replace(index, entry)?,
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn attestation_certificate(&self) -> Result<Option<Vec<u8>>, Ctap2StatusCode> {
|
pub fn attestation_certificate(&self) -> Result<Option<Vec<u8>>, Ctap2StatusCode> {
|
||||||
let data = match self.store.find_one(&Key::AttestationCertificate) {
|
let data = match self.store.find_one(&Key::AttestationCertificate) {
|
||||||
None => return Ok(None),
|
None => return Ok(None),
|
||||||
@@ -456,6 +456,22 @@ impl PersistentStore {
|
|||||||
Ok(Some(data.to_vec()))
|
Ok(Some(data.to_vec()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_attestation_certificate(
|
||||||
|
&mut self,
|
||||||
|
attestation_certificate: &[u8],
|
||||||
|
) -> Result<(), Ctap2StatusCode> {
|
||||||
|
let entry = StoreEntry {
|
||||||
|
tag: ATTESTATION_CERTIFICATE,
|
||||||
|
data: attestation_certificate,
|
||||||
|
sensitive: false,
|
||||||
|
};
|
||||||
|
match self.store.find_one(&Key::AttestationCertificate) {
|
||||||
|
None => self.store.insert(entry)?,
|
||||||
|
Some((index, _)) => self.store.replace(index, entry)?,
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn aaguid(&self) -> Result<&[u8; AAGUID_LENGTH], Ctap2StatusCode> {
|
pub fn aaguid(&self) -> Result<&[u8; AAGUID_LENGTH], Ctap2StatusCode> {
|
||||||
let (_, entry) = self
|
let (_, entry) = self
|
||||||
.store
|
.store
|
||||||
@@ -468,6 +484,19 @@ impl PersistentStore {
|
|||||||
Ok(array_ref!(data, 0, AAGUID_LENGTH))
|
Ok(array_ref!(data, 0, AAGUID_LENGTH))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_aaguid(&mut self, aaguid: &[u8; AAGUID_LENGTH]) -> Result<(), Ctap2StatusCode> {
|
||||||
|
let entry = StoreEntry {
|
||||||
|
tag: AAGUID,
|
||||||
|
data: aaguid,
|
||||||
|
sensitive: false,
|
||||||
|
};
|
||||||
|
match self.store.find_one(&Key::Aaguid) {
|
||||||
|
None => self.store.insert(entry)?,
|
||||||
|
Some((index, _)) => self.store.replace(index, entry)?,
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn reset(&mut self, rng: &mut impl Rng256) {
|
pub fn reset(&mut self, rng: &mut impl Rng256) {
|
||||||
loop {
|
loop {
|
||||||
let index = {
|
let index = {
|
||||||
@@ -783,25 +812,33 @@ mod test {
|
|||||||
let mut rng = ThreadRng256 {};
|
let mut rng = ThreadRng256 {};
|
||||||
let mut persistent_store = PersistentStore::new(&mut rng);
|
let mut persistent_store = PersistentStore::new(&mut rng);
|
||||||
|
|
||||||
// The persistent keys are initialized on a fresh store.
|
// Make sure the attestation are absent. There is no batch attestation in tests.
|
||||||
assert_eq!(
|
assert!(persistent_store
|
||||||
persistent_store.attestation_private_key().unwrap(),
|
.attestation_private_key()
|
||||||
key_material::ATTESTATION_PRIVATE_KEY
|
.unwrap()
|
||||||
);
|
.is_none());
|
||||||
assert_eq!(
|
assert!(persistent_store
|
||||||
persistent_store.attestation_certificate().unwrap(),
|
.attestation_certificate()
|
||||||
key_material::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);
|
assert_eq!(persistent_store.aaguid().unwrap(), key_material::AAGUID);
|
||||||
|
|
||||||
// The persistent keys stay initialized and preserve their value after a reset.
|
// The persistent keys stay initialized and preserve their value after a reset.
|
||||||
persistent_store.reset(&mut rng);
|
persistent_store.reset(&mut rng);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
persistent_store.attestation_private_key().unwrap(),
|
persistent_store.attestation_private_key().unwrap().unwrap(),
|
||||||
key_material::ATTESTATION_PRIVATE_KEY
|
key_material::ATTESTATION_PRIVATE_KEY
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
persistent_store.attestation_certificate().unwrap(),
|
persistent_store.attestation_certificate().unwrap().unwrap(),
|
||||||
key_material::ATTESTATION_CERTIFICATE
|
key_material::ATTESTATION_CERTIFICATE
|
||||||
);
|
);
|
||||||
assert_eq!(persistent_store.aaguid().unwrap(), key_material::AAGUID);
|
assert_eq!(persistent_store.aaguid().unwrap(), key_material::AAGUID);
|
||||||
|
|||||||
Reference in New Issue
Block a user