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

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