aboutsummaryrefslogtreecommitdiff
path: root/src/geminiclient.cpp
diff options
context:
space:
mode:
authorFelix (xq) Queißner <git@mq32.de>2020-06-16 00:41:57 +0200
committerFelix (xq) Queißner <git@mq32.de>2020-06-16 00:41:57 +0200
commit33c91102a58e2fbcf9d7a66e33b41a65fa3f0e0c (patch)
treea724f0c3dcc48c8ce1f78c2665fe8ef170acb379 /src/geminiclient.cpp
parent5bb3f3f92e62a0af02fe475943759b8c25cd4592 (diff)
downloadkristall-33c91102a58e2fbcf9d7a66e33b41a65fa3f0e0c.tar.gz
Adds improved client certificate management, adds server certificate management.
Diffstat (limited to 'src/geminiclient.cpp')
-rw-r--r--src/geminiclient.cpp65
1 files changed, 56 insertions, 9 deletions
diff --git a/src/geminiclient.cpp b/src/geminiclient.cpp
index e3036ce..bf29ed5 100644
--- a/src/geminiclient.cpp
+++ b/src/geminiclient.cpp
@@ -2,6 +2,7 @@
#include <cassert>
#include <QDebug>
#include <QSslConfiguration>
+#include "kristall.hpp"
GeminiClient::GeminiClient(QObject *parent) : QObject(parent)
{
@@ -11,13 +12,10 @@ GeminiClient::GeminiClient(QObject *parent) : QObject(parent)
connect(&socket, QOverload<const QList<QSslError> &>::of(&QSslSocket::sslErrors), this, &GeminiClient::sslErrors);
connect(&socket, QOverload<QAbstractSocket::SocketError>::of(&QSslSocket::error), this, &GeminiClient::socketError);
-
QSslConfiguration ssl_config;
ssl_config.setProtocol(QSsl::TlsV1_2);
- // ssl_config.setLocalCertificate(QSslCertificate::1
-
+ ssl_config.setCaCertificates(QList<QSslCertificate> { });
socket.setSslConfiguration(ssl_config);
-
}
GeminiClient::~GeminiClient()
@@ -76,6 +74,8 @@ void GeminiClient::disableClientCertificate()
void GeminiClient::socketEncrypted()
{
+ qDebug() << "Pub key =" << socket.peerCertificate().publicKey().toPem();
+
QString request = target_url.toString(QUrl::FormattingOptions(QUrl::FullyEncoded)) + "\r\n";
QByteArray request_bytes = request.toUtf8();
@@ -255,13 +255,59 @@ void GeminiClient::socketDisconnected()
}
}
-void GeminiClient::sslErrors(const QList<QSslError> &errors)
+static bool isTrustRelated(QSslError::SslError err)
+{
+ switch(err)
+ {
+ case QSslError::CertificateUntrusted: return true;
+ case QSslError::SelfSignedCertificate: return true;
+ case QSslError::UnableToGetLocalIssuerCertificate: return true;
+ default: return false;
+ }
+}
+
+void GeminiClient::sslErrors(QList<QSslError> const & errors)
{
- for(auto const & error : errors) {
- qWarning() << error.errorString() ;
+ QList<QSslError> remaining_errors = errors;
+ QList<QSslError> ignored_errors;
+
+ int i = 0;
+ while(i < remaining_errors.size())
+ {
+ auto const & err = remaining_errors.at(i);
+
+ bool ignore = false;
+ if(isTrustRelated(err.error()))
+ {
+ if(global_trust.isTrusted(target_url, socket.peerCertificate()))
+ {
+ ignore = true;
+ }
+ }
+ else if(err.error() == QSslError::UnableToVerifyFirstCertificate)
+ {
+ ignore = true;
+ }
+
+ if(ignore) {
+ ignored_errors.append(err);
+ remaining_errors.removeAt(0);
+ } else {
+ i += 1;
+ }
+ }
+
+ socket.ignoreSslErrors(ignored_errors);
+
+ qDebug() << "ignoring" << ignored_errors.size() << "out of" << errors.size();
+
+ for(auto const & error : remaining_errors) {
+ qWarning() << int(error.error()) << error.errorString();
}
- socket.ignoreSslErrors(errors);
+ if(remaining_errors.size() > 0) {
+ emit this->networkError(remaining_errors.first().errorString());
+ }
}
void GeminiClient::socketError(QAbstractSocket::SocketError socketError)
@@ -272,6 +318,7 @@ void GeminiClient::socketError(QAbstractSocket::SocketError socketError)
if(socketError == QAbstractSocket::RemoteHostClosedError) {
socket.close();
} else {
- qWarning() << socketError << socket.errorString();
+ // qWarning() << socketError << socket.errorString();
+ emit this->networkError(socket.errorString());
}
}