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