gosuto_livekit/room/e2ee/
key_provider.rs1use gosuto_libwebrtc::native::frame_cryptor as fc;
16use std::sync::{
17 atomic::{AtomicI32, Ordering},
18 Arc,
19};
20
21use crate::id::ParticipantIdentity;
22
23pub use fc::KeyDerivationAlgorithm;
24
25const DEFAULT_RATCHET_SALT: &str = "LKFrameEncryptionKey";
26const DEFAULT_RATCHET_WINDOW_SIZE: i32 = 16;
27const DEFAULT_FAILURE_TOLERANCE: i32 = -1; #[derive(Clone)]
30pub struct KeyProviderOptions {
31 pub ratchet_window_size: i32,
32 pub ratchet_salt: Vec<u8>,
33 pub failure_tolerance: i32,
34 pub key_derivation_algorithm: KeyDerivationAlgorithm,
35}
36
37impl Default for KeyProviderOptions {
38 fn default() -> Self {
39 Self {
40 ratchet_window_size: DEFAULT_RATCHET_WINDOW_SIZE,
41 ratchet_salt: DEFAULT_RATCHET_SALT.to_owned().into_bytes(),
42 failure_tolerance: DEFAULT_FAILURE_TOLERANCE,
43 key_derivation_algorithm: KeyDerivationAlgorithm::Hkdf,
44 }
45 }
46}
47
48#[derive(Clone)]
49pub struct KeyProvider {
50 pub(crate) handle: fc::KeyProvider,
51 latest_key_index: Arc<AtomicI32>,
52}
53
54impl KeyProvider {
55 pub fn new(options: KeyProviderOptions) -> Self {
57 Self {
58 handle: fc::KeyProvider::new(fc::KeyProviderOptions {
59 shared_key: false,
60 ratchet_window_size: options.ratchet_window_size,
61 ratchet_salt: options.ratchet_salt,
62 failure_tolerance: options.failure_tolerance,
63 key_derivation_algorithm: options.key_derivation_algorithm,
64 }),
65 latest_key_index: Arc::new(AtomicI32::new(0)),
66 }
67 }
68
69 pub fn with_shared_key(options: KeyProviderOptions, shared_key: Vec<u8>) -> Self {
70 let handle = fc::KeyProvider::new(fc::KeyProviderOptions {
71 shared_key: true,
72 ratchet_window_size: options.ratchet_window_size,
73 ratchet_salt: options.ratchet_salt,
74 failure_tolerance: options.failure_tolerance,
75 key_derivation_algorithm: options.key_derivation_algorithm,
76 });
77 handle.set_shared_key(0, shared_key);
78 Self { handle, latest_key_index: Arc::new(AtomicI32::new(0)) }
79 }
80
81 pub fn set_shared_key(&self, shared_key: Vec<u8>, key_index: i32) {
82 self.latest_key_index.store(key_index, Ordering::Relaxed);
83 self.handle.set_shared_key(key_index, shared_key);
84 }
85
86 pub fn ratchet_shared_key(&self, key_index: i32) -> Option<Vec<u8>> {
87 self.handle.ratchet_shared_key(key_index)
88 }
89
90 pub fn get_shared_key(&self, key_index: i32) -> Option<Vec<u8>> {
91 self.handle.get_shared_key(key_index)
92 }
93
94 pub fn set_key(&self, identity: &ParticipantIdentity, key_index: i32, key: Vec<u8>) -> bool {
95 self.latest_key_index.store(key_index, Ordering::Relaxed);
96 self.handle.set_key(identity.to_string(), key_index, key)
97 }
98
99 pub fn ratchet_key(&self, identity: &ParticipantIdentity, key_index: i32) -> Option<Vec<u8>> {
100 self.handle.ratchet_key(identity.to_string(), key_index)
101 }
102
103 pub fn get_key(&self, identity: &ParticipantIdentity, key_index: i32) -> Option<Vec<u8>> {
104 self.handle.get_key(identity.to_string(), key_index)
105 }
106
107 pub fn set_sif_trailer(&self, trailer: Vec<u8>) {
108 self.handle.set_sif_trailer(trailer);
109 }
110
111 pub fn get_latest_key_index(&self) -> i32 {
112 self.latest_key_index.load(Ordering::Relaxed)
113 }
114}