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