aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTatiana Borisova <tatiana.borisova@qt.io>2023-08-17 18:54:33 +0200
committerTatiana Borisova <tatiana.borisova@qt.io>2023-10-05 12:13:20 +0200
commitb44f466621868128672163d3044e508debd57601 (patch)
treec312339ba11f3410fa40145c590cf2d62b2a92cf
parent53bb1758f26e0a7c6e511f445edbc68a20af9f09 (diff)
Add QSslConfiguration and QSslKey to the QtNetwork QML module
Task-number: QTBUG-115056 Change-Id: I14d55e9ef58f0e45c177f39e74ac15c3035e3342 Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
-rw-r--r--src/qml/configure.cmake2
-rw-r--r--src/qmlnetwork/CMakeLists.txt7
-rw-r--r--src/qmlnetwork/ssl/qqmlssl.qdoc200
-rw-r--r--src/qmlnetwork/ssl/qqmlsslconfiguration.cpp175
-rw-r--r--src/qmlnetwork/ssl/qqmlsslconfiguration_p.h109
-rw-r--r--src/qmlnetwork/ssl/qqmlsslkey.cpp68
-rw-r--r--src/qmlnetwork/ssl/qqmlsslkey_p.h77
-rw-r--r--src/qmlnetwork/ssl/qqmlsslnamespace_p.h36
-rw-r--r--src/qmlnetwork/ssl/qqmlsslsocketnamespace_p.h36
-rw-r--r--tests/auto/qmlnetwork/CMakeLists.txt4
-rw-r--r--tests/auto/qmlnetwork/qqmlsslconfiguration/CMakeLists.txt43
-rw-r--r--tests/auto/qmlnetwork/qqmlsslconfiguration/data/cert.pem34
-rw-r--r--tests/auto/qmlnetwork/qqmlsslconfiguration/data/key.pem52
-rw-r--r--tests/auto/qmlnetwork/qqmlsslconfiguration/qml/tst_sslconfiguration.qml158
-rw-r--r--tests/auto/qmlnetwork/qqmlsslconfiguration/tst_sslconfiguration_qml.cpp6
-rw-r--r--tests/auto/qmlnetwork/qqmlsslkey/CMakeLists.txt29
-rw-r--r--tests/auto/qmlnetwork/qqmlsslkey/qml/tst_sslkey.qml60
-rw-r--r--tests/auto/qmlnetwork/qqmlsslkey/tst_sslkey_qml.cpp6
18 files changed, 1101 insertions, 1 deletions
diff --git a/src/qml/configure.cmake b/src/qml/configure.cmake
index bdf8eb6ab3..2d0434643a 100644
--- a/src/qml/configure.cmake
+++ b/src/qml/configure.cmake
@@ -82,7 +82,7 @@ qt_feature("qml-ssl" PUBLIC
SECTION "QML"
LABEL "QML SSL support"
PURPOSE "Provides ssl support in QML."
- ENABLE QT_FEATURE_ssl
+ CONDITION QT_FEATURE_ssl
)
# On arm and arm64 we need a specialization of cacheFlush() for each OS to be
diff --git a/src/qmlnetwork/CMakeLists.txt b/src/qmlnetwork/CMakeLists.txt
index 5e998c57cb..777cbb737b 100644
--- a/src/qmlnetwork/CMakeLists.txt
+++ b/src/qmlnetwork/CMakeLists.txt
@@ -18,6 +18,13 @@ qt_internal_add_qml_module(QmlNetwork
GENERATE_PRIVATE_CPP_EXPORTS
)
+qt_internal_extend_target(QmlNetwork CONDITION QT_FEATURE_qml_ssl
+ SOURCES
+ ssl/qqmlsslnamespace_p.h ssl/qqmlsslsocketnamespace_p.h
+ ssl/qqmlsslconfiguration.cpp ssl/qqmlsslconfiguration_p.h
+ ssl/qqmlsslkey_p.h ssl/qqmlsslkey.cpp
+)
+
qt_internal_add_docs(QmlNetwork
doc/qtqmlnetwork.qdocconf
)
diff --git a/src/qmlnetwork/ssl/qqmlssl.qdoc b/src/qmlnetwork/ssl/qqmlssl.qdoc
new file mode 100644
index 0000000000..cf3eb0802d
--- /dev/null
+++ b/src/qmlnetwork/ssl/qqmlssl.qdoc
@@ -0,0 +1,200 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
+
+/*!
+ \qmltype sslConfiguration
+ \inqmlmodule QtNetwork
+
+ \brief The sslConfiguration class holds the configuration and state of an
+ SSL connection.
+
+ sslConfiguration is used to relay information
+ about an open SSL connection and to allow the application to control
+ certain features of that connection.
+ The sslConfiguration encapsulates QSslConfiguration object inside.
+ The sslConfiguration calls defaultSslCongiguration in ctor.
+
+ \sa QSslConfiguration
+*/
+
+/*!
+ \qmlproperty QList sslConfiguration::sslOptions
+ Holds the list of SslOption values, that are activated by configuration.
+
+ \sa QSsl::SslOption
+*/
+
+/*!
+ \qmlproperty string sslConfiguration::ciphers
+ Holds the cryptographic cipher suite for this configuration to \a ciphers,
+ which is a colon-separated list of cipher suite names.
+
+ \sa QSslConfiguration::ciphers
+*/
+
+/*!
+ \qmlproperty enumeration sslConfiguration::protocol
+ Holds SslProtocol enumeration value.
+ \sa QSsl::SslProtocol
+ */
+
+/*!
+ \qmlproperty enumeration sslConfiguration::peerVerifyMode
+ Holds PeerVerifyMode enumeration value.
+
+ \sa QSslSocket::PeerVerifyMode
+ */
+
+/*!
+ \qmlproperty int sslConfiguration::peerVerifyDepth
+
+ Holds the maximum number of certificates in the peer's certificate chain
+ to be checked during the SSL handshake phase, or 0 (the default) if no
+ maximum depth has been set, indicating that the whole certificate chain
+ should be checked.
+
+ \sa QSslConfiguration::peerVerifyDepth
+ */
+
+/*!
+ \qmlproperty bytearray sslConfiguration::sessionTicket
+
+ Holds the session ticket used in the SSL handshake in ASN.1
+ format, suitable to e.g. be persisted to disk.
+
+ \sa QSslConfiguration::sessionTicket
+ */
+
+/*!
+ \qmlmethod void sslConfiguration::setCertificateFiles(const QStringList &certificateFiles);
+
+ This function loads into configuration the list of certificates \a certificateFiles
+ provided by user.
+*/
+
+/*!
+ \qmlmethod void sslConfiguration::setPrivateKey(const QQmlSslKey &privateKey);
+
+ This function sets into configuration user defined Private key value \a privateKey.
+
+ \sa QSslKey, sslKey
+*/
+
+/*!
+ \qmltype sslDtlsConfiguration
+ \inqmlmodule QtNetwork
+
+ \brief The sslDtlsConfiguration class holds the Dtls
+ default configuration and state of an SSL connection.
+
+ \sa QSslConfiguration
+*/
+
+/*!
+ \qmlproperty QList sslDtlsConfiguration::sslOptions
+ Holds the list of SslOption values, that are activated by configuration.
+
+ \sa QSsl::SslOption
+*/
+
+/*!
+ \qmlproperty string sslDtlsConfiguration::ciphers
+ Holds the cryptographic cipher suite for this configuration to \a ciphers,
+ which is a colon-separated list of cipher suite names.
+
+ \sa QSslConfiguration::ciphers
+*/
+
+/*!
+ \qmlproperty enumeration sslDtlsConfiguration::protocol
+ Holds SslProtocol enumeration value.
+ \sa QSsl::SslProtocol
+ */
+
+/*!
+ \qmlproperty enumeration sslDtlsConfiguration::peerVerifyMode
+ Holds PeerVerifyMode enumeration value.
+
+ \sa QSslSocket::PeerVerifyMode
+*/
+
+/*!
+ \qmlproperty int sslDtlsConfiguration::peerVerifyDepth
+
+ Holds the maximum number of certificates in the peer's certificate chain
+ to be checked during the SSL handshake phase, or 0 (the default) if no
+ maximum depth has been set, indicating that the whole certificate chain
+ should be checked.
+
+ \sa QSslConfiguration::peerVerifyDepth
+*/
+
+/*!
+ \qmlproperty bytearray sslDtlsConfiguration::sessionTicket
+
+ Holds the session ticket used in the SSL handshake in ASN.1
+ format, suitable to e.g. be persisted to disk.
+
+ \sa QSslConfiguration::sessionTicket
+*/
+
+/*!
+ \qmlmethod void sslDtlsConfiguration::setCertificateFiles(const QStringList &certificateFiles);
+
+ This function loads into configuration the list of certificates \a certificateFiles
+ provided by user.
+*/
+
+/*!
+ \qmlmethod void sslDtlsConfiguration::setPrivateKey(const QQmlSslKey &privateKey);
+
+ This function sets into configuration user defined Private key value \a privateKey.
+
+ \sa QSslKey, sslKey
+*/
+
+/*!
+ \qmltype sslKey
+ \inqmlmodule QtNetwork
+
+ \instantiates QSslKey
+ \brief The sslKey class provides the interface for private and public keys.
+
+ The sslKey provides an API for managing keys.
+ The QML sslKey class is \c Q_GADGET based, it generates QSslKey object
+ based on it's QML properties.
+
+ \sa QSslKey
+*/
+
+/*!
+ \qmlproperty string sslKey::keyFile
+ Holds the path to the \c *.pem key file.
+*/
+
+/*!
+ \qmlproperty enumeration sslKey::keyAlgorithm
+ Holds KeyAlgorithm enumeration value.
+
+ \sa QSsl::KeyAlgorithm
+*/
+
+/*!
+ \qmlproperty enumeration sslKey::keyFormat
+ Holds EncodingFormat enumeration value.
+ \sa QSsl::EncodingFormat
+*/
+
+/*!
+ \qmlproperty bytearray sslKey::keyPassPhrase
+
+ Holds the value to be used to decrypt QSslKey.
+
+ \sa QSslKey
+*/
+
+/*!
+ \qmlproperty enumeration sslKey::keyType
+ Holds KeyType enumeration value.
+ \sa QSsl::KeyType
+*/
diff --git a/src/qmlnetwork/ssl/qqmlsslconfiguration.cpp b/src/qmlnetwork/ssl/qqmlsslconfiguration.cpp
new file mode 100644
index 0000000000..74d171fc5e
--- /dev/null
+++ b/src/qmlnetwork/ssl/qqmlsslconfiguration.cpp
@@ -0,0 +1,175 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include <QtCore/qfile.h>
+#include <QtNetwork/qsslcipher.h>
+#include "qqmlsslconfiguration_p.h"
+#include <array>
+
+QT_BEGIN_NAMESPACE
+static constexpr std::array<QSsl::SslOption, 8> SslOptions = {
+ QSsl::SslOptionDisableEmptyFragments,
+ QSsl::SslOptionDisableSessionTickets,
+ QSsl::SslOptionDisableCompression,
+ QSsl::SslOptionDisableServerNameIndication,
+ QSsl::SslOptionDisableLegacyRenegotiation,
+ QSsl::SslOptionDisableSessionSharing,
+ QSsl::SslOptionDisableSessionPersistence,
+ QSsl::SslOptionDisableServerCipherPreference
+};
+
+QString QQmlSslConfiguration::ciphers() const
+{
+ return m_ciphers;
+}
+
+QList<QSsl::SslOption> QQmlSslConfiguration::sslOptions() const
+{
+ return m_sslOptions;
+}
+
+QSsl::SslProtocol QQmlSslConfiguration::protocol() const
+{
+ return m_configuration.protocol();
+}
+
+QSslSocket::PeerVerifyMode QQmlSslConfiguration::peerVerifyMode() const
+{
+ return m_configuration.peerVerifyMode();
+}
+
+int QQmlSslConfiguration::peerVerifyDepth() const
+{
+ return m_configuration.peerVerifyDepth();
+}
+
+QByteArray QQmlSslConfiguration::sessionTicket() const
+{
+ return m_configuration.sessionTicket();
+}
+
+QSslConfiguration const QQmlSslConfiguration::configuration()
+{
+ return m_configuration;
+}
+
+void QQmlSslConfiguration::setCertificateFiles(const QStringList &certificateFiles)
+{
+ if (m_certificateFiles == certificateFiles)
+ return;
+
+ m_certificateFiles = certificateFiles;
+ QList<QSslCertificate> certificates;
+ for (const QString &fileName: m_certificateFiles) {
+ QFile certificateFile(fileName);
+ if (certificateFile.open(QIODevice::ReadOnly)) {
+ QByteArray cert = certificateFile.readAll();
+ certificates.append(QSslCertificate(cert));
+ } else {
+ qWarning() << "File: " << fileName << "is not found. It will be skipped.";
+ }
+ }
+
+ if (!certificates.isEmpty())
+ m_configuration.setCaCertificates(certificates);
+ else
+ qWarning() << "No certificates loaded.";
+}
+
+void QQmlSslConfiguration::setProtocol(QSsl::SslProtocol protocol)
+{
+ if (m_configuration.protocol() == protocol)
+ return;
+
+ m_configuration.setProtocol(protocol);
+}
+
+void QQmlSslConfiguration::setPeerVerifyMode(QSslSocket::PeerVerifyMode mode)
+{
+ if (m_configuration.peerVerifyMode() == mode)
+ return;
+
+ m_configuration.setPeerVerifyMode(mode);
+}
+
+void QQmlSslConfiguration::setPeerVerifyDepth(int depth)
+{
+ if (m_configuration.peerVerifyDepth() == depth)
+ return;
+
+ m_configuration.setPeerVerifyDepth(depth);
+}
+
+void QQmlSslConfiguration::setCiphers(const QString &ciphers)
+{
+ if (ciphers == m_ciphers)
+ return;
+
+ m_ciphers = ciphers;
+ m_configuration.setCiphers(ciphers); // split(":") is used inside
+}
+
+void QQmlSslConfiguration::setSslOptions(const QList<QSsl::SslOption> &options)
+{
+ if (m_sslOptions == options)
+ return;
+
+ m_sslOptions = options;
+ for (QSsl::SslOption option: m_sslOptions)
+ m_configuration.setSslOption(option, true);
+}
+
+void QQmlSslConfiguration::setSessionTicket(const QByteArray &sessionTicket)
+{
+ if (m_configuration.sessionTicket() == sessionTicket)
+ return;
+
+ m_configuration.setSessionTicket(sessionTicket);
+}
+
+void QQmlSslConfiguration::setPrivateKey(const QQmlSslKey &privateKey)
+{
+ m_configuration.setPrivateKey(privateKey.getSslKey());
+}
+
+void QQmlSslConfiguration::setSslOptionsList(const QSslConfiguration &configuration)
+{
+ for (QSsl::SslOption option: SslOptions) {
+ if (configuration.testSslOption(option))
+ m_sslOptions.append(option);
+ }
+}
+
+void QQmlSslConfiguration::setCiphersList(const QSslConfiguration &configuration)
+{
+ QList<QSslCipher> ciphers = configuration.ciphers();
+ for (int i = 0; i < ciphers.size(); ++i) {
+ if (i != 0) {
+ m_ciphers += QString::fromUtf8(":");
+ }
+ m_ciphers += ciphers[i].name();
+ }
+}
+
+QQmlSslDefaultConfiguration::QQmlSslDefaultConfiguration()
+ : QQmlSslConfiguration()
+{
+ m_configuration = QSslConfiguration::defaultConfiguration();
+ setSslOptionsList(m_configuration);
+ setCiphersList(m_configuration);
+}
+
+QQmlSslDefaultDtlsConfiguration::QQmlSslDefaultDtlsConfiguration()
+ : QQmlSslConfiguration()
+{
+#if QT_CONFIG(dtls)
+ m_configuration = QSslConfiguration::defaultDtlsConfiguration();
+#else
+ qWarning() << "No dtls support enabled";
+ m_configuration = QSslConfiguration::defaultConfiguration();
+#endif // QT_CONFIG(dtls)
+ setSslOptionsList(m_configuration);
+ setCiphersList(m_configuration);
+}
+
+QT_END_NAMESPACE
diff --git a/src/qmlnetwork/ssl/qqmlsslconfiguration_p.h b/src/qmlnetwork/ssl/qqmlsslconfiguration_p.h
new file mode 100644
index 0000000000..f463478bde
--- /dev/null
+++ b/src/qmlnetwork/ssl/qqmlsslconfiguration_p.h
@@ -0,0 +1,109 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QQMLSSLCONFIGURATION_P_H
+#define QQMLSSLCONFIGURATION_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <private/qtqmlnetworkexports_p.h>
+#include "qqmlsslkey_p.h"
+
+#include <QtCore/QByteArray>
+#include <QtCore/QMetaType>
+#include <QtQml/qqml.h>
+#include <QtNetwork/qsslconfiguration.h>
+#include <QtNetwork/qsslsocket.h>
+#include <QtNetwork/qssl.h>
+
+QT_BEGIN_NAMESPACE
+
+class Q_QMLNETWORK_PRIVATE_EXPORT QQmlSslConfiguration
+{
+ Q_GADGET
+
+ Q_PROPERTY(QString ciphers READ ciphers WRITE setCiphers)
+ Q_PROPERTY(QList<QSsl::SslOption> sslOptions READ sslOptions WRITE setSslOptions)
+ Q_PROPERTY(QSsl::SslProtocol protocol READ protocol WRITE setProtocol)
+ Q_PROPERTY(QSslSocket::PeerVerifyMode peerVerifyMode READ peerVerifyMode
+ WRITE setPeerVerifyMode)
+ Q_PROPERTY(int peerVerifyDepth READ peerVerifyDepth WRITE setPeerVerifyDepth)
+ Q_PROPERTY(QByteArray sessionTicket READ sessionTicket WRITE setSessionTicket)
+
+public:
+ Q_INVOKABLE void setCertificateFiles(const QStringList &certificateFiles);
+ Q_INVOKABLE void setPrivateKey(const QQmlSslKey &privateKey);
+
+ QString ciphers() const;
+ QList<QSsl::SslOption> sslOptions() const;
+ QSsl::SslProtocol protocol() const;
+ QSslSocket::PeerVerifyMode peerVerifyMode() const;
+ int peerVerifyDepth() const;
+ QByteArray sessionTicket() const;
+ QSslConfiguration const configuration();
+
+ void setProtocol(QSsl::SslProtocol protocol);
+ void setPeerVerifyMode(QSslSocket::PeerVerifyMode mode);
+ void setPeerVerifyDepth(int depth);
+ void setCiphers(const QString &ciphers);
+ void setSslOptions(const QList<QSsl::SslOption> &options);
+ void setSessionTicket(const QByteArray &sessionTicket);
+
+private:
+ inline friend bool operator==(const QQmlSslConfiguration &lval,
+ const QQmlSslConfiguration &rval)
+ {
+ return lval.m_certificateFiles == rval.m_certificateFiles
+ && lval.m_ciphers == rval.m_ciphers
+ && lval.m_sslOptions == rval.m_sslOptions
+ && lval.m_configuration == rval.m_configuration;
+ }
+
+ inline friend bool operator!=(const QQmlSslConfiguration &lval,
+ const QQmlSslConfiguration &rval)
+ {
+ return !(lval == rval);
+ }
+
+protected:
+ void setSslOptionsList(const QSslConfiguration &configuration);
+ void setCiphersList(const QSslConfiguration &configuration);
+
+ QStringList m_certificateFiles;
+ QString m_ciphers;
+ QList<QSsl::SslOption> m_sslOptions;
+ QSslConfiguration m_configuration;
+};
+
+class Q_QMLNETWORK_PRIVATE_EXPORT QQmlSslDefaultConfiguration : public QQmlSslConfiguration
+{
+ Q_GADGET
+ QML_NAMED_ELEMENT(sslConfiguration)
+ QML_ADDED_IN_VERSION(6, 7)
+
+public:
+ QQmlSslDefaultConfiguration();
+};
+
+class Q_QMLNETWORK_PRIVATE_EXPORT QQmlSslDefaultDtlsConfiguration : public QQmlSslConfiguration
+{
+ Q_GADGET
+ QML_NAMED_ELEMENT(sslDtlsConfiguration)
+ QML_ADDED_IN_VERSION(6, 7)
+
+public:
+ QQmlSslDefaultDtlsConfiguration();
+};
+
+QT_END_NAMESPACE
+
+#endif // QQMLSSLCONFIGURATION_P_H
diff --git a/src/qmlnetwork/ssl/qqmlsslkey.cpp b/src/qmlnetwork/ssl/qqmlsslkey.cpp
new file mode 100644
index 0000000000..e3e38c15a9
--- /dev/null
+++ b/src/qmlnetwork/ssl/qqmlsslkey.cpp
@@ -0,0 +1,68 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include <QtCore/qfile.h>
+#include "qqmlsslkey_p.h"
+
+QT_BEGIN_NAMESPACE
+
+QSslKey QQmlSslKey::getSslKey() const
+{
+ if (m_keyFile.isEmpty()) {
+ qWarning() << "SslConfiguration::getSslKey: No key paths set";
+ return QSslKey();
+ }
+
+ QFile file(m_keyFile);
+ if (!file.open(QIODevice::ReadOnly)) {
+ qWarning() << "SslConfiguration::getSslKey: Couldn't open file:" << m_keyFile;
+ return QSslKey();
+ }
+
+ return QSslKey(file.readAll(),
+ m_keyAlgorithm,
+ m_keyFormat,
+ m_keyType,
+ m_keyPassPhrase);
+}
+
+void QQmlSslKey::setKeyFile(const QString &key)
+{
+ if (m_keyFile == key)
+ return;
+
+ m_keyFile = key;
+}
+
+void QQmlSslKey::setKeyAlgorithm(QSsl::KeyAlgorithm value)
+{
+ if (m_keyAlgorithm == value)
+ return;
+
+ m_keyAlgorithm = value;
+}
+
+void QQmlSslKey::setKeyFormat(QSsl::EncodingFormat value)
+{
+ if (m_keyFormat == value)
+ return;
+
+ m_keyFormat = value;
+}
+
+void QQmlSslKey::setKeyPassPhrase(const QByteArray &value)
+{
+ if (m_keyPassPhrase == value)
+ return;
+
+ m_keyPassPhrase = value;
+}
+
+void QQmlSslKey::setKeyType(QSsl::KeyType type)
+{
+ if (m_keyType == type)
+ return;
+ m_keyType = type;
+}
+
+QT_END_NAMESPACE
diff --git a/src/qmlnetwork/ssl/qqmlsslkey_p.h b/src/qmlnetwork/ssl/qqmlsslkey_p.h
new file mode 100644
index 0000000000..ea9580a9bf
--- /dev/null
+++ b/src/qmlnetwork/ssl/qqmlsslkey_p.h
@@ -0,0 +1,77 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QQMLSSLKEY_P_H
+#define QQMLSSLKEY_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <private/qtqmlnetworkexports_p.h>
+
+#include <QtCore/QByteArray>
+#include <QtCore/QMetaType>
+#include <QtNetwork/qsslkey.h>
+#include <QtNetwork/qssl.h>
+#include <QtQml/qqml.h>
+
+QT_BEGIN_NAMESPACE
+
+class Q_QMLNETWORK_PRIVATE_EXPORT QQmlSslKey
+{
+ Q_GADGET
+ QML_NAMED_ELEMENT(sslKey)
+ QML_ADDED_IN_VERSION(6, 7)
+
+ Q_PROPERTY(QString keyFile READ keyFile
+ WRITE setKeyFile)
+ Q_PROPERTY(QSsl::KeyAlgorithm keyAlgorithm READ keyAlgorithm
+ WRITE setKeyAlgorithm)
+ Q_PROPERTY(QSsl::EncodingFormat keyFormat READ keyFormat
+ WRITE setKeyFormat)
+ Q_PROPERTY(QByteArray keyPassPhrase READ keyPassPhrase
+ WRITE setKeyPassPhrase)
+ Q_PROPERTY(QSsl::KeyType keyType READ keyType WRITE setKeyType)
+
+public:
+ QSslKey getSslKey() const;
+ QString keyFile() const { return m_keyFile; }
+ QSsl::KeyAlgorithm keyAlgorithm() const { return m_keyAlgorithm; }
+ QSsl::EncodingFormat keyFormat() const { return m_keyFormat; }
+ QByteArray keyPassPhrase() const { return m_keyPassPhrase; }
+ QSsl::KeyType keyType() const { return m_keyType; }
+
+ void setKeyFile(const QString &key);
+ void setKeyAlgorithm(QSsl::KeyAlgorithm value);
+ void setKeyFormat(QSsl::EncodingFormat value);
+ void setKeyPassPhrase(const QByteArray &value);
+ void setKeyType(QSsl::KeyType type);
+
+private:
+ inline friend bool operator==(const QQmlSslKey &lvalue, const QQmlSslKey &rvalue)
+ {
+ return (lvalue.m_keyFile == rvalue.m_keyFile
+ && lvalue.m_keyAlgorithm == rvalue.m_keyAlgorithm
+ && lvalue.m_keyFormat == rvalue.m_keyFormat
+ && lvalue.m_keyType == rvalue.m_keyType
+ && lvalue.m_keyPassPhrase == rvalue.m_keyPassPhrase);
+ }
+
+ QString m_keyFile;
+ QByteArray m_keyPassPhrase;
+ QSsl::KeyAlgorithm m_keyAlgorithm = QSsl::Rsa;
+ QSsl::EncodingFormat m_keyFormat = QSsl::Pem;
+ QSsl::KeyType m_keyType = QSsl::PrivateKey;
+};
+
+QT_END_NAMESPACE
+
+#endif // QQMLSSLKEY_P_H
diff --git a/src/qmlnetwork/ssl/qqmlsslnamespace_p.h b/src/qmlnetwork/ssl/qqmlsslnamespace_p.h
new file mode 100644
index 0000000000..37f0cf8c09
--- /dev/null
+++ b/src/qmlnetwork/ssl/qqmlsslnamespace_p.h
@@ -0,0 +1,36 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QQMLSSLNAMESPACE_P_H
+#define QQMLSSLNAMESPACE_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <private/qtqmlnetworkexports_p.h>
+
+#include <QtCore/QMetaType>
+#include <QtQml/qqml.h>
+#include <QtNetwork/QSsl>
+
+QT_BEGIN_NAMESPACE
+
+namespace QSslForeignNamespace
+{
+ Q_NAMESPACE
+ QML_FOREIGN_NAMESPACE(QSsl)
+ QML_NAMED_ELEMENT(Ssl)
+ QML_ADDED_IN_VERSION(6, 7)
+};
+
+QT_END_NAMESPACE
+
+#endif // QQMLSSLNAMESPACE_P_H
diff --git a/src/qmlnetwork/ssl/qqmlsslsocketnamespace_p.h b/src/qmlnetwork/ssl/qqmlsslsocketnamespace_p.h
new file mode 100644
index 0000000000..fbb250aaa9
--- /dev/null
+++ b/src/qmlnetwork/ssl/qqmlsslsocketnamespace_p.h
@@ -0,0 +1,36 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QQMLSSLSOCKETNAMESPACE_P_H
+#define QQMLSSLSOCKETNAMESPACE_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <private/qtqmlnetworkexports_p.h>
+
+#include <QtCore/QMetaObject>
+#include <QtQml/qqml.h>
+#include <QtNetwork/qsslsocket.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace SslSocketForeignNamespace
+{
+ Q_NAMESPACE
+ QML_FOREIGN_NAMESPACE(QSslSocket)
+ QML_NAMED_ELEMENT(SslSocket)
+ QML_ADDED_IN_VERSION(6, 7)
+};
+
+QT_END_NAMESPACE
+
+#endif // QQMLSSLSOCKETNAMESPACE_P_H
diff --git a/tests/auto/qmlnetwork/CMakeLists.txt b/tests/auto/qmlnetwork/CMakeLists.txt
index 3f6ae6d6f0..74cdf06a51 100644
--- a/tests/auto/qmlnetwork/CMakeLists.txt
+++ b/tests/auto/qmlnetwork/CMakeLists.txt
@@ -2,3 +2,7 @@
# SPDX-License-Identifier: BSD-3-Clause
add_subdirectory(qqmlnetworkinformation)
+if(QT_FEATURE_qml_ssl)
+ add_subdirectory(qqmlsslconfiguration)
+ add_subdirectory(qqmlsslkey)
+endif()
diff --git a/tests/auto/qmlnetwork/qqmlsslconfiguration/CMakeLists.txt b/tests/auto/qmlnetwork/qqmlsslconfiguration/CMakeLists.txt
new file mode 100644
index 0000000000..bc5709dc86
--- /dev/null
+++ b/tests/auto/qmlnetwork/qqmlsslconfiguration/CMakeLists.txt
@@ -0,0 +1,43 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_sslconfiguration_qml LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_sslconfiguration_qml
+ QMLTEST
+ SOURCES
+ tst_sslconfiguration_qml.cpp
+ LIBRARIES
+ Qt::Qml
+ Qt::QuickTestUtilsPrivate
+ Qt::QmlNetwork
+)
+
+qt_policy(SET QTP0001 NEW)
+
+qt_add_qml_module(tst_sslconfiguration_qml
+ URI QmlTestUri
+ VERSION 1.0
+ QML_FILES
+ qml/tst_sslconfiguration.qml
+)
+
+set_source_files_properties("${CMAKE_CURRENT_LIST_DIR}/data/cert.pem"
+ PROPERTIES QT_RESOURCE_ALIAS data/cert.pem)
+set_source_files_properties("${CMAKE_CURRENT_LIST_DIR}/data/key.pem"
+ PROPERTIES QT_RESOURCE_ALIAS data/key.pem)
+
+qt_add_resources(tst_sslconfiguration_qml
+ "data"
+ PREFIX
+ "/"
+ FILES
+ "${CMAKE_CURRENT_LIST_DIR}/data/cert.pem"
+ "${CMAKE_CURRENT_LIST_DIR}/data/key.pem"
+)
+
+qt_autogen_tools_initial_setup(tst_sslconfiguration_qml)
diff --git a/tests/auto/qmlnetwork/qqmlsslconfiguration/data/cert.pem b/tests/auto/qmlnetwork/qqmlsslconfiguration/data/cert.pem
new file mode 100644
index 0000000000..3fb973e1be
--- /dev/null
+++ b/tests/auto/qmlnetwork/qqmlsslconfiguration/data/cert.pem
@@ -0,0 +1,34 @@
+-----BEGIN CERTIFICATE-----
+MIIF6zCCA9OgAwIBAgIJAMPfLBc9ERZGMA0GCSqGSIb3DQEBCwUAMIGLMQswCQYD
+VQQGEwJERTEPMA0GA1UECAwGQmVybGluMQ8wDQYDVQQHDAZCZXJsaW4xEzARBgNV
+BAoMClF0UHJvdG9idWYxDDAKBgNVBAsMA1JuRDESMBAGA1UEAwwJbG9jYWxob3N0
+MSMwIQYJKoZIhvcNAQkBFhRxdHByb3RvYnVmQGdtYWlsLmNvbTAeFw0xOTA0MjMx
+NTI5MzNaFw0yMDA0MjIxNTI5MzNaMIGLMQswCQYDVQQGEwJERTEPMA0GA1UECAwG
+QmVybGluMQ8wDQYDVQQHDAZCZXJsaW4xEzARBgNVBAoMClF0UHJvdG9idWYxDDAK
+BgNVBAsMA1JuRDESMBAGA1UEAwwJbG9jYWxob3N0MSMwIQYJKoZIhvcNAQkBFhRx
+dHByb3RvYnVmQGdtYWlsLmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC
+ggIBANCB7zdc6v+gsYCsGIYsT3iyGPgvFG7cJJWnQO9iW6Tn/kBcreYuCdVSSODK
+/NtPaA1r8j9FCDvLkzewNQ2Idv08/oKBYfOaVtQvh1cn7ktr1usiXtYv16cimeKk
+8iYbiczkZOah2xq+ivm9+05WkYTzcSjBpXg19894024GHd7oRV9G5MCr760k8YLM
+ALnoPpTl0yfs5cEcTybqvZFZNqkHDX2ziEbcF/mVcxcyEsmenbX6MI0easg2qZeq
+Sb7AW7tIMVoWUxDkUIor4vogbgU2IljAjzn0i+fPncB41TU5IiIU35vO67kFBXyI
+Ms3LpN1+Siz5HYHjwaWl0ecebuT83kP33VNc1ULkKJG5UbZUYfgZjUwZPgFFzVzQ
+cif0mhYj9s5Nmn6Q/twxeIXOIZAQdLOq625Wwx8bh+mGaV5mtw3wtXJjbceGa1z/
+Pnni4x2B7IfSiOzGLZZNRRHIjUskeONHUHn8YBrLLg5RT+tvPnGDVPh0cKEH2P4F
+cNRPmaqg75siFoJ+m3DlFM952tRcfzJumgbUfEnrL8bxTZPYVoq22qCDm3UGNW8n
+pthv8Y2hemv6V9lF050z2vpL2DtU9RmtkBWx7ipPUdsEOm4e0rdOCk7zo8IAiWMQ
+6o1L23IPTsqaEpqk3b7tT+5dtLkpeomAT8Hz91ChWUb6jrTVAgMBAAGjUDBOMB0G
+A1UdDgQWBBQIb2RjqkeMsUjH9QJ5BYnAtJ/vojAfBgNVHSMEGDAWgBQIb2RjqkeM
+sUjH9QJ5BYnAtJ/vojAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4ICAQDG
+2x+I9C+4XFCpg9KVA+BBi6+7yi4ulH0yv7W3hNWBV2MxTpvVN6RIt8xI1sPFXc2T
+g2wCIAIPGIPNDe8hO3gcfIIe059P+J3ZNjybUg5p6CR9O7kqgqV/nL4gVRuBJeYq
+6YLr1lKL9r3Zdbkq1tcaCaj816zdXVky0us72XP28/xJc96crgKzDI69vESy5jq6
+QT/HoBwYiSaWXNgb0zJzc//e0upXSLeTkYizAJ5OGkQ/MQYE7gDvtPlGVhQ0rnl/
+FLsiZJokuxtLOTvYJ8Gynjz3QwbClN/bmUbOgD0fqW6BEZyZSJ4zCz0BJnwg46gc
+IN+p6vi50MG4ZcJcnMl/3tAxt2RxHNLi0j21NSLyFj60gK+vL3/zzkdYF9ZxX1L+
+dqhTqioCVrV96rJIQbz6JrbFhUCdyEHYG7yi6LxHTUex33XouhGAfZ0lri5wWZq8
+0Rx8PEZ7SbjARtnvA7uXIAfgD+n3oqnkg9IDPH8PbdRcJrAdje3O2c1+OzTAC8ni
+czaCWG748gfZPe0JpENP7P56RTh9avj4sHISCx4r+sh0lruLp2JZPr9qtw09uWlq
+Mn58bcnDu9RjVfPXk43s9WfJC9XII+JoNcW3iJDSHxQb9XLvwR9ntWhkVvOKenPP
+b00kWr6FfId6fiOmUww5WkW+Wtt4XOYsypaN+DskeA==
+-----END CERTIFICATE-----
diff --git a/tests/auto/qmlnetwork/qqmlsslconfiguration/data/key.pem b/tests/auto/qmlnetwork/qqmlsslconfiguration/data/key.pem
new file mode 100644
index 0000000000..176f5210c1
--- /dev/null
+++ b/tests/auto/qmlnetwork/qqmlsslconfiguration/data/key.pem
@@ -0,0 +1,52 @@
+-----BEGIN PRIVATE KEY-----
+MIIJQgIBADANBgkqhkiG9w0BAQEFAASCCSwwggkoAgEAAoICAQDQge83XOr/oLGA
+rBiGLE94shj4LxRu3CSVp0DvYluk5/5AXK3mLgnVUkjgyvzbT2gNa/I/RQg7y5M3
+sDUNiHb9PP6CgWHzmlbUL4dXJ+5La9brIl7WL9enIpnipPImG4nM5GTmodsavor5
+vftOVpGE83EowaV4NffPeNNuBh3e6EVfRuTAq++tJPGCzAC56D6U5dMn7OXBHE8m
+6r2RWTapBw19s4hG3Bf5lXMXMhLJnp21+jCNHmrINqmXqkm+wFu7SDFaFlMQ5FCK
+K+L6IG4FNiJYwI859Ivnz53AeNU1OSIiFN+bzuu5BQV8iDLNy6Tdfkos+R2B48Gl
+pdHnHm7k/N5D991TXNVC5CiRuVG2VGH4GY1MGT4BRc1c0HIn9JoWI/bOTZp+kP7c
+MXiFziGQEHSzqutuVsMfG4fphmleZrcN8LVyY23Hhmtc/z554uMdgeyH0ojsxi2W
+TUURyI1LJHjjR1B5/GAayy4OUU/rbz5xg1T4dHChB9j+BXDUT5mqoO+bIhaCfptw
+5RTPedrUXH8ybpoG1HxJ6y/G8U2T2FaKttqgg5t1BjVvJ6bYb/GNoXpr+lfZRdOd
+M9r6S9g7VPUZrZAVse4qT1HbBDpuHtK3TgpO86PCAIljEOqNS9tyD07KmhKapN2+
+7U/uXbS5KXqJgE/B8/dQoVlG+o601QIDAQABAoICAGYHPsxDfoap1lHVZIa7RgQU
+eh1vxDrfJFPKrP62jYurLgHGmB2rZ4poIltFWOfj+lGfAcIuAHJqElbMtZkyrq8K
+Wqv3rburSVO5Eiv20Sc81MToY6nBbXBOgSijeA5nqU2GcU1d5D45AP5mFYPm3nxF
+N5ku8M5a8jEmuab7/T/nPpL5uNQDDlwWWMudEbnmyEDKGUJPLLoLJTww36QxGIsr
+dVGOOWAbMOwjUlcGXKUmJZw3mexj9vKTtPcPD9j0fa6uC+A+TlVUs4h5Iy8sEUoh
+jDsLtsowPQmo0VOujP3nQCmXNzghz70QlPe0GdAUF09/DcLl/6dgkJCDDKxgevhW
+GYfUSaR6gjg6/QYVHIea9wCkxW2jRXPvG6pBAAaoseS4n7M3IckzSol4Nwh2vmzA
+yvGMLlLUkNIYHJ/P29mMt+EoBrtdME8XZln0sCkQC5c0+owvyBsPEjrpnBtqvPse
+CNQaULUZnsJC3kbJeU/xPcqNa8pGjnpiHqjDFN4CUJAYnLDuAanow075DCkLKWej
+ziXWQoJ+RO4ml9Gy0qoHE76iEg9fvKx7aWIv0DSmhRvwKeI8kc1yPp8kACy1rOBu
+f9gvDDB4jMVDQKYRDbZ6kyRrHX5XKvJJ6vkpFBT1fLaWVdH8fOtIsDKaLhSTc0Ia
+TbcDJquaBeLnQmpH5439AoIBAQDpccVOJ2mE1n6sluXkzE/zW17jmWMrBXAtYpnt
+nkBO8SuwNzZW3V0LvCTpEVo1XupvVbuMvWzZyHgAevqDL77Z5FP63hO1l1yT3mcw
+WB1Kr9XTXm52DL4IGnp4agrI1+zp56q8o/PbJfkk3JhiEmpHa3rh575LcYVs8HXV
+5+cTFc5upygXX4odRazS7qXtZdyBL1w7KpZijZJqrcG3t4sjCKEOcZn6XFVFtfHE
+GWrAIz9kWORh5nZ9MTI9TR/4MHBYJ8G/9kwbrnce+FeZ4BTkZHqQTp2MHeC9AFro
+JCtG8y1rhh1cxzoUMB6s3qW6Q/7b2/Wx7Hb6RMFXRFYTaeVXAoIBAQDkp1o5E+OB
+ErGPRBHpt+7nmEFq+U+biNcNUvxTKtL9aQKix5Xt9zgSQTN9LmIhAOKDKfuU2Elb
+rX5tCTbalFYcpUX+wD+idvcgpc7Ju+tRMC5Ai9avuCJ0n2oQZiaxFz8GIPc/1C3a
+gC5s1HHr0qTDKcs37nBiay3lmll49J0grrl0NOEWROGDnILvvgCN8jQoMBN5Od5k
+zCPXFuWl3JhWKtSoF+isk/io2JjM2asZuz0zi4mzBnjnVfCM0dAHufoTMQ8aHiVZ
+45iXDIZY9c8frOLgeZeE12mYTWpxZHUuaZSoqoXuApmW3nhoGHYSfX7sORDTYS/4
+2PEJlhkkPs+zAoIBAQC33GybBn2cK1gv1NWSY7zgnelZdzjc7HaSuGMl/IsH4fkX
+3BSHS+f50yB7FLio6m3YbHy/932g9bxWHIXsBxHZCXV/U6PQVTuMFxHMyMmhRmYy
+COEVRynwtfIZnuOJlk85VsZptvPceccF2lyGeZyNTcDF5kFBqFJ/H9CfPfwIUxd4
+nVz9M7lTHspkg6PaG20VrliFHSC+1GQqc1nsubnzSNuYxa6RumFK+2dEnQQv+lL2
+VPDjjqFqLvIzx+fTEUuakw2NhI4jC0E0+kH8prmtvNmviMubTPjxwzLWPY58XhE6
+67F6nktHFTND0kRTNTSos1CK5wQ6Tya79c2ZksEXAoIBAAdI7a7z20O5fL67xHZV
+zd7DExJ9bvPdoDxkcHWV37MDLXpSMYyrW7X5LdLHL4ktpgnXxJQxb+Tj2itPJ9g+
+8Z9oBJrhNSXP9H+tyLDUs+KaTl7wFZ7zluVwTsjG+GScAP4I/tehwvQ7MT92ZUrG
+I0m0gyz9A8ee8o9mI4OfB4KLDo2NQb6b4zN2QRWyUAI1vUOqhHRQS62ac2ne6OIn
+7RKRusTAPkGBVWLLw9KC/NiNBp4ly/VQN3nnWwqhhKc6XaVO4tRKMZZzkeD+HSmo
+azjvIStVtGYfFtYrYUDLmpAn/PyCslGq84nC/MMURG7CYNDV4JtbdVPQVZ2gkpx9
+A9ECggEAGuw6sJAkp381dHgf6tTkwsOmJldX4Bjxi6q3vXzNwsou+uwYoLNvXVnl
+mfMQdswCGW1Hm1XPMSBqkleyaXChL4bqM/FJGz8DgBD85vWfaYPrfKIELlfSo5lD
+opBZ8wrAEa9rP2Fm1mbAiFFyXtK78y09CuuMgCL5jZjAQEbNFDOSwfcrJzNY+xU7
+KtsDGCm7OmUAizdWjnAfQKQlB94uk7PimI1Hhs8175fgwaSS3KUILSR8oj/gKFPS
+L7DqR8DsvyGg/JuHx+sdSG3T5q5zGzz2w03mDkoSyxWe36u3F3EyChhPfjcaSape
+0mVZG9D69wbsZefVDJii9NLvWThGog==
+-----END PRIVATE KEY-----
diff --git a/tests/auto/qmlnetwork/qqmlsslconfiguration/qml/tst_sslconfiguration.qml b/tests/auto/qmlnetwork/qqmlsslconfiguration/qml/tst_sslconfiguration.qml
new file mode 100644
index 0000000000..ed016750af
--- /dev/null
+++ b/tests/auto/qmlnetwork/qqmlsslconfiguration/qml/tst_sslconfiguration.qml
@@ -0,0 +1,158 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import QtQuick
+import QtTest
+import QtNetwork
+import QmlTestUri
+
+Item {
+ id: root
+
+ property sslConfiguration userSslObject;
+ property sslConfiguration defaultSslObject;
+ property sslDtlsConfiguration dtlsDefaultSslObj;
+ property sslKey key;
+
+ TestCase {
+ name: "qtSslConfigurationTest"
+
+ function test_1initialization() {
+ userSslObject.peerVerifyMode = SslSocket.QueryPeer
+ userSslObject.peerVerifyDepth = 0
+ userSslObject.protocol = Ssl.TlsV1_2
+ userSslObject.sslOptions = [Ssl.SslOptionDisableEmptyFragments]
+
+ defaultSslObject.peerVerifyMode = SslSocket.VerifyPeer;
+ dtlsDefaultSslObj.peerVerifyMode = SslSocket.VerifyNone;
+
+ key.keyFile = ":/data/key.pem"
+ key.keyAlgorithm = Ssl.Rsa
+ key.keyFormat = Ssl.Pem
+
+ // Call invokable functions for ssl object
+ userSslObject.setCertificateFiles([":/data/cert.pem"])
+ userSslObject.setPrivateKey(key)
+ }
+
+ function test_sslEnumsFields_data() {
+ return [
+ // enum SslProtocol
+ { tag: "SslProtocol.TlsV1_2OrLater",
+ field: Ssl.TlsV1_2OrLater, answer: 7 },
+ { tag: "SslProtocol.DtlsV1_2",
+ field: Ssl.DtlsV1_2, answer: 10 },
+ { tag: "SslProtocol.DtlsV1_2OrLater",
+ field: Ssl.DtlsV1_2OrLater, answer: 11},
+ { tag: "SslProtocol.TlsV1_3",
+ field: Ssl.TlsV1_3, answer: 12 },
+ { tag: "SslProtocol.TlsV1_3OrLater",
+ field: Ssl.TlsV1_3OrLater, answer: 13 },
+ { tag: "SslProtocol.UnknownProtocol",
+ field: Ssl.UnknownProtocol, answer: -1 },
+
+ // enum EncodingFormat
+ { tag: "EncodingFormat.Pem",
+ field: Ssl.Pem, answer: 0 },
+ { tag: "EncodingFormat.Der",
+ field: Ssl.Der, answer: 1 },
+
+ // enum KeyType
+ { tag: "KeyType.key",
+ field: Ssl.PrivateKey, answer: 0 },
+ { tag: "KeyType.PublicKey",
+ field: Ssl.PublicKey, answer: 1 },
+
+ //enum KeyAlgorithm
+ { tag: "KeyAlgorithm.Opaque",
+ field: Ssl.Opaque, answer: 0 },
+ { tag: "KeyAlgorithm.Rsa",
+ field: Ssl.Rsa, answer: 1 },
+ { tag: "KeyAlgorithm.Dsa",
+ field: Ssl.Dsa, answer: 2 },
+ { tag: "KeyAlgorithm.Ec",
+ field: Ssl.Ec, answer: 3 },
+ { tag: "KeyAlgorithm.Dh",
+ field: Ssl.Dh, answer: 4 },
+
+ // enum SslOption
+ { tag: "SslOption.SslOptionDisableEmptyFragments",
+ field: Ssl.SslOptionDisableEmptyFragments, answer: 0x01 },
+ { tag: "SslOption.SslOptionDisableSessionTickets",
+ field: Ssl.SslOptionDisableSessionTickets, answer: 0x02 },
+ { tag: "SslOption.SslOptionDisableCompression",
+ field: Ssl.SslOptionDisableCompression, answer: 0x04 },
+ { tag: "SslOption.SslOptionDisableServerNameIndication",
+ field: Ssl.SslOptionDisableServerNameIndication, answer: 0x08 },
+ { tag: "SslOption.SslOptionDisableLegacyRenegotiation",
+ field: Ssl.SslOptionDisableLegacyRenegotiation, answer: 0x10 },
+ { tag: "SslOption.SslOptionDisableSessionSharing",
+ field: Ssl.SslOptionDisableSessionSharing, answer: 0x20 },
+ { tag: "SslOption.SslOptionDisableSessionPersistence",
+ field: Ssl.SslOptionDisableSessionPersistence, answer: 0x40 },
+ { tag: "SslOption.SslOptionDisableServerCipherPreference",
+ field: Ssl.SslOptionDisableServerCipherPreference, answer: 0x80 },
+
+ // enum PeerVerifyMode
+ { tag: "PeerVerifyMode.VerifyNone",
+ field: SslSocket.VerifyNone, answer: 0 },
+ { tag: "PeerVerifyMode.QueryPeer",
+ field: SslSocket.QueryPeer, answer: 1 },
+ { tag: "PeerVerifyMode.VerifyPeer",
+ field: SslSocket.VerifyPeer, answer: 2 },
+ { tag: "PeerVerifyMode.AutoVerifyPeer",
+ field: SslSocket.AutoVerifyPeer, answer: 3 }
+ ]
+ }
+
+ function test_sslEnumsFields(data) {
+ compare(data.field, data.answer)
+ }
+
+ function test_sslConfigurationFields_data() {
+ return [
+ { tag: "userSslObject is creatable object",
+ field: typeof userSslObject, answer: "object" },
+ { tag: "defaultSslObject is creatable object",
+ field: typeof defaultSslObject, answer: "object" },
+ { tag: "dtlsDefaultSslObj is creatable object",
+ field: typeof dtlsDefaultSslObj, answer: "object" },
+ { tag: "key is creatable object",
+ field: typeof key, answer: "object" },
+ { tag: "userSslObject.sslOptions is creatable object",
+ field: typeof userSslObject.sslOptions,
+ answer: "object" },
+
+ // userSslObject
+ { tag: "userSslObject.peerVerifyMode == Ssl.QueryPeer",
+ field: userSslObject.peerVerifyMode, answer: SslSocket.QueryPeer },
+ // defaultSslObject
+ { tag: "defaultSslObject.peerVerifyMode == Ssl.VerifyPeer",
+ field: defaultSslObject.peerVerifyMode, answer: SslSocket.VerifyPeer },
+ // dtlsDefaultSslObj
+ { tag: "dtlsDefaultSslObj.peerVerifyMode == Ssl.VerifyNone",
+ field: dtlsDefaultSslObj.peerVerifyMode,
+ answer: SslSocket.VerifyNone },
+
+ // userSslObject
+ { tag: "userSslObject.peerVerifyDepth == 0",
+ field: userSslObject.peerVerifyDepth, answer: 0 },
+ { tag: "userSslObject.sslOptions == Ssl.SslOptionDisableEmptyFragments",
+ field: userSslObject.sslOptions[0],
+ answer: Ssl.SslOptionDisableEmptyFragments },
+ { tag: "SSL configuration protocol == SslProtocol.TlsV1_2",
+ field: userSslObject.protocol, answer: Ssl.TlsV1_2 },
+ { tag: "key.keyFile == :/data/key.pem",
+ field: key.keyFile, answer: ":/data/key.pem" },
+ { tag: "key.keyAlgorithm == Ssl.Rsa",
+ field: key.keyAlgorithm, answer: Ssl.Rsa },
+ { tag: "key.keyFormat == Ssl.Pem",
+ field: key.keyFormat, answer: Ssl.Pem }
+ ]
+ }
+
+ function test_sslConfigurationFields(data) {
+ compare(data.field, data.answer)
+ }
+ }
+}
diff --git a/tests/auto/qmlnetwork/qqmlsslconfiguration/tst_sslconfiguration_qml.cpp b/tests/auto/qmlnetwork/qqmlsslconfiguration/tst_sslconfiguration_qml.cpp
new file mode 100644
index 0000000000..e852f25cd5
--- /dev/null
+++ b/tests/auto/qmlnetwork/qqmlsslconfiguration/tst_sslconfiguration_qml.cpp
@@ -0,0 +1,6 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#include <QtQuickTest>
+
+QUICK_TEST_MAIN(tst_sslconfiguration_qml)
diff --git a/tests/auto/qmlnetwork/qqmlsslkey/CMakeLists.txt b/tests/auto/qmlnetwork/qqmlsslkey/CMakeLists.txt
new file mode 100644
index 0000000000..eb9562add6
--- /dev/null
+++ b/tests/auto/qmlnetwork/qqmlsslkey/CMakeLists.txt
@@ -0,0 +1,29 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_sslkey_qml LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+qt_internal_add_test(tst_sslkey_qml
+ QMLTEST
+ SOURCES
+ tst_sslkey_qml.cpp
+ LIBRARIES
+ Qt::Qml
+ Qt::QuickTestUtilsPrivate
+ Qt::QmlNetwork
+)
+
+qt_policy(SET QTP0001 NEW)
+
+qt_add_qml_module(tst_sslkey_qml
+ URI QmlTestUri
+ VERSION 1.0
+ QML_FILES
+ qml/tst_sslkey.qml
+)
+
+qt_autogen_tools_initial_setup(tst_sslkey_qml)
diff --git a/tests/auto/qmlnetwork/qqmlsslkey/qml/tst_sslkey.qml b/tests/auto/qmlnetwork/qqmlsslkey/qml/tst_sslkey.qml
new file mode 100644
index 0000000000..d0e745ea0e
--- /dev/null
+++ b/tests/auto/qmlnetwork/qqmlsslkey/qml/tst_sslkey.qml
@@ -0,0 +1,60 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import QtQuick
+import QtTest
+import QtNetwork
+import QmlTestUri
+
+Item {
+ id: root
+
+ property sslKey keyFirst;
+ property sslKey keySecond;
+
+ TestCase {
+ name: "qtSslKeyTest"
+
+ function test_1initialization() {
+ keyFirst.keyFile = ":/assets/key.pem"
+ keyFirst.keyAlgorithm = Ssl.Rsa
+ keyFirst.keyFormat = Ssl.Pem
+ keyFirst.keyType = Ssl.PrivateKey
+
+ keySecond = keyFirst;
+ }
+
+ function test_sslConfigurationFields_data() {
+ return [
+ { tag: "key is creatable object",
+ field: typeof keyFirst, answer: "object" },
+ { tag: "keySecond is creatable object",
+ field: typeof keySecond, answer: "object" },
+
+ // key values
+ { tag: "keyFirst.keyFile == :/assets/key.pem",
+ field: keyFirst.keyFile, answer: ":/assets/key.pem" },
+ { tag: "keyFirst.keyAlgorithm == Ssl.Rsa",
+ field: keyFirst.keyAlgorithm, answer: Ssl.Rsa },
+ { tag: "keyFirst.keyFormat == Ssl.Pem",
+ field: keyFirst.keyFormat, answer: Ssl.Pem },
+ { tag: "keyFirst.keyType == Ssl.PrivateKey",
+ field: keyFirst.keyType, answer: Ssl.PrivateKey },
+
+ // keySecond values
+ { tag: "keySecond.keyFile == :/assets/key.pem",
+ field: keySecond.keyFile, answer: ":/assets/key.pem" },
+ { tag: "keySecond.keyAlgorithm == Ssl.Rsa",
+ field: keySecond.keyAlgorithm, answer: Ssl.Rsa },
+ { tag: "keySecond.keyFormat == Ssl.Pem",
+ field: keySecond.keyFormat, answer: Ssl.Pem },
+ { tag: "keySecond.keyType == Ssl.PrivateKey",
+ field: keySecond.keyType, answer: Ssl.PrivateKey }
+ ]
+ }
+
+ function test_sslConfigurationFields(data) {
+ compare(data.field, data.answer)
+ }
+ }
+}
diff --git a/tests/auto/qmlnetwork/qqmlsslkey/tst_sslkey_qml.cpp b/tests/auto/qmlnetwork/qqmlsslkey/tst_sslkey_qml.cpp
new file mode 100644
index 0000000000..ffe8167c4e
--- /dev/null
+++ b/tests/auto/qmlnetwork/qqmlsslkey/tst_sslkey_qml.cpp
@@ -0,0 +1,6 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#include <QtQuickTest>
+
+QUICK_TEST_MAIN(tst_sslkey_qml)