Chromium Code Reviews| 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/pc/srtptransport.h" | |
|
Taylor Brandstetter
2017/08/26 02:40:39
What part of srtptransport.h does this use?
Zhi Huang
2017/08/29 18:40:35
Removed.
| |
| 19 #include "webrtc/rtc_base/base64.h" | 20 #include "webrtc/rtc_base/base64.h" |
| 20 #include "webrtc/rtc_base/buffer.h" | |
| 21 #include "webrtc/rtc_base/byteorder.h" | 21 #include "webrtc/rtc_base/byteorder.h" |
| 22 #include "webrtc/rtc_base/checks.h" | 22 #include "webrtc/rtc_base/checks.h" |
| 23 #include "webrtc/rtc_base/logging.h" | 23 #include "webrtc/rtc_base/logging.h" |
| 24 #include "webrtc/rtc_base/stringencode.h" | 24 #include "webrtc/rtc_base/stringencode.h" |
| 25 #include "webrtc/rtc_base/timeutils.h" | 25 #include "webrtc/rtc_base/timeutils.h" |
| 26 | 26 |
| 27 namespace cricket { | 27 namespace cricket { |
| 28 | 28 |
| 29 // NOTE: This is called from ChannelManager D'tor. | 29 // NOTE: This is called from ChannelManager D'tor. |
| 30 void ShutdownSrtp() { | 30 void ShutdownSrtp() { |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 56 ContentSource source) { | 56 ContentSource source) { |
| 57 return DoSetAnswer(answer_params, source, true); | 57 return DoSetAnswer(answer_params, source, true); |
| 58 } | 58 } |
| 59 | 59 |
| 60 bool SrtpFilter::SetProvisionalAnswer( | 60 bool SrtpFilter::SetProvisionalAnswer( |
| 61 const std::vector<CryptoParams>& answer_params, | 61 const std::vector<CryptoParams>& answer_params, |
| 62 ContentSource source) { | 62 ContentSource source) { |
| 63 return DoSetAnswer(answer_params, source, false); | 63 return DoSetAnswer(answer_params, source, false); |
| 64 } | 64 } |
| 65 | 65 |
| 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) { | 66 bool SrtpFilter::ExpectOffer(ContentSource source) { |
| 270 return ((state_ == ST_INIT) || | 67 return ((state_ == ST_INIT) || |
| 271 (state_ == ST_ACTIVE) || | 68 (state_ == ST_ACTIVE) || |
| 272 (state_ == ST_SENTOFFER && source == CS_LOCAL) || | 69 (state_ == ST_SENTOFFER && source == CS_LOCAL) || |
| 273 (state_ == ST_SENTUPDATEDOFFER && source == CS_LOCAL) || | 70 (state_ == ST_SENTUPDATEDOFFER && source == CS_LOCAL) || |
| 274 (state_ == ST_RECEIVEDOFFER && source == CS_REMOTE) || | 71 (state_ == ST_RECEIVEDOFFER && source == CS_REMOTE) || |
| 275 (state_ == ST_RECEIVEDUPDATEDOFFER && source == CS_REMOTE)); | 72 (state_ == ST_RECEIVEDUPDATEDOFFER && source == CS_REMOTE)); |
| 276 } | 73 } |
| 277 | 74 |
| 278 bool SrtpFilter::StoreParams(const std::vector<CryptoParams>& params, | 75 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 | 113 // Need to wait for the final answer to decide if |
| 317 // we should go to Active state. | 114 // we should go to Active state. |
| 318 state_ = (source == CS_LOCAL) ? ST_SENTPRANSWER_NO_CRYPTO : | 115 state_ = (source == CS_LOCAL) ? ST_SENTPRANSWER_NO_CRYPTO : |
| 319 ST_RECEIVEDPRANSWER_NO_CRYPTO; | 116 ST_RECEIVEDPRANSWER_NO_CRYPTO; |
| 320 return true; | 117 return true; |
| 321 } | 118 } |
| 322 } | 119 } |
| 323 CryptoParams selected_params; | 120 CryptoParams selected_params; |
| 324 if (!NegotiateParams(answer_params, &selected_params)) | 121 if (!NegotiateParams(answer_params, &selected_params)) |
| 325 return false; | 122 return false; |
| 326 const CryptoParams& send_params = | 123 |
| 124 CryptoParams new_send_params = | |
|
Taylor Brandstetter
2017/08/26 02:40:39
Can't these still be const refs?
Zhi Huang
2017/08/29 18:40:35
Done.
| |
| 327 (source == CS_REMOTE) ? selected_params : answer_params[0]; | 125 (source == CS_REMOTE) ? selected_params : answer_params[0]; |
| 328 const CryptoParams& recv_params = | 126 CryptoParams new_recv_params = |
| 329 (source == CS_REMOTE) ? answer_params[0] : selected_params; | 127 (source == CS_REMOTE) ? answer_params[0] : selected_params; |
| 330 if (!ApplyParams(send_params, recv_params)) { | 128 if (!ParseSendParams(new_send_params) || !ParseRecvParams(new_recv_params)) { |
| 331 return false; | 129 return false; |
| 332 } | 130 } |
| 131 send_params_ = new_send_params; | |
| 132 recv_params_ = new_recv_params; | |
| 333 | 133 |
| 334 if (final) { | 134 if (final) { |
| 335 offer_params_.clear(); | 135 offer_params_.clear(); |
| 336 state_ = ST_ACTIVE; | 136 state_ = ST_ACTIVE; |
| 337 } else { | 137 } else { |
| 338 state_ = | 138 state_ = |
| 339 (source == CS_LOCAL) ? ST_SENTPRANSWER : ST_RECEIVEDPRANSWER; | 139 (source == CS_LOCAL) ? ST_SENTPRANSWER : ST_RECEIVEDPRANSWER; |
| 340 } | 140 } |
| 341 return true; | 141 return true; |
| 342 } | 142 } |
| 343 | 143 |
| 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, | 144 bool SrtpFilter::NegotiateParams(const std::vector<CryptoParams>& answer_params, |
| 356 CryptoParams* selected_params) { | 145 CryptoParams* selected_params) { |
| 357 // We're processing an accept. We should have exactly one set of params, | 146 // 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. | 147 // 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()); | 148 bool ret = (answer_params.size() == 1U && !offer_params_.empty()); |
| 360 if (ret) { | 149 if (ret) { |
| 361 // We should find a match between the answer params and the offered params. | 150 // We should find a match between the answer params and the offered params. |
| 362 std::vector<CryptoParams>::const_iterator it; | 151 std::vector<CryptoParams>::const_iterator it; |
| 363 for (it = offer_params_.begin(); it != offer_params_.end(); ++it) { | 152 for (it = offer_params_.begin(); it != offer_params_.end(); ++it) { |
| 364 if (answer_params[0].Matches(*it)) { | 153 if (answer_params[0].Matches(*it)) { |
| 365 break; | 154 break; |
| 366 } | 155 } |
| 367 } | 156 } |
| 368 | 157 |
| 369 if (it != offer_params_.end()) { | 158 if (it != offer_params_.end()) { |
| 370 *selected_params = *it; | 159 *selected_params = *it; |
| 371 } else { | 160 } else { |
| 372 ret = false; | 161 ret = false; |
| 373 } | 162 } |
| 374 } | 163 } |
| 375 | 164 |
| 376 if (!ret) { | 165 if (!ret) { |
| 377 LOG(LS_WARNING) << "Invalid parameters in SRTP answer"; | 166 LOG(LS_WARNING) << "Invalid parameters in SRTP answer"; |
| 378 } | 167 } |
| 379 return ret; | 168 return ret; |
| 380 } | 169 } |
| 381 | 170 |
| 382 bool SrtpFilter::ApplyParams(const CryptoParams& send_params, | 171 bool SrtpFilter::ResetParams() { |
| 383 const CryptoParams& recv_params) { | 172 offer_params_.clear(); |
| 384 // TODO(jiayl): Split this method to apply send and receive CryptoParams | 173 send_params_ = CryptoParams(); |
| 385 // independently, so that we can skip one method when either send or receive | 174 recv_params_ = CryptoParams(); |
| 386 // CryptoParams is unchanged. | 175 send_cipher_suite_ = rtc::Optional<int>(); |
| 387 if (applied_send_params_.cipher_suite == send_params.cipher_suite && | 176 recv_cipher_suite_ = rtc::Optional<int>(); |
| 388 applied_send_params_.key_params == send_params.key_params && | 177 send_key_.clear(); |
| 389 applied_recv_params_.cipher_suite == recv_params.cipher_suite && | 178 recv_key_.clear(); |
| 390 applied_recv_params_.key_params == recv_params.key_params) { | 179 state_ = ST_INIT; |
| 391 LOG(LS_INFO) << "Applying the same SRTP parameters again. No-op."; | 180 return true; |
| 181 } | |
| 182 | |
| 183 bool SrtpFilter::ParseSendParams(const CryptoParams& send_params) { | |
| 184 if (send_params_.cipher_suite == send_params.cipher_suite && | |
| 185 send_params_.key_params == send_params.key_params) { | |
| 186 LOG(LS_INFO) << "Applying the same SRTP send parameters again. No-op."; | |
| 392 | 187 |
| 393 // We do not want to reset the ROC if the keys are the same. So just return. | 188 // We do not want to reset the ROC if the keys are the same. So just return. |
| 394 return true; | 189 return true; |
| 395 } | 190 } |
| 396 | 191 |
| 397 int send_suite = rtc::SrtpCryptoSuiteFromName(send_params.cipher_suite); | 192 send_cipher_suite_ = rtc::Optional<int>( |
| 398 int recv_suite = rtc::SrtpCryptoSuiteFromName(recv_params.cipher_suite); | 193 rtc::SrtpCryptoSuiteFromName(send_params.cipher_suite)); |
| 399 if (send_suite == rtc::SRTP_INVALID_CRYPTO_SUITE || | 194 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:" | 195 LOG(LS_WARNING) << "Unknown crypto suite(s) received:" |
| 402 << " send cipher_suite " << send_params.cipher_suite | 196 << " send cipher_suite " << send_params.cipher_suite; |
| 197 return false; | |
| 198 } | |
| 199 | |
| 200 int send_key_len, send_salt_len; | |
| 201 if (!rtc::GetSrtpKeyAndSaltLengths(*send_cipher_suite_, &send_key_len, | |
| 202 &send_salt_len)) { | |
| 203 LOG(LS_WARNING) << "Could not get lengths for crypto suite(s):" | |
| 204 << " send cipher_suite " << send_params.cipher_suite; | |
| 205 return false; | |
| 206 } | |
| 207 | |
| 208 return ParseKeyParams(send_params.key_params, &send_key_, | |
| 209 send_key_len + send_salt_len); | |
| 210 } | |
| 211 | |
| 212 bool SrtpFilter::ParseRecvParams(const CryptoParams& recv_params) { | |
| 213 if (recv_params_.cipher_suite == recv_params.cipher_suite && | |
| 214 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 return ParseKeyParams(recv_params.key_params, &recv_key_, |
| 420 bool ret; | 238 recv_key_len + recv_salt_len); |
| 421 rtc::Buffer send_key(send_key_len + send_salt_len); | |
| 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 } | 239 } |
| 462 | 240 |
| 463 bool SrtpFilter::ParseKeyParams(const std::string& key_params, | 241 bool SrtpFilter::ParseKeyParams(const std::string& key_params, |
| 464 uint8_t* key, | 242 std::vector<unsigned char>* key, |
|
Taylor Brandstetter
2017/08/26 02:40:39
Could this be an rtc::Buffer like before, instead
Zhi Huang
2017/08/29 18:40:35
Done.
| |
| 465 size_t len) { | 243 size_t len) { |
| 466 // example key_params: "inline:YUJDZGVmZ2hpSktMbW9QUXJzVHVWd3l6MTIzNDU2" | 244 // example key_params: "inline:YUJDZGVmZ2hpSktMbW9QUXJzVHVWd3l6MTIzNDU2" |
| 467 | 245 |
| 468 // Fail if key-method is wrong. | 246 // Fail if key-method is wrong. |
| 469 if (key_params.find("inline:") != 0) { | 247 if (key_params.find("inline:") != 0) { |
| 470 return false; | 248 return false; |
| 471 } | 249 } |
| 472 | 250 |
| 473 // Fail if base64 decode fails, or the key is the wrong size. | 251 // Fail if base64 decode fails, or the key is the wrong size. |
| 474 std::string key_b64(key_params.substr(7)), key_str; | 252 std::string key_b64(key_params.substr(7)), key_str; |
| 475 if (!rtc::Base64::Decode(key_b64, rtc::Base64::DO_STRICT, | 253 if (!rtc::Base64::Decode(key_b64, rtc::Base64::DO_STRICT, &key_str, |
| 476 &key_str, nullptr) || key_str.size() != len) { | 254 nullptr) || |
| 255 key_str.size() != len) { | |
| 477 return false; | 256 return false; |
| 478 } | 257 } |
| 479 | 258 |
| 480 memcpy(key, key_str.c_str(), len); | 259 std::vector<unsigned char> temp_key(key_str.c_str(), key_str.c_str() + len); |
| 260 *key = temp_key; | |
| 481 return true; | 261 return true; |
| 482 } | 262 } |
| 483 | 263 |
| 484 } // namespace cricket | 264 } // namespace cricket |
| OLD | NEW |