| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2013 The WebRTC project authors. All Rights Reserved. | 2 * Copyright 2013 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/api/webrtcsessiondescriptionfactory.h" | 11 #include "webrtc/api/webrtcsessiondescriptionfactory.h" |
| 12 | 12 |
| 13 #include <utility> | 13 #include <utility> |
| 14 | 14 |
| 15 #include "webrtc/api/dtlsidentitystore.h" | |
| 16 #include "webrtc/api/jsep.h" | 15 #include "webrtc/api/jsep.h" |
| 17 #include "webrtc/api/jsepsessiondescription.h" | 16 #include "webrtc/api/jsepsessiondescription.h" |
| 18 #include "webrtc/api/mediaconstraintsinterface.h" | 17 #include "webrtc/api/mediaconstraintsinterface.h" |
| 19 #include "webrtc/api/webrtcsession.h" | 18 #include "webrtc/api/webrtcsession.h" |
| 20 #include "webrtc/base/sslidentity.h" | 19 #include "webrtc/base/sslidentity.h" |
| 21 | 20 |
| 22 using cricket::MediaSessionOptions; | 21 using cricket::MediaSessionOptions; |
| 23 | 22 |
| 24 namespace webrtc { | 23 namespace webrtc { |
| 25 namespace { | 24 namespace { |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 61 webrtc::CreateSessionDescriptionObserver* observer) | 60 webrtc::CreateSessionDescriptionObserver* observer) |
| 62 : observer(observer) { | 61 : observer(observer) { |
| 63 } | 62 } |
| 64 | 63 |
| 65 rtc::scoped_refptr<webrtc::CreateSessionDescriptionObserver> observer; | 64 rtc::scoped_refptr<webrtc::CreateSessionDescriptionObserver> observer; |
| 66 std::string error; | 65 std::string error; |
| 67 std::unique_ptr<webrtc::SessionDescriptionInterface> description; | 66 std::unique_ptr<webrtc::SessionDescriptionInterface> description; |
| 68 }; | 67 }; |
| 69 } // namespace | 68 } // namespace |
| 70 | 69 |
| 71 void WebRtcIdentityRequestObserver::OnFailure(int error) { | 70 void WebRtcCertificateGeneratorCallback::OnFailure() { |
| 72 SignalRequestFailed(error); | 71 SignalRequestFailed(); |
| 73 } | 72 } |
| 74 | 73 |
| 75 void WebRtcIdentityRequestObserver::OnSuccess( | 74 void WebRtcCertificateGeneratorCallback::OnSuccess( |
| 76 const std::string& der_cert, const std::string& der_private_key) { | 75 const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) { |
| 77 std::string pem_cert = rtc::SSLIdentity::DerToPem( | 76 SignalCertificateReady(certificate); |
| 78 rtc::kPemTypeCertificate, | |
| 79 reinterpret_cast<const unsigned char*>(der_cert.data()), | |
| 80 der_cert.length()); | |
| 81 std::string pem_key = rtc::SSLIdentity::DerToPem( | |
| 82 rtc::kPemTypeRsaPrivateKey, | |
| 83 reinterpret_cast<const unsigned char*>(der_private_key.data()), | |
| 84 der_private_key.length()); | |
| 85 std::unique_ptr<rtc::SSLIdentity> identity( | |
| 86 rtc::SSLIdentity::FromPEMStrings(pem_key, pem_cert)); | |
| 87 SignalCertificateReady(rtc::RTCCertificate::Create(std::move(identity))); | |
| 88 } | |
| 89 | |
| 90 void WebRtcIdentityRequestObserver::OnSuccess( | |
| 91 std::unique_ptr<rtc::SSLIdentity> identity) { | |
| 92 SignalCertificateReady(rtc::RTCCertificate::Create(std::move(identity))); | |
| 93 } | 77 } |
| 94 | 78 |
| 95 // static | 79 // static |
| 96 void WebRtcSessionDescriptionFactory::CopyCandidatesFromSessionDescription( | 80 void WebRtcSessionDescriptionFactory::CopyCandidatesFromSessionDescription( |
| 97 const SessionDescriptionInterface* source_desc, | 81 const SessionDescriptionInterface* source_desc, |
| 98 const std::string& content_name, | 82 const std::string& content_name, |
| 99 SessionDescriptionInterface* dest_desc) { | 83 SessionDescriptionInterface* dest_desc) { |
| 100 if (!source_desc) { | 84 if (!source_desc) { |
| 101 return; | 85 return; |
| 102 } | 86 } |
| (...skipping 17 matching lines...) Expand all Loading... |
| 120 if (!dest_candidates->HasCandidate(new_candidate)) { | 104 if (!dest_candidates->HasCandidate(new_candidate)) { |
| 121 dest_desc->AddCandidate(source_candidates->at(n)); | 105 dest_desc->AddCandidate(source_candidates->at(n)); |
| 122 } | 106 } |
| 123 } | 107 } |
| 124 } | 108 } |
| 125 | 109 |
| 126 // Private constructor called by other constructors. | 110 // Private constructor called by other constructors. |
| 127 WebRtcSessionDescriptionFactory::WebRtcSessionDescriptionFactory( | 111 WebRtcSessionDescriptionFactory::WebRtcSessionDescriptionFactory( |
| 128 rtc::Thread* signaling_thread, | 112 rtc::Thread* signaling_thread, |
| 129 cricket::ChannelManager* channel_manager, | 113 cricket::ChannelManager* channel_manager, |
| 130 std::unique_ptr<DtlsIdentityStoreInterface> dtls_identity_store, | |
| 131 const rtc::scoped_refptr<WebRtcIdentityRequestObserver>& | |
| 132 identity_request_observer, | |
| 133 WebRtcSession* session, | 114 WebRtcSession* session, |
| 134 const std::string& session_id, | 115 const std::string& session_id, |
| 135 bool dtls_enabled) | 116 std::unique_ptr<rtc::RTCCertificateGeneratorInterface> cert_generator, |
| 117 const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) |
| 136 : signaling_thread_(signaling_thread), | 118 : signaling_thread_(signaling_thread), |
| 137 session_desc_factory_(channel_manager, &transport_desc_factory_), | 119 session_desc_factory_(channel_manager, &transport_desc_factory_), |
| 138 // RFC 4566 suggested a Network Time Protocol (NTP) format timestamp | 120 // RFC 4566 suggested a Network Time Protocol (NTP) format timestamp |
| 139 // as the session id and session version. To simplify, it should be fine | 121 // as the session id and session version. To simplify, it should be fine |
| 140 // to just use a random number as session id and start version from | 122 // to just use a random number as session id and start version from |
| 141 // |kInitSessionVersion|. | 123 // |kInitSessionVersion|. |
| 142 session_version_(kInitSessionVersion), | 124 session_version_(kInitSessionVersion), |
| 143 dtls_identity_store_(std::move(dtls_identity_store)), | 125 cert_generator_(std::move(cert_generator)), |
| 144 identity_request_observer_(identity_request_observer), | |
| 145 session_(session), | 126 session_(session), |
| 146 session_id_(session_id), | 127 session_id_(session_id), |
| 147 certificate_request_state_(CERTIFICATE_NOT_NEEDED) { | 128 certificate_request_state_(CERTIFICATE_NOT_NEEDED) { |
| 129 RTC_DCHECK(signaling_thread_); |
| 148 session_desc_factory_.set_add_legacy_streams(false); | 130 session_desc_factory_.set_add_legacy_streams(false); |
| 131 bool dtls_enabled = cert_generator_ || certificate; |
| 149 // SRTP-SDES is disabled if DTLS is on. | 132 // SRTP-SDES is disabled if DTLS is on. |
| 150 SetSdesPolicy(dtls_enabled ? cricket::SEC_DISABLED : cricket::SEC_REQUIRED); | 133 SetSdesPolicy(dtls_enabled ? cricket::SEC_DISABLED : cricket::SEC_REQUIRED); |
| 134 if (!dtls_enabled) { |
| 135 LOG(LS_VERBOSE) << "DTLS-SRTP disabled."; |
| 136 return; |
| 137 } |
| 138 |
| 139 if (certificate) { |
| 140 // Use |certificate|. |
| 141 certificate_request_state_ = CERTIFICATE_WAITING; |
| 142 |
| 143 LOG(LS_VERBOSE) << "DTLS-SRTP enabled; has certificate parameter."; |
| 144 // We already have a certificate but we wait to do |SetIdentity|; if we do |
| 145 // it in the constructor then the caller has not had a chance to connect to |
| 146 // |SignalCertificateReady|. |
| 147 signaling_thread_->Post( |
| 148 this, MSG_USE_CONSTRUCTOR_CERTIFICATE, |
| 149 new rtc::ScopedRefMessageData<rtc::RTCCertificate>(certificate)); |
| 150 } else { |
| 151 // Generate certificate. |
| 152 certificate_request_state_ = CERTIFICATE_WAITING; |
| 153 |
| 154 rtc::scoped_refptr<WebRtcCertificateGeneratorCallback> callback( |
| 155 new rtc::RefCountedObject<WebRtcCertificateGeneratorCallback>()); |
| 156 callback->SignalRequestFailed.connect( |
| 157 this, &WebRtcSessionDescriptionFactory::OnCertificateRequestFailed); |
| 158 callback->SignalCertificateReady.connect( |
| 159 this, &WebRtcSessionDescriptionFactory::SetCertificate); |
| 160 |
| 161 rtc::KeyParams key_params = rtc::KeyParams(); |
| 162 LOG(LS_VERBOSE) << "DTLS-SRTP enabled; sending DTLS identity request (key " |
| 163 << "type: " << key_params.type() << ")."; |
| 164 |
| 165 // Request certificate. This happens asynchronously, so that the caller gets |
| 166 // a chance to connect to |SignalCertificateReady|. |
| 167 cert_generator_->GenerateCertificateAsync( |
| 168 key_params, rtc::Optional<uint64_t>(), callback); |
| 169 } |
| 151 } | 170 } |
| 152 | 171 |
| 153 WebRtcSessionDescriptionFactory::WebRtcSessionDescriptionFactory( | 172 WebRtcSessionDescriptionFactory::WebRtcSessionDescriptionFactory( |
| 154 rtc::Thread* signaling_thread, | 173 rtc::Thread* signaling_thread, |
| 155 cricket::ChannelManager* channel_manager, | 174 cricket::ChannelManager* channel_manager, |
| 156 WebRtcSession* session, | 175 WebRtcSession* session, |
| 157 const std::string& session_id) | 176 const std::string& session_id, |
| 158 : WebRtcSessionDescriptionFactory(signaling_thread, | 177 std::unique_ptr<rtc::RTCCertificateGeneratorInterface> cert_generator) |
| 159 channel_manager, | 178 : WebRtcSessionDescriptionFactory( |
| 160 nullptr, | 179 signaling_thread, |
| 161 nullptr, | 180 channel_manager, |
| 162 session, | 181 session, |
| 163 session_id, | 182 session_id, |
| 164 false) { | 183 std::move(cert_generator), |
| 165 LOG(LS_VERBOSE) << "DTLS-SRTP disabled."; | 184 nullptr) { |
| 166 } | 185 } |
| 167 | 186 |
| 168 WebRtcSessionDescriptionFactory::WebRtcSessionDescriptionFactory( | 187 WebRtcSessionDescriptionFactory::WebRtcSessionDescriptionFactory( |
| 169 rtc::Thread* signaling_thread, | 188 rtc::Thread* signaling_thread, |
| 170 cricket::ChannelManager* channel_manager, | 189 cricket::ChannelManager* channel_manager, |
| 171 std::unique_ptr<DtlsIdentityStoreInterface> dtls_identity_store, | |
| 172 WebRtcSession* session, | 190 WebRtcSession* session, |
| 173 const std::string& session_id) | 191 const std::string& session_id, |
| 174 : WebRtcSessionDescriptionFactory( | 192 const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) |
| 175 signaling_thread, | |
| 176 channel_manager, | |
| 177 std::move(dtls_identity_store), | |
| 178 new rtc::RefCountedObject<WebRtcIdentityRequestObserver>(), | |
| 179 session, | |
| 180 session_id, | |
| 181 true) { | |
| 182 RTC_DCHECK(dtls_identity_store_); | |
| 183 | |
| 184 certificate_request_state_ = CERTIFICATE_WAITING; | |
| 185 | |
| 186 identity_request_observer_->SignalRequestFailed.connect( | |
| 187 this, &WebRtcSessionDescriptionFactory::OnIdentityRequestFailed); | |
| 188 identity_request_observer_->SignalCertificateReady.connect( | |
| 189 this, &WebRtcSessionDescriptionFactory::SetCertificate); | |
| 190 | |
| 191 rtc::KeyParams key_params = rtc::KeyParams(); | |
| 192 LOG(LS_VERBOSE) << "DTLS-SRTP enabled; sending DTLS identity request (key " | |
| 193 << "type: " << key_params.type() << ")."; | |
| 194 | |
| 195 // Request identity. This happens asynchronously, so the caller will have a | |
| 196 // chance to connect to SignalIdentityReady. | |
| 197 dtls_identity_store_->RequestIdentity(key_params, | |
| 198 rtc::Optional<uint64_t>(), | |
| 199 identity_request_observer_); | |
| 200 } | |
| 201 | |
| 202 WebRtcSessionDescriptionFactory::WebRtcSessionDescriptionFactory( | |
| 203 rtc::Thread* signaling_thread, | |
| 204 cricket::ChannelManager* channel_manager, | |
| 205 const rtc::scoped_refptr<rtc::RTCCertificate>& certificate, | |
| 206 WebRtcSession* session, | |
| 207 const std::string& session_id) | |
| 208 : WebRtcSessionDescriptionFactory(signaling_thread, | 193 : WebRtcSessionDescriptionFactory(signaling_thread, |
| 209 channel_manager, | 194 channel_manager, |
| 210 nullptr, | |
| 211 nullptr, | |
| 212 session, | 195 session, |
| 213 session_id, | 196 session_id, |
| 214 true) { | 197 nullptr, |
| 198 certificate) { |
| 215 RTC_DCHECK(certificate); | 199 RTC_DCHECK(certificate); |
| 216 | |
| 217 certificate_request_state_ = CERTIFICATE_WAITING; | |
| 218 | |
| 219 LOG(LS_VERBOSE) << "DTLS-SRTP enabled; has certificate parameter."; | |
| 220 // We already have a certificate but we wait to do SetIdentity; if we do | |
| 221 // it in the constructor then the caller has not had a chance to connect to | |
| 222 // SignalIdentityReady. | |
| 223 signaling_thread_->Post( | |
| 224 this, MSG_USE_CONSTRUCTOR_CERTIFICATE, | |
| 225 new rtc::ScopedRefMessageData<rtc::RTCCertificate>(certificate)); | |
| 226 } | 200 } |
| 227 | 201 |
| 228 WebRtcSessionDescriptionFactory::~WebRtcSessionDescriptionFactory() { | 202 WebRtcSessionDescriptionFactory::~WebRtcSessionDescriptionFactory() { |
| 229 ASSERT(signaling_thread_->IsCurrent()); | 203 ASSERT(signaling_thread_->IsCurrent()); |
| 230 | 204 |
| 231 // Fail any requests that were asked for before identity generation completed. | 205 // Fail any requests that were asked for before identity generation completed. |
| 232 FailPendingRequests(kFailedDueToSessionShutdown); | 206 FailPendingRequests(kFailedDueToSessionShutdown); |
| 233 | 207 |
| 234 // Process all pending notifications in the message queue. If we don't do | 208 // Process all pending notifications in the message queue. If we don't do |
| 235 // this, requests will linger and not know they succeeded or failed. | 209 // this, requests will linger and not know they succeeded or failed. |
| (...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 481 } | 455 } |
| 482 | 456 |
| 483 void WebRtcSessionDescriptionFactory::PostCreateSessionDescriptionSucceeded( | 457 void WebRtcSessionDescriptionFactory::PostCreateSessionDescriptionSucceeded( |
| 484 CreateSessionDescriptionObserver* observer, | 458 CreateSessionDescriptionObserver* observer, |
| 485 SessionDescriptionInterface* description) { | 459 SessionDescriptionInterface* description) { |
| 486 CreateSessionDescriptionMsg* msg = new CreateSessionDescriptionMsg(observer); | 460 CreateSessionDescriptionMsg* msg = new CreateSessionDescriptionMsg(observer); |
| 487 msg->description.reset(description); | 461 msg->description.reset(description); |
| 488 signaling_thread_->Post(this, MSG_CREATE_SESSIONDESCRIPTION_SUCCESS, msg); | 462 signaling_thread_->Post(this, MSG_CREATE_SESSIONDESCRIPTION_SUCCESS, msg); |
| 489 } | 463 } |
| 490 | 464 |
| 491 void WebRtcSessionDescriptionFactory::OnIdentityRequestFailed(int error) { | 465 void WebRtcSessionDescriptionFactory::OnCertificateRequestFailed() { |
| 492 ASSERT(signaling_thread_->IsCurrent()); | 466 ASSERT(signaling_thread_->IsCurrent()); |
| 493 | 467 |
| 494 LOG(LS_ERROR) << "Async identity request failed: error = " << error; | 468 LOG(LS_ERROR) << "Asynchronous certificate generation request failed."; |
| 495 certificate_request_state_ = CERTIFICATE_FAILED; | 469 certificate_request_state_ = CERTIFICATE_FAILED; |
| 496 | 470 |
| 497 FailPendingRequests(kFailedDueToIdentityFailed); | 471 FailPendingRequests(kFailedDueToIdentityFailed); |
| 498 } | 472 } |
| 499 | 473 |
| 500 void WebRtcSessionDescriptionFactory::SetCertificate( | 474 void WebRtcSessionDescriptionFactory::SetCertificate( |
| 501 const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) { | 475 const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) { |
| 502 RTC_DCHECK(certificate); | 476 RTC_DCHECK(certificate); |
| 503 LOG(LS_VERBOSE) << "Setting new certificate"; | 477 LOG(LS_VERBOSE) << "Setting new certificate."; |
| 504 | 478 |
| 505 certificate_request_state_ = CERTIFICATE_SUCCEEDED; | 479 certificate_request_state_ = CERTIFICATE_SUCCEEDED; |
| 506 SignalCertificateReady(certificate); | 480 SignalCertificateReady(certificate); |
| 507 | 481 |
| 508 transport_desc_factory_.set_certificate(certificate); | 482 transport_desc_factory_.set_certificate(certificate); |
| 509 transport_desc_factory_.set_secure(cricket::SEC_ENABLED); | 483 transport_desc_factory_.set_secure(cricket::SEC_ENABLED); |
| 510 | 484 |
| 511 while (!create_session_description_requests_.empty()) { | 485 while (!create_session_description_requests_.empty()) { |
| 512 if (create_session_description_requests_.front().type == | 486 if (create_session_description_requests_.front().type == |
| 513 CreateSessionDescriptionRequest::kOffer) { | 487 CreateSessionDescriptionRequest::kOffer) { |
| 514 InternalCreateOffer(create_session_description_requests_.front()); | 488 InternalCreateOffer(create_session_description_requests_.front()); |
| 515 } else { | 489 } else { |
| 516 InternalCreateAnswer(create_session_description_requests_.front()); | 490 InternalCreateAnswer(create_session_description_requests_.front()); |
| 517 } | 491 } |
| 518 create_session_description_requests_.pop(); | 492 create_session_description_requests_.pop(); |
| 519 } | 493 } |
| 520 } | 494 } |
| 521 } // namespace webrtc | 495 } // namespace webrtc |
| OLD | NEW |