UNPKG

signify-ts

Version:

Signing at the edge for KERI, ACDC, and KERIA

102 lines (101 loc) 3.54 kB
import { desiginput, HEADER_SIG_INPUT, HEADER_SIG_TIME, normalize, siginput, } from "./httping.js"; import { Signage, signature, designature } from "../end/ending.js"; export class Authenticater { constructor(csig, verfer) { this._csig = csig; this._verfer = verfer; } verify(headers, method, path) { const siginput = headers.get(HEADER_SIG_INPUT); if (siginput == null) { return false; } const signature = headers.get('Signature'); if (signature == null) { return false; } let inputs = desiginput(siginput); inputs = inputs.filter((input) => input.name == 'signify'); if (inputs.length == 0) { return false; } inputs.forEach((input) => { const items = new Array(); input.fields.forEach((field) => { if (field.startsWith('@')) { if (field == '@method') { items.push(`"${field}": ${method}`); } else if (field == '@path') { items.push(`"${field}": ${path}`); } } else { if (headers.has(field)) { const value = normalize(headers.get(field)); items.push(`"${field}": ${value}`); } } }); const values = new Array(); values.push(`(${input.fields.join(' ')})`); values.push(`created=${input.created}`); if (input.expires != undefined) { values.push(`expires=${input.expires}`); } if (input.nonce != undefined) { values.push(`nonce=${input.nonce}`); } if (input.keyid != undefined) { values.push(`keyid=${input.keyid}`); } if (input.context != undefined) { values.push(`context=${input.context}`); } if (input.alg != undefined) { values.push(`alg=${input.alg}`); } const params = values.join(';'); items.push(`"@signature-params: ${params}"`); const ser = items.join('\n'); const signage = designature(signature); const markers = signage[0].markers; const cig = markers.get(input.name); if (!cig || !this._verfer.verify(cig.raw, ser)) { throw new Error(`Signature for ${input.keyid} invalid.`); } }); return true; } sign(headers, method, path, fields) { if (fields == undefined) { fields = Authenticater.DefaultFields; } const [header, sig] = siginput(this._csig, { name: 'signify', method, path, headers, fields, alg: 'ed25519', keyid: this._csig.verfer.qb64, }); header.forEach((value, key) => { headers.append(key, value); }); const markers = new Map(); markers.set('signify', sig); const signage = new Signage(markers, false); const signed = signature([signage]); signed.forEach((value, key) => { headers.append(key, value); }); return headers; } } Authenticater.DefaultFields = [ '@method', '@path', 'signify-resource', HEADER_SIG_TIME.toLowerCase(), ];