| Index: webrtc/pc/srtpfilter.cc
|
| diff --git a/webrtc/pc/srtpfilter.cc b/webrtc/pc/srtpfilter.cc
|
| index e8ea2890edab8b51cb273f483016c98dea0f186b..b539a83843b232106b7f015dfe663af08efd0b4a 100644
|
| --- a/webrtc/pc/srtpfilter.cc
|
| +++ b/webrtc/pc/srtpfilter.cc
|
| @@ -15,6 +15,7 @@
|
| #include <algorithm>
|
|
|
| #include "webrtc/base/base64.h"
|
| +#include "webrtc/base/buffer.h"
|
| #include "webrtc/base/byteorder.h"
|
| #include "webrtc/base/common.h"
|
| #include "webrtc/base/logging.h"
|
| @@ -47,17 +48,10 @@ extern "C" debug_module_t mod_alloc;
|
| extern "C" debug_module_t mod_aes_icm;
|
| extern "C" debug_module_t mod_aes_hmac;
|
| #endif
|
| -#else
|
| -// SrtpFilter needs that constant.
|
| -#define SRTP_MASTER_KEY_LEN 30
|
| #endif // HAVE_SRTP
|
|
|
| namespace cricket {
|
|
|
| -const int SRTP_MASTER_KEY_BASE64_LEN = SRTP_MASTER_KEY_LEN * 4 / 3;
|
| -const int SRTP_MASTER_KEY_KEY_LEN = 16;
|
| -const int SRTP_MASTER_KEY_SALT_LEN = 14;
|
| -
|
| #ifndef HAVE_SRTP
|
|
|
| // This helper function is used on systems that don't (yet) have SRTP,
|
| @@ -402,19 +396,45 @@ bool SrtpFilter::ApplyParams(const CryptoParams& send_params,
|
| // We do not want to reset the ROC if the keys are the same. So just return.
|
| return true;
|
| }
|
| +
|
| + int send_suite = rtc::SrtpCryptoSuiteFromName(send_params.cipher_suite);
|
| + int recv_suite = rtc::SrtpCryptoSuiteFromName(recv_params.cipher_suite);
|
| + if (send_suite == rtc::SRTP_INVALID_CRYPTO_SUITE ||
|
| + recv_suite == rtc::SRTP_INVALID_CRYPTO_SUITE) {
|
| + LOG(LS_WARNING) << "Unknown crypto suite(s) received:"
|
| + << " send cipher_suite " << send_params.cipher_suite
|
| + << " recv cipher_suite " << recv_params.cipher_suite;
|
| + return false;
|
| + }
|
| +
|
| + int send_key_len, send_salt_len;
|
| + int recv_key_len, recv_salt_len;
|
| + if (!rtc::GetSrtpKeyAndSaltLengths(send_suite, &send_key_len,
|
| + &send_salt_len) ||
|
| + !rtc::GetSrtpKeyAndSaltLengths(recv_suite, &recv_key_len,
|
| + &recv_salt_len)) {
|
| + LOG(LS_WARNING) << "Could not get lengths for crypto suite(s):"
|
| + << " send cipher_suite " << send_params.cipher_suite
|
| + << " recv cipher_suite " << recv_params.cipher_suite;
|
| + return false;
|
| + }
|
| +
|
| // TODO(juberti): Zero these buffers after use.
|
| bool ret;
|
| - uint8_t send_key[SRTP_MASTER_KEY_LEN], recv_key[SRTP_MASTER_KEY_LEN];
|
| - ret = (ParseKeyParams(send_params.key_params, send_key, sizeof(send_key)) &&
|
| - ParseKeyParams(recv_params.key_params, recv_key, sizeof(recv_key)));
|
| + rtc::Buffer send_key(send_key_len + send_salt_len);
|
| + rtc::Buffer recv_key(recv_key_len + recv_salt_len);
|
| + ret = (ParseKeyParams(send_params.key_params, send_key.data(),
|
| + send_key.size()) &&
|
| + ParseKeyParams(recv_params.key_params, recv_key.data(),
|
| + recv_key.size()));
|
| if (ret) {
|
| CreateSrtpSessions();
|
| ret = (send_session_->SetSend(
|
| - rtc::SrtpCryptoSuiteFromName(send_params.cipher_suite), send_key,
|
| - sizeof(send_key)) &&
|
| + rtc::SrtpCryptoSuiteFromName(send_params.cipher_suite),
|
| + send_key.data(), send_key.size()) &&
|
| recv_session_->SetRecv(
|
| - rtc::SrtpCryptoSuiteFromName(recv_params.cipher_suite), recv_key,
|
| - sizeof(recv_key)));
|
| + rtc::SrtpCryptoSuiteFromName(recv_params.cipher_suite),
|
| + recv_key.data(), recv_key.size()));
|
| }
|
| if (ret) {
|
| LOG(LS_INFO) << "SRTP activated with negotiated parameters:"
|
| @@ -658,20 +678,35 @@ bool SrtpSession::SetKey(int type, int cs, const uint8_t* key, int len) {
|
|
|
| srtp_policy_t policy;
|
| memset(&policy, 0, sizeof(policy));
|
| -
|
| if (cs == rtc::SRTP_AES128_CM_SHA1_80) {
|
| crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtp);
|
| crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtcp);
|
| } else if (cs == rtc::SRTP_AES128_CM_SHA1_32) {
|
| crypto_policy_set_aes_cm_128_hmac_sha1_32(&policy.rtp); // rtp is 32,
|
| crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtcp); // rtcp still 80
|
| + } else if (cs == rtc::SRTP_AEAD_AES_128_GCM) {
|
| + crypto_policy_set_aes_gcm_128_16_auth(&policy.rtp);
|
| + crypto_policy_set_aes_gcm_128_16_auth(&policy.rtcp);
|
| + } else if (cs == rtc::SRTP_AEAD_AES_256_GCM) {
|
| + crypto_policy_set_aes_gcm_256_16_auth(&policy.rtp);
|
| + crypto_policy_set_aes_gcm_256_16_auth(&policy.rtcp);
|
| } else {
|
| LOG(LS_WARNING) << "Failed to create SRTP session: unsupported"
|
| << " cipher_suite " << cs;
|
| return false;
|
| }
|
|
|
| - if (!key || len != SRTP_MASTER_KEY_LEN) {
|
| + int expected_key_len;
|
| + int expected_salt_len;
|
| + if (!rtc::GetSrtpKeyAndSaltLengths(cs, &expected_key_len,
|
| + &expected_salt_len)) {
|
| + // This should never happen.
|
| + LOG(LS_WARNING) << "Failed to create SRTP session: unsupported"
|
| + << " cipher_suite without length information" << cs;
|
| + return false;
|
| + }
|
| +
|
| + if (!key || len != (expected_key_len + expected_salt_len)) {
|
| LOG(LS_WARNING) << "Failed to create SRTP session: invalid key";
|
| return false;
|
| }
|
| @@ -701,7 +736,6 @@ bool SrtpSession::SetKey(int type, int cs, const uint8_t* key, int len) {
|
| return false;
|
| }
|
|
|
| -
|
| rtp_auth_tag_len_ = policy.rtp.auth_tag_len;
|
| rtcp_auth_tag_len_ = policy.rtcp.auth_tag_len;
|
| return true;
|
|
|