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
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index f5431ca..24675d3 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -5785,52 +5785,32 @@
             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 @@
                 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 @@
                     if (Signature.areEffectiveMatch(
                             oldDetails.signatures[0],
                             pastSigningCertificates[i])
-                            && pastSigningCertificatesFlags[i] == flags) {
+                            && pastSigningCertificates[i].getFlags() == flags) {
                         return true;
                     }
                 }
@@ -6006,7 +5983,7 @@
                 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 @@
                             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 @@
             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 @@
             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 @@
             if (!Arrays.equals(pastSigningCertificates, that.pastSigningCertificates)) {
                 return false;
             }
-            if (!Arrays.equals(pastSigningCertificatesFlags, that.pastSigningCertificatesFlags)) {
-                return false;
-            }
 
             return true;
         }
@@ -6188,7 +6160,6 @@
             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 @@
             private Signature[] mSignatures;
             private int mSignatureSchemeVersion = SignatureSchemeVersion.UNKNOWN;
             private Signature[] mPastSigningCertificates;
-            private int[] mPastSigningCertificatesFlags;
 
             @UnsupportedAppUsage
             public Builder() {
@@ -6226,34 +6196,12 @@
                 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 @@
                     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 e58ca60..349bb69 100644
--- a/core/java/android/content/pm/Signature.java
+++ b/core/java/android/content/pm/Signature.java
@@ -45,6 +45,20 @@
     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 @@
     }
 
     /**
+     * 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 @@
 
         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 a299b11..ac4ea75 100644
--- a/core/java/android/util/apk/ApkSignatureVerifier.java
+++ b/core/java/android/util/apk/ApkSignatureVerifier.java
@@ -81,19 +81,17 @@
             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 @@
             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) {
diff --git a/services/core/java/com/android/server/pm/PackageSignatures.java b/services/core/java/com/android/server/pm/PackageSignatures.java
index 471729e..6bce788 100644
--- a/services/core/java/com/android/server/pm/PackageSignatures.java
+++ b/services/core/java/com/android/server/pm/PackageSignatures.java
@@ -16,18 +16,18 @@
 
 package com.android.server.pm;
 
-import com.android.internal.util.XmlUtils;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlSerializer;
-
 import android.annotation.NonNull;
 import android.content.pm.PackageParser;
 import android.content.pm.PackageParser.SigningDetails.SignatureSchemeVersion;
 import android.content.pm.Signature;
 import android.util.Log;
 
+import com.android.internal.util.XmlUtils;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlSerializer;
+
 import java.io.IOException;
 import java.security.cert.CertificateException;
 import java.util.ArrayList;
@@ -61,23 +61,22 @@
         serializer.attribute(null, "count", Integer.toString(mSigningDetails.signatures.length));
         serializer.attribute(null, "schemeVersion",
                 Integer.toString(mSigningDetails.signatureSchemeVersion));
-        writeCertsListXml(serializer, writtenSignatures, mSigningDetails.signatures, null);
+        writeCertsListXml(serializer, writtenSignatures, mSigningDetails.signatures, false);
 
         // if we have past signer certificate information, write it out
         if (mSigningDetails.pastSigningCertificates != null) {
             serializer.startTag(null, "pastSigs");
             serializer.attribute(null, "count",
                     Integer.toString(mSigningDetails.pastSigningCertificates.length));
-            writeCertsListXml(
-                    serializer, writtenSignatures, mSigningDetails.pastSigningCertificates,
-                    mSigningDetails.pastSigningCertificatesFlags);
+            writeCertsListXml(serializer, writtenSignatures,
+                    mSigningDetails.pastSigningCertificates, true);
             serializer.endTag(null, "pastSigs");
         }
         serializer.endTag(null, tagName);
     }
 
     private void writeCertsListXml(XmlSerializer serializer, ArrayList<Signature> writtenSignatures,
-            Signature[] signatures, int[] flags) throws IOException {
+            Signature[] signatures, boolean isPastSigs) throws IOException {
         for (int i=0; i<signatures.length; i++) {
             serializer.startTag(null, "cert");
             final Signature sig = signatures[i];
@@ -96,8 +95,10 @@
                 serializer.attribute(null, "index", Integer.toString(numWritten));
                 serializer.attribute(null, "key", sig.toCharsString());
             }
-            if (flags != null) {
-                serializer.attribute(null, "flags", Integer.toString(flags[i]));
+            // The flags attribute is only written for previous signatures to represent the
+            // capabilities the developer wants to grant to the previous signing certificates.
+            if (isPastSigs) {
+                serializer.attribute(null, "flags", Integer.toString(sig.getFlags()));
             }
             serializer.endTag(null, "cert");
         }
@@ -114,6 +115,7 @@
                     "Error in package manager settings: <sigs> has"
                        + " no count at " + parser.getPositionDescription());
             XmlUtils.skipCurrentTag(parser);
+            return;
         }
         final int count = Integer.parseInt(countStr);
 
@@ -128,16 +130,11 @@
             signatureSchemeVersion = Integer.parseInt(schemeVersionStr);
         }
         builder.setSignatureSchemeVersion(signatureSchemeVersion);
-        Signature[] signatures = new Signature[count];
-        int pos = readCertsListXml(parser, readSignatures, signatures, null, builder);
+        ArrayList<Signature> signatureList = new ArrayList<>();
+        int pos = readCertsListXml(parser, readSignatures, signatureList, count, false, builder);
+        Signature[] signatures = signatureList.toArray(new Signature[signatureList.size()]);
         builder.setSignatures(signatures);
         if (pos < count) {
-            // Should never happen -- there is an error in the written
-            // settings -- but if it does we don't want to generate
-            // a bad array.
-            Signature[] newSigs = new Signature[pos];
-            System.arraycopy(signatures, 0, newSigs, 0, pos);
-            builder = builder.setSignatures(newSigs);
             PackageManagerService.reportSettingsProblem(Log.WARN,
                     "Error in package manager settings: <sigs> count does not match number of "
                             + " <cert> entries" + parser.getPositionDescription());
@@ -154,9 +151,9 @@
     }
 
     private int readCertsListXml(XmlPullParser parser, ArrayList<Signature> readSignatures,
-            Signature[] signatures, int[] flags, PackageParser.SigningDetails.Builder builder)
+            ArrayList<Signature> signatures, int count, boolean isPastSigs,
+            PackageParser.SigningDetails.Builder builder)
             throws IOException, XmlPullParserException {
-        int count = signatures.length;
         int pos = 0;
 
         int outerDepth = parser.getDepth();
@@ -174,6 +171,7 @@
                 if (pos < count) {
                     String index = parser.getAttributeValue(null, "index");
                     if (index != null) {
+                        boolean signatureParsed = false;
                         try {
                             int idx = Integer.parseInt(index);
                             String key = parser.getAttributeValue(null, "key");
@@ -181,7 +179,8 @@
                                 if (idx >= 0 && idx < readSignatures.size()) {
                                     Signature sig = readSignatures.get(idx);
                                     if (sig != null) {
-                                        signatures[pos] = readSignatures.get(idx);
+                                        signatures.add(sig);
+                                        signatureParsed = true;
                                     } else {
                                         PackageManagerService.reportSettingsProblem(Log.WARN,
                                                 "Error in package manager settings: <cert> "
@@ -195,12 +194,15 @@
                                                     + parser.getPositionDescription());
                                 }
                             } else {
-                                while (readSignatures.size() <= idx) {
+                                // Create the signature first to prevent adding null entries to the
+                                // output List if the key value is invalid.
+                                Signature sig = new Signature(key);
+                                while (readSignatures.size() < idx) {
                                     readSignatures.add(null);
                                 }
-                                Signature sig = new Signature(key);
-                                readSignatures.set(idx, sig);
-                                signatures[pos] = sig;
+                                readSignatures.add(sig);
+                                signatures.add(sig);
+                                signatureParsed = true;
                             }
                         } catch (NumberFormatException e) {
                             PackageManagerService.reportSettingsProblem(Log.WARN,
@@ -215,11 +217,22 @@
                                             + e.getMessage());
                         }
 
-                        if (flags != null) {
+                        if (isPastSigs) {
                             String flagsStr = parser.getAttributeValue(null, "flags");
                             if (flagsStr != null) {
                                 try {
-                                    flags[pos] = Integer.parseInt(flagsStr);
+                                    int flagsValue = Integer.parseInt(flagsStr);
+                                    // only modify the flags if the signature of the previous signer
+                                    // was successfully parsed above
+                                    if (signatureParsed) {
+                                        signatures.get(signatures.size() - 1).setFlags(flagsValue);
+                                    } else {
+                                        PackageManagerService.reportSettingsProblem(Log.WARN,
+                                                "Error in package manager settings: signature not "
+                                                        + "available at index "
+                                                        + pos + " to set flags at "
+                                                        + parser.getPositionDescription());
+                                    }
                                 } catch (NumberFormatException e) {
                                     PackageManagerService.reportSettingsProblem(Log.WARN,
                                             "Error in package manager settings: <cert> "
@@ -246,7 +259,7 @@
                 pos++;
                 XmlUtils.skipCurrentTag(parser);
             } else if (tagName.equals("pastSigs")) {
-                if (flags == null) {
+                if (!isPastSigs) {
                     // we haven't encountered pastSigs yet, go ahead
                     String countStr = parser.getAttributeValue(null, "count");
                     if (countStr == null) {
@@ -254,32 +267,23 @@
                                 "Error in package manager settings: <pastSigs> has"
                                         + " no count at " + parser.getPositionDescription());
                         XmlUtils.skipCurrentTag(parser);
+                        continue;
                     }
                     try {
                         final int pastSigsCount = Integer.parseInt(countStr);
-                        Signature[] pastSignatures = new Signature[pastSigsCount];
-                        int[] pastSignaturesFlags = new int[pastSigsCount];
-                        int pastSigsPos = readCertsListXml(parser, readSignatures, pastSignatures,
-                                pastSignaturesFlags, builder);
-                        builder = builder
-                                .setPastSigningCertificates(pastSignatures)
-                                .setPastSigningCertificatesFlags(pastSignaturesFlags);
+                        ArrayList<Signature> pastSignatureList = new ArrayList<>();
+                        int pastSigsPos = readCertsListXml(parser, readSignatures,
+                                pastSignatureList,
+                                pastSigsCount, true, builder);
+                        Signature[] pastSignatures = pastSignatureList.toArray(
+                                new Signature[pastSignatureList.size()]);
+                        builder = builder.setPastSigningCertificates(pastSignatures);
 
                         if (pastSigsPos < pastSigsCount) {
-                            // Should never happen -- there is an error in the written
-                            // settings -- but if it does we don't want to generate
-                            // a bad array.
-                            Signature[] newSigs = new Signature[pastSigsPos];
-                            System.arraycopy(pastSignatures, 0, newSigs, 0, pastSigsPos);
-                            int[] newFlags = new int[pastSigsPos];
-                            System.arraycopy(pastSignaturesFlags, 0, newFlags, 0, pastSigsPos);
-                            builder = builder
-                                    .setPastSigningCertificates(newSigs)
-                                    .setPastSigningCertificatesFlags(newFlags);
                             PackageManagerService.reportSettingsProblem(Log.WARN,
                                     "Error in package manager settings: <pastSigs> count does not "
-                                    + "match number of <cert> entries "
-                                    + parser.getPositionDescription());
+                                            + "match number of <cert> entries "
+                                            + parser.getPositionDescription());
                         }
                     } catch (NumberFormatException e) {
                         PackageManagerService.reportSettingsProblem(Log.WARN,
@@ -326,7 +330,8 @@
                 buf.append(Integer.toHexString(
                         mSigningDetails.pastSigningCertificates[i].hashCode()));
                 buf.append(" flags: ");
-                buf.append(Integer.toHexString(mSigningDetails.pastSigningCertificatesFlags[i]));
+                buf.append(
+                        Integer.toHexString(mSigningDetails.pastSigningCertificates[i].getFlags()));
             }
         }
         buf.append("]}");
diff --git a/services/robotests/src/com/android/server/backup/fullbackup/AppMetadataBackupWriterTest.java b/services/robotests/src/com/android/server/backup/fullbackup/AppMetadataBackupWriterTest.java
index 112e1e3..b771039 100644
--- a/services/robotests/src/com/android/server/backup/fullbackup/AppMetadataBackupWriterTest.java
+++ b/services/robotests/src/com/android/server/backup/fullbackup/AppMetadataBackupWriterTest.java
@@ -183,7 +183,6 @@
                                 new Signature[] {new Signature("1234"), new Signature("5678")},
                                 SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
                                 null,
-                                null,
                                 null));
         File manifestFile = createFile(BACKUP_MANIFEST_FILENAME);
 
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/certs/ec-p256-lineage-2-signers b/services/tests/servicestests/assets/PackageSignaturesTest/certs/ec-p256-lineage-2-signers
new file mode 100644
index 0000000..509ea3b
--- /dev/null
+++ b/services/tests/servicestests/assets/PackageSignaturesTest/certs/ec-p256-lineage-2-signers
Binary files differ
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/certs/ec-p256-lineage-3-signers b/services/tests/servicestests/assets/PackageSignaturesTest/certs/ec-p256-lineage-3-signers
new file mode 100644
index 0000000..bee71c0
--- /dev/null
+++ b/services/tests/servicestests/assets/PackageSignaturesTest/certs/ec-p256-lineage-3-signers
Binary files differ
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/certs/ec-p256.pk8 b/services/tests/servicestests/assets/PackageSignaturesTest/certs/ec-p256.pk8
new file mode 100644
index 0000000..f781c30
--- /dev/null
+++ b/services/tests/servicestests/assets/PackageSignaturesTest/certs/ec-p256.pk8
Binary files differ
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/certs/ec-p256.x509.der b/services/tests/servicestests/assets/PackageSignaturesTest/certs/ec-p256.x509.der
new file mode 100644
index 0000000..e611e3d
--- /dev/null
+++ b/services/tests/servicestests/assets/PackageSignaturesTest/certs/ec-p256.x509.der
Binary files differ
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/certs/ec-p256_2.pk8 b/services/tests/servicestests/assets/PackageSignaturesTest/certs/ec-p256_2.pk8
new file mode 100644
index 0000000..5e73f27
--- /dev/null
+++ b/services/tests/servicestests/assets/PackageSignaturesTest/certs/ec-p256_2.pk8
Binary files differ
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/certs/ec-p256_2.x509.der b/services/tests/servicestests/assets/PackageSignaturesTest/certs/ec-p256_2.x509.der
new file mode 100644
index 0000000..7723bea
--- /dev/null
+++ b/services/tests/servicestests/assets/PackageSignaturesTest/certs/ec-p256_2.x509.der
Binary files differ
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/certs/ec-p256_3.pk8 b/services/tests/servicestests/assets/PackageSignaturesTest/certs/ec-p256_3.pk8
new file mode 100644
index 0000000..d7309dd
--- /dev/null
+++ b/services/tests/servicestests/assets/PackageSignaturesTest/certs/ec-p256_3.pk8
Binary files differ
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/certs/ec-p256_3.x509.der b/services/tests/servicestests/assets/PackageSignaturesTest/certs/ec-p256_3.x509.der
new file mode 100644
index 0000000..cc82af9
--- /dev/null
+++ b/services/tests/servicestests/assets/PackageSignaturesTest/certs/ec-p256_3.x509.der
Binary files differ
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/xml/README b/services/tests/servicestests/assets/PackageSignaturesTest/xml/README
new file mode 100644
index 0000000..43d5bb8
--- /dev/null
+++ b/services/tests/servicestests/assets/PackageSignaturesTest/xml/README
@@ -0,0 +1,58 @@
+The XML files in this directory are taken from the packages tag of a test APK signed with the
+certificates and keys under the certs/ directory. To recreate the XML files run the following:
+
+1. Build the test APK:
+mmm -j cts/hostsidetests/appsecurity/test-apps/tinyapp/
+
+2. Sign the APK with the first signer:
+apksigner sign --in ${OUT}/data/app/CtsPkgInstallTinyApp/CtsPkgInstallTinyApp.apk --out test.apk \
+ --cert certs/ec-p256.x509.der --key certs/ec-p256.pk8
+
+3. Install the APK on a device:
+adb install test.apk
+
+4. Pull the packages.xml file containing the new entry for the APK from the device:
+adb pull /data/system/packages.xml
+
+5. Search the packages.xml file for the package name 'android.appsecurity.cts.tinyapp'. Following is
+   the full entry when the APK is signed as above:
+
+    <package name="android.appsecurity.cts.tinyapp" codePath="/data/app/android.appsecurity.cts.tiny
+    app-4ix3umoWct_iD26jQ03Z_g==" nativeLibraryPath="/data/app/android.appsecurity.cts.tinyapp-4ix3u
+    moWct_iD26jQ03Z_g==/lib" publicFlags="805879364" privateFlags="0" ft="1663710dd00" it="1663710de
+    41" ut="1663710de41" version="10" userId="10051">
+        <sigs count="1" schemeVersion="3">
+            <cert index="16" key="3082016c30820111a003020102020900ca0fb64dfb66e772300a06082a8648ce3d
+            04030230123110300e06035504030c0765632d70323536301e170d3136303333313134353830365a170d3433
+            303831373134353830365a30123110300e06035504030c0765632d703235363059301306072a8648ce3d0201
+            06082a8648ce3d03010703420004a65f113d22cb4913908307ac31ee2ba0e9138b785fac6536d14ea2ce90d2
+            b4bfe194b50cdc8e169f54a73a991ef0fa76329825be078cc782740703da44b4d7eba350304e301d0603551d
+            0e04160414d4133568b95b30158b322071ea8c43ff5b05ccc8301f0603551d23041830168014d4133568b95b
+            30158b322071ea8c43ff5b05ccc8300c0603551d13040530030101ff300a06082a8648ce3d04030203490030
+            46022100f504a0866caef029f417142c5cb71354c79ffcd1d640618dfca4f19e16db78d6022100f8eea48297
+            99c06cad08c6d3d2d2ec05e0574154e747ea0fdbb8042cb655aadd" />
+        </sigs>
+        <proper-signing-keyset identifier="480" />
+    </package>
+
+The PackageSignatures#readXml and writeXml methods read and write everything within the sigs tag.
+The tags and attributes within the sigs tag can be modified and used to verify various good and
+error paths for the PackageSignaturesTest.
+
+Step 2 can be modified to sign with multiple signers by running one of the following commands:
+
+- To sign with two signers in the lineage (after the signing key has been rotated once):
+apksigner sign --in ${OUT}/data/app/CtsPkgInstallTinyApp/CtsPkgInstallTinyApp.apk --out test.apk \
+  --cert certs/ec-p256.x509.der --key certs/ec-p256.pk8 --next-signer --cert \
+  certs/ec-p256_2.x509.der --key certs/ec-p256_2.pk8 --lineage certs/ec-p256-lineage-2-signers
+
+- To sign with three signers in the lineage (after the second key rotation):
+apksigner sign --in ${OUT}/data/app/CtsPkgInstallTinyApp/CtsPkgInstallTinyApp.apk --out test.apk \
+  --cert certs/ec-p256.x509.der --key certs/ec-p256.pk8 --next-signer --cert \
+  certs/ec-p256_3.x509.der --key certs/ec-p256_3.pk8 --lineage certs/ec-p256-lineage-3-signers
+
+- To sign with two distinct signers (NOTE: The V3 signature scheme only supports a single signer,
+  so this method can only be used with signature schemes V1 and V2):
+apksigner sign --in ${OUT}/data/app/CtsPkgInstallTinyApp/CtsPkgInstallTinyApp.apk --out test.apk \
+  --cert certs/ec-p256.x509.der --key certs/ec-p256.pk8 --next-signer --cert \
+  certs/ec-p256_3.x509.der --key certs/ec-p256_3.pk8 --v3-signing-enabled false
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-extra-cert-tag.xml b/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-extra-cert-tag.xml
new file mode 100644
index 0000000..4d55bad
--- /dev/null
+++ b/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-extra-cert-tag.xml
@@ -0,0 +1,5 @@
+        <sigs count="1" schemeVersion="3">
+          <cert index="0" key="3082016c30820111a003020102020900ca0fb64dfb66e772300a06082a8648ce3d04030230123110300e06035504030c0765632d70323536301e170d3136303333313134353830365a170d3433303831373134353830365a30123110300e06035504030c0765632d703235363059301306072a8648ce3d020106082a8648ce3d03010703420004a65f113d22cb4913908307ac31ee2ba0e9138b785fac6536d14ea2ce90d2b4bfe194b50cdc8e169f54a73a991ef0fa76329825be078cc782740703da44b4d7eba350304e301d0603551d0e04160414d4133568b95b30158b322071ea8c43ff5b05ccc8301f0603551d23041830168014d4133568b95b30158b322071ea8c43ff5b05ccc8300c0603551d13040530030101ff300a06082a8648ce3d0403020349003046022100f504a0866caef029f417142c5cb71354c79ffcd1d640618dfca4f19e16db78d6022100f8eea4829799c06cad08c6d3d2d2ec05e0574154e747ea0fdbb8042cb655aadd" />
+            <cert index="0" key="3082016c30820111a003020102020900ca0fb64dfb66e772300a06082a8648ce3d04030230123110300e06035504030c0765632d70323536301e170d3136303333313134353830365a170d3433303831373134353830365a30123110300e06035504030c0765632d703235363059301306072a8648ce3d020106082a8648ce3d03010703420004a65f113d22cb4913908307ac31ee2ba0e9138b785fac6536d14ea2ce90d2b4bfe194b50cdc8e169f54a73a991ef0fa76329825be078cc782740703da44b4d7eba350304e301d0603551d0e04160414d4133568b95b30158b322071ea8c43ff5b05ccc8301f0603551d23041830168014d4133568b95b30158b322071ea8c43ff5b05ccc8300c0603551d13040530030101ff300a06082a8648ce3d0403020349003046022100f504a0866caef029f417142c5cb71354c79ffcd1d640618dfca4f19e16db78d6022100f8eea4829799c06cad08c6d3d2d2ec05e0574154e747ea0fdbb8042cb655aadd" />
+        </sigs>
+
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-invalid-cert-index.xml b/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-invalid-cert-index.xml
new file mode 100644
index 0000000..f7882b1
--- /dev/null
+++ b/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-invalid-cert-index.xml
@@ -0,0 +1,4 @@
+        <sigs count="1" schemeVersion="3">
+            <cert index="x" key="3082016c30820111a003020102020900ca0fb64dfb66e772300a06082a8648ce3d04030230123110300e06035504030c0765632d70323536301e170d3136303333313134353830365a170d3433303831373134353830365a30123110300e06035504030c0765632d703235363059301306072a8648ce3d020106082a8648ce3d03010703420004a65f113d22cb4913908307ac31ee2ba0e9138b785fac6536d14ea2ce90d2b4bfe194b50cdc8e169f54a73a991ef0fa76329825be078cc782740703da44b4d7eba350304e301d0603551d0e04160414d4133568b95b30158b322071ea8c43ff5b05ccc8301f0603551d23041830168014d4133568b95b30158b322071ea8c43ff5b05ccc8300c0603551d13040530030101ff300a06082a8648ce3d0403020349003046022100f504a0866caef029f417142c5cb71354c79ffcd1d640618dfca4f19e16db78d6022100f8eea4829799c06cad08c6d3d2d2ec05e0574154e747ea0fdbb8042cb655aadd" />
+        </sigs>
+
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-invalid-cert-key.xml b/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-invalid-cert-key.xml
new file mode 100644
index 0000000..af2c293
--- /dev/null
+++ b/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-invalid-cert-key.xml
@@ -0,0 +1,4 @@
+        <sigs count="1" schemeVersion="3">
+            <cert index="0" key="082016c30820111a003020102020900ca0fb64dfb66e772300a06082a8648ce3d04030230123110300e06035504030c0765632d70323536301e170d3136303333313134353830365a170d3433303831373134353830365a30123110300e06035504030c0765632d703235363059301306072a8648ce3d020106082a8648ce3d03010703420004a65f113d22cb4913908307ac31ee2ba0e9138b785fac6536d14ea2ce90d2b4bfe194b50cdc8e169f54a73a991ef0fa76329825be078cc782740703da44b4d7eba350304e301d0603551d0e04160414d4133568b95b30158b322071ea8c43ff5b05ccc8301f0603551d23041830168014d4133568b95b30158b322071ea8c43ff5b05ccc8300c0603551d13040530030101ff300a06082a8648ce3d0403020349003046022100f504a0866caef029f417142c5cb71354c79ffcd1d640618dfca4f19e16db78d6022100f8eea4829799c06cad08c6d3d2d2ec05e0574154e747ea0fdbb8042cb655aadd" />
+        </sigs>
+
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-invalid-public-key-cert-key.xml b/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-invalid-public-key-cert-key.xml
new file mode 100644
index 0000000..893402d
--- /dev/null
+++ b/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-invalid-public-key-cert-key.xml
@@ -0,0 +1,4 @@
+        <sigs count="1" schemeVersion="1">
+            <cert index="0" key="4082016c30820111a003020102020900ca0fb64dfb66e772300a06082a8648ce3d04030230123110300e06035504030c0765632d70323536301e170d3136303333313134353830365a170d3433303831373134353830365a30123110300e06035504030c0765632d703235363059301306072a8648ce3d020106082a8648ce3d03010703420004a65f113d22cb4913908307ac31ee2ba0e9138b785fac6536d14ea2ce90d2b4bfe194b50cdc8e169f54a73a991ef0fa76329825be078cc782740703da44b4d7eba350304e301d0603551d0e04160414d4133568b95b30158b322071ea8c43ff5b05ccc8301f0603551d23041830168014d4133568b95b30158b322071ea8c43ff5b05ccc8300c0603551d13040530030101ff300a06082a8648ce3d0403020349003046022100f504a0866caef029f417142c5cb71354c79ffcd1d640618dfca4f19e16db78d6022100f8eea4829799c06cad08c6d3d2d2ec05e0574154e747ea0fdbb8042cb655aadd" />
+        </sigs>
+
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-invalid-tag.xml b/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-invalid-tag.xml
new file mode 100644
index 0000000..1f81dac
--- /dev/null
+++ b/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-invalid-tag.xml
@@ -0,0 +1,5 @@
+        <sigs count="1" schemeVersion="3">
+          <cert index="0" key="3082016c30820111a003020102020900ca0fb64dfb66e772300a06082a8648ce3d04030230123110300e06035504030c0765632d70323536301e170d3136303333313134353830365a170d3433303831373134353830365a30123110300e06035504030c0765632d703235363059301306072a8648ce3d020106082a8648ce3d03010703420004a65f113d22cb4913908307ac31ee2ba0e9138b785fac6536d14ea2ce90d2b4bfe194b50cdc8e169f54a73a991ef0fa76329825be078cc782740703da44b4d7eba350304e301d0603551d0e04160414d4133568b95b30158b322071ea8c43ff5b05ccc8301f0603551d23041830168014d4133568b95b30158b322071ea8c43ff5b05ccc8300c0603551d13040530030101ff300a06082a8648ce3d0403020349003046022100f504a0866caef029f417142c5cb71354c79ffcd1d640618dfca4f19e16db78d6022100f8eea4829799c06cad08c6d3d2d2ec05e0574154e747ea0fdbb8042cb655aadd" />
+          <invalid />
+        </sigs>
+
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-missing-cert-index.xml b/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-missing-cert-index.xml
new file mode 100644
index 0000000..c38e4d9
--- /dev/null
+++ b/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-missing-cert-index.xml
@@ -0,0 +1,4 @@
+        <sigs count="1" schemeVersion="3">
+            <cert key="3082016c30820111a003020102020900ca0fb64dfb66e772300a06082a8648ce3d04030230123110300e06035504030c0765632d70323536301e170d3136303333313134353830365a170d3433303831373134353830365a30123110300e06035504030c0765632d703235363059301306072a8648ce3d020106082a8648ce3d03010703420004a65f113d22cb4913908307ac31ee2ba0e9138b785fac6536d14ea2ce90d2b4bfe194b50cdc8e169f54a73a991ef0fa76329825be078cc782740703da44b4d7eba350304e301d0603551d0e04160414d4133568b95b30158b322071ea8c43ff5b05ccc8301f0603551d23041830168014d4133568b95b30158b322071ea8c43ff5b05ccc8300c0603551d13040530030101ff300a06082a8648ce3d0403020349003046022100f504a0866caef029f417142c5cb71354c79ffcd1d640618dfca4f19e16db78d6022100f8eea4829799c06cad08c6d3d2d2ec05e0574154e747ea0fdbb8042cb655aadd" />
+        </sigs>
+
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-missing-cert-key.xml b/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-missing-cert-key.xml
new file mode 100644
index 0000000..8e8cbcf
--- /dev/null
+++ b/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-missing-cert-key.xml
@@ -0,0 +1,4 @@
+        <sigs count="1" schemeVersion="3">
+          <cert index="0" />
+        </sigs>
+
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-missing-cert-tag.xml b/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-missing-cert-tag.xml
new file mode 100644
index 0000000..57e96a8
--- /dev/null
+++ b/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-missing-cert-tag.xml
@@ -0,0 +1,3 @@
+        <sigs count="1" schemeVersion="3">
+        </sigs>
+
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-missing-scheme-version.xml b/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-missing-scheme-version.xml
new file mode 100644
index 0000000..d9f7a5f
--- /dev/null
+++ b/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-missing-scheme-version.xml
@@ -0,0 +1,4 @@
+        <sigs count="1">
+            <cert index="0" key="3082016c30820111a003020102020900ca0fb64dfb66e772300a06082a8648ce3d04030230123110300e06035504030c0765632d70323536301e170d3136303333313134353830365a170d3433303831373134353830365a30123110300e06035504030c0765632d703235363059301306072a8648ce3d020106082a8648ce3d03010703420004a65f113d22cb4913908307ac31ee2ba0e9138b785fac6536d14ea2ce90d2b4bfe194b50cdc8e169f54a73a991ef0fa76329825be078cc782740703da44b4d7eba350304e301d0603551d0e04160414d4133568b95b30158b322071ea8c43ff5b05ccc8301f0603551d23041830168014d4133568b95b30158b322071ea8c43ff5b05ccc8300c0603551d13040530030101ff300a06082a8648ce3d0403020349003046022100f504a0866caef029f417142c5cb71354c79ffcd1d640618dfca4f19e16db78d6022100f8eea4829799c06cad08c6d3d2d2ec05e0574154e747ea0fdbb8042cb655aadd" />
+        </sigs>
+
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-missing-sigs-count.xml b/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-missing-sigs-count.xml
new file mode 100644
index 0000000..4eefdd9
--- /dev/null
+++ b/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-missing-sigs-count.xml
@@ -0,0 +1,4 @@
+        <sigs schemeVersion="3">
+            <cert index="0" key="3082016c30820111a003020102020900ca0fb64dfb66e772300a06082a8648ce3d04030230123110300e06035504030c0765632d70323536301e170d3136303333313134353830365a170d3433303831373134353830365a30123110300e06035504030c0765632d703235363059301306072a8648ce3d020106082a8648ce3d03010703420004a65f113d22cb4913908307ac31ee2ba0e9138b785fac6536d14ea2ce90d2b4bfe194b50cdc8e169f54a73a991ef0fa76329825be078cc782740703da44b4d7eba350304e301d0603551d0e04160414d4133568b95b30158b322071ea8c43ff5b05ccc8301f0603551d23041830168014d4133568b95b30158b322071ea8c43ff5b05ccc8300c0603551d13040530030101ff300a06082a8648ce3d0403020349003046022100f504a0866caef029f417142c5cb71354c79ffcd1d640618dfca4f19e16db78d6022100f8eea4829799c06cad08c6d3d2d2ec05e0574154e747ea0fdbb8042cb655aadd" />
+        </sigs>
+
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-previous-cert.xml b/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-previous-cert.xml
new file mode 100644
index 0000000..2aeeb71
--- /dev/null
+++ b/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-previous-cert.xml
@@ -0,0 +1,4 @@
+        <sigs count="1" schemeVersion="2">
+          <cert index="0" />
+        </sigs>
+
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer.xml b/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer.xml
new file mode 100644
index 0000000..14471f8
--- /dev/null
+++ b/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer.xml
@@ -0,0 +1,4 @@
+        <sigs count="1" schemeVersion="1">
+            <cert index="0" key="3082016c30820111a003020102020900ca0fb64dfb66e772300a06082a8648ce3d04030230123110300e06035504030c0765632d70323536301e170d3136303333313134353830365a170d3433303831373134353830365a30123110300e06035504030c0765632d703235363059301306072a8648ce3d020106082a8648ce3d03010703420004a65f113d22cb4913908307ac31ee2ba0e9138b785fac6536d14ea2ce90d2b4bfe194b50cdc8e169f54a73a991ef0fa76329825be078cc782740703da44b4d7eba350304e301d0603551d0e04160414d4133568b95b30158b322071ea8c43ff5b05ccc8301f0603551d23041830168014d4133568b95b30158b322071ea8c43ff5b05ccc8300c0603551d13040530030101ff300a06082a8648ce3d0403020349003046022100f504a0866caef029f417142c5cb71354c79ffcd1d640618dfca4f19e16db78d6022100f8eea4829799c06cad08c6d3d2d2ec05e0574154e747ea0fdbb8042cb655aadd" />
+        </sigs>
+
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/xml/three-signers-in-lineage-invalid-pastSigs-count.xml b/services/tests/servicestests/assets/PackageSignaturesTest/xml/three-signers-in-lineage-invalid-pastSigs-count.xml
new file mode 100644
index 0000000..2b2e383
--- /dev/null
+++ b/services/tests/servicestests/assets/PackageSignaturesTest/xml/three-signers-in-lineage-invalid-pastSigs-count.xml
@@ -0,0 +1,9 @@
+        <sigs count="1" schemeVersion="3">
+            <cert index="0" key="3082016e30820115a0030201020209008394f5cad16a89a7300a06082a8648ce3d04030230143112301006035504030c0965632d703235365f32301e170d3138303731343030303532365a170d3238303731313030303532365a30143112301006035504030c0965632d703235365f333059301306072a8648ce3d020106082a8648ce3d03010703420004f31e62430e9db6fc5928d975fc4e47419bacfcb2e07c89299e6cd7e344dd21adfd308d58cb49a1a2a3fecacceea4862069f30be1643bcc255040d8089dfb3743a350304e301d0603551d0e041604146f8d0828b13efaf577fc86b0e99fa3e54bcbcff0301f0603551d230418301680147991d92b0208fc448bf506d4efc9fff428cb5e5f300c0603551d13040530030101ff300a06082a8648ce3d04030203470030440220256bdaa2784c273e4cc291a595a46779dee9de9044dc9f7ab820309567df9fe902201a4ad8c69891b5a8c47434fe9540ed1f4979b5fad3483f3fa04d5677355a579e" />
+            <pastSigs count="x">
+                <cert index="1" key="3082016c30820111a003020102020900ca0fb64dfb66e772300a06082a8648ce3d04030230123110300e06035504030c0765632d70323536301e170d3136303333313134353830365a170d3433303831373134353830365a30123110300e06035504030c0765632d703235363059301306072a8648ce3d020106082a8648ce3d03010703420004a65f113d22cb4913908307ac31ee2ba0e9138b785fac6536d14ea2ce90d2b4bfe194b50cdc8e169f54a73a991ef0fa76329825be078cc782740703da44b4d7eba350304e301d0603551d0e04160414d4133568b95b30158b322071ea8c43ff5b05ccc8301f0603551d23041830168014d4133568b95b30158b322071ea8c43ff5b05ccc8300c0603551d13040530030101ff300a06082a8648ce3d0403020349003046022100f504a0866caef029f417142c5cb71354c79ffcd1d640618dfca4f19e16db78d6022100f8eea4829799c06cad08c6d3d2d2ec05e0574154e747ea0fdbb8042cb655aadd" flags="3" />
+                <cert index="2" key="3082016d30820113a0030201020209008855bd1dd2b2b225300a06082a8648ce3d04030230123110300e06035504030c0765632d70323536301e170d3138303731333137343135315a170d3238303731303137343135315a30143112301006035504030c0965632d703235365f323059301306072a8648ce3d020106082a8648ce3d030107034200041d4cca0472ad97ee3cecef0da93d62b450c6788333b36e7553cde9f74ab5df00bbba6ba950e68461d70bbc271b62151dad2de2bf6203cd2076801c7a9d4422e1a350304e301d0603551d0e041604147991d92b0208fc448bf506d4efc9fff428cb5e5f301f0603551d23041830168014d4133568b95b30158b322071ea8c43ff5b05ccc8300c0603551d13040530030101ff300a06082a8648ce3d040302034800304502202769abb1b49fc2f53479c4ae92a6631dabfd522c9acb0bba2b43ebeb99c63011022100d260fb1d1f176cf9b7fa60098bfd24319f4905a3e5fda100a6fe1a2ab19ff09e" flags="7" />
+                <cert index="0" flags="23" />
+            </pastSigs>
+        </sigs>
+
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/xml/three-signers-in-lineage-missing-pastSigs-cert-tag.xml b/services/tests/servicestests/assets/PackageSignaturesTest/xml/three-signers-in-lineage-missing-pastSigs-cert-tag.xml
new file mode 100644
index 0000000..f992104
--- /dev/null
+++ b/services/tests/servicestests/assets/PackageSignaturesTest/xml/three-signers-in-lineage-missing-pastSigs-cert-tag.xml
@@ -0,0 +1,8 @@
+        <sigs count="1" schemeVersion="3">
+            <cert index="0" key="3082016e30820115a0030201020209008394f5cad16a89a7300a06082a8648ce3d04030230143112301006035504030c0965632d703235365f32301e170d3138303731343030303532365a170d3238303731313030303532365a30143112301006035504030c0965632d703235365f333059301306072a8648ce3d020106082a8648ce3d03010703420004f31e62430e9db6fc5928d975fc4e47419bacfcb2e07c89299e6cd7e344dd21adfd308d58cb49a1a2a3fecacceea4862069f30be1643bcc255040d8089dfb3743a350304e301d0603551d0e041604146f8d0828b13efaf577fc86b0e99fa3e54bcbcff0301f0603551d230418301680147991d92b0208fc448bf506d4efc9fff428cb5e5f300c0603551d13040530030101ff300a06082a8648ce3d04030203470030440220256bdaa2784c273e4cc291a595a46779dee9de9044dc9f7ab820309567df9fe902201a4ad8c69891b5a8c47434fe9540ed1f4979b5fad3483f3fa04d5677355a579e" />
+            <pastSigs count="3">
+                <cert index="1" key="3082016c30820111a003020102020900ca0fb64dfb66e772300a06082a8648ce3d04030230123110300e06035504030c0765632d70323536301e170d3136303333313134353830365a170d3433303831373134353830365a30123110300e06035504030c0765632d703235363059301306072a8648ce3d020106082a8648ce3d03010703420004a65f113d22cb4913908307ac31ee2ba0e9138b785fac6536d14ea2ce90d2b4bfe194b50cdc8e169f54a73a991ef0fa76329825be078cc782740703da44b4d7eba350304e301d0603551d0e04160414d4133568b95b30158b322071ea8c43ff5b05ccc8301f0603551d23041830168014d4133568b95b30158b322071ea8c43ff5b05ccc8300c0603551d13040530030101ff300a06082a8648ce3d0403020349003046022100f504a0866caef029f417142c5cb71354c79ffcd1d640618dfca4f19e16db78d6022100f8eea4829799c06cad08c6d3d2d2ec05e0574154e747ea0fdbb8042cb655aadd" flags="3" />
+                <cert index="0" flags="23" />
+            </pastSigs>
+        </sigs>
+
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/xml/three-signers-in-lineage-missing-pastSigs-count.xml b/services/tests/servicestests/assets/PackageSignaturesTest/xml/three-signers-in-lineage-missing-pastSigs-count.xml
new file mode 100644
index 0000000..6ef0fe5
--- /dev/null
+++ b/services/tests/servicestests/assets/PackageSignaturesTest/xml/three-signers-in-lineage-missing-pastSigs-count.xml
@@ -0,0 +1,9 @@
+        <sigs count="1" schemeVersion="3">
+            <cert index="0" key="3082016e30820115a0030201020209008394f5cad16a89a7300a06082a8648ce3d04030230143112301006035504030c0965632d703235365f32301e170d3138303731343030303532365a170d3238303731313030303532365a30143112301006035504030c0965632d703235365f333059301306072a8648ce3d020106082a8648ce3d03010703420004f31e62430e9db6fc5928d975fc4e47419bacfcb2e07c89299e6cd7e344dd21adfd308d58cb49a1a2a3fecacceea4862069f30be1643bcc255040d8089dfb3743a350304e301d0603551d0e041604146f8d0828b13efaf577fc86b0e99fa3e54bcbcff0301f0603551d230418301680147991d92b0208fc448bf506d4efc9fff428cb5e5f300c0603551d13040530030101ff300a06082a8648ce3d04030203470030440220256bdaa2784c273e4cc291a595a46779dee9de9044dc9f7ab820309567df9fe902201a4ad8c69891b5a8c47434fe9540ed1f4979b5fad3483f3fa04d5677355a579e" />
+            <pastSigs>
+                <cert index="1" key="3082016c30820111a003020102020900ca0fb64dfb66e772300a06082a8648ce3d04030230123110300e06035504030c0765632d70323536301e170d3136303333313134353830365a170d3433303831373134353830365a30123110300e06035504030c0765632d703235363059301306072a8648ce3d020106082a8648ce3d03010703420004a65f113d22cb4913908307ac31ee2ba0e9138b785fac6536d14ea2ce90d2b4bfe194b50cdc8e169f54a73a991ef0fa76329825be078cc782740703da44b4d7eba350304e301d0603551d0e04160414d4133568b95b30158b322071ea8c43ff5b05ccc8301f0603551d23041830168014d4133568b95b30158b322071ea8c43ff5b05ccc8300c0603551d13040530030101ff300a06082a8648ce3d0403020349003046022100f504a0866caef029f417142c5cb71354c79ffcd1d640618dfca4f19e16db78d6022100f8eea4829799c06cad08c6d3d2d2ec05e0574154e747ea0fdbb8042cb655aadd" flags="3" />
+                <cert index="2" key="3082016d30820113a0030201020209008855bd1dd2b2b225300a06082a8648ce3d04030230123110300e06035504030c0765632d70323536301e170d3138303731333137343135315a170d3238303731303137343135315a30143112301006035504030c0965632d703235365f323059301306072a8648ce3d020106082a8648ce3d030107034200041d4cca0472ad97ee3cecef0da93d62b450c6788333b36e7553cde9f74ab5df00bbba6ba950e68461d70bbc271b62151dad2de2bf6203cd2076801c7a9d4422e1a350304e301d0603551d0e041604147991d92b0208fc448bf506d4efc9fff428cb5e5f301f0603551d23041830168014d4133568b95b30158b322071ea8c43ff5b05ccc8300c0603551d13040530030101ff300a06082a8648ce3d040302034800304502202769abb1b49fc2f53479c4ae92a6631dabfd522c9acb0bba2b43ebeb99c63011022100d260fb1d1f176cf9b7fa60098bfd24319f4905a3e5fda100a6fe1a2ab19ff09e" flags="7" />
+                <cert index="0" flags="23" />
+            </pastSigs>
+        </sigs>
+
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/xml/three-signers-in-lineage-missing-scheme-version.xml b/services/tests/servicestests/assets/PackageSignaturesTest/xml/three-signers-in-lineage-missing-scheme-version.xml
new file mode 100644
index 0000000..d98573d
--- /dev/null
+++ b/services/tests/servicestests/assets/PackageSignaturesTest/xml/three-signers-in-lineage-missing-scheme-version.xml
@@ -0,0 +1,9 @@
+        <sigs count="1">
+            <cert index="0" key="3082016e30820115a0030201020209008394f5cad16a89a7300a06082a8648ce3d04030230143112301006035504030c0965632d703235365f32301e170d3138303731343030303532365a170d3238303731313030303532365a30143112301006035504030c0965632d703235365f333059301306072a8648ce3d020106082a8648ce3d03010703420004f31e62430e9db6fc5928d975fc4e47419bacfcb2e07c89299e6cd7e344dd21adfd308d58cb49a1a2a3fecacceea4862069f30be1643bcc255040d8089dfb3743a350304e301d0603551d0e041604146f8d0828b13efaf577fc86b0e99fa3e54bcbcff0301f0603551d230418301680147991d92b0208fc448bf506d4efc9fff428cb5e5f300c0603551d13040530030101ff300a06082a8648ce3d04030203470030440220256bdaa2784c273e4cc291a595a46779dee9de9044dc9f7ab820309567df9fe902201a4ad8c69891b5a8c47434fe9540ed1f4979b5fad3483f3fa04d5677355a579e" />
+            <pastSigs count="3">
+                <cert index="1" key="3082016c30820111a003020102020900ca0fb64dfb66e772300a06082a8648ce3d04030230123110300e06035504030c0765632d70323536301e170d3136303333313134353830365a170d3433303831373134353830365a30123110300e06035504030c0765632d703235363059301306072a8648ce3d020106082a8648ce3d03010703420004a65f113d22cb4913908307ac31ee2ba0e9138b785fac6536d14ea2ce90d2b4bfe194b50cdc8e169f54a73a991ef0fa76329825be078cc782740703da44b4d7eba350304e301d0603551d0e04160414d4133568b95b30158b322071ea8c43ff5b05ccc8301f0603551d23041830168014d4133568b95b30158b322071ea8c43ff5b05ccc8300c0603551d13040530030101ff300a06082a8648ce3d0403020349003046022100f504a0866caef029f417142c5cb71354c79ffcd1d640618dfca4f19e16db78d6022100f8eea4829799c06cad08c6d3d2d2ec05e0574154e747ea0fdbb8042cb655aadd" flags="3" />
+                <cert index="2" key="3082016d30820113a0030201020209008855bd1dd2b2b225300a06082a8648ce3d04030230123110300e06035504030c0765632d70323536301e170d3138303731333137343135315a170d3238303731303137343135315a30143112301006035504030c0965632d703235365f323059301306072a8648ce3d020106082a8648ce3d030107034200041d4cca0472ad97ee3cecef0da93d62b450c6788333b36e7553cde9f74ab5df00bbba6ba950e68461d70bbc271b62151dad2de2bf6203cd2076801c7a9d4422e1a350304e301d0603551d0e041604147991d92b0208fc448bf506d4efc9fff428cb5e5f301f0603551d23041830168014d4133568b95b30158b322071ea8c43ff5b05ccc8300c0603551d13040530030101ff300a06082a8648ce3d040302034800304502202769abb1b49fc2f53479c4ae92a6631dabfd522c9acb0bba2b43ebeb99c63011022100d260fb1d1f176cf9b7fa60098bfd24319f4905a3e5fda100a6fe1a2ab19ff09e" flags="7" />
+                <cert index="0" flags="23" />
+            </pastSigs>
+        </sigs>
+
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/xml/three-signers-in-lineage.xml b/services/tests/servicestests/assets/PackageSignaturesTest/xml/three-signers-in-lineage.xml
new file mode 100644
index 0000000..2ccf5060
--- /dev/null
+++ b/services/tests/servicestests/assets/PackageSignaturesTest/xml/three-signers-in-lineage.xml
@@ -0,0 +1,9 @@
+        <sigs count="1" schemeVersion="3">
+            <cert index="0" key="3082016e30820115a0030201020209008394f5cad16a89a7300a06082a8648ce3d04030230143112301006035504030c0965632d703235365f32301e170d3138303731343030303532365a170d3238303731313030303532365a30143112301006035504030c0965632d703235365f333059301306072a8648ce3d020106082a8648ce3d03010703420004f31e62430e9db6fc5928d975fc4e47419bacfcb2e07c89299e6cd7e344dd21adfd308d58cb49a1a2a3fecacceea4862069f30be1643bcc255040d8089dfb3743a350304e301d0603551d0e041604146f8d0828b13efaf577fc86b0e99fa3e54bcbcff0301f0603551d230418301680147991d92b0208fc448bf506d4efc9fff428cb5e5f300c0603551d13040530030101ff300a06082a8648ce3d04030203470030440220256bdaa2784c273e4cc291a595a46779dee9de9044dc9f7ab820309567df9fe902201a4ad8c69891b5a8c47434fe9540ed1f4979b5fad3483f3fa04d5677355a579e" />
+            <pastSigs count="3">
+                <cert index="1" key="3082016c30820111a003020102020900ca0fb64dfb66e772300a06082a8648ce3d04030230123110300e06035504030c0765632d70323536301e170d3136303333313134353830365a170d3433303831373134353830365a30123110300e06035504030c0765632d703235363059301306072a8648ce3d020106082a8648ce3d03010703420004a65f113d22cb4913908307ac31ee2ba0e9138b785fac6536d14ea2ce90d2b4bfe194b50cdc8e169f54a73a991ef0fa76329825be078cc782740703da44b4d7eba350304e301d0603551d0e04160414d4133568b95b30158b322071ea8c43ff5b05ccc8301f0603551d23041830168014d4133568b95b30158b322071ea8c43ff5b05ccc8300c0603551d13040530030101ff300a06082a8648ce3d0403020349003046022100f504a0866caef029f417142c5cb71354c79ffcd1d640618dfca4f19e16db78d6022100f8eea4829799c06cad08c6d3d2d2ec05e0574154e747ea0fdbb8042cb655aadd" flags="3" />
+                <cert index="2" key="3082016d30820113a0030201020209008855bd1dd2b2b225300a06082a8648ce3d04030230123110300e06035504030c0765632d70323536301e170d3138303731333137343135315a170d3238303731303137343135315a30143112301006035504030c0965632d703235365f323059301306072a8648ce3d020106082a8648ce3d030107034200041d4cca0472ad97ee3cecef0da93d62b450c6788333b36e7553cde9f74ab5df00bbba6ba950e68461d70bbc271b62151dad2de2bf6203cd2076801c7a9d4422e1a350304e301d0603551d0e041604147991d92b0208fc448bf506d4efc9fff428cb5e5f301f0603551d23041830168014d4133568b95b30158b322071ea8c43ff5b05ccc8300c0603551d13040530030101ff300a06082a8648ce3d040302034800304502202769abb1b49fc2f53479c4ae92a6631dabfd522c9acb0bba2b43ebeb99c63011022100d260fb1d1f176cf9b7fa60098bfd24319f4905a3e5fda100a6fe1a2ab19ff09e" flags="7" />
+                <cert index="0" flags="23" />
+            </pastSigs>
+        </sigs>
+
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-in-lineage-invalid-certs-flags.xml b/services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-in-lineage-invalid-certs-flags.xml
new file mode 100644
index 0000000..6d567e9
--- /dev/null
+++ b/services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-in-lineage-invalid-certs-flags.xml
@@ -0,0 +1,8 @@
+        <sigs count="1" schemeVersion="3">
+            <cert index="0" key="3082016d30820113a0030201020209008855bd1dd2b2b225300a06082a8648ce3d04030230123110300e06035504030c0765632d70323536301e170d3138303731333137343135315a170d3238303731303137343135315a30143112301006035504030c0965632d703235365f323059301306072a8648ce3d020106082a8648ce3d030107034200041d4cca0472ad97ee3cecef0da93d62b450c6788333b36e7553cde9f74ab5df00bbba6ba950e68461d70bbc271b62151dad2de2bf6203cd2076801c7a9d4422e1a350304e301d0603551d0e041604147991d92b0208fc448bf506d4efc9fff428cb5e5f301f0603551d23041830168014d4133568b95b30158b322071ea8c43ff5b05ccc8300c0603551d13040530030101ff300a06082a8648ce3d040302034800304502202769abb1b49fc2f53479c4ae92a6631dabfd522c9acb0bba2b43ebeb99c63011022100d260fb1d1f176cf9b7fa60098bfd24319f4905a3e5fda100a6fe1a2ab19ff09e" />
+            <pastSigs count="2">
+                <cert index="1" key="3082016c30820111a003020102020900ca0fb64dfb66e772300a06082a8648ce3d04030230123110300e06035504030c0765632d70323536301e170d3136303333313134353830365a170d3433303831373134353830365a30123110300e06035504030c0765632d703235363059301306072a8648ce3d020106082a8648ce3d03010703420004a65f113d22cb4913908307ac31ee2ba0e9138b785fac6536d14ea2ce90d2b4bfe194b50cdc8e169f54a73a991ef0fa76329825be078cc782740703da44b4d7eba350304e301d0603551d0e04160414d4133568b95b30158b322071ea8c43ff5b05ccc8301f0603551d23041830168014d4133568b95b30158b322071ea8c43ff5b05ccc8300c0603551d13040530030101ff300a06082a8648ce3d0403020349003046022100f504a0866caef029f417142c5cb71354c79ffcd1d640618dfca4f19e16db78d6022100f8eea4829799c06cad08c6d3d2d2ec05e0574154e747ea0fdbb8042cb655aadd" flags="x" />
+                <cert index="0" flags="23" />
+            </pastSigs>
+        </sigs>
+
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-in-lineage-invalid-pastSigs-cert-index.xml b/services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-in-lineage-invalid-pastSigs-cert-index.xml
new file mode 100644
index 0000000..a2146b7
--- /dev/null
+++ b/services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-in-lineage-invalid-pastSigs-cert-index.xml
@@ -0,0 +1,8 @@
+        <sigs count="1" schemeVersion="3">
+            <cert index="0" key="3082016d30820113a0030201020209008855bd1dd2b2b225300a06082a8648ce3d04030230123110300e06035504030c0765632d70323536301e170d3138303731333137343135315a170d3238303731303137343135315a30143112301006035504030c0965632d703235365f323059301306072a8648ce3d020106082a8648ce3d030107034200041d4cca0472ad97ee3cecef0da93d62b450c6788333b36e7553cde9f74ab5df00bbba6ba950e68461d70bbc271b62151dad2de2bf6203cd2076801c7a9d4422e1a350304e301d0603551d0e041604147991d92b0208fc448bf506d4efc9fff428cb5e5f301f0603551d23041830168014d4133568b95b30158b322071ea8c43ff5b05ccc8300c0603551d13040530030101ff300a06082a8648ce3d040302034800304502202769abb1b49fc2f53479c4ae92a6631dabfd522c9acb0bba2b43ebeb99c63011022100d260fb1d1f176cf9b7fa60098bfd24319f4905a3e5fda100a6fe1a2ab19ff09e" />
+            <pastSigs count="2">
+                <cert index="x" key="3082016c30820111a003020102020900ca0fb64dfb66e772300a06082a8648ce3d04030230123110300e06035504030c0765632d70323536301e170d3136303333313134353830365a170d3433303831373134353830365a30123110300e06035504030c0765632d703235363059301306072a8648ce3d020106082a8648ce3d03010703420004a65f113d22cb4913908307ac31ee2ba0e9138b785fac6536d14ea2ce90d2b4bfe194b50cdc8e169f54a73a991ef0fa76329825be078cc782740703da44b4d7eba350304e301d0603551d0e04160414d4133568b95b30158b322071ea8c43ff5b05ccc8301f0603551d23041830168014d4133568b95b30158b322071ea8c43ff5b05ccc8300c0603551d13040530030101ff300a06082a8648ce3d0403020349003046022100f504a0866caef029f417142c5cb71354c79ffcd1d640618dfca4f19e16db78d6022100f8eea4829799c06cad08c6d3d2d2ec05e0574154e747ea0fdbb8042cb655aadd" flags="7" />
+                <cert index="0" flags="0" />
+            </pastSigs>
+        </sigs>
+
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-in-lineage-missing-certs-flags.xml b/services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-in-lineage-missing-certs-flags.xml
new file mode 100644
index 0000000..90a4a84
--- /dev/null
+++ b/services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-in-lineage-missing-certs-flags.xml
@@ -0,0 +1,8 @@
+        <sigs count="1" schemeVersion="3">
+            <cert index="0" key="3082016d30820113a0030201020209008855bd1dd2b2b225300a06082a8648ce3d04030230123110300e06035504030c0765632d70323536301e170d3138303731333137343135315a170d3238303731303137343135315a30143112301006035504030c0965632d703235365f323059301306072a8648ce3d020106082a8648ce3d030107034200041d4cca0472ad97ee3cecef0da93d62b450c6788333b36e7553cde9f74ab5df00bbba6ba950e68461d70bbc271b62151dad2de2bf6203cd2076801c7a9d4422e1a350304e301d0603551d0e041604147991d92b0208fc448bf506d4efc9fff428cb5e5f301f0603551d23041830168014d4133568b95b30158b322071ea8c43ff5b05ccc8300c0603551d13040530030101ff300a06082a8648ce3d040302034800304502202769abb1b49fc2f53479c4ae92a6631dabfd522c9acb0bba2b43ebeb99c63011022100d260fb1d1f176cf9b7fa60098bfd24319f4905a3e5fda100a6fe1a2ab19ff09e" />
+            <pastSigs count="2">
+                <cert index="1" key="3082016c30820111a003020102020900ca0fb64dfb66e772300a06082a8648ce3d04030230123110300e06035504030c0765632d70323536301e170d3136303333313134353830365a170d3433303831373134353830365a30123110300e06035504030c0765632d703235363059301306072a8648ce3d020106082a8648ce3d03010703420004a65f113d22cb4913908307ac31ee2ba0e9138b785fac6536d14ea2ce90d2b4bfe194b50cdc8e169f54a73a991ef0fa76329825be078cc782740703da44b4d7eba350304e301d0603551d0e04160414d4133568b95b30158b322071ea8c43ff5b05ccc8301f0603551d23041830168014d4133568b95b30158b322071ea8c43ff5b05ccc8300c0603551d13040530030101ff300a06082a8648ce3d0403020349003046022100f504a0866caef029f417142c5cb71354c79ffcd1d640618dfca4f19e16db78d6022100f8eea4829799c06cad08c6d3d2d2ec05e0574154e747ea0fdbb8042cb655aadd" />
+                <cert index="0" flags="23" />
+            </pastSigs>
+        </sigs>
+
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-in-lineage-missing-pastSigs-cert-index.xml b/services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-in-lineage-missing-pastSigs-cert-index.xml
new file mode 100644
index 0000000..6525e48
--- /dev/null
+++ b/services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-in-lineage-missing-pastSigs-cert-index.xml
@@ -0,0 +1,8 @@
+        <sigs count="1" schemeVersion="3">
+            <cert index="0" key="3082016d30820113a0030201020209008855bd1dd2b2b225300a06082a8648ce3d04030230123110300e06035504030c0765632d70323536301e170d3138303731333137343135315a170d3238303731303137343135315a30143112301006035504030c0965632d703235365f323059301306072a8648ce3d020106082a8648ce3d030107034200041d4cca0472ad97ee3cecef0da93d62b450c6788333b36e7553cde9f74ab5df00bbba6ba950e68461d70bbc271b62151dad2de2bf6203cd2076801c7a9d4422e1a350304e301d0603551d0e041604147991d92b0208fc448bf506d4efc9fff428cb5e5f301f0603551d23041830168014d4133568b95b30158b322071ea8c43ff5b05ccc8300c0603551d13040530030101ff300a06082a8648ce3d040302034800304502202769abb1b49fc2f53479c4ae92a6631dabfd522c9acb0bba2b43ebeb99c63011022100d260fb1d1f176cf9b7fa60098bfd24319f4905a3e5fda100a6fe1a2ab19ff09e" />
+            <pastSigs count="2">
+                <cert key="3082016c30820111a003020102020900ca0fb64dfb66e772300a06082a8648ce3d04030230123110300e06035504030c0765632d70323536301e170d3136303333313134353830365a170d3433303831373134353830365a30123110300e06035504030c0765632d703235363059301306072a8648ce3d020106082a8648ce3d03010703420004a65f113d22cb4913908307ac31ee2ba0e9138b785fac6536d14ea2ce90d2b4bfe194b50cdc8e169f54a73a991ef0fa76329825be078cc782740703da44b4d7eba350304e301d0603551d0e04160414d4133568b95b30158b322071ea8c43ff5b05ccc8301f0603551d23041830168014d4133568b95b30158b322071ea8c43ff5b05ccc8300c0603551d13040530030101ff300a06082a8648ce3d0403020349003046022100f504a0866caef029f417142c5cb71354c79ffcd1d640618dfca4f19e16db78d6022100f8eea4829799c06cad08c6d3d2d2ec05e0574154e747ea0fdbb8042cb655aadd" flags="7" />
+                <cert flags="0" />
+            </pastSigs>
+        </sigs>
+
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-in-lineage-multiple-pastSigs-tags.xml b/services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-in-lineage-multiple-pastSigs-tags.xml
new file mode 100644
index 0000000..e06892c
--- /dev/null
+++ b/services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-in-lineage-multiple-pastSigs-tags.xml
@@ -0,0 +1,12 @@
+        <sigs count="1" schemeVersion="3">
+            <cert index="0" key="3082016d30820113a0030201020209008855bd1dd2b2b225300a06082a8648ce3d04030230123110300e06035504030c0765632d70323536301e170d3138303731333137343135315a170d3238303731303137343135315a30143112301006035504030c0965632d703235365f323059301306072a8648ce3d020106082a8648ce3d030107034200041d4cca0472ad97ee3cecef0da93d62b450c6788333b36e7553cde9f74ab5df00bbba6ba950e68461d70bbc271b62151dad2de2bf6203cd2076801c7a9d4422e1a350304e301d0603551d0e041604147991d92b0208fc448bf506d4efc9fff428cb5e5f301f0603551d23041830168014d4133568b95b30158b322071ea8c43ff5b05ccc8300c0603551d13040530030101ff300a06082a8648ce3d040302034800304502202769abb1b49fc2f53479c4ae92a6631dabfd522c9acb0bba2b43ebeb99c63011022100d260fb1d1f176cf9b7fa60098bfd24319f4905a3e5fda100a6fe1a2ab19ff09e" />
+            <pastSigs count="2">
+                <cert index="1" key="3082016c30820111a003020102020900ca0fb64dfb66e772300a06082a8648ce3d04030230123110300e06035504030c0765632d70323536301e170d3136303333313134353830365a170d3433303831373134353830365a30123110300e06035504030c0765632d703235363059301306072a8648ce3d020106082a8648ce3d03010703420004a65f113d22cb4913908307ac31ee2ba0e9138b785fac6536d14ea2ce90d2b4bfe194b50cdc8e169f54a73a991ef0fa76329825be078cc782740703da44b4d7eba350304e301d0603551d0e04160414d4133568b95b30158b322071ea8c43ff5b05ccc8301f0603551d23041830168014d4133568b95b30158b322071ea8c43ff5b05ccc8300c0603551d13040530030101ff300a06082a8648ce3d0403020349003046022100f504a0866caef029f417142c5cb71354c79ffcd1d640618dfca4f19e16db78d6022100f8eea4829799c06cad08c6d3d2d2ec05e0574154e747ea0fdbb8042cb655aadd" flags="23" />
+                <cert index="0" flags="23" />
+                <pastSigs count="2">
+                    <cert index="1" key="3082016c30820111a003020102020900ca0fb64dfb66e772300a06082a8648ce3d04030230123110300e06035504030c0765632d70323536301e170d3136303333313134353830365a170d3433303831373134353830365a30123110300e06035504030c0765632d703235363059301306072a8648ce3d020106082a8648ce3d03010703420004a65f113d22cb4913908307ac31ee2ba0e9138b785fac6536d14ea2ce90d2b4bfe194b50cdc8e169f54a73a991ef0fa76329825be078cc782740703da44b4d7eba350304e301d0603551d0e04160414d4133568b95b30158b322071ea8c43ff5b05ccc8301f0603551d23041830168014d4133568b95b30158b322071ea8c43ff5b05ccc8300c0603551d13040530030101ff300a06082a8648ce3d0403020349003046022100f504a0866caef029f417142c5cb71354c79ffcd1d640618dfca4f19e16db78d6022100f8eea4829799c06cad08c6d3d2d2ec05e0574154e747ea0fdbb8042cb655aadd" flags="23" />
+                    <cert index="0" flags="23" />
+                </pastSigs>
+            </pastSigs>
+        </sigs>
+
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-in-lineage-no-caps.xml b/services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-in-lineage-no-caps.xml
new file mode 100644
index 0000000..8081d2e
--- /dev/null
+++ b/services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-in-lineage-no-caps.xml
@@ -0,0 +1,8 @@
+        <sigs count="1" schemeVersion="3">
+            <cert index="0" key="3082016d30820113a0030201020209008855bd1dd2b2b225300a06082a8648ce3d04030230123110300e06035504030c0765632d70323536301e170d3138303731333137343135315a170d3238303731303137343135315a30143112301006035504030c0965632d703235365f323059301306072a8648ce3d020106082a8648ce3d030107034200041d4cca0472ad97ee3cecef0da93d62b450c6788333b36e7553cde9f74ab5df00bbba6ba950e68461d70bbc271b62151dad2de2bf6203cd2076801c7a9d4422e1a350304e301d0603551d0e041604147991d92b0208fc448bf506d4efc9fff428cb5e5f301f0603551d23041830168014d4133568b95b30158b322071ea8c43ff5b05ccc8300c0603551d13040530030101ff300a06082a8648ce3d040302034800304502202769abb1b49fc2f53479c4ae92a6631dabfd522c9acb0bba2b43ebeb99c63011022100d260fb1d1f176cf9b7fa60098bfd24319f4905a3e5fda100a6fe1a2ab19ff09e" />
+            <pastSigs count="2">
+                <cert index="1" key="3082016c30820111a003020102020900ca0fb64dfb66e772300a06082a8648ce3d04030230123110300e06035504030c0765632d70323536301e170d3136303333313134353830365a170d3433303831373134353830365a30123110300e06035504030c0765632d703235363059301306072a8648ce3d020106082a8648ce3d03010703420004a65f113d22cb4913908307ac31ee2ba0e9138b785fac6536d14ea2ce90d2b4bfe194b50cdc8e169f54a73a991ef0fa76329825be078cc782740703da44b4d7eba350304e301d0603551d0e04160414d4133568b95b30158b322071ea8c43ff5b05ccc8301f0603551d23041830168014d4133568b95b30158b322071ea8c43ff5b05ccc8300c0603551d13040530030101ff300a06082a8648ce3d0403020349003046022100f504a0866caef029f417142c5cb71354c79ffcd1d640618dfca4f19e16db78d6022100f8eea4829799c06cad08c6d3d2d2ec05e0574154e747ea0fdbb8042cb655aadd" flags="0" />
+                <cert index="0" flags="7" />
+            </pastSigs>
+        </sigs>
+
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-in-lineage-undefined-pastSigs-index.xml b/services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-in-lineage-undefined-pastSigs-index.xml
new file mode 100644
index 0000000..127000a
--- /dev/null
+++ b/services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-in-lineage-undefined-pastSigs-index.xml
@@ -0,0 +1,8 @@
+        <sigs count="2" schemeVersion="3">
+          <cert index="1" key="3082016c30820111a003020102020900ca0fb64dfb66e772300a06082a8648ce3d04030230123110300e06035504030c0765632d70323536301e170d3136303333313134353830365a170d3433303831373134353830365a30123110300e06035504030c0765632d703235363059301306072a8648ce3d020106082a8648ce3d03010703420004a65f113d22cb4913908307ac31ee2ba0e9138b785fac6536d14ea2ce90d2b4bfe194b50cdc8e169f54a73a991ef0fa76329825be078cc782740703da44b4d7eba350304e301d0603551d0e04160414d4133568b95b30158b322071ea8c43ff5b05ccc8301f0603551d23041830168014d4133568b95b30158b322071ea8c43ff5b05ccc8300c0603551d13040530030101ff300a06082a8648ce3d0403020349003046022100f504a0866caef029f417142c5cb71354c79ffcd1d640618dfca4f19e16db78d6022100f8eea4829799c06cad08c6d3d2d2ec05e0574154e747ea0fdbb8042cb655aadd" />
+            <pastSigs count="2">
+              <cert index="1" flags="23" />
+              <cert index="0" flags="23" />
+            </pastSigs>
+        </sigs>
+
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-in-lineage.xml b/services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-in-lineage.xml
new file mode 100644
index 0000000..6097ea6
--- /dev/null
+++ b/services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-in-lineage.xml
@@ -0,0 +1,8 @@
+        <sigs count="1" schemeVersion="3">
+            <cert index="0" key="3082016d30820113a0030201020209008855bd1dd2b2b225300a06082a8648ce3d04030230123110300e06035504030c0765632d70323536301e170d3138303731333137343135315a170d3238303731303137343135315a30143112301006035504030c0965632d703235365f323059301306072a8648ce3d020106082a8648ce3d030107034200041d4cca0472ad97ee3cecef0da93d62b450c6788333b36e7553cde9f74ab5df00bbba6ba950e68461d70bbc271b62151dad2de2bf6203cd2076801c7a9d4422e1a350304e301d0603551d0e041604147991d92b0208fc448bf506d4efc9fff428cb5e5f301f0603551d23041830168014d4133568b95b30158b322071ea8c43ff5b05ccc8300c0603551d13040530030101ff300a06082a8648ce3d040302034800304502202769abb1b49fc2f53479c4ae92a6631dabfd522c9acb0bba2b43ebeb99c63011022100d260fb1d1f176cf9b7fa60098bfd24319f4905a3e5fda100a6fe1a2ab19ff09e" />
+            <pastSigs count="2">
+                <cert index="1" key="3082016c30820111a003020102020900ca0fb64dfb66e772300a06082a8648ce3d04030230123110300e06035504030c0765632d70323536301e170d3136303333313134353830365a170d3433303831373134353830365a30123110300e06035504030c0765632d703235363059301306072a8648ce3d020106082a8648ce3d03010703420004a65f113d22cb4913908307ac31ee2ba0e9138b785fac6536d14ea2ce90d2b4bfe194b50cdc8e169f54a73a991ef0fa76329825be078cc782740703da44b4d7eba350304e301d0603551d0e04160414d4133568b95b30158b322071ea8c43ff5b05ccc8301f0603551d23041830168014d4133568b95b30158b322071ea8c43ff5b05ccc8300c0603551d13040530030101ff300a06082a8648ce3d0403020349003046022100f504a0866caef029f417142c5cb71354c79ffcd1d640618dfca4f19e16db78d6022100f8eea4829799c06cad08c6d3d2d2ec05e0574154e747ea0fdbb8042cb655aadd" flags="7" />
+                <cert index="0" flags="3" />
+            </pastSigs>
+        </sigs>
+
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-v1v2-missing-cert-tag.xml b/services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-v1v2-missing-cert-tag.xml
new file mode 100644
index 0000000..6ed3be8
--- /dev/null
+++ b/services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-v1v2-missing-cert-tag.xml
@@ -0,0 +1,4 @@
+        <sigs count="2" schemeVersion="1">
+            <cert index="0" key="3082016c30820111a003020102020900ca0fb64dfb66e772300a06082a8648ce3d04030230123110300e06035504030c0765632d70323536301e170d3136303333313134353830365a170d3433303831373134353830365a30123110300e06035504030c0765632d703235363059301306072a8648ce3d020106082a8648ce3d03010703420004a65f113d22cb4913908307ac31ee2ba0e9138b785fac6536d14ea2ce90d2b4bfe194b50cdc8e169f54a73a991ef0fa76329825be078cc782740703da44b4d7eba350304e301d0603551d0e04160414d4133568b95b30158b322071ea8c43ff5b05ccc8301f0603551d23041830168014d4133568b95b30158b322071ea8c43ff5b05ccc8300c0603551d13040530030101ff300a06082a8648ce3d0403020349003046022100f504a0866caef029f417142c5cb71354c79ffcd1d640618dfca4f19e16db78d6022100f8eea4829799c06cad08c6d3d2d2ec05e0574154e747ea0fdbb8042cb655aadd" />
+        </sigs>
+
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-v1v2.xml b/services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-v1v2.xml
new file mode 100644
index 0000000..ee4c4eb
--- /dev/null
+++ b/services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-v1v2.xml
@@ -0,0 +1,5 @@
+        <sigs count="2" schemeVersion="2">
+            <cert index="0" key="3082016c30820111a003020102020900ca0fb64dfb66e772300a06082a8648ce3d04030230123110300e06035504030c0765632d70323536301e170d3136303333313134353830365a170d3433303831373134353830365a30123110300e06035504030c0765632d703235363059301306072a8648ce3d020106082a8648ce3d03010703420004a65f113d22cb4913908307ac31ee2ba0e9138b785fac6536d14ea2ce90d2b4bfe194b50cdc8e169f54a73a991ef0fa76329825be078cc782740703da44b4d7eba350304e301d0603551d0e04160414d4133568b95b30158b322071ea8c43ff5b05ccc8301f0603551d23041830168014d4133568b95b30158b322071ea8c43ff5b05ccc8300c0603551d13040530030101ff300a06082a8648ce3d0403020349003046022100f504a0866caef029f417142c5cb71354c79ffcd1d640618dfca4f19e16db78d6022100f8eea4829799c06cad08c6d3d2d2ec05e0574154e747ea0fdbb8042cb655aadd" />
+            <cert index="1" key="3082016d30820113a0030201020209008855bd1dd2b2b225300a06082a8648ce3d04030230123110300e06035504030c0765632d70323536301e170d3138303731333137343135315a170d3238303731303137343135315a30143112301006035504030c0965632d703235365f323059301306072a8648ce3d020106082a8648ce3d030107034200041d4cca0472ad97ee3cecef0da93d62b450c6788333b36e7553cde9f74ab5df00bbba6ba950e68461d70bbc271b62151dad2de2bf6203cd2076801c7a9d4422e1a350304e301d0603551d0e041604147991d92b0208fc448bf506d4efc9fff428cb5e5f301f0603551d23041830168014d4133568b95b30158b322071ea8c43ff5b05ccc8300c0603551d13040530030101ff300a06082a8648ce3d040302034800304502202769abb1b49fc2f53479c4ae92a6631dabfd522c9acb0bba2b43ebeb99c63011022100d260fb1d1f176cf9b7fa60098bfd24319f4905a3e5fda100a6fe1a2ab19ff09e" />
+        </sigs>
+
diff --git a/services/tests/servicestests/src/com/android/server/backup/utils/AppBackupUtilsTest.java b/services/tests/servicestests/src/com/android/server/backup/utils/AppBackupUtilsTest.java
index 9fcdf2d..d52051eec 100644
--- a/services/tests/servicestests/src/com/android/server/backup/utils/AppBackupUtilsTest.java
+++ b/services/tests/servicestests/src/com/android/server/backup/utils/AppBackupUtilsTest.java
@@ -436,7 +436,6 @@
                         new Signature[] {SIGNATURE_1},
                         PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
                         null,
-                        null,
                         null));
         packageInfo.applicationInfo = new ApplicationInfo();
 
@@ -456,7 +455,6 @@
                         new Signature[] {SIGNATURE_1},
                         PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
                         null,
-                        null,
                         null));
         packageInfo.applicationInfo = new ApplicationInfo();
 
@@ -537,7 +535,6 @@
                         new Signature[] {SIGNATURE_1, SIGNATURE_2, SIGNATURE_3},
                         PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
                         null,
-                        null,
                         null));
         packageInfo.applicationInfo = new ApplicationInfo();
 
@@ -560,7 +557,6 @@
                         new Signature[] {SIGNATURE_1, SIGNATURE_2, SIGNATURE_3},
                         PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
                         null,
-                        null,
                         null));
         packageInfo.applicationInfo = new ApplicationInfo();
 
@@ -583,7 +579,6 @@
                         new Signature[] {signature1Copy, signature2Copy},
                         PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
                         null,
-                        null,
                         null));
         packageInfo.applicationInfo = new ApplicationInfo();
 
@@ -606,7 +601,6 @@
                         new Signature[] {SIGNATURE_1, SIGNATURE_2, SIGNATURE_3},
                         PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
                         null,
-                        null,
                         null));
         packageInfo.applicationInfo = new ApplicationInfo();
 
@@ -629,7 +623,6 @@
                         new Signature[] {SIGNATURE_1},
                         PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
                         null,
-                        null,
                         null));
         packageInfo.applicationInfo = new ApplicationInfo();
 
@@ -654,8 +647,7 @@
                         new Signature[] {SIGNATURE_2},
                         PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
                         null,
-                        new Signature[] {SIGNATURE_1, SIGNATURE_2},
-                        new int[] {0, 0}));
+                        new Signature[] {SIGNATURE_1, SIGNATURE_2}));
         packageInfo.applicationInfo = new ApplicationInfo();
 
         // we know signature1Copy is in history, and we want to assume it has
@@ -682,8 +674,7 @@
                         new Signature[] {SIGNATURE_2},
                         PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
                         null,
-                        new Signature[] {SIGNATURE_1, SIGNATURE_2},
-                        new int[] {0, 0}));
+                        new Signature[] {SIGNATURE_1, SIGNATURE_2}));
         packageInfo.applicationInfo = new ApplicationInfo();
 
         // we know signature1Copy is in history, but we want to assume it does not have
diff --git a/services/tests/servicestests/src/com/android/server/backup/utils/TarBackupReaderTest.java b/services/tests/servicestests/src/com/android/server/backup/utils/TarBackupReaderTest.java
index 12f2991..4774985 100644
--- a/services/tests/servicestests/src/com/android/server/backup/utils/TarBackupReaderTest.java
+++ b/services/tests/servicestests/src/com/android/server/backup/utils/TarBackupReaderTest.java
@@ -377,7 +377,6 @@
                         new Signature[] {FAKE_SIGNATURE_2},
                         PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
                         null,
-                        null,
                         null));
         PackageManagerStub.sPackageInfo = packageInfo;
 
@@ -414,7 +413,6 @@
                         new Signature[] {FAKE_SIGNATURE_1},
                         PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
                         null,
-                        null,
                         null));
         PackageManagerStub.sPackageInfo = packageInfo;
 
@@ -452,7 +450,6 @@
                         new Signature[] {FAKE_SIGNATURE_1},
                         PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
                         null,
-                        null,
                         null));
         PackageManagerStub.sPackageInfo = packageInfo;
 
@@ -493,7 +490,6 @@
                         new Signature[] {FAKE_SIGNATURE_1},
                         PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
                         null,
-                        null,
                         null));
         packageInfo.versionCode = 2;
         PackageManagerStub.sPackageInfo = packageInfo;
@@ -537,7 +533,6 @@
                         new Signature[] {FAKE_SIGNATURE_1},
                         PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
                         null,
-                        null,
                         null));
         packageInfo.versionCode = 1;
         PackageManagerStub.sPackageInfo = packageInfo;
@@ -577,7 +572,6 @@
                         new Signature[] {FAKE_SIGNATURE_1},
                         PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
                         null,
-                        null,
                         null));
         packageInfo.versionCode = 1;
         PackageManagerStub.sPackageInfo = packageInfo;
diff --git a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
index 2de5d87..a3348c2 100644
--- a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
@@ -1052,7 +1052,6 @@
                         genSignatures(signatures),
                         PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
                         null,
-                        null,
                         null));
         return pi;
     }
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java b/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java
index 318ed3a..9af7b1c 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java
@@ -504,7 +504,6 @@
                         new Signature[] { new Signature(new byte[16]) },
                         2,
                         new ArraySet<>(),
-                        null,
                         null);
         pkg.mExtras = new Bundle();
         pkg.mRestrictedAccountType = "foo19";
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageSignaturesTest.java b/services/tests/servicestests/src/com/android/server/pm/PackageSignaturesTest.java
new file mode 100644
index 0000000..d3a77d3
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageSignaturesTest.java
@@ -0,0 +1,474 @@
+/*
+ * Copyright (C) 2018 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.server.pm;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import android.content.Context;
+import android.content.pm.PackageParser;
+import android.content.pm.Signature;
+import android.util.Xml;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.internal.util.HexDump;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.xmlpull.v1.XmlPullParser;
+
+import java.io.File;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+@RunWith(AndroidJUnit4.class)
+public class PackageSignaturesTest {
+    private static final String TEST_RESOURCES_FOLDER = "PackageSignaturesTest";
+
+    private Context mContext;
+
+    private PackageSetting mPackageSetting;
+
+    // These signatures are the DER encoding of the ec-p256[_X] X509 certificates in the certs/
+    // directory. The apksigner tool was used to sign a test APK with these certificates and the
+    // corresponding ec-p256{_X].pk8 private key file. For the lineage tests the
+    // ec-p256-lineage-X-signers file was provided as the parameter to the --lineage option when
+    // signing the APK. The APK was then installed on a test device, the packages.xml file was
+    // pulled from the device, and the APK's <sig> tag was used as the basis for these tests.
+    // For more details see the README under the xml/ directory.
+    private static final String FIRST_EXPECTED_SIGNATURE =
+            "3082016c30820111a003020102020900ca0fb64dfb66e772300a06082a8648ce3d04030230123110300e06"
+            + "035504030c0765632d70323536301e170d3136303333313134353830365a170d34333038313731343538"
+            + "30365a30123110300e06035504030c0765632d703235363059301306072a8648ce3d020106082a8648ce"
+            + "3d03010703420004a65f113d22cb4913908307ac31ee2ba0e9138b785fac6536d14ea2ce90d2b4bfe194"
+            + "b50cdc8e169f54a73a991ef0fa76329825be078cc782740703da44b4d7eba350304e301d0603551d0e04"
+            + "160414d4133568b95b30158b322071ea8c43ff5b05ccc8301f0603551d23041830168014d4133568b95b"
+            + "30158b322071ea8c43ff5b05ccc8300c0603551d13040530030101ff300a06082a8648ce3d0403020349"
+            + "003046022100f504a0866caef029f417142c5cb71354c79ffcd1d640618dfca4f19e16db78d6022100f8"
+            + "eea4829799c06cad08c6d3d2d2ec05e0574154e747ea0fdbb8042cb655aadd";
+    private static final String SECOND_EXPECTED_SIGNATURE =
+            "3082016d30820113a0030201020209008855bd1dd2b2b225300a06082a8648ce3d04030230123110300e06"
+            + "035504030c0765632d70323536301e170d3138303731333137343135315a170d32383037313031373431"
+            + "35315a30143112301006035504030c0965632d703235365f323059301306072a8648ce3d020106082a86"
+            + "48ce3d030107034200041d4cca0472ad97ee3cecef0da93d62b450c6788333b36e7553cde9f74ab5df00"
+            + "bbba6ba950e68461d70bbc271b62151dad2de2bf6203cd2076801c7a9d4422e1a350304e301d0603551d"
+            + "0e041604147991d92b0208fc448bf506d4efc9fff428cb5e5f301f0603551d23041830168014d4133568"
+            + "b95b30158b322071ea8c43ff5b05ccc8300c0603551d13040530030101ff300a06082a8648ce3d040302"
+            + "034800304502202769abb1b49fc2f53479c4ae92a6631dabfd522c9acb0bba2b43ebeb99c63011022100"
+            + "d260fb1d1f176cf9b7fa60098bfd24319f4905a3e5fda100a6fe1a2ab19ff09e";
+    private static final String THIRD_EXPECTED_SIGNATURE =
+            "3082016e30820115a0030201020209008394f5cad16a89a7300a06082a8648ce3d04030230143112301006"
+            + "035504030c0965632d703235365f32301e170d3138303731343030303532365a170d3238303731313030"
+            + "303532365a30143112301006035504030c0965632d703235365f333059301306072a8648ce3d02010608"
+            + "2a8648ce3d03010703420004f31e62430e9db6fc5928d975fc4e47419bacfcb2e07c89299e6cd7e344dd"
+            + "21adfd308d58cb49a1a2a3fecacceea4862069f30be1643bcc255040d8089dfb3743a350304e301d0603"
+            + "551d0e041604146f8d0828b13efaf577fc86b0e99fa3e54bcbcff0301f0603551d230418301680147991"
+            + "d92b0208fc448bf506d4efc9fff428cb5e5f300c0603551d13040530030101ff300a06082a8648ce3d04"
+            + "030203470030440220256bdaa2784c273e4cc291a595a46779dee9de9044dc9f7ab820309567df9fe902"
+            + "201a4ad8c69891b5a8c47434fe9540ed1f4979b5fad3483f3fa04d5677355a579e";
+
+    // When running tests using the pastSigs tag / lineage the past signers and their capabilities
+    // should be returned in the SigningDetails. The flags attribute of the cert tag under the
+    // pastSigs tag contains these capabilities; for tests that verify the lineage the capabilities
+    // of the signers should be set to the values in this Map.
+    private static final Map<String, Integer> SIGNATURE_TO_CAPABILITY_MAP;
+
+    static {
+        SIGNATURE_TO_CAPABILITY_MAP = new HashMap<>();
+        SIGNATURE_TO_CAPABILITY_MAP.put(FIRST_EXPECTED_SIGNATURE, 3);
+        SIGNATURE_TO_CAPABILITY_MAP.put(SECOND_EXPECTED_SIGNATURE, 7);
+        SIGNATURE_TO_CAPABILITY_MAP.put(THIRD_EXPECTED_SIGNATURE, 23);
+    }
+
+    private static final int[] CAPABILITIES =
+            {PackageParser.SigningDetails.CertCapabilities.INSTALLED_DATA,
+                    PackageParser.SigningDetails.CertCapabilities.SHARED_USER_ID,
+                    PackageParser.SigningDetails.CertCapabilities.PERMISSION,
+                    PackageParser.SigningDetails.CertCapabilities.ROLLBACK};
+
+    @Before
+    public void setUp() throws Exception {
+        mContext = InstrumentationRegistry.getContext();
+        mPackageSetting = createPackageSetting();
+    }
+
+    @Test
+    public void testReadXmlWithOneSignerCompletesSuccessfully() throws Exception {
+        // Verifies the good path of reading a single sigs tag with one signer returns the
+        // expected signature and scheme version.
+        verifyReadXmlReturnsExpectedSignatures("xml/one-signer.xml", 1, FIRST_EXPECTED_SIGNATURE);
+    }
+
+    @Test
+    public void testReadXmlWithTwoV1V2Signers() throws Exception {
+        // Verifies the good path of reading a single sigs tag with multiple signers returns the
+        // expected signatures and scheme version.
+        verifyReadXmlReturnsExpectedSignatures("xml/two-signers-v1v2.xml", 2,
+                FIRST_EXPECTED_SIGNATURE, SECOND_EXPECTED_SIGNATURE);
+    }
+
+    @Test
+    public void testReadXmlFromTwoSigsTagsWithSameSigner() throws Exception {
+        // Verifies the good path of reading two separate packages tags from the same signer. The
+        // first call to readXml should return the list with the expected signature, then the second
+        // call should reference this signature and complete successfully with no new entries in the
+        // List.
+        XmlPullParser parser = getXMLFromResources("xml/one-signer.xml");
+        ArrayList<Signature> signatures = new ArrayList<>();
+        mPackageSetting.signatures.readXml(parser, signatures);
+        Set<String> expectedSignatures = createSetOfSignatures(FIRST_EXPECTED_SIGNATURE);
+        verifySignaturesContainExpectedValues(signatures, expectedSignatures);
+        parser = getXMLFromResources("xml/one-signer-previous-cert.xml");
+        mPackageSetting.signatures.readXml(parser, signatures);
+        expectedSignatures = createSetOfSignatures(FIRST_EXPECTED_SIGNATURE);
+        verifySignaturesContainExpectedValues(signatures, expectedSignatures);
+    }
+
+    @Test
+    public void testReadXmlWithSigningLineage() throws Exception {
+        // Verifies the good path of reading a single sigs tag including pastSigs with the
+        // signing lineage returns the expected signatures and lineage for two and three signers
+        // in the lineage.
+        verifyReadXmlReturnsExpectedSignaturesAndLineage("xml/two-signers-in-lineage.xml", 3,
+                FIRST_EXPECTED_SIGNATURE, SECOND_EXPECTED_SIGNATURE);
+        verifyReadXmlReturnsExpectedSignaturesAndLineage("xml/three-signers-in-lineage.xml", 3,
+                FIRST_EXPECTED_SIGNATURE, SECOND_EXPECTED_SIGNATURE, THIRD_EXPECTED_SIGNATURE);
+    }
+
+    @Test
+    public void testReadXmlWithInvalidPublicKeyInCertKey() throws Exception {
+        // If the cert tag key attribute does not contain a valid public key then a
+        // CertificateException should be thrown when attempting to build the SigningDetails; in
+        // this case the signing details should be set to UNKNOWN.
+        XmlPullParser parser = getXMLFromResources(
+                "xml/one-signer-invalid-public-key-cert-key.xml");
+        ArrayList<Signature> signatures = new ArrayList<>();
+        mPackageSetting.signatures.readXml(parser, signatures);
+        assertEquals(
+                "The signing details was not UNKNOWN after parsing an invalid public key cert key"
+                        + " attribute",
+                PackageParser.SigningDetails.UNKNOWN, mPackageSetting.signatures.mSigningDetails);
+    }
+
+    @Test
+    public void testReadXmlWithMissingSigsCount() throws Exception {
+        // Verifies if the sigs count attribute is missing then the signature cannot be read but the
+        // method does not throw an exception.
+        verifyReadXmlReturnsExpectedSignatures("xml/one-signer-missing-sigs-count.xml",
+                PackageParser.SigningDetails.SignatureSchemeVersion.UNKNOWN);
+    }
+
+    @Test
+    public void testReadXmlWithMissingSchemeVersion() throws Exception {
+        // Verifies if the schemeVersion is an invalid value the signature can still be obtained.
+        verifyReadXmlReturnsExpectedSignatures("xml/one-signer-missing-scheme-version.xml",
+                PackageParser.SigningDetails.SignatureSchemeVersion.UNKNOWN,
+                FIRST_EXPECTED_SIGNATURE);
+    }
+
+    @Test
+    public void testReadXmlWithSigningLineageWithMissingSchemeVersion() throws Exception {
+        // Verifies if the scheme version cannot be read the signers in the lineage can still be
+        // obtained.
+        verifyReadXmlReturnsExpectedSignaturesAndLineage(
+                "xml/three-signers-in-lineage-missing-scheme-version.xml",
+                PackageParser.SigningDetails.SignatureSchemeVersion.UNKNOWN,
+                FIRST_EXPECTED_SIGNATURE, SECOND_EXPECTED_SIGNATURE, THIRD_EXPECTED_SIGNATURE);
+    }
+
+    @Test
+    public void testReadXmlWithInvalidCertIndex() throws Exception {
+        // If the cert index attribute is invalid the signature will not be read but the call
+        // should exit gracefully.
+        verifyReadXmlReturnsExpectedSignatures("xml/one-signer-invalid-cert-index.xml", 3);
+    }
+
+    @Test
+    public void testReadXmlWithMissingCertIndex() throws Exception {
+        // If the cert index attribute is missing the signature will not be read but the call should
+        // exit gracefully.
+        verifyReadXmlReturnsExpectedSignatures("xml/one-signer-missing-cert-index.xml", 3);
+    }
+
+    @Test
+    public void testReadXmlWithInvalidCertKey() throws Exception {
+        // If the cert key value is invalid the signature cannot be read but the call should exit
+        // gracefully.
+        verifyReadXmlReturnsExpectedSignatures("xml/one-signer-invalid-cert-key.xml", 3);
+    }
+
+    @Test
+    public void testReadXmlWithMissingCertKey() throws Exception {
+        // If the cert key is missing the signature cannot be read but the call should exit
+        // gracefully.
+        verifyReadXmlReturnsExpectedSignatures("xml/one-signer-missing-cert-key.xml", 3);
+    }
+
+    @Test
+    public void testReadXmlWithMissingCertTag() throws Exception {
+        // If the cert tag is missing there is no signature to read but the call should exit
+        // gracefully.
+        verifyReadXmlReturnsExpectedSignatures("xml/one-signer-missing-cert-tag.xml", 3);
+    }
+
+    @Test
+    public void testReadXmlWithTooFewCertTags() throws Exception {
+        // If the number of cert tags is less than that specified in the count attribute then the
+        // signatures that could be read are copied to a smaller array to be used when building
+        // the SigningDetails object. This test verifies if there are too few cert tags the
+        // available signatures can still be obtained.
+        verifyReadXmlReturnsExpectedSignatures("xml/two-signers-v1v2-missing-cert-tag.xml", 1,
+                FIRST_EXPECTED_SIGNATURE);
+    }
+
+    @Test
+    public void testReadXmlWithExtraCertTag() throws Exception {
+        // Verifies if there are more cert tags than specified by the count attribute the extra cert
+        // tag is ignored and the expected signature from the first cert tag is returned.
+        verifyReadXmlReturnsExpectedSignatures("xml/one-signer-extra-cert-tag.xml", 3,
+                FIRST_EXPECTED_SIGNATURE);
+    }
+
+    @Test
+    public void testReadXmlWithInvalidTag() throws Exception {
+        // Verifies an invalid tag under sigs is ignored and the expected signature is returned.
+        verifyReadXmlReturnsExpectedSignatures("xml/one-signer-invalid-tag.xml", 3,
+                FIRST_EXPECTED_SIGNATURE);
+    }
+
+    @Test
+    public void testReadXmlWithInvalidPastSigsCount() throws Exception {
+        // Verifies if the pastSigs tag contains an invalid count attribute the current signature
+        // is still returned; in this case the third expected signature is the most recent signer.
+        verifyReadXmlReturnsExpectedSignatures(
+                "xml/three-signers-in-lineage-invalid-pastSigs-count.xml", 3,
+                THIRD_EXPECTED_SIGNATURE);
+    }
+
+    @Test
+    public void testReadXmlWithMissingPastSigsCount() throws Exception {
+        // Verifies if the pastSigs tag is missing the count attribute the current signature is
+        // still returned; in this case the third expected signature is the most recent signer.
+        verifyReadXmlReturnsExpectedSignaturesAndLineage(
+                "xml/three-signers-in-lineage-missing-pastSigs-count.xml", 3,
+                THIRD_EXPECTED_SIGNATURE);
+    }
+
+    @Test
+    public void testReadXmlWithInvalidCertFlags() throws Exception {
+        // Verifies if the cert tag contains an invalid flags attribute the expected signatures
+        // are still returned, although since the flags could not be read these signatures will not
+        // include the capabilities of the previous signers in the lineage.
+        verifyReadXmlReturnsExpectedSignatures("xml/two-signers-in-lineage-invalid-certs-flags.xml",
+                3, FIRST_EXPECTED_SIGNATURE, SECOND_EXPECTED_SIGNATURE);
+    }
+
+    @Test
+    public void testReadXmlWithMissingCertFlags() throws Exception {
+        // Verifies if the cert tag does not contain a flags attribute the expected signatures are
+        // still returned, although since there are no flags to read these signatures will not
+        // include the capabilities of the previous signers in the lineage.
+        verifyReadXmlReturnsExpectedSignatures("xml/two-signers-in-lineage-missing-certs-flags.xml",
+                3, FIRST_EXPECTED_SIGNATURE, SECOND_EXPECTED_SIGNATURE);
+    }
+
+    @Test
+    public void testReadXmlWithMultiplePastSigsTags() throws Exception {
+        // Verifies if multiple pastSigs tags are found under the sigs tag the additional pastSigs
+        // tag is ignored and the expected signatures are returned along with the previous signer in
+        // the lineage.
+        verifyReadXmlReturnsExpectedSignaturesAndLineage(
+                "xml/two-signers-in-lineage-multiple-pastSigs-tags.xml", 3,
+                FIRST_EXPECTED_SIGNATURE, SECOND_EXPECTED_SIGNATURE);
+    }
+
+    @Test
+    public void testReadXmlWithInvalidPastSigsCertIndex() throws Exception {
+        // If the pastSigs cert tag contains an invalid index attribute that signature cannot be
+        // read but the current signature should still be returned.
+        verifyReadXmlReturnsExpectedSignaturesAndLineage(
+                "xml/two-signers-in-lineage-invalid-pastSigs-cert-index.xml", 3,
+                SECOND_EXPECTED_SIGNATURE);
+    }
+
+    @Test
+    public void testReadXmlWithMissingPastSigsCertIndex() throws Exception {
+        // If the pastSigs cert tag does not contain an index attribute that signature cannot be
+        // read but the current signature should still be returned.
+        verifyReadXmlReturnsExpectedSignaturesAndLineage(
+                "xml/two-signers-in-lineage-missing-pastSigs-cert-index.xml", 3,
+                SECOND_EXPECTED_SIGNATURE);
+    }
+
+    @Test
+    public void testReadXmlWithUndefinedPastSigsIndex() throws Exception {
+        // If a cert tag does not contain a key attribute it is assumed that the index attribute
+        // refers to a previously seen signature. If a signature does not yet exist at this index
+        // then the current signature cannot be read but any other signatures should still be
+        // returned.
+        verifyReadXmlReturnsExpectedSignatures(
+                "xml/two-signers-in-lineage-undefined-pastSigs-index.xml", 3,
+                FIRST_EXPECTED_SIGNATURE, null);
+    }
+
+    @Test
+    public void testReadXmlWithTooFewPastSigsCertTags() throws Exception {
+        // If the number of cert tags is less than that specified in the count attribute of the
+        // pastSigs tag then the signatures that could be read are copied to a smaller array to be
+        // used when building the SigningDetails object. This test verifies if there are too few
+        // cert tags the available signatures and lineage can still be obtained.
+        verifyReadXmlReturnsExpectedSignaturesAndLineage(
+                "xml/three-signers-in-lineage-missing-pastSigs-cert-tag.xml", 3,
+                FIRST_EXPECTED_SIGNATURE, THIRD_EXPECTED_SIGNATURE);
+    }
+
+    @Test
+    public void testReadXmlWithPastSignerWithNoCapabilities() throws Exception {
+        // When rotating the signing key a developer is able to specify the capabilities granted to
+        // the apps signed with the previous key. This test verifies a previous signing certificate
+        // with the flags set to 0 does not have any capabilities.
+        XmlPullParser parser = getXMLFromResources("xml/two-signers-in-lineage-no-caps.xml");
+        ArrayList<Signature> signatures = new ArrayList<>();
+        mPackageSetting.signatures.readXml(parser, signatures);
+        // obtain the Signature in the list matching the previous signing certificate
+        Signature previousSignature = null;
+        for (Signature signature : signatures) {
+            String signatureValue = HexDump.toHexString(signature.toByteArray(), false);
+            if (signatureValue.equals(FIRST_EXPECTED_SIGNATURE)) {
+                previousSignature = signature;
+                break;
+            }
+        }
+        assertNotNull("Unable to find the expected previous signer", previousSignature);
+        for (int capability : CAPABILITIES) {
+            assertFalse("The previous signer should not have the " + capability + " capability",
+                    mPackageSetting.signatures.mSigningDetails.hasCertificate(previousSignature,
+                            capability));
+        }
+    }
+
+    /**
+     * Verifies reading the sigs tag of the provided XML file returns the specified signature scheme
+     * version and the provided signatures.
+     */
+    private void verifyReadXmlReturnsExpectedSignatures(String xmlFile, int expectedSchemeVersion,
+            String... expectedSignatureValues) throws Exception {
+        XmlPullParser parser = getXMLFromResources(xmlFile);
+        ArrayList<Signature> signatures = new ArrayList<>();
+        mPackageSetting.signatures.readXml(parser, signatures);
+        Set<String> expectedSignatures = createSetOfSignatures(expectedSignatureValues);
+        verifySignaturesContainExpectedValues(signatures, expectedSignatures);
+        assertEquals("The returned signature scheme is not the expected value",
+                expectedSchemeVersion,
+                mPackageSetting.signatures.mSigningDetails.signatureSchemeVersion);
+    }
+
+    /**
+     * Verifies reading the sigs tag of the provided XML file returns the specified signature scheme
+     * version, the provided signatures, and that the previous signers have the expected
+     * capabilities.
+     */
+    private void verifyReadXmlReturnsExpectedSignaturesAndLineage(String xmlFile,
+            int schemeVersion, String... expectedSignatureValues) throws Exception {
+        XmlPullParser parser = getXMLFromResources(xmlFile);
+        ArrayList<Signature> signatures = new ArrayList<>();
+        mPackageSetting.signatures.readXml(parser, signatures);
+        Set<String> expectedSignatures = createSetOfSignatures(expectedSignatureValues);
+        verifySignaturesContainExpectedValues(signatures, expectedSignatures);
+        assertEquals("The returned signature scheme is not the expected value", schemeVersion,
+                mPackageSetting.signatures.mSigningDetails.signatureSchemeVersion);
+        for (Signature signature : signatures) {
+            String signatureValue = HexDump.toHexString(signature.toByteArray(), false);
+            int expectedCapabilities = SIGNATURE_TO_CAPABILITY_MAP.get(signatureValue);
+            assertTrue("The signature " + signatureValue
+                            + " was not found with the expected capabilities of " +
+                            expectedCapabilities
+                            + " in the signing details",
+                    mPackageSetting.signatures.mSigningDetails.hasCertificate(signature,
+                            expectedCapabilities));
+        }
+    }
+
+    /**
+     * Verifies the provided {@code List} contains Signatures that match the provided hex encoded
+     * signature values.
+     *
+     * The provided {@code Set} will be modified by this method as elements will be removed to
+     * ensure duplicate expected Signatures are not in the {@code List}.
+     */
+    private static void verifySignaturesContainExpectedValues(ArrayList<Signature> signatures,
+            Set<String> expectedSignatures) {
+        assertEquals("The number of signatures does not equal the expected number of signatures",
+                expectedSignatures.size(), signatures.size());
+        for (Signature signature : signatures) {
+            String signatureString = null;
+            if (signature != null) {
+                signatureString = HexDump.toHexString(signature.toByteArray(), false);
+            }
+            // If the signature is in the expected set then remove it so that duplicate matching
+            // signatures are reported.
+            if (expectedSignatures.contains(signatureString)) {
+                expectedSignatures.remove(signatureString);
+            } else {
+                fail("The following unexpected signature was returned: " + signatureString);
+            }
+        }
+    }
+
+    private static Set<String> createSetOfSignatures(String... signatures) {
+        Set<String> result = new HashSet<String>();
+        for (String signature : signatures) {
+            result.add(signature);
+        }
+        return result;
+    }
+
+    private XmlPullParser getXMLFromResources(String xmlFile) throws Exception {
+        InputStream xmlStream = mContext.getResources().getAssets().open(
+                TEST_RESOURCES_FOLDER + "/" + xmlFile);
+        XmlPullParser result = Xml.newPullParser();
+        result.setInput(xmlStream, StandardCharsets.UTF_8.name());
+        int type;
+        // advance the parser to the first tag
+        while ((type = result.next()) != XmlPullParser.START_TAG
+                && type != XmlPullParser.END_DOCUMENT) {
+            ;
+        }
+        return result;
+    }
+
+    private static PackageSetting createPackageSetting() {
+        // Generic PackageSetting object with values from a test app installed on a device to be
+        // used to test the methods under the PackageSignatures signatures data member.
+        File appPath = new File("/data/app/app");
+        PackageSetting result = new PackageSetting("test.app", null, appPath, appPath,
+                "/data/app/app", null, null, null,
+                1, 940097092, 0, null,
+                null, 0 /*userId*/, null, null);
+        return result;
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/pm/backup/BackupUtilsTest.java b/services/tests/servicestests/src/com/android/server/pm/backup/BackupUtilsTest.java
index 13612a1..182760b 100644
--- a/services/tests/servicestests/src/com/android/server/pm/backup/BackupUtilsTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/backup/BackupUtilsTest.java
@@ -99,7 +99,6 @@
                         new Signature[] {SIGNATURE_1},
                         PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
                         null,
-                        null,
                         null));
         packageInfo.applicationInfo = new ApplicationInfo();
 
@@ -119,7 +118,6 @@
                         new Signature[] {SIGNATURE_1},
                         PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
                         null,
-                        null,
                         null));
         packageInfo.applicationInfo = new ApplicationInfo();
 
@@ -203,7 +201,6 @@
                         new Signature[] {SIGNATURE_1, SIGNATURE_2, SIGNATURE_3},
                         PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
                         null,
-                        null,
                         null));
         packageInfo.applicationInfo = new ApplicationInfo();
 
@@ -226,7 +223,6 @@
                         new Signature[] {SIGNATURE_1, SIGNATURE_2, SIGNATURE_3},
                         PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
                         null,
-                        null,
                         null));
         packageInfo.applicationInfo = new ApplicationInfo();
 
@@ -248,7 +244,6 @@
                         new Signature[] {SIGNATURE_1, SIGNATURE_2},
                         PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
                         null,
-                        null,
                         null));
         packageInfo.applicationInfo = new ApplicationInfo();
 
@@ -271,7 +266,6 @@
                         new Signature[] {SIGNATURE_1, SIGNATURE_2, SIGNATURE_3},
                         PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
                         null,
-                        null,
                         null));
         packageInfo.applicationInfo = new ApplicationInfo();
 
@@ -295,7 +289,6 @@
                         new Signature[] {SIGNATURE_1},
                         PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
                         null,
-                        null,
                         null));
         packageInfo.applicationInfo = new ApplicationInfo();
 
@@ -320,7 +313,6 @@
                         new Signature[] {SIGNATURE_1, SIGNATURE_2},
                         PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
                         null,
-                        null,
                         null));
         packageInfo.applicationInfo = new ApplicationInfo();
 
@@ -348,7 +340,6 @@
                         new Signature[] {SIGNATURE_1, SIGNATURE_2},
                         PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
                         null,
-                        null,
                         null));
         packageInfo.applicationInfo = new ApplicationInfo();