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": []