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

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: More feedback from Matt Created 4 years, 7 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 56
(...skipping 21 matching lines...) Expand all
75 return false; 78 return false;
76 } 79 }
77 80
78 const MediaContentDescription* mdesc = 81 const MediaContentDescription* mdesc =
79 static_cast<const MediaContentDescription*>(content->description); 82 static_cast<const MediaContentDescription*>(content->description);
80 return mdesc && mdesc->type() == media_type; 83 return mdesc && mdesc->type() == media_type;
81 } 84 }
82 85
83 static bool CreateCryptoParams(int tag, const std::string& cipher, 86 static bool CreateCryptoParams(int tag, const std::string& cipher,
84 CryptoParams *out) { 87 CryptoParams *out) {
85 std::string key; 88 int key_len;
86 key.reserve(SRTP_MASTER_KEY_BASE64_LEN); 89 int salt_len;
87 90 if (!rtc::GetSrtpKeyAndSaltLengths(
88 if (!rtc::CreateRandomString(SRTP_MASTER_KEY_BASE64_LEN, &key)) { 91 rtc::SrtpCryptoSuiteFromName(cipher), &key_len, &salt_len)) {
89 return false; 92 return false;
90 } 93 }
94
95 int master_key_len = key_len + salt_len;
96 std::string master_key;
97 if (!rtc::CreateRandomData(master_key_len, &master_key)) {
98 return false;
99 }
100
101 RTC_CHECK_EQ(static_cast<size_t>(master_key_len), master_key.size());
joachim 2016/05/10 23:09:44 This should never trigger (correct behaviour of Cr
102 std::string key = rtc::Base64::Encode(master_key);
103
91 out->tag = tag; 104 out->tag = tag;
92 out->cipher_suite = cipher; 105 out->cipher_suite = cipher;
93 out->key_params = kInline; 106 out->key_params = kInline;
94 out->key_params += key; 107 out->key_params += key;
95 return true; 108 return true;
96 } 109 }
97 110
98 #ifdef HAVE_SRTP 111 #ifdef HAVE_SRTP
99 static bool AddCryptoParams(const std::string& cipher_suite, 112 static bool AddCryptoParams(const std::string& cipher_suite,
100 CryptoParamsVec *out) { 113 CryptoParamsVec *out) {
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
139 for (CryptoParamsVec::const_iterator it = cryptos.begin(); 152 for (CryptoParamsVec::const_iterator it = cryptos.begin();
140 it != cryptos.end(); ++it) { 153 it != cryptos.end(); ++it) {
141 if (crypto.Matches(*it)) { 154 if (crypto.Matches(*it)) {
142 *out = *it; 155 *out = *it;
143 return true; 156 return true;
144 } 157 }
145 } 158 }
146 return false; 159 return false;
147 } 160 }
148 161
149 // For audio, HMAC 32 is prefered because of the low overhead. 162 // For audio, HMAC 32 is prefered over HMAC 80 because of the low overhead.
150 void GetSupportedAudioCryptoSuites(std::vector<int>* crypto_suites) { 163 void GetSupportedAudioCryptoSuites(const rtc::CryptoOptions& crypto_options,
164 std::vector<int>* crypto_suites) {
151 #ifdef HAVE_SRTP 165 #ifdef HAVE_SRTP
166 if (crypto_options.enable_gcm_crypto_suites) {
167 crypto_suites->push_back(rtc::SRTP_AEAD_AES_256_GCM);
168 crypto_suites->push_back(rtc::SRTP_AEAD_AES_128_GCM);
169 }
152 crypto_suites->push_back(rtc::SRTP_AES128_CM_SHA1_32); 170 crypto_suites->push_back(rtc::SRTP_AES128_CM_SHA1_32);
153 crypto_suites->push_back(rtc::SRTP_AES128_CM_SHA1_80); 171 crypto_suites->push_back(rtc::SRTP_AES128_CM_SHA1_80);
154 #endif 172 #endif
155 } 173 }
156 174
157 void GetSupportedAudioCryptoSuiteNames( 175 void GetSupportedAudioCryptoSuiteNames(const rtc::CryptoOptions& crypto_options,
158 std::vector<std::string>* crypto_suite_names) { 176 std::vector<std::string>* crypto_suite_names) {
159 GetSupportedCryptoSuiteNames(GetSupportedAudioCryptoSuites, 177 GetSupportedCryptoSuiteNames(GetSupportedAudioCryptoSuites,
160 crypto_suite_names); 178 crypto_options, crypto_suite_names);
161 } 179 }
162 180
163 void GetSupportedVideoCryptoSuites(std::vector<int>* crypto_suites) { 181 void GetSupportedVideoCryptoSuites(const rtc::CryptoOptions& crypto_options,
164 GetDefaultSrtpCryptoSuites(crypto_suites); 182 std::vector<int>* crypto_suites) {
183 GetDefaultSrtpCryptoSuites(crypto_options, crypto_suites);
165 } 184 }
166 185
167 void GetSupportedVideoCryptoSuiteNames( 186 void GetSupportedVideoCryptoSuiteNames(const rtc::CryptoOptions& crypto_options,
168 std::vector<std::string>* crypto_suite_names) { 187 std::vector<std::string>* crypto_suite_names) {
169 GetSupportedCryptoSuiteNames(GetSupportedVideoCryptoSuites, 188 GetSupportedCryptoSuiteNames(GetSupportedVideoCryptoSuites,
170 crypto_suite_names); 189 crypto_options, crypto_suite_names);
171 } 190 }
172 191
173 void GetSupportedDataCryptoSuites(std::vector<int>* crypto_suites) { 192 void GetSupportedDataCryptoSuites(const rtc::CryptoOptions& crypto_options,
174 GetDefaultSrtpCryptoSuites(crypto_suites); 193 std::vector<int>* crypto_suites) {
194 GetDefaultSrtpCryptoSuites(crypto_options, crypto_suites);
175 } 195 }
176 196
177 void GetSupportedDataCryptoSuiteNames( 197 void GetSupportedDataCryptoSuiteNames(const rtc::CryptoOptions& crypto_options,
178 std::vector<std::string>* crypto_suite_names) { 198 std::vector<std::string>* crypto_suite_names) {
179 GetSupportedCryptoSuiteNames(GetSupportedDataCryptoSuites, 199 GetSupportedCryptoSuiteNames(GetSupportedDataCryptoSuites,
180 crypto_suite_names); 200 crypto_options, crypto_suite_names);
181 } 201 }
182 202
183 void GetDefaultSrtpCryptoSuites(std::vector<int>* crypto_suites) { 203 void GetDefaultSrtpCryptoSuites(const rtc::CryptoOptions& crypto_options,
204 std::vector<int>* crypto_suites) {
184 #ifdef HAVE_SRTP 205 #ifdef HAVE_SRTP
206 if (crypto_options.enable_gcm_crypto_suites) {
207 crypto_suites->push_back(rtc::SRTP_AEAD_AES_256_GCM);
208 crypto_suites->push_back(rtc::SRTP_AEAD_AES_128_GCM);
209 }
185 crypto_suites->push_back(rtc::SRTP_AES128_CM_SHA1_80); 210 crypto_suites->push_back(rtc::SRTP_AES128_CM_SHA1_80);
186 #endif 211 #endif
187 } 212 }
188 213
189 void GetDefaultSrtpCryptoSuiteNames( 214 void GetDefaultSrtpCryptoSuiteNames(const rtc::CryptoOptions& crypto_options,
190 std::vector<std::string>* crypto_suite_names) { 215 std::vector<std::string>* crypto_suite_names) {
191 GetSupportedCryptoSuiteNames(GetDefaultSrtpCryptoSuites, crypto_suite_names); 216 GetSupportedCryptoSuiteNames(GetDefaultSrtpCryptoSuites,
217 crypto_options, crypto_suite_names);
192 } 218 }
193 219
194 // For video support only 80-bit SHA1 HMAC. For audio 32-bit HMAC is 220 // Support any GCM cipher (if enabled through options). For video support only
195 // tolerated unless bundle is enabled because it is low overhead. Pick the 221 // 80-bit SHA1 HMAC. For audio 32-bit HMAC is tolerated unless bundle is enabled
196 // crypto in the list that is supported. 222 // because it is low overhead.
223 // Pick the crypto in the list that is supported.
197 static bool SelectCrypto(const MediaContentDescription* offer, 224 static bool SelectCrypto(const MediaContentDescription* offer,
198 bool bundle, 225 bool bundle,
226 const rtc::CryptoOptions& crypto_options,
199 CryptoParams *crypto) { 227 CryptoParams *crypto) {
200 bool audio = offer->type() == MEDIA_TYPE_AUDIO; 228 bool audio = offer->type() == MEDIA_TYPE_AUDIO;
201 const CryptoParamsVec& cryptos = offer->cryptos(); 229 const CryptoParamsVec& cryptos = offer->cryptos();
202 230
203 for (CryptoParamsVec::const_iterator i = cryptos.begin(); 231 for (CryptoParamsVec::const_iterator i = cryptos.begin();
204 i != cryptos.end(); ++i) { 232 i != cryptos.end(); ++i) {
205 if (rtc::CS_AES_CM_128_HMAC_SHA1_80 == i->cipher_suite || 233 if ((crypto_options.enable_gcm_crypto_suites &&
234 rtc::IsGcmCryptoSuiteName(i->cipher_suite)) ||
235 rtc::CS_AES_CM_128_HMAC_SHA1_80 == i->cipher_suite ||
206 (rtc::CS_AES_CM_128_HMAC_SHA1_32 == i->cipher_suite && audio && 236 (rtc::CS_AES_CM_128_HMAC_SHA1_32 == i->cipher_suite && audio &&
207 !bundle)) { 237 !bundle)) {
208 return CreateCryptoParams(i->tag, i->cipher_suite, crypto); 238 return CreateCryptoParams(i->tag, i->cipher_suite, crypto);
209 } 239 }
210 } 240 }
211 return false; 241 return false;
212 } 242 }
213 243
214 static const StreamParams* FindFirstStreamParamsByCname( 244 static const StreamParams* FindFirstStreamParamsByCname(
215 const StreamParamsVec& params_vec, 245 const StreamParamsVec& params_vec,
(...skipping 844 matching lines...) Expand 10 before | Expand all | Expand 10 after
1060 &negotiated_rtp_extensions); 1090 &negotiated_rtp_extensions);
1061 answer->set_rtp_header_extensions(negotiated_rtp_extensions); 1091 answer->set_rtp_header_extensions(negotiated_rtp_extensions);
1062 1092
1063 answer->set_rtcp_mux(options.rtcp_mux_enabled && offer->rtcp_mux()); 1093 answer->set_rtcp_mux(options.rtcp_mux_enabled && offer->rtcp_mux());
1064 if (answer->type() == cricket::MEDIA_TYPE_VIDEO) { 1094 if (answer->type() == cricket::MEDIA_TYPE_VIDEO) {
1065 answer->set_rtcp_reduced_size(offer->rtcp_reduced_size()); 1095 answer->set_rtcp_reduced_size(offer->rtcp_reduced_size());
1066 } 1096 }
1067 1097
1068 if (sdes_policy != SEC_DISABLED) { 1098 if (sdes_policy != SEC_DISABLED) {
1069 CryptoParams crypto; 1099 CryptoParams crypto;
1070 if (SelectCrypto(offer, bundle_enabled, &crypto)) { 1100 if (SelectCrypto(offer, bundle_enabled, options.crypto_options, &crypto)) {
1071 if (current_cryptos) { 1101 if (current_cryptos) {
1072 FindMatchingCrypto(*current_cryptos, crypto, &crypto); 1102 FindMatchingCrypto(*current_cryptos, crypto, &crypto);
1073 } 1103 }
1074 answer->AddCrypto(crypto); 1104 answer->AddCrypto(crypto);
1075 } 1105 }
1076 } 1106 }
1077 1107
1078 if (answer->cryptos().empty() && 1108 if (answer->cryptos().empty() &&
1079 (offer->crypto_required() == CT_SDES || sdes_policy == SEC_REQUIRED)) { 1109 (offer->crypto_required() == CT_SDES || sdes_policy == SEC_REQUIRED)) {
1080 return false; 1110 return false;
(...skipping 495 matching lines...) Expand 10 before | Expand all | Expand 10 after
1576 GetFirstAudioContent(current_description); 1606 GetFirstAudioContent(current_description);
1577 std::string content_name = 1607 std::string content_name =
1578 current_audio_content ? current_audio_content->name : CN_AUDIO; 1608 current_audio_content ? current_audio_content->name : CN_AUDIO;
1579 1609
1580 cricket::SecurePolicy sdes_policy = 1610 cricket::SecurePolicy sdes_policy =
1581 IsDtlsActive(content_name, current_description) ? cricket::SEC_DISABLED 1611 IsDtlsActive(content_name, current_description) ? cricket::SEC_DISABLED
1582 : secure(); 1612 : secure();
1583 1613
1584 std::unique_ptr<AudioContentDescription> audio(new AudioContentDescription()); 1614 std::unique_ptr<AudioContentDescription> audio(new AudioContentDescription());
1585 std::vector<std::string> crypto_suites; 1615 std::vector<std::string> crypto_suites;
1586 GetSupportedAudioCryptoSuiteNames(&crypto_suites); 1616 GetSupportedAudioCryptoSuiteNames(options.crypto_options, &crypto_suites);
1587 if (!CreateMediaContentOffer( 1617 if (!CreateMediaContentOffer(
1588 options, 1618 options,
1589 audio_codecs, 1619 audio_codecs,
1590 sdes_policy, 1620 sdes_policy,
1591 GetCryptos(GetFirstAudioContentDescription(current_description)), 1621 GetCryptos(GetFirstAudioContentDescription(current_description)),
1592 crypto_suites, 1622 crypto_suites,
1593 audio_rtp_extensions, 1623 audio_rtp_extensions,
1594 add_legacy_, 1624 add_legacy_,
1595 current_streams, 1625 current_streams,
1596 audio.get())) { 1626 audio.get())) {
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
1636 GetFirstVideoContent(current_description); 1666 GetFirstVideoContent(current_description);
1637 std::string content_name = 1667 std::string content_name =
1638 current_video_content ? current_video_content->name : CN_VIDEO; 1668 current_video_content ? current_video_content->name : CN_VIDEO;
1639 1669
1640 cricket::SecurePolicy sdes_policy = 1670 cricket::SecurePolicy sdes_policy =
1641 IsDtlsActive(content_name, current_description) ? cricket::SEC_DISABLED 1671 IsDtlsActive(content_name, current_description) ? cricket::SEC_DISABLED
1642 : secure(); 1672 : secure();
1643 1673
1644 std::unique_ptr<VideoContentDescription> video(new VideoContentDescription()); 1674 std::unique_ptr<VideoContentDescription> video(new VideoContentDescription());
1645 std::vector<std::string> crypto_suites; 1675 std::vector<std::string> crypto_suites;
1646 GetSupportedVideoCryptoSuiteNames(&crypto_suites); 1676 GetSupportedVideoCryptoSuiteNames(options.crypto_options, &crypto_suites);
1647 if (!CreateMediaContentOffer( 1677 if (!CreateMediaContentOffer(
1648 options, 1678 options,
1649 video_codecs, 1679 video_codecs,
1650 sdes_policy, 1680 sdes_policy,
1651 GetCryptos(GetFirstVideoContentDescription(current_description)), 1681 GetCryptos(GetFirstVideoContentDescription(current_description)),
1652 crypto_suites, 1682 crypto_suites,
1653 video_rtp_extensions, 1683 video_rtp_extensions,
1654 add_legacy_, 1684 add_legacy_,
1655 current_streams, 1685 current_streams,
1656 video.get())) { 1686 video.get())) {
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
1712 // SDES doesn't make sense for SCTP, so we disable it, and we only 1742 // SDES doesn't make sense for SCTP, so we disable it, and we only
1713 // get SDES crypto suites for RTP-based data channels. 1743 // get SDES crypto suites for RTP-based data channels.
1714 sdes_policy = cricket::SEC_DISABLED; 1744 sdes_policy = cricket::SEC_DISABLED;
1715 // Unlike SetMediaProtocol below, we need to set the protocol 1745 // Unlike SetMediaProtocol below, we need to set the protocol
1716 // before we call CreateMediaContentOffer. Otherwise, 1746 // before we call CreateMediaContentOffer. Otherwise,
1717 // CreateMediaContentOffer won't know this is SCTP and will 1747 // CreateMediaContentOffer won't know this is SCTP and will
1718 // generate SSRCs rather than SIDs. 1748 // generate SSRCs rather than SIDs.
1719 data->set_protocol( 1749 data->set_protocol(
1720 secure_transport ? kMediaProtocolDtlsSctp : kMediaProtocolSctp); 1750 secure_transport ? kMediaProtocolDtlsSctp : kMediaProtocolSctp);
1721 } else { 1751 } else {
1722 GetSupportedDataCryptoSuiteNames(&crypto_suites); 1752 GetSupportedDataCryptoSuiteNames(options.crypto_options, &crypto_suites);
1723 } 1753 }
1724 1754
1725 if (!CreateMediaContentOffer( 1755 if (!CreateMediaContentOffer(
1726 options, 1756 options,
1727 *data_codecs, 1757 *data_codecs,
1728 sdes_policy, 1758 sdes_policy,
1729 GetCryptos(GetFirstDataContentDescription(current_description)), 1759 GetCryptos(GetFirstDataContentDescription(current_description)),
1730 crypto_suites, 1760 crypto_suites,
1731 RtpHeaderExtensions(), 1761 RtpHeaderExtensions(),
1732 add_legacy_, 1762 add_legacy_,
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after
2004 GetFirstMediaContentDescription(sdesc, MEDIA_TYPE_VIDEO)); 2034 GetFirstMediaContentDescription(sdesc, MEDIA_TYPE_VIDEO));
2005 } 2035 }
2006 2036
2007 const DataContentDescription* GetFirstDataContentDescription( 2037 const DataContentDescription* GetFirstDataContentDescription(
2008 const SessionDescription* sdesc) { 2038 const SessionDescription* sdesc) {
2009 return static_cast<const DataContentDescription*>( 2039 return static_cast<const DataContentDescription*>(
2010 GetFirstMediaContentDescription(sdesc, MEDIA_TYPE_DATA)); 2040 GetFirstMediaContentDescription(sdesc, MEDIA_TYPE_DATA));
2011 } 2041 }
2012 2042
2013 } // namespace cricket 2043 } // 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