X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=src%2Fvalidation.rs;h=57ba096d53bd64169eb213fbaed47c7c31925da8;hb=1d725ca4a022415c85072bc763d50738df863d6d;hp=e6b585fd44921c70b3c48a4f4e742f81423186bc;hpb=9974cddc11a2d958780f056e4e154c7700f0b2e2;p=dnssec-prover diff --git a/src/validation.rs b/src/validation.rs index e6b585f..57ba096 100644 --- a/src/validation.rs +++ b/src/validation.rs @@ -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,28 +45,7 @@ pub enum ValidationError { Invalid, } -pub(crate) fn bytes_to_rsa_pk<'a>(pubkey: &'a [u8]) --> Result, ()> { - if pubkey.len() <= 3 { return Err(()); } - - let mut pos = 0; - let exponent_length; - if pubkey[0] == 0 { - exponent_length = ((pubkey[1] as usize) << 8) | (pubkey[2] as usize); - pos += 3; - } else { - exponent_length = pubkey[0] as usize; - pos += 1; - } - - if pubkey.len() <= pos + exponent_length { return Err(()); } - Ok(signature::RsaPublicKeyComponents { - n: &pubkey[pos + exponent_length..], - e: &pubkey[pos..pos + exponent_length] - }) -} - -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 { for record in records.iter() { @@ -82,15 +59,23 @@ where Keys: IntoIterator { if dnskey.flags & 0b1_0000_0000 == 0 { continue; } if dnskey.alg != sig.alg { continue; } - 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); + let mut hash_ctx = match sig.alg { + 8 => crypto::hash::Hasher::sha256(), + 10 => crypto::hash::Hasher::sha512(), + 13 => crypto::hash::Hasher::sha256(), + 14 => crypto::hash::Hasher::sha384(), + 15 => crypto::hash::Hasher::sha512(), + _ => return Err(ValidationError::UnsupportedAlgorithm), + }; + + 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(); @@ -106,50 +91,27 @@ where Keys: IntoIterator { 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 => { - let alg = if sig.alg == 8 { - &signature::RSA_PKCS1_1024_8192_SHA256_FOR_LEGACY_USE_ONLY - } else { - &signature::RSA_PKCS1_1024_8192_SHA512_FOR_LEGACY_USE_ONLY - }; - bytes_to_rsa_pk(&dnskey.pubkey).map_err(|_| ValidationError::Invalid)? - .verify(alg, &signed_data, &sig.signature) - .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)] {