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

Side by Side Diff: webrtc/p2p/base/dtlstransportchannel.cc

Issue 2352863003: Revert of Allow the DTLS fingerprint verification to occur after the handshake. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Created 4 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
OLDNEW
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « webrtc/p2p/base/dtlstransportchannel.h ('k') | webrtc/p2p/base/dtlstransportchannel_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698