mumble: update to 1.5.634.

This commit is contained in:
Helmut Pozimski 2024-05-20 11:45:27 +02:00
parent de41d3b8f4
commit a5d0641703
6 changed files with 5 additions and 772 deletions

View File

@ -1,20 +0,0 @@
--- a/src/murmur/CMakeLists.txt 2022-09-13 19:24:40.000000000 +0200
+++ - 2023-07-14 17:23:13.145173297 +0200
@@ -77,6 +77,7 @@
)
target_link_libraries(mumble-server PRIVATE shared Qt5::Sql)
+target_link_libraries(mumble-server PRIVATE shared absl_log_internal_message)
if(static)
# MariaDB and MySQL
--- a/src/mumble/CMakeLists.txt 2022-09-13 19:24:40.000000000 +0200
+++ - 2023-07-14 17:25:05.556023593 +0200
@@ -472,6 +472,7 @@
Qt5::Sql
Qt5::Svg
Qt5::Widgets
+ absl_log_internal_message
)
if(static)

View File

@ -1,11 +0,0 @@
--- a/scripts/murmur.ini
+++ b/scripts/murmur.ini
@@ -13,7 +13,7 @@
; Path to database. If blank, will search for
; murmur.sqlite in default locations or create it if not found.
-database=
+database=/var/lib/murmur/murmur.sqlite
; Murmur defaults to using SQLite with its default rollback journal.
; In some situations, using SQLite's write-ahead log (WAL) can be

View File

@ -1,11 +0,0 @@
--- mumble-1.4.287/CMakeLists.txt 2022-09-13 19:24:40.000000000 +0200
+++ - 2023-07-10 20:12:27.869019033 +0200
@@ -35,7 +35,7 @@
set(3RDPARTY_DIR "${CMAKE_SOURCE_DIR}/3rdparty")
set(PLUGINS_DIR "${CMAKE_SOURCE_DIR}/plugins")
-set(CMAKE_CXX_STANDARD 14)
+set(CMAKE_CXX_STANDARD 17)
set(CMAKE_OSX_DEPLOYMENT_TARGET 10.13)
list(APPEND CMAKE_MODULE_PATH

View File

@ -1,685 +0,0 @@
From f4cea62ed95e4967d8591f25e903f5e8fc2e2a30 Mon Sep 17 00:00:00 2001
From: Terry Geng <terry@terriex.com>
Date: Mon, 6 Dec 2021 10:45:11 -0500
Subject: [PATCH] BUILD(crypto): Migrate to OpenSSL 3.0-compatible API
OpenSSL 3.0 deprecated several low-level APIs and the usage of them
caused errors/warnings that prevent the binary from being built against
OpenSSL 3.0.
Some primitive efforts have been made in #5317 but were incomplete.
This commit follows https://www.openssl.org/docs/man3.0/man7/migration_guide.html,
https://code.woboq.org/qt6/qtopcua/src/opcua/x509/qopcuakeypair_openssl.cpp.html,
and clears all errors/warnings related to the usage of deprecated APIs.
Fixes #5277
Fixes #4266
---
src/SelfSignedCertificate.cpp | 235 +++++++++++-----------------------
src/SelfSignedCertificate.h | 5 +
src/crypto/CryptStateOCB2.cpp | 53 +++++---
src/crypto/CryptStateOCB2.h | 9 +-
4 files changed, 121 insertions(+), 181 deletions(-)
diff --git a/src/SelfSignedCertificate.cpp b/src/SelfSignedCertificate.cpp
index a77e5fad91..ea0dec4cc7 100644
--- a/src/SelfSignedCertificate.cpp
+++ b/src/SelfSignedCertificate.cpp
@@ -5,8 +5,6 @@
#include "SelfSignedCertificate.h"
-#include <openssl/x509v3.h>
-
#define SSL_STRING(x) QString::fromLatin1(x).toUtf8().data()
static int add_ext(X509 *crt, int nid, char *value) {
@@ -28,108 +26,86 @@ static int add_ext(X509 *crt, int nid, char *value) {
return 1;
}
-bool SelfSignedCertificate::generate(CertificateType certificateType, QString clientCertName, QString clientCertEmail,
- QSslCertificate &qscCert, QSslKey &qskKey) {
- bool ok = true;
- X509 *x509 = nullptr;
- EVP_PKEY *pkey = nullptr;
- RSA *rsa = nullptr;
- BIGNUM *e = nullptr;
- X509_NAME *name = nullptr;
- ASN1_INTEGER *serialNumber = nullptr;
- ASN1_TIME *notBefore = nullptr;
- ASN1_TIME *notAfter = nullptr;
- QString commonName;
- bool isServerCert = certificateType == CertificateTypeServerCertificate;
-
- if (CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON) == -1) {
- ok = false;
- goto out;
+EVP_PKEY *SelfSignedCertificate::generate_rsa_keypair() {
+ EVP_PKEY *pkey = EVP_PKEY_new();
+ if (!pkey) {
+ return nullptr;
}
- x509 = X509_new();
- if (!x509) {
- ok = false;
- goto out;
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+ EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, nullptr);
+ if (!ctx) {
+ return nullptr;
}
-
- pkey = EVP_PKEY_new();
- if (!pkey) {
- ok = false;
- goto out;
+ if (EVP_PKEY_keygen_init(ctx) <= 0) {
+ return nullptr;
}
-
- rsa = RSA_new();
+ if (EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, 2048) <= 0) {
+ return nullptr;
+ }
+ if (EVP_PKEY_keygen(ctx, &pkey) <= 0) {
+ return nullptr;
+ }
+ EVP_PKEY_CTX_free(ctx);
+#else
+ RSA *rsa = RSA_new();
+ BIGNUM *e = BN_new();
if (!rsa) {
- ok = false;
- goto out;
+ return nullptr;
}
-
- e = BN_new();
if (!e) {
- ok = false;
- goto out;
+ return nullptr;
}
if (BN_set_word(e, 65537) == 0) {
- ok = false;
- goto out;
+ return nullptr;
}
-
if (RSA_generate_key_ex(rsa, 2048, e, nullptr) == 0) {
- ok = false;
- goto out;
+ return nullptr;
}
-
if (EVP_PKEY_assign_RSA(pkey, rsa) == 0) {
- ok = false;
- goto out;
+ return nullptr;
}
+ BN_free(e);
+ RSA_free(rsa);
+#endif
+ return pkey;
+}
- if (X509_set_version(x509, 2) == 0) {
- ok = false;
- goto out;
+#define CHECK(statement) \
+ if (!(statement)) { \
+ ok = false; \
+ goto out; \
}
- serialNumber = X509_get_serialNumber(x509);
- if (!serialNumber) {
- ok = false;
- goto out;
- }
- if (ASN1_INTEGER_set(serialNumber, 1) == 0) {
- ok = false;
- goto out;
- }
- notBefore = X509_get_notBefore(x509);
- if (!notBefore) {
- ok = false;
- goto out;
- }
- if (!X509_gmtime_adj(notBefore, 0)) {
- ok = false;
- goto out;
- }
+bool SelfSignedCertificate::generate(CertificateType certificateType, QString clientCertName, QString clientCertEmail,
+ QSslCertificate &qscCert, QSslKey &qskKey) {
+ bool ok = true;
+ EVP_PKEY *pkey = nullptr;
+ X509 *x509 = nullptr;
+ X509_NAME *name = nullptr;
+ ASN1_INTEGER *serialNumber = nullptr;
+ ASN1_TIME *notBefore = nullptr;
+ ASN1_TIME *notAfter = nullptr;
+ QString commonName;
+ bool isServerCert = certificateType == CertificateTypeServerCertificate;
- notAfter = X509_get_notAfter(x509);
- if (!notAfter) {
- ok = false;
- goto out;
- }
- if (!X509_gmtime_adj(notAfter, 60 * 60 * 24 * 365 * 20)) {
- ok = false;
- goto out;
- }
+ // In Qt 5.15, a class was added to wrap up the procedures of generating a self-signed certificate.
+ // See https://doc.qt.io/qt-5/qopcuax509certificatesigningrequest.html.
+ // We should consider migrating to this class after switching to Qt 5.15.
- if (X509_set_pubkey(x509, pkey) == 0) {
- ok = false;
- goto out;
- }
+ CHECK(pkey = generate_rsa_keypair());
- name = X509_get_subject_name(x509);
- if (!name) {
- ok = false;
- goto out;
- }
+ CHECK(x509 = X509_new());
+ CHECK(X509_set_version(x509, 2));
+ CHECK(serialNumber = X509_get_serialNumber(x509));
+ CHECK(ASN1_INTEGER_set(serialNumber, 1));
+ CHECK(notBefore = X509_get_notBefore(x509));
+ CHECK(X509_gmtime_adj(notBefore, 0));
+ CHECK(notAfter = X509_get_notAfter(x509));
+ CHECK(X509_gmtime_adj(notAfter, 60 * 60 * 24 * 365 * 20))
+ CHECK(X509_set_pubkey(x509, pkey));
+ CHECK(name = X509_get_subject_name(x509));
if (isServerCert) {
commonName = QLatin1String("Murmur Autogenerated Certificate v2");
@@ -141,120 +117,63 @@ bool SelfSignedCertificate::generate(CertificateType certificateType, QString cl
}
}
- if (X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_UTF8,
- reinterpret_cast< unsigned char * >(commonName.toUtf8().data()), -1, -1, 0)
- == 0) {
- ok = false;
- goto out;
- }
+ CHECK(X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_UTF8,
+ reinterpret_cast< unsigned char * >(commonName.toUtf8().data()), -1, -1, 0));
- if (X509_set_issuer_name(x509, name) == 0) {
- ok = false;
- goto out;
- }
+ CHECK(X509_set_issuer_name(x509, name));
- if (add_ext(x509, NID_basic_constraints, SSL_STRING("critical,CA:FALSE")) == 0) {
- ok = false;
- goto out;
- }
+ CHECK(add_ext(x509, NID_basic_constraints, SSL_STRING("critical,CA:FALSE")));
if (isServerCert) {
- if (add_ext(x509, NID_ext_key_usage, SSL_STRING("serverAuth,clientAuth")) == 0) {
- ok = false;
- goto out;
- }
+ CHECK(add_ext(x509, NID_ext_key_usage, SSL_STRING("serverAuth,clientAuth")))
} else {
- if (add_ext(x509, NID_ext_key_usage, SSL_STRING("clientAuth")) == 0) {
- ok = false;
- goto out;
- }
+ CHECK(add_ext(x509, NID_ext_key_usage, SSL_STRING("clientAuth")));
}
- if (add_ext(x509, NID_subject_key_identifier, SSL_STRING("hash")) == 0) {
- ok = false;
- goto out;
- }
+ CHECK(add_ext(x509, NID_subject_key_identifier, SSL_STRING("hash")));
if (isServerCert) {
- if (add_ext(x509, NID_netscape_comment, SSL_STRING("Generated from murmur")) == 0) {
- ok = false;
- goto out;
- }
+ CHECK(add_ext(x509, NID_netscape_comment, SSL_STRING("Generated from murmur")));
} else {
- if (add_ext(x509, NID_netscape_comment, SSL_STRING("Generated by Mumble")) == 0) {
- ok = false;
- goto out;
- }
+ CHECK(add_ext(x509, NID_netscape_comment, SSL_STRING("Generated by Mumble")));
}
if (!isServerCert) {
if (!clientCertEmail.trimmed().isEmpty()) {
- if (add_ext(x509, NID_subject_alt_name,
- QString::fromLatin1("email:%1").arg(clientCertEmail).toUtf8().data())
- == 0) {
- ok = false;
- goto out;
- }
+ CHECK(add_ext(x509, NID_subject_alt_name,
+ QString::fromLatin1("email:%1").arg(clientCertEmail).toUtf8().data()));
}
}
- if (X509_sign(x509, pkey, EVP_sha1()) == 0) {
- ok = false;
- goto out;
- }
+ CHECK(X509_sign(x509, pkey, EVP_sha1()));
{
QByteArray crt;
int len = i2d_X509(x509, nullptr);
- if (len <= 0) {
- ok = false;
- goto out;
- }
+ CHECK(len > 0);
crt.resize(len);
unsigned char *dptr = reinterpret_cast< unsigned char * >(crt.data());
- if (i2d_X509(x509, &dptr) != len) {
- ok = false;
- goto out;
- }
+ CHECK(i2d_X509(x509, &dptr) == len);
qscCert = QSslCertificate(crt, QSsl::Der);
- if (qscCert.isNull()) {
- ok = false;
- goto out;
- }
+ CHECK(!qscCert.isNull());
}
{
QByteArray key;
int len = i2d_PrivateKey(pkey, nullptr);
- if (len <= 0) {
- ok = false;
- goto out;
- }
+ CHECK(len > 0);
key.resize(len);
unsigned char *dptr = reinterpret_cast< unsigned char * >(key.data());
- if (i2d_PrivateKey(pkey, &dptr) != len) {
- ok = false;
- goto out;
- }
+ CHECK(i2d_PrivateKey(pkey, &dptr) == len);
qskKey = QSslKey(key, QSsl::Rsa, QSsl::Der);
- if (qskKey.isNull()) {
- ok = false;
- goto out;
- }
+ CHECK(!qskKey.isNull());
}
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);
}
diff --git a/src/SelfSignedCertificate.h b/src/SelfSignedCertificate.h
index b85a8752b8..7c5f59e9c5 100644
--- a/src/SelfSignedCertificate.h
+++ b/src/SelfSignedCertificate.h
@@ -6,6 +6,10 @@
#ifndef MUMBLE_SELFSIGNEDCERTIFICATE_H_
#define MUMBLE_SELFSIGNEDCERTIFICATE_H_
+#include <openssl/evp.h>
+#include <openssl/rsa.h>
+#include <openssl/x509v3.h>
+
#include <QtCore/QString>
#include <QtNetwork/QSslCertificate>
#include <QtNetwork/QSslKey>
@@ -16,6 +20,7 @@ class SelfSignedCertificate {
private:
static bool generate(CertificateType certificateType, QString clientCertName, QString clientCertEmail,
QSslCertificate &qscCert, QSslKey &qskKey);
+ static EVP_PKEY *generate_rsa_keypair();
public:
static bool generateMumbleCertificate(QString name, QString email, QSslCertificate &qscCert, QSslKey &qskKey);
diff --git a/src/crypto/CryptStateOCB2.cpp b/src/crypto/CryptStateOCB2.cpp
index 2176d64883..640fdedac8 100644
--- a/src/crypto/CryptStateOCB2.cpp
+++ b/src/crypto/CryptStateOCB2.cpp
@@ -30,7 +30,7 @@
#include <cstring>
#include <openssl/rand.h>
-CryptStateOCB2::CryptStateOCB2() : CryptState() {
+CryptStateOCB2::CryptStateOCB2() : CryptState(), enc_ctx(EVP_CIPHER_CTX_new()), dec_ctx(EVP_CIPHER_CTX_new()) {
for (int i = 0; i < 0x100; i++)
decrypt_history[i] = 0;
memset(raw_key, 0, AES_KEY_SIZE_BYTES);
@@ -38,6 +38,11 @@ CryptStateOCB2::CryptStateOCB2() : CryptState() {
memset(decrypt_iv, 0, AES_BLOCK_SIZE);
}
+CryptStateOCB2::~CryptStateOCB2() noexcept {
+ EVP_CIPHER_CTX_free(enc_ctx);
+ EVP_CIPHER_CTX_free(dec_ctx);
+}
+
bool CryptStateOCB2::isValid() const {
return bInit;
}
@@ -46,8 +51,6 @@ void CryptStateOCB2::genKey() {
CryptographicRandom::fillBuffer(raw_key, AES_KEY_SIZE_BYTES);
CryptographicRandom::fillBuffer(encrypt_iv, AES_BLOCK_SIZE);
CryptographicRandom::fillBuffer(decrypt_iv, AES_BLOCK_SIZE);
- AES_set_encrypt_key(raw_key, AES_KEY_SIZE_BITS, &encrypt_key);
- AES_set_decrypt_key(raw_key, AES_KEY_SIZE_BITS, &decrypt_key);
bInit = true;
}
@@ -56,8 +59,6 @@ bool CryptStateOCB2::setKey(const std::string &rkey, const std::string &eiv, con
memcpy(raw_key, rkey.data(), AES_KEY_SIZE_BYTES);
memcpy(encrypt_iv, eiv.data(), AES_BLOCK_SIZE);
memcpy(decrypt_iv, div.data(), AES_BLOCK_SIZE);
- AES_set_encrypt_key(raw_key, AES_KEY_SIZE_BITS, &encrypt_key);
- AES_set_decrypt_key(raw_key, AES_KEY_SIZE_BITS, &decrypt_key);
bInit = true;
return true;
}
@@ -256,10 +257,24 @@ static void inline ZERO(keyblock &block) {
block[i] = 0;
}
-#define AESencrypt(src, dst, key) \
- AES_encrypt(reinterpret_cast< const unsigned char * >(src), reinterpret_cast< unsigned char * >(dst), key);
-#define AESdecrypt(src, dst, key) \
- AES_decrypt(reinterpret_cast< const unsigned char * >(src), reinterpret_cast< unsigned char * >(dst), key);
+#define AESencrypt(src, dst, key) \
+ { \
+ int outlen = 0; \
+ EVP_EncryptInit_ex(enc_ctx, EVP_aes_128_ecb(), NULL, key, NULL); \
+ EVP_CIPHER_CTX_set_padding(enc_ctx, 0); \
+ EVP_EncryptUpdate(enc_ctx, reinterpret_cast< unsigned char * >(dst), &outlen, \
+ reinterpret_cast< const unsigned char * >(src), AES_BLOCK_SIZE); \
+ EVP_EncryptFinal_ex(enc_ctx, reinterpret_cast< unsigned char * >(dst + outlen), &outlen); \
+ }
+#define AESdecrypt(src, dst, key) \
+ { \
+ int outlen = 0; \
+ EVP_DecryptInit_ex(dec_ctx, EVP_aes_128_ecb(), NULL, key, NULL); \
+ EVP_CIPHER_CTX_set_padding(dec_ctx, 0); \
+ EVP_DecryptUpdate(dec_ctx, reinterpret_cast< unsigned char * >(dst), &outlen, \
+ reinterpret_cast< const unsigned char * >(src), AES_BLOCK_SIZE); \
+ EVP_DecryptFinal_ex(dec_ctx, reinterpret_cast< unsigned char * >(dst + outlen), &outlen); \
+ }
bool CryptStateOCB2::ocb_encrypt(const unsigned char *plain, unsigned char *encrypted, unsigned int len,
const unsigned char *nonce, unsigned char *tag, bool modifyPlainOnXEXStarAttack) {
@@ -267,7 +282,7 @@ bool CryptStateOCB2::ocb_encrypt(const unsigned char *plain, unsigned char *encr
bool success = true;
// Initialize
- AESencrypt(nonce, delta, &encrypt_key);
+ AESencrypt(nonce, delta, raw_key);
ZERO(checksum);
while (len > AES_BLOCK_SIZE) {
@@ -299,7 +314,7 @@ bool CryptStateOCB2::ocb_encrypt(const unsigned char *plain, unsigned char *encr
if (flipABit) {
*reinterpret_cast< unsigned char * >(tmp) ^= 1;
}
- AESencrypt(tmp, tmp, &encrypt_key);
+ AESencrypt(tmp, tmp, raw_key);
XOR(reinterpret_cast< subblock * >(encrypted), delta, tmp);
XOR(checksum, checksum, reinterpret_cast< const subblock * >(plain));
if (flipABit) {
@@ -315,7 +330,7 @@ bool CryptStateOCB2::ocb_encrypt(const unsigned char *plain, unsigned char *encr
ZERO(tmp);
tmp[BLOCKSIZE - 1] = SWAPPED(len * 8);
XOR(tmp, tmp, delta);
- AESencrypt(tmp, pad, &encrypt_key);
+ AESencrypt(tmp, pad, raw_key);
memcpy(tmp, plain, len);
memcpy(reinterpret_cast< unsigned char * >(tmp) + len, reinterpret_cast< const unsigned char * >(pad) + len,
AES_BLOCK_SIZE - len);
@@ -325,7 +340,7 @@ bool CryptStateOCB2::ocb_encrypt(const unsigned char *plain, unsigned char *encr
S3(delta);
XOR(tmp, delta, checksum);
- AESencrypt(tmp, tag, &encrypt_key);
+ AESencrypt(tmp, tag, raw_key);
return success;
}
@@ -336,13 +351,13 @@ bool CryptStateOCB2::ocb_decrypt(const unsigned char *encrypted, unsigned char *
bool success = true;
// Initialize
- AESencrypt(nonce, delta, &encrypt_key);
+ AESencrypt(nonce, delta, raw_key);
ZERO(checksum);
while (len > AES_BLOCK_SIZE) {
S2(delta);
XOR(tmp, delta, reinterpret_cast< const subblock * >(encrypted));
- AESdecrypt(tmp, tmp, &decrypt_key);
+ AESdecrypt(tmp, tmp, raw_key);
XOR(reinterpret_cast< subblock * >(plain), delta, tmp);
XOR(checksum, checksum, reinterpret_cast< const subblock * >(plain));
len -= AES_BLOCK_SIZE;
@@ -354,7 +369,7 @@ bool CryptStateOCB2::ocb_decrypt(const unsigned char *encrypted, unsigned char *
ZERO(tmp);
tmp[BLOCKSIZE - 1] = SWAPPED(len * 8);
XOR(tmp, tmp, delta);
- AESencrypt(tmp, pad, &encrypt_key);
+ AESencrypt(tmp, pad, raw_key);
memset(tmp, 0, AES_BLOCK_SIZE);
memcpy(tmp, encrypted, len);
XOR(tmp, tmp, pad);
@@ -372,7 +387,7 @@ bool CryptStateOCB2::ocb_decrypt(const unsigned char *encrypted, unsigned char *
S3(delta);
XOR(tmp, delta, checksum);
- AESencrypt(tmp, tag, &encrypt_key);
+ AESencrypt(tmp, tag, raw_key);
return success;
}
@@ -381,5 +396,5 @@ bool CryptStateOCB2::ocb_decrypt(const unsigned char *encrypted, unsigned char *
#undef SHIFTBITS
#undef SWAPPED
#undef HIGHBIT
-#undef AES_encrypt
-#undef AES_decrypt
+#undef AESencrypt
+#undef AESdecrypt
diff --git a/src/crypto/CryptStateOCB2.h b/src/crypto/CryptStateOCB2.h
index 53d4b4b6aa..cc3f1c0bc3 100644
--- a/src/crypto/CryptStateOCB2.h
+++ b/src/crypto/CryptStateOCB2.h
@@ -8,8 +8,9 @@
#include "CryptState.h"
-#include <openssl/aes.h>
+#include <openssl/evp.h>
+#define AES_BLOCK_SIZE 16
#define AES_KEY_SIZE_BITS 128
#define AES_KEY_SIZE_BYTES (AES_KEY_SIZE_BITS / 8)
@@ -17,7 +18,7 @@
class CryptStateOCB2 : public CryptState {
public:
CryptStateOCB2();
- ~CryptStateOCB2(){};
+ ~CryptStateOCB2() noexcept override;
virtual bool isValid() const Q_DECL_OVERRIDE;
virtual void genKey() Q_DECL_OVERRIDE;
@@ -43,8 +44,8 @@ class CryptStateOCB2 : public CryptState {
unsigned char decrypt_iv[AES_BLOCK_SIZE];
unsigned char decrypt_history[0x100];
- AES_KEY encrypt_key;
- AES_KEY decrypt_key;
+ EVP_CIPHER_CTX *enc_ctx;
+ EVP_CIPHER_CTX *dec_ctx;
};
From f8d47db318f302f5a7d343f15c9936c7030c49c4 Mon Sep 17 00:00:00 2001
From: Terry Geng <terry@terriex.com>
Date: Sun, 12 Dec 2021 22:39:38 -0500
Subject: [PATCH] FIX(crypto): Sharing EVP context between threads crushes
Mumble
Functions ocb_encrypt and ocb_decrypt share the same set
of encrypt and decrypt contexts. However, they are invoked
in different threads (audio input thread and server
handler thread).
This may lead to conflicts that would crash Mumble.
This patch separates contexts used in these two functions
to avoid such conflicts.
Fixes #5361
---
src/crypto/CryptStateOCB2.cpp | 55 ++++++++++++++++++++++-------------
src/crypto/CryptStateOCB2.h | 6 ++--
2 files changed, 38 insertions(+), 23 deletions(-)
diff --git a/src/crypto/CryptStateOCB2.cpp b/src/crypto/CryptStateOCB2.cpp
index 640fdedac8..3b3473ffec 100644
--- a/src/crypto/CryptStateOCB2.cpp
+++ b/src/crypto/CryptStateOCB2.cpp
@@ -30,7 +30,9 @@
#include <cstring>
#include <openssl/rand.h>
-CryptStateOCB2::CryptStateOCB2() : CryptState(), enc_ctx(EVP_CIPHER_CTX_new()), dec_ctx(EVP_CIPHER_CTX_new()) {
+CryptStateOCB2::CryptStateOCB2()
+ : CryptState(), enc_ctx_ocb_enc(EVP_CIPHER_CTX_new()), dec_ctx_ocb_enc(EVP_CIPHER_CTX_new()),
+ enc_ctx_ocb_dec(EVP_CIPHER_CTX_new()), dec_ctx_ocb_dec(EVP_CIPHER_CTX_new()) {
for (int i = 0; i < 0x100; i++)
decrypt_history[i] = 0;
memset(raw_key, 0, AES_KEY_SIZE_BYTES);
@@ -39,8 +41,10 @@ CryptStateOCB2::CryptStateOCB2() : CryptState(), enc_ctx(EVP_CIPHER_CTX_new()),
}
CryptStateOCB2::~CryptStateOCB2() noexcept {
- EVP_CIPHER_CTX_free(enc_ctx);
- EVP_CIPHER_CTX_free(dec_ctx);
+ EVP_CIPHER_CTX_free(enc_ctx_ocb_enc);
+ EVP_CIPHER_CTX_free(dec_ctx_ocb_enc);
+ EVP_CIPHER_CTX_free(enc_ctx_ocb_dec);
+ EVP_CIPHER_CTX_free(dec_ctx_ocb_dec);
}
bool CryptStateOCB2::isValid() const {
@@ -257,25 +261,28 @@ static void inline ZERO(keyblock &block) {
block[i] = 0;
}
-#define AESencrypt(src, dst, key) \
- { \
- int outlen = 0; \
- EVP_EncryptInit_ex(enc_ctx, EVP_aes_128_ecb(), NULL, key, NULL); \
- EVP_CIPHER_CTX_set_padding(enc_ctx, 0); \
- EVP_EncryptUpdate(enc_ctx, reinterpret_cast< unsigned char * >(dst), &outlen, \
- reinterpret_cast< const unsigned char * >(src), AES_BLOCK_SIZE); \
- EVP_EncryptFinal_ex(enc_ctx, reinterpret_cast< unsigned char * >(dst + outlen), &outlen); \
+#define AESencrypt_ctx(src, dst, key, enc_ctx) \
+ { \
+ int outlen = 0; \
+ EVP_EncryptInit_ex(enc_ctx, EVP_aes_128_ecb(), NULL, key, NULL); \
+ EVP_CIPHER_CTX_set_padding(enc_ctx, 0); \
+ EVP_EncryptUpdate(enc_ctx, reinterpret_cast< unsigned char * >(dst), &outlen, \
+ reinterpret_cast< const unsigned char * >(src), AES_BLOCK_SIZE); \
+ EVP_EncryptFinal_ex(enc_ctx, reinterpret_cast< unsigned char * >((dst) + outlen), &outlen); \
}
-#define AESdecrypt(src, dst, key) \
- { \
- int outlen = 0; \
- EVP_DecryptInit_ex(dec_ctx, EVP_aes_128_ecb(), NULL, key, NULL); \
- EVP_CIPHER_CTX_set_padding(dec_ctx, 0); \
- EVP_DecryptUpdate(dec_ctx, reinterpret_cast< unsigned char * >(dst), &outlen, \
- reinterpret_cast< const unsigned char * >(src), AES_BLOCK_SIZE); \
- EVP_DecryptFinal_ex(dec_ctx, reinterpret_cast< unsigned char * >(dst + outlen), &outlen); \
+#define AESdecrypt_ctx(src, dst, key, dec_ctx) \
+ { \
+ int outlen = 0; \
+ EVP_DecryptInit_ex(dec_ctx, EVP_aes_128_ecb(), NULL, key, NULL); \
+ EVP_CIPHER_CTX_set_padding(dec_ctx, 0); \
+ EVP_DecryptUpdate(dec_ctx, reinterpret_cast< unsigned char * >(dst), &outlen, \
+ reinterpret_cast< const unsigned char * >(src), AES_BLOCK_SIZE); \
+ EVP_DecryptFinal_ex(dec_ctx, reinterpret_cast< unsigned char * >((dst) + outlen), &outlen); \
}
+#define AESencrypt(src, dst, key) AESencrypt_ctx(src, dst, key, enc_ctx_ocb_enc)
+#define AESdecrypt(src, dst, key) AESdecrypt_ctx(src, dst, key, dec_ctx_ocb_enc)
+
bool CryptStateOCB2::ocb_encrypt(const unsigned char *plain, unsigned char *encrypted, unsigned int len,
const unsigned char *nonce, unsigned char *tag, bool modifyPlainOnXEXStarAttack) {
keyblock checksum, delta, tmp, pad;
@@ -345,6 +352,12 @@ bool CryptStateOCB2::ocb_encrypt(const unsigned char *plain, unsigned char *encr
return success;
}
+#undef AESencrypt
+#undef AESdecrypt
+
+#define AESencrypt(src, dst, key) AESencrypt_ctx(src, dst, key, enc_ctx_ocb_dec)
+#define AESdecrypt(src, dst, key) AESdecrypt_ctx(src, dst, key, dec_ctx_ocb_dec)
+
bool CryptStateOCB2::ocb_decrypt(const unsigned char *encrypted, unsigned char *plain, unsigned int len,
const unsigned char *nonce, unsigned char *tag) {
keyblock checksum, delta, tmp, pad;
@@ -392,9 +405,9 @@ bool CryptStateOCB2::ocb_decrypt(const unsigned char *encrypted, unsigned char *
return success;
}
+#undef AESencrypt
+#undef AESdecrypt
#undef BLOCKSIZE
#undef SHIFTBITS
#undef SWAPPED
#undef HIGHBIT
-#undef AESencrypt
-#undef AESdecrypt
diff --git a/src/crypto/CryptStateOCB2.h b/src/crypto/CryptStateOCB2.h
index cc3f1c0bc3..0fd3000ade 100644
--- a/src/crypto/CryptStateOCB2.h
+++ b/src/crypto/CryptStateOCB2.h
@@ -44,8 +44,10 @@ class CryptStateOCB2 : public CryptState {
unsigned char decrypt_iv[AES_BLOCK_SIZE];
unsigned char decrypt_history[0x100];
- EVP_CIPHER_CTX *enc_ctx;
- EVP_CIPHER_CTX *dec_ctx;
+ EVP_CIPHER_CTX *enc_ctx_ocb_enc;
+ EVP_CIPHER_CTX *dec_ctx_ocb_enc;
+ EVP_CIPHER_CTX *enc_ctx_ocb_dec;
+ EVP_CIPHER_CTX *dec_ctx_ocb_dec;
};

View File

@ -1,38 +0,0 @@
From 24b9276d97cac459284143b936e46b626d7396f0 Mon Sep 17 00:00:00 2001
From: Robert Adam <dev@robert-adam.de>
Date: Tue, 11 Apr 2023 13:50:47 +0200
Subject: [PATCH] FIX(client): PipeWire crash
When destroying the PipeWire object we first destroyed the thread loop
and then the stream, but this has to be done in reverse order in order
to avoid crashes.
Fixes #6101
Source: https://github.com/mumble-voip/mumble/pull/6103
---
src/mumble/PipeWire.cpp | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/src/mumble/PipeWire.cpp b/src/mumble/PipeWire.cpp
index 91924e4fb1..c206ab5bbb 100644
--- a/src/mumble/PipeWire.cpp
+++ b/src/mumble/PipeWire.cpp
@@ -213,13 +213,14 @@ PipeWireEngine::~PipeWireEngine() {
return;
}
+ if (m_stream) {
+ pws->pw_stream_destroy(m_stream);
+ }
+
if (m_thread) {
pws->pw_thread_loop_destroy(m_thread);
}
- if (m_stream) {
- pws->pw_stream_destroy(m_stream);
- }
if (m_loop) {
pws->pw_loop_destroy(m_loop);

View File

@ -1,10 +1,10 @@
# Template file for 'mumble'
pkgname=mumble
version=1.4.287
revision=8
version=1.5.634
revision=1
build_style=cmake
make_cmd=make
configure_args="-Doverlay-xcompile=OFF -Dbundled-opus=OFF
configure_args="-Doverlay-xcompile=OFF -DCMAKE_CXX_STANDARD=17
-Dbundled-speex=OFF -Djackaudio=$(vopt_if jack ON OFF) -Dportaudio=$(vopt_if portaudio ON OFF)
-Dupdate=OFF -Dbundle-qt-translations=OFF -Dwarnings-as-errors=OFF"
hostmakedepends="Ice pkg-config protobuf qt5-host-tools qt5-qmake python3 which"
@ -20,17 +20,17 @@ maintainer="Helmut Pozimski <helmut@pozimski.eu>"
license="BSD-3-Clause"
homepage="https://mumble.info"
distfiles="https://github.com/mumble-voip/${pkgname}/releases/download/v${version}/${pkgname}-${version}.tar.gz"
checksum=378e61d5bfa58ba51bfbb645067f459214a9872da09b306f2c2c3f1902200547
checksum=904f3633d28ab0e6925caeff2c65802f586abefdf6d20162f20a71805c2c5929
build_options="jack portaudio"
build_options_default="jack portaudio"
export CMAKE_GENERATOR="Unix Makefiles"
LDFLAGS="-Wl,--copy-dt-needed-entries"
post_install() {
rm -f ${DESTDIR}/usr/share/man/man1/murmur-user-wrapper.1
vconf scripts/murmur.ini
vsv mumble-server
ln -sf murmurd.1 ${DESTDIR}/usr/share/man/man1/mumble-server.1
vlicense LICENSE
@ -40,12 +40,10 @@ murmur_package() {
system_accounts="_murmur"
_murmur_homedir="/var/lib/murmur"
make_dirs="/var/lib/murmur 0750 _murmur _murmur"
conf_files="/etc/murmur.ini"
depends="qt5-plugin-sqlite"
short_desc+=" - Server software (mumble-server)"
pkg_install() {
vmove etc/sv/mumble-server
vmove etc/murmur.ini
vmove usr/bin/mumble-server
vmove usr/share/man/man1/mumble-server.1
vmove usr/share/man/man1/mumble-server-user-wrapper.1