Add SourceStamp verification result model am: b8be05176d
Change-Id: Iddfdda1e16af153fa84c0f84208918a28172e869
diff --git a/src/main/java/com/android/apksig/ApkVerifier.java b/src/main/java/com/android/apksig/ApkVerifier.java
index a164805..2671bcf 100644
--- a/src/main/java/com/android/apksig/ApkVerifier.java
+++ b/src/main/java/com/android/apksig/ApkVerifier.java
@@ -567,12 +567,14 @@
private final List<V2SchemeSignerInfo> mV2SchemeSigners = new ArrayList<>();
private final List<V3SchemeSignerInfo> mV3SchemeSigners = new ArrayList<>();
private final List<V4SchemeSignerInfo> mV4SchemeSigners = new ArrayList<>();
+ private SourceStampInfo mSourceStampInfo;
private boolean mVerified;
private boolean mVerifiedUsingV1Scheme;
private boolean mVerifiedUsingV2Scheme;
private boolean mVerifiedUsingV3Scheme;
private boolean mVerifiedUsingV4Scheme;
+ private boolean mSourceStampVerified;
private SigningCertificateLineage mSigningCertificateLineage;
/**
@@ -615,6 +617,13 @@
}
/**
+ * Returns {@code true} if the APK's SourceStamp signature verified.
+ */
+ public boolean isSourceStampVerified() {
+ return mSourceStampVerified;
+ }
+
+ /**
* Returns the verified signers' certificates, one per signer.
*/
public List<X509Certificate> getSignerCertificates() {
@@ -671,6 +680,13 @@
}
/**
+ * Returns information about SourceStamp associated with the APK's signature.
+ */
+ public SourceStampInfo getSourceStampInfo() {
+ return mSourceStampInfo;
+ }
+
+ /**
* Returns the combined SigningCertificateLineage associated with this APK's APK Signature
* Scheme v3 signing block.
*/
@@ -729,6 +745,11 @@
mV4SchemeSigners.add(new V4SchemeSignerInfo(signer));
}
break;
+ case ApkSigningBlockUtils.VERSION_SOURCE_STAMP:
+ mSourceStampVerified = source.verified;
+ if (!source.signers.isEmpty()) {
+ mSourceStampInfo = new SourceStampInfo(source.signers.get(0));
+ }
default:
throw new IllegalArgumentException("Unknown Signing Block Scheme Id");
}
@@ -765,6 +786,9 @@
}
}
}
+ if (mSourceStampInfo != null && mSourceStampInfo.containsErrors()) {
+ return true;
+ }
return false;
}
@@ -1053,12 +1077,55 @@
return mContentDigests;
}
}
+
+ /**
+ * Information about SourceStamp associated with the APK's signature.
+ */
+ public static class SourceStampInfo {
+ private final List<X509Certificate> mCertificates;
+
+ private final List<IssueWithParams> mErrors;
+ private final List<IssueWithParams> mWarnings;
+
+ private SourceStampInfo(ApkSigningBlockUtils.Result.SignerInfo result) {
+ mCertificates = result.certs;
+ mErrors = result.getErrors();
+ mWarnings = result.getWarnings();
+ }
+
+ /**
+ * Returns the SourceStamp's signing certificate or {@code null} if not available. The
+ * certificate is guaranteed to be available if no errors were encountered during
+ * verification (see {@link #containsErrors()}.
+ *
+ * <p>This certificate contains the SourceStamp's public key.
+ */
+ public X509Certificate getCertificate() {
+ return mCertificates.isEmpty() ? null : mCertificates.get(0);
+ }
+
+ private void addError(Issue msg, Object... parameters) {
+ mErrors.add(new IssueWithParams(msg, parameters));
+ }
+
+ public boolean containsErrors() {
+ return !mErrors.isEmpty();
+ }
+
+ public List<IssueWithParams> getErrors() {
+ return mErrors;
+ }
+
+ public List<IssueWithParams> getWarnings() {
+ return mWarnings;
+ }
+ }
}
/**
* Error or warning encountered while verifying an APK's signatures.
*/
- public static enum Issue {
+ public enum Issue {
/**
* APK is not JAR-signed.
@@ -2064,11 +2131,92 @@
*/
V4_SIG_VERSION_NOT_CURRENT(
"V4 signature format version %1$d is different from the tool's current "
- + "version %2$d");
+ + "version %2$d"),
+
+ /** APK contains SourceStamp file, but does not contain a SourceStamp signature. */
+ SOURCE_STAMP_SIG_MISSING("No SourceStamp signature"),
+
+ /**
+ * SourceStamp's certificate could not be parsed.
+ *
+ * <ul>
+ * <li>Parameter 1: error details ({@code Throwable})
+ * </ul>
+ */
+ SOURCE_STAMP_MALFORMED_CERTIFICATE("Malformed certificate: %1$s"),
+
+ /** Failed to parse SourceStamp's signature. */
+ SOURCE_STAMP_MALFORMED_SIGNATURE("Malformed SourceStamp signature"),
+
+ /**
+ * SourceStamp contains a signature produced using an unknown algorithm.
+ *
+ * <ul>
+ * <li>Parameter 1: algorithm ID ({@code Integer})
+ * </ul>
+ */
+ SOURCE_STAMP_UNKNOWN_SIG_ALGORITHM("Unknown signature algorithm: %1$#x"),
+
+ /**
+ * An exception was encountered while verifying SourceStamp signature.
+ *
+ * <ul>
+ * <li>Parameter 1: signature algorithm ({@link SignatureAlgorithm})
+ * <li>Parameter 2: exception ({@code Throwable})
+ * </ul>
+ */
+ SOURCE_STAMP_VERIFY_EXCEPTION("Failed to verify %1$s signature: %2$s"),
+
+ /**
+ * SourceStamp signature block did not verify.
+ *
+ * <ul>
+ * <li>Parameter 1: signature algorithm ({@link SignatureAlgorithm})
+ * </ul>
+ */
+ SOURCE_STAMP_DID_NOT_VERIFY("%1$s signature over signed-data did not verify"),
+
+ /** SourceStamp offers no signatures. */
+ SOURCE_STAMP_NO_SIGNATURE("No signature"),
+
+ /** SourceStamp offers an unsupported signature. */
+ SOURCE_STAMP_NO_SUPPORTED_SIGNATURE("Signature not supported"),
+
+ /** SourceStamp offers no certificates. */
+ SOURCE_STAMP_NO_CERTIFICATE("No certificates"),
+
+ /**
+ * SourceStamp's certificate listed in the APK signing block does not match the certificate
+ * listed in the SourceStamp file in the APK.
+ *
+ * <ul>
+ * <li>Parameter 1: SHA-256 hash of certificate from SourceStamp block in APK signing
+ * block ({@code String})
+ * <li>Parameter 2: SHA-256 hash of certificate from SourceStamp file in APK ({@code
+ * String})
+ * </ul>
+ */
+ SOURCE_STAMP_CERTIFICATE_MISMATCH_BETWEEN_SIGNATURE_BLOCK_AND_APK(
+ "Certificate mismatch between SourceStamp block in APK signing block and"
+ + " SourceStamp file in APK: <%1$s> vs <%2$s>"),
+
+ /**
+ * The APK's digest in APK signing block does not match the digest contained in the
+ * SourceStamp signature.
+ *
+ * <ul>
+ * <li>Parameter 1: content digest algorithm ({@link ContentDigestAlgorithm})
+ * <li>Parameter 2: hex-encoded expected digest of the APK ({@code String})
+ * <li>Parameter 3: hex-encoded actual digest of the APK ({@code String})
+ * </ul>
+ */
+ SOURCE_STAMP_APK_DIGEST_DID_NOT_VERIFY(
+ "APK integrity check failed. %1$s digest mismatch."
+ + " Expected: <%2$s>, actual: <%3$s>");
private final String mFormat;
- private Issue(String format) {
+ Issue(String format) {
mFormat = format;
}
diff --git a/src/main/java/com/android/apksig/internal/util/AndroidSdkVersion.java b/src/main/java/com/android/apksig/internal/util/AndroidSdkVersion.java
index 615d251..4ef67c7 100644
--- a/src/main/java/com/android/apksig/internal/util/AndroidSdkVersion.java
+++ b/src/main/java/com/android/apksig/internal/util/AndroidSdkVersion.java
@@ -47,4 +47,7 @@
/** Android P. */
public static final int P = 28;
+
+ /** Android R. */
+ public static final int R = 30;
}