mirror of
https://github.com/fluencelabs/fluence-js.git
synced 2025-06-22 20:31:32 +00:00
Sig service redesign (#126)
This commit is contained in:
128
src/internal/builtins/Sig.ts
Normal file
128
src/internal/builtins/Sig.ts
Normal file
@ -0,0 +1,128 @@
|
||||
import { SecurityTetraplet } from '@fluencelabs/avm-runner-interface';
|
||||
import { CallParams, PeerIdB58 } from '../commonTypes';
|
||||
import { KeyPair } from '../KeyPair';
|
||||
import { SigDef } from '../_aqua/services';
|
||||
|
||||
/**
|
||||
* A predicate of call params for sig service's sign method which determines whether signing operation is allowed or not
|
||||
*/
|
||||
export type SigSecurityGuard = (params: CallParams<'data'>) => boolean;
|
||||
|
||||
/**
|
||||
* Only allow calls when tetraplet for 'data' argument satisfies the predicate
|
||||
*/
|
||||
export const allowTetraplet = (pred: (tetraplet: SecurityTetraplet) => boolean): SigSecurityGuard => {
|
||||
return (params) => {
|
||||
const t = params.tetraplets.data[0];
|
||||
return pred(t);
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Only allow data which comes from the specified serviceId and fnName
|
||||
*/
|
||||
export const allowServiceFn = (serviceId: string, fnName: string): SigSecurityGuard => {
|
||||
return allowTetraplet((t) => {
|
||||
return t.service_id === serviceId && t.function_name === fnName;
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Only allow data originated from the specified json_path
|
||||
*/
|
||||
export const allowExactJsonPath = (jsonPath: string): SigSecurityGuard => {
|
||||
return allowTetraplet((t) => {
|
||||
return t.json_path === jsonPath;
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Only allow signing when particle is initiated at the specified peer
|
||||
*/
|
||||
export const allowOnlyParticleOriginatedAt = (peerId: PeerIdB58): SigSecurityGuard => {
|
||||
return (params) => {
|
||||
return params.initPeerId === peerId;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Only allow signing when all of the predicates are satisfied.
|
||||
* Useful for predicates reuse
|
||||
*/
|
||||
export const and = (...predicates: SigSecurityGuard[]): SigSecurityGuard => {
|
||||
return (params) => predicates.every((x) => x(params));
|
||||
};
|
||||
|
||||
/**
|
||||
* Only allow signing when any of the predicates are satisfied.
|
||||
* Useful for predicates reuse
|
||||
*/
|
||||
export const or = (...predicates: SigSecurityGuard[]): SigSecurityGuard => {
|
||||
return (params) => predicates.some((x) => x(params));
|
||||
};
|
||||
|
||||
export const defaultSigGuard = (peerId: PeerIdB58) => {
|
||||
return and(
|
||||
allowOnlyParticleOriginatedAt(peerId),
|
||||
or(
|
||||
allowServiceFn('trust-graph', 'get_trust_bytes'),
|
||||
allowServiceFn('trust-graph', 'get_revocation_bytes'),
|
||||
allowServiceFn('registry', 'get_key_bytes'),
|
||||
allowServiceFn('registry', 'get_record_bytes'),
|
||||
allowServiceFn('registry', 'get_host_record_bytes'),
|
||||
),
|
||||
);
|
||||
};
|
||||
|
||||
export class Sig implements SigDef {
|
||||
private _keyPair: KeyPair;
|
||||
|
||||
constructor(keyPair: KeyPair) {
|
||||
this._keyPair = keyPair;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
securityGuard: SigSecurityGuard = (params) => {
|
||||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the public key of KeyPair. Required by aqua
|
||||
*/
|
||||
get_pub_key() {
|
||||
return this._keyPair.toB58String();
|
||||
}
|
||||
|
||||
/**
|
||||
* Signs the data using key pair's private key. Required by aqua
|
||||
*/
|
||||
async sign(
|
||||
data: number[],
|
||||
callParams: CallParams<'data'>,
|
||||
): Promise<{ error: string | null; signature: number[] | null; success: boolean }> {
|
||||
if (!this.securityGuard(callParams)) {
|
||||
return {
|
||||
success: false,
|
||||
error: 'Security guard validation failed',
|
||||
signature: null,
|
||||
};
|
||||
}
|
||||
|
||||
const signedData = await this._keyPair.signBytes(Uint8Array.from(data));
|
||||
|
||||
return {
|
||||
success: true,
|
||||
error: null,
|
||||
signature: Array.from(signedData),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies the signature. Required by aqua
|
||||
*/
|
||||
verify(signature: number[], data: number[]): Promise<boolean> {
|
||||
return this._keyPair.verify(Uint8Array.from(data), Uint8Array.from(signature));
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user