Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed PasswordDigest Generation #1039

Merged
merged 5 commits into from Feb 13, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions lib/security/WSSecurity.js
Expand Up @@ -71,6 +71,8 @@ WSSecurity.prototype.toXML = function() {
password += "<wsse:Nonce EncodingType=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary\">" + nonce + "</wsse:Nonce>";
}
} else {
/* Specific Testcase for passwordDigest calculation cover this code
/* istanbul ignore next */
password = "<wsse:Password Type=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest\">" + passwordDigest(nonce, created, this._password) + "</wsse:Password>" +
"<wsse:Nonce EncodingType=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary\">" + nonce + "</wsse:Nonce>";
}
Expand Down
9 changes: 7 additions & 2 deletions lib/utils.js
Expand Up @@ -4,8 +4,13 @@ var crypto = require('crypto');
exports.passwordDigest = function passwordDigest(nonce, created, password) {
// digest = base64 ( sha1 ( nonce + created + password ) )
var pwHash = crypto.createHash('sha1');
var rawNonce = new Buffer(nonce || '', 'base64').toString('binary');
pwHash.update(rawNonce + created + password);

var NonceBytes = Buffer.from(nonce || '', 'base64');
var CreatedBytes = Buffer.from(created || '','utf8');
var PasswordBytes = Buffer.from(password || '', 'utf8');
var FullBytes = Buffer.concat([NonceBytes, CreatedBytes, PasswordBytes ]);

pwHash.update(FullBytes);
return pwHash.digest('base64');
};

Expand Down
22 changes: 22 additions & 0 deletions test/security/PasswordDigest.js
@@ -0,0 +1,22 @@
'use strict';

var Utils = require('../../lib/utils'),
assert = require('assert');

describe('PasswordDigest', function () {

var nonce = "2FW1CIo2ZUOJmSjVRcJZlQ==";
var created = "2019-02-12T12:34:12.110Z";
var password = "vM3s1hKVMy6zBOn";
var expected = "wM9xjA92wCw+QcQI1urjZ6B8+LQ=";

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

it('should calculate a valid passworddigest ', function () {

var result = Utils.passwordDigest(nonce, created, password);
assert.equal(result, expected);
});
});
141 changes: 81 additions & 60 deletions test/server-compress-test.js
Expand Up @@ -17,73 +17,94 @@ var request = fs.readFileSync(path + '/request.xml', 'utf8');
var response = fs.readFileSync(path + '/response.xml', 'utf8');

var service = {
MyService: {
MyServicePort: {
DefaultNamespace: function (args) {
return JSON.parse(json);
}
}
}
MyService: {
MyServicePort: {
DefaultNamespace: function (args) {
return JSON.parse(json);
}
}
}
};

describe('SOAP Server', function () {
// This test sends two requests and checks the responses for equality. The
// first request is sent through a soap client. The second request sends the
// same request in gzipped format.
it('should properly handle compression', function (done) {
var server = http.createServer(function (req, res) {});
var clientResponse, gzipResponse;
// This test sends two requests and checks the responses for equality. The
// first request is sent through a soap client. The second request sends the
// same request in gzipped format.
var server = http.createServer(function (req, res) {});

// If both arguments are defined, check if they are equal and exit the test.
var check = function (a, b) {
if (a && b) {
assert(a === b);
done();
}
};
before(function () {
server.listen(8000);
soap.listen(server, '/wsdl', service, xml);
});

after(function () {
server.close();
});

server.listen(8000);
soap.listen(server, '/wsdl', service, xml);

soap.createClient(wsdl, {
endpoint: 'http://localhost:8000/wsdl'
}, function (error, client) {
assert(!error);
client.DefaultNamespace(json, function (error, response) {
assert(!error);
clientResponse = client.lastResponse;
check(clientResponse, gzipResponse);
});
});
it('should properly handle compression', function (done) {

var clientResponse,
gzipResponse;

var gzip = zlib.createGzip();
// If both arguments are defined, check if they are equal and exit the test.
var check = function (a, b) {
if (a && b) {
try {
assert(a === b);
done();
} catch (e) {
done(e);
}
}
};

// Construct a request with the appropriate headers.
gzip.pipe(http.request({
host: 'localhost',
path: '/wsdl',
port: 8000,
method: 'POST',
headers: {
'content-type': 'text/xml; charset=utf-8',
'content-encoding': 'gzip',
'soapaction': '"DefaultNamespace"'
}
}, function (res) {
var body = '';
res.on('data', function (data) {
// Parse the response body.
body += data;
});
res.on('end', function () {
gzipResponse = body;
check(clientResponse, gzipResponse);
// Don't forget to close the server.
server.close();
});
}));
soap.createClient(wsdl, {
endpoint: 'http://localhost:8000/wsdl'
}, function (error, client) {
try {
assert(!error);
} catch (e) {
done(e);
}
client.DefaultNamespace(json, function (error, response) {
try {
assert(!error);
} catch (e) {
done(e);
}
clientResponse = client.lastResponse;
check(clientResponse, gzipResponse);
});
});

// Send the request body through the gzip stream to the server.
gzip.end(request);
});
var gzip = zlib.createGzip();

// Construct a request with the appropriate headers.
gzip.pipe(http.request({
host: 'localhost',
path: '/wsdl',
port: 8000,
method: 'POST',
headers: {
'content-type': 'text/xml; charset=utf-8',
'content-encoding': 'gzip',
'soapaction': '"DefaultNamespace"'
}
}, function (res) {
var body = '';
res.on('data', function (data) {
// Parse the response body.
body += data;
});
res.on('end', function () {
gzipResponse = body;
check(clientResponse, gzipResponse);
// Don't forget to close the server.
});
}));

// Send the request body through the gzip stream to the server.
gzip.end(request);
});
});