Skip to content

Commit

Permalink
Merge pull request #5478 from boundlessgeo/auth-viable
Browse files Browse the repository at this point in the history
[auth][api] Remove deprecated QSslCertificate::isValid()
  • Loading branch information
dakcarto committed Oct 27, 2017
2 parents 88a80e6 + 4b9898b commit 071099c
Show file tree
Hide file tree
Showing 17 changed files with 177 additions and 36 deletions.
23 changes: 23 additions & 0 deletions python/core/auth/qgsauthcertutils.sip
Expand Up @@ -294,6 +294,29 @@ Get short strings describing an SSL error
%End


static bool certIsCurrent( const QSslCertificate &cert );
%Docstring
certIsCurrent checks if ``cert`` is viable for its not before and not after dates
\param cert certificate to be checked
:rtype: bool
%End

static QList<QSslError> certViabilityErrors( const QSslCertificate &cert );
%Docstring
certViabilityErrors checks basic characteristics (validity dates, blacklisting, etc.) of given ``cert``
\param cert certificate to be checked
:return: list of QSslError (will return NO ERRORS if a null QSslCertificate is passed)
:rtype: list of QSslError
%End

static bool certIsViable( const QSslCertificate &cert );
%Docstring
certIsViable checks for viability errors of ``cert`` and whether it is NULL
\param cert certificate to be checked
:return: false if cert is NULL or has viability errors
:rtype: bool
%End

static QList<QSslError> validateCertChain( const QList<QSslCertificate> &certificateChain,
const QString &hostName = QString(),
bool trustRootCa = false ) ;
Expand Down
4 changes: 2 additions & 2 deletions src/auth/identcert/qgsauthidentcertmethod.cpp
Expand Up @@ -251,9 +251,9 @@ QgsPkiConfigBundle *QgsAuthIdentCertMethod::getPkiConfigBundle( const QString &a
// init client cert
// Note: if this is not valid, no sense continuing
QSslCertificate clientcert( cibundle.first );
if ( !clientcert.isValid() )
if ( !QgsAuthCertUtils::certIsViable( clientcert ) )
{
QgsDebugMsg( QString( "PKI bundle for authcfg %1: insert FAILED, client cert is not valid" ).arg( authcfg ) );
QgsDebugMsg( QString( "PKI bundle for authcfg %1: insert FAILED, client cert is not viable" ).arg( authcfg ) );
return bundle;
}

Expand Down
9 changes: 5 additions & 4 deletions src/auth/pkipaths/qgsauthpkipathsedit.cpp
Expand Up @@ -24,6 +24,7 @@
#include <QSslKey>

#include "qgsapplication.h"
#include "qgsauthcertutils.h"
#include "qgsauthmanager.h"
#include "qgsauthguiutils.h"
#include "qgslogger.h"
Expand Down Expand Up @@ -97,21 +98,21 @@ bool QgsAuthPkiPathsEdit::validateConfig()
return validityChange( false );
}

bool certvalid = cert.isValid();
QDateTime startdate( cert.effectiveDate() );
QDateTime enddate( cert.expiryDate() );

writePkiMessage( lePkiPathsMsg,
tr( "%1 thru %2" ).arg( startdate.toString(), enddate.toString() ),
( certvalid ? Valid : Invalid ) );
( QgsAuthCertUtils::certIsCurrent( cert ) ? Valid : Invalid ) );

bool showCas( certvalid && populateCas() );
bool certviable = QgsAuthCertUtils::certIsViable( cert );
bool showCas( certviable && populateCas() );
lblCas->setVisible( showCas );
twCas->setVisible( showCas );
cbAddCas->setVisible( showCas );
cbAddRootCa->setVisible( showCas );

return validityChange( certvalid );
return validityChange( certviable );
}

QgsStringMap QgsAuthPkiPathsEdit::configMap() const
Expand Down
4 changes: 2 additions & 2 deletions src/auth/pkipaths/qgsauthpkipathsmethod.cpp
Expand Up @@ -284,9 +284,9 @@ QgsPkiConfigBundle *QgsAuthPkiPathsMethod::getPkiConfigBundle( const QString &au
// init client cert
// Note: if this is not valid, no sense continuing
QSslCertificate clientcert( QgsAuthCertUtils::certFromFile( mconfig.config( QStringLiteral( "certpath" ) ) ) );
if ( !clientcert.isValid() )
if ( !QgsAuthCertUtils::certIsViable( clientcert ) )
{
QgsDebugMsg( QString( "PKI bundle for authcfg %1: insert FAILED, client cert is not valid" ).arg( authcfg ) );
QgsDebugMsg( QString( "PKI bundle for authcfg %1: insert FAILED, client cert is not viable" ).arg( authcfg ) );
return bundle;
}

Expand Down
4 changes: 2 additions & 2 deletions src/auth/pkipkcs12/qgsauthpkcs12method.cpp
Expand Up @@ -292,9 +292,9 @@ QgsPkiConfigBundle *QgsAuthPkcs12Method::getPkiConfigBundle( const QString &auth
// init client cert
// Note: if this is not valid, no sense continuing
QSslCertificate clientcert( bundlelist.at( 0 ).toLatin1() );
if ( !clientcert.isValid() )
if ( !QgsAuthCertUtils::certIsViable( clientcert ) )
{
QgsDebugMsg( QString( "PKI bundle for authcfg %1: insert FAILED, client cert is not valid" ).arg( authcfg ) );
QgsDebugMsg( QString( "PKI bundle for authcfg %1: insert FAILED, client cert is not viable" ).arg( authcfg ) );
return bundle;
}

Expand Down
62 changes: 48 additions & 14 deletions src/core/auth/qgsauthcertutils.cpp
Expand Up @@ -1241,6 +1241,43 @@ QList<QPair<QSslError::SslError, QString> > QgsAuthCertUtils::sslErrorEnumString
return errenums;
}

bool QgsAuthCertUtils::certIsCurrent( const QSslCertificate &cert )
{
if ( cert.isNull() )
return false;
const QDateTime currentTime = QDateTime::currentDateTime();
return cert.effectiveDate() <= currentTime && cert.expiryDate() >= currentTime;
}

QList<QSslError> QgsAuthCertUtils::certViabilityErrors( const QSslCertificate &cert )
{
QList<QSslError> sslErrors;

if ( cert.isNull() )
return sslErrors;

const QDateTime currentTime = QDateTime::currentDateTime();
if ( cert.expiryDate() <= currentTime )
{
sslErrors << QSslError( QSslError::SslError::CertificateExpired, cert );
}
if ( cert.effectiveDate() >= QDateTime::currentDateTime() )
{
sslErrors << QSslError( QSslError::SslError::CertificateNotYetValid, cert );
}
if ( cert.isBlacklisted() )
{
sslErrors << QSslError( QSslError::SslError::CertificateBlacklisted, cert );
}

return sslErrors;
}

bool QgsAuthCertUtils::certIsViable( const QSslCertificate &cert )
{
return !cert.isNull() && QgsAuthCertUtils::certViabilityErrors( cert ).isEmpty();
}

QList<QSslError> QgsAuthCertUtils::validateCertChain( const QList<QSslCertificate> &certificateChain,
const QString &hostName,
bool trustRootCa )
Expand Down Expand Up @@ -1269,20 +1306,7 @@ QList<QSslError> QgsAuthCertUtils::validateCertChain( const QList<QSslCertificat
const QList<QSslCertificate> constTrustedChain( trustedChain );
for ( const auto &cert : constTrustedChain )
{
// TODO: move all the checks to QgsAuthCertUtils::certIsViable( )
const QDateTime currentTime = QDateTime::currentDateTime();
if ( cert.expiryDate() <= currentTime )
{
sslErrors << QSslError( QSslError::SslError::CertificateExpired, cert );
}
if ( cert.effectiveDate() >= QDateTime::currentDateTime() )
{
sslErrors << QSslError( QSslError::SslError::CertificateNotYetValid, cert );
}
if ( cert.isBlacklisted() )
{
sslErrors << QSslError( QSslError::SslError::CertificateBlacklisted, cert );
}
sslErrors << QgsAuthCertUtils::certViabilityErrors( cert );
}

// Merge in the root CA if present and asked for
Expand All @@ -1307,6 +1331,16 @@ QList<QSslError> QgsAuthCertUtils::validateCertChain( const QList<QSslCertificat
QStringList QgsAuthCertUtils::validatePKIBundle( QgsPkiBundle &bundle, bool useIntermediates, bool trustRootCa )
{
QStringList errors;
if ( bundle.clientCert().isNull() )
errors << QObject::tr( "Client certificate is NULL." );

if ( bundle.clientKey().isNull() )
errors << QObject::tr( "Client certificate key is NULL." );

// immediately bail out if cert or key is NULL
if ( !errors.isEmpty() )
return errors;

QList<QSslError> sslErrors;
if ( useIntermediates )
{
Expand Down
20 changes: 20 additions & 0 deletions src/core/auth/qgsauthcertutils.h
Expand Up @@ -330,6 +330,26 @@ class CORE_EXPORT QgsAuthCertUtils
*/
static QList<QPair<QSslError::SslError, QString> > sslErrorEnumStrings() SIP_SKIP;

/**
* \brief certIsCurrent checks if \a cert is viable for its not before and not after dates
* \param cert certificate to be checked
*/
static bool certIsCurrent( const QSslCertificate &cert );

/**
* \brief certViabilityErrors checks basic characteristics (validity dates, blacklisting, etc.) of given \a cert
* \param cert certificate to be checked
* \return list of QSslError (will return NO ERRORS if a null QSslCertificate is passed)
*/
static QList<QSslError> certViabilityErrors( const QSslCertificate &cert );

/**
* \brief certIsViable checks for viability errors of \a cert and whether it is NULL
* \param cert certificate to be checked
* \return false if cert is NULL or has viability errors
*/
static bool certIsViable( const QSslCertificate &cert );

/**
* \brief validateCertChain validates the given \a certificateChain
* \param certificateChain list of certificates to be checked, with leaf first and with optional root CA last
Expand Down
2 changes: 1 addition & 1 deletion src/core/auth/qgsauthconfig.cpp
Expand Up @@ -275,7 +275,7 @@ bool QgsPkiBundle::isNull() const

bool QgsPkiBundle::isValid() const
{
return ( !isNull() && mCert.isValid() );
return ( !isNull() && QgsAuthCertUtils::certIsViable( mCert ) );
}

const QString QgsPkiBundle::certId() const
Expand Down
4 changes: 2 additions & 2 deletions src/core/auth/qgsauthmanager.cpp
Expand Up @@ -1784,7 +1784,7 @@ const QPair<QSslCertificate, QSslKey> QgsAuthManager::certIdentityBundle( const
const QStringList QgsAuthManager::certIdentityBundleToPem( const QString &id )
{
QPair<QSslCertificate, QSslKey> bundle( certIdentityBundle( id ) );
if ( bundle.first.isValid() && !bundle.second.isNull() )
if ( QgsAuthCertUtils::certIsViable( bundle.first ) && !bundle.second.isNull() )
{
return QStringList() << QString( bundle.first.toPem() ) << QString( bundle.second.toPem() );
}
Expand Down Expand Up @@ -2719,7 +2719,7 @@ const QList<QSslCertificate> QgsAuthManager::trustedCaCerts( bool includeinvalid
}
else if ( defaultpolicy == QgsAuthCertUtils::Trusted && !untrustedids.contains( certid ) )
{
if ( !includeinvalid && !cert.isValid() )
if ( !includeinvalid && !QgsAuthCertUtils::certIsViable( cert ) )
continue;
trustedcerts.append( cert );
}
Expand Down
4 changes: 2 additions & 2 deletions src/gui/auth/qgsauthcertificateinfo.cpp
Expand Up @@ -295,7 +295,7 @@ void QgsAuthCertInfo::updateCurrentCertInfo( int chainindx )
mCurrentTrustPolicy = trustpolicy;

cmbbxTrust->setTrustPolicy( trustpolicy );
if ( !mCurrentQCert.isValid() )
if ( !QgsAuthCertUtils::certIsViable( mCurrentQCert ) )
{
cmbbxTrust->setDefaultTrustPolicy( QgsAuthCertUtils::Untrusted );
}
Expand Down Expand Up @@ -880,7 +880,7 @@ void QgsAuthCertInfo::decorateCertTreeItem( const QSslCertificate &cert,
return;
}

if ( !cert.isValid() )
if ( !QgsAuthCertUtils::certIsViable( cert ) )
{
item->setIcon( 0, QgsApplication::getThemeIcon( QStringLiteral( "/mIconCertificateUntrusted.svg" ) ) );
return;
Expand Down
2 changes: 1 addition & 1 deletion src/gui/auth/qgsauthidentitieseditor.cpp
Expand Up @@ -205,7 +205,7 @@ void QgsAuthIdentitiesEditor::appendIdentitiesToItem( const QList<QSslCertificat
QTreeWidgetItem *item( new QTreeWidgetItem( parent, coltxts, ( int )identype ) );

item->setIcon( 0, QgsApplication::getThemeIcon( QStringLiteral( "/mIconCertificate.svg" ) ) );
if ( !cert.isValid() )
if ( !QgsAuthCertUtils::certIsViable( cert ) )
{
item->setForeground( 2, redb );
item->setIcon( 0, QgsApplication::getThemeIcon( QStringLiteral( "/mIconCertificateUntrusted.svg" ) ) );
Expand Down
2 changes: 1 addition & 1 deletion src/gui/auth/qgsauthimportcertdialog.cpp
Expand Up @@ -170,7 +170,7 @@ void QgsAuthImportCertDialog::validateCertificates()

Q_FOREACH ( const QSslCertificate &cert, certs )
{
if ( cert.isValid() )
if ( QgsAuthCertUtils::certIsViable( cert ) )
++validcerts;

if ( filterCAs )
Expand Down
5 changes: 3 additions & 2 deletions src/gui/auth/qgsauthimportidentitydialog.cpp
Expand Up @@ -277,12 +277,13 @@ bool QgsAuthImportIdentityDialog::validatePkiPaths()
ca_certs = certs;
}

isvalid = clientcert.isValid();
isvalid = QgsAuthCertUtils::certIsViable( clientcert );

QDateTime startdate( clientcert.effectiveDate() );
QDateTime enddate( clientcert.expiryDate() );

writeValidation( tr( "%1 thru %2" ).arg( startdate.toString(), enddate.toString() ),
( isvalid ? Valid : Invalid ) );
( QgsAuthCertUtils::certIsCurrent( clientcert ) ? Valid : Invalid ) );
//TODO: set enabled on cert info button, relative to cert validity

// check for valid private key and that any supplied password works
Expand Down
3 changes: 2 additions & 1 deletion src/gui/auth/qgsauthserverseditor.cpp
Expand Up @@ -24,6 +24,7 @@
#include "qgssettings.h"
#include "qgsapplication.h"
#include "qgsauthcertificateinfo.h"
#include "qgsauthcertutils.h"
#include "qgsauthmanager.h"
#include "qgsauthguiutils.h"
#include "qgslogger.h"
Expand Down Expand Up @@ -206,7 +207,7 @@ void QgsAuthServersEditor::appendSslConfigsToItem( const QList<QgsAuthConfigSslS
QTreeWidgetItem *item( new QTreeWidgetItem( parent, coltxts, ( int )conftype ) );

item->setIcon( 0, QgsApplication::getThemeIcon( QStringLiteral( "/mIconCertificate.svg" ) ) );
if ( !cert.isValid() )
if ( !QgsAuthCertUtils::certIsViable( cert ) )
{
item->setForeground( 2, redb );
item->setIcon( 0, QgsApplication::getThemeIcon( QStringLiteral( "/mIconCertificateUntrusted.svg" ) ) );
Expand Down
3 changes: 2 additions & 1 deletion src/gui/auth/qgsauthtrustedcasdialog.cpp
Expand Up @@ -22,6 +22,7 @@
#include "qgssettings.h"
#include "qgsapplication.h"
#include "qgsauthcertificateinfo.h"
#include "qgsauthcertutils.h"
#include "qgsauthguiutils.h"
#include "qgsauthmanager.h"
#include "qgslogger.h"
Expand Down Expand Up @@ -196,7 +197,7 @@ void QgsAuthTrustedCAsDialog::appendCertsToItem( const QList<QSslCertificate> &c
QTreeWidgetItem *item( new QTreeWidgetItem( parent, coltxts, ( int )catype ) );

item->setIcon( 0, QgsApplication::getThemeIcon( QStringLiteral( "/mIconCertificate.svg" ) ) );
if ( !cert.isValid() )
if ( !QgsAuthCertUtils::certIsViable( cert ) )
{
item->setForeground( 2, redb );
item->setIcon( 0, QgsApplication::getThemeIcon( QStringLiteral( "/mIconCertificateUntrusted.svg" ) ) );
Expand Down
31 changes: 31 additions & 0 deletions tests/src/core/testqgsauthcertutils.cpp
Expand Up @@ -39,6 +39,7 @@ class TestQgsAuthCertUtils: public QObject
void init() {}
void cleanup() {}

void testValidationUtils();
void testPkcsUtils();

private:
Expand All @@ -60,6 +61,36 @@ void TestQgsAuthCertUtils::cleanupTestCase()
QgsApplication::exitQgis();
}

void TestQgsAuthCertUtils::testValidationUtils()
{
// null cert
QSslCertificate cert;
QVERIFY( !QgsAuthCertUtils::certIsCurrent( cert ) );
QList<QSslError> res = QgsAuthCertUtils::certViabilityErrors( cert );
QVERIFY( res.count() == 0 );
QVERIFY( !QgsAuthCertUtils::certIsViable( cert ) );

cert.clear();
res.clear();
// valid cert
cert = QgsAuthCertUtils::certFromFile( sPkiData + "/gerardus_cert.pem" );
QVERIFY( QgsAuthCertUtils::certIsCurrent( cert ) );
res = QgsAuthCertUtils::certViabilityErrors( cert );
QVERIFY( res.count() == 0 );
QVERIFY( QgsAuthCertUtils::certIsViable( cert ) );


cert.clear();
res.clear();
// expired cert
cert = QgsAuthCertUtils::certFromFile( sPkiData + "/marinus_cert-EXPIRED.pem" );
QVERIFY( !QgsAuthCertUtils::certIsCurrent( cert ) );
res = QgsAuthCertUtils::certViabilityErrors( cert );
QVERIFY( res.count() > 0 );
QVERIFY( res.contains( QSslError( QSslError::SslError::CertificateExpired, cert ) ) );
QVERIFY( !QgsAuthCertUtils::certIsViable( cert ) );
}

void TestQgsAuthCertUtils::testPkcsUtils()
{
QByteArray pkcs;
Expand Down

0 comments on commit 071099c

Please sign in to comment.