Index: talk/session/media/mediasession.cc |
diff --git a/talk/session/media/mediasession.cc b/talk/session/media/mediasession.cc |
index 8db37d049abad3dddd1b7be4782b16348c59dbe1..b45a65c8e6b003ff68f844ea3ab61d83bd3174f7 100644 |
--- a/talk/session/media/mediasession.cc |
+++ b/talk/session/media/mediasession.cc |
@@ -98,10 +98,19 @@ static bool IsMediaContentOfType(const ContentInfo* content, |
static bool CreateCryptoParams(int tag, const std::string& cipher, |
CryptoParams *out) { |
+ int key_len; |
+ int salt_len; |
+ if (!rtc::SrtpCryptoSuiteParams( |
+ rtc::SrtpCryptoSuiteFromName(cipher), &key_len, &salt_len)) { |
+ return false; |
+ } |
+ |
+ int master_key_base64_len = (key_len + salt_len) * 4 / 3; |
+ |
std::string key; |
- key.reserve(SRTP_MASTER_KEY_BASE64_LEN); |
+ key.reserve(master_key_base64_len); |
- if (!rtc::CreateRandomString(SRTP_MASTER_KEY_BASE64_LEN, &key)) { |
+ if (!rtc::CreateRandomString(master_key_base64_len, &key)) { |
return false; |
} |
out->tag = tag; |
@@ -162,9 +171,35 @@ bool FindMatchingCrypto(const CryptoParamsVec& cryptos, |
return false; |
} |
-// For audio, HMAC 32 is prefered because of the low overhead. |
+void FilterGcmCiphers(std::vector<int>* crypto_suites) { |
pthatcher1
2015/12/18 20:31:31
Can you break this up to be a bit more generic and
joachim
2015/12/19 15:26:23
Done. Implemented functions in sslstreamadapter (w
|
+ for (std::vector<int>::iterator it = crypto_suites->begin(); |
+ it != crypto_suites->end(); ) { |
+ if (*it == rtc::SRTP_AEAD_AES_256_GCM || |
+ *it == rtc::SRTP_AEAD_AES_128_GCM) { |
+ it = crypto_suites->erase(it); |
+ } else { |
+ ++it; |
+ } |
+ } |
+} |
pthatcher1
2015/12/18 20:31:31
Then you can just remove this function and replace
joachim
2015/12/19 15:26:23
Done.
|
+ |
+void FilterGcmCipherNames(std::vector<std::string>* crypto_suites) { |
+ for (std::vector<std::string>::iterator it = crypto_suites->begin(); |
+ it != crypto_suites->end(); ) { |
+ if (*it == rtc::CS_AEAD_AES_256_GCM || |
+ *it == rtc::CS_AEAD_AES_128_GCM) { |
+ it = crypto_suites->erase(it); |
+ } else { |
+ ++it; |
+ } |
+ } |
+} |
pthatcher1
2015/12/18 20:31:32
Similarly here:
cipher_names.erase(std::remove_if
joachim
2015/12/19 15:26:23
Done.
|
+ |
+// For audio, HMAC 32 is prefered over HMAC 80 because of the low overhead. |
void GetSupportedAudioCryptoSuites(std::vector<int>* crypto_suites) { |
#ifdef HAVE_SRTP |
+ crypto_suites->push_back(rtc::SRTP_AEAD_AES_256_GCM); |
+ crypto_suites->push_back(rtc::SRTP_AEAD_AES_128_GCM); |
crypto_suites->push_back(rtc::SRTP_AES128_CM_SHA1_32); |
crypto_suites->push_back(rtc::SRTP_AES128_CM_SHA1_80); |
#endif |
@@ -198,6 +233,8 @@ void GetSupportedDataCryptoSuiteNames( |
void GetDefaultSrtpCryptoSuites(std::vector<int>* crypto_suites) { |
#ifdef HAVE_SRTP |
+ crypto_suites->push_back(rtc::SRTP_AEAD_AES_256_GCM); |
+ crypto_suites->push_back(rtc::SRTP_AEAD_AES_128_GCM); |
crypto_suites->push_back(rtc::SRTP_AES128_CM_SHA1_80); |
#endif |
} |
@@ -207,18 +244,23 @@ void GetDefaultSrtpCryptoSuiteNames( |
GetSupportedCryptoSuiteNames(GetDefaultSrtpCryptoSuites, crypto_suite_names); |
} |
-// For video support only 80-bit SHA1 HMAC. For audio 32-bit HMAC is |
-// tolerated unless bundle is enabled because it is low overhead. Pick the |
-// crypto in the list that is supported. |
+// Support any GCM cipher (if enabled through options). For video support only |
+// 80-bit SHA1 HMAC. For audio 32-bit HMAC is tolerated unless bundle is enabled |
+// because it is low overhead. |
+// Pick the crypto in the list that is supported. |
static bool SelectCrypto(const MediaContentDescription* offer, |
bool bundle, |
+ const MediaSessionOptions& options, |
CryptoParams *crypto) { |
bool audio = offer->type() == MEDIA_TYPE_AUDIO; |
const CryptoParamsVec& cryptos = offer->cryptos(); |
for (CryptoParamsVec::const_iterator i = cryptos.begin(); |
i != cryptos.end(); ++i) { |
- if (rtc::CS_AES_CM_128_HMAC_SHA1_80 == i->cipher_suite || |
+ if ((options.enable_gcm_ciphers && |
+ (rtc::CS_AEAD_AES_256_GCM == i->cipher_suite || |
+ rtc::CS_AEAD_AES_128_GCM == i->cipher_suite)) || |
pthatcher1
2015/12/18 20:31:31
IsGcmCipherName or IsGcmCryptoSuite would be usefu
joachim
2015/12/19 15:26:23
Done.
|
+ rtc::CS_AES_CM_128_HMAC_SHA1_80 == i->cipher_suite || |
(rtc::CS_AES_CM_128_HMAC_SHA1_32 == i->cipher_suite && audio && |
!bundle)) { |
pthatcher1
2015/12/18 20:31:32
Actually this, method seems to duplicate a lot wit
joachim
2015/12/19 15:26:23
Done.
|
return CreateCryptoParams(i->tag, i->cipher_suite, crypto); |
@@ -1051,7 +1093,7 @@ static bool CreateMediaContentAnswer( |
if (sdes_policy != SEC_DISABLED) { |
CryptoParams crypto; |
- if (SelectCrypto(offer, bundle_enabled, &crypto)) { |
+ if (SelectCrypto(offer, bundle_enabled, options, &crypto)) { |
if (current_cryptos) { |
FindMatchingCrypto(*current_cryptos, crypto, &crypto); |
} |
@@ -1563,6 +1605,9 @@ bool MediaSessionDescriptionFactory::AddAudioContentForOffer( |
scoped_ptr<AudioContentDescription> audio(new AudioContentDescription()); |
std::vector<std::string> crypto_suites; |
GetSupportedAudioCryptoSuiteNames(&crypto_suites); |
+ if (!options.enable_gcm_ciphers) { |
pthatcher1
2015/12/18 20:31:32
Instead of filtering, can we pass options into Get
joachim
2015/12/19 15:26:23
Done.
|
+ FilterGcmCipherNames(&crypto_suites); |
+ } |
if (!CreateMediaContentOffer( |
options, |
audio_codecs, |
@@ -1617,6 +1662,9 @@ bool MediaSessionDescriptionFactory::AddVideoContentForOffer( |
scoped_ptr<VideoContentDescription> video(new VideoContentDescription()); |
std::vector<std::string> crypto_suites; |
GetSupportedVideoCryptoSuiteNames(&crypto_suites); |
+ if (!options.enable_gcm_ciphers) { |
+ FilterGcmCipherNames(&crypto_suites); |
+ } |
pthatcher1
2015/12/18 20:31:32
Instead of filtering, can we pass options into Get
joachim
2015/12/19 15:26:23
Done.
|
if (!CreateMediaContentOffer( |
options, |
video_codecs, |
@@ -1687,6 +1735,9 @@ bool MediaSessionDescriptionFactory::AddDataContentForOffer( |
secure_transport ? kMediaProtocolDtlsSctp : kMediaProtocolSctp); |
} else { |
GetSupportedDataCryptoSuiteNames(&crypto_suites); |
+ if (!options.enable_gcm_ciphers) { |
+ FilterGcmCipherNames(&crypto_suites); |
+ } |
} |
if (!CreateMediaContentOffer( |