Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 16 additions & 3 deletions include/livekit/e2ee.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,18 @@ enum class EncryptionType {
CUSTOM = 2,
};

/* Defaults (match other SDKs / Python defaults). */
/* Key derivation algorithm used by the key provider. */
enum class KeyDerivationFunction {
Comment thread
stephen-derosa marked this conversation as resolved.
PBKDF2 = 0,
HKDF = 1,
Comment thread
stephen-derosa marked this conversation as resolved.
};

/* Defaults (match Rust KeyProviderOptions::default()). */
inline constexpr const char* kDefaultRatchetSalt = "LKFrameEncryptionKey";
inline constexpr int kDefaultRatchetWindowSize = 16;
inline constexpr int kDefaultFailureTolerance = -1;
inline constexpr int kDefaultKeyRingSize = 16;
inline constexpr KeyDerivationFunction kDefaultKeyDerivationFunction = KeyDerivationFunction::PBKDF2;

/**
* Options for configuring the key provider used by E2EE.
Expand All @@ -46,8 +54,7 @@ inline constexpr int kDefaultFailureTolerance = -1;
* - `shared_key` is optional. If omitted, the application may set keys later
* (e.g. via KeyProvider::setSharedKey / per-participant keys).
* - `ratchet_salt` may be empty to indicate "use implementation default".
* - `ratchet_window_size` and `failure_tolerance` use SDK defaults unless
* overridden.
* - Other key provider fields use SDK defaults unless overridden.
*/
struct KeyProviderOptions {
/// Shared static key for "shared-key E2EE" (optional).
Expand All @@ -70,6 +77,12 @@ struct KeyProviderOptions {

/// Number of tolerated ratchet failures before reporting encryption errors.
int failure_tolerance = kDefaultFailureTolerance;

/// Number of key slots retained by the key provider.
int key_ring_size = kDefaultKeyRingSize;

/// Algorithm used when deriving ratcheted keys.
KeyDerivationFunction key_derivation_function = kDefaultKeyDerivationFunction;
};

/**
Expand Down
35 changes: 1 addition & 34 deletions src/ffi_client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
#include "livekit/ffi_handle.h"
#include "livekit/room.h"
#include "livekit/rpc_error.h"
#include "livekit/track.h"
#include "livekit_ffi.h"
#include "lk_log.h"
#include "room.pb.h"
Expand All @@ -37,10 +36,6 @@ namespace livekit {

namespace {

std::string bytesToString(const std::vector<std::uint8_t>& b) {
return std::string(reinterpret_cast<const char*>(b.data()), b.size());
}

inline void logAndThrow(const std::string& error_msg) {
LK_LOG_ERROR("LiveKit SDK Error: {}", error_msg);
throw std::runtime_error(error_msg);
Expand Down Expand Up @@ -333,35 +328,7 @@ std::future<proto::ConnectCallback> FfiClient::connectAsync(const std::string& u

auto* enc = opts->mutable_encryption();
enc->set_encryption_type(static_cast<proto::EncryptionType>(e2ee.encryption_type));
auto* kp = enc->mutable_key_provider_options();
// shared_key is optional. If not set, leave the field unset/cleared.
if (kpo.shared_key && !kpo.shared_key->empty()) {
kp->set_shared_key(bytesToString(*kpo.shared_key));
} else {
kp->clear_shared_key();
}
// Only set ratchet_salt if caller overrides. Otherwise clear so Rust side
// uses default.
if (!kpo.ratchet_salt.empty() &&
kpo.ratchet_salt !=
std::vector<std::uint8_t>(kDefaultRatchetSalt,
kDefaultRatchetSalt + std::char_traits<char>::length(kDefaultRatchetSalt))) {
kp->set_ratchet_salt(bytesToString(kpo.ratchet_salt));
} else {
kp->clear_ratchet_salt();
}
// Same idea for window size / tolerance: set only on override; otherwise
// clear.
if (kpo.ratchet_window_size != kDefaultRatchetWindowSize) {
kp->set_ratchet_window_size(kpo.ratchet_window_size);
} else {
kp->clear_ratchet_window_size();
}
if (kpo.failure_tolerance != kDefaultFailureTolerance) {
kp->set_failure_tolerance(kpo.failure_tolerance);
} else {
kp->clear_failure_tolerance();
}
enc->mutable_key_provider_options()->CopyFrom(toProto(kpo));
}

// --- RTC configuration (optional) ---
Expand Down
24 changes: 23 additions & 1 deletion src/room_proto_converter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,16 @@
#include "room_proto_converter.h"

#include "livekit/data_stream.h"
#include "livekit/local_participant.h"
#include "room.pb.h"

namespace livekit {

namespace {

std::string bytesToString(const std::vector<std::uint8_t>& bytes) {
return std::string(reinterpret_cast<const char*>(bytes.data()), bytes.size());
}

std::vector<proto::PacketTrailerFeature> toProto(const PacketTrailerFeatures& features) {
std::vector<proto::PacketTrailerFeature> out;
out.reserve(2);
Expand Down Expand Up @@ -309,6 +312,25 @@ RoomMovedEvent roomMovedFromProto(const proto::RoomInfo& in) {

// ---------------- Room Options ----------------

proto::KeyProviderOptions toProto(const KeyProviderOptions& in) {
proto::KeyProviderOptions out;
if (in.shared_key && !in.shared_key->empty()) {
out.set_shared_key(bytesToString(*in.shared_key));
} else {
out.clear_shared_key();
}
if (!in.ratchet_salt.empty()) {
out.set_ratchet_salt(bytesToString(in.ratchet_salt));
} else {
out.set_ratchet_salt(kDefaultRatchetSalt);
}
out.set_ratchet_window_size(in.ratchet_window_size);
out.set_failure_tolerance(in.failure_tolerance);
out.set_key_ring_size(in.key_ring_size);
out.set_key_derivation_function(static_cast<proto::KeyDerivationFunction>(in.key_derivation_function));
return out;
}

proto::AudioEncoding toProto(const AudioEncodingOptions& in) {
proto::AudioEncoding msg;
msg.set_max_bitrate(in.max_bitrate);
Expand Down
4 changes: 4 additions & 0 deletions src/room_proto_converter.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@

#include <string>

#include "e2ee.pb.h"
#include "livekit/e2ee.h"
#include "livekit/room_event_types.h"
#include "livekit/visibility.h"
#include "room.pb.h"
Expand Down Expand Up @@ -69,6 +71,8 @@ LIVEKIT_INTERNAL_API RoomMovedEvent roomMovedFromProto(const proto::RoomInfo& in

// --------- room options conversions ---------

LIVEKIT_INTERNAL_API proto::KeyProviderOptions toProto(const KeyProviderOptions& in);

LIVEKIT_INTERNAL_API proto::AudioEncoding toProto(const AudioEncodingOptions& in);
LIVEKIT_INTERNAL_API AudioEncodingOptions fromProto(const proto::AudioEncoding& in);

Expand Down
Loading
Loading