// Copyright 2005-2020 The Mumble Developers. All rights reserved. // Use of this source code is governed by a BSD-style license // that can be found in the LICENSE file at the root of the // Mumble source tree or at . #include #ifdef Q_OS_WIN # include "win.h" #endif #include "Meta.h" #include "Server.h" #include "SelfSignedCertificate.h" #include #include #include #ifdef Q_OS_WIN # include #endif bool Server::isKeyForCert(const QSslKey &key, const QSslCertificate &cert) { if (key.isNull() || cert.isNull() || (key.type() != QSsl::PrivateKey)) return false; QByteArray qbaKey = key.toDer(); QByteArray qbaCert = cert.toDer(); X509 *x509 = NULL; EVP_PKEY *pkey = NULL; BIO *mem = NULL; mem = BIO_new_mem_buf(qbaKey.data(), qbaKey.size()); Q_UNUSED(BIO_set_close(mem, BIO_NOCLOSE)); pkey = d2i_PrivateKey_bio(mem, NULL); BIO_free(mem); mem = BIO_new_mem_buf(qbaCert.data(), qbaCert.size()); Q_UNUSED(BIO_set_close(mem, BIO_NOCLOSE)); x509 = d2i_X509_bio(mem, NULL); BIO_free(mem); mem = NULL; if (x509 && pkey && X509_check_private_key(x509, pkey)) { EVP_PKEY_free(pkey); X509_free(x509); return true; } if (pkey) EVP_PKEY_free(pkey); if (x509) X509_free(x509); return false; } QSslKey Server::privateKeyFromPEM(const QByteArray &buf, const QByteArray &pass) { QSslKey key; key = QSslKey(buf, QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey, pass); if (key.isNull()) key = QSslKey(buf, QSsl::Dsa, QSsl::Pem, QSsl::PrivateKey, pass); #if QT_VERSION >= 0x050500 if (key.isNull()) key = QSslKey(buf, QSsl::Ec, QSsl::Pem, QSsl::PrivateKey, pass); #endif return key; } void Server::initializeCert() { QByteArray crt, key, pass, dhparams; // Clear all exising SSL settings // for this server. qscCert.clear(); qlIntermediates.clear(); qskKey.clear(); #if defined(USE_QSSLDIFFIEHELLMANPARAMETERS) qsdhpDHParams = QSslDiffieHellmanParameters(); #endif crt = getConf("certificate", QString()).toByteArray(); key = getConf("key", QString()).toByteArray(); pass = getConf("passphrase", QByteArray()).toByteArray(); dhparams = getConf("sslDHParams", Meta::mp.qbaDHParams).toByteArray(); QList ql; // Attempt to load the private key. if (! key.isEmpty()) { qskKey = Server::privateKeyFromPEM(key, pass); } // If we still can't load the key, try loading any keys from the certificate if (qskKey.isNull() && ! crt.isEmpty()) { qskKey = Server::privateKeyFromPEM(crt); } // If have a key, walk the list of certs, find the one for our key, // remove any certs for our key from the list, what's left is part of // the CA certificate chain. if (! qskKey.isNull()) { ql << QSslCertificate::fromData(crt); ql << QSslCertificate::fromData(key); for (int i=0;i