mirror of
https://github.com/mailscope/kumomta.git
synced 2026-10-27 00:36:13 +00:00
dkim: tidy up handling of l= body length tag
We should parse at the edge and pass down the parsed number
This commit is contained in:
+3
-10
@@ -99,19 +99,12 @@ impl HashImpl {
|
||||
/// https://datatracker.ietf.org/doc/html/rfc6376#section-3.7
|
||||
pub(crate) fn compute_body_hash<'a>(
|
||||
canonicalization_type: canonicalization::Type,
|
||||
length: Option<&str>,
|
||||
length: Option<usize>,
|
||||
hash_algo: HashAlgo,
|
||||
email: &'a ParsedEmail<'a>,
|
||||
) -> Result<String, DKIMError> {
|
||||
let body = email.get_body_bytes();
|
||||
|
||||
let limit = if let Some(length) = length {
|
||||
length
|
||||
.parse::<usize>()
|
||||
.map_err(|err| DKIMError::SignatureSyntaxError(format!("invalid length: {}", err)))?
|
||||
} else {
|
||||
usize::MAX
|
||||
};
|
||||
let limit = length.unwrap_or(usize::MAX);
|
||||
|
||||
let mut hasher = LimitHasher {
|
||||
hasher: HashImpl::from_algo(hash_algo),
|
||||
@@ -260,7 +253,7 @@ Hello Alice
|
||||
let email = ParsedEmail::parse_bytes(email.as_bytes()).unwrap();
|
||||
|
||||
let canonicalization_type = canonicalization::Type::Relaxed;
|
||||
let length = Some("3");
|
||||
let length = Some(3);
|
||||
let hash_algo = HashAlgo::RsaSha1;
|
||||
assert_eq!(
|
||||
compute_body_hash(canonicalization_type, length, hash_algo, &email).unwrap(),
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use crate::{parser, DKIMError};
|
||||
use indexmap::map::IndexMap;
|
||||
use std::io::Write;
|
||||
use std::str::FromStr;
|
||||
|
||||
pub(crate) const HEADER: &str = "DKIM-Signature";
|
||||
const REQUIRED_TAGS: &[&str] = &["v", "a", "b", "bh", "d", "h", "s"];
|
||||
@@ -84,6 +85,26 @@ impl DKIMHeader {
|
||||
self.tags.get(name).map(|v| v.value.as_str())
|
||||
}
|
||||
|
||||
/// Get the named tag.
|
||||
/// Attempt to parse it into an `R`
|
||||
pub fn parse_tag<R>(&self, name: &str) -> Result<Option<R>, DKIMError>
|
||||
where
|
||||
R: FromStr,
|
||||
<R as FromStr>::Err: std::fmt::Display,
|
||||
{
|
||||
match self.get_tag(name) {
|
||||
None => Ok(None),
|
||||
Some(value) => {
|
||||
let value: R = value.parse().map_err(|err| {
|
||||
DKIMError::SignatureSyntaxError(format!(
|
||||
"invalid \"{name}\" tag value: {err:#}"
|
||||
))
|
||||
})?;
|
||||
Ok(Some(value))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_raw_tag(&self, name: &str) -> Option<&str> {
|
||||
self.tags.get(name).map(|v| v.raw_value.as_str())
|
||||
}
|
||||
|
||||
@@ -93,7 +93,7 @@ async fn verify_email_header<'a>(
|
||||
let hash_algo = parser::parse_hash_algo(&dkim_header.get_required_tag("a"))?;
|
||||
let computed_body_hash = hash::compute_body_hash(
|
||||
body_canonicalization_type,
|
||||
dkim_header.get_tag("l"),
|
||||
dkim_header.parse_tag("l")?,
|
||||
hash_algo,
|
||||
email,
|
||||
)?;
|
||||
|
||||
Reference in New Issue
Block a user