diff options
author | Justus Winter <justus@sequoia-pgp.org> | 2018-08-31 11:51:12 +0200 |
---|---|---|
committer | Justus Winter <justus@sequoia-pgp.org> | 2018-08-31 11:54:19 +0200 |
commit | 4018ba433ec3df4b11baabeacb7701ab881b77e1 (patch) | |
tree | f40296b9966590cef4f49a3201ddf4beda9c3899 /openpgp | |
parent | 3fab78cdfeb96ab5adc03dcac47521f79c52b442 (diff) |
openpgp: Make SKESK's ESK field optional.
Diffstat (limited to 'openpgp')
-rw-r--r-- | openpgp/src/parse/parse.rs | 2 | ||||
-rw-r--r-- | openpgp/src/serialize/mod.rs | 6 | ||||
-rw-r--r-- | openpgp/src/skesk.rs | 36 |
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)), + } } } } |