diff --git a/Cargo.lock b/Cargo.lock index 669b545..a33b9d2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -223,15 +223,17 @@ checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" [[package]] name = "attestation" version = "0.0.1" -source = "git+https://github.com/flashbots/attested-tls?branch=main#eaa10f0528c8c561273717913596de65cff807b3" +source = "git+https://github.com/flashbots/attested-tls?branch=peg%2Fnitro#5ad5ff6d42e94ad42f5c1a5c996d033107e2338a" dependencies = [ "anyhow", "az-tdx-vtpm", "base64 0.22.1", - "dcap-qvl 0.3.12 (git+https://github.com/Phala-Network/dcap-qvl.git?rev=f1dcc65371e941a7b83e3234833d23a1fb232ab1)", + "dcap-qvl", "hex", "http", - "mock-tdx", + "mock-tdx 0.0.1 (git+https://github.com/flashbots/attested-tls?branch=peg%2Fnitro)", + "nsm-nitro-enclave-utils", + "nsm-nitro-enclave-utils-keygen", "num-bigint", "once_cell", "openssl", @@ -261,11 +263,17 @@ dependencies = [ "anyhow", "attested-tls-proxy", "axum", + "bytes", "clap", "hex", + "http", + "http-body-util", + "hyper", + "hyper-util", "parity-scale-codec", "reqwest", "tokio", + "tokio-vsock", "tracing", "tracing-subscriber", ] @@ -273,7 +281,7 @@ dependencies = [ [[package]] name = "attested-tls" version = "0.0.1" -source = "git+https://github.com/flashbots/attested-tls?branch=main#eaa10f0528c8c561273717913596de65cff807b3" +source = "git+https://github.com/flashbots/attested-tls?branch=peg%2Fnitro#5ad5ff6d42e94ad42f5c1a5c996d033107e2338a" dependencies = [ "anyhow", "attestation", @@ -305,7 +313,7 @@ dependencies = [ "hyper", "hyper-util", "jsonrpsee", - "mock-tdx", + "mock-tdx 0.0.1 (git+https://github.com/flashbots/attested-tls?branch=main)", "nested-tls", "p256", "pccs", @@ -361,6 +369,20 @@ dependencies = [ "fs_extra", ] +[[package]] +name = "aws-nitro-enclaves-nsm-api" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d92c1f4471b33f6a7af9ea421b249ed18a11c71156564baf6293148fa6ad1b09" +dependencies = [ + "libc", + "log", + "nix 0.26.4", + "serde", + "serde_bytes", + "serde_cbor", +] + [[package]] name = "axum" version = "0.8.9" @@ -421,7 +443,7 @@ checksum = "9b3d0900c6757c9674b05b0479236458297026e25fb505186dc8d7735091a21c" dependencies = [ "bincode 1.3.3", "jsonwebkey", - "memoffset", + "memoffset 0.9.1", "openssl", "serde", "serde-big-array", @@ -760,6 +782,33 @@ dependencies = [ "serde", ] +[[package]] +name = "ciborium" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42e69ffd6f0917f5c029256a24d0161db17cea3997d185db0d35926308770f0e" +dependencies = [ + "ciborium-io", + "ciborium-ll", + "serde", +] + +[[package]] +name = "ciborium-io" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05afea1e0a06c9be33d539b876f1ce3692f4afea2cb41f740e7743225ed1c757" + +[[package]] +name = "ciborium-ll" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9" +dependencies = [ + "ciborium-io", + "half 2.7.1", +] + [[package]] name = "clap" version = "4.5.51" @@ -874,6 +923,16 @@ dependencies = [ "unicode-segmentation", ] +[[package]] +name = "coset" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1eb98d5e9155e2cf7cd942c8b3033097d4563b6fb0a00b9caecb74669555c058" +dependencies = [ + "ciborium", + "ciborium-io", +] + [[package]] name = "cpufeatures" version = "0.2.17" @@ -922,6 +981,12 @@ version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" +[[package]] +name = "crunchy" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" + [[package]] name = "crypto-bigint" version = "0.5.5" @@ -1010,43 +1075,6 @@ version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476" -[[package]] -name = "dcap-qvl" -version = "0.3.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67e7842b81018f3b991dc65ec0a95ff347332de58478c4ac43459095af00cc89" -dependencies = [ - "anyhow", - "asn1_der", - "base64 0.22.1", - "borsh", - "byteorder", - "chrono", - "const-oid", - "dcap-qvl-webpki", - "der", - "derive_more 2.1.1", - "futures", - "hex", - "log", - "p256", - "parity-scale-codec", - "pem", - "reqwest", - "ring", - "rustls-pki-types", - "scale-info", - "serde", - "serde-human-bytes", - "serde_json", - "sha2", - "signature", - "tracing", - "urlencoding", - "wasm-bindgen-futures", - "x509-cert", -] - [[package]] name = "dcap-qvl" version = "0.3.12" @@ -1256,7 +1284,7 @@ source = "git+https://github.com/Dstack-TEE/dstack.git?rev=07d2cf6bd376a3c56f855 dependencies = [ "anyhow", "cc-eventlog 0.5.11", - "dcap-qvl 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)", + "dcap-qvl", "dstack-types", "errify", "ez-hash", @@ -1341,6 +1369,7 @@ dependencies = [ "ff", "generic-array", "group", + "hkdf", "pem-rfc7468", "pkcs8", "rand_core 0.6.4", @@ -1710,6 +1739,23 @@ dependencies = [ "tracing", ] +[[package]] +name = "half" +version = "1.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b43ede17f21864e81be2fa654110bf1e793774238d86ef8555c37e6519c0403" + +[[package]] +name = "half" +version = "2.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b" +dependencies = [ + "cfg-if", + "crunchy", + "zerocopy", +] + [[package]] name = "hashbrown" version = "0.16.0" @@ -2346,6 +2392,15 @@ version = "2.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" +[[package]] +name = "memoffset" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" +dependencies = [ + "autocfg", +] + [[package]] name = "memoffset" version = "0.9.1" @@ -2404,7 +2459,30 @@ version = "0.0.1" source = "git+https://github.com/flashbots/attested-tls?branch=main#eaa10f0528c8c561273717913596de65cff807b3" dependencies = [ "axum", - "dcap-qvl 0.3.12 (git+https://github.com/Phala-Network/dcap-qvl.git?rev=f1dcc65371e941a7b83e3234833d23a1fb232ab1)", + "dcap-qvl", + "hex", + "p256", + "parity-scale-codec", + "rcgen 0.14.7", + "serde", + "serde-saphyr", + "serde_bytes", + "serde_json", + "sha2", + "time", + "tokio", + "urlencoding", + "x509-parser 0.18.1", + "yasna 0.5.2", +] + +[[package]] +name = "mock-tdx" +version = "0.0.1" +source = "git+https://github.com/flashbots/attested-tls?branch=peg%2Fnitro#5ad5ff6d42e94ad42f5c1a5c996d033107e2338a" +dependencies = [ + "axum", + "dcap-qvl", "hex", "p256", "parity-scale-codec", @@ -2442,7 +2520,7 @@ dependencies = [ [[package]] name = "nested-tls" version = "0.0.1" -source = "git+https://github.com/flashbots/attested-tls?branch=main#eaa10f0528c8c561273717913596de65cff807b3" +source = "git+https://github.com/flashbots/attested-tls?branch=peg%2Fnitro#5ad5ff6d42e94ad42f5c1a5c996d033107e2338a" dependencies = [ "rustls", "tokio", @@ -2450,6 +2528,19 @@ dependencies = [ "tracing", ] +[[package]] +name = "nix" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b" +dependencies = [ + "bitflags 1.3.2", + "cfg-if", + "libc", + "memoffset 0.7.1", + "pin-utils", +] + [[package]] name = "nix" version = "0.31.2" @@ -2460,7 +2551,7 @@ dependencies = [ "cfg-if", "cfg_aliases", "libc", - "memoffset", + "memoffset 0.9.1", ] [[package]] @@ -2479,6 +2570,46 @@ dependencies = [ "minimal-lexical", ] +[[package]] +name = "nsm-nitro-enclave-utils" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0be8326f0a1c769ee90da2bdaf6e0859c7873b2047a5d06d97f7f2abb273dc15" +dependencies = [ + "aws-nitro-enclaves-nsm-api", + "coset", + "getrandom 0.3.4", + "hex", + "nsm-nitro-enclave-utils-keygen", + "p384", + "ring", + "rustls-pki-types", + "rustls-webpki", + "sealed", + "serde", + "serde_bytes", + "serde_json", + "sha2", + "x509-cert", +] + +[[package]] +name = "nsm-nitro-enclave-utils-keygen" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff968e3b62edc3ac9c6fd324490a6a14278ea6289efeb7d91425feaf62592051" +dependencies = [ + "clap", + "p384", + "rand_core 0.6.4", + "sec1", + "serde", + "serde_bytes", + "serde_json", + "sha2", + "x509-cert", +] + [[package]] name = "nu-ansi-term" version = "0.50.3" @@ -2754,10 +2885,10 @@ dependencies = [ [[package]] name = "pccs" version = "0.0.1" -source = "git+https://github.com/flashbots/attested-tls?branch=main#eaa10f0528c8c561273717913596de65cff807b3" +source = "git+https://github.com/flashbots/attested-tls?branch=peg%2Fnitro#5ad5ff6d42e94ad42f5c1a5c996d033107e2338a" dependencies = [ "anyhow", - "dcap-qvl 0.3.12 (git+https://github.com/Phala-Network/dcap-qvl.git?rev=f1dcc65371e941a7b83e3234833d23a1fb232ab1)", + "dcap-qvl", "hex", "reqwest", "serde", @@ -3046,7 +3177,7 @@ dependencies = [ "anyhow", "bon", "cc-eventlog 0.5.11", - "dcap-qvl 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)", + "dcap-qvl", "dstack-attest", "dstack-types", "elliptic-curve", @@ -3485,6 +3616,17 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "sealed" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22f968c5ea23d555e670b449c1c5e7b2fc399fdaec1d304a17cd48e288abc107" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "sec1" version = "0.7.3" @@ -3565,6 +3707,16 @@ dependencies = [ "serde_core", ] +[[package]] +name = "serde_cbor" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bef2ebfde456fb76bbcf9f59315333decc4fda0b2b44b420243c11e0f5ec1f5" +dependencies = [ + "half 1.8.3", + "serde", +] + [[package]] name = "serde_core" version = "1.0.228" @@ -4043,6 +4195,27 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" +[[package]] +name = "tls_codec" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0de2e01245e2bb89d6f05801c564fa27624dbd7b1846859876c7dad82e90bf6b" +dependencies = [ + "tls_codec_derive", + "zeroize", +] + +[[package]] +name = "tls_codec_derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d2e76690929402faae40aebdda620a2c0e25dd6d3b9afe48867dfd95991f4bd" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "tokio" version = "1.50.0" @@ -4107,6 +4280,20 @@ dependencies = [ "tokio", ] +[[package]] +name = "tokio-vsock" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b319ef9394889dab2e1b4f0085b45ba11d0c79dc9d1a9d1afc057d009d0f1c7" +dependencies = [ + "axum", + "bytes", + "futures", + "libc", + "tokio", + "vsock", +] + [[package]] name = "toml_datetime" version = "0.7.3" @@ -4452,7 +4639,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b82aeb12ad864eb8cd26a6c21175d0bdc66d398584ee6c93c76964c3bcfc78ff" dependencies = [ "libc", - "nix", + "nix 0.31.2", ] [[package]] @@ -4867,7 +5054,10 @@ checksum = "1301e935010a701ae5f8655edc0ad17c44bad3ac5ce8c39185f75453b720ae94" dependencies = [ "const-oid", "der", + "sha1", + "signature", "spki", + "tls_codec", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 94303f7..e966fba 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,9 @@ [workspace] members = [".", "attestation-provider-server"] +[patch.crates-io] +dcap-qvl = { git = "https://github.com/Phala-Network/dcap-qvl.git", rev = "f1dcc65371e941a7b83e3234833d23a1fb232ab1" } + [package] name = "attested-tls-proxy" version = "1.1.1" @@ -11,10 +14,10 @@ repository = "https://github.com/flashbots/attested-tls-proxy" keywords = ["attested-TLS", "CVM", "TDX"] [dependencies] -attested-tls = { git = "https://github.com/flashbots/attested-tls", branch = "main" } -nested-tls = { git = "https://github.com/flashbots/attested-tls", branch = "main" } -attestation = { git = "https://github.com/flashbots/attested-tls", branch = "main" } -pccs = { git = "https://github.com/flashbots/attested-tls", branch = "main" } +attested-tls = { git = "https://github.com/flashbots/attested-tls", branch = "peg/nitro" } +nested-tls = { git = "https://github.com/flashbots/attested-tls", branch = "peg/nitro" } +attestation = { git = "https://github.com/flashbots/attested-tls", branch = "peg/nitro" } +pccs = { git = "https://github.com/flashbots/attested-tls", branch = "peg/nitro" } tokio = { version = "1.50.0", features = ["full"] } tokio-rustls = { version = "0.26.4", default-features = false, features = ["aws_lc_rs"] } x509-parser = { version = "0.18.0", features = ["verify"] } @@ -37,7 +40,7 @@ reqwest = { version = "0.12.24", default-features = false, features = [ webpki-roots = "1.0.7" tracing = "0.1.41" tracing-subscriber = { version = "0.3.20", features = ["env-filter", "json"] } -axum = "0.8.8" +axum = "0.8.9" tower-http = { version = "0.6.7", features = ["fs"] } rsa = { version = "0.9", default-features = false } p256 = { version = "0.13.2", features = ["pkcs8"] } @@ -49,7 +52,7 @@ pin-project-lite = "0.2.16" [dev-dependencies] tempfile = "3.23.0" tdx-quote = { version = "0.0.5", features = ["mock"] } -attestation = { git = "https://github.com/flashbots/attested-tls", branch = "main", features = ["mock"] } +attestation = { git = "https://github.com/flashbots/attested-tls", branch = "peg/nitro", features = ["mock"] } tokio = { version = "1.48.0", features = ["full"] } jsonrpsee = { version = "0.26.0", features = ["server"] } mock-tdx = { git = "https://github.com/flashbots/attested-tls", branch = "main" } diff --git a/attestation-provider-server/Cargo.toml b/attestation-provider-server/Cargo.toml index efe98d6..b90cb47 100644 --- a/attestation-provider-server/Cargo.toml +++ b/attestation-provider-server/Cargo.toml @@ -10,10 +10,16 @@ repository = "https://github.com/flashbots/attested-tls-proxy" [dependencies] attested-tls-proxy = { path = ".." } tokio = { version = "1.48.0", features = ["full"] } -axum = "0.8.8" +axum = "0.8.9" clap = { version = "4.5.51", features = ["derive", "env"] } anyhow = "1.0.100" +bytes = "1.11.1" hex = "0.4.3" +http = "1.3.1" +http-body-util = "0.1.3" +hyper = "1.7.0" +hyper-util = { version = "0.1.17", features = ["tokio"] } +tokio-vsock = { version = "0.7.2", features = ["axum08"] } tracing = "0.1.41" tracing-subscriber = { version = "0.3.20", features = ["env-filter", "json"] } parity-scale-codec = "3.7.5" diff --git a/attestation-provider-server/src/lib.rs b/attestation-provider-server/src/lib.rs index a7134c1..6258490 100644 --- a/attestation-provider-server/src/lib.rs +++ b/attestation-provider-server/src/lib.rs @@ -3,13 +3,25 @@ use std::net::SocketAddr; use anyhow::anyhow; use attested_tls_proxy::attestation::{AttestationExchangeMessage, AttestationVerifier}; +use axum::serve::Listener; use axum::{ extract::{Path, State}, http::StatusCode, response::{IntoResponse, Response}, }; +use bytes::Bytes; +use http_body_util::BodyExt; +use hyper::Request; +use hyper::client::conn::http1; +use hyper_util::rt::TokioIo; use parity_scale_codec::{Decode, Encode}; -use tokio::net::TcpListener; +use tokio_vsock::{VsockAddr, VsockStream}; + +#[derive(Debug, Clone, Copy)] +pub enum AttestationProviderEndpoint { + Tcp(SocketAddr), + Vsock { cid: u32, port: u32 }, +} #[derive(Clone)] struct SharedState { @@ -17,10 +29,14 @@ struct SharedState { } /// An HTTP server which provides attestations -pub async fn attestation_provider_server( - listener: TcpListener, +pub async fn attestation_provider_server( + listener: L, attestation_generator: AttestationGenerator, -) -> anyhow::Result<()> { +) -> anyhow::Result<()> +where + L: Listener, + L::Addr: std::fmt::Debug, +{ let app = axum::Router::new() .route("/attest/{input_data}", axum::routing::get(get_attest)) .with_state(SharedState { @@ -52,17 +68,40 @@ async fn get_attest( /// A client helper which makes a request to `/attest` pub async fn attestation_provider_client( - server_addr: SocketAddr, + server_endpoint: AttestationProviderEndpoint, attestation_verifier: AttestationVerifier, ) -> anyhow::Result { let input_data = [0; 64]; - let response = reqwest::get(format!( - "http://{server_addr}/attest/{}", - hex::encode(input_data) - )) - .await? - .bytes() - .await?; + let response = match server_endpoint { + AttestationProviderEndpoint::Tcp(server_addr) => reqwest::get(format!( + "http://{server_addr}/attest/{}", + hex::encode(input_data) + )) + .await? + .bytes() + .await? + .to_vec(), + AttestationProviderEndpoint::Vsock { cid, port } => { + let stream = VsockStream::connect(VsockAddr::new(cid, port)).await?; + let io = TokioIo::new(stream); + let (mut sender, connection) = http1::handshake(io).await?; + + tokio::spawn(async move { + if let Err(err) = connection.await { + eprintln!("vsock HTTP connection error: {err}"); + } + }); + + let request = Request::builder() + .method(http::Method::GET) + .uri(format!("/attest/{}", hex::encode(input_data))) + .header(http::header::HOST, format!("{cid}:{port}")) + .body(http_body_util::Empty::::new())?; + + let response = sender.send_request(request).await?; + response.into_body().collect().await?.to_bytes().to_vec() + } + }; let remote_attestation_message = AttestationExchangeMessage::decode(&mut &response[..])?; let remote_attestation_type = remote_attestation_message.attestation_type; @@ -97,6 +136,7 @@ impl IntoResponse for ServerError { #[cfg(test)] mod tests { use super::*; + use tokio::net::TcpListener; #[tokio::test] async fn test_attestation_provider_server() { @@ -110,8 +150,11 @@ mod tests { .await .unwrap(); }); - attestation_provider_client(server_addr, AttestationVerifier::expect_none()) - .await - .unwrap(); + attestation_provider_client( + AttestationProviderEndpoint::Tcp(server_addr), + AttestationVerifier::expect_none(), + ) + .await + .unwrap(); } } diff --git a/attestation-provider-server/src/main.rs b/attestation-provider-server/src/main.rs index 276d43c..9b4154e 100644 --- a/attestation-provider-server/src/main.rs +++ b/attestation-provider-server/src/main.rs @@ -2,9 +2,10 @@ use attestation_provider_server::{attestation_provider_client, attestation_provi use attested_tls_proxy::attestation::{ AttestationGenerator, AttestationVerifier, measurements::MeasurementPolicy, }; -use clap::{Parser, Subcommand}; +use clap::{Parser, Subcommand, ValueEnum}; use std::{net::SocketAddr, path::PathBuf}; use tokio::net::TcpListener; +use tokio_vsock::{VMADDR_CID_ANY, VsockAddr, VsockListener}; use tracing::level_filters::LevelFilter; const GIT_REV: &str = match option_env!("GIT_REV") { @@ -30,22 +31,44 @@ struct Cli { #[derive(Subcommand, Debug, Clone)] enum CliCommand { Server { + /// Network transport to use for the server listener + #[arg(long, value_enum, default_value_t = NetworkTransport::Tcp)] + listen_transport: NetworkTransport, /// Socket address to listen on #[arg(short, long, default_value = "0.0.0.0:0", env = "LISTEN_ADDR")] listen_addr: SocketAddr, + /// Vsock port to listen on when using `--listen-transport vsock` + #[arg(long, default_value_t = 8000, env = "VSOCK_PORT")] + vsock_port: u32, /// Type of attestation to present (will attempt to detect if not given) #[arg(long)] server_attestation_type: Option, }, Client { + /// Network transport to use for the attestation provider server + #[arg(long, value_enum, default_value_t = NetworkTransport::Tcp)] + server_transport: NetworkTransport, /// Socket address of a attestation provider server + #[arg(short, long, default_value = "127.0.0.1:8000", env = "SERVER_ADDR")] server_addr: SocketAddr, + /// Vsock CID of the attestation provider server when using `--server-transport vsock` + #[arg(long, default_value_t = 10, env = "SERVER_CID")] + server_cid: u32, + /// Vsock port of the attestation provider server when using `--server-transport vsock` + #[arg(long, default_value_t = 8000, env = "SERVER_VSOCK_PORT")] + server_vsock_port: u32, /// Optional path to file containing JSON measurements to be enforced on the remote party #[arg(long, global = true, env = "MEASUREMENTS_FILE")] measurements_file: Option, }, } +#[derive(ValueEnum, Debug, Clone, Copy, PartialEq, Eq)] +enum NetworkTransport { + Tcp, + Vsock, +} + #[tokio::main] async fn main() -> anyhow::Result<()> { let cli = Cli::parse(); @@ -74,19 +97,35 @@ async fn main() -> anyhow::Result<()> { match cli.command { CliCommand::Server { + listen_transport, listen_addr, + vsock_port, server_attestation_type, } => { let attestation_generator = AttestationGenerator::new_with_detection(server_attestation_type, None)?; - let listener = TcpListener::bind(listen_addr).await?; - - println!("Listening on {}", listener.local_addr()?); - attestation_provider_server(listener, attestation_generator).await?; + match listen_transport { + NetworkTransport::Tcp => { + let listener = TcpListener::bind(listen_addr).await?; + println!("Listening on {}", listener.local_addr()?); + attestation_provider_server(listener, attestation_generator).await?; + } + NetworkTransport::Vsock => { + let listener = VsockListener::bind(VsockAddr::new(VMADDR_CID_ANY, vsock_port))?; + println!( + "Listening on vsock cid={} port={}", + VMADDR_CID_ANY, vsock_port + ); + attestation_provider_server(listener, attestation_generator).await?; + } + } } CliCommand::Client { + server_transport, server_addr, + server_cid, + server_vsock_port, measurements_file, } => { let measurement_policy = match measurements_file { @@ -102,8 +141,20 @@ async fn main() -> anyhow::Result<()> { internal_pccs: None, }; + let server_endpoint = match server_transport { + NetworkTransport::Tcp => { + attestation_provider_server::AttestationProviderEndpoint::Tcp(server_addr) + } + NetworkTransport::Vsock => { + attestation_provider_server::AttestationProviderEndpoint::Vsock { + cid: server_cid, + port: server_vsock_port, + } + } + }; + let attestation_message = - attestation_provider_client(server_addr, attestation_verifier).await?; + attestation_provider_client(server_endpoint, attestation_verifier).await?; println!("{attestation_message:?}") } diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..94e0bfb --- /dev/null +++ b/flake.lock @@ -0,0 +1,27 @@ +{ + "nodes": { + "nixpkgs": { + "locked": { + "lastModified": 1778869304, + "narHash": "sha256-30sZNZoA1cqF5JNO9fVX+wgiQYjB7HJqqJ4ztCDeBZE=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "d233902339c02a9c334e7e593de68855ad26c4cb", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..09781a0 --- /dev/null +++ b/flake.nix @@ -0,0 +1,77 @@ +{ + description = "attested-tls-proxy with a reproducible attestation-provider-server OCI image"; + + inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + + outputs = { self, nixpkgs }: + let + system = "x86_64-linux"; + pkgs = import nixpkgs { inherit system; }; + + server = pkgs.rustPlatform.buildRustPackage { + pname = "attestation-provider-server"; + version = "1.1.1"; + src = ./.; + + cargoLock = { + lockFile = ./Cargo.lock; + outputHashes = { + "attestation-0.0.1" = "sha256-1I9iQcFNt02fHs8Q18LK2+f8U0TzhfdFz7JvV0mKJUw="; + "attested-tls-0.0.1" = "sha256-1I9iQcFNt02fHs8Q18LK2+f8U0TzhfdFz7JvV0mKJUw="; + "cc-eventlog-0.5.11" = "sha256-q6Vrlx4N7Ce2EQTQH+0HCSEzFZmY8PzDHxrO8L3kMsQ="; + "cc-eventlog-0.5.8" = "sha256-KEauakj53LrhKTc0yYp5SM8ec0cFNm4YVuHCJYiPQjw="; + "dcap-qvl-0.3.12" = "sha256-rLTp5wIhXRAcBtJb7lfd1TAg7yPRnwa0cBa1YT4LwKU="; + "dstack-attest-0.5.11" = "sha256-q6Vrlx4N7Ce2EQTQH+0HCSEzFZmY8PzDHxrO8L3kMsQ="; + "dstack-types-0.5.11" = "sha256-q6Vrlx4N7Ce2EQTQH+0HCSEzFZmY8PzDHxrO8L3kMsQ="; + "nested-tls-0.0.1" = "sha256-1I9iQcFNt02fHs8Q18LK2+f8U0TzhfdFz7JvV0mKJUw="; + "pccs-0.0.1" = "sha256-1I9iQcFNt02fHs8Q18LK2+f8U0TzhfdFz7JvV0mKJUw="; + "ra-tls-0.5.11" = "sha256-q6Vrlx4N7Ce2EQTQH+0HCSEzFZmY8PzDHxrO8L3kMsQ="; + "size-parser-0.5.11" = "sha256-q6Vrlx4N7Ce2EQTQH+0HCSEzFZmY8PzDHxrO8L3kMsQ="; + "tdx-attest-0.5.11" = "sha256-q6Vrlx4N7Ce2EQTQH+0HCSEzFZmY8PzDHxrO8L3kMsQ="; + "tdx-attest-0.5.8" = "sha256-KEauakj53LrhKTc0yYp5SM8ec0cFNm4YVuHCJYiPQjw="; + }; + }; + cargoBuildFlags = [ "-p" "attestation-provider-server" ]; + cargoHash = "sha256-rLTp5wIhXRAcBtJb7lfd1TAg7yPRnwa0cBa1YT4LwKU="; + + nativeBuildInputs = [ pkgs.pkg-config ]; + buildInputs = [ pkgs.openssl pkgs.tpm2-tss ]; + + doCheck = false; + }; + + imageRoot = pkgs.buildEnv { + name = "attestation-provider-server-image-root"; + paths = [ server pkgs.cacert ]; + pathsToLink = [ "/bin" "/etc/ssl/certs" ]; + }; + in + { + packages.${system} = { + attestation-provider-server = server; + attestation-provider-server-image = pkgs.dockerTools.buildLayeredImage { + name = "attestation-provider-server"; + tag = "latest"; + contents = [ imageRoot ]; + config = { + Cmd = [ + "/bin/attestation-provider-server" + "server" + "--listen-transport" + "vsock" + "--vsock-port" + "8000" + "--server-attestation-type" + "aws-nitro" + ]; + }; + }; + default = self.packages.${system}.attestation-provider-server-image; + }; + + devShells.${system}.default = pkgs.mkShell { + nativeBuildInputs = with pkgs; [ pkg-config ]; + buildInputs = with pkgs; [ tpm2-tss openssl ]; + }; + }; +} diff --git a/src/attested_get.rs b/src/attested_get.rs index 24be0a7..c30558c 100644 --- a/src/attested_get.rs +++ b/src/attested_get.rs @@ -104,7 +104,9 @@ mod tests { }); // Setup a proxy client - let mock_pcs_server = spawn_mock_pcs_server(MockPcsConfig::default()).await.unwrap(); + let mock_pcs_server = spawn_mock_pcs_server(MockPcsConfig::default()) + .await + .unwrap(); let verifier = AttestationVerifier::mock_with_pccs(mock_pcs_server.base_url.clone()); let proxy_client = ProxyClient::new_with_tls_config( client_config, diff --git a/src/file_server.rs b/src/file_server.rs index 72d0e65..6d55b21 100644 --- a/src/file_server.rs +++ b/src/file_server.rs @@ -164,7 +164,9 @@ mod tests { proxy_server.accept().await.unwrap(); }); - let mock_pcs_server = spawn_mock_pcs_server(MockPcsConfig::default()).await.unwrap(); + let mock_pcs_server = spawn_mock_pcs_server(MockPcsConfig::default()) + .await + .unwrap(); let verifier = AttestationVerifier::mock_with_pccs(mock_pcs_server.base_url.clone()); let proxy_client = ProxyClient::new_with_tls_config( client_config,