From 7617d7eea66ba0e2956b6e4640d0acb92c7510fa Mon Sep 17 00:00:00 2001 From: Heiko Schaefer Date: Wed, 11 Oct 2023 17:59:06 +0200 Subject: [PATCH] ch4: write "user id" zooming in section --- book/source/04-certificates.md | 195 ++++++++++++--------------------- 1 file changed, 72 insertions(+), 123 deletions(-) diff --git a/book/source/04-certificates.md b/book/source/04-certificates.md index 83c5e22..b1367a6 100644 --- a/book/source/04-certificates.md +++ b/book/source/04-certificates.md @@ -482,6 +482,7 @@ The overall structure of OpenPGP packets is described in the [Packet Syntax](htt Note that the *Secret-Key packet* contains both the private and the public part of the key. +(zooming_in_dks)= #### Direct Key Signature The next packet is a [*Direct Key Signature*](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#sigtype-direct-key), which is bound to the primary key (the file `alice.priv-1--Signature` contains this packet). @@ -580,7 +581,7 @@ Critical here means: the receiver must be able to interpret the subpacket and is ``` - [Signature creation time](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#signature-creation-subpacket) (subpacket type 2, **critical**): `0x6516eaa6` (also see [Time Fields](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#name-time-fields)) -- [Key expiration time](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#key-expiration-subpacket) (subpacket type 9, **critical**): `0x05a48fbd` (also see [Time Fields](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#name-time-fields)) +- [Key expiration time](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#key-expiration-subpacket) (subpacket type 9, **critical**): `0x05a48fbd` (defined as number of seconds after the key creation time) - [Preferred symmetric ciphers for v1 SEIPD](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#preferred-v1-seipd) (type 11): `0x09 0x07`. (These values [correspond to](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#symmetric-algos): *AES with 256-bit key* and *AES with 128-bit key*) - [Preferred hash algorithms](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#preferred-hashes-subpacket) (subpacket type 21): `0x0a 0x08`. (These values [correspond to](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#name-hash-algorithms): *SHA2-512* and *SHA2-256*) - [Key flags](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#key-flags) (subpacket type 27, **critical**): `0x01`. (This value [corresponds](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#name-key-flags) to the *certifications* key flag) @@ -665,6 +666,7 @@ A minimal OpenPGP public certificate, visualized In the following examples, we will only look at OpenPGP keys that include the private key material. The corresponding "certificate" variants, which only contain the public key material, are easy to imagine: like here, their packet type is changed from a Secret-Key to a Public-Key variant, and they leave out the private key material. +(zoom_enc_subkey)= ### Encryption subkey Now we'll look at a subkey in Alice's key. An OpenPGP subkey, when it is linked to an OpenPGP certificate (via its primary key), effectively consists of two elements: @@ -812,7 +814,7 @@ The first difference is in the `type` field, showing that this signature is of t The `pk_algo` of this signature is informed by the algorithm of the primary key (`0x1b`, corresponding to Ed25519). The signature in this packet is issued by the primary key, so by definition it uses the signing algorithm of the primary key (that is: the algorithm used to produce the cryptographic signature in this packet is entire independent of the `pk_algo` of the key material of this subkey itself, which uses the X25519 mechanism). -As shown in the header of this packet dump, the hashed subpacket data contains four pieces of information: +As shown in the text at the top of this packet dump, the hashed subpacket data contains four pieces of information: - Signature creation time: `2023-09-29 15:17:58 UTC` (**critical**) - Key expiration time: `P1095DT62781S` (**critical**) @@ -952,127 +954,20 @@ Signature Packet, new CTB, 3 header bytes + 325 bytes ``` (zooming_in_user_id)= -### User ID +### Adding an identity component -User IDs are a mechanism for attaching *identities* to an OpenPGP certificate. Traditionally, User IDs contain a string that combines a name and an email address. +Now we'll look at an identity that is associated with Alice's certificate. -To look into these, we'll make a certificate that has one [User ID](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#uid). 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. +User IDs are a mechanism for connecting [identities](identity_components) with an OpenPGP certificate. Traditionally, User IDs contain a string that combines a name and an email address. -Let's look into the details of this key: +Like [above](zoom_enc_subkey), to look at the internal packet structure of this identity and its connection the OpenPGP certificate, we'll inspect the two individual packets that constitute the identity component, the [User ID packet](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#name-user-id-packet-tag-13), in the file `alice.priv-2--UserID`, and the certifying self-signature a [Positive certification of a User ID and Public-Key packet](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#name-positive-certification-of-a) in `alice.priv-3--Signature` (these packets are an excerpt of Alice's full OpenPGP private key). + +#### User ID packet + +First, let's look at the User ID packet, which encodes an identity that Alice has connected to her OpenPGP certificate: ```text ------BEGIN PGP PRIVATE KEY BLOCK----- -Comment: AAA1 8CBB 2546 85C5 8358 3205 63FD 37B6 7F33 00F9 FB0E C457 378C D29F 1026 98B3 -Comment: - -xUsGZRbqphsAAAAgUyTpQ6+rFfdu1bUSmHlpzRtdEGXr50Liq0f0hrOuZT4A7+GZ -tV8R+6qT6CadO7ItciB9/71C3UvpozaBO6XMz/vCtgYfGwoAAAA9BYJlFuqmBYkF -pI+9AwsJBwMVCggCmwECHgEiIQaqoYy7JUaFxYNYMgVj/Te2fzMA+fsOxFc3jNKf -ECaYswAAAAoJEKqhjLslRoXFZ0cgouNjgeNr0E9W18g4gAIl6FM5SWuQxg12j0S0 -7ExCOI5NPRDCrSnAV85mAXOzeIGeiVLPQ40oEal3CX/L+BXIoY2sIEQrLd4TAEEy -0BA8aQZTPEmMdiOCM1QB+V+BQZAOzRM8YWxpY2VAZXhhbXBsZS5vcmc+wrkGExsK -AAAAQAWCZRbqpgWJBaSPvQMLCQcDFQoIApkBApsBAh4BIiEGqqGMuyVGhcWDWDIF -Y/03tn8zAPn7DsRXN4zSnxAmmLMAAAAKCRCqoYy7JUaFxdu4IIotb9pnNbxdBHe0 -nWeobsXWiFNf4u/5Zgi/wuDbwFYN69QspRkBD7om0IKiz1zreqly2fOyZgeLsro9 -t4nkdgRuNSQrJymDvpGceGrMtNVpR3YsKdZUv0MZBP9TmMDVCw== -=bgQM ------END PGP PRIVATE KEY BLOCK----- -``` - -```text -$ sq packet dump --hex alice_userid.priv -Secret-Key Packet, new CTB, 2 header bytes + 75 bytes - Version: 6 - Creation time: 2023-09-29 15:17:58 UTC - Pk algo: Ed25519 - Pk size: 256 bits - Fingerprint: AAA18CBB254685C58358320563FD37B67F3300F9FB0EC457378CD29F102698B3 - KeyID: AAA18CBB254685C5 - - Secret Key: - - Unencrypted - - 00000000 c5 CTB - 00000001 4b length - 00000002 06 version - 00000003 65 16 ea a6 creation_time - 00000007 1b pk_algo - 00000008 00 00 00 20 public_len - 0000000c 53 24 e9 43 ed25519_public - 00000010 af ab 15 f7 6e d5 b5 12 98 79 69 cd 1b 5d 10 65 - 00000020 eb e7 42 e2 ab 47 f4 86 b3 ae 65 3e - 0000002c 00 s2k_usage - 0000002d ef e1 99 ed25519_secret - 00000030 b5 5f 11 fb aa 93 e8 26 9d 3b b2 2d 72 20 7d ff - 00000040 bd 42 dd 4b e9 a3 36 81 3b a5 cc cf fb - -Signature Packet, new CTB, 2 header bytes + 182 bytes - Version: 6 - Type: DirectKey - Pk algo: Ed25519 - Hash algo: SHA512 - Hashed area: - Signature creation time: 2023-09-29 15:17:58 UTC (critical) - Key expiration time: P1095DT62781S (critical) - Symmetric algo preferences: AES256, AES128 - Hash preferences: SHA512, SHA256 - Key flags: C (critical) - Features: MDC - Issuer Fingerprint: AAA18CBB254685C58358320563FD37B67F3300F9FB0EC457378CD29F102698B3 - Unhashed area: - Issuer: AAA18CBB254685C5 - Digest prefix: 6747 - Level: 0 (signature over data) - - 00000000 c2 CTB - 00000001 b6 length - 00000002 06 version - 00000003 1f type - 00000004 1b pk_algo - 00000005 0a hash_algo - 00000006 00 00 00 3d hashed_area_len - 0000000a 05 subpacket length - 0000000b 82 subpacket tag - 0000000c 65 16 ea a6 sig creation time - 00000010 05 subpacket length - 00000011 89 subpacket tag - 00000012 05 a4 8f bd key expiry time - 00000016 03 subpacket length - 00000017 0b subpacket tag - 00000018 09 07 pref sym algos - 0000001a 03 subpacket length - 0000001b 15 subpacket tag - 0000001c 0a 08 pref hash algos - 0000001e 02 subpacket length - 0000001f 9b subpacket tag - 00000020 01 key flags - 00000021 02 subpacket length - 00000022 1e subpacket tag - 00000023 01 features - 00000024 22 subpacket length - 00000025 21 subpacket tag - 00000026 06 version - 00000027 aa a1 8c bb 25 46 85 c5 83 issuer fp - 00000030 58 32 05 63 fd 37 b6 7f 33 00 f9 fb 0e c4 57 37 - 00000040 8c d2 9f 10 26 98 b3 - 00000047 00 00 00 0a unhashed_area_len - 0000004b 09 subpacket length - 0000004c 10 subpacket tag - 0000004d aa a1 8c issuer - 00000050 bb 25 46 85 c5 - 00000055 67 digest_prefix1 - 00000056 47 digest_prefix2 - 00000057 20 salt_len - 00000058 a2 e3 63 81 e3 6b d0 4f salt - 00000060 56 d7 c8 38 80 02 25 e8 53 39 49 6b 90 c6 0d 76 - 00000070 8f 44 b4 ec 4c 42 38 8e - 00000078 4d 3d 10 c2 ad 29 c0 57 ed25519_sig - 00000080 ce 66 01 73 b3 78 81 9e 89 52 cf 43 8d 28 11 a9 - 00000090 77 09 7f cb f8 15 c8 a1 8d ac 20 44 2b 2d de 13 - 000000a0 00 41 32 d0 10 3c 69 06 53 3c 49 8c 76 23 82 33 - 000000b0 54 01 f9 5f 81 41 90 0e - +$ sq packet dump --hex alice.priv-2--UserID User ID Packet, new CTB, 2 header bytes + 19 bytes Value: @@ -1080,7 +975,22 @@ User ID Packet, new CTB, 2 header bytes + 19 bytes 00000001 13 length 00000002 3c 61 6c 69 63 65 40 65 78 61 6d 70 6c 65 value 00000010 2e 6f 72 67 3e +``` +- `CTB: 0xcd`: The Packet Tag for this packet. Bits 7 and 6 show that the packet is in “OpenPGP packet format” (as opposed to in “Legacy packet format”). The remaining 6 bits encode the Tag’s value: “13.” This is the value for a [User ID packet](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#name-user-id-packet-tag-13). +- `length: 0x13`: The remaining length of this packet (here: 19 bytes). +- `value`: 19 bytes of data that contain UTF-8 encoded text. The value corresponds to the string ``. With this identity component, Alice states that she uses (and has control of) this email address. Note that the email address is enclosed in `<` and `>` characters, following [RFC 2822](https://www.rfc-editor.org/rfc/rfc2822) conventions. + +So, a User ID packet is really just a string, marked as a User ID by the packet type id. + +#### Linking the User ID with a certification self-signature + +As above, when [linking a subkey](zoom_enc_subkey) to the OpenPGP certificate, a self-signature is used to connect this new component to the certificate. + +To bind identities to a certificate with a self-signature, one of the signature types `0x10` - `0x13` can be used. Here, the signature type `0x13` (*positive certification*) is used. + +```text +$ sq packet dump --hex alice.priv-3--Signature Signature Packet, new CTB, 2 header bytes + 185 bytes Version: 6 Type: PositiveCertification @@ -1151,13 +1061,52 @@ Signature Packet, new CTB, 2 header bytes + 185 bytes 000000b0 54 bf 43 19 04 ff 53 98 c0 d5 0b ``` -Instead of two packets, as before, we see four packets in this certificate: -* First, a "Secret-Key Packet," -* then a "Signature Packet" (these two packets are the same as above). -* Third, a [*"User ID Packet"*](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#uid), which contains the name and email address we used -* Finally, a [*"Positive Certification Signature"*](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#sigtype-positive-cert) (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) +We'll go over this packet dump in less detail, since its structure closely mirrors the [Direct Key Signature](zooming_in_dks) discussed above. +We're again looking at a Signature packet. Its `type` is `0x13` ([corresponding](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-10.html#name-signature-types) to a *positive certification* signature). + +The public key algorithm and hash function used for this signature are Ed25519 and SHA512. + +As shown in the text at the top of this packet dump, the hashed subpacket data contains the following metadata: + +- Signature creation time: `2023-09-29 15:17:58 UTC` (**critical**) +- Key expiration time: `P1095DT62781S` (**critical**) +- Symmetric algo preferences: `AES256, AES128` +- Hash preferences: `SHA512, SHA256` +- Primary User ID: `true` (**critical**) +- Key flags: `C` (**critical**) +- Features: `MDC` +- Issuer Fingerprint: `AAA18CBB254685C58358320563FD37B67F3300F9FB0EC457378CD29F102698B3` + +This is a combination of metadata about the User ID itself (including defining this User ID as the *primary User ID* of this certificate), algorithm preferences that are associated with this identity, and settings that apply to the primary key. + +````{note} +For historical reasons, the self-signature that binds the primary User ID to the certificate also contains subpackets that apply not to the User ID, but to the primary key itself. + +Setting key expiration time and key flags on the primary User ID self-signature is one mechanism to configure the primary key. + +The interaction between metadata on direct key signatures and User ID binding self-signatures [is subtle](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-11.html#name-notes-on-self-signatures), and there are changes between version 6 and version 4. + + +```{admonition} TODO +:class: warning + +- link to a section that goes into more depth about "#name-notes-on-self-signatures"? +``` + +```` + +Followed, again, by the (informational) unhashed subpacket area. + +And finally, a salt value for the signature and the signature itself. + +The signature is calculated over a hash. The hash, in this case, is calculated over the following data (for details, see [Computing Signatures](https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-11.html#name-computing-signatures) in the RFC): + +- The signature's salt +- A serialized form of the primary key's public data +- A serialized form of the User ID +- A serialized form of this self-signature packet (up to, but excluding the unhashed area) ### Certifications (Third Party Signatures)