zkemail / archive.prove.email

A repository to store historical, timestamped DKIM keys; and for anyone to upload their own. Basically https://archive.org for public key registries.
https://archive.prove.email
MIT License
4 stars 4 forks source link

Handle DNS TXT record sets with > 1 record #83

Closed foolo closed 5 months ago

foolo commented 5 months ago

Some domains have multiple TXT records. Although this is not allowed in the specification (link), it would still be good to handle it.

TXT RRs MUST be unique for a particular selector name; that is, if there are multiple records in an RRset, the results are undefined.

The easiest option is probably to just add them all - any faulty ones will be handled by https://github.com/zkemail/archive.prove.email/issues/85 Alternatively, parse them and pick those that are valid DKIM TVL and have valid ASN1 DER encoded public key in p=.

At the moment, we have just picked the first record. But there seem to be a few cases in the archive (could be as much as 1%), for which we have actually missed the "real" key because the record with the real key was preceded by some invalid value. They are easy to find though, so we can process them and add any extra selectors.

One example:

dig default._domainkey.ictwaarborg.nl txt +short returns 2 records: Record 1 (note the underline in _p=):

"_v=DKIM1; k=rsa; _p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDLjLBpwYVJZWQ46dsN7UE/BdLPgZPg5FTz/FirVwuaiv5/TYyPskX1Xd4Bc7owME/b7QJv4J81T4gn5G/pLtY8fAqhWI6oLUb1stGjpERHqDClwIf7/k0jXlSPt62NrOeG2pcme+8pICY5hmxLrwoeII3TMiOnO/qS9m4zVHZIKwIDAQAB"

Record 2 (probably the correct one):

"v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3+OfJn9qgnu0NqgIYzH9lvsXnHe6fq5Od7PmEmDWvsBLxG3MVj+v694Kzgjhce9J4KGzI4/yyy6rbsdOhPtPcBVmhxNvNsWj1Dbd+NAs8/cEKRrk+ToU1zSl7fFAb6D7Vu68WDVxBo3OKAwBjiJFByD4+uqzNy+RMQFPwcIu2eSu6WpH05KChCblw4uKVrkjN" "r4ZvjoKhrI66+MMoZm1GCe6CbngnzHGphYpc8BOs/V0/NJQu1ovc1LqKLgKQywzard2O1DmOAnXMfx0e59oiDzEh6DsFU8LWlWwg8sZkPNcmhCTRsX56MbvLZRd2NiQMnhQtUZHmd/eFHvzJlqptwIDAQAB;"

Another example:

dig mail._domainkey.flyadeal.com TXT +short 
"k=rsa"
"k=rsa;p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDeMVIzrCa3T14JsNY0IRv5/2V1/v2itlviLQBwXsa7shBD6TrBkswsFUToPyMRWC9tbR/5ey0nRBH0ZVxp+lsmTxid2Y2z+FApQ6ra2VsXfbJP3HE6wAO0YTVEJt1TmeczhEd2Jiz/fcabIISgXEdSpTYJhb0ct0VJRxcg4c8c7wIDAQAB"
foolo commented 5 months ago

Observation: Some domains have divided the data in several DNS records (instead of several partial strings of the same record, which is the normal way)

In the example below, the data is divided in 3 records, which are returned in a random order. To handle cases like this, we would need to try to concatenate together in all possible combinations and see which combination gives a valid key. Maybe for the time being, this is not worth the extra complexity, also given that this does not follow the DKIM specification.

> dig +short TXT mandrill._domainkey.galleon.ph

"B3tVFB+Ch/4mPhXWiNfNdynHWBcPcbJ8kjEQ2U8y78dHZj1YeRXXVvWob2OaKynO8/lQIDAQAB;"

"v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrLHiExVd55zd/IQ/J/mRwSR"

"MAocV/hMB3jXwaHH36d9NaVynQFYV8NaWi69c1veUtRzGt7yAioXqLj7Z4TeEUoOLgrKsn8YnckGs9i3"
foolo commented 5 months ago

fixed by https://github.com/zkemail/archive.prove.email/commit/8d009003ec5cbaea11499997a463d65a0f28bc4b