In a recent message, I asked how I could choose an <id> to use in an
application/key-request to get the CRL for the TIS PCA based on the
certificates I might get in a PEM/MIME message from someone at TIS.
The problem was that the certificates included in application/key-data
portion of the message don't contain a <keyid> for me to use in
requesting the CRL.
It was suggested that I could use one of the two <id> forms that don't
require a <keyid>, which are <id-publickey> and <id-issuer>. But
since the TIS PCA has no issuer, I can't use <id-issuer>. This will
be the same problem for any entity at the "top" of a chain. And using
<id-publickey> requires the CRL database to be indexed by public key
instead of disinguished name as most are. So, using one of the other
<id> forms which still have the unknown <keyid> may still be necessary.
I bring up this example to highlight the implementation difficulties
of keeping track of an arbitrary keyid. Nonetheless, we do need a way
to distinguish among the public keys that an entity may use. The
previous draft, draft-ietf-pem-mime-05.txt, used fields like this:
<id-email> ::= "EN" "," <atstring>
"," <hashalgid> "," <hashpublickey>
<id-string> ::= "STR" "," <string>
"," <hashalgid> "," <hashpublickey>
<id-dname> ::= "DN" "," <dname>
"," <hashalgid> "," <hashpublickey>
This is basically what we have in the current draft except a public
key hash was used instead of the present keyid. It had the advantage
that the key identifier was not arbitrary and could be derived
directly from the public key. There was no need for a database to
seperately store the keyid or for a user to have to convey it.
However, this scheme was abandoned because not all applications would
be willing to implement the hash algorithm that a sender might use
such as MD5 or SHA.
I suggest solving this by using the checksum defined by the TCP/IP
protocol as the keyid. It is easy to implement and all applications
implicitly use it already. It does not need to be irreversible like
MD5 or SHA. All we need is to distinguish among the few possible
public keys that an entity may use. Therefore, for example,
<id-email> for me would look like:
Originator-ID: EN, 1FF3, jefft(_at_)netcom(_dot_)com
where 1FF3 is the hex-encoded 16-bit checksum of the DER encoding of
my public key. The recipient of my message may look up however many
public keys in the database for jefft(_at_)netcom(_dot_)com, compute the
checksum
on the public key encodings and select the one that matches. Best of
all, there is no need to convey or store a seperate arbitrary keyid.
- Jeff
P.S. The definition of the checksum from the TCP document RFC 793 is:
The checksum field is the 16 bit one's complement of the one's
complement sum of all 16 bit words in the header and text. If a
segment contains an odd number of header and text octets to be
checksummed, the last octet is padded on the right with zeros to
form a 16 bit word for checksum purposes.
(For our purposes, substitute "public key encoding" for "header and
text".) This can be implemented in about 10 lines of C code as shown
in RFC 1071.