Add support for DNAME resolution
[dnssec-prover] / src / query.rs
index 07954b3cb9fccc348803c00a5c229b20be1eca76..a523db35662f83d3d56b564b11f6c99e668e9897 100644 (file)
@@ -183,6 +183,11 @@ const MAX_REQUESTS: usize = 10;
 /// [`ProofBuilder::process_response`] should be called, and each fresh query returned should be
 /// sent to the resolver. Once [`ProofBuilder::awaiting_responses`] returns false,
 /// [`ProofBuilder::finish_proof`] should be called to fetch the resulting proof.
+///
+/// To build a DNSSEC proof using a DoH server, take each [`QueryBuf`], encode it as base64url, and
+/// make a query to `https://doh-server/endpoint?dns=base64url_encoded_query` with an `Accept`
+/// header of `application/dns-message`. Each response, in raw binary, can be fed directly into
+/// [`ProofBuilder::process_response`].
 pub struct ProofBuilder {
        proof: Vec<u8>,
        min_ttl: u32,
@@ -547,4 +552,31 @@ mod tests {
                        } else { panic!(); }
                }
        }
+
+       #[cfg(feature = "tokio")]
+       #[tokio::test]
+       async fn test_dname_wildcard_query_async() {
+               for resolver in ["1.1.1.1:53", "8.8.8.8:53", "9.9.9.9:53"] {
+                       let sockaddr = resolver.to_socket_addrs().unwrap().next().unwrap();
+                       let query_name = "wildcard_a.wildcard_b.dname_test.dnssec_proof_tests.bitcoin.ninja.".try_into().unwrap();
+                       let (proof, _) = build_txt_proof_async(sockaddr, &query_name).await.unwrap();
+
+                       let mut rrs = parse_rr_stream(&proof).unwrap();
+                       rrs.shuffle(&mut rand::rngs::OsRng);
+                       let verified_rrs = verify_rr_stream(&rrs).unwrap();
+                       assert_eq!(verified_rrs.verified_rrs.len(), 3);
+
+                       let now = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap().as_secs();
+                       assert!(verified_rrs.valid_from < now);
+                       assert!(verified_rrs.expires > now);
+
+                       let resolved_rrs = verified_rrs.resolve_name(&query_name);
+                       assert_eq!(resolved_rrs.len(), 1);
+                       if let RR::Txt(txt) = &resolved_rrs[0] {
+                               assert_eq!(txt.name.as_str(), "cname.wildcard_test.dnssec_proof_tests.bitcoin.ninja.");
+                               assert_eq!(txt.data, b"wildcard_test");
+                       } else { panic!(); }
+               }
+       }
+
 }