| OLD | NEW |
| (Empty) |
| 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 <memory> | |
| 15 #include <string> | |
| 16 #include <vector> | |
| 17 | |
| 18 #include "webrtc/p2p/base/dtlstransportinternal.h" | |
| 19 #include "webrtc/p2p/base/icetransportinternal.h" | |
| 20 #include "webrtc/rtc_base/buffer.h" | |
| 21 #include "webrtc/rtc_base/bufferqueue.h" | |
| 22 #include "webrtc/rtc_base/constructormagic.h" | |
| 23 #include "webrtc/rtc_base/sslstreamadapter.h" | |
| 24 #include "webrtc/rtc_base/stream.h" | |
| 25 | |
| 26 namespace rtc { | |
| 27 class PacketTransportInternal; | |
| 28 } | |
| 29 | |
| 30 namespace cricket { | |
| 31 | |
| 32 // A bridge between a packet-oriented/transport-type interface on | |
| 33 // the bottom and a StreamInterface on the top. | |
| 34 class StreamInterfaceChannel : public rtc::StreamInterface { | |
| 35 public: | |
| 36 explicit StreamInterfaceChannel(IceTransportInternal* ice_transport); | |
| 37 | |
| 38 // Push in a packet; this gets pulled out from Read(). | |
| 39 bool OnPacketReceived(const char* data, size_t size); | |
| 40 | |
| 41 // Implementations of StreamInterface | |
| 42 rtc::StreamState GetState() const override { return state_; } | |
| 43 void Close() override; | |
| 44 rtc::StreamResult Read(void* buffer, | |
| 45 size_t buffer_len, | |
| 46 size_t* read, | |
| 47 int* error) override; | |
| 48 rtc::StreamResult Write(const void* data, | |
| 49 size_t data_len, | |
| 50 size_t* written, | |
| 51 int* error) override; | |
| 52 | |
| 53 private: | |
| 54 IceTransportInternal* ice_transport_; // owned by DtlsTransport | |
| 55 rtc::StreamState state_; | |
| 56 rtc::BufferQueue packets_; | |
| 57 | |
| 58 RTC_DISALLOW_COPY_AND_ASSIGN(StreamInterfaceChannel); | |
| 59 }; | |
| 60 | |
| 61 | |
| 62 // This class provides a DTLS SSLStreamAdapter inside a TransportChannel-style | |
| 63 // packet-based interface, wrapping an existing TransportChannel instance | |
| 64 // (e.g a P2PTransportChannel) | |
| 65 // Here's the way this works: | |
| 66 // | |
| 67 // DtlsTransport { | |
| 68 // SSLStreamAdapter* dtls_ { | |
| 69 // StreamInterfaceChannel downward_ { | |
| 70 // IceTransportInternal* ice_transport_; | |
| 71 // } | |
| 72 // } | |
| 73 // } | |
| 74 // | |
| 75 // - Data which comes into DtlsTransport from the underlying | |
| 76 // ice_transport_ via OnReadPacket() is checked for whether it is DTLS | |
| 77 // or not, and if it is, is passed to DtlsTransport::HandleDtlsPacket, | |
| 78 // which pushes it into to downward_. dtls_ is listening for events on | |
| 79 // downward_, so it immediately calls downward_->Read(). | |
| 80 // | |
| 81 // - Data written to DtlsTransport is passed either to downward_ or directly | |
| 82 // to ice_transport_, depending on whether DTLS is negotiated and whether | |
| 83 // the flags include PF_SRTP_BYPASS | |
| 84 // | |
| 85 // - The SSLStreamAdapter writes to downward_->Write() which translates it | |
| 86 // into packet writes on ice_transport_. | |
| 87 class DtlsTransport : public DtlsTransportInternal { | |
| 88 public: | |
| 89 // |ice_transport| is the ICE transport this DTLS transport is wrapping. | |
| 90 // | |
| 91 // |crypto_options| are the options used for the DTLS handshake. This affects | |
| 92 // whether GCM crypto suites are negotiated. | |
| 93 explicit DtlsTransport(IceTransportInternal* ice_transport, | |
| 94 const rtc::CryptoOptions& crypto_options); | |
| 95 ~DtlsTransport() override; | |
| 96 | |
| 97 const rtc::CryptoOptions& crypto_options() const override { | |
| 98 return crypto_options_; | |
| 99 } | |
| 100 | |
| 101 DtlsTransportState dtls_state() const override { return dtls_state_; } | |
| 102 | |
| 103 const std::string& transport_name() const override { return transport_name_; } | |
| 104 | |
| 105 int component() const override { return component_; } | |
| 106 | |
| 107 // Returns false if no local certificate was set, or if the peer doesn't | |
| 108 // support DTLS. | |
| 109 bool IsDtlsActive() const override { return dtls_active_; } | |
| 110 | |
| 111 bool SetLocalCertificate( | |
| 112 const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) override; | |
| 113 rtc::scoped_refptr<rtc::RTCCertificate> GetLocalCertificate() const override; | |
| 114 | |
| 115 bool SetRemoteFingerprint(const std::string& digest_alg, | |
| 116 const uint8_t* digest, | |
| 117 size_t digest_len) override; | |
| 118 | |
| 119 | |
| 120 // Called to send a packet (via DTLS, if turned on). | |
| 121 int SendPacket(const char* data, | |
| 122 size_t size, | |
| 123 const rtc::PacketOptions& options, | |
| 124 int flags) override; | |
| 125 | |
| 126 bool GetOption(rtc::Socket::Option opt, int* value) override { | |
| 127 return ice_transport_->GetOption(opt, value); | |
| 128 } | |
| 129 | |
| 130 virtual bool SetSslMaxProtocolVersion(rtc::SSLProtocolVersion version); | |
| 131 | |
| 132 // Find out which DTLS-SRTP cipher was negotiated | |
| 133 bool GetSrtpCryptoSuite(int* cipher) override; | |
| 134 | |
| 135 bool GetSslRole(rtc::SSLRole* role) const override; | |
| 136 bool SetSslRole(rtc::SSLRole role) override; | |
| 137 | |
| 138 // Find out which DTLS cipher was negotiated | |
| 139 bool GetSslCipherSuite(int* cipher) override; | |
| 140 | |
| 141 // Once DTLS has been established, this method retrieves the certificate in | |
| 142 // use by the remote peer, for use in external identity verification. | |
| 143 std::unique_ptr<rtc::SSLCertificate> GetRemoteSSLCertificate() const override; | |
| 144 | |
| 145 // Once DTLS has established (i.e., this ice_transport is writable), this | |
| 146 // method extracts the keys negotiated during the DTLS handshake, for use in | |
| 147 // external encryption. DTLS-SRTP uses this to extract the needed SRTP keys. | |
| 148 // See the SSLStreamAdapter documentation for info on the specific parameters. | |
| 149 bool ExportKeyingMaterial(const std::string& label, | |
| 150 const uint8_t* context, | |
| 151 size_t context_len, | |
| 152 bool use_context, | |
| 153 uint8_t* result, | |
| 154 size_t result_len) override { | |
| 155 return (dtls_.get()) ? dtls_->ExportKeyingMaterial(label, context, | |
| 156 context_len, | |
| 157 use_context, | |
| 158 result, result_len) | |
| 159 : false; | |
| 160 } | |
| 161 | |
| 162 IceTransportInternal* ice_transport() override { return ice_transport_; } | |
| 163 | |
| 164 // For informational purposes. Tells if the DTLS handshake has finished. | |
| 165 // This may be true even if writable() is false, if the remote fingerprint | |
| 166 // has not yet been verified. | |
| 167 bool IsDtlsConnected(); | |
| 168 | |
| 169 bool receiving() const override { return receiving_; } | |
| 170 | |
| 171 bool writable() const override { return writable_; } | |
| 172 | |
| 173 int GetError() override { return ice_transport_->GetError(); } | |
| 174 | |
| 175 int SetOption(rtc::Socket::Option opt, int value) override { | |
| 176 return ice_transport_->SetOption(opt, value); | |
| 177 } | |
| 178 | |
| 179 std::string ToString() const { | |
| 180 const char RECEIVING_ABBREV[2] = {'_', 'R'}; | |
| 181 const char WRITABLE_ABBREV[2] = {'_', 'W'}; | |
| 182 std::stringstream ss; | |
| 183 ss << "DtlsTransport[" << transport_name_ << "|" << component_ << "|" | |
| 184 << RECEIVING_ABBREV[receiving()] << WRITABLE_ABBREV[writable()] << "]"; | |
| 185 return ss.str(); | |
| 186 } | |
| 187 | |
| 188 private: | |
| 189 void OnWritableState(rtc::PacketTransportInternal* transport); | |
| 190 void OnReadPacket(rtc::PacketTransportInternal* transport, | |
| 191 const char* data, | |
| 192 size_t size, | |
| 193 const rtc::PacketTime& packet_time, | |
| 194 int flags); | |
| 195 void OnSentPacket(rtc::PacketTransportInternal* transport, | |
| 196 const rtc::SentPacket& sent_packet); | |
| 197 void OnReadyToSend(rtc::PacketTransportInternal* transport); | |
| 198 void OnReceivingState(rtc::PacketTransportInternal* transport); | |
| 199 void OnDtlsEvent(rtc::StreamInterface* stream_, int sig, int err); | |
| 200 bool SetupDtls(); | |
| 201 void MaybeStartDtls(); | |
| 202 bool HandleDtlsPacket(const char* data, size_t size); | |
| 203 void OnDtlsHandshakeError(rtc::SSLHandshakeError error); | |
| 204 void ConfigureHandshakeTimeout(); | |
| 205 | |
| 206 void set_receiving(bool receiving); | |
| 207 void set_writable(bool writable); | |
| 208 // Sets the DTLS state, signaling if necessary. | |
| 209 void set_dtls_state(DtlsTransportState state); | |
| 210 | |
| 211 std::string transport_name_; | |
| 212 int component_; | |
| 213 DtlsTransportState dtls_state_ = DTLS_TRANSPORT_NEW; | |
| 214 rtc::Thread* network_thread_; // Everything should occur on this thread. | |
| 215 // Underlying ice_transport, not owned by this class. | |
| 216 IceTransportInternal* const ice_transport_; | |
| 217 std::unique_ptr<rtc::SSLStreamAdapter> dtls_; // The DTLS stream | |
| 218 StreamInterfaceChannel* | |
| 219 downward_; // Wrapper for ice_transport_, owned by dtls_. | |
| 220 std::vector<int> srtp_ciphers_; // SRTP ciphers to use with DTLS. | |
| 221 bool dtls_active_ = false; | |
| 222 rtc::scoped_refptr<rtc::RTCCertificate> local_certificate_; | |
| 223 rtc::SSLRole ssl_role_; | |
| 224 rtc::SSLProtocolVersion ssl_max_version_; | |
| 225 rtc::CryptoOptions crypto_options_; | |
| 226 rtc::Buffer remote_fingerprint_value_; | |
| 227 std::string remote_fingerprint_algorithm_; | |
| 228 | |
| 229 // Cached DTLS ClientHello packet that was received before we started the | |
| 230 // DTLS handshake. This could happen if the hello was received before the | |
| 231 // ice transport became writable, or before a remote fingerprint was received. | |
| 232 rtc::Buffer cached_client_hello_; | |
| 233 | |
| 234 bool receiving_ = false; | |
| 235 bool writable_ = false; | |
| 236 | |
| 237 RTC_DISALLOW_COPY_AND_ASSIGN(DtlsTransport); | |
| 238 }; | |
| 239 | |
| 240 } // namespace cricket | |
| 241 | |
| 242 #endif // WEBRTC_P2P_BASE_DTLSTRANSPORTCHANNEL_H_ | |
| OLD | NEW |