diff --git a/book/source/04-certificates.md b/book/source/04-certificates.md index 449b083..4dd44bf 100644 --- a/book/source/04-certificates.md +++ b/book/source/04-certificates.md @@ -1,59 +1,43 @@ (certificates_chapter)= # Certificates / Keys -One central (and non-trivial) element of OpenPGP are certificates/keys. -OpenPGP keys are relatively complex data structures, so it's good to have -a clear mental model of them. +One central (and non-trivial) element of OpenPGP are certificates/keys. OpenPGP keys are relatively complex data structures, so it's good to have a clear mental model of them. -## Terminology: on the various meanings of "key" +## Terminology: various meanings of "key" + +[Two dimensions: 1. private/public, 2. level of abstraction] In the OpenPGP space, the term "key" has historically been used for three distinct concepts, at three layers, all related to each other: -- (Bare) "cryptographic keys" (without additional metadata). - Those might be the secret and/or public parameters that form a key, e.g., in case of an RSA secret key the exponent `d` along with the prime numbers `p` and `q`. -- OpenPGP *component keys*: "OpenPGP primary keys" and "OpenPGP subkeys". - Those are building blocks of OpenPGP certificates, - they consist of a (bare) cryptographic keypair, plus some invariant metadata (e.g. key creation time). -- "OpenPGP key" (or "OpenPGP certificate"): - These consist of a number of component keys plus additional elements, - such as identity information. - (OpenPGP key servers serve this type of object). +- (Bare) "cryptographic keys" (without additional metadata). Those might be the private and/or public parameters that form a key, e.g., in case of an RSA private key, the exponent `d` along with the prime numbers `p` and `q`. +- OpenPGP *component keys*: "OpenPGP primary keys" and "OpenPGP subkeys". Those are building blocks of OpenPGP certificates. They consist of a (bare) cryptographic keypair, plus some invariant metadata (e.g. key creation time). +- "OpenPGP certificate" (often called "OpenPGP key"): These consist of a number of component keys plus additional elements, such as identity information. (OpenPGP key servers serve this type of object). -In the following section we'll look more closely at these three layers. +In the following section, we'll look more closely at these three layers. ## "OpenPGP keys/certificates": collections of cryptographic keys, identity information and other metadata -A complete "OpenPGP certificate" or "OpenPGP key" is composed of an -arbitrary number of elements. +A complete "OpenPGP certificate" or "OpenPGP key" is composed of an arbitrary number of elements. -All elements of an OpenPGP certificate are structured around one central -cryptographic key: the *primary key*. -The primary key acts like a personal CA for the key's owner: -It can make cryptographic statements about subkeys, identities, -expiration times, revocation, ... +All elements of an OpenPGP certificate are structured around one central cryptographic key: the *primary key*. The primary key acts like a personal CA for the key's owner: It can make cryptographic statements about subkeys, identities, expiration times, revocation, ... -OpenPGP keys are often long-lived and may be changed (typically by their -owner), over time. +OpenPGP keys are often long-lived and may be changed (typically by their owner), over time. ### OpenPGP component keys -An OpenPGP component key (either the "primary key", or a "subkey") -consists mainly of a cryptographic keypair: +An OpenPGP component key (either the "primary key", or a "subkey") consists mainly of a cryptographic keypair: ![Image](diag/cryptographic_keys.png "A cryptographic keypair") -A cryptographic keypair consists of a private and a public part. -In this document, we'll show the public part of a cryptographic key in green, -and the private part in red. +A cryptographic keypair consists of a private and a public part. In this document, we'll show the public part of a cryptographic key in green, and the private part in red. We'll visualize cryptographic keypairs in a more compact form: ![Image](diag/keypair.png "A cryptographic keypair") -(In some contexts, instead of the full cryptographic keypair, only the -public part is present. More on that later.) +(In some contexts, instead of the full cryptographic keypair, only the public part is present. More on that later.) An OpenPGP component key consists of @@ -62,22 +46,18 @@ An OpenPGP component key consists of ![Image](diag/primary_key.png "An OpenPGP component key") -For each OpenPGP component key, an *OpenPGP fingerprint* can be derived -from the combination of key material and metadata: +For each OpenPGP component key, an *OpenPGP fingerprint* can be derived from the combination of key material and metadata: ![Image](diag/fingerprint.png "Each OpenPGP component key has a fingerprint") -The fingerprint of our example component OpenPGP key is -`B3D2 7B09 FBA4 1235 2B41 8972 C8B8 6AC4 2455 4239` [^keyid]. +The fingerprint of our example component OpenPGP key is `B3D2 7B09 FBA4 1235 2B41 8972 C8B8 6AC4 2455 4239` [^keyid]. -The fingerprint of the primary key has a central role. -It is used as the unique identifier for the full OpenPGP certificate. +The fingerprint of the primary key has a central role. It is used as the unique identifier for the full OpenPGP certificate. ## What is in a certificate (Structure) / Components of an OpenPGP key/certificate -In addition to the primary key, OpenPGP keys/certificates can contain a -number of other components: +In addition to the primary key, OpenPGP keys/certificates can contain a number of other components: ### Subkeys @@ -87,14 +67,11 @@ Modern OpenPGP keys/certificates contain "subkeys" in addition to the primary ke A component key consists of a cryptographic keypair, plus some additional metadata. -Each component key (this includes the primary key, and all subkeys) has a -marker that specifies which operations the component key can perform. +Each component key (this includes the primary key, and all subkeys) has a marker that specifies which operations the component key can perform. #### Excursion, "Key Flags": defining what operations a component key can perform -Each component key has -["Key Flags"](https://datatracker.ietf.org/doc/html/rfc4880#section-5.2.3.21) -that specify which types of operation the key can perform. +Each component key has ["Key Flags"](https://datatracker.ietf.org/doc/html/rfc4880#section-5.2.3.21) that specify which types of operation the key can perform. The commonly used flags are: @@ -103,19 +80,13 @@ The commonly used flags are: - **E**ncryption - **A**uthentication -Only the primary key can perform "certification" operations. -All other operations can technically be performed by either the primary -key or subkeys. +Only the primary key can perform "certification" operations. All other operations can technically be performed by either the primary key or subkeys. -It is considered good practice to have separate component keys for each -type of operation (specifically: to allow only *Certification* operations -for the primary key, and to have separate *Signing*, *Encryption* and -*Authentication* subkeys). +It is considered good practice to have separate component keys for each type of operation (specifically: to allow only *Certification* operations for the primary key, and to have separate *Signing*, *Encryption* and *Authentication* subkeys). ### User IDs -An OpenPGP certificate can contain any number of User IDs. -Each user ID associates the certificate with an identity. +An OpenPGP certificate can contain any number of User IDs. Each user ID associates the certificate with an identity. Typically, these identities are composed of a name and an email address. @@ -130,30 +101,17 @@ User attributes are similar to User IDs, but less commonly used. ## Linking the components of an OpenPGP certificate together / Bindings -Technically, an OpenPGP certificate consists of a sequence of OpenPGP packets. -These packets are just stringed together, one after the other. -When you have a file that contains a copy of someone's certificate, -it's easy to remove some of these packets, or add new ones. +Technically, an OpenPGP certificate consists of a sequence of OpenPGP packets. These packets are just stringed together, one after the other. When you have a file that contains a copy of someone's certificate, it's easy to remove some of these packets, or add new ones. -However, as the owner of a certificate, I don't want a third party to -add additional subkeys (or identity claims) to my certificate. I don't want -third parties to pretend that those components were put there by me. +However, as the owner of a certificate, I don't want a third party to add additional subkeys (or identity claims) to my certificate. I don't want third parties to pretend that those components were put there by me. -To prevent such malicious addition of components, OpenPGP uses cryptographic -signatures. These signatures show the cryptographic identity that has linked -a component to an OpenPGP certificate (in many cases, the linking is done -by the primary key of the certificate in question). +To prevent such malicious addition of components, OpenPGP uses cryptographic signatures. These signatures show the cryptographic identity that has linked a component to an OpenPGP certificate (in many cases, the linking is done by the primary key of the certificate in question). -So while anyone can still unilaterally put subkeys and identity claims -into a file with my OpenPGP certificate, OpenPGP implementations that -read the file are expected to discard components that aren't -cryptographically linked to my certificate. +So while anyone can still unilaterally put subkeys and identity claims into a file with my OpenPGP certificate, OpenPGP implementations that read the file are expected to discard components that aren't cryptographically linked to my certificate. ### "Binding" subkeys to an OpenPGP certificate -Linking a subkey to an OpenPGP certificate is done with a -["Subkey Binding Signature"](https://datatracker.ietf.org/doc/html/rfc4880#section-5.2.1). -Such a signature signals that the "primary key wants to be associated with the subkey". +Linking a subkey to an OpenPGP certificate is done with a ["Subkey Binding Signature"](https://datatracker.ietf.org/doc/html/rfc4880#section-5.2.1). Such a signature signals that the "primary key wants to be associated with the subkey". The subkey binding signature also adds metadata. @@ -166,30 +124,20 @@ The subkey binding signature also adds metadata. #### Binding signing subkeys -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. +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. +Otherwise, Alice could "adopt" Bob's signing subkey and convincingly claim that she made signatures that were in fact issued by Bob. -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). +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). ### Certifying identity claims / Third party signatures -OpenPGP certificate often contain identity markers. Typically in the form -of "User ID"s (however, User Attributes are analogous for the purpose of -this section). +OpenPGP certificates often contain identity markers. Typically, in the form of "User ID"s (however, User Attributes are analogous for the purpose of this section). -For example, above, we saw the User ID "Alice Adams " -associated with Alice's key `B3D2 7B09 FBA4 1235 2B41 8972 C8B8 6AC4 2455 4239`. +For example, above, we saw the User ID "Alice Adams " associated with Alice's key `B3D2 7B09 FBA4 1235 2B41 8972 C8B8 6AC4 2455 4239`. -Alice can link a User ID to her OpenPGP certificate with a cryptographic -signature. To link a User ID, a signature of the type `PositiveCertification` -is created. The signature is issued using the primary (secret) key. +Alice can link a User ID to her OpenPGP certificate with a cryptographic signature. To link a User ID, a signature of the type `PositiveCertification` is created. The signature is issued using the primary (secret) key. ![Image](diag/user_id_certification.png "Linking a User ID to an OpenPGP certificate") @@ -203,62 +151,36 @@ is created. The signature is issued using the primary (secret) key. Minimized versions, merging, effective "append only" semantics, ... ### Merging + - How to merge two copies of the same certificate? - Canonicalization ### Best Practices regarding Key Freshness + - Expiry - Subkey rotation -- + ## Third party (identity) certifications ## Revocations -[^keyid]: Sometimes, a shortened (64 bit) version of the fingerprint is used instead -of the full fingerprint, like this: `C8B8 6AC4 2455 4239` (the rightmost -64 bit of the fingerprint). This type of identifier is called a "Key ID". -Historically, 32 bit shorthand identifiers have been used with PGP, -like this: `2455 4239`. You may still see such identifiers in very old -documents about PGP, but 32 bit identifiers have -[been unfit for purpose for a long time](https://evil32.com/). -At some point, 32 bit identifiers were called "short Key ID", while -64 bit identifiers were called "long Key ID". +[^keyid]: Sometimes, a shortened (64 bit) version of the fingerprint is used instead of the full fingerprint, like this: `C8B8 6AC4 2455 4239` (the rightmost 64 bit of the fingerprint). This type of identifier is called a "Key ID". Historically, 32 bit shorthand identifiers have been used with PGP, like this: `2455 4239`. You may still see such identifiers in very old documents about PGP, but 32 bit identifiers have [been unfit for purpose for a long time](https://evil32.com/). At some point, 32 bit identifiers were called "short Key ID", while 64 bit identifiers were called "long Key ID". -## Looking at the internal details +## Zooming in: Looking at the package structure and internals -To use OpenPGP, we need "(OpenPGP) keys". +To use OpenPGP, we need "(OpenPGP) keys." -There is an ongoing effort to establish new terminology around "keys". In -particular to use the term "certificate" instead of "(OpenPGP) public key". +There is an ongoing effort to establish new terminology around "keys." In particular, to use the term "certificate" instead of "(OpenPGP) public key." -Note: there is also the related, but distinct, concept of -[cryptographic "keys"](https://en.wikipedia.org/wiki/Key_(cryptography)). -OpenPGP certificates/keys contain one or more cryptographic key(s), among -many other components. +Note: there is also the related, but distinct, concept of [cryptographic "keys"](https://en.wikipedia.org/wiki/Key_(cryptography)). OpenPGP certificates/keys contain one or more cryptographic key(s), among many other components. -An OpenPGP certificate/key consists of a number of elements, many of them -optional. OpenPGP certificates/keys always make use of -[Public-key cryptography (asymmetric cryptography)](https://en.wikipedia.org/wiki/Public-key_cryptography). +An OpenPGP certificate/key consists of a number of elements, many of them optional. OpenPGP certificates/keys always make use of [Public-key cryptography (asymmetric cryptography)](https://en.wikipedia.org/wiki/Public-key_cryptography). -As a consequence, some elements of OpenPGP certificates/keys represent -"private" (sometimes referred to as "secret") key material, while other -elements represent "public" key material. -Yet other elements contain metadata, and finally there are elements that -serve as glue ("binding") between the various other elements of a -certificate. +As a consequence, some elements of OpenPGP certificates/keys represent "private" (sometimes referred to as "secret") key material, while other elements represent "public" key material. Yet other elements contain metadata, and finally there are elements that serve as glue ("binding") between the various other elements of a certificate. -To hand out copies of one's OpenPGP key to third parties, -implementations can generate a "certificate" / "public key" representation -([Transferable Public Keys](https://tools.ietf.org/html/rfc4880#section-11.1) -in the RFC), -which consists of all the elements of the certificate, except for -the private key material (and the optional -[S2K configuration](https://tools.ietf.org/html/rfc4880#section-3.7.2.1)). +To hand out copies of one's OpenPGP key to third parties, implementations can generate a "certificate" / "public key" representation ([Transferable Public Keys](https://tools.ietf.org/html/rfc4880#section-11.1) in the RFC), which consists of all the elements of the certificate, except for the private key material (and the optional [S2K configuration](https://tools.ietf.org/html/rfc4880#section-3.7.2.1)). -The counterpart is called -[Transferable Secret Keys](https://tools.ietf.org/html/rfc4880#section-11.2) -in the RFC. That is, an OpenPGP key that includes private key -material. +The counterpart is called [Transferable Secret Keys](https://tools.ietf.org/html/rfc4880#section-11.2) in the RFC. That is, an OpenPGP key that includes private key material. ### A minimal OpenPGP key @@ -269,8 +191,7 @@ A minimal key can be made with Sequoia-PGP like this: #### Seen as a private OpenPGP key -Viewed as a private key (in ASCII-armored representation), such a minimal key -looks like this: +Viewed as a private key (in ASCII-armored representation), such a minimal key looks like this: ``` -----BEGIN PGP PRIVATE KEY BLOCK----- @@ -285,9 +206,7 @@ HhhgNE7noeQEsJmR0yW7tTYT8RyrJF6o2xZENlXdCw== -----END PGP PRIVATE KEY BLOCK----- ``` -Looking into the internals of this key with `sq packet dump --hex`, -or https://dump.sequoia-pgp.org/, we see that it is made up of a sequence -of "Packets": +Looking into the internals of this key with `sq packet dump --hex`, or https://dump.sequoia-pgp.org/, we see that it is made up of a sequence of "Packets": ``` Secret-Key Packet, new CTB, 2 header bytes + 88 bytes @@ -382,31 +301,15 @@ Signature Packet, new CTB, 2 header bytes + 131 bytes We see that the key consists of two packets: -* First a - [*"Secret-Key Packet"*](https://tools.ietf.org/html/rfc4880#section-5.5.1.3), - which contains the actual cryptographic key data. Note: the "Secret-Key" - Packet contains both the private and the public part of the key. - We also see in the output that this packet is "Unencrypted" (i.e. not - password-protected). -* Second a - [*"Signature Packet"*](https://tools.ietf.org/html/rfc4880#section-5.2) - of type 0x1F, *"Signature directly on a key"*. - This packet *"binds the information in the Signature subpackets to the key"*. - Each entry under "Signature Packet -> Hashed area" is one Signature - subpacket, - including for example information about algorithm preferences (*"Symmetric - algo preferences"* and *"Hash preferences"*). +* First, a [*"Secret-Key Packet"*](https://tools.ietf.org/html/rfc4880#section-5.5.1.3), which contains the actual cryptographic key data. Note: the "Secret-Key" Packet contains both the private and the public part of the key. We also see in the output that this packet is "Unencrypted" (i.e. not password-protected). +* Second, a [*"Signature Packet"*](https://tools.ietf.org/html/rfc4880#section-5.2) of type 0x1F, *"Signature directly on a key"*. This packet *"binds the information in the Signature subpackets to the key"*. Each entry under "Signature Packet -> Hashed area" is one Signature subpacket, including for example information about algorithm preferences (*"Symmetric algo preferences"* and *"Hash preferences"*). ![Image](diag/key-minimal.png "A minimal OpenPGP key, visualized") #### Seen as a public certificate -Let's compare this with the same certificate seen as an armored "public" -certificate (that is, a variant of the key above, but without the private key -material. An OpenPGP user might give such a certificate to a -communication partner, so that the remote party could send encrypted -messages to the user): +Let's compare this with the same certificate seen as an armored "public" certificate (that is, a variant of the key above, but without the private key material. An OpenPGP user might give such a certificate to a communication partner, so that the remote party could send encrypted messages to the user): ``` -----BEGIN PGP PUBLIC KEY BLOCK----- @@ -502,12 +405,9 @@ Signature Packet, new CTB, 2 header bytes + 131 bytes 00000080 44 36 55 dd 0b ``` -Note that the two OpenPGP artifacts (public certificate and private key) -are almost identical. +Note that the two OpenPGP artifacts (public certificate and private key) are almost identical. -The public certificate uses the packet type "Public-Key Packet" -instead of "Secret-Key Packet". The two packet types are very similar. -The "Public-Key Packet" leaves out two types of data +The public certificate uses the packet type "Public-Key Packet" instead of "Secret-Key Packet". The two packet types are very similar. The "Public-Key Packet" leaves out two types of data * the private key material (visualized in red), and * s2k configuration data, if any (this example doesn't have any). @@ -515,20 +415,14 @@ The "Public-Key Packet" leaves out two types of data ![Image](diag/pubcert-minimal.png "A minimal OpenPGP public certificate, visualized") -In following examples we will look at OpenPGP private keys only. The -corresponding public certificates are easy to imagine (just leave out the -private key material). +In the following examples, we will look at OpenPGP private keys only. The corresponding public certificates are easy to imagine (just leave out the private key material). ### User IDs -User IDs are a mechanism for attaching *identities* to an OpenPGP -certificate. Typically, a User ID will contain a name and an email address. +User IDs are a mechanism for attaching *identities* to an OpenPGP certificate. Typically, a User ID will contain a name and an email address. -To look into these, we'll make a certificate that has one -[User ID](https://tools.ietf.org/html/rfc4880#section-5.11). -User IDs are *"intended to represent the name and email address of the key -holder"*. A certificate can have multiple User IDs associated with it. +To look into these, we'll make a certificate that has one [User ID](https://tools.ietf.org/html/rfc4880#section-5.11). User IDs are *"intended to represent the name and email address of the key holder"*. A certificate can have multiple User IDs associated with it. ``` let (cert, _) = CertBuilder::new() @@ -720,28 +614,15 @@ Signature Packet, new CTB, 2 header bytes + 134 bytes Instead of two sections, as before, we see four sections in this certificate: -* First a "Secret-Key Packet", +* First, a "Secret-Key Packet," * then a "Signature Packet" (these two packets are the same as above). -* Third, a - [*"User ID Packet"*](https://tools.ietf.org/html/rfc4880#section-5.11), - which contains the name and email address we used -* Finally a - [*"Signature Packet"*](https://tools.ietf.org/html/rfc4880#section-5.2) - of type 0x13, *"Positive certification of a User ID and Public-Key packet"*. - This is a cryptographic artifact that "binds the User ID packet and the - Key packet together", i.e. it certifies that the owner of the key wants - this User ID associated with their key. - (Only the person who controls the private part of this key can create this - signature packet. The signature serves as proof that the owner of the key - has added this User ID to the certificate) +* Third, a [*"User ID Packet"*](https://tools.ietf.org/html/rfc4880#section-5.11), which contains the name and email address we used +* Finally, a [*"Signature Packet"*](https://tools.ietf.org/html/rfc4880#section-5.2) of type 0x13, *"Positive certification of a User ID and Public-Key packet"*. This is a cryptographic artifact that "binds the User ID packet and the Key packet together", i.e. it certifies that the owner of the key wants this User ID associated with their key. (Only the person who controls the private part of this key can create this signature packet. The signature serves as proof that the owner of the key has added this User ID to the certificate) ### Subkeys - -From here on, we'll look at the dumps in shorter format (you can see more -detail by copying the certificates into the web-dumper at -https://dump.sequoia-pgp.org/ and checking the "HexDump" checkbox). +From here on, we'll look at the dumps in shorter format (you can see more detail by copying the certificates into the web-dumper at https://dump.sequoia-pgp.org/ and checking the "HexDump" checkbox). ### Certifications (Signatures)