diff options
3 files changed, 1 insertions, 231 deletions
diff --git a/core/java/android/security/FileIntegrityManager.java b/core/java/android/security/FileIntegrityManager.java index 478435b1ac5e..9e02ecd19aee 100644 --- a/core/java/android/security/FileIntegrityManager.java +++ b/core/java/android/security/FileIntegrityManager.java @@ -170,11 +170,6 @@ public final class FileIntegrityManager { @Deprecated public boolean isAppSourceCertificateTrusted(@NonNull X509Certificate certificate) throws CertificateEncodingException { - try { - return mService.isAppSourceCertificateTrusted( - certificate.getEncoded(), mContext.getOpPackageName()); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } + return false; } } diff --git a/core/java/android/security/IFileIntegrityService.aidl b/core/java/android/security/IFileIntegrityService.aidl index ddb662ad42cb..c6def239d59a 100644 --- a/core/java/android/security/IFileIntegrityService.aidl +++ b/core/java/android/security/IFileIntegrityService.aidl @@ -25,7 +25,6 @@ import android.os.IInstalld; */ interface IFileIntegrityService { boolean isApkVeritySupported(); - boolean isAppSourceCertificateTrusted(in byte[] certificateBytes, in String packageName); IInstalld.IFsveritySetupAuthToken createAuthToken(in ParcelFileDescriptor authFd); diff --git a/services/core/java/com/android/server/security/FileIntegrityService.java b/services/core/java/com/android/server/security/FileIntegrityService.java index 587be0746149..bfd86d724583 100644 --- a/services/core/java/com/android/server/security/FileIntegrityService.java +++ b/services/core/java/com/android/server/security/FileIntegrityService.java @@ -17,47 +17,24 @@ package com.android.server.security; import android.annotation.EnforcePermission; -import android.annotation.NonNull; -import android.annotation.Nullable; import android.app.AppOpsManager; import android.content.Context; import android.content.pm.PackageManager; import android.content.pm.PackageManagerInternal; import android.os.Binder; -import android.os.Build; -import android.os.Environment; import android.os.IBinder; import android.os.ParcelFileDescriptor; import android.os.PermissionEnforcer; import android.os.RemoteException; -import android.os.ResultReceiver; -import android.os.ShellCallback; -import android.os.ShellCommand; import android.os.UserHandle; import android.os.storage.StorageManagerInternal; import android.security.IFileIntegrityService; -import android.util.Slog; -import com.android.internal.annotations.GuardedBy; import com.android.internal.security.VerityUtils; import com.android.server.LocalServices; import com.android.server.SystemService; -import java.io.ByteArrayInputStream; -import java.io.File; -import java.io.FileDescriptor; import java.io.IOException; -import java.io.InputStream; -import java.io.PrintWriter; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.security.cert.Certificate; -import java.security.cert.CertificateEncodingException; -import java.security.cert.CertificateException; -import java.security.cert.CertificateFactory; -import java.security.cert.X509Certificate; -import java.util.ArrayList; import java.util.Objects; /** @@ -67,15 +44,6 @@ import java.util.Objects; public class FileIntegrityService extends SystemService { private static final String TAG = "FileIntegrityService"; - /** The maximum size of signature file. This is just to avoid potential abuse. */ - private static final int MAX_SIGNATURE_FILE_SIZE_BYTES = 8192; - - private static CertificateFactory sCertFactory; - - @GuardedBy("mTrustedCertificates") - private final ArrayList<X509Certificate> mTrustedCertificates = - new ArrayList<X509Certificate>(); - /** Gets the instance of the service */ public static FileIntegrityService getService() { return LocalServices.getService(FileIntegrityService.class); @@ -91,43 +59,6 @@ public class FileIntegrityService extends SystemService { return VerityUtils.isFsVeritySupported(); } - @Override - public boolean isAppSourceCertificateTrusted(@Nullable byte[] certificateBytes, - @NonNull String packageName) { - checkCallerPermission(packageName); - - if (android.security.Flags.deprecateFsvSig()) { - // When deprecated, stop telling the caller that any app source certificate is - // trusted on the current device. This behavior is also consistent with devices - // without this feature support. - return false; - } - - try { - if (!VerityUtils.isFsVeritySupported()) { - return false; - } - if (certificateBytes == null) { - Slog.w(TAG, "Received a null certificate"); - return false; - } - synchronized (mTrustedCertificates) { - return mTrustedCertificates.contains(toCertificate(certificateBytes)); - } - } catch (CertificateException e) { - Slog.e(TAG, "Failed to convert the certificate: " + e); - return false; - } - } - - @Override - public void onShellCommand(FileDescriptor in, FileDescriptor out, - FileDescriptor err, String[] args, ShellCallback callback, - ResultReceiver resultReceiver) { - new FileIntegrityServiceShellCommand() - .exec(this, in, out, err, args, callback, resultReceiver); - } - private void checkCallerPackageName(String packageName) { final int callingUid = Binder.getCallingUid(); final int callingUserId = UserHandle.getUserId(callingUid); @@ -195,12 +126,6 @@ public class FileIntegrityService extends SystemService { public FileIntegrityService(final Context context) { super(context); mService = new BinderService(context); - try { - sCertFactory = CertificateFactory.getInstance("X.509"); - } catch (CertificateException e) { - Slog.wtf(TAG, "Cannot get an instance of X.509 certificate factory"); - } - LocalServices.addService(FileIntegrityService.class, this); } @@ -215,155 +140,6 @@ public class FileIntegrityService extends SystemService { @Override public void onStart() { - loadAllCertificates(); publishBinderService(Context.FILE_INTEGRITY_SERVICE, mService); } - - /** - * Returns whether the signature over the file's fs-verity digest can be verified by one of the - * known certiticates. - */ - public boolean verifyPkcs7DetachedSignature(String signaturePath, String filePath) - throws IOException { - if (Files.size(Paths.get(signaturePath)) > MAX_SIGNATURE_FILE_SIZE_BYTES) { - throw new SecurityException("Signature file is unexpectedly large: " - + signaturePath); - } - byte[] signatureBytes = Files.readAllBytes(Paths.get(signaturePath)); - byte[] digest = VerityUtils.getFsverityDigest(filePath); - synchronized (mTrustedCertificates) { - for (var cert : mTrustedCertificates) { - try { - byte[] derEncoded = cert.getEncoded(); - if (VerityUtils.verifyPkcs7DetachedSignature(signatureBytes, digest, - new ByteArrayInputStream(derEncoded))) { - return true; - } - } catch (CertificateEncodingException e) { - Slog.w(TAG, "Ignoring ill-formed certificate: " + e); - } - } - } - return false; - } - - private void loadAllCertificates() { - // Load certificates trusted by the device manufacturer. - final String relativeDir = "etc/security/fsverity"; - loadCertificatesFromDirectory(Environment.getRootDirectory().toPath() - .resolve(relativeDir)); - loadCertificatesFromDirectory(Environment.getProductDirectory().toPath() - .resolve(relativeDir)); - } - - private void loadCertificatesFromDirectory(Path path) { - try { - File[] files = path.toFile().listFiles(); - if (files == null) { - return; - } - - for (File cert : files) { - byte[] certificateBytes = Files.readAllBytes(cert.toPath()); - collectCertificate(certificateBytes); - } - } catch (IOException e) { - Slog.wtf(TAG, "Failed to load fs-verity certificate from " + path, e); - } - } - - /** - * Tries to convert {@code bytes} into an X.509 certificate and store in memory. - * Errors need to be surpressed in order fo the next certificates to still be collected. - */ - private void collectCertificate(@NonNull byte[] bytes) { - try { - synchronized (mTrustedCertificates) { - mTrustedCertificates.add(toCertificate(bytes)); - } - } catch (CertificateException e) { - Slog.e(TAG, "Invalid certificate, ignored: " + e); - } - } - - /** - * Converts byte array into one X.509 certificate. If multiple certificate is defined, ignore - * the rest. The rational is to make it harder to smuggle. - */ - @NonNull - private static X509Certificate toCertificate(@NonNull byte[] bytes) - throws CertificateException { - Certificate certificate = sCertFactory.generateCertificate(new ByteArrayInputStream(bytes)); - if (!(certificate instanceof X509Certificate)) { - throw new CertificateException("Expected to contain an X.509 certificate"); - } - return (X509Certificate) certificate; - } - - - private class FileIntegrityServiceShellCommand extends ShellCommand { - @Override - public int onCommand(String cmd) { - if (!Build.IS_DEBUGGABLE) { - return -1; - } - if (cmd == null) { - return handleDefaultCommands(cmd); - } - final PrintWriter pw = getOutPrintWriter(); - switch (cmd) { - case "append-cert": - String nextArg = getNextArg(); - if (nextArg == null) { - pw.println("Invalid argument"); - pw.println(""); - onHelp(); - return -1; - } - ParcelFileDescriptor pfd = openFileForSystem(nextArg, "r"); - if (pfd == null) { - pw.println("Cannot open the file"); - return -1; - } - InputStream is = new ParcelFileDescriptor.AutoCloseInputStream(pfd); - try { - collectCertificate(is.readAllBytes()); - } catch (IOException e) { - pw.println("Failed to add certificate: " + e); - return -1; - } - pw.println("Certificate is added successfully"); - return 0; - - case "remove-last-cert": - synchronized (mTrustedCertificates) { - if (mTrustedCertificates.size() == 0) { - pw.println("Certificate list is already empty"); - return -1; - } - mTrustedCertificates.remove(mTrustedCertificates.size() - 1); - } - pw.println("Certificate is removed successfully"); - return 0; - default: - pw.println("Unknown action"); - pw.println(""); - onHelp(); - } - return -1; - } - - @Override - public void onHelp() { - final PrintWriter pw = getOutPrintWriter(); - pw.println("File integrity service commands:"); - pw.println(" help"); - pw.println(" Print this help text."); - pw.println(" append-cert path/to/cert.der"); - pw.println(" Add the DER-encoded certificate (only in debug builds)"); - pw.println(" remove-last-cert"); - pw.println(" Remove the last certificate in the key list (only in debug builds)"); - pw.println(""); - } - } } |