Issue 6838 - TLS client will not accept certificate for 'localhost'
Summary: TLS client will not accept certificate for 'localhost'
Status: VERIFIED FIXED
Alias: None
Product: OpenLDAP
Classification: Unclassified
Component: slapd (show other issues)
Version: 2.4.24
Hardware: All All
: --- normal
Target Milestone: ---
Assignee: OpenLDAP project
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-02-17 17:52 UTC by Andrew Findlay
Modified: 2011-02-18 18:37 UTC (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description Andrew Findlay 2011-02-17 17:52:52 UTC
Full_Name: Andrew Findlay
Version: 2.4.24
OS: OpenSuSE 11.3
URL: ftp://ftp.openldap.org/incoming/
Submission from: (NULL) (88.97.25.132)


For various test and teaching purposes I have a set of OpenLDAP configs that run
small servers intended for local access only. As I run these on a wide variety
of machines and also give them to students to run on their own machines, all the
LDAP clients are set up to access the servers via the loopback interface:
typically ldap://localhost:1389/

Some of the configs use TLS. I have a local CA which issues simple server certs,
usually with 'CN=localhost' as part of the subject name. Since upgrading the OS
and OpenLDAP version of my main test environment I find that TLS connections are
failing:

> ldapsearch -d 768 -x -ZZ -H ldap://localhost:1389/ -b dc=example,dc=org
sn=trott
TLS: hostname (slab.skills-1st.co.uk) does not match common name in certificate
(localhost).
ldap_start_tls: Connect error (-11)
        additional info: TLS: hostname does not match CN in peer certificate

slab.skills-1st.co.uk is indeed the name of the machine, but I asked to connect
to 'localhost' so that is the name that should be checked against the
certificate.
If I put in any other alias for localhost in /etc/hosts and issue a certificate
for that, the connection is OK so the problem is specific to the string
'localhost', not to the use of the loopback interface in general.

I think the problem is in tlso_session_chkhost() in tls_o.c:

        if( ldap_int_hostname &&
                ( !name_in || !strcasecmp( name_in, "localhost" ) ) )
        {
                name = ldap_int_hostname;
        } else {
                name = name_in;
        }

If I understand this correctly, the intention appears to be to allow a
certificate issued for the FQDN of the machine to be accepted when it is
presented on the loopback interface. This may be a reasonable thing to do, but
the current implementation prevents the use of a certificate issued specifically
for 'localhost'.

My client scripts used to work: I think this was purely because earlier versions
of the TLS client code were less careful about checking certificates.
Specifically, the 'self signed certificate in certificate chain' error was not
even reported unless client-side debugging was turned on.
Comment 1 Howard Chu 2011-02-18 00:29:52 UTC
andrew.findlay@skills-1st.co.uk wrote:
> Full_Name: Andrew Findlay
> Version: 2.4.24
> OS: OpenSuSE 11.3
> URL: ftp://ftp.openldap.org/incoming/
> Submission from: (NULL) (88.97.25.132)
>
>
> For various test and teaching purposes I have a set of OpenLDAP configs that run
> small servers intended for local access only. As I run these on a wide variety
> of machines and also give them to students to run on their own machines, all the
> LDAP clients are set up to access the servers via the loopback interface:
> typically ldap://localhost:1389/
>
> Some of the configs use TLS. I have a local CA which issues simple server certs,
> usually with 'CN=localhost' as part of the subject name. Since upgrading the OS
> and OpenLDAP version of my main test environment I find that TLS connections are
> failing:

> My client scripts used to work: I think this was purely because earlier versions
> of the TLS client code were less careful about checking certificates.
> Specifically, the 'self signed certificate in certificate chain' error was not
> even reported unless client-side debugging was turned on.

Used to work - since when, what release, what else has changed since then? 
I'll note that I just tested some localhost certs a few days ago and they were 
fine, and the cert verification code hasn't changed in quite a long time.

(E.g., ITS#6711 the test setup there uses localhost with no problem.)

-- 
   -- Howard Chu
   CTO, Symas Corp.           http://www.symas.com
   Director, Highland Sun     http://highlandsun.com/hyc/
   Chief Architect, OpenLDAP  http://www.openldap.org/project/

Comment 2 Howard Chu 2011-02-18 09:37:47 UTC
changed state Open to Closed
Comment 3 Andrew Findlay 2011-02-18 12:16:47 UTC
On Fri, Feb 18, 2011 at 12:30:25AM +0000, hyc@symas.com wrote:

> Used to work - since when, what release, what else has changed since then? 

Unfortunately I cannot tell you exactly when this changed. In any case,
the change only affects a different bug which was masking the problem
that I now see.

I do know that 2.3.32 as shipped with SLES 10.3 masks the problem by
not checking the server certificate properly. So does 2.4.12 as shipped
with OpenSuSE 11.1. Both will allow ldapsearch -ZZ to connect to *any*
TLS-capable server if they do *not* have access to the CA certificate.

2.4.24 built on OpenSuSE 11.3 (i.e. using OpenSSL 1.0) correctly refuses
to connect if there is no CA cert.

All versions that I have tested (certainly back to 2.3.32) incorrectly
fail to connect when the URL is ldap://localhost:1389/ and a CA cert is
provided.

> I'll note that I just tested some localhost certs a few days ago and they were 
> fine, and the cert verification code hasn't changed in quite a long time.
> 
> (E.g., ITS#6711 the test setup there uses localhost with no problem.)

Hmm - that seems to be server-to-server. My problem is with the client
tools, so maybe a different code-path is used.

I have put a small test case here:
	ftp://ftp.openldap.org/incoming/afindlay-localhost-tls-test-20110218.tgz

The server cert is valid for 'localhost' and also for '127.0.0.1'

The tests are:

        sh 1-plain
                Plain LDAP connection - no problems
                Connects to ldap://localhost:1389/

        sh 2-tls-no-ca
                With TLS but client has no access to the CA cert so this should fail
                with a complaint about 'self-signed certificate'

        sh 3-tls-with-ca
                With TLS and access to the CA cert.
                Connects to ldap://localhost:1389/
                This should succeed but it does not.

        sh 4-tls-with-ca-numeric
                With TLS and access to the CA cert.
                This one uses ldap://127.0.0.1:1389/ and succeeds.

Andrew
-- 
-----------------------------------------------------------------------
|                 From Andrew Findlay, Skills 1st Ltd                 |
| Consultant in large-scale systems, networks, and directory services |
|     http://www.skills-1st.co.uk/                +44 1628 782565     |
-----------------------------------------------------------------------

Comment 4 Ralf 2011-02-18 16:31:26 UTC
Am Freitag 18 Februar 2011, 13:17:17 schrieb 
andrew.findlay@skills-1st.co.uk:
> On Fri, Feb 18, 2011 at 12:30:25AM +0000, hyc@symas.com wrote:
> > Used to work - since when, what release, what else has changed since
> > then?
> 
> Unfortunately I cannot tell you exactly when this changed. In any
> case, the change only affects a different bug which was masking the
> problem that I now see.
> 
> I do know that 2.3.32 as shipped with SLES 10.3 masks the problem by
> not checking the server certificate properly. So does 2.4.12 as
> shipped with OpenSuSE 11.1. Both will allow ldapsearch -ZZ to connect
> to *any* TLS-capable server if they do *not* have access to the CA
> certificate.
> 
> 2.4.24 built on OpenSuSE 11.3 (i.e. using OpenSSL 1.0) correctly
> refuses to connect if there is no CA cert.
Yes, older openSUSE releases used a bad (i.e. less secure) default for 
the TLS_REQCERT setting. That's why you never ran into the problem before 
:/

> All versions that I have tested (certainly back to 2.3.32) incorrectly
> fail to connect when the URL is ldap://localhost:1389/ and a CA cert
> is provided.
Yes, AFAIK libldap's behavior of trying to figure out the machines real 
hostname when connecting to localhost and using that hostname to verify 
the server's certificate is there since quite some time already. It will 
only verify against "localhost" when it completely fails to get the 
machines' real name. I always considered that a feature more than a bug.

> > I'll note that I just tested some localhost certs a few days ago and 
they were 
> > fine, and the cert verification code hasn't changed in quite a long 
time.
> > 
> > (E.g., ITS#6711 the test setup there uses localhost with no problem.)
But if I see it correctly it sets "TLSVerifyClient allow" on the master 
and "tls_reqcert=never" on the consumer. So it doesn't really verify the 
certificates. (I might have overlooked something, took only a brief 
glance at it).


Ralf

Comment 5 Howard Chu 2011-02-18 17:37:26 UTC
rhafer@suse.de wrote:
> Am Freitag 18 Februar 2011, 13:17:17 schrieb
> andrew.findlay@skills-1st.co.uk:
>> On Fri, Feb 18, 2011 at 12:30:25AM +0000, hyc@symas.com wrote:
>>> Used to work - since when, what release, what else has changed since
>>> then?
>>
>> Unfortunately I cannot tell you exactly when this changed. In any
>> case, the change only affects a different bug which was masking the
>> problem that I now see.
>>
>> I do know that 2.3.32 as shipped with SLES 10.3 masks the problem by
>> not checking the server certificate properly. So does 2.4.12 as
>> shipped with OpenSuSE 11.1. Both will allow ldapsearch -ZZ to connect
>> to *any* TLS-capable server if they do *not* have access to the CA
>> certificate.
>>
>> 2.4.24 built on OpenSuSE 11.3 (i.e. using OpenSSL 1.0) correctly
>> refuses to connect if there is no CA cert.
> Yes, older openSUSE releases used a bad (i.e. less secure) default for
> the TLS_REQCERT setting. That's why you never ran into the problem before
> :/

Sigh... Apparently nobody reads the part of the doc that says "there is no 
good reason to change this from the libldap default."

>> All versions that I have tested (certainly back to 2.3.32) incorrectly
>> fail to connect when the URL is ldap://localhost:1389/ and a CA cert
>> is provided.
> Yes, AFAIK libldap's behavior of trying to figure out the machines real
> hostname when connecting to localhost and using that hostname to verify
> the server's certificate is there since quite some time already. It will
> only verify against "localhost" when it completely fails to get the
> machines' real name. I always considered that a feature more than a bug.

Agreed. Server certs are supposed to carry the host's FQDN. "localhost" is 
just a magic alias; in a cert it shouldn't be anywhere other than a 
subjectAltName.

>>> I'll note that I just tested some localhost certs a few days ago and
> they were
>>> fine, and the cert verification code hasn't changed in quite a long
> time.
>>>
>>> (E.g., ITS#6711 the test setup there uses localhost with no problem.)
> But if I see it correctly it sets "TLSVerifyClient allow" on the master
> and "tls_reqcert=never" on the consumer. So it doesn't really verify the
> certificates. (I might have overlooked something, took only a brief
> glance at it).

Ah, that sounds familiar.

Closing this ITS. It's not a regression and not a bug, just a long established 
feature.
-- 
   -- Howard Chu
   CTO, Symas Corp.           http://www.symas.com
   Director, Highland Sun     http://highlandsun.com/hyc/
   Chief Architect, OpenLDAP  http://www.openldap.org/project/

Comment 6 Kurt Zeilenga 2011-02-18 18:34:04 UTC
On Feb 18, 2011, at 9:37 AM, hyc@symas.com wrote:

> Closing this ITS. It's not a regression and not a bug, just a long established 
> feature.

Right, the bug is listing non-fully-qualified names as subjects in the certificate.

So, generally speaking, subject names checks fail, as they should fail, when the asserted name is not fully-qualified.

The intent of the code is avoid always failing when the non-fully-qualified asserted name can be securely transformed into a fully-qualified name.  This is a feature.

-- Kurt
Comment 7 Kurt Zeilenga 2011-02-18 18:37:58 UTC
And, for the OP, I suggest issuing your test certificates for the FQDN "test" and then setting up name service to resolve this to local host.  Using "test" indicates that the scope of name is limited to some infrastructure used for testing (and is not a name used on the public Internet).

-- Kurt