diff options
author | Arne Schwabe <arne@rfc2549.org> | 2012-06-28 19:33:05 +0200 |
---|---|---|
committer | Arne Schwabe <arne@rfc2549.org> | 2012-06-28 19:33:05 +0200 |
commit | 73d3b9c032eae2074726cd3668546af1c44a8323 (patch) | |
tree | c40b4e6447efa6d1d1c8618a3f79723f29e2db14 /src/de/blinkt/openvpn/VpnProfile.java | |
parent | 629417eb6b9db777b0db6b36d1c8ceb4c2760f7c (diff) |
The 'be ready for Jelly Beans' commit
- fix concurrentaccess occuring on JB
- JB does not allow to extract the private keys from the key storage, rewrite using the key storage to use JAVA API and the external-key management interface
Diffstat (limited to 'src/de/blinkt/openvpn/VpnProfile.java')
-rw-r--r-- | src/de/blinkt/openvpn/VpnProfile.java | 100 |
1 files changed, 53 insertions, 47 deletions
diff --git a/src/de/blinkt/openvpn/VpnProfile.java b/src/de/blinkt/openvpn/VpnProfile.java index dd729a06..8b758b3b 100644 --- a/src/de/blinkt/openvpn/VpnProfile.java +++ b/src/de/blinkt/openvpn/VpnProfile.java @@ -4,25 +4,23 @@ import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; -import java.io.FileOutputStream; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.Serializable; -import java.security.KeyStore; -import java.security.KeyStoreException; -import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.cert.Certificate; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import java.util.Collection; -import java.util.Random; import java.util.UUID; import java.util.Vector; +import org.spongycastle.util.io.pem.PemObject; +import org.spongycastle.util.io.pem.PemWriter; + import android.content.Context; import android.content.Intent; import android.content.pm.ApplicationInfo; @@ -51,8 +49,7 @@ public class VpnProfile implements Serializable{ protected transient String mTransientPW=null; protected transient String mTransientPCKS12PW=null; - - private static transient String mTempPKCS12Password; + private transient PrivateKey mPrivateKey; public static String DEFAULT_DNS1="131.234.137.23"; public static String DEFAULT_DNS2="131.234.137.24"; @@ -100,6 +97,7 @@ public class VpnProfile implements Serializable{ public boolean mUseDefaultRoutev6=true; public String mCustomRoutesv6=""; public String mKeyPassword=""; + public void clearDefaults() { @@ -122,7 +120,8 @@ public class VpnProfile implements Serializable{ } - static final String OVPNCONFIGPKCS12 = "android.pkcs12"; + static final String OVPNCONFIGCA = "android-ca.pem"; + static final String OVPNCONFIGUSERCERT = "android-user.pem"; public VpnProfile(String name) { @@ -223,9 +222,10 @@ public class VpnProfile implements Serializable{ case VpnProfile.TYPE_USERPASS_KEYSTORE: cfg+="auth-user-pass\n"; case VpnProfile.TYPE_KEYSTORE: - cfg+="pkcs12 "; - cfg+=cacheDir.getAbsolutePath() + "/" + OVPNCONFIGPKCS12; - cfg+="\n"; + cfg+="ca " + cacheDir.getAbsolutePath() + "/" + OVPNCONFIGCA + "\n"; + cfg+="cert " + cacheDir.getAbsolutePath() + "/" + OVPNCONFIGUSERCERT + "\n"; + cfg+="management-external-key\n"; + break; case VpnProfile.TYPE_USERPASS: cfg+="auth-user-pass\n"; @@ -447,7 +447,7 @@ public class VpnProfile implements Serializable{ Intent intent = new Intent(context,OpenVpnService.class); if(mAuthenticationType == VpnProfile.TYPE_KEYSTORE || mAuthenticationType == VpnProfile.TYPE_USERPASS_KEYSTORE) { - savePKCS12(context); + saveCertificates(context); } intent.putExtra(prefix + ".ARGV" , buildOpenvpnArgv(context.getCacheDir())); @@ -468,27 +468,13 @@ public class VpnProfile implements Serializable{ return intent; } - private String getTemporaryPKCS12Password() { - if(mTempPKCS12Password!=null) - return mTempPKCS12Password; - - String pw= ""; - // Put enough digits togher to make a password :) - Random r = new Random(); - for(int i=0;i < 4;i++) { - pw += Integer.valueOf(r.nextInt(1000)).toString(); - } - - mTempPKCS12Password=pw; - return mTempPKCS12Password; - - } - - private void savePKCS12(Context context) { + private void saveCertificates(Context context) { PrivateKey privateKey = null; X509Certificate[] cachain=null; try { privateKey = KeyChain.getPrivateKey(context,mAlias); + mPrivateKey = privateKey; + cachain = KeyChain.getCertificateChain(context, mAlias); if(cachain.length <= 1 && !nonNull(mCaFilename)) OpenVPN.logMessage(0, "", context.getString(R.string.keychain_nocacert)); @@ -496,32 +482,50 @@ public class VpnProfile implements Serializable{ for(X509Certificate cert:cachain) { OpenVPN.logInfo(R.string.cert_from_keystore,cert.getSubjectDN()); } + + - KeyStore ks = KeyStore.getInstance("PKCS12"); - ks.load(null, null); + if(nonNull(mCaFilename)) { try { - Certificate cacert = getCacertFromFile(); - - ks.setCertificateEntry("cacert", cacert); + Certificate cacert = getCacertFromFile(); + X509Certificate[] newcachain = new X509Certificate[cachain.length+1]; + for(int i=0;i<cachain.length;i++) + newcachain[i]=cachain[i]; + + newcachain[cachain.length-1]=(X509Certificate) cacert; + } catch (Exception e) { OpenVPN.logError("Could not read CA certificate" + e.getLocalizedMessage()); } } - ks.setKeyEntry("usercert", privateKey, null, cachain); - String mypw = getTemporaryPKCS12Password(); - FileOutputStream fout = new FileOutputStream(context.getCacheDir().getAbsolutePath() + "/" + VpnProfile.OVPNCONFIGPKCS12); - ks.store(fout,mypw.toCharArray()); - fout.flush(); fout.close(); + + + FileWriter fout = new FileWriter(context.getCacheDir().getAbsolutePath() + "/" + VpnProfile.OVPNCONFIGCA); + PemWriter pw = new PemWriter(fout); + for(X509Certificate cert:cachain) { + pw.writeObject(new PemObject("CERTIFICATE", cert.getEncoded())); + } + + pw.close(); + + + if(cachain.length>= 1){ + X509Certificate usercert = cachain[0]; + + FileWriter userout = new FileWriter(context.getCacheDir().getAbsolutePath() + "/" + VpnProfile.OVPNCONFIGUSERCERT); + + PemWriter upw = new PemWriter(userout); + upw.writeObject(new PemObject("CERTIFICATE", usercert.getEncoded())); + upw.close(); + + } + return; } catch (InterruptedException e) { e.printStackTrace(); - } catch (KeyStoreException e) { - e.printStackTrace(); } catch (FileNotFoundException e) { e.printStackTrace(); - } catch (NoSuchAlgorithmException e) { - e.printStackTrace(); } catch (CertificateException e) { e.printStackTrace(); } catch (IOException e) { @@ -574,10 +578,6 @@ public class VpnProfile implements Serializable{ return pwcopy; } switch (mAuthenticationType) { - case TYPE_KEYSTORE: - case TYPE_USERPASS_KEYSTORE: - return getTemporaryPKCS12Password(); - case TYPE_PKCS12: case TYPE_USERPASS_PKCS12: return mPKCS12Password; @@ -623,6 +623,7 @@ public class VpnProfile implements Serializable{ data += new String(buf,0,len); len = fr.read(buf); } + fr.close(); } catch (FileNotFoundException e) { return false; } catch (IOException e) { @@ -684,6 +685,11 @@ public class VpnProfile implements Serializable{ } + public PrivateKey getKeystoreKey() { + return mPrivateKey; + } + + } |