summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/java/android/content/pm/PackageParser.java24
-rw-r--r--core/res/res/values/attrs_manifest.xml6
-rw-r--r--core/tests/coretests/apks/keyset/Android.mk91
-rw-r--r--core/tests/coretests/apks/keyset/permDef/AndroidManifest.xml24
-rw-r--r--core/tests/coretests/apks/keyset/permUse/AndroidManifest.xml31
-rw-r--r--core/tests/coretests/apks/keyset/res/values/strings.xml8
-rw-r--r--core/tests/coretests/apks/keyset/uA/AndroidManifest.xml26
-rw-r--r--core/tests/coretests/apks/keyset/uAB/AndroidManifest.xml29
-rw-r--r--core/tests/coretests/apks/keyset/uAuB/AndroidManifest.xml30
-rw-r--r--core/tests/coretests/apks/keyset/uB/AndroidManifest.xml26
-rw-r--r--core/tests/coretests/apks/keyset/uNone/AndroidManifest.xml20
-rw-r--r--core/tests/coretests/certs/keyset_A.pk8bin0 -> 344 bytes
-rw-r--r--core/tests/coretests/certs/keyset_A.x509.pem14
-rw-r--r--core/tests/coretests/certs/keyset_B.pk8bin0 -> 345 bytes
-rw-r--r--core/tests/coretests/certs/keyset_B.x509.pem14
-rw-r--r--core/tests/coretests/src/android/content/pm/PackageManagerTests.java259
16 files changed, 596 insertions, 6 deletions
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index b40a441..f176dfb 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -828,8 +828,8 @@ public class PackageParser {
if (pkg.mCertificates == null) {
pkg.mCertificates = entryCerts;
pkg.mSignatures = convertToSignatures(entryCerts);
- pkg.mSigningKeys = new ArraySet<>();
- for (int i = 0; i < entryCerts.length; i++) {
+ pkg.mSigningKeys = new ArraySet<PublicKey>();
+ for (int i=0; i < entryCerts.length; i++) {
pkg.mSigningKeys.add(entryCerts[i][0].getPublicKey());
}
} else {
@@ -1222,6 +1222,17 @@ public class PackageParser {
if (parsePermissionTree(pkg, res, parser, attrs, outError) == null) {
return null;
}
+ } else if (tagName.equals("upgrade-keyset")) {
+ sa = res.obtainAttributes(attrs,
+ com.android.internal.R.styleable.AndroidManifestUpgradeKeySet);
+ String name = sa.getNonResourceString(
+ com.android.internal.R.styleable.AndroidManifestUpgradeKeySet_name);
+ sa.recycle();
+ if (pkg.mUpgradeKeySets == null) {
+ pkg.mUpgradeKeySets = new ArraySet<String>();
+ }
+ pkg.mUpgradeKeySets.add(name);
+ XmlUtils.skipCurrentTag(parser);
} else if (tagName.equals("uses-permission")) {
if (!parseUsesPermission(pkg, res, parser, attrs, outError)) {
return null;
@@ -1795,7 +1806,7 @@ public class PackageParser {
}
}
- owner.mKeySetMapping = new ArrayMap<String, ArraySet<PublicKey>>();
+ owner.mKeySetMapping = new ArrayMap<String, Set<PublicKey>>();
for (Map.Entry<PublicKey, Set<String>> e : definedKeySets.entrySet()) {
PublicKey key = e.getKey();
Set<String> keySetNames = e.getValue();
@@ -1803,7 +1814,7 @@ public class PackageParser {
if (owner.mKeySetMapping.containsKey(alias)) {
owner.mKeySetMapping.get(alias).add(key);
} else {
- ArraySet<PublicKey> keys = new ArraySet<PublicKey>();
+ Set<PublicKey> keys = new ArraySet<PublicKey>();
keys.add(key);
owner.mKeySetMapping.put(alias, keys);
}
@@ -3795,8 +3806,9 @@ public class PackageParser {
/**
* Data used to feed the KeySetManager
*/
- public ArraySet<PublicKey> mSigningKeys;
- public ArrayMap<String, ArraySet<PublicKey>> mKeySetMapping;
+ public Set<PublicKey> mSigningKeys;
+ public Set<String> mUpgradeKeySets;
+ public Map<String, Set<PublicKey>> mKeySetMapping;
public Package(String packageName) {
this.packageName = packageName;
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index fc1d0df..afaf2e9 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -2019,4 +2019,10 @@
<declare-styleable name="KeySet">
<attr name="name" />
</declare-styleable>
+
+ <!-- Associate declared KeySets with upgrading capability -->
+ <declare-styleable name="AndroidManifestUpgradeKeySet" parent="AndroidManifest">
+ <attr name="name" />
+ </declare-styleable>
+
</resources>
diff --git a/core/tests/coretests/apks/keyset/Android.mk b/core/tests/coretests/apks/keyset/Android.mk
new file mode 100644
index 0000000..e44ac6c
--- /dev/null
+++ b/core/tests/coretests/apks/keyset/Android.mk
@@ -0,0 +1,91 @@
+LOCAL_PATH:= $(call my-dir)
+
+#apks signed by keyset_A
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+LOCAL_PACKAGE_NAME := keyset_sa_unone
+LOCAL_CERTIFICATE := $(LOCAL_PATH)/../../certs/keyset_A
+LOCAL_MANIFEST_FILE := uNone/AndroidManifest.xml
+include $(FrameworkCoreTests_BUILD_PACKAGE)
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+LOCAL_PACKAGE_NAME := keyset_sa_ua
+LOCAL_CERTIFICATE := $(LOCAL_PATH)/../../certs/keyset_A
+LOCAL_MANIFEST_FILE := uA/AndroidManifest.xml
+include $(FrameworkCoreTests_BUILD_PACKAGE)
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+LOCAL_PACKAGE_NAME := keyset_sa_ub
+LOCAL_CERTIFICATE := $(LOCAL_PATH)/../../certs/keyset_A
+LOCAL_MANIFEST_FILE := uB/AndroidManifest.xml
+include $(FrameworkCoreTests_BUILD_PACKAGE)
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+LOCAL_PACKAGE_NAME := keyset_sa_uab
+LOCAL_CERTIFICATE := $(LOCAL_PATH)/../../certs/keyset_A
+LOCAL_MANIFEST_FILE := uAB/AndroidManifest.xml
+include $(FrameworkCoreTests_BUILD_PACKAGE)
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+LOCAL_PACKAGE_NAME := keyset_sa_ua_ub
+LOCAL_CERTIFICATE := $(LOCAL_PATH)/../../certs/keyset_A
+LOCAL_MANIFEST_FILE := uAuB/AndroidManifest.xml
+include $(FrameworkCoreTests_BUILD_PACKAGE)
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+LOCAL_PACKAGE_NAME := keyset_permdef_sa_unone
+LOCAL_CERTIFICATE := $(LOCAL_PATH)/../../certs/keyset_A
+LOCAL_MANIFEST_FILE := permDef/AndroidManifest.xml
+include $(FrameworkCoreTests_BUILD_PACKAGE)
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+LOCAL_PACKAGE_NAME := keyset_permuse_sa_ua_ub
+LOCAL_CERTIFICATE := $(LOCAL_PATH)/../../certs/keyset_A
+LOCAL_MANIFEST_FILE := permUse/AndroidManifest.xml
+include $(FrameworkCoreTests_BUILD_PACKAGE)
+
+#apks signed by keyset_B
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+LOCAL_PACKAGE_NAME := keyset_sb_ua
+LOCAL_CERTIFICATE := $(LOCAL_PATH)/../../certs/keyset_B
+LOCAL_MANIFEST_FILE := uA/AndroidManifest.xml
+include $(FrameworkCoreTests_BUILD_PACKAGE)
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+LOCAL_PACKAGE_NAME := keyset_sb_ub
+LOCAL_CERTIFICATE := $(LOCAL_PATH)/../../certs/keyset_B
+LOCAL_MANIFEST_FILE := uB/AndroidManifest.xml
+include $(FrameworkCoreTests_BUILD_PACKAGE)
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+LOCAL_PACKAGE_NAME := keyset_permuse_sb_ua_ub
+LOCAL_CERTIFICATE := $(LOCAL_PATH)/../../certs/keyset_B
+LOCAL_MANIFEST_FILE := permUse/AndroidManifest.xml
+include $(FrameworkCoreTests_BUILD_PACKAGE)
+
+#apks signed by keyset_A and keyset_B
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+LOCAL_PACKAGE_NAME := keyset_sab_ua
+LOCAL_CERTIFICATE := $(LOCAL_PATH)/../../certs/keyset_A
+LOCAL_ADDITIONAL_CERTIFICATES := $(LOCAL_PATH)/../../certs/keyset_B
+LOCAL_MANIFEST_FILE := uA/AndroidManifest.xml
+include $(FrameworkCoreTests_BUILD_PACKAGE)
+
+#apks signed by keyset_A and unit_test
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+LOCAL_PACKAGE_NAME := keyset_sau_ub
+LOCAL_CERTIFICATE := $(LOCAL_PATH)/../../certs/keyset_A
+LOCAL_ADDITIONAL_CERTIFICATES := $(LOCAL_PATH)/../../certs/keyset_B
+LOCAL_MANIFEST_FILE := uB/AndroidManifest.xml
+include $(FrameworkCoreTests_BUILD_PACKAGE) \ No newline at end of file
diff --git a/core/tests/coretests/apks/keyset/permDef/AndroidManifest.xml b/core/tests/coretests/apks/keyset/permDef/AndroidManifest.xml
new file mode 100644
index 0000000..8f7ad4a
--- /dev/null
+++ b/core/tests/coretests/apks/keyset/permDef/AndroidManifest.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.frameworks.coretests.keysets_permdef">
+ <application android:hasCode="false">
+ </application>
+ <permission android:description="@string/keyset_perm_desc"
+ android:label="@string/keyset_perm_label"
+ android:name="com.android.frameworks.coretests.keysets_permdef.keyset_perm"
+ android:protectionLevel="signature" />
+</manifest>
diff --git a/core/tests/coretests/apks/keyset/permUse/AndroidManifest.xml b/core/tests/coretests/apks/keyset/permUse/AndroidManifest.xml
new file mode 100644
index 0000000..41a2974
--- /dev/null
+++ b/core/tests/coretests/apks/keyset/permUse/AndroidManifest.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.frameworks.coretests.keysets">
+ <application android:hasCode="false">
+ </application>
+ <uses-permission android:name="com.android.frameworks.coretests.keysets_permdef.keyset_perm" />
+ <keys>
+ <publicKey android:value="MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJoN1Nsgqf0V4C/bbN8wo8O2X/S5D76+5Mb9mlIsHkUTUTbHCNk+LxHIUYLm89YbP9zImrV0bUHLUAZUyoMUCiMCAwEAAQ==">
+ <keyset android:name="A" />
+ </publicKey>
+ <publicKey android:value="MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAMTfQsY8UuXiXmvw/y7Tpr7HoyfAC0nE/8Qdk3ZtEr9asa5qqP0F6xzCI1PGVFV+WLVRwm6FdB9StENL5EKyQFcCAwEAAQ==">
+ <keyset android:name="B" />
+ </publicKey>
+ </keys>
+ <upgrade-keyset android:name="A"/>
+ <upgrade-keyset android:name="B"/>
+</manifest>
diff --git a/core/tests/coretests/apks/keyset/res/values/strings.xml b/core/tests/coretests/apks/keyset/res/values/strings.xml
new file mode 100644
index 0000000..ff99ffa
--- /dev/null
+++ b/core/tests/coretests/apks/keyset/res/values/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!-- Just need this dummy file to have something to build. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="dummy">dummy</string>
+ <string name="keyset_perm_desc">keyset_perm_description</string>
+ <string name="keyset_perm_label">keyset_perm_label</string>
+</resources>
diff --git a/core/tests/coretests/apks/keyset/uA/AndroidManifest.xml b/core/tests/coretests/apks/keyset/uA/AndroidManifest.xml
new file mode 100644
index 0000000..87c420e
--- /dev/null
+++ b/core/tests/coretests/apks/keyset/uA/AndroidManifest.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.frameworks.coretests.keysets">
+ <application android:hasCode="false">
+ </application>
+ <keys>
+ <publicKey android:value="MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJoN1Nsgqf0V4C/bbN8wo8O2X/S5D76+5Mb9mlIsHkUTUTbHCNk+LxHIUYLm89YbP9zImrV0bUHLUAZUyoMUCiMCAwEAAQ==">
+ <keyset android:name="A" />
+ </publicKey>
+ </keys>
+ <upgrade-keyset android:name="A"/>
+</manifest>
diff --git a/core/tests/coretests/apks/keyset/uAB/AndroidManifest.xml b/core/tests/coretests/apks/keyset/uAB/AndroidManifest.xml
new file mode 100644
index 0000000..a65f085
--- /dev/null
+++ b/core/tests/coretests/apks/keyset/uAB/AndroidManifest.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.frameworks.coretests.keysets">
+ <application android:hasCode="false">
+ </application>
+ <keys>
+ <publicKey android:value="MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJoN1Nsgqf0V4C/bbN8wo8O2X/S5D76+5Mb9mlIsHkUTUTbHCNk+LxHIUYLm89YbP9zImrV0bUHLUAZUyoMUCiMCAwEAAQ==">
+ <keyset android:name="AB" />
+ </publicKey>
+ <publicKey android:value="MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAMTfQsY8UuXiXmvw/y7Tpr7HoyfAC0nE/8Qdk3ZtEr9asa5qqP0F6xzCI1PGVFV+WLVRwm6FdB9StENL5EKyQFcCAwEAAQ==">
+ <keyset android:name="AB" />
+ </publicKey>
+ </keys>
+ <upgrade-keyset android:name="AB"/>
+</manifest>
diff --git a/core/tests/coretests/apks/keyset/uAuB/AndroidManifest.xml b/core/tests/coretests/apks/keyset/uAuB/AndroidManifest.xml
new file mode 100644
index 0000000..5b0b864
--- /dev/null
+++ b/core/tests/coretests/apks/keyset/uAuB/AndroidManifest.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.frameworks.coretests.keysets">
+ <application android:hasCode="false">
+ </application>
+ <keys>
+ <publicKey android:value="MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJoN1Nsgqf0V4C/bbN8wo8O2X/S5D76+5Mb9mlIsHkUTUTbHCNk+LxHIUYLm89YbP9zImrV0bUHLUAZUyoMUCiMCAwEAAQ==">
+ <keyset android:name="A" />
+ </publicKey>
+ <publicKey android:value="MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAMTfQsY8UuXiXmvw/y7Tpr7HoyfAC0nE/8Qdk3ZtEr9asa5qqP0F6xzCI1PGVFV+WLVRwm6FdB9StENL5EKyQFcCAwEAAQ==">
+ <keyset android:name="B" />
+ </publicKey>
+ </keys>
+ <upgrade-keyset android:name="A"/>
+ <upgrade-keyset android:name="B"/>
+</manifest>
diff --git a/core/tests/coretests/apks/keyset/uB/AndroidManifest.xml b/core/tests/coretests/apks/keyset/uB/AndroidManifest.xml
new file mode 100644
index 0000000..9b89961
--- /dev/null
+++ b/core/tests/coretests/apks/keyset/uB/AndroidManifest.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.frameworks.coretests.keysets">
+ <application android:hasCode="false">
+ </application>
+ <keys>
+ <publicKey android:value="MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAMTfQsY8UuXiXmvw/y7Tpr7HoyfAC0nE/8Qdk3ZtEr9asa5qqP0F6xzCI1PGVFV+WLVRwm6FdB9StENL5EKyQFcCAwEAAQ==">
+ <keyset android:name="B" />
+ </publicKey>
+ </keys>
+ <upgrade-keyset android:name="B"/>
+</manifest>
diff --git a/core/tests/coretests/apks/keyset/uNone/AndroidManifest.xml b/core/tests/coretests/apks/keyset/uNone/AndroidManifest.xml
new file mode 100644
index 0000000..9c9ef2b
--- /dev/null
+++ b/core/tests/coretests/apks/keyset/uNone/AndroidManifest.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.frameworks.coretests.keysets">
+ <application android:hasCode="false">
+ </application>
+</manifest>
diff --git a/core/tests/coretests/certs/keyset_A.pk8 b/core/tests/coretests/certs/keyset_A.pk8
new file mode 100644
index 0000000..3976b94
--- /dev/null
+++ b/core/tests/coretests/certs/keyset_A.pk8
Binary files differ
diff --git a/core/tests/coretests/certs/keyset_A.x509.pem b/core/tests/coretests/certs/keyset_A.x509.pem
new file mode 100644
index 0000000..0fe334e
--- /dev/null
+++ b/core/tests/coretests/certs/keyset_A.x509.pem
@@ -0,0 +1,14 @@
+-----BEGIN CERTIFICATE-----
+MIICKjCCAdQCCQCpDXPnNpO5UjANBgkqhkiG9w0BAQUFADCBmzELMAkGA1UEBhMC
+VVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50YWluIFZpZXcx
+DzANBgNVBAoTBkdvb2dsZTEQMA4GA1UECxMHQW5kcm9pZDEYMBYGA1UEAxMPd3d3
+LmV4YW1wbGUuY29tMSIwIAYJKoZIhvcNAQkBFhNkY2FzaG1hbkBnb29nbGUuY29t
+MB4XDTE0MDQyMTE4MTkwM1oXDTE3MDQyMDE4MTkwM1owgZsxCzAJBgNVBAYTAlVT
+MRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MQ8w
+DQYDVQQKEwZHb29nbGUxEDAOBgNVBAsTB0FuZHJvaWQxGDAWBgNVBAMTD3d3dy5l
+eGFtcGxlLmNvbTEiMCAGCSqGSIb3DQEJARYTZGNhc2htYW5AZ29vZ2xlLmNvbTBc
+MA0GCSqGSIb3DQEBAQUAA0sAMEgCQQCaDdTbIKn9FeAv22zfMKPDtl/0uQ++vuTG
+/ZpSLB5FE1E2xwjZPi8RyFGC5vPWGz/cyJq1dG1By1AGVMqDFAojAgMBAAEwDQYJ
+KoZIhvcNAQEFBQADQQCPTVDKxVZpxFH6Nm7sxpRplLzxbs/xyGELLIjEBVrgB0CM
+HAxFpPRHDSFpTxGG2mBCSrf+lD2Bf+WiIojx+RLY
+-----END CERTIFICATE-----
diff --git a/core/tests/coretests/certs/keyset_B.pk8 b/core/tests/coretests/certs/keyset_B.pk8
new file mode 100644
index 0000000..a44ebb3
--- /dev/null
+++ b/core/tests/coretests/certs/keyset_B.pk8
Binary files differ
diff --git a/core/tests/coretests/certs/keyset_B.x509.pem b/core/tests/coretests/certs/keyset_B.x509.pem
new file mode 100644
index 0000000..2806de5
--- /dev/null
+++ b/core/tests/coretests/certs/keyset_B.x509.pem
@@ -0,0 +1,14 @@
+-----BEGIN CERTIFICATE-----
+MIICKjCCAdQCCQC+5GnAgmYS6DANBgkqhkiG9w0BAQUFADCBmzELMAkGA1UEBhMC
+VVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50YWluIFZpZXcx
+DzANBgNVBAoTBkdvb2dsZTEQMA4GA1UECxMHQW5kcm9pZDEYMBYGA1UEAxMPd3d3
+LmV4YW1wbGUuY29tMSIwIAYJKoZIhvcNAQkBFhNkY2FzaG1hbkBnb29nbGUuY29t
+MB4XDTE0MDQyMTE4MjczM1oXDTE3MDQyMDE4MjczM1owgZsxCzAJBgNVBAYTAlVT
+MRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MQ8w
+DQYDVQQKEwZHb29nbGUxEDAOBgNVBAsTB0FuZHJvaWQxGDAWBgNVBAMTD3d3dy5l
+eGFtcGxlLmNvbTEiMCAGCSqGSIb3DQEJARYTZGNhc2htYW5AZ29vZ2xlLmNvbTBc
+MA0GCSqGSIb3DQEBAQUAA0sAMEgCQQDE30LGPFLl4l5r8P8u06a+x6MnwAtJxP/E
+HZN2bRK/WrGuaqj9BescwiNTxlRVfli1UcJuhXQfUrRDS+RCskBXAgMBAAEwDQYJ
+KoZIhvcNAQEFBQADQQCYYyur2/sMB88MOhQE8RHNmdO0zEQYAz66z3ctTNqiNsbK
+T9iKj0CT3cjqgfN5ex4onhnoIIPtON7DIHFWke5x
+-----END CERTIFICATE-----
diff --git a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
index 7f41ac1c..0244425 100644
--- a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
+++ b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
@@ -61,7 +61,10 @@ import android.util.Log;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
+import java.util.HashSet;
import java.util.List;
+import java.util.Set;
+
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@@ -3069,6 +3072,262 @@ public class PackageManagerTests extends AndroidTestCase {
}
/**
+ * The following tests are related to testing KeySets-based key rotation
+ */
+ /*
+ * Check if an apk which does not specify an upgrade-keyset may be upgraded
+ * by an apk which does
+ */
+ public void testNoKSToUpgradeKS() throws Exception {
+ replaceCerts(R.raw.keyset_sa_unone, R.raw.keyset_sa_ua, true, false, -1);
+ }
+
+ /*
+ * Check if an apk which does specify an upgrade-keyset may be downgraded to
+ * an apk which does not
+ */
+ public void testUpgradeKSToNoKS() throws Exception {
+ replaceCerts(R.raw.keyset_sa_ua, R.raw.keyset_sa_unone, true, false, -1);
+ }
+
+ /*
+ * Check if an apk signed by a key other than the upgrade keyset can update
+ * an app
+ */
+ public void testUpgradeKSWithWrongKey() throws Exception {
+ replaceCerts(R.raw.keyset_sa_ua, R.raw.keyset_sb_ua, true, true,
+ PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES);
+ }
+
+ /*
+ * Check if an apk signed by its signing key, which is not an upgrade key,
+ * can upgrade an app.
+ */
+ public void testUpgradeKSWithWrongSigningKey() throws Exception {
+ replaceCerts(R.raw.keyset_sa_ub, R.raw.keyset_sa_ub, true, true,
+ PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES);
+ }
+
+ /*
+ * Check if an apk signed by its upgrade key, which is not its signing key,
+ * can upgrade an app.
+ */
+ public void testUpgradeKSWithUpgradeKey() throws Exception {
+ replaceCerts(R.raw.keyset_sa_ub, R.raw.keyset_sb_ub, true, false, -1);
+ }
+ /*
+ * Check if an apk signed by its upgrade key, which is its signing key, can
+ * upgrade an app.
+ */
+ public void testUpgradeKSWithSigningUpgradeKey() throws Exception {
+ replaceCerts(R.raw.keyset_sa_ua, R.raw.keyset_sa_ua, true, false, -1);
+ }
+
+ /*
+ * Check if an apk signed by multiple keys, one of which is its upgrade key,
+ * can upgrade an app.
+ */
+ public void testMultipleUpgradeKSWithUpgradeKey() throws Exception {
+ replaceCerts(R.raw.keyset_sa_ua, R.raw.keyset_sab_ua, true, false, -1);
+ }
+
+ /*
+ * Check if an apk signed by multiple keys, one of which is its signing key,
+ * but none of which is an upgrade key, can upgrade an app.
+ */
+ public void testMultipleUpgradeKSWithSigningKey() throws Exception {
+ replaceCerts(R.raw.keyset_sau_ub, R.raw.keyset_sa_ua, true, true,
+ PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES);
+ }
+
+ /*
+ * Check if an apk which defines multiple (two) upgrade keysets is
+ * upgrade-able by either.
+ */
+ public void testUpgradeKSWithMultipleUpgradeKeySets() throws Exception {
+ replaceCerts(R.raw.keyset_sa_ua_ub, R.raw.keyset_sa_ua, true, false, -1);
+ replaceCerts(R.raw.keyset_sa_ua_ub, R.raw.keyset_sb_ub, true, false, -1);
+ }
+
+ /*
+ * Check if an apk's sigs are changed after upgrading with a non-signing
+ * key.
+ *
+ * TODO: consider checking against hard-coded Signatures in the Sig-tests
+ */
+ public void testSigChangeAfterUpgrade() throws Exception {
+ // install original apk and grab sigs
+ installFromRawResource("tmp.apk", R.raw.keyset_sa_ub,
+ 0, false, false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
+ PackageManager pm = getPm();
+ String pkgName = "com.android.frameworks.coretests.keysets";
+ PackageInfo pi = pm.getPackageInfo(pkgName, PackageManager.GET_SIGNATURES);
+ assertTrue("Package should only have one signature, sig A",
+ pi.signatures.length == 1);
+ String sigBefore = pi.signatures[0].toCharsString();
+ // install apk signed by different upgrade KeySet
+ installFromRawResource("tmp2.apk", R.raw.keyset_sb_ub,
+ PackageManager.INSTALL_REPLACE_EXISTING, false, false, -1,
+ PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
+ pi = pm.getPackageInfo(pkgName, PackageManager.GET_SIGNATURES);
+ assertTrue("Package should only have one signature, sig B",
+ pi.signatures.length == 1);
+ String sigAfter = pi.signatures[0].toCharsString();
+ assertFalse("Package signatures did not change after upgrade!",
+ sigBefore.equals(sigAfter));
+ cleanUpInstall(pkgName);
+ }
+
+ /*
+ * Check if an apk's sig is the same after upgrading with a signing
+ * key.
+ */
+ public void testSigSameAfterUpgrade() throws Exception {
+ // install original apk and grab sigs
+ installFromRawResource("tmp.apk", R.raw.keyset_sa_ua,
+ 0, false, false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
+ PackageManager pm = getPm();
+ String pkgName = "com.android.frameworks.coretests.keysets";
+ PackageInfo pi = pm.getPackageInfo(pkgName, PackageManager.GET_SIGNATURES);
+ assertTrue("Package should only have one signature, sig A",
+ pi.signatures.length == 1);
+ String sigBefore = pi.signatures[0].toCharsString();
+ // install apk signed by same upgrade KeySet
+ installFromRawResource("tmp2.apk", R.raw.keyset_sa_ua,
+ PackageManager.INSTALL_REPLACE_EXISTING, false, false, -1,
+ PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
+ pi = pm.getPackageInfo(pkgName, PackageManager.GET_SIGNATURES);
+ assertTrue("Package should only have one signature, sig A",
+ pi.signatures.length == 1);
+ String sigAfter = pi.signatures[0].toCharsString();
+ assertTrue("Package signatures changed after upgrade!",
+ sigBefore.equals(sigAfter));
+ cleanUpInstall(pkgName);
+ }
+
+ /*
+ * Check if an apk's sigs are the same after upgrading with an app with
+ * a subset of the original signing keys.
+ */
+ public void testSigRemovedAfterUpgrade() throws Exception {
+ // install original apk and grab sigs
+ installFromRawResource("tmp.apk", R.raw.keyset_sab_ua,
+ 0, false, false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
+ PackageManager pm = getPm();
+ String pkgName = "com.android.frameworks.coretests.keysets";
+ PackageInfo pi = pm.getPackageInfo(pkgName, PackageManager.GET_SIGNATURES);
+ assertTrue("Package should have two signatures, sig A and sig B",
+ pi.signatures.length == 2);
+ Set<String> sigsBefore = new HashSet<String>();
+ for (int i = 0; i < pi.signatures.length; i++) {
+ sigsBefore.add(pi.signatures[i].toCharsString());
+ }
+ // install apk signed subset upgrade KeySet
+ installFromRawResource("tmp2.apk", R.raw.keyset_sa_ua,
+ PackageManager.INSTALL_REPLACE_EXISTING, false, false, -1,
+ PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
+ pi = pm.getPackageInfo(pkgName, PackageManager.GET_SIGNATURES);
+ assertTrue("Package should only have one signature, sig A",
+ pi.signatures.length == 1);
+ String sigAfter = pi.signatures[0].toCharsString();
+ assertTrue("Original package signatures did not contain new sig",
+ sigsBefore.contains(sigAfter));
+ cleanUpInstall(pkgName);
+ }
+
+ /*
+ * Check if an apk's sigs are added to after upgrading with an app with
+ * a superset of the original signing keys.
+ */
+ public void testSigAddedAfterUpgrade() throws Exception {
+ // install original apk and grab sigs
+ installFromRawResource("tmp.apk", R.raw.keyset_sa_ua,
+ 0, false, false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
+ PackageManager pm = getPm();
+ String pkgName = "com.android.frameworks.coretests.keysets";
+ PackageInfo pi = pm.getPackageInfo(pkgName, PackageManager.GET_SIGNATURES);
+ assertTrue("Package should only have one signature, sig A",
+ pi.signatures.length == 1);
+ String sigBefore = pi.signatures[0].toCharsString();
+ // install apk signed subset upgrade KeySet
+ installFromRawResource("tmp2.apk", R.raw.keyset_sab_ua,
+ PackageManager.INSTALL_REPLACE_EXISTING, false, false, -1,
+ PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
+ pi = pm.getPackageInfo(pkgName, PackageManager.GET_SIGNATURES);
+ assertTrue("Package should have two signatures, sig A and sig B",
+ pi.signatures.length == 2);
+ Set<String> sigsAfter = new HashSet<String>();
+ for (int i = 0; i < pi.signatures.length; i++) {
+ sigsAfter.add(pi.signatures[i].toCharsString());
+ }
+ assertTrue("Package signatures did not change after upgrade!",
+ sigsAfter.contains(sigBefore));
+ cleanUpInstall(pkgName);
+ }
+
+ /*
+ * Check if an apk gains signature-level permission after changing to the a
+ * new signature, for which a permission should be granted.
+ */
+ public void testUpgradeSigPermGained() throws Exception {
+ // install apk which defines permission
+ installFromRawResource("permDef.apk", R.raw.keyset_permdef_sa_unone,
+ 0, false, false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
+ // install apk which uses permission but does not have sig
+ installFromRawResource("permUse.apk", R.raw.keyset_permuse_sb_ua_ub,
+ 0, false, false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
+ // verify that package does not have perm before
+ PackageManager pm = getPm();
+ String permPkgName = "com.android.frameworks.coretests.keysets_permdef";
+ String pkgName = "com.android.frameworks.coretests.keysets";
+ String permName = "com.android.frameworks.coretests.keysets_permdef.keyset_perm";
+ assertFalse("keyset permission granted to app without same signature!",
+ pm.checkPermission(permName, pkgName)
+ == PackageManager.PERMISSION_GRANTED);
+ // upgrade to apk with perm signature
+ installFromRawResource("permUse2.apk", R.raw.keyset_permuse_sa_ua_ub,
+ PackageManager.INSTALL_REPLACE_EXISTING, false, false, -1,
+ PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
+ assertTrue("keyset permission not granted to app after upgrade to same sig",
+ pm.checkPermission(permName, pkgName)
+ == PackageManager.PERMISSION_GRANTED);
+ cleanUpInstall(permPkgName);
+ cleanUpInstall(pkgName);
+ }
+
+ /*
+ * Check if an apk loses signature-level permission after changing to the a
+ * new signature, from one which a permission should be granted.
+ */
+ public void testUpgradeSigPermLost() throws Exception {
+ // install apk which defines permission
+ installFromRawResource("permDef.apk", R.raw.keyset_permdef_sa_unone,
+ 0, false, false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
+ // install apk which uses permission, signed by same sig
+ installFromRawResource("permUse.apk", R.raw.keyset_permuse_sa_ua_ub,
+ 0, false, false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
+ // verify that package does not have perm before
+ PackageManager pm = getPm();
+ String permPkgName = "com.android.frameworks.coretests.keysets_permdef";
+ String pkgName = "com.android.frameworks.coretests.keysets";
+ String permName = "com.android.frameworks.coretests.keysets_permdef.keyset_perm";
+ assertTrue("keyset permission not granted to app with same sig",
+ pm.checkPermission(permName, pkgName)
+ == PackageManager.PERMISSION_GRANTED);
+ // upgrade to apk without perm signature
+ installFromRawResource("permUse2.apk", R.raw.keyset_permuse_sb_ua_ub,
+ PackageManager.INSTALL_REPLACE_EXISTING, false, false, -1,
+ PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
+
+ assertFalse("keyset permission not revoked from app which upgraded to a "
+ + "different signature",
+ pm.checkPermission(permName, pkgName)
+ == PackageManager.PERMISSION_GRANTED);
+ cleanUpInstall(permPkgName);
+ cleanUpInstall(pkgName);
+ }
+
+ /**
* The following tests are related to testing the checkSignatures api.
*/
private void checkSignatures(int apk1, int apk2, int expMatchResult) throws Exception {