Archived

This forum has been archived. Please start a new discussion on GitHub.

Ice 3.5.1: IceSSL.DefaultDir not respected if certificate found in cwd

https://doc.zeroc.com/display/Ice/IceSSL+Properties#IceSSLProperties-IceSSL.DefaultDir suggests, that IceSSL.DefaultDir is always looked at first when finding certificates:
IceSSL.DefaultDir
Synopsis

IceSSL.DefaultDir=path
Description

Specifies the default directory in which to look for certificate, key, and key store files. See the descriptions of the relevant properties for more information.

https://doc.zeroc.com/display/Ice/IceSSL+Properties#IceSSLProperties-IceSSL.CertAuthFile says:
IceSSL.CertAuthFile
Synopsis

IceSSL.CertAuthFile=file (C++, Ice Touch)
Description

Specifies a file containing the certificate of a trusted certificate authority. The file name may be specified relative to the default directory defined by IceSSL.DefaultDir.
Platform Notes
C++

The certificate must be encoded using the PEM format.


Apparently this is not the case (example from Ice unit tests, which uses ../certs/ as IceSSL.DefaultDir):
[root@srv ~/Ice-3.5.1/cpp/test/IceSSL/configuration]# ./run.py
starting server... ok
starting client... ok
testing manual initialization... ok
testing certificate verification... ok
testing custom certificate verifier... ok
testing protocols... ok
testing expired certificates... ok
testing CA certificate directory... ok
testing password prompt... ok
testing ciphers... ok
testing IceSSL.TrustOnly... ok
testing IceSSL.TrustOnly.Client... ok
testing IceSSL.TrustOnly.Server... ok
testing IceSSL.TrustOnly.Server.<AdapterName>... ok

[root@srv ~/Ice-3.5.1/cpp/test/IceSSL/configuration]# touch cacert1.pem
[root@srv ~/Ice-3.5.1/cpp/test/IceSSL/configuration]# ./run.py
starting server... ok
starting client... ok
testing manual initialization... ok
testing certificate verification... Outgoing.c-! 03/23/15 17:13:47.049 warning: dispatch exception: Instance.cpp:481: Ice::PluginInitializationException:
pp:499: Ice::Unkn   plug-in initialization failed: IceSSL: unable to establish CA certificates
own   identity: factory
   facet: 
Lo   operation: createServer
calE   remote host: 127.0.0.1 remote port: 41083
xception:
unknown local except-! 03/23/15 17:13:47.052 warning: connection exception:
ion:
Instance.cpp:481   TcpTransceiver.cpp:284: Ice::ConnectionLostException:
   connection lost: recv() returned zero
: Ice::PluginInitializationExcept   local address = 127.0.0.1:12010
ion:   remote address = 127.0.0.1:41083

plug-in initialization failed: IceSSL: unable to establish CA certificates
unexpected exit status: expected: 0, got 1

When checking the settings using checkPath, Ice actually does verify that files exist in the correct locations, but then does this in Instance.cpp line 424, which leads to the described behavior:
               string caFile = properties->getProperty(propPrefix + "CertAuthFile");
               string caDir = properties->getPropertyWithDefault(propPrefix + "CertAuthDir", defaultDir);

                const char* file = 0;
                const char* dir = 0;
                if(!caFile.empty())
                {
                    if(!checkPath(caFile, defaultDir, false))
                    { 
                        PluginInitializationException ex(__FILE__, __LINE__);
                        ex.reason = "IceSSL: CA certificate file not found:\n" + caFile;
                        throw ex;
                    } 
                    file = caFile.c_str();
                }
                if(!caDir.empty())
                {
                    if(!checkPath(caDir, defaultDir, true))
                    {
                        PluginInitializationException ex(__FILE__, __LINE__);
                        ex.reason = "IceSSL: CA certificate directory not found:\n" + caDir;
                        throw ex;
                    }
                    dir = caDir.c_str();
                }
                if(file || dir)
                {
                    //
                    // The certificate may be stored in an encrypted file, so handle
                    // password retries.
                    //
                    int count = 0;
                    int err = 0;
                    while(count < passwordRetryMax)
                    {
                        ERR_clear_error();
                        err = SSL_CTX_load_verify_locations(_ctx, file, dir);
                        if(err)
                        {
                            break;
                        }
                        ++count;
                    } 
...

This is quite surprising, as the meaning of a configuration changes based on your current working directory - we actually experienced this first hand when an application was started from a directory that contained a CA certificate of the same name as the one configured.

Based on the code I would also assume that setting IceSSL.CertAuthFile, IceSSL.CertAuthDir and IceSSL.DefaultDir at the same time could lead to surprising results.

I didn't have a chance to test this myself yet, but I would assume that making const char *file point to a string that is composed of IceSSL.DefaultDir and IceSSL.CertAuthFile in the same way as checkPath verifies the existence of the file, should resolve the issue.

Comments

  • mes
    mes California
    Thanks Michael, we'll look into it.

    Mark