Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding "mutable log paths" feature #665

Merged
merged 2 commits into from
Jan 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions GNUmakefile
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ all: $(programs)
$(programs):
cargo build --target-dir="${TARGETDIR}" ${CARGO_ARGS}

.PHONY: clean
clean::
ansasaki marked this conversation as resolved.
Show resolved Hide resolved
${RM} -rf target

.PHONY: install
install: all
mkdir -p /etc/keylime/
Expand Down
17 changes: 16 additions & 1 deletion keylime-agent.conf
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
# The configuration file version
#
# To override, set KEYLIME_AGENT_VERSION environment variable.
version = "2.1"
version = "2.2"

# The agent's UUID.
# If you set this to "generate", Keylime will create a random UUID.
Expand Down Expand Up @@ -298,3 +298,18 @@ run_as = "keylime:tss"
# variable.
agent_data_path = "default"

# Path from where the agent will read the IMA measurement log.
#
# If set as "default", Keylime will use the default path:
# The default path is /sys/kernel/security/ima/ascii_runtime_measurements
# If set as a relative path, it will be considered from the root path "/".
# If set as an absolute path, it will use it without changes
ima_ml_path = "default"

# Path from where the agent will read the measured boot event log.
#
# If set as "default", Keylime will use the default path:
# The default path is /sys/kernel/security/tpm0/binary_boot_measurements
# If set as a relative path, it will be considered from the root path "/".
# If set as an absolute path, it will use it without changes
measuredboot_ml_path = "default"
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
47 changes: 47 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_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";

Check warning on line 67 in keylime-agent/src/config.rs

View check run for this annotation

Codecov / codecov/patch

keylime-agent/src/config.rs#L66-L67

Added lines #L66 - L67 were not covered by tests
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 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>,

Check warning on line 116 in keylime-agent/src/config.rs

View check run for this annotation

Codecov / codecov/patch

keylime-agent/src/config.rs#L116

Added line #L116 was not covered by tests
}

#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
Expand Down Expand Up @@ -152,6 +158,8 @@
pub iak_idevid_template: String,
pub run_as: String,
pub agent_data_path: String,
pub ima_ml_path: String,

Check warning on line 161 in keylime-agent/src/config.rs

View check run for this annotation

Codecov / codecov/patch

keylime-agent/src/config.rs#L161

Added line #L161 was not covered by tests
pub measuredboot_ml_path: String,
}

#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
Expand Down Expand Up @@ -326,6 +334,15 @@
_ = 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());

Check warning on line 338 in keylime-agent/src/config.rs

View check run for this annotation

Codecov / codecov/patch

keylime-agent/src/config.rs#L338

Added line #L338 was not covered by tests
}
if let Some(ref v) = self.measuredboot_ml_path {
_ = agent.insert(
"measuredboot_ml_path".to_string(),
v.to_string().into(),
);

Check warning on line 344 in keylime-agent/src/config.rs

View check run for this annotation

Codecov / codecov/patch

keylime-agent/src/config.rs#L341-L344

Added lines #L341 - L344 were not covered by tests
}
agent
}

Expand Down Expand Up @@ -515,6 +532,14 @@
"agent_data_path".to_string(),
self.agent.agent_data_path.to_string().into(),
);
_ = m.insert(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So many _ seems a bit ugly. I wonder if this can help: rust-lang/rfcs#3092

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the pointer, but unfortunately we cannot use this (yet). It is still available only on nightly:
https://doc.rust-lang.org/std/collections/struct.HashMap.html#method.try_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 @@
.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 @@ -708,13 +735,29 @@
))
})?;

let root_path = Path::new("/");

let mut agent_data_path = config_get_file_path(
"agent_data_path",
&config.agent.agent_data_path,
keylime_dir,
DEFAULT_AGENT_DATA_PATH,
);

let mut ima_ml_path = config_get_file_path(
"ima_ml_path",
&config.agent.ima_ml_path,
root_path,
DEFAULT_IMA_ML_PATH,
);

let mut measuredboot_ml_path = config_get_file_path(
"measuredboot_ml_path",
&config.agent.measuredboot_ml_path,
root_path,
DEFAULT_MEASUREDBOOT_ML_PATH,
);

let mut server_key = config_get_file_path(
"server_key",
&config.agent.server_key,
Expand Down Expand Up @@ -802,6 +845,8 @@
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 +1117,8 @@
("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
52 changes: 44 additions & 8 deletions keylime-agent/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,34 @@

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
#[cfg(test)]
fn ima_ml_path_get(_: &String) -> PathBuf {
Path::new(env!("CARGO_MANIFEST_DIR"))

Check warning on line 138 in keylime-agent/src/main.rs

View check run for this annotation

Codecov / codecov/patch

keylime-agent/src/main.rs#L137-L138

Added lines #L137 - L138 were not covered by tests
.join("test-data")
.join("ima")
.join("ascii_runtime_measurements")
}

#[cfg(not(test))]
fn ima_ml_path_get(s: &String) -> PathBuf {
Path::new(&s).to_path_buf()
}

let ima_ml_path = ima_ml_path_get(&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) {
Ok(file) => Some(Mutex::new(file)),
Expand All @@ -149,16 +176,27 @@
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);
}
ansasaki marked this conversation as resolved.
Show resolved Hide resolved

// 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 @@
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 @@
};

// 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);

Check warning on line 1099 in keylime-agent/src/main.rs

View check run for this annotation

Codecov / codecov/patch

keylime-agent/src/main.rs#L1098-L1099

Added lines #L1098 - L1099 were not covered by tests
let env_mb_path;
#[cfg(feature = "testing")]
if let Ok(v) = std::env::var("TPM_BINARY_MEASUREMENTS") {
Expand Down
Loading