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:
Wez Furlong
2023-06-15 13:23:44 -07:00
parent cf11540f84
commit e5d03052be
3 changed files with 25 additions and 11 deletions
+3 -10
View File
@@ -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(),
+21
View File
@@ -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())
}
+1 -1
View File
@@ -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,
)?;