From db3e11264e5a918f45ae204354baa561bfd0ae7b Mon Sep 17 00:00:00 2001 From: 0xZensh Date: Tue, 5 Nov 2024 20:59:42 +0800 Subject: [PATCH] fix: fix `ic_tee_nitro_attestation` --- Cargo.lock | 58 ++++++-------- Cargo.toml | 3 +- nitro_enclave/host_iptables.sh | 12 +++ nitro_enclave/setup.sh | 2 +- nitro_enclave/supervisord.conf | 2 + src/ic_tee_cli/src/main.rs | 4 +- src/ic_tee_identity/src/api.rs | 25 +++++- src/ic_tee_nitro_attestation/Cargo.toml | 6 +- .../src/attestation.rs | 50 +++++++++--- .../src/test/attestation.hex | 1 + .../src/test/attestation2.hex | 1 + src/ic_tee_nitro_gateway/README.md | 76 +++++++++++++++++++ src/ic_tee_nitro_gateway/src/main.rs | 31 ++++---- 13 files changed, 198 insertions(+), 73 deletions(-) create mode 100644 nitro_enclave/host_iptables.sh create mode 100644 src/ic_tee_nitro_attestation/src/test/attestation.hex create mode 100644 src/ic_tee_nitro_attestation/src/test/attestation2.hex diff --git a/Cargo.lock b/Cargo.lock index 6eeac92..12940fc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -81,9 +81,9 @@ checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" [[package]] name = "anstream" -version = "0.6.17" +version = "0.6.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23a1e53f0f5d86382dafe1cf314783b2044280f406e7e1506368220ad11b1338" +checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" dependencies = [ "anstyle", "anstyle-parse", @@ -545,9 +545,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.1.34" +version = "1.1.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67b9470d453346108f93a59222a9a1a5724db32d0a4727b7ab7ace4b4d822dc9" +checksum = "0f57c4b4da2a9d619dd035f27316d7a426305b75be93d09e92f2b9229c34feaf" dependencies = [ "jobserver", "libc", @@ -967,7 +967,6 @@ dependencies = [ "ff", "generic-array", "group", - "hkdf", "pem-rfc7468", "pkcs8", "rand_core", @@ -1224,9 +1223,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.15.0" +version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" +checksum = "3a9bfc1af68b1726ea47d3d5109de126281def866b33970e10fbab11b5dafab3" [[package]] name = "heck" @@ -1619,7 +1618,7 @@ dependencies = [ [[package]] name = "ic_tee_agent" -version = "0.1.0" +version = "0.1.1" dependencies = [ "axum", "bytes", @@ -1640,7 +1639,7 @@ dependencies = [ [[package]] name = "ic_tee_cdk" -version = "0.1.0" +version = "0.1.1" dependencies = [ "candid", "ciborium", @@ -1652,7 +1651,7 @@ dependencies = [ [[package]] name = "ic_tee_cli" -version = "0.1.0" +version = "0.1.1" dependencies = [ "anyhow", "candid", @@ -1673,7 +1672,7 @@ dependencies = [ [[package]] name = "ic_tee_identity" -version = "0.1.0" +version = "0.1.1" dependencies = [ "candid", "ciborium", @@ -1690,13 +1689,14 @@ dependencies = [ [[package]] name = "ic_tee_nitro_attestation" -version = "0.1.0" +version = "0.1.1" dependencies = [ "candid", "ciborium", + "const-hex", "coset", "lazy_static", - "p384", + "ring", "serde", "serde_bytes", "sha2 0.10.8", @@ -1705,7 +1705,7 @@ dependencies = [ [[package]] name = "ic_tee_nitro_gateway" -version = "0.1.0" +version = "0.1.1" dependencies = [ "anyhow", "aws-nitro-enclaves-nsm-api", @@ -1891,7 +1891,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" dependencies = [ "equivalent", - "hashbrown 0.15.0", + "hashbrown 0.15.1", ] [[package]] @@ -2213,18 +2213,6 @@ dependencies = [ "sha2 0.10.8", ] -[[package]] -name = "p384" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70786f51bcc69f6a4c0360e063a4cac5419ef7c5cd5b3c99ad70f3be5ba79209" -dependencies = [ - "ecdsa", - "elliptic-curve", - "primeorder", - "sha2 0.10.8", -] - [[package]] name = "pairing" version = "0.23.0" @@ -2464,9 +2452,9 @@ dependencies = [ [[package]] name = "quinn-udp" -version = "0.5.6" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e346e016eacfff12233c243718197ca12f148c84e1e84268a896699b41c71780" +checksum = "7d5a626c6807713b15cac82a6acaccd6043c9a5408c24baae07611fec3f243da" dependencies = [ "cfg_aliases", "libc", @@ -2676,9 +2664,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.38" +version = "0.38.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa260229e6538e52293eeb577aabd09945a09d6d9cc0fc550ed7529056c2e32a" +checksum = "375116bee2be9ed569afe2154ea6a99dfdffd257f533f187498c2a8f5feaf4ee" dependencies = [ "bitflags 2.6.0", "errno", @@ -3184,18 +3172,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.67" +version = "1.0.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b3c6efbfc763e64eb85c11c25320f0737cb7364c4b6336db90aa9ebe27a0bbd" +checksum = "02dd99dc800bbb97186339685293e1cc5d9df1f8fae2d0aecd9ff1c77efea892" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.67" +version = "1.0.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b607164372e89797d78b8e23a6d67d5d1038c1c65efd52e1389ef8b77caba2a6" +checksum = "a7c61ec9a6f64d2793d8a45faba21efbe3ced62a886d44c36a009b2b519b4c7e" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index 7b51452..37edb15 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,7 +16,7 @@ strip = true opt-level = 's' [workspace.package] -version = "0.1.0" +version = "0.1.1" edition = "2021" repository = "https://github.com/ldclabs/ic-tee" keywords = ["tee", "canister", "icp", "nitro"] @@ -44,7 +44,6 @@ lazy_static = "1.5" serde = "1" serde_json = "1" serde_bytes = "0.11" -p384 = { version = "0.13" } sha2 = "0.10" sha3 = "0.10" ic-cdk = "0.16" diff --git a/nitro_enclave/host_iptables.sh b/nitro_enclave/host_iptables.sh new file mode 100644 index 0000000..3ffc290 --- /dev/null +++ b/nitro_enclave/host_iptables.sh @@ -0,0 +1,12 @@ +# route local incoming packets on port 8080 to the transparent proxy +iptables -t nat -A OUTPUT -p tcp --dport 8080 -o lo -j REDIRECT --to-port 1200 +iptables -t nat -A OUTPUT -p tcp --dport 8080 -d 127.0.0.1 -j REDIRECT --to-port 1200 + +# route incoming packets on port 443 to the transparent proxy +iptables -A PREROUTING -t nat -p tcp --dport 443 -i ens5 -j REDIRECT --to-port 1200 +# route incoming packets on port 1025:65535 to the transparent proxy +# iptables -A PREROUTING -t nat -p tcp --dport 1025:65535 -i ens5 -j REDIRECT --to-port 1200 + +iptables -L -t nat -v -n --line-number +# delete a rule by line number 7 +# sudo iptables -t nat -D PREROUTING 7 \ No newline at end of file diff --git a/nitro_enclave/setup.sh b/nitro_enclave/setup.sh index 3de3033..7534a01 100644 --- a/nitro_enclave/setup.sh +++ b/nitro_enclave/setup.sh @@ -22,7 +22,7 @@ iptables -t nat -A POSTROUTING -o lo -s 0.0.0.0 -j SNAT --to-source 127.0.0.1 iptables -L -t nat -v -n # your custom setup goes here -export LOG_LEVEL=Debug +# export LOG_LEVEL=Debug # starting supervisord cat /etc/supervisord.conf diff --git a/nitro_enclave/supervisord.conf b/nitro_enclave/supervisord.conf index 87ec024..446519d 100644 --- a/nitro_enclave/supervisord.conf +++ b/nitro_enclave/supervisord.conf @@ -21,6 +21,8 @@ stdout_logfile_maxbytes=0 stderr_logfile=/dev/stdout stderr_logfile_maxbytes=0 +# It is used to develop and test purpose only +# It should be removed in production [program:ic_tee_nitro_gateway-local] command=/app/vsock-to-ip --vsock-addr 88:8080 --ip-addr 127.0.0.1:8080 autorestart=true diff --git a/src/ic_tee_cli/src/main.rs b/src/ic_tee_cli/src/main.rs index 785069c..ddd080b 100644 --- a/src/ic_tee_cli/src/main.rs +++ b/src/ic_tee_cli/src/main.rs @@ -200,8 +200,8 @@ async fn main() -> Result<()> { }; pretty_println(&doc)?; match error { - Some(err) => println!("{} attestation verify failed: {}", kind, err), - None => println!("{} attestation verify success", kind), + Some(err) => println!("{} attestation verification failed: {}", kind, err), + None => println!("{} attestation verification success", kind), } } diff --git a/src/ic_tee_identity/src/api.rs b/src/ic_tee_identity/src/api.rs index e0f4aea..e3d3350 100644 --- a/src/ic_tee_identity/src/api.rs +++ b/src/ic_tee_identity/src/api.rs @@ -34,11 +34,31 @@ fn sign_in(kind: String, attestation: ByteBuf) -> Result .public_key .ok_or_else(|| "missing public key".to_string())?; - // TODO: check request method and params - let _req: AttestationUserRequest = attestation.user_data.map_or_else( + let req: AttestationUserRequest = attestation.user_data.map_or_else( || Err("missing user data".to_string()), |data| from_reader(data.as_slice()).map_err(|err| format!("invalid user data: {:?}", err)), )?; + if req.method != "sign_in" { + return Err("invalid attestation user request method".to_string()); + } + + let user_key = match req.params.as_ref() { + Some(SignInParams { id_scope }) => { + if id_scope == "image" { + canister_user_key(ic_cdk::id(), &kind, pcr0.as_slice(), None) + } else if id_scope == "enclave" { + canister_user_key( + ic_cdk::id(), + &kind, + pcr0.as_slice(), + Some(attestation.module_id.as_bytes()), + ) + } else { + return Err(format!("unsupport id_scope: {}", id_scope)); + } + } + _ => return Err("invalid attestation user request params".to_string()), + }; let session_expires_in_ms = store::state::with_mut(|state| { state.sign_in_count = state.sign_in_count.saturating_add(1); @@ -46,7 +66,6 @@ fn sign_in(kind: String, attestation: ByteBuf) -> Result }); let expiration = (now_ms + session_expires_in_ms) * MILLISECONDS; - let user_key = canister_user_key(ic_cdk::id(), &kind, pcr0.as_slice(), None); let principal = Principal::self_authenticating(&user_key); let delegation_hash = delegation_signature_msg(pubkey.as_slice(), expiration, None); store::state::add_signature(principal.as_slice(), delegation_hash.as_slice()); diff --git a/src/ic_tee_nitro_attestation/Cargo.toml b/src/ic_tee_nitro_attestation/Cargo.toml index 6b6363d..4bcb854 100644 --- a/src/ic_tee_nitro_attestation/Cargo.toml +++ b/src/ic_tee_nitro_attestation/Cargo.toml @@ -15,7 +15,11 @@ lazy_static = { workspace = true } serde = { workspace = true } serde_bytes = { workspace = true } ciborium = { workspace = true } -p384 = { workspace = true } sha2 = { workspace = true } coset = { workspace = true } x509-parser = { workspace = true, features = ["verify"] } +const-hex = { workspace = true } +ring = "0.17" + +[dev-dependencies] +const-hex = { workspace = true } diff --git a/src/ic_tee_nitro_attestation/src/attestation.rs b/src/ic_tee_nitro_attestation/src/attestation.rs index 1c53a0f..c5b1f5e 100644 --- a/src/ic_tee_nitro_attestation/src/attestation.rs +++ b/src/ic_tee_nitro_attestation/src/attestation.rs @@ -1,9 +1,9 @@ use ciborium::from_reader; use coset::{iana, Algorithm, CborSerializable, CoseSign1}; use lazy_static::lazy_static; -use p384::ecdsa::{signature::Verifier, Signature, VerifyingKey}; +use ring::signature::{VerificationAlgorithm, ECDSA_P384_SHA384_FIXED}; use sha2::Sha384; -use x509_parser::prelude::*; +use x509_parser::{pem::Pem, prelude::*}; // https://github.com/aws/aws-nitro-enclaves-nsm-api/blob/main/docs/attestation_process.md @@ -12,10 +12,19 @@ use crate::Attestation; const SIGN1_TAG_PREFIX: &[u8] = &[0xd2]; // COSE_Sign1 Tag 18 const ALG_ES384: Algorithm = Algorithm::Assigned(iana::Algorithm::ES384); -static ROOT_CERT_PEM: &[u8] = include_bytes!("./AWS_NitroEnclaves_Root-G1.pem"); +const ROOT_CERT_PEM: &[u8] = include_bytes!("./AWS_NitroEnclaves_Root-G1.pem"); lazy_static! { - static ref ROOT_CERT: X509Certificate<'static> = x509_cert(ROOT_CERT_PEM).unwrap(); + static ref ROOT_CERT_PUBKEY: Vec = { + let mut pems = Pem::iter_from_buffer(ROOT_CERT_PEM) + .collect::, _>>() + .expect("Failed to parse PEM buffer"); + let pem = pems.pop().expect("No PEM blocks found"); + let cert = pem.parse_x509().expect("Failed to parse X.509 certificate"); + let pk = cert.public_key(); + let pk = pk.subject_public_key.as_ref().to_vec(); + pk + }; } pub fn parse(attestation_doc: &[u8]) -> Result<(CoseSign1, Attestation), String> { @@ -45,16 +54,18 @@ pub fn parse_and_verify(attestation_doc: &[u8]) -> Result { cs1.protected.header.alg )); } - let sig = Signature::from_der(&cs1.signature) - .map_err(|err| format!("invalid signature: {:?}", err))?; + let cert = x509_cert(&doc.certificate)?; let pub_key = cert.public_key(); - let verifying_key = VerifyingKey::from_sec1_bytes(pub_key.raw) - .map_err(|err| format!("invalid public key in X.509 certificate: {:?}", err))?; let msg = cs1.tbs_data(&[]); - verifying_key - .verify(&sha384(&msg), &sig) - .map_err(|err| format!("signature verification failed: {:?}", err))?; + + ECDSA_P384_SHA384_FIXED + .verify( + pub_key.subject_public_key.as_ref().into(), + msg.as_slice().into(), + cs1.signature.as_slice().into(), + ) + .map_err(|_| "signature verification failed".to_string())?; let mut certs: Vec = Vec::with_capacity(doc.cabundle.len()); for pem in &doc.cabundle { @@ -63,6 +74,7 @@ pub fn parse_and_verify(attestation_doc: &[u8]) -> Result { } certs.push(cert); certs.reverse(); + verify_cert_chain(&certs)?; Ok(doc) @@ -102,7 +114,7 @@ pub fn verify_cert_chain(certs: &[X509Certificate]) -> Result<(), String> { err ) })?; - } else if cert.public_key() != ROOT_CERT.public_key() { + } else if cert.public_key().subject_public_key.as_ref() != *ROOT_CERT_PUBKEY { return Err(format!( "certificate chain is broken: last certificate {:?} is not a root certificate", cert.subject() @@ -111,3 +123,17 @@ pub fn verify_cert_chain(certs: &[X509Certificate]) -> Result<(), String> { } Ok(()) } + +#[cfg(test)] +mod tests { + use super::*; + // https://github.com/briansmith/ring/issues/1942 + // export C_INCLUDE_PATH="/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/:$C_INCLUDE_PATH" + #[test] + fn test_parse_and_verify() { + let doc: &[u8] = include_bytes!("./test/attestation2.hex"); + let doc = const_hex::decode(doc).unwrap(); + let attestation = parse_and_verify(&doc).unwrap(); + println!("{:?}", attestation); + } +} diff --git a/src/ic_tee_nitro_attestation/src/test/attestation.hex b/src/ic_tee_nitro_attestation/src/test/attestation.hex new file mode 100644 index 0000000..4e6199a --- /dev/null +++ b/src/ic_tee_nitro_attestation/src/test/attestation.hex @@ -0,0 +1 @@ +8444a1013822a0591148a9696d6f64756c655f69647827692d30383465316464326631623263353239622d656e633031393066656363356231363632353166646967657374665348413338346974696d657374616d701b000001912b93cce76470637273b00058305fec1b73727425848d725d68f4a062c634061a035067bd0b9a6dc73e25ed5013dfe7ccbf8a7e9857eceb0841c4cb6ae6015830bcdf05fefccaa8e55bf2c8d6dee9e79bbff31e34bf28a99aa19e6b29c37ee80b214a414b7607236edf26fcb78654e63f025830ae41ca22df64a32d729667160a7f218e59e31586809e121ff2c446a36dc5354ba4e0f74dce737be3298cf82c364692e70358300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000458304b41d8e9ba3411505c1604762a2e91ba72c2c11d954f4a640bf4402bd195dd432804ffa0ceed1b6c39233d13b1e2e5950558300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000658300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000758300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000858300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000958300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a58300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b58300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c58300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d58300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e58300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f58300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006b63657274696669636174655902813082027d30820203a00302010202100190fecc5b1662510000000066b31651300a06082a8648ce3d04030330818f310b30090603550406130255533113301106035504080c0a57617368696e67746f6e3110300e06035504070c0753656174746c65310f300d060355040a0c06416d617a6f6e310c300a060355040b0c03415753313a303806035504030c31692d30383465316464326631623263353239622e61702d736f7574682d312e6177732e6e6974726f2d656e636c61766573301e170d3234303830373036333830365a170d3234303830373039333830395a308194310b30090603550406130255533113301106035504080c0a57617368696e67746f6e3110300e06035504070c0753656174746c65310f300d060355040a0c06416d617a6f6e310c300a060355040b0c03415753313f303d06035504030c36692d30383465316464326631623263353239622d656e63303139306665636335623136363235312e61702d736f7574682d312e6177733076301006072a8648ce3d020106052b8104002203620004cc2ea9292b533769a0251462271a8aa71d3a6a3066af704fe5013fdade68ccde9d43a25f2cbd40d8d2f1b7c8048de2e8e0978794a2b263fc3cc0a7521a909be368d2d815019534dc8937f5cf50622c16f0a4c14470ece074983f463e1541c702a31d301b300c0603551d130101ff04023000300b0603551d0f0404030206c0300a06082a8648ce3d0403030368003065023064a862f1efbef035aff51a407223ac3ecc4ba5405187fba7b6587feb104d388022d0b6f941e39621c1030a30ead9cf77023100ca7c0a03206a2e1e3c3314d18eddfa918818bbbd18d89d6cf21afba906ab843685d49009ab53d0a24300b9aaf8e4f67e68636162756e646c65845902153082021130820196a003020102021100f93175681b90afe11d46ccb4e4e7f856300a06082a8648ce3d0403033049310b3009060355040613025553310f300d060355040a0c06416d617a6f6e310c300a060355040b0c03415753311b301906035504030c126177732e6e6974726f2d656e636c61766573301e170d3139313032383133323830355a170d3439313032383134323830355a3049310b3009060355040613025553310f300d060355040a0c06416d617a6f6e310c300a060355040b0c03415753311b301906035504030c126177732e6e6974726f2d656e636c617665733076301006072a8648ce3d020106052b8104002203620004fc0254eba608c1f36870e29ada90be46383292736e894bfff672d989444b5051e534a4b1f6dbe3c0bc581a32b7b176070ede12d69a3fea211b66e752cf7dd1dd095f6f1370f4170843d9dc100121e4cf63012809664487c9796284304dc53ff4a3423040300f0603551d130101ff040530030101ff301d0603551d0e041604149025b50dd90547e796c396fa729dcf99a9df4b96300e0603551d0f0101ff040403020186300a06082a8648ce3d0403030369003066023100a37f2f91a1c9bd5ee7b8627c1698d255038e1f0343f95b63a9628c3d39809545a11ebcbf2e3b55d8aeee71b4c3d6adf3023100a2f39b1605b27028a5dd4ba069b5016e65b4fbde8fe0061d6a53197f9cdaf5d943bc61fc2beb03cb6fee8d2302f3dff65902c3308202bf30820245a00302010202103cb53ed20a562aeaa09dbecf7cd1617f300a06082a8648ce3d0403033049310b3009060355040613025553310f300d060355040a0c06416d617a6f6e310c300a060355040b0c03415753311b301906035504030c126177732e6e6974726f2d656e636c61766573301e170d3234303830343137323535345a170d3234303832343138323535345a3065310b3009060355040613025553310f300d060355040a0c06416d617a6f6e310c300a060355040b0c034157533137303506035504030c2e353934366339666637643061313837342e61702d736f7574682d312e6177732e6e6974726f2d656e636c617665733076301006072a8648ce3d020106052b8104002203620004650befbbfa81e43620d1d0269f0b253def7fa36ae1839c7bd76c33f49acf925729f4af6fefbe2a113a36d81b3b852392cc58e1f405b4a0e22b95e0ce4e38e9c4d18497ed6cd10cfc2b1f12303f3d83833b120a2d021abe3e833f5c5823dce78ea381d53081d230120603551d130101ff040830060101ff020102301f0603551d230418301680149025b50dd90547e796c396fa729dcf99a9df4b96301d0603551d0e041604143a0333f28fefadd23b4e72e8b7202126e86a867e300e0603551d0f0101ff040403020186306c0603551d1f046530633061a05fa05d865b687474703a2f2f6177732d6e6974726f2d656e636c617665732d63726c2e73332e616d617a6f6e6177732e636f6d2f63726c2f61623439363063632d376436332d343262642d396539662d3539333338636236376638342e63726c300a06082a8648ce3d0403030368003065023100fb376efc4887fcc2840a4d732a243f2a5ee8459280da297c859481012228b58b89b888b392516ec1fe802bc7236fbb9202301be62087e072166b79249eb59b23ac26c14c520f13b1ab98754727b30a05563f0e4b59574aac586ccb603eb065fdb00659031c308203183082029ea003020102021047b11903f8720e410336ad4cf5b6ff32300a06082a8648ce3d0403033065310b3009060355040613025553310f300d060355040a0c06416d617a6f6e310c300a060355040b0c034157533137303506035504030c2e353934366339666637643061313837342e61702d736f7574682d312e6177732e6e6974726f2d656e636c61766573301e170d3234303830363232303333395a170d3234303831323139303333385a30818a313d303b06035504030c34313366633266316266346236306334392e7a6f6e616c2e61702d736f7574682d312e6177732e6e6974726f2d656e636c61766573310c300a060355040b0c03415753310f300d060355040a0c06416d617a6f6e310b3009060355040613025553310b300906035504080c0257413110300e06035504070c0753656174746c653076301006072a8648ce3d020106052b8104002203620004e379708241e8f815ee093c70162a217860fbe8768cebbf1e7867f81387ea26940120101e252dad038580654509bd3da342dbcb25ea20b679cee6f51e80d235b0de72ea6970f0d994a89723828441dadf336b6e086b7fbab4998b73af8ae58d3aa381ec3081e930120603551d130101ff040830060101ff020101301f0603551d230418301680143a0333f28fefadd23b4e72e8b7202126e86a867e301d0603551d0e04160414d506f8191a635f246ee54fb754e8585fb230f8b9300e0603551d0f0101ff0404030201863081820603551d1f047b30793077a075a0738671687474703a2f2f63726c2d61702d736f7574682d312d6177732d6e6974726f2d656e636c617665732e73332e61702d736f7574682d312e616d617a6f6e6177732e636f6d2f63726c2f30313834633737642d306535612d343365382d386363342d3337663438623933656264652e63726c300a06082a8648ce3d040303036800306502310093b6049011540835485a777bc28ccb340cfad1476fa5680c10a7a17e2219415976cac4e739a58419e19ce9f98e25a43c0230744d40b35a16ace1d41107730f5e9d98e2fc016deb21b4342e7d68f2ecb81bfe7390647ab3c29dcce6a0b8b8747755ed5902c4308202c030820246a003020102021412d6a11c5c9820756d361ce5de93fe62315c8caa300a06082a8648ce3d04030330818a313d303b06035504030c34313366633266316266346236306334392e7a6f6e616c2e61702d736f7574682d312e6177732e6e6974726f2d656e636c61766573310c300a060355040b0c03415753310f300d060355040a0c06416d617a6f6e310b3009060355040613025553310b300906035504080c0257413110300e06035504070c0753656174746c65301e170d3234303830373030323430355a170d3234303830383030323430355a30818f310b30090603550406130255533113301106035504080c0a57617368696e67746f6e3110300e06035504070c0753656174746c65310f300d060355040a0c06416d617a6f6e310c300a060355040b0c03415753313a303806035504030c31692d30383465316464326631623263353239622e61702d736f7574682d312e6177732e6e6974726f2d656e636c617665733076301006072a8648ce3d020106052b8104002203620004cc8e7ddbb457bb509633e999265e0bd04d27656a5be67bd391442f59b859fd49dfa614d58be55a36d67c10fe371d115f4e60fc428f9f3a6053ef668c18cb7073ea024d0c6bcf38f582424d03088da503b454e88517c888b7019b40a433ae6b04a366306430120603551d130101ff040830060101ff020100300e0603551d0f0101ff040403020204301d0603551d0e04160414ee7124baf4ecbfc39072ef63596522ea904b0a3d301f0603551d23041830168014d506f8191a635f246ee54fb754e8585fb230f8b9300a06082a8648ce3d0403030368003065023100cd875a5dfd84cfb601f1ab857ca3376e33bda66ad5a26730dc86f43051cb21c7e6d7a83238d286e2391447e57f0a9125023035e9db695d063960e902d74c9e6d112dde89bbcd097a05981cd60ed60ba43ce52e6f44f6a77eba3c6f81c543d656888c6a7075626c69635f6b6579584057febcf9e7f5081d3d24182817df526a1c9c3df7e46b64613acd13f9aa53b81de888a8562ba7b4a0e42c48d24d7e444ffcba311ceddb5068eca2ea899379ab5069757365725f64617461f6656e6f6e6365f65860f2423138f2866a9f332daaf22fd74704e8311bdb790803fab8be9287176f5a0df06cf6a32c1acdf78648ff8b58985fcc8c40fff9ba225869e3f62ab0540319b2116b20187b51d5f5a4e15d63b8667f70a130ec5ea989badada564ffb58690e04 \ No newline at end of file diff --git a/src/ic_tee_nitro_attestation/src/test/attestation2.hex b/src/ic_tee_nitro_attestation/src/test/attestation2.hex new file mode 100644 index 0000000..60909b9 --- /dev/null +++ b/src/ic_tee_nitro_attestation/src/test/attestation2.hex @@ -0,0 +1 @@ +8444a1013822a0591101a9696d6f64756c655f69647827692d30353665316162396133316364373761302d656e633031393266623461636534346431636666646967657374665348413338346974696d657374616d701b00000192fb4b36786470637273b0005830495f5bf7567422bf53a4ff549a250d35f989062469c06e20eccc1b5f98f82e957a66b44b094372ebd037cb113affd4a10158304b4d5b3661b3efc12920900c80e126e4ce783c522de6c02a2a5bf7af3a2b9327b86776f188e4be1c1c404a129dbda4930258302fdd6697def721b3bc32cbe3506c7e0447bf77ba8e6bc60b6f8321d4f19c9315b41529d7d53eb2986ff03e7077d70c39035830000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000045830234fd04dcbedf021cb980abf49c2b86b497e90d3348711887f33bc1bd07dc2dd13acf462abec2fd36756f1089dc6f0850558300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000658300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000758300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000858300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000958300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a58300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b58300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c58300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d58300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e58300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f58300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006b63657274696669636174655902803082027c30820201a00302010202100192fb4ace44d1cf000000006729cd86300a06082a8648ce3d04030330818e310b30090603550406130255533113301106035504080c0a57617368696e67746f6e3110300e06035504070c0753656174746c65310f300d060355040a0c06416d617a6f6e310c300a060355040b0c034157533139303706035504030c30692d30353665316162396133316364373761302e75732d776573742d312e6177732e6e6974726f2d656e636c61766573301e170d3234313130353037343731355a170d3234313130353130343731385a308193310b30090603550406130255533113301106035504080c0a57617368696e67746f6e3110300e06035504070c0753656174746c65310f300d060355040a0c06416d617a6f6e310c300a060355040b0c03415753313e303c06035504030c35692d30353665316162396133316364373761302d656e63303139326662346163653434643163662e75732d776573742d312e6177733076301006072a8648ce3d020106052b81040022036200040d40a39ce1eb925bdbc39e5981a171bf19d630d86684ab50c2a409229b98eb5003d74b6cb9ceabf3ed4c8472d9134f96dd33d60989a61852adbe9a438c88ff18d8733cded2878cd7b327de16ab553c6c87a5f0d19d29718eaa5cbd6cd8230bbda31d301b300c0603551d130101ff04023000300b0603551d0f0404030206c0300a06082a8648ce3d0403030369003066023100bdd035d0bde402c3eb6ae3f8900621a6bbf40efc4c25cf4d42933e968719855e791168200dbcd469037e70b86a478318023100995ab345de89e9dfb378bbe5a4e88bb34eb71279ef62580b34af165c12f90d6c374ea2ff18c350764f36f8eeb066655b68636162756e646c65845902153082021130820196a003020102021100f93175681b90afe11d46ccb4e4e7f856300a06082a8648ce3d0403033049310b3009060355040613025553310f300d060355040a0c06416d617a6f6e310c300a060355040b0c03415753311b301906035504030c126177732e6e6974726f2d656e636c61766573301e170d3139313032383133323830355a170d3439313032383134323830355a3049310b3009060355040613025553310f300d060355040a0c06416d617a6f6e310c300a060355040b0c03415753311b301906035504030c126177732e6e6974726f2d656e636c617665733076301006072a8648ce3d020106052b8104002203620004fc0254eba608c1f36870e29ada90be46383292736e894bfff672d989444b5051e534a4b1f6dbe3c0bc581a32b7b176070ede12d69a3fea211b66e752cf7dd1dd095f6f1370f4170843d9dc100121e4cf63012809664487c9796284304dc53ff4a3423040300f0603551d130101ff040530030101ff301d0603551d0e041604149025b50dd90547e796c396fa729dcf99a9df4b96300e0603551d0f0101ff040403020186300a06082a8648ce3d0403030369003066023100a37f2f91a1c9bd5ee7b8627c1698d255038e1f0343f95b63a9628c3d39809545a11ebcbf2e3b55d8aeee71b4c3d6adf3023100a2f39b1605b27028a5dd4ba069b5016e65b4fbde8fe0061d6a53197f9cdaf5d943bc61fc2beb03cb6fee8d2302f3dff65902c4308202c030820245a003020102021100bf2c4bc1f7d517c3504856fb2655c939300a06082a8648ce3d0403033049310b3009060355040613025553310f300d060355040a0c06416d617a6f6e310c300a060355040b0c03415753311b301906035504030c126177732e6e6974726f2d656e636c61766573301e170d3234313130333038323332375a170d3234313132333039323332375a3064310b3009060355040613025553310f300d060355040a0c06416d617a6f6e310c300a060355040b0c034157533136303406035504030c2d613661393238326636366630313332642e75732d776573742d312e6177732e6e6974726f2d656e636c617665733076301006072a8648ce3d020106052b810400220362000460e69d162a1ef9e67a5505260f66488acfed464e08486d37e294b4e097424b317c5bf32d9986428404b4c9bf626849c6a6f98076364a302258071cf9c7d595af08c2935c41a8803035491c11607da2e6a330a6e5c808e14e947a995e1ec60f8da381d53081d230120603551d130101ff040830060101ff020102301f0603551d230418301680149025b50dd90547e796c396fa729dcf99a9df4b96301d0603551d0e0416041415cb2fda3d1ade6b5f8fdd2ea66731c1d4a80fa3300e0603551d0f0101ff040403020186306c0603551d1f046530633061a05fa05d865b687474703a2f2f6177732d6e6974726f2d656e636c617665732d63726c2e73332e616d617a6f6e6177732e636f6d2f63726c2f61623439363063632d376436332d343262642d396539662d3539333338636236376638342e63726c300a06082a8648ce3d0403030369003066023100acf964a19ae8ee4bc0803004c52233e51e20e25c77cb8fc4d37bada4c5daeb04b36000e89f86e34a9da0b1eeafeca7ce023100d23e7a606545bdaa6f5948f7cd10c2967c834aa650bfe958a6f14f329186909af66f4a6d28fce90698315b5fcdac1d47590318308203143082029aa00302010202104824761650be86cbd148af92a1c712d6300a06082a8648ce3d0403033064310b3009060355040613025553310f300d060355040a0c06416d617a6f6e310c300a060355040b0c034157533136303406035504030c2d613661393238326636366630313332642e75732d776573742d312e6177732e6e6974726f2d656e636c61766573301e170d3234313130343232303533395a170d3234313131303139303533395a308189313c303a06035504030c33623438383334333037333164386235382e7a6f6e616c2e75732d776573742d312e6177732e6e6974726f2d656e636c61766573310c300a060355040b0c03415753310f300d060355040a0c06416d617a6f6e310b3009060355040613025553310b300906035504080c0257413110300e06035504070c0753656174746c653076301006072a8648ce3d020106052b8104002203620004570eb95f60e65c3a0db41fd0447c28b212f24e0960135d7edb1d23c73c8140c26c7699ef91803a2dbe5723cb7640736e40b8e25f465eb7d90cf545dfd1f5ca8cf1087ce8cd7d14876a8d6f47261f31b0f3ff30d60287f006ef901c98875e7c78a381ea3081e730120603551d130101ff040830060101ff020101301f0603551d2304183016801415cb2fda3d1ade6b5f8fdd2ea66731c1d4a80fa3301d0603551d0e0416041494ba3c69de3923df2fe2d2685a66aa151bfac67f300e0603551d0f0101ff0404030201863081800603551d1f047930773075a073a071866f687474703a2f2f63726c2d75732d776573742d312d6177732d6e6974726f2d656e636c617665732e73332e75732d776573742d312e616d617a6f6e6177732e636f6d2f63726c2f62656666306430392d333130632d343537622d623162622d3662366238373835363261312e63726c300a06082a8648ce3d04030303680030650230197b42e46a45355a0368bf32cacee08f0e8f1f1f90d30af589ff70f62cbd1cd487dee8ecb8ea2deb290e17fd07876537023100a7b05a1322279e7a7c897fd199b1f84ac1f82bad813bd9a6bd74cdee783728a4880f68b17134ee93808e70bbb1aa883a5902c2308202be30820244a00302010202147836a6bc686f68ffd1840245b5d223ef2cb40fd3300a06082a8648ce3d040303308189313c303a06035504030c33623438383334333037333164386235382e7a6f6e616c2e75732d776573742d312e6177732e6e6974726f2d656e636c61766573310c300a060355040b0c03415753310f300d060355040a0c06416d617a6f6e310b3009060355040613025553310b300906035504080c0257413110300e06035504070c0753656174746c65301e170d3234313130353033343935335a170d3234313130363033343935335a30818e310b30090603550406130255533113301106035504080c0a57617368696e67746f6e3110300e06035504070c0753656174746c65310f300d060355040a0c06416d617a6f6e310c300a060355040b0c034157533139303706035504030c30692d30353665316162396133316364373761302e75732d776573742d312e6177732e6e6974726f2d656e636c617665733076301006072a8648ce3d020106052b8104002203620004e903aa94fb07313439f87eb37632424b680d2c85cb5edaacb2b179aee8480d0bcc13e993697a7dc6b07d4f3e5fef54aaba26c7ff8234fc2d2a02e88ccc05dc27d41d4d5bfc2fc83863e670845c8c783ebedca3cce5e0d285ca7d3f45bb3c9335a366306430120603551d130101ff040830060101ff020100300e0603551d0f0101ff040403020204301d0603551d0e04160414b2ee2c180cf26caafa75802eadadb9283e5a6837301f0603551d2304183016801494ba3c69de3923df2fe2d2685a66aa151bfac67f300a06082a8648ce3d0403030368003065023078b080192d4224c08aad8198781c965259ade74ee4de62212b92bdbdf858dea9b989c33f9bae4109e0ded06613f503aa023100d7dbcdc4a40c768c2d218516226345ef98d020793d587b2a00742fbfb274897e640071ddcbe716b47c26ef4f9a4a716e6a7075626c69635f6b6579f669757365725f64617461f6656e6f6e6365f65860b8e84230de933743ee4e968a6d9c24a2781263400460588f7a489b168c64cb1b581452ccc0f291ff95d02c41cebdc378fb792b0e8db03dc614b205ab45813dc15e4375e075999380e82e0f1bddb4234d1cb7d13e9366dbbcfef0231a96c8696c \ No newline at end of file diff --git a/src/ic_tee_nitro_gateway/README.md b/src/ic_tee_nitro_gateway/README.md index f4a4225..5160ebc 100644 --- a/src/ic_tee_nitro_gateway/README.md +++ b/src/ic_tee_nitro_gateway/README.md @@ -5,8 +5,84 @@ [![Docs.rs](https://img.shields.io/docsrs/ic_tee_nitro_gateway?label=docs.rs)](https://docs.rs/ic_tee_nitro_gateway) [![Latest Version](https://img.shields.io/crates/v/ic_tee_nitro_gateway.svg)](https://crates.io/crates/ic_tee_nitro_gateway) +## Overview `ic_tee_nitro_gateway` is a gateway service in an AWS Nitro enclave. +## Deploy +### Building and running AWS Nitro Enclave image + +#### Setup host machine + +https://docs.marlin.org/learn/oyster/core-concepts/networking/outgoing + +```bash +wget -O vsock-to-ip-transparent http://public.artifacts.marlin.pro/projects/enclaves/vsock-to-ip-transparent_v1.0.0_linux_amd64 +chmod +x vsock-to-ip-transparent +./vsock-to-ip-transparent --vsock-addr 3:1200 +``` + +https://docs.marlin.org/learn/oyster/core-concepts/networking/incoming + +iptables rules: +```bash +# route local incoming packets on port 8080 to the transparent proxy +iptables -t nat -A OUTPUT -p tcp --dport 8080 -o lo -j REDIRECT --to-port 1200 +iptables -t nat -A OUTPUT -p tcp --dport 8080 -d 127.0.0.1 -j REDIRECT --to-port 1200 + +# route incoming packets on port 443 to the transparent proxy +iptables -A PREROUTING -t nat -p tcp --dport 443 -i ens5 -j REDIRECT --to-port 1200 +# route incoming packets on port 1025:65535 to the transparent proxy +# iptables -A PREROUTING -t nat -p tcp --dport 1025:65535 -i ens5 -j REDIRECT --to-port 1200 +``` + +```bash +wget -O port-to-vsock-transparent http://public.artifacts.marlin.pro/projects/enclaves/port-to-vsock-transparent_v1.0.0_linux_amd64 +chmod +x port-to-vsock-transparent +./port-to-vsock-transparent --vsock 88 --ip-addr 0.0.0.0:1200 +``` + +#### Build and run enclave + +The following steps should be run in AWS Nitro-based instances. + +https://docs.aws.amazon.com/enclaves/latest/user/getting-started.html + +```bash +cargo install ic_tee_cli +sudo nitro-cli build-enclave --docker-uri ghcr.io/ldclabs/ic_tee_nitro_gateway_enclave_amd64:latest --output-file ic_tee_nitro_gateway_enclave_amd64.eif +# Start building the Enclave Image... +# Enclave Image successfully created. +# { +# "Measurements": { +# "HashAlgorithm": "Sha384 { ... }", +# "PCR0": "57787b1892dfd26b137e14f3299912ccf8879ca81c29e6d4f6f346e10084c9c77f615ef0b3f8a77a56611d4652703260", +# "PCR1": "4b4d5b3661b3efc12920900c80e126e4ce783c522de6c02a2a5bf7af3a2b9327b86776f188e4be1c1c404a129dbda493", +# "PCR2": "b00df67ad3f1a255bccaa9e9f43875a0763cc825e594fb7d14514a708e3b02d6816138d210a407704b5fae8f033d7ba3" +# } +# } +ic_tee_cli -c e7tgb-6aaaa-aaaap-akqfa-cai identity-derive --seed 57787b1892dfd26b137e14f3299912ccf8879ca81c29e6d4f6f346e10084c9c77f615ef0b3f8a77a56611d4652703260 +# principal: 7vzhl-hr6f5-oc2w5-u7ig6-ts7wz-6b7u6-xgmw5-ye65a-wn735-nexe5-oae +sudo nitro-cli run-enclave --cpu-count 2 --memory 512 --enclave-cid 88 --eif-path ic_tee_nitro_gateway_enclave_amd64.eif +# --attach-console +# Start allocating memory... +# Started enclave with enclave-cid: 88, memory: 512 MiB, cpu-ids: [1, 3] +# { +# "EnclaveName": "ic_tee_nitro_gateway_enclave_amd64", +# "EnclaveID": "i-056e1ab9a31cd77a0-enc192fa599ed1cf5f", +# "ProcessID": 3377, +# "EnclaveCID": 88, +# "NumberOfCPUs": 2, +# "CPUIDs": [ +# 1, +# 3 +# ], +# "MemoryMiB": 512 +# } +sudo nitro-cli describe-enclaves +sudo nitro-cli terminate-enclave --enclave-id i-056e1ab9a31cd77a0-enc192fa599ed1cf5f +``` + + ## License Copyright © 2024 [LDC Labs](https://github.com/ldclabs). diff --git a/src/ic_tee_nitro_gateway/src/main.rs b/src/ic_tee_nitro_gateway/src/main.rs index d474e3f..c448fe7 100644 --- a/src/ic_tee_nitro_gateway/src/main.rs +++ b/src/ic_tee_nitro_gateway/src/main.rs @@ -10,7 +10,7 @@ use ic_tee_agent::{ setting::{decrypt_payload, decrypt_tls}, }; use ic_tee_cdk::{to_cbor_bytes, AttestationUserRequest, SignInParams, TEEAppInformation}; -use ic_tee_nitro_attestation::{parse, parse_and_verify, AttestationRequest}; +use ic_tee_nitro_attestation::{parse_and_verify, AttestationRequest}; use std::{net::SocketAddr, sync::Arc, time::Duration}; use structured_logger::{async_json::new_writer, get_env_level, unix_ms, Builder}; use tokio::signal; @@ -91,22 +91,21 @@ async fn main() -> Result<()> { }) .map_err(anyhow::Error::msg)?; - // let attestation = parse_and_verify(doc.as_slice()).map_err(anyhow::Error::msg)?; - let (_, attestation) = parse(doc.as_slice()).map_err(anyhow::Error::msg)?; + let attestation = parse_and_verify(doc.as_slice()).map_err(anyhow::Error::msg)?; - // tee_agent - // .sign_in(TEE_KIND.to_string(), doc.into()) - // .await - // .map_err(anyhow::Error::msg)?; + tee_agent + .sign_in(TEE_KIND.to_string(), doc.into()) + .await + .map_err(anyhow::Error::msg)?; - let upgrade_identity = if let Some(v) = cli.configuration_upgrade_identity { - // Some(Principal::from_text(v).map_err(|err| { - // anyhow::anyhow!("invalid configuration_upgrade_identity: {}", err) - // })?) - None - } else { - None - }; + let upgrade_identity = + if let Some(v) = cli.configuration_upgrade_identity { + Some(Principal::from_text(v).map_err(|err| { + anyhow::anyhow!("invalid configuration_upgrade_identity: {}", err) + })?) + } else { + None + }; // upgrade to a permanent identity let upgrade_identity = if let Some(subject) = upgrade_identity { @@ -164,7 +163,6 @@ async fn main() -> Result<()> { // 24 hours - 10 minutes let refresh_identity_ms = session_expires_in_ms - 1000 * 60 * 10; let refresh_identity = async { - return Result::<()>::Ok(()); loop { tokio::select! { _ = cancel_token.cancelled() => { @@ -224,7 +222,6 @@ async fn main() -> Result<()> { }; let public_server = async { - return Result::<()>::Ok(()); let secret = tee_agent .get_cose_secret(SettingPath { ns: namespace.clone(),