OpenSSL default certificate directory when IceSSL.UsePlatformCA property is used.

I’m attempting to validate certificates on Ubuntu 20.04 using the IceSSL.UsePlatformCAs property using C++. It’s worth noting that I’m using a different distribution of openSSL 1.1.1f, rather than the system distribution.
Even when I copy the PEM certificate file into the directory that OpenSSL should be using by default (/usr/lib/ssl/certs on Ubuntu, as far as I can tell) and configure and run update-ca-certificates
, it fails to validate the certificate. As far as I can tell, no errors are logged, even with a variety of Ice logging settings turned on.
However, when I set the SSL_CERT_DIR or SSL_CERT_FILE environment variables (i.e. running SSL_CERT_DIR=/usr/lib/ssl/certs my_program
) with my PEM certificate file present in that directory or at that file, Ice successfully validates the cert.
My desired behavior is for Ice to use OpenSSL’s default certificate directory (or some other reasonable default) for certificate validation when I set UsePlatformCAs, without me needing to set any environment variables. How can I accomplish this? Is there extra openSSL init code I need to run? Would I need to use the system’s openSSL version instead?
If that isn’t possible, is there a way to find out where Ice is looking?
Comments
Hi Jeremy,
Was your OpenSSL distribution build to use
/usr/lib/ssl/certs
, or maybe your build is using another directory? what is the output ofopenssl version -a
.The fact that it works when you set the environment variables seems to indicate that the default settings are not what you expect.
(This is actually my question--Jeremy just posted it for me while I waited for my account to be approved).
openssl version -a
fails with a symbol lookup error on one of the pieces of information it requests, likely because of how we built it. However, here's the output ofopenssl version
with all the flags that do work (all of them except -o):This is the same OPENSSLDIR that the distro's OpenSSL reports.
did you install you CA certificate in
/usr/share/ca-certificates
and added it to/etc/ca-certificates.conf
before usingupdate-ca-certificates
?`
I just tested with the hello demo and this seems to work, here is what I did
Copy the demo CA certificate to
/usr/share/ca-certificates/zeroc/cacert.pem
Add an entry in
/etc/ca-certificates.conf
withzeroc/cacert.pem
Run
update-ca-certificates
in config.client remove
IceSSL.CAs=cacert.pem
and addIceSSL.UsePlatformCAs=1
I tested it with
OpenSSL 1.1.1f
and Ubuntu 20.10It does work with the system Ice and OpenSSL libraries; it seems to be ours that is the problem. I'm looking into other approaches now, thank you for your help.
did you try installing your version in a different location, it can be a problem with having two versions that are not binary compatible install with the same prefix, this is mentioned in the OpenSSL docs https://wiki.openssl.org/index.php/Compilation_and_Installation#PREFIX_and_OPENSSLDIR
Yes, our prefix and openssldir are set, and we have a different prefix from the system installation.
According to the
openssl
output you posted before you are using the same as the system default for your builds.That is true, but the function call
X509_get_default_cert_dir_env
(which OpenSSL is using) doesn't produce the correct value when compiled and run with our openssl version. It instead looks in the directory where it was compiled.Hi Jose,
A related question on this topic.
We're trying to understand if there's any way to have Ice on Linux package up the sender certificate + intermediates other than creating a PFX that has it all combined. Linux has the concept of a certificate store, albeit more primitive than Windows. It would seem that we could do something with IceSSL.CAs or IceSSL.UsePlatformCAs to make Ice gather intermediates up from the store too. It does this just fine on Windows. I tested by installing a intermediate.crt in my Linux system (Centos7) and setting IceSSL.UsePlatformCAs to 1, and it didn't work. But maybe that's not what that property is intended for.
Thanks
Jeremy
Hi Jeremy,
You can put the keychain with the server certificate in a PEM file,
IceSSL.CertFile
should point to this file and then separately specify the key file usingIceSSL.KeyFile
Seem for example the PEM encoded certificate we use to test this
https://github.com/zeroc-ice/ice/blob/3.7/cpp/test/IceSSL/certs/s_rsa_cai2_pub.pem
https://github.com/zeroc-ice/ice/blob/3.7/cpp/test/IceSSL/certs/s_rsa_cai2_priv.pem
In case you want to test with these certificates, the password is "password".
The property
IceSSL.KeyFile
was deprecated in 3.7 but still works, I think we should actually undeprecate it as it is handy for this use case, I will open an issue to discuss it with my colleagues.IceSSL.CAs
andIceSSL.UsePlatformCAs
are unrelated to this.Cheers,
Jose
Jose,
We're already doing something similar today with the IceSSL.CertFile property. We can create a .PFX that has the sender cert and key, plus the intermediate chain all combined. We don't need the IceSSL.KeyFile property. This does work fine for us on Linux. I think you answered our question though... IceSSL.CAs and IceSSL.UsePlatformCAs do not work on sender side. Basically, you're saying there's no way to put intermediate CAs in the Linux stores like you can on Windows, and have them sent when the receiver established a connection. If that's not correct let me know.
Thanks
Jeremy
Hi Jeremy,
I was mistaken about
IceSSL.UsePlatformCAs
not affecting this, after reviewing the OpenSSL docs I found thishttps://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_add_extra_chain_cert.html
IceSSL calls
SSL_CTX_set_default_verify_paths
whenIceSSL.UsePlatformCAs
is set, keep in mind that this setting is ignored ifIceSSL.CAs
is defined.I did a quick test on Ubuntu with OpenSSL 1.1.1g and seems to work fine
Added the intermediary certs to
/etc/ca-certificates.conf
And copied them to
/usr/share/ca-certificates/zeroc/
Run
update-ca-certificates
to update the storeThen I run hello demo server with this configuration
server_pub.pem
has just the leaf certificate.In a separate machine I check the chain is send by using the following openssl command