1 /* 2 * Copyright (C) 2020 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.security.cts; 18 19 import static org.junit.Assert.assertFalse; 20 import static org.junit.Assert.assertTrue; 21 import static org.junit.Assume.assumeTrue; 22 23 import android.content.Context; 24 import android.content.pm.PackageManager; 25 import android.os.Build; 26 import android.platform.test.annotations.AppModeFull; 27 import android.platform.test.annotations.RestrictedBuildTest; 28 import android.security.FileIntegrityManager; 29 30 import androidx.test.platform.app.InstrumentationRegistry; 31 import androidx.test.runner.AndroidJUnit4; 32 33 import com.android.compatibility.common.util.CddTest; 34 import com.android.compatibility.common.util.PropertyUtil; 35 36 import org.junit.Before; 37 import org.junit.Test; 38 import org.junit.runner.RunWith; 39 40 import java.io.ByteArrayInputStream; 41 import java.io.ByteArrayOutputStream; 42 import java.io.IOException; 43 import java.io.InputStream; 44 import java.security.cert.CertificateException; 45 import java.security.cert.CertificateFactory; 46 import java.security.cert.X509Certificate; 47 48 49 @AppModeFull 50 @RunWith(AndroidJUnit4.class) 51 public class FileIntegrityManagerTest { 52 53 private static final String TAG = "FileIntegrityManagerTest"; 54 private static final int MIN_REQUIRED_API_LEVEL = 30; 55 56 private Context mContext; 57 private FileIntegrityManager mFileIntegrityManager; 58 private CertificateFactory mCertFactory; 59 60 @Before setUp()61 public void setUp() throws Exception { 62 mContext = InstrumentationRegistry.getInstrumentation().getContext(); 63 // This feature name check only applies to devices that first shipped with 64 // SC or later. 65 final int firstApiLevel = 66 Math.min(PropertyUtil.getFirstApiLevel(), PropertyUtil.getVendorApiLevel()); 67 if (firstApiLevel >= Build.VERSION_CODES.S) { 68 // Assumes every test in this file asserts a requirement of CDD section 9. 69 assumeTrue("Skipping test: FEATURE_SECURITY_MODEL_COMPATIBLE missing.", 70 mContext.getPackageManager() 71 .hasSystemFeature(PackageManager.FEATURE_SECURITY_MODEL_COMPATIBLE)); 72 } 73 74 mFileIntegrityManager = mContext.getSystemService(FileIntegrityManager.class); 75 mCertFactory = CertificateFactory.getInstance("X.509"); 76 } 77 78 79 @CddTest(requirement="9.10/C-0-3,C-1-1") 80 @Test testSupportedOnDevicesFirstLaunchedWithR()81 public void testSupportedOnDevicesFirstLaunchedWithR() throws Exception { 82 if (PropertyUtil.getFirstApiLevel() >= MIN_REQUIRED_API_LEVEL) { 83 assertTrue(mFileIntegrityManager.isApkVeritySupported()); 84 } 85 } 86 87 @CddTest(requirement="9.10/C-0-3,C-1-1") 88 @Test testCtsReleaseCertificateTrusted()89 public void testCtsReleaseCertificateTrusted() throws Exception { 90 boolean isReleaseCertTrusted = mFileIntegrityManager.isAppSourceCertificateTrusted( 91 readAssetAsX509Certificate("fsverity-release.x509.der")); 92 if (mFileIntegrityManager.isApkVeritySupported()) { 93 assertTrue(isReleaseCertTrusted); 94 } else { 95 assertFalse(isReleaseCertTrusted); 96 } 97 } 98 99 @CddTest(requirement="9.10/C-0-3,C-1-1") 100 @RestrictedBuildTest 101 @Test testPlatformDebugCertificateNotTrusted()102 public void testPlatformDebugCertificateNotTrusted() throws Exception { 103 boolean isDebugCertTrusted = mFileIntegrityManager.isAppSourceCertificateTrusted( 104 readAssetAsX509Certificate("fsverity-debug.x509.der")); 105 assertFalse(isDebugCertTrusted); 106 } 107 readAssetAsX509Certificate(String assetName)108 private X509Certificate readAssetAsX509Certificate(String assetName) 109 throws CertificateException, IOException { 110 InputStream is = mContext.getAssets().open(assetName); 111 return toX509Certificate(readAllBytes(is)); 112 } 113 114 // TODO: Switch to InputStream#readAllBytes when Java 9 is supported readAllBytes(InputStream is)115 private byte[] readAllBytes(InputStream is) throws IOException { 116 ByteArrayOutputStream output = new ByteArrayOutputStream(); 117 byte[] buf = new byte[8192]; 118 int len; 119 while ((len = is.read(buf, 0, buf.length)) > 0) { 120 output.write(buf, 0, len); 121 } 122 return output.toByteArray(); 123 } 124 toX509Certificate(byte[] bytes)125 private X509Certificate toX509Certificate(byte[] bytes) throws CertificateException { 126 return (X509Certificate) mCertFactory.generateCertificate(new ByteArrayInputStream(bytes)); 127 } 128 } 129