1717#ifndef WEBRTC_FRAME_CRYPTOR_TRANSFORMER_H_
1818#define WEBRTC_FRAME_CRYPTOR_TRANSFORMER_H_
1919
20+ #include < unordered_map>
21+
2022#include " api/frame_transformer_interface.h"
2123#include " rtc_base/buffer.h"
2224#include " rtc_base/synchronization/mutex.h"
2325#include " rtc_base/system/rtc_export.h"
2426#include " rtc_base/thread.h"
2527
28+ int DerivePBKDF2KeyFromRawKey (const std::vector<uint8_t > raw_key,
29+ const std::vector<uint8_t >& salt,
30+ unsigned int optional_length_bits,
31+ std::vector<uint8_t >* derived_key);
32+
2633namespace webrtc {
2734
28- class KeyManager : public rtc ::RefCountInterface {
35+ const size_t KEYRING_SIZE = 16 ;
36+
37+ struct KeyProviderOptions {
38+ bool shared_key;
39+ std::vector<uint8_t > ratchet_salt;
40+ std::vector<uint8_t > uncrypted_magic_bytes;
41+ int ratchet_window_size;
42+ KeyProviderOptions () : shared_key(false ), ratchet_window_size(0 ) {}
43+ KeyProviderOptions (KeyProviderOptions& copy)
44+ : shared_key(copy.shared_key),
45+ ratchet_salt (copy.ratchet_salt),
46+ uncrypted_magic_bytes(copy.uncrypted_magic_bytes),
47+ ratchet_window_size(copy.ratchet_window_size) {}
48+ };
49+
50+ class ParticipantKeyHandler {
51+ public:
52+ struct KeySet {
53+ std::vector<uint8_t > material;
54+ std::vector<uint8_t > encryption_key;
55+ KeySet (std::vector<uint8_t > material, std::vector<uint8_t > encryptionKey)
56+ : material(material), encryption_key(encryptionKey) {}
57+ };
58+
59+ public:
60+ ParticipantKeyHandler (KeyProviderOptions options) : options_(options) {
61+ cryptoKeyRing_.resize (KEYRING_SIZE);
62+ }
63+
64+ virtual ~ParticipantKeyHandler () = default ;
65+
66+ virtual std::vector<uint8_t > RatchetKey (int keyIndex) {
67+ auto currentMaterial = GetKeySet (keyIndex)->material ;
68+ std::vector<uint8_t > newMaterial;
69+ if (DerivePBKDF2KeyFromRawKey (currentMaterial, options_.ratchet_salt , 256 ,
70+ &newMaterial) != 0 ) {
71+ return std::vector<uint8_t >();
72+ }
73+ SetKeyFromMaterial (newMaterial,
74+ keyIndex != -1 ? keyIndex : currentKeyIndex);
75+ return newMaterial;
76+ }
77+
78+ virtual std::shared_ptr<KeySet> GetKeySet (int keyIndex) {
79+ return cryptoKeyRing_[keyIndex != -1 ? keyIndex : currentKeyIndex];
80+ }
81+
82+ virtual void SetKeyFromMaterial (std::vector<uint8_t > password, int keyIndex) {
83+ if (keyIndex >= 0 ) {
84+ currentKeyIndex = keyIndex % cryptoKeyRing_.size ();
85+ }
86+ cryptoKeyRing_[currentKeyIndex] =
87+ DeriveKeys (password, options_.ratchet_salt , 128 );
88+ }
89+
90+ virtual KeyProviderOptions& options () { return options_; }
91+
92+ std::shared_ptr<KeySet> DeriveKeys (std::vector<uint8_t > password,
93+ std::vector<uint8_t > ratchet_salt,
94+ unsigned int optional_length_bits) {
95+ std::vector<uint8_t > derived_key;
96+ if (DerivePBKDF2KeyFromRawKey (password, ratchet_salt, optional_length_bits,
97+ &derived_key) == 0 ) {
98+ return std::make_shared<KeySet>(password, derived_key);
99+ }
100+ return nullptr ;
101+ }
102+
103+ std::vector<uint8_t > RatchetKeyMaterial (
104+ std::vector<uint8_t > currentMaterial) {
105+ std::vector<uint8_t > newMaterial;
106+ if (DerivePBKDF2KeyFromRawKey (currentMaterial, options_.ratchet_salt , 256 ,
107+ &newMaterial) != 0 ) {
108+ return std::vector<uint8_t >();
109+ }
110+ return newMaterial;
111+ }
112+
113+ private:
114+ int currentKeyIndex = 0 ;
115+ KeyProviderOptions options_;
116+ std::vector<std::shared_ptr<KeySet>> cryptoKeyRing_;
117+ };
118+
119+ class KeyProvider : public rtc ::RefCountInterface {
29120 public:
30121 enum { kRawKeySize = 32 };
31122
32123 public:
33- virtual const std::vector<std::vector< uint8_t >> keys (
124+ virtual const std::shared_ptr<ParticipantKeyHandler> GetKey (
34125 const std::string participant_id) const = 0;
35126
127+ virtual bool SetKey (const std::string participant_id,
128+ int index,
129+ std::vector<uint8_t > key) = 0;
130+
131+ virtual const std::vector<uint8_t > RatchetKey (
132+ const std::string participant_id,
133+ int key_index) = 0;
134+
135+ virtual const std::vector<uint8_t > ExportKey (const std::string participant_id,
136+ int key_index) const = 0;
137+
138+ virtual KeyProviderOptions& options () = 0;
139+
36140 protected:
37- virtual ~KeyManager () {}
141+ virtual ~KeyProvider () {}
38142};
39143
40- enum FrameCryptionError {
144+ class DefaultKeyProviderImpl : public KeyProvider {
145+ public:
146+ DefaultKeyProviderImpl (KeyProviderOptions options) : options_(options) {}
147+ ~DefaultKeyProviderImpl () override = default ;
148+
149+ // / Set the key at the given index.
150+ bool SetKey (const std::string participant_id,
151+ int index,
152+ std::vector<uint8_t > key) override {
153+ webrtc::MutexLock lock (&mutex_);
154+
155+ if (keys_.find (participant_id) == keys_.end ()) {
156+ keys_[participant_id] = std::make_shared<ParticipantKeyHandler>(options_);
157+ }
158+
159+ auto keyHandler = keys_[participant_id];
160+ keyHandler->SetKeyFromMaterial (key, index);
161+
162+ return true ;
163+ }
164+
165+ const std::shared_ptr<ParticipantKeyHandler> GetKey (
166+ const std::string participant_id) const override {
167+ webrtc::MutexLock lock (&mutex_);
168+ if (keys_.find (participant_id) == keys_.end ()) {
169+ return nullptr ;
170+ }
171+
172+ return keys_.find (participant_id)->second ;
173+ }
174+
175+ const std::vector<uint8_t > RatchetKey (const std::string participant_id,
176+ int key_index) override {
177+ webrtc::MutexLock lock (&mutex_);
178+ if (keys_.find (participant_id) == keys_.end ()) {
179+ return std::vector<uint8_t >();
180+ }
181+
182+ return keys_[participant_id]->RatchetKey (key_index);
183+ }
184+
185+ const std::vector<uint8_t > ExportKey (const std::string participant_id,
186+ int key_index) const override {
187+ webrtc::MutexLock lock (&mutex_);
188+ if (keys_.find (participant_id) == keys_.end ()) {
189+ return std::vector<uint8_t >();
190+ }
191+
192+ auto keySet = GetKey (participant_id);
193+
194+ if (!keySet) {
195+ return std::vector<uint8_t >();
196+ }
197+
198+ return keySet->GetKeySet (key_index)->material ;
199+ }
200+
201+ KeyProviderOptions& options () override { return options_; }
202+
203+ private:
204+ mutable webrtc::Mutex mutex_;
205+ KeyProviderOptions options_;
206+ std::unordered_map<std::string, std::shared_ptr<ParticipantKeyHandler>> keys_;
207+ };
208+
209+ enum FrameCryptionState {
41210 kNew = 0 ,
42211 kOk ,
43212 kEncryptionFailed ,
44213 kDecryptionFailed ,
45214 kMissingKey ,
215+ kKeyRatcheted ,
46216 kInternalError ,
47217};
48218
49219class FrameCryptorTransformerObserver {
50220 public:
51- virtual void OnFrameCryptionError (const std::string participant_id,
52- FrameCryptionError error) = 0;
221+ virtual void OnFrameCryptionStateChanged (const std::string participant_id,
222+ FrameCryptionState error) = 0;
53223
54224 protected:
55225 virtual ~FrameCryptorTransformerObserver () {}
@@ -71,7 +241,7 @@ class RTC_EXPORT FrameCryptorTransformer
71241 explicit FrameCryptorTransformer (const std::string participant_id,
72242 MediaType type,
73243 Algorithm algorithm,
74- rtc::scoped_refptr<KeyManager> key_manager );
244+ rtc::scoped_refptr<KeyProvider> key_provider );
75245
76246 virtual void SetFrameCryptorTransformerObserver (
77247 FrameCryptorTransformerObserver* observer) {
@@ -85,6 +255,7 @@ class RTC_EXPORT FrameCryptorTransformer
85255 }
86256
87257 virtual int key_index () const { return key_index_; }
258+
88259 virtual void SetEnabled (bool enabled) {
89260 webrtc::MutexLock lock (&mutex_);
90261 enabled_cryption_ = enabled;
@@ -140,11 +311,11 @@ class RTC_EXPORT FrameCryptorTransformer
140311 sink_callbacks_;
141312 int key_index_ = 0 ;
142313 std::map<uint32_t , uint32_t > sendCounts_;
143- rtc::scoped_refptr<KeyManager> key_manager_ ;
314+ rtc::scoped_refptr<KeyProvider> key_provider_ ;
144315 FrameCryptorTransformerObserver* observer_ = nullptr ;
145316 std::unique_ptr<rtc::Thread> thread_;
146- FrameCryptionError last_enc_error_ = FrameCryptionError ::kNew ;
147- FrameCryptionError last_dec_error_ = FrameCryptionError ::kNew ;
317+ FrameCryptionState last_enc_error_ = FrameCryptionState ::kNew ;
318+ FrameCryptionState last_dec_error_ = FrameCryptionState ::kNew ;
148319};
149320
150321} // namespace webrtc
0 commit comments