On Tue, Apr 9, 2024 at 9:21 PM Arrigo Marchiori <ard...@apache.org> wrote:

> > > I think this thread excerpt explains it:
> > > https://lists.apache.org/thread/3rvvgxnws9867krk75rw6bvhmds1t2co
> > >
> > >
> > Is that horrible bug fixed now, or does Curl/OpenSSL still crash AOO in
> > certain setups?
> Now when I check for update I see a dialog box with the following
> error message:
> Status
>   Checking for an update failed.
> Description
>   Error reading data from the Internet.
>   Server error message: Problem with the SSL CA cert (path? access
> rights?).
> I think that on trunk we had solved the crash, but automatic updates
> were just failing silently.
> I need to build ``untouched'' trunk and try again the above.
In curl lib/strerror.c, function curl_easy_strerror(), that message comes

    return "Problem with the SSL CA cert (path? access rights?)";

Searching for where CURLE_SSL_CACERT_BADFILE appears then takes us to
lib/vtls/openssl.c (since we use OpenSSL).

In that file, it's only set in one region of the lengthy
ossl_connect_step1() function, when ssl_cafile or ssl_capath are set,
verifypeer is set, and calling SSL_CTX_load_verify_file() or
SSL_CTX_load_verify_dir() on them fails.

The ssl_cafile and ssl_capath come from options to ./configure, but those
are impossible to change, read acinclude.m4 around CURL_CHECK_CA_BUNDLE,
where if neither --with-ca-bundle nor --with-ca-path are given (or both are
given but disabled), it auto-detects the local location of the bundle. Even
a wrong path is overridden by the auto-detected one. And this auto-detected
one won't work on other Linux distributions.

So one way to fix the error would be to patch Curl's configure and/or code.

But there is another way, and that is to always call:
curl_easy_setopt( m_pCurl, CURLOPT_CAINFO, "/path/to/certificates" );
at run-time, so that the compile-time path is overridden by the one we
specify there.

Curl version 7.77.0 also added the even better option CURLOPT_CAINFO_BLOB,
which can use an in-memory PEM list, instead of a file.

But here we face a problem.

Our ::com::sun::star::xml::crypto::XSecurityEnvironment is intended to own
the certificate verification process. We just ask it whether a certificate
chain is valid, using the verifyCertificate() method. But no method exists,
to tell us what certificates are trusted.

Thus we cannot populate our trusted certificates from Mozilla/Windows, into

There are 2 ways to get it working:
1. Patch XSecurityEnvironment to add further methods to retrieve the
trusted CA root certificates from Mozilla/Windows, and use these to build
the initial certificate list to pass to Curl/OpenSSL. Then use OpenSSL to
do verification, but on certificates that fail OpenSSL's verification, use
our own verification process instead, like we do now.
2. Specify an initial nonsense certificate to Curl and OpenSSL, just to get
them to initialize, then completely override the certificate verification
with our own using the XSecurityEnvironment, before that nonsense
certificate can be used.

Option 1 seems counter-productive: why do certificate verification twice,
first in OpenSSL, and then again in XSecurityEnvironment (via NSS or
Windows's mscrypt)? Also it's quite a pain to develop, UNO interfaces are
immutable so we'd need new interfaces, new services, and many code changes.

Instead, I have successfully developed option 2:
- Curl has been upgraded to the latest version, 8.7.1.
- A nonsense self-signed expired certificate is fed into Curl to get it to
- In Curl's CURLOPT_SSL_CTX_FUNCTION, our Curl_SSLContextCallback, we then
completely override OpenSSL's verification process with ours, using
SSL_CTX_set_cert_verify_callback() (instead of the previous
SSL_CTX_set_verify() which just allows us to override OpenSSL's
verification result).
- The verification is largely the same as before, we just have to call
slightly different functions to retrieve the certificate to verify and the
untrusted chain.
- Various other cleanups, better logging, etc. were made in the process.

And it's working! We should now be able to use HTTPS and WebDAV on any
Linux distribution, including those whose system trusted CA certificates
are in a different location or missing entirely, as long as they have the
Mozilla certificates.

Now what would you guys prefer:
- Should I do more testing, on Windows and Linux, and push my changes in a
few days?
- Should I push my changes now, and let you guys test too, and fix any
problems as we discover them?


Reply via email to