Skip to content

Commit 05d2dd3

Browse files
zurekzUriagat
andauthored
feat: data track encryption (#401)
* feat: crypto aes256gcm * feat: dataTrac Encryptor * fix: DataChannelMessageEncryptorV1 * fix: update aes256gcm to driver functions call * fix: update serialization, make messagesSeq atomic and add sendData method to PeerConnection --------- Co-authored-by: Jerzy Czarkowski <jczarkowski@simplito.com>
1 parent baaec91 commit 05d2dd3

21 files changed

Lines changed: 351 additions & 55 deletions

File tree

conanfile.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ poco/1.13.2
33
pson/1.0.7
44
openssl/[>=3.0 <3.1]
55
gmp/6.2.1
6-
privmxdrvcrypto/1.0.2
6+
privmxdrvcrypto/1.0.3
77
privmxdrvecc/1.0.2
88
privmxdrvnet/1.0.3
99
gtest/[^1.15.0]

crypto/base/include/privmx/crypto/Crypto.hpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ class Crypto
3939
static std::string aes256CbcPkcs7Decrypt(const std::string& data, const std::string& key, const std::string& iv);
4040
static std::string aes256CbcNoPadEncrypt(const std::string& data, const std::string& key, const std::string& iv);
4141
static std::string aes256CbcNoPadDecrypt(const std::string& data, const std::string& key, const std::string& iv);
42+
static std::string aes256GcmEncrypt(const std::string& data, const std::string& key, const std::string& iv, const std::string& aad = "");
43+
static std::string aes256GcmDecrypt(const std::string& data, const std::string& key, const std::string& iv, const std::string& aad = "");
4244
static std::string prf_tls12(const std::string& key, const std::string& seed, size_t length);
4345
static std::string pbkdf2(const std::string& password, const std::string& salt, size_t rounds, size_t length, const std::string& algorithm);
4446
static std::string kdf(size_t length, const std::string& key, const std::string& label);
@@ -127,6 +129,16 @@ inline std::string Crypto::aes256CbcNoPadDecrypt(const std::string& data, const
127129
return crypto_service->aes256CbcNoPadDecrypt(data, key, iv);
128130
}
129131

132+
inline std::string Crypto::aes256GcmEncrypt(const std::string& data, const std::string& key, const std::string& iv, const std::string& aad) {
133+
auto crypto_service = CryptoEnv::getEnv()->getCryptoService();
134+
return crypto_service->aes256GcmEncrypt(data, key, iv, aad);
135+
}
136+
137+
inline std::string Crypto::aes256GcmDecrypt(const std::string& data, const std::string& key, const std::string& iv, const std::string& aad) {
138+
auto crypto_service = CryptoEnv::getEnv()->getCryptoService();
139+
return crypto_service->aes256GcmDecrypt(data, key, iv, aad);
140+
}
141+
130142
inline std::string Crypto::prf_tls12(const std::string& key, const std::string& seed, size_t length) {
131143
auto crypto_service = CryptoEnv::getEnv()->getCryptoService();
132144
return crypto_service->prf_tls12(key, seed, length);

crypto/base/include/privmx/crypto/CryptoService.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ class CryptoService
4141
virtual std::string aes256CbcPkcs7Decrypt(const std::string& data, const std::string& key, const std::string& iv) const = 0;
4242
virtual std::string aes256CbcNoPadEncrypt(const std::string& data, const std::string& key, const std::string& iv) const = 0;
4343
virtual std::string aes256CbcNoPadDecrypt(const std::string& data, const std::string& key, const std::string& iv) const = 0;
44+
virtual std::string aes256GcmEncrypt(const std::string& data, const std::string& key, const std::string& iv, const std::string& aad) const = 0;
45+
virtual std::string aes256GcmDecrypt(const std::string& data, const std::string& key, const std::string& iv, const std::string& aad) const = 0;
4446
virtual std::string prf_tls12(const std::string& key, const std::string& seed, size_t length) const = 0;
4547
virtual std::string kdf(size_t length, const std::string& key, const std::string& label) const = 0;
4648
virtual std::string generateIv(const std::string& key, Poco::Int32 idx) const = 0;

crypto/driver/include/privmx/crypto/driver/CryptoService.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ class CryptoService : public privmx::crypto::CryptoService
3636
virtual std::string aes256CbcPkcs7Decrypt(const std::string& data, const std::string& key, const std::string& iv) const override;
3737
virtual std::string aes256CbcNoPadEncrypt(const std::string& data, const std::string& key, const std::string& iv) const override;
3838
virtual std::string aes256CbcNoPadDecrypt(const std::string& data, const std::string& key, const std::string& iv) const override;
39+
virtual std::string aes256GcmEncrypt(const std::string& data, const std::string& key, const std::string& iv, const std::string& aad) const override;
40+
virtual std::string aes256GcmDecrypt(const std::string& data, const std::string& key, const std::string& iv, const std::string& aad) const override;
3941
virtual std::string prf_tls12(const std::string& key, const std::string& seed, size_t length) const override;
4042
virtual std::string kdf(size_t length, const std::string& key, const std::string& label) const override;
4143
virtual std::string generateIv(const std::string& key, Poco::Int32 idx) const override;

crypto/driver/src/CryptoService.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,38 @@ string driverimpl::CryptoService::aes256CbcNoPadDecrypt(const string& data, cons
199199
return res;
200200
}
201201

202+
std::string driverimpl::CryptoService::aes256GcmEncrypt(const std::string& data, const std::string& key, const std::string& iv, const std::string& aad) const {
203+
char* out;
204+
unsigned int outlen;
205+
char* tag;
206+
unsigned int taglen;
207+
int status = privmxDrvCrypto_aeadEncrypt(key.data(), iv.data(), aad.data(), aad.size(), data.data(), data.size(), "AES-256-GCM", &out, &outlen, &tag, &taglen);
208+
if (status != 0) {
209+
throw PrivmxDriverCryptoException("aes256GcmEncrypt: " + to_string(status));
210+
}
211+
string out_str(out, outlen);
212+
string tag_str(tag, taglen);
213+
privmxDrvCrypto_freeMem(out);
214+
privmxDrvCrypto_freeMem(tag);
215+
return out_str+tag_str;
216+
}
217+
218+
std::string driverimpl::CryptoService::aes256GcmDecrypt(const std::string& data, const std::string& key, const std::string& iv, const std::string& aad) const {
219+
if(data.size() < 16) {
220+
throw PrivmxDriverCryptoException("aes256GcmDecrypt: no tag");
221+
}
222+
std::string tag = data.substr(data.size()-16, 16);
223+
std::string dataWithoutTag = data.substr(0, data.size()-16);
224+
char* out;
225+
unsigned int outlen;
226+
int status = privmxDrvCrypto_aeadDecrypt(key.data(), iv.data(), aad.data(), aad.size(), dataWithoutTag.data(), dataWithoutTag.size(), tag.data(), tag.size(), "AES-256-GCM", &out, &outlen);
227+
if (status != 0) {
228+
throw PrivmxDriverCryptoException("aes256GcmDecrypt: " + to_string(status));
229+
}
230+
string res(out, outlen);
231+
privmxDrvCrypto_freeMem(out);
232+
return res;
233+
}
202234

203235
string driverimpl::CryptoService::prf_tls12(const string& key, const string& seed, size_t length) const {
204236
string a = seed;

endpoint/programs/stream_testing/single_video_receiver.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ class OnTrackImpl : public stream::OnTrackInterface {
167167
auto audioData = std::dynamic_pointer_cast<stream::AudioData>(data);
168168
} else if(data->type == stream::DataType::PLAIN) {
169169
auto plainData = std::dynamic_pointer_cast<stream::PlainData>(data);
170-
LOG_INFO("Recived plain data", plainData->data.stdString());
170+
LOG_INFO("Recived plain data: ", plainData->data.stdString());
171171
} else {
172172
LOG_FATAL("DataType::UNKNOWN")
173173
}

endpoint/stream/stream/include_pub/privmx/endpoint/stream/StreamException.hpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,13 @@ DECLARE_ENDPOINT_EXCEPTION(EndpointStreamException, CannotExtractStreamUpdatedEv
8686
DECLARE_ENDPOINT_EXCEPTION(EndpointStreamException, NullCallbackException, "Callback must not be null", 0x0024)
8787
DECLARE_ENDPOINT_EXCEPTION(EndpointStreamException, UnknownTypeException, "Unknown type encountered", 0x0025)
8888
DECLARE_ENDPOINT_EXCEPTION(EndpointStreamException, ThereCanBeOnlyOneDataTrackException, "There can be only one dataTrack per user in StreamRoom", 0x0026)
89-
DECLARE_ENDPOINT_EXCEPTION(EndpointStreamException, DataTrackNotInitialized, "Data track not initialized", 0x0027);
89+
DECLARE_ENDPOINT_EXCEPTION(EndpointStreamException, DataTrackNotInitializedException, "Data track not initialized", 0x0027);
90+
91+
DECLARE_ENDPOINT_EXCEPTION(EndpointStreamException, NoStreamEncryptionKeyException, "No stream encryption key", 0x0028);
92+
DECLARE_ENDPOINT_EXCEPTION(EndpointStreamException, NoStreamDecryptionKeyException, "No stream decryption key", 0x0029);
93+
DECLARE_ENDPOINT_EXCEPTION(EndpointStreamException, InvalidEncryptionKeyIdLengthException, "Invalid encryption key id length", 0x002A);
94+
DECLARE_ENDPOINT_EXCEPTION(EndpointStreamException, InvalidMessageHeaderLengthException, "Invalid message header length", 0x002B);
95+
DECLARE_ENDPOINT_EXCEPTION(EndpointStreamException, UnsupportedMessageFormatVersionException, "Unsupported message format version length", 0x002C);
9096
} // stream
9197
} // endpoint
9298
} // privmx

endpoint/stream/webrtc/include/privmx/endpoint/stream/DataChannelImpl.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,11 @@ namespace stream {
1616

1717
class DataChannelImpl {
1818
public:
19-
inline DataChannelImpl(std::shared_ptr<OnTrackInterface> onTrackInterface, libwebrtc::scoped_refptr<libwebrtc::RTCDataChannel> dataChannel) :
19+
inline DataChannelImpl(std::shared_ptr<OnTrackInterface> onTrackInterface, std::shared_ptr<DataChannelMessageEncryptorV1> messageEncryptor, libwebrtc::scoped_refptr<libwebrtc::RTCDataChannel> dataChannel) :
2020
_onTrackInterface(onTrackInterface),
2121
_dataChannel(dataChannel),
2222
_dataChannelObserver(std::make_shared<PmxDataChannelObserver>(
23-
onTrackInterface, dataChannel->label().std_string()+":"+std::to_string(dataChannel->id())
23+
onTrackInterface, messageEncryptor, dataChannel->label().std_string()+":"+std::to_string(dataChannel->id())
2424
))
2525
{
2626
_dataChannel->RegisterObserver(_dataChannelObserver.get());

endpoint/stream/webrtc/include/privmx/endpoint/stream/PeerConnectionManager.hpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ limitations under the License.
1212
#ifndef _PRIVMXLIB_ENDPOINT_WEBRTC_PEER_CONNECTIN_MANAGER_HPP_
1313
#define _PRIVMXLIB_ENDPOINT_WEBRTC_PEER_CONNECTIN_MANAGER_HPP_
1414

15+
#include <atomic>
1516
#include <string>
1617
#include <memory>
1718
#include <libwebrtc.h>
@@ -20,6 +21,7 @@ limitations under the License.
2021
#include "privmx/endpoint/stream/DynamicTypes.hpp"
2122
#include "privmx/endpoint/stream/PmxPeerConnectionObserver.hpp"
2223
#include "privmx/endpoint/stream/PmxDataChannelObserver.hpp"
24+
#include "privmx/endpoint/stream/encryptors/dataChannel/DataChannelMessageEncryptorV1.hpp"
2325
#include <privmx/utils/ThreadSaveMap.hpp>
2426

2527
namespace privmx {
@@ -56,9 +58,14 @@ struct PeerConnection {
5658
std::map<std::string, AudioTrackInfo> audioTracks;
5759
std::map<std::string, VideoTrackInfo> videoTracks;
5860
std::optional<DataChannelInfo> dataChannel;
61+
std::shared_ptr<DataChannelMessageEncryptorV1> messageEncryptor;
62+
std::atomic<uint64_t> messagesSeq {0};
5963

6064
std::shared_mutex trackMutex;
65+
std::vector<privmx::endpoint::stream::Key> cpp_keys;
6166
std::shared_ptr<privmx::webrtc::KeyStore> keys;
67+
68+
void sendData(const std::string& data);
6269
};
6370

6471
struct JanusConnection {

endpoint/stream/webrtc/include/privmx/endpoint/stream/PmxDataChannelObserver.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ limitations under the License.
1717
#include <rtc_data_channel.h>
1818
#include "privmx/endpoint/stream/webrtc/Types.hpp"
1919
#include "privmx/endpoint/stream/webrtc/OnTrackInterface.hpp"
20+
#include "privmx/endpoint/stream/encryptors/dataChannel/DataChannelMessageEncryptorV1.hpp"
2021
#include <privmx/utils/ThreadSaveMap.hpp>
2122
#include <privmx/utils/Logger.hpp>
2223

@@ -26,13 +27,14 @@ namespace stream {
2627

2728
class PmxDataChannelObserver : public libwebrtc::RTCDataChannelObserver {
2829
public:
29-
PmxDataChannelObserver(std::shared_ptr<OnTrackInterface> onTrackInterface, const std::string& dataChannelId);
30+
PmxDataChannelObserver(std::shared_ptr<OnTrackInterface> onTrackInterface, std::shared_ptr<DataChannelMessageEncryptorV1> messageEncryptor, const std::string& dataChannelId);
3031
virtual void OnStateChange(libwebrtc::RTCDataChannelState state) override;
3132
virtual void OnMessage(const char* buffer, int length, bool binary) override;
3233
void updateOnTrackInterface(std::shared_ptr<OnTrackInterface> onTrackInterface);
3334
private:
3435
std::mutex _onTrackInterfaceMutex;
3536
std::shared_ptr<OnTrackInterface> _onTrackInterface;
37+
std::shared_ptr<DataChannelMessageEncryptorV1> _messageEncryptor;
3638
std::string _dataChannelId;
3739
};
3840

0 commit comments

Comments
 (0)