summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAzul <azul@riseup.net>2020-11-17 15:54:54 +0100
committerAzul <azul@riseup.net>2020-11-24 12:25:37 +0100
commitb21f22daa452f98845ab9c0ad0cf4b36bbe31251 (patch)
tree60a7418f0ef09e40d268185f1271635db8286fca
parent43ad20c16ccee274cc4ecdb327e70e2349fa12ad (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.rs8
-rw-r--r--openpgp/src/cert/amalgamation.rs28
-rw-r--r--openpgp/src/cert/amalgamation/key.rs30
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>