diff options
Diffstat (limited to 'node_modules/keygrip/index.js')
| -rw-r--r-- | node_modules/keygrip/index.js | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/node_modules/keygrip/index.js b/node_modules/keygrip/index.js new file mode 100644 index 00000000..5cdeba53 --- /dev/null +++ b/node_modules/keygrip/index.js @@ -0,0 +1,71 @@ +/*! + * keygrip + * Copyright(c) 2011-2014 Jed Schmidt + * MIT Licensed + */ + +'use strict' + +var crypto = require("crypto") + +function Keygrip(keys, algorithm, encoding) { + if (!algorithm) algorithm = "sha1"; + if (!encoding) encoding = "base64"; + if (!(this instanceof Keygrip)) return new Keygrip(keys, algorithm, encoding) + + if (!keys || !(0 in keys)) { + throw new Error("Keys must be provided.") + } + + function sign(data, key) { + return crypto + .createHmac(algorithm, key) + .update(data).digest(encoding) + .replace(/\/|\+|=/g, function(x) { + return ({ "/": "_", "+": "-", "=": "" })[x] + }) + } + + this.sign = function(data){ return sign(data, keys[0]) } + + this.verify = function(data, digest) { + return this.index(data, digest) > -1 + } + + this.index = function(data, digest) { + for (var i = 0, l = keys.length; i < l; i++) { + if (constantTimeCompare(digest, sign(data, keys[i]))) return i + } + + return -1 + } +} + +Keygrip.sign = Keygrip.verify = Keygrip.index = function() { + throw new Error("Usage: require('keygrip')(<array-of-keys>)") +} + +//http://codahale.com/a-lesson-in-timing-attacks/ +var constantTimeCompare = function(val1, val2){ + if(val1 == null && val2 != null){ + return false; + } else if(val2 == null && val1 != null){ + return false; + } else if(val1 == null && val2 == null){ + return true; + } + + if(val1.length !== val2.length){ + return false; + } + + var result = 0; + + for(var i = 0; i < val1.length; i++){ + result |= val1.charCodeAt(i) ^ val2.charCodeAt(i); //Don't short circuit + } + + return result === 0; +}; + +module.exports = Keygrip |
