diff options
-rw-r--r-- | openpgp/NEWS | 1 | ||||
-rw-r--r-- | openpgp/src/serialize/cert.rs | 59 |
2 files changed, 60 insertions, 0 deletions
diff --git a/openpgp/NEWS b/openpgp/NEWS index 1ce386c5..9b8204f4 100644 --- a/openpgp/NEWS +++ b/openpgp/NEWS @@ -14,6 +14,7 @@ - KeyAmalgamation::valid_third_party_revocations_by_key - Parse::from_buffered_reader - armor::Reader::from_buffered_reader + - Cert::exportable - CertBuilder::set_exportable * Changes in 1.17.0 ** Notable fixes diff --git a/openpgp/src/serialize/cert.rs b/openpgp/src/serialize/cert.rs index 764a16ac..3278ea2b 100644 --- a/openpgp/src/serialize/cert.rs +++ b/openpgp/src/serialize/cert.rs @@ -11,6 +11,65 @@ use crate::serialize::{ impl Cert { + /// Returns whether the certificate should be exported. + /// + /// A certificate should only be exported if it has at least one + /// exportable direct key signature, or there is at least one user + /// ID with at least one exportable self signature. + /// + /// # Examples + /// + /// ``` + /// use sequoia_openpgp as openpgp; + /// use openpgp::cert::prelude::*; + /// + /// # fn main() -> openpgp::Result<()> { + /// // By default, certificates are exportable. + /// let (cert, _) = + /// CertBuilder::general_purpose(None, Some("alice@example.org")) + /// .generate()?; + /// assert!(cert.exportable()); + /// + /// // Setting the exportable flag to false makes them + /// // not-exportable. + /// let (cert, _) = + /// CertBuilder::general_purpose(None, Some("alice@example.org")) + /// .set_exportable(false) + /// .generate()?; + /// assert!(! cert.exportable()); + /// # Ok(()) + /// # } + /// ``` + #[allow(clippy::if_same_then_else)] + pub fn exportable(&self) -> bool { + let pk = self.primary_key(); + + if pk.self_signatures().chain(pk.self_revocations()) + .any(|sig| sig.exportable().is_ok()) + { + // Exportable direct key signature. Export it. + true + } else if self.userids().any(|userid| { + userid.self_signatures() + .chain(userid.self_revocations()) + .any(|sig| sig.exportable().is_ok()) + }) { + // User ID with exportable self signature. Export it. + true + } else if self.user_attributes().any(|ua| { + ua.self_signatures() + .chain(ua.self_revocations()) + .any(|sig| sig.exportable().is_ok()) + }) { + // User attribute with exportable self signature. Export + // it. + true + } else { + // Don't export it. + false + } + } + /// Serializes or exports the Cert. /// /// If `export` is true, then non-exportable signatures are not |