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)(std::vector<int>*, |
55 std::vector<std::string>* names) { | 55 const cricket::MediaSessionOptions&), |
| 56 std::vector<std::string>* names, |
| 57 const cricket::MediaSessionOptions& options) { |
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_suites, options); |
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(std::vector<int>* crypto_suites, |
| 178 const MediaSessionOptions& options) { |
167 #ifdef HAVE_SRTP | 179 #ifdef HAVE_SRTP |
| 180 if (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( |
174 std::vector<std::string>* crypto_suite_names) { | 190 std::vector<std::string>* crypto_suite_names, |
| 191 const MediaSessionOptions& options) { |
175 GetSupportedCryptoSuiteNames(GetSupportedAudioCryptoSuites, | 192 GetSupportedCryptoSuiteNames(GetSupportedAudioCryptoSuites, |
176 crypto_suite_names); | 193 crypto_suite_names, options); |
177 } | 194 } |
178 | 195 |
179 void GetSupportedVideoCryptoSuites(std::vector<int>* crypto_suites) { | 196 void GetSupportedVideoCryptoSuites(std::vector<int>* crypto_suites, |
180 GetDefaultSrtpCryptoSuites(crypto_suites); | 197 const MediaSessionOptions& options) { |
| 198 GetDefaultSrtpCryptoSuites(crypto_suites, options); |
181 } | 199 } |
182 | 200 |
183 void GetSupportedVideoCryptoSuiteNames( | 201 void GetSupportedVideoCryptoSuiteNames( |
184 std::vector<std::string>* crypto_suite_names) { | 202 std::vector<std::string>* crypto_suite_names, |
| 203 const MediaSessionOptions& options) { |
185 GetSupportedCryptoSuiteNames(GetSupportedVideoCryptoSuites, | 204 GetSupportedCryptoSuiteNames(GetSupportedVideoCryptoSuites, |
186 crypto_suite_names); | 205 crypto_suite_names, options); |
187 } | 206 } |
188 | 207 |
189 void GetSupportedDataCryptoSuites(std::vector<int>* crypto_suites) { | 208 void GetSupportedDataCryptoSuites(std::vector<int>* crypto_suites, |
190 GetDefaultSrtpCryptoSuites(crypto_suites); | 209 const MediaSessionOptions& options) { |
| 210 GetDefaultSrtpCryptoSuites(crypto_suites, options); |
191 } | 211 } |
192 | 212 |
193 void GetSupportedDataCryptoSuiteNames( | 213 void GetSupportedDataCryptoSuiteNames( |
194 std::vector<std::string>* crypto_suite_names) { | 214 std::vector<std::string>* crypto_suite_names, |
| 215 const MediaSessionOptions& options) { |
195 GetSupportedCryptoSuiteNames(GetSupportedDataCryptoSuites, | 216 GetSupportedCryptoSuiteNames(GetSupportedDataCryptoSuites, |
196 crypto_suite_names); | 217 crypto_suite_names, options); |
197 } | 218 } |
198 | 219 |
199 void GetDefaultSrtpCryptoSuites(std::vector<int>* crypto_suites) { | 220 void GetDefaultSrtpCryptoSuites(std::vector<int>* crypto_suites, |
| 221 const MediaSessionOptions& options) { |
200 #ifdef HAVE_SRTP | 222 #ifdef HAVE_SRTP |
| 223 if (options.enable_gcm_crypto_suites) { |
| 224 crypto_suites->push_back(rtc::SRTP_AEAD_AES_256_GCM); |
| 225 crypto_suites->push_back(rtc::SRTP_AEAD_AES_128_GCM); |
| 226 } |
201 crypto_suites->push_back(rtc::SRTP_AES128_CM_SHA1_80); | 227 crypto_suites->push_back(rtc::SRTP_AES128_CM_SHA1_80); |
202 #endif | 228 #endif |
203 } | 229 } |
204 | 230 |
205 void GetDefaultSrtpCryptoSuiteNames( | 231 void GetDefaultSrtpCryptoSuiteNames( |
206 std::vector<std::string>* crypto_suite_names) { | 232 std::vector<std::string>* crypto_suite_names, |
207 GetSupportedCryptoSuiteNames(GetDefaultSrtpCryptoSuites, crypto_suite_names); | 233 const MediaSessionOptions& options) { |
| 234 GetSupportedCryptoSuiteNames(GetDefaultSrtpCryptoSuites, |
| 235 crypto_suite_names, options); |
208 } | 236 } |
209 | 237 |
210 // For video support only 80-bit SHA1 HMAC. For audio 32-bit HMAC is | 238 // 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 | 239 // 80-bit SHA1 HMAC. For audio 32-bit HMAC is tolerated unless bundle is enabled |
212 // crypto in the list that is supported. | 240 // because it is low overhead. |
| 241 // Pick the crypto in the list that is supported. |
213 static bool SelectCrypto(const MediaContentDescription* offer, | 242 static bool SelectCrypto(const MediaContentDescription* offer, |
214 bool bundle, | 243 bool bundle, |
| 244 const MediaSessionOptions& options, |
215 CryptoParams *crypto) { | 245 CryptoParams *crypto) { |
216 bool audio = offer->type() == MEDIA_TYPE_AUDIO; | 246 bool audio = offer->type() == MEDIA_TYPE_AUDIO; |
217 const CryptoParamsVec& cryptos = offer->cryptos(); | 247 const CryptoParamsVec& cryptos = offer->cryptos(); |
218 | 248 |
219 for (CryptoParamsVec::const_iterator i = cryptos.begin(); | 249 for (CryptoParamsVec::const_iterator i = cryptos.begin(); |
220 i != cryptos.end(); ++i) { | 250 i != cryptos.end(); ++i) { |
221 if (rtc::CS_AES_CM_128_HMAC_SHA1_80 == i->cipher_suite || | 251 if ((options.enable_gcm_crypto_suites && |
| 252 rtc::IsGcmCryptoSuiteName(i->cipher_suite)) || |
| 253 rtc::CS_AES_CM_128_HMAC_SHA1_80 == i->cipher_suite || |
222 (rtc::CS_AES_CM_128_HMAC_SHA1_32 == i->cipher_suite && audio && | 254 (rtc::CS_AES_CM_128_HMAC_SHA1_32 == i->cipher_suite && audio && |
223 !bundle)) { | 255 !bundle)) { |
224 return CreateCryptoParams(i->tag, i->cipher_suite, crypto); | 256 return CreateCryptoParams(i->tag, i->cipher_suite, crypto); |
225 } | 257 } |
226 } | 258 } |
227 return false; | 259 return false; |
228 } | 260 } |
229 | 261 |
230 static const StreamParams* FindFirstStreamParamsByCname( | 262 static const StreamParams* FindFirstStreamParamsByCname( |
231 const StreamParamsVec& params_vec, | 263 const StreamParamsVec& params_vec, |
(...skipping 812 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1044 | 1076 |
1045 answer->set_rtcp_mux(options.rtcp_mux_enabled && offer->rtcp_mux()); | 1077 answer->set_rtcp_mux(options.rtcp_mux_enabled && offer->rtcp_mux()); |
1046 // TODO(deadbeef): Once we're sure this works correctly, enable it in | 1078 // TODO(deadbeef): Once we're sure this works correctly, enable it in |
1047 // CreateAnswer. | 1079 // CreateAnswer. |
1048 // if (answer->type() == cricket::MEDIA_TYPE_VIDEO) { | 1080 // if (answer->type() == cricket::MEDIA_TYPE_VIDEO) { |
1049 // answer->set_rtcp_reduced_size(offer->rtcp_reduced_size()); | 1081 // answer->set_rtcp_reduced_size(offer->rtcp_reduced_size()); |
1050 // } | 1082 // } |
1051 | 1083 |
1052 if (sdes_policy != SEC_DISABLED) { | 1084 if (sdes_policy != SEC_DISABLED) { |
1053 CryptoParams crypto; | 1085 CryptoParams crypto; |
1054 if (SelectCrypto(offer, bundle_enabled, &crypto)) { | 1086 if (SelectCrypto(offer, bundle_enabled, options, &crypto)) { |
1055 if (current_cryptos) { | 1087 if (current_cryptos) { |
1056 FindMatchingCrypto(*current_cryptos, crypto, &crypto); | 1088 FindMatchingCrypto(*current_cryptos, crypto, &crypto); |
1057 } | 1089 } |
1058 answer->AddCrypto(crypto); | 1090 answer->AddCrypto(crypto); |
1059 } | 1091 } |
1060 } | 1092 } |
1061 | 1093 |
1062 if (answer->cryptos().empty() && | 1094 if (answer->cryptos().empty() && |
1063 (offer->crypto_required() == CT_SDES || sdes_policy == SEC_REQUIRED)) { | 1095 (offer->crypto_required() == CT_SDES || sdes_policy == SEC_REQUIRED)) { |
1064 return false; | 1096 return false; |
(...skipping 490 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1555 const RtpHeaderExtensions& audio_rtp_extensions, | 1587 const RtpHeaderExtensions& audio_rtp_extensions, |
1556 const AudioCodecs& audio_codecs, | 1588 const AudioCodecs& audio_codecs, |
1557 StreamParamsVec* current_streams, | 1589 StreamParamsVec* current_streams, |
1558 SessionDescription* desc) const { | 1590 SessionDescription* desc) const { |
1559 cricket::SecurePolicy sdes_policy = | 1591 cricket::SecurePolicy sdes_policy = |
1560 IsDtlsActive(CN_AUDIO, current_description) ? | 1592 IsDtlsActive(CN_AUDIO, current_description) ? |
1561 cricket::SEC_DISABLED : secure(); | 1593 cricket::SEC_DISABLED : secure(); |
1562 | 1594 |
1563 scoped_ptr<AudioContentDescription> audio(new AudioContentDescription()); | 1595 scoped_ptr<AudioContentDescription> audio(new AudioContentDescription()); |
1564 std::vector<std::string> crypto_suites; | 1596 std::vector<std::string> crypto_suites; |
1565 GetSupportedAudioCryptoSuiteNames(&crypto_suites); | 1597 GetSupportedAudioCryptoSuiteNames(&crypto_suites, options); |
1566 if (!CreateMediaContentOffer( | 1598 if (!CreateMediaContentOffer( |
1567 options, | 1599 options, |
1568 audio_codecs, | 1600 audio_codecs, |
1569 sdes_policy, | 1601 sdes_policy, |
1570 GetCryptos(GetFirstAudioContentDescription(current_description)), | 1602 GetCryptos(GetFirstAudioContentDescription(current_description)), |
1571 crypto_suites, | 1603 crypto_suites, |
1572 audio_rtp_extensions, | 1604 audio_rtp_extensions, |
1573 add_legacy_, | 1605 add_legacy_, |
1574 current_streams, | 1606 current_streams, |
1575 audio.get())) { | 1607 audio.get())) { |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1609 const RtpHeaderExtensions& video_rtp_extensions, | 1641 const RtpHeaderExtensions& video_rtp_extensions, |
1610 const VideoCodecs& video_codecs, | 1642 const VideoCodecs& video_codecs, |
1611 StreamParamsVec* current_streams, | 1643 StreamParamsVec* current_streams, |
1612 SessionDescription* desc) const { | 1644 SessionDescription* desc) const { |
1613 cricket::SecurePolicy sdes_policy = | 1645 cricket::SecurePolicy sdes_policy = |
1614 IsDtlsActive(CN_VIDEO, current_description) ? | 1646 IsDtlsActive(CN_VIDEO, current_description) ? |
1615 cricket::SEC_DISABLED : secure(); | 1647 cricket::SEC_DISABLED : secure(); |
1616 | 1648 |
1617 scoped_ptr<VideoContentDescription> video(new VideoContentDescription()); | 1649 scoped_ptr<VideoContentDescription> video(new VideoContentDescription()); |
1618 std::vector<std::string> crypto_suites; | 1650 std::vector<std::string> crypto_suites; |
1619 GetSupportedVideoCryptoSuiteNames(&crypto_suites); | 1651 GetSupportedVideoCryptoSuiteNames(&crypto_suites, options); |
1620 if (!CreateMediaContentOffer( | 1652 if (!CreateMediaContentOffer( |
1621 options, | 1653 options, |
1622 video_codecs, | 1654 video_codecs, |
1623 sdes_policy, | 1655 sdes_policy, |
1624 GetCryptos(GetFirstVideoContentDescription(current_description)), | 1656 GetCryptos(GetFirstVideoContentDescription(current_description)), |
1625 crypto_suites, | 1657 crypto_suites, |
1626 video_rtp_extensions, | 1658 video_rtp_extensions, |
1627 add_legacy_, | 1659 add_legacy_, |
1628 current_streams, | 1660 current_streams, |
1629 video.get())) { | 1661 video.get())) { |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1679 // SDES doesn't make sense for SCTP, so we disable it, and we only | 1711 // SDES doesn't make sense for SCTP, so we disable it, and we only |
1680 // get SDES crypto suites for RTP-based data channels. | 1712 // get SDES crypto suites for RTP-based data channels. |
1681 sdes_policy = cricket::SEC_DISABLED; | 1713 sdes_policy = cricket::SEC_DISABLED; |
1682 // Unlike SetMediaProtocol below, we need to set the protocol | 1714 // Unlike SetMediaProtocol below, we need to set the protocol |
1683 // before we call CreateMediaContentOffer. Otherwise, | 1715 // before we call CreateMediaContentOffer. Otherwise, |
1684 // CreateMediaContentOffer won't know this is SCTP and will | 1716 // CreateMediaContentOffer won't know this is SCTP and will |
1685 // generate SSRCs rather than SIDs. | 1717 // generate SSRCs rather than SIDs. |
1686 data->set_protocol( | 1718 data->set_protocol( |
1687 secure_transport ? kMediaProtocolDtlsSctp : kMediaProtocolSctp); | 1719 secure_transport ? kMediaProtocolDtlsSctp : kMediaProtocolSctp); |
1688 } else { | 1720 } else { |
1689 GetSupportedDataCryptoSuiteNames(&crypto_suites); | 1721 GetSupportedDataCryptoSuiteNames(&crypto_suites, options); |
1690 } | 1722 } |
1691 | 1723 |
1692 if (!CreateMediaContentOffer( | 1724 if (!CreateMediaContentOffer( |
1693 options, | 1725 options, |
1694 *data_codecs, | 1726 *data_codecs, |
1695 sdes_policy, | 1727 sdes_policy, |
1696 GetCryptos(GetFirstDataContentDescription(current_description)), | 1728 GetCryptos(GetFirstDataContentDescription(current_description)), |
1697 crypto_suites, | 1729 crypto_suites, |
1698 RtpHeaderExtensions(), | 1730 RtpHeaderExtensions(), |
1699 add_legacy_, | 1731 add_legacy_, |
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1972 GetFirstMediaContentDescription(sdesc, MEDIA_TYPE_VIDEO)); | 2004 GetFirstMediaContentDescription(sdesc, MEDIA_TYPE_VIDEO)); |
1973 } | 2005 } |
1974 | 2006 |
1975 const DataContentDescription* GetFirstDataContentDescription( | 2007 const DataContentDescription* GetFirstDataContentDescription( |
1976 const SessionDescription* sdesc) { | 2008 const SessionDescription* sdesc) { |
1977 return static_cast<const DataContentDescription*>( | 2009 return static_cast<const DataContentDescription*>( |
1978 GetFirstMediaContentDescription(sdesc, MEDIA_TYPE_DATA)); | 2010 GetFirstMediaContentDescription(sdesc, MEDIA_TYPE_DATA)); |
1979 } | 2011 } |
1980 | 2012 |
1981 } // namespace cricket | 2013 } // namespace cricket |
OLD | NEW |