From ea1fd459b4cb1c302ae57205854ae698a3974663 Mon Sep 17 00:00:00 2001 From: George Almasi Date: Mon, 2 Oct 2023 01:31:33 +0000 Subject: [PATCH] Mutable log paths: allow IMA and MBA log paths to be overridden by keylime configuration. Signed-off-by: George Almasi --- GNUmakefile | 3 +++ keylime-agent/src/common.rs | 22 --------------- keylime-agent/src/config.rs | 45 +++++++++++++++++++++++++++++++ keylime-agent/src/crypto.rs | 6 ++--- keylime-agent/src/main.rs | 54 ++++++++++++++++++++++++++++++------- 5 files changed, 96 insertions(+), 34 deletions(-) diff --git a/GNUmakefile b/GNUmakefile index 72f70d265..ee6c8d00f 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -25,6 +25,9 @@ all: $(programs) $(programs): cargo build --target-dir="${TARGETDIR}" ${CARGO_ARGS} +clean:: + ${RM} -rf target + .PHONY: install install: all mkdir -p /etc/keylime/ diff --git a/keylime-agent/src/common.rs b/keylime-agent/src/common.rs index 226bed32a..684357ffa 100644 --- a/keylime-agent/src/common.rs +++ b/keylime-agent/src/common.rs @@ -39,10 +39,6 @@ pub const API_VERSION: &str = "v2.1"; pub const TPM_DATA_PCR: usize = 16; pub const IMA_PCR: usize = 10; pub static RSA_PUBLICKEY_EXPORTABLE: &str = "rsa placeholder"; -pub static IMA_ML: &str = - "/sys/kernel/security/ima/ascii_runtime_measurements"; -pub static MEASUREDBOOT_ML: &str = - "/sys/kernel/security/tpm0/binary_bios_measurements"; pub static KEY: &str = "secret"; pub const AGENT_UUID_LEN: usize = 36; pub const AUTH_TAG_LEN: usize = 48; @@ -50,24 +46,6 @@ pub const AES_128_KEY_LEN: usize = 16; pub const AES_256_KEY_LEN: usize = 32; pub const AES_BLOCK_SIZE: usize = 16; -cfg_if::cfg_if! { - if #[cfg(test)] { - // Secure mount of tpmfs (False is generally used for development environments) - - pub(crate) fn ima_ml_path_get() -> PathBuf { - Path::new(env!("CARGO_MANIFEST_DIR")) - .join("test-data") - .join("ima") - .join("ascii_runtime_measurements") - } - } else { - - pub(crate) fn ima_ml_path_get() -> PathBuf { - Path::new(IMA_ML).to_path_buf() - } - } -} - #[derive(Serialize, Deserialize, Debug)] pub(crate) struct APIVersion { major: u32, diff --git a/keylime-agent/src/config.rs b/keylime-agent/src/config.rs index 862db4285..50cdb7876 100644 --- a/keylime-agent/src/config.rs +++ b/keylime-agent/src/config.rs @@ -63,6 +63,10 @@ pub static DEFAULT_IAK_IDEVID_NAME_ALG: &str = "sha256"; pub static DEFAULT_IAK_IDEVID_TEMPLATE: &str = "H-1"; pub static DEFAULT_RUN_AS: &str = "keylime:tss"; pub static DEFAULT_AGENT_DATA_PATH: &str = "agent_data.json"; +pub static DEFAULT_IMA_ML_PATH: &str = + "/sys/kernel/security/ima/ascii_runtime_measurements"; +pub static DEFAULT_MEASUREDBOOT_ML_PATH: &str = + "/sys/kernel/security/tpm0/binary_boot_measurements"; pub static DEFAULT_CONFIG: &str = "/etc/keylime/agent.conf"; pub static DEFAULT_CONFIG_SYS: &str = "/usr/etc/keylime/agent.conf"; @@ -108,6 +112,8 @@ pub(crate) struct EnvConfig { pub iak_idevid_template: Option, pub run_as: Option, pub agent_data_path: Option, + pub ima_ml_path: Option, + pub measuredboot_ml_path: Option, } #[derive(Clone, Debug, Deserialize, Serialize, PartialEq)] @@ -152,6 +158,8 @@ pub(crate) struct AgentConfig { pub iak_idevid_template: String, pub run_as: String, pub agent_data_path: String, + pub ima_ml_path: String, + pub measuredboot_ml_path: String, } #[derive(Clone, Debug, Deserialize, Serialize, PartialEq)] @@ -326,6 +334,15 @@ impl EnvConfig { _ = agent .insert("agent_data_path".to_string(), v.to_string().into()); } + if let Some(ref v) = self.ima_ml_path { + _ = agent.insert("ima_ml_path".to_string(), v.to_string().into()); + } + if let Some(ref v) = self.measuredboot_ml_path { + _ = agent.insert( + "measuredboot_ml_path".to_string(), + v.to_string().into(), + ); + } agent } @@ -515,6 +532,14 @@ impl Source for KeylimeConfig { "agent_data_path".to_string(), self.agent.agent_data_path.to_string().into(), ); + _ = m.insert( + "ima_ml_path".to_string(), + self.agent.ima_ml_path.to_string().into(), + ); + _ = m.insert( + "measuredboot_ml_path".to_string(), + self.agent.measuredboot_ml_path.to_string().into(), + ); Ok(Map::from([("agent".to_string(), m.into())])) } @@ -580,6 +605,8 @@ impl Default for AgentConfig { .to_string(), iak_idevid_name_alg: DEFAULT_IAK_IDEVID_NAME_ALG.to_string(), iak_idevid_template: DEFAULT_IAK_IDEVID_TEMPLATE.to_string(), + ima_ml_path: "default".to_string(), + measuredboot_ml_path: "default".to_string(), } } } @@ -715,6 +742,20 @@ fn config_translate_keywords( DEFAULT_AGENT_DATA_PATH, ); + let mut ima_ml_path = config_get_file_path( + "ima_ml_path", + &config.agent.ima_ml_path, + keylime_dir, + DEFAULT_IMA_ML_PATH, + ); + + let mut measuredboot_ml_path = config_get_file_path( + "measuredboot_ml_path", + &config.agent.measuredboot_ml_path, + keylime_dir, + DEFAULT_MEASUREDBOOT_ML_PATH, + ); + let mut server_key = config_get_file_path( "server_key", &config.agent.server_key, @@ -802,6 +843,8 @@ fn config_translate_keywords( trusted_client_ca, ek_handle, agent_data_path, + ima_ml_path, + measuredboot_ml_path, revocation_cert, ..config.agent.clone() }, @@ -1072,6 +1115,8 @@ mod tests { ("IAK_IDEVID_TEMPLATE", "override_iak_idevid_template"), ("RUN_AS", "override_run_as"), ("AGENT_DATA_PATH", "override_agent_data_path"), + ("IMA_ML_PATH", "override_ima_ml_path"), + ("MEASUREDBOOT_ML_PATH", "override_measuredboot_ml_path"), ]); for (c, v) in override_map.into_iter() { diff --git a/keylime-agent/src/crypto.rs b/keylime-agent/src/crypto.rs index f7f7db378..ba08a687c 100644 --- a/keylime-agent/src/crypto.rs +++ b/keylime-agent/src/crypto.rs @@ -664,7 +664,7 @@ mod tests { let iv = b"ABCDEFGHIJKLMNOP"; let plaintext = b"test string, longer than the block size"; let result = encrypt_aead(&key[..], &iv[..], &plaintext[..]); - assert!(matches!(result, Err(_))); + assert!(result.is_err()) } #[test] @@ -673,7 +673,7 @@ mod tests { let iv = b"ABCDEFGHIJKLMN"; let plaintext = b"test string, longer than the block size"; let result = encrypt_aead(&key[..], &iv[..], &plaintext[..]); - assert!(matches!(result, Err(_))); + assert!(result.is_err()) } #[test] @@ -681,7 +681,7 @@ mod tests { let key = b"0123456789012345012345678901234"; let ciphertext = hex::decode("4142434445464748494A4B4C4D4E4F50FCE7CA78C08FB1D5E04DB3C4AA6B6ED2F09C4AD7985BD1DB9FF15F9FDA869D0C01B27FF4618737BB53C84D256455AAB53B9AC7EAF88C4B").unwrap(); //#[allow_ci] let result = decrypt_aead(&key[..], &ciphertext[..]); - assert!(matches!(result, Err(_))); + assert!(result.is_err()) } #[test] diff --git a/keylime-agent/src/main.rs b/keylime-agent/src/main.rs index 2f0461cdb..aac97ba0d 100644 --- a/keylime-agent/src/main.rs +++ b/keylime-agent/src/main.rs @@ -129,9 +129,36 @@ async fn main() -> Result<()> { pretty_env_logger::init(); - let ima_ml_path = ima_ml_path_get(); + // Load config + let mut config = config::KeylimeConfig::new()?; + + // load path for IMA logfile + // To fix later: GA 10/1/23: IMA and MBA log path override mechanisms are different + let mut ima_ml_path; + cfg_if::cfg_if! { + if #[cfg(test)] { + + let p = Path::new(env!("CARGO_MANIFEST_DIR")) + .join("test-data") + .join("ima") + .join("ascii_runtime_measurements"); + ima_ml_path = p.as_path(); + } else { + ima_ml_path = Path::new(&config.agent.ima_ml_path); + } + } + + // check whether anyone has overridden the default + if ima_ml_path.as_os_str() != config::DEFAULT_IMA_ML_PATH { + warn!( + "IMA measurement list location override: {}", + ima_ml_path.display() + ); + } + + // check IMA logfile exists & accessible let ima_ml_file = if ima_ml_path.exists() { - match fs::File::open(&ima_ml_path) { + match fs::File::open(ima_ml_path) { Ok(file) => Some(Mutex::new(file)), Err(e) => { warn!( @@ -149,9 +176,9 @@ async fn main() -> Result<()> { None }; - let mut measuredboot_ml_path = Path::new(MEASUREDBOOT_ML); - - // Allow setting the binary bios measurements log path when testing + // load path for MBA logfile + let mut measuredboot_ml_path = + Path::new(&config.agent.measuredboot_ml_path); let env_mb_path: String; #[cfg(feature = "testing")] if let Ok(v) = std::env::var("TPM_BINARY_MEASUREMENTS") { @@ -159,6 +186,17 @@ async fn main() -> Result<()> { measuredboot_ml_path = Path::new(&env_mb_path); } + // check whether anyone has overridden the default MBA logfile + if measuredboot_ml_path.as_os_str() + != config::DEFAULT_MEASUREDBOOT_ML_PATH + { + warn!( + "Measured boot measurement list location override: {}", + measuredboot_ml_path.display() + ); + } + + // check MBA logfile exists & accessible let measuredboot_ml_file = if measuredboot_ml_path.exists() { match fs::File::open(measuredboot_ml_path) { Ok(file) => Some(Mutex::new(file)), @@ -178,9 +216,6 @@ async fn main() -> Result<()> { None }; - // Load config - let mut config = config::KeylimeConfig::new()?; - // The agent cannot run when a payload script is defined, but mTLS is disabled and insecure // payloads are not explicitly enabled if !config.agent.enable_agent_mtls @@ -1060,7 +1095,8 @@ mod testing { }; // Allow setting the binary bios measurements log path when testing - let mut measuredboot_ml_path = Path::new(MEASUREDBOOT_ML); + let mut measuredboot_ml_path = + Path::new(&test_config.agent.measuredboot_ml_path); let env_mb_path; #[cfg(feature = "testing")] if let Ok(v) = std::env::var("TPM_BINARY_MEASUREMENTS") {