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/common/Android.bp b/compos/common/Android.bp
index 5893fd6..7c61d94 100644
--- a/compos/common/Android.bp
+++ b/compos/common/Android.bp
@@ -14,8 +14,10 @@
"libbinder_rpc_unstable_bindgen",
"libbinder_rs",
"liblog_rust",
+ "libnum_traits",
"librustutils",
],
+ proc_macros: ["libnum_derive"],
shared_libs: [
"libbinder_rpc_unstable",
],
diff --git a/compos/common/lib.rs b/compos/common/lib.rs
index 9b07030..5c28379 100644
--- a/compos/common/lib.rs
+++ b/compos/common/lib.rs
@@ -17,6 +17,7 @@
//! Common items used by CompOS server and/or clients
pub mod compos_client;
+pub mod odrefresh;
pub mod timeouts;
/// Special CID indicating "any".
diff --git a/compos/common/odrefresh.rs b/compos/common/odrefresh.rs
new file mode 100644
index 0000000..7838b69
--- /dev/null
+++ b/compos/common/odrefresh.rs
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//! Helpers for running odrefresh
+
+use num_derive::FromPrimitive;
+use num_traits::FromPrimitive;
+
+/// The path to the odrefresh binary
+pub const ODREFRESH_PATH: &str = "/apex/com.android.art/bin/odrefresh";
+
+// TODO: What if this changes?
+const EX_MAX: i8 = 78;
+
+/// The defined odrefresh exit codes - see art/odrefresh/include/odrefresh/odrefresh.h
+#[derive(Debug, PartialEq, Eq, FromPrimitive)]
+#[repr(i8)]
+pub enum ExitCode {
+ /// No compilation required, all artifacts look good
+ Okay = 0i8,
+ /// Compilation required
+ CompilationRequired = EX_MAX + 1,
+ /// New artifacts successfully generated
+ CompilationSuccess = EX_MAX + 2,
+ /// Compilation failed
+ CompilationFailed = EX_MAX + 3,
+ /// Removal of existing invalid artifacts failed
+ CleanupFailed = EX_MAX + 4,
+}
+
+impl ExitCode {
+ /// Map an integer to the corresponding ExitCode enum, if there is one
+ pub fn from_i32(exit_code: i32) -> Option<Self> {
+ FromPrimitive::from_i32(exit_code)
+ }
+}
diff --git a/compos/composd/Android.bp b/compos/composd/Android.bp
index 735b9a5..3190395 100644
--- a/compos/composd/Android.bp
+++ b/compos/composd/Android.bp
@@ -20,13 +20,11 @@
"libcomposd_native_rust",
"libminijail_rust",
"libnix",
- "libnum_traits",
"liblibc",
"liblog_rust",
"librustutils",
"libshared_child",
],
- proc_macros: ["libnum_derive"],
apex_available: [
"com.android.compos",
],
diff --git a/compos/composd/src/compilation_task.rs b/compos/composd/src/compilation_task.rs
index 18f5aac..f82a3e9 100644
--- a/compos/composd/src/compilation_task.rs
+++ b/compos/composd/src/compilation_task.rs
@@ -15,12 +15,13 @@
*/
use crate::instance_starter::CompOsInstance;
-use crate::odrefresh::{self, Odrefresh};
+use crate::odrefresh::Odrefresh;
use android_system_composd::aidl::android::system::composd::{
ICompilationTask::ICompilationTask, ICompilationTaskCallback::ICompilationTaskCallback,
};
use android_system_composd::binder::{Interface, Result as BinderResult, Strong};
use anyhow::Result;
+use compos_common::odrefresh::ExitCode;
use log::{error, warn};
use std::sync::{Arc, Mutex};
use std::thread;
@@ -91,7 +92,7 @@
// We don't do the callback if cancel has already happened.
if let Some(task) = task {
let result = match exit_code {
- Ok(odrefresh::ExitCode::CompilationSuccess) => task.callback.onSuccess(),
+ Ok(ExitCode::CompilationSuccess) => task.callback.onSuccess(),
Ok(exit_code) => {
error!("Unexpected odrefresh result: {:?}", exit_code);
task.callback.onFailure()
diff --git a/compos/composd/src/odrefresh.rs b/compos/composd/src/odrefresh.rs
index d6a3435..2cefab0 100644
--- a/compos/composd/src/odrefresh.rs
+++ b/compos/composd/src/odrefresh.rs
@@ -20,10 +20,9 @@
use anyhow::{bail, Context, Result};
use compos_aidl_interface::aidl::com::android::compos::ICompOsService::ICompOsService;
use compos_aidl_interface::binder::Strong;
+use compos_common::odrefresh::{ExitCode, ODREFRESH_PATH};
use compos_common::timeouts::{need_extra_time, EXTENDED_TIMEOUTS};
use compos_common::VMADDR_CID_ANY;
-use num_derive::FromPrimitive;
-use num_traits::FromPrimitive;
use rustutils::system_properties;
use shared_child::SharedChild;
use std::fs::{File, OpenOptions};
@@ -32,23 +31,8 @@
use std::path::Path;
use std::process::Command;
-// TODO: What if this changes?
-const EX_MAX: i8 = 78;
-
-const ODREFRESH_BIN: &str = "/apex/com.android.art/bin/odrefresh";
const ART_APEX_DATA: &str = "/data/misc/apexdata/com.android.art";
-#[derive(Debug, PartialEq, Eq, FromPrimitive)]
-#[repr(i8)]
-pub enum ExitCode {
- // Copied from art/odrefresh/include/odrefresh/odrefresh.h
- Okay = 0i8,
- CompilationRequired = EX_MAX + 1,
- CompilationSuccess = EX_MAX + 2,
- CompilationFailed = EX_MAX + 3,
- CleanupFailed = EX_MAX + 4,
-}
-
pub struct Odrefresh {
child: SharedChild,
}
@@ -64,7 +48,7 @@
fn spawn_odrefresh(target_dir: &str, compile_arg: &str) -> Result<Self> {
// We don`t need to capture stdout/stderr - odrefresh writes to the log
- let mut cmdline = Command::new(ODREFRESH_BIN);
+ let mut cmdline = Command::new(ODREFRESH_PATH);
if need_extra_time()? {
cmdline
.arg(format!(
@@ -87,7 +71,7 @@
pub fn wait_for_exit(&self) -> Result<ExitCode> {
// No timeout here - but clients can kill the process, which will end the wait.
let status = self.child.wait()?;
- if let Some(exit_code) = status.code().and_then(FromPrimitive::from_i32) {
+ if let Some(exit_code) = status.code().and_then(ExitCode::from_i32) {
Ok(exit_code)
} else {
bail!("odrefresh exited with {}", status)
@@ -122,7 +106,7 @@
)?;
drop(fd_server_raii);
- if let Some(exit_code) = FromPrimitive::from_i8(exit_code) {
+ if let Some(exit_code) = ExitCode::from_i32(exit_code.into()) {
Ok(exit_code)
} else {
bail!("odrefresh exited with {}", exit_code)
diff --git a/compos/composd/src/odrefresh_task.rs b/compos/composd/src/odrefresh_task.rs
index 64565dd..262021c 100644
--- a/compos/composd/src/odrefresh_task.rs
+++ b/compos/composd/src/odrefresh_task.rs
@@ -22,6 +22,7 @@
use android_system_composd::binder::{Interface, Result as BinderResult, Strong};
use anyhow::Result;
use compos_aidl_interface::aidl::com::android::compos::ICompOsService::ICompOsService;
+use compos_common::odrefresh::ExitCode;
use log::{error, warn};
use std::sync::{Arc, Mutex};
use std::thread;
@@ -72,7 +73,7 @@
// We don't do the callback if cancel has already happened.
if let Some(task) = task {
let result = match exit_code {
- Ok(odrefresh::ExitCode::CompilationSuccess) => task.callback.onSuccess(),
+ Ok(ExitCode::CompilationSuccess) => task.callback.onSuccess(),
Ok(exit_code) => {
error!("Unexpected odrefresh result: {:?}", exit_code);
task.callback.onFailure()
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)?;
diff --git a/compos/src/compilation.rs b/compos/src/compilation.rs
index f8a66c2..cf6f30a 100644
--- a/compos/src/compilation.rs
+++ b/compos/src/compilation.rs
@@ -18,10 +18,12 @@
use log::{debug, error, info};
use minijail::{self, Minijail};
use std::env;
-use std::fs::File;
+use std::fs::{read_dir, File};
use std::os::unix::io::{AsRawFd, RawFd};
use std::path::{Path, PathBuf};
+use crate::artifact_signer::ArtifactSigner;
+use crate::compos_key_service::Signer;
use crate::fsverity;
use authfs_aidl_interface::aidl::com::android::virt::fs::{
AuthFsConfig::{
@@ -34,6 +36,7 @@
};
use authfs_aidl_interface::binder::{ParcelFileDescriptor, Strong};
use compos_aidl_interface::aidl::com::android::compos::FdAnnotation::FdAnnotation;
+use compos_common::odrefresh::ExitCode;
const FD_SERVER_PORT: i32 = 3264; // TODO: support dynamic port
@@ -58,28 +61,51 @@
image: ParcelFileDescriptor,
}
-pub fn odrefresh(
- odrefresh_path: &Path,
- target_dir_name: &str,
+pub struct OdrefreshContext<'a> {
system_dir_fd: i32,
output_dir_fd: i32,
staging_dir_fd: i32,
- zygote_arch: &str,
+ target_dir_name: &'a str,
+ zygote_arch: &'a str,
+}
+
+impl<'a> OdrefreshContext<'a> {
+ pub fn new(
+ system_dir_fd: i32,
+ output_dir_fd: i32,
+ staging_dir_fd: i32,
+ target_dir_name: &'a str,
+ zygote_arch: &'a str,
+ ) -> Result<Self> {
+ if system_dir_fd < 0 || output_dir_fd < 0 || staging_dir_fd < 0 {
+ bail!("The remote FDs are expected to be non-negative");
+ }
+ if zygote_arch != "zygote64" && zygote_arch != "zygote64_32" {
+ bail!("Invalid zygote arch");
+ }
+ Ok(Self { system_dir_fd, output_dir_fd, staging_dir_fd, target_dir_name, zygote_arch })
+ }
+}
+
+pub fn odrefresh(
+ odrefresh_path: &Path,
+ context: OdrefreshContext,
authfs_service: Strong<dyn IAuthFsService>,
-) -> Result<i8> {
+ signer: Signer,
+) -> Result<ExitCode> {
// Mount authfs (via authfs_service). The authfs instance unmounts once the `authfs` variable
// is out of scope.
let authfs_config = AuthFsConfig {
port: FD_SERVER_PORT,
inputDirFdAnnotations: vec![InputDirFdAnnotation {
- fd: system_dir_fd,
+ fd: context.system_dir_fd,
// TODO(206869687): Replace /dev/null with the real path when possible.
manifestPath: "/dev/null".to_string(),
prefix: "/system".to_string(),
}],
outputDirFdAnnotations: vec![
- OutputDirFdAnnotation { fd: output_dir_fd },
- OutputDirFdAnnotation { fd: staging_dir_fd },
+ OutputDirFdAnnotation { fd: context.output_dir_fd },
+ OutputDirFdAnnotation { fd: context.staging_dir_fd },
],
..Default::default()
};
@@ -87,21 +113,21 @@
let mountpoint = PathBuf::from(authfs.getMountPoint()?);
let mut android_root = mountpoint.clone();
- android_root.push(system_dir_fd.to_string());
+ android_root.push(context.system_dir_fd.to_string());
android_root.push("system");
env::set_var("ANDROID_ROOT", &android_root);
+ debug!("ANDROID_ROOT={:?}", &android_root);
- let mut art_apex_data = mountpoint.clone();
- art_apex_data.push(output_dir_fd.to_string());
+ let art_apex_data = mountpoint.join(context.output_dir_fd.to_string());
env::set_var("ART_APEX_DATA", &art_apex_data);
+ debug!("ART_APEX_DATA={:?}", &art_apex_data);
- let mut staging_dir = mountpoint;
- staging_dir.push(staging_dir_fd.to_string());
+ let staging_dir = mountpoint.join(context.staging_dir_fd.to_string());
let args = vec![
"odrefresh".to_string(),
- format!("--zygote-arch={}", zygote_arch),
- format!("--dalvik-cache={}", target_dir_name),
+ format!("--zygote-arch={}", context.zygote_arch),
+ format!("--dalvik-cache={}", context.target_dir_name),
"--no-refresh".to_string(),
format!("--staging-dir={}", staging_dir.display()),
"--force-compile".to_string(),
@@ -109,17 +135,47 @@
debug!("Running odrefresh with args: {:?}", &args);
let jail = spawn_jailed_task(odrefresh_path, &args, Vec::new() /* fd_mapping */)
.context("Spawn odrefresh")?;
- match jail.wait() {
- // TODO(161471326): On success, sign all files in the output directory.
- Ok(()) => Ok(0i8),
- Err(minijail::Error::ReturnCode(exit_code)) => {
- info!("odrefresh exited with exit code {}", exit_code);
- Ok(exit_code as i8)
- }
+ let exit_code = match jail.wait() {
+ Ok(_) => Result::<u8>::Ok(0),
+ Err(minijail::Error::ReturnCode(exit_code)) => Ok(exit_code),
Err(e) => {
bail!("Unexpected minijail error: {}", e)
}
+ }?;
+
+ let exit_code = ExitCode::from_i32(exit_code.into())
+ .ok_or_else(|| anyhow!("Unexpected odrefresh exit code: {}", exit_code))?;
+ info!("odrefresh exited with {:?}", exit_code);
+
+ if exit_code == ExitCode::CompilationSuccess {
+ // authfs only shows us the files we created, so it's ok to just sign everything under
+ // the target directory.
+ let target_dir = art_apex_data.join(context.target_dir_name);
+ let mut artifact_signer = ArtifactSigner::new(&target_dir);
+ add_artifacts(&target_dir, &mut artifact_signer)?;
+
+ artifact_signer.write_info_and_signature(signer, &target_dir.join("compos.info"))?;
}
+
+ Ok(exit_code)
+}
+
+fn add_artifacts(target_dir: &Path, artifact_signer: &mut ArtifactSigner) -> Result<()> {
+ for entry in
+ read_dir(&target_dir).with_context(|| format!("Traversing {}", target_dir.display()))?
+ {
+ let entry = entry?;
+ let file_type = entry.file_type()?;
+ if file_type.is_dir() {
+ add_artifacts(&entry.path(), artifact_signer)?;
+ } else if file_type.is_file() {
+ artifact_signer.add_artifact(&entry.path())?;
+ } else {
+ // authfs shouldn't create anything else, but just in case
+ bail!("Unexpected file type in artifacts: {:?}", entry);
+ }
+ }
+ Ok(())
}
/// Runs the compiler with given flags with file descriptors described in `fd_annotation` retrieved
diff --git a/compos/src/compos_key_service.rs b/compos/src/compos_key_service.rs
index f6caac9..086a162 100644
--- a/compos/src/compos_key_service.rs
+++ b/compos/src/compos_key_service.rs
@@ -101,7 +101,7 @@
let mut data = [0u8; 32];
self.random.fill(&mut data).context("No random data")?;
- let signature = self.sign(key_blob, &data)?;
+ let signature = self.new_signer(key_blob).sign(&data)?;
let public_key =
signature::UnparsedPublicKey::new(&signature::RSA_PKCS1_2048_8192_SHA256, public_key);
@@ -110,8 +110,19 @@
Ok(())
}
- pub fn sign(&self, key_blob: &[u8], data: &[u8]) -> Result<Vec<u8>> {
- let key_descriptor = KeyDescriptor { blob: Some(key_blob.to_vec()), ..BLOB_KEY_DESCRIPTOR };
+ pub fn new_signer(&self, key_blob: &[u8]) -> Signer {
+ Signer { key_blob: key_blob.to_vec(), security_level: self.security_level.clone() }
+ }
+}
+
+pub struct Signer {
+ key_blob: Vec<u8>,
+ security_level: Strong<dyn IKeystoreSecurityLevel>,
+}
+
+impl Signer {
+ pub fn sign(self, data: &[u8]) -> Result<Vec<u8>> {
+ let key_descriptor = KeyDescriptor { blob: Some(self.key_blob), ..BLOB_KEY_DESCRIPTOR };
let operation_parameters = [PURPOSE_SIGN, ALGORITHM, PADDING, DIGEST];
let forced = false;
diff --git a/compos/src/compsvc.rs b/compos/src/compsvc.rs
index 4540cd8..aa4b9bd 100644
--- a/compos/src/compsvc.rs
+++ b/compos/src/compsvc.rs
@@ -26,8 +26,8 @@
use std::path::PathBuf;
use std::sync::RwLock;
-use crate::compilation::{compile_cmd, odrefresh, CompilerOutput};
-use crate::compos_key_service::CompOsKeyService;
+use crate::compilation::{compile_cmd, odrefresh, CompilerOutput, OdrefreshContext};
+use crate::compos_key_service::{CompOsKeyService, Signer};
use crate::fsverity;
use authfs_aidl_interface::aidl::com::android::virt::fs::IAuthFsService::IAuthFsService;
use compos_aidl_interface::aidl::com::android::compos::{
@@ -39,10 +39,10 @@
use compos_aidl_interface::binder::{
BinderFeatures, ExceptionCode, Interface, Result as BinderResult, Strong,
};
+use compos_common::odrefresh::ODREFRESH_PATH;
const AUTHFS_SERVICE_NAME: &str = "authfs_service";
const DEX2OAT_PATH: &str = "/apex/com.android.art/bin/dex2oat64";
-const ODREFRESH_PATH: &str = "/apex/com.android.art/bin/odrefresh";
/// Constructs a binder object that implements ICompOsService.
pub fn new_binder() -> Result<Strong<dyn ICompOsService>> {
@@ -65,14 +65,21 @@
impl CompOsService {
fn generate_raw_fsverity_signature(
&self,
- key_blob: &[u8],
fsverity_digest: &fsverity::Sha256Digest,
- ) -> Vec<u8> {
+ ) -> BinderResult<Vec<u8>> {
let formatted_digest = fsverity::to_formatted_digest(fsverity_digest);
- self.key_service.sign(key_blob, &formatted_digest[..]).unwrap_or_else(|e| {
- warn!("Failed to sign the fsverity digest, returning empty signature. Error: {}", e);
- Vec::new()
- })
+ self.new_signer()?
+ .sign(&formatted_digest[..])
+ .map_err(|e| new_binder_exception(ExceptionCode::SERVICE_SPECIFIC, e.to_string()))
+ }
+
+ fn new_signer(&self) -> BinderResult<Signer> {
+ let key = &*self.key_blob.read().unwrap();
+ if key.is_empty() {
+ Err(new_binder_exception(ExceptionCode::ILLEGAL_STATE, "Key is not initialized"))
+ } else {
+ Ok(self.key_service.new_signer(key))
+ }
}
}
@@ -110,36 +117,27 @@
target_dir_name: &str,
zygote_arch: &str,
) -> BinderResult<i8> {
- if system_dir_fd < 0 || output_dir_fd < 0 || staging_dir_fd < 0 {
- return Err(new_binder_exception(
- ExceptionCode::ILLEGAL_ARGUMENT,
- "The remote FDs are expected to be non-negative",
- ));
- }
- if zygote_arch != "zygote64" && zygote_arch != "zygote64_32" {
- return Err(new_binder_exception(
- ExceptionCode::ILLEGAL_ARGUMENT,
- "Invalid zygote arch",
- ));
- }
-
- let authfs_service = get_authfs_service()?;
- odrefresh(
- &self.odrefresh_path,
- target_dir_name,
+ let context = OdrefreshContext::new(
system_dir_fd,
output_dir_fd,
staging_dir_fd,
+ target_dir_name,
zygote_arch,
- authfs_service,
)
- .map_err(|e| {
- warn!("odrefresh failed: {}", e);
- new_binder_exception(
- ExceptionCode::SERVICE_SPECIFIC,
- format!("odrefresh failed: {}", e),
- )
- })
+ .map_err(|e| new_binder_exception(ExceptionCode::ILLEGAL_ARGUMENT, e.to_string()))?;
+
+ let authfs_service = get_authfs_service()?;
+ let exit_code =
+ odrefresh(&self.odrefresh_path, context, authfs_service, self.new_signer()?).map_err(
+ |e| {
+ warn!("odrefresh failed: {:?}", e);
+ new_binder_exception(
+ ExceptionCode::SERVICE_SPECIFIC,
+ format!("odrefresh failed: {}", e),
+ )
+ },
+ )?;
+ Ok(exit_code as i8)
}
fn compile_cmd(
@@ -157,23 +155,15 @@
})?;
match output {
CompilerOutput::Digests { oat, vdex, image } => {
- let key = &*self.key_blob.read().unwrap();
- if key.is_empty() {
- Err(new_binder_exception(
- ExceptionCode::ILLEGAL_STATE,
- "Key is not initialized",
- ))
- } else {
- let oat_signature = self.generate_raw_fsverity_signature(key, &oat);
- let vdex_signature = self.generate_raw_fsverity_signature(key, &vdex);
- let image_signature = self.generate_raw_fsverity_signature(key, &image);
- Ok(CompilationResult {
- exitCode: 0,
- oatSignature: oat_signature,
- vdexSignature: vdex_signature,
- imageSignature: image_signature,
- })
- }
+ let oat_signature = self.generate_raw_fsverity_signature(&oat)?;
+ let vdex_signature = self.generate_raw_fsverity_signature(&vdex)?;
+ let image_signature = self.generate_raw_fsverity_signature(&image)?;
+ Ok(CompilationResult {
+ exitCode: 0,
+ oatSignature: oat_signature,
+ vdexSignature: vdex_signature,
+ imageSignature: image_signature,
+ })
}
CompilerOutput::ExitCode(exit_code) => {
Ok(CompilationResult { exitCode: exit_code, ..Default::default() })
@@ -201,14 +191,9 @@
}
fn sign(&self, data: &[u8]) -> BinderResult<Vec<u8>> {
- let key = &*self.key_blob.read().unwrap();
- if key.is_empty() {
- Err(new_binder_exception(ExceptionCode::ILLEGAL_STATE, "Key is not initialized"))
- } else {
- self.key_service
- .sign(key, data)
- .map_err(|e| new_binder_exception(ExceptionCode::ILLEGAL_STATE, e.to_string()))
- }
+ self.new_signer()?
+ .sign(data)
+ .map_err(|e| new_binder_exception(ExceptionCode::ILLEGAL_STATE, e.to_string()))
}
}