Skip to content

Commit

Permalink
Added tests
Browse files Browse the repository at this point in the history
Simplied the XML SignerOpetions to only include the attribute that is currently causing the issues
Added tests
Updated Readme.
  • Loading branch information
LorneCurrie committed Jul 20, 2019
1 parent 998dd56 commit 8820e15
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 32 deletions.
4 changes: 0 additions & 4 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -860,12 +860,8 @@ the `options` object is optional and can contain the following properties:
* `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
* `signerOptions`: passed options to the XML Signer package - from (https://github.com/yaronn/xml-crypto)
* `prefix`: adds this value as a prefix for the generated signature tags
* `attrs`: a hash of attributes and values attrName: value to add to the signature root node
* `location`: customize the location of the signature, pass an object with a reference key which should contain a XPath expression to a reference node, an action key which should contain one of the following values: `append`, `prepend`, `before`, `after`
* `existingPrefixes`: 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' }`)


### NTLMSecurity

Parameter invocation:
Expand Down
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"serve-static": "^1.11.1",
"strip-bom": "^3.0.0",
"uuid": "^3.1.0",
"xml-crypto": "~1.2.0"
"xml-crypto": "^1.4.0"
},
"repository": {
"type": "git",
Expand Down
6 changes: 0 additions & 6 deletions src/security/WSSecurityCert.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,6 @@ export interface IWSSecurityCertOptions {
}

export interface IXmlSignerOptions {
prefix?: string;
attrs?: { [key: string]: string };
location?: {
action: string;
reference: string;
};
existingPrefixes?: { [key: string]: string };
}

Expand Down
51 changes: 34 additions & 17 deletions test/security/WSSecurityCert.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,30 +3,30 @@
var fs = require('fs'),
join = require('path').join;

describe('WSSecurityCert', function() {
describe('WSSecurityCert', function () {
var WSSecurityCert = require('../../').WSSecurityCert;
var cert = fs.readFileSync(join(__dirname, '..', 'certs', 'agent2-cert.pem'));
var key = fs.readFileSync(join(__dirname, '..', 'certs', 'agent2-key.pem'));
var keyWithPassword = fs.readFileSync(join(__dirname, '..', 'certs', 'agent2-key-with-password.pem')); // The passphrase protecting the private key is "soap"

it('is a function', function() {
it('is a function', function () {
WSSecurityCert.should.be.type('function');
});

it('should accept valid constructor variables', function() {
it('should accept valid constructor variables', function () {
var instance = new WSSecurityCert(key, cert, '');
instance.should.have.property('publicP12PEM');
instance.should.have.property('signer');
instance.should.have.property('x509Id');
});

it('should fail at computing signature when the private key is invalid', function() {
it('should fail at computing signature when the private key is invalid', function () {
var passed = true;

try {
var instance = new WSSecurityCert('*****', cert, '');
instance.postProcess('<soap:Header></soap:Header><soap:Body></soap:Body>', 'soap');
} catch(e) {
} catch (e) {
passed = false;
}

Expand All @@ -35,7 +35,7 @@ describe('WSSecurityCert', function() {
}
});

it('should insert a WSSecurity signing block when postProcess is called (private key is raw)', function() {
it('should insert a WSSecurity signing block when postProcess is called (private key is raw)', function () {
var instance = new WSSecurityCert(key, cert, '');
var xml = instance.postProcess('<soap:Header></soap:Header><soap:Body></soap:Body>', 'soap');

Expand All @@ -52,14 +52,14 @@ describe('WSSecurityCert', function() {
xml.should.containEql('<Created>' + instance.created);
xml.should.containEql('<Expires>' + instance.expires);
xml.should.containEql('<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">');
xml.should.containEql('<wsse:SecurityTokenReference>');
xml.should.containEql('<wsse:SecurityTokenReference');
xml.should.containEql('<wsse:Reference URI="#' + instance.x509Id);
xml.should.containEql('ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"/>');
xml.should.containEql(instance.publicP12PEM);
xml.should.containEql(instance.signer.getSignatureXml());
});
it('should insert a WSSecurity signing block when postProcess is called (private key is protected by a passphrase)', function() {

it('should insert a WSSecurity signing block when postProcess is called (private key is protected by a passphrase)', function () {
var instance = new WSSecurityCert(keyWithPassword, cert, 'soap');
var xml = instance.postProcess('<soap:Header></soap:Header><soap:Body></soap:Body>', 'soap');

Expand All @@ -76,43 +76,60 @@ describe('WSSecurityCert', function() {
xml.should.containEql('<Created>' + instance.created);
xml.should.containEql('<Expires>' + instance.expires);
xml.should.containEql('<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">');
xml.should.containEql('<wsse:SecurityTokenReference>');
xml.should.containEql('<wsse:SecurityTokenReference');
xml.should.containEql('<wsse:Reference URI="#' + instance.x509Id);
xml.should.containEql('ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"/>');
xml.should.containEql(instance.publicP12PEM);
xml.should.containEql(instance.signer.getSignatureXml());
});

it('should only add two Reference elements, for Soap Body and Timestamp inside wsse:Security element', function() {
it('should only add two Reference elements, for Soap Body and Timestamp inside wsse:Security element', function () {
var instance = new WSSecurityCert(key, cert, '');
var xml = instance.postProcess('<soap:Header></soap:Header><soap:Body><Body></Body><Timestamp></Timestamp></soap:Body>', 'soap');
xml.match(/<Reference URI="#/g).should.have.length(2);
});

it('should only add one Reference elements, for Soap Body wsse:Security element when addTimestamp is false', function() {
var instance = new WSSecurityCert(key, cert, '', {hasTimeStamp: false});
it('should only add one Reference elements, for Soap Body wsse:Security element when addTimestamp is false', function () {
var instance = new WSSecurityCert(key, cert, '', { hasTimeStamp: false });
var xml = instance.postProcess('<soap:Header></soap:Header><soap:Body><Body></Body><Timestamp></Timestamp></soap:Body>', 'soap');
xml.match(/<Reference URI="#/g).should.have.length(1);
});

it('double post process should not add extra alments', function() {
it('double post process should not add extra alments', function () {
var instance = new WSSecurityCert(key, cert, '');
var _ = instance.postProcess('<soap:Header></soap:Header><soap:Body><Body></Body><Timestamp></Timestamp></soap:Body>', 'soap');
var xml = instance.postProcess('<soap:Header></soap:Header><soap:Body><Body></Body><Timestamp></Timestamp></soap:Body>', 'soap');
xml.match(/<Reference URI="#/g).should.have.length(2);
});

it('should have no timestamp when addTimestamp is false', function() {
var instance = new WSSecurityCert(key, cert, '', {hasTimeStamp: false});
it('should have no timestamp when addTimestamp is false', function () {
var instance = new WSSecurityCert(key, cert, '', { hasTimeStamp: false });
var xml = instance.postProcess('<soap:Header></soap:Header><soap:Body><Body></Body><Timestamp></Timestamp></soap:Body>', 'soap');
xml.should.not.containEql('<Timestamp xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" Id="_1">');
xml.should.not.containEql('<Created>' + instance.created);
xml.should.not.containEql('<Expires>' + instance.expires);
});

it('should use rsa-sha256 signature method when the signatureAlgorithm option is set to WSSecurityCert', function() {
it('should use rsa-sha256 signature method when the signatureAlgorithm option is set to WSSecurityCert', function () {
var instance = new WSSecurityCert(key, cert, '', { hasTimeStamp: false, signatureAlgorithm: 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256' });
var xml = instance.postProcess('<soap:Header></soap:Header><soap:Body><Body></Body></soap:Body>', 'soap');
xml.should.containEql('SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"');
});

it('should use default xmlns:wsse if no signerOptions.existingPrefixes is provided', function () {
var instance = new WSSecurityCert(key, cert, '');
var xml = instance.postProcess('<soap:Header></soap:Header><soap:Body><Body></Body><Timestamp></Timestamp></soap:Body>', 'soap')
xml.should.containEql('xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"');
})
it('should contain a provided prefix when signerOptions.existingPrefixes is provided', function () {
var instance = new WSSecurityCert(key, cert, '', {
signerOptions: {
location: { action: 'after' },
existingPrefixes: { wsse: 'https://localhost/node-soap.xsd' }
}
});
var xml = instance.postProcess('<soap:Header></soap:Header><soap:Body><Body></Body><Timestamp></Timestamp></soap:Body>', 'soap')
xml.should.containEql('<wsse:SecurityTokenReference xmlns:wsse="https://localhost/node-soap.xsd">');
})

});
42 changes: 42 additions & 0 deletions test/security/tmp.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<soap:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" soap:mustUnderstand="1">
<wsse:BinarySecurityToken EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" wsu:Id="x509-6df39b9626c0466e960f866109756560">MIID8zCCAtugAwIBAgIUfaJJaqBa7P+81aiqjFdwled4g3EwDQYJKoZIhvcNAQELBQAwgYgxCzAJBgNVBAYTAlVTMRAwDgYDVQQIDAdBcml6b25hMRIwEAYDVQQHDAlGbGFnc3RhZmYxDTALBgNVBAoMBEFDTUUxCzAJBgNVBAsMAklUMRIwEAYDVQQDDAlub2RlLXNvYXAxIzAhBgkqhkiG9w0BCQEWFHNvYXBtYXN0ZXJzQGFjbWUuY29tMB4XDTE5MDEyNDE3MDUxMFoXDTIwMDEyNDE3MDUxMFowgYgxCzAJBgNVBAYTAlVTMRAwDgYDVQQIDAdBcml6b25hMRIwEAYDVQQHDAlGbGFnc3RhZmYxDTALBgNVBAoMBEFDTUUxCzAJBgNVBAsMAklUMRIwEAYDVQQDDAlub2RlLXNvYXAxIzAhBgkqhkiG9w0BCQEWFHNvYXBtYXN0ZXJzQGFjbWUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1AmnP/IPSpocMHYJQ5FE1an5eQmfkg+4QyaKq6ECXCv4VhK5N2aD71OL7IKKnW5qqxzXGAGy1vQjCGyUGmPa4/LnXBvM67ED5irFy00djXqc/pNn7FCACxgrg9+6bIWlItSkVkGn/D4VPGiA8xTC05FxJkUXp8be/hYs9EQ0+9WqZ7ZM6W5SMFYNW0CE9G9dQK9b0NrS9Rx7wrNTzwMZp9u1PdY4HtYsS5WHVMOOGXN+ds4v3dP8Ym6sW1rbe2LeYfTB7dM8aZyS4Zn38vpCiMzrqO1/govPgz/6Bw4DhW0FoXLtDgx0giTGEy5GBqZf6+U6z5ZCosKKdD8KZoxrNwIDAQABo1MwUTAdBgNVHQ4EFgQUxbsTaT+279hFiJmplXfBwAfUGy0wHwYDVR0jBBgwFoAUxbsTaT+279hFiJmplXfBwAfUGy0wDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAO04vm1mWY1IagQ+fxH8HGxE8OOwxSVTmmkNz+DZVXG4/8wwMJxCEoLY2CvJH5o/ZdeZPTd9MhmMxTwBNHAM9vmj3AmbD65EukMV76RIATBzavEb6NzTLugar2xco3MMHR945kLJmk1uEyusCJXgxzK0lzk6oGp2OAtlRUT7DvR3AkMvEYia3AHSY1M0Dtsf3r7DsoFIpWvVj9+WDeeoxI19ZIuJ6fzFQnEIX4M4hcfmCTtOlICowqpMCg1JIWryBBUr3KizDrq2Ad5I2i8E4WanGz4pDVShd6Y1XTNLR1xv3Is3Jlhusk9UpTbATyMxOVnfj9OgS1/BK41xRmasgPg==</wsse:BinarySecurityToken>
<Timestamp xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" Id="_1">
<Created>2019-06-24T09:16:27Z</Created>
<Expires>2019-06-24T09:26:27Z</Expires>
</Timestamp>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<Reference URI="#_0">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
<Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<DigestValue>+a/MnIamE2MEuaDxCQq8WpiQbFg=</DigestValue>
</Reference>
<Reference URI="#_1">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
<Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<DigestValue>+AOj65Xa46P6/xRj5KyAgDHjP1Q=</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>npN8Ly8YtIyodpQhcn4M17FJdz11pFrXWGwtO5v6KgNxUcrX6LDIzeeOQRVSzXbK6X2AyIdPKUOG2m/vThx1wXDCD68L8xx3i2WW3r6Hkw+FzgC4y/GncszqTrlPd0BlWtOAWxKoHYSOS+RkYMtC58iMR3I8gysYJ8xC30UtSm7CYP2CQNPVdPFEN5SdTb7334xHB6ifTlqZ92FrdTnwExOt127jf9xqwZruHNoXlBKkLSjanr+uTs38Hf9IkxSS149ExtNsiybgaiccRh5+qagGgb5aAsMeuY4+mvQb/ZpJFF1BQuChpx1fLq5WVmbkzEAUzug61zfoKSv4HGoPMA==</SignatureValue>
<KeyInfo>
<wsse:SecurityTokenReference xmlns:wsse="">
<wsse:Reference URI="#x509-6df39b9626c0466e960f866109756560" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"/>
</wsse:SecurityTokenReference>
</KeyInfo>
</Signature>
</wsse:Security>
</soap:Header>
<soap:Body>
<Body></Body>
<Timestamp></Timestamp>
</soap:Body>

0 comments on commit 8820e15

Please sign in to comment.