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 PC_SRTP_TRANSPORT_H_ 12 #define PC_SRTP_TRANSPORT_H_ 13 14 #include <stddef.h> 15 16 #include <cstdint> 17 #include <memory> 18 #include <string> 19 #include <vector> 20 21 #include "absl/types/optional.h" 22 #include "api/crypto_params.h" 23 #include "api/field_trials_view.h" 24 #include "api/rtc_error.h" 25 #include "p2p/base/packet_transport_internal.h" 26 #include "pc/rtp_transport.h" 27 #include "pc/srtp_session.h" 28 #include "rtc_base/async_packet_socket.h" 29 #include "rtc_base/buffer.h" 30 #include "rtc_base/copy_on_write_buffer.h" 31 #include "rtc_base/network_route.h" 32 33 namespace webrtc { 34 35 // This subclass of the RtpTransport is used for SRTP which is reponsible for 36 // protecting/unprotecting the packets. It provides interfaces to set the crypto 37 // parameters for the SrtpSession underneath. 38 class SrtpTransport : public RtpTransport { 39 public: 40 SrtpTransport(bool rtcp_mux_enabled, const FieldTrialsView& field_trials); 41 42 virtual ~SrtpTransport() = default; 43 44 virtual RTCError SetSrtpSendKey(const cricket::CryptoParams& params); 45 virtual RTCError SetSrtpReceiveKey(const cricket::CryptoParams& params); 46 47 bool SendRtpPacket(rtc::CopyOnWriteBuffer* packet, 48 const rtc::PacketOptions& options, 49 int flags) override; 50 51 bool SendRtcpPacket(rtc::CopyOnWriteBuffer* packet, 52 const rtc::PacketOptions& options, 53 int flags) override; 54 55 // The transport becomes active if the send_session_ and recv_session_ are 56 // created. 57 bool IsSrtpActive() const override; 58 59 bool IsWritable(bool rtcp) const override; 60 61 // Create new send/recv sessions and set the negotiated crypto keys for RTP 62 // packet encryption. The keys can either come from SDES negotiation or DTLS 63 // handshake. 64 bool SetRtpParams(int send_cs, 65 const uint8_t* send_key, 66 int send_key_len, 67 const std::vector<int>& send_extension_ids, 68 int recv_cs, 69 const uint8_t* recv_key, 70 int recv_key_len, 71 const std::vector<int>& recv_extension_ids); 72 73 // Create new send/recv sessions and set the negotiated crypto keys for RTCP 74 // packet encryption. The keys can either come from SDES negotiation or DTLS 75 // handshake. 76 bool SetRtcpParams(int send_cs, 77 const uint8_t* send_key, 78 int send_key_len, 79 const std::vector<int>& send_extension_ids, 80 int recv_cs, 81 const uint8_t* recv_key, 82 int recv_key_len, 83 const std::vector<int>& recv_extension_ids); 84 85 void ResetParams(); 86 87 // If external auth is enabled, SRTP will write a dummy auth tag that then 88 // later must get replaced before the packet is sent out. Only supported for 89 // non-GCM cipher suites and can be checked through "IsExternalAuthActive" 90 // if it is actually used. This method is only valid before the RTP params 91 // have been set. 92 void EnableExternalAuth(); 93 bool IsExternalAuthEnabled() const; 94 95 // A SrtpTransport supports external creation of the auth tag if a non-GCM 96 // cipher is used. This method is only valid after the RTP params have 97 // been set. 98 bool IsExternalAuthActive() const; 99 100 // Returns srtp overhead for rtp packets. 101 bool GetSrtpOverhead(int* srtp_overhead) const; 102 103 // Returns rtp auth params from srtp context. 104 bool GetRtpAuthParams(uint8_t** key, int* key_len, int* tag_len); 105 106 // Cache RTP Absoulute SendTime extension header ID. This is only used when 107 // external authentication is enabled. CacheRtpAbsSendTimeHeaderExtension(int rtp_abs_sendtime_extn_id)108 void CacheRtpAbsSendTimeHeaderExtension(int rtp_abs_sendtime_extn_id) { 109 rtp_abs_sendtime_extn_id_ = rtp_abs_sendtime_extn_id; 110 } 111 112 protected: 113 // If the writable state changed, fire the SignalWritableState. 114 void MaybeUpdateWritableState(); 115 116 private: 117 void ConnectToRtpTransport(); 118 void CreateSrtpSessions(); 119 120 void OnRtpPacketReceived(rtc::CopyOnWriteBuffer packet, 121 int64_t packet_time_us) override; 122 void OnRtcpPacketReceived(rtc::CopyOnWriteBuffer packet, 123 int64_t packet_time_us) override; 124 void OnNetworkRouteChanged( 125 absl::optional<rtc::NetworkRoute> network_route) override; 126 127 // Override the RtpTransport::OnWritableState. 128 void OnWritableState(rtc::PacketTransportInternal* packet_transport) override; 129 130 bool ProtectRtp(void* data, int in_len, int max_len, int* out_len); 131 132 // Overloaded version, outputs packet index. 133 bool ProtectRtp(void* data, 134 int in_len, 135 int max_len, 136 int* out_len, 137 int64_t* index); 138 bool ProtectRtcp(void* data, int in_len, int max_len, int* out_len); 139 140 // Decrypts/verifies an invidiual RTP/RTCP packet. 141 // If an HMAC is used, this will decrease the packet size. 142 bool UnprotectRtp(void* data, int in_len, int* out_len); 143 144 bool UnprotectRtcp(void* data, int in_len, int* out_len); 145 146 bool MaybeSetKeyParams(); 147 bool ParseKeyParams(const std::string& key_params, uint8_t* key, size_t len); 148 149 const std::string content_name_; 150 151 std::unique_ptr<cricket::SrtpSession> send_session_; 152 std::unique_ptr<cricket::SrtpSession> recv_session_; 153 std::unique_ptr<cricket::SrtpSession> send_rtcp_session_; 154 std::unique_ptr<cricket::SrtpSession> recv_rtcp_session_; 155 156 absl::optional<cricket::CryptoParams> send_params_; 157 absl::optional<cricket::CryptoParams> recv_params_; 158 absl::optional<int> send_cipher_suite_; 159 absl::optional<int> recv_cipher_suite_; 160 rtc::ZeroOnFreeBuffer<uint8_t> send_key_; 161 rtc::ZeroOnFreeBuffer<uint8_t> recv_key_; 162 163 bool writable_ = false; 164 165 bool external_auth_enabled_ = false; 166 167 int rtp_abs_sendtime_extn_id_ = -1; 168 169 int decryption_failure_count_ = 0; 170 171 const FieldTrialsView& field_trials_; 172 }; 173 174 } // namespace webrtc 175 176 #endif // PC_SRTP_TRANSPORT_H_ 177