blob: fcff1b1e44d5249e2f6e22c9b750c3f17019fade [file] [log] [blame]
/*
* 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);
}
}