Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(448)

Side by Side Diff: webrtc/pc/srtpfilter.cc

Issue 2997983002: Completed the functionalities of SrtpTransport. (Closed)
Patch Set: Fix the chromimum issue. Created 3 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « webrtc/pc/srtpfilter.h ('k') | webrtc/pc/srtpfilter_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
OLDNEW
« no previous file with comments | « webrtc/pc/srtpfilter.h ('k') | webrtc/pc/srtpfilter_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698