summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKenny Root <kroot@google.com>2013-03-28 11:08:18 -0700
committerKenny Root <kroot@google.com>2013-03-28 11:31:20 -0700
commit53622fc40b88047a1bc1f2dd6c97a5ad8e8c8f66 (patch)
treead4b58f76e97d239f1dd80f34da0230ede54b92d
parentefe0f3ecda4aab3d3d95ce177b6dfd6f6aa26165 (diff)
downloadCertInstaller-53622fc40b88047a1bc1f2dd6c97a5ad8e8c8f66.tar.gz
Add ability to install credentials as other UID
We need the ability to install from the system UID to wifi UID to explicitly bind WiFi credentials to the WiFi profile. This adds the ability for Wifi Settings to invoke installation of a PKCS12 file for the wifi UID. Bug: 8183258 Change-Id: I26970e563d68311b60dcdc78cd529322c5807368
-rw-r--r--AndroidManifest.xml12
-rw-r--r--src/com/android/certinstaller/CertFile.java19
-rw-r--r--src/com/android/certinstaller/CertFileList.java1
-rw-r--r--src/com/android/certinstaller/CertInstallerMain.java18
-rw-r--r--src/com/android/certinstaller/CredentialHelper.java5
5 files changed, 48 insertions, 7 deletions
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 031cc72..b2880d6 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -5,6 +5,9 @@
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+ <permission android:name="com.android.certinstaller.INSTALL_AS_USER"
+ android:protectionLevel="signature" />
+
<application android:label="@string/app_name"
android:allowBackup="false">
<activity android:name=".CertInstallerMain"
@@ -23,6 +26,15 @@
</intent-filter>
</activity>
+ <activity-alias android:name=".InstallCertAsUser"
+ android:targetActivity=".CertInstallerMain"
+ android:permission="com.android.certinstaller.INSTALL_AS_USER">
+ <intent-filter>
+ <action android:name="android.credentials.INSTALL_AS_USER" />
+ <category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
+ </activity-alias>
+
<activity android:name=".CertInstaller"
android:theme="@style/Transparent"
android:configChanges="orientation|keyboardHidden"
diff --git a/src/com/android/certinstaller/CertFile.java b/src/com/android/certinstaller/CertFile.java
index 401c1a3..5b4bfbf 100644
--- a/src/com/android/certinstaller/CertFile.java
+++ b/src/com/android/certinstaller/CertFile.java
@@ -131,9 +131,17 @@ public class CertFile extends PreferenceActivity implements FileFilter {
String fileName = file.getName();
Bundle bundle = getIntent().getExtras();
- String name = ((bundle == null)
- ? fileName
- : bundle.getString(KeyChain.EXTRA_NAME, fileName));
+
+ final String name;
+ final int installAsUid;
+ if (bundle == null) {
+ name = fileName;
+ installAsUid = -1;
+ } else {
+ name = bundle.getString(KeyChain.EXTRA_NAME, fileName);
+ installAsUid = bundle.getInt(Credentials.EXTRA_INSTALL_AS_UID, -1);
+ }
+
if (file.exists()) {
if (file.length() < MAX_FILE_SIZE) {
byte[] data = Util.readFile(file);
@@ -143,7 +151,7 @@ public class CertFile extends PreferenceActivity implements FileFilter {
return;
}
mCertFile = file;
- install(fileName, name, data);
+ install(fileName, name, installAsUid, data);
} else {
Log.w(TAG, "cert file is too large: " + file.length());
toastError(CERT_TOO_LARGE_ERROR);
@@ -176,9 +184,10 @@ public class CertFile extends PreferenceActivity implements FileFilter {
Environment.MEDIA_MOUNTED);
}
- private void install(String fileName, String name, byte[] value) {
+ private void install(String fileName, String name, int uid, byte[] value) {
Intent intent = new Intent(this, CertInstaller.class);
intent.putExtra(KeyChain.EXTRA_NAME, name);
+ intent.putExtra(Credentials.EXTRA_INSTALL_AS_UID, uid);
if (fileName.endsWith(Credentials.EXTENSION_PFX)
|| fileName.endsWith(Credentials.EXTENSION_P12)) {
intent.putExtra(KeyChain.EXTRA_PKCS12, value);
diff --git a/src/com/android/certinstaller/CertFileList.java b/src/com/android/certinstaller/CertFileList.java
index 5e2b681..1d32c26 100644
--- a/src/com/android/certinstaller/CertFileList.java
+++ b/src/com/android/certinstaller/CertFileList.java
@@ -21,6 +21,7 @@ import android.os.Environment;
import android.os.FileObserver;
import android.preference.Preference;
import android.preference.PreferenceScreen;
+import android.security.Credentials;
import android.util.Log;
import android.widget.Toast;
diff --git a/src/com/android/certinstaller/CertInstallerMain.java b/src/com/android/certinstaller/CertInstallerMain.java
index 7d7ed6e..9b10c07 100644
--- a/src/com/android/certinstaller/CertInstallerMain.java
+++ b/src/com/android/certinstaller/CertInstallerMain.java
@@ -60,14 +60,28 @@ public class CertInstallerMain extends CertFile implements Runnable {
Intent intent = getIntent();
String action = (intent == null) ? null : intent.getAction();
- if (Credentials.INSTALL_ACTION.equals(action)) {
+ if (Credentials.INSTALL_ACTION.equals(action)
+ || Credentials.INSTALL_AS_USER_ACTION.equals(action)) {
Bundle bundle = intent.getExtras();
+
+ /*
+ * There is a special INSTALL_AS_USER action that this activity is
+ * aliased to, but you have to have a permission to call it. If the
+ * caller got here any other way, remove the extra that we allow in
+ * that INSTALL_AS_USER path.
+ */
+ if (bundle != null && !Credentials.INSTALL_AS_USER_ACTION.equals(action)) {
+ bundle.remove(Credentials.EXTRA_INSTALL_AS_UID);
+ }
+
// If bundle is empty of any actual credentials, install from external storage.
// Otherwise, pass extras to CertInstaller to install those credentials.
// Either way, we use KeyChain.EXTRA_NAME as the default name if available.
if (bundle == null
|| bundle.isEmpty()
- || (bundle.size() == 1 && bundle.containsKey(KeyChain.EXTRA_NAME))) {
+ || (bundle.size() == 1
+ && (bundle.containsKey(KeyChain.EXTRA_NAME)
+ || bundle.containsKey(Credentials.EXTRA_INSTALL_AS_UID)))) {
if (!isSdCardPresent()) {
Toast.makeText(this, R.string.sdcard_not_present,
Toast.LENGTH_SHORT).show();
diff --git a/src/com/android/certinstaller/CredentialHelper.java b/src/com/android/certinstaller/CredentialHelper.java
index f9c35eb..5f59387 100644
--- a/src/com/android/certinstaller/CredentialHelper.java
+++ b/src/com/android/certinstaller/CredentialHelper.java
@@ -64,6 +64,7 @@ class CredentialHelper {
private HashMap<String, byte[]> mBundle = new HashMap<String, byte[]>();
private String mName = "";
+ private int mUid = -1;
private PrivateKey mUserKey;
private X509Certificate mUserCert;
private List<X509Certificate> mCaCerts = new ArrayList<X509Certificate>();
@@ -83,6 +84,9 @@ class CredentialHelper {
mName = name;
}
+ mUid = bundle.getInt(Credentials.EXTRA_INSTALL_AS_UID, -1);
+ bundle.remove(Credentials.EXTRA_INSTALL_AS_UID);
+
Log.d(TAG, "# extras: " + bundle.size());
for (String key : bundle.keySet()) {
byte[] bytes = bundle.getByteArray(key);
@@ -249,6 +253,7 @@ class CredentialHelper {
// To prevent the private key from being sniffed, we explicitly spell
// out the intent receiver class.
intent.setClassName("com.android.settings", "com.android.settings.CredentialStorage");
+ intent.putExtra(Credentials.EXTRA_INSTALL_AS_UID, mUid);
try {
if (mUserKey != null) {
intent.putExtra(Credentials.EXTRA_USER_PRIVATE_KEY_NAME,