1153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath/* 2153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath * Copyright (C) 2012 The Android Open Source Project 3153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath * 4153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath * Licensed under the Apache License, Version 2.0 (the "License"); 5153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath * you may not use this file except in compliance with the License. 6153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath * You may obtain a copy of the License at 7153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath * 8153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath * http://www.apache.org/licenses/LICENSE-2.0 9153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath * 10153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath * Unless required by applicable law or agreed to in writing, software 11153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath * distributed under the License is distributed on an "AS IS" BASIS, 12153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath * See the License for the specific language governing permissions and 14153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath * limitations under the License. 15153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath */ 16153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath 17153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamathpackage libcore.util; 18153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath 19153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamathimport javax.net.ssl.SSLSocket; 20153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamathimport java.io.File; 21153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamathimport java.io.IOException; 229542e750421542d4dea1f1d33c0f4349b3c48536Narayan Kamathimport java.io.OutputStream; 239542e750421542d4dea1f1d33c0f4349b3c48536Narayan Kamathimport java.lang.reflect.Constructor; 24153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamathimport java.lang.reflect.InvocationTargetException; 25153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamathimport java.lang.reflect.Method; 26153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamathimport java.net.Socket; 27153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamathimport java.net.SocketException; 28153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamathimport java.net.URI; 29153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamathimport java.net.URISyntaxException; 30153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamathimport java.net.URL; 31153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamathimport java.nio.ByteOrder; 329542e750421542d4dea1f1d33c0f4349b3c48536Narayan Kamathimport java.util.zip.Deflater; 339542e750421542d4dea1f1d33c0f4349b3c48536Narayan Kamathimport java.util.zip.DeflaterOutputStream; 34153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath 35153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath/** 36153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath * APIs for interacting with Android's core library. The main purpose of this 37153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath * class is to access hidden methods on 38153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath * 39153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath * org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl 40153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath * 41153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath * via reflection. 42153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath */ 43153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamathpublic final class Libcore { 44153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath 45153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath private Libcore() { 46153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath } 47153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath 48153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath private static final Class<?> openSslSocketClass; 49153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath private static final Method setUseSessionTickets; 50153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath private static final Method setHostname; 51153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath private static final Method setNpnProtocols; 52153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath private static final Method getNpnSelectedProtocol; 539542e750421542d4dea1f1d33c0f4349b3c48536Narayan Kamath private static final Constructor<DeflaterOutputStream> deflaterOutputStreamConstructor; 54153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath 55153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath static { 56153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath try { 57153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath openSslSocketClass = Class.forName( 58153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath "org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl"); 59153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath setUseSessionTickets = openSslSocketClass.getMethod( 60153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath "setUseSessionTickets", boolean.class); 61153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath setHostname = openSslSocketClass.getMethod("setHostname", String.class); 62153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath setNpnProtocols = openSslSocketClass.getMethod("setNpnProtocols", byte[].class); 63153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath getNpnSelectedProtocol = openSslSocketClass.getMethod("getNpnSelectedProtocol"); 649542e750421542d4dea1f1d33c0f4349b3c48536Narayan Kamath deflaterOutputStreamConstructor = DeflaterOutputStream.class.getConstructor( 659542e750421542d4dea1f1d33c0f4349b3c48536Narayan Kamath new Class[] { OutputStream.class, Deflater.class, boolean.class }); 66153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath } catch (ClassNotFoundException cnfe) { 67153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath throw new RuntimeException(cnfe); 68153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath } catch (NoSuchMethodException nsme) { 69153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath throw new RuntimeException(nsme); 70153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath } 71153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath } 72153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath 739542e750421542d4dea1f1d33c0f4349b3c48536Narayan Kamath public static DeflaterOutputStream newDeflaterOutputStream( 749542e750421542d4dea1f1d33c0f4349b3c48536Narayan Kamath OutputStream os, Deflater deflater, boolean syncFlush) { 759542e750421542d4dea1f1d33c0f4349b3c48536Narayan Kamath try { 769542e750421542d4dea1f1d33c0f4349b3c48536Narayan Kamath return deflaterOutputStreamConstructor.newInstance(os, deflater, syncFlush); 779542e750421542d4dea1f1d33c0f4349b3c48536Narayan Kamath } catch (InstantiationException e) { 789542e750421542d4dea1f1d33c0f4349b3c48536Narayan Kamath throw new RuntimeException("Unknown DeflaterOutputStream implementation."); 799542e750421542d4dea1f1d33c0f4349b3c48536Narayan Kamath } catch (IllegalAccessException e) { 809542e750421542d4dea1f1d33c0f4349b3c48536Narayan Kamath throw new RuntimeException("Unknown DeflaterOutputStream implementation."); 819542e750421542d4dea1f1d33c0f4349b3c48536Narayan Kamath } catch (InvocationTargetException e) { 829542e750421542d4dea1f1d33c0f4349b3c48536Narayan Kamath throw new RuntimeException("Unknown DeflaterOutputStream implementation."); 839542e750421542d4dea1f1d33c0f4349b3c48536Narayan Kamath } 849542e750421542d4dea1f1d33c0f4349b3c48536Narayan Kamath } 859542e750421542d4dea1f1d33c0f4349b3c48536Narayan Kamath 86153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath public static void makeTlsTolerant(SSLSocket socket, String socketHost, boolean tlsTolerant) { 87153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath if (!tlsTolerant) { 88153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath socket.setEnabledProtocols(new String[] {"SSLv3"}); 89153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath return; 90153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath } 91153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath 92153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath if (openSslSocketClass.isInstance(socket)) { 93153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath try { 94153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath setUseSessionTickets.invoke(socket, true); 95153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath setHostname.invoke(socket, socketHost); 96153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath } catch (InvocationTargetException e) { 97153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath throw new RuntimeException(e); 98153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath } catch (IllegalAccessException e) { 99153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath throw new AssertionError(e); 100153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath } 101153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath } else { 102153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath throw new RuntimeException("Unknown socket implementation."); 103153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath } 104153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath } 105153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath 106153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath /** 107153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath * Returns the negotiated protocol, or null if no protocol was negotiated. 108153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath */ 109153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath public static byte[] getNpnSelectedProtocol(SSLSocket socket) { 110153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath if (openSslSocketClass.isInstance(socket)) { 111153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath try { 112153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath return (byte[]) getNpnSelectedProtocol.invoke(socket); 113153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath } catch (InvocationTargetException e) { 114153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath throw new RuntimeException(e); 115153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath } catch (IllegalAccessException e) { 116153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath throw new AssertionError(e); 117153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath } 118153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath } else { 119153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath throw new RuntimeException("Unknown socket implementation."); 120153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath } 121153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath } 122153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath 123153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath public static void setNpnProtocols(SSLSocket socket, byte[] npnProtocols) { 124153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath if (openSslSocketClass.isInstance(socket)) { 125153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath try { 126153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath setNpnProtocols.invoke(socket, new Object[] {npnProtocols}); 127153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath } catch (IllegalAccessException e) { 128153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath throw new AssertionError(e); 129153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath } catch (InvocationTargetException e) { 130153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath throw new RuntimeException(e); 131153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath } 132153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath } else { 133153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath throw new RuntimeException("Unknown socket implementation."); 134153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath } 135153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath } 136153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath 137153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath public static void deleteIfExists(File file) throws IOException { 138153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath // okhttp-changed: was Libcore.os.remove() in a try/catch block 139153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath file.delete(); 140153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath } 141153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath 142153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath public static void logW(String warning) { 143153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath // okhttp-changed: was System.logw() 144153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath System.out.println(warning); 145153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath } 146153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath 147153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath public static int getEffectivePort(URI uri) { 148153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath return getEffectivePort(uri.getScheme(), uri.getPort()); 149153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath } 150153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath 151153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath public static int getEffectivePort(URL url) { 152153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath return getEffectivePort(url.getProtocol(), url.getPort()); 153153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath } 154153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath 155153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath private static int getEffectivePort(String scheme, int specifiedPort) { 156153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath if (specifiedPort != -1) { 157153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath return specifiedPort; 158153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath } 159153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath 160153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath if ("http".equalsIgnoreCase(scheme)) { 161153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath return 80; 162153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath } else if ("https".equalsIgnoreCase(scheme)) { 163153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath return 443; 164153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath } else { 165153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath return -1; 166153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath } 167153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath } 168153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath 169153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath public static void checkOffsetAndCount(int arrayLength, int offset, int count) { 170153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath if ((offset | count) < 0 || offset > arrayLength || arrayLength - offset < count) { 171153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath throw new ArrayIndexOutOfBoundsException(); 172153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath } 173153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath } 174153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath 175153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath public static void tagSocket(Socket socket) { 176153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath } 177153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath 178153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath public static void untagSocket(Socket socket) throws SocketException { 179153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath } 180153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath 181153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath public static URI toUriLenient(URL url) throws URISyntaxException { 182153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath return url.toURI(); // this isn't as good as the built-in toUriLenient 183153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath } 184153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath 185153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath public static void pokeInt(byte[] dst, int offset, int value, ByteOrder order) { 186153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath if (order == ByteOrder.BIG_ENDIAN) { 187153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath dst[offset++] = (byte) ((value >> 24) & 0xff); 188153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath dst[offset++] = (byte) ((value >> 16) & 0xff); 189153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath dst[offset++] = (byte) ((value >> 8) & 0xff); 190153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath dst[offset ] = (byte) ((value >> 0) & 0xff); 191153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath } else { 192153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath dst[offset++] = (byte) ((value >> 0) & 0xff); 193153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath dst[offset++] = (byte) ((value >> 8) & 0xff); 194153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath dst[offset++] = (byte) ((value >> 16) & 0xff); 195153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath dst[offset ] = (byte) ((value >> 24) & 0xff); 196153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath } 197153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath } 198153d0953fe0df254bf3ffaa56934c97020b86edbNarayan Kamath} 199