summaryrefslogtreecommitdiffstats
path: root/openpgp
diff options
context:
space:
mode:
authorNeal H. Walfield <neal@pep.foundation>2020-08-13 18:58:20 +0200
committerNeal H. Walfield <neal@pep.foundation>2020-08-13 19:47:56 +0200
commitdeb9d15dc6c71e18b0a06d39ea84daf3004e0058 (patch)
tree2912dfb17288671a8989089834f5b59ea1251817 /openpgp
parented0f5d3019705bf293716b92e5d86f2f1e3d1ec0 (diff)
openpgp: Improve SubpacketAreas' documentation.
- See #470.
Diffstat (limited to 'openpgp')
-rw-r--r--openpgp/src/packet/signature/subpacket.rs737
1 files changed, 604 insertions, 133 deletions
diff --git a/openpgp/src/packet/signature/subpacket.rs b/openpgp/src/packet/signature/subpacket.rs
index d88e97eb..9c6abb25 100644
--- a/openpgp/src/packet/signature/subpacket.rs
+++ b/openpgp/src/packet/signature/subpacket.rs
@@ -1733,14 +1733,22 @@ impl SubpacketLength {
}
impl SubpacketAreas {
- /// Returns the value of the Creation Time subpacket, which
- /// contains the time when the signature was created as a unix
- /// timestamp.
+ /// Returns the value of the Signature Creation Time subpacket.
///
- /// If the subpacket is not present, this returns `None`.
+ /// 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.
+ ///
+ /// [Signature Creation Time subpacket]: https://tools.ietf.org/html/rfc4880#section-5.2.3.4
+ ///
+ /// If the subpacket is not present in the hashed subpacket area,
+ /// this returns `None`.
///
/// Note: if the signature contains multiple instances of this
- /// subpacket, only the last one is considered.
+ /// subpacket in the hashed subpacket area, the last one is
+ /// returned.
pub fn signature_creation_time(&self) -> Option<time::SystemTime> {
// 4-octet time field
if let Some(sb)
@@ -1755,16 +1763,61 @@ impl SubpacketAreas {
}
}
- /// Returns the value of the Signature Expiration Time subpacket,
- /// which contains when the signature expires as the number of
- /// seconds after its creation.
+ /// 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].
+ ///
+ /// [Signature Creation Time subpacket]: https://tools.ietf.org/html/rfc4880#section-5.2.3.4
+ ///
+ /// 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.
+ ///
+ /// [Key Expiration Time subpacket]: https://tools.ietf.org/html/rfc4880#section-5.2.3.6
+ /// [`SubpacketAreas::key_validity_period`]: #method.key_validity_period
+ ///
+ /// 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.
+ ///
+ /// [Let's Encrypt]: https://letsencrypt.org/2015/11/09/why-90-days.html
+ ///
+ /// 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, this returns `None`. If this
- /// function returns `None`, or the returned period is `0`, the
- /// signature does not expire.
+ /// 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, only the last one is considered.
+ /// subpacket in the hashed subpacket area, the last one is
+ /// returned.
pub fn signature_validity_period(&self) -> Option<time::Duration> {
// 4-octet time field
if let Some(sb)
@@ -1779,14 +1832,23 @@ impl SubpacketAreas {
}
}
- /// Returns the value of the Exportable Certification subpacket,
- /// which contains whether the certification should be exported
- /// (i.e., whether the packet is *not* a local signature).
+ /// Returns the value of the Exportable Certification subpacket.
///
- /// If the subpacket is not present, this returns `None`.
+ /// 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.
+ ///
+ /// [Exportable Certification subpacket]: https://tools.ietf.org/html/rfc4880#section-5.2.3.11
+ /// [`Serialize::export`]: https://docs.sequoia-pgp.org/sequoia_openpgp/serialize/trait.Serialize.html#method.export
+ ///
+ /// If the subpacket is not present in the hashed subpacket area,
+ /// this returns `None`.
///
/// Note: if the signature contains multiple instances of this
- /// subpacket, only the last one is considered.
+ /// subpacket in the hashed subpacket area, the last one is
+ /// returned.
pub fn exportable_certification(&self) -> Option<bool> {
// 1 octet of exportability, 0 for not, 1 for exportable
if let Some(sb)
@@ -1803,33 +1865,33 @@ impl SubpacketAreas {
/// Returns the value of the Trust Signature subpacket.
///
- /// The return value is a tuple consisting of the level or depth
- /// and the trust amount.
+ /// The [Trust Signature subpacket] indicates the degree to which
+ /// a certificate holder is trusted to certify other keys.
///
- /// Recall from [Section 5.2.3.13 of RFC 4880]:
+ /// [Trust Signature subpacket]: https://tools.ietf.org/html/rfc4880#section-5.2.3.13
///
- /// ```text
- /// Level 0 has the same meaning as an ordinary
- /// validity signature. Level 1 means that the signed key is asserted to
- /// be a valid trusted introducer, with the 2nd octet of the body
- /// specifying the degree of trust. Level 2 means that the signed key is
- /// asserted to be trusted to issue level 1 trust signatures, i.e., that
- /// it is a "meta introducer".
- /// ```
+ /// 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.
///
- /// And, the trust amount is:
+ /// [certificate authority]: https://en.wikipedia.org/wiki/Certificate_authority
///
- /// ```text
- /// interpreted such that values less than 120 indicate partial
- /// trust and values of 120 or greater indicate complete trust.
- /// Implementations SHOULD emit values of 60 for partial trust and
- /// 120 for complete trust.
- /// ```
+ /// 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.
///
- /// [Section 5.2.3.13 of RFC 4880]: https://tools.ietf.org/html/rfc4880#section-5.2.3.13
+ /// If the subpacket is not present in the hashed subpacket area,
+ /// this returns `None`.
///
/// Note: if the signature contains multiple instances of this
- /// subpacket, only the last one is considered.
+ /// subpacket in the hashed subpacket area, the last one is
+ /// returned.
pub fn trust_signature(&self) -> Option<(u8, u8)> {
// 1 octet "level" (depth), 1 octet of trust amount
if let Some(sb) = self.subpacket(SubpacketTag::TrustSignature) {
@@ -1845,8 +1907,19 @@ impl SubpacketAreas {
/// Returns the value of any Regular Expression subpackets.
///
- /// Note: the serialized form includes a trailing NUL byte. This
- /// returns the value without the trailing NUL.
+ /// 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.
+ ///
+ /// [Trust Signature subpacket]: https://tools.ietf.org/html/rfc4880#section-5.2.3.13
+ /// [Regular Expression subpacket]: https://tools.ietf.org/html/rfc4880#section-5.2.3.14
+ /// [`SubpacketAreas::trust_signature`]: #method.trust_signature
+ ///
+ /// 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.
@@ -1859,14 +1932,26 @@ impl SubpacketAreas {
})
}
- /// Returns the value of the Revocable subpacket, which indicates
- /// whether the signature is revocable, i.e., whether revocation
- /// certificates for this signature should be ignored.
+ /// Returns the value of the Revocable subpacket.
///
- /// If the subpacket is not present, this returns `None`.
+ ///
+ /// 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).
+ ///
+ /// [Revocable subpacket]: https://tools.ietf.org/html/rfc4880#section-5.2.3.12
+ /// [Certification revocation signature]: https://tools.ietf.org/html/rfc4880#section-5.2.1
+ /// [Signature Target subpacket]: https://tools.ietf.org/html/rfc4880#section-5.2.3.25
+ /// [`SubpacketAreas::signature_target`]: #method.signature_target
+ ///
+ /// If the subpacket is not present in the hashed subpacket area,
+ /// this returns `None`.
///
/// Note: if the signature contains multiple instances of this
- /// subpacket, only the last one is considered.
+ /// subpacket in the hashed subpacket area, the last one is
+ /// returned.
pub fn revocable(&self) -> Option<bool> {
// 1 octet of revocability, 0 for not, 1 for revocable
if let Some(sb)
@@ -1881,16 +1966,43 @@ impl SubpacketAreas {
}
}
- /// Returns the value of the Key Expiration Time subpacket, which
- /// contains when the referenced key expires as the number of
- /// seconds after the key's creation.
+ /// Returns the value of the Key Expiration Time subpacket.
///
- /// If the subpacket is not present, this returns `None`. If this
- /// function returns `None`, or the returned period is `0`, the
- /// key does not expire.
+ /// 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].
+ ///
+ /// [Key]: https://tools.ietf.org/html/rfc4880#section-5.5.2
+ ///
+ /// 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.
+ ///
+ /// [Key Expiration Time subpacket]: https://tools.ietf.org/html/rfc4880#section-5.2.3.6
+ /// [Signature Expiration Time subpacket]: https://tools.ietf.org/html/rfc4880#section-5.2.3.6
+ /// [`SubpacketAreas::signature_validity_period`]: #method.signature_validity_period
+ ///
+ /// 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, only the last one is considered.
+ /// subpacket in the hashed subpacket area, the last one is
+ /// returned.
pub fn key_validity_period(&self) -> Option<time::Duration> {
// 4-octet time field
if let Some(sb)
@@ -1906,14 +2018,37 @@ impl SubpacketAreas {
}
/// Returns the value of the Preferred Symmetric Algorithms
- /// subpacket, which contains the list of symmetric algorithms
- /// that the key holder prefers, ordered according by the key
- /// holder's preference.
+ /// subpacket.
///
- /// If the subpacket is not present, this returns `None`.
+ /// 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.
+ ///
+ /// [Preferred Symmetric Algorithms subpacket]: https://tools.ietf.org/html/rfc4880#section-5.2.3.7
+ ///
+ /// 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.
+ ///
+ /// [`Preferences`]: ../../../cert/trait.Preferences.html
+ ///
+ /// If the subpacket is not present in the hashed subpacket area,
+ /// this returns `None`.
///
/// Note: if the signature contains multiple instances of this
- /// subpacket, only the last one is considered.
+ /// subpacket in the hashed subpacket area, the last one is
+ /// returned.
pub fn preferred_symmetric_algorithms(&self)
-> Option<&[SymmetricAlgorithm]> {
// array of one-octet values
@@ -1931,13 +2066,30 @@ impl SubpacketAreas {
}
}
- /// Returns the value of the Revocation Key subpacket, which
- /// contains a designated revoker.
+ /// Returns the value of the Revocation Key subpacket.
///
- /// If the subpacket is not present, this returns `None`.
+ /// 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.
///
- /// Note: if the signature contains multiple instances of this
- /// subpacket, only the last one is considered.
+ /// 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.
+ ///
+ /// [Revocation Key subpacket]: https://tools.ietf.org/html/rfc4880#section-5.2.3.15
+ ///
+ /// This returns all instance of the Revocation Key subpacket in
+ /// the hashed subpacket area.
pub fn revocation_keys(&self) -> impl Iterator<Item=&RevocationKey>
{
self.subpackets(SubpacketTag::RevocationKey)
@@ -1951,6 +2103,14 @@ impl SubpacketAreas {
/// Returns the value of any 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 is stored in the
+ /// unhashed subpacket area.
+ ///
+ /// [Issuer subpacket]: https://tools.ietf.org/html/rfc4880#section-5.2.3.5
+ ///
/// This returns all instances of the Issuer subpacket in both the
/// hashed subpacket area and the unhashed subpacket area.
pub fn issuers(&self) -> impl Iterator<Item=&KeyID> {
@@ -1964,13 +2124,32 @@ impl SubpacketAreas {
})
}
- /// Returns the value of all Notation Data packets.
+ /// 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 Data subpackets]: https://tools.ietf.org/html/rfc4880#section-5.2.3.16
+ /// [Intended Recipient subpacket]:https://www.ietf.org/id/draft-ietf-openpgp-rfc4880bis-09.html#name-intended-recipient-fingerpr
+ ///
+ /// 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.
///
- /// If the subpacket is not present or malformed, this returns
- /// an empty vector.
+ /// [Section 5.2.3.16 of RFC 4880]: https://tools.ietf.org/html/rfc4880#section-5.2.3.16
///
- /// This function only considers Notation Data subpackets in the
- /// hashed area.
+ /// This returns all instances of the Notation Data subpacket in
+ /// the hashed subpacket area.
pub fn notation_data(&self) -> impl Iterator<Item=&NotationData>
{
self.subpackets(SubpacketTag::NotationData)
@@ -1985,8 +2164,30 @@ impl SubpacketAreas {
/// Returns the value of all Notation Data subpackets with the
/// given name.
///
- /// This function only considers Notation Data subpackets in the
- /// hashed area.
+ /// [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 Data subpackets]: https://tools.ietf.org/html/rfc4880#section-5.2.3.16
+ /// [Intended Recipient subpacket]:https://www.ietf.org/id/draft-ietf-openpgp-rfc4880bis-09.html#name-intended-recipient-fingerpr
+ ///
+ /// 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.
+ ///
+ /// [Section 5.2.3.16 of RFC 4880]: https://tools.ietf.org/html/rfc4880#section-5.2.3.16
+ ///
+ /// This returns the values of all instances of the Notation Data
+ /// subpacket with the specified name in the hashed subpacket area.
// name needs 'a, because the closure outlives the function call.
pub fn notation<'a, N>(&'a self, name: N) -> impl Iterator<Item=&'a [u8]>
where N: 'a + AsRef<str>
@@ -2001,15 +2202,38 @@ impl SubpacketAreas {
})
}
- /// Returns the value of the Preferred Hash Algorithms subpacket,
- /// which contains the list of hash algorithms that the key
- /// holders prefers, ordered according by the key holder's
- /// preference.
+ /// Returns the value of the Preferred Hash Algorithms subpacket.
///
- /// If the subpacket is not present, this returns `None`.
+ /// 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.
+ ///
+ /// [Preferred Hash Algorithms subpacket]: https://tools.ietf.org/html/rfc4880#section-5.2.3.8
+ ///
+ /// 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.
+ ///
+ /// [`Preferences`]: ../../../cert/trait.Preferences.html
+ ///
+ /// If the subpacket is not present in the hashed subpacket area,
+ /// this returns `None`.
///
/// Note: if the signature contains multiple instances of this
- /// subpacket, only the last one is considered.
+ /// subpacket in the hashed subpacket area, the last one is
+ /// returned.
pub fn preferred_hash_algorithms(&self) -> Option<&[HashAlgorithm]> {
// array of one-octet values
if let Some(sb)
@@ -2026,14 +2250,37 @@ impl SubpacketAreas {
}
/// Returns the value of the Preferred Compression Algorithms
- /// subpacket, which contains the list of compression algorithms
- /// that the key holder prefers, ordered according by the key
- /// holder's preference.
+ /// subpacket.
///
- /// If the subpacket is not present, this returns `None`.
+ /// 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.
+ ///
+ /// [Preferred Compression Algorithms subpacket]: https://tools.ietf.org/html/rfc4880#section-5.2.3.9
+ ///
+ /// 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.
+ ///
+ /// [`Preferences`]: ../../../cert/trait.Preferences.html
+ ///
+ /// If the subpacket is not present in the hashed subpacket area,
+ /// this returns `None`.
///
/// Note: if the signature contains multiple instances of this
- /// subpacket, only the last one is considered.
+ /// subpacket in the hashed subpacket area, the last one is
+ /// returned.
pub fn preferred_compression_algorithms(&self)
-> Option<&[CompressionAlgorithm]>
{
@@ -2052,13 +2299,35 @@ impl SubpacketAreas {
}
}
- /// Returns the value of the Key Server Preferences subpacket,
- /// which contains the key holder's key server preferences.
+ /// Returns the value of the Key Server Preferences subpacket.
+ ///
+ /// The [Key Server Preferences subpacket] indicates to key
+ /// servers how they should handle the certificate.
+ ///
+ /// [Key Server Preferences subpacket]: https://tools.ietf.org/html/rfc4880#section-5.2.3.17
+ ///
+ /// 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.
///
- /// If the subpacket is not present, this returns `None`.
+ /// 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.
+ ///
+ /// [`Preferences`]: ../../../cert/trait.Preferences.html
+ ///
+ /// If the subpacket is not present in the hashed subpacket area,
+ /// this returns `None`.
///
/// Note: if the signature contains multiple instances of this
- /// subpacket, only the last one is considered.
+ /// subpacket in the hashed subpacket area, the last one is
+ /// returned.
pub fn key_server_preferences(&self) -> Option<KeyServerPreferences> {
// N octets of flags
if let Some(sb) = self.subpacket(SubpacketTag::KeyServerPreferences) {
@@ -2072,16 +2341,41 @@ impl SubpacketAreas {
}
}
- /// Returns the value of the Preferred Key Server subpacket, which
- /// contains the user's preferred key server for updates.
+ /// 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.
+ ///
+ /// [Preferred Key Server subpacket]: https://tools.ietf.org/html/rfc4880#section-5.2.3.18
+ ///
+ /// 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.
///
- /// Note: this packet should be ignored, because it acts as key
- /// tracker.
+ /// [`Preferences`]: ../../../cert/trait.Preferences.html
///
- /// If the subpacket is not present, this returns `None`.
+ /// If the subpacket is not present in the hashed subpacket area,
+ /// this returns `None`.
///
/// Note: if the signature contains multiple instances of this
- /// subpacket, only the last one is considered.
+ /// subpacket in the hashed subpacket area, the last one is
+ /// returned.
pub fn preferred_key_server(&self) -> Option<&[u8]> {
// String
if let Some(sb)
@@ -2096,14 +2390,24 @@ impl SubpacketAreas {
}
}
- /// Returns the value of the Primary UserID subpacket, which
- /// indicates whether the referenced UserID should be considered
- /// the user's primary User ID.
+ /// 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, this returns `None`.
+ /// [Primary User ID subpacket]: https://tools.ietf.org/html/rfc4880#section-5.2.3.19
+ /// [`ValidCert::primary_userid`]: ../../../cert/struct.ValidCert.html#method.primary_userid
+ ///
+ /// If the subpacket is not present in the hashed subpacket area,
+ /// this returns `None`.
<