Coverage Report

Created: 2026-08-17 07:50

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/qtbase/src/network/ssl/qsslerror.cpp
Line
Count
Source
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
77
QT_BEGIN_NAMESPACE
78
79
#ifndef QT_NO_SSL
80
QT_IMPL_METATYPE_EXTERN_TAGGED(QList<QSslError>, QList_QSslError)
81
#endif
82
83
class QSslErrorPrivate
84
{
85
public:
86
    QSslError::SslError error = QSslError::NoError;
87
    QSslCertificate certificate;
88
};
89
90
// RVCT compiler in debug build does not like about default values in const-
91
// So as an workaround we define all constructor overloads here explicitly
92
/*!
93
    Constructs a QSslError object with no error and default certificate.
94
95
*/
96
97
QSslError::QSslError()
98
0
    : d(new QSslErrorPrivate)
99
0
{
100
0
}
101
102
/*!
103
    Constructs a QSslError object. The argument specifies the \a
104
    error that occurred.
105
106
*/
107
QSslError::QSslError(SslError error)
108
0
    : d(new QSslErrorPrivate)
109
0
{
110
0
    d->error = error;
111
0
}
112
113
/*!
114
    Constructs a QSslError object. The two arguments specify the \a
115
    error that occurred, and which \a certificate the error relates to.
116
117
    \sa QSslCertificate
118
*/
119
QSslError::QSslError(SslError error, const QSslCertificate &certificate)
120
0
    : d(new QSslErrorPrivate)
121
0
{
122
0
    d->error = error;
123
0
    d->certificate = certificate;
124
0
}
125
126
/*!
127
    Constructs an identical copy of \a other.
128
*/
129
QSslError::QSslError(const QSslError &other)
130
0
    : d(new QSslErrorPrivate)
131
0
{
132
0
    *d.get() = *other.d.get();
133
0
}
134
135
/*!
136
    Destroys the QSslError object.
137
*/
138
QSslError::~QSslError()
139
0
{
140
0
}
141
142
/*!
143
    \since 4.4
144
145
    Assigns the contents of \a other to this error.
146
*/
147
QSslError &QSslError::operator=(const QSslError &other)
148
0
{
149
0
    *d.get() = *other.d.get();
150
0
    return *this;
151
0
}
152
153
/*!
154
    \fn void QSslError::swap(QSslError &other)
155
    \since 5.0
156
    \memberswap{error instance}
157
*/
158
159
/*!
160
    \since 4.4
161
162
    Returns \c true if this error is equal to \a other; otherwise returns \c false.
163
*/
164
bool QSslError::operator==(const QSslError &other) const
165
0
{
166
0
    return d->error == other.d->error
167
0
        && d->certificate == other.d->certificate;
168
0
}
169
170
/*!
171
    \fn bool QSslError::operator!=(const QSslError &other) const
172
    \since 4.4
173
174
    Returns \c true if this error is not equal to \a other; otherwise returns
175
    false.
176
*/
177
178
/*!
179
    Returns the type of the error.
180
181
    \sa errorString(), certificate()
182
*/
183
QSslError::SslError QSslError::error() const
184
0
{
185
0
    return d->error;
186
0
}
187
188
/*!
189
    Returns a short localized human-readable description of the error.
190
191
    \sa error(), certificate()
192
*/
193
QString QSslError::errorString() const
194
0
{
195
0
    QString errStr;
196
0
    switch (d->error) {
197
0
    case NoError:
198
0
        errStr = QSslSocket::tr("No error");
199
0
        break;
200
0
    case UnableToGetIssuerCertificate:
201
0
        errStr = QSslSocket::tr("The issuer certificate could not be found");
202
0
        break;
203
0
    case UnableToDecryptCertificateSignature:
204
0
        errStr = QSslSocket::tr("The certificate signature could not be decrypted");
205
0
        break;
206
0
    case UnableToDecodeIssuerPublicKey:
207
0
        errStr = QSslSocket::tr("The public key in the certificate could not be read");
208
0
        break;
209
0
    case CertificateSignatureFailed:
210
0
        errStr = QSslSocket::tr("The signature of the certificate is invalid");
211
0
        break;
212
0
    case CertificateNotYetValid:
213
0
        errStr = QSslSocket::tr("The certificate is not yet valid");
214
0
        break;
215
0
    case CertificateExpired:
216
0
        errStr = QSslSocket::tr("The certificate has expired");
217
0
        break;
218
0
    case InvalidNotBeforeField:
219
0
        errStr = QSslSocket::tr("The certificate's notBefore field contains an invalid time");
220
0
        break;
221
0
    case InvalidNotAfterField:
222
0
        errStr = QSslSocket::tr("The certificate's notAfter field contains an invalid time");
223
0
        break;
224
0
    case SelfSignedCertificate:
225
0
        errStr = QSslSocket::tr("The certificate is self-signed, and untrusted");
226
0
        break;
227
0
    case SelfSignedCertificateInChain:
228
0
        errStr = QSslSocket::tr("The root certificate of the certificate chain is self-signed, and untrusted");
229
0
        break;
230
0
    case UnableToGetLocalIssuerCertificate:
231
0
        errStr = QSslSocket::tr("The issuer certificate of a locally looked up certificate could not be found");
232
0
        break;
233
0
    case UnableToVerifyFirstCertificate:
234
0
        errStr = QSslSocket::tr("No certificates could be verified");
235
0
        break;
236
0
    case InvalidCaCertificate:
237
0
        errStr = QSslSocket::tr("One of the CA certificates is invalid");
238
0
        break;
239
0
    case PathLengthExceeded:
240
0
        errStr = QSslSocket::tr("The basicConstraints path length parameter has been exceeded");
241
0
        break;
242
0
    case InvalidPurpose:
243
0
        errStr = QSslSocket::tr("The supplied certificate is unsuitable for this purpose");
244
0
        break;
245
0
    case CertificateUntrusted:
246
0
        errStr = QSslSocket::tr("The root CA certificate is not trusted for this purpose");
247
0
        break;
248
0
    case CertificateRejected:
249
0
        errStr = QSslSocket::tr("The root CA certificate is marked to reject the specified purpose");
250
0
        break;
251
0
    case SubjectIssuerMismatch: // hostname mismatch
252
0
        errStr = QSslSocket::tr("The current candidate issuer certificate was rejected because its"
253
0
                                " subject name did not match the issuer name of the current certificate");
254
0
        break;
255
0
    case AuthorityIssuerSerialNumberMismatch:
256
0
        errStr = QSslSocket::tr("The current candidate issuer certificate was rejected because"
257
0
                             " its issuer name and serial number was present and did not match the"
258
0
                             " authority key identifier of the current certificate");
259
0
        break;
260
0
    case NoPeerCertificate:
261
0
        errStr = QSslSocket::tr("The peer did not present any certificate");
262
0
        break;
263
0
    case HostNameMismatch:
264
0
        errStr = QSslSocket::tr("The host name did not match any of the valid hosts"
265
0
                             " for this certificate");
266
0
        break;
267
0
    case NoSslSupport:
268
0
        break;
269
0
    case CertificateBlacklisted:
270
0
        errStr = QSslSocket::tr("The peer certificate is blacklisted");
271
0
        break;
272
0
    case OcspNoResponseFound:
273
0
        errStr = QSslSocket::tr("No OCSP status response found");
274
0
        break;
275
0
    case OcspMalformedRequest:
276
0
        errStr = QSslSocket::tr("The OCSP status request had invalid syntax");
277
0
        break;
278
0
    case OcspMalformedResponse:
279
0
        errStr = QSslSocket::tr("OCSP response contains an unexpected number of SingleResponse structures");
280
0
        break;
281
0
    case OcspInternalError:
282
0
        errStr = QSslSocket::tr("OCSP responder reached an inconsistent internal state");
283
0
        break;
284
0
    case OcspTryLater:
285
0
        errStr = QSslSocket::tr("OCSP responder was unable to return a status for the requested certificate");
286
0
        break;
287
0
    case OcspSigRequred:
288
0
        errStr = QSslSocket::tr("The server requires the client to sign the OCSP request in order to construct a response");
289
0
        break;
290
0
    case OcspUnauthorized:
291
0
        errStr = QSslSocket::tr("The client is not authorized to request OCSP status from this server");
292
0
        break;
293
0
    case OcspResponseCannotBeTrusted:
294
0
        errStr = QSslSocket::tr("OCSP responder's identity cannot be verified");
295
0
        break;
296
0
    case OcspResponseCertIdUnknown:
297
0
        errStr = QSslSocket::tr("The identity of a certificate in an OCSP response cannot be established");
298
0
        break;
299
0
    case OcspResponseExpired:
300
0
        errStr = QSslSocket::tr("The certificate status response has expired");
301
0
        break;
302
0
    case OcspStatusUnknown:
303
0
        errStr = QSslSocket::tr("The certificate's status is unknown");
304
0
        break;
305
0
    default:
306
0
        errStr = QSslSocket::tr("Unknown error");
307
0
        break;
308
0
    }
309
310
0
    return errStr;
311
0
}
312
313
/*!
314
    Returns the certificate associated with this error, or a null certificate
315
    if the error does not relate to any certificate.
316
317
    \sa error(), errorString()
318
*/
319
QSslCertificate QSslError::certificate() const
320
0
{
321
0
    return d->certificate;
322
0
}
323
324
/*!
325
    \since 5.4
326
    \qhashold{QHash}
327
*/
328
size_t qHash(const QSslError &key, size_t seed) noexcept
329
0
{
330
0
    QtPrivate::QHashCombine hash(seed);
331
0
    seed = hash(seed, key.error());
332
0
    seed = hash(seed, key.certificate());
333
0
    return seed;
334
0
}
335
336
#ifndef QT_NO_DEBUG_STREAM
337
//class QDebug;
338
QDebug operator<<(QDebug debug, const QSslError &error)
339
0
{
340
0
    debug << error.errorString();
341
0
    return debug;
342
0
}
343
344
QDebug print(QDebug debug, QSslError::SslError error)
345
0
{
346
0
    debug << QSslError(error).errorString();
347
0
    return debug;
348
0
}
349
#endif
350
351
QT_END_NAMESPACE
352
353
#include "moc_qsslerror.cpp"