package com.kedzie.vbox.soap.ssl; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import javax.net.ssl.TrustManager; import javax.net.ssl.TrustManagerFactory; import android.util.Log; import com.actionbarsherlock.app.SherlockFragmentActivity; import com.kedzie.vbox.R; import com.kedzie.vbox.VBoxApplication; import com.kedzie.vbox.server.Server; import com.kedzie.vbox.task.DialogTask; /** * Manipulate/load/save truststore to filesystem. Create TrustManagers to use the keystore. */ public class SSLUtil { private static final String TAG = "SSLUtil"; private static final char[] KEYSTORE_PASSWORD = "virtualbox".toCharArray(); private static final String KEYSTORE_NAME = "virtualbox.bks"; /** * Add certificate to the keystore and save */ public static class AddCertificateToKeystoreTask extends DialogTask<X509Certificate, Void> { private Server server; public AddCertificateToKeystoreTask(SherlockFragmentActivity context, Server server) { super(context, null, R.string.progress_updating_keystore); this.server = server; } @Override protected Void work(X509Certificate... chain) throws Exception { X509Certificate root = chain[chain.length-1]; String alias = String.format("%1$s-$2$d", server.toString(), root.getSubjectDN().hashCode()); Log.d(TAG, "Created new certificate entry alias: " + alias); SSLUtil.getKeystore().setEntry(alias, new KeyStore.TrustedCertificateEntry(root), null); SSLUtil.storeKeystore(); return null; } } private static TrustManager[] mTrustManagers; private static KeyStore mKeystore; public static TrustManager[] getKeyStoreTrustManager() { if(mTrustManagers==null) { Log.i(TAG, "Initializing TrustManagers"); try { TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); tmf.init(SSLUtil.getKeystore()); mTrustManagers = tmf.getTrustManagers(); } catch (Exception e) { Log.e(TAG, "Error initializing TrustManagers", e); } } return mTrustManagers; } public static KeyStore getKeystore() throws KeyStoreException, NoSuchAlgorithmException, CertificateException, FileNotFoundException, IOException { if(mKeystore==null) { mKeystore = KeyStore.getInstance("BKS"); if(!new File(getKeystorePath()).exists()) { Log.i(TAG, "Creating new Bouncy Castle keystore"); getKeystoreFolder().mkdirs(); mKeystore.load(null, KEYSTORE_PASSWORD); mKeystore.store(new FileOutputStream(getKeystorePath()), KEYSTORE_PASSWORD); } else { mKeystore.load(new FileInputStream(getKeystorePath()), KEYSTORE_PASSWORD); } } return mKeystore; } public static void storeKeystore() throws KeyStoreException, NoSuchAlgorithmException, CertificateException, FileNotFoundException, IOException { Log.i(TAG, "Saving updated keystore: " + getKeystorePath()); mKeystore.store(new FileOutputStream(getKeystorePath()), KEYSTORE_PASSWORD); mTrustManagers = null; //make sure TrustManagers are using the updated keystore } private static File getKeystoreFolder() { return VBoxApplication.getInstance().getExternalFilesDir(null); } private static String getKeystorePath() { return getKeystoreFolder().toString()+"/"+KEYSTORE_NAME; } }