forked from vpulim/node-soap
-
Notifications
You must be signed in to change notification settings - Fork 0
/
WSSecurityCert.js
95 lines (74 loc) · 3.1 KB
/
WSSecurityCert.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
"use strict";
var fs = require('fs');
var path = require('path');
var ejs = require('ejs');
var SignedXml = require('xml-crypto').SignedXml;
var uuid4 = require('uuid/v4');
var wsseSecurityHeaderTemplate;
var wsseSecurityHeaderTemplateXml = require('./templates/wsse-security-header');
var wsseSecurityTokenTemplate;
var wsseSecurityTokenTemplateXml = require('./templates/wsse-security-token');
function addMinutes(date, minutes) {
return new Date(date.getTime() + minutes * 60000);
}
function dateStringForSOAP(date) {
return date.getUTCFullYear() + '-' + ('0' + (date.getUTCMonth() + 1)).slice(-2) + '-' +
('0' + date.getUTCDate()).slice(-2) + 'T' + ('0' + date.getUTCHours()).slice(-2) + ":" +
('0' + date.getUTCMinutes()).slice(-2) + ":" + ('0' + date.getUTCSeconds()).slice(-2) + "Z";
}
function generateCreated() {
return dateStringForSOAP(new Date());
}
function generateExpires() {
return dateStringForSOAP(addMinutes(new Date(), 10));
}
function insertStr(src, dst, pos) {
return [dst.slice(0, pos), src, dst.slice(pos)].join('');
}
function generateId() {
return uuid4().replace(/-/gm, '');
}
function WSSecurityCert(privatePEM, publicP12PEM, password, options) {
options = options || {};
this.publicP12PEM = publicP12PEM.toString().replace('-----BEGIN CERTIFICATE-----', '').replace('-----END CERTIFICATE-----', '').replace(/(\r\n|\n|\r)/gm, '');
this.signer = new SignedXml();
this.signer.signingKey = {
key: privatePEM,
passphrase: password
};
this.x509Id = "x509-" + generateId();
this.hasTimeStamp = typeof options.hasTimeStamp === 'undefined' ? true : !!options.hasTimeStamp;
this.signatureTransformations = Array.isArray(options.signatureTransformations) ? options.signatureTransformations
: ["http://www.w3.org/2000/09/xmldsig#enveloped-signature", "http://www.w3.org/2001/10/xml-exc-c14n#"];
var _this = this;
this.signer.keyInfoProvider = {};
this.signer.keyInfoProvider.getKeyInfo = function (key) {
if (!wsseSecurityTokenTemplate) {
wsseSecurityTokenTemplate = ejs.compile(wsseSecurityTokenTemplateXml);
}
return wsseSecurityTokenTemplate({ x509Id: _this.x509Id });
};
}
WSSecurityCert.prototype.postProcess = function (xml, envelopeKey) {
this.created = generateCreated();
this.expires = generateExpires();
if (!wsseSecurityHeaderTemplate) {
wsseSecurityHeaderTemplate = ejs.compile(wsseSecurityHeaderTemplateXml);
}
var secHeader = wsseSecurityHeaderTemplate({
binaryToken: this.publicP12PEM,
created: this.created,
expires: this.expires,
hasTimeStamp: this.hasTimeStamp,
id: this.x509Id
});
var xmlWithSec = insertStr(secHeader, xml, xml.indexOf('</soap:Header>'));
var references = this.signatureTransformations;
this.signer.addReference("//*[name(.)='" + envelopeKey + ":Body']", references);
if (this.hasTimeStamp) {
this.signer.addReference("//*[name(.)='wsse:Security']/*[local-name(.)='Timestamp']", references);
}
this.signer.computeSignature(xmlWithSec);
return insertStr(this.signer.getSignatureXml(), xmlWithSec, xmlWithSec.indexOf('</wsse:Security>'));
};
module.exports = WSSecurityCert;