Discussion:
X509_V_FLAG_PARTIAL_CHAIN support in OpenLDAP
Doug Leavitt
2015-06-05 23:04:45 UTC
Permalink
Content preview: Hi, OpenSSL now has X509_V_FLAG_PARTIAL_CHAIN support in the
code base as of 1.0.2a. I would like to submit a patch to enable X509_V_FLAG_PARTIAL_CHAIN
support in OpenLDAP libldap, assuming it exists in the version of OpenSSL
being use to build OpenLDAP. [...]

Content analysis details: (-1.9 points, 5.0 required)

pts rule name description
---- ---------------------- --------------------------------------------------
-0.0 T_RP_MATCHES_RCVD Envelope sender domain matches handover relay
domain
-0.0 SPF_PASS SPF: sender matches SPF record
-1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1%
[score: 0.0000]

Hi,
OpenSSL now has X509_V_FLAG_PARTIAL_CHAIN support in the code base as of
1.0.2a.

I would like to submit a patch to enable X509_V_FLAG_PARTIAL_CHAIN support
in OpenLDAP libldap, assuming it exists in the version of OpenSSL being
use to build
OpenLDAP.

Before I submit any patch I would like to know that would be acceptable
for integration.

Should support always be enabled if the version of OpenSSL has it
e.g. ifdef on X509_V_FLAG_PARTIAL_CHAIN
Should it be a config time option check and ifdef enable if found in
e.g. like the ifdef on HAVE_OPENSSL_CRL
Are there more requirements that is required in the patch, before it would
be accepted such as ldap_set_option support?

Thanks in advance,
Doug.
Howard Chu
2015-06-06 18:35:45 UTC
Permalink
Content preview: Doug Leavitt wrote: > Hi, > OpenSSL now has X509_V_FLAG_PARTIAL_CHAIN
support in the code base as of 1.0.2a. > > I would like to submit a patch
to enable X509_V_FLAG_PARTIAL_CHAIN support > in OpenLDAP libldap, assuming
it exists in the version of OpenSSL being use to > build > OpenLDAP. [...]


Content analysis details: (-4.2 points, 5.0 required)

pts rule name description
---- ---------------------- --------------------------------------------------
-2.3 RCVD_IN_DNSWL_MED RBL: Sender listed at http://www.dnswl.org/, medium
trust
[69.43.206.106 listed in list.dnswl.org]
0.0 URIBL_BLOCKED ADMINISTRATOR NOTICE: The query to URIBL was blocked.
See
http://wiki.apache.org/spamassassin/DnsBlocklists#dnsbl-block
for more information.
[URIs: highlandsun.com]
-1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1%
[score: 0.0000]
Hi,
OpenSSL now has X509_V_FLAG_PARTIAL_CHAIN support in the code base as of 1.0.2a.
I would like to submit a patch to enable X509_V_FLAG_PARTIAL_CHAIN support
in OpenLDAP libldap, assuming it exists in the version of OpenSSL being use to
build
OpenLDAP.
What's the use case? It appears that the feature has been in OpenSSL since
around 2012, but I don't see much documentation or chatter about it. Why is it
useful, and do GnuTLS and MozNSS already support a similar feature?
Before I submit any patch I would like to know that would be acceptable
for integration.
Should support always be enabled if the version of OpenSSL has it
e.g. ifdef on X509_V_FLAG_PARTIAL_CHAIN
Should it be a config time option check and ifdef enable if found in
e.g. like the ifdef on HAVE_OPENSSL_CRL
Are there more requirements that is required in the patch, before it would
be accepted such as ldap_set_option support?
Thanks in advance,
Doug.
--
-- Howard Chu
CTO, Symas Corp. http://www.symas.com
Director, Highland Sun http://highlandsun.com/hyc/
Chief Architect, OpenLDAP http://www.openldap.org/project/
Doug Leavitt
2015-06-22 22:30:42 UTC
Permalink
Content preview: Sorry for the delay. I needed to do some due diligence before
responding. On 06/06/15 13:35, Howard Chu wrote: > Doug Leavitt wrote: >>
Hi, >> OpenSSL now has X509_V_FLAG_PARTIAL_CHAIN support in the code base
as >> of 1.0.2a. >> >> I would like to submit a patch to enable X509_V_FLAG_PARTIAL_CHAIN
Post by Howard Chu
support >> in OpenLDAP libldap, assuming it exists in the version of OpenSSL
being use to >> build >> OpenLDAP. > > What's the use case? It appears
that the feature has been in OpenSSL > since around 2012, but I don't see
much documentation or chatter about > it. Why is it useful, and do GnuTLS
and MozNSS already support a > similar feature? [...]

Content analysis details: (-1.9 points, 5.0 required)

pts rule name description
---- ---------------------- --------------------------------------------------
0.0 RCVD_IN_DNSWL_BLOCKED RBL: ADMINISTRATOR NOTICE: The query to DNSWL
was blocked. See
http://wiki.apache.org/spamassassin/DnsBlocklists#dnsbl-block
for more information.
[156.151.31.81 listed in list.dnswl.org]
0.0 URIBL_BLOCKED ADMINISTRATOR NOTICE: The query to URIBL was blocked.
See
http://wiki.apache.org/spamassassin/DnsBlocklists#dnsbl-block
for more information.
[URIs: gitlab.com]
-0.0 T_RP_MATCHES_RCVD Envelope sender domain matches handover relay
domain
-0.0 SPF_PASS SPF: sender matches SPF record
-1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1%
[score: 0.0000]

Sorry for the delay. I needed to do some due diligence before responding.
Post by Howard Chu
Hi,
OpenSSL now has X509_V_FLAG_PARTIAL_CHAIN support in the code base as of 1.0.2a.
I would like to submit a patch to enable X509_V_FLAG_PARTIAL_CHAIN support
in OpenLDAP libldap, assuming it exists in the version of OpenSSL being use to
build
OpenLDAP.
What's the use case? It appears that the feature has been in OpenSSL
since around 2012, but I don't see much documentation or chatter about
it. Why is it useful, and do GnuTLS and MozNSS already support a
similar feature?
The use case is:

You have a certificate issued by a CA:

rootCA -> mysystem

You don't want to trust all of the certificates issued by that CA. You
only want to trust that particular certificate.

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.

A more complex case:

rootCA -> mycompanyCA -> mysystem

You don't want to trust all of the certificates issued by that CA. You
only want to trust certificates issued by your company's CA. Again,
OpenSSL by default will not let you trust an intermediate CA. With this
change, you can add mycompanyCA's certificate and that will cause
OpenSSL to accept certificates signed by your company CA.


The reason this is coming up now, is that the old Mozilla libldap/NSS
combination supported this by default but the combination of
OpenLDAP/OpenSSL currently does not. We first discovered the issue back
in 2012 and realized that OpenSSL did not support partial chains.
Working through our security team the project that discovered the issue
convinced the OpenSSL upstream to add the X509_V_FLAG_PARTIAL_CHAIN
support so that eventually we could find a way to incorporate that
support back into OpenLDAP.

Additionally we have since uncovered some programs that depend on this
Mozilla functionality and we would like to see it supported in the
OpenLDAP/OpenSSL so those applications can finish moving off Mozilla
libldap/NSS.

Moving forward to today it looks like OpenSSL has the support, disabled
by default, and both GNUTLS and NSS have the support for partial chains
enabled by default.

In GNUTLS, the support is here:
https://gitlab.com/gnutls/gnutls/blob/master/lib/x509/verify.c#L868

In NSS the support is here:
http://mxr.mozilla.org/security/source/security/nss/lib/certhigh/certvfy.c#532

where intermediate certificates are processed (with the final decision
at 557), and that leaf certificates are handled at
http://mxr.mozilla.org/security/source/security/nss/lib/certhigh/certvfy.c#916


In OpenSSL the support is disabled by default here:
https://github.com/openssl/openssl/blob/master/crypto/x509/x509_vfy.c#L819

Our hope is to have OpenLDAP/OpenSSL be either on par with OpenLDAP/NSS and
OpenLDAP/GNUTLS or at least have the option of be on par without having to
maintain a downstream code fork.


The code change itself is simple. At a minimum it is as simple as adding:

#ifdef X509_V_FLAG_PARTIAL_CHAIN
/*
* Allow intermediate or leaf certificates in the trust list to
* act as trust anchors.
*/
X509_STORE_set_flags(SSL_CTX_get_cert_store(ctx),
X509_V_FLAG_PARTIAL_CHAIN);
#endif

after:

http://www.openldap.org/devel/gitweb.cgi?p=openldap.git;a=blob;f=libraries/libldap/tls_o.c;h=5d2367c6c1cc1e45707dbd070dadf88a556f8d74;hb=HEAD#l381



From our investigation always adding the support does not seem to be
harmful in any way and maintains compatibility with some existing software.

Hence the original question.

Thanks in advance for your consideration,
Doug.
Post by Howard Chu
Before I submit any patch I would like to know that would be acceptable
for integration.
Should support always be enabled if the version of OpenSSL has it
e.g. ifdef on X509_V_FLAG_PARTIAL_CHAIN
Should it be a config time option check and ifdef enable if found in
e.g. like the ifdef on HAVE_OPENSSL_CRL
Are there more requirements that is required in the patch, before it would
be accepted such as ldap_set_option support?
Thanks in advance,
Doug.
Aaron Richton
2015-06-23 13:56:33 UTC
Permalink
Content preview: 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. [...]

Content analysis details: (-1.9 points, 5.0 required)

pts rule name description
---- ---------------------- --------------------------------------------------
0.0 RCVD_IN_DNSWL_BLOCKED RBL: ADMINISTRATOR NOTICE: The query to DNSWL
was blocked. See
http://wiki.apache.org/spamassassin/DnsBlocklists#dnsbl-block
for more information.
[128.6.68.250 listed in list.dnswl.org]
-0.0 T_RP_MATCHES_RCVD Envelope sender domain matches handover relay
domain
-1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1%
[score: 0.0000]

On Mon, 22 Jun 2015, Doug Leavitt wrote:

[...]
Post by Doug Leavitt
#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.
Post by Doug Leavitt
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)?
Howard Chu
2015-06-23 14:37:30 UTC
Permalink
Content preview: Doug Leavitt wrote: > Sorry for the delay. I needed to do
Post by Doug Leavitt
Doug Leavitt wrote: >>> Hi, >>> OpenSSL now has X509_V_FLAG_PARTIAL_CHAIN
support in the code base as of >>> 1.0.2a. >>> >>> I would like to submit
a patch to enable X509_V_FLAG_PARTIAL_CHAIN support >>> in OpenLDAP libldap,
assuming it exists in the version of OpenSSL being use to >>> build >>> OpenLDAP.
Post by Doug Leavitt
Post by Howard Chu
What's the use case? It appears that the feature has been in OpenSSL
since >> around 2012, but I don't see much documentation or chatter about
it. Why is >> it useful, and do GnuTLS and MozNSS already support a similar
Post by Doug Leavitt
rootCA -> mysystem > > You don't want to trust all of the certificates
issued by that CA. You only > want to trust that particular certificate.
[...]

Content analysis details: (-1.9 points, 5.0 required)

pts rule name description
---- ---------------------- --------------------------------------------------
0.0 RCVD_IN_DNSWL_BLOCKED RBL: ADMINISTRATOR NOTICE: The query to DNSWL
was blocked. See
http://wiki.apache.org/spamassassin/DnsBlocklists#dnsbl-block
for more information.
[69.43.206.106 listed in list.dnswl.org]
0.0 URIBL_BLOCKED ADMINISTRATOR NOTICE: The query to URIBL was blocked.
See
http://wiki.apache.org/spamassassin/DnsBlocklists#dnsbl-block
for more information.
[URIs: gitlab.com]
-1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1%
[score: 0.0000]
Post by Doug Leavitt
Sorry for the delay. I needed to do some due diligence before responding.
Hi,
OpenSSL now has X509_V_FLAG_PARTIAL_CHAIN support in the code base as of 1.0.2a.
I would like to submit a patch to enable X509_V_FLAG_PARTIAL_CHAIN support
in OpenLDAP libldap, assuming it exists in the version of OpenSSL being use to
build
OpenLDAP.
What's the use case? It appears that the feature has been in OpenSSL since
around 2012, but I don't see much documentation or chatter about it. Why is
it useful, and do GnuTLS and MozNSS already support a similar feature?
rootCA -> mysystem
You don't want to trust all of the certificates issued by that CA. You only
want to trust that particular certificate.
"You" is too ambiguous here. Does the server carry a partial trust chain in
its config, or does the client?

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

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.

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.

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).

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.

All of this smells of worst-practice to me.
Post by Doug Leavitt
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.
rootCA -> mycompanyCA -> mysystem
You don't want to trust all of the certificates issued by that CA. You only
want to trust certificates issued by your company's CA. Again, OpenSSL by
default will not let you trust an intermediate CA. With this change, you can
add mycompanyCA's certificate and that will cause OpenSSL to accept
certificates signed by your company CA.
The reason this is coming up now, is that the old Mozilla libldap/NSS
combination supported this by default but the combination of OpenLDAP/OpenSSL
currently does not. We first discovered the issue back in 2012 and realized
that OpenSSL did not support partial chains. Working through our security team
the project that discovered the issue convinced the OpenSSL upstream to add
the X509_V_FLAG_PARTIAL_CHAIN support so that eventually we could find a way
to incorporate that support back into OpenLDAP.
Additionally we have since uncovered some programs that depend on this Mozilla
functionality and we would like to see it supported in the OpenLDAP/OpenSSL so
those applications can finish moving off Mozilla libldap/NSS.
Moving forward to today it looks like OpenSSL has the support, disabled by
default, and both GNUTLS and NSS have the support for partial chains enabled
by default.
https://gitlab.com/gnutls/gnutls/blob/master/lib/x509/verify.c#L868
http://mxr.mozilla.org/security/source/security/nss/lib/certhigh/certvfy.c#532
where intermediate certificates are processed (with the final decision at
557), and that leaf certificates are handled at
http://mxr.mozilla.org/security/source/security/nss/lib/certhigh/certvfy.c#916
https://github.com/openssl/openssl/blob/master/crypto/x509/x509_vfy.c#L819
Our hope is to have OpenLDAP/OpenSSL be either on par with OpenLDAP/NSS and
OpenLDAP/GNUTLS or at least have the option of be on par without having to
maintain a downstream code fork.
#ifdef X509_V_FLAG_PARTIAL_CHAIN
/*
* Allow intermediate or leaf certificates in the trust list to
* act as trust anchors.
*/
X509_STORE_set_flags(SSL_CTX_get_cert_store(ctx),
X509_V_FLAG_PARTIAL_CHAIN);
#endif
http://www.openldap.org/devel/gitweb.cgi?p=openldap.git;a=blob;f=libraries/libldap/tls_o.c;h=5d2367c6c1cc1e45707dbd070dadf88a556f8d74;hb=HEAD#l381
From our investigation always adding the support does not seem to be harmful
in any way and maintains compatibility with some existing software.
Hence the original question.
Thanks in advance for your consideration,
Doug.
Before I submit any patch I would like to know that would be acceptable
for integration.
Should support always be enabled if the version of OpenSSL has it
e.g. ifdef on X509_V_FLAG_PARTIAL_CHAIN
Should it be a config time option check and ifdef enable if found in
e.g. like the ifdef on HAVE_OPENSSL_CRL
Are there more requirements that is required in the patch, before it would
be accepted such as ldap_set_option support?
Thanks in advance,
Doug.
--
-- Howard Chu
CTO, Symas Corp. http://www.symas.com
Director, Highland Sun http://highlandsun.com/hyc/
Chief Architect, OpenLDAP http://www.openldap.org/project/
Doug Leavitt
2015-07-07 22:30:34 UTC
Permalink
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.
Post by Aaron Richton
[...]
Post by Doug Leavitt
#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.)
Post by Aaron Richton
Post by Doug Leavitt
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
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.
Post by Aaron Richton
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*.
Post by Aaron Richton
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?
Post by Aaron Richton
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.
Post by Aaron Richton
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.
Post by Aaron Richton
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.

Loading...