summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJustus Winter <justus@sequoia-pgp.org>2018-06-28 10:01:17 +0200
committerJustus Winter <justus@sequoia-pgp.org>2018-06-28 10:18:10 +0200
commit1f1d83d5687a7e2ff21f250117e6f5256fcc38e6 (patch)
tree919d1fe7a035aaeab1cee0d2d6d5a6327bd91828
parent06eac62a0619003a317ccc2cccee4c0abcc3eacd (diff)
openpgp: Add `MPIs::Unknown` for parameters of unknown algorithms.
- Fixes #8.
-rw-r--r--openpgp/src/mpis.rs21
-rw-r--r--openpgp/src/parse/mpis.rs52
-rw-r--r--openpgp/src/serialize/mod.rs7
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(())