From daa84c9415809c9a60a569c2da56e3ac58316d9d Mon Sep 17 00:00:00 2001 From: Steven Roebert Date: Sat, 11 Mar 2023 12:07:54 +0100 Subject: [PATCH] Added SHA-256 and SHA-512-256 algorithms to http digest authentication --- .../nodes/core/network/21-httprequest.js | 42 +++++++++++++------ 1 file changed, 30 insertions(+), 12 deletions(-) diff --git a/packages/node_modules/@node-red/nodes/core/network/21-httprequest.js b/packages/node_modules/@node-red/nodes/core/network/21-httprequest.js index ad283657d..bcf3b72b9 100644 --- a/packages/node_modules/@node-red/nodes/core/network/21-httprequest.js +++ b/packages/node_modules/@node-red/nodes/core/network/21-httprequest.js @@ -699,25 +699,43 @@ in your Node-RED user directory (${RED.settings.userDir}). }); const md5 = (value) => { return crypto.createHash('md5').update(value).digest('hex') } + const sha256 = (value) => { return crypto.createHash('sha256').update(value).digest('hex') } + const sha512 = (value) => { return crypto.createHash('sha512').update(value).digest('hex') } + + function digestCompute(algorithm, value) { + var lowercaseAlgorithm = "" + if (algorithm) { + lowercaseAlgorithm = algorithm.toLowerCase().replace(/-sess$/, '') + } + + if (lowercaseAlgorithm === "sha-256") { + return sha256(value) + } else if (lowercaseAlgorithm === "sha-512-256") { + var hash = sha512(value) + return hash.slice(0, 64) // Only use the first 256 bits + } else { + return md5(value) + } + } function ha1Compute(algorithm, user, realm, pass, nonce, cnonce) { /** - * RFC 2617: handle both MD5 and MD5-sess algorithms. + * RFC 2617: handle both standard and -sess algorithms. * - * If the algorithm directive's value is "MD5" or unspecified, then HA1 is - * HA1=MD5(username:realm:password) - * If the algorithm directive's value is "MD5-sess", then HA1 is - * HA1=MD5(MD5(username:realm:password):nonce:cnonce) + * If the algorithm directive's value ends with "-sess", then HA1 is + * HA1=digestCompute(digestCompute(username:realm:password):nonce:cnonce) + * + * If the algorithm directive's value does not end with "-sess", then HA1 is + * HA1=digestCompute(username:realm:password) */ - var ha1 = md5(user + ':' + realm + ':' + pass) - if (algorithm && algorithm.toLowerCase() === 'md5-sess') { - return md5(ha1 + ':' + nonce + ':' + cnonce) + var ha1 = digestCompute(algorithm, user + ':' + realm + ':' + pass) + if (algorithm && /-sess$/i.test(algorithm)) { + return digestCompute(algorithm, ha1 + ':' + nonce + ':' + cnonce) } else { return ha1 } } - function buildDigestHeader(user, pass, method, path, authHeader) { var challenge = {} var re = /([a-z0-9_-]+)=(?:"([^"]+)"|([a-z0-9_-]+))/gi @@ -732,10 +750,10 @@ in your Node-RED user directory (${RED.settings.userDir}). var nc = qop && '00000001' var cnonce = qop && uuid().replace(/-/g, '') var ha1 = ha1Compute(challenge.algorithm, user, challenge.realm, pass, challenge.nonce, cnonce) - var ha2 = md5(method + ':' + path) + var ha2 = digestCompute(challenge.algorithm, method + ':' + path) var digestResponse = qop - ? md5(ha1 + ':' + challenge.nonce + ':' + nc + ':' + cnonce + ':' + qop + ':' + ha2) - : md5(ha1 + ':' + challenge.nonce + ':' + ha2) + ? digestCompute(challenge.algorithm, ha1 + ':' + challenge.nonce + ':' + nc + ':' + cnonce + ':' + qop + ':' + ha2) + : digestCompute(challenge.algorithm, ha1 + ':' + challenge.nonce + ':' + ha2) var authValues = { username: user, realm: challenge.realm,