Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright 2011 The WebRTC Project Authors. All rights reserved. | 2 * Copyright 2011 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 |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 172 LOG(LS_ERROR) << "Not changing max. protocol version " | 172 LOG(LS_ERROR) << "Not changing max. protocol version " |
| 173 << "while DTLS is negotiating"; | 173 << "while DTLS is negotiating"; |
| 174 return false; | 174 return false; |
| 175 } | 175 } |
| 176 | 176 |
| 177 ssl_max_version_ = version; | 177 ssl_max_version_ = version; |
| 178 return true; | 178 return true; |
| 179 } | 179 } |
| 180 | 180 |
| 181 bool DtlsTransportChannelWrapper::SetSslRole(rtc::SSLRole role) { | 181 bool DtlsTransportChannelWrapper::SetSslRole(rtc::SSLRole role) { |
| 182 if (dtls_state() == DTLS_TRANSPORT_CONNECTED) { | 182 if (dtls_) { |
| 183 if (ssl_role_ != role) { | 183 if (ssl_role_ != role) { |
| 184 LOG(LS_ERROR) << "SSL Role can't be reversed after the session is setup."; | 184 LOG(LS_ERROR) << "SSL Role can't be reversed after the session is setup."; |
| 185 return false; | 185 return false; |
| 186 } | 186 } |
| 187 return true; | 187 return true; |
| 188 } | 188 } |
| 189 | 189 |
| 190 ssl_role_ = role; | 190 ssl_role_ = role; |
| 191 return true; | 191 return true; |
| 192 } | 192 } |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 228 } | 228 } |
| 229 | 229 |
| 230 // Otherwise, we must have a local certificate before setting remote | 230 // Otherwise, we must have a local certificate before setting remote |
| 231 // fingerprint. | 231 // fingerprint. |
| 232 if (!dtls_active_) { | 232 if (!dtls_active_) { |
| 233 LOG_J(LS_ERROR, this) << "Can't set DTLS remote settings in this state."; | 233 LOG_J(LS_ERROR, this) << "Can't set DTLS remote settings in this state."; |
| 234 return false; | 234 return false; |
| 235 } | 235 } |
| 236 | 236 |
| 237 // At this point we know we are doing DTLS | 237 // At this point we know we are doing DTLS |
| 238 bool fingerprint_changing = remote_fingerprint_value_.size() > 0u; | |
| 238 remote_fingerprint_value_ = std::move(remote_fingerprint_value); | 239 remote_fingerprint_value_ = std::move(remote_fingerprint_value); |
| 239 remote_fingerprint_algorithm_ = digest_alg; | 240 remote_fingerprint_algorithm_ = digest_alg; |
| 240 | 241 |
| 241 if (dtls_) { | 242 // If the fingerprint is changing, start a completely new DTLS association. |
| 243 if (dtls_ && fingerprint_changing) { | |
| 242 // If the fingerprint is changing, we'll tear down the DTLS association and | 244 // If the fingerprint is changing, we'll tear down the DTLS association and |
| 243 // create a new one, resetting our state. | 245 // create a new one, resetting our state. |
| 244 dtls_.reset(nullptr); | 246 dtls_.reset(nullptr); |
| 245 set_dtls_state(DTLS_TRANSPORT_NEW); | 247 set_dtls_state(DTLS_TRANSPORT_NEW); |
| 246 set_writable(false); | 248 set_writable(false); |
| 247 } | 249 } |
| 248 | 250 |
| 249 if (!SetupDtls()) { | 251 if (dtls_) { |
| 250 set_dtls_state(DTLS_TRANSPORT_FAILED); | 252 // This can occur if DTLS is set up before a remote fingerprint is |
| 251 return false; | 253 // received. For instance, if we set up DTLS due to receiving an early |
| 254 // ClientHello. | |
| 255 if (!dtls_->SetPeerCertificateDigest( | |
| 256 remote_fingerprint_algorithm_, | |
| 257 reinterpret_cast<unsigned char*>(remote_fingerprint_value_.data()), | |
| 258 remote_fingerprint_value_.size())) { | |
| 259 LOG_J(LS_ERROR, this) << "Couldn't set DTLS certificate digest."; | |
| 260 set_dtls_state(DTLS_TRANSPORT_FAILED); | |
| 261 return false; | |
| 262 } | |
| 263 } else { | |
| 264 if (!SetupDtls()) { | |
| 265 set_dtls_state(DTLS_TRANSPORT_FAILED); | |
| 266 return false; | |
| 267 } | |
| 252 } | 268 } |
|
pthatcher1
2016/07/27 19:32:35
Would this be more clear as this flow?
if (dtls_
Taylor Brandstetter
2016/08/13 00:09:53
Done.
| |
| 253 | 269 |
| 254 return true; | 270 return true; |
| 255 } | 271 } |
| 256 | 272 |
| 257 std::unique_ptr<rtc::SSLCertificate> | 273 std::unique_ptr<rtc::SSLCertificate> |
| 258 DtlsTransportChannelWrapper::GetRemoteSSLCertificate() const { | 274 DtlsTransportChannelWrapper::GetRemoteSSLCertificate() const { |
| 259 if (!dtls_) { | 275 if (!dtls_) { |
| 260 return nullptr; | 276 return nullptr; |
| 261 } | 277 } |
| 262 | 278 |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 273 return false; | 289 return false; |
| 274 } | 290 } |
| 275 | 291 |
| 276 downward_ = downward; | 292 downward_ = downward; |
| 277 | 293 |
| 278 dtls_->SetIdentity(local_certificate_->identity()->GetReference()); | 294 dtls_->SetIdentity(local_certificate_->identity()->GetReference()); |
| 279 dtls_->SetMode(rtc::SSL_MODE_DTLS); | 295 dtls_->SetMode(rtc::SSL_MODE_DTLS); |
| 280 dtls_->SetMaxProtocolVersion(ssl_max_version_); | 296 dtls_->SetMaxProtocolVersion(ssl_max_version_); |
| 281 dtls_->SetServerRole(ssl_role_); | 297 dtls_->SetServerRole(ssl_role_); |
| 282 dtls_->SignalEvent.connect(this, &DtlsTransportChannelWrapper::OnDtlsEvent); | 298 dtls_->SignalEvent.connect(this, &DtlsTransportChannelWrapper::OnDtlsEvent); |
| 283 if (!dtls_->SetPeerCertificateDigest( | 299 if (remote_fingerprint_value_.size() && |
| 300 !dtls_->SetPeerCertificateDigest( | |
| 284 remote_fingerprint_algorithm_, | 301 remote_fingerprint_algorithm_, |
| 285 reinterpret_cast<unsigned char*>(remote_fingerprint_value_.data()), | 302 reinterpret_cast<unsigned char*>(remote_fingerprint_value_.data()), |
| 286 remote_fingerprint_value_.size())) { | 303 remote_fingerprint_value_.size())) { |
| 287 LOG_J(LS_ERROR, this) << "Couldn't set DTLS certificate digest."; | 304 LOG_J(LS_ERROR, this) << "Couldn't set DTLS certificate digest."; |
| 288 return false; | 305 return false; |
| 289 } | 306 } |
| 290 | 307 |
| 291 // Set up DTLS-SRTP, if it's been enabled. | 308 // Set up DTLS-SRTP, if it's been enabled. |
| 292 if (!srtp_ciphers_.empty()) { | 309 if (!srtp_ciphers_.empty()) { |
| 293 if (!dtls_->SetDtlsSrtpCryptoSuites(srtp_ciphers_)) { | 310 if (!dtls_->SetDtlsSrtpCryptoSuites(srtp_ciphers_)) { |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 392 case DTLS_TRANSPORT_FAILED: | 409 case DTLS_TRANSPORT_FAILED: |
| 393 case DTLS_TRANSPORT_CLOSED: | 410 case DTLS_TRANSPORT_CLOSED: |
| 394 // Can't send anything when we're closed. | 411 // Can't send anything when we're closed. |
| 395 return -1; | 412 return -1; |
| 396 default: | 413 default: |
| 397 ASSERT(false); | 414 ASSERT(false); |
| 398 return -1; | 415 return -1; |
| 399 } | 416 } |
| 400 } | 417 } |
| 401 | 418 |
| 419 bool DtlsTransportChannelWrapper::IsDtlsConnected() { | |
| 420 return dtls_ && dtls_->IsTlsConnected(); | |
| 421 } | |
| 422 | |
| 402 // The state transition logic here is as follows: | 423 // The state transition logic here is as follows: |
| 403 // (1) If we're not doing DTLS-SRTP, then the state is just the | 424 // (1) If we're not doing DTLS-SRTP, then the state is just the |
| 404 // state of the underlying impl() | 425 // state of the underlying impl() |
| 405 // (2) If we're doing DTLS-SRTP: | 426 // (2) If we're doing DTLS-SRTP: |
| 406 // - Prior to the DTLS handshake, the state is neither receiving nor | 427 // - Prior to the DTLS handshake, the state is neither receiving nor |
| 407 // writable | 428 // writable |
| 408 // - When the impl goes writable for the first time we | 429 // - When the impl goes writable for the first time we |
| 409 // start the DTLS handshake | 430 // start the DTLS handshake |
| 410 // - Once the DTLS handshake completes, the state is that of the | 431 // - Once the DTLS handshake completes, the state is that of the |
| 411 // impl again | 432 // impl again |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 472 LOG_J(LS_INFO, this) << "Packet received before DTLS started."; | 493 LOG_J(LS_INFO, this) << "Packet received before DTLS started."; |
| 473 } else { | 494 } else { |
| 474 LOG_J(LS_WARNING, this) << "Packet received before we know if we are " | 495 LOG_J(LS_WARNING, this) << "Packet received before we know if we are " |
| 475 << "doing DTLS or not."; | 496 << "doing DTLS or not."; |
| 476 } | 497 } |
| 477 // Cache a client hello packet received before DTLS has actually started. | 498 // Cache a client hello packet received before DTLS has actually started. |
| 478 if (IsDtlsClientHelloPacket(data, size)) { | 499 if (IsDtlsClientHelloPacket(data, size)) { |
| 479 LOG_J(LS_INFO, this) << "Caching DTLS ClientHello packet until DTLS is " | 500 LOG_J(LS_INFO, this) << "Caching DTLS ClientHello packet until DTLS is " |
| 480 << "started."; | 501 << "started."; |
| 481 cached_client_hello_.SetData(data, size); | 502 cached_client_hello_.SetData(data, size); |
| 503 // If we haven't started setting up DTLS yet (because we don't have a | |
| 504 // remote fingerprint/role), we can use the client hello as a clue that | |
| 505 // the peer has chosen the client role, and proceed with the handshake. | |
| 506 // The fingerprint will be verified when it's set. | |
| 507 if (!dtls_ && local_certificate_) { | |
| 508 SetSslRole(rtc::SSL_SERVER); | |
| 509 SetupDtls(); | |
| 510 } | |
| 482 } else { | 511 } else { |
| 483 LOG_J(LS_INFO, this) << "Not a DTLS ClientHello packet; dropping."; | 512 LOG_J(LS_INFO, this) << "Not a DTLS ClientHello packet; dropping."; |
| 484 } | 513 } |
| 485 break; | 514 break; |
| 486 | 515 |
| 487 case DTLS_TRANSPORT_CONNECTING: | 516 case DTLS_TRANSPORT_CONNECTING: |
| 488 case DTLS_TRANSPORT_CONNECTED: | 517 case DTLS_TRANSPORT_CONNECTED: |
| 489 // We should only get DTLS or SRTP packets; STUN's already been demuxed. | 518 // We should only get DTLS or SRTP packets; STUN's already been demuxed. |
| 490 // Is this potentially a DTLS packet? | 519 // Is this potentially a DTLS packet? |
| 491 if (IsDtlsPacket(data, size)) { | 520 if (IsDtlsPacket(data, size)) { |
| (...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 670 last_sent_packet_id, ready_to_send); | 699 last_sent_packet_id, ready_to_send); |
| 671 } | 700 } |
| 672 | 701 |
| 673 void DtlsTransportChannelWrapper::OnChannelStateChanged( | 702 void DtlsTransportChannelWrapper::OnChannelStateChanged( |
| 674 TransportChannelImpl* channel) { | 703 TransportChannelImpl* channel) { |
| 675 ASSERT(channel == channel_); | 704 ASSERT(channel == channel_); |
| 676 SignalStateChanged(this); | 705 SignalStateChanged(this); |
| 677 } | 706 } |
| 678 | 707 |
| 679 } // namespace cricket | 708 } // namespace cricket |
| OLD | NEW |