Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CmsSigner blocks signing of a CMS with an Empty Content #111306

Open
Bottswana opened this issue Jan 11, 2025 · 1 comment
Open

CmsSigner blocks signing of a CMS with an Empty Content #111306

Bottswana opened this issue Jan 11, 2025 · 1 comment
Labels
area-System.Security untriaged New issue has not been triaged by the area owner

Comments

@Bottswana
Copy link

Bottswana commented Jan 11, 2025

Hello!

While attempting to implement RFC8894 as SCEP server in dotnet, I have identified an issue that prevents the correct/standard implementation of the RFC using the CmsSigner API in System.Security.Cryptography.Pkcs.

throw new CryptographicException(SR.Cryptography_Cms_Sign_Empty_Content);

// While it shouldn't be possible to change the length of ContentInfo.Content
// after it's built, use the property at this stage, then use the saved value
// (if applicable) after this point.
if (ContentInfo.Content.Length == 0)
{
    throw new CryptographicException(SR.Cryptography_Cms_Sign_Empty_Content);
}

Based on the RFC8894 spec, it implements a signed CMS/PKCS#7 payload containing a valid certificate chain for the CA offering the signing of certificates via the service. Specifically, this payload explicitly should have no content sent, as it is used purely for the certificate chain or CRL.

The relevant part of the RFC is here https://datatracker.ietf.org/doc/html/rfc8894#certs-only

3.4. Degenerate certificates-only CMS SignedData
CMS includes a degenerate case of the SignedData content type in which there are no signers. The use of such a degenerate case is to disseminate certificates and CRLs. For SCEP, the content field of the ContentInfo value of a degenerate certificates-only SignedData MUST be omitted. When carrying certificates, the certificates are included in the certificates field of the SignedData. When carrying a CRL, the CRL is included in the crls field of the SignedData.

This is being implemented in the wild, as seen here with a reference output from a popular CA that supports SCEP:

CMS_ContentInfo: 
  contentType: pkcs7-signedData (1.2.840.113549.1.7.2)
  d.signedData: 
    version: 1
    digestAlgorithms:
        algorithm: sha256 (2.16.840.1.101.3.4.2.1)
        parameter: <ABSENT>
    encapContentInfo: 
      eContentType: pkcs7-data (1.2.840.113549.1.7.1)
      eContent: 
    certificates:

I'll be honest that from a cryptography point of view I am unsure if removing this check would cause other issues. Is there another API that can be used to sign a CMS with an empty content payload, or is this something that can be resolved in order to support this implementation case?

@dotnet-policy-service dotnet-policy-service bot added the untriaged New issue has not been triaged by the area owner label Jan 11, 2025
Copy link
Contributor

Tagging subscribers to this area: @dotnet/area-system-security, @bartonjs, @vcsjones
See info in area-owners.md if you want to be subscribed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-System.Security untriaged New issue has not been triaged by the area owner
Projects
None yet
Development

No branches or pull requests

1 participant