Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mumble-voip/mumble.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/SelfSignedCertificate.cpp280
-rw-r--r--src/SelfSignedCertificate.h22
-rw-r--r--src/mumble.pri4
-rw-r--r--src/mumble/Cert.cpp60
-rw-r--r--src/murmur/Cert.cpp226
-rw-r--r--src/tests/TestSelfSignedCertificate/TestSelfSignedCertificate.cpp44
-rw-r--r--src/tests/TestSelfSignedCertificate/TestSelfSignedCertificate.pro13
-rw-r--r--src/tests/tests.pro3
8 files changed, 371 insertions, 281 deletions
diff --git a/src/SelfSignedCertificate.cpp b/src/SelfSignedCertificate.cpp
new file mode 100644
index 000000000..c6fa9c3cd
--- /dev/null
+++ b/src/SelfSignedCertificate.cpp
@@ -0,0 +1,280 @@
+// Copyright 2005-2017 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 <https://www.mumble.info/LICENSE>.
+
+#include "murmur_pch.h"
+
+#include "SelfSignedCertificate.h"
+
+#define SSL_STRING(x) QString::fromLatin1(x).toUtf8().data()
+
+static int add_ext(X509 * crt, int nid, char *value) {
+ X509V3_CTX ctx;
+ X509V3_set_ctx_nodb(&ctx);
+ X509V3_set_ctx(&ctx, crt, crt, NULL, NULL, 0);
+
+ X509_EXTENSION *ex = X509V3_EXT_conf_nid(NULL, &ctx, nid, value);
+ if (ex == NULL) {
+ return 0;
+ }
+
+ if (X509_add_ext(crt, ex, -1) == 0) {
+ X509_EXTENSION_free(ex);
+ return 0;
+ }
+
+ X509_EXTENSION_free(ex);
+ return 1;
+}
+
+bool SelfSignedCertificate::generate(QString clientCertName, QString clientCertEmail, QSslCertificate &qscCert, QSslKey &qskKey) {
+ bool ok = true;
+ X509 *x509 = NULL;
+ EVP_PKEY *pkey = NULL;
+ RSA *rsa = NULL;
+ BIGNUM *e = NULL;
+ X509_NAME *name = NULL;
+ ASN1_INTEGER *serialNumber = NULL;
+ ASN1_TIME *notBefore = NULL;
+ ASN1_TIME *notAfter = NULL;
+ QString commonName;
+ bool isServerCert = clientCertName.isEmpty() && clientCertEmail.isEmpty();
+
+ if (CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON) == -1) {
+ ok = false;
+ goto out;
+ }
+
+ x509 = X509_new();
+ if (x509 == NULL) {
+ ok = false;
+ goto out;
+ }
+
+ pkey = EVP_PKEY_new();
+ if (pkey == NULL) {
+ ok = false;
+ goto out;
+ }
+
+ rsa = RSA_new();
+ if (rsa == NULL) {
+ ok = false;
+ goto out;
+ }
+
+ e = BN_new();
+ if (e == NULL) {
+ ok = false;
+ goto out;
+ }
+ if (BN_set_word(e, 65537) == 0) {
+ ok = false;
+ goto out;
+ }
+
+ if (RSA_generate_key_ex(rsa, 2048, e, NULL) == 0) {
+ ok = false;
+ goto out;
+ }
+
+ if (EVP_PKEY_assign_RSA(pkey, rsa) == 0) {
+ ok = false;
+ goto out;
+ }
+
+ if (X509_set_version(x509, 2) == 0) {
+ ok = false;
+ goto out;
+ }
+
+ serialNumber = X509_get_serialNumber(x509);
+ if (serialNumber == NULL) {
+ ok = false;
+ goto out;
+ }
+ if (ASN1_INTEGER_set(serialNumber, 1) == 0) {
+ ok = false;
+ goto out;
+ }
+
+ notBefore = X509_get_notBefore(x509);
+ if (notBefore == NULL) {
+ ok = false;
+ goto out;
+ }
+ if (X509_gmtime_adj(notBefore, 0) == NULL) {
+ ok = false;
+ goto out;
+ }
+
+ notAfter = X509_get_notAfter(x509);
+ if (notAfter == NULL) {
+ ok = false;
+ goto out;
+ }
+ if (X509_gmtime_adj(notAfter, 60*60*24*365*20) == NULL) {
+ ok = false;
+ goto out;
+ }
+
+ if (X509_set_pubkey(x509, pkey) == 0) {
+ ok = false;
+ goto out;
+ }
+
+ name = X509_get_subject_name(x509);
+ if (name == NULL) {
+ ok = false;
+ goto out;
+ }
+
+ if (isServerCert) {
+ commonName = QLatin1String("Murmur Autogenerated Certificate v2");
+ } else {
+ if (!clientCertName.isEmpty()) {
+ commonName = clientCertName;
+ } else {
+ commonName = QLatin1String("Mumble User");
+ }
+ }
+
+ if (X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC, reinterpret_cast<unsigned char *>(commonName.toUtf8().data()), -1, -1, 0) == 0) {
+ ok = false;
+ goto out;
+ }
+
+ if (X509_set_issuer_name(x509, name) == 0) {
+ ok = false;
+ goto out;
+ }
+
+ if (add_ext(x509, NID_basic_constraints, SSL_STRING("critical,CA:FALSE")) == 0) {
+ ok = false;
+ goto out;
+ }
+
+ if (isServerCert) {
+ if (add_ext(x509, NID_ext_key_usage, SSL_STRING("serverAuth,clientAuth")) == 0) {
+ ok = false;
+ goto out;
+ }
+ } else {
+ if (add_ext(x509, NID_ext_key_usage, SSL_STRING("clientAuth")) == 0) {
+ ok = false;
+ goto out;
+ }
+ }
+
+ if (add_ext(x509, NID_subject_key_identifier, SSL_STRING("hash")) == 0) {
+ ok = false;
+ goto out;
+ }
+
+ if (isServerCert) {
+ if (add_ext(x509, NID_netscape_comment, SSL_STRING("Generated from murmur")) == 0) {
+ ok = false;
+ goto out;
+ }
+ } else {
+ if (add_ext(x509, NID_netscape_comment, SSL_STRING("Generated by Mumble")) == 0) {
+ ok = false;
+ goto out;
+ }
+ }
+
+ if (!isServerCert) {
+ if (add_ext(x509, NID_subject_alt_name, QString::fromLatin1("email:%1").arg(clientCertEmail).toUtf8().data()) == 0) {
+ ok = false;
+ goto out;
+ }
+ }
+
+ if (X509_sign(x509, pkey, EVP_sha1()) == 0) {
+ ok = false;
+ goto out;
+ }
+
+ {
+ QByteArray crt;
+ int len = i2d_X509(x509, NULL);
+ if (len <= 0) {
+ ok = false;
+ goto out;
+ }
+ crt.resize(len);
+
+ unsigned char *dptr = reinterpret_cast<unsigned char *>(crt.data());
+ if (i2d_X509(x509, &dptr) != len) {
+ ok = false;
+ goto out;
+ }
+
+ qscCert = QSslCertificate(crt, QSsl::Der);
+ if (qscCert.isNull()) {
+ ok = false;
+ }
+ }
+
+ {
+ QByteArray key;
+ int len = i2d_PrivateKey(pkey, NULL);
+ if (len <= 0) {
+ ok = false;
+ goto out;
+ }
+ key.resize(len);
+
+ unsigned char *dptr = reinterpret_cast<unsigned char *>(key.data());
+ if (i2d_PrivateKey(pkey, &dptr) != len) {
+ ok = false;
+ goto out;
+ }
+
+ qskKey = QSslKey(key, QSsl::Rsa, QSsl::Der);
+ if (qskKey.isNull()) {
+ ok = false;
+ }
+ }
+
+out:
+ if (e) {
+ BN_free(e);
+ }
+ // We only need to free the pkey pointer,
+ // not the RSA pointer. We have assigned
+ // our RSA key to pkey, and it will be freed
+ // once we free pkey.
+ if (pkey) {
+ EVP_PKEY_free(pkey);
+ }
+ if (x509) {
+ X509_free(x509);
+ }
+
+ if (!ok) {
+ qscCert = QSslCertificate();
+ qskKey = QSslKey();
+ }
+
+ return ok;
+}
+
+bool SelfSignedCertificate::generateMumbleCertificate(QString name, QString email, QSslCertificate &qscCert, QSslKey &qskKey) {
+ if (name.trimmed().isEmpty()) {
+ qscCert = QSslCertificate();
+ qskKey = QSslKey();
+ return false;
+ }
+ if (email.trimmed().isEmpty()) {
+ qscCert = QSslCertificate();
+ qskKey = QSslKey();
+ return false;
+ }
+ return SelfSignedCertificate::generate(name, email, qscCert, qskKey);
+}
+
+bool SelfSignedCertificate::generateMurmurV2Certificate(QSslCertificate &qscCert, QSslKey &qskKey) {
+ return SelfSignedCertificate::generate(QString(), QString(), qscCert, qskKey);
+} \ No newline at end of file
diff --git a/src/SelfSignedCertificate.h b/src/SelfSignedCertificate.h
new file mode 100644
index 000000000..a62cf472e
--- /dev/null
+++ b/src/SelfSignedCertificate.h
@@ -0,0 +1,22 @@
+// Copyright 2005-2017 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 <https://www.mumble.info/LICENSE>.
+
+#ifndef MUMBLE_SELFSIGNEDCERTIFICATE_H_
+#define MUMBLE_SELFSIGNEDCERTIFICATE_H_
+
+#include <QtCore/QString>
+#include <QtNetwork/QSslCertificate>
+#include <QtNetwork/QSslKey>
+
+class SelfSignedCertificate {
+private:
+ static bool generate(QString clientCertName, QString clientCertEmail, QSslCertificate &qscCert, QSslKey &qskKey);
+
+public:
+ static bool generateMumbleCertificate(QString name, QString email, QSslCertificate &qscCert, QSslKey &qskKey);
+ static bool generateMurmurV2Certificate(QSslCertificate &qscCert, QSslKey &qskKey);
+};
+
+#endif
diff --git a/src/mumble.pri b/src/mumble.pri
index f0c96319e..4ee2f9a3a 100644
--- a/src/mumble.pri
+++ b/src/mumble.pri
@@ -14,8 +14,8 @@ CONFIG += qt thread debug_and_release warn_on
DEFINES *= MUMBLE_VERSION_STRING=$$VERSION
INCLUDEPATH += $$PWD . ../mumble_proto
VPATH += $$PWD
-HEADERS *= ACL.h Channel.h CryptState.h Connection.h Group.h HTMLFilter.h User.h Net.h OSInfo.h Timer.h SSL.h Version.h SSLCipherInfo.h SSLCipherInfoTable.h licenses.h License.h LogEmitter.h CryptographicHash.h CryptographicRandom.h PasswordGenerator.h ByteSwap.h HostAddress.cpp Ban.h EnvUtils.h UnresolvedServerAddress.h ServerAddress.h ServerResolver.h ServerResolverRecord.h
-SOURCES *= ACL.cpp Group.cpp Channel.cpp Connection.cpp HTMLFilter.cpp User.cpp Timer.cpp CryptState.cpp OSInfo.cpp SSL.cpp Version.cpp SSLCipherInfo.cpp License.cpp LogEmitter.cpp CryptographicHash.cpp CryptographicRandom.cpp PasswordGenerator.cpp HostAddress.cpp Ban.cpp EnvUtils.cpp UnresolvedServerAddress.cpp ServerAddress.cpp ServerResolver_qt5.cpp ServerResolverRecord.cpp
+HEADERS *= ACL.h Channel.h CryptState.h Connection.h Group.h HTMLFilter.h User.h Net.h OSInfo.h Timer.h SSL.h Version.h SSLCipherInfo.h SSLCipherInfoTable.h licenses.h License.h LogEmitter.h CryptographicHash.h CryptographicRandom.h PasswordGenerator.h ByteSwap.h HostAddress.cpp Ban.h EnvUtils.h UnresolvedServerAddress.h ServerAddress.h ServerResolver.h ServerResolverRecord.h SelfSignedCertificate.h
+SOURCES *= ACL.cpp Group.cpp Channel.cpp Connection.cpp HTMLFilter.cpp User.cpp Timer.cpp CryptState.cpp OSInfo.cpp SSL.cpp Version.cpp SSLCipherInfo.cpp License.cpp LogEmitter.cpp CryptographicHash.cpp CryptographicRandom.cpp PasswordGenerator.cpp HostAddress.cpp Ban.cpp EnvUtils.cpp UnresolvedServerAddress.cpp ServerAddress.cpp ServerResolver_qt5.cpp ServerResolverRecord.cpp SelfSignedCertificate.cpp
LIBS *= -lmumble_proto
equals(QT_MAJOR_VERSION, 4) {
diff --git a/src/mumble/Cert.cpp b/src/mumble/Cert.cpp
index 30e1abdc1..2c5ecd313 100644
--- a/src/mumble/Cert.cpp
+++ b/src/mumble/Cert.cpp
@@ -16,6 +16,7 @@
#include "Cert.h"
#include "Global.h"
+#include "SelfSignedCertificate.h"
#define SSL_STRING(x) QString::fromLatin1(x).toUtf8().data()
@@ -351,20 +352,6 @@ void CertWizard::on_qlIntroText_linkActivated(const QString &url) {
QDesktopServices::openUrl(QUrl(url));
}
-static int add_ext(X509 * crt, int nid, char *value) {
- X509_EXTENSION *ex;
- X509V3_CTX ctx;
- X509V3_set_ctx_nodb(&ctx);
- X509V3_set_ctx(&ctx, crt, crt, NULL, NULL, 0);
- ex = X509V3_EXT_conf_nid(NULL, &ctx, nid, value);
- if (!ex)
- return 0;
-
- X509_add_ext(crt, ex, -1);
- X509_EXTENSION_free(ex);
- return 1;
-}
-
bool CertWizard::validateCert(const Settings::KeyPair &kp) {
bool valid = ! kp.second.isNull() && ! kp.first.isEmpty();
foreach(const QSslCertificate &cert, kp.first)
@@ -373,47 +360,12 @@ bool CertWizard::validateCert(const Settings::KeyPair &kp) {
}
Settings::KeyPair CertWizard::generateNewCert(QString qsname, const QString &qsemail) {
- CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
-
- X509 *x509 = X509_new();
- EVP_PKEY *pkey = EVP_PKEY_new();
- RSA *rsa = RSA_generate_key(2048,RSA_F4,NULL,NULL);
- EVP_PKEY_assign_RSA(pkey, rsa);
-
- X509_set_version(x509, 2);
- ASN1_INTEGER_set(X509_get_serialNumber(x509),1);
- X509_gmtime_adj(X509_get_notBefore(x509),0);
- X509_gmtime_adj(X509_get_notAfter(x509),60*60*24*365*20);
- X509_set_pubkey(x509, pkey);
-
- X509_NAME *name=X509_get_subject_name(x509);
-
- if (qsname.isEmpty())
- qsname = tr("Mumble User");
-
- X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC, reinterpret_cast<unsigned char *>(qsname.toUtf8().data()), -1, -1, 0);
- X509_set_issuer_name(x509, name);
- add_ext(x509, NID_basic_constraints, SSL_STRING("critical,CA:FALSE"));
- add_ext(x509, NID_ext_key_usage, SSL_STRING("clientAuth"));
- add_ext(x509, NID_subject_key_identifier, SSL_STRING("hash"));
- add_ext(x509, NID_netscape_comment, SSL_STRING("Generated by Mumble"));
- add_ext(x509, NID_subject_alt_name, QString::fromLatin1("email:%1").arg(qsemail).toUtf8().data());
-
- X509_sign(x509, pkey, EVP_sha1());
-
- QByteArray crt, key;
-
- crt.resize(i2d_X509(x509, NULL));
- unsigned char *dptr=reinterpret_cast<unsigned char *>(crt.data());
- i2d_X509(x509, &dptr);
-
- QSslCertificate qscCert = QSslCertificate(crt, QSsl::Der);
-
- key.resize(i2d_PrivateKey(pkey, NULL));
- dptr=reinterpret_cast<unsigned char *>(key.data());
- i2d_PrivateKey(pkey, &dptr);
+ QSslCertificate qscCert;
+ QSslKey qskKey;
- QSslKey qskKey = QSslKey(key, QSsl::Rsa, QSsl::Der);
+ // Ignore return value.
+ // The method sets qscCert and qskKey to null values if it fails.
+ SelfSignedCertificate::generateMumbleCertificate(qsname, qsemail, qscCert, qskKey);
QList<QSslCertificate> qlCert;
qlCert << qscCert;
diff --git a/src/murmur/Cert.cpp b/src/murmur/Cert.cpp
index d860c1caa..167013627 100644
--- a/src/murmur/Cert.cpp
+++ b/src/murmur/Cert.cpp
@@ -7,229 +7,7 @@
#include "Meta.h"
#include "Server.h"
-
-#define SSL_STRING(x) QString::fromLatin1(x).toUtf8().data()
-
-static int add_ext(X509 * crt, int nid, char *value) {
- X509V3_CTX ctx;
- X509V3_set_ctx_nodb(&ctx);
- X509V3_set_ctx(&ctx, crt, crt, NULL, NULL, 0);
-
- X509_EXTENSION *ex = X509V3_EXT_conf_nid(NULL, &ctx, nid, value);
- if (ex == NULL) {
- return 0;
- }
-
- if (X509_add_ext(crt, ex, -1) == 0) {
- X509_EXTENSION_free(ex);
- return 0;
- }
-
- X509_EXTENSION_free(ex);
- return 1;
-}
-
-static bool selfSignedServerCert_SHA1_RSA_2048(QSslCertificate &qscCert, QSslKey &qskKey) {
- bool ok = true;
- X509 *x509 = NULL;
- EVP_PKEY *pkey = NULL;
- RSA *rsa = NULL;
- BIGNUM *e = NULL;
- X509_NAME *name = NULL;
- ASN1_INTEGER *serialNumber = NULL;
- ASN1_TIME *notBefore = NULL;
- ASN1_TIME *notAfter = NULL;
- unsigned char *commonName = NULL;
-
- if (CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON) == -1) {
- ok = false;
- goto out;
- }
-
- x509 = X509_new();
- if (x509 == NULL) {
- ok = false;
- goto out;
- }
-
- pkey = EVP_PKEY_new();
- if (pkey == NULL) {
- ok = false;
- goto out;
- }
-
- rsa = RSA_new();
- if (rsa == NULL) {
- ok = false;
- goto out;
- }
-
- e = BN_new();
- if (e == NULL) {
- ok = false;
- goto out;
- }
- if (BN_set_word(e, 65537) == 0) {
- ok = false;
- goto out;
- }
-
- if (RSA_generate_key_ex(rsa, 2048, e, NULL) == 0) {
- ok = false;
- goto out;
- }
-
- if (EVP_PKEY_assign_RSA(pkey, rsa) == 0) {
- ok = false;
- goto out;
- }
-
- if (X509_set_version(x509, 2) == 0) {
- ok = false;
- goto out;
- }
-
- serialNumber = X509_get_serialNumber(x509);
- if (serialNumber == NULL) {
- ok = false;
- goto out;
- }
- if (ASN1_INTEGER_set(serialNumber, 1) == 0) {
- ok = false;
- goto out;
- }
-
- notBefore = X509_get_notBefore(x509);
- if (notBefore == NULL) {
- ok = false;
- goto out;
- }
- if (X509_gmtime_adj(notBefore, 0) == NULL) {
- ok = false;
- goto out;
- }
-
- notAfter = X509_get_notAfter(x509);
- if (notAfter == NULL) {
- ok = false;
- goto out;
- }
- if (X509_gmtime_adj(notAfter, 60*60*24*365*20) == NULL) {
- ok = false;
- goto out;
- }
-
- if (X509_set_pubkey(x509, pkey) == 0) {
- ok = false;
- goto out;
- }
-
- name = X509_get_subject_name(x509);
- if (name == NULL) {
- ok = false;
- goto out;
- }
-
- commonName = reinterpret_cast<unsigned char *>(const_cast<char *>("Murmur Autogenerated Certificate v2"));
- if (X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC, commonName, -1, -1, 0) == 0) {
- ok = false;
- goto out;
- }
-
- if (X509_set_issuer_name(x509, name) == 0) {
- ok = false;
- goto out;
- }
-
- if (add_ext(x509, NID_basic_constraints, SSL_STRING("critical,CA:FALSE")) == 0) {
- ok = false;
- goto out;
- }
-
- if (add_ext(x509, NID_ext_key_usage, SSL_STRING("serverAuth,clientAuth")) == 0) {
- ok = false;
- goto out;
- }
-
- if (add_ext(x509, NID_subject_key_identifier, SSL_STRING("hash")) == 0) {
- ok = false;
- goto out;
- }
-
- if (add_ext(x509, NID_netscape_comment, SSL_STRING("Generated from murmur")) == 0) {
- ok = false;
- goto out;
- }
-
- if (X509_sign(x509, pkey, EVP_sha1()) == 0) {
- ok = false;
- goto out;
- }
-
- {
- QByteArray crt;
- int len = i2d_X509(x509, NULL);
- if (len <= 0) {
- ok = false;
- goto out;
- }
- crt.resize(len);
-
- unsigned char *dptr = reinterpret_cast<unsigned char *>(crt.data());
- if (i2d_X509(x509, &dptr) != len) {
- ok = false;
- goto out;
- }
-
- qscCert = QSslCertificate(crt, QSsl::Der);
- if (qscCert.isNull()) {
- ok = false;
- }
- }
-
- {
- QByteArray key;
- int len = i2d_PrivateKey(pkey, NULL);
- if (len <= 0) {
- ok = false;
- goto out;
- }
- key.resize(len);
-
- unsigned char *dptr = reinterpret_cast<unsigned char *>(key.data());
- if (i2d_PrivateKey(pkey, &dptr) != len) {
- ok = false;
- goto out;
- }
-
- qskKey = QSslKey(key, QSsl::Rsa, QSsl::Der);
- if (qskKey.isNull()) {
- ok = false;
- }
- }
-
-out:
- if (e) {
- BN_free(e);
- }
- // We only need to free the pkey pointer,
- // not the RSA pointer. We have assigned
- // our RSA key to pkey, and it will be freed
- // once we free pkey.
- if (pkey) {
- EVP_PKEY_free(pkey);
- }
- if (x509) {
- X509_free(x509);
- }
-
- if (!ok) {
- qscCert = QSslCertificate();
- qskKey = QSslKey();
- }
-
- return ok;
-}
+#include "SelfSignedCertificate.h"
#if defined(USE_QSSLDIFFIEHELLMANPARAMETERS)
static BN_GENCB *mumble_BN_GENCB_new() {
@@ -415,7 +193,7 @@ void Server::initializeCert() {
if (qscCert.isNull() || qskKey.isNull()) {
log("Generating new server certificate.");
- if (!selfSignedServerCert_SHA1_RSA_2048(qscCert, qskKey)) {
+ if (!SelfSignedCertificate::generateMurmurV2Certificate(qscCert, qskKey)) {
log("Certificate or key generation failed");
}
diff --git a/src/tests/TestSelfSignedCertificate/TestSelfSignedCertificate.cpp b/src/tests/TestSelfSignedCertificate/TestSelfSignedCertificate.cpp
new file mode 100644
index 000000000..814474366
--- /dev/null
+++ b/src/tests/TestSelfSignedCertificate/TestSelfSignedCertificate.cpp
@@ -0,0 +1,44 @@
+// Copyright 2005-2017 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 <https://www.mumble.info/LICENSE>.
+
+#include <QtCore>
+#include <QtTest>
+
+#include "SelfSignedCertificate.h"
+
+class TestSelfSignedCertificate : public QObject {
+ Q_OBJECT
+ private slots:
+ void exerciseClientCert();
+ void exerciseServerCert();
+};
+
+void TestSelfSignedCertificate::exerciseClientCert() {
+ QSslCertificate cert;
+ QSslKey key;
+
+ bool ok = SelfSignedCertificate::generateMumbleCertificate(QLatin1String("Test"), QLatin1String("test@test.test"), cert, key);
+ QCOMPARE(ok, true);
+ QCOMPARE(cert.isNull(), false);
+ QCOMPARE(cert.isNull(), false);
+
+ ok = SelfSignedCertificate::generateMumbleCertificate(QString(), QString(), cert, key);
+ QCOMPARE(ok, false);
+ QCOMPARE(cert.isNull(), true);
+ QCOMPARE(cert.isNull(), true);
+}
+
+void TestSelfSignedCertificate::exerciseServerCert() {
+ QSslCertificate cert;
+ QSslKey key;
+
+ bool ok = SelfSignedCertificate::generateMurmurV2Certificate(cert, key);
+ QCOMPARE(ok, true);
+ QCOMPARE(cert.isNull(), false);
+ QCOMPARE(cert.isNull(), false);
+}
+
+QTEST_MAIN(TestSelfSignedCertificate)
+#include "TestSelfSignedCertificate.moc"
diff --git a/src/tests/TestSelfSignedCertificate/TestSelfSignedCertificate.pro b/src/tests/TestSelfSignedCertificate/TestSelfSignedCertificate.pro
new file mode 100644
index 000000000..476765249
--- /dev/null
+++ b/src/tests/TestSelfSignedCertificate/TestSelfSignedCertificate.pro
@@ -0,0 +1,13 @@
+# Copyright 2005-2017 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 <https://www.mumble.info/LICENSE>.
+
+include(../test.pri)
+include(../../../qmake/qt.pri)
+
+QT *= network
+
+TARGET = TestSelfSignedCertificate
+SOURCES = TestSelfSignedCertificate.cpp SelfSignedCertificate.cpp
+HEADERS = SelfSignedCertificate.h
diff --git a/src/tests/tests.pro b/src/tests/tests.pro
index 3ed9a767b..2b608453b 100644
--- a/src/tests/tests.pro
+++ b/src/tests/tests.pro
@@ -15,4 +15,5 @@ SUBDIRS += \
TestXMLTools \
TestUnresolvedServerAddress \
TestServerAddress \
- TestServerResolver
+ TestServerResolver \
+ TestSelfSignedCertificate