cloudflare / Odoh Rs
Licence: bsd-2-clause
Oblivious DoH library in Rust
Stars: ✭ 97
Programming Languages
rust
11053 projects
odoh-rs
odoh-rs is a library that implements Oblivious DNS over HTTPS (ODoH) protocol draft-06 in Rust.
It can be used to implement an ODoH client or server (target).
odoh-client-rs uses odoh-rs
to implement its functionality, and is a good source of API usage examples, along with the tests in odoh-rs
, in particular test_vectors_for_odoh.
This library is interoperable with odoh-go.
odoh-rs
uses hpke as the underlying HPKE implementation. It supports the default Oblivious DoH ciphersuite
(KEM: X25519HkdfSha256, KDF: HkdfSha256, AEAD: AesGcm128)
.
It does not provide full crypto agility.
Example API Usage
This example outlines the steps necessary for a successful ODoH query.
// Server generates a secret key pair
fn generate_key_pair() -> ObliviousDoHKeyPair {
// random bytes, should be 32 bytes for X25519 keys
let ikm = rand::thread_rng().gen::<[u8; 32]>();;
let (secret_key, public_key) = derive_keypair_from_seed(&ikm);
let public_key_bytes = public_key.to_bytes().to_vec();
let odoh_public_key = ObliviousDoHConfigContents {
kem_id: 0x0020, // DHKEM(X25519, HKDF-SHA256)
kdf_id: 0x0001, // KDF(SHA-256)
aead_id: 0x0001, // AEAD(AES-GCM-128)
public_key: public_key_bytes,
};
ObliviousDoHKeyPair {
private_key: secret_key,
public_key: odoh_public_key,
}
}
#[tokio::main]
async fn main() -> Result<()> {
// Server generates a key pair and creates an `ObliviousDoHConfigs` struct from it
// which it will distribute to clients via HTTPS records as outlined in the draft:
// https://tools.ietf.org/html/draft-pauly-dprive-oblivious-doh-02#section-5
let key_pair = generate_key_pair();
let config = ObliviousDoHConfig::new(&key_pair.public_key.clone().to_bytes().unwrap()).unwrap();
let odohconfig = ObliviousDoHConfigs {
configs: vec![config.clone()],
}
.to_bytes()
.unwrap();
// Client gets `odohconfig` via an HTTPS record
let client_config = get_supported_config(&odohconfig).unwrap();
// Client creates a query body
let query = ObliviousDoHQueryBody::new(&vec![1, 2], Some(2));
// Client creates a query to send to the server
let (oblivious_query, client_secret) = create_query_msg(&client_config, &query).unwrap();
// Server receives the query and parses it
let (parsed_query, server_secret) = parse_received_query(&key_pair, &oblivious_query)
.await
.unwrap();
// Server generates a DNS response based on the query
let resolver_resp = vec![1, 3, 4];
// Server creates an encrypted response msg to send to the client
let generated_response = create_response_msg(&server_secret, &resolver_resp, None, &query)
.await
.unwrap();
// Client receives the server's encrypted DNS response and parses it to recover the plaintext DNS response.
let parsed_response =
parse_received_response(&client_secret, &generated_response, &query).unwrap();
Ok(())
}
Note that the project description data, including the texts, logos, images, and/or trademarks,
for each open source project belongs to its rightful owner.
If you wish to add or remove any projects, please contact us at [email protected].