diff options
author | Victor Chang <vichang@google.com> | 2016-04-13 20:28:23 +0100 |
---|---|---|
committer | Victor Chang <vichang@google.com> | 2016-04-14 19:42:14 +0100 |
commit | 38856d6bd1acc648b18aceb9af4d68e25f314fb6 (patch) | |
tree | 54c609e7c9f694bf66fc4d59890f75a8900f3da9 | |
parent | 5e8156f9c9ed774b570154b0bb61a9e543ba8c3d (diff) | |
download | android_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.mk | 2 | ||||
-rw-r--r-- | AndroidManifest.xml | 1 | ||||
-rw-r--r-- | src/com/android/certinstaller/CertInstaller.java | 52 | ||||
-rw-r--r-- | src/com/android/certinstaller/CredentialHelper.java | 19 | ||||
-rw-r--r-- | src/com/android/certinstaller/Util.java | 2 |
5 files changed, 59 insertions, 17 deletions
@@ -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 { |