1 2#------------------------------------------------------------------------------ 3# $File: pgp-binary-keys,v 1.2 2021/04/26 15:56:00 christos Exp $ 4# pgp-binary-keys: This file handles pgp binary keys. 5# 6# An PGP certificate or message doesn't have a fixed header. Instead, 7# they are sequences of packets: 8# 9# https://tools.ietf.org/html/rfc4880#section-4.3 10# 11# whose order conforms to a grammar: 12# 13# https://tools.ietf.org/html/rfc4880#section-11 14# 15# Happily most packets have a few fields that are constrained, which 16# allow us to fingerprint them with relatively high certainty. 17# 18# A PGP packet is described by a single byte: the so-called CTB. The 19# high-bit is always set. If bit 6 is set, then it is a so-called 20# new-style CTB; if bit 6 is clear, then it is a so-called old-style 21# CTB. Old-style CTBs have only four bits of type information; bits 22# 1-0 are used to describe the length. New-style CTBs have 6 bits of 23# type information. 24# 25# Following the CTB is the packet's length in bytes. If we blindly 26# advance the file cursor by this amount past the end of the length 27# information we come to the next packet. 28# 29# Data Structures 30# =============== 31# 32# New Style CTB 33# ------------- 34# 35# https://tools.ietf.org/html/rfc4880#section-4.2.2 36# 37# 76543210 38# ||\----/ 39# || tag 40# |always 1 41# always 1 42# 43# Tag bits 7 and 6 set 44# 0 0xC0 -- Reserved - a packet tag MUST NOT have this value 45# 1 0xC1 -- Public-Key Encrypted Session Key Packet 46# 2 0xC2 -- Signature Packet 47# 3 0xC3 -- Symmetric-Key Encrypted Session Key Packet 48# 4 0xC4 -- One-Pass Signature Packet 49# 5 0xC5 -- Secret-Key Packet 50# 6 0xC6 -- Public-Key Packet 51# 7 0xC7 -- Secret-Subkey Packet 52# 8 0xC8 -- Compressed Data Packet 53# 9 0xC9 -- Symmetrically Encrypted Data Packet 54# 10 0xCA -- Marker Packet 55# 11 0xCB -- Literal Data Packet 56# 12 0xCC -- Trust Packet 57# 13 0xCD -- User ID Packet 58# 14 0xCE -- Public-Subkey Packet 59# 17 0xD1 -- User Attribute Packet 60# 18 0xD2 -- Sym. Encrypted and Integrity Protected Data Packet 61# 19 0xD3 -- Modification Detection Code Packet 62# 60 to 63 -- Private or Experimental Values 63# 64# The CTB is followed by the length header, which is densely encoded: 65# 66# if length[0] is: 67# 0..191: one byte length (length[0]) 68# 192..223: two byte length ((length[0] - 192) * 256 + length[2] + 192 69# 224..254: four byte length (big endian interpretation of length[1..5]) 70# 255: partial body encoding 71# 72# The partial body encoding is similar to HTTP's chunk encoding. It 73# is only allowed for container packets (SEIP, Compressed Data and 74# Literal). 75# 76# Old Style CTB 77# ------------- 78# 79# https://tools.ietf.org/html/rfc4880#section-4.2.1 80# 81# CTB: 82# 83# 76543210 84# ||\--/\/ 85# || | length encoding 86# || tag 87# |always 0 88# always 1 89# 90# Tag: 91# 92# Tag bit 7 set, bits 6, 1, 0 clear 93# 0 0x80 -- Reserved - a packet tag MUST NOT have this value 94# 1 0x84 -- Public-Key Encrypted Session Key Packet 95# 2 0x88 -- Signature Packet 96# 3 0x8C -- Symmetric-Key Encrypted Session Key Packet 97# 4 0x90 -- One-Pass Signature Packet 98# 5 0x94 -- Secret-Key Packet 99# 6 0x98 -- Public-Key Packet 100# 7 0x9C -- Secret-Subkey Packet 101# 8 0xA0 -- Compressed Data Packet 102# 9 0xA4 -- Symmetrically Encrypted Data Packet 103# 10 0xA8 -- Marker Packet 104# 11 0xAC -- Literal Data Packet 105# 12 0xB0 -- Trust Packet 106# 13 0xB4 -- User ID Packet 107# 14 0xB8 -- Public-Subkey Packet 108# 109# Length encoding: 110# 111# Value 112# 0 1 byte length (following byte is the length) 113# 1 2 byte length (following two bytes are the length) 114# 2 4 byte length (following four bytes are the length) 115# 3 indeterminate length: natural end of packet, e.g., EOF 116# 117# An indeterminate length is only allowed for container packets 118# (SEIP, Compressed Data and Literal). 119# 120# Certificates 121# ------------ 122# 123# We check the first three packets to determine if a sequence of 124# OpenPGP packets is likely to be a certificate. The grammar allows 125# the following prefixes: 126# 127# [Primary Key] [SIG] (EOF or another certificate) 128# [Primary Key] [SIG] [User ID] [SIG]... 129# [Primary Key] [SIG] [User Attribute] [SIG]... 130# [Primary Key] [SIG] [Subkey] [SIG]... 131# [Primary Key] [User ID] [SIG]... 132# [Primary Key] [User Attribute] [SIG]... 133# [Primary Key] [Subkey] [SIG]... 134# 135# Any number of marker packets are also allowed between each packet, 136# but they are not normally used and we don't currently check for 137# them. 138# 139# The keys and subkeys may be public or private. 140# 141 142# Key packets and signature packets are versioned. There are two 143# packet versions that we need to worry about in practice: v3 and v4. 144# v4 packets were introduced in RFC 2440, which was published in 1998. 145# It also deprecated v3 packets. There are no actively used v3 146# certificates (GnuPG removed the code to support them in November 147# 2014). But there are v3 keys lying around and it is useful to 148# identify them. The next version of OpenPGP will introduce v5 keys. 149# The document has not yet been standardized so changes are still 150# possible. But, for our purposes, it appears that v5 data structures 151# will be identical to v4 data structures modulo the version number. 152# 153# https://tools.ietf.org/html/rfc2440 154# https://lists.gnupg.org/pipermail/gnupg-announce/2014q4/000358.html 155# https://www.ietf.org/id/draft-ietf-openpgp-rfc4880bis-09.html#name-key-material-packet 156 157 158 159 160# The first packet has to be a public key or a secret key. 161# 162# New-Style Public Key 1630 ubyte =0xC6 OpenPGP Public Key 164>&0 use primary_key_length_new 165# New-Style Secret Key 1660 ubyte =0xC5 OpenPGP Secret Key 167>&0 use primary_key_length_new 168# Old-Style Public Key 1690 ubyte&0xFC =0x98 OpenPGP Public Key 170>&-1 use primary_key_length_old 171# Old-Style Secret Key 1720 ubyte&0xFC =0x94 OpenPGP Secret Key 173>&-1 use primary_key_length_old 174 175# Parse the length, check the packet's body and finally advance to the 176# next packet. 177 178# There are 4 different new-style length encodings, but the partial 179# body encoding is only acceptable for the SEIP, Compressed Data, and 180# Literal packets, which isn't valid for any packets in a certificate 181# so we ignore it. 1820 name primary_key_length_new 183>&0 ubyte <192 184#>>&0 ubyte x (1 byte length encoding, %d bytes) 185>>&0 use pgp_binary_key_pk_check 186>>>&(&-1.B) use sig_or_component_1 187>&0 ubyte >191 188>>&-1 ubyte <225 189# offset = ((offset[0] - 192) << 8) + offset[1] + 192 (for the length header) 190# raw - (192 * 256 - 192) 191# = 48960 192#>>>&0 ubeshort x (2 byte length encoding, %d bytes) 193>>>&1 use pgp_binary_key_pk_check 194>>>>&(&-2.S-48960) use sig_or_component_1 195>&0 ubyte =255 196#>>&0 belong x (5 byte length encoding, %d bytes) 197>>&4 use pgp_binary_key_pk_check 198>>>&(&-4.L) use sig_or_component_1 199# Partial body encoding (only valid for container packets). 200# >&0 ubyte >224 201# >>&0 ubyte <255 partial body encoding 202 203# There are 4 different old-style length encodings, but the 204# indeterminate length encoding is only acceptable for the SEIP, 205# Compressed Data, and Literal packets, which isn't valid for any 206# packets in a certificate. 2070 name primary_key_length_old 208#>&0 ubyte x (ctb: %x) 209>&0 ubyte&0x3 =0 210#>>&0 ubyte x (1 byte length encoding, %d bytes) 211>>&1 use pgp_binary_key_pk_check 212>>>&(&-1.B) use sig_or_component_1 213>&0 ubyte&0x3 =1 214#>>&0 ubeshort x (2 byte length encoding, %d bytes) 215>>&2 use pgp_binary_key_pk_check 216>>>&(&-2.S) use sig_or_component_1 217>&0 ubyte&0x3 =2 218#>>&0 ubelong x (4 byte length encoding, %d bytes) 219>>&4 use pgp_binary_key_pk_check 220>>>&(&-4.L) use sig_or_component_1 221 222# Check the Key. 223# 224# https://tools.ietf.org/html/rfc4880#section-5.5.2 2250 name pgp_binary_key_pk_check 226# Valid versions are: 2, 3, 4. 5 is proposed in RFC 4880bis. 227# Anticipate a v6 / v7 format that like v5 is compatible with v4. 228# key format in a decade or so :D. 229>&0 ubyte >1 230>>&-1 ubyte <8 231>>>&-1 byte x Version %d 232# Check that keys were created after 1990. 233# (1990 - 1970) * 365.2524 * 24 * 60 * 60 = 631156147 234>>>&0 bedate >631156147 \b, Created %s 235>>>>&-5 ubyte >3 236>>>>>&4 use pgp_binary_key_algo 237>>>>&-5 ubyte <4 238>>>>>&6 use pgp_binary_key_algo 239 240# Print out the key's algorithm and the number of bits, if this is 241# relevant (ECC keys are a fixed size). 2420 name pgp_binary_key_algo 243>0 clear x 244>&0 ubyte =1 \b, RSA (Encrypt or Sign, 245>>&0 ubeshort x \b %d bits) 246>&0 ubyte =2 \b, RSA (Encrypt, 247>>&0 ubeshort x \b %d bits) 248>&0 ubyte =3 \b, RSA (Sign, 249>>&0 ubeshort x \b %d bits) 250>&0 ubyte =16 \b, El Gamal (Encrypt, 251>>&0 ubeshort x \b %d bits) 252>&0 ubyte =17 \b, DSA 253>>&0 ubeshort x \b (%d bits) 254>&0 ubyte =18 \b, ECDH 255>&0 ubyte =19 \b, ECDSA 256>&0 ubyte =20 \b, El Gamal (Encrypt or Sign, 257>>&0 ubeshort x \b %d bits) 258>&0 ubyte =22 \b, EdDSA 259>&0 default x 260>>&0 ubyte x \b, Unknown Algorithm (%#x) 261 262# Match all possible second packets. 2630 name sig_or_component_1 264#>0 ubyte x (ctb: %x) 265>&0 ubyte =0xC2 266>>0 ubyte x \b; Signature 267>>&0 use sig_or_component_1_length_new 268>&0 ubyte =0xCD 269>>0 ubyte x \b; User ID 270>>&0 use sig_or_component_1_length_new 271>&0 ubyte =0xCE 272>>0 ubyte x \b; Public Subkey 273>>&0 use sig_or_component_1_length_new 274>&0 ubyte =0xC7 275>>0 ubyte x \b; Secret Subkey 276>>&0 use sig_or_component_1_length_new 277>&0 ubyte =0xD1 278>>0 ubyte x \b; User Attribute 279>>&0 use sig_or_component_1_length_new 280>&0 ubyte&0xFC =0x88 281>>0 ubyte x \b; Signature 282>>&-1 use sig_or_component_1_length_old 283>&0 ubyte&0xFC =0xB4 284>>0 ubyte x \b; User ID 285>>&-1 use sig_or_component_1_length_old 286>&0 ubyte&0xFC =0xB8 287>>0 ubyte x \b; Public Subkey 288>>&-1 use sig_or_component_1_length_old 289>&0 ubyte&0xFC =0x9C 290>>0 ubyte x \b; Secret Subkey 291>>&-1 use sig_or_component_1_length_old 292 293# Copy of 'primary_key_length_new', but calls cert_packet_3. 2940 name sig_or_component_1_length_new 295>&0 ubyte <192 296#>>&0 ubyte x (1 byte new length encoding, %d bytes) 297>>&(&-1.B) use cert_packet_3 298>&0 ubyte >191 299>>&-1 ubyte <225 300# offset = ((offset[0] - 192) << 8) + offset[1] + 192 + 1 (for the length header) 301# raw - (192 * 256 - 192 - 1) 302# = 48959 303#>>>&-1 ubeshort x (2 byte new length encoding, %d bytes) 304>>>&(&-1.S-48959) use cert_packet_3 305>&0 ubyte =255 306#>>&0 belong x (5 byte new length encoding, %d bytes) 307>>&(&-4.L) use cert_packet_3 308# Partial body encoding (only valid for container packets). 309# >&0 ubyte >224 310# >>&0 ubyte <255 partial body encoding 311 3120 name sig_or_component_1_length_old 313#>&0 ubyte x (ctb: %x) 314>&0 ubyte&0x3 =0 315#>>&0 ubyte x (1 byte old length encoding, %d bytes) 316>>&(&0.B+1) use cert_packet_3 317>&0 ubyte&0x3 =1 318#>>&0 ubeshort x (2 byte old length encoding, %d bytes) 319>>&(&0.S+2) use cert_packet_3 320>&0 ubyte&0x3 =2 321#>>&0 ubelong x (4 byte old length encoding, %d bytes) 322>>&(&0.L+4) use cert_packet_3 323 324# Copy of above. 3250 name cert_packet_3 326#>0 ubyte x (ctb: %x) 327>&0 ubyte =0xC2 328>>0 ubyte x \b; Signature 329>>&0 use cert_packet_3_length_new 330>&0 ubyte =0xCD 331>>0 ubyte x \b; User ID 332>>&0 use cert_packet_3_length_new 333>&0 ubyte =0xCE 334>>0 ubyte x \b; Public Subkey 335>>&0 use cert_packet_3_length_new 336>&0 ubyte =0xC7 337>>0 ubyte x \b; Secret Subkey 338>>&0 use cert_packet_3_length_new 339>&0 ubyte =0xD1 340>>0 ubyte x \b; User Attribute 341>>&0 use cert_packet_3_length_new 342>&0 ubyte&0xFC =0x88 343>>0 ubyte x \b; Signature 344>>&-1 use cert_packet_3_length_old 345>&0 ubyte&0xFC =0xB4 346>>0 ubyte x \b; User ID 347>>&-1 use cert_packet_3_length_old 348>&0 ubyte&0xFC =0xB8 349>>0 ubyte x \b; Public Subkey 350>>&-1 use cert_packet_3_length_old 351>&0 ubyte&0xFC =0x9C 352>>0 ubyte x \b; Secret Subkey 353>>&-1 use cert_packet_3_length_old 354 355# Copy of above. 3560 name cert_packet_3_length_new 357>&0 ubyte <192 358#>>&0 ubyte x (1 byte new length encoding, %d bytes) 359>>&(&-1.B) use pgp_binary_keys_end 360>&0 ubyte >191 361>>&-1 ubyte <225 362# offset = ((offset[0] - 192) << 8) + offset[1] + 192 + 1 (for the length header) 363# raw - (192 * 256 - 192 - 1) 364# = 48959 365#>>>&-1 ubeshort x (2 byte new length encoding, %d bytes) 366>>>&(&-1.S-48959) use pgp_binary_keys_end 367>&0 ubyte =255 368#>>&0 belong x (5 byte new length encoding, %d bytes) 369>>&(&-4.L) use pgp_binary_keys_end 370 3710 name cert_packet_3_length_old 372#>&0 ubyte x (ctb: %x) 373>&0 ubyte&0x3 =0 374#>>&0 ubyte x (1 byte old length encoding, %d bytes) 375>>&(&0.B+1) use pgp_binary_keys_end 376>&0 ubyte&0x3 =1 377#>>&0 ubeshort x (2 byte old length encoding, %d bytes) 378>>&(&0.S+2) use pgp_binary_keys_end 379>&0 ubyte&0x3 =2 380#>>&0 ubelong x (4 byte old length encoding, %d bytes) 381>>&(&0.L+4) use pgp_binary_keys_end 382 383# We managed to parse the first three packets of the certificate. Declare 384# victory. 3850 name pgp_binary_keys_end 386>0 byte x \b; OpenPGP Certificate 387!:mime application/pgp-keys 388!:ext pgp/gpg/pkr/asd 389