dnsdkimdnsjava

How to read TXT Records longer than 255 characters in correct order


I am using DNSJava lib to fetch DKIM TXT records for a given selector + domain name. I want to ensure I read the record in the correct order when the record size is greater than 255 characters and spans over multiple strings in the result. As per the RFC Doc & RFC DOC we should concatenate all the strings in the result, but it does not tell us if the DNS Server will return the record strings in the correct order.

Eg : "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCUI5E9hZhMEEgjqF6fHNYYBmAEcF7DN2v/FA6yiY/a3R2L8ebGQjCdP2m3PfqLk8ovVd84eJ", "FkNuXGEsR0rXEHveOjc161z1tz4TGzPC5pGmjuzlYaibUQAb8T1GLbRse+ZkXhCxudeeRj7NBbCjaH1biClbp4v4/V0PLdugeGQQIDAQAB", "juzlYaibUQAb8T1GLbRse+ZkXhCxudeeRj7"

In the above example, I have no way to determine the order of records. Only DKIM header portion can be inferred to be start of a record


Solution

  • The order of those strings doesn't have to be determined, it's well-defined. Note that the strings you showed aren't records though!

    You seem to be confusing different strings in the same TXT record with multiple TXT records. You cannot split a string across multiple records, but you can split it across multiple fragments within the same record, and this is probably what you are referring to.

    A TXT record can contain multiple strings, see RFC 1035:

    3.3.14. TXT RDATA format
    
        +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
        /                   TXT-DATA                    /
        +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    
    where:
    
    TXT-DATA        One or more <character-string>s.
    
    TXT RRs are used to hold descriptive text.  The semantics of the text
    depends on the domain where it is found.
    

    As you can see, the order of the strings is part of the record's RDATA itself. A DNS server isn't supposed to mangle it in any way.

    For instance, this is how your example record would be defined in a zone file:

    name IN TXT ("v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCUI5E9hZhMEEgjqF6fHNYYBmAEcF7DN2v/FA6yiY/a3R2L8ebGQjCdP2m3PfqLk8ovVd84eJ"
                 "FkNuXGEsR0rXEHveOjc161z1tz4TGzPC5pGmjuzlYaibUQAb8T1GLbRse+ZkXhCxudeeRj7NBbCjaH1biClbp4v4/V0PLdugeGQQIDAQAB"
                 "juzlYaibUQAb8T1GLbRse+ZkXhCxudeeRj7")
    

    ...while multiple TXT records would look more like this:

    name IN TXT ("v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCUI5E9hZhMEEgjqF6fHNYYBmAEcF7DN2v/FA6yiY/a3R2L8ebGQjCdP2m3PfqLk8ovVd84eJ"
                 "FkNuXGEsR0rXEHveOjc161z1tz4TGzPC5pGmjuzlYaibUQAb8T1GLbRse+ZkXhCxudeeRj7NBbCjaH1biClbp4v4/V0PLdugeGQQIDAQAB"
                 "juzlYaibUQAb8T1GLbRse+ZkXhCxudeeRj7")
    name IN TXT "google-site-verification=abcde_xxxxxxxxxxxxx"
    name IN TXT "MS=ms1234567"
    

    In the latter case, you cannot be sure in which order you'll get those three records returned (v=DKIM1..., google-site... and MS=...), but it shouldn't have any meaning anyway.

    In case of dnsjava, you should get an array with the different records (not necessarily in any order) from getAnswers, but for each record you should get its strings (in order) from getStrings.