Archived
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.
0 -
(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):./openssl version -v -b -f -p -d -e OpenSSL 1.1.1g 21 Apr 2020 (Library: OpenSSL 1.1.1f 31 Mar 2020) built on: Mon Mar 22 11:37:17 2021 UTC platform: debian-amd64 compiler: gcc -fPIC -pthread -m64 -Wa,--noexecstack -Wall -Wa,--noexecstack -g -O2 -fdebug-prefix-map=/build/openssl-Juj39H/openssl-1.1.1f=. -fstack-protector-strong -Wformat -Werror=format-security -DOPENSSL_TLS_SECURITY_LEVEL=2 -DOPENSSL_USE_NODELETE -DL_ENDIAN -DOPENSSL_PIC -DOPENSSL_CPUID_OBJ -DOPENSSL_IA32_SSE2 -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_MONT5 -DOPENSSL_BN_ASM_GF2m -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DKECCAK1600_ASM -DRC4_ASM -DMD5_ASM -DAESNI_ASM -DVPAES_ASM -DGHASH_ASM -DECP_NISTZ256_ASM -DX25519_ASM -DPOLY1305_ASM -DNDEBUG -Wdate-time -D_FORTIFY_SOURCE=2 OPENSSLDIR: "/usr/lib/ssl" ENGINESDIR: "/usr/lib/x86_64-linux-gnu/engines-1.1"
This is the same OPENSSLDIR that the distro's OpenSSL reports.
0 -
did you install you CA certificate in
/usr/share/ca-certificates
and added it to/etc/ca-certificates.conf
before usingupdate-ca-certificates
?
`0 -
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.100 -
It 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.
0 -
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
0 -
Yes, our prefix and openssldir are set, and we have a different prefix from the system installation.
0 -
According to the
openssl
output you posted before you are using the same as the system default for your builds.OPENSSLDIR: "/usr/lib/ssl" ENGINESDIR: "/usr/lib/x86_64-linux-gnu/engines-1.1"
0 -
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.0 -
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
Jeremy0 -
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
IceSSL.CertFile=server_cert_pub.pem IceSSL.KeyFile=server_key.pem
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.pemIn 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,
Jose0 -
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
Jeremy0 -
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
If no chain is specified, the library will try to complete the chain from the available CA certificates in the trusted CA > storage, see SSL_CTX_load_verify_locations(3).
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
zeroc/CA2.crt zeroc/CA1.crt
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
Ice.Plugin.IceSSL=IceSSL:createIceSSL IceSSL.CertFile=server_pub.pem IceSSL.KeyFile=server_priv.pem IceSSL.UsePlatformCAs=1 IceSSL.Password=password
server_pub.pem
has just the leaf certificate.In a separate machine I check the chain is send by using the following openssl command
openssl s_client -showcerts -connect 192.168.1.143:10001
0