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