This commit is contained in:
Tutur33
2023-11-24 22:35:41 +01:00
parent 3c0b507a93
commit 7644b2a0f7
45165 changed files with 4803356 additions and 3 deletions
+44
View File
@@ -0,0 +1,44 @@
/// <reference path="../../adonis-typings/hash.d.ts" />
import { ArgonConfig, ArgonContract } from '@ioc:Adonis/Core/Hash';
/**
* Hash driver built on top of argon hashing algorithm. The driver adheres
* to `phc` string format.
*/
export declare class Argon implements ArgonContract {
private config;
/**
* A list of ids to find if hash belongs to this driver
* or not.
*/
ids: ArgonContract['ids'];
/**
* A list of params encoded to the hash value.
*/
params: ArgonContract['params'];
/**
* The current argon version in use
*/
version: number;
constructor(config: ArgonConfig);
/**
* Hash a value using argon algorithm. The options can be used to override
* default settings.
*/
make(value: string): any;
/**
* Verifies the hash against a plain value to find if it's
* a valid hash or not.
*/
verify(hashedValue: string, plainValue: string): Promise<boolean>;
/**
* Returns a boolean telling if the hash needs a rehash or not. The rehash is
* required when
*
* 1. The argon2 version is changed
* 2. Number of iterations are changed.
* 3. The memory value is changed.
* 4. The parellelism value is changed.
* 5. The argon variant is changed.
*/
needsReHash(value: string): boolean;
}
+92
View File
@@ -0,0 +1,92 @@
"use strict";
/*
* @adonisjs/hash
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Argon = void 0;
/// <reference path="../../adonis-typings/hash.ts" />
const format_1 = __importDefault(require("@phc/format"));
const phc_argon2_1 = __importDefault(require("phc-argon2"));
/**
* Hash driver built on top of argon hashing algorithm. The driver adheres
* to `phc` string format.
*/
class Argon {
constructor(config) {
this.config = config;
/**
* A list of ids to find if hash belongs to this driver
* or not.
*/
this.ids = ['argon2d', 'argon2i', 'argon2id'];
/**
* A list of params encoded to the hash value.
*/
this.params = {
iterations: 't',
memory: 'm',
parallelism: 'p',
};
/**
* The current argon version in use
*/
this.version = 19;
}
/**
* Hash a value using argon algorithm. The options can be used to override
* default settings.
*/
make(value) {
return phc_argon2_1.default.hash(value, this.config);
}
/**
* Verifies the hash against a plain value to find if it's
* a valid hash or not.
*/
verify(hashedValue, plainValue) {
return phc_argon2_1.default.verify(hashedValue, plainValue);
}
/**
* Returns a boolean telling if the hash needs a rehash or not. The rehash is
* required when
*
* 1. The argon2 version is changed
* 2. Number of iterations are changed.
* 3. The memory value is changed.
* 4. The parellelism value is changed.
* 5. The argon variant is changed.
*/
needsReHash(value) {
const deserialized = format_1.default.deserialize(value);
if (!this.ids.includes(deserialized.id)) {
throw new Error('value is not an argon2 hash');
}
/**
* Version mis-match
*/
if (deserialized.version !== this.version) {
return true;
}
/**
* Variant mis-match
*/
if (deserialized.id !== `argon2${this.config.variant}`) {
return true;
}
/**
* Check for params mis-match
*/
return !!Object.keys(this.params).find((key) => {
return deserialized.params[this.params[key]] !== this.config[key];
});
}
}
exports.Argon = Argon;
+26
View File
@@ -0,0 +1,26 @@
/// <reference path="../../adonis-typings/hash.d.ts" />
import { BcryptConfig, BcryptContract } from '@ioc:Adonis/Core/Hash';
/**
* Generates and verifies hash using Bcrypt as underlying
* algorigthm.
*/
export declare class Bcrypt implements BcryptContract {
private config;
ids: BcryptContract['ids'];
params: BcryptContract['params'];
version: number;
constructor(config: BcryptConfig);
/**
* Returns hash for a given value
*/
make(value: string): any;
/**
* Verify hash to know if two values are same.
*/
verify(hashedValue: string, plainValue: string): Promise<boolean>;
/**
* Returns a boolean telling if hash needs a rehash. Returns true when
* one of the original params have been changed.
*/
needsReHash(value: string): boolean;
}
+67
View File
@@ -0,0 +1,67 @@
"use strict";
/*
* @adonisjs/hash
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Bcrypt = void 0;
/// <reference path="../../adonis-typings/hash.ts" />
const format_1 = __importDefault(require("@phc/format"));
const phc_bcrypt_1 = __importDefault(require("phc-bcrypt"));
/**
* Generates and verifies hash using Bcrypt as underlying
* algorigthm.
*/
class Bcrypt {
constructor(config) {
this.config = config;
this.ids = ['bcrypt'];
this.params = { rounds: 'r' };
this.version = 98;
}
/**
* Returns hash for a given value
*/
make(value) {
return phc_bcrypt_1.default.hash(value, this.config);
}
/**
* Verify hash to know if two values are same.
*/
verify(hashedValue, plainValue) {
return phc_bcrypt_1.default.verify(hashedValue, plainValue);
}
/**
* Returns a boolean telling if hash needs a rehash. Returns true when
* one of the original params have been changed.
*/
needsReHash(value) {
const deserialized = format_1.default.deserialize(value);
/**
* Phc formatted Bycrpt hash
*/
if (deserialized.id === 'bcrypt') {
if (this.version !== deserialized.version) {
return true;
}
return !!Object.keys(this.params).find((key) => {
return deserialized.params[this.params[key]] !== this.config[key];
});
}
/**
* Re-format non phc formatted bcrypt hashes.
*/
if (value.startsWith('$2b') || value.startsWith('$2a')) {
return true;
}
throw new Error('value is not a bcrypt hash');
}
}
exports.Bcrypt = Bcrypt;
+21
View File
@@ -0,0 +1,21 @@
/// <reference path="../../adonis-typings/hash.d.ts" />
import { FakeContract } from '@ioc:Adonis/Core/Hash';
/**
* Generates and verifies hash using no algorigthm.
*/
export declare class Fake implements FakeContract {
ids: FakeContract['ids'];
/**
* Returns hash for a given value
*/
make(value: string): Promise<string>;
/**
* Verify hash to know if two values are same.
*/
verify(hashedValue: string, plainValue: string): Promise<boolean>;
/**
* Returns a boolean telling if hash needs a rehash. Returns true when
* one of the original params have been changed.
*/
needsReHash(_value: string): boolean;
}
+39
View File
@@ -0,0 +1,39 @@
"use strict";
/*
* @adonisjs/hash
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.Fake = void 0;
/**
* Generates and verifies hash using no algorigthm.
*/
class Fake {
constructor() {
this.ids = ['fake'];
}
/**
* Returns hash for a given value
*/
make(value) {
return Promise.resolve(value);
}
/**
* Verify hash to know if two values are same.
*/
verify(hashedValue, plainValue) {
return Promise.resolve(hashedValue === plainValue);
}
/**
* Returns a boolean telling if hash needs a rehash. Returns true when
* one of the original params have been changed.
*/
needsReHash(_value) {
return false;
}
}
exports.Fake = Fake;
+33
View File
@@ -0,0 +1,33 @@
import type { ScryptConfig, ScryptContract } from '@ioc:Adonis/Core/Hash';
/**
* Hash driver built on top of scrypt hashing algorithm. The driver adheres
* to `phc` string format.
*/
export declare class Scrypt implements ScryptContract {
private readonly config;
/**
* A list of ids to find if hash belongs to this driver
* or not.
*/
ids: ScryptContract['ids'];
/**
* A list of params encoded to the hash value.
*/
params: ScryptContract['params'];
constructor(config: ScryptConfig);
/**
* Hash a value using scrypt algorithm. The options can be used to override
* default settings.
*/
make(value: string): Promise<any>;
/**
* Verifies the hash against a plain value to find if it's
* a valid hash or not. The hash must be a valid `phc` string
*/
verify(hashedValue: string, plainValue: string): Promise<boolean>;
/**
* Returns a boolean telling if hash needs a rehash. Returns true when
* one of the original params have been changed.
*/
needsReHash(hashedValue: string): boolean;
}
+178
View File
@@ -0,0 +1,178 @@
"use strict";
/*
* @adonisjs/hash
*
* (c) AdonisJS
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Scrypt = void 0;
const format_1 = __importDefault(require("@phc/format"));
const crypto_1 = require("crypto");
const utils_1 = require("../utils");
const defaultConfig = Object.freeze({
cost: 16384,
blockSize: 8,
parallelization: 1,
saltSize: 16,
keyLength: 64,
maxMemory: 128 * 16384 * 8,
});
function scryptAsync(password, salt, keyLength, options) {
return new Promise((resolve, reject) => {
(0, crypto_1.scrypt)(password, salt, keyLength, options, (error, derivedKey) => {
if (error) {
reject(error);
}
else {
resolve(derivedKey);
}
});
});
}
/**
* Hash driver built on top of scrypt hashing algorithm. The driver adheres
* to `phc` string format.
*/
class Scrypt {
constructor(config) {
this.config = config;
/**
* A list of ids to find if hash belongs to this driver
* or not.
*/
this.ids = ['scrypt'];
/**
* A list of params encoded to the hash value.
*/
this.params = {
cost: 'n',
blockSize: 'r',
parallelization: 'p',
};
// Cost Validation
if (config.cost < 1 || config.cost % 2 !== 0) {
throw new TypeError("The 'cost' option must be a power of 2 greater than 1");
}
// Parallelization Validation
if (config.parallelization < 1 || config.parallelization > utils_1.kMaxUint24) {
throw new TypeError(`The 'parallelism' option must be in the range (1 <= parallelism <= ${utils_1.kMaxUint24})`);
}
// Memory Validation
const maxMemory = 128 * config.cost * config.blockSize;
if (maxMemory > config.maxMemory) {
throw new TypeError(`The 'maxmem' option must be less than ${maxMemory}, found ${config.maxMemory}`);
}
// Salt Size Validation
if (config.saltSize < 16 || config.saltSize > 1024) {
throw new TypeError("The 'saltSize' option must be in the range (8 <= saltSize <= 1024)");
}
// Key Length Validation
if (config.keyLength < 64 || config.keyLength > 128) {
throw new TypeError("The 'keylen' option must be in the range (64 <= keylen <= 128)");
}
this.config = Object.assign({}, defaultConfig, config);
}
/**
* Hash a value using scrypt algorithm. The options can be used to override
* default settings.
*/
async make(value) {
const salt = await (0, utils_1.randomBytesAsync)(this.config.saltSize);
const derivedKey = await scryptAsync(value, salt, this.config.keyLength, this.config);
return format_1.default.serialize({
id: this.ids[0],
params: {
n: this.config.cost,
r: this.config.blockSize,
p: this.config.parallelization,
},
salt,
hash: derivedKey,
});
}
/**
* Verifies the hash against a plain value to find if it's
* a valid hash or not. The hash must be a valid `phc` string
*/
async verify(hashedValue, plainValue) {
let deserializedHash;
try {
deserializedHash = format_1.default.deserialize(hashedValue);
}
catch (error) {
throw new TypeError('The hash must be a valid phc string');
}
// Identifier Validation
if (!this.ids.includes(deserializedHash.id)) {
throw new TypeError(`Incompatible ${deserializedHash.id} identifier found in the hash`);
}
// Parameters Existence Validation
if (typeof deserializedHash.params !== 'object') {
throw new TypeError('The param section cannot be empty');
}
// Cost Validation
if (typeof deserializedHash.params.n !== 'number' ||
!Number.isInteger(deserializedHash.params.n)) {
throw new TypeError("The 'n' param must be an integer");
}
// Cost Validation
if (deserializedHash.params.n < 1 || deserializedHash.params.n % 2 !== 0) {
throw new TypeError("The 'n' param must be a power of 2 greater than 1");
}
// Block size Validation
if (typeof deserializedHash.params.r !== 'number' ||
!Number.isInteger(deserializedHash.params.r)) {
throw new TypeError("The 'r' param must be an integer");
}
// Parallelization Validation
if (typeof deserializedHash.params.p !== 'number' ||
!Number.isInteger(deserializedHash.params.p)) {
throw new TypeError("The 'p' param must be an integer");
}
// Parallelization Validation
if (deserializedHash.params.p < 1 || deserializedHash.params.p > utils_1.kMaxUint24) {
throw new TypeError(`The 'p' param must be in the range (1 <= parallelism <= ${utils_1.kMaxUint24})`);
}
// Salt Validation
if (typeof deserializedHash.salt === 'undefined') {
throw new TypeError('No salt found in the given string');
}
// Hash Validation
if (typeof deserializedHash.hash === 'undefined') {
throw new TypeError('No hash found in the given string');
}
const derivedKey = await scryptAsync(plainValue, deserializedHash.salt, deserializedHash.hash.length, {
maxmem: this.config.maxMemory,
cost: deserializedHash.params.n,
blockSize: deserializedHash.params.r,
parallelization: deserializedHash.params.p,
});
return (0, crypto_1.timingSafeEqual)(deserializedHash.hash, derivedKey);
}
/**
* Returns a boolean telling if hash needs a rehash. Returns true when
* one of the original params have been changed.
*/
needsReHash(hashedValue) {
let deserializedHash;
try {
deserializedHash = format_1.default.deserialize(hashedValue);
}
catch (error) {
return true;
}
if (!this.ids.includes(deserializedHash.id)) {
throw new Error('Value is not a scrypt hash');
}
return Object.keys(this.params).some((key) => {
return deserializedHash.params[this.params[key]] !== this.config[key];
});
}
}
exports.Scrypt = Scrypt;