Allow trusted system certificates to be used in EAP network configs
am: 2b16cd3920
* commit '2b16cd3920f95b2cd5c2426d81b5e1584ffc682d':
Allow trusted system certificates to be used in EAP network configs
diff --git a/res/layout/wifi_dialog.xml b/res/layout/wifi_dialog.xml
index 05c33d7..44523f4 100644
--- a/res/layout/wifi_dialog.xml
+++ b/res/layout/wifi_dialog.xml
@@ -175,6 +175,18 @@
android:inputType="textNoSuggestions" />
</LinearLayout>
+ <LinearLayout android:id="@+id/no_domain_warning"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:visibility="gone"
+ style="@style/wifi_item" >
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ style="@style/wifi_item_warning"
+ android:text="@string/wifi_no_domain_warning" />
+ </LinearLayout>
+
<LinearLayout android:id="@+id/l_user_cert"
android:layout_width="match_parent"
android:layout_height="wrap_content"
diff --git a/res/values/strings.xml b/res/values/strings.xml
index c0b0650..5d093f1 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -1644,12 +1644,17 @@
<string name="wifi_unspecified">Please select</string>
<!-- Hint for multiple certificates being added to the configuration -->
<string name="wifi_multiple_cert_added">(Multiple certificates added)</string>
+ <!-- Menu option for using trusted system CA certificates to validate EAP servers -->
+ <string name="wifi_use_system_certs">Use system certificates</string>
<!-- Menu option for not providing an EAP user certificate -->
<string name="wifi_do_not_provide_eap_user_cert">Do not provide</string>
<!-- Menu option for not validating the EAP server -->
<string name="wifi_do_not_validate_eap_server">Do not validate</string>
<!-- Warning message displayed if user choses not to validate the EAP server -->
<string name="wifi_do_not_validate_eap_server_warning">No certificate specified. Your connection will not be private.</string>
+ <!-- Warning message displayed if user does not specify a domain for the CA certificate.
+ Only displayed if the user also chooses to use system certificates. -->
+ <string name="wifi_no_domain_warning">Must specify a domain.</string>
<!-- Substring of status line when Wi-Fi Protected Setup (WPS) is available and
string is listed first [CHAR LIMIT=20]-->
<string name="wifi_wps_available_first_item">WPS available</string>
diff --git a/src/com/android/settings/wifi/WifiConfigController.java b/src/com/android/settings/wifi/WifiConfigController.java
index e0079cb..fbdc4bf 100644
--- a/src/com/android/settings/wifi/WifiConfigController.java
+++ b/src/com/android/settings/wifi/WifiConfigController.java
@@ -77,6 +77,8 @@
TextView.OnEditorActionListener, View.OnKeyListener{
private static final String TAG = "WifiConfigController";
+ private static final String SYSTEM_CA_STORE_PATH = "/system/etc/security/cacerts";
+
private final WifiConfigUiBase mConfigUi;
private final View mView;
private final AccessPoint mAccessPoint;
@@ -117,10 +119,7 @@
private String mUnspecifiedCertString;
private String mMultipleCertSetString;
- private static final int UNSPECIFIED_CERT_INDEX = 0;
- private static final int NO_CERT_INDEX = 1;
- private static final int MULTIPLE_CERT_SET_INDEX = 2;
-
+ private String mUseSystemCertsString;
private String mDoNotProvideEapUserCertString;
private String mDoNotValidateEapServerString;
@@ -188,6 +187,7 @@
mUnspecifiedCertString = mContext.getString(R.string.wifi_unspecified);
mMultipleCertSetString = mContext.getString(R.string.wifi_multiple_cert_added);
+ mUseSystemCertsString = mContext.getString(R.string.wifi_use_system_certs);
mDoNotProvideEapUserCertString =
mContext.getString(R.string.wifi_do_not_provide_eap_user_cert);
mDoNotValidateEapServerString =
@@ -397,28 +397,54 @@
enabled = ipAndProxyFieldsAreValid();
}
if (mEapCaCertSpinner != null
- && mView.findViewById(R.id.l_ca_cert).getVisibility() != View.GONE
- && ((String) mEapCaCertSpinner.getSelectedItem()).equals(mUnspecifiedCertString)) {
- enabled = false;
+ && mView.findViewById(R.id.l_ca_cert).getVisibility() != View.GONE) {
+ String caCertSelection = (String) mEapCaCertSpinner.getSelectedItem();
+ if (caCertSelection.equals(mUnspecifiedCertString)) {
+ // Disallow submit if the user has not selected a CA certificate for an EAP network
+ // configuration.
+ enabled = false;
+ }
+ if (caCertSelection.equals(mUseSystemCertsString)
+ && mEapDomainView != null
+ && mView.findViewById(R.id.l_domain).getVisibility() != View.GONE
+ && TextUtils.isEmpty(mEapDomainView.getText().toString())) {
+ // Disallow submit if the user chooses to use system certificates for EAP server
+ // validation, but does not provide a domain.
+ enabled = false;
+ }
}
if (mEapUserCertSpinner != null
&& mView.findViewById(R.id.l_user_cert).getVisibility() != View.GONE
&& ((String) mEapUserCertSpinner.getSelectedItem())
.equals(mUnspecifiedCertString)) {
+ // Disallow submit if the user has not selected a user certificate for an EAP network
+ // configuration.
enabled = false;
}
return enabled;
}
- void showWarningMessageIfAppropriate() {
+ void showWarningMessagesIfAppropriate() {
mView.findViewById(R.id.no_ca_cert_warning).setVisibility(View.GONE);
+ mView.findViewById(R.id.no_domain_warning).setVisibility(View.GONE);
+
if (mEapCaCertSpinner != null
- && mView.findViewById(R.id.l_ca_cert).getVisibility() != View.GONE
- && ((String) mEapCaCertSpinner.getSelectedItem())
- .equals(mDoNotValidateEapServerString)) {
- // Display warning if user chooses not to validate the EAP server with a user-supplied
- // CA certificate in an EAP network configuration.
- mView.findViewById(R.id.no_ca_cert_warning).setVisibility(View.VISIBLE);
+ && mView.findViewById(R.id.l_ca_cert).getVisibility() != View.GONE) {
+ String caCertSelection = (String) mEapCaCertSpinner.getSelectedItem();
+ if (caCertSelection.equals(mDoNotValidateEapServerString)) {
+ // Display warning if user chooses not to validate the EAP server with a
+ // user-supplied CA certificate in an EAP network configuration.
+ mView.findViewById(R.id.no_ca_cert_warning).setVisibility(View.VISIBLE);
+ }
+ if (caCertSelection.equals(mUseSystemCertsString)
+ && mEapDomainView != null
+ && mView.findViewById(R.id.l_domain).getVisibility() != View.GONE
+ && TextUtils.isEmpty(mEapDomainView.getText().toString())) {
+ // Display warning if user chooses to use pre-installed public CA certificates
+ // without restricting the server domain that these certificates can be used to
+ // validate.
+ mView.findViewById(R.id.no_domain_warning).setVisibility(View.VISIBLE);
+ }
}
}
@@ -518,7 +544,9 @@
} else {
config.enterpriseConfig.setDomainSuffixMatch(
mEapDomainView.getText().toString());
- if (caCert.equals(mMultipleCertSetString)) {
+ if (caCert.equals(mUseSystemCertsString)) {
+ config.enterpriseConfig.setCaPath(SYSTEM_CA_STORE_PATH);
+ } else if (caCert.equals(mMultipleCertSetString)) {
if (mAccessPoint != null) {
if (!mAccessPoint.isSaved()) {
Log.e(TAG, "Multiple certs can only be set "
@@ -745,15 +773,24 @@
mEapCaCertSpinner = (Spinner) mView.findViewById(R.id.ca_cert);
mEapCaCertSpinner.setOnItemSelectedListener(this);
mEapDomainView = (TextView) mView.findViewById(R.id.domain);
+ mEapDomainView.addTextChangedListener(this);
mEapUserCertSpinner = (Spinner) mView.findViewById(R.id.user_cert);
mEapUserCertSpinner.setOnItemSelectedListener(this);
mEapIdentityView = (TextView) mView.findViewById(R.id.identity);
mEapAnonymousView = (TextView) mView.findViewById(R.id.anonymous);
- loadCertificates(mEapCaCertSpinner, Credentials.CA_CERTIFICATE, false,
- mDoNotValidateEapServerString);
- loadCertificates(mEapUserCertSpinner, Credentials.USER_PRIVATE_KEY, false,
- mDoNotProvideEapUserCertString);
+ loadCertificates(
+ mEapCaCertSpinner,
+ Credentials.CA_CERTIFICATE,
+ mDoNotValidateEapServerString,
+ false,
+ true);
+ loadCertificates(
+ mEapUserCertSpinner,
+ Credentials.USER_PRIVATE_KEY,
+ mDoNotProvideEapUserCertString,
+ false,
+ false);
// Modifying an existing network
if (mAccessPoint != null && mAccessPoint.isSaved()) {
@@ -783,16 +820,24 @@
mPhase2Spinner.setSelection(phase2Method);
break;
}
- String[] caCerts = enterpriseConfig.getCaCertificateAliases();
- if (caCerts == null) {
- setSelection(mEapCaCertSpinner, mDoNotValidateEapServerString);
- } else if (caCerts.length == 1) {
- setSelection(mEapCaCertSpinner, caCerts[0]);
+ if (!TextUtils.isEmpty(enterpriseConfig.getCaPath())) {
+ setSelection(mEapCaCertSpinner, mUseSystemCertsString);
} else {
- // Reload the cert spinner with an extra "multiple certificates added" item
- loadCertificates(mEapCaCertSpinner,
- Credentials.CA_CERTIFICATE, true, mDoNotValidateEapServerString);
- mEapCaCertSpinner.setSelection(MULTIPLE_CERT_SET_INDEX);
+ String[] caCerts = enterpriseConfig.getCaCertificateAliases();
+ if (caCerts == null) {
+ setSelection(mEapCaCertSpinner, mDoNotValidateEapServerString);
+ } else if (caCerts.length == 1) {
+ setSelection(mEapCaCertSpinner, caCerts[0]);
+ } else {
+ // Reload the cert spinner with an extra "multiple certificates added" item.
+ loadCertificates(
+ mEapCaCertSpinner,
+ Credentials.CA_CERTIFICATE,
+ mDoNotValidateEapServerString,
+ true,
+ true);
+ setSelection(mEapCaCertSpinner, mMultipleCertSetString);
+ }
}
mEapDomainView.setText(enterpriseConfig.getDomainSuffixMatch());
String userCert = enterpriseConfig.getClientCertificateAlias();
@@ -916,7 +961,7 @@
private void setCaCertInvisible() {
mView.findViewById(R.id.l_ca_cert).setVisibility(View.GONE);
- mEapCaCertSpinner.setSelection(UNSPECIFIED_CERT_INDEX);
+ setSelection(mEapCaCertSpinner, mUnspecifiedCertString);
}
private void setDomainInvisible() {
@@ -926,7 +971,7 @@
private void setUserCertInvisible() {
mView.findViewById(R.id.l_user_cert).setVisibility(View.GONE);
- mEapUserCertSpinner.setSelection(UNSPECIFIED_CERT_INDEX);
+ setSelection(mEapUserCertSpinner, mUnspecifiedCertString);
}
private void setAnonymousIdentInvisible() {
@@ -1051,17 +1096,24 @@
}
private void loadCertificates(
- Spinner spinner, String prefix, boolean showMultipleCerts, String noCertificateString) {
+ Spinner spinner,
+ String prefix,
+ String noCertificateString,
+ boolean showMultipleCerts,
+ boolean showUsePreinstalledCertOption) {
final Context context = mConfigUi.getContext();
ArrayList<String> certs = new ArrayList<String>();
- certs.add(UNSPECIFIED_CERT_INDEX, mUnspecifiedCertString);
- certs.add(NO_CERT_INDEX, noCertificateString);
+ certs.add(mUnspecifiedCertString);
if (showMultipleCerts) {
- certs.add(MULTIPLE_CERT_SET_INDEX, mMultipleCertSetString);
+ certs.add(mMultipleCertSetString);
+ }
+ if (showUsePreinstalledCertOption) {
+ certs.add(mUseSystemCertsString);
}
certs.addAll(
Arrays.asList(KeyStore.getInstance().list(prefix, android.os.Process.WIFI_UID)));
+ certs.add(noCertificateString);
final ArrayAdapter<String> adapter = new ArrayAdapter<String>(
context, android.R.layout.simple_spinner_item,
@@ -1091,6 +1143,7 @@
public void afterTextChanged(Editable s) {
mTextViewChangedHandler.post(new Runnable() {
public void run() {
+ showWarningMessagesIfAppropriate();
enableSubmitIfAppropriate();
}
});
@@ -1159,7 +1212,7 @@
} else {
showIpConfigFields();
}
- showWarningMessageIfAppropriate();
+ showWarningMessagesIfAppropriate();
enableSubmitIfAppropriate();
}