Skip to content

Commit e8e102c

Browse files
authored
Provide more details on pinned certificate files (#1812)
1 parent d924208 commit e8e102c

File tree

2 files changed

+36
-28
lines changed

2 files changed

+36
-28
lines changed

libsrc/leddevice/dev_net/ProviderRestApi.cpp

Lines changed: 35 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
#include <QSslSocket>
1818

1919
//std includes
20-
#include <iostream>
2120
#include <chrono>
2221

2322
// Constants
@@ -231,7 +230,7 @@ httpResponse ProviderRestApi::executeOperation(QNetworkAccessManager::Operation
231230
_networkManager->setTransferTimeout(_requestTimeout.count());
232231
#endif
233232

234-
QDateTime start = QDateTime::currentDateTime();
233+
QDateTime const start = QDateTime::currentDateTime();
235234
QString opCode;
236235
QNetworkReply* reply;
237236

@@ -267,7 +266,7 @@ httpResponse ProviderRestApi::executeOperation(QNetworkAccessManager::Operation
267266

268267
// Go into the loop until the request is finished.
269268
loop.exec();
270-
QDateTime end = QDateTime::currentDateTime();
269+
QDateTime const end = QDateTime::currentDateTime();
271270

272271
httpResponse response = (reply->operation() == operation) ? getResponse(reply) : httpResponse();
273272

@@ -283,18 +282,18 @@ httpResponse ProviderRestApi::getResponse(QNetworkReply* const& reply)
283282
{
284283
httpResponse response;
285284

286-
HttpStatusCode httpStatusCode = static_cast<HttpStatusCode>(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt());
285+
HttpStatusCode const httpStatusCode = static_cast<HttpStatusCode>(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt());
287286
response.setHttpStatusCode(httpStatusCode);
288287
response.setNetworkReplyError(reply->error());
289288
response.setHeaders(reply->rawHeaderPairs());
290289

291290
if (reply->error() == QNetworkReply::NoError)
292291
{
293-
QByteArray replyData = reply->readAll();
292+
QByteArray const replyData = reply->readAll();
294293
if (!replyData.isEmpty())
295294
{
296295
QJsonParseError error;
297-
QJsonDocument jsonDoc = QJsonDocument::fromJson(replyData, &error);
296+
QJsonDocument const jsonDoc = QJsonDocument::fromJson(replyData, &error);
298297

299298
if (error.error != QJsonParseError::NoError)
300299
{
@@ -322,7 +321,7 @@ httpResponse ProviderRestApi::getResponse(QNetworkReply* const& reply)
322321
else
323322
{
324323
if (httpStatusCode > 0) {
325-
QString httpReason = reply->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toString();
324+
QString const httpReason = reply->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toString();
326325
QString advise;
327326
switch ( httpStatusCode ) {
328327
case HttpStatusCode::BadRequest:
@@ -339,7 +338,7 @@ httpResponse ProviderRestApi::getResponse(QNetworkReply* const& reply)
339338
break;
340339
case HttpStatusCode::TooManyRequests:
341340
{
342-
QString retryAfterTime = response.getHeader("Retry-After");
341+
QString const retryAfterTime = response.getHeader("Retry-After");
343342
if (!retryAfterTime.isEmpty())
344343
{
345344
advise = "Retry-After: " + response.getHeader("Retry-After");
@@ -366,7 +365,7 @@ httpResponse ProviderRestApi::getResponse(QNetworkReply* const& reply)
366365

367366
void ProviderRestApi::setHeader(QNetworkRequest::KnownHeaders header, const QVariant& value)
368367
{
369-
QVariant headerValue = _networkRequestHeaders.header(header);
368+
QVariant const headerValue = _networkRequestHeaders.header(header);
370369
if (headerValue.isNull())
371370
{
372371
_networkRequestHeaders.setHeader(header, value);
@@ -394,7 +393,7 @@ void httpResponse::setHeaders(const QList<QNetworkReply::RawHeaderPair>& pairs)
394393
}
395394
}
396395

397-
QByteArray httpResponse::getHeader(const QByteArray header) const
396+
QByteArray httpResponse::getHeader(const QByteArray& header) const
398397
{
399398
return _responseHeaders.value(header);
400399
}
@@ -412,7 +411,7 @@ bool ProviderRestApi::setCaCertificate(const QString& caFileName)
412411
return false;
413412
}
414413

415-
QSslCertificate cert (&caFile);
414+
QSslCertificate const cert (&caFile);
416415
caFile.close();
417416

418417
QList<QSslCertificate> allowedCAs;
@@ -424,8 +423,8 @@ bool ProviderRestApi::setCaCertificate(const QString& caFileName)
424423
#ifndef QT_NO_SSL
425424
if (QSslSocket::supportsSsl())
426425
{
427-
QObject::connect( _networkManager, &QNetworkAccessManager::sslErrors, this, &ProviderRestApi::onSslErrors, Qt::UniqueConnection );
428-
_networkManager->connectToHostEncrypted(_apiUrl.host(), _apiUrl.port(), configuration);
426+
QObject::connect( _networkManager, &QNetworkAccessManager::sslErrors, this, &ProviderRestApi::onSslErrors );
427+
_networkManager->connectToHostEncrypted(_apiUrl.host(), static_cast<quint16>(_apiUrl.port()), configuration);
429428
rc = true;
430429
}
431430
#endif
@@ -453,8 +452,8 @@ bool ProviderRestApi::checkServerIdentity(const QSslConfiguration& sslConfig) co
453452
bool isServerIdentified {false};
454453

455454
// Perform common name validation
456-
QSslCertificate serverCertificate = sslConfig.peerCertificate();
457-
QStringList commonName = serverCertificate.subjectInfo(QSslCertificate::CommonName);
455+
QSslCertificate const serverCertificate = sslConfig.peerCertificate();
456+
QStringList const commonName = serverCertificate.subjectInfo(QSslCertificate::CommonName);
458457
if ( commonName.contains(getAlternateServerIdentity(), Qt::CaseInsensitive) )
459458
{
460459
isServerIdentified = true;
@@ -467,27 +466,36 @@ bool ProviderRestApi::matchesPinnedCertificate(const QSslCertificate& certificat
467466
{
468467
bool isMatching {false};
469468

470-
QList certificateInfos = certificate.subjectInfo(QSslCertificate::CommonName);
469+
QList const certificateInfos = certificate.subjectInfo(QSslCertificate::CommonName);
471470

472471
if (certificateInfos.isEmpty())
473472
{
474473
return false;
475474
}
476-
QString identifier = certificateInfos.constFirst();
475+
QString const& identifier = certificateInfos.constFirst();
476+
QString const appDataDir = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
477+
QString const certDir = appDataDir + "/certificates";
477478

478-
QString appDataDir = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
479-
QString certDir = appDataDir + "/certificates";
480-
QDir().mkpath(certDir);
479+
Debug (_log,"Directory used for pinned certificates: %s", QSTRING_CSTR(certDir));
481480

482-
QString filePath(certDir + "/" + identifier + ".pem");
481+
bool const isMkPath = QDir().mkpath(certDir);
482+
if (!isMkPath)
483+
{
484+
Error (_log,"Failed to create directory \"%s\" to store pinned certificates. 'Trust on first use' is rejected.", QSTRING_CSTR(certDir));
485+
return false;
486+
}
487+
488+
QString const fileName(identifier + ".pem");
489+
QString const filePath(certDir + "/" + fileName);
483490
QFile file(filePath);
491+
484492
if (file.open(QIODevice::ReadOnly))
485493
{
486-
QList certificates = QSslCertificate::fromDevice(&file, QSsl::Pem);
494+
QList const certificates = QSslCertificate::fromDevice(&file, QSsl::Pem);
487495
if (!certificates.isEmpty())
488496
{
489-
Debug (_log,"First used certificate loaded successfully");
490-
QSslCertificate pinnedeCertificate = certificates.constFirst();
497+
Debug (_log,"First used certificate \"%s\" loaded successfully", QSTRING_CSTR(fileName));
498+
QSslCertificate const& pinnedeCertificate = certificates.constFirst();
491499
if (pinnedeCertificate == certificate)
492500
{
493501
isMatching = true;
@@ -503,8 +511,8 @@ bool ProviderRestApi::matchesPinnedCertificate(const QSslCertificate& certificat
503511
{
504512
if (file.open(QIODevice::WriteOnly))
505513
{
506-
QByteArray pemData = certificate.toPem();
507-
qint64 bytesWritten = file.write(pemData);
514+
QByteArray const pemData = certificate.toPem();
515+
qint64 const bytesWritten = file.write(pemData);
508516
if (bytesWritten == pemData.size())
509517
{
510518
Debug (_log,"First used certificate saved to file: %s", QSTRING_CSTR(filePath));
@@ -538,7 +546,7 @@ void ProviderRestApi::onSslErrors(QNetworkReply* reply, const QList<QSslError>&
538546
if (_isSeflSignedCertificateAccpeted)
539547
{
540548
// Get the peer certificate associated with the error
541-
QSslCertificate certificate = error.certificate();
549+
QSslCertificate const certificate = error.certificate();
542550
if (matchesPinnedCertificate(certificate))
543551
{
544552
Debug (_log,"'Trust on first use' - Certificate received matches pinned certificate");

libsrc/leddevice/dev_net/ProviderRestApi.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ class httpResponse
8989
void setBody(const QJsonDocument& body) { _responseBody = body; }
9090

9191

92-
QByteArray getHeader(const QByteArray header) const;
92+
QByteArray getHeader(const QByteArray& header) const;
9393
void setHeaders(const QList<QNetworkReply::RawHeaderPair>& pairs);
9494

9595
QString getErrorReason() const { return _errorReason; }

0 commit comments

Comments
 (0)