1 /*
2  * libjingle
3  * Copyright 2013 Google Inc.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  *  1. Redistributions of source code must retain the above copyright notice,
9  *     this list of conditions and the following disclaimer.
10  *  2. Redistributions in binary form must reproduce the above copyright notice,
11  *     this list of conditions and the following disclaimer in the documentation
12  *     and/or other materials provided with the distribution.
13  *  3. The name of the author may not be used to endorse or promote products
14  *     derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19  * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 #ifndef TALK_APP_WEBRTC_WEBRTCSESSIONDESCRIPTIONFACTORY_H_
29 #define TALK_APP_WEBRTC_WEBRTCSESSIONDESCRIPTIONFACTORY_H_
30 
31 #include "talk/app/webrtc/dtlsidentitystore.h"
32 #include "talk/app/webrtc/peerconnectioninterface.h"
33 #include "talk/session/media/mediasession.h"
34 #include "webrtc/p2p/base/transportdescriptionfactory.h"
35 #include "webrtc/base/messagehandler.h"
36 #include "webrtc/base/rtccertificate.h"
37 
38 namespace cricket {
39 class ChannelManager;
40 class TransportDescriptionFactory;
41 }  // namespace cricket
42 
43 namespace webrtc {
44 class CreateSessionDescriptionObserver;
45 class MediaConstraintsInterface;
46 class SessionDescriptionInterface;
47 class WebRtcSession;
48 
49 // DTLS identity request callback class.
50 class WebRtcIdentityRequestObserver : public DtlsIdentityRequestObserver,
51                                       public sigslot::has_slots<> {
52  public:
53   // DtlsIdentityRequestObserver overrides.
54   void OnFailure(int error) override;
55   void OnSuccess(const std::string& der_cert,
56                  const std::string& der_private_key) override;
57   void OnSuccess(rtc::scoped_ptr<rtc::SSLIdentity> identity) override;
58 
59   sigslot::signal1<int> SignalRequestFailed;
60   sigslot::signal1<const rtc::scoped_refptr<rtc::RTCCertificate>&>
61       SignalCertificateReady;
62 };
63 
64 struct CreateSessionDescriptionRequest {
65   enum Type {
66     kOffer,
67     kAnswer,
68   };
69 
CreateSessionDescriptionRequestCreateSessionDescriptionRequest70   CreateSessionDescriptionRequest(
71       Type type,
72       CreateSessionDescriptionObserver* observer,
73       const cricket::MediaSessionOptions& options)
74       : type(type),
75         observer(observer),
76         options(options) {}
77 
78   Type type;
79   rtc::scoped_refptr<CreateSessionDescriptionObserver> observer;
80   cricket::MediaSessionOptions options;
81 };
82 
83 // This class is used to create offer/answer session description with regards to
84 // the async DTLS identity generation for WebRtcSession.
85 // It queues the create offer/answer request until the DTLS identity
86 // request has completed, i.e. when OnIdentityRequestFailed or OnIdentityReady
87 // is called.
88 class WebRtcSessionDescriptionFactory : public rtc::MessageHandler,
89                                         public sigslot::has_slots<> {
90  public:
91   // Construct with DTLS disabled.
92   WebRtcSessionDescriptionFactory(rtc::Thread* signaling_thread,
93                                   cricket::ChannelManager* channel_manager,
94                                   WebRtcSession* session,
95                                   const std::string& session_id);
96 
97   // Construct with DTLS enabled using the specified |dtls_identity_store| to
98   // generate a certificate.
99   WebRtcSessionDescriptionFactory(
100       rtc::Thread* signaling_thread,
101       cricket::ChannelManager* channel_manager,
102       rtc::scoped_ptr<DtlsIdentityStoreInterface> dtls_identity_store,
103       WebRtcSession* session,
104       const std::string& session_id);
105 
106   // Construct with DTLS enabled using the specified (already generated)
107   // |certificate|.
108   WebRtcSessionDescriptionFactory(
109       rtc::Thread* signaling_thread,
110       cricket::ChannelManager* channel_manager,
111       const rtc::scoped_refptr<rtc::RTCCertificate>& certificate,
112       WebRtcSession* session,
113       const std::string& session_id);
114   virtual ~WebRtcSessionDescriptionFactory();
115 
116   static void CopyCandidatesFromSessionDescription(
117     const SessionDescriptionInterface* source_desc,
118     SessionDescriptionInterface* dest_desc);
119 
120   void CreateOffer(
121       CreateSessionDescriptionObserver* observer,
122       const PeerConnectionInterface::RTCOfferAnswerOptions& options,
123       const cricket::MediaSessionOptions& session_options);
124   void CreateAnswer(CreateSessionDescriptionObserver* observer,
125                     const MediaConstraintsInterface* constraints,
126                     const cricket::MediaSessionOptions& session_options);
127 
128   void SetSdesPolicy(cricket::SecurePolicy secure_policy);
129   cricket::SecurePolicy SdesPolicy() const;
130 
131   sigslot::signal1<const rtc::scoped_refptr<rtc::RTCCertificate>&>
132       SignalCertificateReady;
133 
134   // For testing.
waiting_for_certificate_for_testing()135   bool waiting_for_certificate_for_testing() const {
136     return certificate_request_state_ == CERTIFICATE_WAITING;
137   }
138 
139  private:
140   enum CertificateRequestState {
141     CERTIFICATE_NOT_NEEDED,
142     CERTIFICATE_WAITING,
143     CERTIFICATE_SUCCEEDED,
144     CERTIFICATE_FAILED,
145   };
146 
147   WebRtcSessionDescriptionFactory(
148       rtc::Thread* signaling_thread,
149       cricket::ChannelManager* channel_manager,
150       rtc::scoped_ptr<DtlsIdentityStoreInterface> dtls_identity_store,
151       const rtc::scoped_refptr<WebRtcIdentityRequestObserver>&
152           identity_request_observer,
153       WebRtcSession* session,
154       const std::string& session_id,
155       bool dtls_enabled);
156 
157   // MessageHandler implementation.
158   virtual void OnMessage(rtc::Message* msg);
159 
160   void InternalCreateOffer(CreateSessionDescriptionRequest request);
161   void InternalCreateAnswer(CreateSessionDescriptionRequest request);
162   // Posts failure notifications for all pending session description requests.
163   void FailPendingRequests(const std::string& reason);
164   void PostCreateSessionDescriptionFailed(
165       CreateSessionDescriptionObserver* observer,
166       const std::string& error);
167   void PostCreateSessionDescriptionSucceeded(
168       CreateSessionDescriptionObserver* observer,
169       SessionDescriptionInterface* description);
170 
171   void OnIdentityRequestFailed(int error);
172   void SetCertificate(
173       const rtc::scoped_refptr<rtc::RTCCertificate>& certificate);
174 
175   std::queue<CreateSessionDescriptionRequest>
176       create_session_description_requests_;
177   rtc::Thread* const signaling_thread_;
178   cricket::TransportDescriptionFactory transport_desc_factory_;
179   cricket::MediaSessionDescriptionFactory session_desc_factory_;
180   uint64_t session_version_;
181   const rtc::scoped_ptr<DtlsIdentityStoreInterface> dtls_identity_store_;
182   const rtc::scoped_refptr<WebRtcIdentityRequestObserver>
183       identity_request_observer_;
184   // TODO(jiayl): remove the dependency on session once bug 2264 is fixed.
185   WebRtcSession* const session_;
186   const std::string session_id_;
187   CertificateRequestState certificate_request_state_;
188 
189   RTC_DISALLOW_COPY_AND_ASSIGN(WebRtcSessionDescriptionFactory);
190 };
191 }  // namespace webrtc
192 
193 #endif  // TALK_APP_WEBRTC_WEBRTCSESSIONDESCRIPTIONFACTORY_H_
194