| OLD | NEW |
| 1 /* | 1 /* |
| 2 * libjingle | 2 * libjingle |
| 3 * Copyright 2009 Google Inc. | 3 * Copyright 2009 Google Inc. |
| 4 * | 4 * |
| 5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
| 6 * modification, are permitted provided that the following conditions are met: | 6 * modification, are permitted provided that the following conditions are met: |
| 7 * | 7 * |
| 8 * 1. Redistributions of source code must retain the above copyright notice, | 8 * 1. Redistributions of source code must retain the above copyright notice, |
| 9 * this list of conditions and the following disclaimer. | 9 * this list of conditions and the following disclaimer. |
| 10 * 2. Redistributions in binary form must reproduce the above copyright notice, | 10 * 2. Redistributions in binary form must reproduce the above copyright notice, |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 98 // answer_params should contain the negotiated parameters, which may be none, | 98 // answer_params should contain the negotiated parameters, which may be none, |
| 99 // if crypto was not desired or could not be negotiated (and not required). | 99 // if crypto was not desired or could not be negotiated (and not required). |
| 100 // This must be called after SetOffer. If crypto negotiation completes | 100 // This must be called after SetOffer. If crypto negotiation completes |
| 101 // successfully, this will advance the filter to the active state. | 101 // successfully, this will advance the filter to the active state. |
| 102 bool SetAnswer(const std::vector<CryptoParams>& answer_params, | 102 bool SetAnswer(const std::vector<CryptoParams>& answer_params, |
| 103 ContentSource source); | 103 ContentSource source); |
| 104 | 104 |
| 105 // Just set up both sets of keys directly. | 105 // Just set up both sets of keys directly. |
| 106 // Used with DTLS-SRTP. | 106 // Used with DTLS-SRTP. |
| 107 bool SetRtpParams(const std::string& send_cs, | 107 bool SetRtpParams(const std::string& send_cs, |
| 108 const uint8* send_key, int send_key_len, | 108 const uint8_t* send_key, |
| 109 int send_key_len, |
| 109 const std::string& recv_cs, | 110 const std::string& recv_cs, |
| 110 const uint8* recv_key, int recv_key_len); | 111 const uint8_t* recv_key, |
| 112 int recv_key_len); |
| 111 bool SetRtcpParams(const std::string& send_cs, | 113 bool SetRtcpParams(const std::string& send_cs, |
| 112 const uint8* send_key, int send_key_len, | 114 const uint8_t* send_key, |
| 115 int send_key_len, |
| 113 const std::string& recv_cs, | 116 const std::string& recv_cs, |
| 114 const uint8* recv_key, int recv_key_len); | 117 const uint8_t* recv_key, |
| 118 int recv_key_len); |
| 115 | 119 |
| 116 // Encrypts/signs an individual RTP/RTCP packet, in-place. | 120 // Encrypts/signs an individual RTP/RTCP packet, in-place. |
| 117 // If an HMAC is used, this will increase the packet size. | 121 // If an HMAC is used, this will increase the packet size. |
| 118 bool ProtectRtp(void* data, int in_len, int max_len, int* out_len); | 122 bool ProtectRtp(void* data, int in_len, int max_len, int* out_len); |
| 119 // Overloaded version, outputs packet index. | 123 // Overloaded version, outputs packet index. |
| 120 bool ProtectRtp(void* data, int in_len, int max_len, int* out_len, | 124 bool ProtectRtp(void* data, |
| 121 int64* index); | 125 int in_len, |
| 126 int max_len, |
| 127 int* out_len, |
| 128 int64_t* index); |
| 122 bool ProtectRtcp(void* data, int in_len, int max_len, int* out_len); | 129 bool ProtectRtcp(void* data, int in_len, int max_len, int* out_len); |
| 123 // Decrypts/verifies an invidiual RTP/RTCP packet. | 130 // Decrypts/verifies an invidiual RTP/RTCP packet. |
| 124 // If an HMAC is used, this will decrease the packet size. | 131 // If an HMAC is used, this will decrease the packet size. |
| 125 bool UnprotectRtp(void* data, int in_len, int* out_len); | 132 bool UnprotectRtp(void* data, int in_len, int* out_len); |
| 126 bool UnprotectRtcp(void* data, int in_len, int* out_len); | 133 bool UnprotectRtcp(void* data, int in_len, int* out_len); |
| 127 | 134 |
| 128 // Returns rtp auth params from srtp context. | 135 // Returns rtp auth params from srtp context. |
| 129 bool GetRtpAuthParams(uint8** key, int* key_len, int* tag_len); | 136 bool GetRtpAuthParams(uint8_t** key, int* key_len, int* tag_len); |
| 130 | 137 |
| 131 // Update the silent threshold (in ms) for signaling errors. | 138 // Update the silent threshold (in ms) for signaling errors. |
| 132 void set_signal_silent_time(uint32 signal_silent_time_in_ms); | 139 void set_signal_silent_time(uint32_t signal_silent_time_in_ms); |
| 133 | 140 |
| 134 sigslot::repeater3<uint32, Mode, Error> SignalSrtpError; | 141 sigslot::repeater3<uint32_t, Mode, Error> SignalSrtpError; |
| 135 | 142 |
| 136 protected: | 143 protected: |
| 137 bool ExpectOffer(ContentSource source); | 144 bool ExpectOffer(ContentSource source); |
| 138 bool StoreParams(const std::vector<CryptoParams>& params, | 145 bool StoreParams(const std::vector<CryptoParams>& params, |
| 139 ContentSource source); | 146 ContentSource source); |
| 140 bool ExpectAnswer(ContentSource source); | 147 bool ExpectAnswer(ContentSource source); |
| 141 bool DoSetAnswer(const std::vector<CryptoParams>& answer_params, | 148 bool DoSetAnswer(const std::vector<CryptoParams>& answer_params, |
| 142 ContentSource source, | 149 ContentSource source, |
| 143 bool final); | 150 bool final); |
| 144 void CreateSrtpSessions(); | 151 void CreateSrtpSessions(); |
| 145 bool NegotiateParams(const std::vector<CryptoParams>& answer_params, | 152 bool NegotiateParams(const std::vector<CryptoParams>& answer_params, |
| 146 CryptoParams* selected_params); | 153 CryptoParams* selected_params); |
| 147 bool ApplyParams(const CryptoParams& send_params, | 154 bool ApplyParams(const CryptoParams& send_params, |
| 148 const CryptoParams& recv_params); | 155 const CryptoParams& recv_params); |
| 149 bool ResetParams(); | 156 bool ResetParams(); |
| 150 static bool ParseKeyParams(const std::string& params, uint8* key, int len); | 157 static bool ParseKeyParams(const std::string& params, uint8_t* key, int len); |
| 151 | 158 |
| 152 private: | 159 private: |
| 153 enum State { | 160 enum State { |
| 154 ST_INIT, // SRTP filter unused. | 161 ST_INIT, // SRTP filter unused. |
| 155 ST_SENTOFFER, // Offer with SRTP parameters sent. | 162 ST_SENTOFFER, // Offer with SRTP parameters sent. |
| 156 ST_RECEIVEDOFFER, // Offer with SRTP parameters received. | 163 ST_RECEIVEDOFFER, // Offer with SRTP parameters received. |
| 157 ST_SENTPRANSWER_NO_CRYPTO, // Sent provisional answer without crypto. | 164 ST_SENTPRANSWER_NO_CRYPTO, // Sent provisional answer without crypto. |
| 158 // Received provisional answer without crypto. | 165 // Received provisional answer without crypto. |
| 159 ST_RECEIVEDPRANSWER_NO_CRYPTO, | 166 ST_RECEIVEDPRANSWER_NO_CRYPTO, |
| 160 ST_ACTIVE, // Offer and answer set. | 167 ST_ACTIVE, // Offer and answer set. |
| 161 // SRTP filter is active but new parameters are offered. | 168 // SRTP filter is active but new parameters are offered. |
| 162 // When the answer is set, the state transitions to ST_ACTIVE or ST_INIT. | 169 // When the answer is set, the state transitions to ST_ACTIVE or ST_INIT. |
| 163 ST_SENTUPDATEDOFFER, | 170 ST_SENTUPDATEDOFFER, |
| 164 // SRTP filter is active but new parameters are received. | 171 // SRTP filter is active but new parameters are received. |
| 165 // When the answer is set, the state transitions back to ST_ACTIVE. | 172 // When the answer is set, the state transitions back to ST_ACTIVE. |
| 166 ST_RECEIVEDUPDATEDOFFER, | 173 ST_RECEIVEDUPDATEDOFFER, |
| 167 // SRTP filter is active but the sent answer is only provisional. | 174 // SRTP filter is active but the sent answer is only provisional. |
| 168 // When the final answer is set, the state transitions to ST_ACTIVE or | 175 // When the final answer is set, the state transitions to ST_ACTIVE or |
| 169 // ST_INIT. | 176 // ST_INIT. |
| 170 ST_SENTPRANSWER, | 177 ST_SENTPRANSWER, |
| 171 // SRTP filter is active but the received answer is only provisional. | 178 // SRTP filter is active but the received answer is only provisional. |
| 172 // When the final answer is set, the state transitions to ST_ACTIVE or | 179 // When the final answer is set, the state transitions to ST_ACTIVE or |
| 173 // ST_INIT. | 180 // ST_INIT. |
| 174 ST_RECEIVEDPRANSWER | 181 ST_RECEIVEDPRANSWER |
| 175 }; | 182 }; |
| 176 State state_; | 183 State state_; |
| 177 uint32 signal_silent_time_in_ms_; | 184 uint32_t signal_silent_time_in_ms_; |
| 178 std::vector<CryptoParams> offer_params_; | 185 std::vector<CryptoParams> offer_params_; |
| 179 rtc::scoped_ptr<SrtpSession> send_session_; | 186 rtc::scoped_ptr<SrtpSession> send_session_; |
| 180 rtc::scoped_ptr<SrtpSession> recv_session_; | 187 rtc::scoped_ptr<SrtpSession> recv_session_; |
| 181 rtc::scoped_ptr<SrtpSession> send_rtcp_session_; | 188 rtc::scoped_ptr<SrtpSession> send_rtcp_session_; |
| 182 rtc::scoped_ptr<SrtpSession> recv_rtcp_session_; | 189 rtc::scoped_ptr<SrtpSession> recv_rtcp_session_; |
| 183 CryptoParams applied_send_params_; | 190 CryptoParams applied_send_params_; |
| 184 CryptoParams applied_recv_params_; | 191 CryptoParams applied_recv_params_; |
| 185 }; | 192 }; |
| 186 | 193 |
| 187 // Class that wraps a libSRTP session. | 194 // Class that wraps a libSRTP session. |
| 188 class SrtpSession { | 195 class SrtpSession { |
| 189 public: | 196 public: |
| 190 SrtpSession(); | 197 SrtpSession(); |
| 191 ~SrtpSession(); | 198 ~SrtpSession(); |
| 192 | 199 |
| 193 // Configures the session for sending data using the specified | 200 // Configures the session for sending data using the specified |
| 194 // cipher-suite and key. Receiving must be done by a separate session. | 201 // cipher-suite and key. Receiving must be done by a separate session. |
| 195 bool SetSend(const std::string& cs, const uint8* key, int len); | 202 bool SetSend(const std::string& cs, const uint8_t* key, int len); |
| 196 // Configures the session for receiving data using the specified | 203 // Configures the session for receiving data using the specified |
| 197 // cipher-suite and key. Sending must be done by a separate session. | 204 // cipher-suite and key. Sending must be done by a separate session. |
| 198 bool SetRecv(const std::string& cs, const uint8* key, int len); | 205 bool SetRecv(const std::string& cs, const uint8_t* key, int len); |
| 199 | 206 |
| 200 // Encrypts/signs an individual RTP/RTCP packet, in-place. | 207 // Encrypts/signs an individual RTP/RTCP packet, in-place. |
| 201 // If an HMAC is used, this will increase the packet size. | 208 // If an HMAC is used, this will increase the packet size. |
| 202 bool ProtectRtp(void* data, int in_len, int max_len, int* out_len); | 209 bool ProtectRtp(void* data, int in_len, int max_len, int* out_len); |
| 203 // Overloaded version, outputs packet index. | 210 // Overloaded version, outputs packet index. |
| 204 bool ProtectRtp(void* data, int in_len, int max_len, int* out_len, | 211 bool ProtectRtp(void* data, |
| 205 int64* index); | 212 int in_len, |
| 213 int max_len, |
| 214 int* out_len, |
| 215 int64_t* index); |
| 206 bool ProtectRtcp(void* data, int in_len, int max_len, int* out_len); | 216 bool ProtectRtcp(void* data, int in_len, int max_len, int* out_len); |
| 207 // Decrypts/verifies an invidiual RTP/RTCP packet. | 217 // Decrypts/verifies an invidiual RTP/RTCP packet. |
| 208 // If an HMAC is used, this will decrease the packet size. | 218 // If an HMAC is used, this will decrease the packet size. |
| 209 bool UnprotectRtp(void* data, int in_len, int* out_len); | 219 bool UnprotectRtp(void* data, int in_len, int* out_len); |
| 210 bool UnprotectRtcp(void* data, int in_len, int* out_len); | 220 bool UnprotectRtcp(void* data, int in_len, int* out_len); |
| 211 | 221 |
| 212 // Helper method to get authentication params. | 222 // Helper method to get authentication params. |
| 213 bool GetRtpAuthParams(uint8** key, int* key_len, int* tag_len); | 223 bool GetRtpAuthParams(uint8_t** key, int* key_len, int* tag_len); |
| 214 | 224 |
| 215 // Update the silent threshold (in ms) for signaling errors. | 225 // Update the silent threshold (in ms) for signaling errors. |
| 216 void set_signal_silent_time(uint32 signal_silent_time_in_ms); | 226 void set_signal_silent_time(uint32_t signal_silent_time_in_ms); |
| 217 | 227 |
| 218 // Calls srtp_shutdown if it's initialized. | 228 // Calls srtp_shutdown if it's initialized. |
| 219 static void Terminate(); | 229 static void Terminate(); |
| 220 | 230 |
| 221 sigslot::repeater3<uint32, SrtpFilter::Mode, SrtpFilter::Error> | 231 sigslot::repeater3<uint32_t, SrtpFilter::Mode, SrtpFilter::Error> |
| 222 SignalSrtpError; | 232 SignalSrtpError; |
| 223 | 233 |
| 224 private: | 234 private: |
| 225 bool SetKey(int type, const std::string& cs, const uint8* key, int len); | 235 bool SetKey(int type, const std::string& cs, const uint8_t* key, int len); |
| 226 // Returns send stream current packet index from srtp db. | 236 // Returns send stream current packet index from srtp db. |
| 227 bool GetSendStreamPacketIndex(void* data, int in_len, int64* index); | 237 bool GetSendStreamPacketIndex(void* data, int in_len, int64_t* index); |
| 228 | 238 |
| 229 static bool Init(); | 239 static bool Init(); |
| 230 void HandleEvent(const srtp_event_data_t* ev); | 240 void HandleEvent(const srtp_event_data_t* ev); |
| 231 static void HandleEventThunk(srtp_event_data_t* ev); | 241 static void HandleEventThunk(srtp_event_data_t* ev); |
| 232 | 242 |
| 233 static std::list<SrtpSession*>* sessions(); | 243 static std::list<SrtpSession*>* sessions(); |
| 234 | 244 |
| 235 srtp_ctx_t* session_; | 245 srtp_ctx_t* session_; |
| 236 int rtp_auth_tag_len_; | 246 int rtp_auth_tag_len_; |
| 237 int rtcp_auth_tag_len_; | 247 int rtcp_auth_tag_len_; |
| 238 rtc::scoped_ptr<SrtpStat> srtp_stat_; | 248 rtc::scoped_ptr<SrtpStat> srtp_stat_; |
| 239 static bool inited_; | 249 static bool inited_; |
| 240 static rtc::GlobalLockPod lock_; | 250 static rtc::GlobalLockPod lock_; |
| 241 int last_send_seq_num_; | 251 int last_send_seq_num_; |
| 242 RTC_DISALLOW_COPY_AND_ASSIGN(SrtpSession); | 252 RTC_DISALLOW_COPY_AND_ASSIGN(SrtpSession); |
| 243 }; | 253 }; |
| 244 | 254 |
| 245 // Class that collects failures of SRTP. | 255 // Class that collects failures of SRTP. |
| 246 class SrtpStat { | 256 class SrtpStat { |
| 247 public: | 257 public: |
| 248 SrtpStat(); | 258 SrtpStat(); |
| 249 | 259 |
| 250 // Report RTP protection results to the handler. | 260 // Report RTP protection results to the handler. |
| 251 void AddProtectRtpResult(uint32 ssrc, int result); | 261 void AddProtectRtpResult(uint32_t ssrc, int result); |
| 252 // Report RTP unprotection results to the handler. | 262 // Report RTP unprotection results to the handler. |
| 253 void AddUnprotectRtpResult(uint32 ssrc, int result); | 263 void AddUnprotectRtpResult(uint32_t ssrc, int result); |
| 254 // Report RTCP protection results to the handler. | 264 // Report RTCP protection results to the handler. |
| 255 void AddProtectRtcpResult(int result); | 265 void AddProtectRtcpResult(int result); |
| 256 // Report RTCP unprotection results to the handler. | 266 // Report RTCP unprotection results to the handler. |
| 257 void AddUnprotectRtcpResult(int result); | 267 void AddUnprotectRtcpResult(int result); |
| 258 | 268 |
| 259 // Get silent time (in ms) for SRTP statistics handler. | 269 // Get silent time (in ms) for SRTP statistics handler. |
| 260 uint32 signal_silent_time() const { return signal_silent_time_; } | 270 uint32_t signal_silent_time() const { return signal_silent_time_; } |
| 261 // Set silent time (in ms) for SRTP statistics handler. | 271 // Set silent time (in ms) for SRTP statistics handler. |
| 262 void set_signal_silent_time(uint32 signal_silent_time) { | 272 void set_signal_silent_time(uint32_t signal_silent_time) { |
| 263 signal_silent_time_ = signal_silent_time; | 273 signal_silent_time_ = signal_silent_time; |
| 264 } | 274 } |
| 265 | 275 |
| 266 // Sigslot for reporting errors. | 276 // Sigslot for reporting errors. |
| 267 sigslot::signal3<uint32, SrtpFilter::Mode, SrtpFilter::Error> | 277 sigslot::signal3<uint32_t, SrtpFilter::Mode, SrtpFilter::Error> |
| 268 SignalSrtpError; | 278 SignalSrtpError; |
| 269 | 279 |
| 270 private: | 280 private: |
| 271 // For each different ssrc and error, we collect statistics separately. | 281 // For each different ssrc and error, we collect statistics separately. |
| 272 struct FailureKey { | 282 struct FailureKey { |
| 273 FailureKey() | 283 FailureKey() |
| 274 : ssrc(0), | 284 : ssrc(0), |
| 275 mode(SrtpFilter::PROTECT), | 285 mode(SrtpFilter::PROTECT), |
| 276 error(SrtpFilter::ERROR_NONE) { | 286 error(SrtpFilter::ERROR_NONE) { |
| 277 } | 287 } |
| 278 FailureKey(uint32 in_ssrc, SrtpFilter::Mode in_mode, | 288 FailureKey(uint32_t in_ssrc, |
| 289 SrtpFilter::Mode in_mode, |
| 279 SrtpFilter::Error in_error) | 290 SrtpFilter::Error in_error) |
| 280 : ssrc(in_ssrc), | 291 : ssrc(in_ssrc), mode(in_mode), error(in_error) {} |
| 281 mode(in_mode), | |
| 282 error(in_error) { | |
| 283 } | |
| 284 bool operator <(const FailureKey& key) const { | 292 bool operator <(const FailureKey& key) const { |
| 285 return | 293 return |
| 286 (ssrc < key.ssrc) || | 294 (ssrc < key.ssrc) || |
| 287 (ssrc == key.ssrc && mode < key.mode) || | 295 (ssrc == key.ssrc && mode < key.mode) || |
| 288 (ssrc == key.ssrc && mode == key.mode && error < key.error); | 296 (ssrc == key.ssrc && mode == key.mode && error < key.error); |
| 289 } | 297 } |
| 290 uint32 ssrc; | 298 uint32_t ssrc; |
| 291 SrtpFilter::Mode mode; | 299 SrtpFilter::Mode mode; |
| 292 SrtpFilter::Error error; | 300 SrtpFilter::Error error; |
| 293 }; | 301 }; |
| 294 // For tracing conditions for signaling, currently we only use | 302 // For tracing conditions for signaling, currently we only use |
| 295 // last_signal_time. Wrap this as a struct so that later on, if we need any | 303 // last_signal_time. Wrap this as a struct so that later on, if we need any |
| 296 // other improvements, it will be easier. | 304 // other improvements, it will be easier. |
| 297 struct FailureStat { | 305 struct FailureStat { |
| 298 FailureStat() | 306 FailureStat() |
| 299 : last_signal_time(0) { | 307 : last_signal_time(0) { |
| 300 } | 308 } |
| 301 explicit FailureStat(uint32 in_last_signal_time) | 309 explicit FailureStat(uint32_t in_last_signal_time) |
| 302 : last_signal_time(in_last_signal_time) { | 310 : last_signal_time(in_last_signal_time) {} |
| 303 } | |
| 304 void Reset() { | 311 void Reset() { |
| 305 last_signal_time = 0; | 312 last_signal_time = 0; |
| 306 } | 313 } |
| 307 uint32 last_signal_time; | 314 uint32_t last_signal_time; |
| 308 }; | 315 }; |
| 309 | 316 |
| 310 // Inspect SRTP result and signal error if needed. | 317 // Inspect SRTP result and signal error if needed. |
| 311 void HandleSrtpResult(const FailureKey& key); | 318 void HandleSrtpResult(const FailureKey& key); |
| 312 | 319 |
| 313 std::map<FailureKey, FailureStat> failures_; | 320 std::map<FailureKey, FailureStat> failures_; |
| 314 // Threshold in ms to silent the signaling errors. | 321 // Threshold in ms to silent the signaling errors. |
| 315 uint32 signal_silent_time_; | 322 uint32_t signal_silent_time_; |
| 316 | 323 |
| 317 RTC_DISALLOW_COPY_AND_ASSIGN(SrtpStat); | 324 RTC_DISALLOW_COPY_AND_ASSIGN(SrtpStat); |
| 318 }; | 325 }; |
| 319 | 326 |
| 320 } // namespace cricket | 327 } // namespace cricket |
| 321 | 328 |
| 322 #endif // TALK_SESSION_MEDIA_SRTPFILTER_H_ | 329 #endif // TALK_SESSION_MEDIA_SRTPFILTER_H_ |
| OLD | NEW |