From d6431fb343e1d8db280ce5acc344450357843960 Mon Sep 17 00:00:00 2001 From: Waylon Jepsen Date: Tue, 11 Mar 2025 12:23:57 -0600 Subject: [PATCH 1/8] feat: return response data --- core/src/proof.rs | 1 + notary/src/proxy.rs | 11 ++++------- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/core/src/proof.rs b/core/src/proof.rs index 33d8b5986..12c8ac93d 100644 --- a/core/src/proof.rs +++ b/core/src/proof.rs @@ -33,5 +33,6 @@ impl TryFrom for Vec { #[derive(Debug, Deserialize, Serialize, Clone)] pub struct TeeProofData { + pub value: String, pub manifest_hash: Vec, } diff --git a/notary/src/proxy.rs b/notary/src/proxy.rs index 3f24c2847..0e063b754 100644 --- a/notary/src/proxy.rs +++ b/notary/src/proxy.rs @@ -121,17 +121,14 @@ pub fn create_tee_proof( ) -> Result { let validation_result = validate_notarization_legal(manifest, request, response)?; + let value = response.notary_response_body.clone().json.unwrap(); let manifest_hash = manifest.to_keccak_digest()?; let extraction_hash = validation_result.extraction_keccak_digest()?; let proof_value_hash = keccak_digest(&[manifest_hash, extraction_hash].concat()); - let to_sign = VerifyOutput { - value: format!("0x{}", hex::encode(proof_value_hash)), - manifest: manifest.clone(), - }; - let signature = sign_verification(to_sign, State(state))?; - let data = TeeProofData { manifest_hash: manifest_hash.to_vec() }; - + let to_sign = VerifyOutput { value, manifest: manifest.clone() }; + let signature = sign_verification(to_sign, State(state)).unwrap(); + let data = TeeProofData { value, manifest_hash: manifest_hash.to_vec() }; Ok(TeeProof { data, signature }) } From eb6ef549e8eec123973af4b8ccb58771177c218c Mon Sep 17 00:00:00 2001 From: Waylon Jepsen Date: Tue, 11 Mar 2025 12:37:57 -0600 Subject: [PATCH 2/8] chore: serialized --- notary/src/proxy.rs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/notary/src/proxy.rs b/notary/src/proxy.rs index 0e063b754..af5e58027 100644 --- a/notary/src/proxy.rs +++ b/notary/src/proxy.rs @@ -122,13 +122,10 @@ pub fn create_tee_proof( let validation_result = validate_notarization_legal(manifest, request, response)?; let value = response.notary_response_body.clone().json.unwrap(); - let manifest_hash = manifest.to_keccak_digest()?; - let extraction_hash = validation_result.extraction_keccak_digest()?; - let proof_value_hash = keccak_digest(&[manifest_hash, extraction_hash].concat()); - - let to_sign = VerifyOutput { value, manifest: manifest.clone() }; + let serialized_value = serde_json::to_string(&value).unwrap(); + let to_sign = VerifyOutput { value: serialized_value.clone(), manifest: manifest.clone() }; let signature = sign_verification(to_sign, State(state)).unwrap(); - let data = TeeProofData { value, manifest_hash: manifest_hash.to_vec() }; + let data = TeeProofData { value: serialized_value, manifest_hash: manifest_hash.to_vec() }; Ok(TeeProof { data, signature }) } From bf1c761f81aa8e189798d7574cc9b82c518b901e Mon Sep 17 00:00:00 2001 From: Waylon Jepsen Date: Tue, 11 Mar 2025 12:38:22 -0600 Subject: [PATCH 3/8] fmt --- notary/src/proxy.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/notary/src/proxy.rs b/notary/src/proxy.rs index af5e58027..85beebc01 100644 --- a/notary/src/proxy.rs +++ b/notary/src/proxy.rs @@ -125,7 +125,8 @@ pub fn create_tee_proof( let serialized_value = serde_json::to_string(&value).unwrap(); let to_sign = VerifyOutput { value: serialized_value.clone(), manifest: manifest.clone() }; let signature = sign_verification(to_sign, State(state)).unwrap(); - let data = TeeProofData { value: serialized_value, manifest_hash: manifest_hash.to_vec() }; + let data = + TeeProofData { value: serialized_value, manifest_hash: manifest_hash.to_vec() }; Ok(TeeProof { data, signature }) } From 8b4d4237b96fb0cfd264236809a67a2b053fc8b8 Mon Sep 17 00:00:00 2001 From: Waylon Jepsen Date: Wed, 12 Mar 2025 11:21:46 -0600 Subject: [PATCH 4/8] chore: grab json value from object given path --- README.md | 4 +-- notary/src/proxy.rs | 75 ++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 72 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index f1d6a0034..1ec61db2c 100644 --- a/README.md +++ b/README.md @@ -37,8 +37,8 @@ If you have any questions, please reach out to any of Pluto's [team members](htt ### Usage ``` -cargo run -p notary -- --config ./fixture/notary-config.toml -cargo run -p client -- --config ./fixture/client.proxy.json +cargo run -p web-prover-notary -- --config ./fixture/notary-config.toml +cargo run -p web-prover-client -- --config ./fixture/client.proxy.json ``` ## Security Status diff --git a/notary/src/proxy.rs b/notary/src/proxy.rs index 85beebc01..b4b49a488 100644 --- a/notary/src/proxy.rs +++ b/notary/src/proxy.rs @@ -7,12 +7,13 @@ use axum::{ use reqwest::{Request, Response}; use serde::Deserialize; use serde_json::Value; -use tracing::info; +use tracing::{debug, info}; use uuid::Uuid; use web_prover_core::{ hash::keccak_digest, http::{ - ManifestRequest, ManifestResponse, ManifestResponseBody, NotaryResponse, NotaryResponseBody, + JsonKey, ManifestRequest, ManifestResponse, ManifestResponseBody, NotaryResponse, + NotaryResponseBody, }, manifest::{Manifest, ManifestValidationResult}, proof::{TeeProof, TeeProofData}, @@ -57,7 +58,12 @@ pub async fn proxy( let response = from_reqwest_response(reqwest_response).await; // debug!("{:?}", response); + if !response.matches_client_manifest(&payload.manifest.response) { + return Err(NotaryServerError::ManifestResponseMismatch); + } + let tee_proof = create_tee_proof(&payload.manifest, &request, &response, State(state))?; + debug!("{:?}", tee_proof); Ok(Json(tee_proof)) } @@ -119,9 +125,10 @@ pub fn create_tee_proof( response: &NotaryResponse, State(state): State>, ) -> Result { - let validation_result = validate_notarization_legal(manifest, request, response)?; - - let value = response.notary_response_body.clone().json.unwrap(); + validate_notarization_legal(manifest, request, response)?; + let path = manifest.response.body.json_path.clone(); + let body = response.notary_response_body.clone().json.unwrap(); + let value = get_value_from_json_path(&body, &path); let serialized_value = serde_json::to_string(&value).unwrap(); let to_sign = VerifyOutput { value: serialized_value.clone(), manifest: manifest.clone() }; let signature = sign_verification(to_sign, State(state)).unwrap(); @@ -144,3 +151,61 @@ fn validate_notarization_legal( info!("Manifest returned values: {:?}", result.values()); Ok(result) } + +fn get_value_from_json_path(json_body: &Value, path: &[JsonKey]) -> Value { + let mut current = json_body; + for key in path { + current = match key { + JsonKey::String(s) => current.get(s), + JsonKey::Num(n) => current.get(n), + } + .unwrap(); + } + current.clone() +} + +#[test] +fn test_get_value_from_json_path() { + let json_body = json!({ + "foo": { + "bar": "baz" + } + }); + let path = vec![JsonKey::String("foo".to_string()), JsonKey::String("bar".to_string())]; + let value = get_value_from_json_path(&json_body, &path).unwrap(); + assert_eq!(value, "baz"); +} + +#[test] +fn test_get_value_from_json_path_num() { + let json_body = json!({ + "foo": [1, 2, 3] + }); + let path = vec![JsonKey::String("foo".to_string()), JsonKey::Num(1)]; + let value = get_value_from_json_path(&json_body, &path).unwrap(); + assert_eq!(value, 2); +} + +#[test] +fn test_get_value_from_json_path_bool() { + let json_body = json!({ + "foo": { + "bar": true + } + }); + let path = vec![JsonKey::String("foo".to_string()), JsonKey::String("bar".to_string())]; + let value = get_value_from_json_path(&json_body, &path).unwrap(); + assert_eq!(value, true); +} + +#[test] +fn test_get_value_from_json_path_null() { + let json_body = json!({ + "foo": { + "bar": null + } + }); + let path = vec![JsonKey::String("foo".to_string()), JsonKey::String("bar".to_string())]; + let value = get_value_from_json_path(&json_body, &path).unwrap(); + assert_eq!(value, Value::Null); +} From a6402ecbf310de5dba7488851831e1c4f55d36c6 Mon Sep 17 00:00:00 2001 From: Waylon Jepsen Date: Wed, 12 Mar 2025 14:28:11 -0600 Subject: [PATCH 5/8] chore: pass tests --- notary/src/proxy.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/notary/src/proxy.rs b/notary/src/proxy.rs index b4b49a488..616fd98b7 100644 --- a/notary/src/proxy.rs +++ b/notary/src/proxy.rs @@ -6,7 +6,7 @@ use axum::{ }; use reqwest::{Request, Response}; use serde::Deserialize; -use serde_json::Value; +use serde_json::{json, Value}; use tracing::{debug, info}; use uuid::Uuid; use web_prover_core::{ @@ -172,7 +172,7 @@ fn test_get_value_from_json_path() { } }); let path = vec![JsonKey::String("foo".to_string()), JsonKey::String("bar".to_string())]; - let value = get_value_from_json_path(&json_body, &path).unwrap(); + let value = get_value_from_json_path(&json_body, &path); assert_eq!(value, "baz"); } @@ -182,7 +182,7 @@ fn test_get_value_from_json_path_num() { "foo": [1, 2, 3] }); let path = vec![JsonKey::String("foo".to_string()), JsonKey::Num(1)]; - let value = get_value_from_json_path(&json_body, &path).unwrap(); + let value = get_value_from_json_path(&json_body, &path); assert_eq!(value, 2); } @@ -194,7 +194,7 @@ fn test_get_value_from_json_path_bool() { } }); let path = vec![JsonKey::String("foo".to_string()), JsonKey::String("bar".to_string())]; - let value = get_value_from_json_path(&json_body, &path).unwrap(); + let value = get_value_from_json_path(&json_body, &path); assert_eq!(value, true); } @@ -206,6 +206,6 @@ fn test_get_value_from_json_path_null() { } }); let path = vec![JsonKey::String("foo".to_string()), JsonKey::String("bar".to_string())]; - let value = get_value_from_json_path(&json_body, &path).unwrap(); + let value = get_value_from_json_path(&json_body, &path); assert_eq!(value, Value::Null); } From bf6972c429f10711b65dee1039dc1db625a3d50b Mon Sep 17 00:00:00 2001 From: Waylon Jepsen Date: Wed, 12 Mar 2025 14:49:12 -0600 Subject: [PATCH 6/8] chore: bytes to jason value --- notary/src/proxy.rs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/notary/src/proxy.rs b/notary/src/proxy.rs index 616fd98b7..1342bfff5 100644 --- a/notary/src/proxy.rs +++ b/notary/src/proxy.rs @@ -58,10 +58,6 @@ pub async fn proxy( let response = from_reqwest_response(reqwest_response).await; // debug!("{:?}", response); - if !response.matches_client_manifest(&payload.manifest.response) { - return Err(NotaryServerError::ManifestResponseMismatch); - } - let tee_proof = create_tee_proof(&payload.manifest, &request, &response, State(state))?; debug!("{:?}", tee_proof); @@ -126,9 +122,10 @@ pub fn create_tee_proof( State(state): State>, ) -> Result { validate_notarization_legal(manifest, request, response)?; - let path = manifest.response.body.json_path.clone(); - let body = response.notary_response_body.clone().json.unwrap(); + let path = manifest.response.body.json_path().clone(); + let body = serde_json::from_slice(&response.notary_response_body.clone().body.unwrap()).unwrap(); let value = get_value_from_json_path(&body, &path); + let manifest_hash = manifest.to_keccak_digest().unwrap(); let serialized_value = serde_json::to_string(&value).unwrap(); let to_sign = VerifyOutput { value: serialized_value.clone(), manifest: manifest.clone() }; let signature = sign_verification(to_sign, State(state)).unwrap(); From 6f303291d4c1670383ef6a37a02cf429b3865562 Mon Sep 17 00:00:00 2001 From: Waylon Jepsen Date: Wed, 12 Mar 2025 15:31:15 -0600 Subject: [PATCH 7/8] chore: use reproducible hash --- notary/src/proxy.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/notary/src/proxy.rs b/notary/src/proxy.rs index 1342bfff5..6d8558f54 100644 --- a/notary/src/proxy.rs +++ b/notary/src/proxy.rs @@ -125,7 +125,7 @@ pub fn create_tee_proof( let path = manifest.response.body.json_path().clone(); let body = serde_json::from_slice(&response.notary_response_body.clone().body.unwrap()).unwrap(); let value = get_value_from_json_path(&body, &path); - let manifest_hash = manifest.to_keccak_digest().unwrap(); + let manifest_hash = KeccakHasher::hash(serde_json::to_string(&manifest)?.as_bytes()); let serialized_value = serde_json::to_string(&value).unwrap(); let to_sign = VerifyOutput { value: serialized_value.clone(), manifest: manifest.clone() }; let signature = sign_verification(to_sign, State(state)).unwrap(); From 44ea9a9a360534f9d0a8eba050f26846886cda25 Mon Sep 17 00:00:00 2001 From: Waylon Jepsen Date: Thu, 13 Mar 2025 11:22:08 -0600 Subject: [PATCH 8/8] chore: build --- notary/src/proxy.rs | 4 ++-- notary/src/verifier.rs | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/notary/src/proxy.rs b/notary/src/proxy.rs index 6d8558f54..23a2f9526 100644 --- a/notary/src/proxy.rs +++ b/notary/src/proxy.rs @@ -21,7 +21,7 @@ use web_prover_core::{ use crate::{ error::NotaryServerError, - verifier::{sign_verification, VerifyOutput}, + verifier::{hash_value, sign_verification, VerifyOutput}, SharedState, }; #[derive(Deserialize)] @@ -125,7 +125,7 @@ pub fn create_tee_proof( let path = manifest.response.body.json_path().clone(); let body = serde_json::from_slice(&response.notary_response_body.clone().body.unwrap()).unwrap(); let value = get_value_from_json_path(&body, &path); - let manifest_hash = KeccakHasher::hash(serde_json::to_string(&manifest)?.as_bytes()); + let manifest_hash = hash_value(serde_json::to_string(&manifest)?.as_bytes()); let serialized_value = serde_json::to_string(&value).unwrap(); let to_sign = VerifyOutput { value: serialized_value.clone(), manifest: manifest.clone() }; let signature = sign_verification(to_sign, State(state)).unwrap(); diff --git a/notary/src/verifier.rs b/notary/src/verifier.rs index 771720e6e..5c2a78834 100644 --- a/notary/src/verifier.rs +++ b/notary/src/verifier.rs @@ -8,7 +8,7 @@ use web_prover_core::{manifest::Manifest, proof::SignedVerificationReply}; use crate::{error::NotaryServerError, SharedState, State}; #[derive(Clone)] -struct KeccakHasher; +pub struct KeccakHasher; impl Hasher for KeccakHasher { type Hash = [u8; 32]; @@ -16,6 +16,8 @@ impl Hasher for KeccakHasher { fn hash(data: &[u8]) -> Self::Hash { keccak256(data).into() } } +pub fn hash_value>(value: T) -> [u8; 32] { KeccakHasher::hash(value.as_ref()) } + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct VerifyOutput> { pub value: T,