mirror of
https://github.com/hyperion-project/hyperion.ng.git
synced 2025-03-01 10:33:28 +00:00
Fix self-signed certificate handling
This commit is contained in:
parent
a5625cf984
commit
0a03a29e30
@ -70,6 +70,7 @@ Note: The wizard will configure an APIv2 capable bridge always with Entertainmen
|
|||||||
- Changed default build from Stretch to Buster
|
- Changed default build from Stretch to Buster
|
||||||
- Support Qt 6.7, Update to Protobuf 23.4.0, Update mbedTLS to v3.4.0, Update flatbuffers to v23.5.26
|
- Support Qt 6.7, Update to Protobuf 23.4.0, Update mbedTLS to v3.4.0, Update flatbuffers to v23.5.26
|
||||||
- Use C++17 standard as default
|
- Use C++17 standard as default
|
||||||
|
- Added Pull Request (PR) installation script, allowing users to test development builds savely on Linux
|
||||||
- Fixed missing include limits in QJsonSchemaChecker - Thanks @Portisch
|
- Fixed missing include limits in QJsonSchemaChecker - Thanks @Portisch
|
||||||
- Fixed dependencies for deb packages in Debian Bookworm (#1579) - Thanks @hg42, @Psirus
|
- Fixed dependencies for deb packages in Debian Bookworm (#1579) - Thanks @hg42, @Psirus
|
||||||
- Fixed git version identification when run in docker and local code
|
- Fixed git version identification when run in docker and local code
|
||||||
|
@ -584,11 +584,7 @@ int LedDevicePhilipsHueBridge::close()
|
|||||||
bool LedDevicePhilipsHueBridge::configureSsl()
|
bool LedDevicePhilipsHueBridge::configureSsl()
|
||||||
{
|
{
|
||||||
_restApi->setAlternateServerIdentity(_deviceBridgeId);
|
_restApi->setAlternateServerIdentity(_deviceBridgeId);
|
||||||
|
_restApi->acceptSelfSignedCertificates(true);
|
||||||
if (_isDiyHue)
|
|
||||||
{
|
|
||||||
_restApi->acceptSelfSignedCertificates(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool success = _restApi->setCaCertificate(API_SSL_CA_CERTIFICATE_RESSOURCE);
|
bool success = _restApi->setCaCertificate(API_SSL_CA_CERTIFICATE_RESSOURCE);
|
||||||
if (!success)
|
if (!success)
|
||||||
|
@ -11,6 +11,8 @@
|
|||||||
#include <QList>
|
#include <QList>
|
||||||
#include <QHash>
|
#include <QHash>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
|
#include <QDir>
|
||||||
|
#include <QStandardPaths>
|
||||||
|
|
||||||
#include <QSslSocket>
|
#include <QSslSocket>
|
||||||
|
|
||||||
@ -451,6 +453,63 @@ bool ProviderRestApi::checkServerIdentity(const QSslConfiguration& sslConfig) co
|
|||||||
return isServerIdentified;
|
return isServerIdentified;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ProviderRestApi::matchesPinnedCertificate(const QSslCertificate& certificate)
|
||||||
|
{
|
||||||
|
bool isMatching {false};
|
||||||
|
|
||||||
|
QList certificateInfos = certificate.subjectInfo(QSslCertificate::CommonName);
|
||||||
|
|
||||||
|
if (certificateInfos.isEmpty())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
QString identifier = certificateInfos.constFirst();
|
||||||
|
|
||||||
|
QString appDataDir = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
|
||||||
|
QString certDir = appDataDir + "/certificates";
|
||||||
|
QDir().mkpath(certDir);
|
||||||
|
|
||||||
|
QString filePath(certDir + "/" + identifier + ".pem");
|
||||||
|
QFile file(filePath);
|
||||||
|
if (file.open(QIODevice::ReadOnly))
|
||||||
|
{
|
||||||
|
QList certificates = QSslCertificate::fromDevice(&file, QSsl::Pem);
|
||||||
|
if (!certificates.isEmpty())
|
||||||
|
{
|
||||||
|
Debug (_log,"First used certificate loaded successfully");
|
||||||
|
QSslCertificate pinnedeCertificate = certificates.constFirst();
|
||||||
|
if (pinnedeCertificate == certificate)
|
||||||
|
{
|
||||||
|
isMatching = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug (_log,"Error reading first used certificate file: %s", QSTRING_CSTR(filePath));
|
||||||
|
}
|
||||||
|
file.close();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (file.open(QIODevice::WriteOnly))
|
||||||
|
{
|
||||||
|
QByteArray pemData = certificate.toPem();
|
||||||
|
qint64 bytesWritten = file.write(pemData);
|
||||||
|
if (bytesWritten == pemData.size())
|
||||||
|
{
|
||||||
|
Debug (_log,"First used certificate saved to file: %s", QSTRING_CSTR(filePath));
|
||||||
|
isMatching = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug (_log,"Error writing first used certificate file: %s", QSTRING_CSTR(filePath));
|
||||||
|
}
|
||||||
|
file.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return isMatching;
|
||||||
|
}
|
||||||
|
|
||||||
void ProviderRestApi::onSslErrors(QNetworkReply* reply, const QList<QSslError>& errors)
|
void ProviderRestApi::onSslErrors(QNetworkReply* reply, const QList<QSslError>& errors)
|
||||||
{
|
{
|
||||||
int ignoredErrorCount {0};
|
int ignoredErrorCount {0};
|
||||||
@ -466,11 +525,21 @@ void ProviderRestApi::onSslErrors(QNetworkReply* reply, const QList<QSslError>&
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case QSslError::SelfSignedCertificate :
|
case QSslError::SelfSignedCertificate :
|
||||||
if (_isSeflSignedCertificateAccpeted)
|
if (_isSeflSignedCertificateAccpeted)
|
||||||
|
{
|
||||||
|
// Get the peer certificate associated with the error
|
||||||
|
QSslCertificate certificate = error.certificate();
|
||||||
|
if (matchesPinnedCertificate(certificate))
|
||||||
{
|
{
|
||||||
|
Debug (_log,"'Trust on first use' - Certificate received matches pinned certificate");
|
||||||
ignoreSslError = true;
|
ignoreSslError = true;
|
||||||
}
|
}
|
||||||
break;
|
else
|
||||||
|
{
|
||||||
|
Error (_log,"'Trust on first use' - Certificate received does not match pinned certificate");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -444,6 +444,8 @@ private:
|
|||||||
|
|
||||||
bool checkServerIdentity(const QSslConfiguration& sslConfig) const;
|
bool checkServerIdentity(const QSslConfiguration& sslConfig) const;
|
||||||
|
|
||||||
|
bool matchesPinnedCertificate(const QSslCertificate& certificate);
|
||||||
|
|
||||||
Logger* _log;
|
Logger* _log;
|
||||||
|
|
||||||
/// QNetworkAccessManager object for sending REST-requests.
|
/// QNetworkAccessManager object for sending REST-requests.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user