• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright 2011 The WebRTC Project Authors. All rights reserved.
3  *
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
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #ifndef WEBRTC_P2P_BASE_DTLSTRANSPORTCHANNEL_H_
12 #define WEBRTC_P2P_BASE_DTLSTRANSPORTCHANNEL_H_
13 
14 #include <string>
15 #include <vector>
16 
17 #include "webrtc/p2p/base/transportchannelimpl.h"
18 #include "webrtc/base/buffer.h"
19 #include "webrtc/base/bufferqueue.h"
20 #include "webrtc/base/scoped_ptr.h"
21 #include "webrtc/base/sslstreamadapter.h"
22 #include "webrtc/base/stream.h"
23 
24 namespace cricket {
25 
26 // A bridge between a packet-oriented/channel-type interface on
27 // the bottom and a StreamInterface on the top.
28 class StreamInterfaceChannel : public rtc::StreamInterface {
29  public:
30   explicit StreamInterfaceChannel(TransportChannel* channel);
31 
32   // Push in a packet; this gets pulled out from Read().
33   bool OnPacketReceived(const char* data, size_t size);
34 
35   // Implementations of StreamInterface
GetState()36   rtc::StreamState GetState() const override { return state_; }
Close()37   void Close() override { state_ = rtc::SS_CLOSED; }
38   rtc::StreamResult Read(void* buffer,
39                          size_t buffer_len,
40                          size_t* read,
41                          int* error) override;
42   rtc::StreamResult Write(const void* data,
43                           size_t data_len,
44                           size_t* written,
45                           int* error) override;
46 
47  private:
48   TransportChannel* channel_;  // owned by DtlsTransportChannelWrapper
49   rtc::StreamState state_;
50   rtc::BufferQueue packets_;
51 
52   RTC_DISALLOW_COPY_AND_ASSIGN(StreamInterfaceChannel);
53 };
54 
55 
56 // This class provides a DTLS SSLStreamAdapter inside a TransportChannel-style
57 // packet-based interface, wrapping an existing TransportChannel instance
58 // (e.g a P2PTransportChannel)
59 // Here's the way this works:
60 //
61 //   DtlsTransportChannelWrapper {
62 //       SSLStreamAdapter* dtls_ {
63 //           StreamInterfaceChannel downward_ {
64 //               TransportChannelImpl* channel_;
65 //           }
66 //       }
67 //   }
68 //
69 //   - Data which comes into DtlsTransportChannelWrapper from the underlying
70 //     channel_ via OnReadPacket() is checked for whether it is DTLS
71 //     or not, and if it is, is passed to DtlsTransportChannelWrapper::
72 //     HandleDtlsPacket, which pushes it into to downward_.
73 //     dtls_ is listening for events on downward_, so it immediately calls
74 //     downward_->Read().
75 //
76 //   - Data written to DtlsTransportChannelWrapper is passed either to
77 //      downward_ or directly to channel_, depending on whether DTLS is
78 //     negotiated and whether the flags include PF_SRTP_BYPASS
79 //
80 //   - The SSLStreamAdapter writes to downward_->Write()
81 //     which translates it into packet writes on channel_.
82 class DtlsTransportChannelWrapper : public TransportChannelImpl {
83  public:
84   // The parameters here are:
85   // transport -- the DtlsTransport that created us
86   // channel -- the TransportChannel we are wrapping
87   DtlsTransportChannelWrapper(Transport* transport,
88                               TransportChannelImpl* channel);
89   ~DtlsTransportChannelWrapper() override;
90 
SetIceRole(IceRole role)91   void SetIceRole(IceRole role) override { channel_->SetIceRole(role); }
GetIceRole()92   IceRole GetIceRole() const override { return channel_->GetIceRole(); }
93   bool SetLocalCertificate(
94       const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) override;
95   rtc::scoped_refptr<rtc::RTCCertificate> GetLocalCertificate() const override;
96 
97   bool SetRemoteFingerprint(const std::string& digest_alg,
98                             const uint8_t* digest,
99                             size_t digest_len) override;
100 
101   // Returns false if no local certificate was set, or if the peer doesn't
102   // support DTLS.
IsDtlsActive()103   bool IsDtlsActive() const override { return dtls_active_; }
104 
105   // Called to send a packet (via DTLS, if turned on).
106   int SendPacket(const char* data,
107                  size_t size,
108                  const rtc::PacketOptions& options,
109                  int flags) override;
110 
111   // TransportChannel calls that we forward to the wrapped transport.
SetOption(rtc::Socket::Option opt,int value)112   int SetOption(rtc::Socket::Option opt, int value) override {
113     return channel_->SetOption(opt, value);
114   }
GetOption(rtc::Socket::Option opt,int * value)115   bool GetOption(rtc::Socket::Option opt, int* value) override {
116     return channel_->GetOption(opt, value);
117   }
GetError()118   int GetError() override { return channel_->GetError(); }
GetStats(ConnectionInfos * infos)119   bool GetStats(ConnectionInfos* infos) override {
120     return channel_->GetStats(infos);
121   }
SessionId()122   const std::string SessionId() const override { return channel_->SessionId(); }
123 
124   virtual bool SetSslMaxProtocolVersion(rtc::SSLProtocolVersion version);
125 
126   // Set up the ciphers to use for DTLS-SRTP. If this method is not called
127   // before DTLS starts, or |ciphers| is empty, SRTP keys won't be negotiated.
128   // This method should be called before SetupDtls.
129   bool SetSrtpCryptoSuites(const std::vector<int>& ciphers) override;
130 
131   // Find out which DTLS-SRTP cipher was negotiated
132   bool GetSrtpCryptoSuite(int* cipher) override;
133 
134   bool GetSslRole(rtc::SSLRole* role) const override;
135   bool SetSslRole(rtc::SSLRole role) override;
136 
137   // Find out which DTLS cipher was negotiated
138   bool GetSslCipherSuite(int* cipher) override;
139 
140   // Once DTLS has been established, this method retrieves the certificate in
141   // use by the remote peer, for use in external identity verification.
142   bool GetRemoteSSLCertificate(rtc::SSLCertificate** cert) const override;
143 
144   // Once DTLS has established (i.e., this channel is writable), this method
145   // extracts the keys negotiated during the DTLS handshake, for use in external
146   // encryption. DTLS-SRTP uses this to extract the needed SRTP keys.
147   // See the SSLStreamAdapter documentation for info on the specific parameters.
ExportKeyingMaterial(const std::string & label,const uint8_t * context,size_t context_len,bool use_context,uint8_t * result,size_t result_len)148   bool ExportKeyingMaterial(const std::string& label,
149                             const uint8_t* context,
150                             size_t context_len,
151                             bool use_context,
152                             uint8_t* result,
153                             size_t result_len) override {
154     return (dtls_.get()) ? dtls_->ExportKeyingMaterial(label, context,
155                                                        context_len,
156                                                        use_context,
157                                                        result, result_len)
158         : false;
159   }
160 
161   // TransportChannelImpl calls.
GetTransport()162   Transport* GetTransport() override { return transport_; }
163 
GetState()164   TransportChannelState GetState() const override {
165     return channel_->GetState();
166   }
SetIceTiebreaker(uint64_t tiebreaker)167   void SetIceTiebreaker(uint64_t tiebreaker) override {
168     channel_->SetIceTiebreaker(tiebreaker);
169   }
SetIceCredentials(const std::string & ice_ufrag,const std::string & ice_pwd)170   void SetIceCredentials(const std::string& ice_ufrag,
171                          const std::string& ice_pwd) override {
172     channel_->SetIceCredentials(ice_ufrag, ice_pwd);
173   }
SetRemoteIceCredentials(const std::string & ice_ufrag,const std::string & ice_pwd)174   void SetRemoteIceCredentials(const std::string& ice_ufrag,
175                                const std::string& ice_pwd) override {
176     channel_->SetRemoteIceCredentials(ice_ufrag, ice_pwd);
177   }
SetRemoteIceMode(IceMode mode)178   void SetRemoteIceMode(IceMode mode) override {
179     channel_->SetRemoteIceMode(mode);
180   }
181 
182   void Connect() override;
183 
MaybeStartGathering()184   void MaybeStartGathering() override { channel_->MaybeStartGathering(); }
185 
gathering_state()186   IceGatheringState gathering_state() const override {
187     return channel_->gathering_state();
188   }
189 
AddRemoteCandidate(const Candidate & candidate)190   void AddRemoteCandidate(const Candidate& candidate) override {
191     channel_->AddRemoteCandidate(candidate);
192   }
193 
SetIceConfig(const IceConfig & config)194   void SetIceConfig(const IceConfig& config) override {
195     channel_->SetIceConfig(config);
196   }
197 
198   // Needed by DtlsTransport.
channel()199   TransportChannelImpl* channel() { return channel_; }
200 
201  private:
202   void OnReadableState(TransportChannel* channel);
203   void OnWritableState(TransportChannel* channel);
204   void OnReadPacket(TransportChannel* channel, const char* data, size_t size,
205                     const rtc::PacketTime& packet_time, int flags);
206   void OnSentPacket(TransportChannel* channel,
207                     const rtc::SentPacket& sent_packet);
208   void OnReadyToSend(TransportChannel* channel);
209   void OnReceivingState(TransportChannel* channel);
210   void OnDtlsEvent(rtc::StreamInterface* stream_, int sig, int err);
211   bool SetupDtls();
212   bool MaybeStartDtls();
213   bool HandleDtlsPacket(const char* data, size_t size);
214   void OnGatheringState(TransportChannelImpl* channel);
215   void OnCandidateGathered(TransportChannelImpl* channel, const Candidate& c);
216   void OnRoleConflict(TransportChannelImpl* channel);
217   void OnRouteChange(TransportChannel* channel, const Candidate& candidate);
218   void OnConnectionRemoved(TransportChannelImpl* channel);
219   void Reconnect();
220 
221   Transport* transport_;  // The transport_ that created us.
222   rtc::Thread* worker_thread_;  // Everything should occur on this thread.
223   // Underlying channel, owned by transport_.
224   TransportChannelImpl* const channel_;
225   rtc::scoped_ptr<rtc::SSLStreamAdapter> dtls_;  // The DTLS stream
226   StreamInterfaceChannel* downward_;  // Wrapper for channel_, owned by dtls_.
227   std::vector<int> srtp_ciphers_;     // SRTP ciphers to use with DTLS.
228   bool dtls_active_ = false;
229   rtc::scoped_refptr<rtc::RTCCertificate> local_certificate_;
230   rtc::SSLRole ssl_role_;
231   rtc::SSLProtocolVersion ssl_max_version_;
232   rtc::Buffer remote_fingerprint_value_;
233   std::string remote_fingerprint_algorithm_;
234 
235   RTC_DISALLOW_COPY_AND_ASSIGN(DtlsTransportChannelWrapper);
236 };
237 
238 }  // namespace cricket
239 
240 #endif  // WEBRTC_P2P_BASE_DTLSTRANSPORTCHANNEL_H_
241