1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
5
6/*!
7 \class QSslError
8 \brief The QSslError class provides an SSL error.
9 \since 4.3
10
11 \reentrant
12 \ingroup network
13 \ingroup ssl
14 \ingroup shared
15 \inmodule QtNetwork
16
17 QSslError provides a simple API for managing errors during QSslSocket's
18 SSL handshake.
19
20 \sa QSslSocket, QSslCertificate, QSslCipher
21*/
22
23/*!
24 \enum QSslError::SslError
25
26 Describes all recognized errors that can occur during an SSL handshake.
27
28 \value NoError
29 \value UnableToGetIssuerCertificate
30 \value UnableToDecryptCertificateSignature
31 \value UnableToDecodeIssuerPublicKey
32 \value CertificateSignatureFailed
33 \value CertificateNotYetValid
34 \value CertificateExpired
35 \value InvalidNotBeforeField
36 \value InvalidNotAfterField
37 \value SelfSignedCertificate
38 \value SelfSignedCertificateInChain
39 \value UnableToGetLocalIssuerCertificate
40 \value UnableToVerifyFirstCertificate
41 \value CertificateRevoked
42 \value InvalidCaCertificate
43 \value PathLengthExceeded
44 \value InvalidPurpose
45 \value CertificateUntrusted
46 \value CertificateRejected
47 \value SubjectIssuerMismatch
48 \value AuthorityIssuerSerialNumberMismatch
49 \value NoPeerCertificate
50 \value HostNameMismatch
51 \value UnspecifiedError
52 \value NoSslSupport
53 \value CertificateBlacklisted
54 \value CertificateStatusUnknown
55 \value OcspNoResponseFound
56 \value OcspMalformedRequest
57 \value OcspMalformedResponse
58 \value OcspInternalError
59 \value OcspTryLater
60 \value OcspSigRequred
61 \value OcspUnauthorized
62 \value OcspResponseCannotBeTrusted
63 \value OcspResponseCertIdUnknown
64 \value OcspResponseExpired
65 \value OcspStatusUnknown
66
67
68 \sa QSslError::errorString()
69*/
70
71#include "qsslerror.h"
72#include "qsslsocket.h"
73#ifndef QT_NO_DEBUG_STREAM
74#include <QtCore/qdebug.h>
75#endif
76
77QT_BEGIN_NAMESPACE
78
79#ifndef QT_NO_SSL
80QT_IMPL_METATYPE_EXTERN_TAGGED(QList<QSslError>, QList_QSslError)
81#endif
82
83
84#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0)
85// Avoid an ABI break due to the QScopedPointer->std::unique_ptr change
86static_assert(sizeof(QScopedPointer<QSslErrorPrivate>) == sizeof(std::unique_ptr<QSslErrorPrivate>));
87#endif
88
89class QSslErrorPrivate
90{
91public:
92 QSslError::SslError error = QSslError::NoError;
93 QSslCertificate certificate;
94};
95
96// RVCT compiler in debug build does not like about default values in const-
97// So as an workaround we define all constructor overloads here explicitly
98/*!
99 Constructs a QSslError object with no error and default certificate.
100
101*/
102
103QSslError::QSslError()
104 : d(new QSslErrorPrivate)
105{
106}
107
108/*!
109 Constructs a QSslError object. The argument specifies the \a
110 error that occurred.
111
112*/
113QSslError::QSslError(SslError error)
114 : d(new QSslErrorPrivate)
115{
116 d->error = error;
117}
118
119/*!
120 Constructs a QSslError object. The two arguments specify the \a
121 error that occurred, and which \a certificate the error relates to.
122
123 \sa QSslCertificate
124*/
125QSslError::QSslError(SslError error, const QSslCertificate &certificate)
126 : d(new QSslErrorPrivate)
127{
128 d->error = error;
129 d->certificate = certificate;
130}
131
132/*!
133 Constructs an identical copy of \a other.
134*/
135QSslError::QSslError(const QSslError &other)
136 : d(new QSslErrorPrivate)
137{
138 *d.get() = *other.d.get();
139}
140
141/*!
142 Destroys the QSslError object.
143*/
144QSslError::~QSslError()
145{
146}
147
148/*!
149 \since 4.4
150
151 Assigns the contents of \a other to this error.
152*/
153QSslError &QSslError::operator=(const QSslError &other)
154{
155 *d.get() = *other.d.get();
156 return *this;
157}
158
159/*!
160 \fn void QSslError::swap(QSslError &other)
161 \since 5.0
162 \memberswap{error instance}
163*/
164
165/*!
166 \since 4.4
167
168 Returns \c true if this error is equal to \a other; otherwise returns \c false.
169*/
170bool QSslError::operator==(const QSslError &other) const
171{
172 return d->error == other.d->error
173 && d->certificate == other.d->certificate;
174}
175
176/*!
177 \fn bool QSslError::operator!=(const QSslError &other) const
178 \since 4.4
179
180 Returns \c true if this error is not equal to \a other; otherwise returns
181 false.
182*/
183
184/*!
185 Returns the type of the error.
186
187 \sa errorString(), certificate()
188*/
189QSslError::SslError QSslError::error() const
190{
191 return d->error;
192}
193
194/*!
195 Returns a short localized human-readable description of the error.
196
197 \sa error(), certificate()
198*/
199QString QSslError::errorString() const
200{
201 QString errStr;
202 switch (d->error) {
203 case NoError:
204 errStr = QSslSocket::tr(s: "No error");
205 break;
206 case UnableToGetIssuerCertificate:
207 errStr = QSslSocket::tr(s: "The issuer certificate could not be found");
208 break;
209 case UnableToDecryptCertificateSignature:
210 errStr = QSslSocket::tr(s: "The certificate signature could not be decrypted");
211 break;
212 case UnableToDecodeIssuerPublicKey:
213 errStr = QSslSocket::tr(s: "The public key in the certificate could not be read");
214 break;
215 case CertificateSignatureFailed:
216 errStr = QSslSocket::tr(s: "The signature of the certificate is invalid");
217 break;
218 case CertificateNotYetValid:
219 errStr = QSslSocket::tr(s: "The certificate is not yet valid");
220 break;
221 case CertificateExpired:
222 errStr = QSslSocket::tr(s: "The certificate has expired");
223 break;
224 case InvalidNotBeforeField:
225 errStr = QSslSocket::tr(s: "The certificate's notBefore field contains an invalid time");
226 break;
227 case InvalidNotAfterField:
228 errStr = QSslSocket::tr(s: "The certificate's notAfter field contains an invalid time");
229 break;
230 case SelfSignedCertificate:
231 errStr = QSslSocket::tr(s: "The certificate is self-signed, and untrusted");
232 break;
233 case SelfSignedCertificateInChain:
234 errStr = QSslSocket::tr(s: "The root certificate of the certificate chain is self-signed, and untrusted");
235 break;
236 case UnableToGetLocalIssuerCertificate:
237 errStr = QSslSocket::tr(s: "The issuer certificate of a locally looked up certificate could not be found");
238 break;
239 case UnableToVerifyFirstCertificate:
240 errStr = QSslSocket::tr(s: "No certificates could be verified");
241 break;
242 case InvalidCaCertificate:
243 errStr = QSslSocket::tr(s: "One of the CA certificates is invalid");
244 break;
245 case PathLengthExceeded:
246 errStr = QSslSocket::tr(s: "The basicConstraints path length parameter has been exceeded");
247 break;
248 case InvalidPurpose:
249 errStr = QSslSocket::tr(s: "The supplied certificate is unsuitable for this purpose");
250 break;
251 case CertificateUntrusted:
252 errStr = QSslSocket::tr(s: "The root CA certificate is not trusted for this purpose");
253 break;
254 case CertificateRejected:
255 errStr = QSslSocket::tr(s: "The root CA certificate is marked to reject the specified purpose");
256 break;
257 case SubjectIssuerMismatch: // hostname mismatch
258 errStr = QSslSocket::tr(s: "The current candidate issuer certificate was rejected because its"
259 " subject name did not match the issuer name of the current certificate");
260 break;
261 case AuthorityIssuerSerialNumberMismatch:
262 errStr = QSslSocket::tr(s: "The current candidate issuer certificate was rejected because"
263 " its issuer name and serial number was present and did not match the"
264 " authority key identifier of the current certificate");
265 break;
266 case NoPeerCertificate:
267 errStr = QSslSocket::tr(s: "The peer did not present any certificate");
268 break;
269 case HostNameMismatch:
270 errStr = QSslSocket::tr(s: "The host name did not match any of the valid hosts"
271 " for this certificate");
272 break;
273 case NoSslSupport:
274 break;
275 case CertificateBlacklisted:
276 errStr = QSslSocket::tr(s: "The peer certificate is blacklisted");
277 break;
278 case OcspNoResponseFound:
279 errStr = QSslSocket::tr(s: "No OCSP status response found");
280 break;
281 case OcspMalformedRequest:
282 errStr = QSslSocket::tr(s: "The OCSP status request had invalid syntax");
283 break;
284 case OcspMalformedResponse:
285 errStr = QSslSocket::tr(s: "OCSP response contains an unexpected number of SingleResponse structures");
286 break;
287 case OcspInternalError:
288 errStr = QSslSocket::tr(s: "OCSP responder reached an inconsistent internal state");
289 break;
290 case OcspTryLater:
291 errStr = QSslSocket::tr(s: "OCSP responder was unable to return a status for the requested certificate");
292 break;
293 case OcspSigRequred:
294 errStr = QSslSocket::tr(s: "The server requires the client to sign the OCSP request in order to construct a response");
295 break;
296 case OcspUnauthorized:
297 errStr = QSslSocket::tr(s: "The client is not authorized to request OCSP status from this server");
298 break;
299 case OcspResponseCannotBeTrusted:
300 errStr = QSslSocket::tr(s: "OCSP responder's identity cannot be verified");
301 break;
302 case OcspResponseCertIdUnknown:
303 errStr = QSslSocket::tr(s: "The identity of a certificate in an OCSP response cannot be established");
304 break;
305 case OcspResponseExpired:
306 errStr = QSslSocket::tr(s: "The certificate status response has expired");
307 break;
308 case OcspStatusUnknown:
309 errStr = QSslSocket::tr(s: "The certificate's status is unknown");
310 break;
311 default:
312 errStr = QSslSocket::tr(s: "Unknown error");
313 break;
314 }
315
316 return errStr;
317}
318
319/*!
320 Returns the certificate associated with this error, or a null certificate
321 if the error does not relate to any certificate.
322
323 \sa error(), errorString()
324*/
325QSslCertificate QSslError::certificate() const
326{
327 return d->certificate;
328}
329
330/*!
331 \since 5.4
332 \qhashold{QHash}
333*/
334size_t qHash(const QSslError &key, size_t seed) noexcept
335{
336 QtPrivate::QHashCombine hash(seed);
337 seed = hash(seed, key.error());
338 seed = hash(seed, key.certificate());
339 return seed;
340}
341
342#ifndef QT_NO_DEBUG_STREAM
343//class QDebug;
344QDebug operator<<(QDebug debug, const QSslError &error)
345{
346 debug << error.errorString();
347 return debug;
348}
349
350QDebug print(QDebug debug, QSslError::SslError error)
351{
352 debug << QSslError(error).errorString();
353 return debug;
354}
355#endif
356
357QT_END_NAMESPACE
358
359#include "moc_qsslerror.cpp"
360

source code of qtbase/src/network/ssl/qsslerror.cpp