2024-01-01 14:58:21 -05:00
|
|
|
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
2023-06-27 02:18:22 -04:00
|
|
|
|
|
|
|
// TODO(petamoriken): enable prefer-primordials for node polyfills
|
|
|
|
// deno-lint-ignore-file prefer-primordials
|
|
|
|
|
2024-01-10 17:37:25 -05:00
|
|
|
import { core } from "ext:core/mod.js";
|
|
|
|
const {
|
|
|
|
op_node_pbkdf2,
|
|
|
|
op_node_pbkdf2_async,
|
|
|
|
} = core.ensureFastOps();
|
|
|
|
|
2023-07-02 14:19:30 -04:00
|
|
|
import { Buffer } from "node:buffer";
|
2023-03-08 06:44:54 -05:00
|
|
|
import { HASH_DATA } from "ext:deno_node/internal/crypto/types.ts";
|
2023-02-14 11:38:45 -05:00
|
|
|
|
|
|
|
export const MAX_ALLOC = Math.pow(2, 30) - 1;
|
|
|
|
|
|
|
|
export type NormalizedAlgorithms =
|
|
|
|
| "md5"
|
|
|
|
| "ripemd160"
|
|
|
|
| "sha1"
|
|
|
|
| "sha224"
|
|
|
|
| "sha256"
|
|
|
|
| "sha384"
|
|
|
|
| "sha512";
|
|
|
|
|
|
|
|
export type Algorithms =
|
|
|
|
| "md5"
|
|
|
|
| "ripemd160"
|
|
|
|
| "rmd160"
|
|
|
|
| "sha1"
|
|
|
|
| "sha224"
|
|
|
|
| "sha256"
|
|
|
|
| "sha384"
|
|
|
|
| "sha512";
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param iterations Needs to be higher or equal than zero
|
|
|
|
* @param keylen Needs to be higher or equal than zero but less than max allocation size (2^30)
|
|
|
|
* @param digest Algorithm to be used for encryption
|
|
|
|
*/
|
|
|
|
export function pbkdf2Sync(
|
|
|
|
password: HASH_DATA,
|
|
|
|
salt: HASH_DATA,
|
|
|
|
iterations: number,
|
|
|
|
keylen: number,
|
|
|
|
digest: Algorithms = "sha1",
|
|
|
|
): Buffer {
|
|
|
|
if (typeof iterations !== "number" || iterations < 0) {
|
|
|
|
throw new TypeError("Bad iterations");
|
|
|
|
}
|
|
|
|
if (typeof keylen !== "number" || keylen < 0 || keylen > MAX_ALLOC) {
|
|
|
|
throw new TypeError("Bad key length");
|
|
|
|
}
|
|
|
|
|
2023-03-28 05:40:56 -04:00
|
|
|
const DK = new Uint8Array(keylen);
|
2024-01-10 17:37:25 -05:00
|
|
|
if (!op_node_pbkdf2(password, salt, iterations, digest, DK)) {
|
2023-03-28 05:40:56 -04:00
|
|
|
throw new Error("Invalid digest");
|
2023-02-14 11:38:45 -05:00
|
|
|
}
|
|
|
|
|
2023-03-28 05:40:56 -04:00
|
|
|
return Buffer.from(DK);
|
2023-02-14 11:38:45 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param iterations Needs to be higher or equal than zero
|
|
|
|
* @param keylen Needs to be higher or equal than zero but less than max allocation size (2^30)
|
|
|
|
* @param digest Algorithm to be used for encryption
|
|
|
|
*/
|
|
|
|
export function pbkdf2(
|
|
|
|
password: HASH_DATA,
|
|
|
|
salt: HASH_DATA,
|
|
|
|
iterations: number,
|
|
|
|
keylen: number,
|
|
|
|
digest: Algorithms = "sha1",
|
|
|
|
callback: (err: Error | null, derivedKey?: Buffer) => void,
|
|
|
|
) {
|
2023-03-28 05:40:56 -04:00
|
|
|
if (typeof iterations !== "number" || iterations < 0) {
|
|
|
|
throw new TypeError("Bad iterations");
|
|
|
|
}
|
|
|
|
if (typeof keylen !== "number" || keylen < 0 || keylen > MAX_ALLOC) {
|
|
|
|
throw new TypeError("Bad key length");
|
|
|
|
}
|
|
|
|
|
2023-12-26 20:30:26 -05:00
|
|
|
op_node_pbkdf2_async(
|
2023-03-28 05:40:56 -04:00
|
|
|
password,
|
|
|
|
salt,
|
|
|
|
iterations,
|
|
|
|
digest,
|
|
|
|
keylen,
|
|
|
|
).then(
|
|
|
|
(DK) => callback(null, Buffer.from(DK)),
|
|
|
|
)
|
|
|
|
.catch((err) => callback(err));
|
2023-02-14 11:38:45 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
export default {
|
|
|
|
MAX_ALLOC,
|
|
|
|
pbkdf2,
|
|
|
|
pbkdf2Sync,
|
|
|
|
};
|