Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * libjingle | 2 * libjingle |
| 3 * Copyright 2004 Google Inc. | 3 * Copyright 2004 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 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 91 return false; | 91 return false; |
| 92 } | 92 } |
| 93 | 93 |
| 94 const MediaContentDescription* mdesc = | 94 const MediaContentDescription* mdesc = |
| 95 static_cast<const MediaContentDescription*>(content->description); | 95 static_cast<const MediaContentDescription*>(content->description); |
| 96 return mdesc && mdesc->type() == media_type; | 96 return mdesc && mdesc->type() == media_type; |
| 97 } | 97 } |
| 98 | 98 |
| 99 static bool CreateCryptoParams(int tag, const std::string& cipher, | 99 static bool CreateCryptoParams(int tag, const std::string& cipher, |
| 100 CryptoParams *out) { | 100 CryptoParams *out) { |
| 101 int key_len; | |
| 102 int salt_len; | |
| 103 if (!rtc::SrtpCryptoSuiteParams( | |
| 104 rtc::SrtpCryptoSuiteFromName(cipher), &key_len, &salt_len)) { | |
| 105 return false; | |
| 106 } | |
| 107 | |
| 108 int master_key_base64_len = (key_len + salt_len) * 4 / 3; | |
| 109 | |
| 101 std::string key; | 110 std::string key; |
| 102 key.reserve(SRTP_MASTER_KEY_BASE64_LEN); | 111 key.reserve(master_key_base64_len); |
| 103 | 112 |
| 104 if (!rtc::CreateRandomString(SRTP_MASTER_KEY_BASE64_LEN, &key)) { | 113 if (!rtc::CreateRandomString(master_key_base64_len, &key)) { |
| 105 return false; | 114 return false; |
| 106 } | 115 } |
| 107 out->tag = tag; | 116 out->tag = tag; |
| 108 out->cipher_suite = cipher; | 117 out->cipher_suite = cipher; |
| 109 out->key_params = kInline; | 118 out->key_params = kInline; |
| 110 out->key_params += key; | 119 out->key_params += key; |
| 111 return true; | 120 return true; |
| 112 } | 121 } |
| 113 | 122 |
| 114 #ifdef HAVE_SRTP | 123 #ifdef HAVE_SRTP |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 155 for (CryptoParamsVec::const_iterator it = cryptos.begin(); | 164 for (CryptoParamsVec::const_iterator it = cryptos.begin(); |
| 156 it != cryptos.end(); ++it) { | 165 it != cryptos.end(); ++it) { |
| 157 if (crypto.Matches(*it)) { | 166 if (crypto.Matches(*it)) { |
| 158 *out = *it; | 167 *out = *it; |
| 159 return true; | 168 return true; |
| 160 } | 169 } |
| 161 } | 170 } |
| 162 return false; | 171 return false; |
| 163 } | 172 } |
| 164 | 173 |
| 165 // For audio, HMAC 32 is prefered because of the low overhead. | 174 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
| |
| 175 for (std::vector<int>::iterator it = crypto_suites->begin(); | |
| 176 it != crypto_suites->end(); ) { | |
| 177 if (*it == rtc::SRTP_AEAD_AES_256_GCM || | |
| 178 *it == rtc::SRTP_AEAD_AES_128_GCM) { | |
| 179 it = crypto_suites->erase(it); | |
| 180 } else { | |
| 181 ++it; | |
| 182 } | |
| 183 } | |
| 184 } | |
|
pthatcher1
2015/12/18 20:31:31
Then you can just remove this function and replace
joachim
2015/12/19 15:26:23
Done.
| |
| 185 | |
| 186 void FilterGcmCipherNames(std::vector<std::string>* crypto_suites) { | |
| 187 for (std::vector<std::string>::iterator it = crypto_suites->begin(); | |
| 188 it != crypto_suites->end(); ) { | |
| 189 if (*it == rtc::CS_AEAD_AES_256_GCM || | |
| 190 *it == rtc::CS_AEAD_AES_128_GCM) { | |
| 191 it = crypto_suites->erase(it); | |
| 192 } else { | |
| 193 ++it; | |
| 194 } | |
| 195 } | |
| 196 } | |
|
pthatcher1
2015/12/18 20:31:32
Similarly here:
cipher_names.erase(std::remove_if
joachim
2015/12/19 15:26:23
Done.
| |
| 197 | |
| 198 // For audio, HMAC 32 is prefered over HMAC 80 because of the low overhead. | |
| 166 void GetSupportedAudioCryptoSuites(std::vector<int>* crypto_suites) { | 199 void GetSupportedAudioCryptoSuites(std::vector<int>* crypto_suites) { |
| 167 #ifdef HAVE_SRTP | 200 #ifdef HAVE_SRTP |
| 201 crypto_suites->push_back(rtc::SRTP_AEAD_AES_256_GCM); | |
| 202 crypto_suites->push_back(rtc::SRTP_AEAD_AES_128_GCM); | |
| 168 crypto_suites->push_back(rtc::SRTP_AES128_CM_SHA1_32); | 203 crypto_suites->push_back(rtc::SRTP_AES128_CM_SHA1_32); |
| 169 crypto_suites->push_back(rtc::SRTP_AES128_CM_SHA1_80); | 204 crypto_suites->push_back(rtc::SRTP_AES128_CM_SHA1_80); |
| 170 #endif | 205 #endif |
| 171 } | 206 } |
| 172 | 207 |
| 173 void GetSupportedAudioCryptoSuiteNames( | 208 void GetSupportedAudioCryptoSuiteNames( |
| 174 std::vector<std::string>* crypto_suite_names) { | 209 std::vector<std::string>* crypto_suite_names) { |
| 175 GetSupportedCryptoSuiteNames(GetSupportedAudioCryptoSuites, | 210 GetSupportedCryptoSuiteNames(GetSupportedAudioCryptoSuites, |
| 176 crypto_suite_names); | 211 crypto_suite_names); |
| 177 } | 212 } |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 191 } | 226 } |
| 192 | 227 |
| 193 void GetSupportedDataCryptoSuiteNames( | 228 void GetSupportedDataCryptoSuiteNames( |
| 194 std::vector<std::string>* crypto_suite_names) { | 229 std::vector<std::string>* crypto_suite_names) { |
| 195 GetSupportedCryptoSuiteNames(GetSupportedDataCryptoSuites, | 230 GetSupportedCryptoSuiteNames(GetSupportedDataCryptoSuites, |
| 196 crypto_suite_names); | 231 crypto_suite_names); |
| 197 } | 232 } |
| 198 | 233 |
| 199 void GetDefaultSrtpCryptoSuites(std::vector<int>* crypto_suites) { | 234 void GetDefaultSrtpCryptoSuites(std::vector<int>* crypto_suites) { |
| 200 #ifdef HAVE_SRTP | 235 #ifdef HAVE_SRTP |
| 236 crypto_suites->push_back(rtc::SRTP_AEAD_AES_256_GCM); | |
| 237 crypto_suites->push_back(rtc::SRTP_AEAD_AES_128_GCM); | |
| 201 crypto_suites->push_back(rtc::SRTP_AES128_CM_SHA1_80); | 238 crypto_suites->push_back(rtc::SRTP_AES128_CM_SHA1_80); |
| 202 #endif | 239 #endif |
| 203 } | 240 } |
| 204 | 241 |
| 205 void GetDefaultSrtpCryptoSuiteNames( | 242 void GetDefaultSrtpCryptoSuiteNames( |
| 206 std::vector<std::string>* crypto_suite_names) { | 243 std::vector<std::string>* crypto_suite_names) { |
| 207 GetSupportedCryptoSuiteNames(GetDefaultSrtpCryptoSuites, crypto_suite_names); | 244 GetSupportedCryptoSuiteNames(GetDefaultSrtpCryptoSuites, crypto_suite_names); |
| 208 } | 245 } |
| 209 | 246 |
| 210 // For video support only 80-bit SHA1 HMAC. For audio 32-bit HMAC is | 247 // Support any GCM cipher (if enabled through options). For video support only |
| 211 // tolerated unless bundle is enabled because it is low overhead. Pick the | 248 // 80-bit SHA1 HMAC. For audio 32-bit HMAC is tolerated unless bundle is enabled |
| 212 // crypto in the list that is supported. | 249 // because it is low overhead. |
| 250 // Pick the crypto in the list that is supported. | |
| 213 static bool SelectCrypto(const MediaContentDescription* offer, | 251 static bool SelectCrypto(const MediaContentDescription* offer, |
| 214 bool bundle, | 252 bool bundle, |
| 253 const MediaSessionOptions& options, | |
| 215 CryptoParams *crypto) { | 254 CryptoParams *crypto) { |
| 216 bool audio = offer->type() == MEDIA_TYPE_AUDIO; | 255 bool audio = offer->type() == MEDIA_TYPE_AUDIO; |
| 217 const CryptoParamsVec& cryptos = offer->cryptos(); | 256 const CryptoParamsVec& cryptos = offer->cryptos(); |
| 218 | 257 |
| 219 for (CryptoParamsVec::const_iterator i = cryptos.begin(); | 258 for (CryptoParamsVec::const_iterator i = cryptos.begin(); |
| 220 i != cryptos.end(); ++i) { | 259 i != cryptos.end(); ++i) { |
| 221 if (rtc::CS_AES_CM_128_HMAC_SHA1_80 == i->cipher_suite || | 260 if ((options.enable_gcm_ciphers && |
| 261 (rtc::CS_AEAD_AES_256_GCM == i->cipher_suite || | |
| 262 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.
| |
| 263 rtc::CS_AES_CM_128_HMAC_SHA1_80 == i->cipher_suite || | |
| 222 (rtc::CS_AES_CM_128_HMAC_SHA1_32 == i->cipher_suite && audio && | 264 (rtc::CS_AES_CM_128_HMAC_SHA1_32 == i->cipher_suite && audio && |
| 223 !bundle)) { | 265 !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.
| |
| 224 return CreateCryptoParams(i->tag, i->cipher_suite, crypto); | 266 return CreateCryptoParams(i->tag, i->cipher_suite, crypto); |
| 225 } | 267 } |
| 226 } | 268 } |
| 227 return false; | 269 return false; |
| 228 } | 270 } |
| 229 | 271 |
| 230 static const StreamParams* FindFirstStreamParamsByCname( | 272 static const StreamParams* FindFirstStreamParamsByCname( |
| 231 const StreamParamsVec& params_vec, | 273 const StreamParamsVec& params_vec, |
| 232 const std::string& cname) { | 274 const std::string& cname) { |
| 233 for (StreamParamsVec::const_iterator it = params_vec.begin(); | 275 for (StreamParamsVec::const_iterator it = params_vec.begin(); |
| (...skipping 810 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1044 | 1086 |
| 1045 answer->set_rtcp_mux(options.rtcp_mux_enabled && offer->rtcp_mux()); | 1087 answer->set_rtcp_mux(options.rtcp_mux_enabled && offer->rtcp_mux()); |
| 1046 // TODO(deadbeef): Once we're sure this works correctly, enable it in | 1088 // TODO(deadbeef): Once we're sure this works correctly, enable it in |
| 1047 // CreateAnswer. | 1089 // CreateAnswer. |
| 1048 // if (answer->type() == cricket::MEDIA_TYPE_VIDEO) { | 1090 // if (answer->type() == cricket::MEDIA_TYPE_VIDEO) { |
| 1049 // answer->set_rtcp_reduced_size(offer->rtcp_reduced_size()); | 1091 // answer->set_rtcp_reduced_size(offer->rtcp_reduced_size()); |
| 1050 // } | 1092 // } |
| 1051 | 1093 |
| 1052 if (sdes_policy != SEC_DISABLED) { | 1094 if (sdes_policy != SEC_DISABLED) { |
| 1053 CryptoParams crypto; | 1095 CryptoParams crypto; |
| 1054 if (SelectCrypto(offer, bundle_enabled, &crypto)) { | 1096 if (SelectCrypto(offer, bundle_enabled, options, &crypto)) { |
| 1055 if (current_cryptos) { | 1097 if (current_cryptos) { |
| 1056 FindMatchingCrypto(*current_cryptos, crypto, &crypto); | 1098 FindMatchingCrypto(*current_cryptos, crypto, &crypto); |
| 1057 } | 1099 } |
| 1058 answer->AddCrypto(crypto); | 1100 answer->AddCrypto(crypto); |
| 1059 } | 1101 } |
| 1060 } | 1102 } |
| 1061 | 1103 |
| 1062 if (answer->cryptos().empty() && | 1104 if (answer->cryptos().empty() && |
| 1063 (offer->crypto_required() == CT_SDES || sdes_policy == SEC_REQUIRED)) { | 1105 (offer->crypto_required() == CT_SDES || sdes_policy == SEC_REQUIRED)) { |
| 1064 return false; | 1106 return false; |
| (...skipping 491 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1556 const AudioCodecs& audio_codecs, | 1598 const AudioCodecs& audio_codecs, |
| 1557 StreamParamsVec* current_streams, | 1599 StreamParamsVec* current_streams, |
| 1558 SessionDescription* desc) const { | 1600 SessionDescription* desc) const { |
| 1559 cricket::SecurePolicy sdes_policy = | 1601 cricket::SecurePolicy sdes_policy = |
| 1560 IsDtlsActive(CN_AUDIO, current_description) ? | 1602 IsDtlsActive(CN_AUDIO, current_description) ? |
| 1561 cricket::SEC_DISABLED : secure(); | 1603 cricket::SEC_DISABLED : secure(); |
| 1562 | 1604 |
| 1563 scoped_ptr<AudioContentDescription> audio(new AudioContentDescription()); | 1605 scoped_ptr<AudioContentDescription> audio(new AudioContentDescription()); |
| 1564 std::vector<std::string> crypto_suites; | 1606 std::vector<std::string> crypto_suites; |
| 1565 GetSupportedAudioCryptoSuiteNames(&crypto_suites); | 1607 GetSupportedAudioCryptoSuiteNames(&crypto_suites); |
| 1608 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.
| |
| 1609 FilterGcmCipherNames(&crypto_suites); | |
| 1610 } | |
| 1566 if (!CreateMediaContentOffer( | 1611 if (!CreateMediaContentOffer( |
| 1567 options, | 1612 options, |
| 1568 audio_codecs, | 1613 audio_codecs, |
| 1569 sdes_policy, | 1614 sdes_policy, |
| 1570 GetCryptos(GetFirstAudioContentDescription(current_description)), | 1615 GetCryptos(GetFirstAudioContentDescription(current_description)), |
| 1571 crypto_suites, | 1616 crypto_suites, |
| 1572 audio_rtp_extensions, | 1617 audio_rtp_extensions, |
| 1573 add_legacy_, | 1618 add_legacy_, |
| 1574 current_streams, | 1619 current_streams, |
| 1575 audio.get())) { | 1620 audio.get())) { |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1610 const VideoCodecs& video_codecs, | 1655 const VideoCodecs& video_codecs, |
| 1611 StreamParamsVec* current_streams, | 1656 StreamParamsVec* current_streams, |
| 1612 SessionDescription* desc) const { | 1657 SessionDescription* desc) const { |
| 1613 cricket::SecurePolicy sdes_policy = | 1658 cricket::SecurePolicy sdes_policy = |
| 1614 IsDtlsActive(CN_VIDEO, current_description) ? | 1659 IsDtlsActive(CN_VIDEO, current_description) ? |
| 1615 cricket::SEC_DISABLED : secure(); | 1660 cricket::SEC_DISABLED : secure(); |
| 1616 | 1661 |
| 1617 scoped_ptr<VideoContentDescription> video(new VideoContentDescription()); | 1662 scoped_ptr<VideoContentDescription> video(new VideoContentDescription()); |
| 1618 std::vector<std::string> crypto_suites; | 1663 std::vector<std::string> crypto_suites; |
| 1619 GetSupportedVideoCryptoSuiteNames(&crypto_suites); | 1664 GetSupportedVideoCryptoSuiteNames(&crypto_suites); |
| 1665 if (!options.enable_gcm_ciphers) { | |
| 1666 FilterGcmCipherNames(&crypto_suites); | |
| 1667 } | |
|
pthatcher1
2015/12/18 20:31:32
Instead of filtering, can we pass options into Get
joachim
2015/12/19 15:26:23
Done.
| |
| 1620 if (!CreateMediaContentOffer( | 1668 if (!CreateMediaContentOffer( |
| 1621 options, | 1669 options, |
| 1622 video_codecs, | 1670 video_codecs, |
| 1623 sdes_policy, | 1671 sdes_policy, |
| 1624 GetCryptos(GetFirstVideoContentDescription(current_description)), | 1672 GetCryptos(GetFirstVideoContentDescription(current_description)), |
| 1625 crypto_suites, | 1673 crypto_suites, |
| 1626 video_rtp_extensions, | 1674 video_rtp_extensions, |
| 1627 add_legacy_, | 1675 add_legacy_, |
| 1628 current_streams, | 1676 current_streams, |
| 1629 video.get())) { | 1677 video.get())) { |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1680 // get SDES crypto suites for RTP-based data channels. | 1728 // get SDES crypto suites for RTP-based data channels. |
| 1681 sdes_policy = cricket::SEC_DISABLED; | 1729 sdes_policy = cricket::SEC_DISABLED; |
| 1682 // Unlike SetMediaProtocol below, we need to set the protocol | 1730 // Unlike SetMediaProtocol below, we need to set the protocol |
| 1683 // before we call CreateMediaContentOffer. Otherwise, | 1731 // before we call CreateMediaContentOffer. Otherwise, |
| 1684 // CreateMediaContentOffer won't know this is SCTP and will | 1732 // CreateMediaContentOffer won't know this is SCTP and will |
| 1685 // generate SSRCs rather than SIDs. | 1733 // generate SSRCs rather than SIDs. |
| 1686 data->set_protocol( | 1734 data->set_protocol( |
| 1687 secure_transport ? kMediaProtocolDtlsSctp : kMediaProtocolSctp); | 1735 secure_transport ? kMediaProtocolDtlsSctp : kMediaProtocolSctp); |
| 1688 } else { | 1736 } else { |
| 1689 GetSupportedDataCryptoSuiteNames(&crypto_suites); | 1737 GetSupportedDataCryptoSuiteNames(&crypto_suites); |
| 1738 if (!options.enable_gcm_ciphers) { | |
| 1739 FilterGcmCipherNames(&crypto_suites); | |
| 1740 } | |
| 1690 } | 1741 } |
| 1691 | 1742 |
| 1692 if (!CreateMediaContentOffer( | 1743 if (!CreateMediaContentOffer( |
| 1693 options, | 1744 options, |
| 1694 *data_codecs, | 1745 *data_codecs, |
| 1695 sdes_policy, | 1746 sdes_policy, |
| 1696 GetCryptos(GetFirstDataContentDescription(current_description)), | 1747 GetCryptos(GetFirstDataContentDescription(current_description)), |
| 1697 crypto_suites, | 1748 crypto_suites, |
| 1698 RtpHeaderExtensions(), | 1749 RtpHeaderExtensions(), |
| 1699 add_legacy_, | 1750 add_legacy_, |
| (...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1972 GetFirstMediaContentDescription(sdesc, MEDIA_TYPE_VIDEO)); | 2023 GetFirstMediaContentDescription(sdesc, MEDIA_TYPE_VIDEO)); |
| 1973 } | 2024 } |
| 1974 | 2025 |
| 1975 const DataContentDescription* GetFirstDataContentDescription( | 2026 const DataContentDescription* GetFirstDataContentDescription( |
| 1976 const SessionDescription* sdesc) { | 2027 const SessionDescription* sdesc) { |
| 1977 return static_cast<const DataContentDescription*>( | 2028 return static_cast<const DataContentDescription*>( |
| 1978 GetFirstMediaContentDescription(sdesc, MEDIA_TYPE_DATA)); | 2029 GetFirstMediaContentDescription(sdesc, MEDIA_TYPE_DATA)); |
| 1979 } | 2030 } |
| 1980 | 2031 |
| 1981 } // namespace cricket | 2032 } // namespace cricket |
| OLD | NEW |