diff options
author | Azul <azul@riseup.net> | 2020-11-17 15:54:54 +0100 |
---|---|---|
committer | Azul <azul@riseup.net> | 2020-11-24 12:25:37 +0100 |
commit | b21f22daa452f98845ab9c0ad0cf4b36bbe31251 (patch) | |
tree | 60a7418f0ef09e40d268185f1271635db8286fca | |
parent | 43ad20c16ccee274cc4ecdb327e70e2349fa12ad (diff) |
openpgp: seal traits in cert::amalgamation
- Seal `ValidAmalgamation`, `ValidateAmalgamation` and
`key::PrimaryKey`
- Sealing traits so they cannot be implemented outside the openpgp crate.
This way we can extend the traits without breaking the API compatibility.
Every implementation of a sealed trait needs to also
implement the `seal::Sealed` marker trait.
- Implementing `seal::Sealed` for `ValidKeyAmalgamation<'a, P, R, R2>`
also implements it for
- `ValidPrimaryKeyAmalgamation<'a, P>`
- `ValidSubordinateKeyAmalgamation<'a, P>`
- `ValidErasedKeyAmalgamation<'a, P>`
Therefore these can implement `ValidateAmalgamation`
and `key::PrimaryKey`
without explicitly implementing `seal::Sealed`
- See #538.
-rw-r--r-- | openpgp/src/cert.rs | 8 | ||||
-rw-r--r-- | openpgp/src/cert/amalgamation.rs | 28 | ||||
-rw-r--r-- | openpgp/src/cert/amalgamation/key.rs | 30 |
3 files changed, 57 insertions, 9 deletions
diff --git a/openpgp/src/cert.rs b/openpgp/src/cert.rs index 1b32d87f..f6232bc6 100644 --- a/openpgp/src/cert.rs +++ b/openpgp/src/cert.rs @@ -162,6 +162,7 @@ use crate::{ packet::Unknown, Packet, PacketPile, + seal, KeyID, Fingerprint, KeyHandle, @@ -445,7 +446,7 @@ type UnknownBundles = ComponentBundles<Unknown>; /// you also need to implement the `seal::Sealed` marker trait. /// /// [sealed]: https://rust-lang.github.io/api-guidelines/future-proofing.html#sealed-traits-protect-against-downstream-implementations-c-sealed -pub trait Preferences<'a>: crate::seal::Sealed { +pub trait Preferences<'a>: seal::Sealed { /// Returns the supported symmetric algorithms ordered by /// preference. /// @@ -2798,8 +2799,6 @@ pub struct ValidCert<'a> { time: time::SystemTime, } -impl<'a> crate::seal::Sealed for ValidCert<'a> {} - impl<'a> std::ops::Deref for ValidCert<'a> { type Target = Cert; @@ -3393,7 +3392,8 @@ macro_rules! impl_pref { } } -impl<'a> crate::cert::Preferences<'a> for ValidCert<'a> +impl<'a> seal::Sealed for ValidCert<'a> {} +impl<'a> Preferences<'a> for ValidCert<'a> { impl_pref!(preferred_symmetric_algorithms, &'a [SymmetricAlgorithm]); impl_pref!(preferred_hash_algorithms, &'a [HashAlgorithm]); diff --git a/openpgp/src/cert/amalgamation.rs b/openpgp/src/cert/amalgamation.rs index 6ef268c8..bfd634ef 100644 --- a/openpgp/src/cert/amalgamation.rs +++ b/openpgp/src/cert/amalgamation.rs @@ -234,6 +234,7 @@ use crate::{ }, Result, policy::Policy, + seal, types::{ AEADAlgorithm, CompressionAlgorithm, @@ -273,6 +274,15 @@ pub mod key; /// /// - The certificate is valid. /// +/// # Sealed trait +/// +/// This trait is [sealed] and cannot be implemented for types outside this crate. +/// Therefore it can be extended in a non-breaking way. +/// If you want to implement the trait inside the crate +/// you also need to implement the `seal::Sealed` marker trait. +/// +/// [sealed]: https://rust-lang.github.io/api-guidelines/future-proofing.html#sealed-traits-protect-against-downstream-implementations-c-sealed +/// /// # Examples /// /// ``` @@ -301,7 +311,7 @@ pub mod key; /// [`ValidComponentAmalgamation`]: struct.ValidComponentAmalgamation.html /// [`KeyAmalgamation`]: struct.KeyAmalgamation.html /// [`ValidKeyAmalgamation`]: struct.ValidKeyAmalgamation.html -pub trait ValidateAmalgamation<'a, C: 'a> { +pub trait ValidateAmalgamation<'a, C: 'a>: seal::Sealed { /// The type returned by `with_policy`. /// /// This is either a [`ValidComponentAmalgamation`] or @@ -366,7 +376,17 @@ trait ValidateAmalgamationRelaxed<'a, C: 'a> { /// This helps prevent using different policies or different reference /// times when using a component, which can easily happen when the /// checks span multiple functions. -pub trait ValidAmalgamation<'a, C: 'a> +/// +/// # Sealed trait +/// +/// This trait is [sealed] and cannot be implemented for types outside this crate. +/// Therefore it can be extended in a non-breaking way. +/// If you want to implement the trait inside the crate +/// you also need to implement the `seal::Sealed` marker trait. +/// +/// [sealed]: https://rust-lang.github.io/api-guidelines/future-proofing.html#sealed-traits-protect-against-downstream-implementations-c-sealed +/// +pub trait ValidAmalgamation<'a, C: 'a>: seal::Sealed { /// Maps the given function over binding and direct key signature. /// @@ -924,6 +944,7 @@ macro_rules! impl_with_policy { } } +impl<'a, C> seal::Sealed for ComponentAmalgamation<'a, C> {} impl<'a, C> ValidateAmalgamation<'a, C> for ComponentAmalgamation<'a, C> { type V = ValidComponentAmalgamation<'a, C>; @@ -1057,8 +1078,6 @@ pub struct ValidComponentAmalgamation<'a, C> { binding_signature: &'a Signature, } -impl<'a, C> crate::seal::Sealed for ValidComponentAmalgamation<'a, C> {} - /// A Valid User ID and its associated data. /// /// A specialized version of [`ValidComponentAmalgamation`]. @@ -1221,6 +1240,7 @@ impl<'a, C> ValidComponentAmalgamation<'a, C> } } +impl<'a, C> seal::Sealed for ValidComponentAmalgamation<'a, C> {} impl<'a, C> ValidateAmalgamation<'a, C> for ValidComponentAmalgamation<'a, C> { type V = Self; diff --git a/openpgp/src/cert/amalgamation/key.rs b/openpgp/src/cert/amalgamation/key.rs index 02106f2d..192ba5bf 100644 --- a/openpgp/src/cert/amalgamation/key.rs +++ b/openpgp/src/cert/amalgamation/key.rs @@ -273,6 +273,7 @@ use crate::{ packet::signature::subpacket::SubpacketTag, policy::Policy, Result, + seal, types::{ KeyFlags, RevocationStatus, @@ -295,7 +296,16 @@ pub use iter::{ /// /// [`ValidAmalgamation`]: ../trait.ValidAmalgamation.html /// [`ValidKeyAmalgamation`]: struct.ValidKeyAmalgamation.html -pub trait PrimaryKey<'a, P, R> +/// +/// # Sealed trait +/// +/// This trait is [sealed] and cannot be implemented for types outside this crate. +/// Therefore it can be extended in a non-breaking way. +/// If you want to implement the trait inside the crate +/// you also need to implement the `seal::Sealed` marker trait. +/// +/// [sealed]: https://rust-lang.github.io/api-guidelines/future-proofing.html#sealed-traits-protect-against-downstream-implementations-c-sealed +pub trait PrimaryKey<'a, P, R>: seal::Sealed where P: 'a + key::KeyParts, R: 'a + key::KeyRole, { @@ -504,6 +514,10 @@ impl<'a, P, R, R2> Deref for KeyAmalgamation<'a, P, R, R2> } +impl<'a, P> seal::Sealed + for PrimaryKeyAmalgamation<'a, P> + where P: 'a + key::KeyParts +{} impl<'a, P> ValidateAmalgamation<'a, Key<P, key::PrimaryRole>> for PrimaryKeyAmalgamation<'a, P> where P: 'a + key::KeyParts @@ -520,6 +534,10 @@ impl<'a, P> ValidateAmalgamation<'a, Key<P, key::PrimaryRole>> } } +impl<'a, P> seal::Sealed + for SubordinateKeyAmalgamation<'a, P> + where P: 'a + key::KeyParts +{} impl<'a, P> ValidateAmalgamation<'a, Key<P, key::SubordinateRole>> for SubordinateKeyAmalgamation<'a, P> where P: 'a + key::KeyParts @@ -536,6 +554,10 @@ impl<'a, P> ValidateAmalgamation<'a, Key<P, key::SubordinateRole>> } } +impl<'a, P> seal::Sealed + for ErasedKeyAmalgamation<'a, P> + where P: 'a + key::KeyParts +{} impl<'a, P> ValidateAmalgamation<'a, Key<P, key::UnspecifiedRole>> for ErasedKeyAmalgamation<'a, P> where P: 'a + key::KeyParts @@ -1166,6 +1188,12 @@ impl<'a, P> ValidateAmalgamation<'a, Key<P, key::UnspecifiedRole>> } } +impl<'a, P, R, R2> seal::Sealed for ValidKeyAmalgamation<'a, P, R, R2> + where P: 'a + key::KeyParts, + R: 'a + key::KeyRole, + R2: Copy, + Self: PrimaryKey<'a, P, R>, +{} impl<'a, P, R, R2> ValidAmalgamation<'a, Key<P, R>> for ValidKeyAmalgamation<'a, P, R, R2> |