summaryrefslogtreecommitdiffstats
path: root/openpgp/src/parse.rs
diff options
context:
space:
mode:
authorJustus Winter <justus@sequoia-pgp.org>2022-03-04 14:36:15 +0100
committerJustus Winter <justus@sequoia-pgp.org>2022-03-11 13:44:03 +0100
commit10601351f5eb1854f44254cc21a6353732043e97 (patch)
treef9c44536527632f2db74e212806218d35225df2d /openpgp/src/parse.rs
parent9ebf317fc28a28f325198c31a0cf10594837ae80 (diff)
openpgp: Refactor S2K parsing.
- Add S2K::parse_common that optionally takes an S2K octet count parameter. We'll use that for v5 packet parsing where we now the size of the S2K object we're parsing.
Diffstat (limited to 'openpgp/src/parse.rs')
-rw-r--r--openpgp/src/parse.rs77
1 files changed, 61 insertions, 16 deletions
diff --git a/openpgp/src/parse.rs b/openpgp/src/parse.rs
index 0783c0cc..a7fbb085 100644
--- a/openpgp/src/parse.rs
+++ b/openpgp/src/parse.rs
@@ -1067,30 +1067,75 @@ impl Default for PacketParserSettings {
impl S2K {
/// Reads an S2K from `php`.
- fn parse<T: BufferedReader<Cookie>>(php: &mut PacketHeaderParser<T>) -> Result<Self>
+ fn parse_v4<T: BufferedReader<Cookie>>(php: &mut PacketHeaderParser<T>)
+ -> Result<Self> {
+ Self::parse_common(php, None)
+ }
+
+ /// Reads an S2K from `php` with optional explicit S2K length.
+ fn parse_common<T: BufferedReader<Cookie>>(php: &mut PacketHeaderParser<T>,
+ s2k_len: Option<u8>)
+ -> Result<Self>
{
+ if s2k_len == Some(0) {
+ return Err(Error::MalformedPacket(
+ "Invalid size for S2K object: 0 octets".into()).into());
+ }
+
+ let check_size = |expected| {
+ if let Some(got) = s2k_len {
+ if got != expected {
+ return Err(Error::MalformedPacket(format!(
+ "Invalid size for S2K object: {} octets, expected {}",
+ got, expected)));
+ }
+ }
+ Ok(())
+ };
+
let s2k = php.parse_u8("s2k_type")?;
#[allow(deprecated)]
let ret = match s2k {
- 0 => S2K::Simple {
- hash: HashAlgorithm::from(php.parse_u8("s2k_hash_algo")?),
+ 0 => {
+ check_size(2)?;
+ S2K::Simple {
+ hash: HashAlgorithm::from(php.parse_u8("s2k_hash_algo")?),
+ }
},
- 1 => S2K::Salted {
- hash: HashAlgorithm::from(php.parse_u8("s2k_hash_algo")?),
- salt: Self::read_salt(php)?,
+ 1 => {
+ check_size(10)?;
+ S2K::Salted {
+ hash: HashAlgorithm::from(php.parse_u8("s2k_hash_algo")?),
+ salt: Self::read_salt(php)?,
+ }
},
- 3 => S2K::Iterated {
- hash: HashAlgorithm::from(php.parse_u8("s2k_hash_algo")?),
- salt: Self::read_salt(php)?,
- hash_bytes: S2K::decode_count(php.parse_u8("s2k_count")?),
+ 3 => {
+ check_size(11)?;
+ S2K::Iterated {
+ hash: HashAlgorithm::from(php.parse_u8("s2k_hash_algo")?),
+ salt: Self::read_salt(php)?,
+ hash_bytes: S2K::decode_count(php.parse_u8("s2k_count")?),
+ }
},
100..=110 => S2K::Private {
tag: s2k,
- parameters: None,
+ parameters: if let Some(l) = s2k_len {
+ Some(
+ php.parse_bytes("parameters", l as usize - 1 /* Tag */)?
+ .into())
+ } else {
+ None
+ },
},
u => S2K::Unknown {
tag: u,
- parameters: None,
+ parameters: if let Some(l) = s2k_len {
+ Some(
+ php.parse_bytes("parameters", l as usize - 1 /* Tag */)?
+ .into())
+ } else {
+ None
+ },
},
};
@@ -1111,7 +1156,7 @@ impl<'a> Parse<'a, S2K> for S2K {
let bio = buffered_reader::Generic::with_cookie(
reader, None, Cookie::default());
let mut parser = PacketHeaderParser::new_naked(bio);
- Self::parse(&mut parser)
+ Self::parse_v4(&mut parser)
}
}
@@ -2183,7 +2228,7 @@ impl Key4<key::UnspecifiedParts, key::UnspecifiedRole>
// Encrypted, S2K & SHA-1 checksum
254 | 255 => {
let sk: SymmetricAlgorithm = php_try!(php.parse_u8("sym_algo")).into();
- let s2k = php_try!(S2K::parse(&mut php));
+ let s2k = php_try!(S2K::parse_v4(&mut php));
let s2k_supported = s2k.is_supported();
let cipher =
php_try!(php.parse_bytes_eof("encrypted_mpis"))
@@ -2640,7 +2685,7 @@ impl SKESK4 {
{
make_php_try!(php);
let sym_algo = php_try!(php.parse_u8("sym_algo"));
- let s2k = php_try!(S2K::parse(&mut php));
+ let s2k = php_try!(S2K::parse_v4(&mut php));
let s2k_supported = s2k.is_supported();
let esk = php_try!(php.parse_bytes_eof("esk"));
@@ -2672,7 +2717,7 @@ impl SKESK5 {
php_try!(php.parse_u8("sym_algo")).into();
let aead_algo: AEADAlgorithm =
php_try!(php.parse_u8("aead_algo")).into();
- let s2k = php_try!(S2K::parse(&mut php));
+ let s2k = php_try!(S2K::parse_v4(&mut php));
let s2k_supported = s2k.is_supported();
let iv_size = php_try!(aead_algo.iv_size());
let digest_size = php_try!(aead_algo.digest_size());