Merge pull request #5631 from boundlessgeo/bd-2437-certs-format-sniffing

[auth] Moved the PEM/DER sniffing to a common private function
This commit is contained in:
Alessandro Pasotti 2017-11-16 09:04:00 +01:00 committed by GitHub
commit dfc0305420
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 21 additions and 59 deletions

View File

@ -63,34 +63,7 @@ bool QgsAuthPkiPathsEdit::validateConfig()
} }
// check for issue date validity, then notify status // check for issue date validity, then notify status
QSslCertificate cert; QSslCertificate cert( QgsAuthCertUtils::certFromFile( certpath ) );
QFile file( certpath );
QFileInfo fileinfo( file );
QString ext( fileinfo.fileName().remove( fileinfo.completeBaseName() ).toLower() );
if ( ext.isEmpty() )
{
writePkiMessage( lePkiPathsMsg, tr( "Certificate file has no extension" ), Invalid );
return validityChange( false );
}
QFile::OpenMode openflags( QIODevice::ReadOnly );
QSsl::EncodingFormat encformat( QSsl::Der );
if ( ext == QLatin1String( ".pem" ) )
{
openflags |= QIODevice::Text;
encformat = QSsl::Pem;
}
if ( file.open( openflags ) )
{
cert = QSslCertificate( file.readAll(), encformat );
file.close();
}
else
{
writePkiMessage( lePkiPathsMsg, tr( "Failed to read certificate file" ), Invalid );
return validityChange( false );
}
if ( cert.isNull() ) if ( cert.isNull() )
{ {
@ -212,7 +185,7 @@ void QgsAuthPkiPathsEdit::chkPkiPathsPassShow_stateChanged( int state )
void QgsAuthPkiPathsEdit::btnPkiPathsCert_clicked() void QgsAuthPkiPathsEdit::btnPkiPathsCert_clicked()
{ {
const QString &fn = QgsAuthGuiUtils::getOpenFileName( this, tr( "Open Client Certificate File" ), const QString &fn = QgsAuthGuiUtils::getOpenFileName( this, tr( "Open Client Certificate File" ),
tr( "PEM (*.pem);;DER (*.der)" ) ); tr( "All files (*.*);;PEM (*.pem);;DER (*.der)" ) );
if ( !fn.isEmpty() ) if ( !fn.isEmpty() )
{ {
lePkiPathsCert->setText( fn ); lePkiPathsCert->setText( fn );
@ -223,7 +196,7 @@ void QgsAuthPkiPathsEdit::btnPkiPathsCert_clicked()
void QgsAuthPkiPathsEdit::btnPkiPathsKey_clicked() void QgsAuthPkiPathsEdit::btnPkiPathsKey_clicked()
{ {
const QString &fn = QgsAuthGuiUtils::getOpenFileName( this, tr( "Open Private Key File" ), const QString &fn = QgsAuthGuiUtils::getOpenFileName( this, tr( "Open Private Key File" ),
tr( "PEM (*.pem);;DER (*.der)" ) ); tr( "All files (*.*);;PEM (*.pem);;DER (*.der)" ) );
if ( !fn.isEmpty() ) if ( !fn.isEmpty() )
{ {
lePkiPathsKey->setText( fn ); lePkiPathsKey->setText( fn );

View File

@ -125,8 +125,8 @@ QByteArray QgsAuthCertUtils::fileData( const QString &path )
QList<QSslCertificate> QgsAuthCertUtils::certsFromFile( const QString &certspath ) QList<QSslCertificate> QgsAuthCertUtils::certsFromFile( const QString &certspath )
{ {
QList<QSslCertificate> certs; QList<QSslCertificate> certs;
bool pem = certspath.endsWith( QLatin1String( ".pem" ), Qt::CaseInsensitive ); const QByteArray payload( QgsAuthCertUtils::fileData( certspath ) );
certs = QSslCertificate::fromData( QgsAuthCertUtils::fileData( certspath ), pem ? QSsl::Pem : QSsl::Der ); certs = QSslCertificate::fromData( payload, sniffEncoding( payload ) );
if ( certs.isEmpty() ) if ( certs.isEmpty() )
{ {
QgsDebugMsg( QString( "Parsed cert(s) EMPTY for path: %1" ).arg( certspath ) ); QgsDebugMsg( QString( "Parsed cert(s) EMPTY for path: %1" ).arg( certspath ) );
@ -193,9 +193,7 @@ QSslKey QgsAuthCertUtils::keyFromFile( const QString &keypath,
QByteArray keydata( QgsAuthCertUtils::fileData( keypath ) ); QByteArray keydata( QgsAuthCertUtils::fileData( keypath ) );
QSslKey clientkey; QSslKey clientkey;
QSsl::EncodingFormat keyEncoding( keydata.contains( QByteArrayLiteral( "-----BEGIN " ) ) ? QSsl::EncodingFormat keyEncoding( sniffEncoding( keydata ) );
QSsl::Pem :
QSsl::Der );
const std::vector<QSsl::KeyAlgorithm> algs const std::vector<QSsl::KeyAlgorithm> algs
{ {
@ -652,6 +650,13 @@ void QgsAuthCertUtils::appendDirSegment_( QStringList &dirname,
} }
} }
QSsl::EncodingFormat QgsAuthCertUtils::sniffEncoding( const QByteArray &payload )
{
return payload.contains( QByteArrayLiteral( "-----BEGIN " ) ) ?
QSsl::Pem :
QSsl::Der;
}
QString QgsAuthCertUtils::getCertDistinguishedName( const QSslCertificate &qcert, QString QgsAuthCertUtils::getCertDistinguishedName( const QSslCertificate &qcert,
const QCA::Certificate &acert, const QCA::Certificate &acert,
bool issuer ) bool issuer )

View File

@ -373,6 +373,8 @@ class CORE_EXPORT QgsAuthCertUtils
private: private:
static void appendDirSegment_( QStringList &dirname, const QString &segment, QString value ); static void appendDirSegment_( QStringList &dirname, const QString &segment, QString value );
static QSsl::EncodingFormat sniffEncoding( const QByteArray &payload );
}; };
#endif // QGSAUTHCERTUTILS_H #endif // QGSAUTHCERTUTILS_H

View File

@ -224,7 +224,7 @@ void QgsAuthImportCertDialog::validateCertificates()
void QgsAuthImportCertDialog::btnImportFile_clicked() void QgsAuthImportCertDialog::btnImportFile_clicked()
{ {
const QString &fn = getOpenFileName( tr( "Open Certificate File" ), tr( "PEM (*.pem);;DER (*.der)" ) ); const QString &fn = getOpenFileName( tr( "Open Certificate File" ), tr( "All files (*.*);;PEM (*.pem);;DER (*.der)" ) );
if ( !fn.isEmpty() ) if ( !fn.isEmpty() )
{ {
leImportFile->setText( fn ); leImportFile->setText( fn );

View File

@ -192,7 +192,7 @@ void QgsAuthImportIdentityDialog::chkPkiPathsPassShow_stateChanged( int state )
void QgsAuthImportIdentityDialog::btnPkiPathsCert_clicked() void QgsAuthImportIdentityDialog::btnPkiPathsCert_clicked()
{ {
const QString &fn = getOpenFileName( tr( "Open Client Certificate File" ), tr( "PEM (*.pem);;DER (*.der)" ) ); const QString &fn = getOpenFileName( tr( "Open Client Certificate File" ), tr( "All files (*.*);;PEM (*.pem);;DER (*.der)" ) );
if ( !fn.isEmpty() ) if ( !fn.isEmpty() )
{ {
lePkiPathsCert->setText( fn ); lePkiPathsCert->setText( fn );
@ -202,7 +202,7 @@ void QgsAuthImportIdentityDialog::btnPkiPathsCert_clicked()
void QgsAuthImportIdentityDialog::btnPkiPathsKey_clicked() void QgsAuthImportIdentityDialog::btnPkiPathsKey_clicked()
{ {
const QString &fn = getOpenFileName( tr( "Open Private Key File" ), tr( "PEM (*.pem);;DER (*.der)" ) ); const QString &fn = getOpenFileName( tr( "Open Private Key File" ), tr( "All files (*.*);;PEM (*.pem);;DER (*.der)" ) );
if ( !fn.isEmpty() ) if ( !fn.isEmpty() )
{ {
lePkiPathsKey->setText( fn ); lePkiPathsKey->setText( fn );
@ -287,26 +287,8 @@ bool QgsAuthImportIdentityDialog::validatePkiPaths()
//TODO: set enabled on cert info button, relative to cert validity //TODO: set enabled on cert info button, relative to cert validity
// check for valid private key and that any supplied password works // check for valid private key and that any supplied password works
bool keypem = keypath.endsWith( QLatin1String( ".pem" ), Qt::CaseInsensitive ); QString keypass( lePkiPathsKeyPass->text() );
QByteArray keydata( QgsAuthCertUtils::fileData( keypath ) ); QSslKey clientkey( QgsAuthCertUtils::keyFromFile( keypath, keypass ) );
QSslKey clientkey;
QString keypass = lePkiPathsKeyPass->text();
clientkey = QSslKey( keydata,
QSsl::Rsa,
keypem ? QSsl::Pem : QSsl::Der,
QSsl::PrivateKey,
!keypass.isEmpty() ? keypass.toUtf8() : QByteArray() );
if ( clientkey.isNull() )
{
// try DSA algorithm, since Qt can't seem to determine it otherwise
clientkey = QSslKey( keydata,
QSsl::Dsa,
keypem ? QSsl::Pem : QSsl::Der,
QSsl::PrivateKey,
!keypass.isEmpty() ? keypass.toUtf8() : QByteArray() );
}
if ( clientkey.isNull() ) if ( clientkey.isNull() )
{ {
writeValidation( tr( "Failed to load client private key from file" ), Invalid, true ); writeValidation( tr( "Failed to load client private key from file" ), Invalid, true );

View File

@ -369,7 +369,7 @@ void QgsAuthSslImportDialog::radioFileImportToggled( bool checked )
void QgsAuthSslImportDialog::btnCertPath_clicked() void QgsAuthSslImportDialog::btnCertPath_clicked()
{ {
const QString &fn = getOpenFileName( tr( "Open Server Certificate File" ), tr( "PEM (*.pem);;DER (*.der)" ) ); const QString &fn = getOpenFileName( tr( "Open Server Certificate File" ), tr( "All files (*.*);;PEM (*.pem);;DER (*.der)" ) );
if ( !fn.isEmpty() ) if ( !fn.isEmpty() )
{ {
leCertPath->setText( fn ); leCertPath->setText( fn );