summaryrefslogtreecommitdiffstats
path: root/openpgp/src/parse.rs
diff options
context:
space:
mode:
Diffstat (limited to 'openpgp/src/parse.rs')
-rw-r--r--openpgp/src/parse.rs45
1 files changed, 36 insertions, 9 deletions
diff --git a/openpgp/src/parse.rs b/openpgp/src/parse.rs
index cdf9fb19..a410632b 100644
--- a/openpgp/src/parse.rs
+++ b/openpgp/src/parse.rs
@@ -1331,15 +1331,18 @@ impl Signature4 {
let typ = php_try!(php.parse_u8("type"));
let pk_algo: PublicKeyAlgorithm = php_try!(php.parse_u8("pk_algo")).into();
- let hash_algo = php_try!(php.parse_u8("hash_algo"));
+ let hash_algo: HashAlgorithm =
+ php_try!(php.parse_u8("hash_algo")).into();
let hashed_area_len = php_try!(php.parse_be_u16("hashed_area_len"));
let hashed_area
= php_try!(SubpacketArea::parse(&mut php,
- hashed_area_len as usize));
+ hashed_area_len as usize,
+ hash_algo));
let unhashed_area_len = php_try!(php.parse_be_u16("unhashed_area_len"));
let unhashed_area
= php_try!(SubpacketArea::parse(&mut php,
- unhashed_area_len as usize));
+ unhashed_area_len as usize,
+ hash_algo));
let digest_prefix1 = php_try!(php.parse_u8("digest_prefix1"));
let digest_prefix2 = php_try!(php.parse_u8("digest_prefix2"));
if ! pk_algo.for_signing() {
@@ -1348,7 +1351,6 @@ impl Signature4 {
let mpis = php_try!(
crypto::mpi::Signature::_parse(pk_algo, &mut php));
- let hash_algo = hash_algo.into();
let typ = typ.into();
let need_hash = HashingMode::for_signature(hash_algo, typ);
let mut pp = php.ok(Packet::Signature(Signature4::new(
@@ -1511,12 +1513,15 @@ fn signature_parser_test () {
impl SubpacketArea {
// Parses a subpacket area.
- fn parse<'a, T: 'a + BufferedReader<Cookie>>(php: &mut PacketHeaderParser<T>, mut limit: usize)
- -> Result<Self>
+ fn parse<'a, T>(php: &mut PacketHeaderParser<T>,
+ mut limit: usize,
+ hash_algo: HashAlgorithm)
+ -> Result<Self>
+ where T: 'a + BufferedReader<Cookie>,
{
let mut packets = Vec::new();
while limit > 0 {
- let p = Subpacket::parse(php, limit)?;
+ let p = Subpacket::parse(php, limit, hash_algo)?;
assert!(limit >= p.length.len() + p.length.serialized_len());
limit -= p.length.len() + p.length.serialized_len();
packets.push(p);
@@ -1528,8 +1533,12 @@ impl SubpacketArea {
impl Subpacket {
// Parses a raw subpacket.
- fn parse<'a, T: 'a + BufferedReader<Cookie>>(php: &mut PacketHeaderParser<T>, limit: usize)
- -> Result<Self> {
+ fn parse<'a, T>(php: &mut PacketHeaderParser<T>,
+ limit: usize,
+ hash_algo: HashAlgorithm)
+ -> Result<Self>
+ where T: 'a + BufferedReader<Cookie>,
+ {
let length = SubpacketLength::parse(&mut php.reader)?;
php.field("subpacket length", length.serialized_len());
let len = length.len() as usize;
@@ -1745,6 +1754,24 @@ impl Subpacket {
_ => Fingerprint::Invalid(bytes.into()),
})
},
+ SubpacketTag::AttestedCertifications => {
+ // If we don't know the hash algorithm, put all digest
+ // into one bucket. That way, at least it will
+ // roundtrip. It will never verify, because we don't
+ // know the hash.
+ let digest_size =
+ hash_algo.context().map(|c| c.digest_size())
+ .unwrap_or(len);
+
+ if len % digest_size != 0 {
+ return Err(Error::BadSignature(
+ "Wrong number of bytes in certification subpacket".into())
+ .into());
+ }
+ let bytes = php.parse_bytes("attested crts", len)?;
+ SubpacketValue::AttestedCertifications(
+ bytes.chunks(digest_size).map(Into::into).collect())
+ },
SubpacketTag::Reserved(_)
| SubpacketTag::PlaceholderForBackwardCompatibility
| SubpacketTag::Private(_)