Adding flag to enable/disable use of SRTP_AES128_CM_SHA1_32 crypto suite.
This flag (added to CryptoOptions) will allow applications to opt-in to use of this suite, before it's disabled by default later. See bug for more details. TBR=magjed@webrtc.org Bug: webrtc:7670 Change-Id: I800bedd4b26d807b6b7ac66b505d419c3323e454 Reviewed-on: https://webrtc-review.googlesource.com/64390 Commit-Queue: Taylor Brandstetter <deadbeef@webrtc.org> Reviewed-by: Taylor Brandstetter <deadbeef@webrtc.org> Cr-Commit-Position: refs/heads/master@{#22586}
This commit is contained in:
committed by
Commit Bot
parent
767a2ced73
commit
5e55fe845e
@ -194,14 +194,17 @@ bool FindMatchingCrypto(const CryptoParamsVec& cryptos,
|
||||
return false;
|
||||
}
|
||||
|
||||
// For audio, HMAC 32 is prefered over HMAC 80 because of the low overhead.
|
||||
// For audio, HMAC 32 (if enabled) is prefered over HMAC 80 because of the
|
||||
// low overhead.
|
||||
void GetSupportedAudioSdesCryptoSuites(const rtc::CryptoOptions& crypto_options,
|
||||
std::vector<int>* crypto_suites) {
|
||||
if (crypto_options.enable_gcm_crypto_suites) {
|
||||
crypto_suites->push_back(rtc::SRTP_AEAD_AES_256_GCM);
|
||||
crypto_suites->push_back(rtc::SRTP_AEAD_AES_128_GCM);
|
||||
}
|
||||
crypto_suites->push_back(rtc::SRTP_AES128_CM_SHA1_32);
|
||||
if (crypto_options.enable_aes128_sha1_32_crypto_cipher) {
|
||||
crypto_suites->push_back(rtc::SRTP_AES128_CM_SHA1_32);
|
||||
}
|
||||
crypto_suites->push_back(rtc::SRTP_AES128_CM_SHA1_80);
|
||||
}
|
||||
|
||||
@ -245,8 +248,8 @@ void GetSupportedDataSdesCryptoSuiteNames(
|
||||
}
|
||||
|
||||
// Support any GCM cipher (if enabled through options). For video support only
|
||||
// 80-bit SHA1 HMAC. For audio 32-bit HMAC is tolerated unless bundle is enabled
|
||||
// because it is low overhead.
|
||||
// 80-bit SHA1 HMAC. For audio 32-bit HMAC is tolerated (if enabled) unless
|
||||
// bundle is enabled because it is low overhead.
|
||||
// Pick the crypto in the list that is supported.
|
||||
static bool SelectCrypto(const MediaContentDescription* offer,
|
||||
bool bundle,
|
||||
@ -261,7 +264,7 @@ static bool SelectCrypto(const MediaContentDescription* offer,
|
||||
rtc::IsGcmCryptoSuiteName(i->cipher_suite)) ||
|
||||
rtc::CS_AES_CM_128_HMAC_SHA1_80 == i->cipher_suite ||
|
||||
(rtc::CS_AES_CM_128_HMAC_SHA1_32 == i->cipher_suite && audio &&
|
||||
!bundle)) {
|
||||
!bundle && crypto_options.enable_aes128_sha1_32_crypto_cipher)) {
|
||||
return CreateCryptoParams(i->tag, i->cipher_suite, crypto);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1365,13 +1365,10 @@ class PeerConnectionIntegrationBaseTest : public testing::Test {
|
||||
return expectations_correct;
|
||||
}
|
||||
|
||||
void TestGcmNegotiationUsesCipherSuite(bool local_gcm_enabled,
|
||||
bool remote_gcm_enabled,
|
||||
int expected_cipher_suite) {
|
||||
PeerConnectionFactory::Options caller_options;
|
||||
caller_options.crypto_options.enable_gcm_crypto_suites = local_gcm_enabled;
|
||||
PeerConnectionFactory::Options callee_options;
|
||||
callee_options.crypto_options.enable_gcm_crypto_suites = remote_gcm_enabled;
|
||||
void TestNegotiatedCipherSuite(
|
||||
const PeerConnectionFactory::Options& caller_options,
|
||||
const PeerConnectionFactory::Options& callee_options,
|
||||
int expected_cipher_suite) {
|
||||
ASSERT_TRUE(CreatePeerConnectionWrappersWithOptions(caller_options,
|
||||
callee_options));
|
||||
rtc::scoped_refptr<webrtc::FakeMetricsObserver> caller_observer =
|
||||
@ -1390,6 +1387,17 @@ class PeerConnectionIntegrationBaseTest : public testing::Test {
|
||||
caller()->pc()->RegisterUMAObserver(nullptr);
|
||||
}
|
||||
|
||||
void TestGcmNegotiationUsesCipherSuite(bool local_gcm_enabled,
|
||||
bool remote_gcm_enabled,
|
||||
int expected_cipher_suite) {
|
||||
PeerConnectionFactory::Options caller_options;
|
||||
caller_options.crypto_options.enable_gcm_crypto_suites = local_gcm_enabled;
|
||||
PeerConnectionFactory::Options callee_options;
|
||||
callee_options.crypto_options.enable_gcm_crypto_suites = remote_gcm_enabled;
|
||||
TestNegotiatedCipherSuite(caller_options, callee_options,
|
||||
expected_cipher_suite);
|
||||
}
|
||||
|
||||
protected:
|
||||
const SdpSemantics sdp_semantics_;
|
||||
|
||||
@ -2600,6 +2608,40 @@ TEST_P(PeerConnectionIntegrationTest, CallerDtls10ToCalleeDtls12) {
|
||||
ASSERT_TRUE(ExpectNewFrames(media_expectations));
|
||||
}
|
||||
|
||||
// The three tests below verify that "enable_aes128_sha1_32_crypto_cipher"
|
||||
// works as expected; the cipher should only be used if enabled by both sides.
|
||||
TEST_P(PeerConnectionIntegrationTest,
|
||||
Aes128Sha1_32_CipherNotUsedWhenOnlyCallerSupported) {
|
||||
PeerConnectionFactory::Options caller_options;
|
||||
caller_options.crypto_options.enable_aes128_sha1_32_crypto_cipher = true;
|
||||
PeerConnectionFactory::Options callee_options;
|
||||
callee_options.crypto_options.enable_aes128_sha1_32_crypto_cipher = false;
|
||||
int expected_cipher_suite = rtc::SRTP_AES128_CM_SHA1_80;
|
||||
TestNegotiatedCipherSuite(caller_options, callee_options,
|
||||
expected_cipher_suite);
|
||||
}
|
||||
|
||||
TEST_P(PeerConnectionIntegrationTest,
|
||||
Aes128Sha1_32_CipherNotUsedWhenOnlyCalleeSupported) {
|
||||
PeerConnectionFactory::Options caller_options;
|
||||
caller_options.crypto_options.enable_aes128_sha1_32_crypto_cipher = false;
|
||||
PeerConnectionFactory::Options callee_options;
|
||||
callee_options.crypto_options.enable_aes128_sha1_32_crypto_cipher = true;
|
||||
int expected_cipher_suite = rtc::SRTP_AES128_CM_SHA1_80;
|
||||
TestNegotiatedCipherSuite(caller_options, callee_options,
|
||||
expected_cipher_suite);
|
||||
}
|
||||
|
||||
TEST_P(PeerConnectionIntegrationTest, Aes128Sha1_32_CipherUsedWhenSupported) {
|
||||
PeerConnectionFactory::Options caller_options;
|
||||
caller_options.crypto_options.enable_aes128_sha1_32_crypto_cipher = true;
|
||||
PeerConnectionFactory::Options callee_options;
|
||||
callee_options.crypto_options.enable_aes128_sha1_32_crypto_cipher = true;
|
||||
int expected_cipher_suite = rtc::SRTP_AES128_CM_SHA1_32;
|
||||
TestNegotiatedCipherSuite(caller_options, callee_options,
|
||||
expected_cipher_suite);
|
||||
}
|
||||
|
||||
// Test that a non-GCM cipher is used if both sides only support non-GCM.
|
||||
TEST_P(PeerConnectionIntegrationTest, NonGcmCipherUsedWhenGcmNotSupported) {
|
||||
bool local_gcm_enabled = false;
|
||||
|
||||
@ -105,7 +105,11 @@ std::vector<int> GetSupportedDtlsSrtpCryptoSuites(
|
||||
// Note: SRTP_AES128_CM_SHA1_80 is what is required to be supported (by
|
||||
// draft-ietf-rtcweb-security-arch), but SRTP_AES128_CM_SHA1_32 is allowed as
|
||||
// well, and saves a few bytes per packet if it ends up selected.
|
||||
crypto_suites.push_back(rtc::SRTP_AES128_CM_SHA1_32);
|
||||
// As the cipher suite is potentially insecure, it will only be used if
|
||||
// enabled by both peers.
|
||||
if (crypto_options.enable_aes128_sha1_32_crypto_cipher) {
|
||||
crypto_suites.push_back(rtc::SRTP_AES128_CM_SHA1_32);
|
||||
}
|
||||
crypto_suites.push_back(rtc::SRTP_AES128_CM_SHA1_80);
|
||||
return crypto_suites;
|
||||
}
|
||||
|
||||
@ -80,6 +80,15 @@ struct CryptoOptions {
|
||||
// if both sides enable it.
|
||||
bool enable_gcm_crypto_suites = false;
|
||||
|
||||
// If set to true, the (potentially insecure) crypto cipher
|
||||
// SRTP_AES128_CM_SHA1_32 will be included in the list of supported ciphers
|
||||
// during negotiation. It will only be used if both peers support it and no
|
||||
// other ciphers get preferred.
|
||||
// TODO(crbug.com/webrtc/7670): Change default to false after sending PSA and
|
||||
// giving time for users to set this flag to true explicitly, if they still
|
||||
// want to use this crypto suite.
|
||||
bool enable_aes128_sha1_32_crypto_cipher = true;
|
||||
|
||||
// If set to true, encrypted RTP header extensions as defined in RFC 6904
|
||||
// will be negotiated. They will only be used if both peers support them.
|
||||
bool enable_encrypted_rtp_header_extensions = false;
|
||||
|
||||
@ -107,6 +107,7 @@ public class PeerConnectionFactory {
|
||||
public int networkIgnoreMask;
|
||||
public boolean disableEncryption;
|
||||
public boolean disableNetworkMonitor;
|
||||
public boolean enableAes128Sha1_32CryptoCipher;
|
||||
|
||||
@CalledByNative("Options")
|
||||
int getNetworkIgnoreMask() {
|
||||
@ -122,6 +123,11 @@ public class PeerConnectionFactory {
|
||||
boolean getDisableNetworkMonitor() {
|
||||
return disableNetworkMonitor;
|
||||
}
|
||||
|
||||
@CalledByNative("Options")
|
||||
boolean getEnableAes128Sha1_32CryptoCipher() {
|
||||
return enableAes128Sha1_32CryptoCipher;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
|
||||
@ -52,6 +52,8 @@ JavaToNativePeerConnectionFactoryOptions(JNIEnv* jni,
|
||||
bool disable_encryption = Java_Options_getDisableEncryption(jni, options);
|
||||
bool disable_network_monitor =
|
||||
Java_Options_getDisableNetworkMonitor(jni, options);
|
||||
bool enable_aes128_sha1_32_crypto_cipher =
|
||||
Java_Options_getEnableAes128Sha1_32CryptoCipher(jni, options);
|
||||
|
||||
PeerConnectionFactoryInterface::Options native_options;
|
||||
|
||||
@ -60,6 +62,9 @@ JavaToNativePeerConnectionFactoryOptions(JNIEnv* jni,
|
||||
native_options.network_ignore_mask = network_ignore_mask;
|
||||
native_options.disable_encryption = disable_encryption;
|
||||
native_options.disable_network_monitor = disable_network_monitor;
|
||||
|
||||
native_options.crypto_options.enable_aes128_sha1_32_crypto_cipher =
|
||||
enable_aes128_sha1_32_crypto_cipher;
|
||||
return native_options;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
@ -34,6 +34,7 @@ void setNetworkBit(webrtc::PeerConnectionFactoryInterface::Options* options,
|
||||
@synthesize ignoreCellularNetworkAdapter = _ignoreCellularNetworkAdapter;
|
||||
@synthesize ignoreWiFiNetworkAdapter = _ignoreWiFiNetworkAdapter;
|
||||
@synthesize ignoreEthernetNetworkAdapter = _ignoreEthernetNetworkAdapter;
|
||||
@synthesize enableAes128Sha1_32CryptoCipher = _enableAes128Sha1_32CryptoCipher;
|
||||
|
||||
- (instancetype)init {
|
||||
return [super init];
|
||||
@ -50,6 +51,8 @@ void setNetworkBit(webrtc::PeerConnectionFactoryInterface::Options* options,
|
||||
setNetworkBit(&options, rtc::ADAPTER_TYPE_WIFI, self.ignoreWiFiNetworkAdapter);
|
||||
setNetworkBit(&options, rtc::ADAPTER_TYPE_ETHERNET, self.ignoreEthernetNetworkAdapter);
|
||||
|
||||
options.crypto_options.enable_aes128_sha1_32_crypto_cipher = self.enableAes128Sha1_32CryptoCipher;
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
|
||||
@ -31,6 +31,8 @@ RTC_EXPORT
|
||||
|
||||
@property(nonatomic, assign) BOOL ignoreEthernetNetworkAdapter;
|
||||
|
||||
@property(nonatomic, assign) BOOL enableAes128Sha1_32CryptoCipher;
|
||||
|
||||
- (instancetype)init NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
@end
|
||||
|
||||
Reference in New Issue
Block a user