[Date Prev][Date Next] [Chronological] [Thread] [Top]

Re: openldap-2.0/TLS certificate error



Hi,

I have been doing some testing of SSL and Openldap 2.0 and am having
some trouble with second searches.

I followed Julio's/Kurt's document on the openldap.org web site:

        OpenLDAP Faq-O-Matic: How do I use TLS/SSL?

I found it very useful and accurate.  My results differ, however.  It
seems
that it has been suggested to not use a 'login name' and 'password' when
using
the 'secure' check box in Nscomm.  I found that it did not matter if I
used
an anonymous bind or an actual user bind (as you can see in the
following
trace with an actual bind), the results were exactly the same.  This may
be
because I have the bind dn specified in my preferences.js (pref.js)
file:

        user_pref("ldap_2.servers.TestDir.auth.dn",
"cn=andy,ou=People,o=test");

BACKGROUND

     Nscomm will first do a search to find the email address if you
     put it in
     as the 'login name' (assuming anonymous searching of the
     'mail' dnattr and
     anonymous reading of the entry are allowed :-O  ).  Nscomm
     will then bind
     as the dn that is found and perform the real search. (Oh
     yeah!  Be sure the
     'email address'/'login name' is in the tree in ONLY ONE PLACE
     or nscomm will
     complain that it can't login because multiple entries are
     found! ... Go Kia!)

END BACKGROUND

Sorry for the 'background', you guys know all this.  Anyway, the thing
that is happening is that the second search (connid=1), after the
do_unbind
from the first search (connid=0), is trying to reuse the previous SSL
session and it fails with:

        TLS: error:140D9115:SSL routines:SSL_GET_PREV_SESSION:session id

        context uninitialized ssl_sess.c:278

Considering that this is connid=1 and not connid=0, I would think that
the
"session id context" SHOULD be uninitialized.

I get this error with Nscomm 4.61 on Linux as well as Nscomm 4.7 on
Windows 95.
It shows up as an error 0x5B on both platforms.  I am running Openldap
2.0 from last
night (6/24) around 9:00 pm edt.  I have openssl-0.95a, redhat 6.1, and
cyrus-sasl-1.5.11

Is it possible that the reason you (Julio, Kurt) suggested that a
non-anonymous
bind had trouble was because the "second search" was being attempted
after
the do_unbind from the anonymous first search of the 'mail' dnattr?

I can stop -> start the slapd and then perform a successful search.  If
I
search again (any number of times), error 0x5B and the TLS error above.
If I stop -> start the slapd again, the first search works, subsequent
searches
fail again.  This stop -> start -> search :-) -> search :-( loop can be
duplicated ad infinitum.

Below is a debug trace that clarifies the issue.  It seems to me that
the problem is
with Nscomm.  From what I know about TLS (and I know very little), there

should be no sane/continuing connection after the do_unbind.  Am I
correct
about this?  Either way, why doesn't Nscomm just do SSL renegotiation.
It
seems that would be the correct fallback to use.  Like ...

Reuse SSL Session?
No, sorry, I don't remember it. (that would be insecure and
irresponsible!)
Okay, let's just do it again ...
...
...
close
pause
pause
Reuse SSL Session? ...


Maybe this will help with SSL cert woes.


> > i've taken Mark's advice and gone
> > though and created a self-signed CA certificate that i've used to sign a
> > certificate request but to no avail.
>
> It looks like your CA certificate is not installed properly.
> >
> > here are the steps that i'm using to create the certificates (which comes
> > from the appendix of an article on SSL:
> > http://www.certco.com/b2b/ssl.htm).
>
> Have you tried reading the docs on www.openssl.org? The steps you outline
> here slightly broken.
> >
> > 1) create a self-signed CA certificate:
> >
> > openssl req -new -x509 -keyout /usr/local/ssl/private/CAkey.pem -out
> > /usr/local/ssl/private/CAcert.pem
>
> Created this way, your CA private key has been encrypted with a passphrase.
> This makes it unusable by slapd. You should use the "-nodes" option to skip
> the passphrase encryption.
> >
>

I believe the server key is the one that needs to be non-encoded, not
the root CA certificate's
private key.  The -nodes option is the way to do it.  (Otherwise, cut
and paste the key section
from the server cert REQUEST into a new file and then use the command
**assuming rsa**:

    openssl rsa -in encoded-key.pem -out clear-key.pem

It will prompt you for the password you used to create the cert request.

Try this, but skip step two if you would like to use the 'cut and paste
method'.

1)  Edit the /etc/openssl.cnf for your needs.

2)  Use the CA.pl program with a couple of changes. (on linux it is in
/var/lib/ssl/misc/CA.pl)
        (I copied it to a better location and called it CA1.pl)  Skip if
using the cut and paste method.

    a)  Around line 60 change:     (in the   'elsif (/^-newcert$/)'
section)

            system ("$REQ -new -x509 -keyout newreq.pem -out newreq.pem
$DAYS");
        to
            system ("$REQ -new -x509 -nodes -keyout newreq.pem -out
newreq.pem $DAYS");

    b)  Around line 65 change:     (in the   'elsif (/^-newreq$/)'
section)

             system ("$REQ -new -keyout newreq.pem -out newreq.pem
$DAYS");
        to
             system ("$REQ -new -nodes -keyout newreq.pem -out
newreq.pem $DAYS");

3)  Create a root CA for yourself to sign any other certs you create:

        CA.pl -newca   (or CA1.pl if that is what you called it)

         Be sure to specify the DN, email, etc.  For Common Name (cn),
use something like
        'Test Root CA'.

4)  Create a cert request for the server cert.:

        CA.pl -newreq

        Be sure that you use the EXACT same info as before.  Spaces and
caps matter.
        The only difference should be the Common Name (cn).  It should
be the fqdn of
        the host server (the one running slapd) as dns would reverse
resolve it.  (i.e.
        testserver.test.com).

        Note:  If you used the -nodes option, it will NOT ask for a
passphrase.  If you are
        cutting and pasting, give a different passphrase than you did
for the root CA cert.

5)    Sign the request with your root CA cert:

        CA.pl -sign

        The passphrase it wants is to unlock your root CA so that it may
sign the new
        server certificate.

6)    Move the request and cert to what is needed:

        mv newreq.pem server-req.pem
        mv newcert.pem server-cert.pem

7)    Cut and paste the RSA KEY section from server-req.pem into a new
file
        called temp-key.pem

8)    If you are using the -nodes method, skip this step.

            openssl rsa -in temp-key.pem -out clear-key.pem

        It will prompt you for the second passphrase you gave on the
'CA.pl -newreq' step.

9)    If you are using the -nodes method.

            mv temp-key.pem server-key.pem

        Otherwise, use:

            mv clear-key.pem server-key.pem

10)    Update slapd.conf:  (assuming you started all this in
/usr/local/ssl/certs)

TLSCertificateFile      /usr/local/ssl/certs/server-cert.pem
TLSCertificateKeyFile   /usr/local/ssl/certs/server-key.pem
TLSCACertificateFile    /usr/local/ssl/certs/demoCA/cacert.pem

11)    If this system will be running the client as well as the server,
you can copy the
          server-cert.pem and server-key.pem to client-cert.pem and
client-key.pem
          respectively.

          Otherwise, repeat steps 4 through 9 but this time replace
'server' with 'client'
          Be sure the fqdn of the client is used as the common name (cn)
this time.

If you are using Nscomm as the client, you need a couple things more.

12)    In the current directory (again /usr/local/ssl/certs), with the
cert and request
          for the client in the files newcert.pem and newreq.pem
respectively, run:

            CA.pl -pkcs12 "My Personal LDAP Test Certificate"

            Put in an export password when it asks for one.

            This will create a file that includes the client
certificate, the client's private key,
            and the root CA cert that you use for signing into the file
newcert.p12.  (Don't
            worry, the CA private key is not in there.)

13)    Copy, ftp, or sneaker net the file over to Nscomm and go to:

                Communicator -> Tools -> Security Info

                Click 'Yours' under 'Certificates' then choose 'Import'.

                Point to the newcert.p12 file.  Give it the export
password you set in step 12.

14)    Almost there.  You need to make Nscomm 'Trust' your new 'Test
Root CA'.

          Two choices:

                a)  Click on the 'Signers' and then 'Test Root CA - ..'
and then Edit.

                       Make netscape trust it for everything.

                 b)  Delete the 'Test Root CA' and then follow Julio's
steps for getting
                        Apache to give the root CA cert
(/usr/local/ssl/certs/demoCA/cacert.pem) in
                        the .crt format, and tell Nscomm to trust it for
everything.

                        Again:    OpenLDAP Faq-O-Matic: How do I use
TLS/SSL?

                You must be able to click 'verify' on both the 'Test
Root CA' and the
                'My Personal LDAP Test Certificate' and have Nscomm
respond simply:

                "The Certificate has been successfully verified"

15)    Start slapd with the -h "ldap:/// ldaps:///" options and you are
in business!


Hopefully, you will now be recreating my problem.


Good Luck and BFN,
Andy

Andrew D. Bialock
Experiencing SSLullar confusion
(three monkeys, twice the pudding, octopi for ... tango man)


Here is the trace.  The second search is after the '------ CUT' below.

[root@test openldap]# /usr/local/libexec/slapd -h "ldap:/// ldaps:///"
-d 1
@(#) $OpenLDAP: slapd 2.0-devel (Sat Jun 24 21:17:45 EDT 2000) $
        root@test.test.net:/root/openldap-2.0/ldap/servers/slapd
daemon_init: listen on ldap:///
daemon_init: listen on ldaps:///
daemon_init: 2 listeners to open...
ldap_url_parse(ldap:///)
daemon: socket() failed errno=0 (Success)
daemon: initialized ldap:///
ldap_url_parse(ldaps:///)
daemon: socket() failed errno=0 (Success)
daemon: initialized ldaps:///
daemon_init: 2 listeners opened
slapd init: initiated server.
slapd startup: initiated.
SASL mechanisms: PLAIN,DIGEST-MD5,ANONYMOUS
slapd starting
connection_get(10): got connid=0
connection_read(10): checking for input on id=0
TLS trace: SSL_accept:before/accept initialization
TLS trace: SSL_accept:SSLv3 read client hello A
TLS trace: SSL_accept:SSLv3 write server hello A
TLS trace: SSL_accept:SSLv3 write certificate A
TLS trace: SSL_accept:SSLv3 write certificate request A
TLS trace: SSL_accept:SSLv3 flush data
TLS trace: SSL_accept:error in SSLv3 read client certificate A
TLS trace: SSL_accept:error in SSLv3 read client certificate A
connection_get(10): got connid=0
connection_read(10): checking for input on id=0
TLS trace: SSL3 alert read:warning:no certificate
TLS trace: SSL_accept:error in SSLv3 read client certificate A
connection_get(10): got connid=0
connection_read(10): checking for input on id=0
TLS trace: SSL_accept:SSLv3 read client key exchange A
TLS trace: SSL_accept:SSLv3 read finished A
TLS trace: SSL_accept:SSLv3 write change cipher spec A
TLS trace: SSL_accept:SSLv3 write finished A
TLS trace: SSL_accept:SSLv3 flush data
connection_get(10): got connid=0
connection_read(10): checking for input on id=0
ber_get_next
ber_get_next: tag 0x30 len 48 contents:
ber_get_next
ber_get_next on fd 10 failed errno=11 (Resource temporarily unavailable)

do_bind
ber_scanf fmt ({iat) ber:
ber_scanf fmt (o}) ber:
do_bind: version=2 dn="cn=andy,ou=People,o=test" method=128
dn2entry_r: dn: "CN=ANDY,OU=PEOPLE,O=TEST"
=> dn2id( "CN=ANDY,OU=PEOPLE,O=TEST" )
=> ldbm_cache_open( "/usr/local/var/openldap-ldbm/dn2id.dbb", 7, 600 )
<= ldbm_cache_open (opened 0)
<= dn2id 4
=> id2entry_r( 4 )
=> ldbm_cache_open( "/usr/local/var/openldap-ldbm/id2entry.dbb", 7, 600
)
<= ldbm_cache_open (opened 1)
=> str2entry
<= str2entry(cn=andy,ou=People,o=test) -> -1 (0x80e6558)
<= id2entry_r( 4 ) 0x80e6558 (disk)
====> cache_return_entry_r( 4 ): created (0)
do_bind: v2 bind: "cn=andy,ou=People,o=test" to
"cn=andy,ou=People,o=test"
send_ldap_result: conn=0 op=0 p=2
send_ldap_response: msgid=1 tag=97 err=0
ber_flush: 14 bytes to sd 10
connection_get(10): got connid=0
connection_read(10): checking for input on id=0
ber_get_next
ber_get_next: tag 0x30 len 92 contents:
deferring operation
ber_get_next
ber_get_next on fd 10 failed errno=11 (Resource temporarily unavailable)

do_search
ber_scanf fmt ({aiiiib) ber:
ber_scanf fmt (o) ber:
ber_scanf fmt ({v}}) ber:
=> ldbm_back_search
dn2entry_r: dn: "O=TEST"
=> dn2id( "O=TEST" )
=> ldbm_cache_open( "/usr/local/var/openldap-ldbm/dn2id.dbb", 7, 600 )
<= ldbm_cache_open (cache 0)
<= dn2id 1
=> id2entry_r( 1 )
=> ldbm_cache_open( "/usr/local/var/openldap-ldbm/id2entry.dbb", 7, 600
)
<= ldbm_cache_open (cache 1)
=> str2entry
<= str2entry(o=test) -> -1 (0x80d82b0)
<= id2entry_r( 1 ) 0x80d82b0 (disk)
search_candidates: base="O=TEST" s=2 d=0
=> filter_candidates
=> list_candidates 0xa0
=> filter_candidates
=> dn2idl( "@O=TEST" )
=> ldbm_cache_open( "/usr/local/var/openldap-ldbm/dn2id.dbb", 7, 600 )
<= ldbm_cache_open (cache 0)
<= filter_candidates 3
=> filter_candidates
=> list_candidates 0xa1
=> filter_candidates
=> equality_candidates
=> ldbm_cache_open( "/usr/local/var/openldap-ldbm/nextid.dbb", 7, 600 )
<= ldbm_cache_open (opened 2)
<= filter_candidates 5
=> filter_candidates
=> presence_candidates
<= filter_candidates 5
<= list_candidates 5
<= filter_candidates 5
<= list_candidates 3
<= filter_candidates 3
====> cache_return_entry_r( 1 ): created (0)
=> id2entry_r( 1 )
====> cache_find_entry_id( 1 ) "o=test" (found) (1 tries)
<= id2entry_r( 1 ) 0x80d82b0 (cache)
candidate 1 does match filter
====> cache_return_entry_r( 1 ): returned (0)
=> id2entry_r( 2 )
=> ldbm_cache_open( "/usr/local/var/openldap-ldbm/id2entry.dbb", 7, 600
)
<= ldbm_cache_open (cache 1)
=> str2entry
<= str2entry(ou=People,o=test) -> -1 (0x80e7238)
<= id2entry_r( 2 ) 0x80e7238 (disk)
candidate 2 does match filter
====> cache_return_entry_r( 2 ): created (0)
=> id2entry_r( 4 )
====> cache_find_entry_id( 4 ) "cn=andy,ou=People,o=test" (found) (1
tries)
<= id2entry_r( 4 ) 0x80e6558 (cache)
=> send_search_entry: "cn=andy,ou=People,o=test"
ber_flush: 143 bytes to sd 10
<= send_search_entry
====> cache_return_entry_r( 4 ): returned (0)
send_ldap_search_result 0::
send_ldap_response: msgid=2 tag=101 err=0
ber_flush: 14 bytes to sd 10
connection_get(10): got connid=0
connection_read(10): checking for input on id=0
ber_get_next
ber_get_next: tag 0x30 len 5 contents:
ber_get_next
ber_get_next on fd 10 failed errno=11 (Resource temporarily unavailable)

do_unbind
connection_closing: readying conn=0 sd=10 for close
connection_resched: attempting closing conn=0 sd=10
connection_close: conn=0 sd=10
TLS trace: SSL3 alert write:warning:close notify
----- CUT THIS LINE OUT --- IT IS ONLY TO SEPERATE THE TWO SEARCHES
---------
connection_get(10): got connid=1
connection_read(10): checking for input on id=1
TLS trace: SSL_accept:before/accept initialization
TLS trace: SSL_accept:error in SSLv3 read client hello C
TLS trace: SSL_accept:error in SSLv3 read client hello C
TLS: can't accept.
TLS: error:140D9115:SSL routines:SSL_GET_PREV_SESSION:session id context
uniniti
alized ssl_sess.c:278
connection_read(10): TLS accept error error=-1 id=1, closing
connection_closing: readying conn=1 sd=10 for close
connection_close: conn=1 sd=10