morristech
3/8/2018 - 12:51 PM

SignatureUtils to validate Intent.

SignatureUtils to validate Intent.


import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.Signature;
import android.util.Log;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.List;


public class SignatureUtils {

    private static String getSignatureHash(Context ctxt, String packageName) throws PackageManager.NameNotFoundException, NoSuchAlgorithmException {
        MessageDigest md = MessageDigest.getInstance("SHA-1");
        Signature sig = ctxt.getPackageManager().getPackageInfo(packageName, PackageManager.GET_SIGNATURES).signatures[0];
        return (toHexStringWithColons(md.digest(sig.toByteArray())));
    }

    // based on https://stackoverflow.com/a/2197650/115145
    private static String toHexStringWithColons(byte[] bytes) {
        char[] hexArray = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
        char[] hexChars = new char[(bytes.length * 3) - 1];
        int v;

        for (int j = 0; j < bytes.length; j++) {
            v = bytes[j] & 0xFF;
            hexChars[j * 3] = hexArray[v / 16];
            hexChars[j * 3 + 1] = hexArray[v % 16];

            if (j < bytes.length - 1) {
                hexChars[j * 3 + 2] = ':';
            }
        }

        return new String(hexChars);
    }

    public static Intent validateActivityIntent(Context ctxt, Intent toValidate, List<String> sigHashes) {
        PackageManager pm = ctxt.getPackageManager();
        Intent result = null;
        List<ResolveInfo> activities = pm.queryIntentActivities(toValidate, PackageManager.MATCH_ALL);

        if (activities != null) {
            for (ResolveInfo info : activities) {
                try {
                    if (sigHashes.contains(getSignatureHash(ctxt, info.activityInfo.packageName))) {
                        ComponentName cn = new ComponentName(info.activityInfo.packageName, info.activityInfo.name);
                        result = new Intent(toValidate).setComponent(cn);
                        break;
                    } else {
                        throw new SecurityException("Package has signature hash mismatch: " + info.activityInfo.packageName);
                    }
                } catch (NoSuchAlgorithmException | PackageManager.NameNotFoundException e) {
                    Log.w("SignatureUtils", "Exception when computing signature hash", e);
                }
            }
        }

        return (result);
    }


    public static boolean isPackageInstalled(String packagename, PackageManager packageManager) {
        try {
            packageManager.getPackageInfo(packagename, 0);
            return true;
        } catch (PackageManager.NameNotFoundException e) {
            return false;
        }
    }


}