Merge "compos: mount BuildManifestSystemExt.apk if exists"
diff --git a/TEST_MAPPING b/TEST_MAPPING
index 11648c4..8cce099 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -47,6 +47,9 @@
       "path": "packages/modules/Virtualization/libs/apkverify"
     },
     {
+      "path": "packages/modules/Virtualization/libs/idsig"
+    },
+    {
       "path": "packages/modules/Virtualization/libs/vbmeta"
     },
     {
diff --git a/libs/apkverify/src/algorithms.rs b/libs/apkverify/src/algorithms.rs
index ecca7ed..6d4362b 100644
--- a/libs/apkverify/src/algorithms.rs
+++ b/libs/apkverify/src/algorithms.rs
@@ -77,7 +77,7 @@
 
 impl Default for SignatureAlgorithmID {
     fn default() -> Self {
-        SignatureAlgorithmID::DsaWithSha256
+        SignatureAlgorithmID::RsaPssWithSha256
     }
 }
 
@@ -97,6 +97,14 @@
         &self,
         public_key: &'a PKey<pkey::Public>,
     ) -> Result<Verifier<'a>> {
+        ensure!(
+            !matches!(
+                self,
+                SignatureAlgorithmID::DsaWithSha256 | SignatureAlgorithmID::VerityDsaWithSha256
+            ),
+            "TODO(b/197052981): Algorithm '{:?}' is not implemented.",
+            self
+        );
         ensure!(public_key.id() == self.pkey_id(), "Public key has the wrong ID");
         let mut verifier = Verifier::new(self.new_message_digest(), public_key)?;
         if public_key.id() == pkey::Id::RSA {
@@ -122,14 +130,6 @@
         }
     }
 
-    /// DSA is not directly supported in openssl today. See b/197052981.
-    pub(crate) fn is_supported(&self) -> bool {
-        !matches!(
-            self,
-            SignatureAlgorithmID::DsaWithSha256 | SignatureAlgorithmID::VerityDsaWithSha256,
-        )
-    }
-
     fn pkey_id(&self) -> pkey::Id {
         match self {
             SignatureAlgorithmID::RsaPssWithSha256
diff --git a/libs/apkverify/src/v3.rs b/libs/apkverify/src/v3.rs
index 5272834..2a16cb1 100644
--- a/libs/apkverify/src/v3.rs
+++ b/libs/apkverify/src/v3.rs
@@ -139,7 +139,7 @@
         Ok(self
             .signatures
             .iter()
-            .filter(|sig| sig.signature_algorithm_id.map_or(false, |algo| algo.is_supported()))
+            .filter(|sig| sig.signature_algorithm_id.is_some())
             .max_by_key(|sig| sig.signature_algorithm_id.unwrap().content_digest_algorithm())
             .context("No supported signatures found")?)
     }
diff --git a/libs/apkverify/tests/apkverify_test.rs b/libs/apkverify/tests/apkverify_test.rs
index f2018a1..5bd901d 100644
--- a/libs/apkverify/tests/apkverify_test.rs
+++ b/libs/apkverify/tests/apkverify_test.rs
@@ -40,11 +40,22 @@
 }
 
 #[test]
-fn apks_signed_with_v3_dsa_sha256_are_not_supported() {
+fn test_verify_v3_dsa_sha256() {
     for key_name in KEY_NAMES_DSA.iter() {
         let res = verify(format!("tests/data/v3-only-with-dsa-sha256-{}.apk", key_name));
-        assert!(res.is_err(), "DSA algorithm is not supported for verification. See b/197052981.");
-        assert_contains(&res.unwrap_err().to_string(), "No supported signatures found");
+        assert!(res.is_err());
+        assert_contains(&res.unwrap_err().to_string(), "not implemented");
+    }
+}
+
+/// TODO(b/197052981): DSA algorithm is not yet supported.
+#[test]
+fn apks_signed_with_v3_dsa_sha256_have_valid_apk_digest() {
+    for key_name in KEY_NAMES_DSA.iter() {
+        validate_apk_digest(
+            format!("tests/data/v3-only-with-dsa-sha256-{}.apk", key_name),
+            SignatureAlgorithmID::DsaWithSha256,
+        );
     }
 }
 
@@ -91,6 +102,7 @@
 #[test]
 fn test_verify_v3_sig_does_not_verify() {
     let path_list = [
+        "tests/data/v3-only-with-dsa-sha256-2048-sig-does-not-verify.apk",
         "tests/data/v3-only-with-ecdsa-sha512-p521-sig-does-not-verify.apk",
         "tests/data/v3-only-with-rsa-pkcs1-sha256-3072-sig-does-not-verify.apk",
     ];
@@ -106,9 +118,16 @@
 
 #[test]
 fn test_verify_v3_digest_mismatch() {
-    let res = verify("tests/data/v3-only-with-rsa-pkcs1-sha512-8192-digest-mismatch.apk");
-    assert!(res.is_err());
-    assert_contains(&res.unwrap_err().to_string(), "Digest mismatch");
+    let path_list = [
+        "tests/data/v3-only-with-dsa-sha256-3072-digest-mismatch.apk",
+        "tests/data/v3-only-with-rsa-pkcs1-sha512-8192-digest-mismatch.apk",
+    ];
+    for path in path_list.iter() {
+        let res = verify(path);
+        assert!(res.is_err());
+        let error_msg = &res.unwrap_err().to_string();
+        assert!(error_msg.contains("Digest mismatch") || error_msg.contains("not implemented"));
+    }
 }
 
 #[test]
diff --git a/libs/apkverify/tests/data/v3-only-with-dsa-sha256-1024.apk.apk_digest b/libs/apkverify/tests/data/v3-only-with-dsa-sha256-1024.apk.apk_digest
new file mode 100644
index 0000000..c5aec18
--- /dev/null
+++ b/libs/apkverify/tests/data/v3-only-with-dsa-sha256-1024.apk.apk_digest
Binary files differ
diff --git a/libs/apkverify/tests/data/v3-only-with-dsa-sha256-2048.apk.apk_digest b/libs/apkverify/tests/data/v3-only-with-dsa-sha256-2048.apk.apk_digest
new file mode 100644
index 0000000..c5aec18
--- /dev/null
+++ b/libs/apkverify/tests/data/v3-only-with-dsa-sha256-2048.apk.apk_digest
Binary files differ
diff --git a/libs/apkverify/tests/data/v3-only-with-dsa-sha256-3072.apk.apk_digest b/libs/apkverify/tests/data/v3-only-with-dsa-sha256-3072.apk.apk_digest
new file mode 100644
index 0000000..c5aec18
--- /dev/null
+++ b/libs/apkverify/tests/data/v3-only-with-dsa-sha256-3072.apk.apk_digest
Binary files differ
diff --git a/libs/idsig/TEST_MAPPING b/libs/idsig/TEST_MAPPING
new file mode 100644
index 0000000..eb57380
--- /dev/null
+++ b/libs/idsig/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+  "avf-presubmit" : [
+    {
+      "name" : "libidsig.test"
+    }
+  ]
+}
diff --git a/libs/idsig/src/apksigv4.rs b/libs/idsig/src/apksigv4.rs
index c1b6495..434a429 100644
--- a/libs/idsig/src/apksigv4.rs
+++ b/libs/idsig/src/apksigv4.rs
@@ -299,7 +299,7 @@
 
     #[test]
     fn parse_idsig_file() {
-        let idsig = Cursor::new(include_bytes!("../testdata/test.apk.idsig"));
+        let idsig = Cursor::new(include_bytes!("../testdata/v4-digest-v3-Sha256withEC.apk.idsig"));
         let parsed = V4Signature::from(idsig).unwrap();
 
         assert_eq!(Version::V2, parsed.version);
@@ -309,32 +309,32 @@
         assert_eq!(12, hi.log2_blocksize);
         assert_eq!("", hexstring_from(hi.salt.as_ref()));
         assert_eq!(
-            "ce1194fdb3cb2537daf0ac8cdf4926754adcbce5abeece7945fe25d204a0df6a",
+            "77f063b48b63f846690fa76450a8d3b61a295b6158f50592e873f76dbeeb0201",
             hexstring_from(hi.raw_root_hash.as_ref())
         );
 
         let si = parsed.signing_info;
         assert_eq!(
-            "b5225523a813fb84ed599dd649698c080bcfed4fb19ddb00283a662a2683bc15",
+            "c02fe2eddeb3078801828b930de546ea4f98d37fb98b40c7c7ed169b0d713583",
             hexstring_from(si.apk_digest.as_ref())
         );
         assert_eq!("", hexstring_from(si.additional_data.as_ref()));
         assert_eq!(
-            "303d021c77304d0f4732a90372bbfce095223e4ba82427ceb381f69bc6762d78021d008b99924\
-                   a8585c38d7f654835eb219ae9e176b44e86dcb23153e3d9d6",
+            "3046022100fb6383ba300dc7e1e6931a25b381398a16e5575baefd82afd12ba88660d9a6\
+            4c022100ebdcae13ab18c4e30bf6ae634462e526367e1ba26c2647a1d87a0f42843fc128",
             hexstring_from(si.signature.as_ref())
         );
-        assert_eq!(SignatureAlgorithmID::DsaWithSha256, si.signature_algorithm_id);
+        assert_eq!(SignatureAlgorithmID::EcdsaWithSha256, si.signature_algorithm_id);
 
-        assert_eq!(36864, parsed.merkle_tree_size);
-        assert_eq!(2251, parsed.merkle_tree_offset);
+        assert_eq!(4096, parsed.merkle_tree_size);
+        assert_eq!(648, parsed.merkle_tree_offset);
     }
 
     /// Parse an idsig file into V4Signature and write it. The written date must be the same as
     /// the input file.
     #[test]
     fn parse_and_compose() {
-        let input = Cursor::new(include_bytes!("../testdata/test.apk.idsig"));
+        let input = Cursor::new(include_bytes!("../testdata/v4-digest-v3-Sha256withEC.apk.idsig"));
         let mut parsed = V4Signature::from(input.clone()).unwrap();
 
         let mut output = Cursor::new(Vec::new());
@@ -347,11 +347,11 @@
     /// as those in the idsig file created by the signapk tool.
     #[test]
     fn digest_from_apk() {
-        let mut input = Cursor::new(include_bytes!("../testdata/test.apk"));
+        let mut input = Cursor::new(include_bytes!("../testdata/v4-digest-v3-Sha256withEC.apk"));
         let mut created =
             V4Signature::create(&mut input, 4096, &[], HashAlgorithm::SHA256).unwrap();
 
-        let golden = Cursor::new(include_bytes!("../testdata/test.apk.idsig"));
+        let golden = Cursor::new(include_bytes!("../testdata/v4-digest-v3-Sha256withEC.apk.idsig"));
         let mut golden = V4Signature::from(golden).unwrap();
 
         // Compare the root hash
diff --git a/libs/idsig/testdata/test.apk b/libs/idsig/testdata/test.apk
deleted file mode 100644
index cbee532..0000000
--- a/libs/idsig/testdata/test.apk
+++ /dev/null
Binary files differ
diff --git a/libs/idsig/testdata/test.apk.idsig b/libs/idsig/testdata/test.apk.idsig
deleted file mode 100644
index 8c112de..0000000
--- a/libs/idsig/testdata/test.apk.idsig
+++ /dev/null
Binary files differ
diff --git a/libs/idsig/testdata/v4-digest-v3-Sha256withEC.apk b/libs/idsig/testdata/v4-digest-v3-Sha256withEC.apk
new file mode 100644
index 0000000..b214336
--- /dev/null
+++ b/libs/idsig/testdata/v4-digest-v3-Sha256withEC.apk
Binary files differ
diff --git a/libs/idsig/testdata/v4-digest-v3-Sha256withEC.apk.idsig b/libs/idsig/testdata/v4-digest-v3-Sha256withEC.apk.idsig
new file mode 100644
index 0000000..19d38d5
--- /dev/null
+++ b/libs/idsig/testdata/v4-digest-v3-Sha256withEC.apk.idsig
Binary files differ
diff --git a/virtualizationservice/src/payload.rs b/virtualizationservice/src/payload.rs
index 7807cd6..675ca50 100644
--- a/virtualizationservice/src/payload.rs
+++ b/virtualizationservice/src/payload.rs
@@ -269,13 +269,22 @@
     for (i, (extra_apk, extra_idsig)) in extra_apks.iter().zip(extra_idsigs.iter()).enumerate() {
         partitions.push(Partition {
             label: format!("extra-apk-{}", i),
-            image: Some(ParcelFileDescriptor::new(File::open(PathBuf::from(&extra_apk.path))?)),
+            image: Some(ParcelFileDescriptor::new(
+                File::open(PathBuf::from(&extra_apk.path)).with_context(|| {
+                    format!("Failed to open the extra apk #{} {}", i, extra_apk.path)
+                })?,
+            )),
             writable: false,
         });
 
         partitions.push(Partition {
             label: format!("extra-idsig-{}", i),
-            image: Some(ParcelFileDescriptor::new(extra_idsig.as_ref().try_clone()?)),
+            image: Some(ParcelFileDescriptor::new(
+                extra_idsig
+                    .as_ref()
+                    .try_clone()
+                    .with_context(|| format!("Failed to clone the extra idsig #{}", i))?,
+            )),
             writable: false,
         });
     }