Loading src/com/android/settings/utils/AndroidKeystoreAliasLoader.java +5 −0 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.UnrecoverableKeyException; import java.security.cert.Certificate; import java.util.ArrayList; import java.util.Collection; import java.util.Enumeration; Loading Loading @@ -88,6 +89,10 @@ public class AndroidKeystoreAliasLoader { if (key != null) { if (key instanceof PrivateKey) { mKeyCertAliases.add(alias); final Certificate[] cert = keyStore.getCertificateChain(alias); if (cert != null && cert.length >= 2) { mCaCertAliases.add(alias); } } } else { if (keyStore.getCertificate(alias) != null) { Loading src/com/android/settings/vpn2/ConfigDialog.java +23 −17 Original line number Diff line number Diff line Loading @@ -24,8 +24,6 @@ import android.content.pm.PackageManager; import android.net.ProxyInfo; import android.os.Bundle; import android.os.SystemProperties; import android.security.Credentials; import android.security.KeyStore; import android.text.Editable; import android.text.TextWatcher; import android.view.View; Loading @@ -42,10 +40,12 @@ import androidx.appcompat.app.AlertDialog; import com.android.internal.net.VpnProfile; import com.android.net.module.util.ProxyUtils; import com.android.settings.R; import com.android.settings.utils.AndroidKeystoreAliasLoader; import java.net.InetAddress; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.List; /** Loading @@ -58,7 +58,7 @@ import java.util.List; class ConfigDialog extends AlertDialog implements TextWatcher, View.OnClickListener, AdapterView.OnItemSelectedListener, CompoundButton.OnCheckedChangeListener { private final KeyStore mKeyStore = KeyStore.getInstance(); private static final String TAG = "ConfigDialog"; private final DialogInterface.OnClickListener mListener; private final VpnProfile mProfile; Loading Loading @@ -153,10 +153,13 @@ class ConfigDialog extends AlertDialog implements TextWatcher, mL2tpSecret.setTextAppearance(android.R.style.TextAppearance_DeviceDefault_Medium); mIpsecIdentifier.setText(mProfile.ipsecIdentifier); mIpsecSecret.setText(mProfile.ipsecSecret); loadCertificates(mIpsecUserCert, Credentials.USER_PRIVATE_KEY, 0, mProfile.ipsecUserCert); loadCertificates(mIpsecCaCert, Credentials.CA_CERTIFICATE, AndroidKeystoreAliasLoader androidKeystoreAliasLoader = new AndroidKeystoreAliasLoader(null); loadCertificates(mIpsecUserCert, androidKeystoreAliasLoader.getKeyCertAliases(), 0, mProfile.ipsecUserCert); loadCertificates(mIpsecCaCert, androidKeystoreAliasLoader.getCaCertAliases(), R.string.vpn_no_ca_cert, mProfile.ipsecCaCert); loadCertificates(mIpsecServerCert, Credentials.USER_CERTIFICATE, loadCertificates(mIpsecServerCert, androidKeystoreAliasLoader.getKeyCertAliases(), R.string.vpn_no_server_cert, mProfile.ipsecServerCert); mSaveLogin.setChecked(mProfile.saveLogin); mAlwaysOnVpn.setChecked(mProfile.key.equals(VpnUtils.getLockdownVpn())); Loading Loading @@ -511,27 +514,30 @@ class ConfigDialog extends AlertDialog implements TextWatcher, typeSpinner.setAdapter(adapter); } private void loadCertificates(Spinner spinner, String prefix, int firstId, String selected) { private void loadCertificates(Spinner spinner, Collection<String> choices, int firstId, String selected) { Context context = getContext(); String first = (firstId == 0) ? "" : context.getString(firstId); String[] certificates = mKeyStore.list(prefix); String[] myChoices; if (certificates == null || certificates.length == 0) { certificates = new String[] {first}; if (choices == null || choices.size() == 0) { myChoices = new String[] {first}; } else { String[] array = new String[certificates.length + 1]; array[0] = first; System.arraycopy(certificates, 0, array, 1, certificates.length); certificates = array; myChoices = new String[choices.size() + 1]; myChoices[0] = first; int i = 1; for (String c : choices) { myChoices[i++] = c; } } ArrayAdapter<String> adapter = new ArrayAdapter<String>( context, android.R.layout.simple_spinner_item, certificates); context, android.R.layout.simple_spinner_item, myChoices); adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); spinner.setAdapter(adapter); for (int i = 1; i < certificates.length; ++i) { if (certificates[i].equals(selected)) { for (int i = 1; i < myChoices.length; ++i) { if (myChoices[i].equals(selected)) { spinner.setSelection(i); break; } Loading src/com/android/settings/vpn2/ConfigDialogFragment.java +4 −6 Original line number Diff line number Diff line Loading @@ -25,7 +25,7 @@ import android.os.Bundle; import android.os.RemoteException; import android.os.UserHandle; import android.security.Credentials; import android.security.KeyStore; import android.security.LegacyVpnProfileStore; import android.util.Log; import android.view.View; import android.widget.Toast; Loading Loading @@ -151,9 +151,8 @@ public class ConfigDialogFragment extends InstrumentedDialogFragment implements return; } // Delete from KeyStore KeyStore keyStore = KeyStore.getInstance(); keyStore.delete(Credentials.VPN + profile.key, KeyStore.UID_SELF); // Delete from profile store. LegacyVpnProfileStore.remove(Credentials.VPN + profile.key); updateLockdownVpn(false, profile); } Loading Loading @@ -188,8 +187,7 @@ public class ConfigDialogFragment extends InstrumentedDialogFragment implements } private void save(VpnProfile profile, boolean lockdown) { KeyStore.getInstance().put(Credentials.VPN + profile.key, profile.encode(), KeyStore.UID_SELF, /* flags */ 0); LegacyVpnProfileStore.put(Credentials.VPN + profile.key, profile.encode()); // Flush out old version of profile disconnect(profile); Loading src/com/android/settings/vpn2/VpnSettings.java +7 −9 Original line number Diff line number Diff line Loading @@ -41,7 +41,7 @@ import android.os.Message; import android.os.UserHandle; import android.os.UserManager; import android.security.Credentials; import android.security.KeyStore; import android.security.LegacyVpnProfileStore; import android.util.ArrayMap; import android.util.ArraySet; import android.util.Log; Loading @@ -57,7 +57,6 @@ import com.android.internal.annotations.GuardedBy; import com.android.internal.net.LegacyVpnInfo; import com.android.internal.net.VpnConfig; import com.android.internal.net.VpnProfile; import com.android.internal.util.ArrayUtils; import com.android.settings.R; import com.android.settings.RestrictedSettingsFragment; import com.android.settings.widget.GearPreference; Loading Loading @@ -94,8 +93,6 @@ public class VpnSettings extends RestrictedSettingsFragment implements private UserManager mUserManager; private VpnManager mVpnManager; private final KeyStore mKeyStore = KeyStore.getInstance(); private Map<String, LegacyVpnPreference> mLegacyVpnPreferences = new ArrayMap<>(); private Map<AppVpnInfo, AppPreference> mAppPreferences = new ArrayMap<>(); Loading Loading @@ -222,7 +219,7 @@ public class VpnSettings extends RestrictedSettingsFragment implements final Context context = activity.getApplicationContext(); // Run heavy RPCs before switching to UI thread final List<VpnProfile> vpnProfiles = loadVpnProfiles(mKeyStore); final List<VpnProfile> vpnProfiles = loadVpnProfiles(); final List<AppVpnInfo> vpnApps = getVpnApps(context, /* includeProfiles */ true); final Map<String, LegacyVpnInfo> connectedLegacyVpns = getConnectedLegacyVpns(); Loading Loading @@ -540,12 +537,13 @@ public class VpnSettings extends RestrictedSettingsFragment implements return result; } static List<VpnProfile> loadVpnProfiles(KeyStore keyStore, int... excludeTypes) { private static List<VpnProfile> loadVpnProfiles() { final ArrayList<VpnProfile> result = Lists.newArrayList(); for (String key : keyStore.list(Credentials.VPN)) { final VpnProfile profile = VpnProfile.decode(key, keyStore.get(Credentials.VPN + key)); if (profile != null && !ArrayUtils.contains(excludeTypes, profile.type)) { for (String key : LegacyVpnProfileStore.list(Credentials.VPN)) { final VpnProfile profile = VpnProfile.decode(key, LegacyVpnProfileStore.get(Credentials.VPN + key)); if (profile != null) { result.add(profile); } } Loading src/com/android/settings/vpn2/VpnUtils.java +5 −7 Original line number Diff line number Diff line Loading @@ -20,7 +20,7 @@ import android.net.VpnManager; import android.os.RemoteException; import android.provider.Settings; import android.security.Credentials; import android.security.KeyStore; import android.security.LegacyVpnProfileStore; import com.android.internal.net.LegacyVpnInfo; import com.android.internal.net.VpnConfig; Loading @@ -28,27 +28,25 @@ import com.android.internal.net.VpnConfig; /** * Utility functions for vpn. * * Keystore methods should only be called in system user * LegacyVpnProfileStore methods should only be called in system user */ public class VpnUtils { private static final String TAG = "VpnUtils"; public static String getLockdownVpn() { final byte[] value = KeyStore.getInstance().get( Credentials.LOCKDOWN_VPN, true /* suppressKeyNotFoundWarning */); final byte[] value = LegacyVpnProfileStore.get(Credentials.LOCKDOWN_VPN); return value == null ? null : new String(value); } public static void clearLockdownVpn(Context context) { KeyStore.getInstance().delete(Credentials.LOCKDOWN_VPN); LegacyVpnProfileStore.remove(Credentials.LOCKDOWN_VPN); // Always notify VpnManager after keystore update getVpnManager(context).updateLockdownVpn(); } public static void setLockdownVpn(Context context, String lockdownKey) { KeyStore.getInstance().put(Credentials.LOCKDOWN_VPN, lockdownKey.getBytes(), KeyStore.UID_SELF, /* flags */ 0); LegacyVpnProfileStore.put(Credentials.LOCKDOWN_VPN, lockdownKey.getBytes()); // Always notify VpnManager after keystore update getVpnManager(context).updateLockdownVpn(); } Loading Loading
src/com/android/settings/utils/AndroidKeystoreAliasLoader.java +5 −0 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.UnrecoverableKeyException; import java.security.cert.Certificate; import java.util.ArrayList; import java.util.Collection; import java.util.Enumeration; Loading Loading @@ -88,6 +89,10 @@ public class AndroidKeystoreAliasLoader { if (key != null) { if (key instanceof PrivateKey) { mKeyCertAliases.add(alias); final Certificate[] cert = keyStore.getCertificateChain(alias); if (cert != null && cert.length >= 2) { mCaCertAliases.add(alias); } } } else { if (keyStore.getCertificate(alias) != null) { Loading
src/com/android/settings/vpn2/ConfigDialog.java +23 −17 Original line number Diff line number Diff line Loading @@ -24,8 +24,6 @@ import android.content.pm.PackageManager; import android.net.ProxyInfo; import android.os.Bundle; import android.os.SystemProperties; import android.security.Credentials; import android.security.KeyStore; import android.text.Editable; import android.text.TextWatcher; import android.view.View; Loading @@ -42,10 +40,12 @@ import androidx.appcompat.app.AlertDialog; import com.android.internal.net.VpnProfile; import com.android.net.module.util.ProxyUtils; import com.android.settings.R; import com.android.settings.utils.AndroidKeystoreAliasLoader; import java.net.InetAddress; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.List; /** Loading @@ -58,7 +58,7 @@ import java.util.List; class ConfigDialog extends AlertDialog implements TextWatcher, View.OnClickListener, AdapterView.OnItemSelectedListener, CompoundButton.OnCheckedChangeListener { private final KeyStore mKeyStore = KeyStore.getInstance(); private static final String TAG = "ConfigDialog"; private final DialogInterface.OnClickListener mListener; private final VpnProfile mProfile; Loading Loading @@ -153,10 +153,13 @@ class ConfigDialog extends AlertDialog implements TextWatcher, mL2tpSecret.setTextAppearance(android.R.style.TextAppearance_DeviceDefault_Medium); mIpsecIdentifier.setText(mProfile.ipsecIdentifier); mIpsecSecret.setText(mProfile.ipsecSecret); loadCertificates(mIpsecUserCert, Credentials.USER_PRIVATE_KEY, 0, mProfile.ipsecUserCert); loadCertificates(mIpsecCaCert, Credentials.CA_CERTIFICATE, AndroidKeystoreAliasLoader androidKeystoreAliasLoader = new AndroidKeystoreAliasLoader(null); loadCertificates(mIpsecUserCert, androidKeystoreAliasLoader.getKeyCertAliases(), 0, mProfile.ipsecUserCert); loadCertificates(mIpsecCaCert, androidKeystoreAliasLoader.getCaCertAliases(), R.string.vpn_no_ca_cert, mProfile.ipsecCaCert); loadCertificates(mIpsecServerCert, Credentials.USER_CERTIFICATE, loadCertificates(mIpsecServerCert, androidKeystoreAliasLoader.getKeyCertAliases(), R.string.vpn_no_server_cert, mProfile.ipsecServerCert); mSaveLogin.setChecked(mProfile.saveLogin); mAlwaysOnVpn.setChecked(mProfile.key.equals(VpnUtils.getLockdownVpn())); Loading Loading @@ -511,27 +514,30 @@ class ConfigDialog extends AlertDialog implements TextWatcher, typeSpinner.setAdapter(adapter); } private void loadCertificates(Spinner spinner, String prefix, int firstId, String selected) { private void loadCertificates(Spinner spinner, Collection<String> choices, int firstId, String selected) { Context context = getContext(); String first = (firstId == 0) ? "" : context.getString(firstId); String[] certificates = mKeyStore.list(prefix); String[] myChoices; if (certificates == null || certificates.length == 0) { certificates = new String[] {first}; if (choices == null || choices.size() == 0) { myChoices = new String[] {first}; } else { String[] array = new String[certificates.length + 1]; array[0] = first; System.arraycopy(certificates, 0, array, 1, certificates.length); certificates = array; myChoices = new String[choices.size() + 1]; myChoices[0] = first; int i = 1; for (String c : choices) { myChoices[i++] = c; } } ArrayAdapter<String> adapter = new ArrayAdapter<String>( context, android.R.layout.simple_spinner_item, certificates); context, android.R.layout.simple_spinner_item, myChoices); adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); spinner.setAdapter(adapter); for (int i = 1; i < certificates.length; ++i) { if (certificates[i].equals(selected)) { for (int i = 1; i < myChoices.length; ++i) { if (myChoices[i].equals(selected)) { spinner.setSelection(i); break; } Loading
src/com/android/settings/vpn2/ConfigDialogFragment.java +4 −6 Original line number Diff line number Diff line Loading @@ -25,7 +25,7 @@ import android.os.Bundle; import android.os.RemoteException; import android.os.UserHandle; import android.security.Credentials; import android.security.KeyStore; import android.security.LegacyVpnProfileStore; import android.util.Log; import android.view.View; import android.widget.Toast; Loading Loading @@ -151,9 +151,8 @@ public class ConfigDialogFragment extends InstrumentedDialogFragment implements return; } // Delete from KeyStore KeyStore keyStore = KeyStore.getInstance(); keyStore.delete(Credentials.VPN + profile.key, KeyStore.UID_SELF); // Delete from profile store. LegacyVpnProfileStore.remove(Credentials.VPN + profile.key); updateLockdownVpn(false, profile); } Loading Loading @@ -188,8 +187,7 @@ public class ConfigDialogFragment extends InstrumentedDialogFragment implements } private void save(VpnProfile profile, boolean lockdown) { KeyStore.getInstance().put(Credentials.VPN + profile.key, profile.encode(), KeyStore.UID_SELF, /* flags */ 0); LegacyVpnProfileStore.put(Credentials.VPN + profile.key, profile.encode()); // Flush out old version of profile disconnect(profile); Loading
src/com/android/settings/vpn2/VpnSettings.java +7 −9 Original line number Diff line number Diff line Loading @@ -41,7 +41,7 @@ import android.os.Message; import android.os.UserHandle; import android.os.UserManager; import android.security.Credentials; import android.security.KeyStore; import android.security.LegacyVpnProfileStore; import android.util.ArrayMap; import android.util.ArraySet; import android.util.Log; Loading @@ -57,7 +57,6 @@ import com.android.internal.annotations.GuardedBy; import com.android.internal.net.LegacyVpnInfo; import com.android.internal.net.VpnConfig; import com.android.internal.net.VpnProfile; import com.android.internal.util.ArrayUtils; import com.android.settings.R; import com.android.settings.RestrictedSettingsFragment; import com.android.settings.widget.GearPreference; Loading Loading @@ -94,8 +93,6 @@ public class VpnSettings extends RestrictedSettingsFragment implements private UserManager mUserManager; private VpnManager mVpnManager; private final KeyStore mKeyStore = KeyStore.getInstance(); private Map<String, LegacyVpnPreference> mLegacyVpnPreferences = new ArrayMap<>(); private Map<AppVpnInfo, AppPreference> mAppPreferences = new ArrayMap<>(); Loading Loading @@ -222,7 +219,7 @@ public class VpnSettings extends RestrictedSettingsFragment implements final Context context = activity.getApplicationContext(); // Run heavy RPCs before switching to UI thread final List<VpnProfile> vpnProfiles = loadVpnProfiles(mKeyStore); final List<VpnProfile> vpnProfiles = loadVpnProfiles(); final List<AppVpnInfo> vpnApps = getVpnApps(context, /* includeProfiles */ true); final Map<String, LegacyVpnInfo> connectedLegacyVpns = getConnectedLegacyVpns(); Loading Loading @@ -540,12 +537,13 @@ public class VpnSettings extends RestrictedSettingsFragment implements return result; } static List<VpnProfile> loadVpnProfiles(KeyStore keyStore, int... excludeTypes) { private static List<VpnProfile> loadVpnProfiles() { final ArrayList<VpnProfile> result = Lists.newArrayList(); for (String key : keyStore.list(Credentials.VPN)) { final VpnProfile profile = VpnProfile.decode(key, keyStore.get(Credentials.VPN + key)); if (profile != null && !ArrayUtils.contains(excludeTypes, profile.type)) { for (String key : LegacyVpnProfileStore.list(Credentials.VPN)) { final VpnProfile profile = VpnProfile.decode(key, LegacyVpnProfileStore.get(Credentials.VPN + key)); if (profile != null) { result.add(profile); } } Loading
src/com/android/settings/vpn2/VpnUtils.java +5 −7 Original line number Diff line number Diff line Loading @@ -20,7 +20,7 @@ import android.net.VpnManager; import android.os.RemoteException; import android.provider.Settings; import android.security.Credentials; import android.security.KeyStore; import android.security.LegacyVpnProfileStore; import com.android.internal.net.LegacyVpnInfo; import com.android.internal.net.VpnConfig; Loading @@ -28,27 +28,25 @@ import com.android.internal.net.VpnConfig; /** * Utility functions for vpn. * * Keystore methods should only be called in system user * LegacyVpnProfileStore methods should only be called in system user */ public class VpnUtils { private static final String TAG = "VpnUtils"; public static String getLockdownVpn() { final byte[] value = KeyStore.getInstance().get( Credentials.LOCKDOWN_VPN, true /* suppressKeyNotFoundWarning */); final byte[] value = LegacyVpnProfileStore.get(Credentials.LOCKDOWN_VPN); return value == null ? null : new String(value); } public static void clearLockdownVpn(Context context) { KeyStore.getInstance().delete(Credentials.LOCKDOWN_VPN); LegacyVpnProfileStore.remove(Credentials.LOCKDOWN_VPN); // Always notify VpnManager after keystore update getVpnManager(context).updateLockdownVpn(); } public static void setLockdownVpn(Context context, String lockdownKey) { KeyStore.getInstance().put(Credentials.LOCKDOWN_VPN, lockdownKey.getBytes(), KeyStore.UID_SELF, /* flags */ 0); LegacyVpnProfileStore.put(Credentials.LOCKDOWN_VPN, lockdownKey.getBytes()); // Always notify VpnManager after keystore update getVpnManager(context).updateLockdownVpn(); } Loading