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 P2P_BASE_DTLS_TRANSPORT_H_ 12 #define P2P_BASE_DTLS_TRANSPORT_H_ 13 14 #include <memory> 15 #include <string> 16 #include <vector> 17 18 #include "absl/strings/string_view.h" 19 #include "api/crypto/crypto_options.h" 20 #include "api/dtls_transport_interface.h" 21 #include "api/sequence_checker.h" 22 #include "p2p/base/dtls_transport_internal.h" 23 #include "p2p/base/ice_transport_internal.h" 24 #include "rtc_base/buffer.h" 25 #include "rtc_base/buffer_queue.h" 26 #include "rtc_base/ssl_stream_adapter.h" 27 #include "rtc_base/stream.h" 28 #include "rtc_base/strings/string_builder.h" 29 #include "rtc_base/system/no_unique_address.h" 30 31 namespace rtc { 32 class PacketTransportInternal; 33 } 34 35 namespace cricket { 36 37 // A bridge between a packet-oriented/transport-type interface on 38 // the bottom and a StreamInterface on the top. 39 class StreamInterfaceChannel : public rtc::StreamInterface { 40 public: 41 explicit StreamInterfaceChannel(IceTransportInternal* ice_transport); 42 43 StreamInterfaceChannel(const StreamInterfaceChannel&) = delete; 44 StreamInterfaceChannel& operator=(const StreamInterfaceChannel&) = delete; 45 46 // Push in a packet; this gets pulled out from Read(). 47 bool OnPacketReceived(const char* data, size_t size); 48 49 // Implementations of StreamInterface 50 rtc::StreamState GetState() const override; 51 void Close() override; 52 rtc::StreamResult Read(rtc::ArrayView<uint8_t> buffer, 53 size_t& read, 54 int& error) override; 55 rtc::StreamResult Write(rtc::ArrayView<const uint8_t> data, 56 size_t& written, 57 int& error) override; 58 59 private: 60 RTC_NO_UNIQUE_ADDRESS webrtc::SequenceChecker sequence_checker_; 61 IceTransportInternal* const ice_transport_; // owned by DtlsTransport 62 rtc::StreamState state_ RTC_GUARDED_BY(sequence_checker_); 63 rtc::BufferQueue packets_ RTC_GUARDED_BY(sequence_checker_); 64 }; 65 66 // This class provides a DTLS SSLStreamAdapter inside a TransportChannel-style 67 // packet-based interface, wrapping an existing TransportChannel instance 68 // (e.g a P2PTransportChannel) 69 // Here's the way this works: 70 // 71 // DtlsTransport { 72 // SSLStreamAdapter* dtls_ { 73 // StreamInterfaceChannel downward_ { 74 // IceTransportInternal* ice_transport_; 75 // } 76 // } 77 // } 78 // 79 // - Data which comes into DtlsTransport from the underlying 80 // ice_transport_ via OnReadPacket() is checked for whether it is DTLS 81 // or not, and if it is, is passed to DtlsTransport::HandleDtlsPacket, 82 // which pushes it into to downward_. dtls_ is listening for events on 83 // downward_, so it immediately calls downward_->Read(). 84 // 85 // - Data written to DtlsTransport is passed either to downward_ or directly 86 // to ice_transport_, depending on whether DTLS is negotiated and whether 87 // the flags include PF_SRTP_BYPASS 88 // 89 // - The SSLStreamAdapter writes to downward_->Write() which translates it 90 // into packet writes on ice_transport_. 91 // 92 // This class is not thread safe; all methods must be called on the same thread 93 // as the constructor. 94 class DtlsTransport : public DtlsTransportInternal { 95 public: 96 // `ice_transport` is the ICE transport this DTLS transport is wrapping. It 97 // must outlive this DTLS transport. 98 // 99 // `crypto_options` are the options used for the DTLS handshake. This affects 100 // whether GCM crypto suites are negotiated. 101 // 102 // `event_log` is an optional RtcEventLog for logging state changes. It should 103 // outlive the DtlsTransport. 104 DtlsTransport( 105 IceTransportInternal* ice_transport, 106 const webrtc::CryptoOptions& crypto_options, 107 webrtc::RtcEventLog* event_log, 108 rtc::SSLProtocolVersion max_version = rtc::SSL_PROTOCOL_DTLS_12); 109 110 ~DtlsTransport() override; 111 112 DtlsTransport(const DtlsTransport&) = delete; 113 DtlsTransport& operator=(const DtlsTransport&) = delete; 114 115 webrtc::DtlsTransportState dtls_state() const override; 116 const std::string& transport_name() const override; 117 int component() const override; 118 119 // DTLS is active if a local certificate was set. Otherwise this acts in a 120 // "passthrough" mode, sending packets directly through the underlying ICE 121 // transport. 122 // TODO(deadbeef): Remove this weirdness, and handle it in the upper layers. 123 bool IsDtlsActive() const override; 124 125 // SetLocalCertificate is what makes DTLS active. It must be called before 126 // SetRemoteFinterprint. 127 // TODO(deadbeef): Once DtlsTransport no longer has the concept of being 128 // "active" or not (acting as a passthrough if not active), just require this 129 // certificate on construction or "Start". 130 bool SetLocalCertificate( 131 const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) override; 132 rtc::scoped_refptr<rtc::RTCCertificate> GetLocalCertificate() const override; 133 134 // SetRemoteFingerprint must be called after SetLocalCertificate, and any 135 // other methods like SetDtlsRole. It's what triggers the actual DTLS setup. 136 // TODO(deadbeef): Rename to "Start" like in ORTC? 137 bool SetRemoteFingerprint(absl::string_view digest_alg, 138 const uint8_t* digest, 139 size_t digest_len) override; 140 141 // SetRemoteParameters must be called after SetLocalCertificate. 142 webrtc::RTCError SetRemoteParameters( 143 absl::string_view digest_alg, 144 const uint8_t* digest, 145 size_t digest_len, 146 absl::optional<rtc::SSLRole> role) override; 147 148 // Called to send a packet (via DTLS, if turned on). 149 int SendPacket(const char* data, 150 size_t size, 151 const rtc::PacketOptions& options, 152 int flags) override; 153 154 bool GetOption(rtc::Socket::Option opt, int* value) override; 155 156 // Find out which TLS version was negotiated 157 bool GetSslVersionBytes(int* version) const override; 158 // Find out which DTLS-SRTP cipher was negotiated 159 bool GetSrtpCryptoSuite(int* cipher) override; 160 161 bool GetDtlsRole(rtc::SSLRole* role) const override; 162 bool SetDtlsRole(rtc::SSLRole role) override; 163 164 // Find out which DTLS cipher was negotiated 165 bool GetSslCipherSuite(int* cipher) override; 166 167 // Once DTLS has been established, this method retrieves the certificate 168 // chain in use by the remote peer, for use in external identity 169 // verification. 170 std::unique_ptr<rtc::SSLCertChain> GetRemoteSSLCertChain() const override; 171 172 // Once DTLS has established (i.e., this ice_transport is writable), this 173 // method extracts the keys negotiated during the DTLS handshake, for use in 174 // external encryption. DTLS-SRTP uses this to extract the needed SRTP keys. 175 // See the SSLStreamAdapter documentation for info on the specific parameters. 176 bool ExportKeyingMaterial(absl::string_view label, 177 const uint8_t* context, 178 size_t context_len, 179 bool use_context, 180 uint8_t* result, 181 size_t result_len) override; 182 183 IceTransportInternal* ice_transport() override; 184 185 // For informational purposes. Tells if the DTLS handshake has finished. 186 // This may be true even if writable() is false, if the remote fingerprint 187 // has not yet been verified. 188 bool IsDtlsConnected(); 189 190 bool receiving() const override; 191 bool writable() const override; 192 193 int GetError() override; 194 195 absl::optional<rtc::NetworkRoute> network_route() const override; 196 197 int SetOption(rtc::Socket::Option opt, int value) override; 198 ToString()199 std::string ToString() const { 200 const absl::string_view RECEIVING_ABBREV[2] = {"_", "R"}; 201 const absl::string_view WRITABLE_ABBREV[2] = {"_", "W"}; 202 rtc::StringBuilder sb; 203 sb << "DtlsTransport[" << transport_name() << "|" << component_ << "|" 204 << RECEIVING_ABBREV[receiving()] << WRITABLE_ABBREV[writable()] << "]"; 205 return sb.Release(); 206 } 207 208 private: 209 void ConnectToIceTransport(); 210 211 void OnWritableState(rtc::PacketTransportInternal* transport); 212 void OnReadPacket(rtc::PacketTransportInternal* transport, 213 const char* data, 214 size_t size, 215 const int64_t& packet_time_us, 216 int flags); 217 void OnSentPacket(rtc::PacketTransportInternal* transport, 218 const rtc::SentPacket& sent_packet); 219 void OnReadyToSend(rtc::PacketTransportInternal* transport); 220 void OnReceivingState(rtc::PacketTransportInternal* transport); 221 void OnDtlsEvent(rtc::StreamInterface* stream_, int sig, int err); 222 void OnNetworkRouteChanged(absl::optional<rtc::NetworkRoute> network_route); 223 bool SetupDtls(); 224 void MaybeStartDtls(); 225 bool HandleDtlsPacket(const char* data, size_t size); 226 void OnDtlsHandshakeError(rtc::SSLHandshakeError error); 227 void ConfigureHandshakeTimeout(); 228 229 void set_receiving(bool receiving); 230 void set_writable(bool writable); 231 // Sets the DTLS state, signaling if necessary. 232 void set_dtls_state(webrtc::DtlsTransportState state); 233 234 webrtc::SequenceChecker thread_checker_; 235 236 const int component_; 237 webrtc::DtlsTransportState dtls_state_ = webrtc::DtlsTransportState::kNew; 238 // Underlying ice_transport, not owned by this class. 239 IceTransportInternal* const ice_transport_; 240 std::unique_ptr<rtc::SSLStreamAdapter> dtls_; // The DTLS stream 241 StreamInterfaceChannel* 242 downward_; // Wrapper for ice_transport_, owned by dtls_. 243 const std::vector<int> srtp_ciphers_; // SRTP ciphers to use with DTLS. 244 bool dtls_active_ = false; 245 rtc::scoped_refptr<rtc::RTCCertificate> local_certificate_; 246 absl::optional<rtc::SSLRole> dtls_role_; 247 const rtc::SSLProtocolVersion ssl_max_version_; 248 rtc::Buffer remote_fingerprint_value_; 249 std::string remote_fingerprint_algorithm_; 250 251 // Cached DTLS ClientHello packet that was received before we started the 252 // DTLS handshake. This could happen if the hello was received before the 253 // ice transport became writable, or before a remote fingerprint was received. 254 rtc::Buffer cached_client_hello_; 255 256 bool receiving_ = false; 257 bool writable_ = false; 258 259 webrtc::RtcEventLog* const event_log_; 260 }; 261 262 } // namespace cricket 263 264 #endif // P2P_BASE_DTLS_TRANSPORT_H_ 265