summaryrefslogtreecommitdiffstats
path: root/src/network/ssl/qsslsocket_openssl.cpp
diff options
context:
space:
mode:
authorTimur Pocheptsov <timur.pocheptsov@qt.io>2018-11-13 15:25:25 +0100
committerTimur Pocheptsov <timur.pocheptsov@qt.io>2018-12-06 05:14:45 +0000
commit6a28f6767754f427eb29a266f38252bdf23123c6 (patch)
treecc45c99369385859defed024192ceea41a0a02c4 /src/network/ssl/qsslsocket_openssl.cpp
parenta8dae3ad0bc6377c695326e48d3c0db9f73107db (diff)
Add tst_QOcsp auto-test
This patch introduces a private 'API' to enable server-side OCSP responses and implements a simple OCSP responder, tests OCSP status on a client side (the test is pretty basic, but for now should suffice). Change-Id: I4c6cacd4a1b949dd0ef5e6b59322fb0967d02120 Reviewed-by: MÃ¥rten Nordheim <marten.nordheim@qt.io>
Diffstat (limited to 'src/network/ssl/qsslsocket_openssl.cpp')
-rw-r--r--src/network/ssl/qsslsocket_openssl.cpp52
1 files changed, 52 insertions, 0 deletions
diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp
index 56764ebc7f..f6ee067c15 100644
--- a/src/network/ssl/qsslsocket_openssl.cpp
+++ b/src/network/ssl/qsslsocket_openssl.cpp
@@ -87,6 +87,8 @@
#include <openssl/ocsp.h>
#endif
+#include <algorithm>
+
#include <string.h>
QT_BEGIN_NAMESPACE
@@ -135,6 +137,37 @@ static unsigned int q_ssl_psk_server_callback(SSL *ssl,
return d->tlsPskServerCallback(identity, psk, max_psk_len);
}
#endif
+
+#if QT_CONFIG(ocsp)
+
+int qt_OCSP_status_server_callback(SSL *ssl, void *ocspRequest)
+{
+ Q_UNUSED(ocspRequest)
+ if (!ssl)
+ return SSL_TLSEXT_ERR_ALERT_FATAL;
+
+ auto d = static_cast<QSslSocketBackendPrivate *>(q_SSL_get_ex_data(ssl, QSslSocketBackendPrivate::s_indexForSSLExtraData));
+ if (!d)
+ return SSL_TLSEXT_ERR_ALERT_FATAL;
+
+ Q_ASSERT(d->mode == QSslSocket::SslServerMode);
+ const QByteArray &response = d->ocspResponseDer;
+ Q_ASSERT(response.size());
+
+ unsigned char *derCopy = static_cast<unsigned char *>(q_OPENSSL_malloc(size_t(response.size())));
+ if (!derCopy)
+ return SSL_TLSEXT_ERR_ALERT_FATAL;
+
+ std::copy(response.data(), response.data() + response.size(), derCopy);
+ // We don't check the return value: internally OpenSSL simply assignes the
+ // pointer (it assumes it now owns this memory btw!) and the length.
+ q_SSL_set_tlsext_status_ocsp_resp(ssl, derCopy, response.size());
+
+ return SSL_TLSEXT_ERR_OK;
+}
+
+#endif // ocsp
+
} // extern "C"
QSslSocketBackendPrivate::QSslSocketBackendPrivate()
@@ -507,6 +540,25 @@ bool QSslSocketBackendPrivate::initSslContext()
return false;
}
}
+
+ ocspResponseDer.clear();
+ auto responsePos = configuration.backendConfig.find("Qt-OCSP-response");
+ if (responsePos != configuration.backendConfig.end()) {
+ // This is our private, undocumented 'API' we use for the auto-testing of
+ // OCSP-stapling. It must be a der-encoded OCSP response, presumably set
+ // by tst_QOcsp.
+ const QVariant data(responsePos.value());
+ if (data.canConvert<QByteArray>())
+ ocspResponseDer = data.toByteArray();
+ }
+
+ if (ocspResponseDer.size()) {
+ if (mode != QSslSocket::SslServerMode) {
+ setErrorAndEmit(QAbstractSocket::SslInvalidUserDataError,
+ QSslSocket::tr("Client-side sockets do not send OCSP responses"));
+ return false;
+ }
+ }
#endif // ocsp
return true;