Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 | 41x 41x 41x 41x 41x 41x 5x 5x 6x 5x 1x 1x 5x 5x 5x 5x 5x 5x 5x 5x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x | import { verify } from '@noble/secp256k1'; import { base64ToBytes, bytesToHex, utf8ToBytes } from 'micro-stacks/common'; import base64url from './base64url'; import { joseToDerES256 } from './ecdsa-sig-formatter'; import { hashSha256 } from 'micro-stacks/crypto-sha'; import type { SignedToken } from './types'; export class TokenVerifier { tokenType: string; rawPublicKey: string; constructor(signingAlgorithm: string, rawPublicKey: string) { this.tokenType = 'JWT'; this.rawPublicKey = rawPublicKey; } verify( token: string | SignedToken, // @param {Boolean} strict - whether a signature s should be no more than 1/2 prime order. // true makes signatures compatible with libsecp256k1, false makes signatures compatible with openssl strict = false ): boolean { if (typeof token === 'string') { return this.verifyCompact(token, strict); } else if (typeof token === 'object') { return this.verifyExpanded(token, strict); } else E{ return false; } } verifyCompact(token: string, strict?: boolean): boolean { // decompose the token into parts const tokenParts = token.split('.'); // calculate the signing input hash const signingInput = tokenParts[0] + '.' + tokenParts[1]; const performVerify = (signingInputHash: Uint8Array) => { const signature = tokenParts[2]; // extract the signature as a DER array const formatted: string = joseToDerES256(signature); // verify the signed hash return verify( bytesToHex(base64ToBytes(formatted)), bytesToHex(signingInputHash), this.rawPublicKey, { // TODO: this should be true default // is not compat with legacy tokens. // change reflected here https://github.com/paulmillr/noble-secp256k1/releases/tag/1.4.0 strict, } ); }; const signingInputHash = hashSha256(utf8ToBytes(signingInput)); return performVerify(signingInputHash); } verifyExpanded(token: SignedToken, strict?: boolean): boolean { const signingInput = [token['header'].join('.'), base64url.encode(token['payload'])].join('.'); let verified = true; const performVerify = (signingInputHash: Uint8Array) => { token['signature'].map((signature: string) => { const formatted: string = joseToDerES256(signature); const signatureVerified = verify( bytesToHex(base64ToBytes(formatted)), bytesToHex(signingInputHash), this.rawPublicKey, { strict, } ); Iif (!signatureVerified) { verified = false; } }); return verified; }; const signingInputHash = hashSha256(utf8ToBytes(signingInput)); return performVerify(signingInputHash); } } |