Bjørn Mork <
bjorn@mork.no> writes:
Claus Aßmann
<INVALID_NO_CC_REMOVE_IF_YOU_DO_NOT_POST_ml+sendmail(-no-copies-please)@esmtp.org>
writes:
Bjørn Mork wrote:
>
Note that CACertPath is for validating servers you connect to
(STARTTLS=client), while CACertFile is for validating clients connecting
to you (STARTTLS=server).
>
Please explain why you think this is the case.
SSL_CTX_load_verify_locations(*tls_ctx, cacertfile, cacertpath)
is invoked in inittls() - for server and client side.
>
Mainly based on experiments with all sorts of combinations. But looking
at the code also seems to confirm. The rest of that block is:
>
if ((r = SSL_CTX_load_verify_locations(*ctx, cacertfile,
cacertpath)) == 1)
{
# if !TLS_NO_RSA && MTA_RSA_TMP_CB
if (bitset(TLS_I_RSA_TMP, req))
SSL_CTX_set_tmp_rsa_callback(*ctx, tmp_rsa_key);
# endif
>
if (srv)
{
SSL_CTX_set_client_CA_list(*ctx,
SSL_load_client_CA_file(cacertfile));
}
}
So I have completely misunderstood this, as Claus correctly pointed
out. The call to SSL_CTX_load_verify_locations() means that all
certificates in both CACertPath and CACertFile are equally trusted.
I was confused by that SSL_CTX_set_client_CA_list() call, which defines
the list of trusted certificates sent by the server to clients. But this
list is not enforced. Any certificate signed by a CA in CACertPath is
also accepted and trusted by the server.
Can be tested using the openssl s_client application, which happily
ignores the certificate_authorities hint from the server and sends
whatever you specify using the -cert, -cert_chain and -key options.
But how are we supposed to configure a sendmail server then? MTA-STS
means that the trusted CA list must include every public CA. Using the
same list to validate client certificates makes them useless. If anyone
can get a trusted client certificate, then "AUTH EXTERNAL" is pretty
much an open relay. What am I missing?
Looking at this, I stumbled across _FFR_CLIENTCA which first appeared
in 8.16.0.48 (if the Debian git package log is correct). It's
documented in sendmail/conf.c as
#if _FFR_CLIENTCA
/*
** Allow to set client specific CA values.
** CACertFile: see doc/op.*:
** "The DNs of these certificates are sent to the client
** during the TLS handshake (as part of the CertificateRequest)
** as the list of acceptable CAs.
** However, do not list too many root CAs in that file,
** otherwise the TLS handshake may fail;"
** In TLSv1.3 the certs in CACertFile are also sent by
** the client to the server and there is seemingly a
** 16KB limit (just in OpenSSL?).
** Having a separate CACertFile for the client
** helps to avoid this problem.
*/
"_FFR_CLIENTCA",
#endif
This enables two new options, ClientCACertFile and ClientCACertPath,
which are used instead of CACertFile and CACertPath in client session
contexts. I.e. the contexts which will validate remote servers, and
therefore have to include all public CAs if MTA-STS is enabled.
Server session contexts will continue to use the CACertFile and
CACertPath for validating clients. So we can now limit those to our
private CA authorizing mail clients.
To summarize, this seems to do what I want:
O ClientCACertFile=/etc/ssl/certs/ca-certificates.crt
O ClientCACertPath=/etc/ssl/certs
O CACertPath=/dev/null
O CACertFile=/etc/mail-client-ca.pem
where /etc/ssl/certs and /etc/ssl/certs/ca-certificates.crt contains the
full OS managed list of public CAs, and /etc/mail-client-ca.pem contains
a single private CA certificate.
But depending on a build time _FFR which is not enabled in the default
Debian package worries me. Usually means I'm doing something wrong.
Comments and suggestions are appreciated
Bjørn