mirror of
https://github.com/zerotier/ztchooks-ts.git
synced 2026-05-22 16:29:35 -07:00
add failing tests + clean up TS style
This commit is contained in:
@@ -1,29 +1,19 @@
|
||||
|
||||
import * as crypto from "crypto-js";
|
||||
|
||||
export function verifySignature(
|
||||
preSharedKey: string,
|
||||
sigHeader: string,
|
||||
payload: string,
|
||||
toleranceSeconds: number): boolean {
|
||||
|
||||
export function verifySignature(psk: string, sigHeader: string, payload: string, ttl: number): boolean {
|
||||
try {
|
||||
var header = parseHeader(sigHeader, toleranceSeconds);
|
||||
var expectedSig = generateExpectedSignature(header, preSharedKey, payload);
|
||||
const header = parseHeader(sigHeader, ttl);
|
||||
const expectedSig = generateExpectedSignature(header, psk, payload);
|
||||
|
||||
for (var i = 0; i < header.signatures.length; i++) {
|
||||
if (header.signatures[i] === expectedSig) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return !!header.signatures.find((val) => val == expectedSig);
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
console.error(error);
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
class signedHeader {
|
||||
class SignedHeader {
|
||||
timestamp: number;
|
||||
signatures: string[];
|
||||
|
||||
@@ -33,28 +23,26 @@ class signedHeader {
|
||||
}
|
||||
}
|
||||
|
||||
function parseHeader(sigHeader: string, toleranceSeconds: number): signedHeader {
|
||||
function parseHeader(sigHeader: string, ttl: number): SignedHeader {
|
||||
var pairs: string[] = sigHeader.split(',');
|
||||
var sh = decode(pairs, toleranceSeconds);
|
||||
var sh = decode(pairs, ttl);
|
||||
if (sh.signatures.length == 0) {
|
||||
throw "Invalid Signature";
|
||||
}
|
||||
|
||||
return sh
|
||||
return sh;
|
||||
}
|
||||
|
||||
function decode(pairs: string[], toleranceSeconds: number): signedHeader {
|
||||
var sh = new signedHeader();
|
||||
for (var i = 0; i < pairs.length; i++) {
|
||||
var p = pairs[i];
|
||||
|
||||
function decode(pairs: string[], ttl: number): SignedHeader {
|
||||
const sh = new SignedHeader();
|
||||
for (const p of pairs) {
|
||||
var parts = p.split('=');
|
||||
|
||||
if (parts.length != 2) {
|
||||
throw "Invalid Header";
|
||||
}
|
||||
|
||||
var item = parts[0];
|
||||
var value = parts[1];
|
||||
const [item, value] = parts;
|
||||
|
||||
if (item == "t") {
|
||||
var timestamp = parseInt(value, 10);
|
||||
@@ -65,18 +53,18 @@ function decode(pairs: string[], toleranceSeconds: number): signedHeader {
|
||||
}
|
||||
|
||||
if (item[0] == "v") {
|
||||
sh.signatures.push(value)
|
||||
sh.signatures.push(value);
|
||||
}
|
||||
}
|
||||
|
||||
if ((Date.now() / 1000) > (sh.timestamp + toleranceSeconds)) {
|
||||
if ((Date.now() / 1000) > (sh.timestamp + ttl)) {
|
||||
throw "Timestamp Expired";
|
||||
}
|
||||
|
||||
return sh;
|
||||
}
|
||||
|
||||
function generateExpectedSignature(sh: signedHeader, preSharedKey: string, payload: string) {
|
||||
var tmp = sh.timestamp.toLocaleString().split(',').join('') + "," + payload;
|
||||
return crypto.enc.Hex.stringify(crypto.HmacSHA256(tmp, crypto.enc.Hex.parse(preSharedKey)));
|
||||
function generateExpectedSignature(sh: SignedHeader, psk: string, payload: string) {
|
||||
const sig = sh.timestamp.toLocaleString().split(',').join('') + "," + payload;
|
||||
return crypto.enc.Hex.stringify(crypto.HmacSHA256(sig, crypto.enc.Hex.parse(psk)));
|
||||
}
|
||||
@@ -8,4 +8,22 @@ describe('testing verifySignature', () => {
|
||||
test('test verify signature should pass', () => {
|
||||
expect(verifySignature(psk, signature, payload, Number.MAX_SAFE_INTEGER)).toBe(true);
|
||||
});
|
||||
|
||||
test('invalid signature fails', () => {
|
||||
expect(
|
||||
verifySignature(
|
||||
psk,
|
||||
signature.replace("9", "0"),
|
||||
payload,
|
||||
Number.MAX_SAFE_INTEGER
|
||||
)
|
||||
).toBe(false)
|
||||
});
|
||||
|
||||
// Note: this test depends on the current clock being later than the timestamp
|
||||
// above (6-Sept-2023)
|
||||
test('expired signature fails', () => {
|
||||
jest.spyOn(global.console, 'error').mockImplementationOnce((_: any) => {});
|
||||
expect(verifySignature(psk, signature, payload, 1)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user