Sign artifacts after compilation
If compilation succeeds, pass over all the artifacts we generated and
produce an OdsignInfo file with all the names and digests and a
signature of it using the CompOS key.
Various refactorings along the way to make it eaiser:
- Extract the odrefresh ExitCode enum for reuse
- Extracted a Signer, distinct from an ArtifactSigner
- Defined OdrefreshContext to stop the linter complaining about a
function with >7 arguments.
Also added more debugging to help fix my various silly mistakes.
Bug: 161471326
Test: composd_cmd forced-odrefresh -> signature file produced
Change-Id: Ia6a6abd9e28158f4767e7752727635087f9bb566
diff --git a/compos/src/artifact_signer.rs b/compos/src/artifact_signer.rs
index 54b8d7a..ce32d6b 100644
--- a/compos/src/artifact_signer.rs
+++ b/compos/src/artifact_signer.rs
@@ -19,7 +19,7 @@
#![allow(dead_code)] // Will be used soon
-use crate::compos_key_service::CompOsKeyService;
+use crate::compos_key_service::Signer;
use crate::fsverity;
use anyhow::{anyhow, Context, Result};
use odsign_proto::odsign_info::OdsignInfo;
@@ -27,31 +27,25 @@
use std::fs::File;
use std::io::Write;
use std::os::unix::io::AsRawFd;
-use std::path::{Path, PathBuf};
+use std::path::Path;
const TARGET_DIRECTORY: &str = "/data/misc/apexdata/com.android.art/dalvik-cache";
const SIGNATURE_EXTENSION: &str = ".signature";
/// Accumulates and then signs information about generated artifacts.
pub struct ArtifactSigner<'a> {
- key_blob: Vec<u8>,
- key_service: &'a CompOsKeyService,
- base_directory: PathBuf,
+ base_directory: &'a Path,
file_digests: Vec<(String, String)>, // (File name, digest in hex)
}
impl<'a> ArtifactSigner<'a> {
/// base_directory specifies the directory under which the artifacts are currently located;
/// they will eventually be moved under TARGET_DIRECTORY once they are verified and activated.
- pub fn new(
- key_blob: Vec<u8>,
- key_service: &'a CompOsKeyService,
- base_directory: PathBuf,
- ) -> Self {
- ArtifactSigner { key_blob, key_service, base_directory, file_digests: Vec::new() }
+ pub fn new(base_directory: &'a Path) -> Self {
+ Self { base_directory, file_digests: Vec::new() }
}
- pub fn add_artifact(&mut self, path: PathBuf) -> Result<()> {
+ pub fn add_artifact(&mut self, path: &Path) -> Result<()> {
// The path we store is where the file will be when it is verified, not where it is now.
let suffix = path
.strip_prefix(&self.base_directory)
@@ -59,7 +53,7 @@
let target_path = Path::new(TARGET_DIRECTORY).join(suffix);
let target_path = target_path.to_str().ok_or_else(|| anyhow!("Invalid path"))?;
- let file = File::open(&path)?;
+ let file = File::open(path).with_context(|| format!("Opening {}", path.display()))?;
let digest = fsverity::measure(file.as_raw_fd())?;
let digest = to_hex_string(&digest);
@@ -69,12 +63,12 @@
/// Consume this ArtifactSigner and write details of all its artifacts to the given path,
/// with accompanying sigature file.
- pub fn write_info_and_signature(self, info_path: &Path) -> Result<()> {
+ pub fn write_info_and_signature(self, signer: Signer, info_path: &Path) -> Result<()> {
let mut info = OdsignInfo::new();
info.mut_file_hashes().extend(self.file_digests.into_iter());
let bytes = info.write_to_bytes()?;
- let signature = self.key_service.sign(&self.key_blob, &bytes)?;
+ let signature = signer.sign(&bytes)?;
let mut file = File::create(info_path)?;
file.write_all(&bytes)?;