xref: /aosp_15_r20/external/webrtc/p2p/base/dtls_transport.h (revision d9f758449e529ab9291ac668be2861e7a55c2422)
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