Skip to content

Commit

Permalink
Mutable log paths: allow IMA and MBA log paths to be overridden by ke…
Browse files Browse the repository at this point in the history
…ylime configuration.

Signed-off-by: George Almasi <[email protected]>
  • Loading branch information
George Almasi committed Jan 17, 2024
1 parent c649ae0 commit ea1fd45
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 34 deletions.
3 changes: 3 additions & 0 deletions GNUmakefile
Original file line number Diff line number Diff line change
Expand Up @@ -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/
Expand Down
22 changes: 0 additions & 22 deletions keylime-agent/src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,35 +39,13 @@ 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;
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,
Expand Down
45 changes: 45 additions & 0 deletions keylime-agent/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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";

Expand Down Expand Up @@ -108,6 +112,8 @@ pub(crate) struct EnvConfig {
pub iak_idevid_template: Option<String>,
pub run_as: Option<String>,
pub agent_data_path: Option<String>,
pub ima_ml_path: Option<String>,
pub measuredboot_ml_path: Option<String>,
}

#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
Expand Down Expand Up @@ -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)]
Expand Down Expand Up @@ -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
}

Expand Down Expand Up @@ -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())]))
}
Expand Down Expand Up @@ -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(),
}
}
}
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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()
},
Expand Down Expand Up @@ -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() {
Expand Down
6 changes: 3 additions & 3 deletions keylime-agent/src/crypto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand All @@ -673,15 +673,15 @@ 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]
fn test_decrypt_aead_invalid_key_length() {
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]
Expand Down
54 changes: 45 additions & 9 deletions keylime-agent/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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!(
Expand All @@ -149,16 +176,27 @@ 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") {
env_mb_path = v;
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)),
Expand All @@ -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
Expand Down Expand Up @@ -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") {
Expand Down

0 comments on commit ea1fd45

Please sign in to comment.