• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright 2017 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_FAKE_DTLS_TRANSPORT_H_
12 #define P2P_BASE_FAKE_DTLS_TRANSPORT_H_
13 
14 #include <memory>
15 #include <string>
16 #include <utility>
17 #include <vector>
18 
19 #include "api/crypto/crypto_options.h"
20 #include "p2p/base/dtls_transport_internal.h"
21 #include "p2p/base/fake_ice_transport.h"
22 #include "rtc_base/fake_ssl_identity.h"
23 #include "rtc_base/rtc_certificate.h"
24 
25 namespace cricket {
26 
27 // Fake DTLS transport which is implemented by wrapping a fake ICE transport.
28 // Doesn't interact directly with fake ICE transport for anything other than
29 // sending packets.
30 class FakeDtlsTransport : public DtlsTransportInternal {
31  public:
FakeDtlsTransport(FakeIceTransport * ice_transport)32   explicit FakeDtlsTransport(FakeIceTransport* ice_transport)
33       : ice_transport_(ice_transport),
34         transport_name_(ice_transport->transport_name()),
35         component_(ice_transport->component()),
36         dtls_fingerprint_("", nullptr) {
37     RTC_DCHECK(ice_transport_);
38     ice_transport_->SignalReadPacket.connect(
39         this, &FakeDtlsTransport::OnIceTransportReadPacket);
40     ice_transport_->SignalNetworkRouteChanged.connect(
41         this, &FakeDtlsTransport::OnNetworkRouteChanged);
42   }
43 
FakeDtlsTransport(std::unique_ptr<FakeIceTransport> ice)44   explicit FakeDtlsTransport(std::unique_ptr<FakeIceTransport> ice)
45       : owned_ice_transport_(std::move(ice)),
46         transport_name_(owned_ice_transport_->transport_name()),
47         component_(owned_ice_transport_->component()),
48         dtls_fingerprint_("", rtc::ArrayView<const uint8_t>()) {
49     ice_transport_ = owned_ice_transport_.get();
50     ice_transport_->SignalReadPacket.connect(
51         this, &FakeDtlsTransport::OnIceTransportReadPacket);
52     ice_transport_->SignalNetworkRouteChanged.connect(
53         this, &FakeDtlsTransport::OnNetworkRouteChanged);
54   }
55 
56   // If this constructor is called, a new fake ICE transport will be created,
57   // and this FakeDtlsTransport will take the ownership.
FakeDtlsTransport(const std::string & name,int component)58   explicit FakeDtlsTransport(const std::string& name, int component)
59       : FakeDtlsTransport(std::make_unique<FakeIceTransport>(name, component)) {
60   }
61 
~FakeDtlsTransport()62   ~FakeDtlsTransport() override {
63     if (dest_ && dest_->dest_ == this) {
64       dest_->dest_ = nullptr;
65     }
66   }
67 
68   // Get inner fake ICE transport.
fake_ice_transport()69   FakeIceTransport* fake_ice_transport() { return ice_transport_; }
70 
71   // If async, will send packets by "Post"-ing to message queue instead of
72   // synchronously "Send"-ing.
SetAsync(bool async)73   void SetAsync(bool async) { ice_transport_->SetAsync(async); }
SetAsyncDelay(int delay_ms)74   void SetAsyncDelay(int delay_ms) { ice_transport_->SetAsyncDelay(delay_ms); }
75 
76   // SetWritable, SetReceiving and SetDestination are the main methods that can
77   // be used for testing, to simulate connectivity or lack thereof.
SetWritable(bool writable)78   void SetWritable(bool writable) {
79     ice_transport_->SetWritable(writable);
80     set_writable(writable);
81   }
SetReceiving(bool receiving)82   void SetReceiving(bool receiving) {
83     ice_transport_->SetReceiving(receiving);
84     set_receiving(receiving);
85   }
SetDtlsState(DtlsTransportState state)86   void SetDtlsState(DtlsTransportState state) {
87     dtls_state_ = state;
88     SignalDtlsState(this, dtls_state_);
89   }
90 
91   // Simulates the two DTLS transports connecting to each other.
92   // If |asymmetric| is true this method only affects this FakeDtlsTransport.
93   // If false, it affects |dest| as well.
94   void SetDestination(FakeDtlsTransport* dest, bool asymmetric = false) {
95     if (dest == dest_) {
96       return;
97     }
98     RTC_DCHECK(!dest || !dest_)
99         << "Changing fake destination from one to another is not supported.";
100     if (dest && !dest_) {
101       // This simulates the DTLS handshake.
102       dest_ = dest;
103       if (local_cert_ && dest_->local_cert_) {
104         do_dtls_ = true;
105         RTC_LOG(LS_INFO) << "FakeDtlsTransport is doing DTLS";
106       } else {
107         do_dtls_ = false;
108         RTC_LOG(LS_INFO) << "FakeDtlsTransport is not doing DTLS";
109       }
110       SetWritable(true);
111       if (!asymmetric) {
112         dest->SetDestination(this, true);
113       }
114       // If the |dtls_role_| is unset, set it to SSL_CLIENT by default.
115       if (!dtls_role_) {
116         dtls_role_ = std::move(rtc::SSL_CLIENT);
117       }
118       SetDtlsState(DTLS_TRANSPORT_CONNECTED);
119       ice_transport_->SetDestination(
120           static_cast<FakeIceTransport*>(dest->ice_transport()), asymmetric);
121     } else {
122       // Simulates loss of connectivity, by asymmetrically forgetting dest_.
123       dest_ = nullptr;
124       SetWritable(false);
125       ice_transport_->SetDestination(nullptr, asymmetric);
126     }
127   }
128 
129   // Fake DtlsTransportInternal implementation.
dtls_state()130   DtlsTransportState dtls_state() const override { return dtls_state_; }
transport_name()131   const std::string& transport_name() const override { return transport_name_; }
component()132   int component() const override { return component_; }
dtls_fingerprint()133   const rtc::SSLFingerprint& dtls_fingerprint() const {
134     return dtls_fingerprint_;
135   }
SetRemoteFingerprint(const std::string & alg,const uint8_t * digest,size_t digest_len)136   bool SetRemoteFingerprint(const std::string& alg,
137                             const uint8_t* digest,
138                             size_t digest_len) override {
139     dtls_fingerprint_ =
140         rtc::SSLFingerprint(alg, rtc::MakeArrayView(digest, digest_len));
141     return true;
142   }
SetSslMaxProtocolVersion(rtc::SSLProtocolVersion version)143   bool SetSslMaxProtocolVersion(rtc::SSLProtocolVersion version) override {
144     return true;
145   }
SetDtlsRole(rtc::SSLRole role)146   bool SetDtlsRole(rtc::SSLRole role) override {
147     dtls_role_ = std::move(role);
148     return true;
149   }
GetDtlsRole(rtc::SSLRole * role)150   bool GetDtlsRole(rtc::SSLRole* role) const override {
151     if (!dtls_role_) {
152       return false;
153     }
154     *role = *dtls_role_;
155     return true;
156   }
crypto_options()157   const webrtc::CryptoOptions& crypto_options() const override {
158     return crypto_options_;
159   }
SetCryptoOptions(const webrtc::CryptoOptions & crypto_options)160   void SetCryptoOptions(const webrtc::CryptoOptions& crypto_options) {
161     crypto_options_ = crypto_options;
162   }
SetLocalCertificate(const rtc::scoped_refptr<rtc::RTCCertificate> & certificate)163   bool SetLocalCertificate(
164       const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) override {
165     do_dtls_ = true;
166     local_cert_ = certificate;
167     return true;
168   }
SetRemoteSSLCertificate(rtc::FakeSSLCertificate * cert)169   void SetRemoteSSLCertificate(rtc::FakeSSLCertificate* cert) {
170     remote_cert_ = cert;
171   }
IsDtlsActive()172   bool IsDtlsActive() const override { return do_dtls_; }
GetSslVersionBytes(int * version)173   bool GetSslVersionBytes(int* version) const override {
174     if (!do_dtls_) {
175       return false;
176     }
177     *version = 0x0102;
178     return true;
179   }
GetSrtpCryptoSuite(int * crypto_suite)180   bool GetSrtpCryptoSuite(int* crypto_suite) override {
181     if (!do_dtls_) {
182       return false;
183     }
184     *crypto_suite = crypto_suite_;
185     return true;
186   }
SetSrtpCryptoSuite(int crypto_suite)187   void SetSrtpCryptoSuite(int crypto_suite) { crypto_suite_ = crypto_suite; }
188 
GetSslCipherSuite(int * cipher_suite)189   bool GetSslCipherSuite(int* cipher_suite) override {
190     if (ssl_cipher_suite_) {
191       *cipher_suite = *ssl_cipher_suite_;
192       return true;
193     }
194     return false;
195   }
SetSslCipherSuite(absl::optional<int> cipher_suite)196   void SetSslCipherSuite(absl::optional<int> cipher_suite) {
197     ssl_cipher_suite_ = cipher_suite;
198   }
GetLocalCertificate()199   rtc::scoped_refptr<rtc::RTCCertificate> GetLocalCertificate() const override {
200     return local_cert_;
201   }
GetRemoteSSLCertChain()202   std::unique_ptr<rtc::SSLCertChain> GetRemoteSSLCertChain() const override {
203     if (!remote_cert_) {
204       return nullptr;
205     }
206     return std::make_unique<rtc::SSLCertChain>(remote_cert_->Clone());
207   }
ExportKeyingMaterial(const std::string & label,const uint8_t * context,size_t context_len,bool use_context,uint8_t * result,size_t result_len)208   bool ExportKeyingMaterial(const std::string& label,
209                             const uint8_t* context,
210                             size_t context_len,
211                             bool use_context,
212                             uint8_t* result,
213                             size_t result_len) override {
214     if (!do_dtls_) {
215       return false;
216     }
217     memset(result, 0xff, result_len);
218     return true;
219   }
set_ssl_max_protocol_version(rtc::SSLProtocolVersion version)220   void set_ssl_max_protocol_version(rtc::SSLProtocolVersion version) {
221     ssl_max_version_ = version;
222   }
ssl_max_protocol_version()223   rtc::SSLProtocolVersion ssl_max_protocol_version() const {
224     return ssl_max_version_;
225   }
226 
ice_transport()227   IceTransportInternal* ice_transport() override { return ice_transport_; }
228 
229   // PacketTransportInternal implementation, which passes through to fake ICE
230   // transport for sending actual packets.
writable()231   bool writable() const override { return writable_; }
receiving()232   bool receiving() const override { return receiving_; }
SendPacket(const char * data,size_t len,const rtc::PacketOptions & options,int flags)233   int SendPacket(const char* data,
234                  size_t len,
235                  const rtc::PacketOptions& options,
236                  int flags) override {
237     // We expect only SRTP packets to be sent through this interface.
238     if (flags != PF_SRTP_BYPASS && flags != 0) {
239       return -1;
240     }
241     return ice_transport_->SendPacket(data, len, options, flags);
242   }
SetOption(rtc::Socket::Option opt,int value)243   int SetOption(rtc::Socket::Option opt, int value) override {
244     return ice_transport_->SetOption(opt, value);
245   }
GetOption(rtc::Socket::Option opt,int * value)246   bool GetOption(rtc::Socket::Option opt, int* value) override {
247     return ice_transport_->GetOption(opt, value);
248   }
GetError()249   int GetError() override { return ice_transport_->GetError(); }
250 
network_route()251   absl::optional<rtc::NetworkRoute> network_route() const override {
252     return ice_transport_->network_route();
253   }
254 
255  private:
OnIceTransportReadPacket(PacketTransportInternal * ice_,const char * data,size_t len,const int64_t & packet_time_us,int flags)256   void OnIceTransportReadPacket(PacketTransportInternal* ice_,
257                                 const char* data,
258                                 size_t len,
259                                 const int64_t& packet_time_us,
260                                 int flags) {
261     SignalReadPacket(this, data, len, packet_time_us, flags);
262   }
263 
set_receiving(bool receiving)264   void set_receiving(bool receiving) {
265     if (receiving_ == receiving) {
266       return;
267     }
268     receiving_ = receiving;
269     SignalReceivingState(this);
270   }
271 
set_writable(bool writable)272   void set_writable(bool writable) {
273     if (writable_ == writable) {
274       return;
275     }
276     writable_ = writable;
277     if (writable_) {
278       SignalReadyToSend(this);
279     }
280     SignalWritableState(this);
281   }
282 
OnNetworkRouteChanged(absl::optional<rtc::NetworkRoute> network_route)283   void OnNetworkRouteChanged(absl::optional<rtc::NetworkRoute> network_route) {
284     SignalNetworkRouteChanged(network_route);
285   }
286 
287   FakeIceTransport* ice_transport_;
288   std::unique_ptr<FakeIceTransport> owned_ice_transport_;
289   std::string transport_name_;
290   int component_;
291   FakeDtlsTransport* dest_ = nullptr;
292   rtc::scoped_refptr<rtc::RTCCertificate> local_cert_;
293   rtc::FakeSSLCertificate* remote_cert_ = nullptr;
294   bool do_dtls_ = false;
295   rtc::SSLProtocolVersion ssl_max_version_ = rtc::SSL_PROTOCOL_DTLS_12;
296   rtc::SSLFingerprint dtls_fingerprint_;
297   absl::optional<rtc::SSLRole> dtls_role_;
298   int crypto_suite_ = rtc::SRTP_AES128_CM_SHA1_80;
299   absl::optional<int> ssl_cipher_suite_;
300   webrtc::CryptoOptions crypto_options_;
301 
302   DtlsTransportState dtls_state_ = DTLS_TRANSPORT_NEW;
303 
304   bool receiving_ = false;
305   bool writable_ = false;
306 };
307 
308 }  // namespace cricket
309 
310 #endif  // P2P_BASE_FAKE_DTLS_TRANSPORT_H_
311