OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |