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 |