Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(12)

Side by Side Diff: webrtc/pc/mediasession.cc

Issue 1528843005: Add support for GCM cipher suites from RFC 7714. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Disable GCM if ENABLE_EXTERNAL_AUTH is defined. Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « webrtc/pc/mediasession.h ('k') | webrtc/pc/mediasession_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2004 The WebRTC project authors. All Rights Reserved. 2 * Copyright 2004 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/mediasession.h" 11 #include "webrtc/pc/mediasession.h"
12 12
13 #include <algorithm> // For std::find_if, std::sort. 13 #include <algorithm> // For std::find_if, std::sort.
14 #include <functional> 14 #include <functional>
15 #include <map> 15 #include <map>
16 #include <memory> 16 #include <memory>
17 #include <set> 17 #include <set>
18 #include <unordered_map> 18 #include <unordered_map>
19 #include <utility> 19 #include <utility>
20 20
21 #include "webrtc/base/base64.h"
21 #include "webrtc/base/helpers.h" 22 #include "webrtc/base/helpers.h"
22 #include "webrtc/base/logging.h" 23 #include "webrtc/base/logging.h"
23 #include "webrtc/base/stringutils.h" 24 #include "webrtc/base/stringutils.h"
24 #include "webrtc/media/base/cryptoparams.h" 25 #include "webrtc/media/base/cryptoparams.h"
25 #include "webrtc/media/base/mediaconstants.h" 26 #include "webrtc/media/base/mediaconstants.h"
26 #include "webrtc/p2p/base/p2pconstants.h" 27 #include "webrtc/p2p/base/p2pconstants.h"
27 #include "webrtc/pc/channelmanager.h" 28 #include "webrtc/pc/channelmanager.h"
28 #include "webrtc/pc/srtpfilter.h" 29 #include "webrtc/pc/srtpfilter.h"
29 30
30 #ifdef HAVE_SCTP 31 #ifdef HAVE_SCTP
31 #include "webrtc/media/sctp/sctpdataengine.h" 32 #include "webrtc/media/sctp/sctpdataengine.h"
32 #else 33 #else
33 static const uint32_t kMaxSctpSid = 1023; 34 static const uint32_t kMaxSctpSid = 1023;
34 #endif 35 #endif
35 36
36 namespace { 37 namespace {
37 const char kInline[] = "inline:"; 38 const char kInline[] = "inline:";
38 39
39 void GetSupportedCryptoSuiteNames(void (*func)(std::vector<int>*), 40 void GetSupportedCryptoSuiteNames(void (*func)(const rtc::CryptoOptions&,
41 std::vector<int>*),
42 const rtc::CryptoOptions& crypto_options,
40 std::vector<std::string>* names) { 43 std::vector<std::string>* names) {
41 #ifdef HAVE_SRTP 44 #ifdef HAVE_SRTP
42 std::vector<int> crypto_suites; 45 std::vector<int> crypto_suites;
43 func(&crypto_suites); 46 func(crypto_options, &crypto_suites);
44 for (const auto crypto : crypto_suites) { 47 for (const auto crypto : crypto_suites) {
45 names->push_back(rtc::SrtpCryptoSuiteToName(crypto)); 48 names->push_back(rtc::SrtpCryptoSuiteToName(crypto));
46 } 49 }
47 #endif 50 #endif
48 } 51 }
49 } // namespace 52 } // namespace
50 53
51 namespace cricket { 54 namespace cricket {
52 55
53 // RTP Profile names 56 // RTP Profile names
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
100 return false; 103 return false;
101 } 104 }
102 105
103 const MediaContentDescription* mdesc = 106 const MediaContentDescription* mdesc =
104 static_cast<const MediaContentDescription*>(content->description); 107 static_cast<const MediaContentDescription*>(content->description);
105 return mdesc && mdesc->type() == media_type; 108 return mdesc && mdesc->type() == media_type;
106 } 109 }
107 110
108 static bool CreateCryptoParams(int tag, const std::string& cipher, 111 static bool CreateCryptoParams(int tag, const std::string& cipher,
109 CryptoParams *out) { 112 CryptoParams *out) {
110 std::string key; 113 int key_len;
111 key.reserve(SRTP_MASTER_KEY_BASE64_LEN); 114 int salt_len;
112 115 if (!rtc::GetSrtpKeyAndSaltLengths(
113 if (!rtc::CreateRandomString(SRTP_MASTER_KEY_BASE64_LEN, &key)) { 116 rtc::SrtpCryptoSuiteFromName(cipher), &key_len, &salt_len)) {
114 return false; 117 return false;
115 } 118 }
119
120 int master_key_len = key_len + salt_len;
121 std::string master_key;
122 if (!rtc::CreateRandomData(master_key_len, &master_key)) {
123 return false;
124 }
125
126 RTC_CHECK_EQ(static_cast<size_t>(master_key_len), master_key.size());
127 std::string key = rtc::Base64::Encode(master_key);
128
116 out->tag = tag; 129 out->tag = tag;
117 out->cipher_suite = cipher; 130 out->cipher_suite = cipher;
118 out->key_params = kInline; 131 out->key_params = kInline;
119 out->key_params += key; 132 out->key_params += key;
120 return true; 133 return true;
121 } 134 }
122 135
123 #ifdef HAVE_SRTP 136 #ifdef HAVE_SRTP
124 static bool AddCryptoParams(const std::string& cipher_suite, 137 static bool AddCryptoParams(const std::string& cipher_suite,
125 CryptoParamsVec *out) { 138 CryptoParamsVec *out) {
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
164 for (CryptoParamsVec::const_iterator it = cryptos.begin(); 177 for (CryptoParamsVec::const_iterator it = cryptos.begin();
165 it != cryptos.end(); ++it) { 178 it != cryptos.end(); ++it) {
166 if (crypto.Matches(*it)) { 179 if (crypto.Matches(*it)) {
167 *out = *it; 180 *out = *it;
168 return true; 181 return true;
169 } 182 }
170 } 183 }
171 return false; 184 return false;
172 } 185 }
173 186
174 // For audio, HMAC 32 is prefered because of the low overhead. 187 // For audio, HMAC 32 is prefered over HMAC 80 because of the low overhead.
175 void GetSupportedAudioCryptoSuites(std::vector<int>* crypto_suites) { 188 void GetSupportedAudioCryptoSuites(const rtc::CryptoOptions& crypto_options,
189 std::vector<int>* crypto_suites) {
176 #ifdef HAVE_SRTP 190 #ifdef HAVE_SRTP
191 if (crypto_options.enable_gcm_crypto_suites) {
192 crypto_suites->push_back(rtc::SRTP_AEAD_AES_256_GCM);
193 crypto_suites->push_back(rtc::SRTP_AEAD_AES_128_GCM);
194 }
177 crypto_suites->push_back(rtc::SRTP_AES128_CM_SHA1_32); 195 crypto_suites->push_back(rtc::SRTP_AES128_CM_SHA1_32);
178 crypto_suites->push_back(rtc::SRTP_AES128_CM_SHA1_80); 196 crypto_suites->push_back(rtc::SRTP_AES128_CM_SHA1_80);
179 #endif 197 #endif
180 } 198 }
181 199
182 void GetSupportedAudioCryptoSuiteNames( 200 void GetSupportedAudioCryptoSuiteNames(const rtc::CryptoOptions& crypto_options,
183 std::vector<std::string>* crypto_suite_names) { 201 std::vector<std::string>* crypto_suite_names) {
184 GetSupportedCryptoSuiteNames(GetSupportedAudioCryptoSuites, 202 GetSupportedCryptoSuiteNames(GetSupportedAudioCryptoSuites,
185 crypto_suite_names); 203 crypto_options, crypto_suite_names);
186 } 204 }
187 205
188 void GetSupportedVideoCryptoSuites(std::vector<int>* crypto_suites) { 206 void GetSupportedVideoCryptoSuites(const rtc::CryptoOptions& crypto_options,
189 GetDefaultSrtpCryptoSuites(crypto_suites); 207 std::vector<int>* crypto_suites) {
208 GetDefaultSrtpCryptoSuites(crypto_options, crypto_suites);
190 } 209 }
191 210
192 void GetSupportedVideoCryptoSuiteNames( 211 void GetSupportedVideoCryptoSuiteNames(const rtc::CryptoOptions& crypto_options,
193 std::vector<std::string>* crypto_suite_names) { 212 std::vector<std::string>* crypto_suite_names) {
194 GetSupportedCryptoSuiteNames(GetSupportedVideoCryptoSuites, 213 GetSupportedCryptoSuiteNames(GetSupportedVideoCryptoSuites,
195 crypto_suite_names); 214 crypto_options, crypto_suite_names);
196 } 215 }
197 216
198 void GetSupportedDataCryptoSuites(std::vector<int>* crypto_suites) { 217 void GetSupportedDataCryptoSuites(const rtc::CryptoOptions& crypto_options,
199 GetDefaultSrtpCryptoSuites(crypto_suites); 218 std::vector<int>* crypto_suites) {
219 GetDefaultSrtpCryptoSuites(crypto_options, crypto_suites);
200 } 220 }
201 221
202 void GetSupportedDataCryptoSuiteNames( 222 void GetSupportedDataCryptoSuiteNames(const rtc::CryptoOptions& crypto_options,
203 std::vector<std::string>* crypto_suite_names) { 223 std::vector<std::string>* crypto_suite_names) {
204 GetSupportedCryptoSuiteNames(GetSupportedDataCryptoSuites, 224 GetSupportedCryptoSuiteNames(GetSupportedDataCryptoSuites,
205 crypto_suite_names); 225 crypto_options, crypto_suite_names);
206 } 226 }
207 227
208 void GetDefaultSrtpCryptoSuites(std::vector<int>* crypto_suites) { 228 void GetDefaultSrtpCryptoSuites(const rtc::CryptoOptions& crypto_options,
229 std::vector<int>* crypto_suites) {
209 #ifdef HAVE_SRTP 230 #ifdef HAVE_SRTP
231 if (crypto_options.enable_gcm_crypto_suites) {
232 crypto_suites->push_back(rtc::SRTP_AEAD_AES_256_GCM);
233 crypto_suites->push_back(rtc::SRTP_AEAD_AES_128_GCM);
234 }
210 crypto_suites->push_back(rtc::SRTP_AES128_CM_SHA1_80); 235 crypto_suites->push_back(rtc::SRTP_AES128_CM_SHA1_80);
211 #endif 236 #endif
212 } 237 }
213 238
214 void GetDefaultSrtpCryptoSuiteNames( 239 void GetDefaultSrtpCryptoSuiteNames(const rtc::CryptoOptions& crypto_options,
215 std::vector<std::string>* crypto_suite_names) { 240 std::vector<std::string>* crypto_suite_names) {
216 GetSupportedCryptoSuiteNames(GetDefaultSrtpCryptoSuites, crypto_suite_names); 241 GetSupportedCryptoSuiteNames(GetDefaultSrtpCryptoSuites,
242 crypto_options, crypto_suite_names);
217 } 243 }
218 244
219 // For video support only 80-bit SHA1 HMAC. For audio 32-bit HMAC is 245 // Support any GCM cipher (if enabled through options). For video support only
220 // tolerated unless bundle is enabled because it is low overhead. Pick the 246 // 80-bit SHA1 HMAC. For audio 32-bit HMAC is tolerated unless bundle is enabled
221 // crypto in the list that is supported. 247 // because it is low overhead.
248 // Pick the crypto in the list that is supported.
222 static bool SelectCrypto(const MediaContentDescription* offer, 249 static bool SelectCrypto(const MediaContentDescription* offer,
223 bool bundle, 250 bool bundle,
251 const rtc::CryptoOptions& crypto_options,
224 CryptoParams *crypto) { 252 CryptoParams *crypto) {
225 bool audio = offer->type() == MEDIA_TYPE_AUDIO; 253 bool audio = offer->type() == MEDIA_TYPE_AUDIO;
226 const CryptoParamsVec& cryptos = offer->cryptos(); 254 const CryptoParamsVec& cryptos = offer->cryptos();
227 255
228 for (CryptoParamsVec::const_iterator i = cryptos.begin(); 256 for (CryptoParamsVec::const_iterator i = cryptos.begin();
229 i != cryptos.end(); ++i) { 257 i != cryptos.end(); ++i) {
230 if (rtc::CS_AES_CM_128_HMAC_SHA1_80 == i->cipher_suite || 258 if ((crypto_options.enable_gcm_crypto_suites &&
259 rtc::IsGcmCryptoSuiteName(i->cipher_suite)) ||
260 rtc::CS_AES_CM_128_HMAC_SHA1_80 == i->cipher_suite ||
231 (rtc::CS_AES_CM_128_HMAC_SHA1_32 == i->cipher_suite && audio && 261 (rtc::CS_AES_CM_128_HMAC_SHA1_32 == i->cipher_suite && audio &&
232 !bundle)) { 262 !bundle)) {
233 return CreateCryptoParams(i->tag, i->cipher_suite, crypto); 263 return CreateCryptoParams(i->tag, i->cipher_suite, crypto);
234 } 264 }
235 } 265 }
236 return false; 266 return false;
237 } 267 }
238 268
239 // Generate random SSRC values that are not already present in |params_vec|. 269 // Generate random SSRC values that are not already present in |params_vec|.
240 // The generated values are added to |ssrcs|. 270 // The generated values are added to |ssrcs|.
(...skipping 786 matching lines...) Expand 10 before | Expand all | Expand 10 after
1027 &negotiated_rtp_extensions); 1057 &negotiated_rtp_extensions);
1028 answer->set_rtp_header_extensions(negotiated_rtp_extensions); 1058 answer->set_rtp_header_extensions(negotiated_rtp_extensions);
1029 1059
1030 answer->set_rtcp_mux(options.rtcp_mux_enabled && offer->rtcp_mux()); 1060 answer->set_rtcp_mux(options.rtcp_mux_enabled && offer->rtcp_mux());
1031 if (answer->type() == cricket::MEDIA_TYPE_VIDEO) { 1061 if (answer->type() == cricket::MEDIA_TYPE_VIDEO) {
1032 answer->set_rtcp_reduced_size(offer->rtcp_reduced_size()); 1062 answer->set_rtcp_reduced_size(offer->rtcp_reduced_size());
1033 } 1063 }
1034 1064
1035 if (sdes_policy != SEC_DISABLED) { 1065 if (sdes_policy != SEC_DISABLED) {
1036 CryptoParams crypto; 1066 CryptoParams crypto;
1037 if (SelectCrypto(offer, bundle_enabled, &crypto)) { 1067 if (SelectCrypto(offer, bundle_enabled, options.crypto_options, &crypto)) {
1038 if (current_cryptos) { 1068 if (current_cryptos) {
1039 FindMatchingCrypto(*current_cryptos, crypto, &crypto); 1069 FindMatchingCrypto(*current_cryptos, crypto, &crypto);
1040 } 1070 }
1041 answer->AddCrypto(crypto); 1071 answer->AddCrypto(crypto);
1042 } 1072 }
1043 } 1073 }
1044 1074
1045 if (answer->cryptos().empty() && 1075 if (answer->cryptos().empty() &&
1046 (offer->crypto_required() == CT_SDES || sdes_policy == SEC_REQUIRED)) { 1076 (offer->crypto_required() == CT_SDES || sdes_policy == SEC_REQUIRED)) {
1047 return false; 1077 return false;
(...skipping 617 matching lines...) Expand 10 before | Expand all | Expand 10 after
1665 GetFirstAudioContent(current_description); 1695 GetFirstAudioContent(current_description);
1666 std::string content_name = 1696 std::string content_name =
1667 current_audio_content ? current_audio_content->name : CN_AUDIO; 1697 current_audio_content ? current_audio_content->name : CN_AUDIO;
1668 1698
1669 cricket::SecurePolicy sdes_policy = 1699 cricket::SecurePolicy sdes_policy =
1670 IsDtlsActive(content_name, current_description) ? cricket::SEC_DISABLED 1700 IsDtlsActive(content_name, current_description) ? cricket::SEC_DISABLED
1671 : secure(); 1701 : secure();
1672 1702
1673 std::unique_ptr<AudioContentDescription> audio(new AudioContentDescription()); 1703 std::unique_ptr<AudioContentDescription> audio(new AudioContentDescription());
1674 std::vector<std::string> crypto_suites; 1704 std::vector<std::string> crypto_suites;
1675 GetSupportedAudioCryptoSuiteNames(&crypto_suites); 1705 GetSupportedAudioCryptoSuiteNames(options.crypto_options, &crypto_suites);
1676 if (!CreateMediaContentOffer( 1706 if (!CreateMediaContentOffer(
1677 options, 1707 options,
1678 audio_codecs, 1708 audio_codecs,
1679 sdes_policy, 1709 sdes_policy,
1680 GetCryptos(GetFirstAudioContentDescription(current_description)), 1710 GetCryptos(GetFirstAudioContentDescription(current_description)),
1681 crypto_suites, 1711 crypto_suites,
1682 audio_rtp_extensions, 1712 audio_rtp_extensions,
1683 add_legacy_, 1713 add_legacy_,
1684 current_streams, 1714 current_streams,
1685 audio.get())) { 1715 audio.get())) {
(...skipping 29 matching lines...) Expand all
1715 GetFirstVideoContent(current_description); 1745 GetFirstVideoContent(current_description);
1716 std::string content_name = 1746 std::string content_name =
1717 current_video_content ? current_video_content->name : CN_VIDEO; 1747 current_video_content ? current_video_content->name : CN_VIDEO;
1718 1748
1719 cricket::SecurePolicy sdes_policy = 1749 cricket::SecurePolicy sdes_policy =
1720 IsDtlsActive(content_name, current_description) ? cricket::SEC_DISABLED 1750 IsDtlsActive(content_name, current_description) ? cricket::SEC_DISABLED
1721 : secure(); 1751 : secure();
1722 1752
1723 std::unique_ptr<VideoContentDescription> video(new VideoContentDescription()); 1753 std::unique_ptr<VideoContentDescription> video(new VideoContentDescription());
1724 std::vector<std::string> crypto_suites; 1754 std::vector<std::string> crypto_suites;
1725 GetSupportedVideoCryptoSuiteNames(&crypto_suites); 1755 GetSupportedVideoCryptoSuiteNames(options.crypto_options, &crypto_suites);
1726 if (!CreateMediaContentOffer( 1756 if (!CreateMediaContentOffer(
1727 options, 1757 options,
1728 video_codecs, 1758 video_codecs,
1729 sdes_policy, 1759 sdes_policy,
1730 GetCryptos(GetFirstVideoContentDescription(current_description)), 1760 GetCryptos(GetFirstVideoContentDescription(current_description)),
1731 crypto_suites, 1761 crypto_suites,
1732 video_rtp_extensions, 1762 video_rtp_extensions,
1733 add_legacy_, 1763 add_legacy_,
1734 current_streams, 1764 current_streams,
1735 video.get())) { 1765 video.get())) {
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
1791 // SDES doesn't make sense for SCTP, so we disable it, and we only 1821 // SDES doesn't make sense for SCTP, so we disable it, and we only
1792 // get SDES crypto suites for RTP-based data channels. 1822 // get SDES crypto suites for RTP-based data channels.
1793 sdes_policy = cricket::SEC_DISABLED; 1823 sdes_policy = cricket::SEC_DISABLED;
1794 // Unlike SetMediaProtocol below, we need to set the protocol 1824 // Unlike SetMediaProtocol below, we need to set the protocol
1795 // before we call CreateMediaContentOffer. Otherwise, 1825 // before we call CreateMediaContentOffer. Otherwise,
1796 // CreateMediaContentOffer won't know this is SCTP and will 1826 // CreateMediaContentOffer won't know this is SCTP and will
1797 // generate SSRCs rather than SIDs. 1827 // generate SSRCs rather than SIDs.
1798 data->set_protocol( 1828 data->set_protocol(
1799 secure_transport ? kMediaProtocolDtlsSctp : kMediaProtocolSctp); 1829 secure_transport ? kMediaProtocolDtlsSctp : kMediaProtocolSctp);
1800 } else { 1830 } else {
1801 GetSupportedDataCryptoSuiteNames(&crypto_suites); 1831 GetSupportedDataCryptoSuiteNames(options.crypto_options, &crypto_suites);
1802 } 1832 }
1803 1833
1804 if (!CreateMediaContentOffer( 1834 if (!CreateMediaContentOffer(
1805 options, 1835 options,
1806 *data_codecs, 1836 *data_codecs,
1807 sdes_policy, 1837 sdes_policy,
1808 GetCryptos(GetFirstDataContentDescription(current_description)), 1838 GetCryptos(GetFirstDataContentDescription(current_description)),
1809 crypto_suites, 1839 crypto_suites,
1810 RtpHeaderExtensions(), 1840 RtpHeaderExtensions(),
1811 add_legacy_, 1841 add_legacy_,
(...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after
2164 GetFirstMediaContentDescription(sdesc, MEDIA_TYPE_VIDEO)); 2194 GetFirstMediaContentDescription(sdesc, MEDIA_TYPE_VIDEO));
2165 } 2195 }
2166 2196
2167 DataContentDescription* GetFirstDataContentDescription( 2197 DataContentDescription* GetFirstDataContentDescription(
2168 SessionDescription* sdesc) { 2198 SessionDescription* sdesc) {
2169 return static_cast<DataContentDescription*>( 2199 return static_cast<DataContentDescription*>(
2170 GetFirstMediaContentDescription(sdesc, MEDIA_TYPE_DATA)); 2200 GetFirstMediaContentDescription(sdesc, MEDIA_TYPE_DATA));
2171 } 2201 }
2172 2202
2173 } // namespace cricket 2203 } // namespace cricket
OLDNEW
« no previous file with comments | « webrtc/pc/mediasession.h ('k') | webrtc/pc/mediasession_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698