diff options
Diffstat (limited to '')
-rw-r--r-- | netwerk/protocol/http/oblivious_http/Cargo.toml | 11 | ||||
-rw-r--r-- | netwerk/protocol/http/oblivious_http/src/lib.rs | 188 | ||||
-rw-r--r-- | netwerk/protocol/http/oblivious_http/src/oblivious_http.h | 24 |
3 files changed, 223 insertions, 0 deletions
diff --git a/netwerk/protocol/http/oblivious_http/Cargo.toml b/netwerk/protocol/http/oblivious_http/Cargo.toml new file mode 100644 index 0000000000..9a77d218db --- /dev/null +++ b/netwerk/protocol/http/oblivious_http/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "oblivious_http" +version = "0.1.0" +edition = "2021" + +[dependencies] +nserror = { path = "../../../../xpcom/rust/nserror" } +ohttp = { version = "0.2.2", default-features = false, features = ["gecko", "nss", "client", "server"] } +rand = "0.8" +thin-vec = { version = "0.2.1", features = ["gecko-ffi"] } +xpcom = { path = "../../../../xpcom/rust/xpcom" } diff --git a/netwerk/protocol/http/oblivious_http/src/lib.rs b/netwerk/protocol/http/oblivious_http/src/lib.rs new file mode 100644 index 0000000000..948139ab68 --- /dev/null +++ b/netwerk/protocol/http/oblivious_http/src/lib.rs @@ -0,0 +1,188 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +extern crate nserror; +extern crate ohttp; +extern crate rand; +extern crate thin_vec; +#[macro_use] +extern crate xpcom; + +use nserror::{nsresult, NS_ERROR_FAILURE, NS_ERROR_NOT_AVAILABLE, NS_OK}; +use ohttp::hpke::{Aead, Kdf, Kem}; +use ohttp::{ + ClientRequest, ClientResponse, KeyConfig, KeyId, Server, ServerResponse, SymmetricSuite, +}; +use thin_vec::ThinVec; +use xpcom::interfaces::{ + nsIObliviousHttpClientRequest, nsIObliviousHttpClientResponse, nsIObliviousHttpServer, + nsIObliviousHttpServerResponse, +}; +use xpcom::{xpcom_method, RefPtr}; + +use std::cell::RefCell; + +#[xpcom(implement(nsIObliviousHttpClientResponse), atomic)] +struct ObliviousHttpClientResponse { + response: RefCell<Option<ClientResponse>>, +} + +impl ObliviousHttpClientResponse { + xpcom_method!(decapsulate => Decapsulate(enc_response: *const ThinVec<u8>) -> ThinVec<u8>); + fn decapsulate(&self, enc_response: &ThinVec<u8>) -> Result<ThinVec<u8>, nsresult> { + let response = self + .response + .borrow_mut() + .take() + .ok_or(NS_ERROR_NOT_AVAILABLE)?; + let decapsulated = response + .decapsulate(enc_response) + .map_err(|_| NS_ERROR_FAILURE)?; + Ok(decapsulated.into_iter().collect()) + } +} + +#[xpcom(implement(nsIObliviousHttpClientRequest), atomic)] +struct ObliviousHttpClientRequest { + enc_request: Vec<u8>, + response: RefPtr<nsIObliviousHttpClientResponse>, +} + +impl ObliviousHttpClientRequest { + xpcom_method!(get_enc_request => GetEncRequest() -> ThinVec<u8>); + fn get_enc_request(&self) -> Result<ThinVec<u8>, nsresult> { + Ok(self.enc_request.clone().into_iter().collect()) + } + + xpcom_method!(get_response => GetResponse() -> *const nsIObliviousHttpClientResponse); + fn get_response(&self) -> Result<RefPtr<nsIObliviousHttpClientResponse>, nsresult> { + Ok(self.response.clone()) + } +} + +#[xpcom(implement(nsIObliviousHttpServerResponse), atomic)] +struct ObliviousHttpServerResponse { + request: Vec<u8>, + server_response: RefCell<Option<ServerResponse>>, +} + +impl ObliviousHttpServerResponse { + xpcom_method!(get_request => GetRequest() -> ThinVec<u8>); + fn get_request(&self) -> Result<ThinVec<u8>, nsresult> { + Ok(self.request.clone().into_iter().collect()) + } + + xpcom_method!(encapsulate => Encapsulate(response: *const ThinVec<u8>) -> ThinVec<u8>); + fn encapsulate(&self, response: &ThinVec<u8>) -> Result<ThinVec<u8>, nsresult> { + let server_response = self + .server_response + .borrow_mut() + .take() + .ok_or(NS_ERROR_NOT_AVAILABLE)?; + Ok(server_response + .encapsulate(response) + .map_err(|_| NS_ERROR_FAILURE)? + .into_iter() + .collect()) + } +} + +#[xpcom(implement(nsIObliviousHttpServer), atomic)] +struct ObliviousHttpServer { + server: RefCell<Server>, +} + +impl ObliviousHttpServer { + xpcom_method!(get_encoded_config => GetEncodedConfig() -> ThinVec<u8>); + fn get_encoded_config(&self) -> Result<ThinVec<u8>, nsresult> { + let server = self.server.borrow_mut(); + Ok(server + .config() + .encode() + .map_err(|_| NS_ERROR_FAILURE)? + .into_iter() + .collect()) + } + + xpcom_method!(decapsulate => Decapsulate(enc_request: *const ThinVec<u8>) -> *const nsIObliviousHttpServerResponse); + fn decapsulate( + &self, + enc_request: &ThinVec<u8>, + ) -> Result<RefPtr<nsIObliviousHttpServerResponse>, nsresult> { + let mut server = self.server.borrow_mut(); + let (request, server_response) = server + .decapsulate(enc_request) + .map_err(|_| NS_ERROR_FAILURE)?; + let oblivious_http_server_response = + ObliviousHttpServerResponse::allocate(InitObliviousHttpServerResponse { + request, + server_response: RefCell::new(Some(server_response)), + }); + oblivious_http_server_response + .query_interface::<nsIObliviousHttpServerResponse>() + .ok_or(NS_ERROR_FAILURE) + } +} + +#[xpcom(implement(nsIObliviousHttp), atomic)] +struct ObliviousHttp {} + +impl ObliviousHttp { + xpcom_method!(encapsulate_request => EncapsulateRequest(encoded_config: *const ThinVec<u8>, + request: *const ThinVec<u8>) -> *const nsIObliviousHttpClientRequest); + fn encapsulate_request( + &self, + encoded_config: &ThinVec<u8>, + request: &ThinVec<u8>, + ) -> Result<RefPtr<nsIObliviousHttpClientRequest>, nsresult> { + ohttp::init(); + + let client = ClientRequest::new(encoded_config).map_err(|_| NS_ERROR_FAILURE)?; + let (enc_request, response) = client.encapsulate(request).map_err(|_| NS_ERROR_FAILURE)?; + let oblivious_http_client_response = + ObliviousHttpClientResponse::allocate(InitObliviousHttpClientResponse { + response: RefCell::new(Some(response)), + }); + let response = oblivious_http_client_response + .query_interface::<nsIObliviousHttpClientResponse>() + .ok_or(NS_ERROR_FAILURE)?; + let oblivious_http_client_request = + ObliviousHttpClientRequest::allocate(InitObliviousHttpClientRequest { + enc_request, + response, + }); + oblivious_http_client_request + .query_interface::<nsIObliviousHttpClientRequest>() + .ok_or(NS_ERROR_FAILURE) + } + + xpcom_method!(server => Server() -> *const nsIObliviousHttpServer); + fn server(&self) -> Result<RefPtr<nsIObliviousHttpServer>, nsresult> { + ohttp::init(); + + let key_id: KeyId = rand::random::<u8>(); + let kem: Kem = Kem::X25519Sha256; + let symmetric = vec![ + SymmetricSuite::new(Kdf::HkdfSha256, Aead::Aes128Gcm), + SymmetricSuite::new(Kdf::HkdfSha256, Aead::ChaCha20Poly1305), + ]; + let key_config = KeyConfig::new(key_id, kem, symmetric).map_err(|_| NS_ERROR_FAILURE)?; + let server = Server::new(key_config).map_err(|_| NS_ERROR_FAILURE)?; + let oblivious_http_server = ObliviousHttpServer::allocate(InitObliviousHttpServer { + server: RefCell::new(server), + }); + oblivious_http_server + .query_interface::<nsIObliviousHttpServer>() + .ok_or(NS_ERROR_FAILURE) + } +} + +#[no_mangle] +pub extern "C" fn oblivious_http_constructor( + iid: *const xpcom::nsIID, + result: *mut *mut xpcom::reexports::libc::c_void, +) -> nserror::nsresult { + let oblivious_http = ObliviousHttp::allocate(InitObliviousHttp {}); + unsafe { oblivious_http.QueryInterface(iid, result) } +} diff --git a/netwerk/protocol/http/oblivious_http/src/oblivious_http.h b/netwerk/protocol/http/oblivious_http/src/oblivious_http.h new file mode 100644 index 0000000000..176b4909c1 --- /dev/null +++ b/netwerk/protocol/http/oblivious_http/src/oblivious_http.h @@ -0,0 +1,24 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef _oblivious_http_h_ +#define _oblivious_http_h_ + +#include "nsISupportsUtils.h" // for nsresult, etc. + +// {d581149e-3319-4563-b95e-46c64af5c4e8} +#define NS_OBLIVIOUS_HTTP_CID \ + { \ + 0xd581149e, 0x3319, 0x4563, { \ + 0xb9, 0x5e, 0x46, 0xc6, 0x4a, 0xf5, 0xc4, 0xe8 \ + } \ + } + +extern "C" { +nsresult oblivious_http_constructor(REFNSIID iid, void** result); +}; + +#endif // _oblivious_http_h_ |