code cleanup
- remove callbacks (functions are sync) - update tests for removed callbacks - minimize some code duplication
This commit is contained in:
parent
4475c95ecb
commit
cf96266a20
269
lib/notp.js
269
lib/notp.js
@ -1,16 +1,11 @@
|
|||||||
|
|
||||||
var crypto = require('crypto');
|
var crypto = require('crypto');
|
||||||
var base32 = require('thirty-two');
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Check a One Time Password based on a counter.
|
* Check a One Time Password based on a counter.
|
||||||
*
|
*
|
||||||
* First argument of callback is true if password check is successful,
|
* @return {Object} null if failure, { delta: # } on success
|
||||||
* or false if check fails.
|
* delta is the time step difference between the client and the server
|
||||||
*
|
|
||||||
* Second argument is the time step difference between the client and
|
|
||||||
* the server. This argument is only passed if the password check is
|
|
||||||
* successful.
|
|
||||||
*
|
*
|
||||||
* Arguments:
|
* Arguments:
|
||||||
*
|
*
|
||||||
@ -35,48 +30,33 @@ var base32 = require('thirty-two');
|
|||||||
* be user specific, and be incremented for each request.
|
* be user specific, and be incremented for each request.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
module.exports.checkHOTP = function(args, cb) {
|
module.exports.checkHOTP = function(args) {
|
||||||
|
|
||||||
var hmac,
|
var W = args.W || 50;
|
||||||
digest,
|
var C = args.C || 0;
|
||||||
offset, h, v, p = 6, b,
|
var P = args.P || '';
|
||||||
i,
|
|
||||||
K = args.K || "",
|
|
||||||
W = args.W || 50,
|
|
||||||
C = args.C || 0,
|
|
||||||
P = args.P || "";
|
|
||||||
|
|
||||||
|
|
||||||
// Initiate the HMAC
|
|
||||||
hmac = crypto.createHmac('SHA1', new Buffer(K))
|
|
||||||
|
|
||||||
// Now loop through from C to C + W to determine if there is
|
// Now loop through from C to C + W to determine if there is
|
||||||
// a correct code
|
// a correct code
|
||||||
for(i = C; i <= C+W; i++) {
|
for(i = C; i <= C+W; ++i) {
|
||||||
if(this._calcHMAC(K,i) === P) {
|
args.C = i;
|
||||||
|
if(this.getHOTP(args) === P) {
|
||||||
// We have found a matching code, trigger callback
|
// We have found a matching code, trigger callback
|
||||||
// and pass offset
|
// and pass offset
|
||||||
cb(true, i - C);
|
return { delta: i - C };
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we get to here then no codes have matched, return false
|
// If we get to here then no codes have matched, return false
|
||||||
cb(false);
|
return false;
|
||||||
return;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Check a One Time Password based on a timer.
|
* Check a One Time Password based on a timer.
|
||||||
*
|
*
|
||||||
* First argument of callback is true if password check is successful,
|
* @return {Object} null if failure, { delta: # } on success
|
||||||
* or false if check fails.
|
* delta is the time step difference between the client and the server
|
||||||
*
|
|
||||||
* Second argument is the time step difference between the client and
|
|
||||||
* the server. This argument is only passed if the password check is
|
|
||||||
* successful.
|
|
||||||
*
|
*
|
||||||
* Arguments:
|
* Arguments:
|
||||||
*
|
*
|
||||||
@ -103,60 +83,33 @@ module.exports.checkHOTP = function(args, cb) {
|
|||||||
* Default - 30
|
* Default - 30
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
module.exports.checkTOTP = function(args, cb) {
|
module.exports.checkTOTP = function(args) {
|
||||||
|
|
||||||
var hmac,
|
var T = args.T || 30;
|
||||||
digest,
|
var _t = new Date().getTime();
|
||||||
offset, h, v, p = 6, b,
|
|
||||||
C,i,
|
|
||||||
K = args.K || "",
|
|
||||||
W = args.W || 6,
|
|
||||||
T = args.T || 30,
|
|
||||||
P = args.P || "",
|
|
||||||
_t;
|
|
||||||
|
|
||||||
|
|
||||||
if(args._t) {
|
|
||||||
// Time has been overwritten.
|
// Time has been overwritten.
|
||||||
|
if(args._t) {
|
||||||
console.log('#####################################');
|
console.log('#####################################');
|
||||||
console.log('# NOTE: TOTP TIME VARIABLE HAS BEEN #');
|
console.log('# NOTE: TOTP TIME VARIABLE HAS BEEN #');
|
||||||
console.log('# OVERWRITTEN. THIS SHOULD ONLY BE #');
|
console.log('# OVERWRITTEN. THIS SHOULD ONLY BE #');
|
||||||
console.log('# USED FOR TEST PURPOSES. #');
|
console.log('# USED FOR TEST PURPOSES. #');
|
||||||
console.log('#####################################');
|
console.log('#####################################');
|
||||||
_t = args._t;
|
_t = args._t;
|
||||||
} else {
|
|
||||||
_t = new Date().getTime();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initiate the HMAC
|
|
||||||
hmac = crypto.createHmac('SHA1', new Buffer(K))
|
|
||||||
|
|
||||||
// Determine the value of the counter, C
|
// Determine the value of the counter, C
|
||||||
// This is the number of time steps in seconds since T0
|
// This is the number of time steps in seconds since T0
|
||||||
C = Math.floor((_t / 1000) / T);
|
args.C = Math.floor((_t / 1000) / T);
|
||||||
|
|
||||||
// Now loop through from C - W to C + W and check to see
|
return module.exports.checkHOTP(args);
|
||||||
// if we have a valid code in that time line
|
|
||||||
for(i = C-W; i <= C+W; i++) {
|
|
||||||
|
|
||||||
if(this._calcHMAC(K,i) === P) {
|
|
||||||
// We have found a matching code, trigger callback
|
|
||||||
// and pass offset
|
|
||||||
cb(true, i-C);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we get to here then no codes have matched, return false
|
|
||||||
cb(false);
|
|
||||||
return;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Gennerate a counter based One Time Password
|
* Generate a counter based One Time Password
|
||||||
*
|
*
|
||||||
* First argument of callback is the value of the One Time Password
|
* @return {String} the one time password
|
||||||
*
|
*
|
||||||
* Arguments:
|
* Arguments:
|
||||||
*
|
*
|
||||||
@ -168,28 +121,40 @@ module.exports.checkTOTP = function(args, cb) {
|
|||||||
* be user specific, and be incremented for each request.
|
* be user specific, and be incremented for each request.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
module.exports.getHOTP = function(args, cb) {
|
module.exports.getHOTP = function(args) {
|
||||||
|
var key = args.K || '';
|
||||||
|
var counter = args.C || 0;
|
||||||
|
|
||||||
var hmac,
|
var p = 6;
|
||||||
digest,
|
|
||||||
offset, h, v, p = 6, b,
|
|
||||||
i,
|
|
||||||
K = args.K || "",
|
|
||||||
C = args.C || 0,
|
|
||||||
|
|
||||||
|
// Create the byte array
|
||||||
|
var b = new Buffer(intToBytes(counter));
|
||||||
|
|
||||||
// Initiate the HMAC
|
var hmac = crypto.createHmac('SHA1', new Buffer(key));
|
||||||
hmac = crypto.createHmac('SHA1', new Buffer(K))
|
|
||||||
|
|
||||||
cb(this._calcHMAC(K,C));
|
// Update the HMAC witht he byte array
|
||||||
|
var digest = hmac.update(b).digest('hex');
|
||||||
|
|
||||||
|
// Get byte array
|
||||||
|
var h = hexToBytes(digest);
|
||||||
|
|
||||||
|
// Truncate
|
||||||
|
var offset = h[19] & 0xf;
|
||||||
|
var v = (h[offset] & 0x7f) << 24 |
|
||||||
|
(h[offset + 1] & 0xff) << 16 |
|
||||||
|
(h[offset + 2] & 0xff) << 8 |
|
||||||
|
(h[offset + 3] & 0xff);
|
||||||
|
|
||||||
|
v = v + '';
|
||||||
|
|
||||||
|
return v.substr(v.length - p, p);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Gennerate a time based One Time Password
|
* Generate a time based One Time Password
|
||||||
*
|
*
|
||||||
* First argument of callback is the value of the One Time Password
|
* @return {String} the one time password
|
||||||
*
|
*
|
||||||
* Arguments:
|
* Arguments:
|
||||||
*
|
*
|
||||||
@ -203,127 +168,37 @@ module.exports.getHOTP = function(args, cb) {
|
|||||||
* Default - 30
|
* Default - 30
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
module.exports.getTOTP = function(args, cb) {
|
module.exports.getTOTP = function(args) {
|
||||||
var hmac,
|
var K = args.K || '';
|
||||||
digest,
|
var T = args.T || 30;
|
||||||
offset, h, v, p = 6, b,
|
var _t = new Date().getTime();;
|
||||||
C,i,
|
|
||||||
K = args.K || "",
|
|
||||||
T = args.T || 30,
|
|
||||||
_t;
|
|
||||||
|
|
||||||
|
|
||||||
if(args._t) {
|
|
||||||
// Time has been overwritten.
|
// Time has been overwritten.
|
||||||
|
if(args._t) {
|
||||||
console.log('#####################################');
|
console.log('#####################################');
|
||||||
console.log('# NOTE: TOTP TIME VARIABLE HAS BEEN #');
|
console.log('# NOTE: TOTP TIME VARIABLE HAS BEEN #');
|
||||||
console.log('# OVERWRITTEN. THIS SHOULD ONLY BE #');
|
console.log('# OVERWRITTEN. THIS SHOULD ONLY BE #');
|
||||||
console.log('# USED FOR TEST PURPOSES. #');
|
console.log('# USED FOR TEST PURPOSES. #');
|
||||||
console.log('#####################################');
|
console.log('#####################################');
|
||||||
_t = args._t;
|
_t = args._t;
|
||||||
} else {
|
|
||||||
_t = new Date().getTime();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initiate the HMAC
|
|
||||||
hmac = crypto.createHmac('SHA1', new Buffer(K))
|
|
||||||
|
|
||||||
// Determine the value of the counter, C
|
// Determine the value of the counter, C
|
||||||
// This is the number of time steps in seconds since T0
|
// This is the number of time steps in seconds since T0
|
||||||
C = Math.floor((_t / 1000) / T);
|
args.C = Math.floor((_t / 1000) / T);
|
||||||
|
|
||||||
cb(this._calcHMAC(K,C));
|
return this.getHOTP(args);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
/*
|
* convert an integer to a byte array
|
||||||
* Helper function to convert a string to a base32 encoded string
|
* @param {Integer} num
|
||||||
*
|
* @return {Array} bytes
|
||||||
* Arguments:
|
|
||||||
*
|
|
||||||
* str - String to encode
|
|
||||||
*
|
|
||||||
* Returns: Base 32 encoded string
|
|
||||||
*/
|
*/
|
||||||
module.exports.encBase32 = function(str) {
|
var intToBytes = function(num) {
|
||||||
return base32.encode(str);
|
var bytes = [];
|
||||||
};
|
|
||||||
|
|
||||||
|
for(var i=7 ; i>=0 ; --i) {
|
||||||
/*
|
|
||||||
* Helper function to convert a base32 encoded string to an ascii string
|
|
||||||
*
|
|
||||||
* Arguments:
|
|
||||||
*
|
|
||||||
* b32 - String to decode
|
|
||||||
*
|
|
||||||
* Returns: ASCII string
|
|
||||||
*/
|
|
||||||
module.exports.decBase32 = function(b32) {
|
|
||||||
return base32.decode(b32);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************
|
|
||||||
* NOTE: Any functions below this line are private and therefore *
|
|
||||||
* may change without providing backwards compatibility with *
|
|
||||||
* previous versions. You should not call the functions below *
|
|
||||||
* directly. *
|
|
||||||
*******************************************************************/
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Private functon to calculate an HMAC.
|
|
||||||
*
|
|
||||||
* Arguments
|
|
||||||
*
|
|
||||||
* K - Key value
|
|
||||||
* C - Counter value
|
|
||||||
*
|
|
||||||
* Returns - truncated HMAC
|
|
||||||
*/
|
|
||||||
module.exports._calcHMAC = function(K, C) {
|
|
||||||
|
|
||||||
var hmac = crypto.createHmac('SHA1', new Buffer(K)),
|
|
||||||
digest,
|
|
||||||
offset, h, v, p = 6, b;
|
|
||||||
|
|
||||||
// Create the byte array
|
|
||||||
b = new Buffer(this._intToBytes(C)),
|
|
||||||
|
|
||||||
// Update the HMAC witht he byte array
|
|
||||||
hmac.update(b);
|
|
||||||
|
|
||||||
// Diget the HMAC
|
|
||||||
digest = hmac.digest('hex');
|
|
||||||
|
|
||||||
// Get byte array
|
|
||||||
h = this._hexToBytes(digest);
|
|
||||||
|
|
||||||
// Truncate
|
|
||||||
offset = h[19] & 0xf;
|
|
||||||
v = (h[offset] & 0x7f) << 24 | (h[offset + 1] & 0xff) << 16 | (h[offset + 2] & 0xff) << 8 | (h[offset + 3] & 0xff);
|
|
||||||
v = "" + v;
|
|
||||||
v = v.substr(v.length - p, p);
|
|
||||||
|
|
||||||
return v;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Private function to convert an integer to a byte array
|
|
||||||
*
|
|
||||||
* Arguments
|
|
||||||
*
|
|
||||||
* num - Integer
|
|
||||||
*
|
|
||||||
* Returns - byte array
|
|
||||||
*/
|
|
||||||
module.exports._intToBytes = function(num) {
|
|
||||||
var bytes = [],
|
|
||||||
i;
|
|
||||||
|
|
||||||
for(i=7;i>=0;i--) {
|
|
||||||
bytes[i] = num & (255);
|
bytes[i] = num & (255);
|
||||||
num = num >> 8;
|
num = num >> 8;
|
||||||
}
|
}
|
||||||
@ -332,18 +207,16 @@ module.exports._intToBytes = function(num) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Private function to convert a hex value to a byte array
|
* convert a hex value to a byte array
|
||||||
*
|
* @param {String} hex string of hex to convert to a byte array
|
||||||
* Arguments
|
* @return {Array} bytes
|
||||||
*
|
|
||||||
* hex - Hex value
|
|
||||||
*
|
|
||||||
* Returns - byte array
|
|
||||||
*/
|
*/
|
||||||
module.exports._hexToBytes = function(hex) {
|
var hexToBytes = function(hex) {
|
||||||
for(var bytes = [], c = 0; c < hex.length; c += 2)
|
var bytes = [];
|
||||||
|
for(var c = 0; c < hex.length; c += 2) {
|
||||||
bytes.push(parseInt(hex.substr(c, 2), 16));
|
bytes.push(parseInt(hex.substr(c, 2), 16));
|
||||||
|
}
|
||||||
return bytes;
|
return bytes;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
193
test/notp.js
193
test/notp.js
@ -1,9 +1,5 @@
|
|||||||
|
|
||||||
/*
|
var notp = require('..');
|
||||||
* Notp test suite
|
|
||||||
*/
|
|
||||||
|
|
||||||
var notp = require('../lib/notp');
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Test HOTP. Uses test values from RFC 4226
|
* Test HOTP. Uses test values from RFC 4226
|
||||||
@ -48,40 +44,26 @@ var notp = require('../lib/notp');
|
|||||||
* see http://tools.ietf.org/html/rfc4226
|
* see http://tools.ietf.org/html/rfc4226
|
||||||
*/
|
*/
|
||||||
exports.testHOTP = function(beforeExit, assert) {
|
exports.testHOTP = function(beforeExit, assert) {
|
||||||
var n = 0,
|
var args = {
|
||||||
args = {
|
|
||||||
W : 0,
|
W : 0,
|
||||||
K : '12345678901234567890'
|
K : '12345678901234567890'
|
||||||
},
|
};
|
||||||
HOTP = ['755224', '287082','359152', '969429', '338314', '254676', '287922', '162583', '399871', '520489'];
|
var HOTP = ['755224', '287082','359152', '969429', '338314', '254676', '287922', '162583', '399871', '520489'];
|
||||||
|
|
||||||
|
|
||||||
// Check for failure
|
// Check for failure
|
||||||
args.C = 0;
|
args.C = 0;
|
||||||
args.P = 'WILLNOTPASS';
|
args.P = 'WILLNOTPASS';
|
||||||
notp.checkHOTP(args,
|
assert.ok(!notp.checkHOTP(args), 'Should not pass');
|
||||||
function(ret, w) {
|
|
||||||
assert.eql(ret, false, 'Should not pass');
|
|
||||||
n++;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// Check for passes
|
// Check for passes
|
||||||
for(i=0;i<HOTP.length;i++) {
|
for(i=0;i<HOTP.length;i++) {
|
||||||
args.C = i;
|
args.C = i;
|
||||||
args.P = HOTP[i];
|
args.P = HOTP[i];
|
||||||
notp.checkHOTP(args,
|
var res = notp.checkHOTP(args);
|
||||||
function(ret, w) {
|
|
||||||
assert.eql(ret, true, 'Should pass');
|
|
||||||
assert.eql(w, 0, 'Should be in sync');
|
|
||||||
n++;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
beforeExit(function() {
|
assert.ok(res, 'Should pass');
|
||||||
assert.equal(HOTP.length + 1, n, 'All tests should have been run');
|
assert.eql(res.delta, 0, 'Should be in sync');
|
||||||
});
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -91,55 +73,36 @@ exports.testHOTP = function(beforeExit, assert) {
|
|||||||
* see http://tools.ietf.org/id/draft-mraihi-totp-timebased-06.txt
|
* see http://tools.ietf.org/id/draft-mraihi-totp-timebased-06.txt
|
||||||
*/
|
*/
|
||||||
exports.testTOTP = function(beforeExit, assert) {
|
exports.testTOTP = function(beforeExit, assert) {
|
||||||
var n = 0,
|
var args = {
|
||||||
args = {
|
|
||||||
W : 0,
|
W : 0,
|
||||||
K : '12345678901234567890'
|
K : '12345678901234567890'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Check for failure
|
// Check for failure
|
||||||
args.T = 0;
|
args.T = 0;
|
||||||
args.P = 'WILLNOTPASS';
|
args.P = 'WILLNOTPASS';
|
||||||
notp.checkTOTP(args,
|
assert.ok(!notp.checkTOTP(args), 'Should not pass');
|
||||||
function(ret, w) {
|
|
||||||
assert.eql(ret, false, 'Should not pass');
|
|
||||||
n++;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// Check for test vector at 59s
|
// Check for test vector at 59s
|
||||||
args._t = 59*1000;
|
args._t = 59*1000;
|
||||||
args.P = '287082';
|
args.P = '287082';
|
||||||
notp.checkTOTP(args,
|
var res = notp.checkTOTP(args);
|
||||||
function(ret, w) {
|
assert.ok(res, 'Should pass');
|
||||||
assert.eql(ret, true, 'Should pass');
|
assert.eql(res.delta, 0, 'Should be in sync');
|
||||||
assert.eql(w, 0, 'Should be in sync');
|
|
||||||
n++;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// Check for test vector at 1234567890
|
// Check for test vector at 1234567890
|
||||||
args._t = 1234567890*1000;
|
args._t = 1234567890*1000;
|
||||||
args.P = '005924';
|
args.P = '005924';
|
||||||
notp.checkTOTP(args,
|
var res = notp.checkTOTP(args);
|
||||||
function(ret, w) {
|
assert.ok(res, 'Should pass');
|
||||||
assert.eql(ret, true, 'Should pass');
|
assert.eql(res.delta, 0, 'Should be in sync');
|
||||||
assert.eql(w, 0, 'Should be in sync');
|
|
||||||
n++;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// Check for test vector at 1111111109
|
// Check for test vector at 1111111109
|
||||||
args._t = 1111111109*1000;
|
args._t = 1111111109*1000;
|
||||||
args.P = '081804';
|
args.P = '081804';
|
||||||
notp.checkTOTP(args,
|
var res = notp.checkTOTP(args);
|
||||||
function(ret, w) {
|
assert.ok(res, 'Should pass');
|
||||||
assert.eql(ret, true, 'Should pass');
|
assert.eql(res.delta, 0, 'Should be in sync');
|
||||||
assert.eql(w, 0, 'Should be in sync');
|
|
||||||
n++;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// Check for test vector at 2000000000
|
// Check for test vector at 2000000000
|
||||||
args._t = 2000000000*1000;
|
args._t = 2000000000*1000;
|
||||||
@ -151,10 +114,6 @@ exports.testTOTP = function(beforeExit, assert) {
|
|||||||
n++;
|
n++;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
beforeExit(function() {
|
|
||||||
assert.equal(5, n, 'All tests should have been run');
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -165,8 +124,7 @@ exports.testTOTP = function(beforeExit, assert) {
|
|||||||
*/
|
*/
|
||||||
exports.testHOTPOutOfSync = function(beforeExit, assert) {
|
exports.testHOTPOutOfSync = function(beforeExit, assert) {
|
||||||
|
|
||||||
var n = 0,
|
var args = {
|
||||||
args = {
|
|
||||||
K : '12345678901234567890',
|
K : '12345678901234567890',
|
||||||
P : '520489',
|
P : '520489',
|
||||||
C : 1
|
C : 1
|
||||||
@ -174,25 +132,11 @@ exports.testHOTPOutOfSync = function(beforeExit, assert) {
|
|||||||
|
|
||||||
// Check that the test should fail for W < 8
|
// Check that the test should fail for W < 8
|
||||||
args.W = 7;
|
args.W = 7;
|
||||||
notp.checkHOTP(args,
|
assert.ok(!notp.checkHOTP(args), 'Should not pass for value of W < 8');
|
||||||
function(ret, w) {
|
|
||||||
assert.eql(ret, false, 'Should not pass for value of W < 8');
|
|
||||||
n++;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// Check that the test should pass for W >= 9
|
// Check that the test should pass for W >= 9
|
||||||
args.W = 8;
|
args.W = 8;
|
||||||
notp.checkHOTP(args,
|
assert.ok(notp.checkHOTP(args), 'Should pass for value of W >= 9');
|
||||||
function(ret, w) {
|
|
||||||
assert.eql(ret, true, 'Should pass for value of W >= 9');
|
|
||||||
n++;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
beforeExit(function() {
|
|
||||||
assert.equal(2, n, 'All tests should have been run');
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -202,8 +146,7 @@ exports.testHOTPOutOfSync = function(beforeExit, assert) {
|
|||||||
*/
|
*/
|
||||||
exports.testTOTPOutOfSync = function(beforeExit, assert) {
|
exports.testTOTPOutOfSync = function(beforeExit, assert) {
|
||||||
|
|
||||||
var n = 0,
|
var args = {
|
||||||
args = {
|
|
||||||
K : '12345678901234567890',
|
K : '12345678901234567890',
|
||||||
P : '279037',
|
P : '279037',
|
||||||
_t : 1999999909*1000
|
_t : 1999999909*1000
|
||||||
@ -211,25 +154,11 @@ exports.testTOTPOutOfSync = function(beforeExit, assert) {
|
|||||||
|
|
||||||
// Check that the test should fail for W < 2
|
// Check that the test should fail for W < 2
|
||||||
args.W = 2;
|
args.W = 2;
|
||||||
notp.checkTOTP(args,
|
assert.ok(!notp.checkTOTP(args), 'Should not pass for value of W < 3');
|
||||||
function(ret, w) {
|
|
||||||
assert.eql(ret, false, 'Should not pass for value of W < 3');
|
|
||||||
n++;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// Check that the test should pass for W >= 3
|
// Check that the test should pass for W >= 3
|
||||||
args.W = 3;
|
args.W = 3;
|
||||||
notp.checkTOTP(args,
|
assert.ok(notp.checkTOTP(args), 'Should pass for value of W >= 3');
|
||||||
function(ret, w) {
|
|
||||||
assert.eql(ret, true, 'Should pass for value of W >= 3');
|
|
||||||
n++;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
beforeExit(function() {
|
|
||||||
assert.equal(2, n, 'All tests should have been run');
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -237,27 +166,18 @@ exports.testTOTPOutOfSync = function(beforeExit, assert) {
|
|||||||
* Test getHOTP function. Uses same test values as for checkHOTP
|
* Test getHOTP function. Uses same test values as for checkHOTP
|
||||||
*/
|
*/
|
||||||
exports.testGetHOTP = function(beforeExit, assert) {
|
exports.testGetHOTP = function(beforeExit, assert) {
|
||||||
var n = 0,
|
var args = {
|
||||||
args = {
|
|
||||||
W : 0,
|
W : 0,
|
||||||
K : '12345678901234567890'
|
K : '12345678901234567890'
|
||||||
},
|
};
|
||||||
HOTP = ['755224', '287082','359152', '969429', '338314', '254676', '287922', '162583', '399871', '520489'];
|
|
||||||
|
var HOTP = ['755224', '287082','359152', '969429', '338314', '254676', '287922', '162583', '399871', '520489'];
|
||||||
|
|
||||||
// Check for passes
|
// Check for passes
|
||||||
for(i=0;i<HOTP.length;i++) {
|
for(i=0;i<HOTP.length;i++) {
|
||||||
args.C = i;
|
args.C = i;
|
||||||
notp.getHOTP(args,
|
assert.eql(notp.getHOTP(args), HOTP[i], 'HTOP value should be correct');
|
||||||
function(ret) {
|
|
||||||
assert.eql(ret, HOTP[i], 'HTOP value should be correct');
|
|
||||||
n++;
|
|
||||||
}
|
}
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
beforeExit(function() {
|
|
||||||
assert.equal(HOTP.length, n, 'All tests should have been run');
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -265,66 +185,25 @@ exports.testGetHOTP = function(beforeExit, assert) {
|
|||||||
* Test getTOTP function. Uses same test values as for checkTOTP
|
* Test getTOTP function. Uses same test values as for checkTOTP
|
||||||
*/
|
*/
|
||||||
exports.testGetTOTP = function(beforeExit, assert) {
|
exports.testGetTOTP = function(beforeExit, assert) {
|
||||||
var n = 0,
|
var args = {
|
||||||
args = {
|
|
||||||
W : 0,
|
W : 0,
|
||||||
K : '12345678901234567890'
|
K : '12345678901234567890'
|
||||||
};
|
};
|
||||||
|
|
||||||
// Check for test vector at 59s
|
// Check for test vector at 59s
|
||||||
args._t = 59*1000;
|
args._t = 59*1000;
|
||||||
notp.getTOTP(args,
|
assert.eql(notp.getTOTP(args), '287082', 'TOTP values should match');
|
||||||
function(ret, w) {
|
|
||||||
assert.eql(ret, '287082', 'TOTP values should match');
|
|
||||||
n++;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// Check for test vector at 1234567890
|
// Check for test vector at 1234567890
|
||||||
args._t = 1234567890*1000;
|
args._t = 1234567890*1000;
|
||||||
notp.getTOTP(args,
|
assert.eql(notp.getTOTP(args), '005924', 'TOTP values should match');
|
||||||
function(ret, w) {
|
|
||||||
assert.eql(ret, '005924', 'TOTP values should match');
|
|
||||||
n++;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// Check for test vector at 1111111109
|
// Check for test vector at 1111111109
|
||||||
args._t = 1111111109*1000;
|
args._t = 1111111109*1000;
|
||||||
notp.getTOTP(args,
|
assert.eql(notp.getTOTP(args), '081804', 'TOTP values should match');
|
||||||
function(ret, w) {
|
|
||||||
assert.eql(ret, '081804', 'TOTP values should match');
|
|
||||||
n++;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// Check for test vector at 2000000000
|
// Check for test vector at 2000000000
|
||||||
args._t = 2000000000*1000;
|
args._t = 2000000000*1000;
|
||||||
notp.getTOTP(args,
|
assert.eql(notp.getTOTP(args), '279037', 'TOTP values should match');
|
||||||
function(ret, w) {
|
|
||||||
assert.eql(ret, '279037', 'TOTP values should match');
|
|
||||||
n++;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
beforeExit(function() {
|
|
||||||
assert.equal(4, n, 'All tests should have been run');
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
* Test encode to base32
|
|
||||||
*/
|
|
||||||
exports.testEncodeToBase32 = function(beforeExit, assert) {
|
|
||||||
assert.eql(notp.encBase32('12345678901234567890'), 'GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ');
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Test decode base32
|
|
||||||
*/
|
|
||||||
exports.testDecodeFromBase32 = function(beforeExit, assert) {
|
|
||||||
assert.eql(notp.decBase32('GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ'), '12345678901234567890');
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user