From b8782742d1bd91546887fbc1757a7d024a5469ef Mon Sep 17 00:00:00 2001 From: Alex Plotnick Date: Mon, 10 Aug 2026 16:26:38 +0000 Subject: [PATCH] Put IPCC behind a default-on cargo feature sprockets-tls links libipcc unconditionally, so every consumer's binary carries a NEEDED entry for a library that only exists on Oxide sleds. The support shell (sush) client runs on ordinary machines and only ever uses local keys, so it cannot start at all. Gate the ipcc module, ResolveSetting::Ipcc, AttestConfig::Ipcc, and the libipcc dependency behind an "ipcc" feature, on by default so existing consumers keep building unchanged. --- tls/Cargo.toml | 6 ++++-- tls/src/client.rs | 2 ++ tls/src/keys.rs | 18 ++++++++++++++++-- tls/src/lib.rs | 18 ++++++++++++------ tls/src/server.rs | 2 ++ 5 files changed, 36 insertions(+), 10 deletions(-) diff --git a/tls/Cargo.toml b/tls/Cargo.toml index 8b70c0f..9082732 100644 --- a/tls/Cargo.toml +++ b/tls/Cargo.toml @@ -9,8 +9,8 @@ attest-data.workspace = true camino.workspace = true cfg-if.workspace = true dice-mfg-msgs = { workspace = true, features = ["std"] } -dice-verifier = { workspace = true, features = ["ipcc", "mock"] } -libipcc.workspace = true +dice-verifier = { workspace = true, features = ["mock"] } +libipcc = { workspace = true, optional = true } ed25519-dalek.workspace = true hubpack = "0.1.2" pem-rfc7468 = { workspace = true, features = ["std"] } @@ -37,6 +37,8 @@ camino = { workspace = true, optional = true } pki-playground = { workspace = true, optional = true } [features] +default = ["ipcc"] +ipcc = ["dep:libipcc", "dice-verifier/ipcc"] unittest = ["attest-mock", "camino", "pki-playground"] [dev-dependencies] diff --git a/tls/src/client.rs b/tls/src/client.rs index 0b64f1d..2f0620f 100644 --- a/tls/src/client.rs +++ b/tls/src/client.rs @@ -155,6 +155,7 @@ impl Client { config.roots, log.clone(), )?, + #[cfg(feature = "ipcc")] ResolveSetting::Ipcc => { Client::new_tls_ipcc_client_config(config.roots, log.clone())? } @@ -205,6 +206,7 @@ impl Client { Ok(config) } + #[cfg(feature = "ipcc")] fn new_tls_ipcc_client_config( roots: Vec, log: slog::Logger, diff --git a/tls/src/keys.rs b/tls/src/keys.rs index b0992d8..687cd6e 100644 --- a/tls/src/keys.rs +++ b/tls/src/keys.rs @@ -20,12 +20,15 @@ use slog::{error, info}; use std::io::prelude::*; use std::iter; +#[cfg(feature = "ipcc")] use crate::ipcc::Ipcc; use crate::Error; use serde::Deserialize; use std::{fs::File, sync::Arc}; +#[cfg(feature = "ipcc")] +use x509_cert::der::{self, Reader}; use x509_cert::{ - der::{self, Decode, Encode, Reader}, + der::{Decode, Encode}, Certificate, }; use zeroize::{Zeroize, ZeroizeOnDrop}; @@ -34,6 +37,7 @@ use zeroize::{Zeroize, ZeroizeOnDrop}; #[serde(tag = "which", rename_all = "snake_case")] pub enum ResolveSetting { // Use certificates gathered over IPCC + #[cfg(feature = "ipcc")] Ipcc, // Use specified chain/key Local { @@ -53,6 +57,7 @@ impl CertResolver { CertResolver { log, resolve } } + #[cfg(feature = "ipcc")] fn load_ipcc_key(&self) -> Result, crate::Error> { let ipcc = Ipcc::new().map_err(crate::Error::RotRequest)?; let cert_chain_bytes = ipcc.rot_get_tq_cert_chain()?; @@ -117,6 +122,7 @@ impl CertResolver { pub fn load_certified_key(&self) -> Result, Error> { match &self.resolve { + #[cfg(feature = "ipcc")] ResolveSetting::Ipcc => self.load_ipcc_key(), ResolveSetting::Local { priv_key, @@ -191,9 +197,11 @@ impl SigningKey for LocalEd25519SigningKey { } /// Represents the underlying key returned over IPCC +#[cfg(feature = "ipcc")] #[derive(Debug)] pub struct IpccKey {} +#[cfg(feature = "ipcc")] impl SigningKey for IpccKey { fn choose_scheme( &self, @@ -210,9 +218,11 @@ impl SigningKey for IpccKey { } } +#[cfg(feature = "ipcc")] #[derive(Debug)] pub struct IpccSigner {} +#[cfg(feature = "ipcc")] impl Signer for IpccSigner { fn sign(&self, message: &[u8]) -> Result, rustls::Error> { // We require sha3_256 @@ -384,6 +394,7 @@ pub struct SprocketsConfig { /// Configuration for attestation interface / artifacts. pub enum AttestConfig { // Use `dice-verifier::AttestIpcc`. + #[cfg(feature = "ipcc")] Ipcc, // Use artifacts from local files with `dice_verifier::AttestMock`. Local { @@ -414,11 +425,14 @@ pub async fn get_attest_data( config: &AttestConfig, nonce: &dice_verifier::Nonce, ) -> Result { - use dice_verifier::{ipcc::AttestIpcc, Attest, AttestMock}; + #[cfg(feature = "ipcc")] + use dice_verifier::ipcc::AttestIpcc; + use dice_verifier::{Attest, AttestMock}; // create the `Attest` impl prescribed by the config let (attest, test_corpus): (Box, Vec) = match config { + #[cfg(feature = "ipcc")] AttestConfig::Ipcc => (Box::new(AttestIpcc {}), vec![]), AttestConfig::Local { priv_key, diff --git a/tls/src/lib.rs b/tls/src/lib.rs index 1717eff..389c135 100644 --- a/tls/src/lib.rs +++ b/tls/src/lib.rs @@ -28,6 +28,7 @@ use x509_cert::{ }; pub mod client; +#[cfg(feature = "ipcc")] pub mod ipcc; pub mod keys; pub mod server; @@ -57,6 +58,7 @@ pub enum Error { err: io::Error, }, + #[cfg(feature = "ipcc")] #[error("RotRequest")] RotRequest(#[from] ipcc::RotRequestError), @@ -66,6 +68,7 @@ pub enum Error { #[error("Failed to create mock attester")] AttestMock(#[from] dice_verifier::mock::AttestMockError), + #[cfg(feature = "ipcc")] #[error("Failed to create IPCC attester")] AttestIpcc(#[from] dice_verifier::ipcc::IpccError), @@ -380,13 +383,16 @@ mod tests { #[tokio::test] async fn toml_config() { - let ipcc = r#" - resolve = {which = "ipcc"} - roots = ["/path/to/root1", "/path/to/root2"] - attest = {which = "ipcc"} - "#; + #[cfg(feature = "ipcc")] + { + let ipcc = r#" + resolve = {which = "ipcc"} + roots = ["/path/to/root1", "/path/to/root2"] + attest = {which = "ipcc"} + "#; - let _: keys::SprocketsConfig = toml::from_str(ipcc).unwrap(); + let _: keys::SprocketsConfig = toml::from_str(ipcc).unwrap(); + } let local = r#" resolve = { which = "local", priv_key = "/path/to/tq-priv.pem", cert_chain = "/path/to/tq-chain.pem" } diff --git a/tls/src/server.rs b/tls/src/server.rs index 669bf4a..05dd553 100644 --- a/tls/src/server.rs +++ b/tls/src/server.rs @@ -398,6 +398,7 @@ impl Server { Ok(config) } + #[cfg(feature = "ipcc")] fn new_tls_ipcc_server_config( roots: Vec, log: slog::Logger, @@ -445,6 +446,7 @@ impl Server { config.roots, log.clone(), )?, + #[cfg(feature = "ipcc")] ResolveSetting::Ipcc => { Server::new_tls_ipcc_server_config(config.roots, log.clone())? }