1// Copyright (C) 2021 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#include "qsslsocket_openssl_symbols_p.h"
5#include "qx509_openssl_p.h"
6#include "qtls_openssl_p.h"
7
8#ifdef Q_OS_WIN
9#include "qwindowscarootfetcher_p.h"
10#endif
11
12#include <QtNetwork/private/qsslpresharedkeyauthenticator_p.h>
13#include <QtNetwork/private/qsslcertificate_p.h>
14#include <QtNetwork/private/qocspresponse_p.h>
15#include <QtNetwork/private/qsslsocket_p.h>
16
17#include <QtNetwork/qsslpresharedkeyauthenticator.h>
18
19#include <QtCore/qscopedvaluerollback.h>
20#include <QtCore/qscopeguard.h>
21
22#include <algorithm>
23#include <cstring>
24
25QT_BEGIN_NAMESPACE
26
27using namespace Qt::StringLiterals;
28
29namespace {
30
31QSsl::AlertLevel tlsAlertLevel(int value)
32{
33 using QSsl::AlertLevel;
34
35 if (const char *typeString = q_SSL_alert_type_string(value)) {
36 // Documented to return 'W' for warning, 'F' for fatal,
37 // 'U' for unknown.
38 switch (typeString[0]) {
39 case 'W':
40 return AlertLevel::Warning;
41 case 'F':
42 return AlertLevel::Fatal;
43 default:;
44 }
45 }
46
47 return AlertLevel::Unknown;
48}
49
50QString tlsAlertDescription(int value)
51{
52 QString description = QLatin1StringView(q_SSL_alert_desc_string_long(value));
53 if (!description.size())
54 description = "no description provided"_L1;
55 return description;
56}
57
58QSsl::AlertType tlsAlertType(int value)
59{
60 // In case for some reason openssl gives us a value,
61 // which is not in our enum actually, we leave it to
62 // an application to handle (supposedly they have
63 // if or switch-statements).
64 return QSsl::AlertType(value & 0xff);
65}
66
67#ifdef Q_OS_WIN
68
69QSslCertificate findCertificateToFetch(const QList<QSslError> &tlsErrors, bool checkAIA)
70{
71 QSslCertificate certToFetch;
72
73 for (const auto &tlsError : tlsErrors) {
74 switch (tlsError.error()) {
75 case QSslError::UnableToGetLocalIssuerCertificate: // site presented intermediate cert, but root is unknown
76 case QSslError::SelfSignedCertificateInChain: // site presented a complete chain, but root is unknown
77 certToFetch = tlsError.certificate();
78 break;
79 case QSslError::SelfSignedCertificate:
80 case QSslError::CertificateBlacklisted:
81 //With these errors, we know it will be untrusted so save time by not asking windows
82 return QSslCertificate{};
83 default:
84#ifdef QSSLSOCKET_DEBUG
85 qCDebug(lcTlsBackend) << tlsError.errorString();
86#endif
87 //TODO - this part is strange.
88 break;
89 }
90 }
91
92 if (checkAIA) {
93 const auto extensions = certToFetch.extensions();
94 for (const auto &ext : extensions) {
95 if (ext.oid() == QStringLiteral("1.3.6.1.5.5.7.1.1")) // See RFC 4325
96 return certToFetch;
97 }
98 //The only reason we check this extensions is because an application set trusted
99 //CA certificates explicitly, thus technically disabling CA fetch. So, if it's
100 //the case and an intermediate certificate is missing, and no extensions is
101 //present on the leaf certificate - we fail the handshake immediately.
102 return QSslCertificate{};
103 }
104
105 return certToFetch;
106}
107
108#endif // Q_OS_WIN
109
110} // unnamed namespace
111
112namespace QTlsPrivate {
113
114extern "C" {
115
116int q_X509Callback(int ok, X509_STORE_CTX *ctx)
117{
118 if (!ok) {
119 // Store the error and at which depth the error was detected.
120
121 using ErrorListPtr = QList<QSslErrorEntry> *;
122 ErrorListPtr errors = nullptr;
123
124 // Error list is attached to either 'SSL' or 'X509_STORE'.
125 if (X509_STORE *store = q_X509_STORE_CTX_get0_store(ctx)) // We try store first:
126 errors = ErrorListPtr(q_X509_STORE_get_ex_data(r: store, idx: 0));
127
128 if (!errors) {
129 // Not found on store? Try SSL and its external data then. According to the OpenSSL's
130 // documentation:
131 //
132 // "Whenever a X509_STORE_CTX object is created for the verification of the
133 // peer's certificate during a handshake, a pointer to the SSL object is
134 // stored into the X509_STORE_CTX object to identify the connection affected.
135 // To retrieve this pointer the X509_STORE_CTX_get_ex_data() function can be
136 // used with the correct index."
137 const auto offset = QTlsBackendOpenSSL::s_indexForSSLExtraData
138 + TlsCryptographOpenSSL::errorOffsetInExData;
139 if (SSL *ssl = static_cast<SSL *>(q_X509_STORE_CTX_get_ex_data(
140 ctx, idx: q_SSL_get_ex_data_X509_STORE_CTX_idx()))) {
141
142 // We may be in a renegotiation, check if we are inside a call to SSL_read:
143 const auto tlsOffset = QTlsBackendOpenSSL::s_indexForSSLExtraData
144 + TlsCryptographOpenSSL::socketOffsetInExData;
145 auto tls = static_cast<TlsCryptographOpenSSL *>(q_SSL_get_ex_data(ssl, idx: tlsOffset));
146 Q_ASSERT(tls);
147 if (tls->isInSslRead()) {
148 // We are in a renegotiation, make a note of this for later.
149 // We'll check that the certificate is the same as the one we got during
150 // the initial handshake
151 tls->setRenegotiated(true);
152 return 1;
153 }
154
155 errors = ErrorListPtr(q_SSL_get_ex_data(ssl, idx: offset));
156 }
157 }
158
159 if (!errors) {
160 qCWarning(lcTlsBackend, "Neither X509_STORE, nor SSL contains error list, handshake failure");
161 return 0;
162 }
163
164 errors->append(t: X509CertificateOpenSSL::errorEntryFromStoreContext(ctx));
165 }
166 // Always return OK to allow verification to continue. We handle the
167 // errors gracefully after collecting all errors, after verification has
168 // completed.
169 return 1;
170}
171
172int q_X509CallbackDirect(int ok, X509_STORE_CTX *ctx)
173{
174 // Passed to SSL_CTX_set_verify()
175 // https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_set_verify.html
176 // Returns 0 to abort verification, 1 to continue.
177
178 // This is a new, experimental verification callback, reporting
179 // errors immediately and returning 0 or 1 depending on an application
180 // either ignoring or not ignoring verification errors as they come.
181 if (!ctx) {
182 qCWarning(lcTlsBackend, "Invalid store context (nullptr)");
183 return 0;
184 }
185
186 if (!ok) {
187 // "Whenever a X509_STORE_CTX object is created for the verification of the
188 // peer's certificate during a handshake, a pointer to the SSL object is
189 // stored into the X509_STORE_CTX object to identify the connection affected.
190 // To retrieve this pointer the X509_STORE_CTX_get_ex_data() function can be
191 // used with the correct index."
192 SSL *ssl = static_cast<SSL *>(q_X509_STORE_CTX_get_ex_data(ctx, idx: q_SSL_get_ex_data_X509_STORE_CTX_idx()));
193 if (!ssl) {
194 qCWarning(lcTlsBackend, "No external data (SSL) found in X509 store object");
195 return 0;
196 }
197
198 const auto offset = QTlsBackendOpenSSL::s_indexForSSLExtraData
199 + TlsCryptographOpenSSL::socketOffsetInExData;
200 auto crypto = static_cast<TlsCryptographOpenSSL *>(q_SSL_get_ex_data(ssl, idx: offset));
201 if (!crypto) {
202 qCWarning(lcTlsBackend, "No external data (TlsCryptographOpenSSL) found in SSL object");
203 return 0;
204 }
205
206 return crypto->emitErrorFromCallback(ctx);
207 }
208 return 1;
209}
210
211#ifndef OPENSSL_NO_PSK
212static unsigned q_ssl_psk_client_callback(SSL *ssl, const char *hint, char *identity, unsigned max_identity_len,
213 unsigned char *psk, unsigned max_psk_len)
214{
215 auto *tls = static_cast<TlsCryptographOpenSSL *>(q_SSL_get_ex_data(ssl, idx: QTlsBackendOpenSSL::s_indexForSSLExtraData));
216 return tls->pskClientTlsCallback(hint, identity, max_identity_len, psk, max_psk_len);
217}
218
219static unsigned int q_ssl_psk_server_callback(SSL *ssl, const char *identity, unsigned char *psk,
220 unsigned int max_psk_len)
221{
222 auto *tls = static_cast<TlsCryptographOpenSSL *>(q_SSL_get_ex_data(ssl, idx: QTlsBackendOpenSSL::s_indexForSSLExtraData));
223 Q_ASSERT(tls);
224 return tls->pskServerTlsCallback(identity, psk, max_psk_len);
225}
226
227#ifdef TLS1_3_VERSION
228static unsigned q_ssl_psk_restore_client(SSL *ssl, const char *hint, char *identity, unsigned max_identity_len,
229 unsigned char *psk, unsigned max_psk_len)
230{
231 Q_UNUSED(hint);
232 Q_UNUSED(identity);
233 Q_UNUSED(max_identity_len);
234 Q_UNUSED(psk);
235 Q_UNUSED(max_psk_len);
236
237#ifdef QT_DEBUG
238 auto tls = static_cast<TlsCryptographOpenSSL *>(q_SSL_get_ex_data(ssl, idx: QTlsBackendOpenSSL::s_indexForSSLExtraData));
239 Q_ASSERT(tls);
240 Q_ASSERT(tls->d);
241 Q_ASSERT(tls->d->tlsMode() == QSslSocket::SslClientMode);
242#endif
243 unsigned retVal = 0;
244
245 // Let developers opt-in to having the normal PSK callback get called for TLS 1.3
246 // PSK (which works differently in a few ways, and is called at the start of every connection).
247 // When they do opt-in we just call the old callback from here.
248 if (qEnvironmentVariableIsSet(varName: "QT_USE_TLS_1_3_PSK"))
249 retVal = q_ssl_psk_client_callback(ssl, hint, identity, max_identity_len, psk, max_psk_len);
250
251 q_SSL_set_psk_client_callback(ssl, callback: &q_ssl_psk_client_callback);
252
253 return retVal;
254}
255
256static int q_ssl_psk_use_session_callback(SSL *ssl, const EVP_MD *md, const unsigned char **id,
257 size_t *idlen, SSL_SESSION **sess)
258{
259 Q_UNUSED(md);
260 Q_UNUSED(id);
261 Q_UNUSED(idlen);
262 Q_UNUSED(sess);
263
264#ifdef QT_DEBUG
265 auto *tls = static_cast<TlsCryptographOpenSSL *>(q_SSL_get_ex_data(ssl, idx: QTlsBackendOpenSSL::s_indexForSSLExtraData));
266 Q_ASSERT(tls);
267 Q_ASSERT(tls->d);
268 Q_ASSERT(tls->d->tlsMode() == QSslSocket::SslClientMode);
269#endif
270
271 // Temporarily rebind the psk because it will be called next. The function will restore it.
272 q_SSL_set_psk_client_callback(ssl, callback: &q_ssl_psk_restore_client);
273
274 return 1; // need to return 1 or else "the connection setup fails."
275}
276
277int q_ssl_sess_set_new_cb(SSL *ssl, SSL_SESSION *session)
278{
279 if (!ssl) {
280 qCWarning(lcTlsBackend, "Invalid SSL (nullptr)");
281 return 0;
282 }
283 if (!session) {
284 qCWarning(lcTlsBackend, "Invalid SSL_SESSION (nullptr)");
285 return 0;
286 }
287
288 auto *tls = static_cast<TlsCryptographOpenSSL *>(q_SSL_get_ex_data(ssl, idx: QTlsBackendOpenSSL::s_indexForSSLExtraData));
289 Q_ASSERT(tls);
290 return tls->handleNewSessionTicket(connection: ssl);
291}
292#endif // TLS1_3_VERSION
293
294#endif // !OPENSSL_NO_PSK
295
296#if QT_CONFIG(ocsp)
297
298int qt_OCSP_status_server_callback(SSL *ssl, void *ocspRequest)
299{
300 Q_UNUSED(ocspRequest);
301 if (!ssl)
302 return SSL_TLSEXT_ERR_ALERT_FATAL;
303
304 auto crypto = static_cast<TlsCryptographOpenSSL *>(q_SSL_get_ex_data(ssl, idx: QTlsBackendOpenSSL::s_indexForSSLExtraData));
305 if (!crypto)
306 return SSL_TLSEXT_ERR_ALERT_FATAL;
307
308 Q_ASSERT(crypto->d);
309 Q_ASSERT(crypto->d->tlsMode() == QSslSocket::SslServerMode);
310 const QByteArray &response = crypto->ocspResponseDer;
311 Q_ASSERT(response.size());
312
313 unsigned char *derCopy = static_cast<unsigned char *>(q_OPENSSL_malloc(size_t(response.size())));
314 if (!derCopy)
315 return SSL_TLSEXT_ERR_ALERT_FATAL;
316
317 std::copy(first: response.data(), last: response.data() + response.size(), result: derCopy);
318 // We don't check the return value: internally OpenSSL simply assigns the
319 // pointer (it assumes it now owns this memory btw!) and the length.
320 q_SSL_set_tlsext_status_ocsp_resp(ssl, derCopy, response.size());
321
322 return SSL_TLSEXT_ERR_OK;
323}
324
325#endif // ocsp
326
327void qt_AlertInfoCallback(const SSL *connection, int from, int value)
328{
329 // Passed to SSL_set_info_callback()
330 // https://www.openssl.org/docs/man1.1.1/man3/SSL_set_info_callback.html
331
332 if (!connection) {
333#ifdef QSSLSOCKET_DEBUG
334 qCWarning(lcTlsBackend, "Invalid 'connection' parameter (nullptr)");
335#endif // QSSLSOCKET_DEBUG
336 return;
337 }
338
339 const auto offset = QTlsBackendOpenSSL::s_indexForSSLExtraData
340 + TlsCryptographOpenSSL::socketOffsetInExData;
341 auto crypto = static_cast<TlsCryptographOpenSSL *>(q_SSL_get_ex_data(ssl: connection, idx: offset));
342 if (!crypto) {
343 // SSL_set_ex_data can fail:
344#ifdef QSSLSOCKET_DEBUG
345 qCWarning(lcTlsBackend, "No external data (socket backend) found for parameter 'connection'");
346#endif // QSSLSOCKET_DEBUG
347 return;
348 }
349
350 if (!(from & SSL_CB_ALERT)) {
351 // We only want to know about alerts (at least for now).
352 return;
353 }
354
355 if (from & SSL_CB_WRITE)
356 crypto->alertMessageSent(encoded: value);
357 else
358 crypto->alertMessageReceived(encoded: value);
359}
360
361} // extern "C"
362
363#if QT_CONFIG(ocsp)
364namespace {
365
366QSslError::SslError qt_OCSP_response_status_to_SslError(long code)
367{
368 switch (code) {
369 case OCSP_RESPONSE_STATUS_MALFORMEDREQUEST:
370 return QSslError::OcspMalformedRequest;
371 case OCSP_RESPONSE_STATUS_INTERNALERROR:
372 return QSslError::OcspInternalError;
373 case OCSP_RESPONSE_STATUS_TRYLATER:
374 return QSslError::OcspTryLater;
375 case OCSP_RESPONSE_STATUS_SIGREQUIRED:
376 return QSslError::OcspSigRequred;
377 case OCSP_RESPONSE_STATUS_UNAUTHORIZED:
378 return QSslError::OcspUnauthorized;
379 case OCSP_RESPONSE_STATUS_SUCCESSFUL:
380 default:
381 return {};
382 }
383 Q_UNREACHABLE();
384}
385
386QOcspRevocationReason qt_OCSP_revocation_reason(int reason)
387{
388 switch (reason) {
389 case OCSP_REVOKED_STATUS_NOSTATUS:
390 return QOcspRevocationReason::None;
391 case OCSP_REVOKED_STATUS_UNSPECIFIED:
392 return QOcspRevocationReason::Unspecified;
393 case OCSP_REVOKED_STATUS_KEYCOMPROMISE:
394 return QOcspRevocationReason::KeyCompromise;
395 case OCSP_REVOKED_STATUS_CACOMPROMISE:
396 return QOcspRevocationReason::CACompromise;
397 case OCSP_REVOKED_STATUS_AFFILIATIONCHANGED:
398 return QOcspRevocationReason::AffiliationChanged;
399 case OCSP_REVOKED_STATUS_SUPERSEDED:
400 return QOcspRevocationReason::Superseded;
401 case OCSP_REVOKED_STATUS_CESSATIONOFOPERATION:
402 return QOcspRevocationReason::CessationOfOperation;
403 case OCSP_REVOKED_STATUS_CERTIFICATEHOLD:
404 return QOcspRevocationReason::CertificateHold;
405 case OCSP_REVOKED_STATUS_REMOVEFROMCRL:
406 return QOcspRevocationReason::RemoveFromCRL;
407 default:
408 return QOcspRevocationReason::None;
409 }
410
411 Q_UNREACHABLE();
412}
413
414bool qt_OCSP_certificate_match(OCSP_SINGLERESP *singleResponse, X509 *peerCert, X509 *issuer)
415{
416 // OCSP_basic_verify does verify that the responder is legit, the response is
417 // correctly signed, CertID is correct. But it does not know which certificate
418 // we were presented with by our peer, so it does not check if it's a response
419 // for our peer's certificate.
420 Q_ASSERT(singleResponse && peerCert && issuer);
421
422 const OCSP_CERTID *certId = q_OCSP_SINGLERESP_get0_id(x: singleResponse); // Does not increment refcount.
423 if (!certId) {
424 qCWarning(lcTlsBackend, "A SingleResponse without CertID");
425 return false;
426 }
427
428 ASN1_OBJECT *md = nullptr;
429 ASN1_INTEGER *reportedSerialNumber = nullptr;
430 const int result = q_OCSP_id_get0_info(piNameHash: nullptr, pmd: &md, pikeyHash: nullptr, pserial: &reportedSerialNumber, cid: const_cast<OCSP_CERTID *>(certId));
431 if (result != 1 || !md || !reportedSerialNumber) {
432 qCWarning(lcTlsBackend, "Failed to extract a hash and serial number from CertID structure");
433 return false;
434 }
435
436 if (!q_X509_get_serialNumber(a: peerCert)) {
437 // Is this possible at all? But we have to check this,
438 // ASN1_INTEGER_cmp (called from OCSP_id_cmp) dereferences
439 // without any checks at all.
440 qCWarning(lcTlsBackend, "No serial number in peer's ceritificate");
441 return false;
442 }
443
444 const int nid = q_OBJ_obj2nid(a: md);
445 if (nid == NID_undef) {
446 qCWarning(lcTlsBackend, "Unknown hash algorithm in CertID");
447 return false;
448 }
449
450 const EVP_MD *digest = q_EVP_get_digestbynid(nid); // Does not increment refcount.
451 if (!digest) {
452 qCWarning(lcTlsBackend) << "No digest for nid" << nid;
453 return false;
454 }
455
456 OCSP_CERTID *recreatedId = q_OCSP_cert_to_id(dgst: digest, subject: peerCert, issuer);
457 if (!recreatedId) {
458 qCWarning(lcTlsBackend, "Failed to re-create CertID");
459 return false;
460 }
461 const QSharedPointer<OCSP_CERTID> guard(recreatedId, q_OCSP_CERTID_free);
462
463 if (q_OCSP_id_cmp(a: const_cast<OCSP_CERTID *>(certId), b: recreatedId)) {
464 qCDebug(lcTlsBackend, "Certificate ID mismatch");
465 return false;
466 }
467 // Bingo!
468 return true;
469}
470
471} // unnamed namespace
472#endif // ocsp
473
474TlsCryptographOpenSSL::~TlsCryptographOpenSSL()
475{
476 destroySslContext();
477}
478
479void TlsCryptographOpenSSL::init(QSslSocket *qObj, QSslSocketPrivate *dObj)
480{
481 Q_ASSERT(qObj);
482 Q_ASSERT(dObj);
483 q = qObj;
484 d = dObj;
485
486 ocspResponses.clear();
487 ocspResponseDer.clear();
488
489 systemOrSslErrorDetected = false;
490 handshakeInterrupted = false;
491
492 fetchAuthorityInformation = false;
493 caToFetch.reset();
494}
495
496void TlsCryptographOpenSSL::checkSettingSslContext(std::shared_ptr<QSslContext> tlsContext)
497{
498 if (!sslContextPointer)
499 sslContextPointer = std::move(tlsContext);
500}
501
502std::shared_ptr<QSslContext> TlsCryptographOpenSSL::sslContext() const
503{
504 return sslContextPointer;
505}
506
507QList<QSslError> TlsCryptographOpenSSL::tlsErrors() const
508{
509 return sslErrors;
510}
511
512void TlsCryptographOpenSSL::startClientEncryption()
513{
514 if (!initSslContext()) {
515 Q_ASSERT(d);
516 setErrorAndEmit(d, errorCode: QAbstractSocket::SslInternalError,
517 errorDescription: QSslSocket::tr(s: "Unable to init SSL Context: %1").arg(a: QTlsBackendOpenSSL::getErrorsFromOpenSsl()));
518 return;
519 }
520
521 // Start connecting. This will place outgoing data in the BIO, so we
522 // follow up with calling transmit().
523 startHandshake();
524 transmit();
525}
526
527void TlsCryptographOpenSSL::startServerEncryption()
528{
529 if (!initSslContext()) {
530 Q_ASSERT(d);
531 setErrorAndEmit(d, errorCode: QAbstractSocket::SslInternalError,
532 errorDescription: QSslSocket::tr(s: "Unable to init SSL Context: %1").arg(a: QTlsBackendOpenSSL::getErrorsFromOpenSsl()));
533 return;
534 }
535
536 // Start connecting. This will place outgoing data in the BIO, so we
537 // follow up with calling transmit().
538 startHandshake();
539 transmit();
540}
541
542bool TlsCryptographOpenSSL::startHandshake()
543{
544 // Check if the connection has been established. Get all errors from the
545 // verification stage.
546 Q_ASSERT(q);
547 Q_ASSERT(d);
548
549 using ScopedBool = QScopedValueRollback<bool>;
550
551 if (inSetAndEmitError)
552 return false;
553
554 const auto mode = d->tlsMode();
555
556 pendingFatalAlert = false;
557 errorsReportedFromCallback = false;
558 QList<QSslErrorEntry> lastErrors;
559 q_SSL_set_ex_data(ssl, idx: QTlsBackendOpenSSL::s_indexForSSLExtraData + errorOffsetInExData, arg: &lastErrors);
560
561 // SSL_set_ex_data can fail, but see the callback's code - we handle this there.
562 q_SSL_set_ex_data(ssl, idx: QTlsBackendOpenSSL::s_indexForSSLExtraData + socketOffsetInExData, arg: this);
563 q_SSL_set_info_callback(ssl, cb: qt_AlertInfoCallback);
564
565 int result = (mode == QSslSocket::SslClientMode) ? q_SSL_connect(a: ssl) : q_SSL_accept(a: ssl);
566 q_SSL_set_ex_data(ssl, idx: QTlsBackendOpenSSL::s_indexForSSLExtraData + errorOffsetInExData, arg: nullptr);
567 // Note, unlike errors as external data on SSL object, we do not unset
568 // a callback/ex-data if alert notifications are enabled: an alert can
569 // arrive after the handshake, for example, this happens when the server
570 // does not find a ClientCert or does not like it.
571
572 if (!lastErrors.isEmpty() || errorsReportedFromCallback)
573 storePeerCertificates();
574
575 // storePeerCertificate() if called above - would update the
576 // configuration with peer's certificates.
577 auto configuration = q->sslConfiguration();
578 if (!errorsReportedFromCallback) {
579 const auto &peerCertificateChain = configuration.peerCertificateChain();
580 for (const auto &currentError : std::as_const(t&: lastErrors)) {
581 emit q->peerVerifyError(error: QTlsPrivate::X509CertificateOpenSSL::openSSLErrorToQSslError(errorCode: currentError.code,
582 cert: peerCertificateChain.value(i: currentError.depth)));
583 if (q->state() != QAbstractSocket::ConnectedState)
584 break;
585 }
586 }
587
588 errorList << lastErrors;
589
590 // Connection aborted during handshake phase.
591 if (q->state() != QAbstractSocket::ConnectedState)
592 return false;
593
594 // Check if we're encrypted or not.
595 if (result <= 0) {
596 switch (q_SSL_get_error(a: ssl, b: result)) {
597 case SSL_ERROR_WANT_READ:
598 case SSL_ERROR_WANT_WRITE:
599 // The handshake is not yet complete.
600 break;
601 default:
602 QString errorString = QTlsBackendOpenSSL::msgErrorsDuringHandshake();
603#ifdef QSSLSOCKET_DEBUG
604 qCDebug(lcTlsBackend) << "TlsCryptographOpenSSL::startHandshake: error!" << errorString;
605#endif
606 {
607 const ScopedBool bg(inSetAndEmitError, true);
608 setErrorAndEmit(d, errorCode: QAbstractSocket::SslHandshakeFailedError, errorDescription: errorString);
609 if (pendingFatalAlert) {
610 trySendFatalAlert();
611 pendingFatalAlert = false;
612 }
613 }
614 q->abort();
615 }
616 return false;
617 }
618
619 // store peer certificate chain
620 storePeerCertificates();
621
622 // Start translating errors.
623 QList<QSslError> errors;
624
625 // Note, the storePeerCerificates() probably updated the configuration at this point.
626 configuration = q->sslConfiguration();
627 // Check the whole chain for blacklisting (including root, as we check for subjectInfo and issuer)
628 const auto &peerCertificateChain = configuration.peerCertificateChain();
629 for (const QSslCertificate &cert : peerCertificateChain) {
630 if (QSslCertificatePrivate::isBlacklisted(certificate: cert)) {
631 QSslError error(QSslError::CertificateBlacklisted, cert);
632 errors << error;
633 emit q->peerVerifyError(error);
634 if (q->state() != QAbstractSocket::ConnectedState)
635 return false;
636 }
637 }
638
639 const bool doVerifyPeer = configuration.peerVerifyMode() == QSslSocket::VerifyPeer
640 || (configuration.peerVerifyMode() == QSslSocket::AutoVerifyPeer
641 && mode == QSslSocket::SslClientMode);
642
643#if QT_CONFIG(ocsp)
644 // For now it's always QSslSocket::SslClientMode - initSslContext() will bail out early,
645 // if it's enabled in QSslSocket::SslServerMode. This can change.
646 if (!configuration.peerCertificate().isNull() && configuration.ocspStaplingEnabled() && doVerifyPeer) {
647 if (!checkOcspStatus()) {
648 if (ocspErrors.isEmpty()) {
649 {
650 const ScopedBool bg(inSetAndEmitError, true);
651 setErrorAndEmit(d, errorCode: QAbstractSocket::SslHandshakeFailedError, errorDescription: ocspErrorDescription);
652 }
653 q->abort();
654 return false;
655 }
656
657 for (const QSslError &error : ocspErrors) {
658 errors << error;
659 emit q->peerVerifyError(error);
660 if (q->state() != QAbstractSocket::ConnectedState)
661 return false;
662 }
663 }
664 }
665#endif // ocsp
666
667 // Check the peer certificate itself. First try the subject's common name
668 // (CN) as a wildcard, then try all alternate subject name DNS entries the
669 // same way.
670 if (!configuration.peerCertificate().isNull()) {
671 // but only if we're a client connecting to a server
672 // if we're the server, don't check CN
673 const auto verificationPeerName = d->verificationName();
674 if (mode == QSslSocket::SslClientMode) {
675 QString peerName = (verificationPeerName.isEmpty () ? q->peerName() : verificationPeerName);
676
677 if (!isMatchingHostname(cert: configuration.peerCertificate(), peerName)) {
678 // No matches in common names or alternate names.
679 QSslError error(QSslError::HostNameMismatch, configuration.peerCertificate());
680 errors << error;
681 emit q->peerVerifyError(error);
682 if (q->state() != QAbstractSocket::ConnectedState)
683 return false;
684 }
685 }
686 } else {
687 // No peer certificate presented. Report as error if the socket
688 // expected one.
689 if (doVerifyPeer) {
690 QSslError error(QSslError::NoPeerCertificate);
691 errors << error;
692 emit q->peerVerifyError(error);
693 if (q->state() != QAbstractSocket::ConnectedState)
694 return false;
695 }
696 }
697
698 // Translate errors from the error list into QSslErrors.
699 errors.reserve(asize: errors.size() + errorList.size());
700 for (const auto &error : std::as_const(t&: errorList))
701 errors << X509CertificateOpenSSL::openSSLErrorToQSslError(errorCode: error.code, cert: peerCertificateChain.value(i: error.depth));
702
703 if (!errors.isEmpty()) {
704 sslErrors = errors;
705#ifdef Q_OS_WIN
706 const bool fetchEnabled = QSslSocketPrivate::rootCertOnDemandLoadingSupported()
707 && d->isRootsOnDemandAllowed();
708 // !fetchEnabled is a special case scenario, when we potentially have a missing
709 // intermediate certificate and a recoverable chain, but on demand cert loading
710 // was disabled by setCaCertificates call. For this scenario we check if "Authority
711 // Information Access" is present - wincrypt can deal with such certificates.
712 QSslCertificate certToFetch;
713 if (doVerifyPeer && !d->verifyErrorsHaveBeenIgnored())
714 certToFetch = findCertificateToFetch(sslErrors, !fetchEnabled);
715
716 //Skip this if not using system CAs, or if the SSL errors are configured in advance to be ignorable
717 if (!certToFetch.isNull()) {
718 fetchAuthorityInformation = !fetchEnabled;
719 //Windows desktop versions starting from vista ship with minimal set of roots and download on demand
720 //from the windows update server CA roots that are trusted by MS. It also can fetch a missing intermediate
721 //in case "Authority Information Access" extension is present.
722 //
723 //However, this is only transparent if using WinINET - we have to trigger it
724 //ourselves.
725 fetchCaRootForCert(certToFetch);
726 return false;
727 }
728#endif // Q_OS_WIN
729 if (!checkSslErrors())
730 return false;
731 // A slot, attached to sslErrors signal can call
732 // abort/close/disconnetFromHost/etc; no need to
733 // continue handshake then.
734 if (q->state() != QAbstractSocket::ConnectedState)
735 return false;
736 } else {
737 sslErrors.clear();
738 }
739
740 continueHandshake();
741 return true;
742}
743
744void TlsCryptographOpenSSL::enableHandshakeContinuation()
745{
746 handshakeInterrupted = false;
747}
748
749void TlsCryptographOpenSSL::cancelCAFetch()
750{
751 fetchAuthorityInformation = false;
752 caToFetch.reset();
753}
754
755void TlsCryptographOpenSSL::continueHandshake()
756{
757 Q_ASSERT(q);
758 Q_ASSERT(d);
759
760 auto *plainSocket = d->plainTcpSocket();
761 Q_ASSERT(plainSocket);
762
763 const auto mode = d->tlsMode();
764
765 // if we have a max read buffer size, reset the plain socket's to match
766 if (const auto maxSize = d->maxReadBufferSize())
767 plainSocket->setReadBufferSize(maxSize);
768
769 if (q_SSL_session_reused(a: ssl))
770 QTlsBackend::setPeerSessionShared(d, shared: true);
771
772#ifdef QT_DECRYPT_SSL_TRAFFIC
773 if (q_SSL_get_session(ssl)) {
774 size_t master_key_len = q_SSL_SESSION_get_master_key(q_SSL_get_session(ssl), nullptr, 0);
775 size_t client_random_len = q_SSL_get_client_random(ssl, nullptr, 0);
776 QByteArray masterKey(int(master_key_len), Qt::Uninitialized); // Will not overflow
777 QByteArray clientRandom(int(client_random_len), Qt::Uninitialized); // Will not overflow
778
779 q_SSL_SESSION_get_master_key(q_SSL_get_session(ssl),
780 reinterpret_cast<unsigned char*>(masterKey.data()),
781 masterKey.size());
782 q_SSL_get_client_random(ssl, reinterpret_cast<unsigned char *>(clientRandom.data()),
783 clientRandom.size());
784
785 QByteArray debugLineClientRandom("CLIENT_RANDOM ");
786 debugLineClientRandom.append(clientRandom.toHex().toUpper());
787 debugLineClientRandom.append(" ");
788 debugLineClientRandom.append(masterKey.toHex().toUpper());
789 debugLineClientRandom.append("\n");
790
791 QString sslKeyFile = QDir::tempPath() + "/qt-ssl-keys"_L1;
792 QFile file(sslKeyFile);
793 if (!file.open(QIODevice::Append))
794 qCWarning(lcTlsBackend) << "could not open file" << sslKeyFile << "for appending";
795 if (!file.write(debugLineClientRandom))
796 qCWarning(lcTlsBackend) << "could not write to file" << sslKeyFile;
797 file.close();
798 } else {
799 qCWarning(lcTlsBackend, "could not decrypt SSL traffic");
800 }
801#endif // QT_DECRYPT_SSL_TRAFFIC
802
803 const auto &configuration = q->sslConfiguration();
804 // Cache this SSL session inside the QSslContext
805 if (!(configuration.testSslOption(option: QSsl::SslOptionDisableSessionSharing))) {
806 if (!sslContextPointer->cacheSession(ssl)) {
807 sslContextPointer.reset(); // we could not cache the session
808 } else {
809 // Cache the session for permanent usage as well
810 if (!(configuration.testSslOption(option: QSsl::SslOptionDisableSessionPersistence))) {
811 if (!sslContextPointer->sessionASN1().isEmpty())
812 QTlsBackend::setSessionAsn1(d, asn1: sslContextPointer->sessionASN1());
813 QTlsBackend::setSessionLifetimeHint(d, hint: sslContextPointer->sessionTicketLifeTimeHint());
814 }
815 }
816 }
817
818#if !defined(OPENSSL_NO_NEXTPROTONEG)
819
820 QTlsBackend::setAlpnStatus(d, st: sslContextPointer->npnContext().status);
821 if (sslContextPointer->npnContext().status == QSslConfiguration::NextProtocolNegotiationUnsupported) {
822 // we could not agree -> be conservative and use HTTP/1.1
823 // T.P.: I have to admit, this is a really strange notion of 'conservative',
824 // given the protocol-neutral nature of ALPN/NPN.
825 QTlsBackend::setNegotiatedProtocol(d, QByteArrayLiteral("http/1.1"));
826 } else {
827 const unsigned char *proto = nullptr;
828 unsigned int proto_len = 0;
829
830 q_SSL_get0_alpn_selected(ssl, data: &proto, len: &proto_len);
831 if (proto_len && mode == QSslSocket::SslClientMode) {
832 // Client does not have a callback that sets it ...
833 QTlsBackend::setAlpnStatus(d, st: QSslConfiguration::NextProtocolNegotiationNegotiated);
834 }
835
836 if (!proto_len) { // Test if NPN was more lucky ...
837 q_SSL_get0_next_proto_negotiated(s: ssl, data: &proto, len: &proto_len);
838 }
839
840 if (proto_len)
841 QTlsBackend::setNegotiatedProtocol(d, protocol: QByteArray(reinterpret_cast<const char *>(proto), proto_len));
842 else
843 QTlsBackend::setNegotiatedProtocol(d,protocol: {});
844 }
845#endif // !defined(OPENSSL_NO_NEXTPROTONEG)
846
847 if (mode == QSslSocket::SslClientMode) {
848 EVP_PKEY *key;
849 if (q_SSL_get_server_tmp_key(ssl, &key))
850 QTlsBackend::setEphemeralKey(d, key: QSslKey(key, QSsl::PublicKey));
851 }
852
853 d->setEncrypted(true);
854 emit q->encrypted();
855 if (d->isAutoStartingHandshake() && d->isPendingClose()) {
856 d->setPendingClose(false);
857 q->disconnectFromHost();
858 }
859}
860
861void TlsCryptographOpenSSL::transmit()
862{
863 Q_ASSERT(q);
864 Q_ASSERT(d);
865
866 using ScopedBool = QScopedValueRollback<bool>;
867
868 if (inSetAndEmitError)
869 return;
870
871 // If we don't have any SSL context, don't bother transmitting.
872 if (!ssl)
873 return;
874
875 auto &writeBuffer = d->tlsWriteBuffer();
876 auto &buffer = d->tlsBuffer();
877 auto *plainSocket = d->plainTcpSocket();
878 Q_ASSERT(plainSocket);
879 bool &emittedBytesWritten = d->tlsEmittedBytesWritten();
880
881 bool transmitting;
882 do {
883 transmitting = false;
884
885 // If the connection is secure, we can transfer data from the write
886 // buffer (in plain text) to the write BIO through SSL_write.
887 if (q->isEncrypted() && !writeBuffer.isEmpty()) {
888 qint64 totalBytesWritten = 0;
889 int nextDataBlockSize;
890 while ((nextDataBlockSize = writeBuffer.nextDataBlockSize()) > 0) {
891 int writtenBytes = q_SSL_write(a: ssl, b: writeBuffer.readPointer(), c: nextDataBlockSize);
892 if (writtenBytes <= 0) {
893 int error = q_SSL_get_error(a: ssl, b: writtenBytes);
894 //write can result in a want_write_error - not an error - continue transmitting
895 if (error == SSL_ERROR_WANT_WRITE) {
896 transmitting = true;
897 break;
898 } else if (error == SSL_ERROR_WANT_READ) {
899 //write can result in a want_read error, possibly due to renegotiation - not an error - stop transmitting
900 transmitting = false;
901 break;
902 } else {
903 // ### Better error handling.
904 const ScopedBool bg(inSetAndEmitError, true);
905 setErrorAndEmit(d, errorCode: QAbstractSocket::SslInternalError,
906 errorDescription: QSslSocket::tr(s: "Unable to write data: %1").arg(
907 a: QTlsBackendOpenSSL::getErrorsFromOpenSsl()));
908 return;
909 }
910 }
911#ifdef QSSLSOCKET_DEBUG
912 qCDebug(lcTlsBackend) << "TlsCryptographOpenSSL::transmit: encrypted" << writtenBytes << "bytes";
913#endif
914 writeBuffer.free(bytes: writtenBytes);
915 totalBytesWritten += writtenBytes;
916
917 if (writtenBytes < nextDataBlockSize) {
918 // break out of the writing loop and try again after we had read
919 transmitting = true;
920 break;
921 }
922 }
923
924 if (totalBytesWritten > 0) {
925 // Don't emit bytesWritten() recursively.
926 if (!emittedBytesWritten) {
927 emittedBytesWritten = true;
928 emit q->bytesWritten(bytes: totalBytesWritten);
929 emittedBytesWritten = false;
930 }
931 emit q->channelBytesWritten(channel: 0, bytes: totalBytesWritten);
932 }
933 }
934
935 // Check if we've got any data to be written to the socket.
936 QVarLengthArray<char, 4096> data;
937 int pendingBytes;
938 while (plainSocket->isValid() && (pendingBytes = q_BIO_pending(writeBio)) > 0
939 && plainSocket->openMode() != QIODevice::NotOpen) {
940 // Read encrypted data from the write BIO into a buffer.
941 data.resize(sz: pendingBytes);
942 int encryptedBytesRead = q_BIO_read(a: writeBio, b: data.data(), c: pendingBytes);
943
944 // Write encrypted data from the buffer to the socket.
945 qint64 actualWritten = plainSocket->write(data: data.constData(), len: encryptedBytesRead);
946#ifdef QSSLSOCKET_DEBUG
947 qCDebug(lcTlsBackend) << "TlsCryptographOpenSSL::transmit: wrote" << encryptedBytesRead
948 << "encrypted bytes to the socket" << actualWritten << "actual.";
949#endif
950 if (actualWritten < 0) {
951 //plain socket write fails if it was in the pending close state.
952 const ScopedBool bg(inSetAndEmitError, true);
953 setErrorAndEmit(d, errorCode: plainSocket->error(), errorDescription: plainSocket->errorString());
954 return;
955 }
956 transmitting = true;
957 }
958
959 // Check if we've got any data to be read from the socket.
960 if (!q->isEncrypted() || !d->maxReadBufferSize() || buffer.size() < d->maxReadBufferSize())
961 while ((pendingBytes = plainSocket->bytesAvailable()) > 0) {
962 // Read encrypted data from the socket into a buffer.
963 data.resize(sz: pendingBytes);
964 // just peek() here because q_BIO_write could write less data than expected
965 int encryptedBytesRead = plainSocket->peek(data: data.data(), maxlen: pendingBytes);
966
967#ifdef QSSLSOCKET_DEBUG
968 qCDebug(lcTlsBackend) << "TlsCryptographOpenSSL::transmit: read" << encryptedBytesRead << "encrypted bytes from the socket";
969#endif
970 // Write encrypted data from the buffer into the read BIO.
971 int writtenToBio = q_BIO_write(a: readBio, b: data.constData(), c: encryptedBytesRead);
972
973 // Throw away the results.
974 if (writtenToBio > 0) {
975 plainSocket->skip(maxSize: writtenToBio);
976 } else {
977 // ### Better error handling.
978 const ScopedBool bg(inSetAndEmitError, true);
979 setErrorAndEmit(d, errorCode: QAbstractSocket::SslInternalError,
980 errorDescription: QSslSocket::tr(s: "Unable to decrypt data: %1")
981 .arg(a: QTlsBackendOpenSSL::getErrorsFromOpenSsl()));
982 return;
983 }
984
985 transmitting = true;
986 }
987
988 // If the connection isn't secured yet, this is the time to retry the
989 // connect / accept.
990 if (!q->isEncrypted()) {
991#ifdef QSSLSOCKET_DEBUG
992 qCDebug(lcTlsBackend) << "TlsCryptographOpenSSL::transmit: testing encryption";
993#endif
994 if (startHandshake()) {
995#ifdef QSSLSOCKET_DEBUG
996 qCDebug(lcTlsBackend) << "TlsCryptographOpenSSL::transmit: encryption established";
997#endif
998 d->setEncrypted(true);
999 transmitting = true;
1000 } else if (plainSocket->state() != QAbstractSocket::ConnectedState) {
1001#ifdef QSSLSOCKET_DEBUG
1002 qCDebug(lcTlsBackend) << "TlsCryptographOpenSSL::transmit: connection lost";
1003#endif
1004 break;
1005 } else if (d->isPaused()) {
1006 // just wait until the user continues
1007 return;
1008 } else {
1009#ifdef QSSLSOCKET_DEBUG
1010 qCDebug(lcTlsBackend) << "TlsCryptographOpenSSL::transmit: encryption not done yet";
1011#endif
1012 }
1013 }
1014
1015 // If the request is small and the remote host closes the transmission
1016 // after sending, there's a chance that startHandshake() will already
1017 // have triggered a shutdown.
1018 if (!ssl)
1019 continue;
1020
1021 // We always read everything from the SSL decryption buffers, even if
1022 // we have a readBufferMaxSize. There's no point in leaving data there
1023 // just so that readBuffer.size() == readBufferMaxSize.
1024 int readBytes = 0;
1025 const int bytesToRead = 4096;
1026 do {
1027 if (q->readChannelCount() == 0) {
1028 // The read buffer is deallocated, don't try resize or write to it.
1029 break;
1030 }
1031 // Don't use SSL_pending(). It's very unreliable.
1032 inSslRead = true;
1033 readBytes = q_SSL_read(a: ssl, b: buffer.reserve(bytes: bytesToRead), c: bytesToRead);
1034 inSslRead = false;
1035 if (renegotiated) {
1036 renegotiated = false;
1037 X509 *x509 = q_SSL_get_peer_certificate(a: ssl);
1038 const auto peerCertificate =
1039 QTlsPrivate::X509CertificateOpenSSL::certificateFromX509(x: x509);
1040 // Fail the renegotiate if the certificate has changed, else: continue.
1041 if (peerCertificate != q->peerCertificate()) {
1042 const ScopedBool bg(inSetAndEmitError, true);
1043 setErrorAndEmit(
1044 d, errorCode: QAbstractSocket::RemoteHostClosedError,
1045 errorDescription: QSslSocket::tr(
1046 s: "TLS certificate unexpectedly changed during renegotiation!"));
1047 q->abort();
1048 return;
1049 }
1050 }
1051 if (readBytes > 0) {
1052#ifdef QSSLSOCKET_DEBUG
1053 qCDebug(lcTlsBackend) << "TlsCryptographOpenSSL::transmit: decrypted" << readBytes << "bytes";
1054#endif
1055 buffer.chop(bytes: bytesToRead - readBytes);
1056
1057 if (bool *readyReadEmittedPointer = d->readyReadPointer())
1058 *readyReadEmittedPointer = true;
1059 emit q->readyRead();
1060 emit q->channelReadyRead(channel: 0);
1061 transmitting = true;
1062 continue;
1063 }
1064 buffer.chop(bytes: bytesToRead);
1065
1066 // Error.
1067 switch (q_SSL_get_error(a: ssl, b: readBytes)) {
1068 case SSL_ERROR_WANT_READ:
1069 case SSL_ERROR_WANT_WRITE:
1070 // Out of data.
1071 break;
1072 case SSL_ERROR_ZERO_RETURN:
1073 // The remote host closed the connection.
1074#ifdef QSSLSOCKET_DEBUG
1075 qCDebug(lcTlsBackend) << "TlsCryptographOpenSSL::transmit: remote disconnect";
1076#endif
1077 shutdown = true; // the other side shut down, make sure we do not send shutdown ourselves
1078 {
1079 const ScopedBool bg(inSetAndEmitError, true);
1080 setErrorAndEmit(d, errorCode: QAbstractSocket::RemoteHostClosedError,
1081 errorDescription: QSslSocket::tr(s: "The TLS/SSL connection has been closed"));
1082 }
1083 return;
1084 case SSL_ERROR_SYSCALL: // some IO error
1085 case SSL_ERROR_SSL: // error in the SSL library
1086 // we do not know exactly what the error is, nor whether we can recover from it,
1087 // so just return to prevent an endless loop in the outer "while" statement
1088 systemOrSslErrorDetected = true;
1089 {
1090 const ScopedBool bg(inSetAndEmitError, true);
1091 setErrorAndEmit(d, errorCode: QAbstractSocket::SslInternalError,
1092 errorDescription: QSslSocket::tr(s: "Error while reading: %1")
1093 .arg(a: QTlsBackendOpenSSL::getErrorsFromOpenSsl()));
1094 }
1095 return;
1096 default:
1097 // SSL_ERROR_WANT_CONNECT, SSL_ERROR_WANT_ACCEPT: can only happen with a
1098 // BIO_s_connect() or BIO_s_accept(), which we do not call.
1099 // SSL_ERROR_WANT_X509_LOOKUP: can only happen with a
1100 // SSL_CTX_set_client_cert_cb(), which we do not call.
1101 // So this default case should never be triggered.
1102 {
1103 const ScopedBool bg(inSetAndEmitError, true);
1104 setErrorAndEmit(d, errorCode: QAbstractSocket::SslInternalError,
1105 errorDescription: QSslSocket::tr(s: "Error while reading: %1")
1106 .arg(a: QTlsBackendOpenSSL::getErrorsFromOpenSsl()));
1107 }
1108 break;
1109 }
1110 } while (ssl && readBytes > 0);
1111 } while (ssl && transmitting);
1112}
1113
1114void TlsCryptographOpenSSL::disconnectFromHost()
1115{
1116 if (ssl) {
1117 if (!shutdown && !q_SSL_in_init(s: ssl) && !systemOrSslErrorDetected) {
1118 if (q_SSL_shutdown(a: ssl) != 1) {
1119 // Some error may be queued, clear it.
1120 QTlsBackendOpenSSL::clearErrorQueue();
1121 }
1122 shutdown = true;
1123 transmit();
1124 }
1125 }
1126 Q_ASSERT(d);
1127 auto *plainSocket = d->plainTcpSocket();
1128 Q_ASSERT(plainSocket);
1129 plainSocket->disconnectFromHost();
1130}
1131
1132void TlsCryptographOpenSSL::disconnected()
1133{
1134 Q_ASSERT(d);
1135 auto *plainSocket = d->plainTcpSocket();
1136 Q_ASSERT(plainSocket);
1137 d->setEncrypted(false);
1138
1139 if (plainSocket->bytesAvailable() <= 0) {
1140 destroySslContext();
1141 } else {
1142 // Move all bytes into the plain buffer.
1143 const qint64 tmpReadBufferMaxSize = d->maxReadBufferSize();
1144 // Reset temporarily, so the plain socket buffer is completely drained:
1145 d->setMaxReadBufferSize(0);
1146 transmit();
1147 d->setMaxReadBufferSize(tmpReadBufferMaxSize);
1148 }
1149 //if there is still buffered data in the plain socket, don't destroy the ssl context yet.
1150 //it will be destroyed when the socket is deleted.
1151}
1152
1153QSslCipher TlsCryptographOpenSSL::sessionCipher() const
1154{
1155 if (!ssl)
1156 return {};
1157
1158 const SSL_CIPHER *sessionCipher = q_SSL_get_current_cipher(a: ssl);
1159 return sessionCipher ? QTlsBackendOpenSSL::qt_OpenSSL_cipher_to_QSslCipher(cipher: sessionCipher) : QSslCipher{};
1160}
1161
1162QSsl::SslProtocol TlsCryptographOpenSSL::sessionProtocol() const
1163{
1164 if (!ssl)
1165 return QSsl::UnknownProtocol;
1166
1167 const int ver = q_SSL_version(a: ssl);
1168 switch (ver) {
1169QT_WARNING_PUSH
1170QT_WARNING_DISABLE_DEPRECATED
1171 case 0x301:
1172 return QSsl::TlsV1_0;
1173 case 0x302:
1174 return QSsl::TlsV1_1;
1175QT_WARNING_POP
1176 case 0x303:
1177 return QSsl::TlsV1_2;
1178 case 0x304:
1179 return QSsl::TlsV1_3;
1180 }
1181
1182 return QSsl::UnknownProtocol;
1183}
1184
1185QList<QOcspResponse> TlsCryptographOpenSSL::ocsps() const
1186{
1187 return ocspResponses;
1188}
1189
1190bool TlsCryptographOpenSSL::checkSslErrors()
1191{
1192 Q_ASSERT(q);
1193 Q_ASSERT(d);
1194
1195 if (sslErrors.isEmpty())
1196 return true;
1197
1198 emit q->sslErrors(errors: sslErrors);
1199
1200 const auto vfyMode = q->peerVerifyMode();
1201 const auto mode = d->tlsMode();
1202
1203 bool doVerifyPeer = vfyMode == QSslSocket::VerifyPeer || (vfyMode == QSslSocket::AutoVerifyPeer
1204 && mode == QSslSocket::SslClientMode);
1205 bool doEmitSslError = !d->verifyErrorsHaveBeenIgnored();
1206 // check whether we need to emit an SSL handshake error
1207 if (doVerifyPeer && doEmitSslError) {
1208 if (q->pauseMode() & QAbstractSocket::PauseOnSslErrors) {
1209 QSslSocketPrivate::pauseSocketNotifiers(q);
1210 d->setPaused(true);
1211 } else {
1212 setErrorAndEmit(d, errorCode: QAbstractSocket::SslHandshakeFailedError, errorDescription: sslErrors.constFirst().errorString());
1213 auto *plainSocket = d->plainTcpSocket();
1214 Q_ASSERT(plainSocket);
1215 plainSocket->disconnectFromHost();
1216 }
1217 return false;
1218 }
1219 return true;
1220}
1221
1222int TlsCryptographOpenSSL::handleNewSessionTicket(SSL *connection)
1223{
1224 // If we return 1, this means we own the session, but we don't.
1225 // 0 would tell OpenSSL to deref (but they still have it in the
1226 // internal cache).
1227 Q_ASSERT(connection);
1228
1229 Q_ASSERT(q);
1230 Q_ASSERT(d);
1231
1232 if (q->sslConfiguration().testSslOption(option: QSsl::SslOptionDisableSessionPersistence)) {
1233 // We silently ignore, do nothing, remove from cache.
1234 return 0;
1235 }
1236
1237 SSL_SESSION *currentSession = q_SSL_get_session(ssl: connection);
1238 if (!currentSession) {
1239 qCWarning(lcTlsBackend,
1240 "New session ticket callback, the session is invalid (nullptr)");
1241 return 0;
1242 }
1243
1244 if (q_SSL_version(a: connection) < 0x304) {
1245 // We only rely on this mechanics with TLS >= 1.3
1246 return 0;
1247 }
1248
1249#ifdef TLS1_3_VERSION
1250 if (!q_SSL_SESSION_is_resumable(s: currentSession)) {
1251 qCDebug(lcTlsBackend, "New session ticket, but the session is non-resumable");
1252 return 0;
1253 }
1254#endif // TLS1_3_VERSION
1255
1256 const int sessionSize = q_i2d_SSL_SESSION(in: currentSession, pp: nullptr);
1257 if (sessionSize <= 0) {
1258 qCWarning(lcTlsBackend, "could not store persistent version of SSL session");
1259 return 0;
1260 }
1261
1262 // We have somewhat perverse naming, it's not a ticket, it's a session.
1263 QByteArray sessionTicket(sessionSize, 0);
1264 auto data = reinterpret_cast<unsigned char *>(sessionTicket.data());
1265 if (!q_i2d_SSL_SESSION(in: currentSession, pp: &data)) {
1266 qCWarning(lcTlsBackend, "could not store persistent version of SSL session");
1267 return 0;
1268 }
1269
1270 QTlsBackend::setSessionAsn1(d, asn1: sessionTicket);
1271 QTlsBackend::setSessionLifetimeHint(d, hint: q_SSL_SESSION_get_ticket_lifetime_hint(session: currentSession));
1272
1273 emit q->newSessionTicketReceived();
1274 return 0;
1275}
1276
1277void TlsCryptographOpenSSL::alertMessageSent(int value)
1278{
1279 Q_ASSERT(q);
1280 Q_ASSERT(d);
1281
1282 const auto level = tlsAlertLevel(value);
1283 if (level == QSsl::AlertLevel::Fatal && !q->isEncrypted()) {
1284 // Note, this logic is handshake-time only:
1285 pendingFatalAlert = true;
1286 }
1287
1288 emit q->alertSent(level, type: tlsAlertType(value), description: tlsAlertDescription(value));
1289
1290}
1291
1292void TlsCryptographOpenSSL::alertMessageReceived(int value)
1293{
1294 Q_ASSERT(q);
1295
1296 emit q->alertReceived(level: tlsAlertLevel(value), type: tlsAlertType(value), description: tlsAlertDescription(value));
1297}
1298
1299int TlsCryptographOpenSSL::emitErrorFromCallback(X509_STORE_CTX *ctx)
1300{
1301 // Returns 0 to abort verification, 1 to continue despite error (as
1302 // OpenSSL expects from the verification callback).
1303 Q_ASSERT(q);
1304 Q_ASSERT(ctx);
1305
1306 using ScopedBool = QScopedValueRollback<bool>;
1307 // While we are not setting, we are emitting and in general -
1308 // we want to prevent accidental recursive startHandshake()
1309 // calls:
1310 const ScopedBool bg(inSetAndEmitError, true);
1311
1312 X509 *x509 = q_X509_STORE_CTX_get_current_cert(ctx);
1313 if (!x509) {
1314 qCWarning(lcTlsBackend, "Could not obtain the certificate (that failed to verify)");
1315 return 0;
1316 }
1317
1318 const QSslCertificate certificate = QTlsPrivate::X509CertificateOpenSSL::certificateFromX509(x: x509);
1319 const auto errorAndDepth = QTlsPrivate::X509CertificateOpenSSL::errorEntryFromStoreContext(ctx);
1320 const QSslError tlsError = QTlsPrivate::X509CertificateOpenSSL::openSSLErrorToQSslError(errorCode: errorAndDepth.code, cert: certificate);
1321
1322 errorsReportedFromCallback = true;
1323 handshakeInterrupted = true;
1324 emit q->handshakeInterruptedOnError(error: tlsError);
1325
1326 // Conveniently so, we also can access 'lastErrors' external data set
1327 // in startHandshake, we store it for the case an application later
1328 // wants to check errors (ignored or not):
1329 const auto offset = QTlsBackendOpenSSL::s_indexForSSLExtraData
1330 + TlsCryptographOpenSSL::errorOffsetInExData;
1331 if (auto errorList = static_cast<QList<QSslErrorEntry> *>(q_SSL_get_ex_data(ssl, idx: offset)))
1332 errorList->append(t: errorAndDepth);
1333
1334 // An application is expected to ignore this error (by calling ignoreSslErrors)
1335 // in its directly connected slot:
1336 return !handshakeInterrupted;
1337}
1338
1339void TlsCryptographOpenSSL::trySendFatalAlert()
1340{
1341 Q_ASSERT(pendingFatalAlert);
1342 Q_ASSERT(d);
1343
1344 auto *plainSocket = d->plainTcpSocket();
1345
1346 pendingFatalAlert = false;
1347 QVarLengthArray<char, 4096> data;
1348 int pendingBytes = 0;
1349 while (plainSocket->isValid() && (pendingBytes = q_BIO_pending(writeBio)) > 0
1350 && plainSocket->openMode() != QIODevice::NotOpen) {
1351 // Read encrypted data from the write BIO into a buffer.
1352 data.resize(sz: pendingBytes);
1353 const int bioReadBytes = q_BIO_read(a: writeBio, b: data.data(), c: pendingBytes);
1354
1355 // Write encrypted data from the buffer to the socket.
1356 qint64 actualWritten = plainSocket->write(data: data.constData(), len: bioReadBytes);
1357 if (actualWritten < 0)
1358 return;
1359 plainSocket->flush();
1360 }
1361}
1362
1363bool TlsCryptographOpenSSL::initSslContext()
1364{
1365 Q_ASSERT(q);
1366 Q_ASSERT(d);
1367
1368 // If no external context was set (e.g. by QHttpNetworkConnection) we will
1369 // create a new one.
1370 const auto mode = d->tlsMode();
1371 const auto configuration = q->sslConfiguration();
1372 if (!sslContextPointer)
1373 sslContextPointer = QSslContext::sharedFromConfiguration(mode, configuration, allowRootCertOnDemandLoading: d->isRootsOnDemandAllowed());
1374
1375 if (sslContextPointer->error() != QSslError::NoError) {
1376 setErrorAndEmit(d, errorCode: QAbstractSocket::SslInvalidUserDataError, errorDescription: sslContextPointer->errorString());
1377 sslContextPointer.reset();
1378 return false;
1379 }
1380
1381 // Create and initialize SSL session
1382 if (!(ssl = sslContextPointer->createSsl())) {
1383 setErrorAndEmit(d, errorCode: QAbstractSocket::SslInternalError,
1384 errorDescription: QSslSocket::tr(s: "Error creating SSL session, %1").arg(a: QTlsBackendOpenSSL::getErrorsFromOpenSsl()));
1385 return false;
1386 }
1387
1388 if (configuration.protocol() != QSsl::UnknownProtocol && mode == QSslSocket::SslClientMode) {
1389 const auto verificationPeerName = d->verificationName();
1390 // Set server hostname on TLS extension. RFC4366 section 3.1 requires it in ACE format.
1391 QString tlsHostName = verificationPeerName.isEmpty() ? q->peerName() : verificationPeerName;
1392 if (tlsHostName.isEmpty())
1393 tlsHostName = d->tlsHostName();
1394 QByteArray ace = QUrl::toAce(domain: tlsHostName);
1395 // only send the SNI header if the URL is valid and not an IP
1396 if (!ace.isEmpty()
1397 && !QHostAddress().setAddress(tlsHostName)
1398 && !(configuration.testSslOption(option: QSsl::SslOptionDisableServerNameIndication))) {
1399 // We don't send the trailing dot from the host header if present see
1400 // https://tools.ietf.org/html/rfc6066#section-3
1401 if (ace.endsWith(c: '.'))
1402 ace.chop(n: 1);
1403 if (!q_SSL_ctrl(ssl, SSL_CTRL_SET_TLSEXT_HOSTNAME, TLSEXT_NAMETYPE_host_name, parg: ace.data()))
1404 qCWarning(lcTlsBackend, "could not set SSL_CTRL_SET_TLSEXT_HOSTNAME, Server Name Indication disabled");
1405 }
1406 }
1407
1408 // Clear the session.
1409 errorList.clear();
1410
1411 // Initialize memory BIOs for encryption and decryption.
1412 readBio = q_BIO_new(a: q_BIO_s_mem());
1413 writeBio = q_BIO_new(a: q_BIO_s_mem());
1414 if (!readBio || !writeBio) {
1415 setErrorAndEmit(d, errorCode: QAbstractSocket::SslInternalError,
1416 errorDescription: QSslSocket::tr(s: "Error creating SSL session: %1").arg(a: QTlsBackendOpenSSL::getErrorsFromOpenSsl()));
1417 if (readBio)
1418 q_BIO_free(a: readBio);
1419 if (writeBio)
1420 q_BIO_free(a: writeBio);
1421 return false;
1422 }
1423
1424 // Assign the bios.
1425 q_SSL_set_bio(a: ssl, b: readBio, c: writeBio);
1426
1427 if (mode == QSslSocket::SslClientMode)
1428 q_SSL_set_connect_state(a: ssl);
1429 else
1430 q_SSL_set_accept_state(a: ssl);
1431
1432 q_SSL_set_ex_data(ssl, idx: QTlsBackendOpenSSL::s_indexForSSLExtraData, arg: this);
1433
1434#ifndef OPENSSL_NO_PSK
1435 // Set the client callback for PSK
1436 if (mode == QSslSocket::SslClientMode)
1437 q_SSL_set_psk_client_callback(ssl, callback: &q_ssl_psk_client_callback);
1438 else if (mode == QSslSocket::SslServerMode)
1439 q_SSL_set_psk_server_callback(ssl, callback: &q_ssl_psk_server_callback);
1440
1441#if OPENSSL_VERSION_NUMBER >= 0x10101006L
1442 // Set the client callback for TLSv1.3 PSK
1443 if (mode == QSslSocket::SslClientMode
1444 && QSslSocket::sslLibraryBuildVersionNumber() >= 0x10101006L) {
1445 q_SSL_set_psk_use_session_callback(s: ssl, &q_ssl_psk_use_session_callback);
1446 }
1447#endif // openssl version >= 0x10101006L
1448
1449#endif // OPENSSL_NO_PSK
1450
1451#if QT_CONFIG(ocsp)
1452 if (configuration.ocspStaplingEnabled()) {
1453 if (mode == QSslSocket::SslServerMode) {
1454 setErrorAndEmit(d, errorCode: QAbstractSocket::SslInvalidUserDataError,
1455 errorDescription: QSslSocket::tr(s: "Server-side QSslSocket does not support OCSP stapling"));
1456 return false;
1457 }
1458 if (q_SSL_set_tlsext_status_type(ssl, TLSEXT_STATUSTYPE_ocsp) != 1) {
1459 setErrorAndEmit(d, errorCode: QAbstractSocket::SslInternalError,
1460 errorDescription: QSslSocket::tr(s: "Failed to enable OCSP stapling"));
1461 return false;
1462 }
1463 }
1464
1465 ocspResponseDer.clear();
1466 const auto backendConfig = configuration.backendConfiguration();
1467 auto responsePos = backendConfig.find(key: "Qt-OCSP-response");
1468 if (responsePos != backendConfig.end()) {
1469 // This is our private, undocumented 'API' we use for the auto-testing of
1470 // OCSP-stapling. It must be a der-encoded OCSP response, presumably set
1471 // by tst_QOcsp.
1472 const QVariant data(responsePos.value());
1473 if (data.canConvert<QByteArray>())
1474 ocspResponseDer = data.toByteArray();
1475 }
1476
1477 if (ocspResponseDer.size()) {
1478 if (mode != QSslSocket::SslServerMode) {
1479 setErrorAndEmit(d, errorCode: QAbstractSocket::SslInvalidUserDataError,
1480 errorDescription: QSslSocket::tr(s: "Client-side sockets do not send OCSP responses"));
1481 return false;
1482 }
1483 }
1484#endif // ocsp
1485
1486 return true;
1487}
1488
1489void TlsCryptographOpenSSL::destroySslContext()
1490{
1491 if (ssl) {
1492 if (!q_SSL_in_init(s: ssl) && !systemOrSslErrorDetected) {
1493 // We do not send a shutdown alert here. Just mark the session as
1494 // resumable for qhttpnetworkconnection's "optimization", otherwise
1495 // OpenSSL won't start a session resumption.
1496 if (q_SSL_shutdown(a: ssl) != 1) {
1497 // Some error may be queued, clear it.
1498 const auto errors = QTlsBackendOpenSSL::getErrorsFromOpenSsl();
1499 Q_UNUSED(errors);
1500 }
1501 }
1502 q_SSL_free(a: ssl);
1503 ssl = nullptr;
1504 }
1505 sslContextPointer.reset();
1506}
1507
1508void TlsCryptographOpenSSL::storePeerCertificates()
1509{
1510 Q_ASSERT(d);
1511
1512 // Store the peer certificate and chain. For clients, the peer certificate
1513 // chain includes the peer certificate; for servers, it doesn't. Both the
1514 // peer certificate and the chain may be empty if the peer didn't present
1515 // any certificate.
1516 X509 *x509 = q_SSL_get_peer_certificate(a: ssl);
1517
1518 const auto peerCertificate = QTlsPrivate::X509CertificateOpenSSL::certificateFromX509(x: x509);
1519 QTlsBackend::storePeerCertificate(d, peerCert: peerCertificate);
1520 q_X509_free(a: x509);
1521 auto peerCertificateChain = q->peerCertificateChain();
1522 if (peerCertificateChain.isEmpty()) {
1523 peerCertificateChain = QTlsPrivate::X509CertificateOpenSSL::stackOfX509ToQSslCertificates(x509: q_SSL_get_peer_cert_chain(a: ssl));
1524 if (!peerCertificate.isNull() && d->tlsMode() == QSslSocket::SslServerMode)
1525 peerCertificateChain.prepend(t: peerCertificate);
1526 QTlsBackend::storePeerCertificateChain(d, peerChain: peerCertificateChain);
1527 }
1528}
1529
1530#if QT_CONFIG(ocsp)
1531
1532bool TlsCryptographOpenSSL::checkOcspStatus()
1533{
1534 Q_ASSERT(ssl);
1535 Q_ASSERT(d);
1536
1537 const auto &configuration = q->sslConfiguration();
1538 Q_ASSERT(d->tlsMode() == QSslSocket::SslClientMode); // See initSslContext() for SslServerMode
1539 Q_ASSERT(configuration.peerVerifyMode() != QSslSocket::VerifyNone);
1540
1541 const auto clearErrorQueue = qScopeGuard(f: [] {
1542 QTlsBackendOpenSSL::logAndClearErrorQueue();
1543 });
1544
1545 ocspResponses.clear();
1546 ocspErrorDescription.clear();
1547 ocspErrors.clear();
1548
1549 const unsigned char *responseData = nullptr;
1550 const long responseLength = q_SSL_get_tlsext_status_ocsp_resp(ssl, &responseData);
1551 if (responseLength <= 0 || !responseData) {
1552 ocspErrors.push_back(t: QSslError(QSslError::OcspNoResponseFound));
1553 return false;
1554 }
1555
1556 OCSP_RESPONSE *response = q_d2i_OCSP_RESPONSE(a: nullptr, in: &responseData, len: responseLength);
1557 if (!response) {
1558 // Treat this as a fatal SslHandshakeError.
1559 ocspErrorDescription = QSslSocket::tr(s: "Failed to decode OCSP response");
1560 return false;
1561 }
1562 const QSharedPointer<OCSP_RESPONSE> responseGuard(response, q_OCSP_RESPONSE_free);
1563
1564 const int ocspStatus = q_OCSP_response_status(resp: response);
1565 if (ocspStatus != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
1566 // It's not a definitive response, it's an error message (not signed by the responder).
1567 ocspErrors.push_back(t: QSslError(qt_OCSP_response_status_to_SslError(code: ocspStatus)));
1568 return false;
1569 }
1570
1571 OCSP_BASICRESP *basicResponse = q_OCSP_response_get1_basic(resp: response);
1572 if (!basicResponse) {
1573 // SslHandshakeError.
1574 ocspErrorDescription = QSslSocket::tr(s: "Failed to extract basic OCSP response");
1575 return false;
1576 }
1577 const QSharedPointer<OCSP_BASICRESP> basicResponseGuard(basicResponse, q_OCSP_BASICRESP_free);
1578
1579 SSL_CTX *ctx = q_SSL_get_SSL_CTX(a: ssl); // Does not increment refcount.
1580 Q_ASSERT(ctx);
1581 X509_STORE *store = q_SSL_CTX_get_cert_store(a: ctx); // Does not increment refcount.
1582 if (!store) {
1583 // SslHandshakeError.
1584 ocspErrorDescription = QSslSocket::tr(s: "No certificate verification store, cannot verify OCSP response");
1585 return false;
1586 }
1587
1588 STACK_OF(X509) *peerChain = q_SSL_get_peer_cert_chain(a: ssl); // Does not increment refcount.
1589 X509 *peerX509 = q_SSL_get_peer_certificate(a: ssl);
1590 Q_ASSERT(peerChain || peerX509);
1591 const QSharedPointer<X509> peerX509Guard(peerX509, q_X509_free);
1592 // OCSP_basic_verify with 0 as verificationFlags:
1593 //
1594 // 0) Tries to find the OCSP responder's certificate in either peerChain
1595 // or basicResponse->certs. If not found, verification fails.
1596 // 1) It checks the signature using the responder's public key.
1597 // 2) Then it tries to validate the responder's cert (building a chain
1598 // etc.)
1599 // 3) It checks CertID in response.
1600 // 4) Ensures the responder is authorized to sign the status respond.
1601 //
1602 // Note, OpenSSL prior to 1.0.2b would only use bs->certs to
1603 // verify the responder's chain (see their commit 4ba9a4265bd).
1604 // Working this around - is too much fuss for ancient versions we
1605 // are dropping quite soon anyway.
1606 const unsigned long verificationFlags = 0;
1607 const int success = q_OCSP_basic_verify(bs: basicResponse, certs: peerChain, st: store, flags: verificationFlags);
1608 if (success <= 0)
1609 ocspErrors.push_back(t: QSslError(QSslError::OcspResponseCannotBeTrusted));
1610
1611 if (q_OCSP_resp_count(bs: basicResponse) != 1) {
1612 ocspErrors.push_back(t: QSslError(QSslError::OcspMalformedResponse));
1613 return false;
1614 }
1615
1616 OCSP_SINGLERESP *singleResponse = q_OCSP_resp_get0(bs: basicResponse, idx: 0);
1617 if (!singleResponse) {
1618 ocspErrors.clear();
1619 // A fatal problem -> SslHandshakeError.
1620 ocspErrorDescription = QSslSocket::tr(s: "Failed to decode a SingleResponse from OCSP status response");
1621 return false;
1622 }
1623
1624 // Let's make sure the response is for the correct certificate - we
1625 // can re-create this CertID using our peer's certificate and its
1626 // issuer's public key.
1627 ocspResponses.push_back(t: QOcspResponse());
1628 QOcspResponsePrivate *dResponse = ocspResponses.back().d.data();
1629 dResponse->subjectCert = configuration.peerCertificate();
1630 bool matchFound = false;
1631 if (dResponse->subjectCert.isSelfSigned()) {
1632 dResponse->signerCert = configuration.peerCertificate();
1633 matchFound = qt_OCSP_certificate_match(singleResponse, peerCert: peerX509, issuer: peerX509);
1634 } else {
1635 const STACK_OF(X509) *certs = q_SSL_get_peer_cert_chain(a: ssl);
1636 if (!certs) // Oh, what a cataclysm! Last try:
1637 certs = q_OCSP_resp_get0_certs(bs: basicResponse);
1638 if (certs) {
1639 // It could be the first certificate in 'certs' is our peer's
1640 // certificate. Since it was not captured by the 'self-signed' branch
1641 // above, the CertID will not match and we'll just iterate on to the
1642 // next certificate. So we start from 0, not 1.
1643 for (int i = 0, e = q_sk_X509_num(certs); i < e; ++i) {
1644 X509 *issuer = q_sk_X509_value(certs, i);
1645 matchFound = qt_OCSP_certificate_match(singleResponse, peerCert: peerX509, issuer);
1646 if (matchFound) {
1647 if (q_X509_check_issued(a: issuer, b: peerX509) == X509_V_OK) {
1648 dResponse->signerCert = QTlsPrivate::X509CertificateOpenSSL::certificateFromX509(x: issuer);
1649 break;
1650 }
1651 matchFound = false;
1652 }
1653 }
1654 }
1655 }
1656
1657 if (!matchFound) {
1658 dResponse->signerCert.clear();
1659 ocspErrors.push_back(t: {QSslError::OcspResponseCertIdUnknown, configuration.peerCertificate()});
1660 }
1661
1662 // Check if the response is valid time-wise:
1663 ASN1_GENERALIZEDTIME *revTime = nullptr;
1664 ASN1_GENERALIZEDTIME *thisUpdate = nullptr;
1665 ASN1_GENERALIZEDTIME *nextUpdate = nullptr;
1666 int reason;
1667 const int certStatus = q_OCSP_single_get0_status(single: singleResponse, reason: &reason, revtime: &revTime, thisupd: &thisUpdate, nextupd: &nextUpdate);
1668 if (!thisUpdate) {
1669 // This is unexpected, treat as SslHandshakeError, OCSP_check_validity assumes this pointer
1670 // to be != nullptr.
1671 ocspErrors.clear();
1672 ocspResponses.clear();
1673 ocspErrorDescription = QSslSocket::tr(s: "Failed to extract 'this update time' from the SingleResponse");
1674 return false;
1675 }
1676
1677 // OCSP_check_validity(this, next, nsec, maxsec) does this check:
1678 // this <= now <= next. They allow some freedom to account
1679 // for delays/time inaccuracy.
1680 // this > now + nsec ? -> NOT_YET_VALID
1681 // if maxsec >= 0:
1682 // now - maxsec > this ? -> TOO_OLD
1683 // now - nsec > next ? -> EXPIRED
1684 // next < this ? -> NEXT_BEFORE_THIS
1685 // OK.
1686 if (!q_OCSP_check_validity(thisupd: thisUpdate, nextupd: nextUpdate, nsec: 60, maxsec: -1))
1687 ocspErrors.push_back(t: {QSslError::OcspResponseExpired, configuration.peerCertificate()});
1688
1689 // And finally, the status:
1690 switch (certStatus) {
1691 case V_OCSP_CERTSTATUS_GOOD:
1692 // This certificate was not found among the revoked ones.
1693 dResponse->certificateStatus = QOcspCertificateStatus::Good;
1694 break;
1695 case V_OCSP_CERTSTATUS_REVOKED:
1696 dResponse->certificateStatus = QOcspCertificateStatus::Revoked;
1697 dResponse->revocationReason = qt_OCSP_revocation_reason(reason);
1698 ocspErrors.push_back(t: {QSslError::CertificateRevoked, configuration.peerCertificate()});
1699 break;
1700 case V_OCSP_CERTSTATUS_UNKNOWN:
1701 dResponse->certificateStatus = QOcspCertificateStatus::Unknown;
1702 ocspErrors.push_back(t: {QSslError::OcspStatusUnknown, configuration.peerCertificate()});
1703 }
1704
1705 return !ocspErrors.size();
1706}
1707
1708#endif // QT_CONFIG(ocsp)
1709
1710
1711unsigned TlsCryptographOpenSSL::pskClientTlsCallback(const char *hint, char *identity,
1712 unsigned max_identity_len,
1713 unsigned char *psk, unsigned max_psk_len)
1714{
1715 Q_ASSERT(q);
1716
1717 QSslPreSharedKeyAuthenticator authenticator;
1718 // Fill in some read-only fields (for the user)
1719 const int hintLength = hint ? int(std::strlen(s: hint)) : 0;
1720 QTlsBackend::setupClientPskAuth(auth: &authenticator, hint, hintLength, maxIdentityLen: max_identity_len, maxPskLen: max_psk_len);
1721 // Let the client provide the remaining bits...
1722 emit q->preSharedKeyAuthenticationRequired(authenticator: &authenticator);
1723
1724 // No PSK set? Return now to make the handshake fail
1725 if (authenticator.preSharedKey().isEmpty())
1726 return 0;
1727
1728 // Copy data back into OpenSSL
1729 const int identityLength = qMin(a: authenticator.identity().size(), b: authenticator.maximumIdentityLength());
1730 std::memcpy(dest: identity, src: authenticator.identity().constData(), n: identityLength);
1731 identity[identityLength] = 0;
1732
1733 const int pskLength = qMin(a: authenticator.preSharedKey().size(), b: authenticator.maximumPreSharedKeyLength());
1734 std::memcpy(dest: psk, src: authenticator.preSharedKey().constData(), n: pskLength);
1735 return pskLength;
1736}
1737
1738unsigned TlsCryptographOpenSSL::pskServerTlsCallback(const char *identity, unsigned char *psk,
1739 unsigned max_psk_len)
1740{
1741 Q_ASSERT(q);
1742
1743 QSslPreSharedKeyAuthenticator authenticator;
1744
1745 // Fill in some read-only fields (for the user)
1746 QTlsBackend::setupServerPskAuth(auth: &authenticator, identity, identityHint: q->sslConfiguration().preSharedKeyIdentityHint(),
1747 maxPskLen: max_psk_len);
1748 emit q->preSharedKeyAuthenticationRequired(authenticator: &authenticator);
1749
1750 // No PSK set? Return now to make the handshake fail
1751 if (authenticator.preSharedKey().isEmpty())
1752 return 0;
1753
1754 // Copy data back into OpenSSL
1755 const int pskLength = qMin(a: authenticator.preSharedKey().size(), b: authenticator.maximumPreSharedKeyLength());
1756 std::memcpy(dest: psk, src: authenticator.preSharedKey().constData(), n: pskLength);
1757 return pskLength;
1758}
1759
1760bool TlsCryptographOpenSSL::isInSslRead() const
1761{
1762 return inSslRead;
1763}
1764
1765void TlsCryptographOpenSSL::setRenegotiated(bool renegotiated)
1766{
1767 this->renegotiated = renegotiated;
1768}
1769
1770#ifdef Q_OS_WIN
1771
1772void TlsCryptographOpenSSL::fetchCaRootForCert(const QSslCertificate &cert)
1773{
1774 Q_ASSERT(d);
1775 Q_ASSERT(q);
1776
1777 //The root certificate is downloaded from windows update, which blocks for 15 seconds in the worst case
1778 //so the request is done in a worker thread.
1779 QList<QSslCertificate> customRoots;
1780 if (fetchAuthorityInformation)
1781 customRoots = q->sslConfiguration().caCertificates();
1782
1783 //Remember we are fetching and what we are fetching:
1784 caToFetch = cert;
1785
1786 QWindowsCaRootFetcher *fetcher = new QWindowsCaRootFetcher(cert, d->tlsMode(), customRoots,
1787 q->peerVerifyName());
1788 connect(fetcher, &QWindowsCaRootFetcher::finished, this, &TlsCryptographOpenSSL::caRootLoaded,
1789 Qt::QueuedConnection);
1790 QMetaObject::invokeMethod(fetcher, "start", Qt::QueuedConnection);
1791 QSslSocketPrivate::pauseSocketNotifiers(q);
1792 d->setPaused(true);
1793}
1794
1795void TlsCryptographOpenSSL::caRootLoaded(QSslCertificate cert, QSslCertificate trustedRoot)
1796{
1797 if (caToFetch != cert) {
1798 //Ooops, something from the previous connection attempt, ignore!
1799 return;
1800 }
1801
1802 Q_ASSERT(d);
1803 Q_ASSERT(q);
1804
1805 //Done, fetched already:
1806 caToFetch.reset();
1807
1808 if (fetchAuthorityInformation) {
1809 if (!q->sslConfiguration().caCertificates().contains(trustedRoot))
1810 trustedRoot = QSslCertificate{};
1811 fetchAuthorityInformation = false;
1812 }
1813
1814 if (!trustedRoot.isNull() && !trustedRoot.isBlacklisted()) {
1815 if (QSslSocketPrivate::rootCertOnDemandLoadingSupported()) {
1816 //Add the new root cert to default cert list for use by future sockets
1817 auto defaultConfig = QSslConfiguration::defaultConfiguration();
1818 defaultConfig.addCaCertificate(trustedRoot);
1819 QSslConfiguration::setDefaultConfiguration(defaultConfig);
1820 }
1821 //Add the new root cert to this socket for future connections
1822 QTlsBackend::addTustedRoot(d, trustedRoot);
1823 //Remove the broken chain ssl errors (as chain is verified by windows)
1824 for (int i=sslErrors.count() - 1; i >= 0; --i) {
1825 if (sslErrors.at(i).certificate() == cert) {
1826 switch (sslErrors.at(i).error()) {
1827 case QSslError::UnableToGetLocalIssuerCertificate:
1828 case QSslError::CertificateUntrusted:
1829 case QSslError::UnableToVerifyFirstCertificate:
1830 case QSslError::SelfSignedCertificateInChain:
1831 // error can be ignored if OS says the chain is trusted
1832 sslErrors.removeAt(i);
1833 break;
1834 default:
1835 // error cannot be ignored
1836 break;
1837 }
1838 }
1839 }
1840 }
1841
1842 auto *plainSocket = d->plainTcpSocket();
1843 Q_ASSERT(plainSocket);
1844 // Continue with remaining errors
1845 if (plainSocket)
1846 plainSocket->resume();
1847 d->setPaused(false);
1848 if (checkSslErrors() && ssl) {
1849 bool willClose = (d->isAutoStartingHandshake() && d->isPendingClose());
1850 continueHandshake();
1851 if (!willClose)
1852 transmit();
1853 }
1854}
1855
1856#endif // Q_OS_WIN
1857
1858} // namespace QTlsPrivate
1859
1860QT_END_NAMESPACE
1861

source code of qtbase/src/plugins/tls/openssl/qtls_openssl.cpp