got ssl pinning to work when hardcoded

This commit is contained in:
Andrew Stephan 2014-03-24 19:36:09 -04:00
parent b81f8b3d41
commit b65be932bd
4 changed files with 92 additions and 20 deletions

View File

@ -3,8 +3,22 @@
*/
package com.synconset;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Iterator;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;
import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaInterface;
import org.apache.cordova.CordovaPlugin;
@ -18,12 +32,14 @@ import android.util.Base64;
public class CordovaHTTP extends CordovaPlugin {
private static final String TAG = "CordovaHTTP";
private SSLContext sslContext;
private JSONObject globalHeaders;
@Override
public void initialize(CordovaInterface cordova, CordovaWebView webView) {
super.initialize(cordova, webView);
this.globalHeaders = new JSONObject();
this.sslContext = null;
}
@Override
@ -33,22 +49,28 @@ public class CordovaHTTP extends CordovaPlugin {
JSONObject params = args.getJSONObject(1);
JSONObject headers = args.getJSONObject(2);
this.addToJSONObject(headers, this.globalHeaders);
HTTPGet get = new HTTPGet(urlString, params, headers, callbackContext);
HTTPGet get = new HTTPGet(urlString, params, headers, this.sslContext, callbackContext);
cordova.getThreadPool().execute(get);
} else if (action.equals("post")) {
String urlString = args.getString(0);
JSONObject params = args.getJSONObject(1);
JSONObject headers = args.getJSONObject(2);
this.addToJSONObject(headers, this.globalHeaders);
HTTPPost post = new HTTPPost(urlString, params, headers, callbackContext);
HTTPPost post = new HTTPPost(urlString, params, headers, this.sslContext, callbackContext);
cordova.getThreadPool().execute(post);
} else if (action.equals("setAuthorizationHeaderWithUsernameAndPassword")) {
String username = args.getString(0);
String password = args.getString(1);
this.setAuthorizationHeaderWithUsernameAndPassword(username, password);
callbackContext.success();
} else if (action.equals("downloadFile")) {
} else if (action.equals("setSSLPinningMode")) {
int mode = args.getInt(0);
try {
this.setSSLPinningMode(mode);
callbackContext.success();
} catch(Exception e) {
callbackContext.error("There was an error setting up ssl pinning");
}
} else {
return false;
}
@ -60,6 +82,37 @@ public class CordovaHTTP extends CordovaPlugin {
loginInfo = "Basic " + Base64.encodeToString(loginInfo.getBytes(), Base64.NO_WRAP);
globalHeaders.put("Authorization", loginInfo);
}
private void setSSLPinningMode(int mode) throws CertificateException, IOException, KeyStoreException, NoSuchAlgorithmException, KeyManagementException {
// Load CAs from an InputStream
// (could be from a resource or ByteArrayInputStream or ...)
CertificateFactory cf = CertificateFactory.getInstance("X.509");
// From https://www.washington.edu/itconnect/security/ca/load-der.crt
InputStream in = cordova.getActivity().getAssets().open("PCA-3G5.cer");
InputStream caInput = new BufferedInputStream(in);
Certificate ca;
try {
ca = cf.generateCertificate(caInput);
System.out.println("ca=" + ((X509Certificate) ca).getSubjectDN());
} finally {
caInput.close();
}
// Create a KeyStore containing our trusted CAs
String keyStoreType = KeyStore.getDefaultType();
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(null, null);
keyStore.setCertificateEntry("ca", ca);
// Create a TrustManager that trusts the CAs in our KeyStore
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
tmf.init(keyStore);
// Create an SSLContext that uses our TrustManager
sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, tmf.getTrustManagers(), null);
}
private void addToJSONObject(JSONObject object, JSONObject objectToAdd) throws JSONException {
Iterator<?> i = objectToAdd.keys();

View File

@ -15,6 +15,8 @@ import java.io.BufferedReader;
import java.net.URLConnection;
import javax.net.ssl.SSLContext;
import java.util.Iterator;
import android.util.Log;
@ -27,12 +29,14 @@ public class HTTP {
private String urlString;
private JSONObject params;
private JSONObject headers;
private SSLContext sslContext;
private CallbackContext callbackContext;
public HTTP(String urlString, JSONObject params, JSONObject headers, CallbackContext callbackContext) {
public HTTP(String urlString, JSONObject params, JSONObject headers, SSLContext sslContext, CallbackContext callbackContext) {
this.urlString = urlString;
this.params = params;
this.headers = headers;
this.sslContext = sslContext;
this.callbackContext = callbackContext;
}
@ -60,6 +64,10 @@ public class HTTP {
this.headers = headers;
}
protected SSLContext getSSLContext() {
return this.sslContext;
}
protected CallbackContext getCallbackContext() {
return this.callbackContext;
}

View File

@ -9,6 +9,7 @@ import java.net.MalformedURLException;
import java.net.URL;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import org.apache.cordova.CallbackContext;
import org.json.JSONException;
@ -17,8 +18,8 @@ import org.json.JSONObject;
import android.util.Log;
public class HTTPGet extends HTTP implements Runnable {
public HTTPGet(String urlString, JSONObject params, JSONObject headers, CallbackContext callbackContext) {
super(urlString, params, headers, callbackContext);
public HTTPGet(String urlString, JSONObject params, JSONObject headers, SSLContext sslContext, CallbackContext callbackContext) {
super(urlString, params, headers, sslContext, callbackContext);
}
@Override
@ -26,15 +27,14 @@ public class HTTPGet extends HTTP implements Runnable {
JSONObject params = this.getParams();
String urlString = this.getUrlString();
CallbackContext callbackContext = this.getCallbackContext();
JSONObject response = new JSONObject();
InputStream is = null;
HttpsURLConnection conn = null;
try {
if (params.length() > 0) {
if (params.length() > 0) {
urlString = urlString + "?" + this.getQueryString();
}
URL url = new URL(urlString);
URL url = new URL(urlString);
conn = (HttpsURLConnection)url.openConnection();
conn.setRequestMethod("GET");
conn.setDoInput(true);
@ -42,14 +42,23 @@ public class HTTPGet extends HTTP implements Runnable {
this.addHeaders(conn);
conn.connect();
int status = conn.getResponseCode();
Log.d(TAG, "The response is: " + status);
is = conn.getInputStream();
String responseData = this.readInputStream(is);
response.put("status", status);
response.put("data", responseData);
callbackContext.success(response);
if (status >= 200 && status < 300) {
is = conn.getInputStream();
String responseData = this.readInputStream(is);
JSONObject response = new JSONObject();
response.put("status", status);
response.put("data", responseData);
callbackContext.success(response);
} else {
is = conn.getErrorStream();
String responseData = this.readInputStream(is);
JSONObject response = new JSONObject();
response.put("status", status);
response.put("error", responseData);
callbackContext.error(response);
}
} catch (MalformedURLException e) {
this.respondWithError(callbackContext, "There is an error with the url");
this.respondWithError(callbackContext, "There is an error with the url");
} catch (JSONException e) {
this.respondWithError(callbackContext, "There was an error with the params, headers or generating the response");
} catch (IOException e) {

View File

@ -12,6 +12,7 @@ import java.net.MalformedURLException;
import java.net.URL;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import org.apache.cordova.CallbackContext;
import org.json.JSONException;
@ -20,8 +21,8 @@ import org.json.JSONObject;
import android.util.Log;
public class HTTPPost extends HTTP implements Runnable {
public HTTPPost(String urlString, JSONObject params, JSONObject headers, CallbackContext callbackContext) {
super(urlString, params, headers, callbackContext);
public HTTPPost(String urlString, JSONObject params, JSONObject headers, SSLContext sslContext, CallbackContext callbackContext) {
super(urlString, params, headers, sslContext, callbackContext);
}
@Override
@ -34,6 +35,7 @@ public class HTTPPost extends HTTP implements Runnable {
try {
URL url = new URL(urlString);
conn = (HttpsURLConnection)url.openConnection();
conn.setSSLSocketFactory(this.getSSLContext().getSocketFactory());
conn.setRequestMethod("POST");
conn.setDoInput(true);
conn.setDoOutput(true);
@ -50,7 +52,6 @@ public class HTTPPost extends HTTP implements Runnable {
conn.connect();
int status = conn.getResponseCode();
Log.d(TAG, "The response is: " + status);
if (status >= 200 && status < 300) {
is = conn.getInputStream();
String responseData = this.readInputStream(is);
@ -71,6 +72,7 @@ public class HTTPPost extends HTTP implements Runnable {
} catch (JSONException e) {
this.respondWithError(callbackContext, "There was an error with the params, headers or generating the response");
} catch (IOException e) {
Log.d(TAG, e.getMessage());
this.respondWithError(callbackContext, "There was an error with the request");
} finally {
if (is != null) {