summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArne Schwabe <arne@rfc2549.org>2013-05-20 09:55:50 +0200
committerArne Schwabe <arne@rfc2549.org>2013-05-20 09:55:50 +0200
commit2a9037c749d3395ac65105604ab4936c4af0fc56 (patch)
treeee7672009ac3575f8aeac6c37ac91b7590334f28
parentffcd37e623136697da66e0c23bddc92b01ff0e41 (diff)
Add certificate CN print
Need to fix string for email and order --HG-- extra : rebase_source : c3d5858d53d2f8f340b0d4a07434021f194a247a
-rw-r--r--res/layout/file_select.xml14
-rw-r--r--src/de/blinkt/openvpn/FileSelectLayout.java33
-rw-r--r--src/de/blinkt/openvpn/VpnProfile.java21
-rw-r--r--src/de/blinkt/openvpn/core/X509Utils.java78
-rw-r--r--src/de/blinkt/openvpn/fragments/Settings_Basic.java8
-rw-r--r--src/org/spongycastle/util/io/pem/PemReader.java84
6 files changed, 205 insertions, 33 deletions
diff --git a/res/layout/file_select.xml b/res/layout/file_select.xml
index 0dd1abba..8c9e4da6 100644
--- a/res/layout/file_select.xml
+++ b/res/layout/file_select.xml
@@ -51,5 +51,17 @@
android:ellipsize="end"
android:singleLine="true"
android:text="@string/file_nothing_selected" />
-</RelativeLayout>
+ <TextView
+ android:id="@+id/file_selected_description"
+ android:layout_width="wrap_content"
+ android:textIsSelectable="true"
+ android:layout_height="wrap_content"
+ android:layout_alignParentLeft="true"
+ android:layout_below="@+id/file_selected_item"
+ android:layout_marginLeft="16dip"
+ android:layout_toLeftOf="@+id/file_select_button"
+ android:ellipsize="end"
+ android:singleLine="true" />
+
+</RelativeLayout> \ No newline at end of file
diff --git a/src/de/blinkt/openvpn/FileSelectLayout.java b/src/de/blinkt/openvpn/FileSelectLayout.java
index b7e28b5c..d7bcc475 100644
--- a/src/de/blinkt/openvpn/FileSelectLayout.java
+++ b/src/de/blinkt/openvpn/FileSelectLayout.java
@@ -1,5 +1,6 @@
package de.blinkt.openvpn;
+import de.blinkt.openvpn.core.X509Utils;
import android.app.Fragment;
import android.content.Context;
import android.content.Intent;
@@ -22,19 +23,21 @@ public class FileSelectLayout extends LinearLayout implements OnClickListener {
private boolean mBase64Encode;
private String mTitle;
private boolean mShowClear;
+ private TextView mDataDetails;
public FileSelectLayout( Context context,AttributeSet attrset) {
super(context,attrset);
inflate(getContext(), R.layout.file_select, this);
-
+
TypedArray ta = context.obtainStyledAttributes(attrset,R.styleable.FileSelectLayout);
-
+
mTitle = ta.getString(R.styleable.FileSelectLayout_title);
-
+
TextView tview = (TextView) findViewById(R.id.file_title);
tview.setText(mTitle);
-
+
mDataView = (TextView) findViewById(R.id.file_selected_item);
+ mDataDetails = (TextView) findViewById(R.id.file_selected_description);
mSelectButton = (Button) findViewById(R.id.file_select_button);
mSelectButton.setOnClickListener(this);
@@ -46,7 +49,7 @@ public class FileSelectLayout extends LinearLayout implements OnClickListener {
mTaskId = i;
mFragment = fragment;
}
-
+
public void getCertificateFileDialog() {
Intent startFC = new Intent(getContext(),FileSelect.class);
startFC.putExtra(FileSelect.START_DATA, mData);
@@ -58,20 +61,24 @@ public class FileSelectLayout extends LinearLayout implements OnClickListener {
mFragment.startActivityForResult(startFC,mTaskId);
}
-
+
public String getData() {
return mData;
}
public void setData(String data) {
mData = data;
- if(data==null)
+ if(data==null) {
mDataView.setText(mFragment.getString(R.string.no_data));
- else if(mData.startsWith(VpnProfile.INLINE_TAG))
- mDataView.setText(R.string.inline_file_data);
- else
- mDataView.setText(data);
-
+ mDataDetails.setText("");
+ }else {
+ if(mData.startsWith(VpnProfile.INLINE_TAG))
+ mDataView.setText(R.string.inline_file_data);
+ else
+ mDataView.setText(data);
+ mDataDetails.setText(X509Utils.getCertificateFriendlyName(data));
+ }
+
}
@Override
@@ -88,5 +95,5 @@ public class FileSelectLayout extends LinearLayout implements OnClickListener {
public void setShowClear() {
mShowClear=true;
}
-
+
}
diff --git a/src/de/blinkt/openvpn/VpnProfile.java b/src/de/blinkt/openvpn/VpnProfile.java
index 9d183897..03fcbc1b 100644
--- a/src/de/blinkt/openvpn/VpnProfile.java
+++ b/src/de/blinkt/openvpn/VpnProfile.java
@@ -45,6 +45,7 @@ import de.blinkt.openvpn.R;
import de.blinkt.openvpn.core.NativeUtils;
import de.blinkt.openvpn.core.OpenVPN;
import de.blinkt.openvpn.core.OpenVpnService;
+import de.blinkt.openvpn.core.X509Utils;
public class VpnProfile implements Serializable{
// Note that this class cannot be moved to core where it belongs since
@@ -52,7 +53,7 @@ public class VpnProfile implements Serializable{
// The Serializable documentation mentions that class name change are possible
// but the how is unclear
//
-
+
private static final long serialVersionUID = 7085688938959334563L;
public static final int TYPE_CERTIFICATES=0;
public static final int TYPE_PKCS12=1;
@@ -79,7 +80,7 @@ public class VpnProfile implements Serializable{
public transient String mTransientPW=null;
public transient String mTransientPCKS12PW=null;
private transient PrivateKey mPrivateKey;
-
+
// variable named wrong and should haven beeen transient
// but needs to keep wrong name to guarante loading of old
// profiles
@@ -590,7 +591,7 @@ public class VpnProfile implements Serializable{
if(nonNull(mCaFilename)) {
try {
- Certificate cacert = getCacertFromFile();
+ Certificate cacert = X509Utils.getCertificateFromFile(mCaFilename);
X509Certificate[] newcachain = new X509Certificate[cachain.length+1];
for(int i=0;i<cachain.length;i++)
newcachain[i]=cachain[i];
@@ -645,18 +646,6 @@ public class VpnProfile implements Serializable{
}
return null;
}
- private Certificate getCacertFromFile() throws FileNotFoundException, CertificateException {
- CertificateFactory certFact = CertificateFactory.getInstance("X.509");
-
- InputStream inStream;
-
- if(mCaFilename.startsWith(INLINE_TAG))
- inStream = new ByteArrayInputStream(mCaFilename.replace(INLINE_TAG,"").getBytes());
- else
- inStream = new FileInputStream(mCaFilename);
-
- return certFact.generateCertificate(inStream);
- }
//! Return an error if somethign is wrong
@@ -681,6 +670,8 @@ public class VpnProfile implements Serializable{
}
+
+
//! Openvpn asks for a "Private Key", this should be pkcs12 key
//
public String getPasswordPrivateKey() {
diff --git a/src/de/blinkt/openvpn/core/X509Utils.java b/src/de/blinkt/openvpn/core/X509Utils.java
new file mode 100644
index 00000000..e50343f4
--- /dev/null
+++ b/src/de/blinkt/openvpn/core/X509Utils.java
@@ -0,0 +1,78 @@
+package de.blinkt.openvpn.core;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.io.StringReader;
+import java.security.KeyFactory;
+import java.security.KeyPair;
+import java.security.Principal;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+
+import javax.security.auth.x500.X500Principal;
+
+import org.spongycastle.util.io.pem.PemObject;
+import org.spongycastle.util.io.pem.PemReader;
+
+import android.text.TextUtils;
+
+import de.blinkt.openvpn.VpnProfile;
+
+public class X509Utils {
+ public static Certificate getCertificateFromFile(String certfilename) throws FileNotFoundException, CertificateException {
+ CertificateFactory certFact = CertificateFactory.getInstance("X.509");
+
+ InputStream inStream;
+
+ if(certfilename.startsWith(VpnProfile.INLINE_TAG))
+ inStream = new ByteArrayInputStream(certfilename.replace(VpnProfile.INLINE_TAG,"").getBytes());
+ else
+ inStream = new FileInputStream(certfilename);
+
+ return certFact.generateCertificate(inStream);
+ }
+
+ public static PemObject readPemObjectFromFile (String keyfilename) throws CertificateException, IOException {
+
+ Reader inStream;
+
+ if(keyfilename.startsWith(VpnProfile.INLINE_TAG))
+ inStream = new StringReader(keyfilename.replace(VpnProfile.INLINE_TAG,""));
+ else
+ inStream = new FileReader(new File(keyfilename));
+
+ PemReader pr = new PemReader(inStream);
+ PemObject r = pr.readPemObject();
+ pr.close();
+ return r;
+ }
+
+
+
+
+ public static String getCertificateFriendlyName (String filename) {
+ if(!TextUtils.isEmpty(filename)) {
+ try {
+ X509Certificate cert = (X509Certificate) getCertificateFromFile(filename);
+
+ String friendly = cert.getSubjectDN().getName();
+
+ return friendly;
+
+ } catch (Exception e) {
+ OpenVPN.logError("Could not read certificate" + e.getLocalizedMessage());
+ }
+ }
+ return "Could not read/parse certificate";
+ }
+
+
+}
diff --git a/src/de/blinkt/openvpn/fragments/Settings_Basic.java b/src/de/blinkt/openvpn/fragments/Settings_Basic.java
index 7bcd302d..ad9a79ad 100644
--- a/src/de/blinkt/openvpn/fragments/Settings_Basic.java
+++ b/src/de/blinkt/openvpn/fragments/Settings_Basic.java
@@ -116,7 +116,7 @@ public class Settings_Basic extends Fragment implements View.OnClickListener, On
return mView;
}
-
+
@Override
public void onStart() {
super.onStart();
@@ -138,7 +138,7 @@ public class Settings_Basic extends Fragment implements View.OnClickListener, On
// Private key files may result in showing/hiding the private key password dialog
if(fsl==mClientKey) {
changeType(mType.getSelectedItemPosition());
- }
+ }
}
}
@@ -183,13 +183,13 @@ public class Settings_Basic extends Fragment implements View.OnClickListener, On
if(mProfile.requireTLSKeyPassword())
mView.findViewById(R.id.key_password_layout).setVisibility(View.VISIBLE);
break;
-
+
case VpnProfile.TYPE_USERPASS_PKCS12:
mView.findViewById(R.id.userpassword).setVisibility(View.VISIBLE);
case VpnProfile.TYPE_PKCS12:
mView.findViewById(R.id.pkcs12).setVisibility(View.VISIBLE);
break;
-
+
case VpnProfile.TYPE_STATICKEYS:
mView.findViewById(R.id.statickeys).setVisibility(View.VISIBLE);
break;
diff --git a/src/org/spongycastle/util/io/pem/PemReader.java b/src/org/spongycastle/util/io/pem/PemReader.java
new file mode 100644
index 00000000..cbbebab9
--- /dev/null
+++ b/src/org/spongycastle/util/io/pem/PemReader.java
@@ -0,0 +1,84 @@
+package org.spongycastle.util.io.pem;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.Reader;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.spongycastle.util.encoders.Base64;
+
+public class PemReader
+ extends BufferedReader
+{
+ private static final String BEGIN = "-----BEGIN ";
+ private static final String END = "-----END ";
+
+ public PemReader(Reader reader)
+ {
+ super(reader);
+ }
+
+ public PemObject readPemObject()
+ throws IOException
+ {
+ String line = readLine();
+
+ while (line != null && !line.startsWith(BEGIN))
+ {
+ line = readLine();
+ }
+
+ if (line != null)
+ {
+ line = line.substring(BEGIN.length());
+ int index = line.indexOf('-');
+ String type = line.substring(0, index);
+
+ if (index > 0)
+ {
+ return loadObject(type);
+ }
+ }
+
+ return null;
+ }
+
+ private PemObject loadObject(String type)
+ throws IOException
+ {
+ String line;
+ String endMarker = END + type;
+ StringBuffer buf = new StringBuffer();
+ List headers = new ArrayList();
+
+ while ((line = readLine()) != null)
+ {
+ if (line.indexOf(":") >= 0)
+ {
+ int index = line.indexOf(':');
+ String hdr = line.substring(0, index);
+ String value = line.substring(index + 1).trim();
+
+ headers.add(new PemHeader(hdr, value));
+
+ continue;
+ }
+
+ if (line.indexOf(endMarker) != -1)
+ {
+ break;
+ }
+
+ buf.append(line.trim());
+ }
+
+ if (line == null)
+ {
+ throw new IOException(endMarker + " not found");
+ }
+
+ return new PemObject(type, headers, Base64.decode(buf.toString()));
+ }
+
+}