Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: e2ee and upgrade webrtc #190

Merged
merged 6 commits into from
Sep 21, 2023
Merged
Show file tree
Hide file tree
Changes from 5 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
7 changes: 0 additions & 7 deletions examples/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions livekit-webrtc/src/native/frame_cryptor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use parking_lot::Mutex;
use std::sync::Arc;
use webrtc_sys::frame_cryptor::{self as sys_fc};

use crate::peer_connection_factory::PeerConnectionFactory;
use crate::{rtp_receiver::RtpReceiver, rtp_sender::RtpSender};

pub type OnStateChange = Box<dyn FnMut(String, EncryptionState) + Send + Sync>;
Expand Down Expand Up @@ -67,6 +68,10 @@ impl KeyProvider {
pub fn get_key(&self, participant_id: String, key_index: i32) -> Option<Vec<u8>> {
self.sys_handle.get_key(participant_id, key_index).ok()
}

pub fn set_sif_trailer(&self, trailer: Vec<u8>) {
self.sys_handle.set_sif_trailer(trailer);
}
}

#[derive(Clone)]
Expand All @@ -77,13 +82,15 @@ pub struct FrameCryptor {

impl FrameCryptor {
pub fn new_for_rtp_sender(
peer_factory: &PeerConnectionFactory,
participant_id: String,
algorithm: EncryptionAlgorithm,
key_provider: KeyProvider,
sender: RtpSender,
) -> Self {
let observer = Arc::new(RtcFrameCryptorObserver::default());
let sys_handle = sys_fc::ffi::new_frame_cryptor_for_rtp_sender(
peer_factory.handle.sys_handle.clone(),
participant_id,
algorithm.into(),
key_provider.sys_handle,
Expand All @@ -101,13 +108,15 @@ impl FrameCryptor {
}

pub fn new_for_rtp_receiver(
peer_factory: &PeerConnectionFactory,
participant_id: String,
algorithm: EncryptionAlgorithm,
key_provider: KeyProvider,
receiver: RtpReceiver,
) -> Self {
let observer = Arc::new(RtcFrameCryptorObserver::default());
let sys_handle = sys_fc::ffi::new_frame_cryptor_for_rtp_receiver(
peer_factory.handle.sys_handle.clone(),
participant_id,
algorithm.into(),
key_provider.sys_handle,
Expand Down
2 changes: 1 addition & 1 deletion livekit-webrtc/src/native/peer_connection_factory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ lazy_static! {

#[derive(Clone)]
pub struct PeerConnectionFactory {
sys_handle: SharedPtr<sys_pcf::ffi::PeerConnectionFactory>,
pub(crate) sys_handle: SharedPtr<sys_pcf::ffi::PeerConnectionFactory>,
}

impl Default for PeerConnectionFactory {
Expand Down
4 changes: 4 additions & 0 deletions livekit/src/room/e2ee/key_provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,4 +89,8 @@ impl KeyProvider {
pub fn get_key(&self, identity: &ParticipantIdentity, key_index: i32) -> Option<Vec<u8>> {
self.handle.get_key(identity.to_string(), key_index)
}

pub fn set_sif_trailer(&self, trailer: Vec<u8>) {
self.handle.set_sif_trailer(trailer);
}
}
3 changes: 3 additions & 0 deletions livekit/src/room/e2ee/manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use crate::e2ee::E2eeOptions;
use crate::id::{ParticipantIdentity, TrackSid};
use crate::participant::{LocalParticipant, RemoteParticipant};
use crate::prelude::{LocalTrack, LocalTrackPublication, RemoteTrack, RemoteTrackPublication};
use crate::rtc_engine::lk_runtime::LkRuntime;
use livekit_webrtc::native::frame_cryptor::{EncryptionAlgorithm, EncryptionState, FrameCryptor};
use livekit_webrtc::{rtp_receiver::RtpReceiver, rtp_sender::RtpSender};
use parking_lot::Mutex;
Expand Down Expand Up @@ -194,6 +195,7 @@ impl E2eeManager {
let options = inner.options.as_ref().unwrap();

let frame_cryptor = FrameCryptor::new_for_rtp_sender(
LkRuntime::instance().pc_factory(),
participant_identity.to_string(),
EncryptionAlgorithm::AesGcm,
options.key_provider.handle.clone(),
Expand All @@ -212,6 +214,7 @@ impl E2eeManager {
let options = inner.options.as_ref().unwrap();

let frame_cryptor = FrameCryptor::new_for_rtp_receiver(
LkRuntime::instance().pc_factory(),
participant_identity.to_string(),
EncryptionAlgorithm::AesGcm,
options.key_provider.handle.clone(),
Expand Down
4 changes: 4 additions & 0 deletions livekit/src/room/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,10 @@ impl Room {
let rtc_engine = Arc::new(rtc_engine);

let join_response = rtc_engine.last_info().join_response;
if !join_response.sif_trailer.is_empty() {
e2ee_manager.key_provider().and_then(|key_provider| Some(key_provider.set_sif_trailer(join_response.sif_trailer.to_vec())));
}

let pi = join_response.participant.unwrap();
let local_participant = LocalParticipant::new(
rtc_engine.clone(),
Expand Down
2 changes: 1 addition & 1 deletion webrtc-sys/build/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use regex::Regex;
use reqwest::StatusCode;

pub const SCRATH_PATH: &str = "livekit_webrtc";
pub const WEBRTC_TAG: &str = "webrtc-fcdef0d";
pub const WEBRTC_TAG: &str = "webrtc-0649214";
pub const IGNORE_DEFINES: [&str; 2] = ["CR_CLANG_REVISION", "CR_XCODE_VERSION"];

pub fn target_os() -> String {
Expand Down
20 changes: 17 additions & 3 deletions webrtc-sys/include/livekit/frame_cryptor.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,11 @@
#include <vector>

#include "api/crypto/frame_crypto_transformer.h"
#include "api/scoped_refptr.h"
#include "livekit/peer_connection.h"
#include "livekit/rtp_receiver.h"
#include "livekit/rtp_sender.h"
#include "livekit/webrtc.h"
#include "rtc_base/synchronization/mutex.h"
#include "rust/cxx.h"

Expand Down Expand Up @@ -106,6 +109,12 @@ class KeyProvider {
return vec;
}

void set_sif_trailer(rust::Vec<::std::uint8_t> trailer) const {
std::vector<uint8_t> trailer_vec;
std::copy(trailer.begin(), trailer.end(), std::back_inserter(trailer_vec));
impl_->SetSifTrailer(trailer_vec);
}

rtc::scoped_refptr<webrtc::KeyProvider> rtc_key_provider() { return impl_; }

private:
Expand All @@ -114,12 +123,14 @@ class KeyProvider {

class FrameCryptor {
public:
FrameCryptor(const std::string participant_id,
FrameCryptor(std::shared_ptr<RtcRuntime> rtc_runtime,
const std::string participant_id,
webrtc::FrameCryptorTransformer::Algorithm algorithm,
rtc::scoped_refptr<webrtc::KeyProvider> key_provider,
rtc::scoped_refptr<webrtc::RtpSenderInterface> sender);

FrameCryptor(const std::string participant_id,
FrameCryptor(std::shared_ptr<RtcRuntime> rtc_runtime,
const std::string participant_id,
webrtc::FrameCryptorTransformer::Algorithm algorithm,
rtc::scoped_refptr<webrtc::KeyProvider> key_provider,
rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver);
Expand All @@ -146,13 +157,14 @@ class FrameCryptor {
void unregister_observer() const;

private:
std::shared_ptr<RtcRuntime> rtc_runtime_;
const rust::String participant_id_;
mutable webrtc::Mutex mutex_;
rtc::scoped_refptr<webrtc::FrameCryptorTransformer> e2ee_transformer_;
rtc::scoped_refptr<webrtc::KeyProvider> key_provider_;
rtc::scoped_refptr<webrtc::RtpSenderInterface> sender_;
rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver_;
mutable std::unique_ptr<NativeFrameCryptorObserver> observer_;
mutable rtc::scoped_refptr<NativeFrameCryptorObserver> observer_;
};

class NativeFrameCryptorObserver
Expand All @@ -171,12 +183,14 @@ class NativeFrameCryptorObserver
};

std::shared_ptr<FrameCryptor> new_frame_cryptor_for_rtp_sender(
std::shared_ptr<PeerConnectionFactory> peer_factory,
const ::rust::String participant_id,
Algorithm algorithm,
std::shared_ptr<KeyProvider> key_provider,
std::shared_ptr<RtpSender> sender);

std::shared_ptr<FrameCryptor> new_frame_cryptor_for_rtp_receiver(
std::shared_ptr<PeerConnectionFactory> peer_factory,
const ::rust::String participant_id,
Algorithm algorithm,
std::shared_ptr<KeyProvider> key_provider,
Expand Down
2 changes: 2 additions & 0 deletions webrtc-sys/include/livekit/peer_connection_factory.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ class PeerConnectionFactory {

RtpCapabilities rtp_receiver_capabilities(MediaType type) const;

std::shared_ptr<RtcRuntime> rtc_runtime() const { return rtc_runtime_; }

private:
std::shared_ptr<RtcRuntime> rtc_runtime_;
rtc::scoped_refptr<AudioDevice> audio_device_;
Expand Down
41 changes: 29 additions & 12 deletions webrtc-sys/src/frame_cryptor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@
#include <memory>

#include "absl/types/optional.h"
#include "api/make_ref_counted.h"
#include "livekit/peer_connection.h"
#include "livekit/peer_connection_factory.h"
#include "livekit/webrtc.h"
#include "rtc_base/thread.h"
#include "webrtc-sys/src/frame_cryptor.rs.h"

namespace livekit {
Expand Down Expand Up @@ -57,67 +62,75 @@ KeyProvider::KeyProvider(KeyProviderOptions options) {
}

FrameCryptor::FrameCryptor(
std::shared_ptr<RtcRuntime> rtc_runtime,
const std::string participant_id,
webrtc::FrameCryptorTransformer::Algorithm algorithm,
rtc::scoped_refptr<webrtc::KeyProvider> key_provider,
rtc::scoped_refptr<webrtc::RtpSenderInterface> sender)
: participant_id_(participant_id),
: rtc_runtime_(rtc_runtime),
participant_id_(participant_id),
key_provider_(key_provider),
sender_(sender) {
auto mediaType =
sender->track()->kind() == "audio"
? webrtc::FrameCryptorTransformer::MediaType::kAudioFrame
: webrtc::FrameCryptorTransformer::MediaType::kVideoFrame;
e2ee_transformer_ = rtc::scoped_refptr<webrtc::FrameCryptorTransformer>(
new webrtc::FrameCryptorTransformer(participant_id, mediaType, algorithm,
new webrtc::FrameCryptorTransformer(rtc_runtime->signaling_thread(),
participant_id, mediaType, algorithm,
key_provider_));
sender->SetEncoderToPacketizerFrameTransformer(e2ee_transformer_);
e2ee_transformer_->SetEnabled(false);
}

FrameCryptor::FrameCryptor(
std::shared_ptr<RtcRuntime> rtc_runtime,
const std::string participant_id,
webrtc::FrameCryptorTransformer::Algorithm algorithm,
rtc::scoped_refptr<webrtc::KeyProvider> key_provider,
rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver)
: participant_id_(participant_id),
: rtc_runtime_(rtc_runtime),
participant_id_(participant_id),
key_provider_(key_provider),
receiver_(receiver) {
auto mediaType =
receiver->track()->kind() == "audio"
? webrtc::FrameCryptorTransformer::MediaType::kAudioFrame
: webrtc::FrameCryptorTransformer::MediaType::kVideoFrame;
e2ee_transformer_ = rtc::scoped_refptr<webrtc::FrameCryptorTransformer>(
new webrtc::FrameCryptorTransformer(participant_id, mediaType, algorithm,
new webrtc::FrameCryptorTransformer(rtc_runtime->signaling_thread(),
participant_id, mediaType, algorithm,
key_provider_));
receiver->SetDepacketizerToDecoderFrameTransformer(e2ee_transformer_);
e2ee_transformer_->SetEnabled(false);
}

FrameCryptor::~FrameCryptor() {}
FrameCryptor::~FrameCryptor() {
if(observer_) {
unregister_observer();
}
}

void FrameCryptor::register_observer(
rust::Box<RtcFrameCryptorObserverWrapper> observer) const {
webrtc::MutexLock lock(&mutex_);
observer_ =
std::make_unique<NativeFrameCryptorObserver>(std::move(observer), this);
e2ee_transformer_->SetFrameCryptorTransformerObserver(observer_.get());
observer_ = rtc::make_ref_counted<NativeFrameCryptorObserver>(
std::move(observer), this);
e2ee_transformer_->RegisterFrameCryptorTransformerObserver(observer_);
}

void FrameCryptor::unregister_observer() const {
webrtc::MutexLock lock(&mutex_);
observer_ = nullptr;
e2ee_transformer_->SetFrameCryptorTransformerObserver(nullptr);
e2ee_transformer_->UnRegisterFrameCryptorTransformerObserver();
}

NativeFrameCryptorObserver::NativeFrameCryptorObserver(
rust::Box<RtcFrameCryptorObserverWrapper> observer,
const FrameCryptor* fc)
: observer_(std::move(observer)), fc_(fc) {}

NativeFrameCryptorObserver::~NativeFrameCryptorObserver() {
fc_->unregister_observer();
}
NativeFrameCryptorObserver::~NativeFrameCryptorObserver() {}

void NativeFrameCryptorObserver::OnFrameCryptionStateChanged(
const std::string participant_id,
Expand Down Expand Up @@ -151,22 +164,26 @@ std::shared_ptr<KeyProvider> new_key_provider(KeyProviderOptions options) {
}

std::shared_ptr<FrameCryptor> new_frame_cryptor_for_rtp_sender(
std::shared_ptr<PeerConnectionFactory> peer_factory,
const ::rust::String participant_id,
Algorithm algorithm,
std::shared_ptr<KeyProvider> key_provider,
std::shared_ptr<RtpSender> sender) {
return std::make_shared<FrameCryptor>(
peer_factory->rtc_runtime(),
std::string(participant_id.data(), participant_id.size()),
AlgorithmToFrameCryptorAlgorithm(algorithm),
key_provider->rtc_key_provider(), sender->rtc_sender());
}

std::shared_ptr<FrameCryptor> new_frame_cryptor_for_rtp_receiver(
std::shared_ptr<PeerConnectionFactory> peer_factory,
const ::rust::String participant_id,
Algorithm algorithm,
std::shared_ptr<KeyProvider> key_provider,
std::shared_ptr<RtpReceiver> receiver) {
return std::make_shared<FrameCryptor>(
peer_factory->rtc_runtime(),
std::string(participant_id.data(), participant_id.size()),
AlgorithmToFrameCryptorAlgorithm(algorithm),
key_provider->rtc_key_provider(), receiver->rtc_receiver());
Expand Down
6 changes: 6 additions & 0 deletions webrtc-sys/src/frame_cryptor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ pub mod ffi {

pub fn get_shared_key(self: &KeyProvider, key_index: i32) -> Result<Vec<u8>>;

pub fn set_sif_trailer(&self, trailer: Vec<u8>);

pub fn set_key(
self: &KeyProvider,
participant_id: String,
Expand All @@ -83,20 +85,24 @@ pub mod ffi {
include!("livekit/frame_cryptor.h");
include!("livekit/rtp_sender.h");
include!("livekit/rtp_receiver.h");
include!("livekit/peer_connection_factory.h");

type RtpSender = crate::rtp_sender::ffi::RtpSender;
type RtpReceiver = crate::rtp_receiver::ffi::RtpReceiver;
type PeerConnectionFactory = crate::peer_connection_factory::ffi::PeerConnectionFactory;

pub type FrameCryptor;

pub fn new_frame_cryptor_for_rtp_sender(
peer_factory: SharedPtr<PeerConnectionFactory>,
participant_id: String,
algorithm: Algorithm,
key_provider: SharedPtr<KeyProvider>,
sender: SharedPtr<RtpSender>,
) -> SharedPtr<FrameCryptor>;

pub fn new_frame_cryptor_for_rtp_receiver(
peer_factory: SharedPtr<PeerConnectionFactory>,
participant_id: String,
algorithm: Algorithm,
key_provider: SharedPtr<KeyProvider>,
Expand Down
Loading