zkemail/archive.prove.email

Handle DNS TXT record sets with > 1 record

Closed this issue · 2 comments

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 #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"

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"

fixed by 8d00900