Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Closes #86

  • Loading branch information...
commit 2d476e6f74268f17a90d19cbba082d699cced1b0 1 parent 81633c2
@hueniverse authored
View
14 lib/browser.js
@@ -267,6 +267,20 @@ hawk.client = {
};
return result;
+ },
+
+ authenticateTimestamp: function (message, credentials, updateClock) { // updateClock defaults to true
+
+ var tsm = hawk.crypto.calculateTsMac(message.ts, credentials);
+ if (tsm !== message.tsm) {
+ return false;
+ }
+
+ if (updateClock !== false) {
+ hawk.utils.setNtpOffset(message.ts - Math.floor(Date.now() / 1000)); // Keep offset at 1 second precision
+ }
+
+ return true;
}
};
View
2  lib/client.js
@@ -156,6 +156,8 @@ exports.authenticate = function (res, credentials, artifacts, options) {
return false;
}
+ // Validate server timestamp (not used to update clock since it is done via the SNPT client)
+
if (attributes.ts) {
var tsm = Crypto.calculateTsMac(attributes.ts, credentials);
if (tsm !== attributes.tsm) {
View
7 lib/crypto.js
@@ -109,3 +109,10 @@ exports.calculateTsMac = function (ts, credentials) {
return hmac.digest('base64');
};
+
+exports.timestampMessage = function (credentials, localtimeOffsetMsec) {
+
+ var now = Math.floor((Utils.now() + (localtimeOffsetMsec || 0)) / 1000);
+ var tsm = exports.calculateTsMac(now, credentials);
+ return { ts: now, tsm: tsm };
+};
View
5 lib/server.js
@@ -191,9 +191,8 @@ exports.authenticate = function (req, credentialsFunc, options, callback) {
// Check timestamp staleness
if (Math.abs((attributes.ts * 1000) - now) > (options.timestampSkewSec * 1000)) {
- var fresh = Math.floor((Utils.now() + (options.localtimeOffsetMsec || 0)) / 1000); // Get fresh now
- var tsm = Crypto.calculateTsMac(fresh, credentials);
- return callback(Boom.unauthorized('Stale timestamp', 'Hawk', { ts: fresh, tsm: tsm }), credentials, artifacts);
+ var tsm = Crypto.timestampMessage(credentials, options.localtimeOffsetMsec);
+ return callback(Boom.unauthorized('Stale timestamp', 'Hawk', tsm), credentials, artifacts);
}
// Successful authentication
View
2  package.json
@@ -1,7 +1,7 @@
{
"name": "hawk",
"description": "HTTP Hawk Authentication Scheme",
- "version": "1.0.0",
+ "version": "1.1.0",
"author": "Eran Hammer <eran@hueniverse.com> (http://hueniverse.com)",
"contributors": [],
"repository": "git://github.com/hueniverse/hawk",
View
24 test/browser.js
@@ -728,6 +728,30 @@ describe('Browser', function () {
});
});
});
+
+ describe('#authenticateTimestamp', function (done) {
+
+ it('should validate a timestamp', function (done) {
+
+ credentialsFunc('123456', function (err, credentials) {
+
+ var tsm = Hawk.crypto.timestampMessage(credentials);
+ expect(Browser.client.authenticateTimestamp(tsm, credentials)).to.equal(true);
+ done();
+ });
+ });
+
+ it('should detect a bad timestamp', function (done) {
+
+ credentialsFunc('123456', function (err, credentials) {
+
+ var tsm = Hawk.crypto.timestampMessage(credentials);
+ tsm.ts = 4;
+ expect(Browser.client.authenticateTimestamp(tsm, credentials)).to.equal(false);
+ done();
+ });
+ });
+ });
});
describe('#parseAuthorizationHeader', function (done) {
Please sign in to comment.
Something went wrong with that request. Please try again.