diff options
author | Justus Winter <justus@sequoia-pgp.org> | 2022-03-04 11:54:39 +0100 |
---|---|---|
committer | Justus Winter <justus@sequoia-pgp.org> | 2022-03-22 11:40:50 +0100 |
commit | cc3682a8d03e3ad476e262e4a52df263dc4eba9d (patch) | |
tree | 5fe7b679b4c02d8b7d85c08838ef2ff8bb0722c1 | |
parent | 2f140c0a621a78f7669e5758151ee6f6b00f69d0 (diff) |
openpgp: Split SKESK parsing into SKESK4 and SKESK5 parsing.
-rw-r--r-- | openpgp/src/parse.rs | 163 |
1 files changed, 89 insertions, 74 deletions
diff --git a/openpgp/src/parse.rs b/openpgp/src/parse.rs index 154228f8..d80331d1 100644 --- a/openpgp/src/parse.rs +++ b/openpgp/src/parse.rs @@ -2620,88 +2620,103 @@ fn compressed_data_parser_test () { impl SKESK { /// Parses the body of an SK-ESK packet. - fn parse<'a, T: 'a + BufferedReader<Cookie>>(mut php: PacketHeaderParser<T>) -> Result<PacketParser<'a>> { + fn parse<'a, T: 'a + BufferedReader<Cookie>>(mut php: PacketHeaderParser<T>) + -> Result<PacketParser<'a>> + { make_php_try!(php); let version = php_try!(php.parse_u8("version")); - let skesk = match version { - 4 => { - let sym_algo = php_try!(php.parse_u8("sym_algo")); - let s2k = php_try!(S2K::parse(&mut php)); - let s2k_supported = s2k.is_supported(); - let esk = php_try!(php.parse_bytes_eof("esk")); - - SKESK::V4(php_try!(SKESK4::new_raw( - sym_algo.into(), - s2k, - if s2k_supported || esk.is_empty() { - Ok(if ! esk.is_empty() { - Some(esk.into()) - } else { - None - }) - } else { - Err(esk.into()) - }, - ))) - }, + match version { + 4 => SKESK4::parse(php), + 5 => SKESK5::parse(php), + _ => php.fail("unknown version"), + } + } +} - 5 => { - let sym_algo: SymmetricAlgorithm = - 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_supported = s2k.is_supported(); - let iv_size = php_try!(aead_algo.iv_size()); - let digest_size = php_try!(aead_algo.digest_size()); - - // The rest of the packet is (potentially) the S2K - // parameters, the AEAD IV, the ESK, and the AEAD - // digest. We don't know the size of the S2K - // parameters if the S2K method is not supported, and - // we don't know the size of the ESK. - let mut esk = php_try!(php.reader.steal_eof() - .map_err(anyhow::Error::from)); - let aead_iv = if s2k_supported && esk.len() >= iv_size { - // We know the S2K method, so the parameters have - // been parsed into the S2K object. So, `esk` - // starts with iv_size bytes of IV. - let mut iv = esk; - esk = iv.split_off(iv_size); - iv +impl SKESK4 { + /// Parses the body of an SK-ESK packet. + fn parse<'a, T: 'a + BufferedReader<Cookie>>(mut php: PacketHeaderParser<T>) + -> Result<PacketParser<'a>> + { + make_php_try!(php); + let sym_algo = php_try!(php.parse_u8("sym_algo")); + let s2k = php_try!(S2K::parse(&mut php)); + let s2k_supported = s2k.is_supported(); + let esk = php_try!(php.parse_bytes_eof("esk")); + + let skesk = php_try!(SKESK4::new_raw( + sym_algo.into(), + s2k, + if s2k_supported || esk.is_empty() { + Ok(if ! esk.is_empty() { + Some(esk.into()) } else { - Vec::with_capacity(0) // A dummy value. - }; - - let l = esk.len(); - let aead_digest = esk.split_off(l.saturating_sub(digest_size)); - // Now fix the map. - if s2k_supported { - php.field("aead_iv", iv_size); - } - php.field("esk", esk.len()); - php.field("aead_digest", aead_digest.len()); - - SKESK::V5(php_try!(SKESK5::new_raw( - sym_algo, - aead_algo, - s2k, - if s2k_supported { - Ok((aead_iv.into(), esk.into())) - } else { - Err(esk.into()) - }, - aead_digest.into_boxed_slice(), - ))) + None + }) + } else { + Err(esk.into()) }, + )); - _ => { - // We only support version 4 and 5 SKESK packets. - return php.fail("unknown version"); - } + php.ok(skesk.into()) + } +} + +impl SKESK5 { + /// Parses the body of an SK-ESK packet. + fn parse<'a, T: 'a + BufferedReader<Cookie>>(mut php: PacketHeaderParser<T>) + -> Result<PacketParser<'a>> + { + make_php_try!(php); + let sym_algo: SymmetricAlgorithm = + 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_supported = s2k.is_supported(); + let iv_size = php_try!(aead_algo.iv_size()); + let digest_size = php_try!(aead_algo.digest_size()); + + // The rest of the packet is (potentially) the S2K + // parameters, the AEAD IV, the ESK, and the AEAD + // digest. We don't know the size of the S2K + // parameters if the S2K method is not supported, and + // we don't know the size of the ESK. + let mut esk = php_try!(php.reader.steal_eof() + .map_err(anyhow::Error::from)); + let aead_iv = if s2k_supported && esk.len() >= iv_size { + // We know the S2K method, so the parameters have + // been parsed into the S2K object. So, `esk` + // starts with iv_size bytes of IV. + let mut iv = esk; + esk = iv.split_off(iv_size); + iv + } else { + Vec::with_capacity(0) // A dummy value. }; - php.ok(Packet::SKESK(skesk)) + let l = esk.len(); + let aead_digest = esk.split_off(l.saturating_sub(digest_size)); + // Now fix the map. + if s2k_supported { + php.field("aead_iv", iv_size); + } + php.field("esk", esk.len()); + php.field("aead_digest", aead_digest.len()); + + let skesk = php_try!(SKESK5::new_raw( + sym_algo, + aead_algo, + s2k, + if s2k_supported { + Ok((aead_iv.into(), esk.into())) + } else { + Err(esk.into()) + }, + aead_digest.into_boxed_slice(), + )); + + php.ok(skesk.into()) } } |