Subject: [ietf-dkim] DKIM Requirements Summary

From: Hector Santos <[email-masked]>
Date: Fri, 20 May 2011 19:30:22 -0400

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