Bugzilla will be upgraded to version 5.0 on a still to be determined date in the near future. The original upgrade date has been delayed.
Bug 973743 - ldapsearch with TLS_REQCERT demand is passing even with wrong certificate
ldapsearch with TLS_REQCERT demand is passing even with wrong certificate
Status: CLOSED NOTABUG
Product: Red Hat Enterprise Linux 7
Classification: Red Hat
Component: openldap (Show other bugs)
7.0
Unspecified Unspecified
medium Severity medium
: rc
: ---
Assigned To: Jan Synacek
BaseOS QE Security Team
: Regression
Depends On:
Blocks:
  Show dependency treegraph
 
Reported: 2013-06-12 11:28 EDT by Patrik Kis
Modified: 2013-06-18 03:50 EDT (History)
2 users (show)

See Also:
Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed: 2013-06-18 03:50:32 EDT
Type: Bug
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---


Attachments (Terms of Use)

  None (edit)
Description Patrik Kis 2013-06-12 11:28:09 EDT
Description of problem:
When setting in /etc/openldap/ldap.conf TLS_REQCERT demand or try and the ldap server has a fake certificate ldapsearch via TLS succeeds. With the old version it failed as expecred. The old version is gnutls-2.12.21-2.el7 (RHEL-7.0-20130306.0).
This may looks like an ldap issue rather than gnutls, one but the regression happened with gnutls update and not ldap and I belive ldap uses for certificate validation gnutls API.
If there was a change in API that involves changes also on ldap side, please describe it and forward the bug to openldap.

Version-Release number of selected component (if applicable):
gnutls-3.1.11-1.el7

How reproducible:
always

Steps to Reproduce:
1. Create certificates

# SERVER=`hostname`
# SERVER_IP=`host $SERVER | awk '/has address/ {print $NF;exit}'`
# cat > ca.tmpl <<EOF
organization = "Red Hat"
unit = "GSS"
locality = "Brno"
state = "Moravia"
country = CZ
cn = "$SERVER"
serial = 001
expiration_days = 365
dns_name = "$SERVER"
ip_address = "$SERVER_IP"
email = "root@$SERVER"
crl_dist_points = "http://$SERVER/getcrl/"
ca
cert_signing_key
crl_signing_key
EOF
# certtool --generate-privkey --outfile ca-key.pem
# certtool --generate-self-signed --load-privkey ca-key.pem --template ca.tmpl --outfile ca.pem
#
# cat > server.tmpl <<EOF
organization = "Red Hat"
unit = "GSS"
locality = "Brno"
state = "Moravia"
country = CZ
cn = "$SERVER"
serial = 002
expiration_days = 365
dns_name = "$SERVER"
ip_address = "$SERVER_IP"
email = "root@$SERVER"
EOF
# certtool --generate-privkey --outfile server-key.pem --bits 2048
# certtool --generate-request --template server.tmpl --load-privkey server-key.pem --outfile server-request.pem
# certtool --generate-certificate --template server.tmpl --load-request server-request.pem  --outfile server-cert.pem --load-ca-certificate ca.pem --load-ca-privkey ca-key.pem
# cat > client.tmpl <<EOF
organization = "Red Hat"
unit = "GSS"
locality = "Brno"
state = "Moravia"
country = CZ
cn = "$SERVER"
serial = 003
expiration_days = 365
dns_name = "$SERVER"
ip_address = "$SERVER_IP"
email = "root@$SERVER"
EOF
# certtool --generate-privkey --outfile client-key.pem --bits 2048
# certtool --generate-request --template client.tmpl --load-privkey client-key.pem --outfile client-request.pem
# certtool --generate-certificate --template client.tmpl --load-request client-request.pem  --outfile client-cert.pem --load-ca-certificate ca.pem --load-ca-privkey ca-key.pem
#
# CERTDIR=/etc/openldap/certs
# cp *.pem $CERTDIR
# cat > fake-server.tmpl <<EOF
organization = "Fake Red Hat"
unit = "GSS"
locality = "Brno"
state = "Moravia"
country = CZ
cn = "not$SERVER"
serial = 002
expiration_days = 365
dns_name = "$SERVER"
ip_address = "$SERVER_IP"
email = "root@$SERVER"
EOF
# certtool --generate-privkey --outfile fake-server-key.pem --bits 2048
# certtool --generate-request --template fake-server.tmpl --load-privkey fake-server-key.pem --outfile fake-server-request.pem
# certtool --generate-certificate --template fake-server.tmpl --load-request fake-server-request.pem  --outfile fake-server-cert.pem --load-ca-certificate ca.pem --load-ca-privkey ca-key.pem

2. Prepare ldap server

# cat > data.ldif<<EOF
dn: dc=my-domain,dc=com
objectClass: dcObject
objectClass: organization
dc: my-domain
o: my-domain
description: my-domain

dn: uid=testuser,dc=my-domain,dc=com
cn: testuser
objectClass: account
objectClass: posixAccount
objectClass: top
uid: testuser
uidNumber: 10001
gidNumber: 10001
homeDirectory: /home/ldap/testuser
gecos: testuser
loginShell: /bin/sh
userPassword: {SSHA}op2zlZmLW5uX3549vmuemfMOTUQ6IHIy
EOF
#
# echo 'SLAPD_URLS="ldapi:/// ldap:/// ldaps:///"' > /etc/sysconfig/slapd
# 
# cat >/etc/openldap/slapd.conf<<EOF
include         /etc/openldap/schema/core.schema
include         /etc/openldap/schema/cosine.schema
include         /etc/openldap/schema/inetorgperson.schema
include         /etc/openldap/schema/nis.schema

allow bind_v2
loglevel 256

pidfile         /var/run/openldap/slapd.pid
argsfile        /var/run/openldap/slapd.args

TLSCipherSuite        HIGH:MEDIUM:+SSLv2 
TLSCACertificateFile  $CERTDIR/ca.pem
TLSCertificateFile    $CERTDIR/server-cert.pem
TLSCertificateKeyFile $CERTDIR/server-key.pem
TLSVerifyClient demand

database        bdb
suffix          "dc=my-domain,dc=com"
rootdn          "cn=Manager,dc=my-domain,dc=com"
rootpw          {SSHA}tOSmeQCcYIm1S9ujgpg2Km5rpUnR9dRB

directory       /var/lib/ldap/

index objectClass                       eq,pres
index ou,cn,mail,surname,givenname      eq,pres,sub
index uidNumber,gidNumber,loginShell    eq,pres
index uid,memberUid                     eq,pres,sub
index nisMapName,nisMapEntry            eq,pres,sub
EOF
#
# cat >/etc/openldap/ldap.conf<<EOF
BASE dc=my-domain,dc=com
TLS_CACERT $CERTDIR/ca.pem
TLS_REQCERT demand
EOF
#
# slapadd -l data.ldif
51b89203 bdb_db_open: warning - no DB_CONFIG file found in directory /var/lib/ldap/: (2).
Expect poor performance for suffix "dc=my-domain,dc=com".
51b89203 bdb_monitor_db_open: monitoring disabled; configure monitor database to enable
51b89203 => bdb_tool_entry_put: id2entry_add failed: BDB0067 DB_KEYEXIST: Key/data pair already exists (-30994)
51b89203 => bdb_tool_entry_put: txn_aborted! BDB0067 DB_KEYEXIST: Key/data pair already exists (-30994)
slapadd: could not add entry dn="dc=my-domain,dc=com" (line=1): txn_aborted! BDB0067 DB_KEYEXIST: Key/data pair already exists (-30994)
_######                30.07% eta   none elapsed            none spd 166.6 k/s 
Closing DB...
#
# chown -R ldap:ldap /var/lib/ldap/* && chmod -R a+rx /etc/openldap/
# restorecon -Rv /etc/openldap
# service slapd start

3. Prepare ldap client

# CERTDIR=/etc/openldap/certs
# cat > ~/.ldaprc<<EOF
TLS_CERT $CERTDIR/client-cert.pem
TLS_KEY $CERTDIR/client-key.pem
EOF

4. Query with correct server cert:

# ldapsearch -Z -H ldap://`hostname`/ -x '*'
# extended LDIF
#
# LDAPv3
# base <dc=my-domain,dc=com> (default) with scope subtree
# filter: (objectclass=*)
# requesting: * 
#

# my-domain.com
dn: dc=my-domain,dc=com
objectClass: dcObject
objectClass: organization
dc: my-domain
o: my-domain
description: my-domain

# testuser, my-domain.com
dn: uid=testuser,dc=my-domain,dc=com
cn: testuser
objectClass: account
objectClass: posixAccount
objectClass: top
uid: testuser
uidNumber: 10001
gidNumber: 10001
homeDirectory: /home/ldap/testuser
gecos: testuser
loginShell: /bin/sh
userPassword:: e1NTSEF9b3AyemxabUxXNXVYMzU0OXZtdWVtZk1PVFVRNklISXk=

# search result
search: 3
result: 0 Success

# numResponses: 3
# numEntries: 2
#

5. Query with fake server cert:
# cat fake-server-cert.pem > $CERTDIR/server-cert.pem
# cat fake-server-key.pem > $CERTDIR/server-key.pem
# service slapd restart
Redirecting to /bin/systemctl restart  slapd.service
# 
# # ldapsearch -Z -H ldap://`hostname`/ -x '*'
# extended LDIF
#
# LDAPv3
# base <dc=my-domain,dc=com> (default) with scope subtree
# filter: (objectclass=*)
# requesting: * 
#

# my-domain.com
dn: dc=my-domain,dc=com
objectClass: dcObject
objectClass: organization
dc: my-domain
o: my-domain
description: my-domain

# testuser, my-domain.com
dn: uid=testuser,dc=my-domain,dc=com
cn: testuser
objectClass: account
objectClass: posixAccount
objectClass: top
uid: testuser
uidNumber: 10001
gidNumber: 10001
homeDirectory: /home/ldap/testuser
gecos: testuser
loginShell: /bin/sh
userPassword:: e1NTSEF9b3AyemxabUxXNXVYMzU0OXZtdWVtZk1PVFVRNklISXk=

# search result
search: 3
result: 0 Success

# numResponses: 3
# numEntries: 2


Actual results:
The last query 

Expected results:
The last query should fail because "demand" and fake server cert.

Additional info:
I'd say that this causes also the problem here: https://bugzilla.redhat.com/show_bug.cgi?id=835475#c3
Comment 2 Tomas Mraz 2013-06-12 14:11:01 EDT
It uses NSS AFAIK. But reassigning to openldap for investigation.
Comment 3 Jan Synacek 2013-06-13 02:49:29 EDT
The test is probably wrong.

First, you specify the system configuration for the ldap clients:

# cat >/etc/openldap/ldap.conf<<EOF
BASE dc=my-domain,dc=com
TLS_CACERT $CERTDIR/ca.pem
TLS_REQCERT demand
EOF

Further in the test, you run:

# cat > ~/.ldaprc<<EOF
TLS_CERT $CERTDIR/client-cert.pem
TLS_KEY $CERTDIR/client-key.pem
EOF

That is also a client configuration. But, this one should be read instead of the system one, and apparently it is, because TLS_REQCERT is specified in the system one and so it doesn't work.

Try moving the TLS_REQCERT directive to ~/.ldaprc.
Comment 4 Patrik Kis 2013-06-14 09:16:00 EDT
(In reply to Jan Synacek from comment #3)
> 
> Try moving the TLS_REQCERT directive to ~/.ldaprc.

I tried it and did not helped. 
And that was expected as the same way of configuration was working with previous version of gnutils, gnutls-2.12.21-2.el7, so I'd expect work again. As I mentioned between the good test and bad test the only difference was an updated gnutls. The openldap package remained the same!
Comment 5 Patrik Kis 2013-06-14 09:30:39 EDT
Or to be more precise, not only gnutls was updated but also these packages were pulled as dependencies of gnutls:

Updating:
 gnutls                       x86_64              3.1.11-1.el7                 rhel7              594 k
Installing for dependencies:
 gtk2                         x86_64              2.24.18-1.el7                rhel7              3.4 M
 nettle                       x86_64              2.6-2.el7                    rhel7              243 k
Updating for dependencies:
 cups-libs                    x86_64              1:1.6.2-4.el7                rhel7              342 k
 glibc                        x86_64              2.17-7.el7                   rhel7              3.6 M
 glibc-common                 x86_64              2.17-7.el7                   rhel7               11 M
 glibc-devel                  x86_64              2.17-7.el7                   rhel7              1.0 M
 glibc-headers                x86_64              2.17-7.el7                   rhel7              642 k
 lftp                         x86_64              4.4.6-1.el7                  rhel7              731 k
 libmicrohttpd                x86_64              0.9.27-1.el7                 rhel7               51 k
 libtasn1                     x86_64              3.3-1.el7                    rhel7              314 k
 wireshark                    x86_64              1.8.6-4.el7                  rhel7               12 M
 wireshark-gnome              x86_64              1.8.6-4.el7                  rhel7              874 k
Comment 6 Patrik Kis 2013-06-14 10:01:31 EDT
I also tried to pass to ldapsearch the configuration via command line, but that did not helped either. It seems that it has problems with configuration of this way.

0 [root@rhel7 ~ ]# cat /etc/openldap/ldap.conf 
BASE dc=my-domain,dc=com
TLS_CACERT /etc/openldap/certs/ca.pem
TLS_REQCERT demand
0 [root@rhel7 ~ ]# cat .ldaprc 
TLS_CERT /etc/openldap/certs/client-cert.pem
TLS_KEY /etc/openldap/certs/client-key.pem
0 [root@rhel7 ~ ]# ldapsearch -Z -H ldap://rhel7 -x '*' >/dev/null ||echo FAIL
0 [root@rhel7 ~ ]# 
0 [root@rhel7 ~ ]# rm -f .ldaprc 
0 [root@rhel7 ~ ]# TLS_CERT=/etc/openldap/certs/client-cert.pem TLS_KEY=/etc/openldap/certs/client-key.pem ldapsearch -Z -H ldap://rhel7 -x '*' >/dev/null ||echo FAIL
ldap_start_tls: Connect error (-11)
	additional info: TLS error -12271:SSL peer cannot verify your certificate.
ldap_sasl_bind(SIMPLE): Can't contact LDAP server (-1)
FAIL
0 [root@rhel7 ~ ]# 
0 [root@rhel7 ~ ]# cat >.ldaprc 
TLS_CERT /etc/openldap/certs/client-cert.pem
TLS_KEY /etc/openldap/certs/client-key.pem
0 [root@rhel7 ~ ]# TLS_CERT=/etc/openldap/certs/client-cert.pem TLS_KEY=/etc/openldap/certs/client-key.pem ldapsearch -Z -H ldap://rhel7 -x '*' >/dev/null ||echo FAIL
0 [root@rhel7 ~ ]# 
0 [root@rhel7 ~ ]# cat /etc/openldap/ldap.conf
BASE dc=my-domain,dc=com
TLS_CACERT /etc/openldap/certs/ca.pem
TLS_REQCERT demand
0 [root@rhel7 ~ ]# rm -f /etc/openldap/ldap.conf
0 [root@rhel7 ~ ]# BASE='dc=my-domain,dc=com' TLS_CACERT=/etc/openldap/certs/ca.pem TLS_REQCERT=demand ldapsearch -Z -H ldap://rhel7 -x '*' >/dev/null ||echo FAIL
ldap_start_tls: Connect error (-11)
	additional info: TLS error -8172:Peer's certificate issuer has been marked as not trusted by the user.
ldap_result: Can't contact LDAP server (-1)
FAIL
0 [root@rhel7 ~ ]# 
0 [root@rhel7 ~ ]# cat >/etc/openldap/ldap.conf
BASE dc=my-domain,dc=com
TLS_CACERT /etc/openldap/certs/ca.pem
TLS_REQCERT demand
0 [root@rhel7 ~ ]# 
0 [root@rhel7 ~ ]# ldapsearch -Z -H ldap://rhel7 -x '*' >/dev/null ||echo FAIL
0 [root@rhel7 ~ ]#
Comment 7 Patrik Kis 2013-06-18 03:50:32 EDT
Closing this bug as "not a bug".
Reason: it has been clarified that the problem was in test approach. The the supposed to use a fake server certificate to verify the various setting of ldap client (demand, try, allow, never), but the difference between the fake and correct certificate was only in CN in it. This is, however, not verified by nss. Therefore the test have changed so now the the fake server certificate is the same as the correct one, just signed by a different CA which certificate the client has.

Note You need to log in before you can comment on or make changes to this bug.