UNPKG

httpbis-digest-headers

Version:

Create and verify content digests as found in HTTP headers according to draft-ietf-httpbis-digest-headers

77 lines 3.28 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.verifyContentDigest = exports.createContentDigestHeader = void 0; const crypto_1 = require("crypto"); const structured_headers_1 = require("structured-headers"); /** * Implementation of functions to assist with HTTP Content Digest headers per * https://www.ietf.org/archive/id/draft-ietf-httpbis-digest-headers-10.txt * * Supported algorithms * * +===========+==========+============================+==============+ * | Algorithm | Status | Description | Reference(s) | * | Key | | | | * +===========+==========+============================+==============+ * | sha-512 | standard | The SHA-512 algorithm. | [RFC6234], | * | | | | [RFC4648] | * +-----------+----------+----------------------------+--------------+ * | sha-256 | standard | The SHA-256 algorithm. | [RFC6234], | * | | | | [RFC4648] | * +-----------+----------+----------------------------+--------------+ * */ /** * Returns the nodejs hash digest algorithm identifier given an identifier from a content-digest header * * @param algorithm the algorithm identifier as specified in the header * @returns the algorithm identifier to use in the nodejs `createHash` function */ function nodeAlgo(algorithm) { switch (algorithm) { case 'sha-256': return 'sha256'; case 'sha-512': return 'sha512'; default: throw new Error(`Unsupported digest algorithm '${algorithm}'.`); } } /** * Create the content-digest header for a given message body * * @param body the message body * @param algorithms the digest algorithms to use (only 'sha-256' and 'sha-512' supported) * @returns the string that can be used as the content-digest header value */ function createContentDigestHeader(body, algorithms) { return (0, structured_headers_1.serializeDictionary)(new Map(algorithms.map(algo => { return ([ algo, [ new structured_headers_1.ByteSequence((0, crypto_1.createHash)(nodeAlgo(algo)).update(body || '').digest('base64')), new Map(), ] ]); }))); } exports.createContentDigestHeader = createContentDigestHeader; /** * Verify a content-digest header against a message body * * @param body the message body * @param digestHeader the content-digest header * @returns true if all digests in the header are verified, false if not */ function verifyContentDigest(body, digestHeader) { const digests = (0, structured_headers_1.parseDictionary)(digestHeader); for (const [algo, digest] of digests) { if ((0, structured_headers_1.isInnerList)(digest) || !(0, structured_headers_1.isByteSequence)(digest[0])) { throw new Error(`Invalid value for digest with algorithm key of '${algo}'`); } const hash = (0, crypto_1.createHash)(nodeAlgo(algo)).update(body || '').digest('base64'); if (digest[0].toBase64() !== hash) { return false; } } return true; } exports.verifyContentDigest = verifyContentDigest; //# sourceMappingURL=index.js.map