Bug 1568810 - Intersect platform TLS ciphers with our desired ones; r=nalexander

This would ensure we will not use ciphers not supported by the platform.

Differential Revision: https://phabricator.services.mozilla.com/D39648

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Petru Lingurar 2019-07-30 15:55:46 +00:00
Родитель 1e945a8dd6
Коммит 54ed625fc0
3 изменённых файлов: 54 добавлений и 11 удалений

Просмотреть файл

@ -4,13 +4,23 @@
package org.mozilla.gecko.background.common;
import android.util.Log;
import org.mozilla.gecko.AppConstants;
import org.mozilla.gecko.AppConstants.Versions;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.List;
import javax.net.ssl.SSLContext;
/**
* Constant values common to all Android services.
*/
public class GlobalConstants {
private static final String LOGTAG = "GlobalConstants";
public static final String BROWSER_INTENT_PACKAGE = AppConstants.ANDROID_PACKAGE_NAME;
public static final String BROWSER_INTENT_CLASS = AppConstants.MOZ_ANDROID_BROWSER_INTENT_CLASS;
@ -38,15 +48,44 @@ public class GlobalConstants {
* ELB cipher suites:
* <http://docs.aws.amazon.com/ElasticLoadBalancing/latest/DeveloperGuide/elb-security-policy-table.html>
*/
public static final String[] DEFAULT_CIPHER_SUITES;
public static final String[] DEFAULT_PROTOCOLS;
private static final String[] REQUIRED_CIPHER_SUITES;
private static final String[] REQUIRED_PROTOCOLS;
private static String[] ENABLED_CIPHERS = null;
/**
* Get the TLS cipher suites we want enabled. See {@link #REQUIRED_CIPHER_SUITES}
*
* @return an intersection of our desired ciphers with the ones the platform supports.
*/
public synchronized static String[] getTlsCipherSuites() {
if (ENABLED_CIPHERS == null) {
final List<String> defaultCiphers = Arrays.asList(REQUIRED_CIPHER_SUITES);
String[] platformCiphers = new String[0];
try {
platformCiphers = SSLContext.getDefault().getSocketFactory().getSupportedCipherSuites();
} catch (NoSuchAlgorithmException e) {
Log.e(LOGTAG, e.getLocalizedMessage());
}
defaultCiphers.retainAll(Arrays.asList(platformCiphers));
ENABLED_CIPHERS = defaultCiphers.toArray(new String[0]);
}
return ENABLED_CIPHERS;
}
/**
* Get the TLS protocols we currently support. See {@link #REQUIRED_CIPHER_SUITES}
*/
public static String[] getTlsProtocols() {
return REQUIRED_PROTOCOLS;
}
static {
// ChaCha20-Poly1305 seems fastest on mobile.
// Otherwise prioritize 128 over 256 as a tradeoff between device CPU/battery
// and the minor increase in strength.
if (Versions.feature29Plus) {
DEFAULT_CIPHER_SUITES = new String[]
REQUIRED_CIPHER_SUITES = new String[]
{
"TLS_CHACHA20_POLY1305_SHA256", // 29+
"TLS_AES_128_GCM_SHA256", // 29+
@ -57,7 +96,7 @@ public class GlobalConstants {
"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", // 11+
};
} else if (Versions.feature26Plus) {
DEFAULT_CIPHER_SUITES = new String[]
REQUIRED_CIPHER_SUITES = new String[]
{
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", // 20+
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", // 20+
@ -71,7 +110,7 @@ public class GlobalConstants {
"TLS_RSA_WITH_AES_128_CBC_SHA", // 9+
};
} else if (Versions.feature20Plus) {
DEFAULT_CIPHER_SUITES = new String[]
REQUIRED_CIPHER_SUITES = new String[]
{
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", // 20+
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", // 20+
@ -86,7 +125,7 @@ public class GlobalConstants {
"TLS_RSA_WITH_AES_128_CBC_SHA", // 9+
};
} else {
DEFAULT_CIPHER_SUITES = new String[]
REQUIRED_CIPHER_SUITES = new String[]
{
"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", // 11+
"TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", // 11+
@ -99,13 +138,13 @@ public class GlobalConstants {
}
if (Versions.feature29Plus) {
DEFAULT_PROTOCOLS = new String[]
REQUIRED_PROTOCOLS = new String[]
{
"TLSv1.3",
"TLSv1.2",
};
} else {
DEFAULT_PROTOCOLS = new String[]
REQUIRED_PROTOCOLS = new String[]
{
"TLSv1.2",
"TLSv1.1",

Просмотреть файл

@ -251,7 +251,11 @@ public class BaseResource implements Resource {
sslContext.init(null, null, new SecureRandom());
Logger.debug(LOG_TAG, "Using protocols and cipher suites for Android API " + android.os.Build.VERSION.SDK_INT);
SSLSocketFactory sf = new SSLSocketFactory(sslContext, GlobalConstants.DEFAULT_PROTOCOLS, GlobalConstants.DEFAULT_CIPHER_SUITES, null);
SSLSocketFactory sf = new SSLSocketFactory(
sslContext,
GlobalConstants.getTlsProtocols(),
GlobalConstants.getTlsCipherSuites(),
null);
SchemeRegistry schemeRegistry = new SchemeRegistry();
schemeRegistry.register(new Scheme("https", 443, sf));
schemeRegistry.register(new Scheme("http", 80, new PlainSocketFactory()));

Просмотреть файл

@ -20,7 +20,7 @@ public class TLSSocketFactory extends SSLSocketFactory {
private static final String LOG_TAG = "TLSSocketFactory";
// Guarded by `this`.
private static String[] cipherSuites = GlobalConstants.DEFAULT_CIPHER_SUITES;
private static String[] cipherSuites = GlobalConstants.getTlsCipherSuites();
public TLSSocketFactory(SSLContext sslContext) {
super(sslContext);
@ -55,7 +55,7 @@ public class TLSSocketFactory extends SSLSocketFactory {
@Override
public Socket createSocket(HttpParams params) throws IOException {
SSLSocket socket = (SSLSocket) super.createSocket(params);
socket.setEnabledProtocols(GlobalConstants.DEFAULT_PROTOCOLS);
socket.setEnabledProtocols(GlobalConstants.getTlsProtocols());
setEnabledCipherSuites(socket);
return socket;
}