Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a656b8bf authored by Dan Cashman's avatar Dan Cashman
Browse files

APK Signature Scheme v3: add version number to proof-of-rotation.

The proof-of-rotation record contains a list of signing certificates
and corresponding flags.  New flags may be defined in future platform
versions, but APKs targeting P would have no knowledge of them.  Add
a version code to enable future platform versions to identify which
flags were deliberately set.  Ignore the version code for this
platform version, though, since all flags are known.

Bug: 64686581
Test: Builds, boots.
Change-Id: I765f50918f7f337100aff3ed15999b45369fc9d1
parent bef8a1be
Loading
Loading
Loading
Loading
+19 −15
Original line number Diff line number Diff line
@@ -438,8 +438,8 @@ public class ApkSignatureSchemeV3Verifier {
        List<Integer> flagsList = new ArrayList<>();

        // Proof-of-rotation struct:
        // is basically a singly linked list of nodes, called levels here, each of which have the
        // following structure:
        // A uint32 version code followed by basically a singly linked list of nodes, called levels
        // here, each of which have the following structure:
        // * length-prefix for the entire level
        //     - length-prefixed signed data (if previous level exists)
        //         * length-prefixed X509 Certificate
@@ -450,9 +450,13 @@ public class ApkSignatureSchemeV3Verifier {
        //     - length-prefixed signature over the signed data in this level.  The signature here
        //         is verified using the certificate from the previous level.
        // The linking is provided by the certificate of each level signing the one of the next.

        try {

            // get the version code, but don't do anything with it: creator knew about all our flags
            porBuf.getInt();
            while (porBuf.hasRemaining()) {
                levelCount++;
            try {
                ByteBuffer level = getLengthPrefixedSlice(porBuf);
                ByteBuffer signedData = getLengthPrefixedSlice(level);
                int flags = level.getInt();
@@ -491,6 +495,7 @@ public class ApkSignatureSchemeV3Verifier {
                lastSigAlgorithm = sigAlgorithm;
                certs.add(lastCert);
                flagsList.add(flags);
            }
        } catch (IOException | BufferUnderflowException e) {
            throw new IOException("Failed to parse Proof-of-rotation record", e);
        } catch (NoSuchAlgorithmException | InvalidKeyException
@@ -502,7 +507,6 @@ public class ApkSignatureSchemeV3Verifier {
            throw new SecurityException("Failed to decode certificate #" + levelCount
                    + " when verifying Proof-of-rotation record", e);
        }
        }
        return new VerifiedProofOfRotation(certs, flagsList);
    }