Thanks for your help,
Jan.
http://www.postfix.org/TLS_README.html#client_cert_key
To verify a remote SMTP server certificate, the Postfix SMTP
client needs to trust the certificates of the issuing certification
authorities. These certificates in "pem" format can be stored in
a single $smtp_tls_CAfile or in multiple files, one CA per file
in the $smtp_tls_CApath directory. If you use a directory, don't
forget to create the necessary "hash" links with:
# $OPENSSL_HOME/bin/c_rehash /path/to/directory
The $smtp_tls_CAfile contains the CA certificates of one or more
trusted CAs. The file is opened (with root privileges) before Postfix
enters the optional chroot jail and so need not be accessible from
inside the chroot jail.
Additional trusted CAs can be specified via the $smtp_tls_CApath
directory, in which case the certificates are read (with $mail_owner
privileges) from the files in the directory when the information is
needed. Thus, the $smtp_tls_CApath directory needs to be accessible
inside the optional chroot jail.
The choice between $smtp_tls_CAfile and $smtp_tls_CApath is a
space/time tradeoff. If there are many trusted CAs, the cost of
preloading them all into memory may not pay off in reduced access
time when the certificate is needed.
Example:
/etc/postfix/main.cf:
smtp_tls_CAfile = /etc/postfix/CAcert.pem
smtp_tls_CApath = /etc/postfix/certs
See also the recent posts about migrating from 0.9.8 CApath to 1.0.0
CApath where the hash links made by c_rehash are not 0.9.8 compatible
(and vice versa).
--
Viktor.
When postfix connects to a smtp server (tls verify), certificates
issued by CAs from /etc/ssl/certs AND from /foo/bar are trusted. Do
you confirm this ?
Thanks,
Jan
On Wed, Jun 09, 2010 at 10:22:16AM +0200, Jan C. wrote:
> thanks for your answer but that does not answer by question. Is the
> /etc/ssl/certs directory loaded also by default ? I did the test:
Postfix postconf(5) defaults can be shown with the postconf(1) tool:
$ /usr/sbin/postconf -d smtp_tls_CApath
smtp_tls_CApath =
Defaults are also documented as much as possible in the postconf(5)
man page; every defined setting has its own hyperlink in the HTML
version, as such: postconf.5.html#smtp_tls_CApath
> smtp_tls_CApath = /foo/bar
> I added/hashed some certs in /foo/bar
>
> When postfix connects to a smtp server (tls verify), certificates
> issued by CAs from /etc/ssl/certs AND from /foo/bar are trusted. Do
> you confirm this ?
Um, no. By default Postfix is not going to use TLS at all. When
activated, by default, no certificate verification is done at all.
Consult your distributor's package documentation if they have set
different defaults.
--
Offlist mail to this address is discarded unless
"/dev/rob0" or "not-spam" is in Subject: header
If I set smtp_tls_CApath to /etc/ssl/certs and then again to something
else, it looks like the CAs from /etc/ssl/certs are being all the time
loaded:
Here is what I did:
1- clean installation of Postfix (2.5.5) on Debian Lenny
2- TLS policy mapping for destination tls.com "verify match=test-tls.com"
3- copy the CA of the test-tls.com to /etc/ssl/certs and run c_rehash
3- leave smtp_tls_CApath empty
If I send an email now, it gets deffered (Server certificate not
trusted). Until now it makes perfect sense.
Now I set:
~ $ postconf -e smtp_tls_CApath=/etc/ssl/certs/
and reload postfix
If I send an email, it is correctly sent via TLS. Again, it makes sense.
Thing is that now, I set smtp_tls_CApath to something else (empty
directory) and the CA is still trusted :
~ $ mkdir -p /foo/bar
~ $ postconf -e smtp_tls_CApath=/foo/bar/
~ $ postfix reload
Postfix log:
> tls.com[10.2.87.10]:25: Matched subject_CN=test-tls.com, issuer_CN=Admin Test TLS
.. so how can the certificate be trusted if I point the
smtp_tls_CApath to an empty dir ?
Still with smtp_tls_CApath pointing to /foo/bar, I delete my CA from
/etc/ssl/certs/ and rehash, the email gets again deferred:
> relay=tls.com[10.2.87.10]:25, delay=0.11, delays=0.01/0.03/0.07/0, dsn=4.7.5, status=deferred (Server certificate not trusted)
.. so there must be somewhere a reference to /etc/ssl/certs
Did I miss something ?
to sum it up, when smtp_tls_CApath is not empty, CAs from
/etc/ssl/certs are trusted regardless the value of smtp_tls_CApath.
regards,
Jan
Victor will have to confirm or deny this, but we may have to update
the main code in function tls_set_ca_certificate_info():
if (CAfile || CApath) {
if (!SSL_CTX_load_verify_locations(ctx, CAfile, CApath)) {
msg_info("cannot load Certificate Authority data: "
"disabling TLS support");
tls_print_errors();
return (-1);
}
+ } else {
if (!SSL_CTX_set_default_verify_paths(ctx)) {
msg_info("cannot set certificate verification paths: "
"disabling TLS support");
tls_print_errors();
return (-1);
}
}
Unfortunately OpenSSL has no documentation for the
SSL_CTX_set_default_verify_paths() function, so it is hard to be
sure that the function is used in a correct manner.
The change above is based on a patch for the s_client program:
http://rt.openssl.org/Ticket/Display.html?id=2203&user=guest&pass=guest
Wietse
> > to sum it up, when smtp_tls_CApath is not empty, CAs from
> > /etc/ssl/certs are trusted regardless the value of smtp_tls_CApath.
This is done primarily by OpenSSL, but as Wietse observes:
> Victor will have to confirm or deny this, but we may have to update
> the main code in function tls_set_ca_certificate_info():
>
> if (CAfile || CApath) {
> if (!SSL_CTX_load_verify_locations(ctx, CAfile, CApath)) {
> msg_info("cannot load Certificate Authority data: "
> "disabling TLS support");
> tls_print_errors();
> return (-1);
> }
> + } else {
> if (!SSL_CTX_set_default_verify_paths(ctx)) {
> msg_info("cannot set certificate verification paths: "
> "disabling TLS support");
> tls_print_errors();
> return (-1);
> }
> }
We could make this change, but it would be an incompatibility with past
behaviour. This code dates back to the original TLS patch for Postfix
releases prior to 2.1, and augments the default system CA paths, instead
of replacing them.
I guess our documentation has never promised the use of system CAs when
CApath or CAfile are set, failing to override the system settings is
counter-intuitive, so I can support this change. We'll also have to
document the semantics of "CAfile == CApath == <empty>".
> Unfortunately OpenSSL has no documentation for the
> SSL_CTX_set_default_verify_paths() function, so it is hard to be
> sure that the function is used in a correct manner.
The function is used correctly, and sadly a large part of the OpenSSL
API that is not internal, and ought to be documented, is not.
> The change above is based on a patch for the s_client program:
> http://rt.openssl.org/Ticket/Display.html?id=2203&user=guest&pass=guest
This largely explains how Postfix came to have the code it does. Since
OpenSSL is both complex and incompletely documented, many OpenSSL client
applications are cargo-cult copies of example code in the OpenSSL apps/
directory, with SSL apps typically borrowing code snippets from s_client
and s_server.
The patch whose URL is above has not yet been adopted into OpenSSL, the
1.0.0a release still has the original code:
if ((!SSL_CTX_load_verify_locations(ctx,CAfile,CApath)) ||
(!SSL_CTX_set_default_verify_paths(ctx)))
{
/* BIO_printf(bio_err,"error setting default verify locations\n"); */
ERR_print_errors(bio_err);
/* goto end; */
}
--
Viktor.
On Wed, Jun 9, 2010 at 6:12 PM, Victor Duchovni
<Victor....@morganstanley.com> wrote:
> I guess our documentation has never promised the use of system CAs when
> CApath or CAfile are set, failing to override the system settings is
> counter-intuitive, so I can support this change. We'll also have to
> document the semantics of "CAfile == CApath == <empty>".
so what I should do is to suppose that only the certs from
smtp_tls_CApath are trusted and that's all. If I need the system CAs,
I should copy them to my smtp_tls_CApath directory .. correct ?
Thanks for your support,
Jan
Probably, although I don't think we've reached a final decision yet...
My preference is to not trust some random list of CAs that came with the
O/S OpenSSL package when the user specifies an explicit CAfile/CApath,
but this would be an incompatible change.
In my case, the OpenSSL package I use is built by me, and has an empty
default list of trusted CAs, so I never notice the extra default certs.
--
Viktor.
ok, could you please point me to the place where one can set those
paths while building OpenSSL ?
Jan
You are too lazy to run "Configure --help"? OK, though it is off-topic
here:
Usage: Configure [no-<cipher> ...] [enable-<cipher> ...]
[experimental-<cipher> ...] [-Dxxx] [-lxxx] [-Lxxx] [-fxxx] [-Kxxx]
[no-hw-xxx|no-hw] [[no-]threads] [[no-]shared]
[[no-]zlib|zlib-dynamic] [no-asm] [no-dso] [no-krb5] [386]
--> [--prefix=DIR]
--> [--openssldir=OPENSSLDIR]
[--with-xxx[=vvv]] [--test-sanity] os/compiler[:flags]
If only specify "prefix" the cert directory is $prefix/ssl, otherwise
it is $openssldir, in which OpenSSL itself does not place any default
certificates, that's done by vendor package maintainers. OpenSSL itself
installs just:
.../ssl/
.../ssl/openssl.cnf
.../ssl/private/
.../ssl/certs/
.../ssl/misc/
.../ssl/misc/CA.pl
.../ssl/misc/CA.sh
.../ssl/misc/c_hash
.../ssl/misc/c_info
.../ssl/misc/c_issuer
.../ssl/misc/c_name
.../ssl/misc/tsget
--
Viktor.
The empty setting would correspond with the default system-supplied
CA certificates.
There is at least one Postfix feature that relies on the ability
to override the default system-supplied CA certificates:
permit_tls_all_clientcerts
Permit the request when the remote SMTP client certificate is
verified successfully. This option must be used only if a spe-
cial CA issues the certificates and only this CA is listed as
trusted CA, otherwise all clients with a recognized certificate
would be allowed to relay. This feature is available with Post-
fix version 2.2.
It would seem then that permit_tls_all_clientcerts is broken.
What else would be broken by the current practice of always including
the default CA certificates? If there is nothing else, then most
sites would not be affected, but a lot of sites could be at risk of
breaking when we change the CAfile/CApath behavior.
Therefore it would be desirable to provide a compatibility switch
that is "incompatible" for Postfix 2.8 and "compatible" for the
earlier releases.
Wietse
> > I guess our documentation has never promised the use of system CAs when
> > CApath or CAfile are set, failing to override the system settings is
> > counter-intuitive, so I can support this change. We'll also have to
> > document the semantics of "CAfile == CApath == <empty>".
>
> The empty setting would correspond with the default system-supplied
> CA certificates.
>
> There is at least one Postfix feature that relies on the ability
> to override the default system-supplied CA certificates:
>
> permit_tls_all_clientcerts
> Permit the request when the remote SMTP client certificate is
> verified successfully. This option must be used only if a spe-
> cial CA issues the certificates and only this CA is listed as
> trusted CA, otherwise all clients with a recognized certificate
> would be allowed to relay. This feature is available with Post-
> fix version 2.2.
Good point, oops! This too pre-dates Postfix 2.2, but it is rather unsafe
when the default system CA list includes all the usual suspects.
> It would seem then that permit_tls_all_clientcerts is broken.
Yes, for Postfix distributions where the vendor helpfully populates the
OpenSSL "ssl/certs/" directory.
> What else would be broken by the current practice of always including
> the default CA certificates? If there is nothing else, then most
> sites would not be affected, but a lot of sites could be at risk of
> breaking when we change the CAfile/CApath behavior.
Trusting unwanted CAs on the server side means:
1. The "Received:" header (Client CN, ... verified OK) could
be misleading.
2. The "smtpd_tls_req_ccert" feature may be more permissive
than desired.
3. As you observed "permit_tls_all_clientcerts" is unsafe.
4. Policy service requests may pass client CNs that are not
intended to be trusted.
5. Milters may process the client subject and issuer CN.
On the client side, we only use server certificates for destinations
with a "verify" or "secure" policy, so here the risk is MITM if one
of the public CAs issues certs that one has good cause to not trust.
> Therefore it would be desirable to provide a compatibility switch
> that is "incompatible" for Postfix 2.8 and "compatible" for the
> earlier releases.
Works for me. And of course a new warning in the
"permit_tls_all_clientcerts" postconf(5) entry.
--
Viktor.
Why do we have to document or change Postfix default behavior?
Default Postfix behavior (empty CAfile and CApath) is a NOOP.
Postfix calls neither SSL_CTX_load_verify_locations() nor
SSL_CTX_set_default_verify_paths().
First, I don't see why we should change Postfix default behavior:
the problem is with non-default settings.
Second, I don't see how we could document existing Postfix default
behavior (empty CAfile and CApath), when that behavior is not
defined by the OpenSSL API.
OpenSSL source code does not count as a definition, nor do words
from OpenSSL programmers or code examples. They can change program
behavior because they are not bound by the contract of an API.
Wietse
> Victor Duchovni:
> > I guess our documentation has never promised the use of system CAs when
> > CApath or CAfile are set, failing to override the system settings is
> > counter-intuitive, so I can support this change. We'll also have to
> > document the semantics of "CAfile == CApath == <empty>".
>
> Why do we have to document or change Postfix default behavior?
Sorry, failed to look at the code closely. We can leave the default
behaviour alone.
--
Viktor.