diff options
| author | Michael Groover <mpgroover@google.com> | 2018-07-23 12:55:54 -0700 |
|---|---|---|
| committer | Michael Groover <mpgroover@google.com> | 2018-10-03 09:47:14 -0700 |
| commit | a117b0d4bd3769c6c51348256c0e645cd91bfa16 (patch) | |
| tree | f3f86cf09a622256c8c604f43a4fe581f0484db9 /core/java | |
| parent | bbd22043e0911ea7d4223be8ca7d00b25c309ed8 (diff) | |
Add PackageSignatures readXml tests
This fix also refactors PackageParser.SigningDetails to move the
pastSigningCertificatesFlags to be a data member of Signature; this
allows the capabilities of a previous signing certificate to be
accessed directly from the Signature object as opposed to relying
on the 1-1 mapping of the past certs and flags in the SigningDetails.
Fixes: 73927696
Fixes: 73925989
Test: adb shell am instrument -w -e class com.android.server.pm.PackageSignaturesTest \
com.android.frameworks.servicestests/android.support.test.runner.AndroidJUnitRunner
Change-Id: I635f2d2209350d066d1fa2ef07460071da0c023e
Diffstat (limited to 'core/java')
| -rw-r--r-- | core/java/android/content/pm/PackageParser.java | 70 | ||||
| -rw-r--r-- | core/java/android/content/pm/Signature.java | 32 | ||||
| -rw-r--r-- | core/java/android/util/apk/ApkSignatureVerifier.java | 12 |
3 files changed, 44 insertions, 70 deletions
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java index f5431caaf319..24675d301f4a 100644 --- a/core/java/android/content/pm/PackageParser.java +++ b/core/java/android/content/pm/PackageParser.java @@ -5785,52 +5785,32 @@ public class PackageParser { int AUTH = 16; } - /** - * APK Signature Scheme v3 includes support for adding a proof-of-rotation record that - * contains two pieces of information: - * 1) the past signing certificates - * 2) the flags that APK wants to assign to each of the past signing certificates. - * - * These flags, which have a one-to-one relationship for the {@code pastSigningCertificates} - * collection, represent the second piece of information and are viewed as capabilities. - * They are an APK's way of telling the platform: "this is how I want to trust my old certs, - * please enforce that." This is useful for situation where this app itself is using its - * signing certificate as an authorization mechanism, like whether or not to allow another - * app to have its SIGNATURE permission. An app could specify whether to allow other apps - * signed by its old cert 'X' to still get a signature permission it defines, for example. - */ - @Nullable - public final int[] pastSigningCertificatesFlags; - /** A representation of unknown signing details. Use instead of null. */ public static final SigningDetails UNKNOWN = - new SigningDetails(null, SignatureSchemeVersion.UNKNOWN, null, null, null); + new SigningDetails(null, SignatureSchemeVersion.UNKNOWN, null, null); @VisibleForTesting public SigningDetails(Signature[] signatures, @SignatureSchemeVersion int signatureSchemeVersion, - ArraySet<PublicKey> keys, Signature[] pastSigningCertificates, - int[] pastSigningCertificatesFlags) { + ArraySet<PublicKey> keys, Signature[] pastSigningCertificates) { this.signatures = signatures; this.signatureSchemeVersion = signatureSchemeVersion; this.publicKeys = keys; this.pastSigningCertificates = pastSigningCertificates; - this.pastSigningCertificatesFlags = pastSigningCertificatesFlags; } public SigningDetails(Signature[] signatures, @SignatureSchemeVersion int signatureSchemeVersion, - Signature[] pastSigningCertificates, int[] pastSigningCertificatesFlags) + Signature[] pastSigningCertificates) throws CertificateException { this(signatures, signatureSchemeVersion, toSigningKeys(signatures), - pastSigningCertificates, pastSigningCertificatesFlags); + pastSigningCertificates); } public SigningDetails(Signature[] signatures, @SignatureSchemeVersion int signatureSchemeVersion) throws CertificateException { - this(signatures, signatureSchemeVersion, - null, null); + this(signatures, signatureSchemeVersion, null); } public SigningDetails(SigningDetails orig) { @@ -5844,17 +5824,14 @@ public class PackageParser { this.publicKeys = new ArraySet<>(orig.publicKeys); if (orig.pastSigningCertificates != null) { this.pastSigningCertificates = orig.pastSigningCertificates.clone(); - this.pastSigningCertificatesFlags = orig.pastSigningCertificatesFlags.clone(); } else { this.pastSigningCertificates = null; - this.pastSigningCertificatesFlags = null; } } else { this.signatures = null; this.signatureSchemeVersion = SignatureSchemeVersion.UNKNOWN; this.publicKeys = null; this.pastSigningCertificates = null; - this.pastSigningCertificatesFlags = null; } } @@ -5956,7 +5933,7 @@ public class PackageParser { if (Signature.areEffectiveMatch( oldDetails.signatures[0], pastSigningCertificates[i]) - && pastSigningCertificatesFlags[i] == flags) { + && pastSigningCertificates[i].getFlags() == flags) { return true; } } @@ -6006,7 +5983,7 @@ public class PackageParser { for (int i = 0; i < pastSigningCertificates.length - 1; i++) { if (pastSigningCertificates[i].equals(signature)) { if (flags == PAST_CERT_EXISTS - || (flags & pastSigningCertificatesFlags[i]) == flags) { + || (flags & pastSigningCertificates[i].getFlags()) == flags) { return true; } } @@ -6090,7 +6067,7 @@ public class PackageParser { pastSigningCertificates[i].toByteArray()); if (Arrays.equals(sha256Certificate, digest)) { if (flags == PAST_CERT_EXISTS - || (flags & pastSigningCertificatesFlags[i]) == flags) { + || (flags & pastSigningCertificates[i].getFlags()) == flags) { return true; } } @@ -6127,7 +6104,6 @@ public class PackageParser { dest.writeInt(this.signatureSchemeVersion); dest.writeArraySet(this.publicKeys); dest.writeTypedArray(this.pastSigningCertificates, flags); - dest.writeIntArray(this.pastSigningCertificatesFlags); } protected SigningDetails(Parcel in) { @@ -6136,7 +6112,6 @@ public class PackageParser { this.signatureSchemeVersion = in.readInt(); this.publicKeys = (ArraySet<PublicKey>) in.readArraySet(boot); this.pastSigningCertificates = in.createTypedArray(Signature.CREATOR); - this.pastSigningCertificatesFlags = in.createIntArray(); } public static final Creator<SigningDetails> CREATOR = new Creator<SigningDetails>() { @@ -6175,9 +6150,6 @@ public class PackageParser { if (!Arrays.equals(pastSigningCertificates, that.pastSigningCertificates)) { return false; } - if (!Arrays.equals(pastSigningCertificatesFlags, that.pastSigningCertificatesFlags)) { - return false; - } return true; } @@ -6188,7 +6160,6 @@ public class PackageParser { result = 31 * result + signatureSchemeVersion; result = 31 * result + (publicKeys != null ? publicKeys.hashCode() : 0); result = 31 * result + Arrays.hashCode(pastSigningCertificates); - result = 31 * result + Arrays.hashCode(pastSigningCertificatesFlags); return result; } @@ -6199,7 +6170,6 @@ public class PackageParser { private Signature[] mSignatures; private int mSignatureSchemeVersion = SignatureSchemeVersion.UNKNOWN; private Signature[] mPastSigningCertificates; - private int[] mPastSigningCertificatesFlags; @UnsupportedAppUsage public Builder() { @@ -6226,34 +6196,12 @@ public class PackageParser { return this; } - /** set the flags for the {@code pastSigningCertificates} */ - @UnsupportedAppUsage - public Builder setPastSigningCertificatesFlags(int[] pastSigningCertificatesFlags) { - mPastSigningCertificatesFlags = pastSigningCertificatesFlags; - return this; - } - private void checkInvariants() { // must have signatures and scheme version set if (mSignatures == null) { throw new IllegalStateException("SigningDetails requires the current signing" + " certificates."); } - - // pastSigningCerts and flags must match up - boolean pastMismatch = false; - if (mPastSigningCertificates != null && mPastSigningCertificatesFlags != null) { - if (mPastSigningCertificates.length != mPastSigningCertificatesFlags.length) { - pastMismatch = true; - } - } else if (!(mPastSigningCertificates == null - && mPastSigningCertificatesFlags == null)) { - pastMismatch = true; - } - if (pastMismatch) { - throw new IllegalStateException("SigningDetails must have a one to one mapping " - + "between pastSigningCertificates and pastSigningCertificatesFlags"); - } } /** build a {@code SigningDetails} object */ @UnsupportedAppUsage @@ -6261,7 +6209,7 @@ public class PackageParser { throws CertificateException { checkInvariants(); return new SigningDetails(mSignatures, mSignatureSchemeVersion, - mPastSigningCertificates, mPastSigningCertificatesFlags); + mPastSigningCertificates); } } } diff --git a/core/java/android/content/pm/Signature.java b/core/java/android/content/pm/Signature.java index e58ca609f1a8..349bb693bd9c 100644 --- a/core/java/android/content/pm/Signature.java +++ b/core/java/android/content/pm/Signature.java @@ -45,6 +45,20 @@ public class Signature implements Parcelable { private boolean mHaveHashCode; private SoftReference<String> mStringRef; private Certificate[] mCertificateChain; + /** + * APK Signature Scheme v3 includes support for adding a proof-of-rotation record that + * contains two pieces of information: + * 1) the past signing certificates + * 2) the flags that APK wants to assign to each of the past signing certificates. + * + * These flags represent the second piece of information and are viewed as capabilities. + * They are an APK's way of telling the platform: "this is how I want to trust my old certs, + * please enforce that." This is useful for situation where this app itself is using its + * signing certificate as an authorization mechanism, like whether or not to allow another + * app to have its SIGNATURE permission. An app could specify whether to allow other apps + * signed by its old cert 'X' to still get a signature permission it defines, for example. + */ + private int mFlags; /** * Create Signature from an existing raw byte array. @@ -109,6 +123,22 @@ public class Signature implements Parcelable { } /** + * Sets the flags representing the capabilities of the past signing certificate. + * @hide + */ + public void setFlags(int flags) { + this.mFlags = flags; + } + + /** + * Returns the flags representing the capabilities of the past signing certificate. + * @hide + */ + public int getFlags() { + return mFlags; + } + + /** * Encode the Signature as ASCII text. */ public char[] toChars() { @@ -328,4 +358,4 @@ public class Signature implements Parcelable { return sPrime; } -} +}
\ No newline at end of file diff --git a/core/java/android/util/apk/ApkSignatureVerifier.java b/core/java/android/util/apk/ApkSignatureVerifier.java index a299b11c2b25..ac4ea75b38e3 100644 --- a/core/java/android/util/apk/ApkSignatureVerifier.java +++ b/core/java/android/util/apk/ApkSignatureVerifier.java @@ -81,19 +81,17 @@ public class ApkSignatureVerifier { Certificate[][] signerCerts = new Certificate[][] { vSigner.certs }; Signature[] signerSigs = convertToSignatures(signerCerts); Signature[] pastSignerSigs = null; - int[] pastSignerSigsFlags = null; if (vSigner.por != null) { // populate proof-of-rotation information pastSignerSigs = new Signature[vSigner.por.certs.size()]; - pastSignerSigsFlags = new int[vSigner.por.flagsList.size()]; for (int i = 0; i < pastSignerSigs.length; i++) { pastSignerSigs[i] = new Signature(vSigner.por.certs.get(i).getEncoded()); - pastSignerSigsFlags[i] = vSigner.por.flagsList.get(i); + pastSignerSigs[i].setFlags(vSigner.por.flagsList.get(i)); } } return new PackageParser.SigningDetails( signerSigs, SignatureSchemeVersion.SIGNING_BLOCK_V3, - pastSignerSigs, pastSignerSigsFlags); + pastSignerSigs); } catch (SignatureNotFoundException e) { // not signed with v3, try older if allowed if (minSignatureSchemeVersion >= SignatureSchemeVersion.SIGNING_BLOCK_V3) { @@ -323,19 +321,17 @@ public class ApkSignatureVerifier { Certificate[][] signerCerts = new Certificate[][] { vSigner.certs }; Signature[] signerSigs = convertToSignatures(signerCerts); Signature[] pastSignerSigs = null; - int[] pastSignerSigsFlags = null; if (vSigner.por != null) { // populate proof-of-rotation information pastSignerSigs = new Signature[vSigner.por.certs.size()]; - pastSignerSigsFlags = new int[vSigner.por.flagsList.size()]; for (int i = 0; i < pastSignerSigs.length; i++) { pastSignerSigs[i] = new Signature(vSigner.por.certs.get(i).getEncoded()); - pastSignerSigsFlags[i] = vSigner.por.flagsList.get(i); + pastSignerSigs[i].setFlags(vSigner.por.flagsList.get(i)); } } return new PackageParser.SigningDetails( signerSigs, SignatureSchemeVersion.SIGNING_BLOCK_V3, - pastSignerSigs, pastSignerSigsFlags); + pastSignerSigs); } catch (SignatureNotFoundException e) { // not signed with v3, try older if allowed if (minSignatureSchemeVersion >= SignatureSchemeVersion.SIGNING_BLOCK_V3) { |
