aboutsummaryrefslogtreecommitdiffstats
path: root/repackaged/android
diff options
context:
space:
mode:
authorAdam Vartanian <flooey@google.com>2019-03-19 09:36:23 +0000
committerAdam Vartanian <flooey@google.com>2019-03-22 13:28:08 +0000
commited34271096dedb7af95976e27a94826a2f653cc1 (patch)
treee2aab8860d5da24d381fa23203ac751badfeb149 /repackaged/android
parent6858021441b5c56decd5e3679106db22f9f21e57 (diff)
downloadplatform_external_okhttp-ed34271096dedb7af95976e27a94826a2f653cc1.tar.gz
platform_external_okhttp-ed34271096dedb7af95976e27a94826a2f653cc1.tar.bz2
platform_external_okhttp-ed34271096dedb7af95976e27a94826a2f653cc1.zip
Use public API for Conscrypt features
Historically, extra Conscrypt features were enabled by calling hidden APIs. We now have public APIs for these, so use those instead. Continue calling the non-public APIs in most cases because older versions of Conscrypt may be bundled with apps and third-party SSLSocket providers may have taken advantage of our duck-typing to enable compatibility with these features, but never call them when dealing with a platform socket to ensure we can't break this with Conscrypt module updates. In future, we want to depend on Conscrypt stubs instead, but those don't exist yet. b/129126571 tracks that work. Test: cts -m CtsLibcoreTestCases Test: cts -m CtsLibcoreOkHttpTestCases Bug: 128280837 Change-Id: Id5a04a14ebe9737a85d3347a230132c151e1ec5a
Diffstat (limited to 'repackaged/android')
-rw-r--r--repackaged/android/src/main/java/com/android/okhttp/internal/Platform.java60
1 files changed, 50 insertions, 10 deletions
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