OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2009 The WebRTC project authors. All Rights Reserved. | 2 * Copyright 2009 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
11 #include "webrtc/pc/srtpfilter.h" | 11 #include "webrtc/pc/srtpfilter.h" |
12 | 12 |
13 #include <string.h> | 13 #include <string.h> |
14 | 14 |
15 #include <algorithm> | 15 #include <algorithm> |
16 | 16 |
17 #include "webrtc/media/base/rtputils.h" | 17 #include "webrtc/media/base/rtputils.h" |
18 #include "webrtc/pc/srtpsession.h" | 18 #include "webrtc/pc/srtpsession.h" |
19 #include "webrtc/rtc_base/base64.h" | 19 #include "webrtc/rtc_base/base64.h" |
20 #include "webrtc/rtc_base/buffer.h" | |
21 #include "webrtc/rtc_base/byteorder.h" | 20 #include "webrtc/rtc_base/byteorder.h" |
22 #include "webrtc/rtc_base/checks.h" | 21 #include "webrtc/rtc_base/checks.h" |
23 #include "webrtc/rtc_base/logging.h" | 22 #include "webrtc/rtc_base/logging.h" |
24 #include "webrtc/rtc_base/stringencode.h" | 23 #include "webrtc/rtc_base/stringencode.h" |
25 #include "webrtc/rtc_base/timeutils.h" | 24 #include "webrtc/rtc_base/timeutils.h" |
26 | 25 |
27 namespace cricket { | 26 namespace cricket { |
28 | 27 |
29 // NOTE: This is called from ChannelManager D'tor. | 28 // NOTE: This is called from ChannelManager D'tor. |
30 void ShutdownSrtp() { | 29 void ShutdownSrtp() { |
(...skipping 25 matching lines...) Expand all Loading... |
56 ContentSource source) { | 55 ContentSource source) { |
57 return DoSetAnswer(answer_params, source, true); | 56 return DoSetAnswer(answer_params, source, true); |
58 } | 57 } |
59 | 58 |
60 bool SrtpFilter::SetProvisionalAnswer( | 59 bool SrtpFilter::SetProvisionalAnswer( |
61 const std::vector<CryptoParams>& answer_params, | 60 const std::vector<CryptoParams>& answer_params, |
62 ContentSource source) { | 61 ContentSource source) { |
63 return DoSetAnswer(answer_params, source, false); | 62 return DoSetAnswer(answer_params, source, false); |
64 } | 63 } |
65 | 64 |
66 bool SrtpFilter::SetRtpParams(int send_cs, | |
67 const uint8_t* send_key, | |
68 int send_key_len, | |
69 int recv_cs, | |
70 const uint8_t* recv_key, | |
71 int recv_key_len) { | |
72 if (IsActive()) { | |
73 LOG(LS_ERROR) << "Tried to set SRTP Params when filter already active"; | |
74 return false; | |
75 } | |
76 CreateSrtpSessions(); | |
77 send_session_->SetEncryptedHeaderExtensionIds( | |
78 send_encrypted_header_extension_ids_); | |
79 if (!send_session_->SetSend(send_cs, send_key, send_key_len)) { | |
80 return false; | |
81 } | |
82 | |
83 recv_session_->SetEncryptedHeaderExtensionIds( | |
84 recv_encrypted_header_extension_ids_); | |
85 if (!recv_session_->SetRecv(recv_cs, recv_key, recv_key_len)) { | |
86 return false; | |
87 } | |
88 | |
89 state_ = ST_ACTIVE; | |
90 | |
91 LOG(LS_INFO) << "SRTP activated with negotiated parameters:" | |
92 << " send cipher_suite " << send_cs | |
93 << " recv cipher_suite " << recv_cs; | |
94 return true; | |
95 } | |
96 | |
97 bool SrtpFilter::UpdateRtpParams(int send_cs, | |
98 const uint8_t* send_key, | |
99 int send_key_len, | |
100 int recv_cs, | |
101 const uint8_t* recv_key, | |
102 int recv_key_len) { | |
103 if (!IsActive()) { | |
104 LOG(LS_ERROR) << "Tried to update SRTP Params when filter is not active"; | |
105 return false; | |
106 } | |
107 send_session_->SetEncryptedHeaderExtensionIds( | |
108 send_encrypted_header_extension_ids_); | |
109 if (!send_session_->UpdateSend(send_cs, send_key, send_key_len)) { | |
110 return false; | |
111 } | |
112 | |
113 recv_session_->SetEncryptedHeaderExtensionIds( | |
114 recv_encrypted_header_extension_ids_); | |
115 if (!recv_session_->UpdateRecv(recv_cs, recv_key, recv_key_len)) { | |
116 return false; | |
117 } | |
118 | |
119 LOG(LS_INFO) << "SRTP updated with negotiated parameters:" | |
120 << " send cipher_suite " << send_cs | |
121 << " recv cipher_suite " << recv_cs; | |
122 return true; | |
123 } | |
124 | |
125 // This function is provided separately because DTLS-SRTP behaves | |
126 // differently in RTP/RTCP mux and non-mux modes. | |
127 // | |
128 // - In the non-muxed case, RTP and RTCP are keyed with different | |
129 // keys (from different DTLS handshakes), and so we need a new | |
130 // SrtpSession. | |
131 // - In the muxed case, they are keyed with the same keys, so | |
132 // this function is not needed | |
133 bool SrtpFilter::SetRtcpParams(int send_cs, | |
134 const uint8_t* send_key, | |
135 int send_key_len, | |
136 int recv_cs, | |
137 const uint8_t* recv_key, | |
138 int recv_key_len) { | |
139 // This can only be called once, but can be safely called after | |
140 // SetRtpParams | |
141 if (send_rtcp_session_ || recv_rtcp_session_) { | |
142 LOG(LS_ERROR) << "Tried to set SRTCP Params when filter already active"; | |
143 return false; | |
144 } | |
145 | |
146 send_rtcp_session_.reset(new SrtpSession()); | |
147 if (!send_rtcp_session_->SetRecv(send_cs, send_key, send_key_len)) { | |
148 return false; | |
149 } | |
150 | |
151 recv_rtcp_session_.reset(new SrtpSession()); | |
152 if (!recv_rtcp_session_->SetRecv(recv_cs, recv_key, recv_key_len)) { | |
153 return false; | |
154 } | |
155 | |
156 LOG(LS_INFO) << "SRTCP activated with negotiated parameters:" | |
157 << " send cipher_suite " << send_cs | |
158 << " recv cipher_suite " << recv_cs; | |
159 | |
160 return true; | |
161 } | |
162 | |
163 bool SrtpFilter::ProtectRtp(void* p, int in_len, int max_len, int* out_len) { | |
164 if (!IsActive()) { | |
165 LOG(LS_WARNING) << "Failed to ProtectRtp: SRTP not active"; | |
166 return false; | |
167 } | |
168 RTC_CHECK(send_session_); | |
169 return send_session_->ProtectRtp(p, in_len, max_len, out_len); | |
170 } | |
171 | |
172 bool SrtpFilter::ProtectRtp(void* p, | |
173 int in_len, | |
174 int max_len, | |
175 int* out_len, | |
176 int64_t* index) { | |
177 if (!IsActive()) { | |
178 LOG(LS_WARNING) << "Failed to ProtectRtp: SRTP not active"; | |
179 return false; | |
180 } | |
181 RTC_CHECK(send_session_); | |
182 return send_session_->ProtectRtp(p, in_len, max_len, out_len, index); | |
183 } | |
184 | |
185 bool SrtpFilter::ProtectRtcp(void* p, int in_len, int max_len, int* out_len) { | |
186 if (!IsActive()) { | |
187 LOG(LS_WARNING) << "Failed to ProtectRtcp: SRTP not active"; | |
188 return false; | |
189 } | |
190 if (send_rtcp_session_) { | |
191 return send_rtcp_session_->ProtectRtcp(p, in_len, max_len, out_len); | |
192 } else { | |
193 RTC_CHECK(send_session_); | |
194 return send_session_->ProtectRtcp(p, in_len, max_len, out_len); | |
195 } | |
196 } | |
197 | |
198 bool SrtpFilter::UnprotectRtp(void* p, int in_len, int* out_len) { | |
199 if (!IsActive()) { | |
200 LOG(LS_WARNING) << "Failed to UnprotectRtp: SRTP not active"; | |
201 return false; | |
202 } | |
203 RTC_CHECK(recv_session_); | |
204 return recv_session_->UnprotectRtp(p, in_len, out_len); | |
205 } | |
206 | |
207 bool SrtpFilter::UnprotectRtcp(void* p, int in_len, int* out_len) { | |
208 if (!IsActive()) { | |
209 LOG(LS_WARNING) << "Failed to UnprotectRtcp: SRTP not active"; | |
210 return false; | |
211 } | |
212 if (recv_rtcp_session_) { | |
213 return recv_rtcp_session_->UnprotectRtcp(p, in_len, out_len); | |
214 } else { | |
215 RTC_CHECK(recv_session_); | |
216 return recv_session_->UnprotectRtcp(p, in_len, out_len); | |
217 } | |
218 } | |
219 | |
220 bool SrtpFilter::GetRtpAuthParams(uint8_t** key, int* key_len, int* tag_len) { | |
221 if (!IsActive()) { | |
222 LOG(LS_WARNING) << "Failed to GetRtpAuthParams: SRTP not active"; | |
223 return false; | |
224 } | |
225 | |
226 RTC_CHECK(send_session_); | |
227 return send_session_->GetRtpAuthParams(key, key_len, tag_len); | |
228 } | |
229 | |
230 bool SrtpFilter::GetSrtpOverhead(int* srtp_overhead) const { | |
231 if (!IsActive()) { | |
232 LOG(LS_WARNING) << "Failed to GetSrtpOverhead: SRTP not active"; | |
233 return false; | |
234 } | |
235 | |
236 RTC_CHECK(send_session_); | |
237 *srtp_overhead = send_session_->GetSrtpOverhead(); | |
238 return true; | |
239 } | |
240 | |
241 void SrtpFilter::EnableExternalAuth() { | |
242 RTC_DCHECK(!IsActive()); | |
243 external_auth_enabled_ = true; | |
244 } | |
245 | |
246 bool SrtpFilter::IsExternalAuthEnabled() const { | |
247 return external_auth_enabled_; | |
248 } | |
249 | |
250 bool SrtpFilter::IsExternalAuthActive() const { | |
251 if (!IsActive()) { | |
252 LOG(LS_WARNING) << "Failed to check IsExternalAuthActive: SRTP not active"; | |
253 return false; | |
254 } | |
255 | |
256 RTC_CHECK(send_session_); | |
257 return send_session_->IsExternalAuthActive(); | |
258 } | |
259 | |
260 void SrtpFilter::SetEncryptedHeaderExtensionIds(ContentSource source, | |
261 const std::vector<int>& extension_ids) { | |
262 if (source == CS_LOCAL) { | |
263 recv_encrypted_header_extension_ids_ = extension_ids; | |
264 } else { | |
265 send_encrypted_header_extension_ids_ = extension_ids; | |
266 } | |
267 } | |
268 | |
269 bool SrtpFilter::ExpectOffer(ContentSource source) { | 65 bool SrtpFilter::ExpectOffer(ContentSource source) { |
270 return ((state_ == ST_INIT) || | 66 return ((state_ == ST_INIT) || |
271 (state_ == ST_ACTIVE) || | 67 (state_ == ST_ACTIVE) || |
272 (state_ == ST_SENTOFFER && source == CS_LOCAL) || | 68 (state_ == ST_SENTOFFER && source == CS_LOCAL) || |
273 (state_ == ST_SENTUPDATEDOFFER && source == CS_LOCAL) || | 69 (state_ == ST_SENTUPDATEDOFFER && source == CS_LOCAL) || |
274 (state_ == ST_RECEIVEDOFFER && source == CS_REMOTE) || | 70 (state_ == ST_RECEIVEDOFFER && source == CS_REMOTE) || |
275 (state_ == ST_RECEIVEDUPDATEDOFFER && source == CS_REMOTE)); | 71 (state_ == ST_RECEIVEDUPDATEDOFFER && source == CS_REMOTE)); |
276 } | 72 } |
277 | 73 |
278 bool SrtpFilter::StoreParams(const std::vector<CryptoParams>& params, | 74 bool SrtpFilter::StoreParams(const std::vector<CryptoParams>& params, |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
316 // Need to wait for the final answer to decide if | 112 // Need to wait for the final answer to decide if |
317 // we should go to Active state. | 113 // we should go to Active state. |
318 state_ = (source == CS_LOCAL) ? ST_SENTPRANSWER_NO_CRYPTO : | 114 state_ = (source == CS_LOCAL) ? ST_SENTPRANSWER_NO_CRYPTO : |
319 ST_RECEIVEDPRANSWER_NO_CRYPTO; | 115 ST_RECEIVEDPRANSWER_NO_CRYPTO; |
320 return true; | 116 return true; |
321 } | 117 } |
322 } | 118 } |
323 CryptoParams selected_params; | 119 CryptoParams selected_params; |
324 if (!NegotiateParams(answer_params, &selected_params)) | 120 if (!NegotiateParams(answer_params, &selected_params)) |
325 return false; | 121 return false; |
326 const CryptoParams& send_params = | 122 |
| 123 const CryptoParams& new_send_params = |
327 (source == CS_REMOTE) ? selected_params : answer_params[0]; | 124 (source == CS_REMOTE) ? selected_params : answer_params[0]; |
328 const CryptoParams& recv_params = | 125 const CryptoParams& new_recv_params = |
329 (source == CS_REMOTE) ? answer_params[0] : selected_params; | 126 (source == CS_REMOTE) ? answer_params[0] : selected_params; |
330 if (!ApplyParams(send_params, recv_params)) { | 127 if (!ApplySendParams(new_send_params) || !ApplyRecvParams(new_recv_params)) { |
331 return false; | 128 return false; |
332 } | 129 } |
| 130 applied_send_params_ = new_send_params; |
| 131 applied_recv_params_ = new_recv_params; |
333 | 132 |
334 if (final) { | 133 if (final) { |
335 offer_params_.clear(); | 134 offer_params_.clear(); |
336 state_ = ST_ACTIVE; | 135 state_ = ST_ACTIVE; |
337 } else { | 136 } else { |
338 state_ = | 137 state_ = |
339 (source == CS_LOCAL) ? ST_SENTPRANSWER : ST_RECEIVEDPRANSWER; | 138 (source == CS_LOCAL) ? ST_SENTPRANSWER : ST_RECEIVEDPRANSWER; |
340 } | 139 } |
341 return true; | 140 return true; |
342 } | 141 } |
343 | 142 |
344 void SrtpFilter::CreateSrtpSessions() { | |
345 send_session_.reset(new SrtpSession()); | |
346 applied_send_params_ = CryptoParams(); | |
347 recv_session_.reset(new SrtpSession()); | |
348 applied_recv_params_ = CryptoParams(); | |
349 | |
350 if (external_auth_enabled_) { | |
351 send_session_->EnableExternalAuth(); | |
352 } | |
353 } | |
354 | |
355 bool SrtpFilter::NegotiateParams(const std::vector<CryptoParams>& answer_params, | 143 bool SrtpFilter::NegotiateParams(const std::vector<CryptoParams>& answer_params, |
356 CryptoParams* selected_params) { | 144 CryptoParams* selected_params) { |
357 // We're processing an accept. We should have exactly one set of params, | 145 // We're processing an accept. We should have exactly one set of params, |
358 // unless the offer didn't mention crypto, in which case we shouldn't be here. | 146 // unless the offer didn't mention crypto, in which case we shouldn't be here. |
359 bool ret = (answer_params.size() == 1U && !offer_params_.empty()); | 147 bool ret = (answer_params.size() == 1U && !offer_params_.empty()); |
360 if (ret) { | 148 if (ret) { |
361 // We should find a match between the answer params and the offered params. | 149 // We should find a match between the answer params and the offered params. |
362 std::vector<CryptoParams>::const_iterator it; | 150 std::vector<CryptoParams>::const_iterator it; |
363 for (it = offer_params_.begin(); it != offer_params_.end(); ++it) { | 151 for (it = offer_params_.begin(); it != offer_params_.end(); ++it) { |
364 if (answer_params[0].Matches(*it)) { | 152 if (answer_params[0].Matches(*it)) { |
365 break; | 153 break; |
366 } | 154 } |
367 } | 155 } |
368 | 156 |
369 if (it != offer_params_.end()) { | 157 if (it != offer_params_.end()) { |
370 *selected_params = *it; | 158 *selected_params = *it; |
371 } else { | 159 } else { |
372 ret = false; | 160 ret = false; |
373 } | 161 } |
374 } | 162 } |
375 | 163 |
376 if (!ret) { | 164 if (!ret) { |
377 LOG(LS_WARNING) << "Invalid parameters in SRTP answer"; | 165 LOG(LS_WARNING) << "Invalid parameters in SRTP answer"; |
378 } | 166 } |
379 return ret; | 167 return ret; |
380 } | 168 } |
381 | 169 |
382 bool SrtpFilter::ApplyParams(const CryptoParams& send_params, | 170 bool SrtpFilter::ResetParams() { |
383 const CryptoParams& recv_params) { | 171 offer_params_.clear(); |
384 // TODO(jiayl): Split this method to apply send and receive CryptoParams | 172 applied_send_params_ = CryptoParams(); |
385 // independently, so that we can skip one method when either send or receive | 173 applied_recv_params_ = CryptoParams(); |
386 // CryptoParams is unchanged. | 174 send_cipher_suite_ = rtc::Optional<int>(); |
| 175 recv_cipher_suite_ = rtc::Optional<int>(); |
| 176 send_key_.Clear(); |
| 177 recv_key_.Clear(); |
| 178 state_ = ST_INIT; |
| 179 return true; |
| 180 } |
| 181 |
| 182 bool SrtpFilter::ApplySendParams(const CryptoParams& send_params) { |
387 if (applied_send_params_.cipher_suite == send_params.cipher_suite && | 183 if (applied_send_params_.cipher_suite == send_params.cipher_suite && |
388 applied_send_params_.key_params == send_params.key_params && | 184 applied_send_params_.key_params == send_params.key_params) { |
389 applied_recv_params_.cipher_suite == recv_params.cipher_suite && | 185 LOG(LS_INFO) << "Applying the same SRTP send parameters again. No-op."; |
390 applied_recv_params_.key_params == recv_params.key_params) { | |
391 LOG(LS_INFO) << "Applying the same SRTP parameters again. No-op."; | |
392 | 186 |
393 // We do not want to reset the ROC if the keys are the same. So just return. | 187 // We do not want to reset the ROC if the keys are the same. So just return. |
394 return true; | 188 return true; |
395 } | 189 } |
396 | 190 |
397 int send_suite = rtc::SrtpCryptoSuiteFromName(send_params.cipher_suite); | 191 send_cipher_suite_ = rtc::Optional<int>( |
398 int recv_suite = rtc::SrtpCryptoSuiteFromName(recv_params.cipher_suite); | 192 rtc::SrtpCryptoSuiteFromName(send_params.cipher_suite)); |
399 if (send_suite == rtc::SRTP_INVALID_CRYPTO_SUITE || | 193 if (send_cipher_suite_ == rtc::SRTP_INVALID_CRYPTO_SUITE) { |
400 recv_suite == rtc::SRTP_INVALID_CRYPTO_SUITE) { | |
401 LOG(LS_WARNING) << "Unknown crypto suite(s) received:" | 194 LOG(LS_WARNING) << "Unknown crypto suite(s) received:" |
402 << " send cipher_suite " << send_params.cipher_suite | 195 << " send cipher_suite " << send_params.cipher_suite; |
| 196 return false; |
| 197 } |
| 198 |
| 199 int send_key_len, send_salt_len; |
| 200 if (!rtc::GetSrtpKeyAndSaltLengths(*send_cipher_suite_, &send_key_len, |
| 201 &send_salt_len)) { |
| 202 LOG(LS_WARNING) << "Could not get lengths for crypto suite(s):" |
| 203 << " send cipher_suite " << send_params.cipher_suite; |
| 204 return false; |
| 205 } |
| 206 |
| 207 send_key_ = rtc::Buffer(send_key_len + send_salt_len); |
| 208 return ParseKeyParams(send_params.key_params, send_key_.data(), |
| 209 send_key_.size()); |
| 210 } |
| 211 |
| 212 bool SrtpFilter::ApplyRecvParams(const CryptoParams& recv_params) { |
| 213 if (applied_recv_params_.cipher_suite == recv_params.cipher_suite && |
| 214 applied_recv_params_.key_params == recv_params.key_params) { |
| 215 LOG(LS_INFO) << "Applying the same SRTP recv parameters again. No-op."; |
| 216 |
| 217 // We do not want to reset the ROC if the keys are the same. So just return. |
| 218 return true; |
| 219 } |
| 220 |
| 221 recv_cipher_suite_ = rtc::Optional<int>( |
| 222 rtc::SrtpCryptoSuiteFromName(recv_params.cipher_suite)); |
| 223 if (recv_cipher_suite_ == rtc::SRTP_INVALID_CRYPTO_SUITE) { |
| 224 LOG(LS_WARNING) << "Unknown crypto suite(s) received:" |
403 << " recv cipher_suite " << recv_params.cipher_suite; | 225 << " recv cipher_suite " << recv_params.cipher_suite; |
404 return false; | 226 return false; |
405 } | 227 } |
406 | 228 |
407 int send_key_len, send_salt_len; | |
408 int recv_key_len, recv_salt_len; | 229 int recv_key_len, recv_salt_len; |
409 if (!rtc::GetSrtpKeyAndSaltLengths(send_suite, &send_key_len, | 230 if (!rtc::GetSrtpKeyAndSaltLengths(*recv_cipher_suite_, &recv_key_len, |
410 &send_salt_len) || | |
411 !rtc::GetSrtpKeyAndSaltLengths(recv_suite, &recv_key_len, | |
412 &recv_salt_len)) { | 231 &recv_salt_len)) { |
413 LOG(LS_WARNING) << "Could not get lengths for crypto suite(s):" | 232 LOG(LS_WARNING) << "Could not get lengths for crypto suite(s):" |
414 << " send cipher_suite " << send_params.cipher_suite | |
415 << " recv cipher_suite " << recv_params.cipher_suite; | 233 << " recv cipher_suite " << recv_params.cipher_suite; |
416 return false; | 234 return false; |
417 } | 235 } |
418 | 236 |
419 // TODO(juberti): Zero these buffers after use. | 237 recv_key_ = rtc::Buffer(recv_key_len + recv_salt_len); |
420 bool ret; | 238 return ParseKeyParams(recv_params.key_params, recv_key_.data(), |
421 rtc::Buffer send_key(send_key_len + send_salt_len); | 239 recv_key_.size()); |
422 rtc::Buffer recv_key(recv_key_len + recv_salt_len); | |
423 ret = (ParseKeyParams(send_params.key_params, send_key.data(), | |
424 send_key.size()) && | |
425 ParseKeyParams(recv_params.key_params, recv_key.data(), | |
426 recv_key.size())); | |
427 if (ret) { | |
428 CreateSrtpSessions(); | |
429 send_session_->SetEncryptedHeaderExtensionIds( | |
430 send_encrypted_header_extension_ids_); | |
431 recv_session_->SetEncryptedHeaderExtensionIds( | |
432 recv_encrypted_header_extension_ids_); | |
433 ret = (send_session_->SetSend( | |
434 rtc::SrtpCryptoSuiteFromName(send_params.cipher_suite), | |
435 send_key.data(), send_key.size()) && | |
436 recv_session_->SetRecv( | |
437 rtc::SrtpCryptoSuiteFromName(recv_params.cipher_suite), | |
438 recv_key.data(), recv_key.size())); | |
439 } | |
440 if (ret) { | |
441 LOG(LS_INFO) << "SRTP activated with negotiated parameters:" | |
442 << " send cipher_suite " << send_params.cipher_suite | |
443 << " recv cipher_suite " << recv_params.cipher_suite; | |
444 applied_send_params_ = send_params; | |
445 applied_recv_params_ = recv_params; | |
446 } else { | |
447 LOG(LS_WARNING) << "Failed to apply negotiated SRTP parameters"; | |
448 } | |
449 return ret; | |
450 } | |
451 | |
452 bool SrtpFilter::ResetParams() { | |
453 offer_params_.clear(); | |
454 state_ = ST_INIT; | |
455 send_session_ = nullptr; | |
456 recv_session_ = nullptr; | |
457 send_rtcp_session_ = nullptr; | |
458 recv_rtcp_session_ = nullptr; | |
459 LOG(LS_INFO) << "SRTP reset to init state"; | |
460 return true; | |
461 } | 240 } |
462 | 241 |
463 bool SrtpFilter::ParseKeyParams(const std::string& key_params, | 242 bool SrtpFilter::ParseKeyParams(const std::string& key_params, |
464 uint8_t* key, | 243 uint8_t* key, |
465 size_t len) { | 244 size_t len) { |
466 // example key_params: "inline:YUJDZGVmZ2hpSktMbW9QUXJzVHVWd3l6MTIzNDU2" | 245 // example key_params: "inline:YUJDZGVmZ2hpSktMbW9QUXJzVHVWd3l6MTIzNDU2" |
467 | 246 |
468 // Fail if key-method is wrong. | 247 // Fail if key-method is wrong. |
469 if (key_params.find("inline:") != 0) { | 248 if (key_params.find("inline:") != 0) { |
470 return false; | 249 return false; |
471 } | 250 } |
472 | 251 |
473 // Fail if base64 decode fails, or the key is the wrong size. | 252 // Fail if base64 decode fails, or the key is the wrong size. |
474 std::string key_b64(key_params.substr(7)), key_str; | 253 std::string key_b64(key_params.substr(7)), key_str; |
475 if (!rtc::Base64::Decode(key_b64, rtc::Base64::DO_STRICT, | 254 if (!rtc::Base64::Decode(key_b64, rtc::Base64::DO_STRICT, &key_str, |
476 &key_str, nullptr) || key_str.size() != len) { | 255 nullptr) || |
| 256 key_str.size() != len) { |
477 return false; | 257 return false; |
478 } | 258 } |
479 | 259 |
480 memcpy(key, key_str.c_str(), len); | 260 memcpy(key, key_str.c_str(), len); |
481 return true; | 261 return true; |
482 } | 262 } |
483 | 263 |
484 } // namespace cricket | 264 } // namespace cricket |
OLD | NEW |