You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

125 lines
3.2 KiB
JavaScript

var Promise, defaultParameters, errors, getDefaultParameters, normalizePassword, scrypt, scryptErrorMap, scryptHandler;
scrypt = require("scrypt");
errors = require("errors");
Promise = require("bluebird");
errors.create({
name: "ScryptError"
});
errors.create({
name: "ScryptInputError",
parents: errors.ScryptError
});
errors.create({
name: "ScryptPasswordError",
parents: errors.ScryptError
});
errors.create({
name: "ScryptInternalError",
parents: errors.ScryptError
});
scryptErrorMap = {
"getrlimit or sysctl(hw.usermem) failed": 1,
"clock_getres or clock_gettime failed": 2,
"error computing derived key": 3,
"could not read salt from /dev/urandom": 4,
"error in OpenSSL": 5,
"malloc failed": 6,
"data is not a valid scrypt-encrypted block": 7,
"unrecognized scrypt format": 8,
"decrypting file would take too much memory": 9,
"decrypting file would take too long": 10,
"password is incorrect": 11,
"error writing output file": 12,
"error reading input file": 13,
"error unkown": -1
};
defaultParameters = Promise.promisify(scrypt.params)(0.1, void 0, void 0);
getDefaultParameters = function(params) {
if (params != null) {
return params;
} else {
return defaultParameters;
}
};
normalizePassword = function(password) {
if (Buffer.isBuffer(password)) {
return password;
} else {
return new Buffer(password);
}
};
scryptHandler = function(resolve, reject) {
return function(err, result) {
var errorObj;
if (err != null) {
errorObj = (function() {
switch (scryptErrorMap[err.message]) {
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 9:
case 10:
case 12:
case 13:
case -1:
return errors.ScryptInternalError;
case 7:
case 8:
return errors.ScryptInputError;
case 11:
return errors.ScryptPasswordError;
}
})();
return reject(new errorObj(err.message));
} else if (result === true) {
return resolve(result);
} else if (result === false) {
return reject(new errors.ScryptPasswordError("The password did not match."));
} else {
return resolve(result.toString("base64"));
}
};
};
module.exports = {
hash: function(password, options, callback) {
if (options == null) {
options = {};
}
return Promise["try"](function() {
return getDefaultParameters(options.params);
}).then(function(parameters) {
return new Promise(function(resolve, reject) {
return scrypt.kdf(normalizePassword(password), parameters, scryptHandler(resolve, reject));
});
}).nodeify(callback);
},
verifyHash: function(password, hash, callback) {
return (new Promise(function(resolve, reject) {
var hashBuffer;
hashBuffer = new Buffer(hash, "base64");
return scrypt.verifyKdf(hashBuffer, normalizePassword(password), scryptHandler(resolve, reject));
})).nodeify(callback);
},
ScryptError: errors.ScryptError,
InputError: errors.ScryptInputError,
PasswordError: errors.ScryptPasswordError,
InternalError: errors.ScryptInternalError,
scryptLib: scrypt
};