1 /* 2 * Copyright 2016 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_INTERNAL_H_ 12 #define P2P_BASE_DTLS_TRANSPORT_INTERNAL_H_ 13 14 #include <stddef.h> 15 #include <stdint.h> 16 17 #include <memory> 18 #include <string> 19 #include <utility> 20 21 #include "absl/base/attributes.h" 22 #include "absl/strings/string_view.h" 23 #include "api/crypto/crypto_options.h" 24 #include "api/dtls_transport_interface.h" 25 #include "api/scoped_refptr.h" 26 #include "p2p/base/ice_transport_internal.h" 27 #include "p2p/base/packet_transport_internal.h" 28 #include "rtc_base/callback_list.h" 29 #include "rtc_base/ssl_certificate.h" 30 #include "rtc_base/ssl_fingerprint.h" 31 #include "rtc_base/ssl_stream_adapter.h" 32 33 namespace cricket { 34 35 enum PacketFlags { 36 PF_NORMAL = 0x00, // A normal packet. 37 PF_SRTP_BYPASS = 0x01, // An encrypted SRTP packet; bypass any additional 38 // crypto provided by the transport (e.g. DTLS) 39 }; 40 41 // DtlsTransportInternal is an internal interface that does DTLS, also 42 // negotiating SRTP crypto suites so that it may be used for DTLS-SRTP. 43 // 44 // Once the public interface is supported, 45 // (https://www.w3.org/TR/webrtc/#rtcdtlstransport-interface) 46 // the DtlsTransportInterface will be split from this class. 47 class DtlsTransportInternal : public rtc::PacketTransportInternal { 48 public: 49 ~DtlsTransportInternal() override; 50 51 DtlsTransportInternal(const DtlsTransportInternal&) = delete; 52 DtlsTransportInternal& operator=(const DtlsTransportInternal&) = delete; 53 54 virtual webrtc::DtlsTransportState dtls_state() const = 0; 55 56 virtual int component() const = 0; 57 58 virtual bool IsDtlsActive() const = 0; 59 60 virtual bool GetDtlsRole(rtc::SSLRole* role) const = 0; 61 62 virtual bool SetDtlsRole(rtc::SSLRole role) = 0; 63 64 // Finds out which TLS/DTLS version is running. 65 virtual bool GetSslVersionBytes(int* version) const = 0; 66 // Finds out which DTLS-SRTP cipher was negotiated. 67 // TODO(zhihuang): Remove this once all dependencies implement this. 68 virtual bool GetSrtpCryptoSuite(int* cipher) = 0; 69 70 // Finds out which DTLS cipher was negotiated. 71 // TODO(zhihuang): Remove this once all dependencies implement this. 72 virtual bool GetSslCipherSuite(int* cipher) = 0; 73 74 // Gets the local RTCCertificate used for DTLS. 75 virtual rtc::scoped_refptr<rtc::RTCCertificate> GetLocalCertificate() 76 const = 0; 77 78 virtual bool SetLocalCertificate( 79 const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) = 0; 80 81 // Gets a copy of the remote side's SSL certificate chain. 82 virtual std::unique_ptr<rtc::SSLCertChain> GetRemoteSSLCertChain() const = 0; 83 84 // Allows key material to be extracted for external encryption. 85 virtual bool ExportKeyingMaterial(absl::string_view label, 86 const uint8_t* context, 87 size_t context_len, 88 bool use_context, 89 uint8_t* result, 90 size_t result_len) = 0; 91 92 // Set DTLS remote fingerprint. Must be after local identity set. 93 ABSL_DEPRECATED("Use SetRemoteParameters instead.") 94 virtual bool SetRemoteFingerprint(absl::string_view digest_alg, 95 const uint8_t* digest, 96 size_t digest_len) = 0; 97 98 // Set DTLS remote fingerprint and role. Must be after local identity set. 99 virtual webrtc::RTCError SetRemoteParameters( 100 absl::string_view digest_alg, 101 const uint8_t* digest, 102 size_t digest_len, 103 absl::optional<rtc::SSLRole> role) = 0; 104 105 ABSL_DEPRECATED("Set the max version via construction.") SetSslMaxProtocolVersion(rtc::SSLProtocolVersion version)106 bool SetSslMaxProtocolVersion(rtc::SSLProtocolVersion version) { 107 return true; 108 } 109 110 // Expose the underneath IceTransport. 111 virtual IceTransportInternal* ice_transport() = 0; 112 113 // F: void(DtlsTransportInternal*, const webrtc::DtlsTransportState) 114 template <typename F> SubscribeDtlsTransportState(F && callback)115 void SubscribeDtlsTransportState(F&& callback) { 116 dtls_transport_state_callback_list_.AddReceiver(std::forward<F>(callback)); 117 } 118 119 template <typename F> SubscribeDtlsTransportState(const void * id,F && callback)120 void SubscribeDtlsTransportState(const void* id, F&& callback) { 121 dtls_transport_state_callback_list_.AddReceiver(id, 122 std::forward<F>(callback)); 123 } 124 // Unsubscribe the subscription with given id. UnsubscribeDtlsTransportState(const void * id)125 void UnsubscribeDtlsTransportState(const void* id) { 126 dtls_transport_state_callback_list_.RemoveReceivers(id); 127 } 128 SendDtlsState(DtlsTransportInternal * transport,webrtc::DtlsTransportState state)129 void SendDtlsState(DtlsTransportInternal* transport, 130 webrtc::DtlsTransportState state) { 131 dtls_transport_state_callback_list_.Send(transport, state); 132 } 133 134 // Emitted whenever the Dtls handshake failed on some transport channel. 135 // F: void(rtc::SSLHandshakeError) 136 template <typename F> SubscribeDtlsHandshakeError(F && callback)137 void SubscribeDtlsHandshakeError(F&& callback) { 138 dtls_handshake_error_callback_list_.AddReceiver(std::forward<F>(callback)); 139 } 140 SendDtlsHandshakeError(rtc::SSLHandshakeError error)141 void SendDtlsHandshakeError(rtc::SSLHandshakeError error) { 142 dtls_handshake_error_callback_list_.Send(error); 143 } 144 145 protected: 146 DtlsTransportInternal(); 147 148 private: 149 webrtc::CallbackList<const rtc::SSLHandshakeError> 150 dtls_handshake_error_callback_list_; 151 webrtc::CallbackList<DtlsTransportInternal*, const webrtc::DtlsTransportState> 152 dtls_transport_state_callback_list_; 153 }; 154 155 } // namespace cricket 156 157 #endif // P2P_BASE_DTLS_TRANSPORT_INTERNAL_H_ 158