diff options
author | Justus Winter <justus@sequoia-pgp.org> | 2020-02-21 15:02:42 +0100 |
---|---|---|
committer | Justus Winter <justus@sequoia-pgp.org> | 2020-02-21 15:02:42 +0100 |
commit | 7df48a11d4fe7fda5b47369793f794549b78eea3 (patch) | |
tree | 1195686357473cb8db8da90be60770e1b26b864a | |
parent | a02817dc6de10516365a379161bac13826979a26 (diff) |
openpgp: Extend policy to check AEAD algorithms.
-rw-r--r-- | openpgp/src/parse/stream.rs | 3 | ||||
-rw-r--r-- | openpgp/src/policy.rs | 59 |
2 files changed, 62 insertions, 0 deletions
diff --git a/openpgp/src/parse/stream.rs b/openpgp/src/parse/stream.rs index 2d44d9bb..4e8c652e 100644 --- a/openpgp/src/parse/stream.rs +++ b/openpgp/src/parse/stream.rs @@ -1328,6 +1328,9 @@ impl<'a, H: VerificationHelper + DecryptionHelper> Decryptor<'a, H> { let sym_algo = sym_algo.expect("if we got here, sym_algo is set"); v.policy.symmetric_algorithm(sym_algo)?; + if let Packet::AED(ref p) = pp.packet { + v.policy.aead_algorithm(p.aead())?; + } v.structure.new_encryption_layer( sym_algo, diff --git a/openpgp/src/policy.rs b/openpgp/src/policy.rs index 88df7811..25b83f5a 100644 --- a/openpgp/src/policy.rs +++ b/openpgp/src/policy.rs @@ -41,6 +41,7 @@ use crate::{ }, Result, types::{ + AEADAlgorithm, HashAlgorithm, SignatureType, SymmetricAlgorithm, @@ -108,6 +109,17 @@ pub trait Policy : fmt::Debug { Ok(()) } + /// Returns an error if the AEAD mode violates the policy. + /// + /// This function performs the last check before an encryption + /// container is decrypted by the streaming decryptor. + /// + /// With this function, you can prevent the use of insecure AEAD + /// constructions. + fn aead_algorithm(&self, _algo: AEADAlgorithm) -> Result<()> { + Ok(()) + } + /// Returns an error if the packet violates the policy. /// /// This function performs the last check before a packet is @@ -156,6 +168,9 @@ pub struct StandardPolicy { // Symmetric algorithms. symmetric_algos: SymmetricAlgorithmCutoffList, + // AEAD algorithms. + aead_algos: AEADAlgorithmCutoffList, + // Asymmetric algorithms. asymmetric_algos: AsymmetricAlgorithmCutoffList, } @@ -243,6 +258,13 @@ a_cutoff_list!(SymmetricAlgorithmCutoffList, SymmetricAlgorithm, 14, ACCEPT, // 13. Camellia256. ]); +a_cutoff_list!(AEADAlgorithmCutoffList, AEADAlgorithm, 3, + [ + REJECT, // 0. Reserved. + ACCEPT, // 1. EAX. + ACCEPT, // 2. OCB. + ]); + a_cutoff_list!(PacketTagCutoffList, Tag, 21, [ REJECT, // 0. Reserved. @@ -302,6 +324,7 @@ impl StandardPolicy { hash_algos_revocation: RevocationHashCutoffList::Default(), asymmetric_algos: AsymmetricAlgorithmCutoffList::Default(), symmetric_algos: SymmetricAlgorithmCutoffList::Default(), + aead_algos: AEADAlgorithmCutoffList::Default(), packet_tags: PacketTagCutoffList::Default(), } } @@ -512,6 +535,37 @@ impl StandardPolicy { self.symmetric_algos.cutoff(s).map(|t| t.into()) } + /// Always considers `s` to be secure. + pub fn accept_aead_algo(&mut self, a: AEADAlgorithm) { + self.aead_algos.set(a, ACCEPT); + } + + /// Always considers `s` to be insecure. + pub fn reject_aead_algo(&mut self, a: AEADAlgorithm) { + self.aead_algos.set(a, REJECT); + } + + /// Considers `a` to be insecure starting at `cutoff`. + /// + /// A cutoff of `None` means that there is no cutoff and the + /// algorithm has no known vulnerabilities. + /// + /// By default, we accept all AEAD modes. + pub fn reject_aead_algo_at<C>(&mut self, a: AEADAlgorithm, + cutoff: C) + where C: Into<Option<SystemTime>>, + { + self.aead_algos.set( + a, + cutoff.into().and_then(system_time_cutoff_to_timestamp)); + } + + /// Returns the cutoff times for the specified hash algorithm. + pub fn aead_algo_cutoff(&self, a: AEADAlgorithm) + -> Option<SystemTime> { + self.aead_algos.cutoff(a).map(|t| t.into()) + } + /// Always accept packets with the given tag. pub fn accept_packet_tag(&mut self, tag: Tag) { self.packet_tags.set(tag, ACCEPT); @@ -664,6 +718,11 @@ impl Policy for StandardPolicy { let time = self.time.unwrap_or_else(Timestamp::now); self.symmetric_algos.check(algo, time) } + + fn aead_algorithm(&self, algo: AEADAlgorithm) -> Result<()> { + let time = self.time.unwrap_or_else(Timestamp::now); + self.aead_algos.check(algo, time) + } } /// Asymmetric encryption algorithms. |