diff options
author | Timur Pocheptsov <timur.pocheptsov@qt.io> | 2018-11-13 15:25:25 +0100 |
---|---|---|
committer | Timur Pocheptsov <timur.pocheptsov@qt.io> | 2018-12-06 05:14:45 +0000 |
commit | 6a28f6767754f427eb29a266f38252bdf23123c6 (patch) | |
tree | cc45c99369385859defed024192ceea41a0a02c4 /src/network/ssl/qsslsocket_openssl.cpp | |
parent | a8dae3ad0bc6377c695326e48d3c0db9f73107db (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.cpp | 52 |
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; |