#3916: Mutt 1.8: TOFU approach bails out on first fail or reject, not offering
higher links of the cert' chain
--------------------------+----------------------
Reporter: kratem32 | Owner: mutt-dev
Type: enhancement | Status: new
Priority: minor | Milestone: 1.8
Component: crypto | Version:
Resolution: | Keywords: tofu
--------------------------+----------------------
Comment (by m-a):
Replying to [comment:48 kevin8t8's comment:48] (and after having read
kratem32's comment:49):
> Matthias,
>
> I feel as if some confusion is occurring about how the option/patch is
intended to be used. Or it may be that I am too ignorant and am missing
an important point.
TL;DR: {{{X509_V_FLAG_PARTIAL_CHAIN}}} appears to be the flag we need to
get this going right. The gist of prototypical code I have given below.
Details:
The important point is providing a sound user interface that lives up to
the users' expectations, makes the options do what they promise, and we
can stop the quadoption abuse and go for a binary option instead.
If "let them tinker" is the excuse to waive that requirement, we can forgo
the UI altogether and make them stuff the certificates manually into their
mutt_certificates file, but even then we need to permit OpenSSL to accept
partial chains.
So, preliminary results with a piece of code such as the one below (not
ready to be sewn onto the code yet) mutt_ssl.c makes "=ask-yes" exactly
what we set out to reinstate, barring the "presents root certificate
twice". With this code and Ubuntu 16.04's OpenSSL 1.0.2blah, **any**
certificate from the chain (including root, either single one of both
intermediate CAs, or the server's certificate) that is in our cache makes
OpenSSL accept the host certificate without further ado. This is
incremental to the other two patches. We may then even be able to reduce
the complexity of the ticket-3916-verify-partial-quadoption.patch quite a
bit, I hope that we can omit the entire "skip" logic.
TODOS:
* add error handling
* make $ssl_verify_partial_chains a binary option (instead of the
quadoption), and make the new "yes" of the new option behave the same as
the old ask-yes/ask-no of the current quadoption
* mask the entire rig with partial chain support under the "yes"/true
path of $ssl_verify_partial_chains
* test on OpenSSL 1.0.2b+ with {{{OPENSSL_NO_SSL_INTERN}}} (no longer
supported as of 1.1.0) and
* see if this whole lot is needed at all with OpenSSL 1.1.0+ because it
sets {{{X509_V_FLAG_TRUSTED_FIRST}}}
* test on OpenSSL 1.1.0blah with {{{OPENSSL_NO_DEPRECATED}}}
* test on OpenSSL master with {{{OPENSSL_NO_DEPRECATED}}}
* consider if we need to support older OpenSSL versions. Upstream
doesn't, so I won't contribute here. If anyone wants to run mutt 1.8.1 on
OpenSSL 1.0.1 they can seek paid support.
* figure out why the root cert is presented twice, and avoid that.
{{{
...
+#include <openssl/x509_vfy.h>
...
@@ -459,6 +460,16 @@
SSL_CTX_set_cipher_list (data->ctx, SslCiphers);
}
+ X509_VERIFY_PARAM *param;
+ param = X509_VERIFY_PARAM_new();
+ if (param) {
+ X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_PARTIAL_CHAIN);
+ SSL_CTX_set1_param(data->ctx, param);
+ X509_VERIFY_PARAM_free(param);
+ } else {
+ /* XXX Handle error */
+ }
+
}}}
> > Saving the cert of the intermediate that is closer to the root (2/4),
however, mutt
> > will ask for the root again next time.
> No. The **next** time you connect, ssl_verify_partial_chains should be
set to "=yes". The patch will ignore (1/4), find (2/4) in the certificate
file and return true, and so (3/4) and (4/4) should then be marked
preverify_ok=1.
Unacceptable. This needs to become a binary option, as laid out above.
> The ssl_verify_partial_chains=ask-yes setting is **only** for the
**first** time you connect to a host. The (s)kip option is only to help
you save one of the certificates in the chain to your certificate file.
Once you do this, you set it back to "=yes".
This option flipping is not needed for the function, isn't process-safe
(i. e. will generate a lot of frustration and user support, and require a
lot of documentation to get right), and should not be made.
> > Or we implement an even more complex concept that uses the
> > earlier callbacks to just build a global view of the chain,
> > always pretending success and caching the preverify results as
> > well as the cache state, until we get to the final
> > callback (which is the one concerning the host certificate), when
> > we present the user with the necessary questions. This would,
> > however, amount to doing most of the verification in loops
> > ourselves again. But before we go into code, we need to
> > understand how OpenSSL itself deals with "alternative trust
>
> This is certainly the *best* way to go about it. But I am trying to
avoid this option
> if at all possible. I feel the quadoption patch allows the tinkerers to
tinker
> without too much effort from mutt development side, while the "=no"
option
> preserves the safe/correct behavior for 99% of the users.
>
> With the above explanation, does the patch make more sense? MichaĆ does
it
> make sense to you?
The current patch is inferior to a solution that is based on your patch,
simplified, and flips a few OpenSSL levers in the right way. A patch that
causes confusing behaviour cannot be rectified or justified with
documentation, let's get it right, and we can. I can't promise any more
refined version before 2017-03-06 though.
--
Ticket URL: <https://dev.mutt.org/trac/ticket/3916#comment:50>
Mutt <http://www.mutt.org/>
The Mutt mail user agent