mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-14 00:07:35 -04:00
[auth][bugfix] Import pvt keys with unknown file extension
This fixes an unreported bug that prevent imports of private keys with wrong/unknown extension. The old logic relied on the file extension, that is not only weak but plain wrong because the same extension can have different encodings. The new implementation is 100% robust because completely ignores the file extentions and try to load the key with all supported encodings and algorithms before giving up.
This commit is contained in:
parent
940c4ed5c5
commit
d09d7048fa
@ -81,11 +81,10 @@ Map certificate sha1 to certificate as simple cache
|
||||
%End
|
||||
|
||||
|
||||
static QByteArray fileData( const QString &path, bool astext = false );
|
||||
static QByteArray fileData( const QString &path );
|
||||
%Docstring
|
||||
Return data from a local file via a read-only operation
|
||||
\param path Path to file to read
|
||||
\param astext Whether to open the file as text, otherwise as binary
|
||||
:return: All data contained in file or empty contents if file does not exist
|
||||
:rtype: QByteArray
|
||||
%End
|
||||
|
@ -101,7 +101,7 @@ QMap<QString, QList<QgsAuthConfigSslServer> > QgsAuthCertUtils::sslConfigsGroupe
|
||||
return orgconfigs;
|
||||
}
|
||||
|
||||
QByteArray QgsAuthCertUtils::fileData( const QString &path, bool astext )
|
||||
QByteArray QgsAuthCertUtils::fileData( const QString &path )
|
||||
{
|
||||
QByteArray data;
|
||||
QFile file( path );
|
||||
@ -112,8 +112,6 @@ QByteArray QgsAuthCertUtils::fileData( const QString &path, bool astext )
|
||||
}
|
||||
// TODO: add checks for locked file, etc., to ensure it can be read
|
||||
QFile::OpenMode openflags( QIODevice::ReadOnly );
|
||||
if ( astext )
|
||||
openflags |= QIODevice::Text;
|
||||
bool ret = file.open( openflags );
|
||||
if ( ret )
|
||||
{
|
||||
@ -128,7 +126,7 @@ QList<QSslCertificate> QgsAuthCertUtils::certsFromFile( const QString &certspath
|
||||
{
|
||||
QList<QSslCertificate> certs;
|
||||
bool pem = certspath.endsWith( QLatin1String( ".pem" ), Qt::CaseInsensitive );
|
||||
certs = QSslCertificate::fromData( QgsAuthCertUtils::fileData( certspath, pem ), pem ? QSsl::Pem : QSsl::Der );
|
||||
certs = QSslCertificate::fromData( QgsAuthCertUtils::fileData( certspath ), pem ? QSsl::Pem : QSsl::Der );
|
||||
if ( certs.isEmpty() )
|
||||
{
|
||||
QgsDebugMsg( QString( "Parsed cert(s) EMPTY for path: %1" ).arg( certspath ) );
|
||||
@ -191,37 +189,55 @@ QSslKey QgsAuthCertUtils::keyFromFile( const QString &keypath,
|
||||
const QString &keypass,
|
||||
QString *algtype )
|
||||
{
|
||||
bool pem = keypath.endsWith( QLatin1String( ".pem" ), Qt::CaseInsensitive );
|
||||
QByteArray keydata( QgsAuthCertUtils::fileData( keypath, pem ) );
|
||||
// The approach here is to try all possible encodings and algorithms
|
||||
QByteArray keydata( QgsAuthCertUtils::fileData( keypath ) );
|
||||
|
||||
QSslKey clientkey;
|
||||
clientkey = QSslKey( keydata,
|
||||
QSsl::Rsa,
|
||||
pem ? QSsl::Pem : QSsl::Der,
|
||||
QSsl::Pem,
|
||||
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,
|
||||
pem ? QSsl::Pem : QSsl::Der,
|
||||
QSsl::PrivateKey,
|
||||
!keypass.isEmpty() ? keypass.toUtf8() : QByteArray() );
|
||||
if ( clientkey.isNull() )
|
||||
{
|
||||
return QSslKey();
|
||||
}
|
||||
if ( algtype )
|
||||
*algtype = QStringLiteral( "dsa" );
|
||||
}
|
||||
else
|
||||
if ( ! clientkey.isNull() )
|
||||
{
|
||||
if ( algtype )
|
||||
*algtype = QStringLiteral( "rsa" );
|
||||
return clientkey;
|
||||
}
|
||||
|
||||
return clientkey;
|
||||
clientkey = QSslKey( keydata,
|
||||
QSsl::Dsa,
|
||||
QSsl::Pem,
|
||||
QSsl::PrivateKey,
|
||||
!keypass.isEmpty() ? keypass.toUtf8() : QByteArray() );
|
||||
if ( ! clientkey.isNull() )
|
||||
{
|
||||
if ( algtype )
|
||||
*algtype = QStringLiteral( "dsa" );
|
||||
return clientkey;
|
||||
}
|
||||
clientkey = QSslKey( keydata,
|
||||
QSsl::Rsa,
|
||||
QSsl::Der,
|
||||
QSsl::PrivateKey,
|
||||
!keypass.isEmpty() ? keypass.toUtf8() : QByteArray() );
|
||||
if ( ! clientkey.isNull() )
|
||||
{
|
||||
if ( algtype )
|
||||
*algtype = QStringLiteral( "rsa" );
|
||||
return clientkey;
|
||||
}
|
||||
clientkey = QSslKey( keydata,
|
||||
QSsl::Dsa,
|
||||
QSsl::Der,
|
||||
QSsl::PrivateKey,
|
||||
!keypass.isEmpty() ? keypass.toUtf8() : QByteArray() );
|
||||
if ( ! clientkey.isNull() )
|
||||
{
|
||||
if ( algtype )
|
||||
*algtype = QStringLiteral( "dsa" );
|
||||
return clientkey;
|
||||
}
|
||||
return QSslKey();
|
||||
}
|
||||
|
||||
QList<QSslCertificate> QgsAuthCertUtils::certsFromString( const QString &pemtext )
|
||||
|
@ -108,10 +108,9 @@ class CORE_EXPORT QgsAuthCertUtils
|
||||
/**
|
||||
* Return data from a local file via a read-only operation
|
||||
* \param path Path to file to read
|
||||
* \param astext Whether to open the file as text, otherwise as binary
|
||||
* \returns All data contained in file or empty contents if file does not exist
|
||||
*/
|
||||
static QByteArray fileData( const QString &path, bool astext = false );
|
||||
static QByteArray fileData( const QString &path );
|
||||
|
||||
//! Return list of concatenated certs from a PEM or DER formatted file
|
||||
static QList<QSslCertificate> certsFromFile( const QString &certspath );
|
||||
|
@ -183,35 +183,16 @@ const QgsPkiBundle QgsPkiBundle::fromPemPaths( const QString &certPath,
|
||||
if ( !certPath.isEmpty() && !keyPath.isEmpty()
|
||||
&& ( certPath.endsWith( QLatin1String( ".pem" ), Qt::CaseInsensitive )
|
||||
|| certPath.endsWith( QLatin1String( ".der" ), Qt::CaseInsensitive ) )
|
||||
&& ( keyPath.endsWith( QLatin1String( ".pem" ), Qt::CaseInsensitive )
|
||||
|| keyPath.endsWith( QLatin1String( ".der" ), Qt::CaseInsensitive ) )
|
||||
&& QFile::exists( certPath ) && QFile::exists( keyPath )
|
||||
)
|
||||
{
|
||||
// client cert
|
||||
bool pem = certPath.endsWith( QLatin1String( ".pem" ), Qt::CaseInsensitive );
|
||||
QSslCertificate clientcert( QgsAuthCertUtils::fileData( certPath, pem ), pem ? QSsl::Pem : QSsl::Der );
|
||||
QSslCertificate clientcert( QgsAuthCertUtils::fileData( certPath ), pem ? QSsl::Pem : QSsl::Der );
|
||||
pkibundle.setClientCert( clientcert );
|
||||
|
||||
// client key
|
||||
bool pem_key = keyPath.endsWith( QLatin1String( ".pem" ), Qt::CaseInsensitive );
|
||||
QByteArray keydata( QgsAuthCertUtils::fileData( keyPath, pem_key ) );
|
||||
|
||||
QSslKey clientkey;
|
||||
clientkey = QSslKey( keydata,
|
||||
QSsl::Rsa,
|
||||
pem_key ? QSsl::Pem : QSsl::Der,
|
||||
QSsl::PrivateKey,
|
||||
!keyPass.isNull() ? keyPass.toUtf8() : QByteArray() );
|
||||
if ( clientkey.isNull() )
|
||||
{
|
||||
// try DSA algorithm, since Qt can't seem to determine it otherwise
|
||||
clientkey = QSslKey( keydata,
|
||||
QSsl::Dsa,
|
||||
pem_key ? QSsl::Pem : QSsl::Der,
|
||||
QSsl::PrivateKey,
|
||||
!keyPass.isNull() ? keyPass.toUtf8() : QByteArray() );
|
||||
}
|
||||
clientkey = QgsAuthCertUtils::keyFromFile( keyPath, keyPass );
|
||||
pkibundle.setClientKey( clientkey );
|
||||
if ( !caChain.isEmpty() )
|
||||
{
|
||||
|
@ -288,7 +288,7 @@ bool QgsAuthImportIdentityDialog::validatePkiPaths()
|
||||
|
||||
// check for valid private key and that any supplied password works
|
||||
bool keypem = keypath.endsWith( QLatin1String( ".pem" ), Qt::CaseInsensitive );
|
||||
QByteArray keydata( QgsAuthCertUtils::fileData( keypath, keypem ) );
|
||||
QByteArray keydata( QgsAuthCertUtils::fileData( keypath ) );
|
||||
|
||||
QSslKey clientkey;
|
||||
QString keypass = lePkiPathsKeyPass->text();
|
||||
|
Loading…
x
Reference in New Issue
Block a user