Filter using `VerifiedRRStream::resolve_name` in wasm
[dnssec-prover] / src / validation.rs
index 2fb97448d7f0f65e870cfd15481676f08dad84cb..57ba096d53bd64169eb213fbaed47c7c31925da8 100644 (file)
@@ -5,8 +5,6 @@ use alloc::vec::Vec;
 use alloc::vec;
 use core::cmp::{self, Ordering};
 
-use ring::signature;
-
 use crate::base32;
 use crate::crypto;
 use crate::rr::*;
@@ -47,7 +45,7 @@ pub enum ValidationError {
        Invalid,
 }
 
-fn verify_rrsig<'a, RR: Record, Keys>(sig: &RRSig, dnskeys: Keys, mut records: Vec<&RR>)
+fn verify_rrsig<'a, RR: WriteableRecord, Keys>(sig: &RRSig, dnskeys: Keys, mut records: Vec<&RR>)
 -> Result<(), ValidationError>
 where Keys: IntoIterator<Item = &'a DnsKey> {
        for record in records.iter() {
@@ -70,15 +68,14 @@ where Keys: IntoIterator<Item = &'a DnsKey> {
                                _ => return Err(ValidationError::UnsupportedAlgorithm),
                        };
 
-                       let mut signed_data = Vec::with_capacity(2048);
-                       signed_data.extend_from_slice(&sig.ty.to_be_bytes());
-                       signed_data.extend_from_slice(&sig.alg.to_be_bytes());
-                       signed_data.extend_from_slice(&sig.labels.to_be_bytes());
-                       signed_data.extend_from_slice(&sig.orig_ttl.to_be_bytes());
-                       signed_data.extend_from_slice(&sig.expiration.to_be_bytes());
-                       signed_data.extend_from_slice(&sig.inception.to_be_bytes());
-                       signed_data.extend_from_slice(&sig.key_tag.to_be_bytes());
-                       write_name(&mut signed_data, &sig.key_name);
+                       hash_ctx.update(&sig.ty.to_be_bytes());
+                       hash_ctx.update(&sig.alg.to_be_bytes());
+                       hash_ctx.update(&sig.labels.to_be_bytes());
+                       hash_ctx.update(&sig.orig_ttl.to_be_bytes());
+                       hash_ctx.update(&sig.expiration.to_be_bytes());
+                       hash_ctx.update(&sig.inception.to_be_bytes());
+                       hash_ctx.update(&sig.key_tag.to_be_bytes());
+                       write_name(&mut hash_ctx, &sig.key_name);
 
                        records.sort_unstable();
 
@@ -94,46 +91,27 @@ where Keys: IntoIterator<Item = &'a DnsKey> {
                                        let signed_name = record.name().trailing_n_labels(sig.labels);
                                        debug_assert!(signed_name.is_some());
                                        if let Some(name) = signed_name {
-                                               signed_data.extend_from_slice(b"\x01*");
-                                               write_name(&mut signed_data, name);
+                                               hash_ctx.update(b"\x01*");
+                                               write_name(&mut hash_ctx, name);
                                        } else { return Err(ValidationError::Invalid); }
                                } else {
-                                       write_name(&mut signed_data, record.name());
+                                       write_name(&mut hash_ctx, record.name());
                                }
-                               signed_data.extend_from_slice(&record.ty().to_be_bytes());
-                               signed_data.extend_from_slice(&1u16.to_be_bytes()); // The INternet class
-                               signed_data.extend_from_slice(&sig.orig_ttl.to_be_bytes());
-                               record.write_u16_len_prefixed_data(&mut signed_data);
+                               hash_ctx.update(&record.ty().to_be_bytes());
+                               hash_ctx.update(&1u16.to_be_bytes()); // The INternet class
+                               hash_ctx.update(&sig.orig_ttl.to_be_bytes());
+                               record.serialize_u16_len_prefixed(&mut hash_ctx);
                        }
 
+                       let hash = hash_ctx.finish();
                        let sig_validation = match sig.alg {
-                               8|10 => {
-                                       hash_ctx.update(&signed_data);
-                                       let hash = hash_ctx.finish();
-                                       crypto::rsa::validate_rsa(&dnskey.pubkey, &sig.signature, hash.as_ref())
-                                               .map_err(|_| ValidationError::Invalid)
-                               },
-                               13|14 => {
-                                       let alg = if sig.alg == 13 {
-                                               &signature::ECDSA_P256_SHA256_FIXED
-                                       } else {
-                                               &signature::ECDSA_P384_SHA384_FIXED
-                                       };
-
-                                       // Add 0x4 identifier to the ECDSA pubkey as expected by ring.
-                                       let mut key = Vec::with_capacity(dnskey.pubkey.len() + 1);
-                                       key.push(0x4);
-                                       key.extend_from_slice(&dnskey.pubkey);
-
-                                       signature::UnparsedPublicKey::new(alg, &key)
-                                               .verify(&signed_data, &sig.signature)
-                                               .map_err(|_| ValidationError::Invalid)
-                               },
-                               15 => {
-                                       signature::UnparsedPublicKey::new(&signature::ED25519, &dnskey.pubkey)
-                                               .verify(&signed_data, &sig.signature)
-                                               .map_err(|_| ValidationError::Invalid)
-                               },
+                               8|10 => crypto::rsa::validate_rsa(&dnskey.pubkey, &sig.signature, hash.as_ref())
+                                       .map_err(|_| ValidationError::Invalid),
+                               13 => crypto::secp256r1::validate_ecdsa(&dnskey.pubkey, &sig.signature, hash.as_ref())
+                                       .map_err(|_| ValidationError::Invalid),
+                               14 => crypto::secp384r1::validate_ecdsa(&dnskey.pubkey, &sig.signature, hash.as_ref())
+                                       .map_err(|_| ValidationError::Invalid),
+                               // TODO: 15 => ED25519
                                _ => return Err(ValidationError::UnsupportedAlgorithm),
                        };
                        #[cfg(fuzzing)] {