Including Jordan Brown who is the person that has been replying
previously.
This is a merger of both previous responses from Aaron and Howard.
Doug.
On 06/23/15 09:37, Howard Chu wrote:
On 06/23/15 08:56, Aaron Richton wrote:
On Mon, 22 Jun 2015, Doug Leavitt wrote:
[...]
The code change itself is simple. At a
minimum it is as simple as adding:
#ifdef X509_V_FLAG_PARTIAL_CHAIN
Perhaps with a doc patch too, since this would make OpenLDAP one
of (apparently very) few OpenSSL-linked applications that honors
partial chains.
I think perhaps the most informative way to look at it is by way of
comparison to browser behavior.
If you have a web site with a certificate like:
rootCA -> servercert
and your browser's trust list doesn't include rootCA, your browser
will prompt you for a security exception. When you approve the
security exception, it will add servercert to its trust list... not
rootCA. After that, it will accept connections using servercert,
but will not in general accept certificates signed by rootCA.
We want that same semantic in LDAP processing.
(Now, to be complete there would also be ways to accept cases like
certificates that have the wrong server name in them. Browsers
handle that; I'm not proposing a way for LDAP to handle those
cases.)
OpenSSL by default ignores trust-list
entries that are not for root CAs. Adding just the "mysystem"
certificate has no effect. With this change, you can add the
"mysystem" certificate and that will cause OpenSSL to accept
this certificate, even though the trust list does not include
the CA's root certificate.
The comment "even though the trust list does not include the CA's
root certificate" seems a bit odd to me:
An argument that we take today's behavior (require rootCA;
mysystemA[rootCA] or mysystemB[rootCA] are both OK) and make it
more strict with "require rootCA AND mysystemA[rootCA]"
intuitively sounds like an increase in security...if you have a
client environment controlled enough to distribute
ldap.example.com's material along with your CA store, go for it.
But the concept of "require ldap.example.com" while (optionally?)
throwing out the existing rootCA (and presumably its associated
CRL/OCSP/etc.) checking sounds like it could introduce risk. So is
ldap.example.com truly an "add" to the chain, or is the rootCA not
included (i.e. removed)?
This change is interesting in cases where rootCA is not included in
the trust list. (It may have been removed, or may have never been
included; that depends on what your original trust list looked
like.)
Let's take a few examples.
Consider two certificates: a certificate issued to myserver by
rootCA, and a certificate issued to a villain by rootCA.
Trust list: rootCA
Today: accept all certificates rootCA->*, including both
rootCA->myserver and rootCA->villain
With this change: Same
Trust list: rootCA, rootCA->myserver
Today: Accept all certificates rootCA->*. (myserver entry has
no effect)
With this change: Same
Trust list: rootCA->myserver (no rootCA certificate)
Today: Accept nothing.
With this change: Accept rootCA->myserver (but not
rootCA->villain)
First, note that the behavior changes only when the
rootCA->myserver certificate is included in the trust list.
Today, that entry is completely meaningless in an OpenLDAP trust
list.
Second, note that today, if you want to be able to connect to
myserver, you *must* accept all rootCA-signed
certificates. You cannot choose to accept rootCA->myserver while
rejecting rootCA->villain. With this change, you can choose to
accept myserver while rejecting villain.
Similar discussions apply to intermediate CAs and are left as an
exercise for the reader.
Pretty
sure adding this feature will break compatibility with default
OpenSSL installs. We already went thru this headache for GnuTLS.
http://www.openldap.org/its/index.cgi/Software%20Bugs?id=5991
This bug talks about what certificates one presents to the peer.
That's not at all the question. The question is what certificates
one (in particular the client, but could apply to the server too) *accepts*.
Normal
practice for servers is to trust only a single CA chain - the one
that issued its own cert and all the client certs that it intends
to honor.
I'm talking about what certificates a client accepts, not what
certificates a server accepts, but the same principles apply.
Suppose that Verisign issued your server's certificate, and will
issue all of your clients' certificates. OK, but... you are also
forced to accept certificates that Verisign issued to *me*. Did you really want to accept
those?
Normal
practice for clients is to trust multiple CA chains, assuming the
client is used with multiple servers owned by disparate admin
authorities. (Or, if only used in one administrative context, just
a single chain.)
So far it looks to me like you want to support broken server
configurations.
No... we want to trust only particular subtrees, not necessarily all
certificates signed by the root.
I
recognize the desire to only trust the immediate superior CA of an
end entity's own cert; that sort of makes sense. But certs can
only be trusted if you also trust their issuer, you cannot make
valid assertions about a cert if you don't follow the chain all
the way back to a self-signer (which you also explicitly trust).
Not at all true.
Once Verisign has issued a CA certificate to (say) Oracle, only
Oracle can issue new certificates against that CA certificate. Even
Verisign cannot issue certificates against that CA certificate,
because Verisign does not have the private key for that
certificate. Verisign could issue a new (bogus) certificate that
says "Oracle", but it would not be the same certificate; if you are
trusting that original certificate then certificates based on the
new bogus certificate would not be trusted.
Also if you only want to trust the 1-level superior of a
particular cert, you probably should not have been using
commercial/3rd-party CAs in the first place. Clearly in the
scenarios you've outlined, the fact that someone paid for a cert
from a well-known commercial root CA is irrelevant here. They
would have been better off creating their own CA cert and using it
to create their end entity certs.
That assumes that the server administrators and all of the client
share the same level of paranoia.
Less paranoid clients might trust the 3rd party root CA, while more
paranoid clients might trust only the organization's CA
(rootCA->orgCA), and still more paranoid clients might trust only
the particular server (rootCA->orgCA->myserver). A client
should be in charge of its own level of paranoia - it would be wrong
for a paranoid client to force the server to force all of the other
clients to be paranoid, just as it would be wrong for a
less-paranoid client to force the server to force all of the other
clients to be less paranoid.