diff --git a/python/core/auth/qgsauthcertutils.sip b/python/core/auth/qgsauthcertutils.sip index 1d2520068d3..706d400f49a 100644 --- a/python/core/auth/qgsauthcertutils.sip +++ b/python/core/auth/qgsauthcertutils.sip @@ -275,6 +275,15 @@ Get short strings describing an SSL error %End + static QList validateCertChain( const QList &certificateChain, const QString &hostName = QString(), bool addRootCa = false ) ; +%Docstring + validateCertChain validates the given ``certificateChain`` + \param certificateChain list of certificates to be checked, with leaf first and with optional root CA last + \param addRootCa if true the CA will be added to the trusted CAs for this validation check + :return: list of QSslError, if the list is empty then the cert chain is valid + :rtype: list of QSslError +%End + }; /************************************************************************ diff --git a/src/core/auth/qgsauthcertutils.cpp b/src/core/auth/qgsauthcertutils.cpp index a338150bcc3..2f956ab4153 100644 --- a/src/core/auth/qgsauthcertutils.cpp +++ b/src/core/auth/qgsauthcertutils.cpp @@ -1018,3 +1018,25 @@ QList > QgsAuthCertUtils::sslErrorEnumString QgsAuthCertUtils::sslErrorEnumString( QSslError::CertificateBlacklisted ) ); return errenums; } + +QList QgsAuthCertUtils::validateCertChain( const QList &certificateChain, const QString &hostName, bool addRootCa ) +{ + QList results; + // Merge in the root CA if present and asked for + if ( addRootCa && certificateChain.count() > 1 && certificateChain.last().isSelfSigned() ) + { + static QMutex sMutex; + QMutexLocker lock( &sMutex ); + QSslConfiguration oldSslConfig( QSslConfiguration::defaultConfiguration() ); + QSslConfiguration sslConfig( oldSslConfig ); + sslConfig.setCaCertificates( casMerge( sslConfig.caCertificates(), QList() << certificateChain.last() ) ); + QSslConfiguration::setDefaultConfiguration( sslConfig ); + results = QSslCertificate::verify( certificateChain, hostName ); + QSslConfiguration::setDefaultConfiguration( oldSslConfig ); + } + else + { + results = QSslCertificate::verify( certificateChain, hostName ); + } + return results; +} diff --git a/src/core/auth/qgsauthcertutils.h b/src/core/auth/qgsauthcertutils.h index 5b2932a2170..90aa7156ea5 100644 --- a/src/core/auth/qgsauthcertutils.h +++ b/src/core/auth/qgsauthcertutils.h @@ -296,6 +296,14 @@ class CORE_EXPORT QgsAuthCertUtils */ static QList > sslErrorEnumStrings() SIP_SKIP; + /** + * \brief validateCertChain validates the given \a certificateChain + * \param certificateChain list of certificates to be checked, with leaf first and with optional root CA last + * \param addRootCa if true the CA will be added to the trusted CAs for this validation check + * \return list of QSslError, if the list is empty then the cert chain is valid + */ + static QList validateCertChain( const QList &certificateChain, const QString &hostName = QString(), bool addRootCa = false ) ; + private: static void appendDirSegment_( QStringList &dirname, const QString &segment, QString value ); };