1 /****************************************************************************
2 ** Copyright (C) 2011 Richard J. Moore <rich@kde.org>
3 ** Copyright (C) 2019 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the QtNetwork module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 3 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 3 requirements
23 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24 **
25 ** GNU General Public License Usage
26 ** Alternatively, this file may be used under the terms of the GNU
27 ** General Public License version 2.0 or (at your option) the GNU General
28 ** Public license version 3 or any later version approved by the KDE Free
29 ** Qt Foundation. The licenses are as published by the Free Software
30 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31 ** included in the packaging of this file. Please review the following
32 ** information to ensure the GNU General Public License requirements will
33 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34 ** https://www.gnu.org/licenses/gpl-3.0.html.
35 **
36 ** $QT_END_LICENSE$
37 **
38 ****************************************************************************/
39 
40 #include "qocspresponse_p.h"
41 #include "qocspresponse.h"
42 
43 #include "qhashfunctions.h"
44 
45 QT_BEGIN_NAMESPACE
46 
47 /*!
48     \class QOcspResponse
49     \brief This class represents Online Certificate Status Protocol response.
50     \since 5.13
51 
52     \ingroup network
53     \ingroup ssl
54     \inmodule QtNetwork
55 
56     The QOcspResponse class represents the revocation status of a server's certficate,
57     received by the client-side socket during the TLS handshake. QSslSocket must be
58     configured with OCSP stapling enabled.
59 
60     \sa QSslSocket, QSslSocket::ocspResponses(), certificateStatus(),
61     revocationReason(), responder(), subject(), QOcspCertificateStatus, QOcspRevocationReason,
62     QSslConfiguration::setOcspStaplingEnabled(), QSslConfiguration::ocspStaplingEnabled(),
63     QSslConfiguration::peerCertificate()
64 */
65 
66 /*!
67     \enum QOcspCertificateStatus
68     \brief Describes the Online Certificate Status
69     \relates QOcspResponse
70     \since 5.13
71 
72     \ingroup network
73     \ingroup ssl
74     \inmodule QtNetwork
75 
76     \value Good The certificate is not revoked, but this does not necessarily
77            mean that the certificate was ever issued or that the time at which
78            the response was produced is within the certificate's validity interval.
79     \value Revoked This state indicates that the certificate has been revoked
80            (either permanently or temporarily - on hold).
81     \value Unknown This state indicates that the responder doesn't know about
82            the certificate being requested.
83 
84     \sa QOcspRevocationReason
85 */
86 
87 /*!
88     \enum QOcspRevocationReason
89     \brief Describes the reason for revocation
90     \relates QOcspResponse
91     \since 5.13
92 
93     \ingroup network
94     \ingroup ssl
95     \inmodule QtNetwork
96 
97 
98     This enumeration describes revocation reasons, defined in \l{https://tools.ietf.org/html/rfc5280#section-5.3.1}{RFC 5280, section 5.3.1}
99 
100     \value None
101     \value Unspecified
102     \value KeyCompromise
103     \value CACompromise
104     \value AffiliationChanged
105     \value Superseded
106     \value CessationOfOperation
107     \value CertificateHold
108     \value RemoveFromCRL
109 */
110 
111 /*!
112     \since 5.13
113 
114     Creates a new response with status QOcspCertificateStatus::Unknown
115     and revocation reason QOcspRevocationReason::None.
116 
117     \sa QOcspCertificateStatus
118 */
QOcspResponse()119 QOcspResponse::QOcspResponse()
120     : d(new QOcspResponsePrivate)
121 {
122 }
123 
124 /*!
125     \since 5.13
126 
127     Copy-constructs a QOcspResponse instance.
128 */
129 QOcspResponse::QOcspResponse(const QOcspResponse &) = default;
130 
131 /*!
132     \since 5.13
133 
134     Move-constructs a QOcspResponse instance.
135 */
136 QOcspResponse::QOcspResponse(QOcspResponse &&) noexcept = default;
137 
138 /*!
139     \since 5.13
140 
141     Destroys the response.
142 */
143 QOcspResponse::~QOcspResponse() = default;
144 
145 /*!
146     \since 5.13
147 
148     Copy-assigns \a other and returns a reference to this response.
149 */
150 QOcspResponse &QOcspResponse::operator=(const QOcspResponse &) = default;
151 
152 /*!
153     \since 5.13
154 
155     Move-assigns \a other to this QOcspResponse instance.
156 */
157 QOcspResponse &QOcspResponse::operator=(QOcspResponse &&) noexcept = default;
158 
159 /*!
160     \fn void QOcspResponse::swap(QOcspResponse &other)
161     \since 5.13
162 
163     Swaps this response with \a other.
164 */
165 
166 /*!
167     \since 5.13
168 
169     Returns the certificate status.
170 
171     \sa QOcspCertificateStatus
172 */
certificateStatus() const173 QOcspCertificateStatus QOcspResponse::certificateStatus() const
174 {
175     return d->certificateStatus;
176 }
177 
178 /*!
179     \since 5.13
180 
181     Returns the reason for revocation.
182 */
revocationReason() const183 QOcspRevocationReason QOcspResponse::revocationReason() const
184 {
185     return d->revocationReason;
186 }
187 
188 /*!
189     \since 5.13
190 
191     This function returns a certificate used to sign OCSP response.
192 */
responder() const193 QSslCertificate QOcspResponse::responder() const
194 {
195     return d->signerCert;
196 }
197 
198 /*!
199     \since 5.13
200 
201     This function returns a certificate, for which this response was issued.
202 */
subject() const203 QSslCertificate QOcspResponse::subject() const
204 {
205     return d->subjectCert;
206 }
207 
208 /*!
209     \fn bool operator==(const QOcspResponse &lhs, const QOcspResponse &rhs)
210 
211     Returns \c true if \a lhs and \a rhs are the responses for the same
212     certificate, signed by the same responder, have the same
213     revocation reason and the same certificate status.
214 
215     \since 5.13
216     \relates QOcspResponse
217  */
operator ==(const QOcspResponse & lhs,const QOcspResponse & rhs)218 Q_NETWORK_EXPORT bool operator==(const QOcspResponse &lhs, const QOcspResponse &rhs)
219 {
220     return lhs.d == rhs.d || *lhs.d == *rhs.d;
221 }
222 
223 /*!
224   \fn bool operator != (const QOcspResponse &lhs, const QOcspResponse &rhs)
225 
226   Returns \c true if \a lhs and \a rhs are responses for different certificates,
227   or signed by different responders, or have different revocation reasons, or different
228   certificate statuses.
229 
230   \since 5.13
231   \relates QOcspResponse
232 */
233 
234 /*!
235     \fn uint qHash(const QOcspResponse &response, uint seed)
236 
237     Returns the hash value for the \a response, using \a seed to seed the calculation.
238 
239     \since 5.13
240     \relates QHash
241 */
qHash(const QOcspResponse & response,uint seed)242 uint qHash(const QOcspResponse &response, uint seed) noexcept
243 {
244     const QOcspResponsePrivate *d = response.d.data();
245     Q_ASSERT(d);
246 
247     QtPrivate::QHashCombine hasher;
248     uint hash = hasher(seed, int(d->certificateStatus));
249     hash = hasher(hash, int(d->revocationReason));
250     if (!d->signerCert.isNull())
251         hash = hasher(hash, d->signerCert);
252     if (!d->subjectCert.isNull())
253         hash = hasher(hash, d->subjectCert);
254 
255     return hash;
256 }
257 
258 QT_END_NAMESPACE
259