Ignore CMS_PARTIAL in CMS_add1_signer

Currently we reject it, but I'm actually not sure what the intent there
was. We already defer actually signing it to the end anyway. Looking at
OpenSSL, they only look at CMS_PARTIAL as part of this CMS_REUSE_DIGEST
mode that we do not implement.

The kernel started passing a bunch of unused flags to all these
functions. This seems a mistake[*] because CMS_PARTIAL is really a
per-operation thing, but it also seems to be harmless so we may as well
keep it working.

[*] They also pass it to CMS_final which *really* doesn't make sense. Ah
well.

Bug: 316589225
Change-Id: Id88bd659848975814363fbd26355196e4d712cb5
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/90287
Reviewed-by: Lily Chen <chlily@google.com>
Auto-Submit: David Benjamin <davidben@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
Commit-Queue: Lily Chen <chlily@google.com>
diff --git a/crypto/cms/cms.cc b/crypto/cms/cms.cc
index d0b4870..e7b1803 100644
--- a/crypto/cms/cms.cc
+++ b/crypto/cms/cms.cc
@@ -96,9 +96,6 @@
       !impl->der.empty() ||
       // We only support one signer.
       impl->has_signer_info ||
-      // We do not support configuring a signer in multiple steps. (In OpenSSL,
-      // this is used to configure attributes.
-      (flags & CMS_PARTIAL) != 0 ||
       // We do not support embedding certificates in SignedData.
       (flags & CMS_NOCERTS) == 0 ||
       // We do not support attributes in SignedData.
diff --git a/crypto/cms/cms_test.cc b/crypto/cms/cms_test.cc
index f0d8281..9a96f38 100644
--- a/crypto/cms/cms_test.cc
+++ b/crypto/cms/cms_test.cc
@@ -119,6 +119,26 @@
   expected = GetTestData("crypto/pkcs7/test/sign_sha256_key_id.p7s");
   EXPECT_EQ(Bytes(BIOMemContents(out.get())), Bytes(expected));
 
+  // After
+  // https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=0ad9a71933e7,
+  // the kernel started accidentally passing extra flag to every function, even
+  // where it doesn't make sense. Make sure it works, even if though it's
+  // dubious. (Passing |CMS_PARTIAL| to |CMS_final| is particularly
+  // questionable.)
+  const uint32_t many_flags = CMS_NOCERTS | CMS_PARTIAL | CMS_BINARY |
+                              CMS_DETACHED | CMS_STREAM | CMS_NOSMIMECAP |
+                              CMS_NO_SIGNING_TIME | CMS_USE_KEYID | CMS_NOATTR;
+  ASSERT_TRUE(BIO_reset(data_bio.get()));
+  cms.reset(CMS_sign(nullptr, nullptr, nullptr, nullptr, many_flags));
+  ASSERT_TRUE(cms);
+  ASSERT_TRUE(CMS_add1_signer(cms.get(), cert.get(), key.get(), EVP_sha256(),
+                              many_flags));
+  ASSERT_TRUE(
+      CMS_final(cms.get(), data_bio.get(), /*dcont=*/nullptr, many_flags));
+  ASSERT_TRUE(BIO_reset(out.get()));
+  ASSERT_TRUE(i2d_CMS_bio(out.get(), cms.get()));
+  EXPECT_EQ(Bytes(BIOMemContents(out.get())), Bytes(expected));
+
   // Specify a different hash function.
   ASSERT_TRUE(BIO_reset(data_bio.get()));
   cms.reset(