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