summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVictor Chang <vichang@google.com>2016-04-13 20:28:23 +0100
committerVictor Chang <vichang@google.com>2016-04-14 19:42:14 +0100
commit38856d6bd1acc648b18aceb9af4d68e25f314fb6 (patch)
tree54c609e7c9f694bf66fc4d59890f75a8900f3da9
parent5e8156f9c9ed774b570154b0bb61a9e543ba8c3d (diff)
downloadandroid_packages_apps_CertInstaller-38856d6bd1acc648b18aceb9af4d68e25f314fb6.tar.gz
android_packages_apps_CertInstaller-38856d6bd1acc648b18aceb9af4d68e25f314fb6.tar.bz2
android_packages_apps_CertInstaller-38856d6bd1acc648b18aceb9af4d68e25f314fb6.zip
Approve CA certs automatically in CertInstaller
- Since the cert is installed by real user, the cert is approved by the user - It avoids cert pending approval notification posted by DPM - Also, show screenlock only it has ca certs Test: - if no screenlock, it doesn't ask user to unlock. User will be asked to set a screenlock after naming the cert - work chanllenge is shown if the cert is installed from work profile Bug: 28161447 Change-Id: I3eea305fc6d8023f7a30a1644b7b0c2a873a3b75
-rw-r--r--Android.mk2
-rw-r--r--AndroidManifest.xml1
-rw-r--r--src/com/android/certinstaller/CertInstaller.java52
-rw-r--r--src/com/android/certinstaller/CredentialHelper.java19
-rw-r--r--src/com/android/certinstaller/Util.java2
5 files changed, 59 insertions, 17 deletions
diff --git a/Android.mk b/Android.mk
index 98b6641..a5face5 100644
--- a/Android.mk
+++ b/Android.mk
@@ -4,7 +4,7 @@ include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := $(call all-java-files-under, src)
-LOCAL_JAVA_LIBRARIES := bouncycastle
+LOCAL_JAVA_LIBRARIES := bouncycastle conscrypt
LOCAL_PACKAGE_NAME := CertInstaller
LOCAL_CERTIFICATE := platform
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index cc02a95..03291ae 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -7,6 +7,7 @@
android:protectionLevel="signature" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
+ <uses-permission android:name="android.permission.MANAGE_USERS" />
<application android:label="@string/app_name"
android:allowBackup="false">
diff --git a/src/com/android/certinstaller/CertInstaller.java b/src/com/android/certinstaller/CertInstaller.java
index fedbadf..b4850d0 100644
--- a/src/com/android/certinstaller/CertInstaller.java
+++ b/src/com/android/certinstaller/CertInstaller.java
@@ -19,6 +19,7 @@ package com.android.certinstaller;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
+import android.app.KeyguardManager;
import android.app.ProgressDialog;
import android.content.ActivityNotFoundException;
import android.content.Context;
@@ -61,6 +62,7 @@ public class CertInstaller extends Activity {
private static final int PROGRESS_BAR_DIALOG = 3;
private static final int REQUEST_SYSTEM_INSTALL_CODE = 1;
+ private static final int REQUEST_CONFIRM_CREDENTIALS = 2;
// key to states Bundle
private static final String NEXT_ACTION_KEY = "na";
@@ -101,19 +103,17 @@ public class CertInstaller extends Activity {
if (!mCredentials.containsAnyRawData()) {
toastErrorAndFinish(R.string.no_cert_to_saved);
finish();
- } else if (mCredentials.hasPkcs12KeyStore()) {
- if (mCredentials.hasPassword()) {
- showDialog(PKCS12_PASSWORD_DIALOG);
- } else {
- new Pkcs12ExtractAction("").run(this);
- }
} else {
- MyAction action = new InstallOthersAction();
- if (needsKeyStoreAccess()) {
- sendUnlockKeyStoreIntent();
- mNextAction = action;
+ if (mCredentials.hasCaCerts()) {
+ KeyguardManager keyguardManager = getSystemService(KeyguardManager.class);
+ Intent intent = keyguardManager.createConfirmDeviceCredentialIntent(null, null);
+ if (intent == null) { // No screenlock
+ onScreenlockOk();
+ } else {
+ startActivityForResult(intent, REQUEST_CONFIRM_CREDENTIALS);
+ }
} else {
- action.run(this);
+ onScreenlockOk();
}
}
} else {
@@ -182,8 +182,8 @@ public class CertInstaller extends Activity {
if (requestCode == REQUEST_SYSTEM_INSTALL_CODE) {
if (resultCode == RESULT_OK) {
Log.d(TAG, "credential is added: " + mCredentials.getName());
- Toast.makeText(this, getString(R.string.cert_is_added,
- mCredentials.getName()), Toast.LENGTH_LONG).show();
+ Toast.makeText(this, getString(R.string.cert_is_added, mCredentials.getName()),
+ Toast.LENGTH_LONG).show();
if (mCredentials.includesVpnAndAppsTrustAnchors()) {
// more work to do, don't finish just yet
@@ -195,19 +195,43 @@ public class CertInstaller extends Activity {
Log.d(TAG, "credential not saved, err: " + resultCode);
toastErrorAndFinish(R.string.cert_not_saved);
}
+ } else if (requestCode == REQUEST_CONFIRM_CREDENTIALS) {
+ if (resultCode == RESULT_OK) {
+ onScreenlockOk();
+ return;
+ }
+ // Fail to confirm credentials. Let it finish
} else {
Log.w(TAG, "unknown request code: " + requestCode);
}
finish();
}
+ private void onScreenlockOk() {
+ if (mCredentials.hasPkcs12KeyStore()) {
+ if (mCredentials.hasPassword()) {
+ showDialog(PKCS12_PASSWORD_DIALOG);
+ } else {
+ new Pkcs12ExtractAction("").run(this);
+ }
+ } else {
+ MyAction action = new InstallOthersAction();
+ if (needsKeyStoreAccess()) {
+ sendUnlockKeyStoreIntent();
+ mNextAction = action;
+ } else {
+ action.run(this);
+ }
+ }
+ }
+
private class InstallVpnAndAppsTrustAnchorsTask extends AsyncTask<Void, Void, Boolean> {
@Override protected Boolean doInBackground(Void... unused) {
try {
KeyChainConnection keyChainConnection = KeyChain.bind(CertInstaller.this);
try {
- return mCredentials.installVpnAndAppsTrustAnchors(
+ return mCredentials.installVpnAndAppsTrustAnchors(CertInstaller.this,
keyChainConnection.getService());
} finally {
keyChainConnection.close();
diff --git a/src/com/android/certinstaller/CredentialHelper.java b/src/com/android/certinstaller/CredentialHelper.java
index 55447f3..3285a36 100644
--- a/src/com/android/certinstaller/CredentialHelper.java
+++ b/src/com/android/certinstaller/CredentialHelper.java
@@ -16,11 +16,13 @@
package com.android.certinstaller;
+import android.app.admin.DevicePolicyManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.RemoteException;
+import android.os.UserHandle;
import android.security.Credentials;
import android.security.KeyChain;
import android.security.IKeyChainService;
@@ -31,6 +33,8 @@ 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 com.android.org.conscrypt.TrustedCertificateStore;
+
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.security.KeyFactory;
@@ -268,7 +272,7 @@ class CredentialHelper {
// To prevent the private key from being sniffed, we explicitly spell
// out the intent receiver class.
if (!isWear(context)) {
- intent.setClassName("com.android.settings", "com.android.settings.CredentialStorage");
+ intent.setClassName(Util.SETTINGS_PACKAGE, "com.android.settings.CredentialStorage");
} else {
intent.setClassName("com.google.android.apps.wearable.settings",
"com.google.android.clockwork.settings.CredentialStorage");
@@ -303,7 +307,9 @@ class CredentialHelper {
}
}
- boolean installVpnAndAppsTrustAnchors(IKeyChainService keyChainService) {
+ boolean installVpnAndAppsTrustAnchors(Context context, IKeyChainService keyChainService) {
+ final TrustedCertificateStore trustedCertificateStore = new TrustedCertificateStore();
+ final DevicePolicyManager dpm = context.getSystemService(DevicePolicyManager.class);
for (X509Certificate caCert : mCaCerts) {
byte[] bytes = null;
try {
@@ -318,6 +324,15 @@ class CredentialHelper {
Log.w(TAG, "installCaCertsToKeyChain(): " + e);
return false;
}
+
+ String alias = trustedCertificateStore.getCertificateAlias(caCert);
+ if (alias == null) {
+ Log.e(TAG, "alias is null");
+ return false;
+ }
+
+ // Since the cert is installed by real user, the cert is approved by the user
+ dpm.approveCaCert(alias, UserHandle.myUserId(), true);
}
}
return true;
diff --git a/src/com/android/certinstaller/Util.java b/src/com/android/certinstaller/Util.java
index 00c14c4..6178c3c 100644
--- a/src/com/android/certinstaller/Util.java
+++ b/src/com/android/certinstaller/Util.java
@@ -30,6 +30,8 @@ import java.security.NoSuchAlgorithmException;
class Util {
private static final String TAG = "certinstaller.Util";
+ public static final String SETTINGS_PACKAGE = "com.android.settings";
+
static byte[] toBytes(Object object) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {