| /* |
| * Copyright (C) 2022 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. |
| */ |
| |
| package android.security.cts.CVE_2021_39706; |
| |
| import static androidx.test.core.app.ApplicationProvider.getApplicationContext; |
| import static org.junit.Assert.fail; |
| import static org.junit.Assume.assumeFalse; |
| import static org.junit.Assume.assumeTrue; |
| |
| import android.content.Context; |
| import android.content.Intent; |
| import android.content.pm.PackageInfo; |
| import android.content.pm.PackageManager; |
| import android.content.res.Resources; |
| import android.security.cts.CVE_2021_39706.PocActivity; |
| |
| import androidx.test.InstrumentationRegistry; |
| import androidx.test.runner.AndroidJUnit4; |
| import androidx.test.uiautomator.By; |
| import androidx.test.uiautomator.BySelector; |
| import androidx.test.uiautomator.UiDevice; |
| import androidx.test.uiautomator.UiObject2; |
| import androidx.test.uiautomator.Until; |
| |
| import org.junit.Before; |
| import org.junit.Test; |
| import org.junit.runner.RunWith; |
| |
| import java.util.List; |
| |
| @RunWith(AndroidJUnit4.class) |
| public class DeviceTest { |
| private static final int TIMEOUT = 10000; |
| private static Resources resources; |
| private static String settingsPkg; |
| |
| /* |
| * The Certificate and keypair below are generated with: |
| * |
| * openssl req -nodes -new -x509 -keyout key.pem -out cert.pem -days 3650 |
| */ |
| |
| // Content from cert.pem |
| public static final String TEST_CA = "-----BEGIN CERTIFICATE-----\n" |
| + "MIIDAzCCAeugAwIBAgIUax98yDH6YvGpzh2XQBYV7MU2ao8wDQYJKoZIhvcNAQEL\n" |
| + "BQAwETEPMA0GA1UECgwGZ29vZ2xlMB4XDTIyMDIxNzExMzcxNloXDTMyMDIxNTEx\n" |
| + "MzcxNlowETEPMA0GA1UECgwGZ29vZ2xlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A\n" |
| + "MIIBCgKCAQEAoPTRA3pjJc1JTQN3EK6Jtl9JkJaI0+P/e3Bzyi4MkxrSuHDvfqP0\n" |
| + "08roSZgG0a/I1oSlfTSt5QEOvuJH3KVW0IuUF71JYO6rmm7wU2Clx89qmONgQGJR\n" |
| + "G72qvhIBEN1zma2WK9NFcQ4amYspLfkB9HSjy3C+LCwgqoQFfND6uaCGELayx4km\n" |
| + "CnJgBfxNddcz0abWShJ0fr0lOPtKY4tPHhE/1oWGGqAI/U808veLJDpQ06c8wjNf\n" |
| + "8GD7thykOwoTlF630gz0gA/VkmxiOfn0WXRS8VeJ6TeilFsBNUSD4tLA250U8r0F\n" |
| + "d9yFMRVtdFPuNP1ajf2IO+RLpQUr2kWAbQIDAQABo1MwUTAdBgNVHQ4EFgQU1gXp\n" |
| + "r3L/Gf39tvSOZrD5wSQmUJAwHwYDVR0jBBgwFoAU1gXpr3L/Gf39tvSOZrD5wSQm\n" |
| + "UJAwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAFDTpZ1LNtd29\n" |
| + "hh+8TFvAOoaMx06AgnTRdLdsWwcjJCCAHvBiimE23XFO91VjTbttIXynpnKHVwOf\n" |
| + "lgTsExLtXDFU65OQNaWt7UebtWdvxsThd754SUsSGVuZ6VXyI5EuADoU/MocdE3B\n" |
| + "+EJZnl/HvG4KKPTL+YdlvthI1j5WUmI2m7yVzYouC72y92L3ebPaGdMcbp9wjZ89\n" |
| + "LdvAJ8yaLqVxv7TQgXORUo1NrqASsVVW/IgmovHuZj9wK7ZenFhT58ue7nxqQm4Z\n" |
| + "nQfdnxdV19tprMfx1+uu7NNqvxCv1UN6peeBzF/0Bony+9oNzOnGYwMRm9Ww8+mJ\n" |
| + "v02a06J8kg==\n" + "-----END CERTIFICATE-----"; |
| |
| private UiDevice device; |
| private Context context; |
| private PackageManager packageManager; |
| |
| private void openApplication(String applicationName) { |
| Intent intent = context.getPackageManager().getLaunchIntentForPackage(applicationName); |
| intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK); |
| context.startActivity(intent); |
| assumeTrue(resources.getString(R.string.openFail) + applicationName, |
| device.wait(Until.hasObject(By.pkg(applicationName)), TIMEOUT)); |
| } |
| |
| private void tapText(String text) { |
| boolean buttonClicked = false; |
| UiObject2 object = device.findObject(By.text(text)); |
| if (object != null && object.getText() != null) { |
| object.click(); |
| buttonClicked = true; |
| } |
| assumeTrue(resources.getString(R.string.tapFail) + text, buttonClicked); |
| } |
| |
| protected boolean isPackageInstalled(String packageName) { |
| try { |
| PackageInfo pi = packageManager.getPackageInfo(packageName, 0); |
| return pi != null; |
| } catch (PackageManager.NameNotFoundException e) { |
| return false; |
| } |
| } |
| |
| @Before |
| public void setUp() { |
| // Initialize UiDevice instance |
| device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()); |
| context = InstrumentationRegistry.getInstrumentation().getContext(); |
| packageManager = context.getPackageManager(); |
| resources = context.getResources(); |
| settingsPkg = PocActivity.checkIsCar() ? resources.getString(R.string.settingsPkgCar) |
| : resources.getString(R.string.settingsPkg); |
| assumeTrue(settingsPkg + resources.getString(R.string.pkgInstallFail), |
| isPackageInstalled(settingsPkg)); |
| } |
| |
| @Test |
| public void testCredentialReset() { |
| final byte[] cert = TEST_CA.getBytes(); |
| PocPolicyManager policyManager = new PocPolicyManager(getApplicationContext()); |
| assumeFalse(resources.getString(R.string.certInstalled), |
| policyManager.hasCaCertInstalled(cert)); |
| assumeTrue(resources.getString(R.string.certInstallFail), |
| policyManager.installCaCert(cert)); |
| assumeTrue(resources.getString(R.string.certNotFound), |
| policyManager.hasCaCertInstalled(cert)); |
| |
| // Open the PoC and attempt to reset credentials |
| openApplication(resources.getString(R.string.pkgName)); |
| // Button is used to reset credentials after confirming that PoC opened successfully |
| tapText(resources.getString(R.string.cleanCache)); |
| if (device.wait(Until.hasObject(By.pkg(settingsPkg)), TIMEOUT)) { |
| // Press OK in the reset dialog which confirms before clearing certificates |
| tapText(resources.getString(R.string.oK)); |
| } |
| long end = System.currentTimeMillis() + TIMEOUT; |
| while (System.currentTimeMillis() < end) { |
| if (!policyManager.hasCaCertInstalled(cert)) { |
| // Without fix, the certificate is reset |
| fail(resources.getString(R.string.failMessage)); |
| } |
| } |
| |
| // With fix, the certificate is not reset. Uninstall it explicitly |
| policyManager.uninstallCaCert(cert); |
| } |
| } |