-
-
Notifications
You must be signed in to change notification settings - Fork 65
/
Copy pathauth.ts
43 lines (36 loc) · 1.35 KB
/
auth.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
import { createHash, SupportedAlgorithm } from "../deps.ts";
import { xor } from "./util.ts";
import { encode } from "./buffer.ts";
function hash(algorithm: SupportedAlgorithm, data: Uint8Array): Uint8Array {
return new Uint8Array(createHash(algorithm).update(data).digest());
}
function mysqlNativePassword(password: string, seed: Uint8Array): Uint8Array {
const pwd1 = hash("sha1", encode(password));
const pwd2 = hash("sha1", pwd1);
let seedAndPwd2 = new Uint8Array(seed.length + pwd2.length);
seedAndPwd2.set(seed);
seedAndPwd2.set(pwd2, seed.length);
seedAndPwd2 = hash("sha1", seedAndPwd2);
return xor(seedAndPwd2, pwd1);
}
function cachingSha2Password(password: string, seed: Uint8Array): Uint8Array {
const stage1 = hash("sha256", encode(password));
const stage2 = hash("sha256", stage1);
const stage3 = hash("sha256", Uint8Array.from([...stage2, ...seed]));
return xor(stage1, stage3);
}
export default function auth(
authPluginName: string,
password: string,
seed: Uint8Array,
) {
switch (authPluginName) {
case "mysql_native_password":
// Native password authentication only need and will need 20-byte challenge.
return mysqlNativePassword(password, seed.slice(0, 20));
case "caching_sha2_password":
return cachingSha2Password(password, seed);
default:
throw new Error("Not supported");
}
}