asymmetric keys
Some checks failed
continuous-integration/drone/push Build is failing

This commit is contained in:
2021-01-06 16:06:03 +01:00
parent 1437316519
commit adfeeaa52c
9 changed files with 207 additions and 147 deletions

View File

@ -21,7 +21,6 @@ interface AccessResult {
refresh_token_id?: string;
}
interface AccessResponse {
token_type: string;
access_token: string;
@ -69,15 +68,20 @@ class AuthRequest {
this.response.setHeader ('Content-Type', 'application/json');
}
public allow_access ({
public async allow_access ({
access_token_expires_in,
include_refresh_token,
refresh_token_expires_in,
data
}: AccessSettings): AccessResult {
}: AccessSettings): Promise<AccessResult> {
this.default_header ();
const at = auth.sign ('access_token', access_token_expires_in, { data });
const at = await auth.sign (
'access_token',
access_token_expires_in,
{ data }
);
const result: AccessResult = { access_token_id: at.id };
const res: AccessResponse = {
@ -96,7 +100,7 @@ class AuthRequest {
if (include_refresh_token) {
if (typeof refresh_token_expires_in !== 'number')
throw new Error ('no expiry time defined for refresh tokens');
const rt = auth.sign (
const rt = await auth.sign (
'refresh_token',
refresh_token_expires_in,
{ data }
@ -111,14 +115,14 @@ class AuthRequest {
return result;
}
public allow_part (
public async allow_part (
part_token_expires_in: number,
next_module: string,
data?: Record<string, unknown>
): string {
): Promise<string> {
this.default_header ();
const pt = auth.sign (
const pt = await auth.sign (
'part_token',
part_token_expires_in,
{ next_module, data }

View File

@ -79,13 +79,13 @@ class Authority {
return result;
}
public sign (
public async sign (
type: TokenType,
valid_for: number,
options?: SignatureOptions
): SignatureResult {
): Promise<SignatureResult> {
const time = Date.now ();
const key = keystore.get_key (time / 1000, valid_for);
const key = await keystore.get_sign_key (time / 1000, valid_for);
const attributes = {
id: create_salt (),
iat: time,

View File

@ -5,14 +5,24 @@
* Created by Timo Hocker <timo@scode.ovh>, December 2020
*/
import { create_salt } from '@sapphirecode/crypto-helper';
import { generate_keypair } from '@sapphirecode/crypto-helper';
interface Keypair {
private_key: string;
public_key: string;
}
interface Key {
key: string;
key: Keypair;
valid_until: number;
timeout: NodeJS.Timeout;
}
function get_index (iat: number): string {
return Math.floor (iat / 60)
.toFixed (0);
}
class KeyStore {
private _keys: Record<string, Key> = {};
@ -22,38 +32,46 @@ class KeyStore {
}, (valid_for + 5) * 1000);
}
public get_key (iat: number, valid_for = 0): string {
const index = Math.floor (iat / 60)
.toFixed (0);
public async get_sign_key (iat: number, valid_for: number): Promise<string> {
const index = get_index (iat);
if (valid_for <= 0)
throw new Error ('cannot create infinitely valid key');
if ((iat + 1) * 1000 < (new Date)
.getTime ())
throw new Error ('cannot access already expired keys');
const valid_until = (new Date)
.getTime () + (valid_for * 1000);
if (typeof this._keys[index] !== 'undefined') {
const key = this._keys[index];
if (valid_for !== 0 && key.valid_until < valid_until) {
if (key.valid_until < valid_until) {
clearTimeout (key.timeout);
key.timeout = this.set_timeout (index, valid_for);
key.valid_until = valid_until;
}
return key.key;
return key.key.private_key;
}
if (valid_for !== 0) {
if ((iat + 1) * 1000 < (new Date)
.getTime ())
throw new Error ('cannot create already expired keys');
this._keys[index] = {
key: await generate_keypair (),
timeout: this.set_timeout (index, valid_for),
valid_until
};
this._keys[index] = {
key: create_salt (),
timeout: this.set_timeout (index, valid_for),
valid_until
};
return this._keys[index].key.private_key;
}
return this._keys[index].key;
}
public get_key (iat: number): string {
const index = get_index (iat);
throw new Error ('key could not be found');
if (typeof this._keys[index] === 'undefined')
throw new Error ('key could not be found');
const key = this._keys[index];
return key.key.public_key;
}
}