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

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

APK Signature Scheme v3: require Proof-of-rotation and signing certs to match.

Though not yet used, the Proof-of-rotation certificates are intended to be
used by the platform as equivalent to signing certificates, i.e. the presence
of a certificate in a Proof-of-rotation record should grant equivalent
capabilities as if the APK were signed by that certificate.  For this to work,
each certificate needs to be signed by the previous one indicating a transfer
of trust all the way to the signing certificate of the APK.  There is no case
in which the last certificate in the Proof-of-rotation record should not be
the one used to sign the APK, so enforce this during verification.

Bug: 64686581
Change-Id: Ia1b25a917a878fb378c8557b25a2bbfdd9da7d3d
Test: Builds, boots, passes
      android.appsecurity.cts.PkgInstallSignatureVerificationTest
parent 67096e08
Loading
Loading
Loading
Loading
+16 −1
Original line number Diff line number Diff line
@@ -49,6 +49,7 @@ import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.security.Signature;
import java.security.SignatureException;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
@@ -398,9 +399,23 @@ public class ApkSignatureSchemeV3Verifier {
                case PROOF_OF_ROTATION_ATTR_ID:
                    if (por != null) {
                        throw new SecurityException("Encountered multiple Proof-of-rotation records"
                                + " when verifying APK Signature Scheme v3 signature.");
                                + " when verifying APK Signature Scheme v3 signature");
                    }
                    por = verifyProofOfRotationStruct(attr, certFactory);
                    // make sure that the last certificate in the Proof-of-rotation record matches
                    // the one used to sign this APK.
                    try {
                        if (por.certs.size() > 0
                                && !Arrays.equals(por.certs.get(por.certs.size() - 1).getEncoded(),
                                        certChain[0].getEncoded())) {
                            throw new SecurityException("Terminal certificate in Proof-of-rotation"
                                    + " record does not match APK signing certificate");
                        }
                    } catch (CertificateEncodingException e) {
                        throw new SecurityException("Failed to encode certificate when comparing"
                                + " Proof-of-rotation record and signing certificate", e);
                    }

                    break;
                default:
                    // not the droid we're looking for, move along, move along.