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