verify server certicate

Bug #551811 reported by buzzdee
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
Coccinella
Fix Released
Wishlist
buzzdee

Bug Description

Coccinella is not able to very the server SSL certitificate.

in jabber/JUI.tcl I see the following:

proc ::JUI::SetSecurityIcons {} {
    variable jwapp

    if {[llength $jwapp(securityWinL)]} {

        # security-high: SASL+TLS with a certificate signed by a trusted source
        # security-medium: {SASL+TLS|TLS on separate port} with a certificate
        # signed by a source that is not trusted (self-signed certificate)
        # security-low: only SASL or no security at all
        set any 0
        set sasl [::Jabber::Jlib connect feature sasl]
        set ssl [::Jabber::Jlib connect feature ssl]
        set tls [::Jabber::Jlib connect feature tls]
        set cert 0
        set w $jwapp(w)
        if {$sasl && $tls && $cert} {
            # TRANSLATORS; code for these strings is not finished
            set str [mc "The connection is secure"]
            set image [::Theme::Find16Icon $w secureHighImage]
            set any 1
        } elseif {($sasl && $tls) || $ssl} {

but when I manually specify to require a valid server certificate and provide a CA certificate in:
jabberlib/jlibtls.tcl
proc jlib::tls_proceed {jlibname tag xmllist} {

    upvar ${jlibname}::lib lib
    upvar ${jlibname}::locals locals

    Debug 2 "jlib::tls_proceed"

    set sock $lib(sock)

    # Make it a SSL connection.
    if {[catch {
        tls::import $sock -cafile "~/Documents/coccinella-trunk/coccinella/sub.class1.server.ca.pem" -certfile "" -keyfile "" \
          -request 1 -server 0 -require 1 -ssl2 no -ssl3 yes -tls1 yes
    } err]} {
        close $sock
        tls_finish $jlibname starttls-failure $err
    }
then Coccinella is able to verify the certificate of the server.

The SSL Icon should be come green when the server certificate is verified.

The User should be able to specify a server CA certificate in the Preferences -> Network -> Certificates

This should work for both: SSL and TLS

buzzdee (sebastia)
Changed in coccinella:
assignee: nobody → buzzdee (sebastia)
description: updated
buzzdee (sebastia)
Changed in coccinella:
importance: Medium → Wishlist
Revision history for this message
buzzdee (sebastia) wrote :

This bothered me since a long time, and it turned out implementing it was easier than anticipated ;)

svn version #2797 adds the check of the servers certificate.

How does it work:
1. in the Preferences, General, Network, Certificates Tab
   - activate the ckeckbox "TLS CA certificate file"
   - Browse to your CA certificate file (The certificate file should contain the whole certificate chain, from the Root CA, down to the CA that signed the server certificate.)

2. when login to the server either using TLS/SASL or SSL, and coccinella verified the Server certificate, then the connection to the server will be established, and the icon in the roster indicating the security of the connection turns green ;)

3. If the server certificate cannot be verified from Coccinella, then the connection to the server will fail, it will NOT fall back to a medium secure connection. If you do not want to verify the server certificate, then disable the checkbox option in the preferences.

Also the patch that was checked in to svn revision #2797 is attached for review. As this is a security related feature, intensive testing is necessary. So PLEASE TEST

Tested against ejabberd 2.1.3 using TLS/SASL and SSL connections.

Changed in coccinella:
status: New → Fix Committed
Revision history for this message
sander (s-devrieze) wrote :

I get the following error trying to save the settings in the preferences dialog:

Hook prefsSaveHook failed: 1
can't read "tmpCertPrefs(usecertfile)": no such variable
    while executing
"set jprefs(tls,$key) $tmpCertPrefs($key)"
    (procedure "ServersSaveHook" line 10)
    invoked from within
"ServersSaveHook"
    (procedure "::PrefNet::SavePrefsHook" line 3)
    invoked from within
"::PrefNet::SavePrefsHook"
    ("eval" body line 1)
    invoked from within
"eval $func $args"
can't read "tmpCertPrefs(usecertfile)": no such variable
    while executing
"set jprefs(tls,$key) $tmpCertPrefs($key)"
    (procedure "ServersSaveHook" line 10)
    invoked from within
"ServersSaveHook"
    (procedure "::PrefNet::SavePrefsHook" line 3)
    invoked from within
"::PrefNet::SavePrefsHook"
    ("eval" body line 1)
    invoked from within
"eval $func $args"

Also, what is the difference between the three certificate options? This is not 100% clear to me.

Revision history for this message
buzzdee (sebastia) wrote :

The exception is fixed, I somehow missed to add variable tmpCertPrefs in the procedure.

The TLS certificate and TLS key files are intended to be used for client certificate verification. The client sends the certificate to the server in order to get authenticated.

The TLS CA certificate file is used to verify the certificate received from the server by the client. The TLS CA certificate should contain the whole certificate chain in order to be able to verify the server certificate.

Maybe we should add some explanatory text to the preferences TAB, and also maybe a FAQ entry.

Revision history for this message
sander (s-devrieze) wrote :

I think it first should be tried to improve the interface so that less explanation is needed.

Some additional questions:
* Did you already tried the jabber.org certificate?
* What if a user has multiple profiles with different servers? Is it possible to use the same certificate(s) for all servers?
* What is the difference between the TLS certificate and TLS key? Do you need both?

Revision history for this message
buzzdee (sebastia) wrote :

> I think it first should be tried to improve the interface so that less explanation is needed.
Yes, but Certificate handling/management was never easy to explain ;)

The easiest thing is to put a horizontal line between the TLS certfile/keyfile and the TLS CA file to separate those options, and put a meaningful headline in each of the section.

Some additional questions:
* Did you already tried the jabber.org certificate?
No, I was unable to register, via web and via using coccinella/pidgin, got an error, but you may try to use the certificate file I appended here.

* What if a user has multiple profiles with different servers? Is it possible to use the same certificate(s) for all servers?
Yes, it is all certificates can be stuffed into the same TLS CA file like I did, I put the certificate chain for StartSSL, CAcert and Equifax into one file, and coccinella is able to verify all three kinds of server certificates. See appended file. So we could add this file to coccinella and install it together with Coccinella and make it the default TLS CA file.

* What is the difference between the TLS certificate and TLS key? Do you need both?
Yes, both are needed, its public key cryptography ;) The TLS key is the private part, and need to be kept secret, the TLS certificate is the public part, and is sent to the server. And in case the server knows about the certificate that signed the client certificate, the server will be able to verify authenticity of the client certificate.

Changed in coccinella:
status: Fix Committed → In Progress
Revision history for this message
buzzdee (sebastia) wrote :

With the appended patch we could redistribute the certificate chains for CACert, startSSL and Equifax.

However, with Equifax, we would need to sign such a form:
open this page: https://www.geotrust.com/resources/root-certificates/index.html
and take a look at: Root Certificate Distribution Agreement
not really sure if we want to do this, Sander?

The statement regarding cacert certificate license can be found here:
http://www.cacert.org/policy/NRPDisclaimerAndLicence.php
If you want to use certificates issued by CAcert, read the CAcert Disclaimer and Licence .This license applies to using the CAcert root keys.

For startssl I haven't found anything.

Sander, do you can figure out whether including startssl root certificates would be OK?
As far as I can see, including cacert root certificates should be fine.

With the patch applied, Coccinella checks (at least here for me on Linux right now) in ~/.coccinella/certificates for the existence of cacerts.pem file, and if not there, it copies the file from the "application directory/certificates/cacerts.pem" to the above mentioned directory. I chose to put the cacerts.pem file in certificates/cacerts.pem so that it should also work when the configuration is saved in the application path.

Sander, any objections when I commit this one to see how the windows breakfast build binary behaves with using/copying the certificate file?

Revision history for this message
buzzdee (sebastia) wrote :

svn revision 2815 contains the default certificate file, and enabled its usage in the preferences.

The default is still to not veryify the server certificate, in order to get a "green" security sign, the user has to enable the checkbox in the preferences.

When everything works out, probably worth a new hint in the Tip of the day ;)

Next thing to explore, when everything works fine is figuring out whether tcltls is able to sth. like a capath or cadir parameter instead of the cafile parameter, and if so, make use of this one. Was suggesty by sander to make certificate management easier for the end user, which is probably a good idea.

Revision history for this message
sander (s-devrieze) wrote :

"When everything works out, probably worth a new hint in the Tip of the day"

What do you have in mind for the hint? Is a hint really needed? Isn't the mouse over balloon help text enough? It's better to have a limited number of very good hints instead of a large quantity of hints.

Revision history for this message
buzzdee (sebastia) wrote :

I meant just a small comment in the Totd entry like: If you want to verify your server certificate you have to enable it in the Preferences -> Network -> certificates ...
For a more detailed explanation how it works, an entry in the FAQ should be added, or we will only have a FAQ entry.

However, with a clean svn checkout running on Linux, the certificate gets installed, and it is used, and certificate check works.

Using the binary, I now get the following exception on startup:

Hook prefsInitHook failed: 1
error copying "/home/user/Desktop/Coccinella-0.96.19Linux-x86/certificates/cacerts.pem": no such file or directory
    while executing
"file copy [file join $this(appPath) certificates cacerts.pem] $jprefs(tls,cafile)"
    (procedure "::PrefNet::InitPrefsHook" line 23)
    invoked from within
"::PrefNet::InitPrefsHook"
    ("eval" body line 1)
    invoked from within
"eval $func $args"
error copying "/home/user/Desktop/Coccinella-0.96.19Linux-x86/certificates/cacerts.pem": no such file or directory
    while executing
"file copy [file join $this(appPath) certificates cacerts.pem] $jprefs(tls,cafile)"
    (procedure "::PrefNet::InitPrefsHook" line 23)
    invoked from within
"::PrefNet::InitPrefsHook"
    ("eval" body line 1)
    invoked from within
"eval $func $args"

I can dismiss it, and coccinella starts up fine afterwards.

The directory /home/user/Desktop/Coccinella-0.96.19Linux-x86 is the directory where I extracted the downloaded binary.

When I put the certificate in place in /home/user/.coccinella/certificates/cacerts.pem, and then restart coccinella, the error doesn't show up as expected, but then on login, I get an error that the certificate cannot be checked:
SSL channel "sock16": error: certificate verify failed
SSL channel "sock16": error: certificate verify failed
The tcltls package I use here on Linux x86_64 (installed opensuse rpm) is tls-1.6-5.42, on OpenBSD I use tcltls-1.5.0p2 installed from ports. The tcltls binary that is included with coccinella is version 1.4.
Sander, this may also be the problem why it did not worked for you when you tried it, I guess we probably need to update the tcltls binary to a more recent version.

My guess is that on Windows I'll run into the same problem. Will hopefully have time today in the evening to test.

Revision history for this message
buzzdee (sebastia) wrote :

ok, tested on windows, and got the same behaviour as mentioned above.

now in svn revision 2816 I check for the existence of starkit::topdir variable, and if it exists, then I copy the cacerts file from $starkit::topdir if it not exists, from the $appDir as when running from sources.

If that works out, maybe additionally I should add a catch statement to prevent the exception for other edge cases.

svn revision 2817 contains tcltls updates for windows to tcltls 1.6 and Linux x86 to tcltls 1.5. Linux is only 1.5 because there is no binary available for 1.6 release.

At least on OpenBSD I have tcltls 1.5 and there the validation works well.

Revision history for this message
buzzdee (sebastia) wrote :

Yeah, after fiddling around a lot with the tcltls package update on Linux in the binary to 1.50, now the certificate verification works for me on Linux with the binary too ;)
Still need to test on Windows, but I guess that should also work, as there it is updated to 1.6.

Sander do you can test this on the MAC?
In case it doesn't work for you, do you can run the binary with -debugLevel 10 and add the output here.

Also the copying/creation of the cacerts from the binary also works well. The next thing is to split the certificates, and then just copy the directory with the certificates inside, and then switch the code from using -cafile to -cadir.

Revision history for this message
buzzdee (sebastia) wrote :

It seems just creating a directory and putting *.pem files into it will not be enough.

The certificates need to have a specific file name to be able for tcltls to use the certificates in the specified directory to pick them up for verification.

See:
http://sourceforge.net/tracker/index.php?func=detail&aid=2953768&group_id=13248&atid=113248

and:
http://www.openssl.org/docs/ssl/SSL_CTX_load_verify_locations.html

when the user wants to add own certificate he has to run the c_rehash command.

For users without openssl installed, especially on Windows, this may be much more complicated than just opening a text editor to add their custom *pem file from the server.

Sander, what do you think about that, I'd say we should stick to the cafile stuff instead of using a directory.

Revision history for this message
sander (s-devrieze) wrote :

1) It works on Mac OS X.

2) I build tcltls 1.6 for Linux because the 1.5 version depended on OpenSSL 0.9.7 which is not available on modern Linux systems. Can you test on a 64 bit Linux system?

3) Alternatively, a good certificate manager to import certificates may be a solution? Or do you think this is not necessary?

Revision history for this message
buzzdee (sebastia) wrote :

I also tested on Windows XP, the Linux binary on a 64 Bit box, both work fine.

I think a certificate manager would be overkill, but in case many people out there start whining because they will miss such thing, then we could probably add it at a later time. For the time being, a FAQ entry how to add a custom server certificate chain should be enough.

Therefore marking this now as fix committed.

Changed in coccinella:
status: In Progress → Fix Committed
sander (s-devrieze)
Changed in coccinella:
status: Fix Committed → Fix Released
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.