Try to delete entire UdsCerts file if not empty am: c94e70a634
Original change: https://android-review.googlesource.com/c/trusty/app/keymint/+/3261775
Change-Id: I646de6cebe5238380185159491c272251e123319
Signed-off-by: Automerger Merge Worker <[email protected]>
diff --git a/ipc_manager.rs b/ipc_manager.rs
index 70dbf93..c4b8996 100644
--- a/ipc_manager.rs
+++ b/ipc_manager.rs
@@ -390,7 +390,7 @@
Ok(TrustyPerformOpRsp::AppendUdsCertificate(AppendUdsCertificateResponse {}))
}
TrustyPerformOpReq::ClearUdsCertificate(..) => {
- secure_storage_manager::clear_uds_cert_chain()?;
+ secure_storage_manager::maybe_delete_uds_cert_chain()?;
Ok(TrustyPerformOpRsp::ClearUdsCertificate(ClearUdsCertificateResponse {}))
}
}
diff --git a/secure_storage_manager.rs b/secure_storage_manager.rs
index 8d7795c..be7100e 100644
--- a/secure_storage_manager.rs
+++ b/secure_storage_manager.rs
@@ -170,6 +170,22 @@
OpenSecureFile::new(KM_RKP_UDS_CERT_FILENAME)
}
+/// Delete the existing UDS certificates file
+fn delete_uds_cert_file() -> Result<(), Error> {
+ let mut session = Session::new(Port::TamperProof, true).map_err(|e| {
+ km_err!(SecureHwCommunicationFailed, "failed to connect to storage port: {:?}", e)
+ })?;
+ session.remove(KM_RKP_UDS_CERT_FILENAME).map_err(|e| {
+ km_err!(
+ SecureHwCommunicationFailed,
+ "failed to delete {:?}: {:?}",
+ KM_RKP_UDS_CERT_FILENAME,
+ e
+ )
+ })?;
+ Ok(())
+}
+
fn write_protobuf_to_uds_cert_file(uds_cert_pb: UdsCerts) -> Result<(), Error> {
let serialized_buffer = uds_cert_pb.write_to_bytes().map_err(|e| {
km_err!(SecureHwCommunicationFailed, "couldn't serialize UdsCerts: {:?}", e)
@@ -249,22 +265,18 @@
write_protobuf_to_attestation_key_file(algorithm, attestation_key_data)
}
-/// Tries to read the file containing the UdsCert and delete the certificate section.
-pub(crate) fn clear_uds_cert_chain() -> Result<(), Error> {
+/// Tries to read the file containing the UdsCert. It's fine if that file is clear, or will try to
+/// delete it. After this call, all "read" operation will get a default <UdsCerts> object.
+pub(crate) fn maybe_delete_uds_cert_chain() -> Result<(), Error> {
let mut uds_cert_pb = read_uds_cert_content()?;
if uds_cert_pb.get_certs().is_empty() {
// No certs found, nothing to delete.
return Ok(());
}
- uds_cert_pb.clear_certs();
- write_protobuf_to_uds_cert_file(uds_cert_pb)?;
+ delete_uds_cert_file()?;
uds_cert_pb = read_uds_cert_content()?;
let cert_chain_len = uds_cert_pb.get_certs().len();
if cert_chain_len != 0 {
- error!(
- "Couldn't delete all certificates in {:?}, found {}",
- KM_RKP_UDS_CERT_FILENAME, cert_chain_len
- );
return Err(km_err!(
UnknownError,
"couldn't delete all certificates, found {}",
@@ -619,6 +631,12 @@
session.open_file(&file_name, OpenMode::Open).is_ok()
}
+ fn check_uds_certs_file_exists() -> bool {
+ let mut session =
+ Session::new(Port::TamperProof, true).expect("Couldn't connect to storage");
+ session.open_file(KM_RKP_UDS_CERT_FILENAME, OpenMode::Open).is_ok()
+ }
+
fn delete_attestation_id_file() {
let mut session =
Session::new(Port::TamperProof, true).expect("Couldn't connect to storage");
@@ -940,6 +958,66 @@
// This test should be run manually as it writes to storage.
// #[test]
+ fn provision_uds_certs_works() {
+ if check_uds_certs_file_exists() {
+ delete_uds_cert_file().expect("Couldn't delete UdsCerts file");
+ }
+ let cert1 = [b'a'; 500].as_slice();
+ let cert2 = [b'b'; 500].as_slice();
+ let cert3 = [b'c'; 500].as_slice();
+ let certs = [cert1, cert2, cert3];
+ for cert_data in certs.iter() {
+ append_uds_cert_chain(cert_data).expect("Couldn't provision UdsCerts");
+ }
+ expect!(
+ append_uds_cert_chain(cert3).is_err(),
+ "Shouldn't be able to add more certificates"
+ );
+
+ let read_uds_certs = read_uds_cert().expect("Couldn't read attestation key");
+ for i in 0..certs.len() {
+ expect_eq!(certs[i], read_uds_certs[i].encoded_certificate, "Uds Certs didn't match");
+ }
+
+ delete_uds_cert_file().expect("Couldn't delete UdsCerts file");
+ }
+
+ // This test should be run manually as it writes to storage.
+ // #[test]
+ fn clear_uds_certs_works() {
+ if check_uds_certs_file_exists() {
+ delete_uds_cert_file().expect("Couldn't delete UdsCerts file");
+ }
+ let cert = [b'a'; 500].as_slice();
+ append_uds_cert_chain(cert).expect("Couldn't provision certificate");
+ let read_certs = read_uds_cert().expect("Couldn't get UdsCerts from storage");
+ expect_eq!(read_certs.len(), 1, "Didn't get all certificates back");
+
+ maybe_delete_uds_cert_chain().expect("Couldn't delete UdsCerts file");
+
+ expect!(read_uds_cert().is_err(), "Certificates were not deleted");
+ }
+
+ // This test should be run manually as it writes to storage.
+ // #[test]
+ fn get_clear_uds_certs_after_delete_works() {
+ if check_uds_certs_file_exists() {
+ delete_uds_cert_file().expect("Couldn't delete UdsCerts file");
+ }
+ let cert = [b'a'; 500].as_slice();
+ append_uds_cert_chain(cert).expect("Couldn't provision certificate");
+ let read_certs = read_uds_cert().expect("Couldn't get UdsCerts from storage");
+ expect_eq!(read_certs.len(), 1, "Didn't get all certificates back");
+
+ maybe_delete_uds_cert_chain().expect("couldn't delete UdsCerts file");
+
+ let expected_clear_uds_cert =
+ read_uds_cert_content().expect("Couldn't get a default UdsCerts objec");
+ expect_eq!(expected_clear_uds_cert.certs.len(), 0, "Not a clear UdsCerts object");
+ }
+
+ // This test should be run manually as it writes to storage.
+ // #[test]
fn unprovisioned_attestation_ids_do_not_error() {
if check_attestation_id_file_exists() {
delete_attestation_id_file();