/** * Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * You may not use this file except in compliance with the License. A copy of the License is located the "LICENSE.txt" * file accompanying this source. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the specific language governing permissions and limitations * under the License. */ package com.rockchip.smart.rockhome.softap.http; import android.content.Context; import android.os.Build; import android.text.TextUtils; import android.util.Log; import com.rockchip.smart.rockhome.R; import com.rockchip.smart.rockhome.WifiInfo; import org.apache.commons.io.IOUtils; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import java.io.ByteArrayInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.InetAddress; import java.net.Socket; import java.net.URL; import java.net.UnknownHostException; import java.security.KeyManagementException; import java.security.KeyStore; import java.security.NoSuchAlgorithmException; import java.security.cert.Certificate; import java.security.cert.CertificateFactory; import java.util.ArrayList; import java.util.List; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocket; import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.TrustManagerFactory; public class ProvisioningClient { private static final String TAG = "ProvisioningClient"; private String endpoint; private SSLSocketFactory pinnedSSLSocketFactory; private static ProvisioningClient mClient; public static ProvisioningClient getProvisioningClient(Context context) { if (mClient == null) { try { mClient = new ProvisioningClient(context); mClient.setEndpoint("http://10.201.126.1:8443"); } catch (Exception e) { } } return mClient; } private ProvisioningClient(Context context) throws Exception { this.pinnedSSLSocketFactory = getPinnedSSLSocketFactory(context); } public void setEndpoint(String endpoint) { this.endpoint = endpoint; } public boolean isWifiConnected() { Log.d(TAG, "check isWifiConnected"); try { DeviceContextInfo info = getDeviceContextInfo(); return !info.getIp().equals("127.0.0.1"); } catch (JSONException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return false; } public DeviceContextInfo getDeviceContextInfo() throws JSONException, IOException { URL companionInfoEndpoint = new URL(endpoint + "/provision/deviceContext"); HttpURLConnection connection = (HttpURLConnection) companionInfoEndpoint.openConnection(); JSONObject request = doRequest(connection); String ssid = request.getString("ssid"); String ip = request.getString("ip"); boolean authorized = request.getBoolean("authorized"); return new DeviceContextInfo(ssid, ip, authorized); } public List getWifiListInfo() throws JSONException, IOException { List result = new ArrayList(); URL companionInfoEndpoint = new URL(endpoint + "/provision/wifiListInfo"); HttpURLConnection connection = (HttpURLConnection) companionInfoEndpoint.openConnection(); JSONObject response = doRequest(connection); if (response == null) { Log.d(TAG, "Get wifi list, response is null."); return result; } JSONArray array = response.getJSONArray("content"); if (array == null) { return result; } JSONObject obj = null; WifiInfo info = null; int length = array.length(); for (int i=0; i= 300) { response = connection.getErrorStream(); if (response != null) { String responseString = IOUtils.toString(response); //throw new RuntimeException(responseString); } } throw e; } finally { IOUtils.closeQuietly(outputStream); IOUtils.closeQuietly(response); } } String doRequestGetString(HttpURLConnection connection) throws IOException, JSONException { int responseCode = -1; InputStream response = null; DataOutputStream outputStream = null; try { if (connection instanceof HttpsURLConnection) { ((HttpsURLConnection) connection).setSSLSocketFactory(pinnedSSLSocketFactory); } connection.setRequestProperty("Content-Type", "application/json"); connection.setRequestMethod("GET"); responseCode = connection.getResponseCode(); Log.d(TAG, "responseCode:" + responseCode); response = connection.getInputStream(); if (responseCode != 204) { String responseString = IOUtils.toString(response); if (TextUtils.isEmpty(responseString)) return ""; return responseString; } else { return ""; } } catch (IOException e) { if (responseCode < 200 || responseCode >= 300) { response = connection.getErrorStream(); if (response != null) { String responseString = IOUtils.toString(response); //throw new RuntimeException(responseString); } } throw e; } finally { IOUtils.closeQuietly(outputStream); IOUtils.closeQuietly(response); } } boolean doRequestForResult(HttpURLConnection connection, String data) throws IOException, JSONException { int responseCode = -1; InputStream response = null; DataOutputStream outputStream = null; try { if (connection instanceof HttpsURLConnection) { ((HttpsURLConnection) connection).setSSLSocketFactory(pinnedSSLSocketFactory); } connection.setRequestProperty("Content-Type", "application/json"); if (data != null) { connection.setRequestMethod("POST"); connection.setDoOutput(true); outputStream = new DataOutputStream(connection.getOutputStream()); outputStream.write(data.getBytes()); outputStream.flush(); outputStream.close(); } else { connection.setRequestMethod("GET"); } responseCode = connection.getResponseCode(); Log.d(TAG, "responseCode:" + responseCode); response = connection.getInputStream(); if (responseCode == 200) { return true; } } catch (IOException e) { } finally { IOUtils.closeQuietly(outputStream); IOUtils.closeQuietly(response); } return false; } private SSLSocketFactory getPinnedSSLSocketFactory(Context context) throws Exception { InputStream caCertInputStream = null; try { caCertInputStream = context.getResources().openRawResource(R.raw.ca); CertificateFactory cf = CertificateFactory.getInstance("X.509"); Certificate caCert = cf.generateCertificate(caCertInputStream); KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType()); trustStore.load(null, null); trustStore.setCertificateEntry("myca", caCert); TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); trustManagerFactory.init(trustStore); SSLContext sslContext = SSLContext.getInstance("TLS"); sslContext.init(null, trustManagerFactory.getTrustManagers(), null); if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) { return new TLSSocketFactory(sslContext.getSocketFactory()); } return sslContext.getSocketFactory(); } finally { IOUtils.closeQuietly(caCertInputStream); } } private SSLSocketFactory getPinnedSSLSocketFactory(String crt) throws Exception { InputStream caCertInputStream = null; try { caCertInputStream = new ByteArrayInputStream(crt.getBytes("UTF-8")); CertificateFactory cf = CertificateFactory.getInstance("X.509"); Certificate caCert = cf.generateCertificate(caCertInputStream); KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType()); trustStore.load(null, null); trustStore.setCertificateEntry("myca", caCert); TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); trustManagerFactory.init(trustStore); SSLContext sslContext = SSLContext.getInstance("TLS"); sslContext.init(null, trustManagerFactory.getTrustManagers(), null); return sslContext.getSocketFactory(); } finally { IOUtils.closeQuietly(caCertInputStream); } } public static class TLSSocketFactory extends SSLSocketFactory { private SSLSocketFactory internalSSLSocketFactory; public TLSSocketFactory(SSLSocketFactory delegate) throws KeyManagementException, NoSuchAlgorithmException { internalSSLSocketFactory = delegate; } @Override public String[] getDefaultCipherSuites() { return internalSSLSocketFactory.getDefaultCipherSuites(); } @Override public String[] getSupportedCipherSuites() { return internalSSLSocketFactory.getSupportedCipherSuites(); } @Override public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException { return enableTLSOnSocket(internalSSLSocketFactory.createSocket(s, host, port, autoClose)); } @Override public Socket createSocket(String host, int port) throws IOException, UnknownHostException { return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port)); } @Override public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException, UnknownHostException { return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port, localHost, localPort)); } @Override public Socket createSocket(InetAddress host, int port) throws IOException { return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port)); } @Override public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException { return enableTLSOnSocket(internalSSLSocketFactory.createSocket(address, port, localAddress, localPort)); } /* * Utility methods */ private static Socket enableTLSOnSocket(Socket socket) { if (socket != null && (socket instanceof SSLSocket) && isTLSServerEnabled((SSLSocket) socket)) { // skip the fix if server doesn't provide the TLS version ((SSLSocket) socket).setEnabledProtocols(new String[]{"TLSv1.2"}); } return socket; } private static boolean isTLSServerEnabled(SSLSocket sslSocket) { for (String protocol : sslSocket.getSupportedProtocols()) { if (protocol.equals("TLSv1.2")) { return true; } } return false; } } }