[network/libktorrent] src/mse: ABI/API break: port RC4 encryptor to use QByteArrayView

Jack Hill <[email protected]>
Newsgroups gmane.comp.kde.cvs
Message-ID <[email protected]>
Git commit 7c7158a054049e8487a76ec60832a96ea29d9db4 by Jack Hill.
Committed on 29/07/2026 at 21:32.
Pushed by jackh into branch 'master'.

ABI/API break: port RC4 encryptor to use QByteArrayView

No downstream changes required.

M  +2    -2    src/mse/encryptedauthenticate.cpp
M  +2    -2    src/mse/encryptedpacketsocket.cpp
M  +6    -6    src/mse/encryptedserverauthenticate.cpp
M  +10   -10   src/mse/rc4encryptor.cpp
M  +5    -3    src/mse/rc4encryptor.h

https://invent.kde.org/network/libktorrent/-/commit/7c7158a054049e8487a76ec60832a96ea29d9db4

diff --git a/src/mse/encryptedauthenticate.cpp b/src/mse/encryptedauthenticate.cpp
index 77b7583e..fbc507e9 100644
--- a/src/mse/encryptedauthenticate.cpp
+++ b/src/mse/encryptedauthenticate.cpp
@@ -117,7 +117,7 @@ void EncryptedAuthenticate::handleYB()
     WriteUint16(tmp_buf, 14, 68); // length of IA, which will be the bittorrent handshake
     // send IA which is the handshake
     makeHandshake(tmp_buf + 16, info_hash, our_peer_id);
-    sock->sendData(QByteArrayView{our_rc4->encrypt(tmp_buf, 84), 84});
+    sock->sendData(our_rc4->encrypt(QByteArrayView{tmp_buf, 84}));
 
     // search for the encrypted VC in the data
     findVC();
@@ -128,7 +128,7 @@ void EncryptedAuthenticate::findVC()
     Uint8 vc[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
 
     RC4Encryptor rc4(enc, dec);
-    memcpy(vc, rc4.encrypt(vc, 8), 8);
+    rc4.encryptReplace(vc, 8);
 
     const Uint32 max_i = buf_size - 8;
     for (Uint32 i = 96; i < max_i; i++) {
diff --git a/src/mse/encryptedpacketsocket.cpp b/src/mse/encryptedpacketsocket.cpp
index 69164fe2..e22945f9 100644
--- a/src/mse/encryptedpacketsocket.cpp
+++ b/src/mse/encryptedpacketsocket.cpp
@@ -99,9 +99,9 @@ Uint32 EncryptedPacketSocket::sendData(QByteArrayView data)
     if (enc) {
         // we need to make sure all data is sent because of the encryption
         Uint32 ds = 0;
-        const Uint8 *ed = enc->encrypt(reinterpret_cast<const Uint8 *>(data.data()), data.size());
+        const auto ed = enc->encrypt(data);
         while (sock->ok() && ds < data.size()) {
-            const Uint32 ret = sock->send(QByteArrayView{ed, data.size()}.sliced(ds));
+            const Uint32 ret = sock->send(ed.sliced(ds));
             ds += ret;
             if (ret == 0) {
                 Out(SYS_CON | LOG_DEBUG) << "ret = 0" << endl;
diff --git a/src/mse/encryptedserverauthenticate.cpp b/src/mse/encryptedserverauthenticate.cpp
index 814f8f82..713faac0 100644
--- a/src/mse/encryptedserverauthenticate.cpp
+++ b/src/mse/encryptedserverauthenticate.cpp
@@ -6,6 +6,7 @@
 #include "encryptedserverauthenticate.h"
 
 #include <array>
+#include <cstddef>
 
 #include <QRandomGenerator>
 
@@ -152,18 +153,17 @@ void EncryptedServerAuthenticate::processVC()
 
     // now we have crypto_provide we can send
     // ENCRYPT(VC, crypto_select, len(padD), padD)
-    Uint8 tmp[14];
-    memset(tmp, 0, 14); // VC
+    std::array<std::byte, 14> tmp{};
+    memset(tmp.data(), 0, 8); // VC
     if (crypto_provide & 0x0000002) { // RC4
-        WriteUint32(tmp, 8, 0x0000002);
         crypto_select = 0x0000002;
     } else {
-        WriteUint32(tmp, 8, 0x0000001);
         crypto_select = 0x0000001;
     }
-    bt::WriteUint16(tmp, 12, 0); // no pad D
+    WriteUint32(tmp.data(), 8, crypto_select);
+    WriteUint16(tmp.data(), 12, 0); // no pad D
 
-    sock->sendData(QByteArrayView{our_rc4->encrypt(tmp, 14), 14});
+    sock->sendData(our_rc4->encrypt(tmp));
 
     // handle pad C
     if (buf_size < req1_off + 14 + pad_C_len) {
diff --git a/src/mse/rc4encryptor.cpp b/src/mse/rc4encryptor.cpp
index 1bdded34..7fafae9e 100644
--- a/src/mse/rc4encryptor.cpp
+++ b/src/mse/rc4encryptor.cpp
@@ -82,16 +82,16 @@ void RC4Encryptor::decrypt(Uint8 *data, Uint32 len)
     EVP_DecryptUpdate(dec.get(), data, &out_len, data, static_cast<int>(len));
 }
 
-const Uint8 *RC4Encryptor::encrypt(const Uint8 *data, Uint32 len)
+QByteArrayView RC4Encryptor::encrypt(QByteArrayView data)
 {
     static_assert(sizeof(rc4_enc_buffer) <= static_cast<unsigned int>(INT_MAX), "rc4_enc_buffer size is too large");
-    if (len > sizeof(rc4_enc_buffer)) {
-        throw bt::Error(QStringLiteral("RC4Encryptor::encrypt is called with a too large input: ") + QString::number(len) + QStringLiteral(" bytes"));
+    if (static_cast<size_t>(data.size()) > sizeof(rc4_enc_buffer)) {
+        throw bt::Error(QStringLiteral("RC4Encryptor::encrypt is called with a too large input: %1 bytes").arg(data.size()));
     }
 
     int out_len = 0;
-    EVP_EncryptUpdate(enc.get(), rc4_enc_buffer, &out_len, data, static_cast<int>(len));
-    return rc4_enc_buffer;
+    EVP_EncryptUpdate(enc.get(), rc4_enc_buffer, &out_len, reinterpret_cast<const Uint8 *>(data.data()), static_cast<int>(data.size()));
+    return QByteArrayView{rc4_enc_buffer, data.size()};
 }
 
 void RC4Encryptor::encryptReplace(Uint8 *data, Uint32 len)
@@ -130,13 +130,13 @@ void RC4Encryptor::decrypt(Uint8 *data, Uint32 len)
     gcry_cipher_decrypt(dec, data, len, data, len);
 }
 
-const Uint8 *RC4Encryptor::encrypt(const Uint8 *data, Uint32 len)
+QByteArrayView RC4Encryptor::encrypt(QByteArrayView data)
 {
-    if (len > sizeof(rc4_enc_buffer)) {
-        throw bt::Error(QStringLiteral("RC4Encryptor::encrypt is called with a too large input: ") + QString::number(len) + QStringLiteral(" bytes"));
+    if (static_cast<size_t>(data.size()) > sizeof(rc4_enc_buffer)) {
+        throw bt::Error(QStringLiteral("RC4Encryptor::encrypt is called with a too large input: %1 bytes").arg(data.size()));
     }
-    gcry_cipher_encrypt(enc, rc4_enc_buffer, len, data, len);
-    return rc4_enc_buffer;
+    gcry_cipher_encrypt(enc, rc4_enc_buffer, data.size(), data.data(), data.size());
+    return QByteArrayView{rc4_enc_buffer, data.size()};
 }
 
 void RC4Encryptor::encryptReplace(Uint8 *data, Uint32 len)
diff --git a/src/mse/rc4encryptor.h b/src/mse/rc4encryptor.h
index a7f1fab5..e8e1f779 100644
--- a/src/mse/rc4encryptor.h
+++ b/src/mse/rc4encryptor.h
@@ -12,6 +12,9 @@
 #elif defined(LIBKTORRENT_USE_LIBGCRYPT)
 #include <gcrypt.h>
 #endif
+
+#include <QByteArrayView>
+
 #include <ktorrent_export.h>
 #include <util/constants.h>
 #include <util/sha1hash.h>
@@ -46,10 +49,9 @@ public:
      * If we send pieces we point directly to the mmap region of data,
      * this cannot be overwritten, hence the static buffer.
      * \param data The data
-     * \param len The length of the data
-     * \return Pointer to the static buffer
+     * \return View over the static buffer
      */
-    const bt::Uint8 *encrypt(const bt::Uint8 *data, bt::Uint32 len);
+    QByteArrayView encrypt(QByteArrayView data);
 
     /*!
      * Encrypt data, encryption will happen in the same buffer. So data will
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.