| 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_) { | 182 if (dtls_state() == DTLS_TRANSPORT_CONNECTED) { |
| 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; | |
| 239 remote_fingerprint_value_ = std::move(remote_fingerprint_value); | 238 remote_fingerprint_value_ = std::move(remote_fingerprint_value); |
| 240 remote_fingerprint_algorithm_ = digest_alg; | 239 remote_fingerprint_algorithm_ = digest_alg; |
| 241 | 240 |
| 242 if (dtls_ && !fingerprint_changing) { | 241 if (dtls_) { |
| 243 // This can occur if DTLS is set up before a remote fingerprint is | 242 // If the fingerprint is changing, we'll tear down the DTLS association and |
| 244 // received. For instance, if we set up DTLS due to receiving an early | 243 // create a new one, resetting our state. |
| 245 // ClientHello. | |
| 246 auto err = dtls_->SetPeerCertificateDigest( | |
| 247 remote_fingerprint_algorithm_, | |
| 248 reinterpret_cast<unsigned char*>(remote_fingerprint_value_.data()), | |
| 249 remote_fingerprint_value_.size()); | |
| 250 if (err != rtc::SSLPeerCertificateDigestError::NONE) { | |
| 251 LOG_J(LS_ERROR, this) << "Couldn't set DTLS certificate digest."; | |
| 252 set_dtls_state(DTLS_TRANSPORT_FAILED); | |
| 253 // If the error is "verification failed", don't return false, because | |
| 254 // this means the fingerprint was formatted correctly but didn't match | |
| 255 // the certificate from the DTLS handshake. Thus the DTLS state should go | |
| 256 // to "failed", but SetRemoteDescription shouldn't fail. | |
| 257 return err == rtc::SSLPeerCertificateDigestError::VERIFICATION_FAILED; | |
| 258 } | |
| 259 return true; | |
| 260 } | |
| 261 | |
| 262 // If the fingerprint is changing, we'll tear down the DTLS association and | |
| 263 // create a new one, resetting our state. | |
| 264 if (dtls_ && fingerprint_changing) { | |
| 265 dtls_.reset(nullptr); | 244 dtls_.reset(nullptr); |
| 266 set_dtls_state(DTLS_TRANSPORT_NEW); | 245 set_dtls_state(DTLS_TRANSPORT_NEW); |
| 267 set_writable(false); | 246 set_writable(false); |
| 268 } | 247 } |
| 269 | 248 |
| 270 if (!SetupDtls()) { | 249 if (!SetupDtls()) { |
| 271 set_dtls_state(DTLS_TRANSPORT_FAILED); | 250 set_dtls_state(DTLS_TRANSPORT_FAILED); |
| 272 return false; | 251 return false; |
| 273 } | 252 } |
| 274 | 253 |
| (...skipping 21 matching lines...) Expand all Loading... |
| 296 | 275 |
| 297 downward_ = downward; | 276 downward_ = downward; |
| 298 | 277 |
| 299 dtls_->SetIdentity(local_certificate_->identity()->GetReference()); | 278 dtls_->SetIdentity(local_certificate_->identity()->GetReference()); |
| 300 dtls_->SetMode(rtc::SSL_MODE_DTLS); | 279 dtls_->SetMode(rtc::SSL_MODE_DTLS); |
| 301 dtls_->SetMaxProtocolVersion(ssl_max_version_); | 280 dtls_->SetMaxProtocolVersion(ssl_max_version_); |
| 302 dtls_->SetServerRole(ssl_role_); | 281 dtls_->SetServerRole(ssl_role_); |
| 303 dtls_->SignalEvent.connect(this, &DtlsTransportChannelWrapper::OnDtlsEvent); | 282 dtls_->SignalEvent.connect(this, &DtlsTransportChannelWrapper::OnDtlsEvent); |
| 304 dtls_->SignalSSLHandshakeError.connect( | 283 dtls_->SignalSSLHandshakeError.connect( |
| 305 this, &DtlsTransportChannelWrapper::OnDtlsHandshakeError); | 284 this, &DtlsTransportChannelWrapper::OnDtlsHandshakeError); |
| 306 if (remote_fingerprint_value_.size() && | 285 if (!dtls_->SetPeerCertificateDigest( |
| 307 dtls_->SetPeerCertificateDigest( | |
| 308 remote_fingerprint_algorithm_, | 286 remote_fingerprint_algorithm_, |
| 309 reinterpret_cast<unsigned char*>(remote_fingerprint_value_.data()), | 287 reinterpret_cast<unsigned char*>(remote_fingerprint_value_.data()), |
| 310 remote_fingerprint_value_.size()) != | 288 remote_fingerprint_value_.size())) { |
| 311 rtc::SSLPeerCertificateDigestError::NONE) { | |
| 312 LOG_J(LS_ERROR, this) << "Couldn't set DTLS certificate digest."; | 289 LOG_J(LS_ERROR, this) << "Couldn't set DTLS certificate digest."; |
| 313 return false; | 290 return false; |
| 314 } | 291 } |
| 315 | 292 |
| 316 // Set up DTLS-SRTP, if it's been enabled. | 293 // Set up DTLS-SRTP, if it's been enabled. |
| 317 if (!srtp_ciphers_.empty()) { | 294 if (!srtp_ciphers_.empty()) { |
| 318 if (!dtls_->SetDtlsSrtpCryptoSuites(srtp_ciphers_)) { | 295 if (!dtls_->SetDtlsSrtpCryptoSuites(srtp_ciphers_)) { |
| 319 LOG_J(LS_ERROR, this) << "Couldn't set DTLS-SRTP ciphers."; | 296 LOG_J(LS_ERROR, this) << "Couldn't set DTLS-SRTP ciphers."; |
| 320 return false; | 297 return false; |
| 321 } | 298 } |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 417 case DTLS_TRANSPORT_FAILED: | 394 case DTLS_TRANSPORT_FAILED: |
| 418 case DTLS_TRANSPORT_CLOSED: | 395 case DTLS_TRANSPORT_CLOSED: |
| 419 // Can't send anything when we're closed. | 396 // Can't send anything when we're closed. |
| 420 return -1; | 397 return -1; |
| 421 default: | 398 default: |
| 422 ASSERT(false); | 399 ASSERT(false); |
| 423 return -1; | 400 return -1; |
| 424 } | 401 } |
| 425 } | 402 } |
| 426 | 403 |
| 427 bool DtlsTransportChannelWrapper::IsDtlsConnected() { | |
| 428 return dtls_ && dtls_->IsTlsConnected(); | |
| 429 } | |
| 430 | |
| 431 // The state transition logic here is as follows: | 404 // The state transition logic here is as follows: |
| 432 // (1) If we're not doing DTLS-SRTP, then the state is just the | 405 // (1) If we're not doing DTLS-SRTP, then the state is just the |
| 433 // state of the underlying impl() | 406 // state of the underlying impl() |
| 434 // (2) If we're doing DTLS-SRTP: | 407 // (2) If we're doing DTLS-SRTP: |
| 435 // - Prior to the DTLS handshake, the state is neither receiving nor | 408 // - Prior to the DTLS handshake, the state is neither receiving nor |
| 436 // writable | 409 // writable |
| 437 // - When the impl goes writable for the first time we | 410 // - When the impl goes writable for the first time we |
| 438 // start the DTLS handshake | 411 // start the DTLS handshake |
| 439 // - Once the DTLS handshake completes, the state is that of the | 412 // - Once the DTLS handshake completes, the state is that of the |
| 440 // impl again | 413 // impl again |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 501 LOG_J(LS_INFO, this) << "Packet received before DTLS started."; | 474 LOG_J(LS_INFO, this) << "Packet received before DTLS started."; |
| 502 } else { | 475 } else { |
| 503 LOG_J(LS_WARNING, this) << "Packet received before we know if we are " | 476 LOG_J(LS_WARNING, this) << "Packet received before we know if we are " |
| 504 << "doing DTLS or not."; | 477 << "doing DTLS or not."; |
| 505 } | 478 } |
| 506 // Cache a client hello packet received before DTLS has actually started. | 479 // Cache a client hello packet received before DTLS has actually started. |
| 507 if (IsDtlsClientHelloPacket(data, size)) { | 480 if (IsDtlsClientHelloPacket(data, size)) { |
| 508 LOG_J(LS_INFO, this) << "Caching DTLS ClientHello packet until DTLS is " | 481 LOG_J(LS_INFO, this) << "Caching DTLS ClientHello packet until DTLS is " |
| 509 << "started."; | 482 << "started."; |
| 510 cached_client_hello_.SetData(data, size); | 483 cached_client_hello_.SetData(data, size); |
| 511 // If we haven't started setting up DTLS yet (because we don't have a | |
| 512 // remote fingerprint/role), we can use the client hello as a clue that | |
| 513 // the peer has chosen the client role, and proceed with the handshake. | |
| 514 // The fingerprint will be verified when it's set. | |
| 515 if (!dtls_ && local_certificate_) { | |
| 516 SetSslRole(rtc::SSL_SERVER); | |
| 517 SetupDtls(); | |
| 518 } | |
| 519 } else { | 484 } else { |
| 520 LOG_J(LS_INFO, this) << "Not a DTLS ClientHello packet; dropping."; | 485 LOG_J(LS_INFO, this) << "Not a DTLS ClientHello packet; dropping."; |
| 521 } | 486 } |
| 522 break; | 487 break; |
| 523 | 488 |
| 524 case DTLS_TRANSPORT_CONNECTING: | 489 case DTLS_TRANSPORT_CONNECTING: |
| 525 case DTLS_TRANSPORT_CONNECTED: | 490 case DTLS_TRANSPORT_CONNECTED: |
| 526 // We should only get DTLS or SRTP packets; STUN's already been demuxed. | 491 // We should only get DTLS or SRTP packets; STUN's already been demuxed. |
| 527 // Is this potentially a DTLS packet? | 492 // Is this potentially a DTLS packet? |
| 528 if (IsDtlsPacket(data, size)) { | 493 if (IsDtlsPacket(data, size)) { |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 582 if (dtls_->GetState() == rtc::SS_OPEN) { | 547 if (dtls_->GetState() == rtc::SS_OPEN) { |
| 583 // The check for OPEN shouldn't be necessary but let's make | 548 // The check for OPEN shouldn't be necessary but let's make |
| 584 // sure we don't accidentally frob the state if it's closed. | 549 // sure we don't accidentally frob the state if it's closed. |
| 585 set_dtls_state(DTLS_TRANSPORT_CONNECTED); | 550 set_dtls_state(DTLS_TRANSPORT_CONNECTED); |
| 586 set_writable(true); | 551 set_writable(true); |
| 587 } | 552 } |
| 588 } | 553 } |
| 589 if (sig & rtc::SE_READ) { | 554 if (sig & rtc::SE_READ) { |
| 590 char buf[kMaxDtlsPacketLen]; | 555 char buf[kMaxDtlsPacketLen]; |
| 591 size_t read; | 556 size_t read; |
| 592 int read_error; | 557 if (dtls_->Read(buf, sizeof(buf), &read, NULL) == rtc::SR_SUCCESS) { |
| 593 rtc::StreamResult ret = dtls_->Read(buf, sizeof(buf), &read, &read_error); | |
| 594 if (ret == rtc::SR_SUCCESS) { | |
| 595 SignalReadPacket(this, buf, read, rtc::CreatePacketTime(0), 0); | 558 SignalReadPacket(this, buf, read, rtc::CreatePacketTime(0), 0); |
| 596 } else if (ret == rtc::SR_EOS) { | |
| 597 // Remote peer shut down the association with no error. | |
| 598 LOG_J(LS_INFO, this) << "DTLS channel closed"; | |
| 599 set_writable(false); | |
| 600 set_dtls_state(DTLS_TRANSPORT_CLOSED); | |
| 601 } else if (ret == rtc::SR_ERROR) { | |
| 602 // Remote peer shut down the association with an error. | |
| 603 LOG_J(LS_INFO, this) << "DTLS channel error, code=" << read_error; | |
| 604 set_writable(false); | |
| 605 set_dtls_state(DTLS_TRANSPORT_FAILED); | |
| 606 } | 559 } |
| 607 } | 560 } |
| 608 if (sig & rtc::SE_CLOSE) { | 561 if (sig & rtc::SE_CLOSE) { |
| 609 ASSERT(sig == rtc::SE_CLOSE); // SE_CLOSE should be by itself. | 562 ASSERT(sig == rtc::SE_CLOSE); // SE_CLOSE should be by itself. |
| 610 set_writable(false); | 563 set_writable(false); |
| 611 if (!err) { | 564 if (!err) { |
| 612 LOG_J(LS_INFO, this) << "DTLS channel closed"; | 565 LOG_J(LS_INFO, this) << "DTLS channel closed"; |
| 613 set_dtls_state(DTLS_TRANSPORT_CLOSED); | 566 set_dtls_state(DTLS_TRANSPORT_CLOSED); |
| 614 } else { | 567 } else { |
| 615 LOG_J(LS_INFO, this) << "DTLS channel error, code=" << err; | 568 LOG_J(LS_INFO, this) << "DTLS channel error, code=" << err; |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 724 ASSERT(channel == channel_); | 677 ASSERT(channel == channel_); |
| 725 SignalStateChanged(this); | 678 SignalStateChanged(this); |
| 726 } | 679 } |
| 727 | 680 |
| 728 void DtlsTransportChannelWrapper::OnDtlsHandshakeError( | 681 void DtlsTransportChannelWrapper::OnDtlsHandshakeError( |
| 729 rtc::SSLHandshakeError error) { | 682 rtc::SSLHandshakeError error) { |
| 730 SignalDtlsHandshakeError(error); | 683 SignalDtlsHandshakeError(error); |
| 731 } | 684 } |
| 732 | 685 |
| 733 } // namespace cricket | 686 } // namespace cricket |
| OLD | NEW |