diff options
Diffstat (limited to 'core')
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 Binary files differnew file mode 100644 index 0000000..3976b94 --- /dev/null +++ b/core/tests/coretests/certs/keyset_A.pk8 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 Binary files differnew file mode 100644 index 0000000..a44ebb3 --- /dev/null +++ b/core/tests/coretests/certs/keyset_B.pk8 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 { |
