diff --git a/lib/signer.js b/lib/signer.js index 3262ac2..f59299c 100644 --- a/lib/signer.js +++ b/lib/signer.js @@ -204,7 +204,9 @@ RequestSigner.prototype.sign = function (cb) { assert.string(sig.keyId, 'signature.keyId'); assert.string(sig.algorithm, 'signature.algorithm'); assert.string(sig.signature, 'signature.signature'); - alg = validateAlgorithm(sig.algorithm); + if (sig.algorithm !== "hs2019") { + alg = validateAlgorithm(sig.algorithm); + } authz = FormatAuthz('Signature ', { keyId: sig.keyId, @@ -226,11 +228,13 @@ RequestSigner.prototype.sign = function (cb) { cb(e); return; } - alg = (this.rs_alg[0] || this.rs_key.type) + '-' + sigObj.hashAlgorithm; + if (!sigObj.hideAlgorithm) { + alg = (this.rs_alg[0] || this.rs_key.type) + '-' + sigObj.hashAlgorithm; + } var signature = sigObj.toString(); authz = FormatAuthz('Signature ', { keyId: this.rs_keyId, - algorithm: alg, + algorithm: sigObj.hideAlgorithm ? "hs2019" : alg, headers: this.rs_headers.join(' '), signature: signature }); @@ -294,6 +298,9 @@ module.exports = { * signing algorithm for the type of key given * - {String} httpVersion optional; defaults to '1.1'. * - {Boolean} strict optional; defaults to 'false'. + * - {Boolean} hideAlgorithm optional; if true, hides + * algorithm by writing "hs2019" to signature; + * defaults to 'false'. * @return {Boolean} true if Authorization (and optionally Date) were added. * @throws {TypeError} on bad parameter types (input). * @throws {InvalidAlgorithmError} if algorithm was bad or incompatible with @@ -310,6 +317,7 @@ module.exports = { assert.optionalString(options.opaque, 'options.opaque'); assert.optionalArrayOfString(options.headers, 'options.headers'); assert.optionalString(options.httpVersion, 'options.httpVersion'); + assert.optionalBool(options.hideAlgorithm, 'options.hideAlgorithm'); if (!request.getHeader('Date')) request.setHeader('Date', jsprim.rfc1123(new Date())); @@ -433,7 +441,7 @@ module.exports = { var params = { 'keyId': options.keyId, - 'algorithm': options.algorithm, + 'algorithm': options.hideAlgorithm ? "hs2019" : options.algorithm, 'signature': signature }; if (options.opaque) diff --git a/lib/verify.js b/lib/verify.js index 4dba400..27296ed 100644 --- a/lib/verify.js +++ b/lib/verify.js @@ -20,17 +20,23 @@ module.exports = { * * @param {Object} parsedSignature the object you got from `parse`. * @param {String} pubkey RSA/DSA private key PEM. + * @param {String} overriddenAlgorithm if signature has hidden algorithm this tells the verifier the real algorithm to use * @return {Boolean} true if valid, false otherwise. * @throws {TypeError} if you pass in bad arguments. * @throws {InvalidAlgorithmError} */ - verifySignature: function verifySignature(parsedSignature, pubkey) { + verifySignature: function verifySignature(parsedSignature, pubkey, overriddenAlgorithm = null) { assert.object(parsedSignature, 'parsedSignature'); if (typeof (pubkey) === 'string' || Buffer.isBuffer(pubkey)) pubkey = sshpk.parseKey(pubkey); assert.ok(sshpk.Key.isKey(pubkey, [1, 1]), 'pubkey must be a sshpk.Key'); - var alg = validateAlgorithm(parsedSignature.algorithm); + var algorithm = parsedSignature.algorithm; + if (algorithm === "hs2019" && overriddenAlgorithm !== null) { + algorithm = overriddenAlgorithm; + } + + var alg = validateAlgorithm(algorithm); if (alg[0] === 'hmac' || alg[0] !== pubkey.type) return (false);