From 647f40fc96cf737850e09965b6c18a2d655e57c4 Mon Sep 17 00:00:00 2001 From: 0xZensh Date: Mon, 13 Jan 2025 14:23:48 +0800 Subject: [PATCH] feat: 1. reload servers after identity refreshing; 2. remove RwLock on TEEAgent --- Cargo.lock | 193 +++++++-------- Cargo.toml | 2 +- src/ic_tee_agent/Cargo.toml | 1 - src/ic_tee_agent/src/agent.rs | 170 ++++++------- src/ic_tee_nitro_gateway/src/handler.rs | 4 +- src/ic_tee_nitro_gateway/src/main.rs | 301 +++++++++++++++--------- 6 files changed, 360 insertions(+), 311 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 93ea448..8700ae0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -191,7 +191,7 @@ checksum = "965c2d33e53cb6b267e148a4cb0760bc01f4904c1cd4bb4002a085bb016d1490" dependencies = [ "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", "synstructure", ] @@ -203,7 +203,7 @@ checksum = "7b18050c2cd6fe86c3a76584ef5e0baf286d038cda203eb6223df2cc413565f7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] @@ -249,7 +249,7 @@ checksum = "3f934833b4b7233644e5848f235df3f57ed8c80f1528a26c3dfa13d2147fa056" dependencies = [ "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] @@ -461,7 +461,7 @@ version = "0.69.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.7.0", "cexpr", "clang-sys", "itertools 0.12.1", @@ -474,7 +474,7 @@ dependencies = [ "regex", "rustc-hash 1.1.0", "shlex", - "syn 2.0.95", + "syn 2.0.96", "which", ] @@ -509,9 +509,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.6.0" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" +checksum = "1be3f42a67d6d345ecd59f675f3f012d6974981560836e938c22b424b85ce1be" [[package]] name = "block-buffer" @@ -616,14 +616,14 @@ dependencies = [ "lazy_static", "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] name = "cc" -version = "1.2.7" +version = "1.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a012a0df96dd6d06ba9a1b29d6402d1a5d77c6befd2566afdc26e10603dc93d7" +checksum = "c8293772165d9345bdaaa39b45b2109591e63fe5e6fbc23c6ff930a048aa310b" dependencies = [ "jobserver", "libc", @@ -714,9 +714,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.25" +version = "4.5.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b95dca1b68188a08ca6af9d96a6576150f598824bdb528c1190460c2940a0b48" +checksum = "a8eb5e908ef3a6efbe1ed62520fb7287959888c88485abe072543190ecc66783" dependencies = [ "clap_builder", "clap_derive", @@ -724,9 +724,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.25" +version = "4.5.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ab52925392148efd3f7562f2136a81ffb778076bcc85727c6e020d6dd57cf15" +checksum = "96b01801b5fc6a0a232407abc821660c9c6d25a1cafc0d4f85f29fb8d9afc121" dependencies = [ "anstream", "anstyle", @@ -743,7 +743,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] @@ -970,7 +970,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] @@ -1096,7 +1096,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] @@ -1382,7 +1382,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] @@ -1761,7 +1761,7 @@ dependencies = [ "sha2 0.10.8", "simple_asn1", "stop-token", - "thiserror 2.0.10", + "thiserror 2.0.11", "time", "tokio", "tower-service", @@ -1867,7 +1867,7 @@ dependencies = [ "quote", "serde", "serde_tokenstream", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] @@ -1881,7 +1881,7 @@ dependencies = [ "quote", "serde", "serde_tokenstream", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] @@ -2332,7 +2332,7 @@ dependencies = [ "serde_cbor", "serde_repr", "sha2 0.10.8", - "thiserror 2.0.10", + "thiserror 2.0.11", ] [[package]] @@ -2472,7 +2472,7 @@ dependencies = [ "serde_bytes", "sha2 0.10.8", "sha3", - "thiserror 2.0.10", + "thiserror 2.0.11", "x25519-dalek", ] @@ -2491,7 +2491,7 @@ dependencies = [ [[package]] name = "ic_tee_agent" -version = "0.2.3" +version = "0.2.4" dependencies = [ "axum-core", "base64 0.22.1", @@ -2514,13 +2514,12 @@ dependencies = [ "serde_bytes", "serde_json", "structured-logger", - "thiserror 2.0.10", - "tokio", + "thiserror 2.0.11", ] [[package]] name = "ic_tee_cdk" -version = "0.2.3" +version = "0.2.4" dependencies = [ "candid", "ciborium", @@ -2532,7 +2531,7 @@ dependencies = [ [[package]] name = "ic_tee_cli" -version = "0.2.3" +version = "0.2.4" dependencies = [ "anyhow", "candid", @@ -2555,7 +2554,7 @@ dependencies = [ [[package]] name = "ic_tee_host_daemon" -version = "0.2.3" +version = "0.2.4" dependencies = [ "anyhow", "clap", @@ -2568,7 +2567,7 @@ dependencies = [ [[package]] name = "ic_tee_identity" -version = "0.2.3" +version = "0.2.4" dependencies = [ "candid", "ciborium", @@ -2586,7 +2585,7 @@ dependencies = [ [[package]] name = "ic_tee_logtail" -version = "0.2.3" +version = "0.2.4" dependencies = [ "anyhow", "clap", @@ -2597,7 +2596,7 @@ dependencies = [ [[package]] name = "ic_tee_nitro_attestation" -version = "0.2.3" +version = "0.2.4" dependencies = [ "candid", "ciborium", @@ -2613,7 +2612,7 @@ dependencies = [ [[package]] name = "ic_tee_nitro_gateway" -version = "0.2.3" +version = "0.2.4" dependencies = [ "anyhow", "aws-nitro-enclaves-nsm-api", @@ -2781,7 +2780,7 @@ checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] @@ -2886,9 +2885,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.76" +version = "0.3.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6717b6b5b077764fb5966237269cb3c64edddde4b14ce42647430a78ced9e7b7" +checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" dependencies = [ "once_cell", "wasm-bindgen", @@ -3120,7 +3119,7 @@ version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.7.0", "cfg-if", "cfg_aliases", "libc", @@ -3237,7 +3236,7 @@ version = "0.10.68" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6174bc48f102d208783c2c84bf931bb75927a617866870de8a4ea85597f871f5" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.7.0", "cfg-if", "foreign-types", "libc", @@ -3254,7 +3253,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] @@ -3393,7 +3392,7 @@ checksum = "d56a66c0c55993aa927429d0f8a0abfd74f084e4d9c192cffed01e418d83eefb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] @@ -3485,12 +3484,12 @@ dependencies = [ [[package]] name = "prettyplease" -version = "0.2.27" +version = "0.2.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "483f8c21f64f3ea09fe0f30f5d48c3e8eefe5dac9129f0075f76593b4c1da705" +checksum = "6924ced06e1f7dfe3fa48d57b9f74f55d8915f5036121bef647ef4b204895fac" dependencies = [ "proc-macro2", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] @@ -3504,9 +3503,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.92" +version = "1.0.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" +checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99" dependencies = [ "unicode-ident", ] @@ -3517,7 +3516,7 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "14cae93065090804185d3b75f0bf93b8eeda30c7a9b4a33d3bdb3988d6229e50" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.7.0", "lazy_static", "num-traits", "rand", @@ -3547,7 +3546,7 @@ dependencies = [ "itertools 0.13.0", "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] @@ -3572,7 +3571,7 @@ dependencies = [ "rustc-hash 2.1.0", "rustls", "socket2", - "thiserror 2.0.10", + "thiserror 2.0.11", "tokio", "tracing", ] @@ -3591,7 +3590,7 @@ dependencies = [ "rustls", "rustls-pki-types", "slab", - "thiserror 2.0.10", + "thiserror 2.0.11", "tinyvec", "tracing", "web-time", @@ -3671,7 +3670,7 @@ version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.7.0", ] [[package]] @@ -3845,7 +3844,7 @@ version = "0.38.43" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a78891ee6bf2340288408954ac787aa063d8e8817e9f53abb37c695c6d834ef6" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.7.0", "errno", "libc", "linux-raw-sys", @@ -3854,9 +3853,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.20" +version = "0.23.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5065c3f250cbd332cd894be57c40fa52387247659b14a2d6041d121547903b1b" +checksum = "8f287924602bf649d949c63dc8ac8b235fa5387d394020705b80c4eb597ce5b8" dependencies = [ "aws-lc-rs", "log", @@ -3972,7 +3971,7 @@ version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.7.0", "core-foundation 0.9.4", "core-foundation-sys", "libc", @@ -3985,7 +3984,7 @@ version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "271720403f46ca04f7ba6f55d438f8bd878d6b8ca0a1046e8228c4145bcbb316" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.7.0", "core-foundation 0.10.0", "core-foundation-sys", "libc", @@ -4044,7 +4043,7 @@ checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] @@ -4086,7 +4085,7 @@ checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] @@ -4098,7 +4097,7 @@ dependencies = [ "proc-macro2", "quote", "serde", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] @@ -4196,13 +4195,13 @@ dependencies = [ [[package]] name = "simple_asn1" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adc4e5204eb1910f40f9cfa375f6f05b68c3abac4b6fd879c8ff5e7ae8a0a085" +checksum = "297f631f50729c8c99b84667867963997ec0b50f32b2a7dbcab828ef0541e8bb" dependencies = [ "num-bigint", "num-traits", - "thiserror 1.0.69", + "thiserror 2.0.11", "time", ] @@ -4331,7 +4330,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] @@ -4437,9 +4436,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.95" +version = "2.0.96" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46f71c0377baf4ef1cc3e3402ded576dccc315800fbc62dfc7fe04b009773b4a" +checksum = "d5d0adab1ae378d7f53bdebc67a39f1f151407ef230f0ce2883572f5d8985c80" dependencies = [ "proc-macro2", "quote", @@ -4463,7 +4462,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] @@ -4485,7 +4484,7 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.7.0", "core-foundation 0.9.4", "system-configuration-sys", ] @@ -4525,11 +4524,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.10" +version = "2.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3ac7f54ca534db81081ef1c1e7f6ea8a3ef428d2fc069097c079443d24124d3" +checksum = "d452f284b73e6d76dd36758a0c8684b1d5be31f92b89d07fd5822175732206fc" dependencies = [ - "thiserror-impl 2.0.10", + "thiserror-impl 2.0.11", ] [[package]] @@ -4540,18 +4539,18 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] name = "thiserror-impl" -version = "2.0.10" +version = "2.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e9465d30713b56a37ede7185763c3492a91be2f5fa68d958c44e41ab9248beb" +checksum = "26afc1baea8a989337eeb52b6e72a039780ce45c3edfcc9c5b9d112feeb173c2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] @@ -4642,7 +4641,7 @@ checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] @@ -4948,34 +4947,35 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.99" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a474f6281d1d70c17ae7aa6a613c87fce69a127e2624002df63dcb39d6cf6396" +checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" dependencies = [ "cfg-if", "once_cell", + "rustversion", "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.99" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f89bb38646b4f81674e8f5c3fb81b562be1fd936d84320f3264486418519c79" +checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" dependencies = [ "bumpalo", "log", "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.49" +version = "0.4.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38176d9b44ea84e9184eff0bc34cc167ed044f816accfe5922e54d84cf48eca2" +checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61" dependencies = [ "cfg-if", "js-sys", @@ -4986,9 +4986,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.99" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2cc6181fd9a7492eef6fef1f33961e3695e4579b9872a6f7c83aee556666d4fe" +checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -4996,22 +4996,25 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.99" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30d7a95b763d3c45903ed6c81f156801839e5ee968bb07e534c44df0fcd330c2" +checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" dependencies = [ "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.99" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "943aab3fdaaa029a6e0271b35ea10b72b943135afe9bffca82384098ad0e06a6" +checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +dependencies = [ + "unicode-ident", +] [[package]] name = "wasm-streams" @@ -5028,9 +5031,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.76" +version = "0.3.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04dd7223427d52553d3702c004d3b2fe07c148165faa56313cb00211e31c12bc" +checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" dependencies = [ "js-sys", "wasm-bindgen", @@ -5312,7 +5315,7 @@ checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" dependencies = [ "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", "synstructure", ] @@ -5334,7 +5337,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] @@ -5354,7 +5357,7 @@ checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808" dependencies = [ "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", "synstructure", ] @@ -5375,7 +5378,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", ] [[package]] @@ -5397,5 +5400,5 @@ checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.95", + "syn 2.0.96", ] diff --git a/Cargo.toml b/Cargo.toml index 5090153..5cb6c93 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,7 +18,7 @@ strip = true opt-level = 's' [workspace.package] -version = "0.2.3" +version = "0.2.4" edition = "2021" repository = "https://github.com/ldclabs/ic-tee" keywords = ["tee", "canister", "icp", "nitro"] diff --git a/src/ic_tee_agent/Cargo.toml b/src/ic_tee_agent/Cargo.toml index fbd43b0..a44f04b 100644 --- a/src/ic_tee_agent/Cargo.toml +++ b/src/ic_tee_agent/Cargo.toml @@ -22,7 +22,6 @@ serde_json = { workspace = true } serde_bytes = { workspace = true } ic-agent = { workspace = true } rand = { workspace = true } -tokio = { workspace = true } bytes = { workspace = true } mime = { workspace = true } thiserror = { workspace = true } diff --git a/src/ic_tee_agent/src/agent.rs b/src/ic_tee_agent/src/agent.rs index e30391f..7994be3 100644 --- a/src/ic_tee_agent/src/agent.rs +++ b/src/ic_tee_agent/src/agent.rs @@ -16,29 +16,16 @@ use ic_cose_types::{ use ic_tee_cdk::{Delegation, SignInResponse, SignedDelegation}; use serde_bytes::ByteBuf; use std::sync::Arc; -use tokio::sync::RwLock; use crate::{BasicIdentity, TEEIdentity}; #[derive(Clone)] pub struct TEEAgent { - agents: Arc>, - auth_canister: Principal, -} - -struct Agents { - identity: TEEIdentity, - agent: Agent, - cose: Client, - cose_canister: Principal, -} - -impl Agents { - fn set_identity(&mut self, identity: TEEIdentity) { - self.identity = identity; - self.agent.set_identity(self.identity.clone()); - self.cose = Client::new(Arc::new(self.agent.clone()), self.cose_canister); - } + pub auth_canister: Principal, + pub cose_canister: Principal, + pub identity: TEEIdentity, + pub agent: Agent, + pub cose: Client, } impl TEEAgent { @@ -57,60 +44,64 @@ impl TEEAgent { if host.starts_with("http://") { agent.fetch_root_key().await.map_err(format_error)?; } - let agents = Agents { - identity, - agent: agent.clone(), - cose: Client::new(Arc::new(agent), configuration_canister), - cose_canister: configuration_canister, - }; + let cose = Client::new(Arc::new(agent.clone()), configuration_canister); Ok(Self { auth_canister: authentication_canister, - agents: Arc::new(RwLock::new(agents)), + cose_canister: configuration_canister, + identity, + agent, + cose, }) } - pub async fn get_principal(&self) -> Principal { - self.agents.read().await.identity.get_principal() + fn with_new_identity(&self, identity: TEEIdentity) -> Self { + let mut agent = self.agent.clone(); + agent.set_identity(identity.clone()); + let cose = Client::new(Arc::new(agent.clone()), self.cose_canister); + Self { + auth_canister: self.auth_canister, + cose_canister: self.cose_canister, + identity, + agent, + cose, + } } - pub async fn is_authenticated(&self) -> bool { - self.agents.read().await.identity.is_authenticated() + pub fn get_principal(&self) -> Principal { + self.identity.get_principal() } - pub async fn with_identity(&self, f: impl FnOnce(&TEEIdentity) -> R) -> R { - f(&self.agents.read().await.identity) + pub fn is_authenticated(&self) -> bool { + self.identity.is_authenticated() } - pub async fn set_identity(&self, identity: &BasicIdentity, expires_in_ms: u64) { - let mut id = { - self.agents.read().await.identity.clone() - // drop read lock - }; - id.upgrade_with_identity(identity, expires_in_ms); - self.agents.write().await.set_identity(id.clone()); + pub fn with_identity(&self, identity: BasicIdentity, expires_in_ms: u64) -> Self { + let mut id = self.identity.clone(); + id.upgrade_with_identity(&identity, expires_in_ms); + self.with_new_identity(id) } pub async fn sign_in_with_attestation( &self, session_key: (SigningKey, Vec), f: impl FnOnce() -> Result<(String, ByteBuf), String>, - ) -> Result<(), String> { + ) -> Result { let (kind, attestation) = f()?; - let mut id = { - self.agents.read().await.identity.clone() - // drop read lock - }; - + let mut id = self.identity.clone(); let (user_key, delegation) = { - let agent = &self.agents.read().await.agent; - let res: Result = - update_call(agent, &self.auth_canister, "sign_in", (kind, attestation)).await?; + let res: Result = update_call( + &self.agent, + &self.auth_canister, + "sign_in", + (kind, attestation), + ) + .await?; let res = res?; let user_key = res.user_key.to_vec(); let res: Result = query_call( - agent, + &self.agent, &self.auth_canister, "get_delegation", ( @@ -124,9 +115,7 @@ impl TEEAgent { }; id.update_with_delegation(user_key, session_key, delegation); - self.agents.write().await.set_identity(id.clone()); - - Ok(()) + Ok(self.with_new_identity(id)) } // upgrade to a fixed identity derived from a name in a namespace on COSE canister @@ -135,62 +124,52 @@ impl TEEAgent { ns: String, name: String, session_key: (SigningKey, Vec), - ) -> Result<(), String> { - let mut id = { - self.agents.read().await.identity.clone() - // drop read lock - }; - + ) -> Result { + let mut id = self.identity.clone(); let mut msg = vec![]; into_writer(&(&ns, &name, &id.get_principal()), &mut msg) .expect("failed to encode Delegations data"); let sig = session_key.0.sign(&msg); let pubkey = ByteBuf::from(session_key.1.clone()); - { - let cose = &self.agents.read().await.cose; - let res = cose - .namespace_sign_delegation(&SignDelegationInput { - ns, - name, - pubkey: pubkey.clone(), - sig: sig.to_bytes().to_vec().into(), - }) - .await?; + let res = self + .cose + .namespace_sign_delegation(&SignDelegationInput { + ns, + name, + pubkey: pubkey.clone(), + sig: sig.to_bytes().to_vec().into(), + }) + .await?; - let user_key = res.user_key.to_vec(); - let res = cose - .get_delegation(&res.seed, &pubkey, res.expiration) - .await?; - - id.update_with_delegation( - user_key, - session_key, - SignedDelegation { - delegation: Delegation { - pubkey: res.delegation.pubkey, - expiration: res.delegation.expiration, - targets: res.delegation.targets, - }, - signature: res.signature, + let user_key = res.user_key.to_vec(); + let res = self + .cose + .get_delegation(&res.seed, &pubkey, res.expiration) + .await?; + id.update_with_delegation( + user_key, + session_key, + SignedDelegation { + delegation: Delegation { + pubkey: res.delegation.pubkey, + expiration: res.delegation.expiration, + targets: res.delegation.targets, }, - ); - // drop read lock - } + signature: res.signature, + }, + ); - self.agents.write().await.set_identity(id); - Ok(()) + Ok(self.with_new_identity(id)) } pub async fn cose_get_secret(&self, path: &SettingPath) -> Result<[u8; 32], String> { - let cose = &self.agents.read().await.cose; - let key = cose.get_cose_encrypted_key(path).await?; + let key = self.cose.get_cose_encrypted_key(path).await?; Ok(*key) } pub async fn cose_get_setting(&self, path: &SettingPath) -> Result { - let cose = &self.agents.read().await.cose; - cose.setting_get(path).await + self.cose.setting_get(path).await } pub async fn cose_create_setting( @@ -198,8 +177,7 @@ impl TEEAgent { path: &SettingPath, input: &CreateSettingInput, ) -> Result { - let cose = &self.agents.read().await.cose; - cose.setting_create(path, input).await + self.cose.setting_create(path, input).await } pub async fn update_call_raw( @@ -209,9 +187,6 @@ impl TEEAgent { input: Vec, ) -> Result { let res = self - .agents - .read() - .await .agent .update(canister_id, method_name) .with_arg(input) @@ -228,9 +203,6 @@ impl TEEAgent { input: Vec, ) -> Result { let res = self - .agents - .read() - .await .agent .query(canister_id, method_name) .with_arg(input) diff --git a/src/ic_tee_nitro_gateway/src/handler.rs b/src/ic_tee_nitro_gateway/src/handler.rs index 32a0b61..6ae558d 100644 --- a/src/ic_tee_nitro_gateway/src/handler.rs +++ b/src/ic_tee_nitro_gateway/src/handler.rs @@ -499,9 +499,7 @@ async fn handle_identity_request(req: &RPCRequest, app: &AppState) -> RPCRespons "sign_http" => { let digest: ByteArray<32> = from_reader(req.params.as_slice()).map_err(format_error)?; let mut headers = HeaderMap::new(); - app.tee_agent - .with_identity(|id| sign_digest_to_headers(id, &mut headers, digest.as_slice())) - .await?; + sign_digest_to_headers(&app.tee_agent.identity, &mut headers, digest.as_slice())?; let headers: HashMap<&str, &str> = headers .iter() .map(|(k, v)| (k.as_str(), v.to_str().unwrap())) diff --git a/src/ic_tee_nitro_gateway/src/main.rs b/src/ic_tee_nitro_gateway/src/main.rs index f30b48d..591bfdf 100644 --- a/src/ic_tee_nitro_gateway/src/main.rs +++ b/src/ic_tee_nitro_gateway/src/main.rs @@ -46,6 +46,9 @@ static LOCAL_HTTP_ADDR: &str = "127.0.0.1:8080"; static PUBLIC_HTTP_ADDR: &str = "127.0.0.1:8443"; static LOG_TARGET: &str = "bootstrap"; +const PUBLIC_SERVER_GRACEFUL_DURATION: Duration = Duration::from_secs(3); +const LOCAL_SERVER_SHUTDOWN_DURATION: Duration = Duration::from_secs(5); + #[derive(Parser)] #[clap(author, version, about, long_about = None)] struct Cli { @@ -123,7 +126,7 @@ async fn main() -> Result<()> { async fn bootstrap(cli: Cli) -> Result<()> { let start = Instant::now(); - let is_local = cli.ic_host.starts_with("http://"); + let is_dev = cli.ic_host.starts_with("http://"); // https://github.com/rustls/rustls/issues/1938 rustls::crypto::ring::default_provider() @@ -134,7 +137,7 @@ async fn bootstrap(cli: Cli) -> Result<()> { .map_err(|err| anyhow::anyhow!("invalid identity_canister id: {}", err))?; let cose_canister = Principal::from_text(cli.cose_canister) .map_err(|err| anyhow::anyhow!("invalid cose_canister id: {}", err))?; - let tee_agent = TEEAgent::new(&cli.ic_host, identity_canister, cose_canister) + let mut tee_agent = TEEAgent::new(&cli.ic_host, identity_canister, cose_canister) .await .map_err(anyhow::Error::msg)?; @@ -149,13 +152,12 @@ async fn bootstrap(cli: Cli) -> Result<()> { }), }); - let attestation = if is_local { + let attestation = if is_dev { // use a fixed identity for local development let sk = SigningKey::from([8u8; 32]); let id = BasicIdentity::from_signing_key(sk); // jjn6g-sh75l-r3cxb-wxrkl-frqld-6p6qq-d4ato-wske5-op7s5-n566f-bqe - - tee_agent.set_identity(&id, SESSION_EXPIRES_IN_MS).await; + tee_agent = tee_agent.with_identity(id, SESSION_EXPIRES_IN_MS); Attestation { timestamp: unix_ms(), @@ -184,7 +186,7 @@ async fn bootstrap(cli: Cli) -> Result<()> { elapsed = start.elapsed().as_millis() as u64; "parse_and_verify attestation for sign in, module_id: {:?}", attestation.module_id); - tee_agent + tee_agent = tee_agent .sign_in_with_attestation(session_key.clone(), || { Ok((TEE_KIND.to_string(), doc.into())) }) @@ -195,25 +197,25 @@ async fn bootstrap(cli: Cli) -> Result<()> { log::info!(target: LOG_TARGET, elapsed = start.elapsed().as_millis() as u64; - "sign_in, principal: {:?}", tee_agent.get_principal().await.to_text()); + "sign_in, principal: {:?}", tee_agent.get_principal().to_text()); // upgrade to a permanent identity let upgrade_identity = if let Some(ref name) = cli.cose_identity_name { log::info!(target: LOG_TARGET, "start to cose_upgrade_identity"); - tee_agent + tee_agent = tee_agent .cose_upgrade_identity(namespace.clone(), name.clone(), session_key) .await .map_err(anyhow::Error::msg)?; log::info!(target: LOG_TARGET, elapsed = start.elapsed().as_millis() as u64; - "upgrade to fixed identity, namespace: {}, name: {}, principal: {:?}", namespace, name, tee_agent.get_principal().await.to_text()); + "upgrade to fixed identity, namespace: {}, name: {}, principal: {:?}", namespace, name, tee_agent.get_principal().to_text()); Some(name.clone()) } else { None }; - let principal = tee_agent.get_principal().await; + let principal = tee_agent.get_principal(); log::info!(target: LOG_TARGET, "start to get master_secret"); // should replace with vetkey in the future let master_secret = tee_agent @@ -254,17 +256,63 @@ async fn bootstrap(cli: Cli) -> Result<()> { "TEE app information, principal: {:?}", principal.to_text()); let info = Arc::new(info); - let tee_agent = Arc::new(tee_agent); - let handle = axum_server::Handle::new(); - let cancel_token = CancellationToken::new(); - let shutdown_future = shutdown_signal(handle.clone(), cancel_token.clone()); - - // 24 hours - 10 minutes - let refresh_identity_ms = session_expires_in_ms - 1000 * 60 * 10; - let refresh_identity = async { + let global_cancel_token = CancellationToken::new(); + let shutdown_future = shutdown_signal(global_cancel_token.clone()); + + // 24 hours - 30 minutes + let refresh_identity_ms = session_expires_in_ms - 1000 * 60 * 30; + let task = async { + let mut prev_server_cancel_token: Option = None; loop { + let server_cancel_token = global_cancel_token.child_token(); + let local_server = start_local_server( + handler::AppState::new( + info.clone(), + Arc::new(tee_agent.clone()), + root_secret, + None, + cli.apps.clone(), + ), + start, + server_cancel_token.clone(), + ); + + let tls_config = if is_dev { + None + } else { + log::info!(target: LOG_TARGET, "start to get_tls"); + let tls = get_tls(&tee_agent, &start, namespace.clone(), &master_secret).await?; + let config = RustlsConfig::from_pem(tls.crt.to_vec(), tls.key.to_vec()) + .await + .map_err(|err| anyhow::anyhow!("read tls file failed: {:?}", err))?; + Some(config) + }; + + let public_server = start_public_server( + handler::AppState::new( + info.clone(), + Arc::new(tee_agent.clone()), + [0u8; 48], + None, + Vec::new(), + ), + start, + server_cancel_token.clone(), + tls_config, + ); + + tokio::spawn(async move { + // TODO: handle errors + let _ = tokio::join!(local_server, public_server); + }); + + if let Some(cancel_token) = prev_server_cancel_token { + cancel_token.cancel(); + } + prev_server_cancel_token = Some(server_cancel_token); + tokio::select! { - _ = cancel_token.cancelled() => { + _ = global_cancel_token.cancelled() => { break; } _ = tokio::time::sleep(Duration::from_millis(refresh_identity_ms)) => {} @@ -275,12 +323,14 @@ async fn bootstrap(cli: Cli) -> Result<()> { // ignore error match upgrade_identity { Some(ref name) => { - let _ = tee_agent + // remember to `dfx canister call ic_cose_canister namespace_add_delegator` + tee_agent = tee_agent .cose_upgrade_identity(namespace.clone(), name.clone(), session_key) - .await; + .await + .map_err(anyhow::Error::msg)?; } None => { - let _ = tee_agent + tee_agent = tee_agent .sign_in_with_attestation(session_key, || { let doc = sign_attestation(AttestationRequest { public_key: Some(public_key.into()), @@ -289,109 +339,123 @@ async fn bootstrap(cli: Cli) -> Result<()> { })?; Ok((TEE_KIND.to_string(), doc.into())) }) - .await; + .await + .map_err(anyhow::Error::msg)?; } } } Result::<()>::Ok(()) }; - let local_server = async { - let app = Router::new() - .route("/information", routing::get(handler::get_information)) - .route( - "/attestation", - routing::get(handler::get_attestation).post(handler::local_sign_attestation), - ) - .route( - "/canister/query", - routing::post(handler::local_query_canister), - ) - .route( - "/canister/update", - routing::post(handler::local_update_canister), - ) - .route("/keys", routing::post(handler::local_call_keys)) - .route("/identity", routing::post(handler::local_call_identity)) - .with_state(handler::AppState::new( - info.clone(), - tee_agent.clone(), - root_secret, - None, - cli.apps, - )); - let addr: SocketAddr = LOCAL_HTTP_ADDR.parse().map_err(anyhow::Error::new)?; - let listener = tokio::net::TcpListener::bind(&addr) - .await - .map_err(anyhow::Error::new)?; + match tokio::try_join!(task, shutdown_future) { + Ok(_) => Ok(()), + Err(err) => { + log::error!(target: LOG_TARGET, "server error: {:?}", err); + Err(err) + } + } +} + +async fn start_local_server( + app_state: handler::AppState, + start: Instant, + cancel_token: CancellationToken, +) -> anyhow::Result<()> { + let app = Router::new() + .route("/information", routing::get(handler::get_information)) + .route( + "/attestation", + routing::get(handler::get_attestation).post(handler::local_sign_attestation), + ) + .route( + "/canister/query", + routing::post(handler::local_query_canister), + ) + .route( + "/canister/update", + routing::post(handler::local_update_canister), + ) + .route("/keys", routing::post(handler::local_call_keys)) + .route("/identity", routing::post(handler::local_call_identity)) + .with_state(app_state); + + let addr: SocketAddr = LOCAL_HTTP_ADDR.parse().map_err(anyhow::Error::new)?; + + let listener = create_reuse_port_listener(addr).await?; + + log::warn!(target: LOG_TARGET, + elapsed = start.elapsed().as_millis() as u64; + "local {}@{} listening on {:?}", APP_NAME, APP_VERSION, addr); + + axum::serve(listener, app) + .with_graceful_shutdown(async move { + let _ = cancel_token.cancelled().await; + tokio::time::sleep(LOCAL_SERVER_SHUTDOWN_DURATION).await; + }) + .await + .map_err(anyhow::Error::new) +} + +async fn start_public_server( + app_state: handler::AppState, + start: Instant, + cancel_token: CancellationToken, + tls_config: Option, +) -> anyhow::Result<()> { + let app = Router::new() + .route( + "/.well-known/information", + routing::get(handler::get_information), + ) + .route( + "/.well-known/attestation", + routing::get(handler::get_attestation), + ) + .route("/{*any}", routing::any(handler::proxy)) + .with_state(app_state); + let addr: SocketAddr = PUBLIC_HTTP_ADDR.parse().map_err(anyhow::Error::new)?; + if let Some(tls_config) = tls_config { log::warn!(target: LOG_TARGET, elapsed = start.elapsed().as_millis() as u64; - "local {}@{} listening on {:?}", APP_NAME, APP_VERSION, addr); - axum::serve(listener, app) - .with_graceful_shutdown(shutdown_future) - .await - .map_err(anyhow::Error::new) - }; + "public {}@{} listening on {:?} with TLS", APP_NAME, APP_VERSION, addr); - let public_server = async { - let app = Router::new() - .route( - "/.well-known/information", - routing::get(handler::get_information), - ) - .route( - "/.well-known/attestation", - routing::get(handler::get_attestation), - ) - .route("/{*any}", routing::any(handler::proxy)) - .with_state(handler::AppState::new( - info.clone(), - tee_agent.clone(), - [0u8; 48], - None, - Vec::new(), - )); - let addr: SocketAddr = PUBLIC_HTTP_ADDR.parse().map_err(anyhow::Error::new)?; - - if is_local { - let listener = tokio::net::TcpListener::bind(&addr) - .await - .map_err(anyhow::Error::new)?; - log::warn!(target: LOG_TARGET, - elapsed = start.elapsed().as_millis() as u64; - "public {}@{} listening on {:?}", APP_NAME, APP_VERSION, addr); - axum::serve(listener, app) - .with_graceful_shutdown(shutdown_signal(handle.clone(), cancel_token.clone())) - .await - .map_err(anyhow::Error::new) - } else { - log::info!(target: LOG_TARGET, "start to get_tls"); - let tls = get_tls(&tee_agent, &start, namespace.clone(), &master_secret).await?; - let config = RustlsConfig::from_pem(tls.crt.to_vec(), tls.key.to_vec()) - .await - .map_err(|err| anyhow::anyhow!("read tls file failed: {:?}", err))?; + let handle = axum_server::Handle::new(); + let res = tokio::join!( + async { + let listener = create_reuse_port_listener(addr).await?; + axum_server::from_tcp_rustls(listener.into_std()?, tls_config) + .handle(handle.clone()) + .serve(app.into_make_service()) + .await + .map_err(anyhow::Error::new) + }, + async { + let _ = cancel_token.cancelled().await; + handle.graceful_shutdown(Some(PUBLIC_SERVER_GRACEFUL_DURATION)); + Result::<()>::Ok(()) + } + ); + res.0?; + res.1?; - log::warn!(target: LOG_TARGET, + Ok(()) + } else { + log::warn!(target: LOG_TARGET, elapsed = start.elapsed().as_millis() as u64; - "public {}@{} listening on {:?} with TLS", APP_NAME, APP_VERSION, addr); - axum_server::bind_rustls(addr, config) - .handle(handle) - .serve(app.into_make_service()) - .await - .map_err(anyhow::Error::new) - } - }; + "public {}@{} listening on {:?}", APP_NAME, APP_VERSION, addr); - match tokio::try_join!(refresh_identity, local_server, public_server) { - Ok(_) => Ok(()), - Err(err) => { - log::error!(target: LOG_TARGET, "server error: {:?}", err); - Err(err) - } + let listener = create_reuse_port_listener(addr).await?; + axum::serve(listener, app) + .with_graceful_shutdown(async move { + let _ = cancel_token.cancelled().await; + tokio::time::sleep(PUBLIC_SERVER_GRACEFUL_DURATION).await; + }) + .await + .map_err(anyhow::Error::new) } } -async fn shutdown_signal(handle: axum_server::Handle, cancel_token: CancellationToken) { +async fn shutdown_signal(cancel_token: CancellationToken) -> anyhow::Result<()> { let ctrl_c = async { signal::ctrl_c() .await @@ -415,9 +479,10 @@ async fn shutdown_signal(handle: axum_server::Handle, cancel_token: Cancellation } log::warn!(target: LOG_TARGET, "received termination signal, starting graceful shutdown"); - // 10 secs is how long server will wait to force shutdown - handle.graceful_shutdown(Some(Duration::from_secs(10))); cancel_token.cancel(); + tokio::time::sleep(LOCAL_SERVER_SHUTDOWN_DURATION).await; + + Ok(()) } async fn get_or_set_root_secret( @@ -503,3 +568,15 @@ async fn get_tls( } } } + +async fn create_reuse_port_listener(addr: SocketAddr) -> anyhow::Result { + let socket = match &addr { + SocketAddr::V4(_) => tokio::net::TcpSocket::new_v4()?, + SocketAddr::V6(_) => tokio::net::TcpSocket::new_v6()?, + }; + + socket.set_reuseport(true)?; + socket.bind(addr)?; + let listener = socket.listen(1024)?; + Ok(listener) +}