diff options
author | Neal H. Walfield <neal@pep.foundation> | 2019-10-23 14:23:28 +0200 |
---|---|---|
committer | Neal H. Walfield <neal@pep.foundation> | 2019-10-23 14:23:28 +0200 |
commit | e6e2658e8159449b0a6752d83db6f490942b8bf8 (patch) | |
tree | 4a4e083d5dc59129f961a4808babeb217cfb5fc5 /openpgp/src/crypto/aead.rs | |
parent | a3c4f05848d0d9d46a7b9cdc9b227ed27189e231 (diff) |
openpgp: Make Decryptor::reader_helper only do a short read on EOF
- `Decryptor::reader_helper` is used to implement
`BufferedReader::data`, which has the requirement that short reads
only occur on EOF.
- Adjust Decryptor::reader_helper to implement these semantics.
Diffstat (limited to 'openpgp/src/crypto/aead.rs')
-rw-r--r-- | openpgp/src/crypto/aead.rs | 31 |
1 files changed, 8 insertions, 23 deletions
diff --git a/openpgp/src/crypto/aead.rs b/openpgp/src/crypto/aead.rs index f5b8424e..0a34cbae 100644 --- a/openpgp/src/crypto/aead.rs +++ b/openpgp/src/crypto/aead.rs @@ -193,6 +193,10 @@ impl<'a> Decryptor<'a> { } } + // Note: this implementation tries *very* hard to make sure we don't + // gratuitiously do a short read. Specifically, if the return value + // is less than `plaintext.len()`, then it is either because we + // reached the end of the input or an error occured. fn read_helper(&mut self, plaintext: &mut [u8]) -> Result<usize> { use std::cmp::Ordering; @@ -273,11 +277,7 @@ impl<'a> Decryptor<'a> { } if chunk.len() < final_digest_size { - if pos > 0 { - return Ok(pos); - } else { - return Err(Error::ManipulatedMessage.into()); - } + return Err(Error::ManipulatedMessage.into()); } check_final_tag = chunk.len() < to_read; @@ -285,9 +285,6 @@ impl<'a> Decryptor<'a> { // Return the chunk. &chunk[..cmp::min(chunk.len(), to_read) - final_digest_size] }, - // We encountered an error, but we've already read - // something, so return that. - Err(_) if pos > 0 => return Ok(pos), Err(e) => return Err(e.into()), }; @@ -298,11 +295,7 @@ impl<'a> Decryptor<'a> { // the final tag. } else if chunk.len() <= self.digest_size { // A chunk has to include at least one byte and a tag. - if pos > 0 { - return Ok(pos); - } else { - return Err(Error::ManipulatedMessage.into()); - } + return Err(Error::ManipulatedMessage.into()); } else { // Decrypt the chunk and check the tag. let to_decrypt = chunk.len() - self.digest_size; @@ -326,11 +319,7 @@ impl<'a> Decryptor<'a> { if secure_cmp(&digest[..], &chunk[to_decrypt..]) != Ordering::Equal { - if pos > 0 { - return Ok(pos); - } else { - return Err(Error::ManipulatedMessage.into()); - } + return Err(Error::ManipulatedMessage.into()); } if double_buffer { @@ -368,11 +357,7 @@ impl<'a> Decryptor<'a> { if final_digest.len() != final_digest_size || secure_cmp(&digest[..], final_digest) != Ordering::Equal { - if pos > 0 { - return Ok(pos); - } else { - return Err(Error::ManipulatedMessage.into()); - } + return Err(Error::ManipulatedMessage.into()); } // Consume the data only on success so that we keep |