Basic workflow of the ARC implementation
Hi Steve!
Now going back to the implementation, the message needs to be signed after its headers have been cooked, since they are included in some of the signatures below. So after the message headers have been cooked, and before the message has been enqueued by the switchboards onto the various queues, we shall catch the email, and perform the ARC operations on it as given below. After this we can reinject the mail into the queues. This can be done by modifying the process that handles the queuing of the mails.(This can be done when the integration process into Mailman starts later on)
For now, I will assume that only the message is available to us in its complete form after the list has cooked its headers.
We need to generate a private and a public key for the signing purposes. For testing purposes, and while working on the code, I can probably generate the keys locally using the openssl tool.
As a rough sketch of implementation,
- ARC Seal
The tags -
NOTE - Now, here we needed to check the given message for any pre-existing signatures in most of the fields. For this I think a separate module can be created which can extract the previous ARC headers if they exist from the message. The code for this can be again used from the dkimpy package.
i: The value for this tag can be determined by performing a check on the original signature and seeing if there were previous ARC headers. If yes, we increment the value of the previous "i" by 1, and if no, make it 1. a: The value for this is fixed.
t,s,d: These can be obtained by using pre-existing dkimpy package.
b: Now we can compute the header hash using the dkimpy package again by using the headers given here <https://tools.ietf.org/html/draft-andersen-arc-02#section-5.1.1.3>. Here, we call the dkimpy package and get the signature for the above headers and then affix it to the "b="header.
cv: Use the same check as "i", if there is already an ARC i.e. i>1, then we make it as "V", else "N".
The ARC Seal gets computed here.
NOTE-For giving the "s" and "d" (selector and domain tag values), we will need to produce records for these where the key can be stored so that it is available for query by the verifiers (I still have to look up this mechanism).
- ARC Message Signature
The tags -
i: The value for this tag is determined similar to the "i" tag for the ARC Seal.
a,t,s,d: These can again be obtained from the dkimpy package.
bh: The body hash. This can be obtained from the package. Here, we set the canonicalization to 'relaxed' and get the body hash.
h: The "h=" header list is signed with the implicit list (as given in the draft) and any explicit list that we want in addition. Now, for mailing lists, the recommended headers are - List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe:Reply-To: and any other fields added by the list like the Precedence, XTopics or else. We will also sign the DKIM signature of the previous mail here if available(suggested by the draft). For this signing, we can use a modified version where the FROZEN_HEADERS(headers that are signed by default) will specify the implicit headers according to ARC specs(Another option could be to get all the implicit+explicit headers signed by the package, extract the h header, and modify it to include only the explicit headers.) b: The signature, calculated from the package. The h tag is used as described above.
- ARC Authentication Results. The "i" tag simply takes on the value same as the above "i" tags. Now from our previous conversation, as you suggested, the authenticity of the previous MTA who sent us the mail is not sure to be trusted. So in the case where we don't trust the previous MTA, we will have to perform our own DMARC, SPF, DKIM testing of the recieved mail. If previous ARC chain exists i.e. cv=V, then we perform the ARC test too. Now for performing the tests - In one of the earlier mails, we discussed the use of the "authres" package for generating the authentication results header. The package conforms to the RFC7001 format, and now the format used is RFC7601. But according to the changes that I verified, we can use the package without any changes. (The changes were mostly related to extra specifications that are optional. Can be skipped for our purposes) So the "authres" package can be called here for generating the AAR.
If we need to perform the ARC test, then the module for that will have to be implemented manually. Though most of the code from the package for DKIM verification can be used. This is also the point where we detect if the mail is spam or not. If the arc test fails, then there is something fishy here. DKIM, DMARC, SPF may fail, but the failure of this test means the mail is not authentic. At this point the mail should probably be discarded (or any other measures that need to be taken).
Now coming to the testing part. There can be a number of tests like verifying the generated ARC signature, changing the body of the message, failing when the implicitly signed AMS headers are changed and other such tests.
Is this the workflow you were expecting to see, or should I write a more explanatory draft ? I would like to know your review of this, so that I can figure out if I am going wrong anywhere. :)
(Also wherever I have mentioned the use of dkimpy, a lot of custom implementation is needed to suit our requirements. )
Thanks!
Aditya
participants (1)
-
Aditya Divekar