QtBase  v6.3.1
qsslconfiguration.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Copyright (C) 2014 BlackBerry Limited. All rights reserved.
5 ** Contact: https://www.qt.io/licensing/
6 **
7 ** This file is part of the QtNetwork module of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** Commercial License Usage
11 ** Licensees holding valid commercial Qt licenses may use this file in
12 ** accordance with the commercial license agreement provided with the
13 ** Software or, alternatively, in accordance with the terms contained in
14 ** a written agreement between you and The Qt Company. For licensing terms
15 ** and conditions see https://www.qt.io/terms-conditions. For further
16 ** information use the contact form at https://www.qt.io/contact-us.
17 **
18 ** GNU Lesser General Public License Usage
19 ** Alternatively, this file may be used under the terms of the GNU Lesser
20 ** General Public License version 3 as published by the Free Software
21 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
22 ** packaging of this file. Please review the following information to
23 ** ensure the GNU Lesser General Public License version 3 requirements
24 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
25 **
26 ** GNU General Public License Usage
27 ** Alternatively, this file may be used under the terms of the GNU
28 ** General Public License version 2.0 or (at your option) the GNU General
29 ** Public license version 3 or any later version approved by the KDE Free
30 ** Qt Foundation. The licenses are as published by the Free Software
31 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
32 ** included in the packaging of this file. Please review the following
33 ** information to ensure the GNU General Public License requirements will
34 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
35 ** https://www.gnu.org/licenses/gpl-3.0.html.
36 **
37 ** $QT_END_LICENSE$
38 **
39 ****************************************************************************/
40 
41 #include "qssl_p.h"
42 #include "qsslconfiguration.h"
43 #include "qsslconfiguration_p.h"
44 #include "qsslsocket.h"
45 #include "qsslsocket_p.h"
46 #include "qmutex.h"
47 #include "qdebug.h"
48 
50 
55 
56 const char QSslConfiguration::ALPNProtocolHTTP2[] = "h2";
57 const char QSslConfiguration::NextProtocolHttp1_1[] = "http/1.1";
58 
150 {
151 }
152 
158  : d(other.d)
159 {
160 }
161 
166 {
167  // QSharedDataPointer deletes d for us if necessary
168 }
169 
175 {
176  d = other.d;
177  return *this;
178 }
179 
198 {
199  if (d == other.d)
200  return true;
201  return d->peerCertificate == other.d->peerCertificate &&
202  d->peerCertificateChain == other.d->peerCertificateChain &&
203  d->localCertificateChain == other.d->localCertificateChain &&
204  d->privateKey == other.d->privateKey &&
205  d->sessionCipher == other.d->sessionCipher &&
206  d->sessionProtocol == other.d->sessionProtocol &&
207  d->preSharedKeyIdentityHint == other.d->preSharedKeyIdentityHint &&
208  d->ciphers == other.d->ciphers &&
209  d->ellipticCurves == other.d->ellipticCurves &&
210  d->ephemeralServerKey == other.d->ephemeralServerKey &&
211  d->dhParams == other.d->dhParams &&
212  d->caCertificates == other.d->caCertificates &&
213  d->protocol == other.d->protocol &&
214  d->peerVerifyMode == other.d->peerVerifyMode &&
215  d->peerVerifyDepth == other.d->peerVerifyDepth &&
216  d->allowRootCertOnDemandLoading == other.d->allowRootCertOnDemandLoading &&
217  d->backendConfig == other.d->backendConfig &&
218  d->sslOptions == other.d->sslOptions &&
219  d->sslSession == other.d->sslSession &&
220  d->sslSessionTicketLifeTimeHint == other.d->sslSessionTicketLifeTimeHint &&
221  d->nextAllowedProtocols == other.d->nextAllowedProtocols &&
222  d->nextNegotiatedProtocol == other.d->nextNegotiatedProtocol &&
223  d->nextProtocolNegotiationStatus == other.d->nextProtocolNegotiationStatus &&
224  d->dtlsCookieEnabled == other.d->dtlsCookieEnabled &&
225  d->ocspStaplingEnabled == other.d->ocspStaplingEnabled &&
226  d->reportFromCallback == other.d->reportFromCallback &&
227  d->missingCertIsFatal == other.d->missingCertIsFatal;
228 }
229 
250 {
251  return (d->protocol == QSsl::SecureProtocols &&
253  d->peerVerifyDepth == 0 &&
254  d->allowRootCertOnDemandLoading == true &&
255  d->caCertificates.count() == 0 &&
256  d->ciphers.count() == 0 &&
257  d->ellipticCurves.isEmpty() &&
258  d->ephemeralServerKey.isNull() &&
261  d->privateKey.isNull() &&
262  d->peerCertificate.isNull() &&
263  d->peerCertificateChain.count() == 0 &&
264  d->backendConfig.isEmpty() &&
266  d->sslSession.isNull() &&
267  d->sslSessionTicketLifeTimeHint == -1 &&
272  d->ocspStaplingEnabled == false &&
273  d->reportFromCallback == false &&
274  d->missingCertIsFatal == false);
275 }
276 
283 {
284  return d->protocol;
285 }
286 
297 {
298  d->protocol = protocol;
299 }
300 
313 {
314  return d->peerVerifyMode;
315 }
316 
329 {
330  d->peerVerifyMode = mode;
331 }
332 
333 
346 {
347  return d->peerVerifyDepth;
348 }
349 
362 {
363  if (depth < 0) {
364  qCWarning(lcSsl,
365  "QSslConfiguration::setPeerVerifyDepth: cannot set negative depth of %d", depth);
366  return;
367  }
368  d->peerVerifyDepth = depth;
369 }
370 
379 {
380  return d->localCertificateChain;
381 }
382 
406 {
407  d->localCertificateChain = localChain;
408 }
409 
417 {
419  return QSslCertificate();
420  return d->localCertificateChain[0];
421 }
422 
440 {
442  d->localCertificateChain += certificate;
443 }
444 
474 {
475  return d->peerCertificate;
476 }
477 
506 {
507  return d->peerCertificateChain;
508 }
509 
524 {
525  return d->sessionCipher;
526 }
527 
537 {
538  return d->sessionProtocol;
539 }
540 
548 {
549  return d->privateKey;
550 }
551 
566 {
567  d->privateKey = key;
568 }
569 
592 {
593  return d->ciphers;
594 }
595 
609 {
610  d->ciphers = ciphers;
611 }
612 
632 {
633  auto *p = d.data();
634  p->ciphers.clear();
635  const auto cipherNames = ciphers.split(QLatin1Char(':'), Qt::SkipEmptyParts);
636  for (const QString &cipherName : cipherNames) {
637  QSslCipher cipher(cipherName);
638  if (!cipher.isNull())
639  p->ciphers << cipher;
640  }
641 }
642 
653 {
655 }
656 
667 {
668  return d->caCertificates;
669 }
670 
684 {
685  d->caCertificates = certificates;
686  d->allowRootCertOnDemandLoading = false;
687 }
688 
708 {
710  if (certs.isEmpty())
711  return false;
712 
713  d->caCertificates += certs;
714  return true;
715 }
716 
732 {
733  d->caCertificates += certificate;
734  d->allowRootCertOnDemandLoading = false;
735 }
736 
752 {
753  d->caCertificates += certificates;
754  d->allowRootCertOnDemandLoading = false;
755 }
756 
769 {
770  // we are calling ensureInitialized() in the method below
772 }
773 
782 {
783  d->sslOptions.setFlag(option, on);
784 }
785 
794 {
795  return d->sslOptions & option;
796 }
797 
815 {
816  return d->sslSession;
817 }
818 
830 {
832 }
833 
848 {
850 }
851 
865 {
866  return d->ephemeralServerKey;
867 }
868 
892 {
893  return d->ellipticCurves;
894 }
895 
909 {
910  d->ellipticCurves = curves;
911 }
912 
923 {
925 }
926 
935 {
936  return d->preSharedKeyIdentityHint;
937 }
938 
949 {
950  d->preSharedKeyIdentityHint = hint;
951 }
952 
962 {
963  return d->dhParams;
964 }
965 
976 {
977  d->dhParams = dhparams;
978 }
979 
991 {
992  return d->backendConfig;
993 }
994 
1014 {
1015  d->backendConfig[name] = value;
1016 }
1017 
1030 {
1032 }
1033 
1049 {
1050  return d->nextNegotiatedProtocol;
1051 }
1052 
1068 {
1069  d->nextAllowedProtocols = protocols;
1070 }
1071 
1082 {
1083  return d->nextAllowedProtocols;
1084 }
1085 
1098 {
1100 }
1101 
1119 {
1121 }
1122 
1131 {
1133 }
1134 
1135 #if QT_CONFIG(dtls) || defined(Q_CLANG_QDOC)
1136 
1143 bool QSslConfiguration::dtlsCookieVerificationEnabled() const
1144 {
1145  return d->dtlsCookieEnabled;
1146 }
1147 
1154 {
1156 }
1157 
1175 QSslConfiguration QSslConfiguration::defaultDtlsConfiguration()
1176 {
1178 }
1179 
1187 void QSslConfiguration::setDefaultDtlsConfiguration(const QSslConfiguration &configuration)
1188 {
1190 }
1191 
1192 #endif // dtls
1193 
1204 {
1205 #if QT_CONFIG(ocsp)
1207 #else
1208  if (enabled)
1209  qCWarning(lcSsl, "Enabling OCSP-stapling requires the feature 'ocsp'");
1210 #endif // ocsp
1211 }
1212 
1221 {
1222  return d->ocspStaplingEnabled;
1223 }
1224 
1236 {
1237  return d->reportFromCallback;
1238 }
1239 
1263 {
1264 #if QT_CONFIG(openssl)
1265  d->reportFromCallback = interrupt;
1266 #else
1267  Q_UNUSED(interrupt);
1268  qCWarning(lcSsl, "This operation requires OpenSSL as TLS backend");
1269 #endif
1270 }
1271 
1283 {
1284  return d->missingCertIsFatal;
1285 }
1286 
1301 {
1302 #if QT_CONFIG(openssl)
1303  d->missingCertIsFatal = cannotRecover;
1304 #else
1305  Q_UNUSED(cannotRecover);
1306  qCWarning(lcSsl, "Handling a missing certificate as a fatal error requires an OpenSSL backend");
1307 #endif // openssl
1308 }
1309 
1313  return configuration.d->peerSessionShared;
1314  }
1315 
#define value
[5]
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:85
bool isNull() const noexcept
bool isEmpty() const noexcept
Definition: qlist.h:418
qsizetype count() const noexcept
Definition: qlist.h:415
void clear()
Definition: qlist.h:445
bool isEmpty() const
Definition: qmap.h:304
The QSslCertificate class provides a convenient API for an X509 certificate.
static QList< QSslCertificate > fromPath(const QString &path, QSsl::EncodingFormat format=QSsl::Pem, PatternSyntax syntax=PatternSyntax::FixedString)
bool isNull() const
The QSslCipher class represents an SSL cryptographic cipher.
Definition: qsslcipher.h:58
bool isNull() const
Definition: qsslcipher.cpp:180
The QSslConfiguration class holds the configuration and state of an SSL connection.
QList< QByteArray > allowedNextProtocols() const
QSslCertificate localCertificate() const
bool testSslOption(QSsl::SslOption option) const
void setSessionTicket(const QByteArray &sessionTicket)
void setEllipticCurves(const QList< QSslEllipticCurve > &curves)
QSslConfiguration & operator=(QSslConfiguration &&other) noexcept
QList< QSslCertificate > caCertificates() const
void setPeerVerifyMode(QSslSocket::PeerVerifyMode mode)
bool ocspStaplingEnabled() const
QList< QSslCertificate > localCertificateChain() const
void setMissingCertificateIsFatal(bool cannotRecover)
void setBackendConfigurationOption(const QByteArray &name, const QVariant &value)
QSslSocket::PeerVerifyMode peerVerifyMode() const
QSsl::SslProtocol protocol() const
static const char ALPNProtocolHTTP2[]
QSslKey ephemeralServerKey() const
void setHandshakeMustInterruptOnError(bool interrupt)
QSslDiffieHellmanParameters diffieHellmanParameters() const
QSslConfiguration()
The value used for negotiating HTTP 1.1 during the Next Protocol Negotiation.
QByteArray preSharedKeyIdentityHint() const
int sessionTicketLifeTimeHint() const
QSsl::SslProtocol sessionProtocol() const
static void setDefaultConfiguration(const QSslConfiguration &configuration)
void setDiffieHellmanParameters(const QSslDiffieHellmanParameters &dhparams)
bool operator==(const QSslConfiguration &other) const
QSslCipher sessionCipher() const
QByteArray nextNegotiatedProtocol() const
QSslKey privateKey() const
void addCaCertificate(const QSslCertificate &certificate)
QList< QSslEllipticCurve > ellipticCurves() const
void setSslOption(QSsl::SslOption option, bool on)
QList< QSslCipher > ciphers() const
void setBackendConfiguration(const QMap< QByteArray, QVariant > &backendConfiguration=QMap< QByteArray, QVariant >())
QByteArray sessionTicket() const
void setLocalCertificate(const QSslCertificate &certificate)
QList< QSslCertificate > peerCertificateChain() const
bool handshakeMustInterruptOnError() const
void setPreSharedKeyIdentityHint(const QByteArray &hint)
bool missingCertificateIsFatal() const
static QList< QSslCipher > supportedCiphers()
bool addCaCertificates(const QString &path, QSsl::EncodingFormat format=QSsl::Pem, QSslCertificate::PatternSyntax syntax=QSslCertificate::PatternSyntax::FixedString)
QMap< QByteArray, QVariant > backendConfiguration() const
static QList< QSslCertificate > systemCaCertificates()
void setPrivateKey(const QSslKey &key)
void setAllowedNextProtocols(const QList< QByteArray > &protocols)
void setLocalCertificateChain(const QList< QSslCertificate > &localChain)
QSslCertificate peerCertificate() const
static const char NextProtocolHttp1_1[]
void setCiphers(const QList< QSslCipher > &ciphers)
void setPeerVerifyDepth(int depth)
static QSslConfiguration defaultConfiguration()
void setOcspStaplingEnabled(bool enable)
static QList< QSslEllipticCurve > supportedEllipticCurves()
void setCaCertificates(const QList< QSslCertificate > &certificates)
void setProtocol(QSsl::SslProtocol protocol)
NextProtocolNegotiationStatus nextProtocolNegotiationStatus() const
static Q_AUTOTEST_EXPORT bool peerSessionWasShared(const QSslConfiguration &configuration)
QSslSocket::PeerVerifyMode peerVerifyMode
QList< QSslEllipticCurve > ellipticCurves
QSslConfiguration::NextProtocolNegotiationStatus nextProtocolNegotiationStatus
QList< QSslCertificate > caCertificates
static QSslConfiguration defaultConfiguration()
static void setDefaultDtlsConfiguration(const QSslConfiguration &configuration)
static const QSsl::SslOptions defaultSslOptions
QMap< QByteArray, QVariant > backendConfig
QList< QSslCertificate > peerCertificateChain
static void setDefaultConfiguration(const QSslConfiguration &configuration)
QList< QByteArray > nextAllowedProtocols
QList< QSslCipher > ciphers
QSsl::SslProtocol sessionProtocol
QList< QSslCertificate > localCertificateChain
QSslDiffieHellmanParameters dhParams
static QSslConfiguration defaultDtlsConfiguration()
The QSslDiffieHellmanParameters class provides an interface for Diffie-Hellman parameters for servers...
static QSslDiffieHellmanParameters defaultParameters()
The QSslKey class provides an interface for private and public keys.
Definition: qsslkey.h:59
bool isNull() const
Definition: qsslkey_p.cpp:263
@ AutoVerifyPeer
Definition: qsslsocket.h:79
static QList< QSslCipher > supportedCiphers()
static QList< QSslEllipticCurve > supportedEllipticCurves()
static QList< QSslCertificate > systemCaCertificates()
The QString class provides a Unicode character string.
Definition: qstring.h:388
The QVariant class acts like a union for the most common Qt data types.
Definition: qvariant.h:95
EncodingFormat
Definition: qssl.h:56
SslOption
Definition: qssl.h:97
@ SslOptionDisableSessionPersistence
Definition: qssl.h:104
@ SslOptionDisableCompression
Definition: qssl.h:100
@ SslOptionDisableLegacyRenegotiation
Definition: qssl.h:102
@ SslOptionDisableEmptyFragments
Definition: qssl.h:98
SslProtocol
Definition: qssl.h:75
@ SecureProtocols
Definition: qssl.h:80
@ SkipEmptyParts
Definition: qnamespace.h:153
EGLOutputLayerEXT EGLint EGLAttrib value
#define qCWarning(category,...)
GLint GLenum GLsizei GLsizei GLsizei depth
GLenum mode
GLuint64 key
GLenum GLenum GLsizei const GLuint GLboolean enabled
GLboolean enable
GLuint name
GLint GLsizei GLsizei GLenum format
GLsizei const GLchar *const * path
Definition: qopenglext.h:4283
GLfloat GLfloat p
[1]
Definition: qopenglext.h:12698
GLuint GLenum option
Definition: qopenglext.h:5929
#define enabled
Definition: qopenglext.h:3098
Q_UNUSED(salary)
[21]
QSharedPointer< T > other(t)
[5]
config setDtlsCookieVerificationEnabled(false)
const auto certs
[1]
The QLatin1Char class provides an 8-bit ASCII/Latin-1 character.
Definition: qchar.h:53