[−][src]Struct sequoia_openpgp::cert::Cert
A collection of components and their associated signatures.
The Cert
data structure mirrors the TPK and TSK data
structures defined in RFC 4880. Specifically, it contains
components (Key
s, UserID
s, and UserAttribute
s), their
associated self signatures, self revocations, third-party
signatures, and third-party revocations, use useful methods.
Cert
s are canonicalized in the sense that their Component
s are
deduplicated, and their signatures and revocations are
deduplicated and checked for validity. The canonicalization
routine does not throw away components that have no self
signatures. These are returned as usual by, e.g.,
Cert::userids
.
Keys are deduplicated by comparing their public bits using
Key::public_cmp
. If two keys are considered equal, and only
one of them has secret key material, the key with the secret key
material is preferred. If both keys have secret material, then
one of them is chosen in a deterministic, but undefined manner,
which is subject to change. Note: the secret key material
is not integrity checked. Hence when updating a certificate with
secret key material, it is essential to first strip the secret key
material from copies that came from an untrusted source.
Signatures are deduplicated using their Eq
implementation,
which compares the data that is hashed and the MPIs. That is, it
does not compare the unhashed data, the digest prefix and the
unhashed subpacket area. If two signatures are considered equal,
but have different unhashed data, the unhashed data are merged in
a deterministic, but undefined manner, which is subject to change.
This policy prevents an attacker from flooding a certificate with
valid signatures that only differ in their unhashed data.
Self signatures and self revocations are checked for validity by
making sure that the signature is mathematically correct. At
this point, the signature is not checked against a Policy
.
Third-party signatures and revocations are checked for validity by
making sure the computed digest matches the digest prefix stored
in the signature packet. This is not an integrity check and is
easily spoofed. Unfortunately, at the time of canonicalization,
the actual signatures cannot be checked, because the public keys
are not available. If you rely on these signatures, it is up to
you to check their validity by using an appropriate signature
verification method, e.g., Signature::verify_userid_binding
or Signature::verify_userid_revocation
.
If a signature or a revocation is not valid,
we check to see whether it is simply out of place (i.e., belongs
to a different component) and, if so, we reorder it. If not, it
is added to a list of bad signatures. These can be retrieved
using Cert::bad_signatures
.
Signatures and revocations are sorted so that the newest signature comes first. Components are sorted, but in an undefined manner (i.e., when parsing the same certificate multiple times, the components will be in the same order, but we reserve the right to change the sort function between versions).
Secret Keys
Any key in a certificate may include secret key material. To
protect secret key material from being leaked, secret keys are not
written out when a Cert
is serialized. To also serialize secret
key material, you need to serialize the object returned by
Cert::as_tsk()
.
Secret key material may be protected with a password. In such
cases, it needs to be decrypted before it can be used to decrypt
data or generate a signature. Refer to Key::decrypt_secret
for details.
Filtering Certificates
Component-wise filtering of userids, user attributes, and subkeys
can be done with Cert::retain_userids
,
Cert::retain_user_attributes
, and Cert::retain_subkeys
.
If you need even more control, iterate over all components, clone what you want to keep, and then reassemble the certificate. The following example simply copies all the packets, and can be adapted to suit your policy:
use std::convert::TryFrom; use openpgp::cert::prelude::*; fn identity_filter(cert: &Cert) -> Result<Cert> { // Iterate over all of the Cert components, pushing packets we // want to keep into the accumulator. let mut acc = Vec::new(); // Primary key and related signatures. let c = cert.primary_key(); acc.push(c.key().clone().into()); for s in c.self_signatures() { acc.push(s.clone().into()) } for s in c.certifications() { acc.push(s.clone().into()) } for s in c.self_revocations() { acc.push(s.clone().into()) } for s in c.other_revocations() { acc.push(s.clone().into()) } // UserIDs and related signatures. for c in cert.userids() { acc.push(c.userid().clone().into()); for s in c.self_signatures() { acc.push(s.clone().into()) } for s in c.certifications() { acc.push(s.clone().into()) } for s in c.self_revocations() { acc.push(s.clone().into()) } for s in c.other_revocations() { acc.push(s.clone().into()) } } // UserAttributes and related signatures. for c in cert.user_attributes() { acc.push(c.user_attribute().clone().into()); for s in c.self_signatures() { acc.push(s.clone().into()) } for s in c.certifications() { acc.push(s.clone().into()) } for s in c.self_revocations() { acc.push(s.clone().into()) } for s in c.other_revocations() { acc.push(s.clone().into()) } } // Subkeys and related signatures. for c in cert.keys().subkeys() { acc.push(c.key().clone().into()); for s in c.self_signatures() { acc.push(s.clone().into()) } for s in c.certifications() { acc.push(s.clone().into()) } for s in c.self_revocations() { acc.push(s.clone().into()) } for s in c.other_revocations() { acc.push(s.clone().into()) } } // Unknown components and related signatures. for c in cert.unknowns() { acc.push(c.unknown().clone().into()); for s in c.self_signatures() { acc.push(s.clone().into()) } for s in c.certifications() { acc.push(s.clone().into()) } for s in c.self_revocations() { acc.push(s.clone().into()) } for s in c.other_revocations() { acc.push(s.clone().into()) } } // Any signatures that we could not associate with a component. for s in cert.bad_signatures() { acc.push(s.clone().into()) } // Finally, parse into Cert. Cert::try_from(acc) } let (cert, _) = CertBuilder::general_purpose(None, Some("alice@example.org")) .generate()?; assert_eq!(cert, identity_filter(&cert)?);
Examples
Parse a certificate:
use std::convert::TryFrom; use sequoia_openpgp as openpgp; use openpgp::Cert; match Cert::try_from(ppr) { Ok(cert) => { println!("Key: {}", cert.fingerprint()); for uid in cert.userids() { println!("User ID: {}", uid.userid()); } } Err(err) => { eprintln!("Error parsing Cert: {}", err); } }
Implementations
impl Cert
[src]
pub fn primary_key(&self) -> PrimaryKeyAmalgamation<'_, PublicParts>
[src]
Returns the primary key.
Unlike getting the certificate's primary key using the
Cert::keys
method, this method does not erase the key's
role.
A key's secret key material may be protected with a password.
In such cases, it needs to be decrypted before it can be used
to decrypt data or generate a signature. Refer to
Key::decrypt_secret
for details.
Examples
The first key returned by Cert::keys
is the primary key,
but its role has been erased:
assert_eq!(cert.primary_key().key().role_as_unspecified(), cert.keys().nth(0).unwrap().key());
pub fn revocation_status<T>(
&self,
policy: &dyn Policy,
t: T
) -> RevocationStatus<'_> where
T: Into<Option<SystemTime>>,
[src]
&self,
policy: &dyn Policy,
t: T
) -> RevocationStatus<'_> where
T: Into<Option<SystemTime>>,
Returns the certificate's revocation status.
Normally, methods that take a policy and a reference time are
only provided by ValidCert
. This method is provided here
because there are two revocation criteria, and one of them is
independent of the reference time. That is, even if it is not
possible to turn a Cert
into a ValidCert
at time t
, it
may still be considered revoked at time t
.
A certificate is considered revoked at time t
if:
-
There is a valid and live revocation at time
t
that is newer than all valid and live self signatures at timet
, or -
There is a valid hard revocation (even if it is not live at time
t
, and even if there is a newer self signature).
Note: certificates and subkeys have different revocation criteria from User IDs and User Attributes.
Examples
use sequoia_openpgp as openpgp; use openpgp::cert::prelude::*; use openpgp::types::RevocationStatus; use openpgp::policy::StandardPolicy; let p = &StandardPolicy::new(); let (cert, rev) = CertBuilder::general_purpose(None, Some("alice@example.org")) .generate()?; assert_eq!(cert.revocation_status(p, None), RevocationStatus::NotAsFarAsWeKnow); // Merge the revocation certificate. `cert` is now considered // to be revoked. let cert = cert.insert_packets(rev.clone())?; assert_eq!(cert.revocation_status(p, None), RevocationStatus::Revoked(vec![&rev.into()]));
pub fn revoke(
&self,
primary_signer: &mut dyn Signer,
code: ReasonForRevocation,
reason: &[u8]
) -> Result<Signature>
[src]
&self,
primary_signer: &mut dyn Signer,
code: ReasonForRevocation,
reason: &[u8]
) -> Result<Signature>
Revokes the certificate in place.
This is a convenience function around
CertRevocationBuilder
to generate a revocation
certificate.
If you want to revoke an individual component, use
SubkeyRevocationBuilder
, UserIDRevocationBuilder
, or
UserAttributeRevocationBuilder
, as appropriate.
Examples
use sequoia_openpgp as openpgp; use openpgp::types::{ReasonForRevocation, RevocationStatus, SignatureType}; use openpgp::cert::prelude::*; use openpgp::crypto::KeyPair; use openpgp::parse::Parse; use openpgp::policy::StandardPolicy; let p = &StandardPolicy::new(); let (cert, rev) = CertBuilder::new() .set_cipher_suite(CipherSuite::Cv25519) .generate()?; // A new certificate is not revoked. assert_eq!(cert.revocation_status(p, None), RevocationStatus::NotAsFarAsWeKnow); // The default revocation certificate is a generic // revocation. assert_eq!(rev.reason_for_revocation().unwrap().0, ReasonForRevocation::Unspecified); // Create a revocation to explain what *really* happened. let mut keypair = cert.primary_key() .key().clone().parts_into_secret()?.into_keypair()?; let rev = cert.revoke(&mut keypair, ReasonForRevocation::KeyCompromised, b"It was the maid :/")?; let cert = cert.insert_packets(rev)?; if let RevocationStatus::Revoked(revs) = cert.revocation_status(p, None) { assert_eq!(revs.len(), 1); let rev = revs[0]; assert_eq!(rev.typ(), SignatureType::KeyRevocation); assert_eq!(rev.reason_for_revocation(), Some((ReasonForRevocation::KeyCompromised, "It was the maid :/".as_bytes()))); } else { unreachable!() }
pub fn set_expiration_time<T>(
&self,
policy: &dyn Policy,
t: T,
primary_signer: &mut dyn Signer,
expiration: Option<SystemTime>
) -> Result<Vec<Signature>> where
T: Into<Option<SystemTime>>,
[src]
&self,
policy: &dyn Policy,
t: T,
primary_signer: &mut dyn Signer,
expiration: Option<SystemTime>
) -> Result<Vec<Signature>> where
T: Into<Option<SystemTime>>,
Sets the certificate to expire at the specified time.
If no time (None
) is specified, then the certificate is set
to not expire.
This function creates new binding signatures that cause the certificate to expire at the specified time. Specifically, it updates the current binding signature on each of the valid, non-revoked User IDs, and the direct key signature, if any. This is necessary, because the primary User ID is first consulted when determining the certificate's expiration time, and certificates can be distributed with a possibly empty subset of User IDs.
A policy is needed, because the expiration is updated by updating the current binding signatures.
Examples
use std::time; use sequoia_openpgp as openpgp; use openpgp::cert::prelude::*; use openpgp::crypto::KeyPair; use openpgp::policy::StandardPolicy; let p = &StandardPolicy::new(); // The certificate is alive (not expired). assert!(cert.with_policy(p, None)?.alive().is_ok()); // Make cert expire now. let mut keypair = cert.primary_key() .key().clone().parts_into_secret()?.into_keypair()?; let sigs = cert.set_expiration_time(p, None, &mut keypair, Some(time::SystemTime::now()))?; let cert = cert.insert_packets(sigs)?; assert!(cert.with_policy(p, None)?.alive().is_err());
pub fn userids(&self) -> UserIDAmalgamationIter<'_>
[src]
Returns an iterator over the certificate's User IDs.
This returns all User IDs, even those without a binding signature.
Examples
println!("{}'s User IDs:", cert.fingerprint()); for ua in cert.userids() { println!(" {}", String::from_utf8_lossy(ua.value())); }
pub fn user_attributes(&self) -> UserAttributeAmalgamationIter<'_>
[src]
Returns an iterator over the certificate's User Attributes.
This returns all User Attributes, even those without a binding signature.
Examples
println!("{}'s has {} User Attributes.", cert.fingerprint(), cert.user_attributes().count());
pub fn keys(&self) -> KeyAmalgamationIter<'_, PublicParts, UnspecifiedRole>ⓘNotable traits for KeyAmalgamationIter<'a, PublicParts, PrimaryRole>
impl<'a> Iterator for KeyAmalgamationIter<'a, PublicParts, PrimaryRole> type Item = PrimaryKeyAmalgamation<'a, PublicParts>;impl<'a> Iterator for KeyAmalgamationIter<'a, SecretParts, PrimaryRole> type Item = PrimaryKeyAmalgamation<'a, SecretParts>;impl<'a> Iterator for KeyAmalgamationIter<'a, UnspecifiedParts, PrimaryRole> type Item = PrimaryKeyAmalgamation<'a, UnspecifiedParts>;impl<'a> Iterator for KeyAmalgamationIter<'a, PublicParts, SubordinateRole> type Item = SubordinateKeyAmalgamation<'a, PublicParts>;impl<'a> Iterator for KeyAmalgamationIter<'a, SecretParts, SubordinateRole> type Item = SubordinateKeyAmalgamation<'a, SecretParts>;impl<'a> Iterator for KeyAmalgamationIter<'a, UnspecifiedParts, SubordinateRole> type Item = SubordinateKeyAmalgamation<'a, UnspecifiedParts>;impl<'a> Iterator for KeyAmalgamationIter<'a, PublicParts, UnspecifiedRole> type Item = ErasedKeyAmalgamation<'a, PublicParts>;impl<'a> Iterator for KeyAmalgamationIter<'a, SecretParts, UnspecifiedRole> type Item = ErasedKeyAmalgamation<'a, SecretParts>;impl<'a> Iterator for KeyAmalgamationIter<'a, UnspecifiedParts, UnspecifiedRole> type Item = ErasedKeyAmalgamation<'a, UnspecifiedParts>;
[src]
Notable traits for KeyAmalgamationIter<'a, PublicParts, PrimaryRole>
impl<'a> Iterator for KeyAmalgamationIter<'a, PublicParts, PrimaryRole> type Item = PrimaryKeyAmalgamation<'a, PublicParts>;impl<'a> Iterator for KeyAmalgamationIter<'a, SecretParts, PrimaryRole> type Item = PrimaryKeyAmalgamation<'a, SecretParts>;impl<'a> Iterator for KeyAmalgamationIter<'a, UnspecifiedParts, PrimaryRole> type Item = PrimaryKeyAmalgamation<'a, UnspecifiedParts>;impl<'a> Iterator for KeyAmalgamationIter<'a, PublicParts, SubordinateRole> type Item = SubordinateKeyAmalgamation<'a, PublicParts>;impl<'a> Iterator for KeyAmalgamationIter<'a, SecretParts, SubordinateRole> type Item = SubordinateKeyAmalgamation<'a, SecretParts>;impl<'a> Iterator for KeyAmalgamationIter<'a, UnspecifiedParts, SubordinateRole> type Item = SubordinateKeyAmalgamation<'a, UnspecifiedParts>;impl<'a> Iterator for KeyAmalgamationIter<'a, PublicParts, UnspecifiedRole> type Item = ErasedKeyAmalgamation<'a, PublicParts>;impl<'a> Iterator for KeyAmalgamationIter<'a, SecretParts, UnspecifiedRole> type Item = ErasedKeyAmalgamation<'a, SecretParts>;impl<'a> Iterator for KeyAmalgamationIter<'a, UnspecifiedParts, UnspecifiedRole> type Item = ErasedKeyAmalgamation<'a, UnspecifiedParts>;
Returns an iterator over the certificate's keys.
That is, this returns an iterator over the primary key and any subkeys. It returns all keys, even those without a binding signature.
By necessity, this function erases the returned keys' roles.
If you are only interested in the primary key, use
Cert::primary_key
. If you are only interested in the
subkeys, use KeyAmalgamationIter::subkeys
. These
functions preserve the keys' role in the type system.
A key's secret secret key material may be protected with a
password. In such cases, it needs to be decrypted before it
can be used to decrypt data or generate a signature. Refer to
Key::decrypt_secret
for details.
Examples
println!("{}'s has {} keys.", cert.fingerprint(), cert.keys().count());
pub fn unknowns(&self) -> UnknownComponentAmalgamationIter<'_>
[src]
Returns an iterator over the certificate's unknown components.
This function returns all unknown components even those without a binding signature.
Examples
println!("{}'s has {} unknown components.", cert.fingerprint(), cert.unknowns().count()); for ua in cert.unknowns() { println!(" Unknown component with tag {} ({}), error: {}", ua.tag(), u8::from(ua.tag()), ua.error()); }
pub fn bad_signatures(&self) -> impl Iterator<Item = &Signature> + Send + Sync
[src]
Returns a slice containing the bad signatures.
Bad signatures are signatures and revocations that we could not associate with one of the certificate's components.
For self signatures and self revocations, we check that the signature is correct. For third-party signatures and third-party revocations, we only check that the digest prefix is correct, because third-party keys are not available. Checking the digest prefix is not an integrity check; third party-signatures and third-party revocations may be invalid and must still be checked for validity before use.
Examples
println!("{}'s has {} bad signatures.", cert.fingerprint(), cert.bad_signatures().count());
pub fn revocation_keys<'a>(
&'a self,
policy: &dyn Policy
) -> Box<dyn Iterator<Item = &'a RevocationKey> + 'a>
[src]
&'a self,
policy: &dyn Policy
) -> Box<dyn Iterator<Item = &'a RevocationKey> + 'a>
Returns a list of any designated revokers for this certificate.
This function returns the designated revokers listed on the primary key's binding signatures and the certificate's direct key signatures.
Note: the returned list is deduplicated.
Examples
use sequoia_openpgp as openpgp; use openpgp::cert::prelude::*; use openpgp::policy::StandardPolicy; use openpgp::types::RevocationKey; let p = &StandardPolicy::new(); let (alice, _) = CertBuilder::general_purpose(None, Some("alice@example.org")) .generate()?; // Make Alice a designated revoker for Bob. let (bob, _) = CertBuilder::general_purpose(None, Some("bob@example.org")) .set_revocation_keys(vec![(&alice).into()]) .generate()?; // Make sure Alice is listed as a designated revoker for Bob. assert_eq!(bob.revocation_keys(p).collect::<Vec<&RevocationKey>>(), vec![&(&alice).into()]);
pub fn into_packets(self) -> impl Iterator<Item = Packet> + Send + Sync
[src]
Converts the certificate into an iterator over a sequence of packets.
WARNING: When serializing a Cert
, any secret key
material is dropped. In order to serialize the secret key
material, it is first necessary to convert the Cert
into a
TSK
and serialize that. This behavior makes it harder to
accidentally leak secret key material. This function is
different. If a key contains secret key material, it is
exported as a SecretKey
or SecretSubkey
, as
appropriate. This means that if you serialize the resulting
packets, the secret key material will be serialized too.
Examples
println!("Cert contains {} packets", cert.into_packets().count());
pub fn from_packets(
p: impl Iterator<Item = Packet> + Send + Sync
) -> Result<Self>
[src]
p: impl Iterator<Item = Packet> + Send + Sync
) -> Result<Self>
Returns the first certificate found in the sequence of packets.
If the sequence of packets does not start with a certificate (specifically, if it does not start with a primary key packet), then this fails.
If the sequence contains multiple certificates (i.e., it is a
keyring), or the certificate is followed by an invalid packet
this function will fail. To parse keyrings, use
CertParser
instead of this function.
Examples
use sequoia_openpgp as openpgp; use openpgp::cert::prelude::*; use openpgp::packet::prelude::*; use openpgp::PacketPile; let (cert, rev) = CertBuilder::general_purpose(None, Some("alice@example.org")) .generate()?; // We should be able to turn a certificate into a PacketPile // and back. assert!(Cert::from_packets(cert.into_packets()).is_ok()); // But a revocation certificate is not a certificate, so this // will fail. let p : Vec<Packet> = vec![rev.into()]; assert!(Cert::from_packets(p.into_iter()).is_err());
pub fn into_packet_pile(self) -> PacketPile
[src]
pub fn key_handle(&self) -> KeyHandle
[src]
Returns the certificate's fingerprint as a KeyHandle
.
Examples
println!("{}", cert.key_handle()); // This always returns a fingerprint. match cert.key_handle() { KeyHandle::Fingerprint(_) => (), KeyHandle::KeyID(_) => unreachable!(), }
pub fn fingerprint(&self) -> Fingerprint
[src]
pub fn keyid(&self) -> KeyID
[src]
Returns the certificate's Key ID.
As a general rule of thumb, you should prefer the fingerprint as it is possible to create keys with a colliding Key ID using a birthday attack.
Examples
println!("{}", cert.keyid());
pub fn merge_public(self, other: Cert) -> Result<Self>
[src]
Merges other
into self
, ignoring secret key material in
other
.
If other
is a different certificate, then an error is
returned.
This routine merges duplicate packets. This is different from
Cert::insert_packets
, which prefers keys in the packets that
are being merged into the certificate.
This function is appropriate to merge certificate material
from untrusted sources like keyservers. If other
contains
secret key material, it is ignored. See
Cert::merge_public_and_secret
on how to merge certificates
containing secret key material from trusted sources.
Examples
// Merge the local version with the version from the keyserver. let cert = local.merge_public(keyserver)?;
pub fn merge_public_and_secret(self, other: Cert) -> Result<Self>
[src]
Merges other
into self
, including secret key material.
If other
is a different certificate, then an error is
returned.
This routine merges duplicate packets. This is different from
Cert::insert_packets
, which prefers keys in the packets that
are being merged into the certificate.
It is important to only merge key material from trusted sources using this function, because it may be used to import secret key material. Secret key material is not authenticated by OpenPGP, and there are plausible attack scenarios where a malicious actor injects secret key material.
Examples
// Merge the local version with the version from your other device. let cert = local.merge_public_and_secret(other_device)?;
pub fn insert_packets<I>(self, packets: I) -> Result<Self> where
I: IntoIterator,
I::Item: Into<Packet>,
[src]
I: IntoIterator,
I::Item: Into<Packet>,
Adds packets to the certificate.
This function turns the certificate into a sequence of packets, appends the packets to the end of it, and canonicalizes the result. Known packets that don't belong in a TPK or TSK cause this function to return an error. Unknown packets are retained and added to the list of unknown components. The goal is to provide some future compatibility.
If a key is merged that already exists in the certificate, it replaces the existing key. This way, secret key material can be added, removed, encrypted, or decrypted.
Similarly, if a signature is merged that already exists in the certificate, it replaces the existing signature. This way, the unhashed subpacket area can be updated.
Examples
use sequoia_openpgp as openpgp; use openpgp::cert::prelude::*; use openpgp::packet::prelude::*; use openpgp::serialize::Serialize; use openpgp::parse::Parse; use openpgp::types::DataFormat; // Create a new key. let (cert, rev) = CertBuilder::general_purpose(None, Some("alice@example.org")) .generate()?; assert!(cert.is_tsk()); // Merge in the revocation certificate. assert_eq!(cert.primary_key().self_revocations().count(), 0); let cert = cert.insert_packets(rev)?; assert_eq!(cert.primary_key().self_revocations().count(), 1); // Add an unknown packet. let tag = Tag::Private(61.into()); let unknown = Unknown::new(tag, openpgp::Error::UnsupportedPacketType(tag).into()); // It shows up as an unknown component. let cert = cert.insert_packets(unknown)?; assert_eq!(cert.unknowns().count(), 1); for p in cert.unknowns() { assert_eq!(p.tag(), tag); } // Try and merge a literal data packet. let mut lit = Literal::new(DataFormat::Text); lit.set_body(b"test".to_vec()); // Merging packets that are known to not belong to a // certificate result in an error. assert!(cert.insert_packets(lit).is_err());
Remove secret key material:
use sequoia_openpgp as openpgp; use openpgp::cert::prelude::*; use openpgp::packet::prelude::*; // Create a new key. let (cert, _) = CertBuilder::general_purpose(None, Some("alice@example.org")) .generate()?; assert!(cert.is_tsk()); // We just created the key, so all of the keys have secret key // material. let mut pk = cert.primary_key().key().clone(); // Split off the secret key material. let (pk, sk) = pk.take_secret(); assert!(sk.is_some()); assert!(! pk.has_secret()); // Merge in the public key. Recall: the packets that are // being merged into the certificate take precedence. let cert = cert.insert_packets(pk)?; // The secret key material is stripped. assert!(! cert.primary_key().has_secret());
Update a binding signature's unhashed subpacket area:
use sequoia_openpgp as openpgp; use openpgp::cert::prelude::*; use openpgp::packet::prelude::*; use openpgp::packet::signature::subpacket::*; // Create a new key. let (cert, _) = CertBuilder::general_purpose(None, Some("alice@example.org")) .generate()?; assert_eq!(cert.userids().nth(0).unwrap().self_signatures().count(), 1); // Grab the binding signature so that we can modify it. let mut sig = cert.userids().nth(0).unwrap().self_signatures().nth(0) .unwrap().clone(); // Add a notation subpacket. Note that the information is not // authenticated, therefore it may only be trusted if the // certificate with the signature is placed in a trusted store. let notation = NotationData::new("retrieved-from@example.org", "generated-locally", NotationDataFlags::empty() .set_human_readable()); sig.unhashed_area_mut().add( Subpacket::new(SubpacketValue::NotationData(notation), false)?)?; // Merge in the signature. Recall: the packets that are // being merged into the certificate take precedence. let cert = cert.insert_packets(sig)?; // The old binding signature is replaced. assert_eq!(cert.userids().nth(0).unwrap().self_signatures().count(), 1); assert_eq!(cert.userids().nth(0).unwrap().self_signatures().nth(0) .unwrap() .unhashed_area() .subpackets(SubpacketTag::NotationData).count(), 1);
pub fn is_tsk(&self) -> bool
[src]
Returns whether at least one of the keys includes secret key material.
This returns true if either the primary key or at least one of the subkeys includes secret key material.
Examples
use sequoia_openpgp as openpgp; use openpgp::cert::prelude::*; use openpgp::policy::StandardPolicy; use openpgp::serialize::Serialize; use openpgp::parse::Parse; let p = &StandardPolicy::new(); // Create a new key. let (cert, _) = CertBuilder::general_purpose(None, Some("alice@example.org")) .generate()?; assert!(cert.is_tsk()); // If we serialize the certificate, the secret key material is // stripped, unless we first convert it to a TSK. let mut buffer = Vec::new(); cert.as_tsk().serialize(&mut buffer); let cert = Cert::from_bytes(&buffer)?; assert!(cert.is_tsk()); // Now round trip it without first converting it to a TSK. This // drops the secret key material. let mut buffer = Vec::new(); cert.serialize(&mut buffer); let cert = Cert::from_bytes(&buffer)?; assert!(!cert.is_tsk());
pub fn strip_secret_key_material(self) -> Cert
[src]
Strips any secret key material.
Examples
use sequoia_openpgp as openpgp; use openpgp::cert::prelude::*; // Create a new key. let (cert, _) = CertBuilder::general_purpose(None, Some("alice@example.org")) .generate()?; assert!(cert.is_tsk()); let cert = cert.strip_secret_key_material(); assert!(! cert.is_tsk());
pub fn retain_userids<P>(self, predicate: P) -> Cert where
P: FnMut(UserIDAmalgamation<'_>) -> bool,
[src]
P: FnMut(UserIDAmalgamation<'_>) -> bool,
Retains only the userids specified by the predicate.
Removes all the userids for which the given predicate returns false.
Warning
Because userid binding signatures are traditionally used to
provide additional information like the certificate holder's
algorithm preferences (see Preferences
) and primary key
flags (see ValidKeyAmalgamation::key_flags
). Removing a
userid may inadvertently change this information.
Examples
use sequoia_openpgp as openpgp; use openpgp::cert::prelude::*; // Create a new key. let (cert, _) = CertBuilder::general_purpose(None, Some("alice@example.org")) .add_userid("Alice Lovelace <alice@lovelace.name>") .generate()?; assert_eq!(cert.userids().count(), 2); let cert = cert.retain_userids(|ua| { if let Ok(Some(address)) = ua.email() { address == "alice@example.org" // Only keep this one. } else { false // Drop malformed userids. } }); assert_eq!(cert.userids().count(), 1); assert_eq!(cert.userids().nth(0).unwrap().email()?.unwrap(), "alice@example.org");
pub fn retain_user_attributes<P>(self, predicate: P) -> Cert where
P: FnMut(UserAttributeAmalgamation<'_>) -> bool,
[src]
P: FnMut(UserAttributeAmalgamation<'_>) -> bool,
Retains only the user attributes specified by the predicate.
Removes all the user attributes for which the given predicate returns false.
Examples
use sequoia_openpgp as openpgp; use openpgp::cert::prelude::*; // Create a new key. let (cert, _) = CertBuilder::general_purpose(None, Some("alice@example.org")) // Add nonsensical user attribute. .add_user_attribute(vec![0, 1, 2]) .generate()?; assert_eq!(cert.user_attributes().count(), 1); // Strip all user attributes let cert = cert.retain_user_attributes(|_| false); assert_eq!(cert.user_attributes().count(), 0);
pub fn retain_subkeys<P>(self, predicate: P) -> Cert where
P: FnMut(SubordinateKeyAmalgamation<'_, PublicParts>) -> bool,
[src]
P: FnMut(SubordinateKeyAmalgamation<'_, PublicParts>) -> bool,
Retains only the subkeys specified by the predicate.
Removes all the subkeys for which the given predicate returns false.
Examples
use sequoia_openpgp as openpgp; use openpgp::policy::StandardPolicy; use openpgp::cert::prelude::*; // Create a new key. let (cert, _) = CertBuilder::new() .add_userid("Alice Lovelace <alice@lovelace.name>") .add_transport_encryption_subkey() .add_storage_encryption_subkey() .generate()?; assert_eq!(cert.keys().subkeys().count(), 2); // Retain only the transport encryption subkey. For that, we // need to examine the key flags, therefore we need to turn // the `KeyAmalgamation` into a `ValidKeyAmalgamation` under a // policy. let p = &StandardPolicy::new(); let cert = cert.retain_subkeys(|ka| { if let Ok(vka) = ka.with_policy(p, None) { vka.key_flags().map(|flags| flags.for_transport_encryption()) .unwrap_or(false) // Keep transport encryption keys. } else { false // Drop unbound keys. } }); assert_eq!(cert.keys().subkeys().count(), 1); assert!(cert.with_policy(p, None)?.keys().subkeys().nth(0).unwrap() .key_flags().unwrap().for_transport_encryption());
pub fn with_policy<'a, T>(
&'a self,
policy: &'a dyn Policy,
time: T
) -> Result<ValidCert<'a>> where
T: Into<Option<SystemTime>>,
[src]
&'a self,
policy: &'a dyn Policy,
time: T
) -> Result<ValidCert<'a>> where
T: Into<Option<SystemTime>>,
Associates a policy and a reference time with the certificate.
This is used to turn a Cert
into a
ValidCert
. (See also ValidateAmalgamation
,
which does the same for component amalgamations.)
A certificate is considered valid if:
-
It has a self signature that is live at time
t
. -
The policy considers it acceptable.
This doesn't say anything about whether the certificate itself
is alive (see ValidCert::alive
) or revoked (see
ValidCert::revoked
).
Examples
use sequoia_openpgp as openpgp; use openpgp::policy::StandardPolicy; let p = &StandardPolicy::new(); let vc = cert.with_policy(p, None)?;
impl Cert
[src]
pub fn as_tsk<'a>(&'a self) -> TSK<'a>
[src]
Derive a TSK
object from this key.
This object writes out secret keys during serialization.
impl Cert
[src]
pub fn armor_headers(&self) -> Vec<String>
[src]
Creates descriptive armor headers.
Returns armor headers that describe this Cert. The Cert's primary fingerprint and valid userids (according to the default policy) are included as comments, so that it is easier to identify the Cert when looking at the armored data.
pub fn armored<'a>(&'a self) -> impl Serialize + SerializeInto + 'a
[src]
Wraps this Cert in an armor structure when serialized.
Derives an object from this Cert that adds an armor structure to the serialized Cert when it is serialized. Additionally, the Cert's userids are added as comments, so that it is easier to identify the Cert when looking at the armored data.
Examples
use sequoia_openpgp as openpgp; use openpgp::cert::prelude::*; use openpgp::serialize::SerializeInto; let (cert, _) = CertBuilder::general_purpose(None, Some("Mr. Pink ☮☮☮")) .generate()?; let armored = String::from_utf8(cert.armored().to_vec()?)?; assert!(armored.starts_with("-----BEGIN PGP PUBLIC KEY BLOCK-----")); assert!(armored.contains("Mr. Pink ☮☮☮"));
Trait Implementations
impl Clone for Cert
[src]
impl Debug for Cert
[src]
impl Display for Cert
[src]
impl<'_> From<&'_ Cert> for RevocationKey
[src]
impl From<Cert> for Vec<Packet>
[src]
impl From<Cert> for PacketPile
[src]
pub fn from(cert: Cert) -> PacketPile
[src]
Converts the Cert
into a PacketPile
.
If any packets include secret key material, that secret key
material is not dropped, as it is when serializing a Cert
.
impl FromStr for Cert
[src]
type Err = Error
The associated error which can be returned from parsing.
pub fn from_str(s: &str) -> Result<Self, Self::Err>
[src]
impl IntoIterator for Cert
[src]
type Item = Packet
The type of the elements being iterated over.
type IntoIter = IntoIter
Which kind of iterator are we turning this into?
pub fn into_iter(self) -> Self::IntoIter
[src]
impl Marshal for Cert
[src]
pub fn serialize(&self, o: &mut dyn Write) -> Result<()>
[src]
pub fn export(&self, o: &mut dyn Write) -> Result<()>
[src]
impl MarshalInto for Cert
[src]
pub fn serialized_len(&self) -> usize
[src]
pub fn serialize_into(&self, buf: &mut [u8]) -> Result<usize>
[src]
pub fn export_into(&self, buf: &mut [u8]) -> Result<usize>
[src]
pub fn to_vec(&self) -> Result<Vec<u8>>
[src]
pub fn export_to_vec(&self) -> Result<Vec<u8>>
[src]
impl<'a> Parse<'a, Cert> for Cert
[src]
pub fn from_reader<R: Read + Send + Sync>(reader: R) -> Result<Self>
[src]
Returns the first Cert encountered in the reader.
pub fn from_file<P: AsRef<Path>>(path: P) -> Result<Self>
[src]
Returns the first Cert encountered in the file.
pub fn from_bytes<D: AsRef<[u8]> + ?Sized + Send + Sync>(
data: &'a D
) -> Result<Self>
[src]
data: &'a D
) -> Result<Self>
Returns the first Cert found in buf
.
buf
must be an OpenPGP-encoded message.
impl PartialEq<Cert> for Cert
[src]
impl Serialize for Cert
[src]
pub fn serialize(&self, o: &mut dyn Write) -> Result<()>
[src]
pub fn export(&self, o: &mut dyn Write) -> Result<()>
[src]
impl SerializeInto for Cert
[src]
pub fn serialized_len(&self) -> usize
[src]
pub fn serialize_into(&self, buf: &mut [u8]) -> Result<usize>
[src]
pub fn to_vec(&self) -> Result<Vec<u8>>
[src]
pub fn export_into(&self, buf: &mut [u8]) -> Result<usize>
[src]
pub fn export_to_vec(&self) -> Result<Vec<u8>>
[src]
impl StructuralPartialEq for Cert
[src]
impl TryFrom<Packet> for Cert
[src]
type Error = Error
The type returned in the event of a conversion error.
pub fn try_from(p: Packet) -> Result<Self>
[src]
impl<'_> TryFrom<PacketParserResult<'_>> for Cert
[src]
type Error = Error
The type returned in the event of a conversion error.
pub fn try_from(ppr: PacketParserResult<'_>) -> Result<Self>
[src]
Returns the Cert found in the packet stream.
If the sequence contains multiple certificates (i.e., it is a
keyring), or the certificate is followed by an invalid packet
this function will fail. To parse keyrings, use
CertParser
instead of this function.
impl TryFrom<PacketPile> for Cert
[src]
type Error = Error
The type returned in the event of a conversion error.
pub fn try_from(p: PacketPile) -> Result<Self>
[src]
Returns the certificate found in the PacketPile
.
If the PacketPile
does not start with a certificate
(specifically, if it does not start with a primary key
packet), then this fails.
If the sequence contains multiple certificates (i.e., it is a
keyring), or the certificate is followed by an invalid packet
this function will fail. To parse keyrings, use
CertParser
instead of this function.
Examples
use sequoia_openpgp as openpgp; use openpgp::cert::prelude::*; use openpgp::packet::prelude::*; use openpgp::PacketPile; use std::convert::TryFrom; let (cert, rev) = CertBuilder::general_purpose(None, Some("alice@example.org")) .generate()?; // We should be able to turn a certificate into a PacketPile // and back. let pp : PacketPile = cert.into(); assert!(Cert::try_from(pp).is_ok()); // But a revocation certificate is not a certificate, so this // will fail. let pp : PacketPile = Packet::from(rev).into(); assert!(Cert::try_from(pp).is_err());
impl TryFrom<Vec<Packet, Global>> for Cert
[src]
Auto Trait Implementations
impl RefUnwindSafe for Cert
[src]
impl Send for Cert
[src]
impl Sync for Cert
[src]
impl Unpin for Cert
[src]
impl UnwindSafe for Cert
[src]
Blanket Implementations
impl<T> Any for T where
T: 'static + ?Sized,
[src]
T: 'static + ?Sized,
impl<T> Borrow<T> for T where
T: ?Sized,
[src]
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
[src]
T: ?Sized,
pub fn borrow_mut(&mut self) -> &mut T
[src]
impl<T> DynClone for T where
T: Clone,
[src]
T: Clone,
pub fn __clone_box(&self, Private) -> *mut ()
[src]
impl<T> From<T> for T
[src]
impl<T, U> Into<U> for T where
U: From<T>,
[src]
U: From<T>,
impl<T> Same<T> for T
type Output = T
Should always be Self
impl<T> ToOwned for T where
T: Clone,
[src]
T: Clone,
type Owned = T
The resulting type after obtaining ownership.
pub fn to_owned(&self) -> T
[src]
pub fn clone_into(&self, target: &mut T)
[src]
impl<T> ToString for T where
T: Display + ?Sized,
[src]
T: Display + ?Sized,
impl<T, U> TryFrom<U> for T where
U: Into<T>,
[src]
U: Into<T>,
type Error = Infallible
The type returned in the event of a conversion error.
pub fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
[src]
impl<T, U> TryInto<U> for T where
U: TryFrom<T>,
[src]
U: TryFrom<T>,