195 lines
6.2 KiB
TypeScript
Raw Normal View History

/*
* Copyright (C) Sapphirecode - All Rights Reserved
* This file is part of Auth-Server-Helper which is released under MIT.
* See file 'LICENSE' for full license details.
* Created by Timo Hocker <timo@scode.ovh>, December 2020
*/
2021-01-08 13:30:53 +01:00
import ks, { KeyStore } from '../../lib/KeyStore';
2021-01-07 15:43:54 +01:00
import { clock_finalize, clock_setup } from '../Helper';
2020-12-06 21:06:40 +01:00
2021-01-08 13:30:53 +01:00
const frame = 3600;
2021-01-06 11:15:56 +01:00
2020-12-06 21:06:40 +01:00
/* eslint-disable-next-line max-lines-per-function */
describe ('key store', () => {
beforeAll (() => {
2021-01-07 15:43:54 +01:00
clock_setup ();
});
afterAll (() => {
clock_finalize ();
2020-12-06 21:06:40 +01:00
});
2021-05-10 12:41:00 +02:00
const keys: {key: string, sign: string, iat: number}[] = [];
2020-12-06 21:06:40 +01:00
2021-01-06 16:06:03 +01:00
it ('should generate a new key', async () => {
2020-12-06 21:06:40 +01:00
const iat = (new Date)
.getTime () / 1000;
2021-01-06 11:15:56 +01:00
const duration = 10 * frame;
2021-01-06 16:06:03 +01:00
const key = await ks.get_sign_key (iat, duration);
2022-08-08 15:52:56 +02:00
const sign = await ks.get_key (iat);
2020-12-06 21:06:40 +01:00
expect (typeof key)
.toEqual ('string');
2021-01-06 16:06:03 +01:00
expect (typeof sign)
.toEqual ('string');
keys.push ({ iat, key, sign });
2020-12-06 21:06:40 +01:00
});
2021-01-06 16:06:03 +01:00
it ('should return the generated key', async () => {
const key = await ks.get_sign_key (keys[0].iat, 1);
2020-12-06 21:06:40 +01:00
expect (key)
.toEqual (keys[0].key);
2022-08-08 15:52:56 +02:00
const sign = await ks.get_key (keys[0].iat);
2021-01-06 16:06:03 +01:00
expect (sign)
.toEqual (keys[0].sign);
2020-12-06 21:06:40 +01:00
});
2021-01-06 16:06:03 +01:00
it ('should return the same key on a different time', async () => {
const key = await ks.get_sign_key (keys[0].iat + (frame / 2), 1);
2020-12-06 21:06:40 +01:00
expect (key)
.toEqual (keys[0].key);
2022-08-08 15:52:56 +02:00
const sign = await ks.get_key (keys[0].iat + (frame / 2));
2021-01-06 16:06:03 +01:00
expect (sign)
.toEqual (keys[0].sign);
2020-12-06 21:06:40 +01:00
});
2021-01-06 16:06:03 +01:00
it ('should generate a new key after time frame is over', async () => {
2020-12-06 21:06:40 +01:00
jasmine.clock ()
2021-01-06 11:15:56 +01:00
.tick (frame * 1000);
2020-12-06 21:06:40 +01:00
const iat = (new Date)
.getTime () / 1000;
2021-01-06 11:15:56 +01:00
const duration = 10 * frame;
2021-01-06 16:06:03 +01:00
const key = await ks.get_sign_key (iat, duration);
2022-08-08 15:52:56 +02:00
const sign = await ks.get_key (iat);
2020-12-06 21:06:40 +01:00
expect (typeof key)
.toEqual ('string');
expect (key).not.toEqual (keys[0].key);
2021-01-06 16:06:03 +01:00
expect (sign).not.toEqual (keys[0].sign);
keys.push ({ iat, key, sign });
2020-12-06 21:06:40 +01:00
});
2021-01-06 16:06:03 +01:00
it ('should return both keys, but not the first sign key', async () => {
2022-08-08 15:52:56 +02:00
const sign = await ks.get_key (keys[0].iat);
2021-01-06 16:06:03 +01:00
expect (sign)
.toEqual (keys[0].sign);
await expectAsync (ks.get_sign_key (keys[0].iat, 1))
.toBeRejectedWithError ('cannot access already expired keys');
const k2 = await ks.get_sign_key (keys[1].iat, 1);
2022-08-08 15:52:56 +02:00
const s2 = await ks.get_key (keys[1].iat);
2020-12-06 21:06:40 +01:00
expect (k2)
.toEqual (keys[1].key);
2021-01-06 16:06:03 +01:00
expect (s2)
.toEqual (keys[1].sign);
2020-12-06 21:06:40 +01:00
});
2022-08-08 15:52:56 +02:00
it ('should throw on non existing key', async () => {
await expectAsync (ks.get_key (keys[1].iat + frame))
.toBeRejectedWithError ('key could not be found');
2020-12-06 21:06:40 +01:00
});
2022-08-08 15:52:56 +02:00
it ('should delete a key after it expires', async () => {
2021-01-07 15:43:54 +01:00
// go to 10 frames + 1ms after key creation
2020-12-06 21:06:40 +01:00
jasmine.clock ()
2021-01-07 15:43:54 +01:00
.tick ((frame * 9e3) + 1);
// eslint-disable-next-line dot-notation
ks['garbage_collect'] ();
2022-08-08 15:52:56 +02:00
await expectAsync (ks.get_key (keys[0].iat))
.toBeRejectedWithError ('key could not be found');
2020-12-06 21:06:40 +01:00
});
2021-01-06 16:06:03 +01:00
it (
'should still retrieve the second key, but not its sign key',
async () => {
await expectAsync (ks.get_sign_key (keys[1].iat, 1))
.toBeRejectedWithError ('cannot access already expired keys');
2022-08-08 15:52:56 +02:00
const sign = await ks.get_key (keys[1].iat);
2021-01-06 16:06:03 +01:00
expect (sign)
.toEqual (keys[1].sign);
}
);
it ('should reject key generation of expired keys', async () => {
2020-12-06 21:29:11 +01:00
const iat = ((new Date)
2021-01-06 11:15:56 +01:00
.getTime () / 1000) - 2;
2020-12-06 21:29:11 +01:00
const duration = 5;
2021-01-06 16:06:03 +01:00
await expectAsync (ks.get_sign_key (iat, duration))
.toBeRejectedWithError ('cannot access already expired keys');
2020-12-06 21:29:11 +01:00
});
2021-01-06 16:06:03 +01:00
it ('key should live as long as the longest created token', async () => {
2021-01-06 11:15:56 +01:00
jasmine.clock ()
2021-01-07 15:43:54 +01:00
.tick (frame * 10e3);
2021-01-06 11:15:56 +01:00
const iat = (new Date)
.getTime () / 1000;
const duration1 = frame;
const duration2 = frame * 10;
2021-01-06 16:06:03 +01:00
const key1 = await ks.get_sign_key (iat, duration1);
2021-01-06 11:15:56 +01:00
const step = 0.9 * frame;
jasmine.clock ()
.tick (step * 1000);
2021-01-06 16:06:03 +01:00
const key2 = await ks.get_sign_key (iat + step, duration2);
2022-08-08 15:52:56 +02:00
const sign = await ks.get_key (iat);
2021-01-06 11:15:56 +01:00
expect (key1)
.toEqual (key2);
jasmine.clock ()
.tick (5000 * frame);
2022-08-08 15:52:56 +02:00
const signv = await ks.get_key (iat + step);
2021-01-06 16:06:03 +01:00
expect (signv)
.toEqual (sign);
2021-01-06 11:15:56 +01:00
});
2021-01-06 22:43:03 +01:00
it ('should not allow invalid expiry times', async () => {
await expectAsync (ks.get_sign_key (0, 0))
.toBeRejectedWithError ('cannot create infinitely valid key');
await expectAsync (ks.get_sign_key (0, -1))
.toBeRejectedWithError ('cannot create infinitely valid key');
});
2021-01-08 13:30:53 +01:00
it ('should export and import all keys', async () => {
const iat = (new Date)
.getTime () / 1000;
const sign = await ks.get_sign_key (iat, frame);
2022-08-08 15:52:56 +02:00
const ver = await ks.get_key (iat);
2021-01-08 13:30:53 +01:00
const exp = ks.export_verification_data ();
// eslint-disable-next-line dot-notation
expect (Object.keys (ks['_keys']))
2021-01-14 21:31:21 +01:00
.toEqual (exp.map ((v) => v.index));
2021-01-08 13:30:53 +01:00
const ks2 = (new KeyStore);
expect (ks2.instance_id).not.toEqual (ks.instance_id);
ks2.import_verification_data (exp);
// eslint-disable-next-line dot-notation
2021-01-14 21:31:21 +01:00
expect (Object.keys (ks2['_keys']))
.toEqual (exp.map ((v) => v.index));
2021-01-08 13:30:53 +01:00
const sign2 = await ks2.get_sign_key (iat, frame);
2022-08-08 15:52:56 +02:00
const ver2 = await ks2.get_key (iat);
2021-01-08 13:30:53 +01:00
expect (sign).not.toEqual (sign2);
expect (ver).not.toEqual (ver2);
await expectAsync (ks2.get_sign_key (iat, 60, ks.instance_id))
.toBeRejectedWithError ('cannot access already expired keys');
2022-08-08 15:52:56 +02:00
expect (await ks2.get_key (iat, ks.instance_id))
2021-01-08 13:30:53 +01:00
.toEqual (ver);
});
it ('should disallow importing to itself', () => {
const exp = ks.export_verification_data ();
expect (() => ks.import_verification_data (exp))
.toThrowError ('cannot import to the same instance');
});
2021-01-15 14:45:05 +01:00
it ('should clear all', () => {
// eslint-disable-next-line dot-notation
expect (Object.keys (ks['_keys']).length)
.toBeGreaterThan (0);
const instance = ks.instance_id;
ks.reset_instance ();
// eslint-disable-next-line dot-notation
expect (Object.keys (ks['_keys']).length)
.toEqual (0);
expect (instance).not.toEqual (ks.instance_id);
});
2020-12-06 21:06:40 +01:00
});