Skip to content

Commit

Permalink
okhttp: introduced new TLS1.2 cipher suites and internal okhttp imple…
Browse files Browse the repository at this point in the history
…mentation for TLS1.3 prepared (#8650)

This introduces new TLS 1.2 cipher suites (#8610) and prepares the
internal okhttp implementation for TLS1.3. A new method for creating
internal ConnectionSpec was added to be able to use the newly introduced
cipher suites in the OkHttpChannelBuilder. Okhttp cipher suites
synchronized with the ones from netty.
  • Loading branch information
beatrausch committed Nov 17, 2021
1 parent a2398ce commit 5a3b8e2
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 31 deletions.
47 changes: 40 additions & 7 deletions okhttp/src/main/java/io/grpc/okhttp/OkHttpChannelBuilder.java
Expand Up @@ -105,15 +105,22 @@ private enum NegotiationType {
new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
.cipherSuites(
// The following items should be sync with Netty's Http2SecurityUtil.CIPHERS.
CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
CipherSuite.TLS_DHE_DSS_WITH_AES_128_GCM_SHA256,
CipherSuite.TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,
CipherSuite.TLS_DHE_DSS_WITH_AES_256_GCM_SHA384)
.tlsVersions(TlsVersion.TLS_1_2)
CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
CipherSuite.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
CipherSuite.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256

// TLS 1.3 does not work so far. See issues:
// https://github.com/grpc/grpc-java/issues/7765
//
// TLS 1.3
//CipherSuite.TLS_AES_128_GCM_SHA256,
//CipherSuite.TLS_AES_256_GCM_SHA384,
//CipherSuite.TLS_CHACHA20_POLY1305_SHA256
)
.tlsVersions(/*TlsVersion.TLS_1_3,*/ TlsVersion.TLS_1_2)
.supportsTlsExtensions(true)
.build();

Expand Down Expand Up @@ -396,6 +403,32 @@ public OkHttpChannelBuilder connectionSpec(
return this;
}

/**
* Sets the connection specification used for secure connections.
*
* <p>By default a modern, HTTP/2-compatible spec will be used.
*
* <p>This method is only used when building a secure connection. For plaintext
* connection, use {@link #usePlaintext()} instead.
*
* @param tlsVersions List of tls versions.
* @param cipherSuites List of cipher suites.
*/
public OkHttpChannelBuilder tlsConnectionSpec(
String[] tlsVersions, String[] cipherSuites) {
Preconditions.checkState(!freezeSecurityConfiguration,
"Cannot change security when using ChannelCredentials");
Preconditions.checkNotNull(tlsVersions, "tls versions must not null");
Preconditions.checkNotNull(cipherSuites, "ciphers must not null");

this.connectionSpec = new ConnectionSpec.Builder(true)
.supportsTlsExtensions(true)
.tlsVersions(tlsVersions)
.cipherSuites(cipherSuites)
.build();
return this;
}

/** Sets the negotiation type for the HTTP/2 connection to plaintext. */
@Override
public OkHttpChannelBuilder usePlaintext() {
Expand Down
Expand Up @@ -354,6 +354,22 @@ public enum CipherSuite {
// TLS_ECDHE_ECDSA_WITH_AES_256_CCM("TLS_ECDHE_ECDSA_WITH_AES_256_CCM", 0xc0ad, 7251, MAX_VALUE, MAX_VALUE),
// TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8("TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8", 0xc0ae, 7251, MAX_VALUE, MAX_VALUE),
// TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8("TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8", 0xc0af, 7251, MAX_VALUE, MAX_VALUE),

TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256("TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", 0xcca8),
TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256("TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256", 0xcca9),
TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256("TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256", 0xccaa),
// TLS_PSK_WITH_CHACHA20_POLY1305_SHA256("TLS_PSK_WITH_CHACHA20_POLY1305_SHA256", 0xccab),
TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256("TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256", 0xccac),
// TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256("TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256", 0xccad),
// TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256("TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256", 0xccae),

// TLS 1.3 https://tools.ietf.org/html/rfc8446
TLS_AES_128_GCM_SHA256("TLS_AES_128_GCM_SHA256", 0x1301),
TLS_AES_256_GCM_SHA384("TLS_AES_256_GCM_SHA384", 0x1302),
TLS_CHACHA20_POLY1305_SHA256("TLS_CHACHA20_POLY1305_SHA256", 0x1303),
TLS_AES_128_CCM_SHA256("TLS_AES_128_CCM_SHA256", 0x1304),
TLS_AES_128_CCM_8_SHA256("TLS_AES_128_CCM_8_SHA256", 0x1305),

;

final String javaName;
Expand All @@ -372,6 +388,12 @@ private CipherSuite(
this.javaName = javaName;
}

@SuppressWarnings("UnusedVariable")
private CipherSuite(
String javaName, int value) {
this.javaName = javaName;
}

public static CipherSuite forJavaName(String javaName) {
return javaName.startsWith("SSL_")
? valueOf("TLS_" + javaName.substring(4))
Expand Down
Expand Up @@ -30,40 +30,43 @@
*/
public final class ConnectionSpec {

// This is a subset of the cipher suites supported in Chrome 37, current as of 2014-10-5.
// All of these suites are available on Android 5.0; earlier releases support a subset of
// these suites. https://github.com/square/okhttp/issues/330
// This is nearly equal to the cipher suites supported in Chrome 72, current as of 2019-02-24.
// See https://tinyurl.com/okhttp-cipher-suites for availability.
private static final CipherSuite[] APPROVED_CIPHER_SUITES = new CipherSuite[] {
CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,

// Note that the following cipher suites are all on HTTP/2's bad cipher suites list. We'll
// continue to include them until better suites are commonly available. For example, none
// of the better cipher suites listed above shipped with Android 4.4 or Java 7.
CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA,
CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
CipherSuite.TLS_RSA_WITH_AES_128_GCM_SHA256,
CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA,
CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA,
CipherSuite.TLS_RSA_WITH_3DES_EDE_CBC_SHA,
// TLSv1.3.
CipherSuite.TLS_AES_128_GCM_SHA256,
CipherSuite.TLS_AES_256_GCM_SHA384,
CipherSuite.TLS_CHACHA20_POLY1305_SHA256,

// TLSv1.0, TLSv1.1, TLSv1.2.
CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
CipherSuite.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
CipherSuite.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,

// Note that the following cipher suites are all on HTTP/2's bad cipher suites list. We'll
// continue to include them until better suites are commonly available.
CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
CipherSuite.TLS_RSA_WITH_AES_128_GCM_SHA256,
CipherSuite.TLS_RSA_WITH_AES_256_GCM_SHA384,
CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA,
CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA,
CipherSuite.TLS_RSA_WITH_3DES_EDE_CBC_SHA
};

/** A modern TLS connection with extensions like SNI and ALPN available. */
public static final ConnectionSpec MODERN_TLS = new Builder(true)
.cipherSuites(APPROVED_CIPHER_SUITES)
.tlsVersions(TlsVersion.TLS_1_2, TlsVersion.TLS_1_1, TlsVersion.TLS_1_0)
.tlsVersions(TlsVersion.TLS_1_3, TlsVersion.TLS_1_2)
.supportsTlsExtensions(true)
.build();

/** A backwards-compatible fallback connection for interop with obsolete servers. */
public static final ConnectionSpec COMPATIBLE_TLS = new Builder(MODERN_TLS)
.tlsVersions(TlsVersion.TLS_1_0)
.tlsVersions(TlsVersion.TLS_1_3, TlsVersion.TLS_1_2, TlsVersion.TLS_1_1, TlsVersion.TLS_1_0)
.supportsTlsExtensions(true)
.build();

Expand Down
Expand Up @@ -26,6 +26,7 @@
* {@link SSLSocket#setEnabledProtocols}.
*/
public enum TlsVersion {
TLS_1_3("TLSv1.3"), // 2016.
TLS_1_2("TLSv1.2"), // 2008.
TLS_1_1("TLSv1.1"), // 2006.
TLS_1_0("TLSv1"), // 1999.
Expand All @@ -39,7 +40,9 @@ private TlsVersion(String javaName) {
}

public static TlsVersion forJavaName(String javaName) {
if ("TLSv1.2".equals(javaName)) {
if ("TLSv1.3".equals(javaName)) {
return TLS_1_3;
} else if ("TLSv1.2".equals(javaName)) {
return TLS_1_2;
} else if ("TLSv1.1".equals(javaName)) {
return TLS_1_1;
Expand Down

0 comments on commit 5a3b8e2

Please sign in to comment.