1use std::sync::Arc;
16
17use crate::impl_thread_safety;
18
19#[cxx::bridge(namespace = "livekit_ffi")]
20pub mod ffi {
21
22 #[derive(Debug)]
23 pub struct KeyProviderOptions {
24 pub shared_key: bool,
25 pub ratchet_window_size: i32,
26 pub ratchet_salt: Vec<u8>,
27 pub failure_tolerance: i32,
28 pub key_ring_size: i32,
29 pub key_derivation_algorithm: KeyDerivationAlgorithm,
30 }
31
32 #[derive(Debug)]
33 #[repr(i32)]
34 pub enum KeyDerivationAlgorithm {
35 PBKDF2 = 0,
36 HKDF,
37 }
38
39 #[derive(Debug)]
40 #[repr(i32)]
41 pub enum Algorithm {
42 AesGcm = 0,
43 AesCbc,
44 }
45
46 #[derive(Debug)]
47 #[repr(i32)]
48 pub enum FrameCryptionState {
49 New = 0,
50 Ok,
51 EncryptionFailed,
52 DecryptionFailed,
53 MissingKey,
54 KeyRatcheted,
55 InternalError,
56 }
57
58 #[derive(Debug)]
59 pub struct EncryptedPacket {
60 pub data: Vec<u8>,
61 pub iv: Vec<u8>,
62 pub key_index: u32,
63 }
64
65 unsafe extern "C++" {
66 include!("livekit/frame_cryptor.h");
67
68 pub type KeyProvider;
69
70 pub fn new_key_provider(options: KeyProviderOptions) -> SharedPtr<KeyProvider>;
71
72 pub fn set_shared_key(self: &KeyProvider, key_index: i32, key: Vec<u8>) -> bool;
73
74 pub fn ratchet_shared_key(self: &KeyProvider, key_index: i32) -> Result<Vec<u8>>;
75
76 pub fn get_shared_key(self: &KeyProvider, key_index: i32) -> Result<Vec<u8>>;
77
78 pub fn set_sif_trailer(&self, trailer: Vec<u8>);
79
80 pub fn set_key(
81 self: &KeyProvider,
82 participant_id: String,
83 key_index: i32,
84 key: Vec<u8>,
85 ) -> bool;
86
87 pub fn ratchet_key(
88 self: &KeyProvider,
89 participant_id: String,
90 key_index: i32,
91 ) -> Result<Vec<u8>>;
92
93 pub fn get_key(
94 self: &KeyProvider,
95 participant_id: String,
96 key_index: i32,
97 ) -> Result<Vec<u8>>;
98 }
99
100 unsafe extern "C++" {
101 include!("livekit/frame_cryptor.h");
102 include!("livekit/rtp_sender.h");
103 include!("livekit/rtp_receiver.h");
104 include!("livekit/peer_connection_factory.h");
105 include!("livekit/packet_trailer.h");
106
107 type RtpSender = crate::rtp_sender::ffi::RtpSender;
108 type RtpReceiver = crate::rtp_receiver::ffi::RtpReceiver;
109 type PeerConnectionFactory = crate::peer_connection_factory::ffi::PeerConnectionFactory;
110 type PacketTrailerHandler = crate::packet_trailer::ffi::PacketTrailerHandler;
111
112 pub type FrameCryptor;
113
114 pub fn new_frame_cryptor_for_rtp_sender(
115 peer_factory: SharedPtr<PeerConnectionFactory>,
116 participant_id: String,
117 algorithm: Algorithm,
118 key_provider: SharedPtr<KeyProvider>,
119 sender: SharedPtr<RtpSender>,
120 ) -> SharedPtr<FrameCryptor>;
121
122 pub fn new_frame_cryptor_for_rtp_receiver(
123 peer_factory: SharedPtr<PeerConnectionFactory>,
124 participant_id: String,
125 algorithm: Algorithm,
126 key_provider: SharedPtr<KeyProvider>,
127 receiver: SharedPtr<RtpReceiver>,
128 ) -> SharedPtr<FrameCryptor>;
129
130 pub fn set_enabled(self: &FrameCryptor, enabled: bool);
131
132 pub fn enabled(self: &FrameCryptor) -> bool;
133
134 pub fn set_key_index(self: &FrameCryptor, index: i32);
135
136 pub fn key_index(self: &FrameCryptor) -> i32;
137
138 pub fn participant_id(self: &FrameCryptor) -> String;
139
140 pub fn register_observer(
141 self: &FrameCryptor,
142 observer: Box<RtcFrameCryptorObserverWrapper>,
143 );
144
145 pub fn unregister_observer(self: &FrameCryptor);
146
147 pub fn set_packet_trailer_handler(
148 self: &FrameCryptor,
149 handler: SharedPtr<PacketTrailerHandler>,
150 );
151 }
152
153 unsafe extern "C++" {
154 include!("livekit/frame_cryptor.h");
155
156 pub type DataPacketCryptor;
157
158 pub fn new_data_packet_cryptor(
159 algorithm: Algorithm,
160 key_provider: SharedPtr<KeyProvider>,
161 ) -> SharedPtr<DataPacketCryptor>;
162
163 pub fn encrypt_data_packet(
164 self: &DataPacketCryptor,
165 participant_id: String,
166 key_index: u32,
167 data: Vec<u8>,
168 ) -> Result<EncryptedPacket>;
169
170 pub fn decrypt_data_packet(
171 self: &DataPacketCryptor,
172 participant_id: String,
173 encrypted_packet: &EncryptedPacket,
174 ) -> Result<Vec<u8>>;
175 }
176
177 extern "Rust" {
178 type RtcFrameCryptorObserverWrapper;
179
180 fn on_frame_cryption_state_change(
181 self: &RtcFrameCryptorObserverWrapper,
182 participant_id: String,
183 state: FrameCryptionState,
184 );
185 }
186} impl_thread_safety!(ffi::FrameCryptor, Send + Sync);
189impl_thread_safety!(ffi::KeyProvider, Send + Sync);
190impl_thread_safety!(ffi::DataPacketCryptor, Send + Sync);
191
192use ffi::FrameCryptionState;
193
194pub use ffi::EncryptedPacket;
196
197pub trait RtcFrameCryptorObserver: Send + Sync {
198 fn on_frame_cryption_state_change(&self, participant_id: String, state: FrameCryptionState);
199}
200
201pub struct RtcFrameCryptorObserverWrapper {
202 observer: Arc<dyn RtcFrameCryptorObserver>,
203}
204
205impl RtcFrameCryptorObserverWrapper {
206 pub fn new(observer: Arc<dyn RtcFrameCryptorObserver>) -> Self {
207 Self { observer }
208 }
209
210 fn on_frame_cryption_state_change(
211 self: &RtcFrameCryptorObserverWrapper,
212 participant_id: String,
213 state: FrameCryptionState,
214 ) {
215 self.observer.on_frame_cryption_state_change(participant_id, state);
216 }
217}
218
219pub struct DataPacketCryptor {
221 inner: cxx::SharedPtr<ffi::DataPacketCryptor>,
222}
223
224impl DataPacketCryptor {
225 pub fn new(algorithm: ffi::Algorithm, key_provider: cxx::SharedPtr<ffi::KeyProvider>) -> Self {
227 Self { inner: ffi::new_data_packet_cryptor(algorithm, key_provider) }
228 }
229
230 pub fn encrypt(
232 &self,
233 participant_id: &str,
234 key_index: u32,
235 data: &[u8],
236 ) -> Result<ffi::EncryptedPacket, Box<dyn std::error::Error>> {
237 let data_vec: Vec<u8> = data.to_vec();
238 match self.inner.encrypt_data_packet(participant_id.to_string(), key_index, data_vec) {
239 Ok(packet) => Ok(packet),
240 Err(e) => Err(format!("Encryption failed: {}", e).into()),
241 }
242 }
243
244 pub fn decrypt(
246 &self,
247 participant_id: &str,
248 encrypted_packet: &ffi::EncryptedPacket,
249 ) -> Result<Vec<u8>, Box<dyn std::error::Error>> {
250 match self.inner.decrypt_data_packet(participant_id.to_string(), encrypted_packet) {
251 Ok(data) => Ok(data.into_iter().collect()),
252 Err(e) => Err(format!("Decryption failed: {}", e).into()),
253 }
254 }
255}
256
257#[cfg(test)]
258mod tests {
259 use super::*;
260
261 #[test]
262 fn test_data_packet_cryptor_creation() {
263 let options = ffi::KeyProviderOptions {
264 shared_key: true,
265 ratchet_window_size: 16,
266 ratchet_salt: vec![],
267 failure_tolerance: -1,
268 key_ring_size: 16,
269 key_derivation_algorithm: ffi::KeyDerivationAlgorithm::HKDF,
270 };
271
272 let key_provider = ffi::new_key_provider(options);
273 let _cryptor = DataPacketCryptor::new(ffi::Algorithm::AesGcm, key_provider);
274 }
275}