Skip to content

Signing omits a KeyInfo the caller asked for, instead of throwing #598

Description

@cjbarth

Summary

Follow-up to #596. With #597, signing leaves out KeyInfo whenever getKeyInfoContent returns no content, because XMLDSig requires KeyInfo to have at least one child element (4.5). That includes configurations that set keyInfoAttributes, so the caller asks for a KeyInfo with those attributes and gets a signature without one, with no error.

The same is true of publicCert. When the default getKeyInfoContent is in use, publicCert is its only input, so a publicCert that holds no certificate is also a request for KeyInfo that signing cannot meet. #605 has the details and covers the non-breaking part in 6.4. This issue covers the error.

#597 omits the element instead of throwing so that configurations that sign in 6.x keep signing. For 7.0, an explicit error is the better contract.

Expected

computeSignature() throws when getKeyInfoContent returns null or an empty string and either:

  • keyInfoAttributes has at least one attribute, or
  • getKeyInfoContent is the default, and publicCert is a string or Buffer.

For example:

const sig = new SignedXml({
  privateKey,
  canonicalizationAlgorithm: "http://www.w3.org/2001/10/xml-exc-c14n#",
  signatureAlgorithm: "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256",
  keyInfoAttributes: { Id: "key" },
});
sig.addReference({
  xpath: "//*[local-name(.)='book']",
  digestAlgorithm: "http://www.w3.org/2001/04/xmlenc#sha256",
  transforms: ["http://www.w3.org/2001/10/xml-exc-c14n#"],
});
sig.computeSignature("<library><book/></library>"); // should throw

and the same configuration with publicCert set to a PEM public key in place of keyInfoAttributes.

Configurations that set neither keep omitting KeyInfo when there is no content. So does a custom getKeyInfoContent that returns nothing when keyInfoAttributes is unset, because it may not use publicCert at all.

Also decide whether a key object given as the signing publicCert is an error. That is a KeyObject today, and a CryptoKey too once #545 lands. It can never supply a certificate, but 6.x deliberately treats it as producing no KeyInfo.

Release notes

This is a breaking change: the PR needs the breaking-change and semver-major labels and an entry in the README's Upgrading section.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions