File indexing completed on 2024-11-24 04:44:44

0001 /*
0002    SPDX-FileCopyrightText: 2013 Christian Mollekopf <mollekopf@kolabsys.com>
0003 
0004    SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 #include "sslserver.h"
0007 
0008 #include <QDebug>
0009 #include <QSslConfiguration>
0010 #include <QSslKey>
0011 
0012 // Generated on 2020-10-07 using command:
0013 // openssl req -nodes -new -x509 -keyout key.pem -out cert.pem -days 36500
0014 //
0015 // The cert should be valid until 2120.
0016 
0017 static QByteArray staticCert()
0018 {
0019     // a dummy certificate
0020     return QByteArray(
0021         "-----BEGIN CERTIFICATE-----\n\
0022 MIIDZzCCAk+gAwIBAgIUQoBjjbd//7DD9zWfru/epnVT2vAwDQYJKoZIhvcNAQEL\n\
0023 BQAwQjELMAkGA1UEBhMCWFgxFTATBgNVBAcMDERlZmF1bHQgQ2l0eTEcMBoGA1UE\n\
0024 CgwTRGVmYXVsdCBDb21wYW55IEx0ZDAgFw0yMDEwMDcxMzMxMTJaGA8yMTIwMDkx\n\
0025 MzEzMzExMlowQjELMAkGA1UEBhMCWFgxFTATBgNVBAcMDERlZmF1bHQgQ2l0eTEc\n\
0026 MBoGA1UECgwTRGVmYXVsdCBDb21wYW55IEx0ZDCCASIwDQYJKoZIhvcNAQEBBQAD\n\
0027 ggEPADCCAQoCggEBAMIu0Osija2bIINdCjuP0T+tdlQOI8l52J+z/dI45MxecEn5\n\
0028 LAsYWhqanpgZSM5tFf4xqWaX/1/TVDB5JiLx3voWOODTtNKzFVFCzfKHuH6cBboE\n\
0029 E4TZ+H6hTq+YyMKUDN7XqRtBIf1FBf0lMhalWdtEDtlXcsuoaGXkr671JwR34+EU\n\
0030 6YH/8kbBQQBoL640/gxtgevGmpqfqLW0/hogF5pOhMOfwVlYo28IqaPScUGEpopf\n\
0031 zqL+z6NwdEsNLygwq21kU0hhRnx2UgdPcZNX3dc7sUkZjxn53t6XPeVvgGXCte1o\n\
0032 Ad6L0rMunlda+Tj02FXn7jo6G7ELj05Bg8JNB8sCAwEAAaNTMFEwHQYDVR0OBBYE\n\
0033 FLi6xsBAkbc06veA7t+8slAUCVebMB8GA1UdIwQYMBaAFLi6xsBAkbc06veA7t+8\n\
0034 slAUCVebMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAFpcIzOl\n\
0035 iqMK/kre/xJyE+S1UoS85rmegZDkNdEXUS6zCozL+eO2NxHxumxfD3qrdwLvXfn0\n\
0036 y30xUlNecB30/egXrel9z7Xop70sVCfgfb/vfMmQ5KSUZC8968rgHPl5qPmjZk6X\n\
0037 z0M9hktTRpIk43DPuz5k1qD+LsmrKzI7twGu00EenwVZa4eLN36Ju4ZRg3I0h2zH\n\
0038 vAnuAku0F0JU9GXdbjOW/248k+jhMP1noDaLqwVkkjgzaJwHxFNiKxnG3f7anneK\n\
0039 HxybczmNl3a6IsZN0CSUSwLfvr1Wezk2Mb7dwzhPbycP5icB/KXWgApkRZ3MKfLN\n\
0040 aBvBMCfr7GXmLQk=\n\
0041 -----END CERTIFICATE-----");
0042 }
0043 
0044 static QByteArray staticKey()
0045 {
0046     // a dummy key without password
0047     return QByteArray(
0048         "-----BEGIN PRIVATE KEY-----\n\
0049 MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDCLtDrIo2tmyCD\n\
0050 XQo7j9E/rXZUDiPJedifs/3SOOTMXnBJ+SwLGFoamp6YGUjObRX+Malml/9f01Qw\n\
0051 eSYi8d76Fjjg07TSsxVRQs3yh7h+nAW6BBOE2fh+oU6vmMjClAze16kbQSH9RQX9\n\
0052 JTIWpVnbRA7ZV3LLqGhl5K+u9ScEd+PhFOmB//JGwUEAaC+uNP4MbYHrxpqan6i1\n\
0053 tP4aIBeaToTDn8FZWKNvCKmj0nFBhKaKX86i/s+jcHRLDS8oMKttZFNIYUZ8dlIH\n\
0054 T3GTV93XO7FJGY8Z+d7elz3lb4BlwrXtaAHei9KzLp5XWvk49NhV5+46OhuxC49O\n\
0055 QYPCTQfLAgMBAAECggEAFdV/xkCfX5rmv/6RLPtR0vAlMvRYD8p0khiB/MZK67Pe\n\
0056 umKbEjBNyVoDZSTKq/NWGrvoyVFj9JlliQHGSP2bTdF72cPUPDDIv9dcIt4h35KZ\n\
0057 jj3xF+oOZ+apW1M5l69f9xqWuCrNsJW3Q6yQAj3baa0wYj3T+ZRZEMPzASAtn/HM\n\
0058 8r/ToZ9jzObVeNAKoHy30bn5a5NwUcpdOfj84l/qJalXEMtR05FTOa+UEjbqpxjM\n\
0059 +HR9RhlLyxXoFkBjtBowEWZcJSik7t5Vpk4brhUZTVxR1bC5zAXxtnDg2SmR9bKO\n\
0060 4wttLEtTTrXeTkxpYMTZWt7FplUmP92RdcW8PCbe2QKBgQDl+QYUhaQdmRC1ylny\n\
0061 2XP0lvPBHQr7jIHYcsGgit7XKMu6wSq/NGuLNT7WL1A9UDWBCdsdqXBFjR3rwhzh\n\
0062 krbymy1H6PGPYYMQg0DeoAG7I1YTYhrp25bO0WTXVyYrhbZiQkFontUFYIbqu+Rf\n\
0063 glVnhEXXN6wXBjY1F0qM4KjydQKBgQDYKNspAaxX/GxnydtlxXTXWSKD/kMlbAeu\n\
0064 +AI9PRn6LckT7pKEE4Qd/gHnrlnxlqgLTJDcGgTeNutHmaHToQNSWiNltr7igzsU\n\
0065 nABUwlNpl2NwUqttCvsGcyxhabDIjO6Iw+jbnLsWwyMzwf/5YaP8wwmznWYDGn6Y\n\
0066 UXbyXn5JPwKBgQCzHM/qfefDkaqdG/wQk+KnFkbFGnyqTNX4ofBCvMYwp7p9OuOz\n\
0067 Rf2Yz6CgKvuAtY7mcKmzIXuq/+zU6TubSKyqqceLoVc6iAUPgFquycpvWWc584fo\n\
0068 qjl73USAH4VAEoVpZBcTh9l7taF/A1YsORORa0kGBXtH93OSyBAtRvDu3QKBgHZm\n\
0069 2rU5f2eqks6/GPhEEl4rKubWDX2gEQ1cOA3HPEV3ct8CHStPbVzoV67KJ+ZXObEG\n\
0070 vYpyjhwSRQoxMx0y4xjm2uDKGwEEFQaS9PN4hiweio9qGRBfpWTBDZxGQll4KOit\n\
0071 Nw2kai5rsQqWx1mYjDTVuKi0HL6ycomIhfj4nYANAoGATXXc8Ekg+w7hfzLS3BTV\n\
0072 SovH/d6/fC5B7nD5+wB7s0dD8NqqOUKvRm/HPRzMWejSOMXWQzpWSAGTheaFArTw\n\
0073 2k6FDQ7S1lEt6jbVBtS189LtaZBnEWZQfyjKl8h6lJyVU2kBfaYoEOO31T8n20sG\n\
0074 NdkmACeCyNMs5V3yq1vAeN4=\n\
0075 -----END PRIVATE KEY-----");
0076 }
0077 
0078 SslServer::SslServer(QSsl::SslProtocol protocol, bool waitForStartTls)
0079     : QTcpServer()
0080     , mProtocol(protocol)
0081     , mWaitForStartTls(waitForStartTls)
0082 {
0083 }
0084 
0085 void SslServer::incomingConnection(qintptr handle)
0086 {
0087     auto socket = new QSslSocket();
0088     socket->setSocketDescriptor(handle);
0089 
0090     socket->setProtocol(mProtocol);
0091 
0092     QSslKey ssl_key(staticKey(), QSsl::Rsa);
0093     QSslCertificate ssl_cert(staticCert());
0094     Q_ASSERT(QDateTime::currentDateTime() >= ssl_cert.effectiveDate());
0095     Q_ASSERT(QDateTime::currentDateTime() <= ssl_cert.expiryDate());
0096     Q_ASSERT(!ssl_cert.isBlacklisted());
0097 
0098     socket->setPrivateKey(ssl_key);
0099     socket->setLocalCertificate(ssl_cert);
0100     socket->sslConfiguration().addCaCertificates(QList<QSslCertificate>() << ssl_cert);
0101     socket->setPeerVerifyMode(QSslSocket::VerifyNone);
0102     socket->ignoreSslErrors();
0103     connect(socket, &QSslSocket::sslErrors, this, &SslServer::sslErrors);
0104     connect(socket, &QAbstractSocket::errorOccurred, this, &SslServer::error);
0105     if (!mWaitForStartTls) {
0106         socket->startServerEncryption();
0107     }
0108 
0109     addPendingConnection(socket);
0110 }
0111 
0112 void SslServer::sslErrors(const QList<QSslError> &errors)
0113 {
0114     for (const QSslError &error : errors) {
0115         qWarning() << "Received ssl error: " << error.errorString();
0116     }
0117     auto socket = qobject_cast<QSslSocket *>(QObject::sender());
0118     if (socket) {
0119         socket->disconnectFromHost();
0120     }
0121 }
0122 
0123 void SslServer::error(QAbstractSocket::SocketError error)
0124 {
0125     auto socket = qobject_cast<QSslSocket *>(QObject::sender());
0126     if (socket) {
0127         qWarning() << socket->errorString();
0128     }
0129     qWarning() << error;
0130 }
0131 
0132 #include "moc_sslserver.cpp"