Skip to content

Commit

Permalink
Merge pull request fdo-rs#656 from mmartinv/verify-trusted-manufacturers
Browse files Browse the repository at this point in the history
feat: verify trusted manufacturers
  • Loading branch information
mergify[bot] authored Apr 10, 2024
2 parents 7a146a3 + dfdf239 commit f524b28
Show file tree
Hide file tree
Showing 11 changed files with 90 additions and 25 deletions.
9 changes: 6 additions & 3 deletions HOWTO.md
Original file line number Diff line number Diff line change
Expand Up @@ -491,8 +491,8 @@ 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_device_keys_path`: path to the Device Certificate Authority
certificate.
- `trusted_device_keys_path` [OPTIONAL]: path to the CA certificates
used for device certificate chain verification.
- `owner_private_key_path`: path to the Owner's private key.
- `owner_public_key_path`: path to the Owner's public key certificate.
- `bind`: IP address and port that this server will take.
Expand Down Expand Up @@ -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"
```
Expand Down Expand Up @@ -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.
Expand Down
13 changes: 9 additions & 4 deletions admin-tool/src/aio/configure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)?,
Expand Down Expand Up @@ -325,10 +330,10 @@ fn generate_configs(aio_dir: &Path, config_args: &Configuration) -> Result<(), E
ownership_voucher_store_driver: StoreConfig::Directory {
path: aio_dir.join("stores").join("owner_vouchers"),
},
trusted_device_keys_path: AbsolutePathBuf::new(
aio_dir.join("keys").join("device_ca_cert.pem"),
)
.unwrap(),
trusted_device_keys_path: Some(
AbsolutePathBuf::new(aio_dir.join("keys").join("device_ca_cert.pem"))
.expect("Failed to build absolute path"),
),
owner_private_key_path: AbsolutePathBuf::new(
aio_dir.join("keys").join("owner_key.der"),
)
Expand Down
1 change: 1 addition & 0 deletions examples/config/rendezvous-server.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
4 changes: 2 additions & 2 deletions owner-onboarding-server/src/handlers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ pub(super) async fn hello_device(
return Err(Error::new(
ErrorCode::MessageBodyError,
messages::v11::to2::HelloDevice::message_type(),
"Invcalid signature info",
"Invalid signature info",
)
.into())
}
Expand All @@ -64,7 +64,7 @@ pub(super) async fn hello_device(
return Err(Error::new(
ErrorCode::MessageBodyError,
messages::v11::to2::HelloDevice::message_type(),
"Invcalid signature info",
"Invalid signature info",
)
.into());
}
Expand Down
50 changes: 38 additions & 12 deletions owner-onboarding-server/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,7 @@ mod handlers;

pub(crate) struct OwnerServiceUD {
// Trusted keys
#[allow(dead_code)]
trusted_device_keys: X5Bag,
trusted_device_keys: Option<X5Bag>,

// Stores
ownership_voucher_store: Box<
Expand Down Expand Up @@ -90,6 +89,7 @@ async fn _handle_report_to_rendezvous(udt: &OwnerServiceUDT, ov: &OwnershipVouch
&udt.owner_addresses,
&udt.owner_key,
udt.ov_registration_period,
&udt.trusted_device_keys,
)
.await
{
Expand Down Expand Up @@ -172,6 +172,7 @@ async fn check_registration_window(udt: &OwnerServiceUDT) -> Result<()> {
&udt.owner_addresses,
&udt.owner_key,
udt.ov_registration_period,
&udt.trusted_device_keys,
)
.await
{
Expand Down Expand Up @@ -210,6 +211,7 @@ async fn report_ov_to_rendezvous(
owner_addresses: &[TO2AddressEntry],
owner_key: &PKey<Private>,
registration_period: u32,
trusted_device_keys: &Option<X5Bag>,
) -> Result<u32> {
let ov_header = ov.header();
if ov_header.protocol_version() != ProtocolVersion::Version1_1 {
Expand All @@ -219,6 +221,24 @@ async fn report_ov_to_rendezvous(
ProtocolVersion::Version1_1
);
}

match ov.device_certificate_chain() {
None => {
bail!("No device certificate chain found");
}
Some(device_cert_chain) => {
if let Some(trusted_device_keys) = trusted_device_keys {
device_cert_chain
.verify_from_x5bag(trusted_device_keys)
.context("Device certificate is not trusted")?
} else {
device_cert_chain
.insecure_verify_without_root_verification()
.context("Device certificate chain is malformed")?
};
}
};

// Determine the RV IP
let rv_info = ov_header
.rendezvous_info()
Expand Down Expand Up @@ -380,16 +400,22 @@ async fn main() -> Result<()> {
// Bind information
let bind_addr = settings.bind.clone();

// Trusted keys
let trusted_device_keys = {
let trusted_keys_path = &settings.trusted_device_keys_path;
let contents = std::fs::read(trusted_keys_path).with_context(|| {
format!("Error reading trusted device keys from {trusted_keys_path}")
})?;
X509::stack_from_pem(&contents).context("Error parsing trusted device keys")?
};
let trusted_device_keys = X5Bag::with_certs(trusted_device_keys)
.context("Error building trusted device keys X5Bag")?;
// Load trusted CA certs for device certificate chain verification
let trusted_device_keys = settings
.trusted_device_keys_path
.as_ref()
.map(|path| -> Result<X5Bag, anyhow::Error> {
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")?;

// Our private key
let owner_key = load_private_key(&settings.owner_private_key_path).with_context(|| {
Expand Down
10 changes: 8 additions & 2 deletions rendezvous-server/src/handlers_to0.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
19 changes: 19 additions & 0 deletions rendezvous-server/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ impl fdo_store::MetadataLocalKey for RendezvousStoreMetadataKey {
struct RendezvousUD {
max_wait_seconds: u32,
trusted_manufacturer_keys: Option<X5Bag>,
trusted_device_keys: Option<X5Bag>,

store: Box<dyn Store<fdo_store::ReadWriteOpen, Guid, StoredItem, RendezvousStoreMetadataKey>>,

session_store: Arc<fdo_http_wrapper::server::SessionStore>,
Expand Down Expand Up @@ -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<X5Bag, anyhow::Error> {
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(),
});
Expand Down
1 change: 1 addition & 0 deletions test/fdo/rendezvous-server.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
1 change: 1 addition & 0 deletions test/fmf/tests/onboarding/run-onboarding.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion util/src/servers/configuration/owner_onboarding_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ pub struct OwnerOnboardingServerSettings {
pub session_store_driver: StoreConfig,

// Trusted keys
pub trusted_device_keys_path: AbsolutePathBuf,
pub trusted_device_keys_path: Option<AbsolutePathBuf>,

// Our private owner key
pub owner_private_key_path: AbsolutePathBuf,
Expand Down
5 changes: 4 additions & 1 deletion util/src/servers/configuration/rendezvous_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<AbsolutePathBuf>,

// Trusted CA certs for device cert chain verification
pub trusted_device_keys_path: Option<AbsolutePathBuf>,

// Other info
pub max_wait_seconds: Option<u32>,

Expand Down

0 comments on commit f524b28

Please sign in to comment.