diff --git a/.reuse/dep5 b/.reuse/dep5 index 836a0a8..d968ced 100644 --- a/.reuse/dep5 +++ b/.reuse/dep5 @@ -6,3 +6,7 @@ Source: https://codeberg.org/openpgp/notes Files: book/source/diag/*.png book/source/diag/*.svg Copyright: 2023 The "Notes on OpenPGP" project License: CC-BY-SA-4.0 + +Files: book/source/mermaid/*.md book/source/mermaid/*.png +Copyright: 2023 The "Notes on OpenPGP" project +License: CC-BY-SA-4.0 diff --git a/book/source/06-certifications.md b/book/source/06-certifications.md deleted file mode 100644 index d394bd2..0000000 --- a/book/source/06-certifications.md +++ /dev/null @@ -1,95 +0,0 @@ - - -(certifications_chapter)= - -# Certification signatures - -Signatures make up the magic of OpenPGP. -They act as the syntax that allows forming and interpreting complex statements about data and identities. -Without signatures there would only be loose keys, impossible to associate with their owner. -Signatures are the glue that allows for keys, subkeys and identities to be assembled into hierarchical certificates and for messages to gain authenticity. - -```{admonition} TODO -:class: warning - - - Purpose of a signature - - Meaning of different signature types, nuances of subpackets - - Can we have a "catalogue" of statements a user might want to make, mapping these to archetypical signatures? - - Revocation; Hard vs. Soft -``` - -## Terminology - -The term *signature* can have multiple meanings in the context of the OpenPGP specification. -Cryptographic keys create raw signatures which are byte sequences calculated according to some signature scheme. -OpenPGP packs these raw signatures up into OpenPGP signature packets, which carry additional information in the form of signature subpackets. -For the purpose of this document, the term signature will refer to an OpenPGP signature packet (tag 2). - -OpenPGP signatures can be separated into *data signatures* and *certifications*. -A data signature serves the purpose to cryptographically guarantee the authenticity (and implicitly also the integrity) of a message, e.g. an email or a file, while a certification is used to attach metadata or subkeys to a certificate. -Data signatures are always calculated by keys carrying the **S**igning key flag, while certifications require keys carrying the **C**ertify Others key flag (with the exception of so called Primary Key Binding Signatures). -Different types of signatures are distinguished by a signature type code and are calculated in different ways. -Signatures can either be distributed standalone as *detached* signatures, or can be inlined with OpenPGP data, such as an OpenPGP message or a key or certificate. - -Data signatures (type 0x00 and 0x01) are created by hashing the message content and calculating a cryptographic signature over the hash. -The result is packed up into an OpenPGP signature packet, which can either be included in the OpenPGP message (TODO: See section about forming messages, cleartext signature framework), or distributed separately as a so called *detached* signature. -Data signatures are always calculated using a **S**igning key. - -A certification made by a key over components of the same certificate is referred to as a *self-certification*. -A typical use-case for a self-certification is to attach a user ID, such as a name and email address to a certificate. -This is done by calculating the signature over the user ID and the public primary key. -The resulting user ID certification (typically type 0x13, potentially type 0x10-0x12) can then be inserted into the certificate, right after the user ID packet. - -Other examples for self-signatures are binding signatures for subkeys. -In order to add an OpenPGP subkey to a certificate, a subkey binding signature is calculated over the public primary key, followed by the public subkey. -The resulting subkey binding signature (type 0x18) can then be inserted into the certificate right after the subkey. -If the subkey itself is intended to be used as a **S**igning key, an extra step is required. -To prevent an attacker from being able to "adopt" a victims signing subkey and then being able to claim to be the origin of signatures in fact made by victim, subkey binding signatures for signing subkeys need to include an embedded "back signature" (formally known as primary key binding signature) made by the signing key itself. - -Certifications over user IDs can also be used to certify certificates of third-parties. -If Alice is certain that `Bob Baker ` controls the key 0xB0B, she can create a user ID certification signature for that identity and send it to Bob. -Bob can then add this signature to his certificate. -TODO: More WoT. - -Another important category of signatures are revocations. -A revocation is used to retract the statement formed by a prior signature. -A subkey revocation signature revokes a prior subkey binding signature, while a certification revocation revokes a certification signature. -Typical use-cases for revocations are marking certificates or individual subkeys as unusable, or marking user IDs as no longer used. - -## Signature Subpackets - -A cryptographic signature alone is often not expressive enough to fulfil certain use-cases. -For this reason, the OpenPGP protocol introduced signature subpackets with rfc4880. -These are well-defined data structures that can be placed as subelements into signature packets, which give additional context and meaning to a signature. -Typical examples are the issuer fingerprint subpacket, which contains the fingerprint of the issuer key, or the key flags subpacket which states, what purpose a component key is intended for. - -Signature subpackets can reside in two different areas of a signature packet. -Subpackets in the *hashed area* are incorporated in the digest calculation that is done during signature calculation and are therefore covered by the cryptographic signature. -Hashed subpackets are *authenticated*. -If a subpacket is placed in the *unhashed area* instead, it is not included in the signature calculation procedure. -The unhashed area can be used to retroactively add, change or remove subpackets from a signature without invalidating it. - -Due to the fact that the unhashed area doesn't provide any cryptographic guarantees, it is only intended for advisory packets, or packets that self-authenticate (e.g. issuer key ID / issuer fingerprint subpackets, whose "correctness" can be proven by successfully verifying the signature using the referenced issuer key). -In most cases, signature subpackets are simply added into the hashed area. - -Since the hashed and unhashed areas of a signature are just lists of subpackets, in principle they allow duplicates of the same subpacket, which might lead to conflicts. -Therefore, packets in the hashed area take precendence over the unhashed area. -However, there may still be conflicts between packets in the same area, e.g. two conflicting expiration dates, etc. -The specification recommends that implementations favor the last occurence of a conflicting packet. - -In some cases, duplicate packets with conflicting content even make sense, e.g. if a signature was made by a version 6 issuer key whose key material was migrated from an older OpenPGP version such as v4. -In this case, the v4 key could be used to validate the v6 signature, but since the fingerprint and key ID calculation scheme was changed between v4 and v6, these identifiers would differ. -Therefore, the signature could contain two sets of issuer fingerprint and isuer key ID subpackets with conflicting, but correct values. - -```{admonition} TODO -:class: warning - -- Key Flags -- Preferences -- Embedded Signature (back sig) -- Trust Signatures (amount, depth) -- Direct key signatures -``` diff --git a/book/source/06-signatures.md b/book/source/06-signatures.md new file mode 100644 index 0000000..f8c16f7 --- /dev/null +++ b/book/source/06-signatures.md @@ -0,0 +1,120 @@ + + +# OpenPGP Signatures + +Signatures make up the magic of OpenPGP. They act as the syntax that allows forming and interpreting rich statements about certificates and their components, as well as data. + +Without signatures, there would only be loose keys, impossible to associate with a certificate, or their owner. Signatures are the glue that allows for components (component keys and identity components) to be assembled into hierarchical certificates, and for messages to gain authenticity. + +## Terminology + +The term *signature* can have multiple meanings in the context of OpenPGP: + +- Cryptographic keys create raw signatures which are byte sequences calculated according to some signature scheme. +- [*OpenPGP signature packets*](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#name-signature-packet-type-id-2), which combine a *type* setting, additional metadata, and a raw cryptographic signature. + +For the purpose of this document, the term signature will refer to OpenPGP signature packets. + +```{admonition} VISUAL +:class: warning + +show our visuals for these two layers of meaning? + +- "sig-circle", vs +- box with yellow tag-thing, including sig-circle +``` + +(signature_types)= +## Types of signatures in OpenPGP + +The OpenPGP standard defines a set of [Signature Types](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#name-signature-types), each identified by a numerical *signature type ID*. Signature types define the intent of a signature, and how it needs to be interpreted. + +```{figure} mermaid/06-terminology.png + +An overview of signature types in OpenPGP +``` + +Most OpenPGP signature types can be classified as either: + +- *Signatures over data*, or +- *Signatures on components* (that is: signatures that apply to component keys or identity components). + +In this chapter, we discuss the general principles of OpenPGP signatures, which apply to all types of OpenPGP signatures. + +For more detail about specific types of signatures, see the chapters {ref}`signing_data` and {ref}`component_signatures_chapter`, respectively. + +## Structure of an OpenPGP signature + +As outlined above, an OpenPGP signature is a composite data structure, which combines: + +- A *signature type ID* (see above), which specifies the intended meaning of the signature, +- Metadata (which is variable and depends in part on the type ID), + - Most of this metadata is encoded as so-called "subpackets," see {ref}`signature_subpackets`, +- A raw cryptographic signature. + + +```{admonition} VISUAL +:class: warning + +show a version of our "yellow tag-thing with sig-circle" visual? +``` + +The cryptographic signature is calculated by its issuer. It certifies a hash digest, which in turn combines a set of input data. The exact input data depends on the signature type. Roughly: the hash digest is over the elements that the OpenPGP signature makes a statement about, combined with the metadata in the OpenPGP signature packet itself. More on this later. + +(signature_subpackets)= +## Signature subpackets + +Just a cryptographic signature, combined with a signature type identifier, is often not sufficiently expressive. For this reason, the OpenPGP protocol introduced signature subpackets (in [RFC 2440](https://datatracker.ietf.org/doc/html/rfc2440)). + +Subpackets are well-defined data structures that can be placed into signature packets as subelements. They give additional context and meaning to a signature. Subpackets encode data in a key-value format. All possible keys are defined in the RFC as [subpacket type IDs](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#name-signature-subpacket-types-r), and the value format (and meaning) are defined in the RFC for each subpacket type ID. + +Typical examples are: +- the [*issuer fingerprint*](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#issuer-fingerprint-subpacket) subpacket, which contains the fingerprint of the issuer key, or +- the [*key flags*](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#name-key-flags) subpacket which defines what purpose a component key is used for, in a certificate. + +Signature subpackets can reside in two different areas of a signature packet: + +- Subpackets in the *hashed area* are incorporated in the digest calculation that is done during signature calculation and are therefore covered by the cryptographic signature. In other words; hashed subpackets are *authenticated*. +- If a subpacket is placed in the *unhashed area* instead, it is not included in the signature calculation procedure and is therefore not protected against tampering. The unhashed area can be used to retroactively add, change or remove subpackets from a signature without invalidating it. Since the unhashed area doesn't provide any cryptographic guarantees, it is only intended for advisory packets, or packets that self-authenticate (e.g. the issuer fingerprint subpacket, whose "correctness" can be proven by successfully verifying the signature using the referenced issuer key). + +In most cases, signature subpackets are stored in the hashed area. + +### Criticality of subpackets + +Each signature subpacket has a flag that indicates whether the subpacket is *critical*. + +Since different OpenPGP implementations might support subsets of the standard, it would be fatal if, for example, an implementation did not understand the concept of signature expiration. Such an implementation would potentially accept an already expired signature. +By marking the expiration date subpacket as critical, the user can indicate that implementations that do not understand this type of subpacket are supposed to reject the signature as invalid. + +RFC Sections [5.2.3.11](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#name-signature-creation-time) - [5.2.3.36](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#name-intended-recipient-fingerpr) give guidance on which subpackets are usually marked as critical. + +## Advanced topics + +### Notation signature subpackets + +[Notations](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#notation-data) are a signature subpacket type that can be used to effectively extend the otherwise limited set of signature subpacket types with user-defined notations. An issuer can use notations to add name-value data to an OpenPGP signature. + +Notation names are UTF-8 encoded strings. They may reside in the "user namespace," which means a notation *tag* (in UTF-8 string format) followed by a DNS domain name. + +#### Use of notations by Keyoxide + +Notations have, for example, been used for the popular decentralized identity verification service [Keyoxide](https://keyoxide.org/). Keyoxide uses notations in the `ariadne.id` namespace. See the [Keyoxide documentation](https://docs.keyoxide.org/wiki/ariadne-identity/) for more details. + +### "Negotiating" signature hash algorithm based on recipients preference subpackets + +```{admonition} TODO +:class: warning + +investigate, discuss: GnuPG uses preference packets for the User ID that was addressed while sequoia completely omits User ID preferences and either uses Direct Key Sigs or (I think) primary User ID. +``` + +### Explore viability of having multiple signatures, e.g. v4+v6? + +```{admonition} TODO +:class: warning + +C-R 5.2. says: An implementation MUST generate a version 6 signature when signing with a version 6 key. An implementation MUST generate a version 4 signature when signing with a version 4 key. +``` diff --git a/book/source/07-signing_data.md b/book/source/07-signing_data.md index a778c09..77d0642 100644 --- a/book/source/07-signing_data.md +++ b/book/source/07-signing_data.md @@ -6,13 +6,72 @@ SPDX-License-Identifier: CC-BY-SA-4.0 (signing_data)= # Signatures over data -```{admonition} TODO -:class: warning +A data signature guarantees the authenticity (and implicitly also the integrity) of a message, e.g., an email or a file. -Add content, including: +Note that signatures over data are different from {ref}`component_signatures_chapter`, which are used to attach metadata or subkeys to a certificate. -- Signature of a binary document +One major use case for OpenPGP is to create signatures for software packages or emails. These are examples for signatures over data, with OpenPGP. -- Signature of a canonical text document - - "The signature is calculated over the text data with its line endings converted to ``" -``` +When signing data, OpenPGP offers the advantage that it comes with mechanisms for strong authentication, based on bindings between certificates and identities, and the option to certify those bindings. + +Other signing solutions, like [signify](https://flak.tedunangst.com/post/signify), typically only offer a solution for pure signing, without offering +a mechanism for authentication. + +## Signature types + +Two OpenPGP [signature types](signature_types) apply to data signatures: + +- Signature of a binary document (*Binary Signature*, type ID `0x00`): a universal signature type for binary data. This signature type is typically used for files or data streams. +Binary signatures are calculated over the data "as is", without performing any transformations. +- Signature of a canonical text document (*Text Signature*, type ID `0x01`): used for textual data, such as email bodies. When calculating a text signature, the data is first normalized by converting line endings into a canonical form (``). This normalization mitigates issues caused by platform-specific default text encodings. + (This can be useful for detached signatures, when the message file may get re-encoded between signature generation and validation) + +Data signatures are always calculated by a component key that carries the *signing* key flag. + +Data signatures are created by hashing the message content and calculating a cryptographic signature over the hash. +The resulting cryptographic signature is stored in an OpenPGP signature packet, which can be used in different ways: + +## Forms of OpenPGP data signatures + +OpenPGP signatures over data can be generated and distributed in three forms[^sign-modes-gpg]: + +- *Detached*: The signature is a standalone artifact, separate from the signed data. +- *Inline*: The original data and the signature over the data are stored in an OpenPGP container. +- *Cleartext signature*: A method to sign text while leaving the original message in a human-readable format. + +[^sign-modes-gpg]: These signature forms correspond with GnuPG's `--detach-sign`, `--sign` and `--clear-sign` modes. + +### Detached signatures + +A detached signature is produced by calculating an OpenPGP signature over a piece of data. +The resulting OpenPGP signature packet can then be distributed alongside or independent of the original data. + +This method is especially useful for signing software releases and other files that must not be modified by the signing process. + +### Inline signatures + +This method is usually used with signed and/or encrypted emails. + +Most clients that support OpenPGP for encrypted and/or signed messages make use of inline-signatures. +To produce a signature, the entirety of the data needs to be processed by the producer. This has the consequence that an application that efficiently emits signed data can only append the signature at the end of the data stream. +On the other hand, an application that needs to efficiently verify signed data needs to know the signer's public key and used hash algorithm before processing the data. +To solve this issue, so-called One-Pass-Signature packets are prefixed to the signed data. Those are small packets containing the fingerprint of the signing key, as well as the used hash algorithm. This is all the information a receiving application needs to know to initiate the verification process. + +To produce an inline-signed message, the original data is first wrapped in a Literal Data packet, which is prefixed with one or more One-Pass-Signature packets, and affixed with the corresponding signature packets. +The verifying application can read the One-Pass-Signature packets and initiate the verification process. +The literal data can then be processed, such that the signatures at the end of the message can be verified in *one pass*. + +TODO: explain nesting of OPSs. + +### Cleartext signatures + +The *Cleartext Signature Framework* (CSF) is a mechanism that combines two goals: + +- It leaves the message in clear text format, so that it can be viewed directly by a human in a program that knows nothing about OpenPGP. +- But also adds an OpenPGP signature that allows verification of that message by users whose software supports OpenPGP. + +TODO: explain text transforms for cleartext signatures (LF->CRLF etc) + +#### Pitfalls + +The RFC points out a number of [pitfalls of cleartext signatures](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#name-issues-with-the-cleartext-s), and advises that in many cases, the inline and detached signature forms are preferable. diff --git a/book/source/08-signature_internals.md b/book/source/08-signature_internals.md deleted file mode 100644 index 250abcd..0000000 --- a/book/source/08-signature_internals.md +++ /dev/null @@ -1,18 +0,0 @@ - - -# Signature "internals" - -```{admonition} TODO -:class: warning - - - Subpackets and how to make sense of them - - "Negotiating" signature hash algorithm based on recipients preference subpackets - - Explore viability of having multiple signatures, e.g. v4+v6? -``` - -## Notations - -## Zooming in: Packet structure diff --git a/book/source/08-signing_components.md b/book/source/08-signing_components.md new file mode 100644 index 0000000..ae75c3a --- /dev/null +++ b/book/source/08-signing_components.md @@ -0,0 +1,340 @@ + + +(certifications_chapter)= + +# Signatures on components + +In this chapter, we'll consider OpenPGP signatures that apply to components. That is, signatures that apply to: + +- Component keys (primary keys or subkeys), or +- Identity components (User IDs or User attributes). + +This chapter adds a lot of detail to the material we discussed in the {ref}`certificates_chapter` chapter. Signatures on components are a crucial mechanism for forming OpenPGP certificates (which combine component keys and identities, via signatures on those components). + +Additionally, signatures on components play a crucial role for authentication of identities. Mechanisms for decentralized authentication are one of OpenPGP's core strenghts, we'll look into how they work. + +Finally, signatures on components are also a central mechanism for life-cycle management of OpenPGP certificates and their components. This includes defining or changing expiration dates, or issuing revocations, for certificates or their components. + +## Self-signatures and third-party signatures + +There are two important scenarios to distinguish: + +- *Self-signatures*: Issued by the certificate's owner, using the primary key of the same certificate. +- *Third-party signatures*: Issued by a key that is part of a different certificate. + +### Meaning differs between self- and third-party signatures + +The meaning of a signature depends in part on who issued it. A self-signature often has a different meaning from a signature issued by a third party. + +For example: + +- A [direct key signature](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#name-direct-key-signature-type-i) issued as a self-signature can be used to set preferences and advertise features that apply to the whole certificate, while +- A similar [direct key signature](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#name-direct-key-signature-type-i) issued by a third party, which carries a [trust signature](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#name-trust-signature) subpacket, acts as a statement by the issuer that they delegate trust to the signed certificate (the issuer thereby uses the remote certificate as a trust root in the *Web of Trust*). + +Or: + +- Certifying self-signatures (type IDs `0x10` - `0x13`) are used to bind a User ID to a certificate, while +- the same signature type IDs issued by a third party are statements by the signer that they endorse the authenticity of the signed User ID to some degree. + +There are further signature types for signatures on data, as well as designated types to bind and revoke subkeys. + +## Signatures on components + +A typical use-case for a self-signature is to attach a User ID, such as a name and email address to a certificate. +This is done by calculating the signature over the User ID and the public primary key. +The resulting User ID certification (typically type 0x13, potentially type 0x10-0x12) can then be inserted into the certificate, right after the User ID packet. + +Other examples for self-signatures are binding signatures for subkeys. To add an OpenPGP subkey to a certificate, a subkey binding signature is calculated over the public primary key, followed by the public subkey. +The resulting subkey binding signature (type 0x18) can then be inserted into the certificate right after the subkey. +If the subkey itself is intended to be used as a **S**igning key, an extra step is required. +To prevent an attacker from being able to "adopt" a victims signing subkey and then being able to claim to be the origin of signatures in fact made by victim, subkey binding signatures for signing subkeys need to include an embedded "back signature" (formally known as [primary key binding signature](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#sigtype-primary-binding)) made by the signing key itself. + +Certifications over User IDs can also be used to certify certificates of third-parties. +If Alice is certain that `Bob Baker ` controls the key `0xB0B`, she can create a User ID certification signature for that identity and send it to Bob. +Bob can then add this signature to his certificate. +TODO: More WoT. + +```{note} +The **certify others** key flag is not required in order to issue certifying self-signatures. +This key flag is only necessary to issue valid third-party certifications. +``` + +### Revocations + +One important class of self-signatures are revocations. + +A revocation signature is used to retract the statement formed by a prior signature. +A subkey revocation signature revokes a prior subkey binding signature, while a certification revocation revokes a certification signature. +Typical use-cases for revocations are marking certificates or individual subkeys as unusable (for example, when the private key has been compromised or superseded), or marking User IDs as no longer used. + +A revocation signature can either be hard or soft. A soft revocation of a certificate invalidates it from the revocation signature's creation time onwards. This means signatures issued before the revocation remain intact. A hard revocation, by contrast, invalidates the certificate retroactively, rendering all issued signatures invalid, regardless of creation time. Soft revocations are typically used whenever a key or User ID is retired or superseded gracefully, while hard revocations can, for example, signal compromise of secret key material. + +## Self-signatures: Linking the components of a certificate + +So far we've looked at the components in an OpenPGP certificate, but certificates actually contain another set of elements, which bind the components together, and add metadata to them. + +Internally, an OpenPGP certificate consists of a sequence of OpenPGP packets. These packets are just stringed together, one after the other. When a certificate is stored in a file[^tpk], it's easy to remove some of these packets, or add new ones. + +[^tpk]: When stored in a file, OpenPGP certificates are in a format called [transferable public key](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#name-transferable-public-keys). + +However, the owner of a certificate doesn't want a third party to add subkeys (or add [identity components](identity_components)) to their certificate, pretending that the certificate owner put those components there. + +To prevent malicious addition of components, OpenPGP uses cryptographic signatures. These signatures show that components have been added by the owner of the OpenPGP certificate (these linking signatures are issued by the primary key of the certificate). + +So while anyone can still unilaterally store unrelated subkeys and [identity components](identity_components) in an OpenPGP certificate dataset, OpenPGP implementations that read this certificate should discard components that don't have a valid cryptographic connection with the certificate. + +(Conversely, it's easy for a third party to leave out packets when passing on an OpenPGP certificate. An attacker can, for example, choose to omit revocation packets. The recipient of such a partial copy has no way to notice the omission, without access to a different source for the certificate that contains the revocation packet.) + +Note, though, that there are some cases where third parties legitimately add "unbound" packets to certificates (that is: packets that are not signed by the certificate's owner): + +- [Third-party certifications](third_party_cert) are traditionally added to the certificate that they make a statement about (this can cause problems in systems that unconditionally accept and include such certifications[^flooding]), +- OpenPGP software may add [unbound identity data](unbound_user_ids), locally. + +[^flooding]: Storing third-party identity certifications in the target OpenPGP certificate is convenient for consumers: it is easy to find all relevant certifications in one central location. However, when third parties can unilaterally add certifications, this opens an avenue for denial-of-service attacks by flooding. The SKS network of OpenPGP key servers [allowed and experienced this problem](https://dkg.fifthhorseman.net/blog/openpgp-certificate-flooding.html). + +### Binding subkeys to a certificate + +Linking a subkey to an OpenPGP certificate is done with a ["Subkey Binding Signature"](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#sigtype-subkey-binding). Such a signature signals that the "primary key wants to be associated with the subkey". + +The subkey binding signature also adds metadata. + +```{figure} diag/subkey_binding_signature.png + +Linking an OpenPGP subkey to the primary key with a binding signature +``` + +The [Signature packet](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#name-signature-packet-tag-2) that binds the subkey to the primary key has the signature type [SubkeyBinding](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#name-subkey-binding-signature-si). + + +In order to specify an expiration time for the subkey, a key expiration time subpacket can be included. Note, that the validity of the subkey is bounded by that of the primary key, meaning an expired primary key causes the subkey to be invalidated, no matter the subkey expiration time. + +Note, that a subkey cannot be "older" than the primary key. The value of the subkeys creation date MUST be greater than that of the primary key. + +### Special case: Binding signing subkeys to a certificate + +Binding subkeys with the "signing" key flag is a special case. For the most part, it works the same as binding other types of subkeys, but there is an additional requirement: + +When binding a signing subkey to a primary key, it is not sufficient that the "primary key wants to be associated with the subkey." In addition, the subkey must signal that it "wants to be associated with that primary key." + +Otherwise, Alice could "adopt" Bob's signing subkey and convincingly claim that she made signatures that were in fact issued by Bob. +This is to prevent an attack where the attacker "adopts" the victims signing subkey as their own in order to claim ownership over documents which were in fact signed by the victim. +Contrary to the `SubkeyBinding` signature, which is issued by the certificates primary key, the `PrimaryKeyBinding` signature is instead created by the subkey. + +```{figure} diag/subkey_binding_signatur_for_signing_sk.png + +Linking an OpenPGP signing subkey to the primary key with a binding signature, and an embedded primary key binding signature +``` + +This additional "Primary Key Binding" Signature is informally called a "back signature" (because the subkey uses the signature to point "back" to the primary key) is an embedded `PrimaryKeyBinding` "back signature" (type 0x19). + + +### Binding identities to a certificate + +"User ID" identity components are bound to an OpenPGP certificate by issuing a self-signature ("User Attributes" work analogously). + +For example, the User ID `Alice Adams ` may be associated with Alice's certificate `AAA1 8CBB 2546 85C5 8358 3205 63FD 37B6 7F33 00F9 FB0E C457 378C D29F 1026 98B3`. + +Alice can link a User ID to her OpenPGP certificate with a cryptographic signature. To link a User ID, a self-signature is created (usually with the signature type [PositiveCertification](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#sigtype-positive-cert)). This signature is issued by the primary key. + +```{figure} diag/user_id_certification.png +--- +--- +Linking a User ID to an OpenPGP certificate +``` + +This signature is calculated over the primary key and User ID. + + +(direct_key_signature)= +### Direct key signature: Adding metadata to the primary key + +```{admonition} TODO +:class: warning + +explain metadata associated with this signature, and that c-r prefers this over primary user id. +``` + +### Revocations: Invalidating components of a certificate + +```{admonition} TODO +:class: warning + +This section only contains notes and still needs to be written +``` + +Note: certification signatures [can be made irrevocable](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#name-revocable). + +#### Hard vs. soft revocations + +A revocation signature may contain a subpacket indicating the reason for revocation. This subpacket contains a code which specifies why the revocation was issued. This code determines, whether the revocation is hard or soft. + +A soft revocation is typically used for graceful or planned revocations. A soft revocation can be reverted by re-validating the certificate, User ID or subkey with a fresh binding signature. +A soft revocation invalidates the target certificate beginning with the revocations creation time. + +Contrary, a hard revocation cannot be re-validated. Furthermore, a hard-revoked certificate is invalidated retroactively. + +A missing revocation reason subpacket is equivalent with a hard revocation reason. + +## Third-party signatures: Making statements about other people's certificates and identities + +```{admonition} TODO +:class: warning + +write +``` + +## Advanced topics + +### Certification Recipes + +As mentioned above, different signatures are used for different purposes. +In this section, we will try to give guidance on how to create certain signatures by example. + +#### Change Algorithm Preferences + +In order to change what symmetric, compression, hash or AEAD algorithms are preferred by the key owner, they can issue a direct-key signature (type 0x1F) on the primary key. +This signature should have the following structure: + +| Subpacket | Area | Critical | Mandatory | Notes | +|-----------|------|----------|-----------|-------| +| Signature Creation Time | Hashed | True | True | Current time | +| Issuer Fingerprint | Hashed | True or false | Strongly recommended | The primary key is the issuer | +| Key Flags | Hashed | True | False | Carry over key flags from previous self-signature | +| Features | Hashed | True | False | Carry over features from previous self-signature | +| Key Expiration Time | Hashed | True | False | Carry over expiration time from previous self-signature, if present | +| Hash Alg. Pref. | Hashed | False | False | New preferences | +| Comp. Alg. Pref. | Hashed | False | False | New preferences | +| Symm. Alg. Pref. | Hashed | False | False | New preferences | +| AEAD Alg. Pref. | Hashed | False | False | New preferences | + +#### Change Expiration Time + +The recommended way to change the expiration time of a certificate is by issuing a new `DirectKey` signature (type 0x1F) with an adjusted Key Expiration Time subpacket. +The structure of such a signature is the same as in the section above. +It is also possible to change the expiration date of individual User IDs (see section below) or separate subkeys (see [section X](#add_subkey)). + +#### Add User ID + +A signature that binds a User ID to a certificate should have the following structure: + +| Subpacket | Area | Critical | Mandatory | Notes | +|-----------|------|----------|-----------|-------| +| Signature Creation Time | Hashed | True | True | Current time | +| Issuer Fingerprint | Hashed | True or false | Strongly Recommended | The primary key is the issuer | +| Primary User ID | Hashed | True | False | Optional | +| Signature Expiration Time | Hashed | True | False | Optional | + +Self-certifications over User IDs can optionally carry the same subpackets as listed in the previous table (key flags, features, algorithm preferences). +This way, separate capabilities can be assigned to different identities. + +#### Remove / Revoke User ID + +Since OpenPGP certificates are often distributed by the means of key servers, new signatures on a certificate are often "merged" into existing copies of the certificate locally by the recipient. +This means, that it is not really possible to remove signatures / User IDs from a certificate, as there is no way to communicate the intention of packet deletion to the recipient. + +So to mark a User ID as invalid, the user can publish a copy of their certificate with a `CertificationRevocation` (signature type 0x30) attached to the invalidated User ID. +This signature signals that the holder of the certificate no longer wants to be associated with that User ID. + +The structure of a certification revocation is as follows: + +| Subpacket | Area | Critical | Mandatory | Notes | +|-----------|------|----------|-----------|-------| +| Signature Creation Time | Hashed | True | True | Current time | +| Issuer Fingerprint | Hashed | True or false | Strongly Recommended | The primary key is the issuer | +| Reason for Revocation | Hashed | True | False | Decides over soft / hard revocation | + +For User ID revocations, the value of the reason subpacket can either be `0` (no reason specified) or `32`, signaling that the User ID is no longer valid. +The latter would result in a soft revocation, while a reason code of `0` is considered a hard revocation. +Omitting the reason packet altogether is also equivalent to a hard revocation. +It is recommended to issue User ID certifications using a reason code `32` and to do certificate revocations using a direct-key signature. + +(binding_subkeys)= +#### Add a Subkey + +For the purpose of key freshness, a user might want to add a new subkey to their certificate. + + +The structure is as follows: + +| Subpacket | Area | Critical | Mandatory | Notes | +|-----------|------|----------|-----------|-------| +| Signature Creation Time | Hashed | True | True | Current time | +| Issuer Fingerprint | Hashed | True or false | Strongly Recommended | The primary key is the issuer | +| Key Flags | Hashed | True | Strongly Recommended | Determine the usage of the key | +| Key Expiration Time | Hashed | True | False | Specifies the expiration date of the subkey | +| Embedded Signature | Hashed | True | If Key Flags contains **S** | Signing subkeys require embedded `PrimaryKeyBinding` signature | +| Hash Alg. Pref. | Hashed | False | False | Per key preferences | +| Comp. Alg. Pref. | Hashed | False | False | Per key preferences | +| Symm. Alg. Pref. | Hashed | False | False | Per key preferences | +| AEAD Alg. Pref. | Hashed | False | False | Per key preferences | + +Optional algorithm preference subpackets can be used to signal per-subkey preferences that deviate from those set in the certificates `DirectKey` signature. + +#### Revoke a Subkey + +Analogous to User IDs, subkeys can be revoked individually. +This is done by issuing a `SubkeyRevocation` signature (type 0x28) using the primary key. +The structure of such a signature is rather minimal: + +| Subpacket | Area | Critical | Mandatory | Notes | +|-----------|------|----------|-----------|-------| +| Signature Creation Time | Hashed | True | True | Current time | +| Issuer Fingerprint | Hashed | True or false | Strongly Recommended | The primary key is the issuer | +| Reason for Revocation | Hashed | True | False | Decides over soft / hard revocation | + +In `SubkeyRevocation` signatures, the reason subpacket cannot have value `32`, but instead may be from the range of `0-3`. +Values `1` (key superseded) and `3` (key retired and no longer used) are soft reasons, while `0` (no reason) and `2` (key compromised) are considered hard. + +#### Revoke a Certificate + +A user might want to revoke their whole certificate, rendering it unusable. +Depending on the circumstances, they might either want to revoke it softly, e.g. in case of migration to a new certificate, or they want to issue a hard revocation, e.g. in case of secret key material compromise. A soft-revoked certificate can be re-validated at a later point in time, by issuing a new certification, while a hard revocation is typically permanent. + +The recommended way to revoke a certificate is by issuing a `KeyRevocation` signature (type 0x20). +The structure of a key revocation signature is similar to that of a `CertificationRevocation` signature. + +| Subpacket | Area | Critical | Mandatory | Notes | +|-----------|------|----------|-----------|-------| +| Signature Creation Time | Hashed | True | True | Current time | +| Issuer Fingerprint | Hashed | True or false | Strongly Recommended | The primary key is the issuer | +| Reason for Revocation | Hashed | True | False | Decides over soft / hard revocation | + +For `KeyRevocation` signatures, the same constraints as for `SubkeyRevocation` signatures apply to the reason subpacket. + +#### Common Subpackets + +There are some subpackets that are expected to be included in any type of signature. + +* **Signature Creation Time**: Every OpenPGP signature MUST contain a Signature Creation Time subpacket (2) containing the timestamp at which the signature was made. This packet MUST be present in the hashed area of the signature and SHOULD be marked as critical. + +* **Issuer Fingerprint**: To be able to verify a signature, the verifier needs to know which (sub-)key was used to issue the signature in the first place. Therefore, every OpenPGP v6 signature SHOULD contain an Issuer Fingerprint subpacket (33) containing the 32 byte fingerprint of the particular component key that was used to create the signature. + +```{note} +The issuer key might be a subkey. +``` + +Since the issuer fingerprint subpacket is self-authenticating, it can either be included as a hashed or unhashed subpacket, but the authors of this book recommend to place it in the hashed area of the signature. + +### Potential subpacket conflicts and duplication + +Since the hashed and unhashed areas of a signature are just lists of subpackets, in principle they allow duplicates of the same subpacket, which might lead to conflicts. +Therefore, packets in the hashed area take precedence over the unhashed area. +However, there may still be conflicts between packets in the same area, e.g., two conflicting expiration dates, etc. +The [specification recommends](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-12.html#name-notes-on-subpackets) that implementations favor the last occurrence of a conflicting packet in the hashed area. + +In some cases, duplicate packets with conflicting content even make sense, e.g., if a signature was made by a version 4 issuer key whose key material was migrated from an older OpenPGP version such as v3. +In this case, either the v3 or v4 key could be used to validate the v4 signature, but since the key ID calculation scheme was changed between v3 and v4, these identifiers would differ. +Therefore, the signature could contain two isuer key ID subpackets with conflicting, but correct values. + +```{admonition} TODO +:class: warning + +- Key Flags +- Preferences +- Embedded Signature (back sig) +- Trust Signatures (amount, depth) +- Direct key signatures +``` diff --git a/book/source/19-zoom_signatures.md b/book/source/19-zoom_signatures.md index 7f29aef..f384ef4 100644 --- a/book/source/19-zoom_signatures.md +++ b/book/source/19-zoom_signatures.md @@ -3,4 +3,229 @@ SPDX-FileCopyrightText: 2023 The "Notes on OpenPGP" project SPDX-License-Identifier: CC-BY-SA-4.0 --> +(zoom_sign_data)= # Zooming in: Packet structure of data signatures + +In this chapter, we'll create signatures using [Alice's private key](alice_priv) material, and inspect the packet structure of those signatures. + +In some examples, we'll use a test-message that contains the string `hello world` followed by one line feed (`0x0a`) character: + +```text +$ echo "hello world" > message.txt +``` + +## Detached signature + +We can produce a detached signature for this "hello world" message, using Alice's private signing key material: + +```text +$ sq sign --detached --signer-file alice.pgp message.txt +-----BEGIN PGP SIGNATURE----- + +wpgGABsKAAAAKQWCZT0tDyIhBtB7JOyRoU3SQKwtU+bIqeBUlJpBIi6nOFdu0Zyu +o9yZAAAAANueIJCkVJ5aC1Zw485o7Y72uHPnk7ktkZyhKH2MuHjCdIHQU0qe/8bR +0B3ywHNzLwUoqj0efYWhj6XeXa08haxUH7i50MEDjfFrPc281B0C5fiiGN4PYc76 +B8tA2/ZjsSgHCw== +=n8EV +-----END PGP SIGNATURE----- +``` + +And inspect the packet structure of this signature: + +```text +$ sq packet dump --hex detached-sig.txt +Signature Packet, new CTB, 2 header bytes + 152 bytes + Version: 6 + Type: Binary + Pk algo: Ed25519 + Hash algo: SHA512 + Hashed area: + Signature creation time: 2023-10-28 15:47:27 UTC (critical) + Issuer Fingerprint: D07B24EC91A14DD240AC2D53E6C8A9E054949A41222EA738576ED19CAEA3DC99 + Digest prefix: DB9E + Level: 0 (signature over data) + + 00000000 c2 CTB + 00000001 98 length + 00000002 06 version + 00000003 00 type + 00000004 1b pk_algo + 00000005 0a hash_algo + 00000006 00 00 00 29 hashed_area_len + 0000000a 05 subpacket length + 0000000b 82 subpacket tag + 0000000c 65 3d 2d 0f sig creation time + 00000010 22 subpacket length + 00000011 21 subpacket tag + 00000012 06 version + 00000013 d0 7b 24 ec 91 a1 4d d2 40 ac 2d 53 e6 issuer fp + 00000020 c8 a9 e0 54 94 9a 41 22 2e a7 38 57 6e d1 9c ae + 00000030 a3 dc 99 + 00000033 00 00 00 00 unhashed_area_len + 00000037 db digest_prefix1 + 00000038 9e digest_prefix2 + 00000039 20 salt_len + 0000003a 90 a4 54 9e 5a 0b salt + 00000040 56 70 e3 ce 68 ed 8e f6 b8 73 e7 93 b9 2d 91 9c + 00000050 a1 28 7d 8c b8 78 c2 74 81 d0 + 0000005a 53 4a 9e ff c6 d1 ed25519_sig + 00000060 d0 1d f2 c0 73 73 2f 05 28 aa 3d 1e 7d 85 a1 8f + 00000070 a5 de 5d ad 3c 85 ac 54 1f b8 b9 d0 c1 03 8d f1 + 00000080 6b 3d cd bc d4 1d 02 e5 f8 a2 18 de 0f 61 ce fa + 00000090 07 cb 40 db f6 63 b1 28 07 0b +``` + +## Inline signature + +```text +$ sq sign --signer-file alice.pgp message.txt +-----BEGIN PGP MESSAGE----- + +xEYGAAobIK+vlFDAK62+055LpOCoOGecp66NiyRz6M+emCLp5Nbg0Hsk7JGhTdJA +rC1T5sip4FSUmkEiLqc4V27RnK6j3JkByxJiAAAAAABoZWxsbyB3b3JsZArCmAYA +GwoAAAApBYJlPXuNIiEG0Hsk7JGhTdJArC1T5sip4FSUmkEiLqc4V27RnK6j3JkA +AAAAhrggr6+UUMArrb7Tnkuk4Kg4Z5ynro2LJHPoz56YIunk1uApSiAe9CYGgqrs +p6Ud6ARDVcOWWFhxTJK2rNULlZ9k4HPFvUT4PTrjpb4kjRAb6MDgSSclPaj14FjL +rpr/eqQF +=r993 +-----END PGP MESSAGE----- +``` + +```text +$ sq packet dump --hex inline-sig.txt +One-Pass Signature Packet, new CTB, 2 header bytes + 70 bytes + Version: 6 + Type: Binary + Pk algo: Ed25519 + Hash algo: SHA512 + Issuer: D07B24EC91A14DD240AC2D53E6C8A9E054949A41222EA738576ED19CAEA3DC99 + Last: true + + 00000000 c4 CTB + 00000001 46 length + 00000002 06 version + 00000003 00 type + 00000004 0a hash_algo + 00000005 1b pk_algo + 00000006 20 salt_len + 00000007 af af 94 50 c0 2b ad be d3 salt + 00000010 9e 4b a4 e0 a8 38 67 9c a7 ae 8d 8b 24 73 e8 cf + 00000020 9e 98 22 e9 e4 d6 e0 + 00000027 d0 7b 24 ec 91 a1 4d d2 40 issuer + 00000030 ac 2d 53 e6 c8 a9 e0 54 94 9a 41 22 2e a7 38 57 + 00000040 6e d1 9c ae a3 dc 99 + 00000047 01 last + +Literal Data Packet, new CTB, 2 header bytes + 18 bytes + Format: Binary data + Content: "hello world\n" + + 00000000 cb CTB + 00000001 12 length + 00000002 62 format + 00000003 00 filename_len + 00000004 00 00 00 00 date + 00000008 68 65 6c 6c 6f 20 77 6f hello wo + 00000010 72 6c 64 0a rld. + +Signature Packet, new CTB, 2 header bytes + 152 bytes + Version: 6 + Type: Binary + Pk algo: Ed25519 + Hash algo: SHA512 + Hashed area: + Signature creation time: 2023-10-28 21:22:21 UTC (critical) + Issuer Fingerprint: D07B24EC91A14DD240AC2D53E6C8A9E054949A41222EA738576ED19CAEA3DC99 + Digest prefix: 86B8 + Level: 0 (signature over data) + + 00000000 c2 CTB + 00000001 98 length + 00000002 06 version + 00000003 00 type + 00000004 1b pk_algo + 00000005 0a hash_algo + 00000006 00 00 00 29 hashed_area_len + 0000000a 05 subpacket length + 0000000b 82 subpacket tag + 0000000c 65 3d 7b 8d sig creation time + 00000010 22 subpacket length + 00000011 21 subpacket tag + 00000012 06 version + 00000013 d0 7b 24 ec 91 a1 4d d2 40 ac 2d 53 e6 issuer fp + 00000020 c8 a9 e0 54 94 9a 41 22 2e a7 38 57 6e d1 9c ae + 00000030 a3 dc 99 + 00000033 00 00 00 00 unhashed_area_len + 00000037 86 digest_prefix1 + 00000038 b8 digest_prefix2 + 00000039 20 salt_len + 0000003a af af 94 50 c0 2b salt + 00000040 ad be d3 9e 4b a4 e0 a8 38 67 9c a7 ae 8d 8b 24 + 00000050 73 e8 cf 9e 98 22 e9 e4 d6 e0 + 0000005a 29 4a 20 1e f4 26 ed25519_sig + 00000060 06 82 aa ec a7 a5 1d e8 04 43 55 c3 96 58 58 71 + 00000070 4c 92 b6 ac d5 0b 95 9f 64 e0 73 c5 bd 44 f8 3d + 00000080 3a e3 a5 be 24 8d 10 1b e8 c0 e0 49 27 25 3d a8 + 00000090 f5 e0 58 cb ae 9a ff 7a a4 05 +``` + +## Cleartext signature + +```text +$ sq sign --cleartext-signature --signer-file alice.pgp message.txt +-----BEGIN PGP SIGNED MESSAGE----- +Hash: SHA512 + +hello world +-----BEGIN PGP SIGNATURE----- + +wpgGARsKAAAAKQWCZT0vBCIhBtB7JOyRoU3SQKwtU+bIqeBUlJpBIi6nOFdu0Zyu +o9yZAAAAANqgIHAzoRTzu/7Zuxc8Izf4r3/qSCmBfDqWzTXqmVtsSBSHACka3qbN +eehqu8H6S0UK8V7yHbpVhExu9Hu72jWEzU/B0h9MR5gDhJPoWurx8YfyXBDsRS4y +r13/eqMN8kfCDw== +=Ks9w +-----END PGP SIGNATURE----- +``` + +```text +$ sq packet dump --hex cleartext-sig.txt +Signature Packet, new CTB, 2 header bytes + 152 bytes + Version: 6 + Type: Text + Pk algo: Ed25519 + Hash algo: SHA512 + Hashed area: + Signature creation time: 2023-10-28 15:55:48 UTC (critical) + Issuer Fingerprint: D07B24EC91A14DD240AC2D53E6C8A9E054949A41222EA738576ED19CAEA3DC99 + Digest prefix: DAA0 + Level: 0 (signature over data) + + 00000000 c2 CTB + 00000001 98 length + 00000002 06 version + 00000003 01 type + 00000004 1b pk_algo + 00000005 0a hash_algo + 00000006 00 00 00 29 hashed_area_len + 0000000a 05 subpacket length + 0000000b 82 subpacket tag + 0000000c 65 3d 2f 04 sig creation time + 00000010 22 subpacket length + 00000011 21 subpacket tag + 00000012 06 version + 00000013 d0 7b 24 ec 91 a1 4d d2 40 ac 2d 53 e6 issuer fp + 00000020 c8 a9 e0 54 94 9a 41 22 2e a7 38 57 6e d1 9c ae + 00000030 a3 dc 99 + 00000033 00 00 00 00 unhashed_area_len + 00000037 da digest_prefix1 + 00000038 a0 digest_prefix2 + 00000039 20 salt_len + 0000003a 70 33 a1 14 f3 bb salt + 00000040 fe d9 bb 17 3c 23 37 f8 af 7f ea 48 29 81 7c 3a + 00000050 96 cd 35 ea 99 5b 6c 48 14 87 + 0000005a 00 29 1a de a6 cd ed25519_sig + 00000060 79 e8 6a bb c1 fa 4b 45 0a f1 5e f2 1d ba 55 84 + 00000070 4c 6e f4 7b bb da 35 84 cd 4f c1 d2 1f 4c 47 98 + 00000080 03 84 93 e8 5a ea f1 f1 87 f2 5c 10 ec 45 2e 32 + 00000090 af 5d ff 7a a3 0d f2 47 c2 0f +``` diff --git a/book/source/diag/subkey_binding_signatur_for_signing_sk.png b/book/source/diag/subkey_binding_signatur_for_signing_sk.png new file mode 100644 index 0000000..d4cc751 Binary files /dev/null and b/book/source/diag/subkey_binding_signatur_for_signing_sk.png differ diff --git a/book/source/diag/subkey_binding_signature.png b/book/source/diag/subkey_binding_signature.png new file mode 100644 index 0000000..0a68fd5 Binary files /dev/null and b/book/source/diag/subkey_binding_signature.png differ diff --git a/book/source/diag/subkey_binding_signature.svg b/book/source/diag/subkey_binding_signature.svg new file mode 100644 index 0000000..e42149c --- /dev/null +++ b/book/source/diag/subkey_binding_signature.svg @@ -0,0 +1,871 @@ + +C0A5 8384 A438 E5A1 4F73 7124 26A4 D45D BAEE F4A3 9E6B 30B0 9D55 13F9 78AC CA94FingerprintPrimary key creates a "subkey binding signature" to bind the subkey to the primary keySubkey binding signatureComponent KeyencryptionC0A5 8384 A438 E5A1 4F73 7124 26A4 D45D BAEE F4A3 9E6B 30B0 9D55 13F9 78AC CA94- key creation timeComponent Key (primary)AAA1 8CBB 2546 85C5 8358 3205 63FD 37B6 7F33 00F9 FB0E C457 378C D29F 1026 98B3certification- key creation timeSubkey binding signature- signature creation time- key expiration time- key flags- issuer fingerprintAdditional MetadataSignature over:- primary key- subkey diff --git a/book/source/diag/user_id_certification.png b/book/source/diag/user_id_certification.png index 5f4c7e5..1765602 100644 Binary files a/book/source/diag/user_id_certification.png and b/book/source/diag/user_id_certification.png differ diff --git a/book/source/mermaid/06-terminology.md b/book/source/mermaid/06-terminology.md new file mode 100644 index 0000000..4e49a41 --- /dev/null +++ b/book/source/mermaid/06-terminology.md @@ -0,0 +1,49 @@ +```{mermaid} +%%{ init: { 'flowchart': { 'curve': '' } } }%% +flowchart LR + signature(OpenPGP Signature) + 3rdcert(Third-Party Certification) + data(Data Signature) + selfcert(Self-Signature) + certification("Third-Party Certification + -------------------------------- + Self-Certification") + + signature --> data & selfcert & 3rdcert & confsig & standalone & timestamp + data --> binary & text + selfcert --> skbind & skrev + selfcert & 3rdcert --> certification + certification --> uidcert & uidrev & dksig & krev + subgraph Siganture Types and Targets + standalone[0x02: Standalone] + subgraph Signature Packet + confsig[0x50: Third-Party Confirmation] + timestamp[0x40: Timestamp] + end + subgraph Data + binary[0x00: Binary Data] + text[0x01: Canonical Text] + end + subgraph Primary Key + User ID / Attr. Packet + uidcert[ + 0x10: Generic Certification + 0x11: Persona Certification + 0x12: Casual Certification + 0x13: Positive Certification + ] + uidrev[0x30: Certification Revocation] + end + subgraph Primary Key + dksig[0x1F: Direct-Key Signature] + krev[0x20: Key Revocation] + end + subgraph Primary + Subkey + skbind[ + 0x18: Subkey Binding + 0x19: Primary Key Binding + ] + skrev[0x28: Subkey Revocation] + end + end +``` + diff --git a/book/source/mermaid/06-terminology.png b/book/source/mermaid/06-terminology.png new file mode 100644 index 0000000..55f8814 Binary files /dev/null and b/book/source/mermaid/06-terminology.png differ