/*
 * Copyright (C) 2016 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 com.android.apksigner;

import com.android.apksig.ApkSigner;
import com.android.apksig.ApkVerifier;
import com.android.apksig.SigningCertificateLineage;
import com.android.apksig.SigningCertificateLineage.SignerCapabilities;
import com.android.apksig.apk.ApkFormatException;
import com.android.apksig.apk.MinSdkVersionException;
import com.android.apksig.util.DataSource;
import com.android.apksig.util.DataSources;

import org.conscrypt.OpenSSLProvider;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.io.RandomAccessFile;
import java.nio.ByteOrder;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.Provider;
import java.security.PublicKey;
import java.security.Security;
import java.security.cert.CertificateEncodingException;
import java.security.cert.X509Certificate;
import java.security.interfaces.DSAKey;
import java.security.interfaces.DSAParams;
import java.security.interfaces.ECKey;
import java.security.interfaces.RSAKey;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * Command-line tool for signing APKs and for checking whether an APK's signature are expected to
 * verify on Android devices.
 */
public class ApkSignerTool {

    private static final String VERSION = "0.9";
    private static final String HELP_PAGE_GENERAL = "help.txt";
    private static final String HELP_PAGE_SIGN = "help_sign.txt";
    private static final String HELP_PAGE_VERIFY = "help_verify.txt";
    private static final String HELP_PAGE_ROTATE = "help_rotate.txt";
    private static final String HELP_PAGE_LINEAGE = "help_lineage.txt";

    private static MessageDigest sha256 = null;
    private static MessageDigest sha1 = null;
    private static MessageDigest md5 = null;

    public static final int ZIP_MAGIC = 0x04034b50;

    public static void main(String[] params) throws Exception {
        if ((params.length == 0) || ("--help".equals(params[0])) || ("-h".equals(params[0]))) {
            printUsage(HELP_PAGE_GENERAL);
            return;
        } else if ("--version".equals(params[0])) {
            System.out.println(VERSION);
            return;
        }

        addProviders();

        String cmd = params[0];
        try {
            if ("sign".equals(cmd)) {
                sign(Arrays.copyOfRange(params, 1, params.length));
                return;
            } else if ("verify".equals(cmd)) {
                verify(Arrays.copyOfRange(params, 1, params.length));
                return;
            } else if ("rotate".equals(cmd)) {
                rotate(Arrays.copyOfRange(params, 1, params.length));
                return;
            } else if ("lineage".equals(cmd)) {
                lineage(Arrays.copyOfRange(params, 1, params.length));
                return;
            } else if ("help".equals(cmd)) {
                printUsage(HELP_PAGE_GENERAL);
                return;
            } else if ("version".equals(cmd)) {
                System.out.println(VERSION);
                return;
            } else {
                throw new ParameterException(
                        "Unsupported command: " + cmd + ". See --help for supported commands");
            }
        } catch (ParameterException | OptionsParser.OptionsException e) {
            System.err.println(e.getMessage());
            System.exit(1);
            return;
        }
    }

    /**
     * Adds additional security providers to add support for signature algorithms not covered by
     * the default providers.
     */
    private static void addProviders() {
        try {
            Security.addProvider(new OpenSSLProvider());
        } catch (UnsatisfiedLinkError e) {
            // This is expected if the library path does not include the native conscrypt library;
            // the default providers support all but PSS algorithms.
        }
    }

    private static void sign(String[] params) throws Exception {
        if (params.length == 0) {
            printUsage(HELP_PAGE_SIGN);
            return;
        }

        File outputApk = null;
        File inputApk = null;
        boolean verbose = false;
        boolean v1SigningEnabled = true;
        boolean v2SigningEnabled = true;
        boolean v3SigningEnabled = true;
        boolean v4SigningEnabled = true;
        boolean forceSourceStampOverwrite = false;
        boolean verityEnabled = false;
        boolean debuggableApkPermitted = true;
        int minSdkVersion = 1;
        boolean minSdkVersionSpecified = false;
        int maxSdkVersion = Integer.MAX_VALUE;
        List<SignerParams> signers = new ArrayList<>(1);
        SignerParams signerParams = new SignerParams();
        SignerParams sourceStampSignerParams = new SignerParams();
        SigningCertificateLineage lineage = null;
        List<ProviderInstallSpec> providers = new ArrayList<>();
        ProviderInstallSpec providerParams = new ProviderInstallSpec();
        OptionsParser optionsParser = new OptionsParser(params);
        String optionName;
        String optionOriginalForm = null;
        boolean v4SigningFlagFound = false;
        boolean sourceStampFlagFound = false;
        while ((optionName = optionsParser.nextOption()) != null) {
            optionOriginalForm = optionsParser.getOptionOriginalForm();
            if (("help".equals(optionName)) || ("h".equals(optionName))) {
                printUsage(HELP_PAGE_SIGN);
                return;
            } else if ("out".equals(optionName)) {
                outputApk = new File(optionsParser.getRequiredValue("Output file name"));
            } else if ("in".equals(optionName)) {
                inputApk = new File(optionsParser.getRequiredValue("Input file name"));
            } else if ("min-sdk-version".equals(optionName)) {
                minSdkVersion = optionsParser.getRequiredIntValue("Mininimum API Level");
                minSdkVersionSpecified = true;
            } else if ("max-sdk-version".equals(optionName)) {
                maxSdkVersion = optionsParser.getRequiredIntValue("Maximum API Level");
            } else if ("v1-signing-enabled".equals(optionName)) {
                v1SigningEnabled = optionsParser.getOptionalBooleanValue(true);
            } else if ("v2-signing-enabled".equals(optionName)) {
                v2SigningEnabled = optionsParser.getOptionalBooleanValue(true);
            } else if ("v3-signing-enabled".equals(optionName)) {
                v3SigningEnabled = optionsParser.getOptionalBooleanValue(true);
            } else if ("v4-signing-enabled".equals(optionName)) {
                v4SigningEnabled = optionsParser.getOptionalBooleanValue(true);
                v4SigningFlagFound = true;
            } else if ("force-stamp-overwrite".equals(optionName)) {
                forceSourceStampOverwrite = optionsParser.getOptionalBooleanValue(true);
            } else if ("verity-enabled".equals(optionName)) {
                verityEnabled = optionsParser.getOptionalBooleanValue(true);
            } else if ("debuggable-apk-permitted".equals(optionName)) {
                debuggableApkPermitted = optionsParser.getOptionalBooleanValue(true);
            } else if ("next-signer".equals(optionName)) {
                if (!signerParams.isEmpty()) {
                    signers.add(signerParams);
                    signerParams = new SignerParams();
                }
            } else if ("ks".equals(optionName)) {
                signerParams.setKeystoreFile(optionsParser.getRequiredValue("KeyStore file"));
            } else if ("ks-key-alias".equals(optionName)) {
                signerParams.setKeystoreKeyAlias(
                        optionsParser.getRequiredValue("KeyStore key alias"));
            } else if ("ks-pass".equals(optionName)) {
                signerParams.setKeystorePasswordSpec(
                        optionsParser.getRequiredValue("KeyStore password"));
            } else if ("key-pass".equals(optionName)) {
                signerParams.setKeyPasswordSpec(optionsParser.getRequiredValue("Key password"));
            } else if ("pass-encoding".equals(optionName)) {
                String charsetName =
                        optionsParser.getRequiredValue("Password character encoding");
                try {
                    signerParams.setPasswordCharset(
                            PasswordRetriever.getCharsetByName(charsetName));
                } catch (IllegalArgumentException e) {
                    throw new ParameterException(
                            "Unsupported password character encoding requested using"
                                    + " --pass-encoding: " + charsetName);
                }
            } else if ("v1-signer-name".equals(optionName)) {
                signerParams.setV1SigFileBasename(
                        optionsParser.getRequiredValue("JAR signature file basename"));
            } else if ("ks-type".equals(optionName)) {
                signerParams.setKeystoreType(optionsParser.getRequiredValue("KeyStore type"));
            } else if ("ks-provider-name".equals(optionName)) {
                signerParams.setKeystoreProviderName(
                        optionsParser.getRequiredValue("JCA KeyStore Provider name"));
            } else if ("ks-provider-class".equals(optionName)) {
                signerParams.setKeystoreProviderClass(
                        optionsParser.getRequiredValue("JCA KeyStore Provider class name"));
            } else if ("ks-provider-arg".equals(optionName)) {
                signerParams.setKeystoreProviderArg(
                        optionsParser.getRequiredValue(
                                "JCA KeyStore Provider constructor argument"));
            } else if ("key".equals(optionName)) {
                signerParams.setKeyFile(optionsParser.getRequiredValue("Private key file"));
            } else if ("cert".equals(optionName)) {
                signerParams.setCertFile(optionsParser.getRequiredValue("Certificate file"));
            } else if ("lineage".equals(optionName)) {
                File lineageFile = new File(optionsParser.getRequiredValue("Lineage File"));
                lineage = getLineageFromInputFile(lineageFile);
            } else if ("v".equals(optionName) || "verbose".equals(optionName)) {
                verbose = optionsParser.getOptionalBooleanValue(true);
            } else if ("next-provider".equals(optionName)) {
                if (!providerParams.isEmpty()) {
                    providers.add(providerParams);
                    providerParams = new ProviderInstallSpec();
                }
            } else if ("provider-class".equals(optionName)) {
                providerParams.className =
                        optionsParser.getRequiredValue("JCA Provider class name");
            } else if ("provider-arg".equals(optionName)) {
                providerParams.constructorParam =
                        optionsParser.getRequiredValue("JCA Provider constructor argument");
            } else if ("provider-pos".equals(optionName)) {
                providerParams.position =
                        optionsParser.getRequiredIntValue("JCA Provider position");
            } else if ("stamp-signer".equals(optionName)) {
                sourceStampFlagFound = true;
                sourceStampSignerParams = processSignerParams(optionsParser);
            } else {
                throw new ParameterException(
                        "Unsupported option: " + optionOriginalForm + ". See --help for supported"
                                + " options.");
            }
        }
        if (!signerParams.isEmpty()) {
            signers.add(signerParams);
        }
        signerParams = null;
        if (!providerParams.isEmpty()) {
            providers.add(providerParams);
        }
        providerParams = null;

        if (signers.isEmpty()) {
            throw new ParameterException("At least one signer must be specified");
        }

        params = optionsParser.getRemainingParams();
        if (inputApk != null) {
            // Input APK has been specified via preceding parameters. We don't expect any more
            // parameters.
            if (params.length > 0) {
                throw new ParameterException(
                        "Unexpected parameter(s) after " + optionOriginalForm + ": " + params[0]);
            }
        } else {
            // Input APK has not been specified via preceding parameters. The next parameter is
            // supposed to be the path to input APK.
            if (params.length < 1) {
                throw new ParameterException("Missing input APK");
            } else if (params.length > 1) {
                throw new ParameterException(
                        "Unexpected parameter(s) after input APK (" + params[1] + ")");
            }
            inputApk = new File(params[0]);
        }
        if ((minSdkVersionSpecified) && (minSdkVersion > maxSdkVersion)) {
            throw new ParameterException(
                    "Min API Level (" + minSdkVersion + ") > max API Level (" + maxSdkVersion
                            + ")");
        }

        // Install additional JCA Providers
        for (ProviderInstallSpec providerInstallSpec : providers) {
            providerInstallSpec.installProvider();
        }

        ApkSigner.SignerConfig sourceStampSignerConfig = null;
        List<ApkSigner.SignerConfig> signerConfigs = new ArrayList<>(signers.size());
        int signerNumber = 0;
        try (PasswordRetriever passwordRetriever = new PasswordRetriever()) {
            for (SignerParams signer : signers) {
                signerNumber++;
                signer.setName("signer #" + signerNumber);
                ApkSigner.SignerConfig signerConfig = getSignerConfig(signer, passwordRetriever);
                if (signerConfig == null) {
                    return;
                }
                signerConfigs.add(signerConfig);
            }
            if (sourceStampFlagFound) {
                sourceStampSignerParams.setName("stamp signer");
                sourceStampSignerConfig =
                        getSignerConfig(sourceStampSignerParams, passwordRetriever);
                if (sourceStampSignerConfig == null) {
                    return;
                }
            }
        }

        if (outputApk == null) {
            outputApk = inputApk;
        }
        File tmpOutputApk;
        if (inputApk.getCanonicalPath().equals(outputApk.getCanonicalPath())) {
            tmpOutputApk = File.createTempFile("apksigner", ".apk");
            tmpOutputApk.deleteOnExit();
        } else {
            tmpOutputApk = outputApk;
        }
        ApkSigner.Builder apkSignerBuilder =
                new ApkSigner.Builder(signerConfigs)
                        .setInputApk(inputApk)
                        .setOutputApk(tmpOutputApk)
                        .setOtherSignersSignaturesPreserved(false)
                        .setV1SigningEnabled(v1SigningEnabled)
                        .setV2SigningEnabled(v2SigningEnabled)
                        .setV3SigningEnabled(v3SigningEnabled)
                        .setV4SigningEnabled(v4SigningEnabled)
                        .setForceSourceStampOverwrite(forceSourceStampOverwrite)
                        .setVerityEnabled(verityEnabled)
                        .setV4ErrorReportingEnabled(v4SigningEnabled && v4SigningFlagFound)
                        .setDebuggableApkPermitted(debuggableApkPermitted)
                        .setSigningCertificateLineage(lineage);
        if (minSdkVersionSpecified) {
            apkSignerBuilder.setMinSdkVersion(minSdkVersion);
        }
        if (v4SigningEnabled) {
            final File outputV4SignatureFile =
                    new File(outputApk.getCanonicalPath() + ".idsig");
            Files.deleteIfExists(outputV4SignatureFile.toPath());
            apkSignerBuilder.setV4SignatureOutputFile(outputV4SignatureFile);
        }
        if (sourceStampSignerConfig != null) {
            apkSignerBuilder.setSourceStampSignerConfig(sourceStampSignerConfig);
        }
        ApkSigner apkSigner = apkSignerBuilder.build();
        try {
            apkSigner.sign();
        } catch (MinSdkVersionException e) {
            String msg = e.getMessage();
            if (!msg.endsWith(".")) {
                msg += '.';
            }
            throw new MinSdkVersionException(
                    "Failed to determine APK's minimum supported platform version"
                            + ". Use --min-sdk-version to override",
                    e);
        }
        if (!tmpOutputApk.getCanonicalPath().equals(outputApk.getCanonicalPath())) {
            Files.move(
                    tmpOutputApk.toPath(), outputApk.toPath(), StandardCopyOption.REPLACE_EXISTING);
        }

        if (verbose) {
            System.out.println("Signed");
        }
    }

    private static ApkSigner.SignerConfig getSignerConfig(
            SignerParams signer, PasswordRetriever passwordRetriever) {
        try {
            signer.loadPrivateKeyAndCerts(passwordRetriever);
        } catch (ParameterException e) {
            System.err.println(
                    "Failed to load signer \"" + signer.getName() + "\": " + e.getMessage());
            System.exit(2);
            return null;
        } catch (Exception e) {
            System.err.println("Failed to load signer \"" + signer.getName() + "\"");
            e.printStackTrace();
            System.exit(2);
            return null;
        }
        String v1SigBasename;
        if (signer.getV1SigFileBasename() != null) {
            v1SigBasename = signer.getV1SigFileBasename();
        } else if (signer.getKeystoreKeyAlias() != null) {
            v1SigBasename = signer.getKeystoreKeyAlias();
        } else if (signer.getKeyFile() != null) {
            String keyFileName = new File(signer.getKeyFile()).getName();
            int delimiterIndex = keyFileName.indexOf('.');
            if (delimiterIndex == -1) {
                v1SigBasename = keyFileName;
            } else {
                v1SigBasename = keyFileName.substring(0, delimiterIndex);
            }
        } else {
            throw new RuntimeException("Neither KeyStore key alias nor private key file available");
        }
        ApkSigner.SignerConfig signerConfig =
                new ApkSigner.SignerConfig.Builder(
                        v1SigBasename, signer.getPrivateKey(), signer.getCerts())
                        .build();
        return signerConfig;
    }

    private static void verify(String[] params) throws Exception {
        if (params.length == 0) {
            printUsage(HELP_PAGE_VERIFY);
            return;
        }

        File inputApk = null;
        int minSdkVersion = 1;
        boolean minSdkVersionSpecified = false;
        int maxSdkVersion = Integer.MAX_VALUE;
        boolean maxSdkVersionSpecified = false;
        boolean printCerts = false;
        boolean verbose = false;
        boolean warningsTreatedAsErrors = false;
        boolean verifySourceStamp = false;
        File v4SignatureFile = null;
        OptionsParser optionsParser = new OptionsParser(params);
        String optionName;
        String optionOriginalForm = null;
        String sourceCertDigest = null;
        while ((optionName = optionsParser.nextOption()) != null) {
            optionOriginalForm = optionsParser.getOptionOriginalForm();
            if ("min-sdk-version".equals(optionName)) {
                minSdkVersion = optionsParser.getRequiredIntValue("Mininimum API Level");
                minSdkVersionSpecified = true;
            } else if ("max-sdk-version".equals(optionName)) {
                maxSdkVersion = optionsParser.getRequiredIntValue("Maximum API Level");
                maxSdkVersionSpecified = true;
            } else if ("print-certs".equals(optionName)) {
                printCerts = optionsParser.getOptionalBooleanValue(true);
            } else if (("v".equals(optionName)) || ("verbose".equals(optionName))) {
                verbose = optionsParser.getOptionalBooleanValue(true);
            } else if ("Werr".equals(optionName)) {
                warningsTreatedAsErrors = optionsParser.getOptionalBooleanValue(true);
            } else if (("help".equals(optionName)) || ("h".equals(optionName))) {
                printUsage(HELP_PAGE_VERIFY);
                return;
            } else if ("v4-signature-file".equals(optionName)) {
                v4SignatureFile = new File(optionsParser.getRequiredValue(
                        "Input V4 Signature File"));
            } else if ("in".equals(optionName)) {
                inputApk = new File(optionsParser.getRequiredValue("Input APK file"));
            } else if ("verify-source-stamp".equals(optionName)) {
                verifySourceStamp = optionsParser.getOptionalBooleanValue(true);
            } else if ("stamp-cert-digest".equals(optionName)) {
                sourceCertDigest = optionsParser.getRequiredValue(
                        "Expected source stamp certificate digest");
            } else {
                throw new ParameterException(
                        "Unsupported option: " + optionOriginalForm + ". See --help for supported"
                                + " options.");
            }
        }
        params = optionsParser.getRemainingParams();

        if (inputApk != null) {
            // Input APK has been specified in preceding parameters. We don't expect any more
            // parameters.
            if (params.length > 0) {
                throw new ParameterException(
                        "Unexpected parameter(s) after " + optionOriginalForm + ": " + params[0]);
            }
        } else {
            // Input APK has not been specified in preceding parameters. The next parameter is
            // supposed to be the input APK.
            if (params.length < 1) {
                throw new ParameterException("Missing APK");
            } else if (params.length > 1) {
                throw new ParameterException(
                        "Unexpected parameter(s) after APK (" + params[1] + ")");
            }
            inputApk = new File(params[0]);
        }

        if ((minSdkVersionSpecified) && (maxSdkVersionSpecified)
                && (minSdkVersion > maxSdkVersion)) {
            throw new ParameterException(
                    "Min API Level (" + minSdkVersion + ") > max API Level (" + maxSdkVersion
                            + ")");
        }

        ApkVerifier.Builder apkVerifierBuilder = new ApkVerifier.Builder(inputApk);
        if (minSdkVersionSpecified) {
            apkVerifierBuilder.setMinCheckedPlatformVersion(minSdkVersion);
        }
        if (maxSdkVersionSpecified) {
            apkVerifierBuilder.setMaxCheckedPlatformVersion(maxSdkVersion);
        }
        if (v4SignatureFile != null) {
            if (!v4SignatureFile.exists()) {
                throw new ParameterException("V4 signature file does not exist: "
                        + v4SignatureFile.getCanonicalPath());
            }
            apkVerifierBuilder.setV4SignatureFile(v4SignatureFile);
        }

        ApkVerifier apkVerifier = apkVerifierBuilder.build();
        ApkVerifier.Result result;
        try {
            result = verifySourceStamp
                    ? apkVerifier.verifySourceStamp(sourceCertDigest)
                    : apkVerifier.verify();
        } catch (MinSdkVersionException e) {
            String msg = e.getMessage();
            if (!msg.endsWith(".")) {
                msg += '.';
            }
            throw new MinSdkVersionException(
                    "Failed to determine APK's minimum supported platform version"
                            + ". Use --min-sdk-version to override",
                    e);
        }

        boolean verified = result.isVerified();
        ApkVerifier.Result.SourceStampInfo sourceStampInfo = result.getSourceStampInfo();
        boolean warningsEncountered = false;
        if (verified) {
            List<X509Certificate> signerCerts = result.getSignerCertificates();
            if (verbose) {
                System.out.println("Verifies");
                System.out.println(
                        "Verified using v1 scheme (JAR signing): "
                                + result.isVerifiedUsingV1Scheme());
                System.out.println(
                        "Verified using v2 scheme (APK Signature Scheme v2): "
                                + result.isVerifiedUsingV2Scheme());
                System.out.println(
                        "Verified using v3 scheme (APK Signature Scheme v3): "
                                + result.isVerifiedUsingV3Scheme());
                System.out.println(
                        "Verified using v4 scheme (APK Signature Scheme v4): "
                                + result.isVerifiedUsingV4Scheme());
                System.out.println("Verified for SourceStamp: " + result.isSourceStampVerified());
                if (!verifySourceStamp) {
                    System.out.println("Number of signers: " + signerCerts.size());
                }
            }
            if (printCerts) {
                int signerNumber = 0;
                for (X509Certificate signerCert : signerCerts) {
                    signerNumber++;
                    printCertificate(signerCert, "Signer #" + signerNumber, verbose);
                }
                if (sourceStampInfo != null) {
                    printCertificate(sourceStampInfo.getCertificate(), "Source Stamp Signer",
                            verbose);
                }
            }
        } else {
            System.err.println("DOES NOT VERIFY");
        }

        for (ApkVerifier.IssueWithParams error : result.getErrors()) {
            System.err.println("ERROR: " + error);
        }

        @SuppressWarnings("resource") // false positive -- this resource is not opened here
        PrintStream warningsOut = warningsTreatedAsErrors ? System.err : System.out;
        for (ApkVerifier.IssueWithParams warning : result.getWarnings()) {
            warningsEncountered = true;
            warningsOut.println("WARNING: " + warning);
        }
        for (ApkVerifier.Result.V1SchemeSignerInfo signer : result.getV1SchemeSigners()) {
            String signerName = signer.getName();
            for (ApkVerifier.IssueWithParams error : signer.getErrors()) {
                System.err.println("ERROR: JAR signer " + signerName + ": " + error);
            }
            for (ApkVerifier.IssueWithParams warning : signer.getWarnings()) {
                warningsEncountered = true;
                warningsOut.println("WARNING: JAR signer " + signerName + ": " + warning);
            }
        }
        for (ApkVerifier.Result.V2SchemeSignerInfo signer : result.getV2SchemeSigners()) {
            String signerName = "signer #" + (signer.getIndex() + 1);
            for (ApkVerifier.IssueWithParams error : signer.getErrors()) {
                System.err.println(
                        "ERROR: APK Signature Scheme v2 " + signerName + ": " + error);
            }
            for (ApkVerifier.IssueWithParams warning : signer.getWarnings()) {
                warningsEncountered = true;
                warningsOut.println(
                        "WARNING: APK Signature Scheme v2 " + signerName + ": " + warning);
            }
        }
        for (ApkVerifier.Result.V3SchemeSignerInfo signer : result.getV3SchemeSigners()) {
            String signerName = "signer #" + (signer.getIndex() + 1);
            for (ApkVerifier.IssueWithParams error : signer.getErrors()) {
                System.err.println(
                        "ERROR: APK Signature Scheme v3 " + signerName + ": " + error);
            }
            for (ApkVerifier.IssueWithParams warning : signer.getWarnings()) {
                warningsEncountered = true;
                warningsOut.println(
                        "WARNING: APK Signature Scheme v3 " + signerName + ": " + warning);
            }
        }

        if (sourceStampInfo != null) {
            for (ApkVerifier.IssueWithParams error : sourceStampInfo.getErrors()) {
                System.err.println("ERROR: SourceStamp: " + error);
            }
            for (ApkVerifier.IssueWithParams warning : sourceStampInfo.getWarnings()) {
                warningsOut.println("WARNING: SourceStamp: " + warning);
            }
        }

        if (!verified) {
            System.exit(1);
            return;
        }
        if ((warningsTreatedAsErrors) && (warningsEncountered)) {
            System.exit(1);
            return;
        }
    }

    private static void rotate(String[] params) throws Exception {
        if (params.length == 0) {
            printUsage(HELP_PAGE_ROTATE);
            return;
        }

        File outputKeyLineage = null;
        File inputKeyLineage = null;
        boolean verbose = false;
        SignerParams oldSignerParams = null;
        SignerParams newSignerParams = null;
        int minSdkVersion = 0;
        List<ProviderInstallSpec> providers = new ArrayList<>();
        ProviderInstallSpec providerParams = new ProviderInstallSpec();
        OptionsParser optionsParser = new OptionsParser(params);
        String optionName;
        String optionOriginalForm = null;
        while ((optionName = optionsParser.nextOption()) != null) {
            optionOriginalForm = optionsParser.getOptionOriginalForm();
            if (("help".equals(optionName)) || ("h".equals(optionName))) {
                printUsage(HELP_PAGE_ROTATE);
                return;
            } else if ("out".equals(optionName)) {
                outputKeyLineage = new File(optionsParser.getRequiredValue("Output file name"));
            } else if ("in".equals(optionName)) {
                inputKeyLineage = new File(optionsParser.getRequiredValue("Input file name"));
            } else if ("old-signer".equals(optionName)) {
                oldSignerParams = processSignerParams(optionsParser);
            } else if ("new-signer".equals(optionName)) {
                newSignerParams = processSignerParams(optionsParser);
            } else if ("min-sdk-version".equals(optionName)) {
                minSdkVersion = optionsParser.getRequiredIntValue("Mininimum API Level");
            } else if (("v".equals(optionName)) || ("verbose".equals(optionName))) {
                verbose = optionsParser.getOptionalBooleanValue(true);
            } else if ("next-provider".equals(optionName)) {
                if (!providerParams.isEmpty()) {
                    providers.add(providerParams);
                    providerParams = new ProviderInstallSpec();
                }
            } else if ("provider-class".equals(optionName)) {
                providerParams.className =
                        optionsParser.getRequiredValue("JCA Provider class name");
            } else if ("provider-arg".equals(optionName)) {
                providerParams.constructorParam =
                        optionsParser.getRequiredValue("JCA Provider constructor argument");
            } else if ("provider-pos".equals(optionName)) {
                providerParams.position =
                        optionsParser.getRequiredIntValue("JCA Provider position");
            } else {
                throw new ParameterException(
                        "Unsupported option: " + optionOriginalForm + ". See --help for supported"
                                + " options.");
            }
        }
        if (!providerParams.isEmpty()) {
            providers.add(providerParams);
        }
        providerParams = null;

        if (oldSignerParams.isEmpty()) {
            throw new ParameterException("Signer parameters for old signer not present");
        }

        if (newSignerParams.isEmpty()) {
            throw new ParameterException("Signer parameters for new signer not present");
        }

        if (outputKeyLineage == null) {
            throw new ParameterException("Output lineage file parameter not present");
        }

        params = optionsParser.getRemainingParams();
        if (params.length > 0) {
            throw new ParameterException(
                    "Unexpected parameter(s) after " + optionOriginalForm + ": " + params[0]);
        }


        // Install additional JCA Providers
        for (ProviderInstallSpec providerInstallSpec : providers) {
            providerInstallSpec.installProvider();
        }

        try (PasswordRetriever passwordRetriever = new PasswordRetriever()) {
            // populate SignerConfig for old signer
            oldSignerParams.setName("old signer");
            loadPrivateKeyAndCerts(oldSignerParams, passwordRetriever);
            SigningCertificateLineage.SignerConfig oldSignerConfig =
                    new SigningCertificateLineage.SignerConfig.Builder(
                            oldSignerParams.getPrivateKey(), oldSignerParams.getCerts().get(0))
                            .build();

            // TOOD: don't require private key
            newSignerParams.setName("new signer");
            loadPrivateKeyAndCerts(newSignerParams, passwordRetriever);
            SigningCertificateLineage.SignerConfig newSignerConfig =
                    new SigningCertificateLineage.SignerConfig.Builder(
                            newSignerParams.getPrivateKey(), newSignerParams.getCerts().get(0))
                            .build();

            // ok we're all set up, let's rotate!
            SigningCertificateLineage lineage;
            if (inputKeyLineage != null) {
                // we already have history, add the new key to the end of it
                lineage = getLineageFromInputFile(inputKeyLineage);
                lineage.updateSignerCapabilities(
                        oldSignerConfig, oldSignerParams.getSignerCapabilitiesBuilder().build());
                lineage =
                        lineage.spawnDescendant(
                                oldSignerConfig,
                                newSignerConfig,
                                newSignerParams.getSignerCapabilitiesBuilder().build());
            } else {
                // this is the first entry in our signing history, create a new one from the old and
                // new signer info
                lineage =
                        new SigningCertificateLineage.Builder(oldSignerConfig, newSignerConfig)
                                .setMinSdkVersion(minSdkVersion)
                                .setOriginalCapabilities(
                                        oldSignerParams.getSignerCapabilitiesBuilder().build())
                                .setNewCapabilities(
                                        newSignerParams.getSignerCapabilitiesBuilder().build())
                                .build();
            }
            // and write out the result
            lineage.writeToFile(outputKeyLineage);
        }
        if (verbose) {
            System.out.println("Rotation entry generated.");
        }
    }

    public static void lineage(String[] params) throws Exception {
        if (params.length == 0) {
            printUsage(HELP_PAGE_LINEAGE);
            return;
        }

        boolean verbose = false;
        boolean printCerts = false;
        boolean lineageUpdated = false;
        File inputKeyLineage = null;
        File outputKeyLineage = null;
        String optionName;
        OptionsParser optionsParser = new OptionsParser(params);
        List<SignerParams> signers = new ArrayList<>(1);
        while ((optionName = optionsParser.nextOption()) != null) {
            if (("help".equals(optionName)) || ("h".equals(optionName))) {
                printUsage(HELP_PAGE_LINEAGE);
                return;
            } else if ("in".equals(optionName)) {
                inputKeyLineage = new File(optionsParser.getRequiredValue("Input file name"));
            } else if ("out".equals(optionName)) {
                outputKeyLineage = new File(optionsParser.getRequiredValue("Output file name"));
            } else if ("signer".equals(optionName)) {
                SignerParams signerParams = processSignerParams(optionsParser);
                signers.add(signerParams);
            } else if (("v".equals(optionName)) || ("verbose".equals(optionName))) {
                verbose = optionsParser.getOptionalBooleanValue(true);
            } else if ("print-certs".equals(optionName)) {
                printCerts = optionsParser.getOptionalBooleanValue(true);
            } else {
                throw new ParameterException(
                        "Unsupported option: " + optionsParser.getOptionOriginalForm()
                                + ". See --help for supported options.");
            }
        }
        if (inputKeyLineage == null) {
            throw new ParameterException("Input lineage file parameter not present");
        }
        SigningCertificateLineage lineage = getLineageFromInputFile(inputKeyLineage);

        try (PasswordRetriever passwordRetriever = new PasswordRetriever()) {
            for (int i = 0; i < signers.size(); i++) {
                SignerParams signerParams = signers.get(i);
                signerParams.setName("signer #" + (i + 1));
                loadPrivateKeyAndCerts(signerParams, passwordRetriever);
                SigningCertificateLineage.SignerConfig signerConfig =
                        new SigningCertificateLineage.SignerConfig.Builder(
                                signerParams.getPrivateKey(), signerParams.getCerts().get(0))
                                .build();
                try {
                    // since only the caller specified capabilities will be updated a direct
                    // comparison between the original capabilities of the signer and the
                    // signerCapabilitiesBuilder object with potential default values is not
                    // possible. Instead the capabilities should be updated first, then the new
                    // capabilities can be compared against the original to determine if the
                    // lineage has been updated and needs to be written out to a file.
                    SignerCapabilities origCapabilities = lineage.getSignerCapabilities(
                            signerConfig);
                    lineage.updateSignerCapabilities(
                            signerConfig, signerParams.getSignerCapabilitiesBuilder().build());
                    SignerCapabilities newCapabilities = lineage.getSignerCapabilities(
                            signerConfig);
                    if (origCapabilities.equals(newCapabilities)) {
                        if (verbose) {
                            System.out.println(
                                    "The provided signer capabilities for "
                                            + signerParams.getName()
                                            + " are unchanged.");
                        }
                    } else {
                        lineageUpdated = true;
                        if (verbose) {
                            System.out.println(
                                    "Updated signer capabilities for " + signerParams.getName()
                                            + ".");
                        }
                    }
                } catch (IllegalArgumentException e) {
                    throw new ParameterException(
                            "The signer " + signerParams.getName()
                                    + " was not found in the specified lineage.");
                }
            }
        }
        if (printCerts) {
            List<X509Certificate> signingCerts = lineage.getCertificatesInLineage();
            for (int i = 0; i < signingCerts.size(); i++) {
                X509Certificate signerCert = signingCerts.get(i);
                SignerCapabilities signerCapabilities = lineage.getSignerCapabilities(signerCert);
                printCertificate(signerCert, "Signer #" + (i + 1) + " in lineage", verbose);
                printCapabilities(signerCapabilities);
            }
        }
        if (lineageUpdated) {
            if (outputKeyLineage != null) {
                lineage.writeToFile(outputKeyLineage);
                if (verbose) {
                    System.out.println("Updated lineage saved to " + outputKeyLineage + ".");
                }
            } else {
                throw new ParameterException(
                        "The lineage was modified but an output file for the lineage was not "
                                + "specified");
            }
        }
    }

    /**
     * Extracts the Signing Certificate Lineage from the provided lineage or APK file.
     */
    private static SigningCertificateLineage getLineageFromInputFile(File inputLineageFile)
            throws ParameterException {
        try (RandomAccessFile f = new RandomAccessFile(inputLineageFile, "r")) {
            if (f.length() < 4) {
                throw new ParameterException("The input file is not a valid lineage file.");
            }
            DataSource apk = DataSources.asDataSource(f);
            int magicValue = apk.getByteBuffer(0, 4).order(ByteOrder.LITTLE_ENDIAN).getInt();
            if (magicValue == SigningCertificateLineage.MAGIC) {
                return SigningCertificateLineage.readFromFile(inputLineageFile);
            } else if (magicValue == ZIP_MAGIC) {
                return SigningCertificateLineage.readFromApkFile(inputLineageFile);
            } else {
                throw new ParameterException("The input file is not a valid lineage file.");
            }
        } catch (IOException | ApkFormatException | IllegalArgumentException e) {
            throw new ParameterException(e.getMessage());
        }
    }

    private static SignerParams processSignerParams(OptionsParser optionsParser)
            throws OptionsParser.OptionsException, ParameterException {
        SignerParams signerParams = new SignerParams();
        String optionName;
        while ((optionName = optionsParser.nextOption()) != null) {
            if ("ks".equals(optionName)) {
                signerParams.setKeystoreFile(optionsParser.getRequiredValue("KeyStore file"));
            } else if ("ks-key-alias".equals(optionName)) {
                signerParams.setKeystoreKeyAlias(
                        optionsParser.getRequiredValue("KeyStore key alias"));
            } else if ("ks-pass".equals(optionName)) {
                signerParams.setKeystorePasswordSpec(
                        optionsParser.getRequiredValue("KeyStore password"));
            } else if ("key-pass".equals(optionName)) {
                signerParams.setKeyPasswordSpec(optionsParser.getRequiredValue("Key password"));
            } else if ("pass-encoding".equals(optionName)) {
                String charsetName =
                        optionsParser.getRequiredValue("Password character encoding");
                try {
                    signerParams.setPasswordCharset(
                            PasswordRetriever.getCharsetByName(charsetName));
                } catch (IllegalArgumentException e) {
                    throw new ParameterException(
                            "Unsupported password character encoding requested using"
                                    + " --pass-encoding: " + charsetName);
                }
            } else if ("ks-type".equals(optionName)) {
                signerParams.setKeystoreType(optionsParser.getRequiredValue("KeyStore type"));
            } else if ("ks-provider-name".equals(optionName)) {
                signerParams.setKeystoreProviderName(
                        optionsParser.getRequiredValue("JCA KeyStore Provider name"));
            } else if ("ks-provider-class".equals(optionName)) {
                signerParams.setKeystoreProviderClass(
                        optionsParser.getRequiredValue("JCA KeyStore Provider class name"));
            } else if ("ks-provider-arg".equals(optionName)) {
                signerParams.setKeystoreProviderArg(
                        optionsParser.getRequiredValue(
                                "JCA KeyStore Provider constructor argument"));
            } else if ("key".equals(optionName)) {
                signerParams.setKeyFile(optionsParser.getRequiredValue("Private key file"));
            } else if ("cert".equals(optionName)) {
                signerParams.setCertFile(optionsParser.getRequiredValue("Certificate file"));
            } else if ("set-installed-data".equals(optionName)) {
                signerParams
                        .getSignerCapabilitiesBuilder()
                        .setInstalledData(optionsParser.getOptionalBooleanValue(true));
            } else if ("set-shared-uid".equals(optionName)) {
                signerParams
                        .getSignerCapabilitiesBuilder()
                        .setSharedUid(optionsParser.getOptionalBooleanValue(true));
            } else if ("set-permission".equals(optionName)) {
                signerParams
                        .getSignerCapabilitiesBuilder()
                        .setPermission(optionsParser.getOptionalBooleanValue(true));
            } else if ("set-rollback".equals(optionName)) {
                signerParams
                        .getSignerCapabilitiesBuilder()
                        .setRollback(optionsParser.getOptionalBooleanValue(true));
            } else if ("set-auth".equals(optionName)) {
                signerParams
                        .getSignerCapabilitiesBuilder()
                        .setAuth(optionsParser.getOptionalBooleanValue(true));
            } else {
                // not a signer option, reset optionsParser and let caller deal with it
                optionsParser.putOption();
                break;
            }
        }

        if (signerParams.isEmpty()) {
            throw new ParameterException("Signer specified without arguments");
        }
        return signerParams;
    }

    private static void printUsage(String page) {
        try (BufferedReader in =
                new BufferedReader(
                        new InputStreamReader(
                                ApkSignerTool.class.getResourceAsStream(page),
                                StandardCharsets.UTF_8))) {
            String line;
            while ((line = in.readLine()) != null) {
                System.out.println(line);
            }
        } catch (IOException e) {
            throw new RuntimeException("Failed to read " + page + " resource");
        }
    }

    /**
     * Prints details from the provided certificate to stdout.
     *
     * @param cert    the certificate to be displayed.
     * @param name    the name to be used to identify the certificate.
     * @param verbose boolean indicating whether public key details from the certificate should be
     *                displayed.
     *
     * @throws NoSuchAlgorithmException     if an instance of MD5, SHA-1, or SHA-256 cannot be
     *                                      obtained.
     * @throws CertificateEncodingException if an error is encountered when encoding the
     *                                      certificate.
     */
    public static void printCertificate(X509Certificate cert, String name, boolean verbose)
            throws NoSuchAlgorithmException, CertificateEncodingException {
        if (cert == null) {
            throw new NullPointerException("cert == null");
        }
        if (sha256 == null || sha1 == null || md5 == null) {
            sha256 = MessageDigest.getInstance("SHA-256");
            sha1 = MessageDigest.getInstance("SHA-1");
            md5 = MessageDigest.getInstance("MD5");
        }
        System.out.println(name + " certificate DN: " + cert.getSubjectDN());
        byte[] encodedCert = cert.getEncoded();
        System.out.println(name + " certificate SHA-256 digest: " + HexEncoding.encode(
                sha256.digest(encodedCert)));
        System.out.println(name + " certificate SHA-1 digest: " + HexEncoding.encode(
                sha1.digest(encodedCert)));
        System.out.println(
                name + " certificate MD5 digest: " + HexEncoding.encode(md5.digest(encodedCert)));
        if (verbose) {
            PublicKey publicKey = cert.getPublicKey();
            System.out.println(name + " key algorithm: " + publicKey.getAlgorithm());
            int keySize = -1;
            if (publicKey instanceof RSAKey) {
                keySize = ((RSAKey) publicKey).getModulus().bitLength();
            } else if (publicKey instanceof ECKey) {
                keySize = ((ECKey) publicKey).getParams()
                        .getOrder().bitLength();
            } else if (publicKey instanceof DSAKey) {
                // DSA parameters may be inherited from the certificate. We
                // don't handle this case at the moment.
                DSAParams dsaParams = ((DSAKey) publicKey).getParams();
                if (dsaParams != null) {
                    keySize = dsaParams.getP().bitLength();
                }
            }
            System.out.println(
                    name + " key size (bits): " + ((keySize != -1) ? String.valueOf(keySize)
                            : "n/a"));
            byte[] encodedKey = publicKey.getEncoded();
            System.out.println(name + " public key SHA-256 digest: " + HexEncoding.encode(
                    sha256.digest(encodedKey)));
            System.out.println(name + " public key SHA-1 digest: " + HexEncoding.encode(
                    sha1.digest(encodedKey)));
            System.out.println(
                    name + " public key MD5 digest: " + HexEncoding.encode(md5.digest(encodedKey)));
        }
    }

    /**
     * Prints the capabilities of the provided object to stdout. Each of the potential
     * capabilities is displayed along with a boolean indicating whether this object has
     * that capability.
     */
    public static void printCapabilities(SignerCapabilities capabilities) {
        System.out.println("Has installed data capability: " + capabilities.hasInstalledData());
        System.out.println("Has shared UID capability    : " + capabilities.hasSharedUid());
        System.out.println("Has permission capability    : " + capabilities.hasPermission());
        System.out.println("Has rollback capability      : " + capabilities.hasRollback());
        System.out.println("Has auth capability          : " + capabilities.hasAuth());
    }

    private static class ProviderInstallSpec {
        String className;
        String constructorParam;
        Integer position;

        private boolean isEmpty() {
            return (className == null) && (constructorParam == null) && (position == null);
        }

        private void installProvider() throws Exception {
            if (className == null) {
                throw new ParameterException(
                        "JCA Provider class name (--provider-class) must be specified");
            }

            Class<?> providerClass = Class.forName(className);
            if (!Provider.class.isAssignableFrom(providerClass)) {
                throw new ParameterException(
                        "JCA Provider class " + providerClass + " not subclass of "
                                + Provider.class.getName());
            }
            Provider provider;
            if (constructorParam != null) {
                // Single-arg Provider constructor
                provider =
                        (Provider) providerClass.getConstructor(String.class)
                                .newInstance(constructorParam);
            } else {
                // No-arg Provider constructor
                provider = (Provider) providerClass.getConstructor().newInstance();
            }

            if (position == null) {
                Security.addProvider(provider);
            } else {
                Security.insertProviderAt(provider, position);
            }
        }
    }

    /**
     * Loads the private key and certificates from either the specified keystore or files specified
     * in the signer params using the provided passwordRetriever.
     *
     * @throws ParameterException if any errors are encountered when attempting to load
     *                            the private key and certificates.
     */
    private static void loadPrivateKeyAndCerts(SignerParams params,
            PasswordRetriever passwordRetriever) throws ParameterException {
        try {
            params.loadPrivateKeyAndCerts(passwordRetriever);
            if (params.getKeystoreKeyAlias() != null) {
                params.setName(params.getKeystoreKeyAlias());
            } else if (params.getKeyFile() != null) {
                String keyFileName = new File(params.getKeyFile()).getName();
                int delimiterIndex = keyFileName.indexOf('.');
                if (delimiterIndex == -1) {
                    params.setName(keyFileName);
                } else {
                    params.setName(keyFileName.substring(0, delimiterIndex));
                }
            } else {
                throw new RuntimeException(
                        "Neither KeyStore key alias nor private key file available for "
                                + params.getName());
            }
        } catch (ParameterException e) {
            throw new ParameterException(
                    "Failed to load signer \"" + params.getName() + "\":" + e.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
            throw new ParameterException("Failed to load signer \"" + params.getName() + "\"");
        }
    }
}
