/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" |