/*
 * Copyright (C) 2011 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;

import com.android.cts.stub.R;

import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.Signature;
import android.content.res.Resources.NotFoundException;
import android.test.AndroidTestCase;
import android.util.Log;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class PackageSignatureTest extends AndroidTestCase {

    private static final String TAG = PackageSignatureTest.class.getSimpleName();

    public void testPackageSignatures() throws Exception {
        Set<String> badPackages = new HashSet<String>();
        Set<Signature> wellKnownSignatures = getWellKnownSignatures();

        PackageManager packageManager = mContext.getPackageManager();
        List<PackageInfo> allPackageInfos = packageManager.getInstalledPackages(
                PackageManager.GET_UNINSTALLED_PACKAGES |
                PackageManager.GET_SIGNATURES);
        for (PackageInfo packageInfo : allPackageInfos) {
            String packageName = packageInfo.packageName;
            if (packageName != null && !isWhitelistedPackage(packageName)) {
                for (Signature signature : packageInfo.signatures) {
                    if (wellKnownSignatures.contains(signature)) {
                        badPackages.add(packageInfo.packageName);
                    }
                }
            }
        }

        assertTrue("These packages should not be signed with a well known key: " + badPackages,
                badPackages.isEmpty());
    }

    private Set<Signature> getWellKnownSignatures() throws NotFoundException, IOException {
        Set<Signature> wellKnownSignatures = new HashSet<Signature>();
        wellKnownSignatures.add(getSignature(R.raw.sig_media));
        wellKnownSignatures.add(getSignature(R.raw.sig_platform));
        wellKnownSignatures.add(getSignature(R.raw.sig_shared));
        wellKnownSignatures.add(getSignature(R.raw.sig_testkey));
        return wellKnownSignatures;
    }

    private static final Set<String> WHITELISTED_PACKAGES = new HashSet<String>(Arrays.asList(
            // The accessibility APK required to be installed while running CTS
            "android.accessibilityservice.delegate",

            // The device management APK required to be installed while running CTS
            "android.deviceadmin.cts",

            // APK for an activity that collects information printed in the CTS report header
            "android.tests.devicesetup",

            // APK for the Android core tests runner used only during CTS
            "android.core.tests.runner"
            ));

    private boolean isWhitelistedPackage(String packageName) {
        // Don't check the signatures of CTS test packages on the device.
        // devicesetup is the APK CTS loads to collect information needed in the final report
        return packageName.startsWith("com.android.cts")
                || WHITELISTED_PACKAGES.contains(packageName);
    }

    private static final int DEFAULT_BUFFER_BYTES = 1024 * 4;

    private Signature getSignature(int resId) throws NotFoundException, IOException {
        InputStream input = mContext.getResources().openRawResource(resId);
        ByteArrayOutputStream output = new ByteArrayOutputStream();

        try {
            byte[] buffer = new byte[DEFAULT_BUFFER_BYTES];
            int numBytes = 0;
            while ((numBytes = input.read(buffer)) != -1) {
                output.write(buffer, 0, numBytes);
            }
            return new Signature(output.toByteArray());
        } finally {
            input.close();
            output.close();
        }
    }

    /**
     * Writes a package's signature to a file on the device's external storage.
     * This method was used to generate the well known signatures used by this test.
     */
    @SuppressWarnings("unused")
    private void writeSignature(String packageName, String fileName)
            throws NameNotFoundException, IOException {
        PackageManager packageManager = mContext.getPackageManager();
        PackageInfo packageInfo = packageManager.getPackageInfo(packageName,
                PackageManager.GET_SIGNATURES);
        File directory = mContext.getExternalFilesDir(null);
        int numSignatures = packageInfo.signatures.length;
        Log.i(TAG, "Will dump " + numSignatures + " signatures to " + directory);
        for (int i = 0; i < numSignatures; i++) {
            Signature signature = packageInfo.signatures[i];
            byte[] signatureBytes = signature.toByteArray();
            File signatureFile = new File(directory, fileName + "." + i);
            FileOutputStream output = null;
            try {
                output = new FileOutputStream(signatureFile);
                output.write(signatureBytes);
            } finally {
                if (output != null) {
                    output.close();
                }
            }
        }
    }
}
