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