diff options
| author | 2018-03-28 15:58:14 -0700 | |
|---|---|---|
| committer | 2018-03-30 15:13:42 +0000 | |
| commit | 10d19e98081bec0e2ee5274f2c46d02d036ce89f (patch) | |
| tree | 45f0a53cb3b4521972fecfd72578317702b0a964 | |
| parent | ea3377b4d47cf590548428df230b713231793ea6 (diff) | |
Require signing cert history certs to be unique.
Bug: 73943012
Test: android.appsecurity.cts.PkgInstallSignatureVerificationTest
Change-Id: Id7e91c60f1619ef793d73a9dd736debf7ad2ae0c
(cherry picked from commit ef05408bcdcb32d005f91ca295a1e514845a58f4)
| -rw-r--r-- | core/java/android/util/apk/ApkSignatureSchemeV3Verifier.java | 8 | ||||
| -rw-r--r-- | core/java/android/util/apk/VerbatimX509Certificate.java | 28 |
2 files changed, 36 insertions, 0 deletions
diff --git a/core/java/android/util/apk/ApkSignatureSchemeV3Verifier.java b/core/java/android/util/apk/ApkSignatureSchemeV3Verifier.java index 4431bcef1ff4..758cd2b877f2 100644 --- a/core/java/android/util/apk/ApkSignatureSchemeV3Verifier.java +++ b/core/java/android/util/apk/ApkSignatureSchemeV3Verifier.java @@ -62,6 +62,7 @@ import java.security.spec.InvalidKeySpecException; import java.security.spec.X509EncodedKeySpec; import java.util.ArrayList; import java.util.Arrays; +import java.util.HashSet; import java.util.List; import java.util.Map; @@ -457,6 +458,7 @@ public class ApkSignatureSchemeV3Verifier { // get the version code, but don't do anything with it: creator knew about all our flags porBuf.getInt(); + HashSet<X509Certificate> certHistorySet = new HashSet<>(); while (porBuf.hasRemaining()) { levelCount++; ByteBuffer level = getLengthPrefixedSlice(porBuf); @@ -495,6 +497,12 @@ public class ApkSignatureSchemeV3Verifier { lastCert = new VerbatimX509Certificate(lastCert, encodedCert); lastSigAlgorithm = sigAlgorithm; + if (certHistorySet.contains(lastCert)) { + throw new SecurityException("Encountered duplicate entries in " + + "Proof-of-rotation record at certificate #" + levelCount + ". All " + + "signing certificates should be unique"); + } + certHistorySet.add(lastCert); certs.add(lastCert); flagsList.add(flags); } diff --git a/core/java/android/util/apk/VerbatimX509Certificate.java b/core/java/android/util/apk/VerbatimX509Certificate.java index 9984c6d26c64..391c5fc39416 100644 --- a/core/java/android/util/apk/VerbatimX509Certificate.java +++ b/core/java/android/util/apk/VerbatimX509Certificate.java @@ -18,6 +18,7 @@ package android.util.apk; import java.security.cert.CertificateEncodingException; import java.security.cert.X509Certificate; +import java.util.Arrays; /** * For legacy reasons we need to return exactly the original encoded certificate bytes, instead @@ -25,6 +26,7 @@ import java.security.cert.X509Certificate; */ class VerbatimX509Certificate extends WrappedX509Certificate { private final byte[] mEncodedVerbatim; + private int mHash = -1; VerbatimX509Certificate(X509Certificate wrapped, byte[] encodedVerbatim) { super(wrapped); @@ -35,4 +37,30 @@ class VerbatimX509Certificate extends WrappedX509Certificate { public byte[] getEncoded() throws CertificateEncodingException { return mEncodedVerbatim; } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof VerbatimX509Certificate)) return false; + + try { + byte[] a = this.getEncoded(); + byte[] b = ((VerbatimX509Certificate) o).getEncoded(); + return Arrays.equals(a, b); + } catch (CertificateEncodingException e) { + return false; + } + } + + @Override + public int hashCode() { + if (mHash == -1) { + try { + mHash = Arrays.hashCode(this.getEncoded()); + } catch (CertificateEncodingException e) { + mHash = 0; + } + } + return mHash; + } } |