odoh_rs/lib.rs
1/*!
2
3[odoh-rs] is a library that implements [RFC 9230] Oblivious DNS over HTTPS protocol in Rust.
4
5It can be used to implement an ODoH client or server (target).
6[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].
7
8This library is interoperable with [odoh-go].
9
10`odoh-rs` uses [hpke] as the underlying HPKE implementation. It supports the default Oblivious DoH ciphersuite
11`(KEM: X25519HkdfSha256, KDF: HkdfSha256, AEAD: AesGcm128)`.
12
13It does not provide full crypto agility.
14
15[odoh-rs]: https://github.com/cloudflare/odoh-rs/
16[RFC 9230]: https://datatracker.ietf.org/doc/rfc9230/
17[odoh-client-rs]: https://github.com/cloudflare/odoh-client-rs/
18[odoh-go]: https://github.com/cloudflare/odoh-go
19[test_vectors_for_odoh]: https://github.com/cloudflare/odoh-rs/blob/master/tests/test-vectors.json
20[hpke]: https://github.com/rozbb/rust-hpke
21
22# Example API usage
23
24This example outlines the steps necessary for a successful ODoH query.
25
26```
27# use crate::odoh_rs::*;
28# use rand::{rngs::StdRng, SeedableRng};
29
30// Use a seed to initialize a RNG. *Note* you should rely on some
31// random source.
32let mut rng = StdRng::from_seed([0; 32]);
33
34// Generate a key pair on server side.
35let key_pair = ObliviousDoHKeyPair::new(&mut rng);
36
37// Create client configs from the key pair. It can be distributed
38// to the clients.
39let public_key = key_pair.public().clone();
40let client_configs: ObliviousDoHConfigs = vec![ObliviousDoHConfig::from(public_key)].into();
41let client_configs_bytes = compose(&client_configs).unwrap().freeze();
42
43// ... distributing client_configs_bytes ...
44
45// Parse and extract first supported config from client configs on client side.
46let client_configs: ObliviousDoHConfigs = parse(&mut client_configs_bytes.clone()).unwrap();
47let client_config = client_configs.into_iter().next().unwrap();
48let config_contents = client_config.into();
49
50// This is a example client request. This library doesn't validate
51// DNS message.
52let query = ObliviousDoHMessagePlaintext::new(b"What's the IP of one.one.one.one?", 0);
53
54// Encrypt the above request. The client_secret returned will be
55// used later to decrypt server's response.
56let (query_enc, cli_secret) = encrypt_query(&query, &config_contents, &mut rng).unwrap();
57
58// ... sending query_enc to the server ...
59
60// Server decrypt request.
61let (query_dec, srv_secret) = decrypt_query(&query_enc, &key_pair).unwrap();
62assert_eq!(query, query_dec);
63
64// Server could now resolve the decrypted query, and compose a response.
65let response = ObliviousDoHMessagePlaintext::new(b"The IP is 1.1.1.1", 0);
66
67// server encrypt response
68let nonce = ResponseNonce::default();
69let response_enc = encrypt_response(&query_dec, &response, srv_secret, nonce).unwrap();
70
71// ... sending response_enc back to the client ...
72
73// client descrypt response
74let response_dec = decrypt_response(&query, &response_enc, cli_secret).unwrap();
75assert_eq!(response, response_dec);
76```
77*/
78
79mod protocol;
80
81pub use protocol::*;