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