Borrowing the style in RFC1123 (Internet Mail Hosting Requirements) I
did a regular expression grep for
{MUST}|{SHOULD}|{MAY}|{RECOMMENDED}|{OPTIONAL}|{REQUIRED}|{SHALL}
to begin to look at all the RFC2119 semantics.
At first, I was going to pull out some old prolog AI code that makes
associations and connections in sentences to see if there was a "AI"
way to validate RFC2119 conformity but instead I just wrote this draft
table summarizing all the RFC4781bis references to RFC2119 semantics.
I first I started to just record it as it appeared in the document
searches, then I began to consolidate by role and as it appeared in
the doc.
I did come across some things that arguably in conflict with RFC2119,
but I footnoted the ones I believe may need some attention. The top
one (#1) was that signer has no MUST explicit statements for using
C14N "simple" or "relaxed" unlike an explicit statement for verifiers.
Also, I did find section 5.6 a little ambiguous.
DKIM is a complex beast. I think once we see there are no conflicts,
we can consolidate the table into a DKIM component roles like it was
done in RFC1123 and like RFC1123 was very helpful, a table like this
for DKIM will be helpful as well.
DKIM REQUIREMENTS SUMMARY (DRAFT)
+-----------------------------------------------------------------------+
| | | | | |S| | |
| | | | | |H| |F|
| | | | | |O|M|o|
| | | |S| |U|U|o|
| | | |H| |L|S|t|
| | |M|O| |D|T|n|
| | |U|U|M| | |o|
| | |S|L|A|N|N|t|
| | |T|D|Y|O|O|t|
|FEATURE |SECTION | | | |T|T|e|
|-----------------------------------------------|-----------|-|-|-|-|-|-|
|SIGNER ISSUES | | | | | | | |
| | | | | | | | |
|DKIM-Quoted-Printable |2.11 | | | | | | |
| encode any character |2.11 | | |X| | | |
| encode control characters |2.11 |X| | | | | |
| encode white spaces |2.11 |X| | | | | |
| after encoding add FWS |2.11 | | |X| | | |
| remove whitespace after decoding |2.11 |X| | | | | |
| | | | | | | | |
|Tag=Values | | | | | | | |
| Tags unencoded semicolon |3.2 | | | | |X| |
| Tags case sensitive |3.2 |X| | | | | |
| Tags values case sensitive |3.2 |X| | | | | |
| Duplicate Tags |3.2 | | | | |X| |
| Retain WS tag value |3.2 |X| | | | | |
| Add tag=value defaults |3.2 | | |X| | | |
| add "v=1" |3.5 |X| | | | | |
| add "a=" |3.5 |X| | | | | |
| add "b=" |3.5 |X| | | | | |
| ignore "b=" WSP |3.5 |X| | | | | |
| add "bh=" |3.5 |X| | | | | |
| ignore "bh=" WSP |3.5 |X| | | | | |
| add "c=" |3.5 | | |O| | | |
| add "d=" SDID |3.5 |X| | | | | |
| SDID valid DNS name |3.5 |X| | | | | |
| encode IDN as A-LABEL |3.5 |X| | | | | |
| add "h=" |3.5 |X| | | | | |
| empty list |3.5 | | | | |X| |
| order header field list |3.5 |X| | | | | |
| non-existing header fields |3.5 | | |X| | | |
| contain DKIM-Signature Header |3.5 | | | | |X| |
| folding WSP |3.5 | | |X| | | |
| header name case insensitive |3.5 |X| | | | | |
| add "i=" |3.5 | | |O| | | |
| omit local part |3.5 | | |X| | | |
| domain related to "d=" |3.5 |X| | | | | |
| encode IDN as A-LABEL |3.5 |X| | | | | |
| local part related to From |3.5 | | |X| | | |
| same name space |3.5 | | |X| | | |
| represent users |3.5 | | |X| | | |
| persistent with same signer sphere |3.5 | |X| | | | |
| add "l=" body length |3.5 | | |O| | | |
| larger than actual body length |3.5 | | | | |X| |
| add "q=" query method |3.5 | | |O| | | |
| implement recognized method |3.5 |X| | | | | |
| ignore unrecognized method |3.5 |X| | | | | |
| method changes interpretation |3.5 | | | | |X| |
| "dns" type uses "txt" |3.5 |X| | | | | |
| add "s=" |3.5 |X| | | | | |
| encode IDN as A-LABEL |3.5 |X| | | | | |
| add "t=" |3.5 | |R| | | | |
| support 40 bits |3.5 | |X| | | | |
| DoS Attacks ignore 12 digits |3.5 | | |X| | | |
| ignore future timestampes |3.5 | | |X| | | |
| add "X=" |3.5 | |R| | | | |
| greater then "t=" value |3.5 |X| | | | | |
| add time-shifted fudge factor |3.5 | | |X| | | |
| add "z=" |3.5 | | |O| | | |
| add FWS |3.5 | | |X| | | |
| removed added FWS |3.5 |X| | | | | |
| | | | | | | | |
|Signing by Domain t=s |3.10 | | |X| | | |
| if set, d= equal i= domain |3.10 |X| | | | | |
|Provide Agent or User Identity |3.11 | | |X| | | |
| | | | | | | | |
|Hashing: | | | | | | | |
| Implement rsa-sha1: |3.3 | |X| | | |1|
| truncate/convert from native form |3.3.1 | | | |X| | |
| algorythm public exponent of 65537 |3.3.1 | |X| | | | |
| Implement rsa-sha256: |3.3 |X| | | | | |
| sign with rsa-sha256: |3.3 | |X| | | | |
| truncate/convert from native form |3.3.2 | | | |X| | |
| Implement other rsa algorithms |3.3.4 | | |X| | | |
| Compute two hashes (bh=, b=) |3.7 |X| | | | | |
| Signer compute hashes in order |3.7 |X| | | | | |
| Verifier compute hashes in order |3.7 | | |X| | | |
| Hash Message Body |3.7 |X| | | | | |
| Hash h=, than DKIM-Signature |3.7 |X| | | | | |
| end header with CRLF |3.7 |X| | | | | |
| add non-existing headers |5.4 | | |X| | | |
| treat as NULL string |5.4 |X| | | | | |
| hash last header for duplicates |5.4 |X| | | | | |
| Add multiple h= fields |5.4 | | |X| | | |
| Sign each multiple field (Bottom to Top) |5.4 |X| | | | | |
| Add additional h= fields |5.4 | | |X| | | |
| Match header fields |5.4 | | | | |X| |
| b= treated as NULL string |3.7 |X| | | | |2|
| include all tags |3.7 |X| | | | | |
| Hash 5322.From |5.4, 5.5 |X| | | | | |
| Hash Any Header |5.4 | | |X| | | |
| Hash Non-Persistent Headers |5.4 | | | |X| | |
| Hash headers after body |3.7 |X| | | | | |
| Include DKIM-Signature in own h= |3.7, 5.4 | | | | |X| |
| Hash Other DKIM-Signature |3.7 | | |X| | | |
| hash with c= methods |3.7 |X| | | | | |
| hash after encoding |3.7 |X| | | | | |
| verify incorporate hash before decoding |3.7 |X| | | | | |
| verify computer hash before SMTP dbl dot |3.7 |X| | | | | |
| | | | | | | | |
|DKIM Messages | | | | | | | |
| CR/CRLF translation |5.3 |X| | | | | |
| Output RFC5322 |5.3 | |X| | | | |
| Prepare Verifiers/Receivers |5.3 |X| | | | | |
| Plain Text |3.7 | | |X| | | |
| MIME format |3.7 | | |X| | | |
| Convert to quoted-printable, base64 |5.3 | |X| | | | |
| MUA/MSA perform conversion |5.3 |X| | | | | |
| MIME format |3.7 | | |X| | | |
| Sign MIME attachments |3.7 |X| | | | | |
| Sign other DKIM-Signatures |4.2 | | |X| | | |
| Add two DKIM-Signatures (SHA1, SHA256) |4.2 | | |X| | | |
| Remove signed headers |4.2 | | | |X| | |
| | | | | | | | |
| Insert DKIM-Signature |5.7 |X| | | | |3|
| Same as privious |5.7 |X| | | | |3|
| b= set to new value |5.7 |X| | | | |3|
| before others (prepend) |5.7 |X| | | | | |
| | | | | | | | |
|Canonicalization (C14N) | | | | | | | |
| Implement "simple" |3.4 |?| | | | |4|
| Implement "relaxed" |3.4 |?| | | | |4|
| use C14N for minimum damage risk |5.5 | |X| | | | |
| Add "c=" tag |3.4 | | |X| | | |
| Add "l=" body length |3.4.5 | | |X| | | |
| body length set to C14N length |3.4.5 |X| | | | | |
| no intermediate processor, use l= |5,5 | | | | |X| |
| for mailing list, set l= |5,6 | | |X| | | |
| hash entire body |5,5 | |X| | | | |
| set l=0 |5,5 | | | |X| | |
| Add future C14N |3.4 | | |X| | | |
| Change transmitted data |3.4 | | | | |X| |
| "simple" header fields persistent |3.4.1 |X| | | | | |
| "simple" header fields folded |3.4.1 | | | | |X| |
| "simple" header fields WSP changed |3.4.1 | | | | |X| |
| follow "relaxed" header algorithm order |3.4.2 |X| | | | | |
| unfold "relaxed" headers |3.4.2 |X| | | | | |
| remove "relaxed" header CRLF |3.4.2 | | | | |X| |
| retain "relaxed" header colon separator |3.4.2 |X| | | | | |
| follow "simple" body algorithm order |3.4.4 |X| | | | | |
| remove "simple" body line CRLF |3.4.4 | | | | |X| |
| | | | | | | | |
|Public Key: | | | | | | | |
| remove or revoke any time |6.0 | | |X| | | |
| sign with at least 1024 bit |3.3.3 |X| | | | | |
| add unknown tags |3.6.1 | | |X| | | |
| ignore unknown tags |3.6.1 |X| | | | | |
| add "v=DKIM1" first |3.6.1 |X| | | | | |
| discard record not starting with "v=" |3.6.1 |X| | | | | |
| add "h=" |3.6.1 | | |O| | | |
| ignore ignore values |3.6.1 |X| | | | | |
| add "k=" |3.6.1 | | |O| | | |
| support "rsa" type |3.6.1 |X| | | | | |
| ignore ignore values |3.6.1 |X| | | | | |
| add "n=" |3.6.1 | | |O| | | |
| add "p=" |3.6.1 |X| | | | | |
| error with revoked keys |3.6.1 | |X| | | |5|
| add "s=" |3.6.1 | | |O| | | |
| ignore ignore values |3.6.1 |X| | | | | |
| ignore unknown service type |3.6.1 |X| | | | | |
| add "t=" |3.6.1 | | |O| | | |
| ignore unknown flags |3.6.1 |X| | | | | |
| t=y invalid signatures |3.6.1 | | | | |X| |
| t=y track abuse |3.6.1 | | |X| | | |
| t=s match i= and d= |3.6.1 |X| | | | | |
| using t=s |3.6.1 | |R| | | | |
| | | | | | | | |
|DNS Binding: | | | | | | | |
| DNS TXT |3.6.2 |X| | | | | |
| Concatenate TXT RR strings |3.6.2.2 |X| | | | | |
| Unique TXT RR |3.6.2.2 |X| | | | | |
| | | | | | | | |
|-----------------------------------------------|-----------|-|-|-|-|-|-|
|VERIFIER ISSUES: | | | | | | | |
| | | | | | | | |
|Tag=Values | | | | | | | |
| Ignore unrecognized tags |3.2, 3.5 |X| | | | | |
|Verifiers implement SHA1, SHA256 |3.3 |X| | | | | |
|support 512 to 1024 bits |3.3.3 |X| | | | | |
|support larger than 1024 bits |3.3.3 | | |X| | | |
|ignore unknown hash algorithms |3.3.4 |X| | | | | |
|Verifiers implement c14n "simple" |3.4 |X| | | | | |
|Verifiers implement c14n "relaxed" |3.4 |X| | | | | |
|Verifiers ignore unknown c14n |3.4 |X| | | | | |
|Treat DKIM-Signature as trace line |3.5 | |X| | | | |
|Reorder DKIM-Signature |3.5 | | | |X| | |
|Prepend DKIM-Signature |3.5 | |X| | | | |
|Calculate "b=" as empty string |3.5 |X| | | | | |
|Calculate unknown tags |3.5 |X| | | | | |
|Unknown SDID invalid signature |3.5 |X| | | | | |
|verifier implement q=dns/txt |3.5 |X| | | | | |
|verifier invalidate expired signatures |3.5 | | |X| | | |
|RFC5322 Input |3.8 | |X| | | | |
|RFC2045 Input |3.8 | |X| | | | |
|Output Verifier Status |3.9 |X| | | | | |
|Output Verifier SDID |3.9 |X| | | | | |
|Output Other Values |3.9 | | |X| | | |
|Communicate SDID to Trust Assessor |3.11 |X| | | | | |
|Communicate AUID to Trust Assessor |3.11 | | |X| | | |
|Evaluate Independent Signatures |4.2 | |X| | | | |
|Process Signatures in any other |4.2 | | |X| | | |
|Check all signatures until first valid |4.2 | |X| | | | |
|Limit total number of signatures |4.2 | | |X| | | |
|Ignore PERMFAIL |4.2 | |X| | | | |
|Invalidate RFC4409 Authorized Messages |5.3 | | | | |X| |
|Mailing list check signatures |5.6 | |X| | | | |
| make modifications |5.6 |X| | | | |6|
| | | | | | | | |
|border or MTA verify signatures |6.0 | | |X| | | |
|MTA reporting signature results |6.0 | | |X| | | |
|MTA implement policy |6.0 | | |X| | | |
|Verify Order |6.0 |X| | | | | |
| Extract signature in any order |6.1 | | |X| | | |
| Assign multiple results meanings |6.1 | | | | |X| |
| treat invalid sigs different than no sig |6.1 | | | | |X| |
| Limit signatures |6.1 | | |X| | | |
| cease processsing PERMFAIL |6.1 |X| | | | | |
| cease processsing TEMPFAIL |6.1 |X| | | | | |
| queue for retry verification |6.1 | | |X| | | |
| process next signature |6.1 | |X| | | | |
| record invalid |6.1 | | |X| | | |
| Validate headers |6.1.1 |X| | | | | |
| incorrect values invalid sigs |6.1.1 |X| | | | | |
| incorrect v=1 invalid sigs |6.1.1 |X| | | | | |
| missing required tag invalid sigs |6.1.1 |X| | | | | |
| missing AUID set to "@"+SDID |6.1.1 |X| | | | | |
| check AUID is SDID or subdomain |6.1.1 |X| | | | | |
| mismatch invalid sigs |6.1.1 |X| | | | | |
| missing h=from invalid sigs |6.1.1 |X| | | | | |
| expiration invalid sigs |6.1.1 | | |X| | | |
| invalid signer invalids sigs |6.1.1 | | |X| | | |
| prepare unacceptable domains |6.1.1 | |X| | | | |
| invalid sig for any reason |6.1.1 | | |X| | | |
| Public key | | | | | | | |
| retrieve key record using g=, d=, s= |6.1.2 |X| | | | | |
| tempfail retried later |6.1.2 | | |X| | | |
| permfail for missing key |6.1.2 |X| | | | | |
| validate key record |6.1.2 |X| | | | | |
| invalidate malformed records |6.1.2 |X| | | | | |
| invalidate incorrect v=DKIM1 tag |6.1.2 |X| | | | | |
| invalidate mismatch key h= and sig a= |6.1.2 |X| | | | | |
| invalidate missing p= |6.1.2 |X| | | | | |
| invalidate mismatch k= and a= |6.1.2 |X| | | | | |
| Compute Verification | | | | | | | |
| case-insensitive headers |6.1.3 |X| | | | | |
| invalid body hash mismatch |6.1.3 | |X| | | | |
| invalid header hash mismatch |6.1.3 | |X| | | | |
| Reporting | | | | | | | |
| Insert report headers before sig |6.2 | |X| | | | |
| Use AUTH-RES |6.2 | | |X| | | |
| remove AUTH-RES from other systems |6.2 | | |X| | | |
| Interpretation | | | | | | | |
| Consumers not accept invalid sigs |6.3 | | | |X| | |
| DATA permanent rejects 550 5.7.X |6.3 | |X| | | | |
| DATA temporary rejects 45x |6.3 | |X| | | | |
| use 45x for crypto failures |6.3 | | | | |X| |
| use 451 4.7.5 |6.3 | | |X| | | |
| convey to identity assessor |6.3 |X| | | | | |
| highlight SDID mismatch with From.Domain |6.3 | |X| | | | |
| log failures |6.3 | |X| | | | |
| treat invalid sigs as no sigs |6.3 | |X| | | | |
| | | | | | | | |
|Security | | | | | | | |
| Verify key records from DNS |8.7 |X| | | | | |
| Be prepared for malformed DKIM-Signatures |8.8 |X| | | | | |
| Verify ignore unlikely domains |8.13 | | |X| | | |
| | | | | | | | |
+-----------------------------------------------------------------------+
FootNotes
1. No explicit statement for signer and sha1
2. is a NULL string an asciiz String?
3. Section is confusing, mixes up sections (i.e. "previous steps"
... what steps?)
4. There is no explicit statement for a signer MUST implement simple or
relaxed, unlike explicit MUST statements for verifier.
5. Should this say "invalid signature"?
6. Ambiguous?
--
Hector Santos, CTO
http://www.santronics.com
http://santronics.blogspot.com
_______________________________________________
NOTE WELL: This list operates according to
http://mipassoc.org/dkim/ietf-list-rules.html