Revisit single-`SignerInfo` restriction in `dotnetup` CMS signature verification (PQC crypto-agility)
- Dominant language
- C#
- Stars
- 3.2k
- Forks
- 1.3k
- PR merge metrics
- PR metrics pending
Description
### Prerequisites
- [x] I have read the [dotnetup documentation](https://github.com/dotnet/sdk/tree/release/dnup/documentation/general/dotnetup).
- [x] I have searched for [existing dotnetup issues](https://github.com/dotnet/sdk/issues?q=is%3Aissue%20state%3Aopen%20label%3Adotnetup).
- [x] I have searched for [existing dotnetup discussions](https://github.com/dotnet/sdk/discussions/categories/dotnetup).
### Issue type
Feature request
### Description
## Summary
The current `dotnetup` signature verifier requires the CMS to contain **exactly one
`SignerInfo`**. That rule was inherited from the NuGet package signature
specification, which states:
> The CMS MUST have exactly 1 SignerInfo
>
> — [NuGet Home wiki — Package Signatures Technical Details](https://github.com/NuGet/Home/wiki/Package-Signatures-Technical-Details#-package-signature-file-content)
In review of #54300, @dtivel flagged that this narrows our crypto-agility options:
> This narrows crypto-agility options. Requiring exactly one `SignerInfo` rules out
> CMS parallel-signature strategies that use multiple `SignerInfo` entries, such as
> carrying both a legacy RSA signature and a PQC signature over the same content. It
> may still allow single-signer composite or hybrid algorithms, depending on
> implementation and ecosystem support, but that is a narrower migration space than
> permitting parallel signatures.
>
> — @dtivel, [#54300 (comment)](https://github.com/dotnet/sdk/pull/54300#discussion_r3335947482)
The original NuGet decision is most likely from before PQC was a near-term concern,
and was a simplifying restriction that also prevented a "bad" `SignerInfo` from
sitting alongside a "good" one. With PQC migration on the horizon, parallel
`SignerInfo` entries (legacy RSA + PQC over the same content) are a likely
transition strategy for the release manifest signatures, so we should not
permanently bake in the single-signer assumption.
## Work to do
This is a tracking issue — no code change is intended here on its own.
**a)** Research whether there are any compromises (security, complexity,
interoperability) in allowing more than one `SignerInfo` on the CMS signature
**when none of them are PQC**, including:
- Why NuGet originally chose exactly one `SignerInfo` (talk to NuGet signing
owners; capture the rationale).
- What threat model concerns the single-signer rule was protecting against (e.g.
a "bad" `SignerInfo` riding alongside a "good" one) and how those would be
handled if we allow multiple.
- How verification should behave when multiple `SignerInfo`s are present — must
all validate, must at least one validate, are unknown ones ignored, etc.
- Whether allowing multiple in advance (even before PQC ships) buys us a smoother
migration window or only adds attack surface.
**b)** Based on the outcome of (a), add support to `SignatureVerifier` for
multiple `SignerInfo`s on the CMS, with the policy chosen in (a). Update
`documentation/general/dotnetup/signature-verification.md` (currently states
exactly one `SignerInfo`) to match, and add tests covering the supported
multi-signer scenarios as well as negative cases (e.g. mixed valid/invalid
signers).
## Out of scope
- Any change to the verifier itself before (a) is answered.
- The certificate pinning follow-up tracked separately in
[#54534](https://github.com/dotnet/sdk/issues/54534).
- The other crypto-agility / multi-version-`dotnetup` and CAdES wording feedback
from #54300 — tracked separately.
## References
- PR: [dotnet/sdk#54300 — `dotnetup` verifies release signatures](https://github.com/dotnet/sdk/pull/54300)
- Specific thread: [#54300 (comment)](https://github.com/dotnet/sdk/pull/54300#discussion_r3335947482)
- NuGet single-`SignerInfo` rule: [Package Signatures Technical Details](https://github.com/NuGet/Home/wiki/Package-Signatures-Technical-Details#-package-signature-file-content)
- Spec doc affected: `documentation/general/dotnetup/signature-verification.md`
- Code affected: `src/Installer/Microsoft.Dotnet.Installation/Internal/Signing/SignatureVerifier.cs`
### dotnetup version
_No response_
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.