From b376b820640ed9f097c3d62011c5e9cf2462304b Mon Sep 17 00:00:00 2001 From: Sean Leonard Date: Tue, 13 Aug 2013 14:30:49 -0600 Subject: Use java.security classes to validate string certificates and keys from provider --- src/se/leap/leapclient/ConfigHelper.java | 31 ++++++++++++++++ src/se/leap/leapclient/ProviderAPI.java | 62 ++++++++++++++++++++------------ 2 files changed, 71 insertions(+), 22 deletions(-) (limited to 'src/se/leap') diff --git a/src/se/leap/leapclient/ConfigHelper.java b/src/se/leap/leapclient/ConfigHelper.java index e139bf62..fd7e527f 100644 --- a/src/se/leap/leapclient/ConfigHelper.java +++ b/src/se/leap/leapclient/ConfigHelper.java @@ -23,12 +23,18 @@ import java.io.FileNotFoundException; import java.io.IOException; import java.math.BigInteger; import java.io.InputStream; +import java.security.KeyFactory; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.PrivateKey; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; +import java.security.interfaces.RSAPrivateKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.PKCS8EncodedKeySpec; import org.json.JSONException; import org.json.JSONObject; @@ -315,6 +321,31 @@ public class ConfigHelper { return (X509Certificate) certificate; } + + protected static RSAPrivateKey parseRsaKeyFromString(String RsaKeyString) { + RSAPrivateKey key = null; + try { + KeyFactory kf = KeyFactory.getInstance("RSA", "BC"); + + RsaKeyString = RsaKeyString.replaceFirst("-----BEGIN RSA PRIVATE KEY-----", "").replaceFirst("-----END RSA PRIVATE KEY-----", ""); + PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec( Base64.decode(RsaKeyString, Base64.DEFAULT) ); + key = (RSAPrivateKey) kf.generatePrivate(keySpec); + } catch (InvalidKeySpecException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + return null; + } catch (NoSuchAlgorithmException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + return null; + } catch (NoSuchProviderException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + return null; + } + + return key; + } /** * Adds a new X509 certificate given its input stream and its provider name diff --git a/src/se/leap/leapclient/ProviderAPI.java b/src/se/leap/leapclient/ProviderAPI.java index dc0b2aa6..935d6a87 100644 --- a/src/se/leap/leapclient/ProviderAPI.java +++ b/src/se/leap/leapclient/ProviderAPI.java @@ -16,20 +16,9 @@ */ package se.leap.leapclient; -import java.io.ByteArrayInputStream; import java.io.FileNotFoundException; import java.io.IOException; -import java.io.InputStream; import java.math.BigInteger; -import java.security.KeyManagementException; -import java.security.KeyStore; -import java.security.KeyStoreException; -import java.security.NoSuchAlgorithmException; -import java.security.cert.CertificateException; -import java.security.cert.CertificateFactory; -import java.security.cert.X509Certificate; -import java.security.SecureRandom; -import javax.net.ssl.KeyManager; import java.net.CookieHandler; import java.net.CookieManager; import java.net.HttpCookie; @@ -39,14 +28,23 @@ import java.net.URISyntaxException; import java.net.URL; import java.net.URLConnection; import java.net.UnknownHostException; +import java.security.KeyManagementException; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import java.security.interfaces.RSAPrivateKey; import java.util.Scanner; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.KeyManager; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSession; -import javax.net.ssl.TrustManagerFactory; import javax.net.ssl.TrustManager; +import javax.net.ssl.TrustManagerFactory; import javax.net.ssl.X509TrustManager; import org.apache.http.HttpEntity; @@ -66,7 +64,6 @@ import org.json.JSONException; import org.json.JSONObject; import se.leap.leapclient.ProviderListContent.ProviderItem; - import android.app.IntentService; import android.content.Intent; import android.os.Bundle; @@ -180,12 +177,19 @@ public class ProviderAPI extends IntentService { boolean danger_on = task.getBoolean(ConfigHelper.DANGER_ON); try { String cert_string = getStringFromProvider(cert_url, danger_on); - ConfigHelper.saveSharedPref(ConfigHelper.MAIN_CERT_KEY, cert_string); + X509Certificate certCert = ConfigHelper.parseX509CertificateFromString(cert_string); + cert_string = Base64.encodeToString( certCert.getEncoded(), Base64.DEFAULT); + ConfigHelper.saveSharedPref(ConfigHelper.MAIN_CERT_KEY, "-----BEGIN CERTIFICATE-----\n"+cert_string+"-----END CERTIFICATE-----"); + JSONObject eip_service_json = getJSONFromProvider(eip_service_json_url, danger_on); ConfigHelper.saveSharedPref(ConfigHelper.EIP_SERVICE_KEY, eip_service_json); return true; } catch (JSONException e) { return false; + } catch (CertificateException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + return false; } } @@ -726,17 +730,31 @@ public class ProviderAPI extends IntentService { String cert_string = getStringFromProvider(new_cert_string_url, danger_on); if(!cert_string.isEmpty()) { // API returns concatenated cert & key. Split them for OpenVPN options - String certificate = null, key = null; + String certificateString = null, keyString = null; String[] certAndKey = cert_string.split("(?<=-\n)"); for (int i=0; i < certAndKey.length-1; i++){ - if ( certAndKey[i].contains("KEY") ) - key = certAndKey[i++] + certAndKey[i]; - else if ( certAndKey[i].contains("CERTIFICATE") ) - certificate = certAndKey[i++] + certAndKey[i]; + if ( certAndKey[i].contains("KEY") ) { + keyString = certAndKey[i++] + certAndKey[i]; + } + else if ( certAndKey[i].contains("CERTIFICATE") ) { + certificateString = certAndKey[i++] + certAndKey[i]; + } + } + try { + RSAPrivateKey keyCert = ConfigHelper.parseRsaKeyFromString(keyString); + keyString = Base64.encodeToString( keyCert.getEncoded(), Base64.DEFAULT ); + ConfigHelper.saveSharedPref(ConfigHelper.KEY_KEY, "-----BEGIN RSA PRIVATE KEY-----\n"+keyString+"-----END RSA PRIVATE KEY-----"); + + X509Certificate certCert = ConfigHelper.parseX509CertificateFromString(certificateString); + certificateString = Base64.encodeToString( certCert.getEncoded(), Base64.DEFAULT); + ConfigHelper.saveSharedPref(ConfigHelper.CERT_KEY, "-----BEGIN CERTIFICATE-----\n"+certificateString+"-----END CERTIFICATE-----"); + + return true; + } catch (CertificateException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + return false; } - ConfigHelper.saveSharedPref(ConfigHelper.CERT_KEY, certificate); - ConfigHelper.saveSharedPref(ConfigHelper.KEY_KEY, key); - return true; } else { return false; } -- cgit v1.2.3