summaryrefslogtreecommitdiffstats
path: root/openpgp
diff options
context:
space:
mode:
authorJustus Winter <justus@sequoia-pgp.org>2018-08-31 11:51:12 +0200
committerJustus Winter <justus@sequoia-pgp.org>2018-08-31 11:54:19 +0200
commit4018ba433ec3df4b11baabeacb7701ab881b77e1 (patch)
treef40296b9966590cef4f49a3201ddf4beda9c3899 /openpgp
parent3fab78cdfeb96ab5adc03dcac47521f79c52b442 (diff)
openpgp: Make SKESK's ESK field optional.
Diffstat (limited to 'openpgp')
-rw-r--r--openpgp/src/parse/parse.rs2
-rw-r--r--openpgp/src/serialize/mod.rs6
-rw-r--r--openpgp/src/skesk.rs36
3 files changed, 23 insertions, 21 deletions
diff --git a/openpgp/src/parse/parse.rs b/openpgp/src/parse/parse.rs
index 8cd38a9f..6f76ba90 100644
--- a/openpgp/src/parse/parse.rs
+++ b/openpgp/src/parse/parse.rs
@@ -1627,7 +1627,7 @@ impl SKESK {
version: version,
symm_algo: symm_algo.into(),
s2k: s2k,
- esk: esk,
+ esk: if esk.len() > 0 { Some(esk) } else { None },
}))
}
}
diff --git a/openpgp/src/serialize/mod.rs b/openpgp/src/serialize/mod.rs
index 6a26094d..50ea10ac 100644
--- a/openpgp/src/serialize/mod.rs
+++ b/openpgp/src/serialize/mod.rs
@@ -918,7 +918,7 @@ impl Serialize for SKESK {
1 // Version
+ 1 // Algo
+ self.s2k.serialized_len() // s2k.
- + self.esk.len(); // ESK.
+ + self.esk.as_ref().map(|esk| esk.len()).unwrap_or(0); // ESK.
CTB::new(Tag::SKESK).serialize(o)?;
BodyLength::Full(len as u32).serialize(o)?;
@@ -926,7 +926,9 @@ impl Serialize for SKESK {
write_byte(o, self.version)?;
write_byte(o, self.symm_algo.into())?;
self.s2k.serialize(o)?;
- o.write(&self.esk[..])?;
+ if let Some(ref esk) = self.esk {
+ o.write(&esk[..])?;
+ }
Ok(())
}
diff --git a/openpgp/src/skesk.rs b/openpgp/src/skesk.rs
index a3b74f0a..692da7c0 100644
--- a/openpgp/src/skesk.rs
+++ b/openpgp/src/skesk.rs
@@ -23,7 +23,7 @@ pub struct SKESK {
/// Key derivation method for the symmetric key.
pub(crate) s2k: S2K,
/// The encrypted session key.
- pub(crate) esk: Vec<u8>,
+ pub(crate) esk: Option<Vec<u8>>,
}
impl SKESK {
@@ -57,7 +57,7 @@ impl SKESK {
version: 4,
symm_algo: algo,
s2k: s2k,
- esk: esk,
+ esk: Some(esk),
})
}
@@ -87,12 +87,12 @@ impl SKESK {
}
/// Gets the encrypted session key.
- pub fn esk(&self) -> &[u8] {
- self.esk.as_slice()
+ pub fn esk(&self) -> Option<&[u8]> {
+ self.esk.as_ref().map(|esk| esk.as_slice())
}
/// Sets the encrypted session key.
- pub fn set_esk(&mut self, esk: Vec<u8>) {
+ pub fn set_esk(&mut self, esk: Option<Vec<u8>>) {
self.esk = esk;
}
@@ -109,24 +109,14 @@ impl SKESK {
{
let key = self.s2k.derive_key(password, self.symm_algo.key_size()?)?;
- if self.esk.len() == 0 {
- // No ESK, we return the derived key.
-
- match self.s2k {
- S2K::Simple{ .. } =>
- Err(Error::InvalidOperation(
- "SKESK: Cannot use Simple S2K without ESK".into())
- .into()),
- _ => Ok((self.symm_algo, key)),
- }
- } else {
+ if let Some(ref esk) = self.esk {
// Use the derived key to decrypt the ESK. Unlike SEP &
// SEIP we have to use plain CFB here.
let blk_sz = self.symm_algo.block_size()?;
let mut iv = vec![0u8; blk_sz];
let mut dec = self.symm_algo.make_decrypt_cfb(&key[..])?;
- let mut plain = vec![0u8; self.esk.len()];
- let cipher = &self.esk[..];
+ let mut plain = vec![0u8; esk.len()];
+ let cipher = &esk[..];
for (pl, ct)
in plain[..].chunks_mut(blk_sz).zip(cipher.chunks(blk_sz))
@@ -138,6 +128,16 @@ impl SKESK {
let key = plain[1..].to_vec();
Ok((sym, key))
+ } else {
+ // No ESK, we return the derived key.
+
+ match self.s2k {
+ S2K::Simple{ .. } =>
+ Err(Error::InvalidOperation(
+ "SKESK: Cannot use Simple S2K without ESK".into())
+ .into()),
+ _ => Ok((self.symm_algo, key)),
+ }
}
}
}