diff options
-rw-r--r-- | examples/opcua/opcuaviewer/CMakeLists.txt | 14 | ||||
-rw-r--r-- | examples/opcua/opcuaviewer/mainwindow.cpp | 92 | ||||
-rw-r--r-- | examples/opcua/opcuaviewer/mainwindow.h | 2 | ||||
-rw-r--r-- | examples/opcua/opcuaviewer/opcuaviewer.pro | 12 | ||||
-rw-r--r-- | src/opcua/doc/src/security.qdoc | 7 |
5 files changed, 73 insertions, 54 deletions
diff --git a/examples/opcua/opcuaviewer/CMakeLists.txt b/examples/opcua/opcuaviewer/CMakeLists.txt index 08776be..1445a85 100644 --- a/examples/opcua/opcuaviewer/CMakeLists.txt +++ b/examples/opcua/opcuaviewer/CMakeLists.txt @@ -14,9 +14,6 @@ find_package(Qt6 REQUIRED COMPONENTS Core Gui OpcUa Widgets) qt_standard_project_setup() -file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/pki" - DESTINATION "${CMAKE_CURRENT_BINARY_DIR}") - qt_add_executable(opcuaviewer certificatedialog.cpp certificatedialog.h certificatedialog.ui main.cpp @@ -25,6 +22,17 @@ qt_add_executable(opcuaviewer treeitem.cpp treeitem.h ) +qt_add_resources(opcuaviewer "pki" + PREFIX / + FILES + pki/own/certs/opcuaviewer.der + pki/own/private/opcuaviewer.pem + pki/trusted/certs/3d8ec65c47524d6ad67bed912c19a895.der + pki/trusted/certs/ca.der + pki/trusted/certs/open62541-testserver.der + pki/trusted/crl/ca.crl.pem +) + set_target_properties(opcuaviewer PROPERTIES WIN32_EXECUTABLE TRUE MACOSX_BUNDLE TRUE diff --git a/examples/opcua/opcuaviewer/mainwindow.cpp b/examples/opcua/opcuaviewer/mainwindow.cpp index b05605f..00d6e55 100644 --- a/examples/opcua/opcuaviewer/mainwindow.cpp +++ b/examples/opcua/opcuaviewer/mainwindow.cpp @@ -9,6 +9,7 @@ #include <QApplication> #include <QDir> #include <QMessageBox> +#include <QStandardPaths> #include <QTextCharFormat> #include <QTextBlock> #include <QOpcUaProvider> @@ -117,23 +118,51 @@ MainWindow::~MainWindow() delete ui; } +static bool copyDirRecursively(const QString &from, const QString &to) +{ + const QDir srcDir(from); + const QDir targetDir(to); + if (!QDir().mkpath(to)) + return false; + + const QFileInfoList infos = + srcDir.entryInfoList(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot); + for (const QFileInfo &info : infos) { + const QString srcItemPath = info.absoluteFilePath(); + const QString dstItemPath = targetDir.absoluteFilePath(info.fileName()); + if (info.isDir()) { + if (!copyDirRecursively(srcItemPath, dstItemPath)) + return false; + } else if (info.isFile()) { + if (!QFile::copy(srcItemPath, dstItemPath)) + return false; + } + } + return true; +} + //! [PKI Configuration] void MainWindow::setupPkiConfiguration() { - QString pkidir = QCoreApplication::applicationDirPath(); -#ifdef Q_OS_WIN - pkidir += "../"; -#endif - pkidir += "/pki"; - m_pkiConfig.setClientCertificateFile(pkidir + "/own/certs/opcuaviewer.der"); - m_pkiConfig.setPrivateKeyFile(pkidir + "/own/private/opcuaviewer.pem"); - m_pkiConfig.setTrustListDirectory(pkidir + "/trusted/certs"); - m_pkiConfig.setRevocationListDirectory(pkidir + "/trusted/crl"); - m_pkiConfig.setIssuerListDirectory(pkidir + "/issuers/certs"); - m_pkiConfig.setIssuerRevocationListDirectory(pkidir + "/issuers/crl"); - - // create the folders if they don't exist yet - createPkiFolders(); + const QDir pkidir = + QDir(QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + "/pki"); + + if (!pkidir.exists() && !copyDirRecursively(":/pki", pkidir.path())) + qFatal("Could not set up directory %s!", qUtf8Printable(pkidir.path())); + + m_pkiConfig.setClientCertificateFile(pkidir.absoluteFilePath("own/certs/opcuaviewer.der")); + m_pkiConfig.setPrivateKeyFile(pkidir.absoluteFilePath("own/private/opcuaviewer.pem")); + m_pkiConfig.setTrustListDirectory(pkidir.absoluteFilePath("trusted/certs")); + m_pkiConfig.setRevocationListDirectory(pkidir.absoluteFilePath("trusted/crl")); + m_pkiConfig.setIssuerListDirectory(pkidir.absoluteFilePath("issuers/certs")); + m_pkiConfig.setIssuerRevocationListDirectory(pkidir.absoluteFilePath("issuers/crl")); + + const QStringList toCreate = { m_pkiConfig.issuerListDirectory(), + m_pkiConfig.issuerRevocationListDirectory() }; + for (const QString &dir : toCreate) { + if (!QDir().mkpath(dir)) + qFatal("Could not create directory %s!", qUtf8Printable(dir)); + } } //! [PKI Configuration] @@ -343,41 +372,6 @@ void MainWindow::log(const QString &text, const QColor &color) log(text, QString(), color); } -bool MainWindow::createPkiPath(const QString &path) -{ - const QString msg = tr("Creating PKI path '%1': %2"); - - QDir dir; - const bool ret = dir.mkpath(path); - if (ret) - qDebug() << msg.arg(path, "SUCCESS."); - else - qCritical("%s", qPrintable(msg.arg(path, "FAILED."))); - - return ret; -} - -bool MainWindow::createPkiFolders() -{ - bool result = createPkiPath(m_pkiConfig.trustListDirectory()); - if (!result) - return result; - - result = createPkiPath(m_pkiConfig.revocationListDirectory()); - if (!result) - return result; - - result = createPkiPath(m_pkiConfig.issuerListDirectory()); - if (!result) - return result; - - result = createPkiPath(m_pkiConfig.issuerRevocationListDirectory()); - if (!result) - return result; - - return result; -} - void MainWindow::showErrorDialog(QOpcUaErrorState *errorState) { int result = 0; diff --git a/examples/opcua/opcuaviewer/mainwindow.h b/examples/opcua/opcuaviewer/mainwindow.h index 1f59048..5f08f50 100644 --- a/examples/opcua/opcuaviewer/mainwindow.h +++ b/examples/opcua/opcuaviewer/mainwindow.h @@ -48,8 +48,6 @@ private: void createClient(); void updateUiState(); void setupPkiConfiguration(); - bool createPkiFolders(); - bool createPkiPath(const QString &path); private: Ui::MainWindow *ui; diff --git a/examples/opcua/opcuaviewer/opcuaviewer.pro b/examples/opcua/opcuaviewer/opcuaviewer.pro index cbe8057..ca0a31a 100644 --- a/examples/opcua/opcuaviewer/opcuaviewer.pro +++ b/examples/opcua/opcuaviewer/opcuaviewer.pro @@ -21,3 +21,15 @@ HEADERS += \ FORMS += \ certificatedialog.ui \ mainwindow.ui \ + +pki.files = \ + pki/own/certs/opcuaviewer.der \ + pki/own/private/opcuaviewer.pem \ + pki/trusted/certs/3d8ec65c47524d6ad67bed912c19a895.der \ + pki/trusted/certs/ca.der \ + pki/trusted/certs/open62541-testserver.der \ + pki/trusted/crl/ca.crl.pem + +pki.prefix = / + +RESOURCES += pki diff --git a/src/opcua/doc/src/security.qdoc b/src/opcua/doc/src/security.qdoc index 62656c7..cdcff38 100644 --- a/src/opcua/doc/src/security.qdoc +++ b/src/opcua/doc/src/security.qdoc @@ -129,7 +129,14 @@ Certificate: \li Configure the correct Application Identity \snippet ../../examples/opcua/opcuaviewer/mainwindow.cpp Application Identity \li Configure PKI locations so that the SDK can find the certificate, private key, trust list etc. + + See for instance the code from the \l{Qt OPC UA Viewer Example}: \snippet ../../examples/opcua/opcuaviewer/mainwindow.cpp PKI Configuration + + In the example, we extract pre-configured own and trusted certificates + from the Qt resource system to a writable location in the file system. + The remaining directories for issuer (revocation) lists are created + manually. \endlist \section2 PKI Folder Layout |