summaryrefslogtreecommitdiff
path: root/node_modules/notp/index.js
diff options
context:
space:
mode:
authorMinteck <contact@minteck.org>2022-08-10 10:38:44 +0200
committerMinteck <contact@minteck.org>2022-08-10 10:38:44 +0200
commitc6dbf0450566c40efc4a26f4f0717452b6ef95cd (patch)
treeb4be2d508223820d0a77d5a3e35e82684da3b6ec /node_modules/notp/index.js
downloadhornchat-c6dbf0450566c40efc4a26f4f0717452b6ef95cd.tar.gz
hornchat-c6dbf0450566c40efc4a26f4f0717452b6ef95cd.tar.bz2
hornchat-c6dbf0450566c40efc4a26f4f0717452b6ef95cd.zip
Initial commitHEADmane
Diffstat (limited to 'node_modules/notp/index.js')
-rw-r--r--node_modules/notp/index.js221
1 files changed, 221 insertions, 0 deletions
diff --git a/node_modules/notp/index.js b/node_modules/notp/index.js
new file mode 100644
index 0000000..de0d91f
--- /dev/null
+++ b/node_modules/notp/index.js
@@ -0,0 +1,221 @@
+
+var crypto = require('crypto');
+
+var hotp = {};
+
+/**
+ * Generate a counter based One Time Password
+ *
+ * @return {String} the one time password
+ *
+ * Arguments:
+ *
+ * args
+ * key - Key for the one time password. This should be unique and secret for
+ * every user as this is the seed that is used to calculate the HMAC
+ *
+ * counter - Counter value. This should be stored by the application, must
+ * be user specific, and be incremented for each request.
+ *
+ */
+hotp.gen = function(key, opt) {
+ key = key || '';
+ opt = opt || {};
+ var counter = opt.counter || 0;
+
+ var p = 6;
+
+ // Create the byte array
+ var b = new Buffer(intToBytes(counter));
+
+ var hmac = crypto.createHmac('sha1', new Buffer(key));
+
+ // Update the HMAC with the 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);
+};
+
+/**
+ * Check a One Time Password based on a counter.
+ *
+ * @return {Object} null if failure, { delta: # } on success
+ * delta is the time step difference between the client and the server
+ *
+ * Arguments:
+ *
+ * args
+ * key - Key for the one time password. This should be unique and secret for
+ * every user as it is the seed used to calculate the HMAC
+ *
+ * token - Passcode to validate.
+ *
+ * window - The allowable margin for the counter. The function will check
+ * 'W' codes in the future against the provided passcode. Note,
+ * it is the calling applications responsibility to keep track of
+ * 'W' and increment it for each password check, and also to adjust
+ * it accordingly in the case where the client and server become
+ * out of sync (second argument returns non zero).
+ * E.g. if W = 100, and C = 5, this function will check the passcode
+ * against all One Time Passcodes between 5 and 105.
+ *
+ * Default - 50
+ *
+ * counter - Counter value. This should be stored by the application, must
+ * be user specific, and be incremented for each request.
+ *
+ */
+hotp.verify = function(token, key, opt) {
+ opt = opt || {};
+ var window = opt.window || 50;
+ var counter = opt.counter || 0;
+
+ // Now loop through from C to C + W to determine if there is
+ // a correct code
+ for(var i = counter - window; i <= counter + window; ++i) {
+ opt.counter = i;
+ if(this.gen(key, opt) === token) {
+ // We have found a matching code, trigger callback
+ // and pass offset
+ return { delta: i - counter };
+ }
+ }
+
+ // If we get to here then no codes have matched, return null
+ return null;
+};
+
+var totp = {};
+
+/**
+ * Generate a time based One Time Password
+ *
+ * @return {String} the one time password
+ *
+ * Arguments:
+ *
+ * args
+ * key - Key for the one time password. This should be unique and secret for
+ * every user as it is the seed used to calculate the HMAC
+ *
+ * time - The time step of the counter. This must be the same for
+ * every request and is used to calculat C.
+ *
+ * Default - 30
+ *
+ */
+totp.gen = function(key, opt) {
+ opt = opt || {};
+ var time = opt.time || 30;
+ var _t = new Date().getTime();;
+
+ // Time has been overwritten.
+ if(opt._t) {
+ if(process.env.NODE_ENV != 'test') {
+ throw new Error('cannot overwrite time in non-test environment!');
+ }
+ _t = opt._t;
+ }
+
+ // Determine the value of the counter, C
+ // This is the number of time steps in seconds since T0
+ opt.counter = Math.floor((_t / 1000) / time);
+
+ return hotp.gen(key, opt);
+};
+
+/**
+ * Check a One Time Password based on a timer.
+ *
+ * @return {Object} null if failure, { delta: # } on success
+ * delta is the time step difference between the client and the server
+ *
+ * Arguments:
+ *
+ * args
+ * key - Key for the one time password. This should be unique and secret for
+ * every user as it is the seed used to calculate the HMAC
+ *
+ * token - Passcode to validate.
+ *
+ * window - The allowable margin for the counter. The function will check
+ * 'W' codes either side of the provided counter. Note,
+ * it is the calling applications responsibility to keep track of
+ * 'W' and increment it for each password check, and also to adjust
+ * it accordingly in the case where the client and server become
+ * out of sync (second argument returns non zero).
+ * E.g. if W = 5, and C = 1000, this function will check the passcode
+ * against all One Time Passcodes between 995 and 1005.
+ *
+ * Default - 6
+ *
+ * time - The time step of the counter. This must be the same for
+ * every request and is used to calculate C.
+ *
+ * Default - 30
+ *
+ */
+totp.verify = function(token, key, opt) {
+ opt = opt || {};
+ var time = opt.time || 30;
+ var _t = new Date().getTime();
+
+ // Time has been overwritten.
+ if(opt._t) {
+ if(process.env.NODE_ENV != 'test') {
+ throw new Error('cannot overwrite time in non-test environment!');
+ }
+ _t = opt._t;
+ }
+
+ // Determine the value of the counter, C
+ // This is the number of time steps in seconds since T0
+ opt.counter = Math.floor((_t / 1000) / time);
+
+ return hotp.verify(token, key, opt);
+};
+
+module.exports.hotp = hotp;
+module.exports.totp = totp;
+
+/**
+ * convert an integer to a byte array
+ * @param {Integer} num
+ * @return {Array} bytes
+ */
+var intToBytes = function(num) {
+ var bytes = [];
+
+ for(var i=7 ; i>=0 ; --i) {
+ bytes[i] = num & (255);
+ num = num >> 8;
+ }
+
+ return bytes;
+};
+
+
+/**
+ * convert a hex value to a byte array
+ * @param {String} hex string of hex to convert to a byte array
+ * @return {Array} bytes
+ */
+var hexToBytes = function(hex) {
+ var bytes = [];
+ for(var c = 0; c < hex.length; c += 2) {
+ bytes.push(parseInt(hex.substr(c, 2), 16));
+ }
+ return bytes;
+};