public key packet (tag 6) public subkey packet (tag 14) user id packet (tag 13) trust packet (tag 12) implementation defined? used by horowitz keyserver to mean disabled on key: "signature directly on a key" (tag 2 type 0x1f) key revocation signature (tag 2 type 0x20) by key or authorized revocation key on key+subkey: subkey signature (tag 2 type 0x18) by key, binds key to subkey subkey revocation signature (tag 2 type 0x28) by key or authorized revocation key on key+userid: user-id signature (tag 2 type 0x10,0x11,0x12,0x13) by any key, binds key to user-id on ???: certification revocation signature (tag 2 type 0x30) by key which issued user-id signature signature subpackets: signature creation time (type 2) key expiration time (type 9, only on userid-signature) issuer key id (type 16) primary user id (type 25) [only in userid-signature] exportable certification (type 4) rfc 2440 section 11.1: public-key[6] direct-key-revocation[2.x20] on public-key by key or revoker direct-key-signature[2.x1f]* on public-key by key (user-id[13] (user-id-signature[2.x10,2.x11,2.x12,2.x13] on key+userid by anyone (user-id-signature-revocation[2.x30]*)*)+ on ?? by user-id issuer (public-subkey[14] subkey-signature-revocation[2.x28] on subkey by public-key or revoker subkey-signature[2.x18])* on key+subkey by key I can tell what packet a signature refers to by checking that the 16-bit hash of the signed data matches the packet in question. XXX what do I do if I have a revocation, but no signature? the current keyserver also includes: per key: the modulus and exponent of the public key (for computing the fingerprint) the number of bits in the modulus (for index output) the key id the pubkey alg the creation time disabled-p a list of words which userid is the primary userid per userid: the printable form of the user id per sig: the issuer keyid the signature timestamp additional stuff needed for a pgp5-style listing: per key: key usage (sign,encrypt) expire time per signature: sig-valid-p ================================================================ RFC issues: What is a sigtype 0x30 calculated over? section 5.2 is vague about how to compute sigtypes 0x30, and 0x40. subpacket 23 (key server prefs) is "only on a self-signature". Does this mean a direct-key self-signature only? or in a user-id self-sig, too? What is "advisory information" in the context of signature subpackets (section 5.2.3)? The critical bit MUST be ignored on an unhashed signature subpacket (section 5.2.3.1). This text in section 5.2.1 is misleading: 0x18: Subkey Binding Signature This signature is a statement by the top-level signing key indicates that it owns the subkey. This signature is calculated directly on the subkey itself, not on any User ID or other packets. It implies that the signature is only over that single key. The text in section 5.2.4 indicates otherwise, and empirically matches what the existing implementations do: When a signature is made over a key, the hash data starts with the octet 0x99, followed by a two-octet length of the key, and then body of the key packet. (Note that this is an old-style packet header for a key packet with two-octet length.) A subkey signature (type 0x18) then hashes the subkey, using the same format as the main key. Immediately following this, the rfc says: Key revocation signatures (types 0x20 and 0x28) hash only the key being revoked. Analysis of existing implementations indicates that this is incorrect for subkey revocation signatures (type 0x28); both the primary key and the subkey are signed. ================================================================ XXX this needs to be rewritten $packet->{"ctag"} => content tag ->{"body"} => body of packet ->{"packet"} => complete packet (tag+length+body) $key->{"public-key"} => $packet ->{"subkeys"}->[0]->{"public-subkey"} => $packet ->{"subkey-signature-revocation"}->[0] => $packet ->{"subkey-signature"}->[0] => $packet ->{"userids"}->[0]->{"userid"} => $packet ->{"userid-signature"}->[0] => $packet ->{"userid-signature-revocation"}->[0] => $packet ->{"self-signature-revocation"}->[0] => $packet ->{"self-signature"}->[0] => $packet $pubkey->{"subkey"} ->{"version"} ->{"created"} ->{"expires"} (v4: from self-sig) ->{"pkalg"} ->{"modlength"} ->{"fingerprint"} ->{"keyid"} $userid->{"userid"} $signature->{"version"} ->{"sigtype"} ->{"created"} (v4: hashonly) ->{"issuer"} ->{"pkalg"} ->{"hashalg"} ================================================================ PGP::Packet::Signature ->ctag ->body ->packet PGP::Certificate::Signature ->{"version"} ->{"sigtype"} ->{"created"} -> ================================================================ The text in rfc2440 is incredibly vague as to which signature subpackets should be in the hashed or unhashed sections. It would be very useful for the text above to be in the next version of the RFC. It turns out I've been doing some openpgp related work lately, and I had come to the conclusion that unhashed signature subpackets were a bad idea even before the ADK bug was announced. I don't know how many would agree with me, but I would say that unhashed signature subpackets add substantial complexity and risk to the formats with very little benefit, and therefore should be deprecated for future use. I can't think of any reason *ever* to permit a third party to add subpackets to a signature. Of the list of signature subpacket types in rfc2440, after removing the types from Hal's list above, I get: 4 = exportable certification The RFC says that a keyserver should drop keys with this subpacket containing a flag == 0. If I add such a flag to someone else's signature and upload it, presumably that would result in the signature being dropped. Perhaps it might be uploaded again, but this provides for a type of DOS attack, and therefore I'd say it should be signed. 20 = notation data The risk here is that an implementation would present the notations to the user without indicating if they are signed or not. 23 = key server preferences If I add an unsigned no-modify flag to someone else's self-signature, then nobody will be able to upload new signatures to keyservers which implement this feature. I know Phil wouldn't regard this as a problem, but other users might consider this a DOS attack. 24 = preferred key server If I add to someone else's key a rogue preferred key server which I control, I can cause all updates to that key to be dropped, including, for example, revocations, if the user's implementation isn't careful. 28 = signer's user id If I use my "personal" user id to sign someone else's key, I don't want an attacker modifying the user id to claim my "work" user id signed the key, since this might imply a level of trust which does not exist. Personally, I find the this field questionable, but without including it in the signature, it is worthless. 100 to 110 = internal or user-defined It's impossible to say if these are safe or not when unhashed. 16 = issuer key ID Changing the issuer isn't really a DOS, since presumably the old signature with the correct issuer would remain. Except for the issuer key id, I believe every single defined subpacket is unsafe if not hashed. I'm curious what the perceived value of unhashed subpackets are, but unless someone makes a pretty good argument, I'd like to push for removing them completely from the RFC, with an exception for the issuer key id, since it's not usually signed, there are many unhashed issuer subpackets out there, and they are necessary for the efficient interpretation of signatures. This is a simple policy for implementors to code and test, and is much safer than each implementor deciding for themselves what "advisory information" means.