From daf1764a763635c3857ba4738157bc93ff4753ba Mon Sep 17 00:00:00 2001 From: Alexey Rochev Date: Mon, 30 Dec 2024 01:10:42 +0300 Subject: [PATCH 1/4] Fix logging QSslCertificate on Windows --- src/rpc/requestrouter.cpp | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/rpc/requestrouter.cpp b/src/rpc/requestrouter.cpp index e825f726..6a7a96a6 100644 --- a/src/rpc/requestrouter.cpp +++ b/src/rpc/requestrouter.cpp @@ -32,6 +32,21 @@ SPECIALIZE_FORMATTER_FOR_QDEBUG(QNetworkProxy) SPECIALIZE_FORMATTER_FOR_QDEBUG(QSslError) namespace fmt { + template<> + struct formatter : tremotesf::SimpleFormatter { + fmt::format_context::iterator format(const QSslCertificate& certificate, fmt::format_context& ctx) const { + // QSslCertificate::toText is implemented only for OpenSSL backend +#if QT_VERSION_MAJOR >= 6 + using tremotesf::operator""_l1; + static const bool isOpenSSL = (QSslSocket::activeBackend() == "openssl"_l1); + if (!isOpenSSL) { + return tremotesf::impl::QDebugFormatter{}.format(certificate, ctx); + } +#endif + return fmt::formatter{}.format(certificate.toText(), ctx); + } + }; + template<> struct formatter : tremotesf::SimpleFormatter { fmt::format_context::iterator format(QSsl::SslProtocol protocol, fmt::format_context& ctx) const { @@ -165,7 +180,7 @@ namespace tremotesf::impl { i, sslError.error(), sslError.errorString(), - sslError.certificate().toText() + sslError.certificate() )); ++i; } From 684eabf23d8f5f388a04844015ee16d700da0635 Mon Sep 17 00:00:00 2001 From: Alexey Rochev Date: Mon, 30 Dec 2024 01:16:52 +0300 Subject: [PATCH 2/4] Ignore CertificateUntrusted error for self-signed certificates schannel backend seems to use it instead of SelfSignedCertificate. --- src/rpc/requestrouter.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/rpc/requestrouter.cpp b/src/rpc/requestrouter.cpp index 6a7a96a6..54ef2df8 100644 --- a/src/rpc/requestrouter.cpp +++ b/src/rpc/requestrouter.cpp @@ -227,11 +227,12 @@ namespace tremotesf::impl { mSslConfiguration.setPrivateKey(mConfiguration->clientPrivateKey); } mExpectedSslErrors.clear(); - mExpectedSslErrors.reserve(mConfiguration->serverCertificateChain.size() * 3); + mExpectedSslErrors.reserve(mConfiguration->serverCertificateChain.size() * 4); for (const auto& certificate : mConfiguration->serverCertificateChain) { mExpectedSslErrors.push_back(QSslError(QSslError::HostNameMismatch, certificate)); mExpectedSslErrors.push_back(QSslError(QSslError::SelfSignedCertificate, certificate)); mExpectedSslErrors.push_back(QSslError(QSslError::SelfSignedCertificateInChain, certificate)); + mExpectedSslErrors.push_back(QSslError(QSslError::CertificateUntrusted, certificate)); } } From 7b7abc4e7de79a1e7157e83ac5776b45360a6668 Mon Sep 17 00:00:00 2001 From: Alexey Rochev Date: Thu, 2 Jan 2025 04:17:06 +0300 Subject: [PATCH 3/4] Build cpp-httplib with OpenSSL on Windows x86 --- vcpkg.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vcpkg.json b/vcpkg.json index 61285a42..191f5e13 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -47,7 +47,7 @@ "features": [ { "name": "openssl", - "platform": "!windows" + "platform": "!(windows & arm64)" } ] }, From 2c1d8ef0304b775af3c207170ae22d7ed2cb09a1 Mon Sep 17 00:00:00 2001 From: Alexey Rochev Date: Thu, 2 Jan 2025 05:57:44 +0300 Subject: [PATCH 4/4] Handle timeout with TLS 1.3 and client certificate --- src/rpc/requestrouter_test.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/rpc/requestrouter_test.cpp b/src/rpc/requestrouter_test.cpp index 2c75f49f..db9eee1c 100644 --- a/src/rpc/requestrouter_test.cpp +++ b/src/rpc/requestrouter_test.cpp @@ -320,7 +320,12 @@ namespace { } const auto error = waitForError("foo"_l1, QByteArray{}); QCOMPARE(error.has_value(), true); - QCOMPARE(error.value(), RpcError::ConnectionError); + if (error.value() == RpcError::TimedOut) { + // Can happen with TLS 1.3 + warning().log("Connecting to server requiring client certificate timed out"); + } else { + QCOMPARE(error.value(), RpcError::ConnectionError); + } } void checkClientCertificateSuccess() {