diff options
author | Timur Pocheptsov <timur.pocheptsov@qt.io> | 2019-02-11 16:07:04 +0100 |
---|---|---|
committer | Timur Pocheptsov <timur.pocheptsov@qt.io> | 2019-02-18 16:03:56 +0000 |
commit | 28a87f1f213a84781ef6a4ddfdd3ef1362d03743 (patch) | |
tree | ad091a0180f02d920b50c6a6d1a682d6a320ed82 /src/network | |
parent | 94a4f06fb88ec6c7fa5e31dfd28af4e9b3cdbdd8 (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.cpp | 109 | ||||
-rw-r--r-- | src/network/ssl/qocspresponse.h | 29 | ||||
-rw-r--r-- | src/network/ssl/qocspresponse_p.h | 17 | ||||
-rw-r--r-- | src/network/ssl/qsslsocket.h | 2 | ||||
-rw-r--r-- | src/network/ssl/qsslsocket_openssl.cpp | 28 |
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}); } |