UNPKG

@ltonetwork/http-message-signatures

Version:

Implementation of the IETF HTTP Message Signatures draft standard

39 lines (29 loc) 1.8 kB
import { LTO, LTOAccount, Parameters, RequestLike, ResponseLike, Verify } from './types'; import { parseSignatureHeader, parseSignatureInputHeader } from './parse'; import { buildSignedData, extractHeader } from './build'; const algToKeyType = { ed25519: 'ed25519', 'ecdsa-secp256k1': 'secp256k1', 'ecdsa-p256': 'secp256r1', }; export function verifyWithLTO<T>(lto: LTO<T>, signedData: string, signature: Uint8Array, parameters: Parameters): T { const keyType = algToKeyType[parameters.alg]; if (!keyType) throw new Error(`Unsupported algorithm for LTO: ${parameters.alg}`); const account = lto.account({ keyType, publicKey: parameters.keyid }) as LTOAccount; if (!account.verify(signedData, signature)) throw new Error('Invalid signature'); return account as T; } export async function verify<T>(message: RequestLike | ResponseLike, verifier: Verify<T> | LTO<T>): Promise<T> { const signatureInputHeader = extractHeader(message, 'signature-input'); if (!signatureInputHeader) throw new Error('Message does not contain Signature-Input header'); const { key, components, parameters } = parseSignatureInputHeader(signatureInputHeader); if (parameters.expires && parameters.expires < new Date()) throw new Error('Signature expired'); const signatureHeader = extractHeader(message, 'signature'); if (!signatureHeader) throw new Error('Message does not contain Signature header'); const signature = parseSignatureHeader(key, signatureHeader); const signatureInputString = signatureInputHeader.toString().replace(/^[^=]+=/, ''); const signedData = buildSignedData(message, components, signatureInputString); return typeof verifier === 'function' ? verifier(signedData, signature, parameters) : verifyWithLTO(verifier, signedData, signature, parameters); }