Loading tests/Android.mk +1 −1 Original line number Diff line number Diff line Loading @@ -5,7 +5,7 @@ include $(CLEAR_VARS) LOCAL_MODULE_TAGS := tests LOCAL_CERTIFICATE := platform LOCAL_JAVA_LIBRARIES := android.test.runner LOCAL_JAVA_LIBRARIES := android.test.runner bouncycastle # Include all test java files. LOCAL_SRC_FILES := $(call all-java-files-under, src) Loading tests/AndroidManifest.xml +3 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,9 @@ <uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.USE_CREDENTIALS" /> <application> <uses-library android:name="android.test.runner" /> Loading tests/src/com/android/settings/vpn2/CertInstallerHelper.java 0 → 100644 +223 −0 Original line number Diff line number Diff line /* * Copyright (C) 2013 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.settings.vpn2; import android.os.Environment; import android.security.Credentials; import android.security.KeyStore; import android.util.Log; import com.android.internal.net.VpnProfile; import com.android.org.bouncycastle.asn1.ASN1InputStream; import com.android.org.bouncycastle.asn1.ASN1Sequence; import com.android.org.bouncycastle.asn1.DEROctetString; import com.android.org.bouncycastle.asn1.x509.BasicConstraints; import junit.framework.Assert; import libcore.io.Streams; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.nio.charset.StandardCharsets; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.KeyStore.PasswordProtection; import java.security.KeyStore.PrivateKeyEntry; import java.security.PrivateKey; import java.security.UnrecoverableEntryException; import java.security.cert.Certificate; import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Collections; import java.util.Enumeration; import java.util.List; /** * Certificate installer helper to extract information from a provided file * and install certificates to keystore. */ public class CertInstallerHelper { private static final String TAG = "CertInstallerHelper"; /* Define a password to unlock keystore after it is reset */ private static final String CERT_STORE_PASSWORD = "password"; private final int mUid = KeyStore.UID_SELF; private PrivateKey mUserKey; // private key private X509Certificate mUserCert; // user certificate private List<X509Certificate> mCaCerts = new ArrayList<X509Certificate>(); private KeyStore mKeyStore = KeyStore.getInstance(); /** * Unlock keystore and set password */ public CertInstallerHelper() { mKeyStore.reset(); mKeyStore.password(CERT_STORE_PASSWORD); } private void extractCertificate(String certFile, String password) { InputStream in = null; final byte[] raw; java.security.KeyStore keystore = null; try { // Read .p12 file from SDCARD and extract with password in = new FileInputStream(new File( Environment.getExternalStorageDirectory(), certFile)); raw = Streams.readFully(in); keystore = java.security.KeyStore.getInstance("PKCS12"); PasswordProtection passwordProtection = new PasswordProtection(password.toCharArray()); keystore.load(new ByteArrayInputStream(raw), passwordProtection.getPassword()); // Install certificates and private keys Enumeration<String> aliases = keystore.aliases(); if (!aliases.hasMoreElements()) { Assert.fail("key store failed to put in keychain"); } ArrayList<String> aliasesList = Collections.list(aliases); // The keystore is initialized for each test case, there will // be only one alias in the keystore Assert.assertEquals(1, aliasesList.size()); String alias = aliasesList.get(0); java.security.KeyStore.Entry entry = keystore.getEntry(alias, passwordProtection); Log.d(TAG, "extracted alias = " + alias + ", entry=" + entry.getClass()); if (entry instanceof PrivateKeyEntry) { Assert.assertTrue(installFrom((PrivateKeyEntry) entry)); } } catch (IOException e) { Assert.fail("Failed to read certficate: " + e); } catch (KeyStoreException e) { Log.e(TAG, "failed to extract certificate" + e); } catch (NoSuchAlgorithmException e) { Log.e(TAG, "failed to extract certificate" + e); } catch (CertificateException e) { Log.e(TAG, "failed to extract certificate" + e); } catch (UnrecoverableEntryException e) { Log.e(TAG, "failed to extract certificate" + e); } finally { if (in != null) { try { in.close(); } catch (IOException e) { Log.e(TAG, "close FileInputStream error: " + e); } } } } /** * Extract private keys, user certificates and ca certificates */ private synchronized boolean installFrom(PrivateKeyEntry entry) { mUserKey = entry.getPrivateKey(); mUserCert = (X509Certificate) entry.getCertificate(); Certificate[] certs = entry.getCertificateChain(); Log.d(TAG, "# certs extracted = " + certs.length); mCaCerts = new ArrayList<X509Certificate>(certs.length); for (Certificate c : certs) { X509Certificate cert = (X509Certificate) c; if (isCa(cert)) { mCaCerts.add(cert); } } Log.d(TAG, "# ca certs extracted = " + mCaCerts.size()); return true; } private boolean isCa(X509Certificate cert) { try { byte[] asn1EncodedBytes = cert.getExtensionValue("2.5.29.19"); if (asn1EncodedBytes == null) { return false; } DEROctetString derOctetString = (DEROctetString) new ASN1InputStream(asn1EncodedBytes).readObject(); byte[] octets = derOctetString.getOctets(); ASN1Sequence sequence = (ASN1Sequence) new ASN1InputStream(octets).readObject(); return BasicConstraints.getInstance(sequence).isCA(); } catch (IOException e) { return false; } } /** * Extract certificate from the given file, and install it to keystore * @param name certificate name * @param certFile .p12 file which includes certificates * @param password password to extract the .p12 file */ public void installCertificate(VpnProfile profile, String certFile, String password) { // extract private keys, certificates from the provided file extractCertificate(certFile, password); // install certificate to the keystore int flags = KeyStore.FLAG_ENCRYPTED; try { if (mUserKey != null) { Log.v(TAG, "has private key"); String key = Credentials.USER_PRIVATE_KEY + profile.ipsecUserCert; byte[] value = mUserKey.getEncoded(); if (!mKeyStore.importKey(key, value, mUid, flags)) { Log.e(TAG, "Failed to install " + key + " as user " + mUid); return; } Log.v(TAG, "install " + key + " as user " + mUid + " is successful"); } if (mUserCert != null) { String certName = Credentials.USER_CERTIFICATE + profile.ipsecUserCert; byte[] certData = Credentials.convertToPem(mUserCert); if (!mKeyStore.put(certName, certData, mUid, flags)) { Log.e(TAG, "Failed to install " + certName + " as user " + mUid); return; } Log.v(TAG, "install " + certName + " as user" + mUid + " is successful."); } if (!mCaCerts.isEmpty()) { String caListName = Credentials.CA_CERTIFICATE + profile.ipsecCaCert; X509Certificate[] caCerts = mCaCerts.toArray(new X509Certificate[mCaCerts.size()]); byte[] caListData = Credentials.convertToPem(caCerts); if (!mKeyStore.put(caListName, caListData, mUid, flags)) { Log.e(TAG, "Failed to install " + caListName + " as user " + mUid); return; } Log.v(TAG, " install " + caListName + " as user " + mUid + " is successful"); } } catch (CertificateEncodingException e) { Log.e(TAG, "Exception while convert certificates to pem " + e); throw new AssertionError(e); } catch (IOException e) { Log.e(TAG, "IOException while convert to pem: " + e); } } public int getUid() { return mUid; } } tests/src/com/android/settings/vpn2/VpnInfo.java 0 → 100644 +65 −0 Original line number Diff line number Diff line /* * Copyright (C) 2013 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.settings.vpn2; import com.android.internal.net.VpnProfile; /** * Wrapper for VPN Profile and associated certificate files */ public class VpnInfo { // VPN Profile private VpnProfile mVpnProfile; // Certificate file in PC12 format for user certificates and private keys private String mCertificateFile = null; // Password to extract certificates from the file private String mPassword = null; public VpnInfo(VpnProfile vpnProfile, String certFile, String password) { mVpnProfile = vpnProfile; mCertificateFile = certFile; mPassword = password; } public VpnInfo(VpnProfile vpnProfile) { mVpnProfile = vpnProfile; } public void setVpnProfile(VpnProfile vpnProfile) { mVpnProfile = vpnProfile; } public void setCertificateFile(String certFile) { mCertificateFile = certFile; } public void setPassword(String password) { mPassword = password; } public VpnProfile getVpnProfile() { return mVpnProfile; } public String getCertificateFile() { return mCertificateFile; } public String getPassword() { return mPassword; } } tests/src/com/android/settings/vpn2/VpnProfileParser.java 0 → 100644 +246 −0 Original line number Diff line number Diff line /* * Copyright (C) 2013 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.settings.vpn2; import android.util.Log; import com.android.internal.net.VpnProfile; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; import java.io.IOException; import java.io.InputStream; import java.util.HashMap; import java.util.Map; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; /** * Parse VPN profiles from an XML file */ public class VpnProfileParser { private final static String TAG = "VpnProfileParser"; private static Map<Integer, VpnInfo> mVpnPool = new HashMap<Integer, VpnInfo>(); static DefaultHandler mHandler = new DefaultHandler() { boolean name; boolean type; boolean server; boolean username; boolean password; boolean dnsServers; boolean searchDomains; boolean routes; boolean mppe; boolean l2tpSecret; boolean ipsecIdentifier; boolean ipsecSecret; boolean ipsecUserCert; boolean ipsecCaCert; boolean ipsecServerCert; boolean certFile; boolean certFilePassword; VpnProfile profile = null; VpnInfo vpnInfo = null; @Override public void startElement(String uri, String localName, String tagName, Attributes attributes) throws SAXException { if (tagName.equalsIgnoreCase("vpn")) { //create a new VPN profile profile = new VpnProfile(Long.toHexString(System.currentTimeMillis())); vpnInfo = new VpnInfo(profile); } if (tagName.equalsIgnoreCase("name")) { name = true; } if (tagName.equalsIgnoreCase("type")) { type = true; } if (tagName.equalsIgnoreCase("server")) { server = true; } if (tagName.equalsIgnoreCase("username")) { username = true; } if (tagName.equalsIgnoreCase("password")) { password = true; } if (tagName.equalsIgnoreCase("dnsServers")) { dnsServers = true; } if (tagName.equalsIgnoreCase("searchDomains")) { searchDomains = true; } if (tagName.equalsIgnoreCase("mppe")) { mppe = true; } if (tagName.equalsIgnoreCase("l2tpSecret")) { l2tpSecret = true; } if (tagName.equalsIgnoreCase("ipsecIdentifier")) { ipsecIdentifier = true; } if (tagName.equalsIgnoreCase("ipsecSecret")) { ipsecSecret = true; } if (tagName.equalsIgnoreCase("ipsecUserCert")) { ipsecUserCert = true; } if (tagName.equalsIgnoreCase("ipsecCaCert")) { ipsecCaCert = true; } if (tagName.equalsIgnoreCase("ipsecServerCert")) { ipsecServerCert = true; } if (tagName.equalsIgnoreCase("routes")) { routes = true; } if (tagName.equalsIgnoreCase("cert-file")) { certFile = true; } if (tagName.equalsIgnoreCase("cert-file-password")) { certFilePassword = true; } } @Override public void endElement(String uri, String localName, String tagName) throws SAXException { if (tagName.equalsIgnoreCase("vpn")) { mVpnPool.put(profile.type, vpnInfo); } } @Override public void characters(char ch[], int start, int length) throws SAXException { String strValue = new String(ch, start, length); if (name) { profile.name = strValue; name = false; } if (type) { int t = getVpnProfileType(strValue); if (t < 0) { throw new SAXException("not a valid VPN type"); } else { profile.type = t; } type = false; } if (server) { profile.server = strValue; server = false; } if (username) { profile.username = strValue; username = false; } if (password) { profile.password = strValue; password = false; } if (dnsServers) { profile.dnsServers = strValue; dnsServers = false; } if (searchDomains) { profile.searchDomains = strValue; searchDomains = false; } if (mppe) { profile.mppe = Boolean.valueOf(strValue); mppe = false; } if (l2tpSecret) { profile.l2tpSecret = strValue; l2tpSecret = false; } if (ipsecIdentifier) { profile.ipsecIdentifier = strValue; ipsecIdentifier = false; } if (ipsecSecret) { profile.ipsecSecret = strValue; ipsecSecret = false; } if (ipsecUserCert) { profile.ipsecUserCert = strValue; ipsecUserCert = false; } if (ipsecCaCert) { profile.ipsecCaCert = strValue; ipsecCaCert = false; } if (ipsecServerCert) { profile.ipsecServerCert = strValue; ipsecServerCert = false; } if (routes) { profile.routes = strValue; routes = false; } if (certFile) { vpnInfo.setCertificateFile(strValue); certFile = false; } if (certFilePassword) { vpnInfo.setPassword(strValue); certFilePassword = false; } } private int getVpnProfileType(String type) { if (type.equalsIgnoreCase("TYPE_PPTP")) { return VpnProfile.TYPE_PPTP; } else if (type.equalsIgnoreCase("TYPE_L2TP_IPSEC_PSK")) { return VpnProfile.TYPE_L2TP_IPSEC_PSK; } else if (type.equalsIgnoreCase("TYPE_L2TP_IPSEC_RSA")) { return VpnProfile.TYPE_L2TP_IPSEC_RSA; } else if (type.equalsIgnoreCase("TYPE_IPSEC_XAUTH_PSK")) { return VpnProfile.TYPE_IPSEC_XAUTH_PSK; } else if (type.equalsIgnoreCase("TYPE_IPSEC_XAUTH_RSA")) { return VpnProfile.TYPE_IPSEC_XAUTH_RSA; } else if (type.equalsIgnoreCase("TYPE_IPSEC_HYBRID_RSA")) { return VpnProfile.TYPE_IPSEC_HYBRID_RSA; } else { Log.v(TAG, "Invalid VPN type: " + type); return -1; } } }; public static Map<Integer, VpnInfo> parse(InputStream in) { try { SAXParserFactory factory = SAXParserFactory.newInstance(); SAXParser saxParser = factory.newSAXParser(); saxParser.parse(in, mHandler); } catch (SAXException e) { Log.e(TAG, "Parse vpn profile exception: " + e.toString()); } catch (IOException e) { Log.e(TAG, "Parse vpn profile exception: " + e.toString()); } catch (ParserConfigurationException e) { Log.e(TAG, "Parse vpn profile exception: " + e.toString()); } finally { return mVpnPool; } } } Loading
tests/Android.mk +1 −1 Original line number Diff line number Diff line Loading @@ -5,7 +5,7 @@ include $(CLEAR_VARS) LOCAL_MODULE_TAGS := tests LOCAL_CERTIFICATE := platform LOCAL_JAVA_LIBRARIES := android.test.runner LOCAL_JAVA_LIBRARIES := android.test.runner bouncycastle # Include all test java files. LOCAL_SRC_FILES := $(call all-java-files-under, src) Loading
tests/AndroidManifest.xml +3 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,9 @@ <uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.USE_CREDENTIALS" /> <application> <uses-library android:name="android.test.runner" /> Loading
tests/src/com/android/settings/vpn2/CertInstallerHelper.java 0 → 100644 +223 −0 Original line number Diff line number Diff line /* * Copyright (C) 2013 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.settings.vpn2; import android.os.Environment; import android.security.Credentials; import android.security.KeyStore; import android.util.Log; import com.android.internal.net.VpnProfile; import com.android.org.bouncycastle.asn1.ASN1InputStream; import com.android.org.bouncycastle.asn1.ASN1Sequence; import com.android.org.bouncycastle.asn1.DEROctetString; import com.android.org.bouncycastle.asn1.x509.BasicConstraints; import junit.framework.Assert; import libcore.io.Streams; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.nio.charset.StandardCharsets; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.KeyStore.PasswordProtection; import java.security.KeyStore.PrivateKeyEntry; import java.security.PrivateKey; import java.security.UnrecoverableEntryException; import java.security.cert.Certificate; import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Collections; import java.util.Enumeration; import java.util.List; /** * Certificate installer helper to extract information from a provided file * and install certificates to keystore. */ public class CertInstallerHelper { private static final String TAG = "CertInstallerHelper"; /* Define a password to unlock keystore after it is reset */ private static final String CERT_STORE_PASSWORD = "password"; private final int mUid = KeyStore.UID_SELF; private PrivateKey mUserKey; // private key private X509Certificate mUserCert; // user certificate private List<X509Certificate> mCaCerts = new ArrayList<X509Certificate>(); private KeyStore mKeyStore = KeyStore.getInstance(); /** * Unlock keystore and set password */ public CertInstallerHelper() { mKeyStore.reset(); mKeyStore.password(CERT_STORE_PASSWORD); } private void extractCertificate(String certFile, String password) { InputStream in = null; final byte[] raw; java.security.KeyStore keystore = null; try { // Read .p12 file from SDCARD and extract with password in = new FileInputStream(new File( Environment.getExternalStorageDirectory(), certFile)); raw = Streams.readFully(in); keystore = java.security.KeyStore.getInstance("PKCS12"); PasswordProtection passwordProtection = new PasswordProtection(password.toCharArray()); keystore.load(new ByteArrayInputStream(raw), passwordProtection.getPassword()); // Install certificates and private keys Enumeration<String> aliases = keystore.aliases(); if (!aliases.hasMoreElements()) { Assert.fail("key store failed to put in keychain"); } ArrayList<String> aliasesList = Collections.list(aliases); // The keystore is initialized for each test case, there will // be only one alias in the keystore Assert.assertEquals(1, aliasesList.size()); String alias = aliasesList.get(0); java.security.KeyStore.Entry entry = keystore.getEntry(alias, passwordProtection); Log.d(TAG, "extracted alias = " + alias + ", entry=" + entry.getClass()); if (entry instanceof PrivateKeyEntry) { Assert.assertTrue(installFrom((PrivateKeyEntry) entry)); } } catch (IOException e) { Assert.fail("Failed to read certficate: " + e); } catch (KeyStoreException e) { Log.e(TAG, "failed to extract certificate" + e); } catch (NoSuchAlgorithmException e) { Log.e(TAG, "failed to extract certificate" + e); } catch (CertificateException e) { Log.e(TAG, "failed to extract certificate" + e); } catch (UnrecoverableEntryException e) { Log.e(TAG, "failed to extract certificate" + e); } finally { if (in != null) { try { in.close(); } catch (IOException e) { Log.e(TAG, "close FileInputStream error: " + e); } } } } /** * Extract private keys, user certificates and ca certificates */ private synchronized boolean installFrom(PrivateKeyEntry entry) { mUserKey = entry.getPrivateKey(); mUserCert = (X509Certificate) entry.getCertificate(); Certificate[] certs = entry.getCertificateChain(); Log.d(TAG, "# certs extracted = " + certs.length); mCaCerts = new ArrayList<X509Certificate>(certs.length); for (Certificate c : certs) { X509Certificate cert = (X509Certificate) c; if (isCa(cert)) { mCaCerts.add(cert); } } Log.d(TAG, "# ca certs extracted = " + mCaCerts.size()); return true; } private boolean isCa(X509Certificate cert) { try { byte[] asn1EncodedBytes = cert.getExtensionValue("2.5.29.19"); if (asn1EncodedBytes == null) { return false; } DEROctetString derOctetString = (DEROctetString) new ASN1InputStream(asn1EncodedBytes).readObject(); byte[] octets = derOctetString.getOctets(); ASN1Sequence sequence = (ASN1Sequence) new ASN1InputStream(octets).readObject(); return BasicConstraints.getInstance(sequence).isCA(); } catch (IOException e) { return false; } } /** * Extract certificate from the given file, and install it to keystore * @param name certificate name * @param certFile .p12 file which includes certificates * @param password password to extract the .p12 file */ public void installCertificate(VpnProfile profile, String certFile, String password) { // extract private keys, certificates from the provided file extractCertificate(certFile, password); // install certificate to the keystore int flags = KeyStore.FLAG_ENCRYPTED; try { if (mUserKey != null) { Log.v(TAG, "has private key"); String key = Credentials.USER_PRIVATE_KEY + profile.ipsecUserCert; byte[] value = mUserKey.getEncoded(); if (!mKeyStore.importKey(key, value, mUid, flags)) { Log.e(TAG, "Failed to install " + key + " as user " + mUid); return; } Log.v(TAG, "install " + key + " as user " + mUid + " is successful"); } if (mUserCert != null) { String certName = Credentials.USER_CERTIFICATE + profile.ipsecUserCert; byte[] certData = Credentials.convertToPem(mUserCert); if (!mKeyStore.put(certName, certData, mUid, flags)) { Log.e(TAG, "Failed to install " + certName + " as user " + mUid); return; } Log.v(TAG, "install " + certName + " as user" + mUid + " is successful."); } if (!mCaCerts.isEmpty()) { String caListName = Credentials.CA_CERTIFICATE + profile.ipsecCaCert; X509Certificate[] caCerts = mCaCerts.toArray(new X509Certificate[mCaCerts.size()]); byte[] caListData = Credentials.convertToPem(caCerts); if (!mKeyStore.put(caListName, caListData, mUid, flags)) { Log.e(TAG, "Failed to install " + caListName + " as user " + mUid); return; } Log.v(TAG, " install " + caListName + " as user " + mUid + " is successful"); } } catch (CertificateEncodingException e) { Log.e(TAG, "Exception while convert certificates to pem " + e); throw new AssertionError(e); } catch (IOException e) { Log.e(TAG, "IOException while convert to pem: " + e); } } public int getUid() { return mUid; } }
tests/src/com/android/settings/vpn2/VpnInfo.java 0 → 100644 +65 −0 Original line number Diff line number Diff line /* * Copyright (C) 2013 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.settings.vpn2; import com.android.internal.net.VpnProfile; /** * Wrapper for VPN Profile and associated certificate files */ public class VpnInfo { // VPN Profile private VpnProfile mVpnProfile; // Certificate file in PC12 format for user certificates and private keys private String mCertificateFile = null; // Password to extract certificates from the file private String mPassword = null; public VpnInfo(VpnProfile vpnProfile, String certFile, String password) { mVpnProfile = vpnProfile; mCertificateFile = certFile; mPassword = password; } public VpnInfo(VpnProfile vpnProfile) { mVpnProfile = vpnProfile; } public void setVpnProfile(VpnProfile vpnProfile) { mVpnProfile = vpnProfile; } public void setCertificateFile(String certFile) { mCertificateFile = certFile; } public void setPassword(String password) { mPassword = password; } public VpnProfile getVpnProfile() { return mVpnProfile; } public String getCertificateFile() { return mCertificateFile; } public String getPassword() { return mPassword; } }
tests/src/com/android/settings/vpn2/VpnProfileParser.java 0 → 100644 +246 −0 Original line number Diff line number Diff line /* * Copyright (C) 2013 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.settings.vpn2; import android.util.Log; import com.android.internal.net.VpnProfile; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; import java.io.IOException; import java.io.InputStream; import java.util.HashMap; import java.util.Map; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; /** * Parse VPN profiles from an XML file */ public class VpnProfileParser { private final static String TAG = "VpnProfileParser"; private static Map<Integer, VpnInfo> mVpnPool = new HashMap<Integer, VpnInfo>(); static DefaultHandler mHandler = new DefaultHandler() { boolean name; boolean type; boolean server; boolean username; boolean password; boolean dnsServers; boolean searchDomains; boolean routes; boolean mppe; boolean l2tpSecret; boolean ipsecIdentifier; boolean ipsecSecret; boolean ipsecUserCert; boolean ipsecCaCert; boolean ipsecServerCert; boolean certFile; boolean certFilePassword; VpnProfile profile = null; VpnInfo vpnInfo = null; @Override public void startElement(String uri, String localName, String tagName, Attributes attributes) throws SAXException { if (tagName.equalsIgnoreCase("vpn")) { //create a new VPN profile profile = new VpnProfile(Long.toHexString(System.currentTimeMillis())); vpnInfo = new VpnInfo(profile); } if (tagName.equalsIgnoreCase("name")) { name = true; } if (tagName.equalsIgnoreCase("type")) { type = true; } if (tagName.equalsIgnoreCase("server")) { server = true; } if (tagName.equalsIgnoreCase("username")) { username = true; } if (tagName.equalsIgnoreCase("password")) { password = true; } if (tagName.equalsIgnoreCase("dnsServers")) { dnsServers = true; } if (tagName.equalsIgnoreCase("searchDomains")) { searchDomains = true; } if (tagName.equalsIgnoreCase("mppe")) { mppe = true; } if (tagName.equalsIgnoreCase("l2tpSecret")) { l2tpSecret = true; } if (tagName.equalsIgnoreCase("ipsecIdentifier")) { ipsecIdentifier = true; } if (tagName.equalsIgnoreCase("ipsecSecret")) { ipsecSecret = true; } if (tagName.equalsIgnoreCase("ipsecUserCert")) { ipsecUserCert = true; } if (tagName.equalsIgnoreCase("ipsecCaCert")) { ipsecCaCert = true; } if (tagName.equalsIgnoreCase("ipsecServerCert")) { ipsecServerCert = true; } if (tagName.equalsIgnoreCase("routes")) { routes = true; } if (tagName.equalsIgnoreCase("cert-file")) { certFile = true; } if (tagName.equalsIgnoreCase("cert-file-password")) { certFilePassword = true; } } @Override public void endElement(String uri, String localName, String tagName) throws SAXException { if (tagName.equalsIgnoreCase("vpn")) { mVpnPool.put(profile.type, vpnInfo); } } @Override public void characters(char ch[], int start, int length) throws SAXException { String strValue = new String(ch, start, length); if (name) { profile.name = strValue; name = false; } if (type) { int t = getVpnProfileType(strValue); if (t < 0) { throw new SAXException("not a valid VPN type"); } else { profile.type = t; } type = false; } if (server) { profile.server = strValue; server = false; } if (username) { profile.username = strValue; username = false; } if (password) { profile.password = strValue; password = false; } if (dnsServers) { profile.dnsServers = strValue; dnsServers = false; } if (searchDomains) { profile.searchDomains = strValue; searchDomains = false; } if (mppe) { profile.mppe = Boolean.valueOf(strValue); mppe = false; } if (l2tpSecret) { profile.l2tpSecret = strValue; l2tpSecret = false; } if (ipsecIdentifier) { profile.ipsecIdentifier = strValue; ipsecIdentifier = false; } if (ipsecSecret) { profile.ipsecSecret = strValue; ipsecSecret = false; } if (ipsecUserCert) { profile.ipsecUserCert = strValue; ipsecUserCert = false; } if (ipsecCaCert) { profile.ipsecCaCert = strValue; ipsecCaCert = false; } if (ipsecServerCert) { profile.ipsecServerCert = strValue; ipsecServerCert = false; } if (routes) { profile.routes = strValue; routes = false; } if (certFile) { vpnInfo.setCertificateFile(strValue); certFile = false; } if (certFilePassword) { vpnInfo.setPassword(strValue); certFilePassword = false; } } private int getVpnProfileType(String type) { if (type.equalsIgnoreCase("TYPE_PPTP")) { return VpnProfile.TYPE_PPTP; } else if (type.equalsIgnoreCase("TYPE_L2TP_IPSEC_PSK")) { return VpnProfile.TYPE_L2TP_IPSEC_PSK; } else if (type.equalsIgnoreCase("TYPE_L2TP_IPSEC_RSA")) { return VpnProfile.TYPE_L2TP_IPSEC_RSA; } else if (type.equalsIgnoreCase("TYPE_IPSEC_XAUTH_PSK")) { return VpnProfile.TYPE_IPSEC_XAUTH_PSK; } else if (type.equalsIgnoreCase("TYPE_IPSEC_XAUTH_RSA")) { return VpnProfile.TYPE_IPSEC_XAUTH_RSA; } else if (type.equalsIgnoreCase("TYPE_IPSEC_HYBRID_RSA")) { return VpnProfile.TYPE_IPSEC_HYBRID_RSA; } else { Log.v(TAG, "Invalid VPN type: " + type); return -1; } } }; public static Map<Integer, VpnInfo> parse(InputStream in) { try { SAXParserFactory factory = SAXParserFactory.newInstance(); SAXParser saxParser = factory.newSAXParser(); saxParser.parse(in, mHandler); } catch (SAXException e) { Log.e(TAG, "Parse vpn profile exception: " + e.toString()); } catch (IOException e) { Log.e(TAG, "Parse vpn profile exception: " + e.toString()); } catch (ParserConfigurationException e) { Log.e(TAG, "Parse vpn profile exception: " + e.toString()); } finally { return mVpnPool; } } }