summaryrefslogtreecommitdiffstats
path: root/node_modules/pbkdf2/lib/async.js
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/pbkdf2/lib/async.js')
-rw-r--r--node_modules/pbkdf2/lib/async.js102
1 files changed, 102 insertions, 0 deletions
diff --git a/node_modules/pbkdf2/lib/async.js b/node_modules/pbkdf2/lib/async.js
new file mode 100644
index 0000000..9ef67c3
--- /dev/null
+++ b/node_modules/pbkdf2/lib/async.js
@@ -0,0 +1,102 @@
+var Buffer = require('safe-buffer').Buffer
+
+var checkParameters = require('./precondition')
+var defaultEncoding = require('./default-encoding')
+var sync = require('./sync')
+var toBuffer = require('./to-buffer')
+
+var ZERO_BUF
+var subtle = global.crypto && global.crypto.subtle
+var toBrowser = {
+ sha: 'SHA-1',
+ 'sha-1': 'SHA-1',
+ sha1: 'SHA-1',
+ sha256: 'SHA-256',
+ 'sha-256': 'SHA-256',
+ sha384: 'SHA-384',
+ 'sha-384': 'SHA-384',
+ 'sha-512': 'SHA-512',
+ sha512: 'SHA-512'
+}
+var checks = []
+function checkNative (algo) {
+ if (global.process && !global.process.browser) {
+ return Promise.resolve(false)
+ }
+ if (!subtle || !subtle.importKey || !subtle.deriveBits) {
+ return Promise.resolve(false)
+ }
+ if (checks[algo] !== undefined) {
+ return checks[algo]
+ }
+ ZERO_BUF = ZERO_BUF || Buffer.alloc(8)
+ var prom = browserPbkdf2(ZERO_BUF, ZERO_BUF, 10, 128, algo)
+ .then(function () {
+ return true
+ }).catch(function () {
+ return false
+ })
+ checks[algo] = prom
+ return prom
+}
+
+function browserPbkdf2 (password, salt, iterations, length, algo) {
+ return subtle.importKey(
+ 'raw', password, { name: 'PBKDF2' }, false, ['deriveBits']
+ ).then(function (key) {
+ return subtle.deriveBits({
+ name: 'PBKDF2',
+ salt: salt,
+ iterations: iterations,
+ hash: {
+ name: algo
+ }
+ }, key, length << 3)
+ }).then(function (res) {
+ return Buffer.from(res)
+ })
+}
+
+function resolvePromise (promise, callback) {
+ promise.then(function (out) {
+ process.nextTick(function () {
+ callback(null, out)
+ })
+ }, function (e) {
+ process.nextTick(function () {
+ callback(e)
+ })
+ })
+}
+module.exports = function (password, salt, iterations, keylen, digest, callback) {
+ if (typeof digest === 'function') {
+ callback = digest
+ digest = undefined
+ }
+
+ digest = digest || 'sha1'
+ var algo = toBrowser[digest.toLowerCase()]
+
+ if (!algo || typeof global.Promise !== 'function') {
+ return process.nextTick(function () {
+ var out
+ try {
+ out = sync(password, salt, iterations, keylen, digest)
+ } catch (e) {
+ return callback(e)
+ }
+ callback(null, out)
+ })
+ }
+
+ checkParameters(iterations, keylen)
+ password = toBuffer(password, defaultEncoding, 'Password')
+ salt = toBuffer(salt, defaultEncoding, 'Salt')
+ if (typeof callback !== 'function') throw new Error('No callback provided to pbkdf2')
+
+ resolvePromise(checkNative(algo).then(function (resp) {
+ if (resp) return browserPbkdf2(password, salt, iterations, keylen, algo)
+
+ return sync(password, salt, iterations, keylen, digest)
+ }), callback)
+}