| OLD | NEW | 
|---|
| 1 /* | 1 /* | 
| 2  *  Copyright 2009 The WebRTC project authors. All Rights Reserved. | 2  *  Copyright 2009 The WebRTC project authors. All Rights Reserved. | 
| 3  * | 3  * | 
| 4  *  Use of this source code is governed by a BSD-style license | 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 | 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 | 6  *  tree. An additional intellectual property rights grant can be found | 
| 7  *  in the file PATENTS.  All contributing project authors may | 7  *  in the file PATENTS.  All contributing project authors may | 
| 8  *  be found in the AUTHORS file in the root of the source tree. | 8  *  be found in the AUTHORS file in the root of the source tree. | 
| 9  */ | 9  */ | 
| 10 | 10 | 
| 11 #include "webrtc/pc/srtpfilter.h" | 11 #include "webrtc/pc/srtpfilter.h" | 
| 12 | 12 | 
| 13 #include <string.h> | 13 #include <string.h> | 
| 14 | 14 | 
| 15 #include <algorithm> | 15 #include <algorithm> | 
| 16 | 16 | 
| 17 #include "webrtc/base/base64.h" | 17 #include "webrtc/base/base64.h" | 
|  | 18 #include "webrtc/base/buffer.h" | 
| 18 #include "webrtc/base/byteorder.h" | 19 #include "webrtc/base/byteorder.h" | 
| 19 #include "webrtc/base/checks.h" | 20 #include "webrtc/base/checks.h" | 
| 20 #include "webrtc/base/common.h" | 21 #include "webrtc/base/common.h" | 
| 21 #include "webrtc/base/logging.h" | 22 #include "webrtc/base/logging.h" | 
| 22 #include "webrtc/base/stringencode.h" | 23 #include "webrtc/base/stringencode.h" | 
| 23 #include "webrtc/base/timeutils.h" | 24 #include "webrtc/base/timeutils.h" | 
| 24 #include "webrtc/media/base/rtputils.h" | 25 #include "webrtc/media/base/rtputils.h" | 
| 25 | 26 | 
| 26 // Enable this line to turn on SRTP debugging | 27 // Enable this line to turn on SRTP debugging | 
| 27 // #define SRTP_DEBUG | 28 // #define SRTP_DEBUG | 
| (...skipping 13 matching lines...) Expand all  Loading... | 
| 41 #endif  // ENABLE_EXTERNAL_AUTH | 42 #endif  // ENABLE_EXTERNAL_AUTH | 
| 42 #if !defined(NDEBUG) | 43 #if !defined(NDEBUG) | 
| 43 extern "C" debug_module_t mod_srtp; | 44 extern "C" debug_module_t mod_srtp; | 
| 44 extern "C" debug_module_t mod_auth; | 45 extern "C" debug_module_t mod_auth; | 
| 45 extern "C" debug_module_t mod_cipher; | 46 extern "C" debug_module_t mod_cipher; | 
| 46 extern "C" debug_module_t mod_stat; | 47 extern "C" debug_module_t mod_stat; | 
| 47 extern "C" debug_module_t mod_alloc; | 48 extern "C" debug_module_t mod_alloc; | 
| 48 extern "C" debug_module_t mod_aes_icm; | 49 extern "C" debug_module_t mod_aes_icm; | 
| 49 extern "C" debug_module_t mod_aes_hmac; | 50 extern "C" debug_module_t mod_aes_hmac; | 
| 50 #endif | 51 #endif | 
| 51 #else |  | 
| 52 // SrtpFilter needs that constant. |  | 
| 53 #define SRTP_MASTER_KEY_LEN 30 |  | 
| 54 #endif  // HAVE_SRTP | 52 #endif  // HAVE_SRTP | 
| 55 | 53 | 
| 56 namespace cricket { | 54 namespace cricket { | 
| 57 | 55 | 
| 58 const int SRTP_MASTER_KEY_BASE64_LEN = SRTP_MASTER_KEY_LEN * 4 / 3; |  | 
| 59 const int SRTP_MASTER_KEY_KEY_LEN = 16; |  | 
| 60 const int SRTP_MASTER_KEY_SALT_LEN = 14; |  | 
| 61 |  | 
| 62 #ifndef HAVE_SRTP | 56 #ifndef HAVE_SRTP | 
| 63 | 57 | 
| 64 // This helper function is used on systems that don't (yet) have SRTP, | 58 // This helper function is used on systems that don't (yet) have SRTP, | 
| 65 // to log that the functions that require it won't do anything. | 59 // to log that the functions that require it won't do anything. | 
| 66 namespace { | 60 namespace { | 
| 67 bool SrtpNotAvailable(const char *func) { | 61 bool SrtpNotAvailable(const char *func) { | 
| 68   LOG(LS_ERROR) << func << ": SRTP is not available on your system."; | 62   LOG(LS_ERROR) << func << ": SRTP is not available on your system."; | 
| 69   return false; | 63   return false; | 
| 70 } | 64 } | 
| 71 }  // anonymous namespace | 65 }  // anonymous namespace | 
| (...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 396   // CryptoParams is unchanged. | 390   // CryptoParams is unchanged. | 
| 397   if (applied_send_params_.cipher_suite == send_params.cipher_suite && | 391   if (applied_send_params_.cipher_suite == send_params.cipher_suite && | 
| 398       applied_send_params_.key_params == send_params.key_params && | 392       applied_send_params_.key_params == send_params.key_params && | 
| 399       applied_recv_params_.cipher_suite == recv_params.cipher_suite && | 393       applied_recv_params_.cipher_suite == recv_params.cipher_suite && | 
| 400       applied_recv_params_.key_params == recv_params.key_params) { | 394       applied_recv_params_.key_params == recv_params.key_params) { | 
| 401     LOG(LS_INFO) << "Applying the same SRTP parameters again. No-op."; | 395     LOG(LS_INFO) << "Applying the same SRTP parameters again. No-op."; | 
| 402 | 396 | 
| 403     // We do not want to reset the ROC if the keys are the same. So just return. | 397     // We do not want to reset the ROC if the keys are the same. So just return. | 
| 404     return true; | 398     return true; | 
| 405   } | 399   } | 
|  | 400 | 
|  | 401   int send_suite = rtc::SrtpCryptoSuiteFromName(send_params.cipher_suite); | 
|  | 402   int recv_suite = rtc::SrtpCryptoSuiteFromName(recv_params.cipher_suite); | 
|  | 403   if (send_suite == rtc::SRTP_INVALID_CRYPTO_SUITE || | 
|  | 404       recv_suite == rtc::SRTP_INVALID_CRYPTO_SUITE) { | 
|  | 405     LOG(LS_WARNING) << "Unknown crypto suite(s) received:" | 
|  | 406                     << " send cipher_suite " << send_params.cipher_suite | 
|  | 407                     << " recv cipher_suite " << recv_params.cipher_suite; | 
|  | 408     return false; | 
|  | 409   } | 
|  | 410 | 
|  | 411   int send_key_len, send_salt_len; | 
|  | 412   int recv_key_len, recv_salt_len; | 
|  | 413   if (!rtc::GetSrtpKeyAndSaltLengths(send_suite, &send_key_len, | 
|  | 414                                      &send_salt_len) || | 
|  | 415       !rtc::GetSrtpKeyAndSaltLengths(recv_suite, &recv_key_len, | 
|  | 416                                      &recv_salt_len)) { | 
|  | 417     LOG(LS_WARNING) << "Could not get lengths for crypto suite(s):" | 
|  | 418                     << " send cipher_suite " << send_params.cipher_suite | 
|  | 419                     << " recv cipher_suite " << recv_params.cipher_suite; | 
|  | 420     return false; | 
|  | 421   } | 
|  | 422 | 
| 406   // TODO(juberti): Zero these buffers after use. | 423   // TODO(juberti): Zero these buffers after use. | 
| 407   bool ret; | 424   bool ret; | 
| 408   uint8_t send_key[SRTP_MASTER_KEY_LEN], recv_key[SRTP_MASTER_KEY_LEN]; | 425   rtc::Buffer send_key(send_key_len + send_salt_len); | 
| 409   ret = (ParseKeyParams(send_params.key_params, send_key, sizeof(send_key)) && | 426   rtc::Buffer recv_key(recv_key_len + recv_salt_len); | 
| 410          ParseKeyParams(recv_params.key_params, recv_key, sizeof(recv_key))); | 427   ret = (ParseKeyParams(send_params.key_params, send_key.data(), | 
|  | 428                         send_key.size()) && | 
|  | 429          ParseKeyParams(recv_params.key_params, recv_key.data(), | 
|  | 430                         recv_key.size())); | 
| 411   if (ret) { | 431   if (ret) { | 
| 412     CreateSrtpSessions(); | 432     CreateSrtpSessions(); | 
| 413     ret = (send_session_->SetSend( | 433     ret = (send_session_->SetSend( | 
| 414                rtc::SrtpCryptoSuiteFromName(send_params.cipher_suite), send_key, | 434                rtc::SrtpCryptoSuiteFromName(send_params.cipher_suite), | 
| 415                sizeof(send_key)) && | 435                send_key.data(), send_key.size()) && | 
| 416            recv_session_->SetRecv( | 436            recv_session_->SetRecv( | 
| 417                rtc::SrtpCryptoSuiteFromName(recv_params.cipher_suite), recv_key, | 437                rtc::SrtpCryptoSuiteFromName(recv_params.cipher_suite), | 
| 418                sizeof(recv_key))); | 438                recv_key.data(), recv_key.size())); | 
| 419   } | 439   } | 
| 420   if (ret) { | 440   if (ret) { | 
| 421     LOG(LS_INFO) << "SRTP activated with negotiated parameters:" | 441     LOG(LS_INFO) << "SRTP activated with negotiated parameters:" | 
| 422                  << " send cipher_suite " << send_params.cipher_suite | 442                  << " send cipher_suite " << send_params.cipher_suite | 
| 423                  << " recv cipher_suite " << recv_params.cipher_suite; | 443                  << " recv cipher_suite " << recv_params.cipher_suite; | 
| 424     applied_send_params_ = send_params; | 444     applied_send_params_ = send_params; | 
| 425     applied_recv_params_ = recv_params; | 445     applied_recv_params_ = recv_params; | 
| 426   } else { | 446   } else { | 
| 427     LOG(LS_WARNING) << "Failed to apply negotiated SRTP parameters"; | 447     LOG(LS_WARNING) << "Failed to apply negotiated SRTP parameters"; | 
| 428   } | 448   } | 
| (...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 653                   << "SRTP session already created"; | 673                   << "SRTP session already created"; | 
| 654     return false; | 674     return false; | 
| 655   } | 675   } | 
| 656 | 676 | 
| 657   if (!Init()) { | 677   if (!Init()) { | 
| 658     return false; | 678     return false; | 
| 659   } | 679   } | 
| 660 | 680 | 
| 661   srtp_policy_t policy; | 681   srtp_policy_t policy; | 
| 662   memset(&policy, 0, sizeof(policy)); | 682   memset(&policy, 0, sizeof(policy)); | 
| 663 |  | 
| 664   if (cs == rtc::SRTP_AES128_CM_SHA1_80) { | 683   if (cs == rtc::SRTP_AES128_CM_SHA1_80) { | 
| 665     crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtp); | 684     crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtp); | 
| 666     crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtcp); | 685     crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtcp); | 
| 667   } else if (cs == rtc::SRTP_AES128_CM_SHA1_32) { | 686   } else if (cs == rtc::SRTP_AES128_CM_SHA1_32) { | 
| 668     crypto_policy_set_aes_cm_128_hmac_sha1_32(&policy.rtp);   // rtp is 32, | 687     crypto_policy_set_aes_cm_128_hmac_sha1_32(&policy.rtp);   // rtp is 32, | 
| 669     crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtcp);  // rtcp still 80 | 688     crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtcp);  // rtcp still 80 | 
|  | 689   } else if (cs == rtc::SRTP_AEAD_AES_128_GCM) { | 
|  | 690     crypto_policy_set_aes_gcm_128_16_auth(&policy.rtp); | 
|  | 691     crypto_policy_set_aes_gcm_128_16_auth(&policy.rtcp); | 
|  | 692   } else if (cs == rtc::SRTP_AEAD_AES_256_GCM) { | 
|  | 693     crypto_policy_set_aes_gcm_256_16_auth(&policy.rtp); | 
|  | 694     crypto_policy_set_aes_gcm_256_16_auth(&policy.rtcp); | 
| 670   } else { | 695   } else { | 
| 671     LOG(LS_WARNING) << "Failed to create SRTP session: unsupported" | 696     LOG(LS_WARNING) << "Failed to create SRTP session: unsupported" | 
| 672                     << " cipher_suite " << cs; | 697                     << " cipher_suite " << cs; | 
| 673     return false; | 698     return false; | 
| 674   } | 699   } | 
| 675 | 700 | 
| 676   if (!key || len != SRTP_MASTER_KEY_LEN) { | 701   int expected_key_len; | 
|  | 702   int expected_salt_len; | 
|  | 703   if (!rtc::GetSrtpKeyAndSaltLengths(cs, &expected_key_len, | 
|  | 704       &expected_salt_len)) { | 
|  | 705     // This should never happen. | 
|  | 706     LOG(LS_WARNING) << "Failed to create SRTP session: unsupported" | 
|  | 707                     << " cipher_suite without length information" << cs; | 
|  | 708     return false; | 
|  | 709   } | 
|  | 710 | 
|  | 711   if (!key || len != (expected_key_len + expected_salt_len)) { | 
| 677     LOG(LS_WARNING) << "Failed to create SRTP session: invalid key"; | 712     LOG(LS_WARNING) << "Failed to create SRTP session: invalid key"; | 
| 678     return false; | 713     return false; | 
| 679   } | 714   } | 
| 680 | 715 | 
| 681   policy.ssrc.type = static_cast<ssrc_type_t>(type); | 716   policy.ssrc.type = static_cast<ssrc_type_t>(type); | 
| 682   policy.ssrc.value = 0; | 717   policy.ssrc.value = 0; | 
| 683   policy.key = const_cast<uint8_t*>(key); | 718   policy.key = const_cast<uint8_t*>(key); | 
| 684   // TODO(astor) parse window size from WSH session-param | 719   // TODO(astor) parse window size from WSH session-param | 
| 685   policy.window_size = 1024; | 720   policy.window_size = 1024; | 
| 686   policy.allow_repeat_tx = 1; | 721   policy.allow_repeat_tx = 1; | 
| (...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 922   SrtpNotAvailable(__FUNCTION__); | 957   SrtpNotAvailable(__FUNCTION__); | 
| 923 } | 958 } | 
| 924 | 959 | 
| 925 void SrtpStat::HandleSrtpResult(const SrtpStat::FailureKey& key) { | 960 void SrtpStat::HandleSrtpResult(const SrtpStat::FailureKey& key) { | 
| 926   SrtpNotAvailable(__FUNCTION__); | 961   SrtpNotAvailable(__FUNCTION__); | 
| 927 } | 962 } | 
| 928 | 963 | 
| 929 #endif  // HAVE_SRTP | 964 #endif  // HAVE_SRTP | 
| 930 | 965 | 
| 931 }  // namespace cricket | 966 }  // namespace cricket | 
| OLD | NEW | 
|---|