diff options
author | Tatiana Borisova <tatiana.borisova@qt.io> | 2023-08-17 18:54:33 +0200 |
---|---|---|
committer | Tatiana Borisova <tatiana.borisova@qt.io> | 2023-10-05 12:13:20 +0200 |
commit | b44f466621868128672163d3044e508debd57601 (patch) | |
tree | c312339ba11f3410fa40145c590cf2d62b2a92cf | |
parent | 53bb1758f26e0a7c6e511f445edbc68a20af9f09 (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>
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----- +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 +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) |