diff options
author | Michael Groover <mpgroover@google.com> | 2022-05-06 17:04:40 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2022-05-06 17:04:40 +0000 |
commit | 19e6c94a835c19304f9c59f91640c85ae97f5bb4 (patch) | |
tree | 12ad8842ff01eb7d33ec4d7db9f0c22bc90559e5 | |
parent | 4214bbd1f0677504149de81072afd7712cc66801 (diff) | |
parent | 37dcfdcbcb6fe5845f375a2ef10a2e45402dbb8c (diff) | |
download | apksig-19e6c94a835c19304f9c59f91640c85ae97f5bb4.tar.gz |
Merge "Add option to apksigner to display PEM encoding of signing certs" into tm-dev am: 37dcfdcbcb
Original change: https://googleplex-android-review.googlesource.com/c/platform/tools/apksig/+/18104170
Change-Id: I8d9df8657c97bd8ce30c8bc6385b12b23f9d33e9
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
3 files changed, 57 insertions, 7 deletions
diff --git a/src/apksigner/java/com/android/apksigner/ApkSignerTool.java b/src/apksigner/java/com/android/apksigner/ApkSignerTool.java index 4a303b6..742a966 100644 --- a/src/apksigner/java/com/android/apksigner/ApkSignerTool.java +++ b/src/apksigner/java/com/android/apksigner/ApkSignerTool.java @@ -49,6 +49,7 @@ 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; /** @@ -63,6 +64,8 @@ public class ApkSignerTool { 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; @@ -461,6 +464,7 @@ public class ApkSignerTool { int maxSdkVersion = Integer.MAX_VALUE; boolean maxSdkVersionSpecified = false; boolean printCerts = false; + boolean printCertsPem = false; boolean verbose = false; boolean warningsTreatedAsErrors = false; boolean verifySourceStamp = false; @@ -479,6 +483,13 @@ public class ApkSignerTool { 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)) { @@ -602,24 +613,25 @@ public class ApkSignerTool { + (signer.getRotationTargetsDevRelease() ? " (dev release=true)" : "") + ", maxSdkVersion=" + signer.getMaxSdkVersion() + ")", - verbose); + verbose, printCertsPem); } for (ApkVerifier.Result.V3SchemeSignerInfo signer : result.getV3SchemeSigners()) { printCertificate(signer.getCertificate(), "Signer (minSdkVersion=" + signer.getMinSdkVersion() + ", maxSdkVersion=" + signer.getMaxSdkVersion() + ")", - verbose); + verbose, printCertsPem); } } else { int signerNumber = 0; for (X509Certificate signerCert : signerCerts) { signerNumber++; - printCertificate(signerCert, "Signer #" + signerNumber, verbose); + printCertificate(signerCert, "Signer #" + signerNumber, verbose, + printCertsPem); } } if (sourceStampInfo != null) { printCertificate(sourceStampInfo.getCertificate(), "Source Stamp Signer", - verbose); + verbose, printCertsPem); } } } else { @@ -844,6 +856,7 @@ public class ApkSignerTool { boolean verbose = false; boolean printCerts = false; + boolean printCertsPem = false; boolean lineageUpdated = false; File inputKeyLineage = null; File outputKeyLineage = null; @@ -865,6 +878,13 @@ public class ApkSignerTool { 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() @@ -925,7 +945,8 @@ public class ApkSignerTool { 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); + printCertificate(signerCert, "Signer #" + (i + 1) + " in lineage", verbose, + printCertsPem); printCapabilities(signerCapabilities); } } @@ -1057,19 +1078,29 @@ public class ApkSignerTool { } /** + * @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) - throws NoSuchAlgorithmException, CertificateEncodingException { + public static void printCertificate(X509Certificate cert, String name, boolean verbose, + boolean pemOutput) throws NoSuchAlgorithmException, CertificateEncodingException { if (cert == null) { throw new NullPointerException("cert == null"); } @@ -1114,6 +1145,18 @@ public class ApkSignerTool { 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); + } } /** diff --git a/src/apksigner/java/com/android/apksigner/help_lineage.txt b/src/apksigner/java/com/android/apksigner/help_lineage.txt index 3f4922d..8fe410b 100644 --- a/src/apksigner/java/com/android/apksigner/help_lineage.txt +++ b/src/apksigner/java/com/android/apksigner/help_lineage.txt @@ -19,6 +19,10 @@ has been migrated to the new signing certificate. --print-certs Show information about the signing certificates and their capabilities in the SigningCertificateLineage. +--print-certs-pem Show information about the signing certificates and their capabilities + in the SigningCertificateLineage; prints the PEM encoding of each signing + certificate to stdout. + -v, --verbose Verbose output mode. -h, --help Show help about this command and exit. diff --git a/src/apksigner/java/com/android/apksigner/help_verify.txt b/src/apksigner/java/com/android/apksigner/help_verify.txt index c5cf663..bc70924 100644 --- a/src/apksigner/java/com/android/apksigner/help_verify.txt +++ b/src/apksigner/java/com/android/apksigner/help_verify.txt @@ -11,6 +11,9 @@ range of API Levels. --print-certs Show information about the APK's signing certificates +--print-certs-pem Show information about the APK's signing certificates and prints the PEM + encoding of each signing certificate to stdout. + -v, --verbose Verbose output mode --min-sdk-version Lowest API Level on which this APK's signatures will be |