summary refs log tree commit diff
path: root/src/util/Signing.ts
diff options
context:
space:
mode:
authorRory& <root@rory.gay>2026-04-21 21:11:02 +0200
committerRory& <root@rory.gay>2026-04-21 21:11:02 +0200
commit7905fc9f5fc9612e2aed37a85cacff538fc03fbe (patch)
treed1596c6512ceb68f416bf637ee40cc4b92b2f76a /src/util/Signing.ts
parentUpdate genIndex to add ane xtra newline (diff)
downloadserver-ts-7905fc9f5fc9612e2aed37a85cacff538fc03fbe.tar.xz
Hexdump CDN hashes
Diffstat (limited to 'src/util/Signing.ts')
-rw-r--r--src/util/Signing.ts53
1 files changed, 53 insertions, 0 deletions
diff --git a/src/util/Signing.ts b/src/util/Signing.ts

index 141ca0ff..4aa29a24 100644 --- a/src/util/Signing.ts +++ b/src/util/Signing.ts
@@ -19,6 +19,9 @@ import { Config } from "@spacebar/util"; import { createHmac, timingSafeEqual } from "node:crypto"; import ms, { StringValue } from "ms"; +import { TextDecoder } from "node:util"; +import { ConsoleUtils } from "./util/ConsoleUtils"; +import { ColorUtils } from "./util/ColorUtils"; export class NewUrlUserSignatureData { ip?: string; @@ -132,11 +135,14 @@ export const getUrlSignature = (data: NewUrlSignatureData): UrlSignResult => { function calculateHash(request: UrlSignatureData): UrlSignResult { const { cdnSignatureKey } = Config.get().security; + const newData = createHmac("sha256", cdnSignatureKey as string); const data = createHmac("sha256", cdnSignatureKey as string) .update(request.path!) .update(request.issuedAt) .update(request.expiresAt); + let ipData = new Int8Array(); + if (Config.get().security.cdnSignatureIncludeIp) { if (!request.ip) console.log( @@ -145,9 +151,11 @@ function calculateHash(request: UrlSignatureData): UrlSignResult { else { if (process.env["LOG_CDN_SIGNATURES"]) console.log("[Signing] CDN Signature IP is enabled, adding IP to hash:", request.ip); data.update(request.ip!); + ipData = new Int8Array(new TextEncoder().encode(request.ip!)); } } + let userAgentData = new Int8Array(); if (Config.get().security.cdnSignatureIncludeUserAgent) { if (!request.userAgent) console.log( @@ -156,10 +164,29 @@ function calculateHash(request: UrlSignatureData): UrlSignResult { else { if (process.env["LOG_CDN_SIGNATURES"]) console.log("[Signing] CDN Signature User-Agent is enabled, adding User-Agent to hash:", request.userAgent); data.update(request.userAgent!); + userAgentData = new Int8Array(new TextEncoder().encode(request.userAgent!)); } } + const rawData = new Int8Array([ + ...new TextEncoder().encode(request.path!), + ...new TextEncoder().encode(request.issuedAt), + ...new TextEncoder().encode(request.expiresAt), + ...ipData, + ...userAgentData, + ]); + if (process.env["LOG_CDN_SIGNATURES"]) { + console.log("[Signing] Signature data for ", request.path!); + hexdump(rawData); + } + newData.update(rawData); + const hash = data.digest("hex"); + const newHash = newData.digest("hex"); + if (process.env["LOG_CDN_SIGNATURES"]) { + console.log(hash); + console.log(newHash); + } const result = new UrlSignResult({ path: request.path, issuedAt: request.issuedAt, @@ -257,3 +284,29 @@ export const hasValidSignature = (req: NewUrlUserSignatureData, sig: UrlSignResu return isHashValid; }; + +// port of https://github.com/TheArcaneBrony/ArcaneLibs/blob/master/ArcaneLibs/Extensions/DictionaryExtensions.cs#L80 +function hexdump(arr: Int8Array, width: number = 32, colorize: boolean = true) { + const colorizeFunc = colorize ? (val: number, str: string) => ConsoleUtils.ColoredString(str, ColorUtils.cnv8To24(val)) : (val: number, str: string) => str; + for (let i = 0; i < arr.length; i += width) { + const end = Math.min(i + width, arr.length); + const section = arr.slice(i, end); + console.log( + Array.from(section) + .map((x) => colorizeFunc(x, x.toString(16).toUpperCase())) + .join(" ") + .padEnd(3 * section.length), + "|", + new TextDecoder("utf-8") + .decode(section) + .replaceAll("\n", ".") + .replaceAll("\r", ".") + .replaceAll("\0", ".") + .replaceAll("\t", ".") + .replaceAll("\v", ".") + .replaceAll("\b", ".") + .replaceAll("\x07", ".") // \a + .replaceAll("\f", "."), + ); + } +}