Home | History | Annotate | Download | only in base
      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
     36   rtc::StreamState GetState() const override { return state_; }
     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 
     91   void SetIceRole(IceRole role) override { channel_->SetIceRole(role); }
     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.
    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.
    112   int SetOption(rtc::Socket::Option opt, int value) override {
    113     return channel_->SetOption(opt, value);
    114   }
    115   bool GetOption(rtc::Socket::Option opt, int* value) override {
    116     return channel_->GetOption(opt, value);
    117   }
    118   int GetError() override { return channel_->GetError(); }
    119   bool GetStats(ConnectionInfos* infos) override {
    120     return channel_->GetStats(infos);
    121   }
    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.
    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.
    162   Transport* GetTransport() override { return transport_; }
    163 
    164   TransportChannelState GetState() const override {
    165     return channel_->GetState();
    166   }
    167   void SetIceTiebreaker(uint64_t tiebreaker) override {
    168     channel_->SetIceTiebreaker(tiebreaker);
    169   }
    170   void SetIceCredentials(const std::string& ice_ufrag,
    171                          const std::string& ice_pwd) override {
    172     channel_->SetIceCredentials(ice_ufrag, ice_pwd);
    173   }
    174   void SetRemoteIceCredentials(const std::string& ice_ufrag,
    175                                const std::string& ice_pwd) override {
    176     channel_->SetRemoteIceCredentials(ice_ufrag, ice_pwd);
    177   }
    178   void SetRemoteIceMode(IceMode mode) override {
    179     channel_->SetRemoteIceMode(mode);
    180   }
    181 
    182   void Connect() override;
    183 
    184   void MaybeStartGathering() override { channel_->MaybeStartGathering(); }
    185 
    186   IceGatheringState gathering_state() const override {
    187     return channel_->gathering_state();
    188   }
    189 
    190   void AddRemoteCandidate(const Candidate& candidate) override {
    191     channel_->AddRemoteCandidate(candidate);
    192   }
    193 
    194   void SetIceConfig(const IceConfig& config) override {
    195     channel_->SetIceConfig(config);
    196   }
    197 
    198   // Needed by DtlsTransport.
    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