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
JavaScript
;
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