Skip to content

Commit ad93c20

Browse files
committed
str -> Digest in calculate_and_validate
Signed-off-by: Stepan Koltsov <[email protected]>
1 parent a1a9597 commit ad93c20

File tree

1 file changed

+27
-11
lines changed

1 file changed

+27
-11
lines changed

src/digest.rs

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
33
use http::HeaderMap;
44
use sha2::Digest as _;
5+
use std::fmt::{Display, Formatter};
56

67
use crate::sha256_digest;
78

@@ -38,6 +39,13 @@ pub struct Digest<'a> {
3839
pub digest: &'a str,
3940
}
4041

42+
impl<'a> Display for Digest<'a> {
43+
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
44+
let Digest { algorithm, digest } = self;
45+
write!(f, "{algorithm}:{digest}")
46+
}
47+
}
48+
4149
impl<'a> Digest<'a> {
4250
/// Create a new digest from a str. This isn't using `FromStr` because we can't use lifetimes
4351
/// properly when implementing the trait
@@ -106,45 +114,53 @@ pub fn digest_header_value(headers: HeaderMap) -> Result<Option<String>> {
106114
/// digest. If both digests are provided, but they use different algorithms, then the header digest
107115
/// is returned after validation as according to the spec it is the "canonical" digest for the given
108116
/// content.
109-
pub fn validate_digest(
117+
pub(crate) fn validate_digest(
110118
body: &[u8],
111119
digest_header: Option<String>,
112120
reference_digest: Option<&str>,
113121
) -> Result<String> {
122+
let digest_header = digest_header.as_ref().map(|s| Digest::new(s)).transpose()?;
123+
let reference_digest = reference_digest.map(|s| Digest::new(s)).transpose()?;
114124
match (digest_header, reference_digest) {
115125
// If both digests are equal, then just calculate once
116126
(Some(digest), Some(reference)) if digest == reference => {
117-
calculate_and_validate(body, &digest)
127+
calculate_and_validate(body, digest)
118128
}
119129
(Some(digest), Some(reference)) => {
120130
calculate_and_validate(body, reference)?;
121-
calculate_and_validate(body, &digest)
131+
calculate_and_validate(body, digest)
122132
}
123-
(Some(digest), None) => calculate_and_validate(body, &digest),
133+
(Some(digest), None) => calculate_and_validate(body, digest),
124134
(None, Some(reference)) => calculate_and_validate(body, reference),
125135
// If we have neither, just digest the body
126136
(None, None) => Ok(sha256_digest(body)),
127137
}
128138
}
129139

130140
/// Helper for calculating and validating the digest of the given content
131-
fn calculate_and_validate(content: &[u8], digest: &str) -> Result<String> {
132-
let parsed_digest = Digest::new(digest)?;
141+
fn calculate_and_validate(content: &[u8], parsed_digest: Digest) -> Result<String> {
133142
let digest_calculated = match parsed_digest.algorithm {
134143
"sha256" => format!("{:x}", sha2::Sha256::digest(content)),
135144
"sha384" => format!("{:x}", sha2::Sha384::digest(content)),
136145
"sha512" => format!("{:x}", sha2::Sha512::digest(content)),
137146
other => return Err(DigestError::UnsupportedAlgorithm(other.to_string())),
138147
};
139-
let hex = format!("{}:{digest_calculated}", parsed_digest.algorithm);
148+
let hex = Digest {
149+
algorithm: parsed_digest.algorithm,
150+
digest: &digest_calculated,
151+
};
140152
tracing::debug!(%hex, "Computed digest of payload");
141-
if hex != digest {
153+
if hex != parsed_digest {
142154
return Err(DigestError::VerificationError {
143-
expected: digest.to_owned(),
144-
actual: hex,
155+
expected: parsed_digest.to_string(),
156+
actual: Digest {
157+
algorithm: parsed_digest.algorithm,
158+
digest: &digest_calculated,
159+
}
160+
.to_string(),
145161
});
146162
}
147-
Ok(hex)
163+
Ok(hex.to_string())
148164
}
149165

150166
#[cfg(test)]

0 commit comments

Comments
 (0)