diff options
author | Justus Winter <justus@sequoia-pgp.org> | 2018-09-24 17:32:44 +0200 |
---|---|---|
committer | Justus Winter <justus@sequoia-pgp.org> | 2018-09-24 17:41:06 +0200 |
commit | 33c473b627d3e14d2e8784d78ef3681722fa0a1d (patch) | |
tree | 14dfef8e27ac2f2790551647295147ef132ba713 /openpgp/src/parse/hashed_reader.rs | |
parent | e14fb53aba36de023642eb3ea03bec9e4e8b84c3 (diff) |
openpgp: Fix deferred hashing of one-pass-signature framing.
- Previously, the stashed data was hashed into all signature group's
hashes, duplicating framing in level >1 signatures. This broke
verification of notarizations over notarizations over signatures.
Diffstat (limited to 'openpgp/src/parse/hashed_reader.rs')
-rw-r--r-- | openpgp/src/parse/hashed_reader.rs | 28 |
1 files changed, 24 insertions, 4 deletions
diff --git a/openpgp/src/parse/hashed_reader.rs b/openpgp/src/parse/hashed_reader.rs index 761935cf..9bf2aac9 100644 --- a/openpgp/src/parse/hashed_reader.rs +++ b/openpgp/src/parse/hashed_reader.rs @@ -41,9 +41,32 @@ impl<R: BufferedReader<Cookie>> HashedReader<R> { impl Cookie { fn hash_update(&mut self, data: &[u8]) { + let level = self.level.unwrap_or(0); + let hashes_for = self.hashes_for; + let ngroups = self.sig_groups.len(); + // Hash stashed data first. if let Some(stashed_data) = self.hash_stash.take() { - self.hash_update(&stashed_data); + // The stashed data was supposed to be hashed into the + // then-topmost signature-group's hash, but wasn't, + // because framing isn't hashed into the topmost signature + // group. By the time the parser encountered a new + // signature group, the data has already been consumed. + // We fix that here by hashing the stashed data into the + // former topmost signature-group's hash. + assert!(ngroups > 1); + for (algo, ref mut h) in + self.sig_groups[ngroups-2].hashes.iter_mut() + { + if TRACE { + eprintln!("{} hash_update({:?}): group {} {:?} hashing {} \ + stashed bytes.", + indent(cmp::max(0, level) as u8), + hashes_for, ngroups-2, algo, data.len()); + } + + h.update(&stashed_data); + } } if data.len() == 0 { @@ -66,9 +89,6 @@ impl Cookie { return; } - let level = self.level.unwrap_or(0); - let hashes_for = self.hashes_for; - let ngroups = self.sig_groups.len(); let topmost_group = |i| i == ngroups - 1; for (i, sig_group) in self.sig_groups.iter_mut().enumerate() { if topmost_group(i) && self.hashing != Hashing::Enabled { |