Struct sequoia_openpgp::cert::SubkeyRevocationBuilder
source · pub struct SubkeyRevocationBuilder { /* private fields */ }
Expand description
A builder for revocation certificates for subkeys.
A revocation certificate for a subkey has three degrees of freedom: the certificate, the key used to generate the revocation certificate, and the subkey being revoked.
Normally, the key used to sign the revocation certificate is the
certificate’s primary key, and the subkey is a subkey that is
bound to the certificate. However, this is not required. For
instance, if Alice has marked Robert’s certificate (R
) as a
designated revoker for her certificate (A
), then R
can
revoke A
or parts of A
. In such a case, the certificate is
A
, the key used to sign the revocation certificate comes from
R
, and the subkey being revoked is bound to A
.
But, the subkey doesn’t technically need to be bound to the
certificate either. For instance, it is technically possible for
R
to create a revocation certificate for a subkey in the context
of A
, even if that subkey is not bound to A
. Semantically,
such a revocation certificate is currently meaningless.
§Examples
Revoke a subkey, which is now considered to be too weak:
use sequoia_openpgp as openpgp;
use openpgp::cert::prelude::*;
use openpgp::policy::StandardPolicy;
use openpgp::types::ReasonForRevocation;
use openpgp::types::RevocationStatus;
use openpgp::types::SignatureType;
let p = &StandardPolicy::new();
// Create and sign a revocation certificate.
let mut signer = cert.primary_key().key().clone()
.parts_into_secret()?.into_keypair()?;
let subkey = cert.keys().subkeys().nth(0).unwrap();
let sig = SubkeyRevocationBuilder::new()
.set_reason_for_revocation(ReasonForRevocation::KeyRetired,
b"Revoking due to the recent crypto vulnerabilities.")?
.build(&mut signer, &cert, subkey.key(), None)?;
// Merge it into the certificate.
let cert = cert.insert_packets(sig.clone())?;
// Now it's revoked.
let subkey = cert.keys().subkeys().nth(0).unwrap();
if let RevocationStatus::Revoked(revocations) = subkey.revocation_status(p, None) {
assert_eq!(revocations.len(), 1);
assert_eq!(*revocations[0], sig);
} else {
panic!("Subkey is not revoked.");
}
// But the certificate isn't.
assert_eq!(RevocationStatus::NotAsFarAsWeKnow,
cert.revocation_status(p, None));
Implementations§
source§impl SubkeyRevocationBuilder
impl SubkeyRevocationBuilder
sourcepub fn new() -> Self
pub fn new() -> Self
Returns a new SubkeyRevocationBuilder
.
§Examples
use sequoia_openpgp as openpgp;
use openpgp::cert::prelude::*;
let builder = SubkeyRevocationBuilder::new();
sourcepub fn set_reason_for_revocation(
self,
code: ReasonForRevocation,
reason: &[u8],
) -> Result<Self>
pub fn set_reason_for_revocation( self, code: ReasonForRevocation, reason: &[u8], ) -> Result<Self>
Sets the reason for revocation.
§Examples
Revoke a possibly compromised subkey:
use sequoia_openpgp as openpgp;
use openpgp::cert::prelude::*;
use openpgp::types::ReasonForRevocation;
let builder = SubkeyRevocationBuilder::new()
.set_reason_for_revocation(ReasonForRevocation::KeyCompromised,
b"I lost my smartcard.");
sourcepub fn set_signature_creation_time(
self,
creation_time: SystemTime,
) -> Result<Self>
pub fn set_signature_creation_time( self, creation_time: SystemTime, ) -> Result<Self>
Sets the revocation certificate’s creation time.
The creation time is interpreted as the time at which the subkey should be considered revoked. For a soft revocation, artifacts created prior to the revocation are still considered valid.
You’ll usually want to set this explicitly and not use the current time. In particular, if a subkey is compromised, you’ll want to set this to the time when the compromise happened.
§Examples
Create a revocation certificate for a subkey that was compromised yesterday:
use sequoia_openpgp as openpgp;
use openpgp::cert::prelude::*;
let builder = SubkeyRevocationBuilder::new()
.set_signature_creation_time(yesterday);
sourcepub fn add_notation<N, V, F>(
self,
name: N,
value: V,
flags: F,
critical: bool,
) -> Result<Self>
pub fn add_notation<N, V, F>( self, name: N, value: V, flags: F, critical: bool, ) -> Result<Self>
Adds a notation to the revocation certificate.
Unlike the SubkeyRevocationBuilder::set_notation
method, this function
does not first remove any existing notation with the specified name.
See SignatureBuilder::add_notation
for further documentation.
§Examples
use sequoia_openpgp as openpgp;
use openpgp::cert::prelude::*;
use openpgp::packet::signature::subpacket::NotationDataFlags;
let builder = CertRevocationBuilder::new().add_notation(
"revocation-policy@example.org",
"https://policy.example.org/cert-revocation-policy",
NotationDataFlags::empty().set_human_readable(),
false,
);
sourcepub fn set_notation<N, V, F>(
self,
name: N,
value: V,
flags: F,
critical: bool,
) -> Result<Self>
pub fn set_notation<N, V, F>( self, name: N, value: V, flags: F, critical: bool, ) -> Result<Self>
Sets a notation to the revocation certificate.
Unlike the SubkeyRevocationBuilder::add_notation
method, this function
first removes any existing notation with the specified name.
See SignatureBuilder::set_notation
for further documentation.
§Examples
use sequoia_openpgp as openpgp;
use openpgp::cert::prelude::*;
use openpgp::packet::signature::subpacket::NotationDataFlags;
let builder = CertRevocationBuilder::new().set_notation(
"revocation-policy@example.org",
"https://policy.example.org/cert-revocation-policy",
NotationDataFlags::empty().set_human_readable(),
false,
);
sourcepub fn build<H, P>(
self,
signer: &mut dyn Signer,
cert: &Cert,
key: &Key<P, SubordinateRole>,
hash_algo: H,
) -> Result<Signature>
pub fn build<H, P>( self, signer: &mut dyn Signer, cert: &Cert, key: &Key<P, SubordinateRole>, hash_algo: H, ) -> Result<Signature>
Returns a signed revocation certificate.
A revocation certificate is generated for cert
and key
and
signed using signer
with the specified hash algorithm.
Normally, you should pass None
to select the default hash
algorithm.
§Examples
Revoke a subkey, which is now considered to be too weak:
use sequoia_openpgp as openpgp;
use openpgp::cert::prelude::*;
use openpgp::policy::StandardPolicy;
use openpgp::types::ReasonForRevocation;
let p = &StandardPolicy::new();
// Create and sign a revocation certificate.
let mut signer = cert.primary_key().key().clone()
.parts_into_secret()?.into_keypair()?;
let subkey = cert.keys().subkeys().nth(0).unwrap();
let sig = SubkeyRevocationBuilder::new()
.set_reason_for_revocation(ReasonForRevocation::KeyRetired,
b"Revoking due to the recent crypto vulnerabilities.")?
.build(&mut signer, &cert, subkey.key(), None)?;
Methods from Deref<Target = SignatureBuilder>§
sourcepub fn signature_expiration_time(&self) -> Option<SystemTime>
pub fn signature_expiration_time(&self) -> Option<SystemTime>
Returns the value of the Signature Expiration Time subpacket as an absolute time.
A Signature Expiration Time subpacket specifies when the
signature expires. The value stored is not an absolute time,
but a duration, which is relative to the Signature’s creation
time. To better reflect the subpacket’s name, this method
returns the absolute expiry time, and the
SubpacketAreas::signature_validity_period
method returns
the subpacket’s raw value.
The Signature Expiration Time subpacket is different from the
Key Expiration Time subpacket, which is accessed using
SubpacketAreas::key_validity_period
, and used specifies
when an associated key expires. The difference is that in the
former case, the signature itself expires, but in the latter
case, only the associated key expires. This difference is
critical: if a binding signature expires, then an OpenPGP
implementation will still consider the associated key to be
valid if there is another valid binding signature, even if it
is older than the expired signature; if the active binding
signature indicates that the key has expired, then OpenPGP
implementations will not fallback to an older binding
signature.
There are several cases where having a signature expire is
useful. Say Alice certifies Bob’s certificate for
bob@example.org
. She can limit the lifetime of the
certification to force her to reevaluate the certification
shortly before it expires. For instance, is Bob still
associated with example.org
? Does she have reason to
believe that his key has been compromised? Using an
expiration is common in the X.509 ecosystem. For instance,
Let’s Encrypt issues certificates with 90-day lifetimes.
Having signatures expire can also be useful when deploying software. For instance, you might have a service that installs an update if it has been signed by a trusted certificate. To prevent an adversary from coercing the service to install an older version, you could limit the signature’s lifetime to just a few minutes.
If the subpacket is not present in the hashed subpacket area,
this returns None
. If this function returns None
, the
signature does not expire.
Note: if the signature contains multiple instances of this subpacket in the hashed subpacket area, the last one is returned.
sourcepub fn effective_signature_creation_time(&self) -> Result<Option<SystemTime>>
pub fn effective_signature_creation_time(&self) -> Result<Option<SystemTime>>
Returns the signature creation time that would be used if a signature were created now.
§Examples
use std::time::{Duration, SystemTime};
use sequoia_openpgp as openpgp;
use openpgp::types::SignatureType;
use openpgp::packet::prelude::*;
// If we don't set a creation time, then the current time is used.
let sig = SignatureBuilder::new(SignatureType::PositiveCertification);
let ct = sig.effective_signature_creation_time()?.expect("creation time");
assert!(SystemTime::now().duration_since(ct).expect("ct is in the past")
< Duration::new(1, 0));
// If we set a signature creation time, then we should get it back.
let t = SystemTime::now() - Duration::new(24 * 60 * 60, 0);
let sig = sig.set_signature_creation_time(t)?;
assert!(t.duration_since(
sig.effective_signature_creation_time()?.unwrap()).unwrap()
< Duration::new(1, 0));
Methods from Deref<Target = SignatureFields>§
sourcepub fn hash_standalone(&self, hash: &mut dyn Digest)
pub fn hash_standalone(&self, hash: &mut dyn Digest)
Hashes this standalone signature.
sourcepub fn hash_timestamp(&self, hash: &mut dyn Digest)
pub fn hash_timestamp(&self, hash: &mut dyn Digest)
Hashes this timestamp signature.
sourcepub fn hash_direct_key<P>(
&self,
hash: &mut dyn Digest,
key: &Key<P, PrimaryRole>,
)where
P: KeyParts,
pub fn hash_direct_key<P>(
&self,
hash: &mut dyn Digest,
key: &Key<P, PrimaryRole>,
)where
P: KeyParts,
Hashes this direct key signature over the specified primary key, and the primary key.
sourcepub fn hash_subkey_binding<P, Q>(
&self,
hash: &mut dyn Digest,
key: &Key<P, PrimaryRole>,
subkey: &Key<Q, SubordinateRole>,
)
pub fn hash_subkey_binding<P, Q>( &self, hash: &mut dyn Digest, key: &Key<P, PrimaryRole>, subkey: &Key<Q, SubordinateRole>, )
Hashes this subkey binding over the specified primary key and subkey, the primary key, and the subkey.
sourcepub fn hash_primary_key_binding<P, Q>(
&self,
hash: &mut dyn Digest,
key: &Key<P, PrimaryRole>,
subkey: &Key<Q, SubordinateRole>,
)
pub fn hash_primary_key_binding<P, Q>( &self, hash: &mut dyn Digest, key: &Key<P, PrimaryRole>, subkey: &Key<Q, SubordinateRole>, )
Hashes this primary key binding over the specified primary key and subkey, the primary key, and the subkey.
sourcepub fn hash_userid_binding<P>(
&self,
hash: &mut dyn Digest,
key: &Key<P, PrimaryRole>,
userid: &UserID,
)where
P: KeyParts,
pub fn hash_userid_binding<P>(
&self,
hash: &mut dyn Digest,
key: &Key<P, PrimaryRole>,
userid: &UserID,
)where
P: KeyParts,
Hashes this user ID binding over the specified primary key and user ID, the primary key, and the userid.
sourcepub fn hash_user_attribute_binding<P>(
&self,
hash: &mut dyn Digest,
key: &Key<P, PrimaryRole>,
ua: &UserAttribute,
)where
P: KeyParts,
pub fn hash_user_attribute_binding<P>(
&self,
hash: &mut dyn Digest,
key: &Key<P, PrimaryRole>,
ua: &UserAttribute,
)where
P: KeyParts,
Hashes this user attribute binding over the specified primary key and user attribute, the primary key, and the user attribute.
sourcepub fn typ(&self) -> SignatureType
pub fn typ(&self) -> SignatureType
Gets the signature type.
This function is called typ
and not type
, because type
is a reserved word.
sourcepub fn hash_algo(&self) -> HashAlgorithm
pub fn hash_algo(&self) -> HashAlgorithm
Gets the hash algorithm.
Methods from Deref<Target = SubpacketAreas>§
sourcepub fn hashed_area(&self) -> &SubpacketArea
pub fn hashed_area(&self) -> &SubpacketArea
Gets a reference to the hashed area.
sourcepub fn hashed_area_mut(&mut self) -> &mut SubpacketArea
pub fn hashed_area_mut(&mut self) -> &mut SubpacketArea
Gets a mutable reference to the hashed area.
Note: if you modify the hashed area of a Signature4
, this
will invalidate the signature. Instead, you should normally
convert the Signature4
into a signature::SignatureBuilder
,
modify that, and then create a new signature.
sourcepub fn unhashed_area(&self) -> &SubpacketArea
pub fn unhashed_area(&self) -> &SubpacketArea
Gets a reference to the unhashed area.
sourcepub fn unhashed_area_mut(&mut self) -> &mut SubpacketArea
pub fn unhashed_area_mut(&mut self) -> &mut SubpacketArea
Gets a mutable reference to the unhashed area.
sourcepub fn subpacket(&self, tag: SubpacketTag) -> Option<&Subpacket>
pub fn subpacket(&self, tag: SubpacketTag) -> Option<&Subpacket>
Returns a reference to the last instance of the specified subpacket, if any.
This function returns the last instance of the specified
subpacket in the subpacket areas in which it can occur. Thus,
when looking for the Signature Creation Time
subpacket, this
function only considers the hashed subpacket area. But, when
looking for the Embedded Signature
subpacket, this function
considers both subpacket areas.
Unknown subpackets are assumed to only safely occur in the hashed subpacket area. Thus, any instances of them in the unhashed area are ignored.
For subpackets that can safely occur in both subpacket areas, this function prefers instances in the hashed subpacket area.
sourcepub fn subpacket_mut(&mut self, tag: SubpacketTag) -> Option<&mut Subpacket>
pub fn subpacket_mut(&mut self, tag: SubpacketTag) -> Option<&mut Subpacket>
Returns a mutable reference to the last instance of the specified subpacket, if any.
This function returns the last instance of the specified
subpacket in the subpacket areas in which it can occur. Thus,
when looking for the Signature Creation Time
subpacket, this
function only considers the hashed subpacket area. But, when
looking for the Embedded Signature
subpacket, this function
considers both subpacket areas.
Unknown subpackets are assumed to only safely occur in the hashed subpacket area. Thus, any instances of them in the unhashed area are ignored.
For subpackets that can safely occur in both subpacket areas, this function prefers instances in the hashed subpacket area.
sourcepub fn subpackets(
&self,
tag: SubpacketTag,
) -> impl Iterator<Item = &Subpacket> + Send + Sync
pub fn subpackets( &self, tag: SubpacketTag, ) -> impl Iterator<Item = &Subpacket> + Send + Sync
Returns an iterator over all instances of the specified subpacket.
This function returns an iterator over all instances of the
specified subpacket in the subpacket areas in which it can
occur. Thus, when looking for the Issuer
subpacket, the
iterator includes instances of the subpacket from both the
hashed subpacket area and the unhashed subpacket area, but
when looking for the Signature Creation Time
subpacket, the
iterator only includes instances of the subpacket from the
hashed subpacket area; any instances of the subpacket in the
unhashed subpacket area are ignored.
Unknown subpackets are assumed to only safely occur in the hashed subpacket area. Thus, any instances of them in the unhashed area are ignored.
sourcepub fn signature_creation_time(&self) -> Option<SystemTime>
pub fn signature_creation_time(&self) -> Option<SystemTime>
Returns the value of the Signature Creation Time subpacket.
The Signature Creation Time subpacket specifies when the signature was created. According to the standard, all signatures must include a Signature Creation Time subpacket in the signature’s hashed area. This doesn’t mean that the time stamp is correct: the issuer can always forge it.
If the subpacket is not present in the hashed subpacket area,
this returns None
.
Note: if the signature contains multiple instances of this subpacket in the hashed subpacket area, the last one is returned.
sourcepub fn signature_validity_period(&self) -> Option<Duration>
pub fn signature_validity_period(&self) -> Option<Duration>
Returns the value of the Signature Expiration Time subpacket.
This function is called signature_validity_period
and not
signature_expiration_time
, which would be more consistent
with the subpacket’s name, because the latter suggests an
absolute time, but the time is actually relative to the
signature’s creation time, which is stored in the signature’s
Signature Creation Time subpacket.
A Signature Expiration Time subpacket specifies when the
signature expires. This is different from the Key Expiration
Time subpacket, which is accessed using
SubpacketAreas::key_validity_period
, and used to
specify when an associated key expires. The difference is
that in the former case, the signature itself expires, but in
the latter case, only the associated key expires. This
difference is critical: if a binding signature expires, then
an OpenPGP implementation will still consider the associated
key to be valid if there is another valid binding signature,
even if it is older than the expired signature; if the active
binding signature indicates that the key has expired, then
OpenPGP implementations will not fallback to an older binding
signature.
There are several cases where having a signature expire is
useful. Say Alice certifies Bob’s certificate for
bob@example.org
. She can limit the lifetime of the
certification to force her to reevaluate the certification
shortly before it expires. For instance, is Bob still
associated with example.org
? Does she have reason to
believe that his key has been compromised? Using an
expiration is common in the X.509 ecosystem. For instance,
Let’s Encrypt issues certificates with 90-day lifetimes.
Having signatures expire can also be useful when deploying software. For instance, you might have a service that installs an update if it has been signed by a trusted certificate. To prevent an adversary from coercing the service to install an older version, you could limit the signature’s lifetime to just a few minutes.
If the subpacket is not present in the hashed subpacket area,
this returns None
. If this function returns None
, or the
returned period is 0
, the signature does not expire.
Note: if the signature contains multiple instances of this subpacket in the hashed subpacket area, the last one is returned.
sourcepub fn signature_expiration_time(&self) -> Option<SystemTime>
pub fn signature_expiration_time(&self) -> Option<SystemTime>
Returns the value of the Signature Expiration Time subpacket as an absolute time.
A Signature Expiration Time subpacket specifies when the
signature expires. The value stored is not an absolute time,
but a duration, which is relative to the Signature’s creation
time. To better reflect the subpacket’s name, this method
returns the absolute expiry time, and the
SubpacketAreas::signature_validity_period
method returns
the subpacket’s raw value.
The Signature Expiration Time subpacket is different from the
Key Expiration Time subpacket, which is accessed using
SubpacketAreas::key_validity_period
, and used specifies
when an associated key expires. The difference is that in the
former case, the signature itself expires, but in the latter
case, only the associated key expires. This difference is
critical: if a binding signature expires, then an OpenPGP
implementation will still consider the associated key to be
valid if there is another valid binding signature, even if it
is older than the expired signature; if the active binding
signature indicates that the key has expired, then OpenPGP
implementations will not fallback to an older binding
signature.
There are several cases where having a signature expire is
useful. Say Alice certifies Bob’s certificate for
bob@example.org
. She can limit the lifetime of the
certification to force her to reevaluate the certification
shortly before it expires. For instance, is Bob still
associated with example.org
? Does she have reason to
believe that his key has been compromised? Using an
expiration is common in the X.509 ecosystem. For instance,
Let’s Encrypt issues certificates with 90-day lifetimes.
Having signatures expire can also be useful when deploying software. For instance, you might have a service that installs an update if it has been signed by a trusted certificate. To prevent an adversary from coercing the service to install an older version, you could limit the signature’s lifetime to just a few minutes.
If the subpacket is not present in the hashed subpacket area,
this returns None
. If this function returns None
, the
signature does not expire.
Note: if the signature contains multiple instances of this subpacket in the hashed subpacket area, the last one is returned.
sourcepub fn signature_alive<T, U>(
&self,
time: T,
clock_skew_tolerance: U,
) -> Result<()>
pub fn signature_alive<T, U>( &self, time: T, clock_skew_tolerance: U, ) -> Result<()>
Returns whether or not the signature is alive at the specified time.
A signature is considered to be alive if creation time - tolerance <= time
and time < expiration time
.
This function does not check whether the key is revoked.
If time
is None
, then this function uses the current time
for time
.
If time
is None
, and clock_skew_tolerance
is None
,
then this function uses CLOCK_SKEW_TOLERANCE
for the
tolerance. If time
is not None
and clock_skew_tolerance
is None
, it uses no tolerance. The intuition here is that
we only need a tolerance when checking if a signature is alive
right now; if we are checking at a specific time, we don’t
want to use a tolerance.
A small amount of tolerance for clock skew is necessary, because although most computers synchronize their clocks with a time server, up to a few seconds of clock skew are not unusual in practice. And, even worse, several minutes of clock skew appear to be not uncommon on virtual machines.
Not accounting for clock skew can result in signatures being unexpectedly considered invalid. Consider: computer A sends a message to computer B at 9:00, but computer B, whose clock says the current time is 8:59, rejects it, because the signature appears to have been made in the future. This is particularly problematic for low-latency protocols built on top of OpenPGP, e.g., when two MUAs synchronize their state via a shared IMAP folder.
Being tolerant to potential clock skew is not always
appropriate. For instance, when determining a User ID’s
current self signature at time t
, we don’t ever want to
consider a self-signature made after t
to be valid, even if
it was made just a few moments after t
. This goes doubly so
for soft revocation certificates: the user might send a
message that she is retiring, and then immediately create a
soft revocation. The soft revocation should not invalidate
the message.
Unfortunately, in many cases, whether we should account for clock skew or not depends on application-specific context. As a rule of thumb, if the time and the timestamp come from different clocks, you probably want to account for clock skew.
§Errors
Section 5.2.3.4 of RFC 4880 states that a Signature Creation
Time subpacket “MUST be present in the hashed area.”
Consequently, if such a packet does not exist, this function
returns Error::MalformedPacket
.
§Examples
Alice’s desktop computer and laptop exchange messages in real time via a shared IMAP folder. Unfortunately, the clocks are not perfectly synchronized: the desktop computer’s clock is a few seconds ahead of the laptop’s clock. When there is little or no propagation delay, this means that the laptop will consider the signatures to be invalid, because they appear to have been created in the future. Using a tolerance prevents this from happening.
use std::time::{SystemTime, Duration};
use sequoia_openpgp as openpgp;
use openpgp::cert::prelude::*;
use openpgp::packet::signature::SignatureBuilder;
use openpgp::types::SignatureType;
let (alice, _) =
CertBuilder::general_purpose(None, Some("alice@example.org"))
.generate()?;
// Alice's Desktop computer signs a message. Its clock is a
// few seconds fast.
let now = SystemTime::now() + Duration::new(5, 0);
let mut alices_signer = alice.primary_key().key().clone()
.parts_into_secret()?.into_keypair()?;
let msg = "START PROTOCOL";
let mut sig = SignatureBuilder::new(SignatureType::Binary)
.set_signature_creation_time(now)?
.sign_message(&mut alices_signer, msg)?;
// The desktop computer transfers the message to the laptop
// via the shared IMAP folder. Because the laptop receives a
// push notification, it immediately processes it.
// Unfortunately, it is considered to be invalid: the message
// appears to be from the future!
assert!(sig.signature_alive(None, Duration::new(0, 0)).is_err());
// But, using the small default tolerance causes the laptop
// to consider the signature to be alive.
assert!(sig.signature_alive(None, None).is_ok());
sourcepub fn key_validity_period(&self) -> Option<Duration>
pub fn key_validity_period(&self) -> Option<Duration>
Returns the value of the Key Expiration Time subpacket.
This function is called key_validity_period
and not
key_expiration_time
, which would be more consistent with
the subpacket’s name, because the latter suggests an absolute
time, but the time is actually relative to the associated
key’s (not the signature’s) creation time, which is stored
in the Key.
A Key Expiration Time subpacket specifies when the
associated key expires. This is different from the Signature
Expiration Time subpacket (accessed using
SubpacketAreas::signature_validity_period
), which is
used to specify when the signature expires. That is, in the
former case, the associated key expires, but in the latter
case, the signature itself expires. This difference is
critical: if a binding signature expires, then an OpenPGP
implementation will still consider the associated key to be
valid if there is another valid binding signature, even if it
is older than the expired signature; if the active binding
signature indicates that the key has expired, then OpenPGP
implementations will not fallback to an older binding
signature.
If the subpacket is not present in the hashed subpacket area,
this returns None
. If this function returns None
, or the
returned period is 0
, the key does not expire.
Note: if the signature contains multiple instances of this subpacket in the hashed subpacket area, the last one is returned.
sourcepub fn key_expiration_time<P, R>(&self, key: &Key<P, R>) -> Option<SystemTime>
pub fn key_expiration_time<P, R>(&self, key: &Key<P, R>) -> Option<SystemTime>
Returns the value of the Key Expiration Time subpacket as an absolute time.
A Key Expiration Time subpacket specifies when a key
expires. The value stored is not an absolute time, but a
duration, which is relative to the associated Key’s creation
time, which is stored in the Key packet, not the binding
signature. As such, the Key Expiration Time subpacket is only
meaningful on a key’s binding signature. To better reflect
the subpacket’s name, this method returns the absolute expiry
time, and the SubpacketAreas::key_validity_period
method
returns the subpacket’s raw value.
The Key Expiration Time subpacket is different from the
Signature Expiration Time subpacket, which is accessed using
SubpacketAreas::signature_validity_period
, and specifies
when a signature expires. The difference is that in the
former case, only the associated key expires, but in the
latter case, the signature itself expires. This difference is
critical: if a binding signature expires, then an OpenPGP
implementation will still consider the associated key to be
valid if there is another valid binding signature, even if it
is older than the expired signature; if the active binding
signature indicates that the key has expired, then OpenPGP
implementations will not fallback to an older binding
signature.
Because the absolute time is relative to the key’s creation time, which is stored in the key itself, this function needs the associated key. Since there is no way to get the associated key from a signature, the key must be passed to this function. This function does not check that the key is in fact associated with this signature.
If the subpacket is not present in the hashed subpacket area,
this returns None
. If this function returns None
, the
signature does not expire.
Note: if the signature contains multiple instances of this subpacket in the hashed subpacket area, the last one is returned.
sourcepub fn key_alive<P, R, T>(&self, key: &Key<P, R>, t: T) -> Result<()>
pub fn key_alive<P, R, T>(&self, key: &Key<P, R>, t: T) -> Result<()>
Returns whether or not a key is alive at the specified time.
A Key is considered to be alive if creation time - tolerance <= time
and time < expiration time
.
This function does not check whether the signature is alive
(cf. SubpacketAreas::signature_alive
), or whether the key
is revoked (cf. ValidKeyAmalgamation::revoked
).
If time
is None
, then this function uses the current time
for time
.
Whereas a Key’s expiration time is stored in the Key’s active binding signature in the Key Expiration Time subpacket, its creation time is stored in the Key packet. As such, the associated Key must be passed to this function. This function, however, has no way to check that the signature is actually a binding signature for the specified Key.
§Examples
Even keys that don’t expire may not be considered alive. This is the case if they were created after the specified time.
use std::time::{SystemTime, Duration};
use sequoia_openpgp as openpgp;
use openpgp::cert::prelude::*;
use openpgp::policy::StandardPolicy;
let p = &StandardPolicy::new();
let (cert, _) = CertBuilder::new().generate()?;
let mut pk = cert.primary_key().key();
let sig = cert.primary_key().with_policy(p, None)?.binding_signature();
assert!(sig.key_alive(pk, None).is_ok());
// A key is not considered alive prior to its creation time.
let the_past = SystemTime::now() - Duration::new(300, 0);
assert!(sig.key_alive(pk, the_past).is_err());
sourcepub fn exportable_certification(&self) -> Option<bool>
pub fn exportable_certification(&self) -> Option<bool>
Returns the value of the Exportable Certification subpacket.
The Exportable Certification subpacket indicates whether the
signature should be exported (e.g., published on a public key
server) or not. When using Serialize::export
to export a
certificate, signatures that have this subpacket present and
set to false are not serialized.
Normally, you’ll want to use Signature4::exportable
to
check if a signature should be exported. That function also
checks whether the signature includes any sensitive
Revocation Key subpackets, which also shouldn’t be exported.
If the subpacket is not present in the hashed subpacket area,
this returns None
.
Note: if the signature contains multiple instances of this subpacket in the hashed subpacket area, the last one is returned.
sourcepub fn trust_signature(&self) -> Option<(u8, u8)>
pub fn trust_signature(&self) -> Option<(u8, u8)>
Returns the value of the Trust Signature subpacket.
The Trust Signature subpacket indicates the degree to which a certificate holder is trusted to certify other keys.
A level of 0 means that the certificate holder is not trusted to certificate other keys, a level of 1 means that the certificate holder is a trusted introducer (a certificate authority) and any certifications that they make should be considered valid. A level of 2 means the certificate holder can designate level 1 trusted introducers, etc.
The trust indicates the degree of confidence. A value of 120 means that a certification should be considered valid. A value of 60 means that a certification should only be considered partially valid. In the latter case, typically three such certifications are required for a binding to be considered authenticated.
If the subpacket is not present in the hashed subpacket area,
this returns None
.
Note: if the signature contains multiple instances of this subpacket in the hashed subpacket area, the last one is returned.
sourcepub fn regular_expressions(&self) -> impl Iterator<Item = &[u8]> + Send + Sync
pub fn regular_expressions(&self) -> impl Iterator<Item = &[u8]> + Send + Sync
Returns the values of all Regular Expression subpackets.
The Regular Expression subpacket is used in conjunction with
a Trust Signature subpacket, which is accessed using
SubpacketAreas::trust_signature
, to limit the scope
of a trusted introducer. This is useful, for instance, when a
company has a CA and you only want to trust them to certify
their own employees.
Note: The serialized form includes a trailing NUL
byte.
Sequoia strips the NUL
when parsing the subpacket.
This returns all instances of the Regular Expression subpacket in the hashed subpacket area.
sourcepub fn revocable(&self) -> Option<bool>
pub fn revocable(&self) -> Option<bool>
Returns the value of the Revocable subpacket.
The Revocable subpacket indicates whether a certification
may be later revoked by creating a Certification revocation
signature (0x30) that targets the signature using the
Signature Target subpacket (accessed using the
SubpacketAreas::signature_target
method).
If the subpacket is not present in the hashed subpacket area,
this returns None
.
Note: if the signature contains multiple instances of this subpacket in the hashed subpacket area, the last one is returned.
sourcepub fn revocation_keys(
&self,
) -> impl Iterator<Item = &RevocationKey> + Send + Sync
pub fn revocation_keys( &self, ) -> impl Iterator<Item = &RevocationKey> + Send + Sync
Returns the values of all Revocation Key subpackets.
A Revocation Key subpacket indicates certificates (so-called designated revokers) that are allowed to revoke the signer’s certificate. For instance, if Alice trusts Bob, she can set him as a designated revoker. This is useful if Alice loses access to her key, and therefore is unable to generate a revocation certificate on her own. In this case, she can still Bob to generate one on her behalf.
When getting a certificate’s revocation keys, all valid self-signatures should be checked, not only the active self-signature. This prevents an attacker who has gained access to the private key material from invalidating a third-party revocation by publishing a new self signature that doesn’t include any revocation keys.
Due to the complexity of verifying such signatures, many OpenPGP implementations do not support this feature.
This returns all instance of the Revocation Key subpacket in the hashed subpacket area.
sourcepub fn issuers(&self) -> impl Iterator<Item = &KeyID> + Send + Sync
pub fn issuers(&self) -> impl Iterator<Item = &KeyID> + Send + Sync
Returns the values of all Issuer subpackets.
The Issuer subpacket is used when processing a signature to identify which certificate created the signature. Since this information is self-authenticating (the act of validating the signature authenticates the subpacket), it may be stored in the unhashed subpacket area.
This returns all instances of the Issuer subpacket in both the hashed subpacket area and the unhashed subpacket area.
sourcepub fn issuer_fingerprints(
&self,
) -> impl Iterator<Item = &Fingerprint> + Send + Sync
pub fn issuer_fingerprints( &self, ) -> impl Iterator<Item = &Fingerprint> + Send + Sync
Returns the values of all Issuer Fingerprint subpackets.
The Issuer Fingerprint subpacket is used when processing a signature to identify which certificate created the signature. Since this information is self-authenticating (the act of validating the signature authenticates the subpacket), it is normally stored in the unhashed subpacket area.
This returns all instances of the Issuer Fingerprint subpacket in both the hashed subpacket area and the unhashed subpacket area.
sourcepub fn notation_data(&self) -> impl Iterator<Item = &NotationData> + Send + Sync
pub fn notation_data(&self) -> impl Iterator<Item = &NotationData> + Send + Sync
Returns all Notation Data subpackets.
Notation Data subpackets are key-value pairs. They can be used by applications to annotate signatures in a structured way. For instance, they can define additional, application-specific security requirements. Because they are functionally equivalent to subpackets, they can also be used for OpenPGP extensions. This is how the Intended Recipient subpacket started life.
Notation names are structured, and are divided into two
namespaces: the user namespace and the IETF namespace. Names
in the user namespace have the form name@example.org
and
their meaning is defined by the owner of the domain. The
meaning of the notation name@example.org
, for instance, is
defined by whoever controls example.org
. Names in the IETF
namespace do not contain an @
and are managed by IANA. See
Section 5.2.3.16 of RFC 4880 for details.
This returns all instances of the Notation Data subpacket in the hashed subpacket area.
sourcepub fn notation<'a, N>(
&'a self,
name: N,
) -> impl Iterator<Item = &'a [u8]> + Send + Sync
pub fn notation<'a, N>( &'a self, name: N, ) -> impl Iterator<Item = &'a [u8]> + Send + Sync
Returns the values of all Notation Data subpackets with the given name.
Notation Data subpackets are key-value pairs. They can be used by applications to annotate signatures in a structured way. For instance, they can define additional, application-specific security requirements. Because they are functionally equivalent to subpackets, they can also be used for OpenPGP extensions. This is how the Intended Recipient subpacket started life.
Notation names are structured, and are divided into two
namespaces: the user namespace and the IETF namespace. Names
in the user namespace have the form name@example.org
and
their meaning is defined by the owner of the domain. The
meaning of the notation name@example.org
, for instance, is
defined by whoever controls example.org
. Names in the IETF
namespace do not contain an @
and are managed by IANA. See
Section 5.2.3.16 of RFC 4880 for details.
This returns the values of all instances of the Notation Data subpacket with the specified name in the hashed subpacket area.
sourcepub fn preferred_symmetric_algorithms(&self) -> Option<&[SymmetricAlgorithm]>
pub fn preferred_symmetric_algorithms(&self) -> Option<&[SymmetricAlgorithm]>
Returns the value of the Preferred Symmetric Algorithms subpacket.
A Preferred Symmetric Algorithms subpacket lists what symmetric algorithms the user prefers. When encrypting a message for a recipient, the OpenPGP implementation should not use an algorithm that is not on this list.
This subpacket is a type of preference. When looking up a
preference, an OpenPGP implementation should first look for
the subpacket on the binding signature of the User ID or the
User Attribute used to locate the certificate (or the primary
User ID, if it was addressed by Key ID or fingerprint). If
the binding signature doesn’t contain the subpacket, then the
direct key signature should be checked. See the
Preferences
trait for details.
Unless addressing different User IDs really should result in different behavior, it is best to only set this preference on the direct key signature. This guarantees that even if some or all User IDs are stripped, the behavior remains consistent.
If the subpacket is not present in the hashed subpacket area,
this returns None
.
Note: if the signature contains multiple instances of this subpacket in the hashed subpacket area, the last one is returned.
sourcepub fn preferred_hash_algorithms(&self) -> Option<&[HashAlgorithm]>
pub fn preferred_hash_algorithms(&self) -> Option<&[HashAlgorithm]>
Returns the value of the Preferred Hash Algorithms subpacket.
A Preferred Hash Algorithms subpacket lists what hash algorithms the user prefers. When signing a message that should be verified by a particular recipient, the OpenPGP implementation should not use an algorithm that is not on this list.
This subpacket is a type of preference. When looking up a
preference, an OpenPGP implementation should first look for
the subpacket on the binding signature of the User ID or the
User Attribute used to locate the certificate (or the primary
User ID, if it was addressed by Key ID or fingerprint). If
the binding signature doesn’t contain the subpacket, then the
direct key signature should be checked. See the
Preferences
trait for details.
Unless addressing different User IDs really should result in different behavior, it is best to only set this preference on the direct key signature. This guarantees that even if some or all User IDs are stripped, the behavior remains consistent.
If the subpacket is not present in the hashed subpacket area,
this returns None
.
Note: if the signature contains multiple instances of this subpacket in the hashed subpacket area, the last one is returned.
sourcepub fn preferred_compression_algorithms(
&self,
) -> Option<&[CompressionAlgorithm]>
pub fn preferred_compression_algorithms( &self, ) -> Option<&[CompressionAlgorithm]>
Returns the value of the Preferred Compression Algorithms subpacket.
A Preferred Compression Algorithms subpacket lists what compression algorithms the user prefers. When compressing a message for a recipient, the OpenPGP implementation should not use an algorithm that is not on the list.
This subpacket is a type of preference. When looking up a
preference, an OpenPGP implementation should first for the
subpacket on the binding signature of the User ID or the User
Attribute used to locate the certificate (or the primary User
ID, if it was addressed by Key ID or fingerprint). If the
binding signature doesn’t contain the subpacket, then the
direct key signature should be checked. See the
Preferences
trait for details.
Unless addressing different User IDs really should result in different behavior, it is best to only set this preference on the direct key signature. This guarantees that even if some or all User IDs are stripped, the behavior remains consistent.
If the subpacket is not present in the hashed subpacket area,
this returns None
.
Note: if the signature contains multiple instances of this subpacket in the hashed subpacket area, the last one is returned.
sourcepub fn preferred_aead_algorithms(&self) -> Option<&[AEADAlgorithm]>
👎Deprecated
pub fn preferred_aead_algorithms(&self) -> Option<&[AEADAlgorithm]>
Returns the value of the Preferred AEAD Algorithms subpacket.
The Preferred AEAD Algorithms subpacket indicates what AEAD algorithms the key holder prefers ordered by preference. If this is set, then the AEAD feature flag should in the Features subpacket should also be set.
Note: because support for AEAD has not yet been standardized, we recommend not yet advertising support for it.
This subpacket is a type of preference. When looking up a
preference, an OpenPGP implementation should first look for
the subpacket on the binding signature of the User ID or the
User Attribute used to locate the certificate (or the primary
User ID, if it was addressed by Key ID or fingerprint). If
the binding signature doesn’t contain the subpacket, then the
direct key signature should be checked. See the
Preferences
trait for details.
Unless addressing different User IDs really should result in different behavior, it is best to only set this preference on the direct key signature. This guarantees that even if some or all User IDs are stripped, the behavior remains consistent.
If the subpacket is not present in the hashed subpacket area,
this returns None
.
Note: if the signature contains multiple instances of this subpacket in the hashed subpacket area, the last one is returned.
sourcepub fn key_server_preferences(&self) -> Option<KeyServerPreferences>
pub fn key_server_preferences(&self) -> Option<KeyServerPreferences>
Returns the value of the Key Server Preferences subpacket.
The Key Server Preferences subpacket indicates to key servers how they should handle the certificate.
This subpacket is a type of preference. When looking up a
preference, an OpenPGP implementation should first for the
subpacket on the binding signature of the User ID or the User
Attribute used to locate the certificate (or the primary User
ID, if it was addressed by Key ID or fingerprint). If the
binding signature doesn’t contain the subpacket, then the
direct key signature should be checked. See the
Preferences
trait for details.
Unless addressing different User IDs really should result in different behavior, it is best to only set this preference on the direct key signature. This guarantees that even if some or all User IDs are stripped, the behavior remains consistent.
If the subpacket is not present in the hashed subpacket area,
this returns None
.
Note: if the signature contains multiple instances of this subpacket in the hashed subpacket area, the last one is returned.
sourcepub fn preferred_key_server(&self) -> Option<&[u8]>
pub fn preferred_key_server(&self) -> Option<&[u8]>
Returns the value of the Preferred Key Server subpacket.
The Preferred Key Server subpacket contains a link to a key server where the certificate holder plans to publish updates to their certificate (e.g., extensions to the expiration time, new subkeys, revocation certificates).
The Preferred Key Server subpacket should be handled cautiously, because it can be used by a certificate holder to track communication partners.
This subpacket is a type of preference. When looking up a
preference, an OpenPGP implementation should first look for
the subpacket on the binding signature of the User ID or the
User Attribute used to locate the certificate (or the primary
User ID, if it was addressed by Key ID or fingerprint). If
the binding signature doesn’t contain the subpacket, then the
direct key signature should be checked. See the
Preferences
trait for details.
Unless addressing different User IDs really should result in different behavior, it is best to only set this preference on the direct key signature. This guarantees that even if some or all User IDs are stripped, the behavior remains consistent.
If the subpacket is not present in the hashed subpacket area,
this returns None
.
Note: if the signature contains multiple instances of this subpacket in the hashed subpacket area, the last one is returned.
sourcepub fn policy_uri(&self) -> Option<&[u8]>
pub fn policy_uri(&self) -> Option<&[u8]>
Returns the value of the Policy URI subpacket.
The Policy URI subpacket contains a link to a policy document, which contains information about the conditions under which the signature was made.
This subpacket is a type of preference. When looking up a
preference, an OpenPGP implementation should first look for
the subpacket on the binding signature of the User ID or the
User Attribute used to locate the certificate (or the primary
User ID, if it was addressed by Key ID or fingerprint). If
the binding signature doesn’t contain the subpacket, then the
direct key signature should be checked. See the
Preferences
trait for details.
Unless addressing different User IDs really should result in different behavior, it is best to only set this preference on the direct key signature. This guarantees that even if some or all User IDs are stripped, the behavior remains consistent.
If the subpacket is not present in the hashed subpacket area,
this returns None
.
Note: if the signature contains multiple instances of this subpacket in the hashed subpacket area, the last one is returned.
sourcepub fn primary_userid(&self) -> Option<bool>
pub fn primary_userid(&self) -> Option<bool>
Returns the value of the Primary UserID subpacket.
The Primary User ID subpacket indicates whether the
associated User ID or User Attribute should be considered the
primary User ID. It is possible that this is set on multiple
User IDs. See the documentation for
ValidCert::primary_userid
for an explanation of how
Sequoia resolves this ambiguity.
If the subpacket is not present in the hashed subpacket area,
this returns None
.
Note: if the signature contains multiple instances of this subpacket in the hashed subpacket area, the last one is returned.
sourcepub fn key_flags(&self) -> Option<KeyFlags>
pub fn key_flags(&self) -> Option<KeyFlags>
Returns the value of the Key Flags subpacket.
The Key Flags subpacket describes a key’s capabilities (certification capable, signing capable, etc.). In the case of subkeys, the Key Flags are located on the subkey’s binding signature. For primary keys, locating the correct Key Flags subpacket is more complex: First, the primary User ID is consulted. If the primary User ID contains a Key Flags subpacket, that is used. Otherwise, any direct key signature is considered. If that still doesn’t contain a Key Flags packet, then the primary key should be assumed to be certification capable.
If the subpacket is not present in the hashed subpacket area,
this returns None
.
Note: if the signature contains multiple instances of this subpacket in the hashed subpacket area, the last one is returned.
sourcepub fn signers_user_id(&self) -> Option<&[u8]>
pub fn signers_user_id(&self) -> Option<&[u8]>
Returns the value of the Signer’s UserID subpacket.
The Signer’s User ID subpacket indicates, which User ID made the signature. This is useful when a key has multiple User IDs, which correspond to different roles. For instance, it is not uncommon to use the same certificate in private as well as for a club.
If the subpacket is not present in the hashed subpacket area,
this returns None
.
Note: if the signature contains multiple instances of this subpacket in the hashed subpacket area, the last one is returned.
sourcepub fn reason_for_revocation(&self) -> Option<(ReasonForRevocation, &[u8])>
pub fn reason_for_revocation(&self) -> Option<(ReasonForRevocation, &[u8])>
Returns the value of the Reason for Revocation subpacket.
The Reason For Revocation subpacket indicates why a key, User ID, or User Attribute is being revoked. It includes both a machine readable code, and a human-readable string. The code is essential as it indicates to the OpenPGP implementation that reads the certificate whether the key was compromised (a hard revocation), or is no longer used (a soft revocation). In the former case, the OpenPGP implementation must conservatively consider all past signatures as suspect whereas in the latter case, past signatures can still be considered valid.
If the subpacket is not present in the hashed subpacket area,
this returns None
.
Note: if the signature contains multiple instances of this subpacket in the hashed subpacket area, the last one is returned.
sourcepub fn features(&self) -> Option<Features>
pub fn features(&self) -> Option<Features>
Returns the value of the Features subpacket.
A Features subpacket lists what OpenPGP features the user wants to use. When creating a message, features that the intended recipients do not support should not be used. However, because this information is rarely held up to date in practice, this information is only advisory, and implementations are allowed to infer what features the recipients support from contextual clues, e.g., their past behavior.
This subpacket is a type of preference. When looking up a
preference, an OpenPGP implementation should first look for
the subpacket on the binding signature of the User ID or the
User Attribute used to locate the certificate (or the primary
User ID, if it was addressed by Key ID or fingerprint). If
the binding signature doesn’t contain the subpacket, then the
direct key signature should be checked. See the
Preferences
trait for details.
Unless addressing different User IDs really should result in different behavior, it is best to only set this preference on the direct key signature. This guarantees that even if some or all User IDs are stripped, the behavior remains consistent.
If the subpacket is not present in the hashed subpacket area,
this returns None
.
Note: if the signature contains multiple instances of this subpacket in the hashed subpacket area, the last one is returned.
sourcepub fn signature_target(
&self,
) -> Option<(PublicKeyAlgorithm, HashAlgorithm, &[u8])>
pub fn signature_target( &self, ) -> Option<(PublicKeyAlgorithm, HashAlgorithm, &[u8])>
Returns the value of the Signature Target subpacket.
The Signature Target subpacket is used to identify the target of a signature. This is used when revoking a signature, and by timestamp signatures. It contains a hash of the target signature.
If the subpacket is not present in the hashed subpacket area,
this returns None
.
Note: if the signature contains multiple instances of this subpacket in the hashed subpacket area, the last one is returned.
sourcepub fn embedded_signatures(
&self,
) -> impl Iterator<Item = &Signature> + Send + Sync
pub fn embedded_signatures( &self, ) -> impl Iterator<Item = &Signature> + Send + Sync
Returns references to all Embedded Signature subpackets.
The Embedded Signature subpacket is normally used to hold a Primary Key Binding signature, which binds a signing-capable, authentication-capable, or certification-capable subkey to the primary key. Since this information is self-authenticating, it is usually stored in the unhashed subpacket area.
If the subpacket is not present in the hashed subpacket area
or in the unhashed subpacket area, this returns None
.
Note: if the signature contains multiple instances of this subpacket in the hashed subpacket area, the last one is returned. Otherwise, the last one is returned from the unhashed subpacket area.
sourcepub fn embedded_signatures_mut(
&mut self,
) -> impl Iterator<Item = &mut Signature> + Send + Sync
pub fn embedded_signatures_mut( &mut self, ) -> impl Iterator<Item = &mut Signature> + Send + Sync
Returns mutable references to all Embedded Signature subpackets.
The Embedded Signature subpacket is normally used to hold a Primary Key Binding signature, which binds a signing-capable, authentication-capable, or certification-capable subkey to the primary key. Since this information is self-authenticating, it is usually stored in the unhashed subpacket area.
If the subpacket is not present in the hashed subpacket area
or in the unhashed subpacket area, this returns None
.
Note: if the signature contains multiple instances of this subpacket in the hashed subpacket area, the last one is returned. Otherwise, the last one is returned from the unhashed subpacket area.
sourcepub fn intended_recipients(
&self,
) -> impl Iterator<Item = &Fingerprint> + Send + Sync
pub fn intended_recipients( &self, ) -> impl Iterator<Item = &Fingerprint> + Send + Sync
Returns the intended recipients.
The Intended Recipient subpacket holds the fingerprint of a certificate.
When signing a message, the message should include one such subpacket for each intended recipient. Note: not all messages have intended recipients. For instance, when signing an open letter, or a software release, the message is intended for anyone.
When processing a signature, the application should ensure that if there are any such subpackets, then one of the subpackets identifies the recipient’s certificate (or user signed the message). If this is not the case, then an attacker may have taken the message out of its original context. For instance, if Alice sends a signed email to Bob, with the content: “I agree to the contract”, and Bob forwards that message to Carol, then Carol may think that Alice agreed to a contract with her if the signature appears to be valid! By adding an intended recipient, it is possible for Carol’s mail client to warn her that although Alice signed the message, the content was intended for Bob and not for her.
This returns all instances of the Intended Recipient subpacket in the hashed subpacket area.
sourcepub fn attested_certifications(
&self,
) -> Result<impl Iterator<Item = &[u8]> + Send + Sync>
pub fn attested_certifications( &self, ) -> Result<impl Iterator<Item = &[u8]> + Send + Sync>
Returns the digests of attested certifications.
This feature is experimental.
Allows the certificate holder to attest to third party certifications, allowing them to be distributed with the certificate. This can be used to address certificate flooding concerns.
Note: The maximum size of the hashed signature subpacket area constrains the number of attestations that can be stored in a signature. If the certificate holder attested to more certifications, the digests are split across multiple attested key signatures with the same creation time.
The standard strongly suggests that the digests should be sorted. However, this function returns the digests in the order they are stored in the subpacket, which may not be sorted.
To address both issues, collect all digests from all attested
key signatures with the most recent creation time into a data
structure that allows efficient lookups, such as HashSet
or BTreeSet
.
See Section 5.2.3.30 of RFC 4880bis for details.