diff --git a/CHANGELOG.md b/CHANGELOG.md index 8a58602..9b848f1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## v1.2.0 + +- Added support for TLSv1.1 and TLSv1.2 for android versions 4.1-4.4 (API levels 16-19) + +### Potentially Breaking Changes that really shouldn't matter because you shouldn't be using SSLv3 + +- Dropped SSLv3 support for all API Levels < 20. It will now only work on API Levels 20-22. + ## v1.1.0 - Fixed the body of errors not being returned in iOS diff --git a/plugin.xml b/plugin.xml index 06203f6..fc26d9c 100644 --- a/plugin.xml +++ b/plugin.xml @@ -2,7 +2,7 @@ + version="1.2.0"> SSL Pinning @@ -78,5 +78,6 @@ + diff --git a/src/android/com/synconset/CordovaHTTP/HttpRequest.java b/src/android/com/synconset/CordovaHTTP/HttpRequest.java index 78dce7a..8016504 100644 --- a/src/android/com/synconset/CordovaHTTP/HttpRequest.java +++ b/src/android/com/synconset/CordovaHTTP/HttpRequest.java @@ -305,7 +305,12 @@ public class HttpRequest { try { SSLContext context = SSLContext.getInstance("TLS"); context.init(null, trustAllCerts, new SecureRandom()); - TRUSTED_FACTORY = context.getSocketFactory(); + + if (android.os.Build.VERSION.SDK_INT < 20) { + TRUSTED_FACTORY = new TLSSocketFactory(context); + } else { + TRUSTED_FACTORY = context.getSocketFactory(); + } } catch (GeneralSecurityException e) { IOException ioException = new IOException( "Security exception configuring SSL context"); @@ -436,7 +441,7 @@ public class HttpRequest { */ public static void addCert(Certificate ca) throws GeneralSecurityException, IOException { if (PINNED_CERTS == null) { - PINNED_CERTS = new ArrayList(); + PINNED_CERTS = new ArrayList(); } PINNED_CERTS.add(ca); String keyStoreType = KeyStore.getDefaultType(); @@ -444,7 +449,7 @@ public class HttpRequest { keyStore.load(null, null); for (int i = 0; i < PINNED_CERTS.size(); i++) { - keyStore.setCertificateEntry("CA" + i, PINNED_CERTS.get(i)); + keyStore.setCertificateEntry("CA" + i, PINNED_CERTS.get(i)); } // Create a TrustManager that trusts the CAs in our KeyStore @@ -455,7 +460,12 @@ public class HttpRequest { // Create an SSLContext that uses our TrustManager SSLContext sslContext = SSLContext.getInstance("TLS"); sslContext.init(null, tmf.getTrustManagers(), null); - PINNED_FACTORY = sslContext.getSocketFactory(); + + if (android.os.Build.VERSION.SDK_INT < 20) { + PINNED_FACTORY = new TLSSocketFactory(sslContext); + } else { + PINNED_FACTORY = sslContext.getSocketFactory(); + } } /** diff --git a/src/android/com/synconset/CordovaHTTP/TLSSocketFactory.java b/src/android/com/synconset/CordovaHTTP/TLSSocketFactory.java new file mode 100644 index 0000000..8d3170f --- /dev/null +++ b/src/android/com/synconset/CordovaHTTP/TLSSocketFactory.java @@ -0,0 +1,63 @@ +package com.github.kevinsawicki.http; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.Socket; +import java.net.UnknownHostException; +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSocket; +import javax.net.ssl.SSLSocketFactory; + +public class TLSSocketFactory extends SSLSocketFactory { + + private SSLSocketFactory internalSSLSocketFactory; + + public TLSSocketFactory(SSLContext context) { + internalSSLSocketFactory = context.getSocketFactory(); + } + + @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)); + } + + private Socket enableTLSOnSocket(Socket socket) { + if(socket != null && (socket instanceof SSLSocket)) { + ((SSLSocket)socket).setEnabledProtocols(new String[] {"TLSv1", "TLSv1.1", "TLSv1.2"}); + } + return socket; + } +} \ No newline at end of file diff --git a/zedconfig.json b/zedconfig.json index 3f52390..e6a16fa 100644 --- a/zedconfig.json +++ b/zedconfig.json @@ -1,6 +1,6 @@ { "preferences": { - "tabSize": 4, + "tabSize": 2, "wordWrap": true, "useSoftTabs": true, "gotoExclude": []