Filter using `VerifiedRRStream::resolve_name` in wasm
authorMatt Corallo <git@bluematt.me>
Sun, 14 Apr 2024 16:41:54 +0000 (16:41 +0000)
committerMatt Corallo <git@bluematt.me>
Sun, 14 Apr 2024 17:22:46 +0000 (17:22 +0000)
When resolving a name in WASM we should let `resolve_name` handle
C/DNAMEs, which we do here.

wasmpack/doh_lookup.js
wasmpack/src/lib.rs

index 17c5bbf1c03a99bafcb6b9305242bb955266fb70..fec246c1b899b44ec1b05d4e7161bf0c75420566 100644 (file)
@@ -46,7 +46,7 @@ export async function lookup_doh(domain, ty, doh_endpoint) {
                                } else if (queries_pending == 0) {
                                        var proof = wasm.get_unverified_proof(builder);
                                        if (proof != null) {
-                                               var result = wasm.verify_byte_stream(proof);
+                                               var result = wasm.verify_byte_stream(proof, domain);
                                                return JSON.stringify(JSON.parse(result), null, 1);
                                        } else {
                                                return "{\"error\":\"Failed to build proof\"}";
index 57fe0a03a89b9b4a7c6b1ba3f0829ccefff2fe65..75ca16cc5b9dcc72e811e589791543495d2ba4f3 100644 (file)
@@ -2,6 +2,7 @@
 
 use dnssec_prover::ser::parse_rr_stream;
 use dnssec_prover::validation::{verify_rr_stream, ValidationError};
+use dnssec_prover::rr::Name;
 use dnssec_prover::query::{ProofBuilder, QueryBuf};
 
 use wasm_bindgen::prelude::wasm_bindgen;
@@ -72,23 +73,29 @@ pub fn get_unverified_proof(proof_builder: WASMProofBuilder) -> Option<Vec<u8>>
 }
 
 #[wasm_bindgen]
-/// Verifies an RFC 9102-formatted proof and returns the [`VerifiedRRStream`] in JSON form.
-pub fn verify_byte_stream(stream: Vec<u8>) -> String {
-       match do_verify_byte_stream(stream) {
+/// Verifies an RFC 9102-formatted proof and returns verified records matching the given name
+/// (resolving any C/DNAMEs as required).
+pub fn verify_byte_stream(stream: Vec<u8>, name_to_resolve: String) -> String {
+       let name = match Name::try_from(name_to_resolve) {
+               Ok(name) => name,
+               Err(()) => return "{\"error\":\"Bad name to resolve\"}".to_string(),
+       };
+       match do_verify_byte_stream(stream, name) {
                Ok(r) => r,
                Err(e) => format!("{{\"error\":\"{:?}\"}}", e),
        }
 }
 
-fn do_verify_byte_stream(stream: Vec<u8>) -> Result<String, ValidationError> {
+fn do_verify_byte_stream(stream: Vec<u8>, name_to_resolve: Name) -> Result<String, ValidationError> {
        let rrs = parse_rr_stream(&stream).map_err(|()| ValidationError::Invalid)?;
        let verified_rrs = verify_rr_stream(&rrs)?;
+       let resolved_rrs = verified_rrs.resolve_name(&name_to_resolve);
        let mut resp = String::new();
        write!(&mut resp, "{}",
                format_args!("{{\"valid_from\": {}, \"expires\": {}, \"max_cache_ttl\": {}, \"verified_rrs\": [",
                verified_rrs.valid_from, verified_rrs.expires, verified_rrs.max_cache_ttl)
        ).expect("Write to a String shouldn't fail");
-       for (idx, rr) in verified_rrs.verified_rrs.iter().enumerate() {
+       for (idx, rr) in resolved_rrs.iter().enumerate() {
                write!(&mut resp, "{}{}", if idx != 0 { ", " } else { "" }, rr.json())
                        .expect("Write to a String shouldn't fail");
        }