From fc253f45593375de1b37cd08a5a92ccb13631b28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20Mart=C3=ADn?= Date: Thu, 4 Apr 2024 12:45:14 +0200 Subject: [PATCH] feat(rendezvous-server): verify the device certificate chain MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit use trusted CAs specified by the optional `trusted_device_keys_path` configuration variable to verify the device certificate chain. if the configuration variable is not specified we still validate that the chain is correct but all the certificates will be trusted. Signed-off-by: Miguel Martín --- HOWTO.md | 5 ++++- admin-tool/src/aio/configure.rs | 5 +++++ examples/config/rendezvous-server.yml | 1 + rendezvous-server/src/handlers_to0.rs | 10 ++++++++-- rendezvous-server/src/main.rs | 19 +++++++++++++++++++ test/fdo/rendezvous-server.yml | 1 + test/fmf/tests/onboarding/run-onboarding.sh | 1 + .../configuration/rendezvous_server.rs | 5 ++++- 8 files changed, 43 insertions(+), 4 deletions(-) diff --git a/HOWTO.md b/HOWTO.md index fd59b882f..6eef24888 100644 --- a/HOWTO.md +++ b/HOWTO.md @@ -532,6 +532,7 @@ session_store_driver: Directory: path: /path/to/stores/rendezvous_sessions trusted_manufacturer_keys_path: /path/to/keys/manufacturer_cert.pem +trusted_device_keys_path: /path/to/keys/device_ca_cert.pem max_wait_seconds: ~ bind: "0.0.0.0:8082" ``` @@ -568,7 +569,9 @@ Where: Please refer to the [Database management section](#database-management) on how to initialize databases. - `session_store_driver`: path to a directory that will hold session information. -- `trusted_manufacturer_keys_path`: path to the Manufacturer Certificate. +- `trusted_manufacturer_keys_path` [OPTIONAL]: path to the Manufacturer Certificate. +- `trusted_device_keys_path` [OPTIONAL]: path to the CA certificates used for +device certificate chain verification. - `max_wait_seconds`: [OPTIONAL] maximum wait time in seconds for the TO0 and TO1 protocols (default 2592000). - `bind`: IP address and port that the Rendezvous Server will take. diff --git a/admin-tool/src/aio/configure.rs b/admin-tool/src/aio/configure.rs index 4678e2a28..89d256797 100644 --- a/admin-tool/src/aio/configure.rs +++ b/admin-tool/src/aio/configure.rs @@ -219,6 +219,11 @@ fn generate_configs(aio_dir: &Path, config_args: &Configuration) -> Result<(), E .expect("Failed to build absolute path"), ), + trusted_device_keys_path: Some( + AbsolutePathBuf::new(aio_dir.join("keys").join("device_ca_cert.pem")) + .expect("Failed to build absolute path"), + ), + max_wait_seconds: None, bind: get_bind(config_args.listen_port_rendezvous_server)?, diff --git a/examples/config/rendezvous-server.yml b/examples/config/rendezvous-server.yml index 9e27974a1..4cf71152c 100644 --- a/examples/config/rendezvous-server.yml +++ b/examples/config/rendezvous-server.yml @@ -6,5 +6,6 @@ session_store_driver: Directory: path: /path/to/stores/rendezvous_sessions trusted_manufacturer_keys_path: /path/to/keys/manufacturer_cert.pem +trusted_device_keys_path: /path/to/keys/device_ca_cert.pem max_wait_seconds: ~ bind: "0.0.0.0:8082" diff --git a/rendezvous-server/src/handlers_to0.rs b/rendezvous-server/src/handlers_to0.rs index d2d32f9b2..dddfb719b 100644 --- a/rendezvous-server/src/handlers_to0.rs +++ b/rendezvous-server/src/handlers_to0.rs @@ -157,8 +157,14 @@ pub(super) async fn ownersign( } Some(v) => v, }; - //let device_pubkey = match device_cert_chain.verify_from_x5bag(&user_data.trusted_device_keys) { - let device_pubkey = match device_cert_chain.insecure_verify_without_root_verification() { + + let verify_device_pubkey = if let Some(trusted_device_keys) = &user_data.trusted_device_keys { + device_cert_chain.verify_from_x5bag(trusted_device_keys) + } else { + device_cert_chain.insecure_verify_without_root_verification() + }; + + let device_pubkey = match verify_device_pubkey { Err(cert_chain_err) => { log::debug!("Error verifying device certificate: {:?}", cert_chain_err); return Err(Error::new( diff --git a/rendezvous-server/src/main.rs b/rendezvous-server/src/main.rs index 8721dd7c4..a7b0d3483 100644 --- a/rendezvous-server/src/main.rs +++ b/rendezvous-server/src/main.rs @@ -25,6 +25,8 @@ impl fdo_store::MetadataLocalKey for RendezvousStoreMetadataKey { struct RendezvousUD { max_wait_seconds: u32, trusted_manufacturer_keys: Option, + trusted_device_keys: Option, + store: Box>, session_store: Arc, @@ -102,11 +104,28 @@ async fn main() -> Result<()> { .transpose() .context("Error loading trusted manufacturer keys")?; + // Load trusted CA certs for device certificate chain verification + let trusted_device_keys = settings + .trusted_device_keys_path + .as_ref() + .map(|path| -> Result { + let trusted_device_keys = { + let contents = std::fs::read(path) + .with_context(|| format!("Error reading trusted device keys at {}", &path))?; + X509::stack_from_pem(&contents).context("Error parsing trusted device keys")? + }; + X5Bag::with_certs(trusted_device_keys) + .context("Error building trusted device keys X5Bag") + }) + .transpose() + .context("Error loading trusted device keys")?; + // Initialize handler stores let user_data = Arc::new(RendezvousUD { max_wait_seconds, store, trusted_manufacturer_keys, + trusted_device_keys, session_store: session_store.clone(), }); diff --git a/test/fdo/rendezvous-server.yml b/test/fdo/rendezvous-server.yml index 1144009a1..e14f2247e 100644 --- a/test/fdo/rendezvous-server.yml +++ b/test/fdo/rendezvous-server.yml @@ -6,5 +6,6 @@ session_store_driver: Directory: path: /etc/fdo/stores/rendezvous_sessions trusted_manufacturer_keys_path: /etc/fdo/keys/manufacturer_cert.pem +trusted_device_keys_path: /etc/fdo/keys/device_ca_cert.pem max_wait_seconds: ~ bind: "0.0.0.0:8082" diff --git a/test/fmf/tests/onboarding/run-onboarding.sh b/test/fmf/tests/onboarding/run-onboarding.sh index 54f54db2e..3a3463bed 100755 --- a/test/fmf/tests/onboarding/run-onboarding.sh +++ b/test/fmf/tests/onboarding/run-onboarding.sh @@ -158,6 +158,7 @@ session_store_driver: Directory: path: ${STORES_DIR}/rendezvous_sessions trusted_manufacturer_keys_path: ${KEYS_DIR}/manufacturer_cert.pem +trusted_device_keys_path: ${KEYS_DIR}/device_ca_cert.pem max_wait_seconds: ~ bind: "0.0.0.0:8082" EOF diff --git a/util/src/servers/configuration/rendezvous_server.rs b/util/src/servers/configuration/rendezvous_server.rs index d9717c364..1351713c3 100644 --- a/util/src/servers/configuration/rendezvous_server.rs +++ b/util/src/servers/configuration/rendezvous_server.rs @@ -13,9 +13,12 @@ pub struct RendezvousServerSettings { #[serde(with = "serde_yaml::with::singleton_map")] pub session_store_driver: StoreConfig, - // Trusted keys + // Trusted manufacturer public keys pub trusted_manufacturer_keys_path: Option, + // Trusted CA certs for device cert chain verification + pub trusted_device_keys_path: Option, + // Other info pub max_wait_seconds: Option,