Skip to content

Commit

Permalink
Okhttp cipher suites for TLS1.3 prepared
Browse files Browse the repository at this point in the history
Additional TLS1.2 cipher suites added
Default connection spec synced with netty
Introduced new method for internal connection in OkHttpChannelBuilder
  • Loading branch information
beatrausch committed Nov 4, 2021
1 parent ee395e0 commit 49fd62a
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 31 deletions.
69 changes: 62 additions & 7 deletions okhttp/src/main/java/io/grpc/okhttp/OkHttpChannelBuilder.java
Expand Up @@ -105,15 +105,21 @@ 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 +402,55 @@ 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.
* @param supportsTlsExtensions Support of TLS extensions.
*/
public OkHttpChannelBuilder tlsConnectionSpec(
String[] tlsVersions, String[] cipherSuites,
boolean supportsTlsExtensions) {
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(supportsTlsExtensions)
.tlsVersions(tlsVersions)
.cipherSuites(cipherSuites)
.build();
return this;
}

/**
* For secure connection, provides a ConnectionSpec to specify Cipher suite and
* TLS versions.
*
* <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.
*
* @throws IllegalArgumentException
* If {@code connectionSpec} is not with TLS
*/
public OkHttpChannelBuilder internalConnectionSpec(
io.grpc.okhttp.internal.ConnectionSpec connectionSpec) {
Preconditions.checkState(!freezeSecurityConfiguration,
"Cannot change security when using ChannelCredentials");
Preconditions.checkArgument(connectionSpec.isTls(), "plaintext ConnectionSpec is not accepted");
this.connectionSpec = connectionSpec;
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 49fd62a

Please sign in to comment.