Including Jordan Brown who is the person that has been replying previously.
This is a merger of both previous responses from Aaron and Howard.


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:


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's material along with your CA store, go for it.

But the concept of "require" while (optionally?) throwing out the existing rootCA (and presumably its associated CRL/OCSP/etc.) checking sounds like it could introduce risk. So is 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.

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.