From 6bf0a5cb5034a7e684dcc3500e841785237ce2dd Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 19:32:43 +0200 Subject: Adding upstream version 1:115.7.0. Signed-off-by: Daniel Baumann --- netwerk/protocol/http/oblivious_http/src/lib.rs | 188 ++++++++++++++++++++++++ 1 file changed, 188 insertions(+) create mode 100644 netwerk/protocol/http/oblivious_http/src/lib.rs (limited to 'netwerk/protocol/http/oblivious_http/src/lib.rs') 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>, +} + +impl ObliviousHttpClientResponse { + xpcom_method!(decapsulate => Decapsulate(enc_response: *const ThinVec) -> ThinVec); + fn decapsulate(&self, enc_response: &ThinVec) -> Result, 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, + response: RefPtr, +} + +impl ObliviousHttpClientRequest { + xpcom_method!(get_enc_request => GetEncRequest() -> ThinVec); + fn get_enc_request(&self) -> Result, nsresult> { + Ok(self.enc_request.clone().into_iter().collect()) + } + + xpcom_method!(get_response => GetResponse() -> *const nsIObliviousHttpClientResponse); + fn get_response(&self) -> Result, nsresult> { + Ok(self.response.clone()) + } +} + +#[xpcom(implement(nsIObliviousHttpServerResponse), atomic)] +struct ObliviousHttpServerResponse { + request: Vec, + server_response: RefCell>, +} + +impl ObliviousHttpServerResponse { + xpcom_method!(get_request => GetRequest() -> ThinVec); + fn get_request(&self) -> Result, nsresult> { + Ok(self.request.clone().into_iter().collect()) + } + + xpcom_method!(encapsulate => Encapsulate(response: *const ThinVec) -> ThinVec); + fn encapsulate(&self, response: &ThinVec) -> Result, 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, +} + +impl ObliviousHttpServer { + xpcom_method!(get_encoded_config => GetEncodedConfig() -> ThinVec); + fn get_encoded_config(&self) -> Result, 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) -> *const nsIObliviousHttpServerResponse); + fn decapsulate( + &self, + enc_request: &ThinVec, + ) -> Result, 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::() + .ok_or(NS_ERROR_FAILURE) + } +} + +#[xpcom(implement(nsIObliviousHttp), atomic)] +struct ObliviousHttp {} + +impl ObliviousHttp { + xpcom_method!(encapsulate_request => EncapsulateRequest(encoded_config: *const ThinVec, + request: *const ThinVec) -> *const nsIObliviousHttpClientRequest); + fn encapsulate_request( + &self, + encoded_config: &ThinVec, + request: &ThinVec, + ) -> Result, 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::() + .ok_or(NS_ERROR_FAILURE)?; + let oblivious_http_client_request = + ObliviousHttpClientRequest::allocate(InitObliviousHttpClientRequest { + enc_request, + response, + }); + oblivious_http_client_request + .query_interface::() + .ok_or(NS_ERROR_FAILURE) + } + + xpcom_method!(server => Server() -> *const nsIObliviousHttpServer); + fn server(&self) -> Result, nsresult> { + ohttp::init(); + + let key_id: KeyId = rand::random::(); + 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::() + .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) } +} -- cgit v1.2.3