diff options
author | Neal H. Walfield <neal@sequoia-pgp.org> | 2024-01-23 09:10:22 +0100 |
---|---|---|
committer | Neal H. Walfield <neal@sequoia-pgp.org> | 2024-01-23 11:14:04 +0100 |
commit | 51e75567206d9645a36b2d1df5fac1dee1279129 (patch) | |
tree | cf0fad6452e9abafe5e1eb3c060c207410ac22fc /openpgp | |
parent | 7c5efa151eb99429401f871792090c0c5cf9f63e (diff) |
openpgp: Add Cert::exportable.
- Add `Cert::exportable` to return whether a certificate is
exportable or not.
- A certificate should only be exported if it has at least one
exportable direct key signature, or there is at least one user ID
or user attribute with at least one exportable self-signature.
Diffstat (limited to 'openpgp')
-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 |