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 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
44 | 44 |
45 #ifdef HAVE_SCTP | 45 #ifdef HAVE_SCTP |
46 #include "talk/media/sctp/sctpdataengine.h" | 46 #include "talk/media/sctp/sctpdataengine.h" |
47 #else | 47 #else |
48 static const uint32_t kMaxSctpSid = 1023; | 48 static const uint32_t kMaxSctpSid = 1023; |
49 #endif | 49 #endif |
50 | 50 |
51 namespace { | 51 namespace { |
52 const char kInline[] = "inline:"; | 52 const char kInline[] = "inline:"; |
53 | 53 |
54 void GetSupportedCryptoSuiteNames(void (*func)(std::vector<int>*), | 54 void GetSupportedCryptoSuiteNames(void (*func)(const rtc::CryptoOptions&, |
| 55 std::vector<int>*), |
| 56 const rtc::CryptoOptions& crypto_options, |
55 std::vector<std::string>* names) { | 57 std::vector<std::string>* names) { |
56 #ifdef HAVE_SRTP | 58 #ifdef HAVE_SRTP |
57 std::vector<int> crypto_suites; | 59 std::vector<int> crypto_suites; |
58 func(&crypto_suites); | 60 func(crypto_options, &crypto_suites); |
59 for (const auto crypto : crypto_suites) { | 61 for (const auto crypto : crypto_suites) { |
60 names->push_back(rtc::SrtpCryptoSuiteToName(crypto)); | 62 names->push_back(rtc::SrtpCryptoSuiteToName(crypto)); |
61 } | 63 } |
62 #endif | 64 #endif |
63 } | 65 } |
64 } | 66 } |
65 | 67 |
66 namespace cricket { | 68 namespace cricket { |
67 | 69 |
68 using rtc::scoped_ptr; | 70 using rtc::scoped_ptr; |
(...skipping 22 matching lines...) Expand all Loading... |
91 return false; | 93 return false; |
92 } | 94 } |
93 | 95 |
94 const MediaContentDescription* mdesc = | 96 const MediaContentDescription* mdesc = |
95 static_cast<const MediaContentDescription*>(content->description); | 97 static_cast<const MediaContentDescription*>(content->description); |
96 return mdesc && mdesc->type() == media_type; | 98 return mdesc && mdesc->type() == media_type; |
97 } | 99 } |
98 | 100 |
99 static bool CreateCryptoParams(int tag, const std::string& cipher, | 101 static bool CreateCryptoParams(int tag, const std::string& cipher, |
100 CryptoParams *out) { | 102 CryptoParams *out) { |
| 103 int key_len; |
| 104 int salt_len; |
| 105 if (!rtc::GetSrtpKeyAndSaltLengths( |
| 106 rtc::SrtpCryptoSuiteFromName(cipher), &key_len, &salt_len)) { |
| 107 return false; |
| 108 } |
| 109 |
| 110 int master_key_base64_len = (key_len + salt_len) * 4 / 3; |
| 111 |
101 std::string key; | 112 std::string key; |
102 key.reserve(SRTP_MASTER_KEY_BASE64_LEN); | 113 key.reserve(master_key_base64_len); |
103 | 114 |
104 if (!rtc::CreateRandomString(SRTP_MASTER_KEY_BASE64_LEN, &key)) { | 115 if (!rtc::CreateRandomString(master_key_base64_len, &key)) { |
105 return false; | 116 return false; |
106 } | 117 } |
107 out->tag = tag; | 118 out->tag = tag; |
108 out->cipher_suite = cipher; | 119 out->cipher_suite = cipher; |
109 out->key_params = kInline; | 120 out->key_params = kInline; |
110 out->key_params += key; | 121 out->key_params += key; |
111 return true; | 122 return true; |
112 } | 123 } |
113 | 124 |
114 #ifdef HAVE_SRTP | 125 #ifdef HAVE_SRTP |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
155 for (CryptoParamsVec::const_iterator it = cryptos.begin(); | 166 for (CryptoParamsVec::const_iterator it = cryptos.begin(); |
156 it != cryptos.end(); ++it) { | 167 it != cryptos.end(); ++it) { |
157 if (crypto.Matches(*it)) { | 168 if (crypto.Matches(*it)) { |
158 *out = *it; | 169 *out = *it; |
159 return true; | 170 return true; |
160 } | 171 } |
161 } | 172 } |
162 return false; | 173 return false; |
163 } | 174 } |
164 | 175 |
165 // For audio, HMAC 32 is prefered because of the low overhead. | 176 // For audio, HMAC 32 is prefered over HMAC 80 because of the low overhead. |
166 void GetSupportedAudioCryptoSuites(std::vector<int>* crypto_suites) { | 177 void GetSupportedAudioCryptoSuites(const rtc::CryptoOptions& crypto_options, |
| 178 std::vector<int>* crypto_suites) { |
167 #ifdef HAVE_SRTP | 179 #ifdef HAVE_SRTP |
| 180 if (crypto_options.enable_gcm_crypto_suites) { |
| 181 crypto_suites->push_back(rtc::SRTP_AEAD_AES_256_GCM); |
| 182 crypto_suites->push_back(rtc::SRTP_AEAD_AES_128_GCM); |
| 183 } |
168 crypto_suites->push_back(rtc::SRTP_AES128_CM_SHA1_32); | 184 crypto_suites->push_back(rtc::SRTP_AES128_CM_SHA1_32); |
169 crypto_suites->push_back(rtc::SRTP_AES128_CM_SHA1_80); | 185 crypto_suites->push_back(rtc::SRTP_AES128_CM_SHA1_80); |
170 #endif | 186 #endif |
171 } | 187 } |
172 | 188 |
173 void GetSupportedAudioCryptoSuiteNames( | 189 void GetSupportedAudioCryptoSuiteNames(const rtc::CryptoOptions& crypto_options, |
174 std::vector<std::string>* crypto_suite_names) { | 190 std::vector<std::string>* crypto_suite_names) { |
175 GetSupportedCryptoSuiteNames(GetSupportedAudioCryptoSuites, | 191 GetSupportedCryptoSuiteNames(GetSupportedAudioCryptoSuites, |
176 crypto_suite_names); | 192 crypto_options, crypto_suite_names); |
177 } | 193 } |
178 | 194 |
179 void GetSupportedVideoCryptoSuites(std::vector<int>* crypto_suites) { | 195 void GetSupportedVideoCryptoSuites(const rtc::CryptoOptions& crypto_options, |
180 GetDefaultSrtpCryptoSuites(crypto_suites); | 196 std::vector<int>* crypto_suites) { |
| 197 GetDefaultSrtpCryptoSuites(crypto_options, crypto_suites); |
181 } | 198 } |
182 | 199 |
183 void GetSupportedVideoCryptoSuiteNames( | 200 void GetSupportedVideoCryptoSuiteNames(const rtc::CryptoOptions& crypto_options, |
184 std::vector<std::string>* crypto_suite_names) { | 201 std::vector<std::string>* crypto_suite_names) { |
185 GetSupportedCryptoSuiteNames(GetSupportedVideoCryptoSuites, | 202 GetSupportedCryptoSuiteNames(GetSupportedVideoCryptoSuites, |
186 crypto_suite_names); | 203 crypto_options, crypto_suite_names); |
187 } | 204 } |
188 | 205 |
189 void GetSupportedDataCryptoSuites(std::vector<int>* crypto_suites) { | 206 void GetSupportedDataCryptoSuites(const rtc::CryptoOptions& crypto_options, |
190 GetDefaultSrtpCryptoSuites(crypto_suites); | 207 std::vector<int>* crypto_suites) { |
| 208 GetDefaultSrtpCryptoSuites(crypto_options, crypto_suites); |
191 } | 209 } |
192 | 210 |
193 void GetSupportedDataCryptoSuiteNames( | 211 void GetSupportedDataCryptoSuiteNames(const rtc::CryptoOptions& crypto_options, |
194 std::vector<std::string>* crypto_suite_names) { | 212 std::vector<std::string>* crypto_suite_names) { |
195 GetSupportedCryptoSuiteNames(GetSupportedDataCryptoSuites, | 213 GetSupportedCryptoSuiteNames(GetSupportedDataCryptoSuites, |
196 crypto_suite_names); | 214 crypto_options, crypto_suite_names); |
197 } | 215 } |
198 | 216 |
199 void GetDefaultSrtpCryptoSuites(std::vector<int>* crypto_suites) { | 217 void GetDefaultSrtpCryptoSuites(const rtc::CryptoOptions& crypto_options, |
| 218 std::vector<int>* crypto_suites) { |
200 #ifdef HAVE_SRTP | 219 #ifdef HAVE_SRTP |
| 220 if (crypto_options.enable_gcm_crypto_suites) { |
| 221 crypto_suites->push_back(rtc::SRTP_AEAD_AES_256_GCM); |
| 222 crypto_suites->push_back(rtc::SRTP_AEAD_AES_128_GCM); |
| 223 } |
201 crypto_suites->push_back(rtc::SRTP_AES128_CM_SHA1_80); | 224 crypto_suites->push_back(rtc::SRTP_AES128_CM_SHA1_80); |
202 #endif | 225 #endif |
203 } | 226 } |
204 | 227 |
205 void GetDefaultSrtpCryptoSuiteNames( | 228 void GetDefaultSrtpCryptoSuiteNames(const rtc::CryptoOptions& crypto_options, |
206 std::vector<std::string>* crypto_suite_names) { | 229 std::vector<std::string>* crypto_suite_names) { |
207 GetSupportedCryptoSuiteNames(GetDefaultSrtpCryptoSuites, crypto_suite_names); | 230 GetSupportedCryptoSuiteNames(GetDefaultSrtpCryptoSuites, |
| 231 crypto_options, crypto_suite_names); |
208 } | 232 } |
209 | 233 |
210 // For video support only 80-bit SHA1 HMAC. For audio 32-bit HMAC is | 234 // 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 | 235 // 80-bit SHA1 HMAC. For audio 32-bit HMAC is tolerated unless bundle is enabled |
212 // crypto in the list that is supported. | 236 // because it is low overhead. |
| 237 // Pick the crypto in the list that is supported. |
213 static bool SelectCrypto(const MediaContentDescription* offer, | 238 static bool SelectCrypto(const MediaContentDescription* offer, |
214 bool bundle, | 239 bool bundle, |
| 240 const rtc::CryptoOptions& crypto_options, |
215 CryptoParams *crypto) { | 241 CryptoParams *crypto) { |
216 bool audio = offer->type() == MEDIA_TYPE_AUDIO; | 242 bool audio = offer->type() == MEDIA_TYPE_AUDIO; |
217 const CryptoParamsVec& cryptos = offer->cryptos(); | 243 const CryptoParamsVec& cryptos = offer->cryptos(); |
218 | 244 |
219 for (CryptoParamsVec::const_iterator i = cryptos.begin(); | 245 for (CryptoParamsVec::const_iterator i = cryptos.begin(); |
220 i != cryptos.end(); ++i) { | 246 i != cryptos.end(); ++i) { |
221 if (rtc::CS_AES_CM_128_HMAC_SHA1_80 == i->cipher_suite || | 247 if ((crypto_options.enable_gcm_crypto_suites && |
| 248 rtc::IsGcmCryptoSuiteName(i->cipher_suite)) || |
| 249 rtc::CS_AES_CM_128_HMAC_SHA1_80 == i->cipher_suite || |
222 (rtc::CS_AES_CM_128_HMAC_SHA1_32 == i->cipher_suite && audio && | 250 (rtc::CS_AES_CM_128_HMAC_SHA1_32 == i->cipher_suite && audio && |
223 !bundle)) { | 251 !bundle)) { |
224 return CreateCryptoParams(i->tag, i->cipher_suite, crypto); | 252 return CreateCryptoParams(i->tag, i->cipher_suite, crypto); |
225 } | 253 } |
226 } | 254 } |
227 return false; | 255 return false; |
228 } | 256 } |
229 | 257 |
230 static const StreamParams* FindFirstStreamParamsByCname( | 258 static const StreamParams* FindFirstStreamParamsByCname( |
231 const StreamParamsVec& params_vec, | 259 const StreamParamsVec& params_vec, |
(...skipping 815 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1047 | 1075 |
1048 answer->set_rtcp_mux(options.rtcp_mux_enabled && offer->rtcp_mux()); | 1076 answer->set_rtcp_mux(options.rtcp_mux_enabled && offer->rtcp_mux()); |
1049 // TODO(deadbeef): Once we're sure this works correctly, enable it in | 1077 // TODO(deadbeef): Once we're sure this works correctly, enable it in |
1050 // CreateAnswer. | 1078 // CreateAnswer. |
1051 // if (answer->type() == cricket::MEDIA_TYPE_VIDEO) { | 1079 // if (answer->type() == cricket::MEDIA_TYPE_VIDEO) { |
1052 // answer->set_rtcp_reduced_size(offer->rtcp_reduced_size()); | 1080 // answer->set_rtcp_reduced_size(offer->rtcp_reduced_size()); |
1053 // } | 1081 // } |
1054 | 1082 |
1055 if (sdes_policy != SEC_DISABLED) { | 1083 if (sdes_policy != SEC_DISABLED) { |
1056 CryptoParams crypto; | 1084 CryptoParams crypto; |
1057 if (SelectCrypto(offer, bundle_enabled, &crypto)) { | 1085 if (SelectCrypto(offer, bundle_enabled, options.crypto_options, &crypto)) { |
1058 if (current_cryptos) { | 1086 if (current_cryptos) { |
1059 FindMatchingCrypto(*current_cryptos, crypto, &crypto); | 1087 FindMatchingCrypto(*current_cryptos, crypto, &crypto); |
1060 } | 1088 } |
1061 answer->AddCrypto(crypto); | 1089 answer->AddCrypto(crypto); |
1062 } | 1090 } |
1063 } | 1091 } |
1064 | 1092 |
1065 if (answer->cryptos().empty() && | 1093 if (answer->cryptos().empty() && |
1066 (offer->crypto_required() == CT_SDES || sdes_policy == SEC_REQUIRED)) { | 1094 (offer->crypto_required() == CT_SDES || sdes_policy == SEC_REQUIRED)) { |
1067 return false; | 1095 return false; |
(...skipping 495 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1563 GetFirstAudioContent(current_description); | 1591 GetFirstAudioContent(current_description); |
1564 std::string content_name = | 1592 std::string content_name = |
1565 current_audio_content ? current_audio_content->name : CN_AUDIO; | 1593 current_audio_content ? current_audio_content->name : CN_AUDIO; |
1566 | 1594 |
1567 cricket::SecurePolicy sdes_policy = | 1595 cricket::SecurePolicy sdes_policy = |
1568 IsDtlsActive(content_name, current_description) ? cricket::SEC_DISABLED | 1596 IsDtlsActive(content_name, current_description) ? cricket::SEC_DISABLED |
1569 : secure(); | 1597 : secure(); |
1570 | 1598 |
1571 scoped_ptr<AudioContentDescription> audio(new AudioContentDescription()); | 1599 scoped_ptr<AudioContentDescription> audio(new AudioContentDescription()); |
1572 std::vector<std::string> crypto_suites; | 1600 std::vector<std::string> crypto_suites; |
1573 GetSupportedAudioCryptoSuiteNames(&crypto_suites); | 1601 GetSupportedAudioCryptoSuiteNames(options.crypto_options, &crypto_suites); |
1574 if (!CreateMediaContentOffer( | 1602 if (!CreateMediaContentOffer( |
1575 options, | 1603 options, |
1576 audio_codecs, | 1604 audio_codecs, |
1577 sdes_policy, | 1605 sdes_policy, |
1578 GetCryptos(GetFirstAudioContentDescription(current_description)), | 1606 GetCryptos(GetFirstAudioContentDescription(current_description)), |
1579 crypto_suites, | 1607 crypto_suites, |
1580 audio_rtp_extensions, | 1608 audio_rtp_extensions, |
1581 add_legacy_, | 1609 add_legacy_, |
1582 current_streams, | 1610 current_streams, |
1583 audio.get())) { | 1611 audio.get())) { |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1622 GetFirstVideoContent(current_description); | 1650 GetFirstVideoContent(current_description); |
1623 std::string content_name = | 1651 std::string content_name = |
1624 current_video_content ? current_video_content->name : CN_VIDEO; | 1652 current_video_content ? current_video_content->name : CN_VIDEO; |
1625 | 1653 |
1626 cricket::SecurePolicy sdes_policy = | 1654 cricket::SecurePolicy sdes_policy = |
1627 IsDtlsActive(content_name, current_description) ? cricket::SEC_DISABLED | 1655 IsDtlsActive(content_name, current_description) ? cricket::SEC_DISABLED |
1628 : secure(); | 1656 : secure(); |
1629 | 1657 |
1630 scoped_ptr<VideoContentDescription> video(new VideoContentDescription()); | 1658 scoped_ptr<VideoContentDescription> video(new VideoContentDescription()); |
1631 std::vector<std::string> crypto_suites; | 1659 std::vector<std::string> crypto_suites; |
1632 GetSupportedVideoCryptoSuiteNames(&crypto_suites); | 1660 GetSupportedVideoCryptoSuiteNames(options.crypto_options, &crypto_suites); |
1633 if (!CreateMediaContentOffer( | 1661 if (!CreateMediaContentOffer( |
1634 options, | 1662 options, |
1635 video_codecs, | 1663 video_codecs, |
1636 sdes_policy, | 1664 sdes_policy, |
1637 GetCryptos(GetFirstVideoContentDescription(current_description)), | 1665 GetCryptos(GetFirstVideoContentDescription(current_description)), |
1638 crypto_suites, | 1666 crypto_suites, |
1639 video_rtp_extensions, | 1667 video_rtp_extensions, |
1640 add_legacy_, | 1668 add_legacy_, |
1641 current_streams, | 1669 current_streams, |
1642 video.get())) { | 1670 video.get())) { |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1697 // SDES doesn't make sense for SCTP, so we disable it, and we only | 1725 // SDES doesn't make sense for SCTP, so we disable it, and we only |
1698 // get SDES crypto suites for RTP-based data channels. | 1726 // get SDES crypto suites for RTP-based data channels. |
1699 sdes_policy = cricket::SEC_DISABLED; | 1727 sdes_policy = cricket::SEC_DISABLED; |
1700 // Unlike SetMediaProtocol below, we need to set the protocol | 1728 // Unlike SetMediaProtocol below, we need to set the protocol |
1701 // before we call CreateMediaContentOffer. Otherwise, | 1729 // before we call CreateMediaContentOffer. Otherwise, |
1702 // CreateMediaContentOffer won't know this is SCTP and will | 1730 // CreateMediaContentOffer won't know this is SCTP and will |
1703 // generate SSRCs rather than SIDs. | 1731 // generate SSRCs rather than SIDs. |
1704 data->set_protocol( | 1732 data->set_protocol( |
1705 secure_transport ? kMediaProtocolDtlsSctp : kMediaProtocolSctp); | 1733 secure_transport ? kMediaProtocolDtlsSctp : kMediaProtocolSctp); |
1706 } else { | 1734 } else { |
1707 GetSupportedDataCryptoSuiteNames(&crypto_suites); | 1735 GetSupportedDataCryptoSuiteNames(options.crypto_options, &crypto_suites); |
1708 } | 1736 } |
1709 | 1737 |
1710 if (!CreateMediaContentOffer( | 1738 if (!CreateMediaContentOffer( |
1711 options, | 1739 options, |
1712 *data_codecs, | 1740 *data_codecs, |
1713 sdes_policy, | 1741 sdes_policy, |
1714 GetCryptos(GetFirstDataContentDescription(current_description)), | 1742 GetCryptos(GetFirstDataContentDescription(current_description)), |
1715 crypto_suites, | 1743 crypto_suites, |
1716 RtpHeaderExtensions(), | 1744 RtpHeaderExtensions(), |
1717 add_legacy_, | 1745 add_legacy_, |
(...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1987 GetFirstMediaContentDescription(sdesc, MEDIA_TYPE_VIDEO)); | 2015 GetFirstMediaContentDescription(sdesc, MEDIA_TYPE_VIDEO)); |
1988 } | 2016 } |
1989 | 2017 |
1990 const DataContentDescription* GetFirstDataContentDescription( | 2018 const DataContentDescription* GetFirstDataContentDescription( |
1991 const SessionDescription* sdesc) { | 2019 const SessionDescription* sdesc) { |
1992 return static_cast<const DataContentDescription*>( | 2020 return static_cast<const DataContentDescription*>( |
1993 GetFirstMediaContentDescription(sdesc, MEDIA_TYPE_DATA)); | 2021 GetFirstMediaContentDescription(sdesc, MEDIA_TYPE_DATA)); |
1994 } | 2022 } |
1995 | 2023 |
1996 } // namespace cricket | 2024 } // namespace cricket |
OLD | NEW |