aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Vartanian <flooey@google.com>2019-03-22 11:57:18 -0700
committerandroid-build-merger <android-build-merger@google.com>2019-03-22 11:57:18 -0700
commit38cdd2e75ecd31b6c5de29ccf9c357626456ee2f (patch)
treee2aab8860d5da24d381fa23203ac751badfeb149
parenta8fdc956d4f16e0ee0eb012cee3fa4a026983e93 (diff)
parent7c89c012daeaaa7b4634008d3e0243697bb69222 (diff)
downloadokhttp-38cdd2e75ecd31b6c5de29ccf9c357626456ee2f.tar.gz
Merge "Use public API for Conscrypt features" am: daf92ccb09 am: d980250445
am: 7c89c012da Change-Id: Ie29b1c987f7de1f85ebdafad68877af6016e4d70
-rw-r--r--Android.bp6
-rw-r--r--android/src/main/java/com/squareup/okhttp/internal/Platform.java60
-rw-r--r--repackaged/android/src/main/java/com/android/okhttp/internal/Platform.java60
3 files changed, 106 insertions, 20 deletions
diff --git a/Android.bp b/Android.bp
index 7ce807d..e9f1dde 100644
--- a/Android.bp
+++ b/Android.bp
@@ -39,6 +39,8 @@ java_library {
no_standard_libs: true,
libs: [
"core-all",
+ // TODO(b/129126571): Depend on Conscrypt stubs instead
+ "conscrypt",
],
system_modules: "core-all-system-modules",
java_version: "1.7",
@@ -63,6 +65,8 @@ java_library {
no_standard_libs: true,
libs: [
"core-all",
+ // TODO(b/129126571): Depend on Conscrypt stubs instead
+ "conscrypt",
],
system_modules: "core-all-system-modules",
java_version: "1.7",
@@ -80,6 +84,8 @@ java_library {
no_standard_libs: true,
libs: [
"core-all",
+ // TODO(b/129126571): Depend on Conscrypt stubs instead
+ "conscrypt",
],
dex_preopt: {
enabled: false,
diff --git a/android/src/main/java/com/squareup/okhttp/internal/Platform.java b/android/src/main/java/com/squareup/okhttp/internal/Platform.java
index f4828f2..9edd58e 100644
--- a/android/src/main/java/com/squareup/okhttp/internal/Platform.java
+++ b/android/src/main/java/com/squareup/okhttp/internal/Platform.java
@@ -16,6 +16,7 @@
*/
package com.squareup.okhttp.internal;
+import android.net.ssl.SSLSockets;
import com.squareup.okhttp.Protocol;
import com.squareup.okhttp.internal.tls.RealTrustRootIndex;
import com.squareup.okhttp.internal.tls.TrustRootIndex;
@@ -25,8 +26,12 @@ import java.lang.reflect.Field;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketException;
+import java.util.Collections;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
+import javax.net.ssl.SNIHostName;
+import javax.net.ssl.SNIServerName;
+import javax.net.ssl.SSLParameters;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.X509TrustManager;
@@ -74,6 +79,13 @@ public class Platform {
return INSTANCE_HOLDER.getAndSet(platform);
}
+ // NOTE: Prior to Android Q, the standard way of accessing some Conscrypt features was to
+ // use reflection to call hidden APIs. Beginning in Q, there is public API for all of these
+ // features. We attempt to use the public API where possible, but also still call the
+ // hidden versions to continue to support old versions of Conscrypt that might be bundled with
+ // apps or third-party TLS providers that might have taken advantage of being able to
+ // duck-type their way into compatibility. For more background, see b/128280837.
+
/** setUseSessionTickets(boolean) */
private static final OptionalMethod<Socket> SET_USE_SESSION_TICKETS =
new OptionalMethod<Socket>(null, "setUseSessionTickets", Boolean.TYPE);
@@ -101,22 +113,31 @@ public class Platform {
public void configureTlsExtensions(
SSLSocket sslSocket, String hostname, List<Protocol> protocols) {
- // Enable SNI and session tickets.
+ // All extensions here use both public API and reflective calls, see note above.
+ SSLParameters sslParams = sslSocket.getSSLParameters();
if (hostname != null) {
- SET_USE_SESSION_TICKETS.invokeOptionalWithoutCheckedException(sslSocket, true);
- SET_HOSTNAME.invokeOptionalWithoutCheckedException(sslSocket, hostname);
+ // Enable session tickets
+ if (SSLSockets.isSupportedSocket(sslSocket)) {
+ SSLSockets.setUseSessionTickets(sslSocket, true);
+ } else {
+ SET_USE_SESSION_TICKETS.invokeOptionalWithoutCheckedException(sslSocket, true);
+ }
+ // Enable SNI
+ sslParams.setServerNames(
+ Collections.<SNIServerName>singletonList(new SNIHostName(hostname)));
+ if (!isPlatformSocket(sslSocket)) {
+ SET_HOSTNAME.invokeOptionalWithoutCheckedException(sslSocket, hostname);
+ }
}
- // Enable ALPN.
- boolean alpnSupported = SET_ALPN_PROTOCOLS.isSupported(sslSocket);
- if (!alpnSupported) {
- return;
- }
+ // Enable ALPN, if necessary
+ sslParams.setApplicationProtocols(getProtocolIds(protocols));
- Object[] parameters = { concatLengthPrefixed(protocols) };
- if (alpnSupported) {
+ if (!isPlatformSocket(sslSocket) && SET_ALPN_PROTOCOLS.isSupported(sslSocket)) {
+ Object[] parameters = {concatLengthPrefixed(protocols)};
SET_ALPN_PROTOCOLS.invokeWithoutCheckedException(sslSocket, parameters);
}
+ sslSocket.setSSLParameters(sslParams);
}
/**
@@ -127,6 +148,13 @@ public class Platform {
}
public String getSelectedProtocol(SSLSocket socket) {
+ // This API was added in Android Q
+ try {
+ return socket.getApplicationProtocol();
+ } catch (UnsupportedOperationException ignored) {
+ // The socket doesn't support this API, try the old reflective method
+ }
+ // This method was used through Android P, see note above
boolean alpnSupported = GET_ALPN_SELECTED_PROTOCOL.isSupported(socket);
if (!alpnSupported) {
return null;
@@ -200,6 +228,18 @@ public class Platform {
return null;
}
+ private static boolean isPlatformSocket(SSLSocket socket) {
+ return socket.getClass().getName().startsWith("com.android.org.conscrypt");
+ }
+
+ private static String[] getProtocolIds(List<Protocol> protocols) {
+ String[] result = new String[protocols.size()];
+ for (int i = 0; i < protocols.size(); i++) {
+ result[i] = protocols.get(i).toString();
+ }
+ return result;
+ }
+
/**
* Returns the concatenation of 8-bit, length prefixed protocol names.
* http://tools.ietf.org/html/draft-agl-tls-nextprotoneg-04#page-4
diff --git a/repackaged/android/src/main/java/com/android/okhttp/internal/Platform.java b/repackaged/android/src/main/java/com/android/okhttp/internal/Platform.java
index 6ddff7e..f4505af 100644
--- a/repackaged/android/src/main/java/com/android/okhttp/internal/Platform.java
+++ b/repackaged/android/src/main/java/com/android/okhttp/internal/Platform.java
@@ -17,6 +17,7 @@
*/
package com.android.okhttp.internal;
+import android.net.ssl.SSLSockets;
import com.android.okhttp.Protocol;
import com.android.okhttp.internal.tls.RealTrustRootIndex;
import com.android.okhttp.internal.tls.TrustRootIndex;
@@ -26,8 +27,12 @@ import java.lang.reflect.Field;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketException;
+import java.util.Collections;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
+import javax.net.ssl.SNIHostName;
+import javax.net.ssl.SNIServerName;
+import javax.net.ssl.SSLParameters;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.X509TrustManager;
@@ -77,6 +82,13 @@ public class Platform {
return INSTANCE_HOLDER.getAndSet(platform);
}
+ // NOTE: Prior to Android Q, the standard way of accessing some Conscrypt features was to
+ // use reflection to call hidden APIs. Beginning in Q, there is public API for all of these
+ // features. We attempt to use the public API where possible, but also still call the
+ // hidden versions to continue to support old versions of Conscrypt that might be bundled with
+ // apps or third-party TLS providers that might have taken advantage of being able to
+ // duck-type their way into compatibility. For more background, see b/128280837.
+
/** setUseSessionTickets(boolean) */
private static final OptionalMethod<Socket> SET_USE_SESSION_TICKETS =
new OptionalMethod<Socket>(null, "setUseSessionTickets", Boolean.TYPE);
@@ -105,22 +117,31 @@ public class Platform {
public void configureTlsExtensions(
SSLSocket sslSocket, String hostname, List<Protocol> protocols) {
- // Enable SNI and session tickets.
+ // All extensions here use both public API and reflective calls, see note above.
+ SSLParameters sslParams = sslSocket.getSSLParameters();
if (hostname != null) {
- SET_USE_SESSION_TICKETS.invokeOptionalWithoutCheckedException(sslSocket, true);
- SET_HOSTNAME.invokeOptionalWithoutCheckedException(sslSocket, hostname);
+ // Enable session tickets
+ if (SSLSockets.isSupportedSocket(sslSocket)) {
+ SSLSockets.setUseSessionTickets(sslSocket, true);
+ } else {
+ SET_USE_SESSION_TICKETS.invokeOptionalWithoutCheckedException(sslSocket, true);
+ }
+ // Enable SNI
+ sslParams.setServerNames(
+ Collections.<SNIServerName>singletonList(new SNIHostName(hostname)));
+ if (!isPlatformSocket(sslSocket)) {
+ SET_HOSTNAME.invokeOptionalWithoutCheckedException(sslSocket, hostname);
+ }
}
- // Enable ALPN.
- boolean alpnSupported = SET_ALPN_PROTOCOLS.isSupported(sslSocket);
- if (!alpnSupported) {
- return;
- }
+ // Enable ALPN, if necessary
+ sslParams.setApplicationProtocols(getProtocolIds(protocols));
- Object[] parameters = { concatLengthPrefixed(protocols) };
- if (alpnSupported) {
+ if (!isPlatformSocket(sslSocket) && SET_ALPN_PROTOCOLS.isSupported(sslSocket)) {
+ Object[] parameters = {concatLengthPrefixed(protocols)};
SET_ALPN_PROTOCOLS.invokeWithoutCheckedException(sslSocket, parameters);
}
+ sslSocket.setSSLParameters(sslParams);
}
/**
@@ -131,6 +152,13 @@ public class Platform {
}
public String getSelectedProtocol(SSLSocket socket) {
+ // This API was added in Android Q
+ try {
+ return socket.getApplicationProtocol();
+ } catch (UnsupportedOperationException ignored) {
+ // The socket doesn't support this API, try the old reflective method
+ }
+ // This method was used through Android P, see note above
boolean alpnSupported = GET_ALPN_SELECTED_PROTOCOL.isSupported(socket);
if (!alpnSupported) {
return null;
@@ -204,6 +232,18 @@ public class Platform {
return null;
}
+ private static boolean isPlatformSocket(SSLSocket socket) {
+ return socket.getClass().getName().startsWith("com.android.org.conscrypt");
+ }
+
+ private static String[] getProtocolIds(List<Protocol> protocols) {
+ String[] result = new String[protocols.size()];
+ for (int i = 0; i < protocols.size(); i++) {
+ result[i] = protocols.get(i).toString();
+ }
+ return result;
+ }
+
/**
* Returns the concatenation of 8-bit, length prefixed protocol names.
* http://tools.ietf.org/html/draft-agl-tls-nextprotoneg-04#page-4