Merge "Make batch attestation keys/certs optional" into main
diff --git a/CHANGELOG.md b/CHANGELOG.md
index e8ce915..fcc33c8 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,9 @@
 where "significant" means things that are likely to affect vendors whose KeyMint implementations are
 based on this codebase.
 
+- The `sign_info` field in `kmr_ta::device::Implementation` is now an `Option`, reflecting that
+  batch attestation is now optional (devices can be RKP-only, as indicated by the
+  `remote_provisioning.tee.rkp_only` system property).
 - The `BootInfo` structure passed to `kmr_ta::KeyMintTa::set_boot_info()` method did not make clear
   what the contents of the `verified_boot_key` field should be: the key itself, or a SHA-256 hash of
   the key.  The KeyMint implementation has been modified to cope with either, using a SHA-256 hash
diff --git a/README.md b/README.md
index 3b1f412..b3257b6 100644
--- a/README.md
+++ b/README.md
@@ -176,7 +176,7 @@
 **Checklist:**
 
 - [ ] Root key retrieval implementation.
-- [ ] Attestation key / chain retrieval implementation.
+- [ ] Attestation key / chain retrieval implementation (optional).
 - [ ] Attestation device ID retrieval implementation.
 - [ ] Retrieval of BCC and DICE artefacts.
 - [ ] Secure storage implementation (optional).
diff --git a/ta/src/device.rs b/ta/src/device.rs
index ade2574..5c1c199 100644
--- a/ta/src/device.rs
+++ b/ta/src/device.rs
@@ -38,7 +38,7 @@
     pub keys: Box<dyn RetrieveKeyMaterial>,
 
     /// Retrieval of attestation certificate signing information.
-    pub sign_info: Box<dyn RetrieveCertSigningInfo>,
+    pub sign_info: Option<Box<dyn RetrieveCertSigningInfo>>,
 
     /// Retrieval of attestation ID information.
     pub attest_ids: Option<Box<dyn RetrieveAttestationIds>>,
diff --git a/ta/src/keys.rs b/ta/src/keys.rs
index 0133aaf..c9f563f 100644
--- a/ta/src/keys.rs
+++ b/ta/src/keys.rs
@@ -105,13 +105,16 @@
         &self,
         key_type: device::SigningKeyType,
     ) -> Result<SigningInfo, Error> {
+        let sign_info = self.dev.sign_info.as_ref().ok_or_else(|| {
+            km_err!(AttestationKeysNotProvisioned, "batch attestation keys not available")
+        })?;
         // Retrieve the chain and issuer information, which is cached after first retrieval.
         let mut attestation_chain_info = self.attestation_chain_info.borrow_mut();
         let chain_info = match attestation_chain_info.entry(key_type) {
             Entry::Occupied(e) => e.into_mut(),
             Entry::Vacant(e) => {
                 // Retrieve and store the cert chain information (as this is public).
-                let chain = self.dev.sign_info.cert_chain(key_type)?;
+                let chain = sign_info.cert_chain(key_type)?;
                 let issuer =
                     cert::extract_subject(chain.first().ok_or_else(|| {
                         km_err!(KeymintNotConfigured, "empty attestation chain")
@@ -121,7 +124,7 @@
         };
 
         // Retrieve the signing key information (which will be dropped when signing is done).
-        let signing_key = self.dev.sign_info.signing_key(key_type)?;
+        let signing_key = sign_info.signing_key(key_type)?;
         Ok(SigningInfo {
             attestation_info: None,
             signing_key,