summaryrefslogtreecommitdiffstats
path: root/openpgp/src/serialize.rs
diff options
context:
space:
mode:
authorJustus Winter <justus@sequoia-pgp.org>2020-08-14 10:36:48 +0200
committerJustus Winter <justus@sequoia-pgp.org>2020-08-14 10:36:48 +0200
commit4c34450ef5b6f261f1dedd0117875f03d22e3dc8 (patch)
tree7122a46f2d7470d47d38ad6dac1800b82a8e1ad5 /openpgp/src/serialize.rs
parentd0c55a462ab80f8f982aac7a5dd7474145888704 (diff)
openpgp: Fix error handling serializing PublicKey and Ciphertext.
- When writing out fields with explicit length as u8, make sure that we do not exceed that limit. - See #542.
Diffstat (limited to 'openpgp/src/serialize.rs')
-rw-r--r--openpgp/src/serialize.rs28
1 files changed, 18 insertions, 10 deletions
diff --git a/openpgp/src/serialize.rs b/openpgp/src/serialize.rs
index 502bbbcf..fb80a85d 100644
--- a/openpgp/src/serialize.rs
+++ b/openpgp/src/serialize.rs
@@ -136,7 +136,7 @@
use std::io::{self, Write};
use std::cmp;
-use std::convert::TryFrom;
+use std::convert::{TryFrom, TryInto};
use super::*;
@@ -895,6 +895,19 @@ impl MarshalInto for crypto::mpi::ProtectedMPI {
}
}
+/// Writes `buf` into `w` prefixed by the length as u8, bailing out if
+/// the length exceeds 256 bytes.
+fn write_field_with_u8_size(w: &mut dyn Write, name: &str, buf: &[u8])
+ -> Result<()> {
+ w.write_all(&[buf.len().try_into()
+ .map_err(|_| anyhow::Error::from(
+ Error::InvalidArgument(
+ format!("{} exceeds 255 bytes: {:?}",
+ name, buf))))?])?;
+ w.write_all(buf)?;
+ Ok(())
+}
+
impl Marshal for crypto::mpi::PublicKey {
fn serialize(&self, w: &mut dyn std::io::Write) -> Result<()> {
use crate::crypto::mpi::PublicKey::*;
@@ -919,20 +932,17 @@ impl Marshal for crypto::mpi::PublicKey {
}
&EdDSA { ref curve, ref q } => {
- w.write_all(&[curve.oid().len() as u8])?;
- w.write_all(curve.oid())?;
+ write_field_with_u8_size(w, "Curve's OID", curve.oid())?;
q.serialize(w)?;
}
&ECDSA { ref curve, ref q } => {
- w.write_all(&[curve.oid().len() as u8])?;
- w.write_all(curve.oid())?;
+ write_field_with_u8_size(w, "Curve's OID", curve.oid())?;
q.serialize(w)?;
}
&ECDH { ref curve, ref q, hash, sym } => {
- w.write_all(&[curve.oid().len() as u8])?;
- w.write_all(curve.oid())?;
+ write_field_with_u8_size(w, "Curve's OID", curve.oid())?;
q.serialize(w)?;
w.write_all(&[3u8, 1u8, u8::from(hash), u8::from(sym)])?;
}
@@ -1116,9 +1126,7 @@ impl Marshal for crypto::mpi::Ciphertext {
&ECDH{ ref e, ref key } => {
e.serialize(w)?;
-
- w.write_all(&[key.len() as u8])?;
- w.write_all(&key)?;
+ write_field_with_u8_size(w, "Key", key)?;
}
&Unknown { ref mpis, ref rest } => {