From 315969725da24c336b5dd5c5463c605ee679781d Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Fri, 25 Jan 2019 15:11:34 +0100 Subject: QSslSocket - make ocsp response into ... ocsp responseS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If later we try to introduce multiple ocsp support, the API returning a single response will be somewhat broken and illogical/not clear how to use at all. Let's return a vector of responses (for now it's one, can change in future). This makes isNull() redundant on a response, also, we now need 'subject' - a cert that response was for. Change-Id: Ibbd9dec163b53906b2fd61fa31c43db7d08adc4d Reviewed-by: MÃ¥rten Nordheim --- src/network/ssl/qocspresponse.cpp | 53 +++++++++++----------------------- src/network/ssl/qocspresponse.h | 4 +-- src/network/ssl/qocspresponse_p.h | 2 +- src/network/ssl/qsslsocket.cpp | 14 ++++----- src/network/ssl/qsslsocket.h | 3 +- src/network/ssl/qsslsocket_openssl.cpp | 10 +++---- src/network/ssl/qsslsocket_p.h | 4 +-- 7 files changed, 35 insertions(+), 55 deletions(-) (limited to 'src/network') diff --git a/src/network/ssl/qocspresponse.cpp b/src/network/ssl/qocspresponse.cpp index acc24047e7..1466364af2 100644 --- a/src/network/ssl/qocspresponse.cpp +++ b/src/network/ssl/qocspresponse.cpp @@ -53,11 +53,10 @@ QT_BEGIN_NAMESPACE The QOcspResponse class represents the revocation status of a server's certficate, received by the client-side socket during the TLS handshake. QSslSocket must be - configured with OCSP stapling enabled. A non-empty response corresponds to the - certificate that can be obtained from QSslConfiguration::peerCertificate(). + configured with OCSP stapling enabled. - \sa QSslSocket, QSslSocket::ocspResponse(), isNull(), clear(), certificateStatus(), - revocationReason(), responder(), OcspCertificateStatus, OcspRevocationReason, + \sa QSslSocket, QSslSocket::ocspResponse(), certificateStatus(), + revocationReason(), responder(), subject(), OcspCertificateStatus, OcspRevocationReason, QSslConfiguration::setOcspStaplingEnabled(), QSslConfiguration::ocspStaplingEnabled(), QSslConfiguration::peerCertificate() */ @@ -110,9 +109,10 @@ QT_BEGIN_NAMESPACE /*! \since 5.13 - Creates a new, null OCSP response. + Creates a new response with status OcspCertificateStatus::Unknown + and revocation reason OcspRevocationReason::None. - \sa isNull() + \sa OcspCertificateStatus */ QOcspResponse::QOcspResponse() : d(new QOcspResponsePrivate) @@ -132,7 +132,7 @@ QOcspResponse::QOcspResponse(const QOcspResponse &other) /*! \since 5.13 - Move-constructs a QOcspResponse instance. + Move-constructs a QOcspResponse instance from \a other. */ QOcspResponse::QOcspResponse(QOcspResponse &&other) Q_DECL_NOTHROW { @@ -174,35 +174,6 @@ QOcspResponse &QOcspResponse::operator=(QOcspResponse &&other) Q_DECL_NOTHROW return *this; } -/*! - \since 5.13 - - Returns \c true for default-constructed OCSP responses and also if during a - handshake no definitive OCSP response, or no response was received at all. - - \sa QOcspResponse(), QSslSocket::ocspResponse() -*/ -bool QOcspResponse::isNull() const -{ - return d->isNull; -} - -/*! - \since 5.13 - - Resets this QOcspResponse to its default, null state. - - \sa QOcspResponse(), isNull() -*/ -void QOcspResponse::clear() -{ - - d->certificateStatus = OcspCertificateStatus::Unknown; - d->revocationReason = OcspRevocationReason::None; - d->isNull = true; - d->signerCert.clear(); -} - /*! \since 5.13 @@ -235,4 +206,14 @@ QSslCertificate QOcspResponse::responder() const return d->signerCert; } +/*! + \since 5.13 + + This function returns a certificate, for which this response was issued. +*/ +QSslCertificate QOcspResponse::subject() const +{ + return d->subjectCert; +} + QT_END_NAMESPACE diff --git a/src/network/ssl/qocspresponse.h b/src/network/ssl/qocspresponse.h index 163acd535f..5cff625b84 100644 --- a/src/network/ssl/qocspresponse.h +++ b/src/network/ssl/qocspresponse.h @@ -84,13 +84,11 @@ public: QOcspResponse &operator = (const QOcspResponse &other); QOcspResponse &operator = (QOcspResponse &&other) Q_DECL_NOTHROW; - bool isNull() const; - void clear(); - OcspCertificateStatus certificateStatus() const; OcspRevocationReason revocationReason() const; class QSslCertificate responder() const; + QSslCertificate subject() const; private: diff --git a/src/network/ssl/qocspresponse_p.h b/src/network/ssl/qocspresponse_p.h index 652b2bfca7..44480df633 100644 --- a/src/network/ssl/qocspresponse_p.h +++ b/src/network/ssl/qocspresponse_p.h @@ -63,9 +63,9 @@ public: OcspCertificateStatus certificateStatus = OcspCertificateStatus::Unknown; OcspRevocationReason revocationReason = OcspRevocationReason::None; - bool isNull = true; QSslCertificate signerCert; + QSslCertificate subjectCert; }; QT_END_NAMESPACE diff --git a/src/network/ssl/qsslsocket.cpp b/src/network/ssl/qsslsocket.cpp index 68de9dedaa..88398488a5 100644 --- a/src/network/ssl/qsslsocket.cpp +++ b/src/network/ssl/qsslsocket.cpp @@ -1155,16 +1155,16 @@ QSsl::SslProtocol QSslSocket::sessionProtocol() const /*! \since 5.13 - This function returns Online Certificate Status Protocol response that - a server may send during a TLS handshake using OCSP stapling. If no - definitive or no response was received at all, the response is empty. + This function returns Online Certificate Status Protocol responses that + a server may send during a TLS handshake using OCSP stapling. The vector + is empty if no definitive response or no response at all was received. - \sa QSslConfiguration::setOcspStaplingEnabled(), QOcspResponse::isNull() + \sa QSslConfiguration::setOcspStaplingEnabled() */ -QOcspResponse QSslSocket::ocspResponse() const +QVector QSslSocket::ocspResponses() const { Q_D(const QSslSocket); - return d->ocspResponse; + return d->ocspResponses; } /*! @@ -2150,7 +2150,7 @@ void QSslSocketPrivate::init() shutdown = false; pendingClose = false; flushTriggered = false; - ocspResponse.clear(); + ocspResponses.clear(); // we don't want to clear the ignoreErrorsList, so // that it is possible setting it before connecting diff --git a/src/network/ssl/qsslsocket.h b/src/network/ssl/qsslsocket.h index 8dfb9f2018..4a695a6b01 100644 --- a/src/network/ssl/qsslsocket.h +++ b/src/network/ssl/qsslsocket.h @@ -61,6 +61,7 @@ class QSslConfiguration; class QSslEllipticCurve; class QSslPreSharedKeyAuthenticator; class QOcspResponse; +template class QVector; class QSslSocketPrivate; class Q_NETWORK_EXPORT QSslSocket : public QTcpSocket @@ -143,7 +144,7 @@ public: QList peerCertificateChain() const; QSslCipher sessionCipher() const; QSsl::SslProtocol sessionProtocol() const; - QOcspResponse ocspResponse() const; + QVector ocspResponses() const; // Private keys, for server sockets. void setPrivateKey(const QSslKey &key); diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp index a7c681920e..15b2b4c2cf 100644 --- a/src/network/ssl/qsslsocket_openssl.cpp +++ b/src/network/ssl/qsslsocket_openssl.cpp @@ -1458,9 +1458,7 @@ bool QSslSocketBackendPrivate::checkOcspStatus() Q_ASSERT(mode == QSslSocket::SslClientMode); // See initSslContext() for SslServerMode Q_ASSERT(configuration.peerVerifyMode != QSslSocket::VerifyNone); - ocspResponse.clear(); - QOcspResponsePrivate *dResponse = ocspResponse.d.data(); - + ocspResponses.clear(); ocspErrorDescription.clear(); ocspErrors.clear(); @@ -1556,7 +1554,9 @@ bool QSslSocketBackendPrivate::checkOcspStatus() // Let's make sure the response is for the correct certificate - we // can re-create this CertID using our peer's certificate and its // issuer's public key. - dResponse->isNull = false; + ocspResponses.push_back(QOcspResponse()); + QOcspResponsePrivate *dResponse = ocspResponses.back().d.data(); + dResponse->subjectCert = configuration.peerCertificate; bool matchFound = false; if (configuration.peerCertificate.isSelfSigned()) { dResponse->signerCert = configuration.peerCertificate; @@ -1599,7 +1599,7 @@ bool QSslSocketBackendPrivate::checkOcspStatus() // This is unexpected, treat as SslHandshakeError, OCSP_check_validity assumes this pointer // to be != nullptr. ocspErrors.clear(); - ocspResponse.clear(); + ocspResponses.clear(); ocspErrorDescription = QSslSocket::tr("Failed to extract 'this update time' from the SingleResponse"); return false; } diff --git a/src/network/ssl/qsslsocket_p.h b/src/network/ssl/qsslsocket_p.h index 31eee478ee..daa9be23f4 100644 --- a/src/network/ssl/qsslsocket_p.h +++ b/src/network/ssl/qsslsocket_p.h @@ -66,7 +66,7 @@ class QSslContext; #endif #include - +#include #include #if defined(Q_OS_MAC) @@ -208,7 +208,7 @@ protected: bool verifyErrorsHaveBeenIgnored(); bool paused; bool flushTriggered; - QOcspResponse ocspResponse; + QVector ocspResponses; }; #if QT_CONFIG(securetransport) || QT_CONFIG(schannel) -- cgit v1.2.3