diff --git a/Cargo.lock b/Cargo.lock index 833ffc0d7..45da0dd83 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -602,7 +602,7 @@ dependencies = [ "clap", "documented", "fs-err 3.0.0", - "rustls 0.23.16", + "rustls 0.23.17", "serde", "tokio", "toml_edit", @@ -749,12 +749,6 @@ version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" -[[package]] -name = "convert_case" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" - [[package]] name = "convert_case" version = "0.6.0" @@ -1020,13 +1014,33 @@ version = "0.99.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce" dependencies = [ - "convert_case 0.4.0", "proc-macro2", "quote", - "rustc_version", "syn 2.0.87", ] +[[package]] +name = "derive_more" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a9b99b9cbbe49445b21764dc0625032a89b145a2642e67603e1c936f5458d05" +dependencies = [ + "derive_more-impl", +] + +[[package]] +name = "derive_more-impl" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22" +dependencies = [ + "convert_case", + "proc-macro2", + "quote", + "syn 2.0.87", + "unicode-xid", +] + [[package]] name = "devise" version = "0.4.2" @@ -1121,7 +1135,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a62757be20672657b088dd945d8468968cfa4389c37d14be991f0ef07005ed6" dependencies = [ - "convert_case 0.6.0", + "convert_case", "itertools 0.13.0", "optfield", "proc-macro2", @@ -1871,7 +1885,7 @@ dependencies = [ "http 1.1.0", "hyper 1.4.1", "hyper-util", - "rustls 0.23.16", + "rustls 0.23.17", "rustls-native-certs", "rustls-pki-types", "tokio", @@ -2194,7 +2208,7 @@ dependencies = [ "anyhow", "fs-err 3.0.0", "parity-scale-codec", - "prost 0.12.6", + "prost 0.13.3", "prpc", "prpc-build", "serde", @@ -2888,12 +2902,6 @@ dependencies = [ "version_check", ] -[[package]] -name = "proc-macro-hack" -version = "0.5.20+deprecated" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" - [[package]] name = "proc-macro2" version = "1.0.89" @@ -2916,30 +2924,6 @@ dependencies = [ "yansi", ] -[[package]] -name = "proc-quote" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e84ab161de78c915302ca325a19bee6df272800e2ae1a43fe3ef430bab2a100" -dependencies = [ - "proc-macro-hack", - "proc-macro2", - "proc-quote-impl", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "proc-quote-impl" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fb3ec628b063cdbcf316e06a8b8c1a541d28fa6c0a8eacd2bfb2b7f49e88aa0" -dependencies = [ - "proc-macro-hack", - "proc-macro2", - "quote", -] - [[package]] name = "prost" version = "0.9.0" @@ -2952,12 +2936,12 @@ dependencies = [ [[package]] name = "prost" -version = "0.12.6" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "deb1435c188b76130da55f17a466d252ff7b1418b2ad3e037d127b94e3411f29" +checksum = "7b0487d90e047de87f984913713b85c601c05609aad5b0df4b4573fbf69aa13f" dependencies = [ "bytes", - "prost-derive 0.12.6", + "prost-derive 0.13.3", ] [[package]] @@ -2982,20 +2966,20 @@ dependencies = [ [[package]] name = "prost-build" -version = "0.12.6" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22505a5c94da8e3b7c2996394d1c933236c4d743e81a410bcca4e6989fc066a4" +checksum = "0c1318b19085f08681016926435853bbf7858f9c082d0999b80550ff5d9abe15" dependencies = [ "bytes", "heck 0.5.0", - "itertools 0.12.1", + "itertools 0.13.0", "log", "multimap 0.10.0", "once_cell", "petgraph", "prettyplease", - "prost 0.12.6", - "prost-types 0.12.6", + "prost 0.13.3", + "prost-types 0.13.3", "regex", "syn 2.0.87", "tempfile", @@ -3016,12 +3000,12 @@ dependencies = [ [[package]] name = "prost-derive" -version = "0.12.6" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81bddcdb20abf9501610992b6759a4c888aef7d1a7247ef75e2404275ac24af1" +checksum = "e9552f850d5f0964a4e4d0bf306459ac29323ddfbae05e35a7c0d35cb0803cc5" dependencies = [ "anyhow", - "itertools 0.12.1", + "itertools 0.13.0", "proc-macro2", "quote", "syn 2.0.87", @@ -3039,26 +3023,26 @@ dependencies = [ [[package]] name = "prost-types" -version = "0.12.6" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9091c90b0a32608e984ff2fa4091273cbdd755d54935c51d520887f4a1dbd5b0" +checksum = "4759aa0d3a6232fb8dbdb97b61de2c20047c68aca932c7ed76da9d788508d670" dependencies = [ - "prost 0.12.6", + "prost 0.13.3", ] [[package]] name = "prpc" -version = "0.2.2" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c4fe07d7f7d8d7f3eefbc8c4ecec470fd713614fb1d810cf46b9023e2aa2066" +checksum = "e83ca4bb539b92a92f3320a41482346d66bc591acd41c52b4ca22aa6960f3259" dependencies = [ "anyhow", "async-trait", - "derive_more", + "derive_more 1.0.0", "hex", "hex_fmt", "parity-scale-codec", - "prost 0.12.6", + "prost 0.13.3", "prpc-serde-bytes", "serde", "serde_json", @@ -3066,20 +3050,20 @@ dependencies = [ [[package]] name = "prpc-build" -version = "0.2.1" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f06a2f0b36c564ed01f5a1e3ecf14a031e859bd4214c5fca6abe8f74ed21f0e5" +checksum = "d831001d28230b9b322bcb91194d52ecadaa04417e8e6319afe2b10daf5ce765" dependencies = [ "either", "heck 0.5.0", - "itertools 0.12.1", + "itertools 0.13.0", "log", "multimap 0.10.0", "proc-macro2", - "prost 0.12.6", - "prost-build 0.12.6", + "prost 0.13.3", + "prost-build 0.13.3", "prost-build 0.9.0", - "prost-types 0.12.6", + "prost-types 0.13.3", "quote", "syn 2.0.87", "template-quote", @@ -3112,7 +3096,7 @@ dependencies = [ "quinn-proto", "quinn-udp", "rustc-hash 2.0.0", - "rustls 0.23.16", + "rustls 0.23.17", "socket2", "thiserror 1.0.65", "tokio", @@ -3129,7 +3113,7 @@ dependencies = [ "rand 0.8.5", "ring", "rustc-hash 2.0.0", - "rustls 0.23.16", + "rustls 0.23.17", "slab", "thiserror 1.0.65", "tinyvec", @@ -3443,7 +3427,7 @@ dependencies = [ "percent-encoding", "pin-project-lite", "quinn", - "rustls 0.23.16", + "rustls 0.23.17", "rustls-pemfile 2.1.3", "rustls-pki-types", "serde", @@ -3565,7 +3549,7 @@ dependencies = [ "ref-swap", "rocket_codegen", "rocket_http", - "rustls 0.23.16", + "rustls 0.23.17", "rustls-pemfile 2.1.3", "s2n-quic-h3", "serde", @@ -3685,9 +3669,8 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eee87ff5d9b36712a58574e12e9f0ea80f915a5b0ac518d322b24a465617925e" +version = "0.23.17" +source = "git+https://github.com/kvinwang/rustls?branch=fix-panic#db19eb388d301ef86ac2e4bd422e6f186a836456" dependencies = [ "aws-lc-rs", "log", @@ -3905,7 +3888,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c973d29e9b6669473f205b47d015480d7e79b103dfbd1c789184d9adc31af05" dependencies = [ "bytes", - "rustls 0.23.16", + "rustls 0.23.17", "rustls-pemfile 2.1.3", "s2n-codec 0.46.0", "s2n-quic-core 0.46.0", @@ -3938,7 +3921,7 @@ checksum = "eca070c12893629e2cc820a9761bedf6ce1dcddc9852984d1dc734b8bd9bd024" dependencies = [ "bitvec", "cfg-if", - "derive_more", + "derive_more 0.99.18", "parity-scale-codec", "scale-info-derive", ] @@ -4451,7 +4434,7 @@ version = "0.1.0" dependencies = [ "anyhow", "parity-scale-codec", - "prost 0.12.6", + "prost 0.13.3", "prpc", "prpc-build", "serde", @@ -4495,7 +4478,9 @@ dependencies = [ "getrandom 0.2.15", "hex", "hex_fmt", + "kms-rpc", "parity-scale-codec", + "ra-rpc", "ra-tls", "rand 0.8.5", "regex", @@ -4505,6 +4490,7 @@ dependencies = [ "serde_json", "sha2", "tdx-attest", + "tokio", "tproxy-rpc", "tracing", "tracing-subscriber", @@ -4545,7 +4531,7 @@ version = "0.1.0" dependencies = [ "anyhow", "parity-scale-codec", - "prost 0.12.6", + "prost 0.13.3", "prpc", "prpc-build", "serde", @@ -4567,19 +4553,19 @@ dependencies = [ [[package]] name = "template-quote" -version = "0.3.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41b79602418bea6101014d9648243a478b992bf00e136f856bef5c496ad24b21" +checksum = "cc002ce9580af57b063e49f50f3f0da0682a42897a1f42b2f523893163319e5f" dependencies = [ - "proc-quote", + "quote", "template-quote-impl", ] [[package]] name = "template-quote-impl" -version = "0.3.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48245913d30c549fa6b219f94f0aae683a8848d124944bc03f77fbf021053b68" +checksum = "771674c8b6053d12596dbc4edb19babd846eba27cd47e0e432f7dc2beac23b16" dependencies = [ "proc-macro-error", "proc-macro2", @@ -4728,7 +4714,7 @@ version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" dependencies = [ - "rustls 0.23.16", + "rustls 0.23.17", "rustls-pki-types", "tokio", ] @@ -4836,7 +4822,7 @@ dependencies = [ "rand 0.8.5", "rinja", "rocket", - "rustls 0.23.16", + "rustls 0.23.17", "serde", "serde_json", "shared_child", @@ -4853,7 +4839,7 @@ version = "0.1.0" dependencies = [ "anyhow", "parity-scale-codec", - "prost 0.12.6", + "prost 0.13.3", "prpc", "prpc-build", "serde", diff --git a/Cargo.toml b/Cargo.toml index de469a3ea..8aeab78c5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,3 +20,6 @@ members = [ "ct_monitor", ] resolver = "2" + +[patch.crates-io] +"rustls" = { git = "https://github.com/kvinwang/rustls", branch = "fix-panic" } diff --git a/certbot/cli/Cargo.toml b/certbot/cli/Cargo.toml index dfee9473b..6829fdd18 100644 --- a/certbot/cli/Cargo.toml +++ b/certbot/cli/Cargo.toml @@ -17,4 +17,4 @@ serde = { version = "1.0.213", features = ["derive"] } tokio = { version = "1.41.0", features = ["full"] } toml_edit = { version = "0.22.22", features = ["serde"] } tracing-subscriber = "0.3.18" -rustls = "0.23.15" +rustls = "0.23.17" diff --git a/certgen/src/main.rs b/certgen/src/main.rs index d9a4b4cbe..4f33c3dcc 100644 --- a/certgen/src/main.rs +++ b/certgen/src/main.rs @@ -22,7 +22,7 @@ fn main() -> anyhow::Result<()> { let tmp_ca_key = KeyPair::generate_for(&PKCS_ECDSA_P256_SHA256)?; let ca_key = KeyPair::generate_for(&PKCS_ECDSA_P256_SHA256)?; - let kms_www_key = KeyPair::generate_for(&PKCS_ECDSA_P256_SHA256)?; + let kms_rpc_key = KeyPair::generate_for(&PKCS_ECDSA_P256_SHA256)?; let tproxy_rpc_key = KeyPair::generate_for(&PKCS_ECDSA_P256_SHA256)?; let tmp_ca_cert = CertRequest::builder() @@ -42,15 +42,19 @@ fn main() -> anyhow::Result<()> { .build() .self_signed()?; + let kms_domain = format!("kms.{}", args.domain); // Sign WWW server cert with KMS cert - let kms_www_cert = CertRequest::builder() - .subject(&format!("kms.{}", args.domain)) - .key(&kms_www_key) + let kms_rpc_cert = CertRequest::builder() + .subject(&kms_domain) + .alt_names(&[kms_domain.clone()]) + .key(&kms_rpc_key) .build() .signed_by(&ca_cert, &ca_key)?; + let tproxy_domain = format!("tproxy.{}", args.domain); let tproxy_rpc_cert = CertRequest::builder() - .subject(&format!("tproxy.{}", args.domain)) + .subject(&tproxy_domain) + .alt_names(&[tproxy_domain.clone()]) .key(&tproxy_rpc_key) .build() .signed_by(&ca_cert, &ca_key)?; @@ -66,8 +70,8 @@ fn main() -> anyhow::Result<()> { store_cert( output_dir, "kms-rpc", - &kms_www_cert.pem(), - &kms_www_key.serialize_pem(), + &kms_rpc_cert.pem(), + &kms_rpc_key.serialize_pem(), )?; store_cert( output_dir, diff --git a/kms/rpc/Cargo.toml b/kms/rpc/Cargo.toml index efdd54db8..4ac55385e 100644 --- a/kms/rpc/Cargo.toml +++ b/kms/rpc/Cargo.toml @@ -4,13 +4,13 @@ version = "0.1.0" edition = "2021" [dependencies] -prpc = "0.2.2" -prost = "0.12.4" +prpc = "0.3.0" +prost = "0.13.3" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" anyhow = "1" scale = { version = "3.6.12", package = "parity-scale-codec", features = ["derive"] } [build-dependencies] -prpc-build = "0.2.1" +prpc-build = "0.3.1" fs-err = "3.0.0" diff --git a/ra-rpc/Cargo.toml b/ra-rpc/Cargo.toml index 1ce82478b..8ed3c0983 100644 --- a/ra-rpc/Cargo.toml +++ b/ra-rpc/Cargo.toml @@ -5,7 +5,7 @@ edition = "2021" [dependencies] anyhow = "1.0.88" -prpc = "0.2.2" +prpc = "0.3.0" ra-tls = { version = "0.1.0", path = "../ra-tls" } rocket = { git = "https://github.com/rwf2/Rocket", branch = "master", features = ["mtls"], optional = true } serde_json = "1.0.128" diff --git a/ra-rpc/src/client.rs b/ra-rpc/src/client.rs index 6c58b2fe8..8118de654 100644 --- a/ra-rpc/src/client.rs +++ b/ra-rpc/src/client.rs @@ -1,7 +1,8 @@ use std::time::Duration; +use anyhow::{Context, Result}; use prpc::client::{Error, RequestClient}; -use reqwest::Client; +use reqwest::{Certificate, Client, Identity}; pub struct RaClient { remote_uri: String, @@ -19,6 +20,27 @@ impl RaClient { .expect("failed to create client"); Self { remote_uri, client } } + pub fn new_mtls( + remote_uri: String, + ca_cert: String, + cert_pem: String, + key_pem: String, + ) -> Result { + let root_ca = + Certificate::from_pem(ca_cert.as_bytes()).context("Failed to parse CA cert")?; + let identity_pem = format!("{cert_pem}\n{key_pem}"); + let identity = + Identity::from_pem(identity_pem.as_bytes()).context("Failed to parse identity")?; + let client = Client::builder() + .tls_sni(true) + .add_root_certificate(root_ca) + .identity(identity) + .connect_timeout(Duration::from_secs(5)) + .timeout(Duration::from_secs(60)) + .build() + .context("failed to create client")?; + Ok(Self { remote_uri, client }) + } } impl RequestClient for RaClient { @@ -30,11 +52,18 @@ impl RequestClient for RaClient { .body(body) .send() .await - .map_err(|err| Error::RpcError(format!("failed to send request: {}", err)))?; - response + .map_err(|err| Error::RpcError(format!("failed to send request: {:?}", err)))?; + if !response.status().is_success() { + return Err(Error::RpcError(format!( + "request failed with status: {}", + response.status() + ))); + } + let body = response .bytes() .await - .map_err(|err| Error::RpcError(format!("failed to read response: {}", err))) - .map(|bytes| bytes.to_vec()) + .map_err(|err| Error::RpcError(format!("failed to read response: {:?}", err)))? + .to_vec(); + Ok(body) } } diff --git a/tappd/rpc/Cargo.toml b/tappd/rpc/Cargo.toml index 0dc5c118f..30b756640 100644 --- a/tappd/rpc/Cargo.toml +++ b/tappd/rpc/Cargo.toml @@ -4,12 +4,12 @@ version = "0.1.0" edition = "2021" [dependencies] -prpc = "0.2.2" -prost = "0.12.4" +prpc = "0.3.0" +prost = "0.13.3" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" anyhow = "1" scale = { version = "3.6.12", package = "parity-scale-codec", features = ["derive"] } [build-dependencies] -prpc-build = "0.2.1" +prpc-build = "0.3.1" diff --git a/tdxctl/Cargo.toml b/tdxctl/Cargo.toml index f48919b9f..fa48c9217 100644 --- a/tdxctl/Cargo.toml +++ b/tdxctl/Cargo.toml @@ -12,6 +12,8 @@ fs-err = "3.0.0" getrandom = "0.2.15" hex = "0.4.3" hex_fmt = "0.3.0" +kms-rpc = { version = "0.1.0", path = "../kms/rpc" } +ra-rpc = { version = "0.1.0", path = "../ra-rpc" } ra-tls = { version = "0.1.0", path = "../ra-tls" } regex = "1.11.1" scale = { version = "3.6.12", package = "parity-scale-codec", features = ["derive"] } @@ -21,6 +23,7 @@ serde-human-bytes = "0.1.0" serde_json = "1.0.128" sha2 = "0.10.8" tdx-attest = { path = "../tdx-attest" } +tokio = { version = "1.41.1", features = ["macros", "rt"] } tproxy-rpc = { version = "0.1.0", path = "../tproxy/rpc" } tracing = "0.1.40" tracing-subscriber = "0.3.18" diff --git a/tdxctl/src/fde_setup.rs b/tdxctl/src/fde_setup.rs index 39e364e5a..16035c97d 100644 --- a/tdxctl/src/fde_setup.rs +++ b/tdxctl/src/fde_setup.rs @@ -7,6 +7,7 @@ use std::{ use anyhow::{bail, Context, Result}; use env_process::convert_env_to_str; use fs_err as fs; +use ra_rpc::client::RaClient; use serde::{Deserialize, Serialize}; use tracing::info; @@ -150,7 +151,7 @@ impl HostShared { } } -pub fn cmd_setup_fde(args: SetupFdeArgs) -> Result<()> { +pub async fn cmd_setup_fde(args: SetupFdeArgs) -> Result<()> { fs::create_dir_all(&args.host_shared).context("Failed to create host-sharing mount point")?; mount_9p("host-shared", &args.host_shared.display().to_string()) .context("Failed to mount host-sharing")?; @@ -215,21 +216,19 @@ pub fn cmd_setup_fde(args: SetupFdeArgs) -> Result<()> { key_path: gen_certs_dir.join("key.pem"), })?; info!("Requesting app keys from KMS: {kms_url}"); - let todo = "use rust library"; - run_command( - "curl", - &[ - "--cacert", - &host_shared_dir.kms_ca_cert_file().display().to_string(), - "--cert", - &gen_certs_dir.join("cert.pem").display().to_string(), - "--key", - &gen_certs_dir.join("key.pem").display().to_string(), - "-o", - &app_keys_file.display().to_string(), - &format!("{kms_url}/prpc/KMS.GetAppKey"), - ], + let ra_client = RaClient::new_mtls( + format!("{kms_url}/prpc"), + fs::read_to_string(host_shared_dir.kms_ca_cert_file())?, + fs::read_to_string(gen_certs_dir.join("cert.pem"))?, + fs::read_to_string(gen_certs_dir.join("key.pem"))?, )?; + let kms_client = kms_rpc::kms_client::KmsClient::new(ra_client); + let response = kms_client + .get_app_key() + .await + .context("Failed to get app key")?; + let keys_json = serde_json::to_string(&response).context("Failed to serialize app keys")?; + fs::write(&app_keys_file, keys_json).context("Failed to write app keys")?; } else { info!("KMS is not enabled, generating local app keys"); cmd_gen_app_keys(GenAppKeysArgs { diff --git a/tdxctl/src/main.rs b/tdxctl/src/main.rs index 9c5c0cee3..a292d1714 100644 --- a/tdxctl/src/main.rs +++ b/tdxctl/src/main.rs @@ -5,12 +5,13 @@ use fs_err as fs; use getrandom::getrandom; use ra_tls::{attestation::QuoteContentType, cert::CaCert}; use scale::Decode; -use tracing::error; use std::{ io::{self, Read, Write}, path::PathBuf, }; +use tboot::TbootArgs; use tdx_attest as att; +use tracing::error; use utils::{deserialize_json_file, run_command, AppCompose}; mod crypto; @@ -168,14 +169,6 @@ struct TestAppFeatureArgs { compose: String, } -#[derive(Parser)] -/// Boot the Tapp -struct TbootArgs { - /// shutdown if the tboot fails - #[arg(short, long)] - shutdown_on_fail: bool, -} - fn cmd_quote() -> Result<()> { let mut report_data = [0; 64]; io::stdin() @@ -397,7 +390,8 @@ fn sha256(data: &[u8]) -> String { hex::encode(sha256.finalize()) } -fn main() -> Result<()> { +#[tokio::main] +async fn main() -> Result<()> { tracing_subscriber::fmt::init(); let cli = Cli::parse(); @@ -428,10 +422,10 @@ fn main() -> Result<()> { cmd_test_app_feature(args)?; } Commands::SetupFde(args) => { - cmd_setup_fde(args)?; + cmd_setup_fde(args).await?; } Commands::Tboot(args) => { - if let Err(err) = tboot::tboot() { + if let Err(err) = tboot::tboot(&args).await { error!("{:?}", err); if args.shutdown_on_fail { let _ = run_command("shutdown", &["-h", "now"]); diff --git a/tdxctl/src/tboot.rs b/tdxctl/src/tboot.rs index 4a023de7f..7724e2830 100644 --- a/tdxctl/src/tboot.rs +++ b/tdxctl/src/tboot.rs @@ -1,7 +1,9 @@ use anyhow::{bail, Context, Result}; +use clap::Parser; use fs_err as fs; +use ra_rpc::client::RaClient; use std::io::Write; -use tproxy_rpc::RegisterCvmResponse; +use tproxy_rpc::RegisterCvmRequest; use tracing::info; use crate::{ @@ -12,62 +14,69 @@ use crate::{ GenRaCertArgs, }; -fn prepare_docker_compose(compose: &AppCompose) -> Result<()> { +#[derive(Parser)] +/// Boot the Tapp +pub(crate) struct TbootArgs { + /// shutdown if the tboot fails + #[arg(long)] + pub(crate) shutdown_on_fail: bool, + /// Source directory + #[arg(short, long, default_value = "")] + prefix: String, +} + +impl TbootArgs { + pub(crate) fn resolve(&self, path: &str) -> String { + format!("{}/{}", self.prefix, path) + } +} + +fn prepare_docker_compose(args: &TbootArgs, compose: &AppCompose) -> Result<()> { info!("Preparing docker compose"); if compose.runner == "docker-compose" { let docker_compose = compose .docker_compose_file .as_ref() .context("Missing docker_compose_file")?; - fs::write("/tapp/docker-compose.yaml", docker_compose)?; + fs::write(args.resolve("/tapp/docker-compose.yaml"), docker_compose)?; } else { bail!("Unsupported runner: {}", compose.runner); } Ok(()) } -fn setup_tproxy_net(compose: &AppCompose) -> Result<()> { +async fn setup_tproxy_net(args: &TbootArgs, compose: &AppCompose) -> Result<()> { if !compose.feature_enabled("tproxy-net") { info!("tproxy is not enabled"); return Ok(()); } info!("Setting up tproxy network"); // Generate WireGuard keys - let client_private_key = run_command("wg", &["genkey"])?; - let client_private_key = - String::from_utf8(client_private_key).context("Failed to parse client private key")?; - let client_private_key = client_private_key.trim(); - let client_public_key = run_command_with_stdin("wg", &["pubkey"], &client_private_key)?; - let client_public_key = - String::from_utf8(client_public_key).context("Failed to parse client public key")?; - let client_public_key = client_public_key.trim(); + let sk = run_command("wg", &["genkey"])?; + let sk = String::from_utf8(sk).context("Failed to parse client private key")?; + let sk = sk.trim(); + let pk = run_command_with_stdin("wg", &["pubkey"], &sk)?; + let pk = String::from_utf8(pk).context("Failed to parse client public key")?; + let pk = pk.trim(); // Read config and make API call - let config: VmConfig = deserialize_json_file("/tapp/config.json")?; + let config: VmConfig = deserialize_json_file(args.resolve("/tapp/config.json"))?; let tproxy_url = config.tproxy_url.as_ref().context("Missing tproxy_url")?; - let url = format!("{}/prpc/Tproxy.RegisterCvm?json", tproxy_url); - let body = serde_json::to_string(&serde_json::json!({ - "client_public_key": client_public_key - }))?; - let todo = "Use rust library"; - let output = run_command( - "curl", - &[ - "--cacert", - "/etc/tappd/ca.cert", - "--cert", - "/etc/tappd/tls.cert", - "--key", - "/etc/tappd/tls.key", - "-d", - &body, - &url, - ], + let url = format!("{}/prpc", tproxy_url); + let client = RaClient::new_mtls( + url, + fs::read_to_string(args.resolve("/etc/tappd/ca.cert"))?, + fs::read_to_string(args.resolve("/etc/tappd/tls.cert"))?, + fs::read_to_string(args.resolve("/etc/tappd/tls.key"))?, )?; - let response: RegisterCvmResponse = - serde_json::from_slice(&output).context("Failed to parse response")?; - + let tproxy_client = tproxy_rpc::tproxy_client::TproxyClient::new(client); + let response = tproxy_client + .register_cvm(RegisterCvmRequest { + client_public_key: pk.to_string(), + }) + .await + .context("Failed to register CVM")?; let wg_info = response.wg.context("Missing wg info")?; let _tappd_info = response.tappd.context("Missing tappd info")?; @@ -82,10 +91,10 @@ fn setup_tproxy_net(compose: &AppCompose) -> Result<()> { info!("WG SERVER_IP: {}", server_ip); // Create WireGuard config - fs::create_dir_all("/etc/wireguard")?; + fs::create_dir_all(args.resolve("/etc/wireguard"))?; let config = format!( "[Interface]\n\ - PrivateKey = {client_private_key}\n\ + PrivateKey = {sk}\n\ Address = {client_ip}/24\n\n\ [Peer]\n\ PublicKey = {server_public_key}\n\ @@ -93,49 +102,52 @@ fn setup_tproxy_net(compose: &AppCompose) -> Result<()> { Endpoint = {server_endpoint}\n\ PersistentKeepalive = 25\n" ); - fs::write("/etc/wireguard/wg0.conf", config)?; + fs::write(args.resolve("/etc/wireguard/wg0.conf"), config)?; info!("Starting WireGuard"); run_command("wg-quick", &["up", "wg0"]).context("Failed to start WireGuard")?; Ok(()) } -fn prepare_certs() -> Result<()> { +fn prepare_certs(args: &TbootArgs) -> Result<()> { info!("Preparing certs"); - fs::create_dir_all("/etc/tappd")?; - fs::copy("/tapp/certs/ca.cert", "/etc/tappd/ca.cert")?; + fs::create_dir_all(args.resolve("/etc/tappd"))?; + fs::copy( + args.resolve("/tapp/certs/ca.cert"), + args.resolve("/etc/tappd/ca.cert"), + )?; - let appkeys_data = fs::read_to_string("/tapp/appkeys.json")?; + let appkeys_data = fs::read_to_string(args.resolve("/tapp/appkeys.json"))?; let appkeys: AppKeys = serde_json::from_str(&appkeys_data)?; if appkeys.app_key.is_empty() { bail!("Invalid app_key"); } - fs::write("/etc/tappd/app-ca.key", &appkeys.app_key)?; + fs::write(args.resolve("/etc/tappd/app-ca.key"), &appkeys.app_key)?; let cert_chain_str = appkeys.certificate_chain.join("\n"); - fs::write("/etc/tappd/app-ca.cert", cert_chain_str)?; + fs::write(args.resolve("/etc/tappd/app-ca.cert"), cert_chain_str)?; cmd_gen_ra_cert(GenRaCertArgs { - ca_key: "/etc/tappd/app-ca.key".into(), - ca_cert: "/etc/tappd/app-ca.cert".into(), - cert_path: "/etc/tappd/tls.cert".into(), - key_path: "/etc/tappd/tls.key".into(), + ca_key: args.resolve("/etc/tappd/app-ca.key").into(), + ca_cert: args.resolve("/etc/tappd/app-ca.cert").into(), + cert_path: args.resolve("/etc/tappd/tls.cert").into(), + key_path: args.resolve("/etc/tappd/tls.key").into(), }) .context("Failed to generate RA cert")?; let mut tls_cert = fs::OpenOptions::new() .append(true) - .open("/etc/tappd/tls.cert")?; - tls_cert.write_all(&fs::read("/etc/tappd/app-ca.cert")?)?; + .open(args.resolve("/etc/tappd/tls.cert"))?; + tls_cert.write_all(&fs::read(args.resolve("/etc/tappd/app-ca.cert"))?)?; Ok(()) } -pub fn tboot() -> Result<()> { - let compose: AppCompose = - deserialize_json_file("/tapp/app-compose.json").context("Failed to read compose file")?; - prepare_certs()?; - setup_tproxy_net(&compose)?; - prepare_docker_compose(&compose)?; +pub async fn tboot(args: &TbootArgs) -> Result<()> { + let compose: AppCompose = deserialize_json_file(args.resolve("/tapp/app-compose.json")) + .context("Failed to read compose file")?; + prepare_certs(args)?; + setup_tproxy_net(args, &compose).await?; + prepare_docker_compose(args, &compose)?; Ok(()) } diff --git a/teepod/rpc/Cargo.toml b/teepod/rpc/Cargo.toml index 682e57b77..73f93f946 100644 --- a/teepod/rpc/Cargo.toml +++ b/teepod/rpc/Cargo.toml @@ -4,12 +4,12 @@ version = "0.1.0" edition = "2021" [dependencies] -prpc = "0.2.2" -prost = "0.12.4" +prpc = "0.3.0" +prost = "0.13.3" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" anyhow = "1" scale = { version = "3.6.12", package = "parity-scale-codec", features = ["derive"] } [build-dependencies] -prpc-build = "0.2.1" +prpc-build = "0.3.1" diff --git a/tproxy/rpc/Cargo.toml b/tproxy/rpc/Cargo.toml index 583cb90e2..b1e9bc66b 100644 --- a/tproxy/rpc/Cargo.toml +++ b/tproxy/rpc/Cargo.toml @@ -4,12 +4,12 @@ version = "0.1.0" edition = "2021" [dependencies] -prpc = "0.2.2" -prost = "0.12.4" +prpc = "0.3.0" +prost = "0.13.3" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" anyhow = "1" scale = { version = "3.6.12", package = "parity-scale-codec", features = ["derive"] } [build-dependencies] -prpc-build = "0.2.1" +prpc-build = "0.3.1"