/*
 * 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.internal.apk.v3.V3SchemeConstants;
import com.android.apksig.util.DataSource;
import com.android.apksig.util.DataSources;

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.Base64;
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 final String BEGIN_CERTIFICATE = "-----BEGIN CERTIFICATE-----";
    private static final String END_CERTIFICATE = "-----END CERTIFICATE-----";

    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;
        }

        // BEGIN-AOSP
        addProviders();
        // END-AOSP

        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;
        }
    }

    // BEGIN-AOSP
    /**
     * Adds additional security providers to add support for signature algorithms not covered by
     * the default providers.
     */
    private static void addProviders() {
        try {
            Security.addProvider(new org.conscrypt.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.
        }
    }
    // END-AOSP

    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;
        int rotationMinSdkVersion = V3SchemeConstants.DEFAULT_ROTATION_MIN_SDK_VERSION;
        boolean rotationTargetsDevRelease = false;
        List<SignerParams> signers = new ArrayList<>(1);
        SignerParams signerParams = new SignerParams();
        SigningCertificateLineage lineage = null;
        SignerParams sourceStampSignerParams = new SignerParams();
        SigningCertificateLineage sourceStampLineage = 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;
        boolean deterministicDsaSigning = false;
        boolean otherSignersSignaturesPreserved = 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 ("rotation-min-sdk-version".equals(optionName)) {
                rotationMinSdkVersion = optionsParser.getRequiredIntValue(
                        "Minimum API Level for Rotation");
            } else if ("rotation-targets-dev-release".equals(optionName)) {
                rotationTargetsDevRelease = optionsParser.getOptionalBooleanValue(true);
            }
            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 if ("stamp-lineage".equals(optionName)) {
                File stampLineageFile = new File(
                        optionsParser.getRequiredValue("Stamp Lineage File"));
                sourceStampLineage = getLineageFromInputFile(stampLineageFile);
            } else if ("deterministic-dsa-signing".equals(optionName)) {
                deterministicDsaSigning = optionsParser.getOptionalBooleanValue(false);
            } else if ("append-signature".equals(optionName)) {
                otherSignersSignaturesPreserved = optionsParser.getOptionalBooleanValue(true);
            } 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,
                        deterministicDsaSigning);
                if (signerConfig == null) {
                    return;
                }
                signerConfigs.add(signerConfig);
            }
            if (sourceStampFlagFound) {
                sourceStampSignerParams.setName("stamp signer");
                sourceStampSignerConfig =
                        getSignerConfig(sourceStampSignerParams, passwordRetriever,
                                deterministicDsaSigning);
                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(otherSignersSignaturesPreserved)
                        .setV1SigningEnabled(v1SigningEnabled)
                        .setV2SigningEnabled(v2SigningEnabled)
                        .setV3SigningEnabled(v3SigningEnabled)
                        .setV4SigningEnabled(v4SigningEnabled)
                        .setForceSourceStampOverwrite(forceSourceStampOverwrite)
                        .setVerityEnabled(verityEnabled)
                        .setV4ErrorReportingEnabled(v4SigningEnabled && v4SigningFlagFound)
                        .setDebuggableApkPermitted(debuggableApkPermitted)
                        .setSigningCertificateLineage(lineage)
                        .setMinSdkVersionForRotation(rotationMinSdkVersion)
                        .setRotationTargetsDevRelease(rotationTargetsDevRelease);
        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)
                    .setSourceStampSigningCertificateLineage(sourceStampLineage);
        }
        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, boolean deterministicDsaSigning) {
        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(),
                        deterministicDsaSigning)
                        .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 printCertsPem = 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 ("print-certs-pem".equals(optionName)) {
                printCertsPem = optionsParser.getOptionalBooleanValue(true);
                // If the PEM output of the certs is requested, this implicitly implies the
                // cert details should be printed.
                if (printCertsPem && !printCerts) {
                    printCerts = 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 v3.1 scheme (APK Signature Scheme v3.1): "
                                + result.isVerifiedUsingV31Scheme());
                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) {
                // The v3.1 signature scheme allows key rotation to target T+ while the original
                // signing key can still be used with v3.0; if a v3.1 block is present then also
                // include the target SDK versions for both rotation and the original signing key.
                if (result.isVerifiedUsingV31Scheme()) {
                    for (ApkVerifier.Result.V3SchemeSignerInfo signer :
                            result.getV31SchemeSigners()) {

                        printCertificate(signer.getCertificate(),
                                "Signer (minSdkVersion=" + signer.getMinSdkVersion()
                                        + (signer.getRotationTargetsDevRelease()
                                        ? " (dev release=true)" : "")
                                        + ", maxSdkVersion=" + signer.getMaxSdkVersion() + ")",
                                verbose, printCertsPem);
                    }
                    for (ApkVerifier.Result.V3SchemeSignerInfo signer : result.getV3SchemeSigners()) {
                        printCertificate(signer.getCertificate(),
                                "Signer (minSdkVersion=" + signer.getMinSdkVersion()
                                        + ", maxSdkVersion=" + signer.getMaxSdkVersion() + ")",
                                verbose, printCertsPem);
                    }
                } else {
                    int signerNumber = 0;
                    for (X509Certificate signerCert : signerCerts) {
                        signerNumber++;
                        printCertificate(signerCert, "Signer #" + signerNumber, verbose,
                                printCertsPem);
                    }
                }
                if (sourceStampInfo != null) {
                    printCertificate(sourceStampInfo.getCertificate(), "Source Stamp Signer",
                            verbose, printCertsPem);
                }
            }
        } 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);
            }
        }
        for (ApkVerifier.Result.V3SchemeSignerInfo signer : result.getV31SchemeSigners()) {
            String signerName = "signer #" + (signer.getIndex() + 1) + "(minSdkVersion="
                    + signer.getMinSdkVersion() + ", maxSdkVersion=" + signer.getMaxSdkVersion()
                    + ")";
            for (ApkVerifier.IssueWithParams error : signer.getErrors()) {
                System.err.println(
                        "ERROR: APK Signature Scheme v3.1 " + signerName + ": " + error);
            }
            for (ApkVerifier.IssueWithParams warning : signer.getWarnings()) {
                warningsEncountered = true;
                warningsOut.println(
                        "WARNING: APK Signature Scheme v3.1 " + 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 printCertsPem = 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 if ("print-certs-pem".equals(optionName)) {
                printCertsPem = optionsParser.getOptionalBooleanValue(true);
                // If the PEM output of the certs is requested, this implicitly implies the
                // cert details should be printed.
                if (printCertsPem && !printCerts) {
                    printCerts = 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,
                        printCertsPem);
                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");
        }
    }

    /**
     * @see #printCertificate(X509Certificate, String, boolean, boolean)
     */
    public static void printCertificate(X509Certificate cert, String name, boolean verbose)
            throws NoSuchAlgorithmException, CertificateEncodingException {
        printCertificate(cert, name, verbose, false);
    }

    /**
     * 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.
     * @param pemOutput boolean indicating whether the PEM encoding of 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,
            boolean pemOutput) 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)));
        }

        if (pemOutput) {
            System.out.println(BEGIN_CERTIFICATE);
            final int lineWidth = 64;
            String pemEncodedCert = Base64.getEncoder().encodeToString(cert.getEncoded());
            for (int i = 0; i < pemEncodedCert.length(); i += lineWidth) {
                System.out.println(pemEncodedCert.substring(i, i + lineWidth > pemEncodedCert.length()
                        ? pemEncodedCert.length()
                        : i + lineWidth));
            }
            System.out.println(END_CERTIFICATE);
        }
    }

    /**
     * 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) {
                try {
                    // Single-arg Provider constructor
                    provider =
                            (Provider) providerClass.getConstructor(String.class)
                                    .newInstance(constructorParam);
                } catch (NoSuchMethodException e) {
                    // Starting from JDK 9 the single-arg constructor accepting the configuration
                    // has been replaced by a configure(String) method to be invoked after
                    // instantiating the Provider with the no-arg constructor.
                    provider = (Provider) providerClass.getConstructor().newInstance();
                    provider = (Provider) providerClass.getMethod("configure", String.class)
                            .invoke(provider, 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() + "\"");
        }
    }
}
