From 6bee17dcec1f72c2af4671c13a106b7a31e19b1c Mon Sep 17 00:00:00 2001 From: pzemljic-git Date: Mon, 10 Feb 2025 17:04:19 -0800 Subject: [PATCH 1/2] Add option for digest algorithm --- src/security/WSSecurityCert.ts | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/security/WSSecurityCert.ts b/src/security/WSSecurityCert.ts index bf6673ad..2d8e95bc 100644 --- a/src/security/WSSecurityCert.ts +++ b/src/security/WSSecurityCert.ts @@ -43,6 +43,7 @@ export interface IWSSecurityCertOptions { hasTimeStamp?: boolean; signatureTransformations?: string[]; signatureAlgorithm?: string; + digestAlgorithm?: string; additionalReferences?: string[]; signerOptions?: IXmlSignerOptions; } @@ -74,6 +75,9 @@ export class WSSecurityCert implements ISecurity { this.signer = new SignedXml({ idMode: options?.signerOptions?.idMode, signatureAlgorithm: options?.signatureAlgorithm }); + if (options.digestAlgorithm) { + this.signer.digestAlgorithm = options.digestAlgorithm; + } if (options.signatureAlgorithm === 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256') { this.signer.signatureAlgorithm = options.signatureAlgorithm; @@ -180,19 +184,19 @@ export class WSSecurityCert implements ISecurity { resolvePlaceholderInReferences(this.signer.references, bodyXpath); if (!(this.signer.references.filter((ref: { xpath: string; }) => (ref.xpath === bodyXpath)).length > 0)) { - this.signer.addReference({ xpath: bodyXpath, transforms: references, digestAlgorithm: 'http://www.w3.org/2001/04/xmlenc#sha256' }); + this.signer.addReference({ xpath: bodyXpath, transforms: references, digestAlgorithm: this.signer.digestAlgorithm }); } for (const name of this.additionalReferences) { const xpath = `//*[name(.)='${name}']`; if (!(this.signer.references.filter((ref: { xpath: string; }) => (ref.xpath === xpath)).length > 0)) { - this.signer.addReference({ xpath: xpath, transforms: references, digestAlgorithm: 'http://www.w3.org/2001/04/xmlenc#sha256' }); + this.signer.addReference({ xpath: xpath, transforms: references, digestAlgorithm: this.signer.digestAlgorithm }); } } const timestampXpath = `//*[name(.)='wsse:Security']/*[local-name(.)='Timestamp']`; if (this.hasTimeStamp && !(this.signer.references.filter((ref: { xpath: string; }) => (ref.xpath === timestampXpath)).length > 0)) { - this.signer.addReference({ xpath: timestampXpath, transforms: references, digestAlgorithm: 'http://www.w3.org/2001/04/xmlenc#sha256' }); + this.signer.addReference({ xpath: timestampXpath, transforms: references, digestAlgorithm: this.signer.digestAlgorithm }); } this.signer.computeSignature(xmlWithSec, this.signerOptions); From 278fb9b0b3ed7ecfe23359df301d11373bcacfb6 Mon Sep 17 00:00:00 2001 From: pzemljic-git Date: Tue, 11 Feb 2025 10:37:31 -0800 Subject: [PATCH 2/2] Set default value for digestAlgorithm to sha256, add test, and update documentation. --- Readme.md | 1 + src/security/WSSecurityCert.ts | 7 +++---- test/security/WSSecurityCert.js | 10 ++++++++++ 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/Readme.md b/Readme.md index c4c6f551..3931a821 100644 --- a/Readme.md +++ b/Readme.md @@ -981,6 +981,7 @@ The `options` object is optional and can contain the following properties: * `hasTimeStamp`: Includes Timestamp tags (default: `true`) * `signatureTransformations`: sets the Reference Transforms Algorithm (default ['http://www.w3.org/2000/09/xmldsig#enveloped-signature', 'http://www.w3.org/2001/10/xml-exc-c14n#']). Type is a string array * `signatureAlgorithm`: set to `http://www.w3.org/2001/04/xmldsig-more#rsa-sha256` to use sha256 +* `digestAlgorithm`: set to `http://www.w3.org/2000/09/xmldsig#sha1` to use sha1 (default `http://www.w3.org/2001/04/xmlenc#sha256`) * `additionalReferences` : (optional) Array of Soap headers that need to be signed. This need to be added using `client.addSoapHeader('header')` * `signerOptions`: (optional) passes options to the XML Signer package - from (https://github.com/yaronn/xml-crypto) * `existingPrefixes`: (optional) A hash of prefixes and namespaces prefix: namespace that shouldn't be in the signature because they already exist in the xml (default: `{ 'wsse': 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd' }`) diff --git a/src/security/WSSecurityCert.ts b/src/security/WSSecurityCert.ts index 2d8e95bc..2a188b6f 100644 --- a/src/security/WSSecurityCert.ts +++ b/src/security/WSSecurityCert.ts @@ -74,11 +74,10 @@ export class WSSecurityCert implements ISecurity { this.signer = new SignedXml({ idMode: options?.signerOptions?.idMode, - signatureAlgorithm: options?.signatureAlgorithm }); - if (options.digestAlgorithm) { - this.signer.digestAlgorithm = options.digestAlgorithm; - } + signatureAlgorithm: options?.signatureAlgorithm, + }); + this.signer.digestAlgorithm = options.digestAlgorithm ?? 'http://www.w3.org/2001/04/xmlenc#sha256'; if (options.signatureAlgorithm === 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256') { this.signer.signatureAlgorithm = options.signatureAlgorithm; this.signer.addReference({ diff --git a/test/security/WSSecurityCert.js b/test/security/WSSecurityCert.js index 8ffb92e0..9f2a8d0e 100644 --- a/test/security/WSSecurityCert.js +++ b/test/security/WSSecurityCert.js @@ -256,4 +256,14 @@ describe('WSSecurityCert', function () { var xml = instance.postProcess('', 'soap'); xml.should.containEql('SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha512"'); }); + + it('should use digest method when the digestAlgorithm option is set on WSSecurityCert', function () { + var instance = new WSSecurityCert(key, cert, '', { + hasTimeStamp: false, + digestAlgorithm: 'http://www.w3.org/2000/09/xmldsig#sha1' + }); + var xml = instance.postProcess('', 'soap'); + xml.should.containEql('DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"'); + }); + });