diff options
author | Justus Winter <justus@sequoia-pgp.org> | 2022-03-04 14:36:15 +0100 |
---|---|---|
committer | Justus Winter <justus@sequoia-pgp.org> | 2022-03-11 13:44:03 +0100 |
commit | 10601351f5eb1854f44254cc21a6353732043e97 (patch) | |
tree | f9c44536527632f2db74e212806218d35225df2d /openpgp/src/parse.rs | |
parent | 9ebf317fc28a28f325198c31a0cf10594837ae80 (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.rs | 77 |
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()); |