Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-88639

QSslConfiguration::setCaCertificates() does not disable system certificates

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Closed
    • Priority: P2: Important
    • Resolution: Done
    • Affects Version/s: 5.14.0, 5.15.1
    • Fix Version/s: 6.0.0, 6.1.0
    • Component/s: Network: SSL
    • Labels:
      None
    • Platform/s:
      Windows
    • Commits:
      1158ff67b492853b72199ed78bfcf24132e1c7ff (qt/qtbase/dev) 65e2837b30becb745036f13d98a9472a0332b152 (qt/qtbase/6.0.0) 94983639fc559fd57c6075b1323b28f034a49071 (qt/qtbase/6.0) f4152d268e842961597b53819f2821df9804e303 (qt/qtbase/5.15)

      Description

      In order to validate that an SSL certificate belongs to a specific root certificate, you can set the list of trusted root certificate using the (now deprecated) QSslSocket::setDefaultCaCertificates static method. This makes sure that further certificate validation uses only the root certificate list given.

      After the above method has been deprecated, I believe that the QSslConfiguration:: setCaCertificates() method should be used instead in a manner like this:

      // Set up CA certificates using QSslConfiguration:
      auto conf = QSslConfiguration::defaultConfiguration();
      conf.setCaCertificates(rootCert);
      QSslConfiguration::setDefaultConfiguration(conf);  

      However, at least on the Windows platform, this does not make QT exclude the trusted root certificates retrieved from the Windows certificate store. This is a problem if you need to validate that a certificate is based on a specific set of root certificates (as certificate chains ending in a certificate in the Windows store will be validatable as well).

      Find attached a small project that illustrates the problem. The project includes a self-signed root certificate. With this set up as the only trusted certificate (using either of the two methods above), the official certificate found on www.qt.io is validated. The validation should fail, as the qt.io certificate chain does not end in the specified root certificate. However if the root certificate is set through QSslConfiguration::setCaCertificates, the validation succeeds, as it can be validated against the root certificates in the Windows store.

      Using the old setDefaultCaCertificates method, the validation fails as expected.

      The problem seems to be related to the QSslSocketPrivate::s_loadRootCertsOnDemand variable, which appears to be reset by QSslSocket::setDefaultCaCertificates, but not by QSslConfiguration::setCaCertificates.

       In the attached test application, the two methods can be tested by switching between “#if 0” and “#if 1”. After setting the root certificate, tests are performed using QSslCertificate::verify as well as a QSslSocket-connection to www.qt.io.

      A working libssl/libcrypto DLL set must be available when testing the application. I was using openssl 1.1.1g in my test.

        Attachments

        1. CertReader.pro
          0.9 kB
        2. main.cpp
          8 kB
        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

          Activity

            People

            Assignee:
            tpochep Timur Pocheptsov
            Reporter:
            s_j_hansen Søren J. Hansen
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Dates

              Created:
              Updated:
              Resolved:

                Gerrit Reviews

                There are no open Gerrit changes