Skip to content

fix: implement PKCS#7 signature verification using Node.js crypto#212

Open
bryan-anthropic wants to merge 1 commit intomainfrom
fix/pkcs7-verify-node-crypto
Open

fix: implement PKCS#7 signature verification using Node.js crypto#212
bryan-anthropic wants to merge 1 commit intomainfrom
fix/pkcs7-verify-node-crypto

Conversation

@bryan-anthropic
Copy link
Collaborator

Fixes #21
Related: #71

Summary

node-forge's pkcs7.verify() is not implemented and always throws, causing mcpb verify and mcpb info to report all signed bundles as unsigned — regardless of whether they were signed with a local key or via PKCS#11.

This PR replaces the broken verification with a custom verifyPkcs7DetachedSignature() function that:

  1. Parses the PKCS#7 ASN.1 structure with node-forge (for structure traversal only)
  2. Verifies the messageDigest authenticated attribute matches the content hash using Node.js crypto.createHash()
  3. Verifies the RSA signature over the authenticated attributes using Node.js crypto.createVerify(), per RFC 5652 Section 5.4

Additionally:

  • Self-signed certificates now return "self-signed" status directly, without attempting OS chain verification (which would always fail for them)
  • The verifier handles the EOCD comment_length update introduced in fix: update ZIP EOCD comment_length when signing #204 — the signer modifies the ZIP EOCD after computing the signature, so the verifier restores the original content before checking

The verification handles both bundles signed with mcpb sign and bundles signed externally (e.g., via PKCS#11/HSM pipelines), as the function operates on standard PKCS#7/CMS structures.

Attribution

This is based on @vcolin7's work in #195, rebased onto current main (post-#204 merge) with the EOCD compatibility fix added. Thank you @vcolin7 for the thorough implementation and RFC 5652 research.

How Has This Been Tested?

  • All 219 existing tests pass (including the updated self-signed signing test)
  • End-to-end smoke test: packsignverifyinfo all work correctly
  • Unsigned bundles still correctly report "Extension is not signed"

Before / After

Before:

$ mcpb verify signed-bundle.mcpb
ERROR: Extension is not signed

After:

$ mcpb verify signed-bundle.mcpb
Signature is valid (self-signed)
Signed by: Test Publisher
Valid from: 3/20/2026 to 3/21/2026
Fingerprint: 2434e3...

Copy link

@claude claude bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Code review skipped — your organization's overage spend limit has been reached.

Code review is billed via overage credits. To resume reviews, an organization admin can raise the monthly limit in Settings → Usage.

Once credits are available, reopen this pull request to trigger a review.

node-forge's pkcs7.verify() is not implemented and always throws,
causing mcpb verify and mcpb info to report all signed bundles as
unsigned. Replace with a custom verification function that:

1. Parses the PKCS#7 ASN.1 structure with node-forge
2. Verifies the messageDigest attribute matches the content hash
   using Node.js crypto.createHash()
3. Verifies the RSA signature over the authenticated attributes
   using Node.js crypto.createVerify(), per RFC 5652 Section 5.4

Also handles the EOCD comment_length update from the signing flow:
the signer modifies the ZIP EOCD after signing, so the verifier
restores the original content before checking the signature.

Self-signed certificates now return "self-signed" status without
attempting OS chain verification (which would always fail for them).

Fixes #21

Co-authored-by: vcolin7 <victor.y.asi@gmail.com>
@bryan-anthropic bryan-anthropic force-pushed the fix/pkcs7-verify-node-crypto branch from 564621d to 85a0260 Compare March 20, 2026 10:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ERROR: Extension is not signed

2 participants