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>bb10
parent
94a4f06fb8
commit
28a87f1f21
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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});
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue