473 lines
20 KiB
Java
473 lines
20 KiB
Java
package io.grpc.okhttp.internal;
|
|
|
|
import com.google.android.gms.analytics.ecommerce.ProductAction;
|
|
import com.google.android.gms.security.ProviderInstaller;
|
|
import java.io.IOException;
|
|
import java.lang.reflect.InvocationHandler;
|
|
import java.lang.reflect.InvocationTargetException;
|
|
import java.lang.reflect.Method;
|
|
import java.lang.reflect.Proxy;
|
|
import java.net.InetSocketAddress;
|
|
import java.net.Socket;
|
|
import java.net.SocketException;
|
|
import java.security.AccessController;
|
|
import java.security.KeyManagementException;
|
|
import java.security.NoSuchAlgorithmException;
|
|
import java.security.PrivilegedActionException;
|
|
import java.security.PrivilegedExceptionAction;
|
|
import java.security.Provider;
|
|
import java.security.Security;
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
import java.util.logging.Level;
|
|
import java.util.logging.Logger;
|
|
import javax.net.ssl.SSLContext;
|
|
import javax.net.ssl.SSLEngine;
|
|
import javax.net.ssl.SSLParameters;
|
|
import javax.net.ssl.SSLSocket;
|
|
import o.C14957gcv;
|
|
import o.C15111ghZ;
|
|
import org.apache.http.conn.ssl.SSLSocketFactory;
|
|
|
|
/* loaded from: classes6.dex */
|
|
public class Platform {
|
|
private final Provider sslProvider;
|
|
public static final Logger logger = Logger.getLogger(Platform.class.getName());
|
|
private static final String[] ANDROID_SECURITY_PROVIDERS = {"com.google.android.gms.org.conscrypt.OpenSSLProvider", "org.conscrypt.OpenSSLProvider", "com.android.org.conscrypt.OpenSSLProvider", "org.apache.harmony.xnet.provider.jsse.OpenSSLProvider", "com.google.android.libraries.stitch.sslguard.SslGuardProvider"};
|
|
private static final Platform PLATFORM = findPlatform();
|
|
|
|
/* loaded from: classes6.dex */
|
|
public enum TlsExtensionType {
|
|
ALPN_AND_NPN,
|
|
NPN,
|
|
NONE
|
|
}
|
|
|
|
public void afterHandshake(SSLSocket sSLSocket) {
|
|
}
|
|
|
|
public void configureTlsExtensions(SSLSocket sSLSocket, String str, List<Protocol> list) {
|
|
}
|
|
|
|
public String getSelectedProtocol(SSLSocket sSLSocket) {
|
|
return null;
|
|
}
|
|
|
|
public void tagSocket(Socket socket) throws SocketException {
|
|
}
|
|
|
|
public void untagSocket(Socket socket) throws SocketException {
|
|
}
|
|
|
|
public Platform(Provider provider) {
|
|
this.sslProvider = provider;
|
|
}
|
|
|
|
public void logW(String str) {
|
|
System.out.println(str);
|
|
}
|
|
|
|
public TlsExtensionType getTlsExtensionType() {
|
|
return TlsExtensionType.NONE;
|
|
}
|
|
|
|
public void connectSocket(Socket socket, InetSocketAddress inetSocketAddress, int i) throws IOException {
|
|
socket.connect(inetSocketAddress, i);
|
|
}
|
|
|
|
private static Platform findPlatform() {
|
|
Method method;
|
|
Method method2;
|
|
Method method3;
|
|
TlsExtensionType tlsExtensionType;
|
|
Provider androidSecurityProvider = getAndroidSecurityProvider();
|
|
if (androidSecurityProvider != null) {
|
|
OptionalMethod optionalMethod = new OptionalMethod(null, "setUseSessionTickets", Boolean.TYPE);
|
|
OptionalMethod optionalMethod2 = new OptionalMethod(null, "setHostname", String.class);
|
|
OptionalMethod optionalMethod3 = new OptionalMethod(byte[].class, "getAlpnSelectedProtocol", new Class[0]);
|
|
OptionalMethod optionalMethod4 = new OptionalMethod(null, "setAlpnProtocols", byte[].class);
|
|
try {
|
|
Class<?> cls = Class.forName("android.net.TrafficStats");
|
|
method = cls.getMethod("tagSocket", Socket.class);
|
|
try {
|
|
Method method4 = cls.getMethod("untagSocket", Socket.class);
|
|
method2 = method;
|
|
method3 = method4;
|
|
} catch (ClassNotFoundException | NoSuchMethodException unused) {
|
|
method2 = method;
|
|
method3 = null;
|
|
if (!androidSecurityProvider.getName().equals(ProviderInstaller.PROVIDER_NAME)) {
|
|
}
|
|
tlsExtensionType = TlsExtensionType.ALPN_AND_NPN;
|
|
return new Android(optionalMethod, optionalMethod2, method2, method3, optionalMethod3, optionalMethod4, androidSecurityProvider, tlsExtensionType);
|
|
}
|
|
} catch (ClassNotFoundException | NoSuchMethodException unused2) {
|
|
method = null;
|
|
}
|
|
if (!androidSecurityProvider.getName().equals(ProviderInstaller.PROVIDER_NAME) || androidSecurityProvider.getName().equals("Conscrypt") || androidSecurityProvider.getName().equals("Ssl_Guard") || isAtLeastAndroid5()) {
|
|
tlsExtensionType = TlsExtensionType.ALPN_AND_NPN;
|
|
} else if (isAtLeastAndroid41()) {
|
|
tlsExtensionType = TlsExtensionType.NPN;
|
|
} else {
|
|
tlsExtensionType = TlsExtensionType.NONE;
|
|
}
|
|
return new Android(optionalMethod, optionalMethod2, method2, method3, optionalMethod3, optionalMethod4, androidSecurityProvider, tlsExtensionType);
|
|
}
|
|
try {
|
|
Provider provider = SSLContext.getDefault().getProvider();
|
|
try {
|
|
try {
|
|
SSLContext sSLContext = SSLContext.getInstance(SSLSocketFactory.TLS, provider);
|
|
sSLContext.init(null, null, null);
|
|
((Method) AccessController.doPrivileged(new PrivilegedExceptionAction<Method>() { // from class: io.grpc.okhttp.internal.Platform.1
|
|
@Override // java.security.PrivilegedExceptionAction
|
|
public Method run() throws Exception {
|
|
return SSLEngine.class.getMethod("getApplicationProtocol", new Class[0]);
|
|
}
|
|
})).invoke(sSLContext.createSSLEngine(), new Object[0]);
|
|
return new JdkAlpnPlatform(provider, (Method) AccessController.doPrivileged(new PrivilegedExceptionAction<Method>() { // from class: io.grpc.okhttp.internal.Platform.2
|
|
@Override // java.security.PrivilegedExceptionAction
|
|
public Method run() throws Exception {
|
|
return SSLParameters.class.getMethod("setApplicationProtocols", String[].class);
|
|
}
|
|
}), (Method) AccessController.doPrivileged(new PrivilegedExceptionAction<Method>() { // from class: io.grpc.okhttp.internal.Platform.3
|
|
@Override // java.security.PrivilegedExceptionAction
|
|
public Method run() throws Exception {
|
|
return SSLSocket.class.getMethod("getApplicationProtocol", new Class[0]);
|
|
}
|
|
}));
|
|
} catch (IllegalAccessException | InvocationTargetException | KeyManagementException | NoSuchAlgorithmException | PrivilegedActionException unused3) {
|
|
Class<?> cls2 = Class.forName("org.eclipse.jetty.alpn.ALPN");
|
|
return new JdkWithJettyBootPlatform(cls2.getMethod("put", SSLSocket.class, Class.forName("org.eclipse.jetty.alpn.ALPN$Provider")), cls2.getMethod("get", SSLSocket.class), cls2.getMethod(ProductAction.ACTION_REMOVE, SSLSocket.class), Class.forName("org.eclipse.jetty.alpn.ALPN$ClientProvider"), Class.forName("org.eclipse.jetty.alpn.ALPN$ServerProvider"), provider);
|
|
}
|
|
} catch (ClassNotFoundException | NoSuchMethodException unused4) {
|
|
return new Platform(provider);
|
|
}
|
|
} catch (NoSuchAlgorithmException e) {
|
|
throw new RuntimeException(e);
|
|
}
|
|
}
|
|
|
|
private static boolean isAtLeastAndroid5() {
|
|
try {
|
|
Platform.class.getClassLoader().loadClass("android.net.Network");
|
|
return true;
|
|
} catch (ClassNotFoundException e) {
|
|
logger.log(Level.FINE, "Can't find class", (Throwable) e);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
private static boolean isAtLeastAndroid41() {
|
|
try {
|
|
Platform.class.getClassLoader().loadClass("android.app.ActivityOptions");
|
|
return true;
|
|
} catch (ClassNotFoundException e) {
|
|
logger.log(Level.FINE, "Can't find class", (Throwable) e);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
private static Provider getAndroidSecurityProvider() {
|
|
for (Provider provider : Security.getProviders()) {
|
|
for (String str : ANDROID_SECURITY_PROVIDERS) {
|
|
if (str.equals(provider.getClass().getName())) {
|
|
logger.log(Level.FINE, "Found registered provider {0}", str);
|
|
return provider;
|
|
}
|
|
}
|
|
}
|
|
logger.log(Level.WARNING, "Unable to find Conscrypt");
|
|
return null;
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: package-private */
|
|
/* loaded from: classes6.dex */
|
|
public static class Android extends Platform {
|
|
private final OptionalMethod<Socket> getAlpnSelectedProtocol;
|
|
private final OptionalMethod<Socket> setAlpnProtocols;
|
|
private final OptionalMethod<Socket> setHostname;
|
|
private final OptionalMethod<Socket> setUseSessionTickets;
|
|
private final TlsExtensionType tlsExtensionType;
|
|
private final Method trafficStatsTagSocket;
|
|
private final Method trafficStatsUntagSocket;
|
|
|
|
public Android(OptionalMethod<Socket> optionalMethod, OptionalMethod<Socket> optionalMethod2, Method method, Method method2, OptionalMethod<Socket> optionalMethod3, OptionalMethod<Socket> optionalMethod4, Provider provider, TlsExtensionType tlsExtensionType) {
|
|
super(provider);
|
|
this.setUseSessionTickets = optionalMethod;
|
|
this.setHostname = optionalMethod2;
|
|
this.trafficStatsTagSocket = method;
|
|
this.trafficStatsUntagSocket = method2;
|
|
this.getAlpnSelectedProtocol = optionalMethod3;
|
|
this.setAlpnProtocols = optionalMethod4;
|
|
this.tlsExtensionType = tlsExtensionType;
|
|
}
|
|
|
|
@Override // io.grpc.okhttp.internal.Platform
|
|
public void connectSocket(Socket socket, InetSocketAddress inetSocketAddress, int i) throws IOException {
|
|
try {
|
|
socket.connect(inetSocketAddress, i);
|
|
} catch (SecurityException e) {
|
|
IOException iOException = new IOException("Exception in connect");
|
|
iOException.initCause(e);
|
|
throw iOException;
|
|
}
|
|
}
|
|
|
|
@Override // io.grpc.okhttp.internal.Platform
|
|
public void configureTlsExtensions(SSLSocket sSLSocket, String str, List<Protocol> list) {
|
|
if (str != null) {
|
|
this.setUseSessionTickets.invokeOptionalWithoutCheckedException(sSLSocket, Boolean.TRUE);
|
|
this.setHostname.invokeOptionalWithoutCheckedException(sSLSocket, str);
|
|
}
|
|
if (this.setAlpnProtocols.isSupported(sSLSocket)) {
|
|
this.setAlpnProtocols.invokeWithoutCheckedException(sSLSocket, concatLengthPrefixed(list));
|
|
}
|
|
}
|
|
|
|
@Override // io.grpc.okhttp.internal.Platform
|
|
public String getSelectedProtocol(SSLSocket sSLSocket) {
|
|
byte[] bArr;
|
|
if (this.getAlpnSelectedProtocol.isSupported(sSLSocket) && (bArr = (byte[]) this.getAlpnSelectedProtocol.invokeWithoutCheckedException(sSLSocket, new Object[0])) != null) {
|
|
return new String(bArr, Util.UTF_8);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
@Override // io.grpc.okhttp.internal.Platform
|
|
public void tagSocket(Socket socket) throws SocketException {
|
|
Method method = this.trafficStatsTagSocket;
|
|
if (method == null) {
|
|
return;
|
|
}
|
|
try {
|
|
method.invoke(null, socket);
|
|
} catch (IllegalAccessException e) {
|
|
throw new RuntimeException(e);
|
|
} catch (InvocationTargetException e2) {
|
|
throw new RuntimeException(e2.getCause());
|
|
}
|
|
}
|
|
|
|
@Override // io.grpc.okhttp.internal.Platform
|
|
public void untagSocket(Socket socket) throws SocketException {
|
|
Method method = this.trafficStatsUntagSocket;
|
|
if (method == null) {
|
|
return;
|
|
}
|
|
try {
|
|
method.invoke(null, socket);
|
|
} catch (IllegalAccessException e) {
|
|
throw new RuntimeException(e);
|
|
} catch (InvocationTargetException e2) {
|
|
throw new RuntimeException(e2.getCause());
|
|
}
|
|
}
|
|
|
|
@Override // io.grpc.okhttp.internal.Platform
|
|
public TlsExtensionType getTlsExtensionType() {
|
|
return this.tlsExtensionType;
|
|
}
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: package-private */
|
|
/* loaded from: classes6.dex */
|
|
public static class JdkAlpnPlatform extends Platform {
|
|
private final Method getApplicationProtocol;
|
|
private final Method setApplicationProtocols;
|
|
|
|
private JdkAlpnPlatform(Provider provider, Method method, Method method2) {
|
|
super(provider);
|
|
this.setApplicationProtocols = method;
|
|
this.getApplicationProtocol = method2;
|
|
}
|
|
|
|
@Override // io.grpc.okhttp.internal.Platform
|
|
public TlsExtensionType getTlsExtensionType() {
|
|
return TlsExtensionType.ALPN_AND_NPN;
|
|
}
|
|
|
|
@Override // io.grpc.okhttp.internal.Platform
|
|
public void configureTlsExtensions(SSLSocket sSLSocket, String str, List<Protocol> list) {
|
|
SSLParameters sSLParameters = sSLSocket.getSSLParameters();
|
|
ArrayList arrayList = new ArrayList(list.size());
|
|
for (Protocol protocol : list) {
|
|
if (protocol != Protocol.HTTP_1_0) {
|
|
arrayList.add(protocol.toString());
|
|
}
|
|
}
|
|
try {
|
|
this.setApplicationProtocols.invoke(sSLParameters, arrayList.toArray(new String[arrayList.size()]));
|
|
sSLSocket.setSSLParameters(sSLParameters);
|
|
} catch (IllegalAccessException e) {
|
|
throw new RuntimeException(e);
|
|
} catch (InvocationTargetException e2) {
|
|
throw new RuntimeException(e2);
|
|
}
|
|
}
|
|
|
|
@Override // io.grpc.okhttp.internal.Platform
|
|
public String getSelectedProtocol(SSLSocket sSLSocket) {
|
|
try {
|
|
return (String) this.getApplicationProtocol.invoke(sSLSocket, new Object[0]);
|
|
} catch (IllegalAccessException e) {
|
|
throw new RuntimeException(e);
|
|
} catch (InvocationTargetException e2) {
|
|
throw new RuntimeException(e2);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: package-private */
|
|
/* loaded from: classes6.dex */
|
|
public static class JdkWithJettyBootPlatform extends Platform {
|
|
private final Class<?> clientProviderClass;
|
|
private final Method getMethod;
|
|
private final Method putMethod;
|
|
private final Method removeMethod;
|
|
private final Class<?> serverProviderClass;
|
|
|
|
public JdkWithJettyBootPlatform(Method method, Method method2, Method method3, Class<?> cls, Class<?> cls2, Provider provider) {
|
|
super(provider);
|
|
this.putMethod = method;
|
|
this.getMethod = method2;
|
|
this.removeMethod = method3;
|
|
this.clientProviderClass = cls;
|
|
this.serverProviderClass = cls2;
|
|
}
|
|
|
|
@Override // io.grpc.okhttp.internal.Platform
|
|
public TlsExtensionType getTlsExtensionType() {
|
|
return TlsExtensionType.ALPN_AND_NPN;
|
|
}
|
|
|
|
@Override // io.grpc.okhttp.internal.Platform
|
|
public void configureTlsExtensions(SSLSocket sSLSocket, String str, List<Protocol> list) {
|
|
ArrayList arrayList = new ArrayList(list.size());
|
|
int size = list.size();
|
|
for (int i = 0; i < size; i++) {
|
|
Protocol protocol = list.get(i);
|
|
if (protocol != Protocol.HTTP_1_0) {
|
|
arrayList.add(protocol.toString());
|
|
}
|
|
}
|
|
try {
|
|
this.putMethod.invoke(null, sSLSocket, Proxy.newProxyInstance(Platform.class.getClassLoader(), new Class[]{this.clientProviderClass, this.serverProviderClass}, new JettyNegoProvider(arrayList)));
|
|
} catch (IllegalAccessException e) {
|
|
throw new AssertionError(e);
|
|
} catch (InvocationTargetException e2) {
|
|
throw new AssertionError(e2);
|
|
}
|
|
}
|
|
|
|
@Override // io.grpc.okhttp.internal.Platform
|
|
public void afterHandshake(SSLSocket sSLSocket) {
|
|
try {
|
|
this.removeMethod.invoke(null, sSLSocket);
|
|
} catch (IllegalAccessException unused) {
|
|
throw new AssertionError();
|
|
} catch (InvocationTargetException e) {
|
|
logger.log(Level.FINE, "Failed to remove SSLSocket from Jetty ALPN", (Throwable) e);
|
|
}
|
|
}
|
|
|
|
@Override // io.grpc.okhttp.internal.Platform
|
|
public String getSelectedProtocol(SSLSocket sSLSocket) {
|
|
try {
|
|
JettyNegoProvider jettyNegoProvider = (JettyNegoProvider) Proxy.getInvocationHandler(this.getMethod.invoke(null, sSLSocket));
|
|
if (!jettyNegoProvider.unsupported && jettyNegoProvider.selected == null) {
|
|
logger.log(Level.INFO, "ALPN callback dropped: SPDY and HTTP/2 are disabled. Is alpn-boot on the boot class path?");
|
|
return null;
|
|
}
|
|
if (jettyNegoProvider.unsupported) {
|
|
return null;
|
|
}
|
|
return jettyNegoProvider.selected;
|
|
} catch (IllegalAccessException unused) {
|
|
throw new AssertionError();
|
|
} catch (InvocationTargetException unused2) {
|
|
throw new AssertionError();
|
|
}
|
|
}
|
|
}
|
|
|
|
/* loaded from: classes6.dex */
|
|
static class JettyNegoProvider implements InvocationHandler {
|
|
private final List<String> protocols;
|
|
private String selected;
|
|
private boolean unsupported;
|
|
|
|
public JettyNegoProvider(List<String> list) {
|
|
this.protocols = list;
|
|
}
|
|
|
|
@Override // java.lang.reflect.InvocationHandler
|
|
public Object invoke(Object obj, Method method, Object[] objArr) throws Throwable {
|
|
String name = method.getName();
|
|
Class<?> returnType = method.getReturnType();
|
|
if (objArr == null) {
|
|
objArr = Util.EMPTY_STRING_ARRAY;
|
|
}
|
|
if (name.equals("supports") && Boolean.TYPE == returnType) {
|
|
return Boolean.TRUE;
|
|
}
|
|
if (name.equals("unsupported") && Void.TYPE == returnType) {
|
|
this.unsupported = true;
|
|
return null;
|
|
}
|
|
if (name.equals("protocols") && objArr.length == 0) {
|
|
return this.protocols;
|
|
}
|
|
if ((name.equals("selectProtocol") || name.equals("select")) && String.class == returnType && objArr.length == 1) {
|
|
Object obj2 = objArr[0];
|
|
if (obj2 instanceof List) {
|
|
List list = (List) obj2;
|
|
int size = list.size();
|
|
for (int i = 0; i < size; i++) {
|
|
if (this.protocols.contains(list.get(i))) {
|
|
String str = (String) list.get(i);
|
|
this.selected = str;
|
|
return str;
|
|
}
|
|
}
|
|
String str2 = this.protocols.get(0);
|
|
this.selected = str2;
|
|
return str2;
|
|
}
|
|
}
|
|
if ((name.equals("protocolSelected") || name.equals("selected")) && objArr.length == 1) {
|
|
this.selected = (String) objArr[0];
|
|
return null;
|
|
}
|
|
return method.invoke(this, objArr);
|
|
}
|
|
}
|
|
|
|
public static byte[] concatLengthPrefixed(List<Protocol> list) {
|
|
C15111ghZ c15111ghZ = new C15111ghZ();
|
|
int size = list.size();
|
|
for (int i = 0; i < size; i++) {
|
|
Protocol protocol = list.get(i);
|
|
if (protocol != Protocol.HTTP_1_0) {
|
|
c15111ghZ.b(protocol.toString().length());
|
|
String obj = protocol.toString();
|
|
C14957gcv.e(obj, "");
|
|
c15111ghZ.c(obj, 0, obj.length());
|
|
}
|
|
}
|
|
return c15111ghZ.e(c15111ghZ.c);
|
|
}
|
|
|
|
public Provider getProvider() {
|
|
return this.sslProvider;
|
|
}
|
|
|
|
public String getPrefix() {
|
|
return "OkHttp";
|
|
}
|
|
|
|
public static Platform get() {
|
|
return PLATFORM;
|
|
}
|
|
}
|