diff --git a/pingora-router/Cargo.toml b/pingora-router/Cargo.toml index 6be7d3e..a55e7f3 100644 --- a/pingora-router/Cargo.toml +++ b/pingora-router/Cargo.toml @@ -9,4 +9,5 @@ pingora = { version = "0.5.0", features = ["lb", "boringssl"] } serde = "1.0.219" serde_json = "1.0.140" chrono = "0.4.40" -uuid = "1.16.0" \ No newline at end of file +uuid = "1.16.0" +bincode = "2.0.1" diff --git a/reverse-proxy/Cargo.toml b/reverse-proxy/Cargo.toml index 194e0be..d565ac2 100644 --- a/reverse-proxy/Cargo.toml +++ b/reverse-proxy/Cargo.toml @@ -19,7 +19,7 @@ futures = "0.3.31" boring = "4.17.0" once_cell = "1.21.3" dotenv = "0.15.0" -ntor = { git = "https://github.com/globe-and-citizen/ntor.git", tag = "0.1.1" } +ntor = { git = "https://github.com/globe-and-citizen/ntor.git", tag = "0.1.2"} config = "0.15.11" toml = "0.8.23" uuid = { version = "1.16.0", features = ["v4"] } @@ -27,3 +27,4 @@ utils = { path = "../utils", version = "0.1.0" } envy = "0.4.2" hex = "0.4.3" tracing = "0.1.41" +bincode = "2.0.1" diff --git a/reverse-proxy/cert b/reverse-proxy/cert new file mode 100644 index 0000000..e69de29 diff --git a/reverse-proxy/src/handler/mod.rs b/reverse-proxy/src/handler/mod.rs index 9a4dec3..e895e01 100644 --- a/reverse-proxy/src/handler/mod.rs +++ b/reverse-proxy/src/handler/mod.rs @@ -180,9 +180,10 @@ impl ReverseHandler { shared_secret, ) { Ok(encrypted_message) => { + let body = utils::type_to_bincode(&encrypted_message); APIHandlerResponse { status: StatusCode::OK, - body: Some(encrypted_message.to_bytes()), + body: Some(body), } } Err(res) => res diff --git a/reverse-proxy/src/handler/proxy/handler.rs b/reverse-proxy/src/handler/proxy/handler.rs index 0b78a5a..7932ccf 100644 --- a/reverse-proxy/src/handler/proxy/handler.rs +++ b/reverse-proxy/src/handler/proxy/handler.rs @@ -1,7 +1,7 @@ use pingora_router::ctx::{Layer8Context, Layer8ContextTrait}; use reqwest::header::HeaderMap; use pingora_router::handler::{APIHandlerResponse, DefaultHandlerTrait, ResponseBodyTrait}; -use ntor::common::NTorParty; +use ntor::common::{EncryptedMessage, NTorParty}; use ntor::server::NTorServer; use reqwest::Client; use pingora::http::StatusCode; @@ -10,7 +10,7 @@ use utils::bytes_to_json; use utils::jwt::JWTClaims; use crate::handler::common::consts::{HeaderKeys, LogTypes}; use crate::handler::common::types::ErrorResponse; -use crate::handler::proxy::{EncryptedMessage, L8ResponseObject, L8RequestObject}; +use crate::handler::proxy::{L8ResponseObject, L8RequestObject}; /// Struct containing only associated methods (no instance methods or fields) pub struct ProxyHandler {} @@ -103,28 +103,25 @@ impl ProxyHandler { { let correlation_id = ctx.get_correlation_id(); - match ProxyHandler::parse_request_body::< - EncryptedMessage, - ErrorResponse - >(&ctx.get_request_body()) { + // deserialize from bincode + match utils::bincode_to_type(ctx.get_request_body().as_slice()) { Ok(res) => Ok(res), Err(err) => { - let body = match err { - None => None, - Some(err_response) => { - error!( - %correlation_id, - log_type=LogTypes::HANDLE_PROXY_REQUEST, - "Error parsing request body: {}", - err_response.error - ); - Some(err_response.to_bytes()) - } - }; - Err(APIHandlerResponse { + error!( + %correlation_id, + log_type=LogTypes::HANDLE_PROXY_REQUEST, + "Error parsing request body: {}", + err + ); + return Err(APIHandlerResponse { status: StatusCode::BAD_REQUEST, - body, - }) + body: Some( + ErrorResponse { + error: format!("Error parsing request body: {}", err), + } + .to_bytes(), + ), + }); } } } @@ -139,25 +136,30 @@ impl ProxyHandler { ntor_server.set_shared_secret(shared_secret.clone()); // Decrypt the request body using nTor shared secret - let decrypted_data = ntor_server.decrypt(ntor::common::EncryptedMessage { - nonce: <[u8; 12]>::try_from(request_body.nonce).unwrap_or_default(), - data: request_body.data, - }).map_err(|err| { - return APIHandlerResponse { - status: StatusCode::BAD_REQUEST, - body: Some(format!("Decryption failed: {}", err).as_bytes().to_vec()), - }; - })?; - // let decrypted_data = request_body.data; - - // parse decrypted data into WrappedUserRequest - let wrapped_request: L8RequestObject = bytes_to_json(decrypted_data) + let decrypted_data = ntor_server + .decrypt(ntor::common::EncryptedMessage { + nonce: <[u8; 12]>::try_from(request_body.nonce).unwrap_or_default(), + data: request_body.data, + }) .map_err(|err| { return APIHandlerResponse { status: StatusCode::BAD_REQUEST, - body: Some(format!("Failed to parse request body: {}", err).as_bytes().to_vec()), + body: Some(format!("Decryption failed: {}", err).as_bytes().to_vec()), }; })?; + // let decrypted_data = request_body.data; + + // parse decrypted data into WrappedUserRequest + let wrapped_request: L8RequestObject = bytes_to_json(decrypted_data).map_err(|err| { + return APIHandlerResponse { + status: StatusCode::BAD_REQUEST, + body: Some( + format!("Failed to parse request body: {}", err) + .as_bytes() + .to_vec(), + ), + }; + })?; Ok(wrapped_request) } @@ -269,7 +271,7 @@ impl ProxyHandler { })?; Ok(EncryptedMessage { - nonce: encrypted_data.nonce.to_vec(), + nonce: encrypted_data.nonce, data: encrypted_data.data, }) } diff --git a/reverse-proxy/src/handler/proxy/mod.rs b/reverse-proxy/src/handler/proxy/mod.rs index 0458ea0..5c7a396 100644 --- a/reverse-proxy/src/handler/proxy/mod.rs +++ b/reverse-proxy/src/handler/proxy/mod.rs @@ -4,15 +4,6 @@ use std::collections::HashMap; use pingora_router::handler::{RequestBodyTrait, ResponseBodyTrait}; use serde::{Deserialize, Serialize}; -#[derive(Serialize, Deserialize, Debug)] -pub struct EncryptedMessage { - pub nonce: Vec, - pub data: Vec, -} - -impl RequestBodyTrait for EncryptedMessage {} -impl ResponseBodyTrait for EncryptedMessage {} - #[derive(Serialize, Deserialize, Debug)] pub struct L8RequestObject { pub method: String, diff --git a/spa/frontend/package-lock.json b/spa/frontend/package-lock.json index 94e6cb8..e271ebd 100644 --- a/spa/frontend/package-lock.json +++ b/spa/frontend/package-lock.json @@ -8,7 +8,7 @@ "name": "frontend2", "version": "0.0.0", "dependencies": { - "layer8-interceptor-production": "^0.3.0", + "layer8-interceptor-production": "^0.4.0", "vue": "^3.5.13", "vue-router": "^4.5.0" }, @@ -80,6 +80,7 @@ "integrity": "sha512-UlLAnTPrFdNGoFtbSXwcGFQBtQZJCNjaN6hQNP3UPvuNXT1i82N26KL3dZeIpNalWywr9IuQuncaAfUaS1g6sQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.27.1", @@ -1317,6 +1318,7 @@ "integrity": "sha512-jnVe5ULKl6tijxUhvQeNbQG/84fHfg+yMak02cT8QVhBx/F05rAVxCGBYYTh2EKz22D6JF5ktXuNwdx7b9iEGw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "undici-types": "~6.21.0" } @@ -1708,6 +1710,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "caniuse-lite": "^1.0.30001726", "electron-to-chromium": "^1.5.173", @@ -2305,9 +2308,9 @@ "license": "MIT" }, "node_modules/layer8-interceptor-production": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/layer8-interceptor-production/-/layer8-interceptor-production-0.3.0.tgz", - "integrity": "sha512-vTSvoSWdba/YxkLtZ1hwrluxXPuz0hpLAnfdcupVR3c27kQD4w+G4FA+3huOuSJV2mshUe/I7MYkA0jlyhTq1g==" + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/layer8-interceptor-production/-/layer8-interceptor-production-0.4.0.tgz", + "integrity": "sha512-XmTAwWTQFtNI5JtuT3XDxyqlPRsT24AFJbqh9E1UNam1pK7idcdX5zs5KX0eMhEhU7w6H1EDOQoPXLtoU/uxQw==" }, "node_modules/lru-cache": { "version": "5.1.1", @@ -2642,6 +2645,7 @@ "integrity": "sha512-LW+Vse3BJPyGJGAJt1j8pWDKPd73QM8cRXYK1IxOBgL2AGLu7Xd2YOW0M2sLUBCkF5MshXXtMApyEAEzMVMsnw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@types/estree": "1.0.8" }, @@ -2841,6 +2845,7 @@ "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", "devOptional": true, "license": "Apache-2.0", + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -2916,6 +2921,7 @@ "integrity": "sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.4.4", @@ -3095,6 +3101,7 @@ "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.16.tgz", "integrity": "sha512-rjOV2ecxMd5SiAmof2xzh2WxntRcigkX/He4YFJ6WdRvVUrbt6DxC1Iujh10XLl8xCDRDtGKMeO3D+pRQ1PP9w==", "license": "MIT", + "peer": true, "dependencies": { "@vue/compiler-dom": "3.5.16", "@vue/compiler-sfc": "3.5.16", diff --git a/spa/frontend/package.json b/spa/frontend/package.json index 6d34d58..642ba50 100644 --- a/spa/frontend/package.json +++ b/spa/frontend/package.json @@ -11,7 +11,7 @@ "type-check": "vue-tsc --build" }, "dependencies": { - "layer8-interceptor-production": "^0.3.0", + "layer8-interceptor-production": "^0.4.0", "vue": "^3.5.13", "vue-router": "^4.5.0" }, @@ -27,4 +27,4 @@ "vite-plugin-wasm": "^3.4.1", "vue-tsc": "^2.2.8" } -} +} \ No newline at end of file diff --git a/utils/Cargo.toml b/utils/Cargo.toml index 6eb22a5..564a945 100644 --- a/utils/Cargo.toml +++ b/utils/Cargo.toml @@ -18,4 +18,5 @@ hex = "0.4.3" tracing = "0.1.41" tracing-subscriber = { version = "0.3.19", features = ["json", "env-filter", "fmt"] } tracing-appender = "0.2.3" +bincode = "2.0.1" diff --git a/utils/src/lib.rs b/utils/src/lib.rs index ecda098..ca2347e 100644 --- a/utils/src/lib.rs +++ b/utils/src/lib.rs @@ -141,4 +141,16 @@ pub fn get_socket_addrs(url: &Url) -> String { .map(|addr| addr.to_string()) .collect::>() .join(",") -} \ No newline at end of file +} + +pub fn bincode_to_type>( + data: &[u8], +) -> Result { + let (_type, _) = bincode::decode_from_slice::(data, bincode::config::standard())?; + Ok(_type) +} + +pub fn type_to_bincode(_type: &T) -> Vec { + bincode::encode_to_vec(_type, bincode::config::standard()) + .expect("this will be a compilation error before it gets to runtime") +}