1970935fdSSascha Wildner 2970935fdSSascha Wildner#------------------------------------------------------------------------------ 3*614728caSSascha Wildner# $File: pgp-binary-keys,v 1.2 2021/04/26 15:56:00 christos Exp $ 4970935fdSSascha Wildner# pgp-binary-keys: This file handles pgp binary keys. 5970935fdSSascha Wildner# 6970935fdSSascha Wildner# An PGP certificate or message doesn't have a fixed header. Instead, 7970935fdSSascha Wildner# they are sequences of packets: 8970935fdSSascha Wildner# 9970935fdSSascha Wildner# https://tools.ietf.org/html/rfc4880#section-4.3 10970935fdSSascha Wildner# 11970935fdSSascha Wildner# whose order conforms to a grammar: 12970935fdSSascha Wildner# 13970935fdSSascha Wildner# https://tools.ietf.org/html/rfc4880#section-11 14970935fdSSascha Wildner# 15970935fdSSascha Wildner# Happily most packets have a few fields that are constrained, which 16970935fdSSascha Wildner# allow us to fingerprint them with relatively high certainty. 17970935fdSSascha Wildner# 18970935fdSSascha Wildner# A PGP packet is described by a single byte: the so-called CTB. The 19970935fdSSascha Wildner# high-bit is always set. If bit 6 is set, then it is a so-called 20970935fdSSascha Wildner# new-style CTB; if bit 6 is clear, then it is a so-called old-style 21970935fdSSascha Wildner# CTB. Old-style CTBs have only four bits of type information; bits 22970935fdSSascha Wildner# 1-0 are used to describe the length. New-style CTBs have 6 bits of 23970935fdSSascha Wildner# type information. 24970935fdSSascha Wildner# 25970935fdSSascha Wildner# Following the CTB is the packet's length in bytes. If we blindly 26970935fdSSascha Wildner# advance the file cursor by this amount past the end of the length 27970935fdSSascha Wildner# information we come to the next packet. 28970935fdSSascha Wildner# 29970935fdSSascha Wildner# Data Structures 30970935fdSSascha Wildner# =============== 31970935fdSSascha Wildner# 32970935fdSSascha Wildner# New Style CTB 33970935fdSSascha Wildner# ------------- 34970935fdSSascha Wildner# 35970935fdSSascha Wildner# https://tools.ietf.org/html/rfc4880#section-4.2.2 36970935fdSSascha Wildner# 37970935fdSSascha Wildner# 76543210 38970935fdSSascha Wildner# ||\----/ 39970935fdSSascha Wildner# || tag 40970935fdSSascha Wildner# |always 1 41970935fdSSascha Wildner# always 1 42970935fdSSascha Wildner# 43970935fdSSascha Wildner# Tag bits 7 and 6 set 44970935fdSSascha Wildner# 0 0xC0 -- Reserved - a packet tag MUST NOT have this value 45970935fdSSascha Wildner# 1 0xC1 -- Public-Key Encrypted Session Key Packet 46970935fdSSascha Wildner# 2 0xC2 -- Signature Packet 47970935fdSSascha Wildner# 3 0xC3 -- Symmetric-Key Encrypted Session Key Packet 48970935fdSSascha Wildner# 4 0xC4 -- One-Pass Signature Packet 49970935fdSSascha Wildner# 5 0xC5 -- Secret-Key Packet 50970935fdSSascha Wildner# 6 0xC6 -- Public-Key Packet 51970935fdSSascha Wildner# 7 0xC7 -- Secret-Subkey Packet 52970935fdSSascha Wildner# 8 0xC8 -- Compressed Data Packet 53970935fdSSascha Wildner# 9 0xC9 -- Symmetrically Encrypted Data Packet 54970935fdSSascha Wildner# 10 0xCA -- Marker Packet 55970935fdSSascha Wildner# 11 0xCB -- Literal Data Packet 56970935fdSSascha Wildner# 12 0xCC -- Trust Packet 57970935fdSSascha Wildner# 13 0xCD -- User ID Packet 58970935fdSSascha Wildner# 14 0xCE -- Public-Subkey Packet 59970935fdSSascha Wildner# 17 0xD1 -- User Attribute Packet 60970935fdSSascha Wildner# 18 0xD2 -- Sym. Encrypted and Integrity Protected Data Packet 61970935fdSSascha Wildner# 19 0xD3 -- Modification Detection Code Packet 62970935fdSSascha Wildner# 60 to 63 -- Private or Experimental Values 63970935fdSSascha Wildner# 64970935fdSSascha Wildner# The CTB is followed by the length header, which is densely encoded: 65970935fdSSascha Wildner# 66970935fdSSascha Wildner# if length[0] is: 67970935fdSSascha Wildner# 0..191: one byte length (length[0]) 68970935fdSSascha Wildner# 192..223: two byte length ((length[0] - 192) * 256 + length[2] + 192 69970935fdSSascha Wildner# 224..254: four byte length (big endian interpretation of length[1..5]) 70970935fdSSascha Wildner# 255: partial body encoding 71970935fdSSascha Wildner# 72970935fdSSascha Wildner# The partial body encoding is similar to HTTP's chunk encoding. It 73970935fdSSascha Wildner# is only allowed for container packets (SEIP, Compressed Data and 74970935fdSSascha Wildner# Literal). 75970935fdSSascha Wildner# 76970935fdSSascha Wildner# Old Style CTB 77970935fdSSascha Wildner# ------------- 78970935fdSSascha Wildner# 79970935fdSSascha Wildner# https://tools.ietf.org/html/rfc4880#section-4.2.1 80970935fdSSascha Wildner# 81970935fdSSascha Wildner# CTB: 82970935fdSSascha Wildner# 83970935fdSSascha Wildner# 76543210 84970935fdSSascha Wildner# ||\--/\/ 85970935fdSSascha Wildner# || | length encoding 86970935fdSSascha Wildner# || tag 87970935fdSSascha Wildner# |always 0 88970935fdSSascha Wildner# always 1 89970935fdSSascha Wildner# 90970935fdSSascha Wildner# Tag: 91970935fdSSascha Wildner# 92970935fdSSascha Wildner# Tag bit 7 set, bits 6, 1, 0 clear 93970935fdSSascha Wildner# 0 0x80 -- Reserved - a packet tag MUST NOT have this value 94970935fdSSascha Wildner# 1 0x84 -- Public-Key Encrypted Session Key Packet 95970935fdSSascha Wildner# 2 0x88 -- Signature Packet 96970935fdSSascha Wildner# 3 0x8C -- Symmetric-Key Encrypted Session Key Packet 97970935fdSSascha Wildner# 4 0x90 -- One-Pass Signature Packet 98970935fdSSascha Wildner# 5 0x94 -- Secret-Key Packet 99970935fdSSascha Wildner# 6 0x98 -- Public-Key Packet 100970935fdSSascha Wildner# 7 0x9C -- Secret-Subkey Packet 101970935fdSSascha Wildner# 8 0xA0 -- Compressed Data Packet 102970935fdSSascha Wildner# 9 0xA4 -- Symmetrically Encrypted Data Packet 103970935fdSSascha Wildner# 10 0xA8 -- Marker Packet 104970935fdSSascha Wildner# 11 0xAC -- Literal Data Packet 105970935fdSSascha Wildner# 12 0xB0 -- Trust Packet 106970935fdSSascha Wildner# 13 0xB4 -- User ID Packet 107970935fdSSascha Wildner# 14 0xB8 -- Public-Subkey Packet 108970935fdSSascha Wildner# 109970935fdSSascha Wildner# Length encoding: 110970935fdSSascha Wildner# 111970935fdSSascha Wildner# Value 112970935fdSSascha Wildner# 0 1 byte length (following byte is the length) 113970935fdSSascha Wildner# 1 2 byte length (following two bytes are the length) 114970935fdSSascha Wildner# 2 4 byte length (following four bytes are the length) 115970935fdSSascha Wildner# 3 indeterminate length: natural end of packet, e.g., EOF 116970935fdSSascha Wildner# 117970935fdSSascha Wildner# An indeterminate length is only allowed for container packets 118970935fdSSascha Wildner# (SEIP, Compressed Data and Literal). 119970935fdSSascha Wildner# 120970935fdSSascha Wildner# Certificates 121970935fdSSascha Wildner# ------------ 122970935fdSSascha Wildner# 123970935fdSSascha Wildner# We check the first three packets to determine if a sequence of 124970935fdSSascha Wildner# OpenPGP packets is likely to be a certificate. The grammar allows 125970935fdSSascha Wildner# the following prefixes: 126970935fdSSascha Wildner# 127970935fdSSascha Wildner# [Primary Key] [SIG] (EOF or another certificate) 128970935fdSSascha Wildner# [Primary Key] [SIG] [User ID] [SIG]... 129970935fdSSascha Wildner# [Primary Key] [SIG] [User Attribute] [SIG]... 130970935fdSSascha Wildner# [Primary Key] [SIG] [Subkey] [SIG]... 131970935fdSSascha Wildner# [Primary Key] [User ID] [SIG]... 132970935fdSSascha Wildner# [Primary Key] [User Attribute] [SIG]... 133970935fdSSascha Wildner# [Primary Key] [Subkey] [SIG]... 134970935fdSSascha Wildner# 135970935fdSSascha Wildner# Any number of marker packets are also allowed between each packet, 136970935fdSSascha Wildner# but they are not normally used and we don't currently check for 137970935fdSSascha Wildner# them. 138970935fdSSascha Wildner# 139970935fdSSascha Wildner# The keys and subkeys may be public or private. 140970935fdSSascha Wildner# 141970935fdSSascha Wildner 142970935fdSSascha Wildner# Key packets and signature packets are versioned. There are two 143970935fdSSascha Wildner# packet versions that we need to worry about in practice: v3 and v4. 144970935fdSSascha Wildner# v4 packets were introduced in RFC 2440, which was published in 1998. 145970935fdSSascha Wildner# It also deprecated v3 packets. There are no actively used v3 146970935fdSSascha Wildner# certificates (GnuPG removed the code to support them in November 147970935fdSSascha Wildner# 2014). But there are v3 keys lying around and it is useful to 148970935fdSSascha Wildner# identify them. The next version of OpenPGP will introduce v5 keys. 149970935fdSSascha Wildner# The document has not yet been standardized so changes are still 150970935fdSSascha Wildner# possible. But, for our purposes, it appears that v5 data structures 151970935fdSSascha Wildner# will be identical to v4 data structures modulo the version number. 152970935fdSSascha Wildner# 153970935fdSSascha Wildner# https://tools.ietf.org/html/rfc2440 154970935fdSSascha Wildner# https://lists.gnupg.org/pipermail/gnupg-announce/2014q4/000358.html 155970935fdSSascha Wildner# https://www.ietf.org/id/draft-ietf-openpgp-rfc4880bis-09.html#name-key-material-packet 156970935fdSSascha Wildner 157970935fdSSascha Wildner 158970935fdSSascha Wildner 159970935fdSSascha Wildner 160970935fdSSascha Wildner# The first packet has to be a public key or a secret key. 161970935fdSSascha Wildner# 162970935fdSSascha Wildner# New-Style Public Key 163970935fdSSascha Wildner0 ubyte =0xC6 OpenPGP Public Key 164970935fdSSascha Wildner>&0 use primary_key_length_new 165970935fdSSascha Wildner# New-Style Secret Key 166970935fdSSascha Wildner0 ubyte =0xC5 OpenPGP Secret Key 167970935fdSSascha Wildner>&0 use primary_key_length_new 168970935fdSSascha Wildner# Old-Style Public Key 169970935fdSSascha Wildner0 ubyte&0xFC =0x98 OpenPGP Public Key 170970935fdSSascha Wildner>&-1 use primary_key_length_old 171970935fdSSascha Wildner# Old-Style Secret Key 172970935fdSSascha Wildner0 ubyte&0xFC =0x94 OpenPGP Secret Key 173970935fdSSascha Wildner>&-1 use primary_key_length_old 174970935fdSSascha Wildner 175970935fdSSascha Wildner# Parse the length, check the packet's body and finally advance to the 176970935fdSSascha Wildner# next packet. 177970935fdSSascha Wildner 178970935fdSSascha Wildner# There are 4 different new-style length encodings, but the partial 179970935fdSSascha Wildner# body encoding is only acceptable for the SEIP, Compressed Data, and 180970935fdSSascha Wildner# Literal packets, which isn't valid for any packets in a certificate 181970935fdSSascha Wildner# so we ignore it. 182970935fdSSascha Wildner0 name primary_key_length_new 183970935fdSSascha Wildner>&0 ubyte <192 184970935fdSSascha Wildner#>>&0 ubyte x (1 byte length encoding, %d bytes) 185970935fdSSascha Wildner>>&0 use pgp_binary_key_pk_check 186970935fdSSascha Wildner>>>&(&-1.B) use sig_or_component_1 187970935fdSSascha Wildner>&0 ubyte >191 188970935fdSSascha Wildner>>&-1 ubyte <225 189970935fdSSascha Wildner# offset = ((offset[0] - 192) << 8) + offset[1] + 192 (for the length header) 190970935fdSSascha Wildner# raw - (192 * 256 - 192) 191970935fdSSascha Wildner# = 48960 192970935fdSSascha Wildner#>>>&0 ubeshort x (2 byte length encoding, %d bytes) 193970935fdSSascha Wildner>>>&1 use pgp_binary_key_pk_check 194970935fdSSascha Wildner>>>>&(&-2.S-48960) use sig_or_component_1 195970935fdSSascha Wildner>&0 ubyte =255 196970935fdSSascha Wildner#>>&0 belong x (5 byte length encoding, %d bytes) 197970935fdSSascha Wildner>>&4 use pgp_binary_key_pk_check 198970935fdSSascha Wildner>>>&(&-4.L) use sig_or_component_1 199970935fdSSascha Wildner# Partial body encoding (only valid for container packets). 200970935fdSSascha Wildner# >&0 ubyte >224 201970935fdSSascha Wildner# >>&0 ubyte <255 partial body encoding 202970935fdSSascha Wildner 203970935fdSSascha Wildner# There are 4 different old-style length encodings, but the 204970935fdSSascha Wildner# indeterminate length encoding is only acceptable for the SEIP, 205970935fdSSascha Wildner# Compressed Data, and Literal packets, which isn't valid for any 206970935fdSSascha Wildner# packets in a certificate. 207970935fdSSascha Wildner0 name primary_key_length_old 208970935fdSSascha Wildner#>&0 ubyte x (ctb: %x) 209970935fdSSascha Wildner>&0 ubyte&0x3 =0 210970935fdSSascha Wildner#>>&0 ubyte x (1 byte length encoding, %d bytes) 211970935fdSSascha Wildner>>&1 use pgp_binary_key_pk_check 212970935fdSSascha Wildner>>>&(&-1.B) use sig_or_component_1 213970935fdSSascha Wildner>&0 ubyte&0x3 =1 214970935fdSSascha Wildner#>>&0 ubeshort x (2 byte length encoding, %d bytes) 215970935fdSSascha Wildner>>&2 use pgp_binary_key_pk_check 216970935fdSSascha Wildner>>>&(&-2.S) use sig_or_component_1 217970935fdSSascha Wildner>&0 ubyte&0x3 =2 218970935fdSSascha Wildner#>>&0 ubelong x (4 byte length encoding, %d bytes) 219970935fdSSascha Wildner>>&4 use pgp_binary_key_pk_check 220970935fdSSascha Wildner>>>&(&-4.L) use sig_or_component_1 221970935fdSSascha Wildner 222970935fdSSascha Wildner# Check the Key. 223970935fdSSascha Wildner# 224970935fdSSascha Wildner# https://tools.ietf.org/html/rfc4880#section-5.5.2 225970935fdSSascha Wildner0 name pgp_binary_key_pk_check 226970935fdSSascha Wildner# Valid versions are: 2, 3, 4. 5 is proposed in RFC 4880bis. 227970935fdSSascha Wildner# Anticipate a v6 / v7 format that like v5 is compatible with v4. 228970935fdSSascha Wildner# key format in a decade or so :D. 229970935fdSSascha Wildner>&0 ubyte >1 230970935fdSSascha Wildner>>&-1 ubyte <8 231970935fdSSascha Wildner>>>&-1 byte x Version %d 232970935fdSSascha Wildner# Check that keys were created after 1990. 233970935fdSSascha Wildner# (1990 - 1970) * 365.2524 * 24 * 60 * 60 = 631156147 234970935fdSSascha Wildner>>>&0 bedate >631156147 \b, Created %s 235970935fdSSascha Wildner>>>>&-5 ubyte >3 236970935fdSSascha Wildner>>>>>&4 use pgp_binary_key_algo 237970935fdSSascha Wildner>>>>&-5 ubyte <4 238970935fdSSascha Wildner>>>>>&6 use pgp_binary_key_algo 239970935fdSSascha Wildner 240970935fdSSascha Wildner# Print out the key's algorithm and the number of bits, if this is 241970935fdSSascha Wildner# relevant (ECC keys are a fixed size). 242970935fdSSascha Wildner0 name pgp_binary_key_algo 243970935fdSSascha Wildner>0 clear x 244970935fdSSascha Wildner>&0 ubyte =1 \b, RSA (Encrypt or Sign, 245970935fdSSascha Wildner>>&0 ubeshort x \b %d bits) 246970935fdSSascha Wildner>&0 ubyte =2 \b, RSA (Encrypt, 247970935fdSSascha Wildner>>&0 ubeshort x \b %d bits) 248970935fdSSascha Wildner>&0 ubyte =3 \b, RSA (Sign, 249970935fdSSascha Wildner>>&0 ubeshort x \b %d bits) 250970935fdSSascha Wildner>&0 ubyte =16 \b, El Gamal (Encrypt, 251970935fdSSascha Wildner>>&0 ubeshort x \b %d bits) 252970935fdSSascha Wildner>&0 ubyte =17 \b, DSA 253970935fdSSascha Wildner>>&0 ubeshort x \b (%d bits) 254970935fdSSascha Wildner>&0 ubyte =18 \b, ECDH 255970935fdSSascha Wildner>&0 ubyte =19 \b, ECDSA 256970935fdSSascha Wildner>&0 ubyte =20 \b, El Gamal (Encrypt or Sign, 257970935fdSSascha Wildner>>&0 ubeshort x \b %d bits) 258970935fdSSascha Wildner>&0 ubyte =22 \b, EdDSA 259970935fdSSascha Wildner>&0 default x 260*614728caSSascha Wildner>>&0 ubyte x \b, Unknown Algorithm (%#x) 261970935fdSSascha Wildner 262970935fdSSascha Wildner# Match all possible second packets. 263970935fdSSascha Wildner0 name sig_or_component_1 264970935fdSSascha Wildner#>0 ubyte x (ctb: %x) 265970935fdSSascha Wildner>&0 ubyte =0xC2 266970935fdSSascha Wildner>>0 ubyte x \b; Signature 267970935fdSSascha Wildner>>&0 use sig_or_component_1_length_new 268970935fdSSascha Wildner>&0 ubyte =0xCD 269970935fdSSascha Wildner>>0 ubyte x \b; User ID 270970935fdSSascha Wildner>>&0 use sig_or_component_1_length_new 271970935fdSSascha Wildner>&0 ubyte =0xCE 272970935fdSSascha Wildner>>0 ubyte x \b; Public Subkey 273970935fdSSascha Wildner>>&0 use sig_or_component_1_length_new 274970935fdSSascha Wildner>&0 ubyte =0xC7 275970935fdSSascha Wildner>>0 ubyte x \b; Secret Subkey 276970935fdSSascha Wildner>>&0 use sig_or_component_1_length_new 277970935fdSSascha Wildner>&0 ubyte =0xD1 278970935fdSSascha Wildner>>0 ubyte x \b; User Attribute 279970935fdSSascha Wildner>>&0 use sig_or_component_1_length_new 280970935fdSSascha Wildner>&0 ubyte&0xFC =0x88 281970935fdSSascha Wildner>>0 ubyte x \b; Signature 282970935fdSSascha Wildner>>&-1 use sig_or_component_1_length_old 283970935fdSSascha Wildner>&0 ubyte&0xFC =0xB4 284970935fdSSascha Wildner>>0 ubyte x \b; User ID 285970935fdSSascha Wildner>>&-1 use sig_or_component_1_length_old 286970935fdSSascha Wildner>&0 ubyte&0xFC =0xB8 287970935fdSSascha Wildner>>0 ubyte x \b; Public Subkey 288970935fdSSascha Wildner>>&-1 use sig_or_component_1_length_old 289970935fdSSascha Wildner>&0 ubyte&0xFC =0x9C 290970935fdSSascha Wildner>>0 ubyte x \b; Secret Subkey 291970935fdSSascha Wildner>>&-1 use sig_or_component_1_length_old 292970935fdSSascha Wildner 293970935fdSSascha Wildner# Copy of 'primary_key_length_new', but calls cert_packet_3. 294970935fdSSascha Wildner0 name sig_or_component_1_length_new 295970935fdSSascha Wildner>&0 ubyte <192 296970935fdSSascha Wildner#>>&0 ubyte x (1 byte new length encoding, %d bytes) 297970935fdSSascha Wildner>>&(&-1.B) use cert_packet_3 298970935fdSSascha Wildner>&0 ubyte >191 299970935fdSSascha Wildner>>&-1 ubyte <225 300970935fdSSascha Wildner# offset = ((offset[0] - 192) << 8) + offset[1] + 192 + 1 (for the length header) 301970935fdSSascha Wildner# raw - (192 * 256 - 192 - 1) 302970935fdSSascha Wildner# = 48959 303970935fdSSascha Wildner#>>>&-1 ubeshort x (2 byte new length encoding, %d bytes) 304970935fdSSascha Wildner>>>&(&-1.S-48959) use cert_packet_3 305970935fdSSascha Wildner>&0 ubyte =255 306970935fdSSascha Wildner#>>&0 belong x (5 byte new length encoding, %d bytes) 307970935fdSSascha Wildner>>&(&-4.L) use cert_packet_3 308970935fdSSascha Wildner# Partial body encoding (only valid for container packets). 309970935fdSSascha Wildner# >&0 ubyte >224 310970935fdSSascha Wildner# >>&0 ubyte <255 partial body encoding 311970935fdSSascha Wildner 312970935fdSSascha Wildner0 name sig_or_component_1_length_old 313970935fdSSascha Wildner#>&0 ubyte x (ctb: %x) 314970935fdSSascha Wildner>&0 ubyte&0x3 =0 315970935fdSSascha Wildner#>>&0 ubyte x (1 byte old length encoding, %d bytes) 316970935fdSSascha Wildner>>&(&0.B+1) use cert_packet_3 317970935fdSSascha Wildner>&0 ubyte&0x3 =1 318970935fdSSascha Wildner#>>&0 ubeshort x (2 byte old length encoding, %d bytes) 319970935fdSSascha Wildner>>&(&0.S+2) use cert_packet_3 320970935fdSSascha Wildner>&0 ubyte&0x3 =2 321970935fdSSascha Wildner#>>&0 ubelong x (4 byte old length encoding, %d bytes) 322970935fdSSascha Wildner>>&(&0.L+4) use cert_packet_3 323970935fdSSascha Wildner 324970935fdSSascha Wildner# Copy of above. 325970935fdSSascha Wildner0 name cert_packet_3 326970935fdSSascha Wildner#>0 ubyte x (ctb: %x) 327970935fdSSascha Wildner>&0 ubyte =0xC2 328970935fdSSascha Wildner>>0 ubyte x \b; Signature 329970935fdSSascha Wildner>>&0 use cert_packet_3_length_new 330970935fdSSascha Wildner>&0 ubyte =0xCD 331970935fdSSascha Wildner>>0 ubyte x \b; User ID 332970935fdSSascha Wildner>>&0 use cert_packet_3_length_new 333970935fdSSascha Wildner>&0 ubyte =0xCE 334970935fdSSascha Wildner>>0 ubyte x \b; Public Subkey 335970935fdSSascha Wildner>>&0 use cert_packet_3_length_new 336970935fdSSascha Wildner>&0 ubyte =0xC7 337970935fdSSascha Wildner>>0 ubyte x \b; Secret Subkey 338970935fdSSascha Wildner>>&0 use cert_packet_3_length_new 339970935fdSSascha Wildner>&0 ubyte =0xD1 340970935fdSSascha Wildner>>0 ubyte x \b; User Attribute 341970935fdSSascha Wildner>>&0 use cert_packet_3_length_new 342970935fdSSascha Wildner>&0 ubyte&0xFC =0x88 343970935fdSSascha Wildner>>0 ubyte x \b; Signature 344970935fdSSascha Wildner>>&-1 use cert_packet_3_length_old 345970935fdSSascha Wildner>&0 ubyte&0xFC =0xB4 346970935fdSSascha Wildner>>0 ubyte x \b; User ID 347970935fdSSascha Wildner>>&-1 use cert_packet_3_length_old 348970935fdSSascha Wildner>&0 ubyte&0xFC =0xB8 349970935fdSSascha Wildner>>0 ubyte x \b; Public Subkey 350970935fdSSascha Wildner>>&-1 use cert_packet_3_length_old 351970935fdSSascha Wildner>&0 ubyte&0xFC =0x9C 352970935fdSSascha Wildner>>0 ubyte x \b; Secret Subkey 353970935fdSSascha Wildner>>&-1 use cert_packet_3_length_old 354970935fdSSascha Wildner 355970935fdSSascha Wildner# Copy of above. 356970935fdSSascha Wildner0 name cert_packet_3_length_new 357970935fdSSascha Wildner>&0 ubyte <192 358970935fdSSascha Wildner#>>&0 ubyte x (1 byte new length encoding, %d bytes) 359970935fdSSascha Wildner>>&(&-1.B) use pgp_binary_keys_end 360970935fdSSascha Wildner>&0 ubyte >191 361970935fdSSascha Wildner>>&-1 ubyte <225 362970935fdSSascha Wildner# offset = ((offset[0] - 192) << 8) + offset[1] + 192 + 1 (for the length header) 363970935fdSSascha Wildner# raw - (192 * 256 - 192 - 1) 364970935fdSSascha Wildner# = 48959 365970935fdSSascha Wildner#>>>&-1 ubeshort x (2 byte new length encoding, %d bytes) 366970935fdSSascha Wildner>>>&(&-1.S-48959) use pgp_binary_keys_end 367970935fdSSascha Wildner>&0 ubyte =255 368970935fdSSascha Wildner#>>&0 belong x (5 byte new length encoding, %d bytes) 369970935fdSSascha Wildner>>&(&-4.L) use pgp_binary_keys_end 370970935fdSSascha Wildner 371970935fdSSascha Wildner0 name cert_packet_3_length_old 372970935fdSSascha Wildner#>&0 ubyte x (ctb: %x) 373970935fdSSascha Wildner>&0 ubyte&0x3 =0 374970935fdSSascha Wildner#>>&0 ubyte x (1 byte old length encoding, %d bytes) 375970935fdSSascha Wildner>>&(&0.B+1) use pgp_binary_keys_end 376970935fdSSascha Wildner>&0 ubyte&0x3 =1 377970935fdSSascha Wildner#>>&0 ubeshort x (2 byte old length encoding, %d bytes) 378970935fdSSascha Wildner>>&(&0.S+2) use pgp_binary_keys_end 379970935fdSSascha Wildner>&0 ubyte&0x3 =2 380970935fdSSascha Wildner#>>&0 ubelong x (4 byte old length encoding, %d bytes) 381970935fdSSascha Wildner>>&(&0.L+4) use pgp_binary_keys_end 382970935fdSSascha Wildner 383970935fdSSascha Wildner# We managed to parse the first three packets of the certificate. Declare 384970935fdSSascha Wildner# victory. 385970935fdSSascha Wildner0 name pgp_binary_keys_end 386970935fdSSascha Wildner>0 byte x \b; OpenPGP Certificate 387970935fdSSascha Wildner!:mime application/pgp-keys 388970935fdSSascha Wildner!:ext pgp/gpg/pkr/asd 389