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
This commit is contained in:
Alan Stokes 2022-03-21 14:02:09 +00:00
parent 33b12ca8f7
commit 5430ecaaa2
5 changed files with 54 additions and 2 deletions

View File

@ -55,4 +55,11 @@ interface ICompOsService {
* (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();
}

View File

@ -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 @@ int write_public_key() {
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 @@ int main(int argc, char** argv) {
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();
}

View File

@ -87,7 +87,13 @@ impl InstanceStarter {
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(

View File

@ -21,8 +21,16 @@ use std::process::{Command, Stdio};
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())

View File

@ -86,6 +86,10 @@ impl ICompOsService for CompOsService {
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<()> {