summaryrefslogtreecommitdiffstats
path: root/src/network
diff options
context:
space:
mode:
authorTimur Pocheptsov <timur.pocheptsov@qt.io>2019-02-11 16:07:04 +0100
committerTimur Pocheptsov <timur.pocheptsov@qt.io>2019-02-18 16:03:56 +0000
commit28a87f1f213a84781ef6a4ddfdd3ef1362d03743 (patch)
treead091a0180f02d920b50c6a6d1a682d6a320ed82 /src/network
parent94a4f06fb88ec6c7fa5e31dfd28af4e9b3cdbdd8 (diff)
OCSP response - fix API
as proposed in the API review. Change-Id: I607a38d24d533da59fc0d33dac886fa7693ed6c8 Fixes: QTBUG-73739 Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io> Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
Diffstat (limited to 'src/network')
-rw-r--r--src/network/ssl/qocspresponse.cpp109
-rw-r--r--src/network/ssl/qocspresponse.h29
-rw-r--r--src/network/ssl/qocspresponse_p.h17
-rw-r--r--src/network/ssl/qsslsocket.h2
-rw-r--r--src/network/ssl/qsslsocket_openssl.cpp28
5 files changed, 125 insertions, 60 deletions
diff --git a/src/network/ssl/qocspresponse.cpp b/src/network/ssl/qocspresponse.cpp
index 1466364af2..496979913b 100644
--- a/src/network/ssl/qocspresponse.cpp
+++ b/src/network/ssl/qocspresponse.cpp
@@ -40,6 +40,8 @@
#include "qocspresponse_p.h"
#include "qocspresponse.h"
+#include "qhashfunctions.h"
+
QT_BEGIN_NAMESPACE
/*!
@@ -56,13 +58,13 @@ QT_BEGIN_NAMESPACE
configured with OCSP stapling enabled.
\sa QSslSocket, QSslSocket::ocspResponse(), certificateStatus(),
- revocationReason(), responder(), subject(), OcspCertificateStatus, OcspRevocationReason,
+ revocationReason(), responder(), subject(), QOcspCertificateStatus, QOcspRevocationReason,
QSslConfiguration::setOcspStaplingEnabled(), QSslConfiguration::ocspStaplingEnabled(),
QSslConfiguration::peerCertificate()
*/
/*!
- \enum OcspCertificateStatus
+ \enum QOcspCertificateStatus
\brief Describes the Online Certificate Status
\relates QOcspResponse
\since 5.13
@@ -79,11 +81,11 @@ QT_BEGIN_NAMESPACE
\value Unknown This state indicates that the responder doesn't know about
the certificate being requested.
- \sa OcspRevocationReason
+ \sa QOcspRevocationReason
*/
/*!
- \enum OcspRevocationReason
+ \enum QOcspRevocationReason
\brief Describes the reason for revocation
\relates QOcspResponse
\since 5.13
@@ -109,10 +111,10 @@ QT_BEGIN_NAMESPACE
/*!
\since 5.13
- Creates a new response with status OcspCertificateStatus::Unknown
- and revocation reason OcspRevocationReason::None.
+ Creates a new response with status QOcspCertificateStatus::Unknown
+ and revocation reason QOcspRevocationReason::None.
- \sa OcspCertificateStatus
+ \sa QOcspCertificateStatus
*/
QOcspResponse::QOcspResponse()
: d(new QOcspResponsePrivate)
@@ -124,64 +126,51 @@ QOcspResponse::QOcspResponse()
Creates a new response, the copy of \a other.
*/
-QOcspResponse::QOcspResponse(const QOcspResponse &other)
-{
- *d = *other.d;
-}
+QOcspResponse::QOcspResponse(const QOcspResponse &other) = default;
/*!
\since 5.13
Move-constructs a QOcspResponse instance from \a other.
*/
-QOcspResponse::QOcspResponse(QOcspResponse &&other) Q_DECL_NOTHROW
-{
- d.swap(other.d);
-}
+QOcspResponse::QOcspResponse(QOcspResponse &&other) Q_DECL_NOTHROW = default;
/*!
\since 5.13
Destroys the response.
*/
-QOcspResponse::~QOcspResponse()
-{
-}
+QOcspResponse::~QOcspResponse() = default;
/*!
\since 5.13
- Assignes \a other to the response and returns a reference to this response.
+ Assigns \a other to the response and returns a reference to this response.
*/
-QOcspResponse &QOcspResponse::operator=(const QOcspResponse &other)
-{
- if (this != &other)
- *d = *other.d;
-
- return *this;
-}
+QOcspResponse &QOcspResponse::operator=(const QOcspResponse &other) = default;
/*!
\since 5.13
Move-assigns \a other to this QOcspResponse instance.
*/
-QOcspResponse &QOcspResponse::operator=(QOcspResponse &&other) Q_DECL_NOTHROW
-{
- if (this != &other)
- d.swap(other.d);
+QOcspResponse &QOcspResponse::operator=(QOcspResponse &&other) Q_DECL_NOTHROW = default;
- return *this;
-}
+/*!
+ \fn void QOcspResponse::swap(QOcspResponse &other)
+ \since 5.13
+
+ Swaps this response with \a other.
+*/
/*!
\since 5.13
Returns the certificate status.
- \sa OcspCertificateStatus
+ \sa QOcspCertificateStatus
*/
-OcspCertificateStatus QOcspResponse::certificateStatus() const
+QOcspCertificateStatus QOcspResponse::certificateStatus() const
{
return d->certificateStatus;
}
@@ -191,7 +180,7 @@ OcspCertificateStatus QOcspResponse::certificateStatus() const
Returns the reason for revocation.
*/
-OcspRevocationReason QOcspResponse::revocationReason() const
+QOcspRevocationReason QOcspResponse::revocationReason() const
{
return d->revocationReason;
}
@@ -216,4 +205,54 @@ QSslCertificate QOcspResponse::subject() const
return d->subjectCert;
}
+/*!
+ \fn bool operator==(const QOcspResponse &lhs, const QOcspResponse &rhs)
+
+ Returns \c true if \a lhs and \a rhs are the responses for the same
+ certificate, signed by the same responder, have the same
+ revocation reason and the same certificate status.
+
+ \since 5.13
+ \relates QOcspResponse
+ */
+Q_NETWORK_EXPORT bool operator==(const QOcspResponse &lhs, const QOcspResponse &rhs)
+{
+ return lhs.d == rhs.d || *lhs.d == *rhs.d;
+}
+
+/*!
+ \fn bool operator != (const QOcspResponse &lhs, const QOcspResponse &rhs)
+
+ Returns \c true if \a lhs and \a rhs are responses for different certificates,
+ or signed by different responders, or have different revocation reasons, or different
+ certificate statuses.
+
+ \since 5.13
+ \relates QOcspResponse
+*/
+
+/*!
+ \fn uint qHash(const QOcspResponse &response, uint seed)
+
+ Returns the hash value for the \a response, using \a seed to seed the calculation.
+
+ \since 5.13
+ \relates QHash
+*/
+uint qHash(const QOcspResponse &response, uint seed)
+{
+ const QOcspResponsePrivate *d = response.d.data();
+ Q_ASSERT(d);
+
+ QtPrivate::QHashCombine hasher;
+ uint hash = hasher(seed, int(d->certificateStatus));
+ hash = hasher(hash, int(d->revocationReason));
+ if (!d->signerCert.isNull())
+ hash = hasher(hash, d->signerCert);
+ if (!d->subjectCert.isNull())
+ hash = hasher(hash, d->subjectCert);
+
+ return hash;
+}
+
QT_END_NAMESPACE
diff --git a/src/network/ssl/qocspresponse.h b/src/network/ssl/qocspresponse.h
index 5cff625b84..552a088ba5 100644
--- a/src/network/ssl/qocspresponse.h
+++ b/src/network/ssl/qocspresponse.h
@@ -42,8 +42,9 @@
#include <QtNetwork/qtnetworkglobal.h>
+#include <QtCore/qshareddata.h>
+#include <QtCore/qmetatype.h>
#include <QtCore/qobject.h>
-#include <QtCore/qscopedpointer.h>
#ifndef Q_CLANG_QDOC
QT_REQUIRE_CONFIG(ssl);
@@ -51,14 +52,14 @@ QT_REQUIRE_CONFIG(ssl);
QT_BEGIN_NAMESPACE
-enum class OcspCertificateStatus
+enum class QOcspCertificateStatus
{
Good,
Revoked,
Unknown
};
-enum class OcspRevocationReason
+enum class QOcspRevocationReason
{
None = -1,
Unspecified,
@@ -71,8 +72,11 @@ enum class OcspRevocationReason
RemoveFromCRL
};
+class QOcspResponse;
+Q_NETWORK_EXPORT uint qHash(const QOcspResponse &response, uint seed = 0);
+
class QOcspResponsePrivate;
-class QOcspResponse
+class Q_NETWORK_EXPORT QOcspResponse
{
public:
@@ -84,18 +88,29 @@ public:
QOcspResponse &operator = (const QOcspResponse &other);
QOcspResponse &operator = (QOcspResponse &&other) Q_DECL_NOTHROW;
- OcspCertificateStatus certificateStatus() const;
- OcspRevocationReason revocationReason() const;
+ QOcspCertificateStatus certificateStatus() const;
+ QOcspRevocationReason revocationReason() const;
class QSslCertificate responder() const;
QSslCertificate subject() const;
+ void swap(QOcspResponse &other) Q_DECL_NOTHROW { d.swap(other.d); }
+
private:
friend class QSslSocketBackendPrivate;
- QScopedPointer<QOcspResponsePrivate> d;
+ friend Q_NETWORK_EXPORT bool operator==(const QOcspResponse &lhs, const QOcspResponse &rhs);
+ friend Q_NETWORK_EXPORT uint qHash(const QOcspResponse &response, uint seed);
+
+ QSharedDataPointer<QOcspResponsePrivate> d;
};
+inline bool operator!=(const QOcspResponse &lhs, const QOcspResponse &rhs) { return !(lhs == rhs); }
+
+Q_DECLARE_SHARED(QOcspResponse)
+
QT_END_NAMESPACE
+Q_DECLARE_METATYPE(QOcspResponse)
+
#endif // QOCSPRESPONSE_H
diff --git a/src/network/ssl/qocspresponse_p.h b/src/network/ssl/qocspresponse_p.h
index 44480df633..e421b76899 100644
--- a/src/network/ssl/qocspresponse_p.h
+++ b/src/network/ssl/qocspresponse_p.h
@@ -44,6 +44,9 @@
#include <qsslcertificate.h>
#include <qocspresponse.h>
+
+#include <qshareddata.h>
+
//
// W A R N I N G
// -------------
@@ -57,17 +60,25 @@
QT_BEGIN_NAMESPACE
-class QOcspResponsePrivate
+class QOcspResponsePrivate : public QSharedData
{
public:
- OcspCertificateStatus certificateStatus = OcspCertificateStatus::Unknown;
- OcspRevocationReason revocationReason = OcspRevocationReason::None;
+ QOcspCertificateStatus certificateStatus = QOcspCertificateStatus::Unknown;
+ QOcspRevocationReason revocationReason = QOcspRevocationReason::None;
QSslCertificate signerCert;
QSslCertificate subjectCert;
};
+inline bool operator==(const QOcspResponsePrivate &lhs, const QOcspResponsePrivate &rhs)
+{
+ return lhs.certificateStatus == rhs.certificateStatus
+ && lhs.revocationReason == rhs.revocationReason
+ && lhs.signerCert == rhs.signerCert
+ && lhs.subjectCert == rhs.subjectCert;
+}
+
QT_END_NAMESPACE
#endif // QOCSPRESPONSE_P_H
diff --git a/src/network/ssl/qsslsocket.h b/src/network/ssl/qsslsocket.h
index 4a695a6b01..35943c7d7e 100644
--- a/src/network/ssl/qsslsocket.h
+++ b/src/network/ssl/qsslsocket.h
@@ -44,6 +44,7 @@
#include <QtNetwork/qtnetworkglobal.h>
#include <QtCore/qlist.h>
#include <QtCore/qregexp.h>
+#include <QtCore/qvector.h>
#ifndef QT_NO_SSL
# include <QtNetwork/qtcpsocket.h>
# include <QtNetwork/qsslerror.h>
@@ -61,7 +62,6 @@ class QSslConfiguration;
class QSslEllipticCurve;
class QSslPreSharedKeyAuthenticator;
class QOcspResponse;
-template<class> class QVector;
class QSslSocketPrivate;
class Q_NETWORK_EXPORT QSslSocket : public QTcpSocket
diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp
index 9f5a11294d..c48cd42360 100644
--- a/src/network/ssl/qsslsocket_openssl.cpp
+++ b/src/network/ssl/qsslsocket_openssl.cpp
@@ -258,29 +258,29 @@ QSslError qt_OCSP_response_status_to_QSslError(long code)
Q_UNREACHABLE();
}
-OcspRevocationReason qt_OCSP_revocation_reason(int reason)
+QOcspRevocationReason qt_OCSP_revocation_reason(int reason)
{
switch (reason) {
case OCSP_REVOKED_STATUS_NOSTATUS:
- return OcspRevocationReason::None;
+ return QOcspRevocationReason::None;
case OCSP_REVOKED_STATUS_UNSPECIFIED:
- return OcspRevocationReason::Unspecified;
+ return QOcspRevocationReason::Unspecified;
case OCSP_REVOKED_STATUS_KEYCOMPROMISE:
- return OcspRevocationReason::KeyCompromise;
+ return QOcspRevocationReason::KeyCompromise;
case OCSP_REVOKED_STATUS_CACOMPROMISE:
- return OcspRevocationReason::CACompromise;
+ return QOcspRevocationReason::CACompromise;
case OCSP_REVOKED_STATUS_AFFILIATIONCHANGED:
- return OcspRevocationReason::AffiliationChanged;
+ return QOcspRevocationReason::AffiliationChanged;
case OCSP_REVOKED_STATUS_SUPERSEDED:
- return OcspRevocationReason::Superseded;
+ return QOcspRevocationReason::Superseded;
case OCSP_REVOKED_STATUS_CESSATIONOFOPERATION:
- return OcspRevocationReason::CessationOfOperation;
+ return QOcspRevocationReason::CessationOfOperation;
case OCSP_REVOKED_STATUS_CERTIFICATEHOLD:
- return OcspRevocationReason::CertificateHold;
+ return QOcspRevocationReason::CertificateHold;
case OCSP_REVOKED_STATUS_REMOVEFROMCRL:
- return OcspRevocationReason::RemoveFromCRL;
+ return QOcspRevocationReason::RemoveFromCRL;
default:
- return OcspRevocationReason::None;
+ return QOcspRevocationReason::None;
}
Q_UNREACHABLE();
@@ -1624,15 +1624,15 @@ bool QSslSocketBackendPrivate::checkOcspStatus()
switch (certStatus) {
case V_OCSP_CERTSTATUS_GOOD:
// This certificate was not found among the revoked ones.
- dResponse->certificateStatus = OcspCertificateStatus::Good;
+ dResponse->certificateStatus = QOcspCertificateStatus::Good;
break;
case V_OCSP_CERTSTATUS_REVOKED:
- dResponse->certificateStatus = OcspCertificateStatus::Revoked;
+ dResponse->certificateStatus = QOcspCertificateStatus::Revoked;
dResponse->revocationReason = qt_OCSP_revocation_reason(reason);
ocspErrors.push_back({QSslError::CertificateRevoked, configuration.peerCertificate});
break;
case V_OCSP_CERTSTATUS_UNKNOWN:
- dResponse->certificateStatus = OcspCertificateStatus::Unknown;
+ dResponse->certificateStatus = QOcspCertificateStatus::Unknown;
ocspErrors.push_back({QSslError::OcspStatusUnknown, configuration.peerCertificate});
}