diff options
author | Justus Winter <justus@sequoia-pgp.org> | 2018-06-28 10:01:17 +0200 |
---|---|---|
committer | Justus Winter <justus@sequoia-pgp.org> | 2018-06-28 10:18:10 +0200 |
commit | 1f1d83d5687a7e2ff21f250117e6f5256fcc38e6 (patch) | |
tree | 919d1fe7a035aaeab1cee0d2d6d5a6327bd91828 | |
parent | 06eac62a0619003a317ccc2cccee4c0abcc3eacd (diff) |
openpgp: Add `MPIs::Unknown` for parameters of unknown algorithms.
- Fixes #8.
-rw-r--r-- | openpgp/src/mpis.rs | 21 | ||||
-rw-r--r-- | openpgp/src/parse/mpis.rs | 52 | ||||
-rw-r--r-- | openpgp/src/serialize/mod.rs | 7 |
3 files changed, 72 insertions, 8 deletions
diff --git a/openpgp/src/mpis.rs b/openpgp/src/mpis.rs index d72740c2..ab9d8bae 100644 --- a/openpgp/src/mpis.rs +++ b/openpgp/src/mpis.rs @@ -212,6 +212,14 @@ pub enum MPIs { /// Symmetrically encrypted poition. key: Box<[u8]> }, + + /// Unknown number of MPIs for an unknown algorithm. + Unknown { + /// The successfully parsed MPIs. + mpis: Box<[MPI]>, + /// Any data that failed to parse. + rest: Box<[u8]>, + }, } impl MPIs { @@ -280,6 +288,10 @@ impl MPIs { 2 + e.value.len() + // one length octet plus ephemeral key 1 + key.len(), + + &Unknown { ref mpis, ref rest } => + mpis.iter().map(|m| 2 + m.value.len()).sum::<usize>() + + rest.len(), } } @@ -399,6 +411,13 @@ impl MPIs { hash.update(&[key.len() as u8]); hash.update(&key); } + + &Unknown { ref mpis, ref rest } => { + for mpi in mpis.iter() { + mpi.hash(hash); + } + hash.update(rest); + } } } } @@ -580,6 +599,8 @@ mod tests { ElgamalEncrypt, cur.into_inner()).unwrap(), MPIs::ECDHCiphertext { .. } => MPIs::parse_ciphertext_naked(ECDH, cur.into_inner()).unwrap(), + + MPIs::Unknown { .. } => unreachable!(), }; mpis == mpis2 diff --git a/openpgp/src/parse/mpis.rs b/openpgp/src/parse/mpis.rs index bf82caa8..99311dc7 100644 --- a/openpgp/src/parse/mpis.rs +++ b/openpgp/src/parse/mpis.rs @@ -125,8 +125,17 @@ impl MPIs { }) } - Unknown(p) | Private(p) => { - Err(Error::UnknownPublicKeyAlgorithm(p.into()).into()) + Unknown(_) | Private(_) => { + let mut mpis = Vec::new(); + while let Ok(mpi) = MPI::parse("unknown_parameter", php) { + mpis.push(mpi); + } + let mut rest = php.parse_bytes_eof("rest")?; + + Ok(MPIs::Unknown { + mpis: mpis.into_boxed_slice(), + rest: rest.into_boxed_slice(), + }) } } } @@ -243,8 +252,17 @@ impl MPIs { scalar: MPI::parse("ecdh_secret", php)? }) } - Unknown(p) | Private(p) => { - Err(Error::UnknownPublicKeyAlgorithm(p.into()).into()) + Unknown(_) | Private(_) => { + let mut mpis = Vec::new(); + while let Ok(mpi) = MPI::parse("unknown_parameter", php) { + mpis.push(mpi); + } + let mut rest = php.parse_bytes_eof("rest")?; + + Ok(MPIs::Unknown { + mpis: mpis.into_boxed_slice(), + rest: rest.into_boxed_slice(), + }) } } } @@ -308,8 +326,17 @@ impl MPIs { }) } - Unknown(p) | Private(p) => { - Err(Error::UnknownPublicKeyAlgorithm(p.into()).into()) + Unknown(_) | Private(_) => { + let mut mpis = Vec::new(); + while let Ok(mpi) = MPI::parse("unknown_parameter", php) { + mpis.push(mpi); + } + let mut rest = php.parse_bytes_eof("rest")?; + + Ok(MPIs::Unknown { + mpis: mpis.into_boxed_slice(), + rest: rest.into_boxed_slice(), + }) } RSASign | DSA | EdDSA | ECDSA => { @@ -398,8 +425,17 @@ impl MPIs { }) } - Unknown(p) | Private(p) => { - Err(Error::UnknownPublicKeyAlgorithm(p.into()).into()) + Unknown(_) | Private(_) => { + let mut mpis = Vec::new(); + while let Ok(mpi) = MPI::parse("unknown_parameter", php) { + mpis.push(mpi); + } + let mut rest = php.parse_bytes_eof("rest")?; + + Ok(MPIs::Unknown { + mpis: mpis.into_boxed_slice(), + rest: rest.into_boxed_slice(), + }) } RSAEncrypt | ElgamalEncrypt | ECDH => { diff --git a/openpgp/src/serialize/mod.rs b/openpgp/src/serialize/mod.rs index e133ab1b..a53ed048 100644 --- a/openpgp/src/serialize/mod.rs +++ b/openpgp/src/serialize/mod.rs @@ -285,6 +285,13 @@ impl Serialize for mpis::MPIs { } &None => unreachable!(), + + &Unknown { ref mpis, ref rest } => { + for mpi in mpis.iter() { + mpi.serialize(w)?; + } + w.write_all(rest)?; + } } Ok(()) |