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