| 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 |