Write out the BCC when signing

We don't use it yet, but this is a helpful first step.

Bug: 225177477
Test: composd_cmd staged-apex-compile
Test: See /data/misc/apexdata/com.android.compos/current/bcc
Change-Id: I81daaa9f8e1bb3e81cea0bcfddb8f0455c0d3c21
diff --git a/compos/aidl/com/android/compos/ICompOsService.aidl b/compos/aidl/com/android/compos/ICompOsService.aidl
index ef48ccf..48a46b1 100644
--- a/compos/aidl/com/android/compos/ICompOsService.aidl
+++ b/compos/aidl/com/android/compos/ICompOsService.aidl
@@ -55,4 +55,11 @@
      * (https://datatracker.ietf.org/doc/html/rfc8032#section-5.1.5).
      */
     byte[] getPublicKey();
+
+    /**
+     * Returns the attestation certificate chain of the current VM. The result is in the form of a
+     * CBOR encoded Boot Certificate Chain (BCC) as defined in
+     * hardware/interfaces/security/dice/aidl/android/hardware/security/dice/Bcc.aidl.
+     */
+    byte[] getAttestationChain();
 }
diff --git a/compos/compos_key_helper/compos_key_main.cpp b/compos/compos_key_helper/compos_key_main.cpp
index a0d0b18..9ba9f8d 100644
--- a/compos/compos_key_helper/compos_key_main.cpp
+++ b/compos/compos_key_helper/compos_key_main.cpp
@@ -25,6 +25,7 @@
 
 #include "compos_key.h"
 
+using aidl::android::hardware::security::dice::Bcc;
 using aidl::android::hardware::security::dice::BccHandover;
 using aidl::android::hardware::security::dice::InputValues;
 using aidl::android::security::dice::IDiceNode;
@@ -68,6 +69,30 @@
     return 0;
 }
 
+int write_bcc() {
+    ndk::SpAIBinder binder{AServiceManager_getService("android.security.dice.IDiceNode")};
+    auto dice_node = IDiceNode::fromBinder(binder);
+    if (!dice_node) {
+        LOG(ERROR) << "Unable to connect to IDiceNode";
+        return 1;
+    }
+
+    const std::vector<InputValues> empty_input_values;
+    Bcc bcc;
+    auto status = dice_node->getAttestationChain(empty_input_values, &bcc);
+    if (!status.isOk()) {
+        LOG(ERROR) << "GetAttestationChain failed: " << status.getDescription();
+        return 1;
+    }
+
+    if (!WriteFully(STDOUT_FILENO, bcc.data.data(), bcc.data.size())) {
+        PLOG(ERROR) << "Write failed";
+        return 1;
+    }
+
+    return 0;
+}
+
 int sign_input() {
     std::string to_sign;
     if (!ReadFdToString(STDIN_FILENO, &to_sign)) {
@@ -103,6 +128,8 @@
     if (argc == 2) {
         if (argv[1] == "public_key"sv) {
             return write_public_key();
+        } else if (argv[1] == "bcc"sv) {
+            return write_bcc();
         } else if (argv[1] == "sign"sv) {
             return sign_input();
         }
diff --git a/compos/composd/src/instance_starter.rs b/compos/composd/src/instance_starter.rs
index 4873d7a..f899497 100644
--- a/compos/composd/src/instance_starter.rs
+++ b/compos/composd/src/instance_starter.rs
@@ -87,7 +87,13 @@
         let _ = fs::remove_file(&self.idsig);
         let _ = fs::remove_file(&self.idsig_manifest_apk);
 
-        self.start_vm(virtualization_service)
+        let instance = self.start_vm(virtualization_service)?;
+
+        // Retrieve the VM's attestation chain as a BCC and save it in the instance directory.
+        let bcc = instance.service.getAttestationChain().context("Getting attestation chain")?;
+        fs::write(self.instance_root.join("bcc"), bcc).context("Writing BCC")?;
+
+        Ok(instance)
     }
 
     fn start_vm(
diff --git a/compos/src/compos_key.rs b/compos/src/compos_key.rs
index eb6248f..faa9d67 100644
--- a/compos/src/compos_key.rs
+++ b/compos/src/compos_key.rs
@@ -21,8 +21,16 @@
 const COMPOS_KEY_HELPER_PATH: &str = "/apex/com.android.compos/bin/compos_key_helper";
 
 pub fn get_public_key() -> Result<Vec<u8>> {
+    get_data_from_helper("public_key")
+}
+
+pub fn get_attestation_chain() -> Result<Vec<u8>> {
+    get_data_from_helper("bcc")
+}
+
+fn get_data_from_helper(command: &str) -> Result<Vec<u8>> {
     let child = Command::new(COMPOS_KEY_HELPER_PATH)
-        .arg("public_key")
+        .arg(command)
         .stdin(Stdio::null())
         .stdout(Stdio::piped())
         .stderr(Stdio::piped())
diff --git a/compos/src/compsvc.rs b/compos/src/compsvc.rs
index 3a794ee..e21aa7d 100644
--- a/compos/src/compsvc.rs
+++ b/compos/src/compsvc.rs
@@ -86,6 +86,10 @@
     fn getPublicKey(&self) -> BinderResult<Vec<u8>> {
         to_binder_result(compos_key::get_public_key())
     }
+
+    fn getAttestationChain(&self) -> BinderResult<Vec<u8>> {
+        to_binder_result(compos_key::get_attestation_chain())
+    }
 }
 
 fn add_artifacts(target_dir: &Path, artifact_signer: &mut ArtifactSigner) -> Result<()> {