--- /dev/null
+// This file is Copyright its original authors, visible in version control
+// history.
+//
+// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
+// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
+// You may not use this file except in accordance with one or both of these
+// licenses.
+
+#![cfg_attr(feature = "libfuzzer_fuzz", no_main)]
+
+#[cfg(not(fuzzing))]
+compile_error!("Fuzz targets need cfg=fuzzing");
+
+extern crate dnssec_prover;
+use dnssec_prover::ser::parse_rr_stream;
+use dnssec_prover::validation::verify_rr_stream;
+
+#[cfg(feature = "afl")]
+#[macro_use] extern crate afl;
+#[cfg(feature = "afl")]
+fn main() {
+ fuzz!(|data| {
+ let _ = parse_rr_stream(data).as_ref()
+ .map(|rrs| verify_rr_stream(rrs));
+ });
+}
+
+#[cfg(feature = "honggfuzz")]
+#[macro_use] extern crate honggfuzz;
+#[cfg(feature = "honggfuzz")]
+fn main() {
+ loop {
+ fuzz!(|data| {
+ let _ = parse_rr_stream(data).as_ref()
+ .map(|rrs| verify_rr_stream(rrs));
+ });
+ }
+}
+
+#[cfg(feature = "libfuzzer_fuzz")]
+#[macro_use] extern crate libfuzzer_sys;
+#[cfg(feature = "libfuzzer_fuzz")]
+fuzz_target!(|data: &[u8]| {
+ let _ = parse_rr_stream(data).as_ref()
+ .map(|rrs| verify_rr_stream(rrs));
+});
+
+#[cfg(feature = "stdin_fuzz")]
+fn main() {
+ use std::io::Read;
+
+ let mut data = Vec::with_capacity(8192);
+ std::io::stdin().read_to_end(&mut data).unwrap();
+ let _ = parse_rr_stream(data).as_ref()
+ .map(|rrs| verify_rr_stream(rrs));
+}
+
+#[test]
+fn run_test_cases() {
+ use std::fs;
+ use std::io::Read;
+
+ if let Ok(tests) = fs::read_dir("test_cases/parse_response") {
+ for test in tests {
+ let mut data: Vec<u8> = Vec::new();
+ let path = test.unwrap().path();
+ fs::File::open(&path).unwrap().read_to_end(&mut data).unwrap();
+
+ let _ = parse_rr_stream(data).as_ref()
+ .map(|rrs| verify_rr_stream(rrs));
+ }
+ }
+}
record.write_u16_len_prefixed_data(&mut signed_data);
}
- match sig.alg {
+ let sig_validation = match sig.alg {
8|10 => {
let alg = if sig.alg == 8 {
&signature::RSA_PKCS1_1024_8192_SHA256_FOR_LEGACY_USE_ONLY
};
bytes_to_rsa_pk(&dnskey.pubkey).map_err(|_| ValidationError::Invalid)?
.verify(alg, &signed_data, &sig.signature)
- .map_err(|_| ValidationError::Invalid)?;
+ .map_err(|_| ValidationError::Invalid)
},
13|14 => {
let alg = if sig.alg == 13 {
signature::UnparsedPublicKey::new(alg, &key)
.verify(&signed_data, &sig.signature)
- .map_err(|_| ValidationError::Invalid)?;
+ .map_err(|_| ValidationError::Invalid)
},
15 => {
signature::UnparsedPublicKey::new(&signature::ED25519, &dnskey.pubkey)
.verify(&signed_data, &sig.signature)
- .map_err(|_| ValidationError::Invalid)?;
+ .map_err(|_| ValidationError::Invalid)
},
_ => return Err(ValidationError::UnsupportedAlgorithm),
+ };
+ #[cfg(fuzzing)] {
+ // When fuzzing, treat any signature starting with a 1 as valid, but only after
+ // parsing and checking signatures to give that code a chance to panic.
+ if sig.signature.get(0) == Some(&1) {
+ return Ok(());
+ }
}
+ sig_validation?;
return Ok(());
}