{"ast":null,"code":"// Copyright 2012 Joyent, Inc. All rights reserved.\nvar assert = require('assert-plus');\n\nvar crypto = require('crypto');\n\nvar http = require('http');\n\nvar util = require('util');\n\nvar sshpk = require('sshpk');\n\nvar jsprim = require('jsprim');\n\nvar utils = require('./utils');\n\nvar sprintf = require('util').format;\n\nvar HASH_ALGOS = utils.HASH_ALGOS;\nvar PK_ALGOS = utils.PK_ALGOS;\nvar InvalidAlgorithmError = utils.InvalidAlgorithmError;\nvar HttpSignatureError = utils.HttpSignatureError;\nvar validateAlgorithm = utils.validateAlgorithm; ///--- Globals\n\nvar AUTHZ_FMT = 'Signature keyId=\"%s\",algorithm=\"%s\",headers=\"%s\",signature=\"%s\"'; ///--- Specific Errors\n\nfunction MissingHeaderError(message) {\n HttpSignatureError.call(this, message, MissingHeaderError);\n}\n\nutil.inherits(MissingHeaderError, HttpSignatureError);\n\nfunction StrictParsingError(message) {\n HttpSignatureError.call(this, message, StrictParsingError);\n}\n\nutil.inherits(StrictParsingError, HttpSignatureError);\n/* See createSigner() */\n\nfunction RequestSigner(options) {\n assert.object(options, 'options');\n var alg = [];\n\n if (options.algorithm !== undefined) {\n assert.string(options.algorithm, 'options.algorithm');\n alg = validateAlgorithm(options.algorithm);\n }\n\n this.rs_alg = alg;\n /*\n * RequestSigners come in two varieties: ones with an rs_signFunc, and ones\n * with an rs_signer.\n *\n * rs_signFunc-based RequestSigners have to build up their entire signing\n * string within the rs_lines array and give it to rs_signFunc as a single\n * concat'd blob. rs_signer-based RequestSigners can add a line at a time to\n * their signing state by using rs_signer.update(), thus only needing to\n * buffer the hash function state and one line at a time.\n */\n\n if (options.sign !== undefined) {\n assert.func(options.sign, 'options.sign');\n this.rs_signFunc = options.sign;\n } else if (alg[0] === 'hmac' && options.key !== undefined) {\n assert.string(options.keyId, 'options.keyId');\n this.rs_keyId = options.keyId;\n if (typeof options.key !== 'string' && !Buffer.isBuffer(options.key)) throw new TypeError('options.key for HMAC must be a string or Buffer');\n /*\n * Make an rs_signer for HMACs, not a rs_signFunc -- HMACs digest their\n * data in chunks rather than requiring it all to be given in one go\n * at the end, so they are more similar to signers than signFuncs.\n */\n\n this.rs_signer = crypto.createHmac(alg[1].toUpperCase(), options.key);\n\n this.rs_signer.sign = function () {\n var digest = this.digest('base64');\n return {\n hashAlgorithm: alg[1],\n toString: function () {\n return digest;\n }\n };\n };\n } else if (options.key !== undefined) {\n var key = options.key;\n if (typeof key === 'string' || Buffer.isBuffer(key)) key = sshpk.parsePrivateKey(key);\n assert.ok(sshpk.PrivateKey.isPrivateKey(key, [1, 2]), 'options.key must be a sshpk.PrivateKey');\n this.rs_key = key;\n assert.string(options.keyId, 'options.keyId');\n this.rs_keyId = options.keyId;\n\n if (!PK_ALGOS[key.type]) {\n throw new InvalidAlgorithmError(key.type.toUpperCase() + ' type ' + 'keys are not supported');\n }\n\n if (alg[0] !== undefined && key.type !== alg[0]) {\n throw new InvalidAlgorithmError('options.key must be a ' + alg[0].toUpperCase() + ' key, was given a ' + key.type.toUpperCase() + ' key instead');\n }\n\n this.rs_signer = key.createSign(alg[1]);\n } else {\n throw new TypeError('options.sign (func) or options.key is required');\n }\n\n this.rs_headers = [];\n this.rs_lines = [];\n}\n/**\n * Adds a header to be signed, with its value, into this signer.\n *\n * @param {String} header\n * @param {String} value\n * @return {String} value written\n */\n\n\nRequestSigner.prototype.writeHeader = function (header, value) {\n assert.string(header, 'header');\n header = header.toLowerCase();\n assert.string(value, 'value');\n this.rs_headers.push(header);\n\n if (this.rs_signFunc) {\n this.rs_lines.push(header + ': ' + value);\n } else {\n var line = header + ': ' + value;\n if (this.rs_headers.length > 0) line = '\\n' + line;\n this.rs_signer.update(line);\n }\n\n return value;\n};\n/**\n * Adds a default Date header, returning its value.\n *\n * @return {String}\n */\n\n\nRequestSigner.prototype.writeDateHeader = function () {\n return this.writeHeader('date', jsprim.rfc1123(new Date()));\n};\n/**\n * Adds the request target line to be signed.\n *\n * @param {String} method, HTTP method (e.g. 'get', 'post', 'put')\n * @param {String} path\n */\n\n\nRequestSigner.prototype.writeTarget = function (method, path) {\n assert.string(method, 'method');\n assert.string(path, 'path');\n method = method.toLowerCase();\n this.writeHeader('(request-target)', method + ' ' + path);\n};\n/**\n * Calculate the value for the Authorization header on this request\n * asynchronously.\n *\n * @param {Func} callback (err, authz)\n */\n\n\nRequestSigner.prototype.sign = function (cb) {\n assert.func(cb, 'callback');\n if (this.rs_headers.length < 1) throw new Error('At least one header must be signed');\n var alg, authz;\n\n if (this.rs_signFunc) {\n var data = this.rs_lines.join('\\n');\n var self = this;\n this.rs_signFunc(data, function (err, sig) {\n if (err) {\n cb(err);\n return;\n }\n\n try {\n assert.object(sig, 'signature');\n assert.string(sig.keyId, 'signature.keyId');\n assert.string(sig.algorithm, 'signature.algorithm');\n assert.string(sig.signature, 'signature.signature');\n alg = validateAlgorithm(sig.algorithm);\n authz = sprintf(AUTHZ_FMT, sig.keyId, sig.algorithm, self.rs_headers.join(' '), sig.signature);\n } catch (e) {\n cb(e);\n return;\n }\n\n cb(null, authz);\n });\n } else {\n try {\n var sigObj = this.rs_signer.sign();\n } catch (e) {\n cb(e);\n return;\n }\n\n alg = (this.rs_alg[0] || this.rs_key.type) + '-' + sigObj.hashAlgorithm;\n var signature = sigObj.toString();\n authz = sprintf(AUTHZ_FMT, this.rs_keyId, alg, this.rs_headers.join(' '), signature);\n cb(null, authz);\n }\n}; ///--- Exported API\n\n\nmodule.exports = {\n /**\n * Identifies whether a given object is a request signer or not.\n *\n * @param {Object} object, the object to identify\n * @returns {Boolean}\n */\n isSigner: function (obj) {\n if (typeof obj === 'object' && obj instanceof RequestSigner) return true;\n return false;\n },\n\n /**\n * Creates a request signer, used to asynchronously build a signature\n * for a request (does not have to be an http.ClientRequest).\n *\n * @param {Object} options, either:\n * - {String} keyId\n * - {String|Buffer} key\n * - {String} algorithm (optional, required for HMAC)\n * or:\n * - {Func} sign (data, cb)\n * @return {RequestSigner}\n */\n createSigner: function createSigner(options) {\n return new RequestSigner(options);\n },\n\n /**\n * Adds an 'Authorization' header to an http.ClientRequest object.\n *\n * Note that this API will add a Date header if it's not already set. Any\n * other headers in the options.headers array MUST be present, or this\n * will throw.\n *\n * You shouldn't need to check the return type; it's just there if you want\n * to be pedantic.\n *\n * The optional flag indicates whether parsing should use strict enforcement\n * of the version draft-cavage-http-signatures-04 of the spec or beyond.\n * The default is to be loose and support\n * older versions for compatibility.\n *\n * @param {Object} request an instance of http.ClientRequest.\n * @param {Object} options signing parameters object:\n * - {String} keyId required.\n * - {String} key required (either a PEM or HMAC key).\n * - {Array} headers optional; defaults to ['date'].\n * - {String} algorithm optional (unless key is HMAC);\n * default is the same as the sshpk default\n * signing algorithm for the type of key given\n * - {String} httpVersion optional; defaults to '1.1'.\n * - {Boolean} strict optional; defaults to 'false'.\n * @return {Boolean} true if Authorization (and optionally Date) were added.\n * @throws {TypeError} on bad parameter types (input).\n * @throws {InvalidAlgorithmError} if algorithm was bad or incompatible with\n * the given key.\n * @throws {sshpk.KeyParseError} if key was bad.\n * @throws {MissingHeaderError} if a header to be signed was specified but\n * was not present.\n */\n signRequest: function signRequest(request, options) {\n assert.object(request, 'request');\n assert.object(options, 'options');\n assert.optionalString(options.algorithm, 'options.algorithm');\n assert.string(options.keyId, 'options.keyId');\n assert.optionalArrayOfString(options.headers, 'options.headers');\n assert.optionalString(options.httpVersion, 'options.httpVersion');\n if (!request.getHeader('Date')) request.setHeader('Date', jsprim.rfc1123(new Date()));\n if (!options.headers) options.headers = ['date'];\n if (!options.httpVersion) options.httpVersion = '1.1';\n var alg = [];\n\n if (options.algorithm) {\n options.algorithm = options.algorithm.toLowerCase();\n alg = validateAlgorithm(options.algorithm);\n }\n\n var i;\n var stringToSign = '';\n\n for (i = 0; i < options.headers.length; i++) {\n if (typeof options.headers[i] !== 'string') throw new TypeError('options.headers must be an array of Strings');\n var h = options.headers[i].toLowerCase();\n\n if (h === 'request-line') {\n if (!options.strict) {\n /**\n * We allow headers from the older spec drafts if strict parsing isn't\n * specified in options.\n */\n stringToSign += request.method + ' ' + request.path + ' HTTP/' + options.httpVersion;\n } else {\n /* Strict parsing doesn't allow older draft headers. */\n throw new StrictParsingError('request-line is not a valid header ' + 'with strict parsing enabled.');\n }\n } else if (h === '(request-target)') {\n stringToSign += '(request-target): ' + request.method.toLowerCase() + ' ' + request.path;\n } else {\n var value = request.getHeader(h);\n\n if (value === undefined || value === '') {\n throw new MissingHeaderError(h + ' was not in the request');\n }\n\n stringToSign += h + ': ' + value;\n }\n\n if (i + 1 < options.headers.length) stringToSign += '\\n';\n }\n /* This is just for unit tests. */\n\n\n if (request.hasOwnProperty('_stringToSign')) {\n request._stringToSign = stringToSign;\n }\n\n var signature;\n\n if (alg[0] === 'hmac') {\n if (typeof options.key !== 'string' && !Buffer.isBuffer(options.key)) throw new TypeError('options.key must be a string or Buffer');\n var hmac = crypto.createHmac(alg[1].toUpperCase(), options.key);\n hmac.update(stringToSign);\n signature = hmac.digest('base64');\n } else {\n var key = options.key;\n if (typeof key === 'string' || Buffer.isBuffer(key)) key = sshpk.parsePrivateKey(options.key);\n assert.ok(sshpk.PrivateKey.isPrivateKey(key, [1, 2]), 'options.key must be a sshpk.PrivateKey');\n\n if (!PK_ALGOS[key.type]) {\n throw new InvalidAlgorithmError(key.type.toUpperCase() + ' type ' + 'keys are not supported');\n }\n\n if (alg[0] !== undefined && key.type !== alg[0]) {\n throw new InvalidAlgorithmError('options.key must be a ' + alg[0].toUpperCase() + ' key, was given a ' + key.type.toUpperCase() + ' key instead');\n }\n\n var signer = key.createSign(alg[1]);\n signer.update(stringToSign);\n var sigObj = signer.sign();\n\n if (!HASH_ALGOS[sigObj.hashAlgorithm]) {\n throw new InvalidAlgorithmError(sigObj.hashAlgorithm.toUpperCase() + ' is not a supported hash algorithm');\n }\n\n options.algorithm = key.type + '-' + sigObj.hashAlgorithm;\n signature = sigObj.toString();\n assert.notStrictEqual(signature, '', 'empty signature produced');\n }\n\n var authzHeaderName = options.authorizationHeaderName || 'Authorization';\n request.setHeader(authzHeaderName, sprintf(AUTHZ_FMT, options.keyId, options.algorithm, options.headers.join(' '), signature));\n return true;\n }\n};","map":{"version":3,"sources":["/Users/tylerkoenig/Code/personal/react-scss2/node_modules/http-signature/lib/signer.js"],"names":["assert","require","crypto","http","util","sshpk","jsprim","utils","sprintf","format","HASH_ALGOS","PK_ALGOS","InvalidAlgorithmError","HttpSignatureError","validateAlgorithm","AUTHZ_FMT","MissingHeaderError","message","call","inherits","StrictParsingError","RequestSigner","options","object","alg","algorithm","undefined","string","rs_alg","sign","func","rs_signFunc","key","keyId","rs_keyId","Buffer","isBuffer","TypeError","rs_signer","createHmac","toUpperCase","digest","hashAlgorithm","toString","parsePrivateKey","ok","PrivateKey","isPrivateKey","rs_key","type","createSign","rs_headers","rs_lines","prototype","writeHeader","header","value","toLowerCase","push","line","length","update","writeDateHeader","rfc1123","Date","writeTarget","method","path","cb","Error","authz","data","join","self","err","sig","signature","e","sigObj","module","exports","isSigner","obj","createSigner","signRequest","request","optionalString","optionalArrayOfString","headers","httpVersion","getHeader","setHeader","i","stringToSign","h","strict","hasOwnProperty","_stringToSign","hmac","signer","notStrictEqual","authzHeaderName","authorizationHeaderName"],"mappings":"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","sourcesContent":["// Copyright 2012 Joyent, Inc. All rights reserved.\n\nvar assert = require('assert-plus');\nvar crypto = require('crypto');\nvar http = require('http');\nvar util = require('util');\nvar sshpk = require('sshpk');\nvar jsprim = require('jsprim');\nvar utils = require('./utils');\n\nvar sprintf = require('util').format;\n\nvar HASH_ALGOS = utils.HASH_ALGOS;\nvar PK_ALGOS = utils.PK_ALGOS;\nvar InvalidAlgorithmError = utils.InvalidAlgorithmError;\nvar HttpSignatureError = utils.HttpSignatureError;\nvar validateAlgorithm = utils.validateAlgorithm;\n\n///--- Globals\n\nvar AUTHZ_FMT =\n 'Signature keyId=\"%s\",algorithm=\"%s\",headers=\"%s\",signature=\"%s\"';\n\n///--- Specific Errors\n\nfunction MissingHeaderError(message) {\n HttpSignatureError.call(this, message, MissingHeaderError);\n}\nutil.inherits(MissingHeaderError, HttpSignatureError);\n\nfunction StrictParsingError(message) {\n HttpSignatureError.call(this, message, StrictParsingError);\n}\nutil.inherits(StrictParsingError, HttpSignatureError);\n\n/* See createSigner() */\nfunction RequestSigner(options) {\n assert.object(options, 'options');\n\n var alg = [];\n if (options.algorithm !== undefined) {\n assert.string(options.algorithm, 'options.algorithm');\n alg = validateAlgorithm(options.algorithm);\n }\n this.rs_alg = alg;\n\n /*\n * RequestSigners come in two varieties: ones with an rs_signFunc, and ones\n * with an rs_signer.\n *\n * rs_signFunc-based RequestSigners have to build up their entire signing\n * string within the rs_lines array and give it to rs_signFunc as a single\n * concat'd blob. rs_signer-based RequestSigners can add a line at a time to\n * their signing state by using rs_signer.update(), thus only needing to\n * buffer the hash function state and one line at a time.\n */\n if (options.sign !== undefined) {\n assert.func(options.sign, 'options.sign');\n this.rs_signFunc = options.sign;\n\n } else if (alg[0] === 'hmac' && options.key !== undefined) {\n assert.string(options.keyId, 'options.keyId');\n this.rs_keyId = options.keyId;\n\n if (typeof (options.key) !== 'string' && !Buffer.isBuffer(options.key))\n throw (new TypeError('options.key for HMAC must be a string or Buffer'));\n\n /*\n * Make an rs_signer for HMACs, not a rs_signFunc -- HMACs digest their\n * data in chunks rather than requiring it all to be given in one go\n * at the end, so they are more similar to signers than signFuncs.\n */\n this.rs_signer = crypto.createHmac(alg[1].toUpperCase(), options.key);\n this.rs_signer.sign = function () {\n var digest = this.digest('base64');\n return ({\n hashAlgorithm: alg[1],\n toString: function () { return (digest); }\n });\n };\n\n } else if (options.key !== undefined) {\n var key = options.key;\n if (typeof (key) === 'string' || Buffer.isBuffer(key))\n key = sshpk.parsePrivateKey(key);\n\n assert.ok(sshpk.PrivateKey.isPrivateKey(key, [1, 2]),\n 'options.key must be a sshpk.PrivateKey');\n this.rs_key = key;\n\n assert.string(options.keyId, 'options.keyId');\n this.rs_keyId = options.keyId;\n\n if (!PK_ALGOS[key.type]) {\n throw (new InvalidAlgorithmError(key.type.toUpperCase() + ' type ' +\n 'keys are not supported'));\n }\n\n if (alg[0] !== undefined && key.type !== alg[0]) {\n throw (new InvalidAlgorithmError('options.key must be a ' +\n alg[0].toUpperCase() + ' key, was given a ' +\n key.type.toUpperCase() + ' key instead'));\n }\n\n this.rs_signer = key.createSign(alg[1]);\n\n } else {\n throw (new TypeError('options.sign (func) or options.key is required'));\n }\n\n this.rs_headers = [];\n this.rs_lines = [];\n}\n\n/**\n * Adds a header to be signed, with its value, into this signer.\n *\n * @param {String} header\n * @param {String} value\n * @return {String} value written\n */\nRequestSigner.prototype.writeHeader = function (header, value) {\n assert.string(header, 'header');\n header = header.toLowerCase();\n assert.string(value, 'value');\n\n this.rs_headers.push(header);\n\n if (this.rs_signFunc) {\n this.rs_lines.push(header + ': ' + value);\n\n } else {\n var line = header + ': ' + value;\n if (this.rs_headers.length > 0)\n line = '\\n' + line;\n this.rs_signer.update(line);\n }\n\n return (value);\n};\n\n/**\n * Adds a default Date header, returning its value.\n *\n * @return {String}\n */\nRequestSigner.prototype.writeDateHeader = function () {\n return (this.writeHeader('date', jsprim.rfc1123(new Date())));\n};\n\n/**\n * Adds the request target line to be signed.\n *\n * @param {String} method, HTTP method (e.g. 'get', 'post', 'put')\n * @param {String} path\n */\nRequestSigner.prototype.writeTarget = function (method, path) {\n assert.string(method, 'method');\n assert.string(path, 'path');\n method = method.toLowerCase();\n this.writeHeader('(request-target)', method + ' ' + path);\n};\n\n/**\n * Calculate the value for the Authorization header on this request\n * asynchronously.\n *\n * @param {Func} callback (err, authz)\n */\nRequestSigner.prototype.sign = function (cb) {\n assert.func(cb, 'callback');\n\n if (this.rs_headers.length < 1)\n throw (new Error('At least one header must be signed'));\n\n var alg, authz;\n if (this.rs_signFunc) {\n var data = this.rs_lines.join('\\n');\n var self = this;\n this.rs_signFunc(data, function (err, sig) {\n if (err) {\n cb(err);\n return;\n }\n try {\n assert.object(sig, 'signature');\n assert.string(sig.keyId, 'signature.keyId');\n assert.string(sig.algorithm, 'signature.algorithm');\n assert.string(sig.signature, 'signature.signature');\n alg = validateAlgorithm(sig.algorithm);\n\n authz = sprintf(AUTHZ_FMT,\n sig.keyId,\n sig.algorithm,\n self.rs_headers.join(' '),\n sig.signature);\n } catch (e) {\n cb(e);\n return;\n }\n cb(null, authz);\n });\n\n } else {\n try {\n var sigObj = this.rs_signer.sign();\n } catch (e) {\n cb(e);\n return;\n }\n alg = (this.rs_alg[0] || this.rs_key.type) + '-' + sigObj.hashAlgorithm;\n var signature = sigObj.toString();\n authz = sprintf(AUTHZ_FMT,\n this.rs_keyId,\n alg,\n this.rs_headers.join(' '),\n signature);\n cb(null, authz);\n }\n};\n\n///--- Exported API\n\nmodule.exports = {\n /**\n * Identifies whether a given object is a request signer or not.\n *\n * @param {Object} object, the object to identify\n * @returns {Boolean}\n */\n isSigner: function (obj) {\n if (typeof (obj) === 'object' && obj instanceof RequestSigner)\n return (true);\n return (false);\n },\n\n /**\n * Creates a request signer, used to asynchronously build a signature\n * for a request (does not have to be an http.ClientRequest).\n *\n * @param {Object} options, either:\n * - {String} keyId\n * - {String|Buffer} key\n * - {String} algorithm (optional, required for HMAC)\n * or:\n * - {Func} sign (data, cb)\n * @return {RequestSigner}\n */\n createSigner: function createSigner(options) {\n return (new RequestSigner(options));\n },\n\n /**\n * Adds an 'Authorization' header to an http.ClientRequest object.\n *\n * Note that this API will add a Date header if it's not already set. Any\n * other headers in the options.headers array MUST be present, or this\n * will throw.\n *\n * You shouldn't need to check the return type; it's just there if you want\n * to be pedantic.\n *\n * The optional flag indicates whether parsing should use strict enforcement\n * of the version draft-cavage-http-signatures-04 of the spec or beyond.\n * The default is to be loose and support\n * older versions for compatibility.\n *\n * @param {Object} request an instance of http.ClientRequest.\n * @param {Object} options signing parameters object:\n * - {String} keyId required.\n * - {String} key required (either a PEM or HMAC key).\n * - {Array} headers optional; defaults to ['date'].\n * - {String} algorithm optional (unless key is HMAC);\n * default is the same as the sshpk default\n * signing algorithm for the type of key given\n * - {String} httpVersion optional; defaults to '1.1'.\n * - {Boolean} strict optional; defaults to 'false'.\n * @return {Boolean} true if Authorization (and optionally Date) were added.\n * @throws {TypeError} on bad parameter types (input).\n * @throws {InvalidAlgorithmError} if algorithm was bad or incompatible with\n * the given key.\n * @throws {sshpk.KeyParseError} if key was bad.\n * @throws {MissingHeaderError} if a header to be signed was specified but\n * was not present.\n */\n signRequest: function signRequest(request, options) {\n assert.object(request, 'request');\n assert.object(options, 'options');\n assert.optionalString(options.algorithm, 'options.algorithm');\n assert.string(options.keyId, 'options.keyId');\n assert.optionalArrayOfString(options.headers, 'options.headers');\n assert.optionalString(options.httpVersion, 'options.httpVersion');\n\n if (!request.getHeader('Date'))\n request.setHeader('Date', jsprim.rfc1123(new Date()));\n if (!options.headers)\n options.headers = ['date'];\n if (!options.httpVersion)\n options.httpVersion = '1.1';\n\n var alg = [];\n if (options.algorithm) {\n options.algorithm = options.algorithm.toLowerCase();\n alg = validateAlgorithm(options.algorithm);\n }\n\n var i;\n var stringToSign = '';\n for (i = 0; i < options.headers.length; i++) {\n if (typeof (options.headers[i]) !== 'string')\n throw new TypeError('options.headers must be an array of Strings');\n\n var h = options.headers[i].toLowerCase();\n\n if (h === 'request-line') {\n if (!options.strict) {\n /**\n * We allow headers from the older spec drafts if strict parsing isn't\n * specified in options.\n */\n stringToSign +=\n request.method + ' ' + request.path + ' HTTP/' +\n options.httpVersion;\n } else {\n /* Strict parsing doesn't allow older draft headers. */\n throw (new StrictParsingError('request-line is not a valid header ' +\n 'with strict parsing enabled.'));\n }\n } else if (h === '(request-target)') {\n stringToSign +=\n '(request-target): ' + request.method.toLowerCase() + ' ' +\n request.path;\n } else {\n var value = request.getHeader(h);\n if (value === undefined || value === '') {\n throw new MissingHeaderError(h + ' was not in the request');\n }\n stringToSign += h + ': ' + value;\n }\n\n if ((i + 1) < options.headers.length)\n stringToSign += '\\n';\n }\n\n /* This is just for unit tests. */\n if (request.hasOwnProperty('_stringToSign')) {\n request._stringToSign = stringToSign;\n }\n\n var signature;\n if (alg[0] === 'hmac') {\n if (typeof (options.key) !== 'string' && !Buffer.isBuffer(options.key))\n throw (new TypeError('options.key must be a string or Buffer'));\n\n var hmac = crypto.createHmac(alg[1].toUpperCase(), options.key);\n hmac.update(stringToSign);\n signature = hmac.digest('base64');\n\n } else {\n var key = options.key;\n if (typeof (key) === 'string' || Buffer.isBuffer(key))\n key = sshpk.parsePrivateKey(options.key);\n\n assert.ok(sshpk.PrivateKey.isPrivateKey(key, [1, 2]),\n 'options.key must be a sshpk.PrivateKey');\n\n if (!PK_ALGOS[key.type]) {\n throw (new InvalidAlgorithmError(key.type.toUpperCase() + ' type ' +\n 'keys are not supported'));\n }\n\n if (alg[0] !== undefined && key.type !== alg[0]) {\n throw (new InvalidAlgorithmError('options.key must be a ' +\n alg[0].toUpperCase() + ' key, was given a ' +\n key.type.toUpperCase() + ' key instead'));\n }\n\n var signer = key.createSign(alg[1]);\n signer.update(stringToSign);\n var sigObj = signer.sign();\n if (!HASH_ALGOS[sigObj.hashAlgorithm]) {\n throw (new InvalidAlgorithmError(sigObj.hashAlgorithm.toUpperCase() +\n ' is not a supported hash algorithm'));\n }\n options.algorithm = key.type + '-' + sigObj.hashAlgorithm;\n signature = sigObj.toString();\n assert.notStrictEqual(signature, '', 'empty signature produced');\n }\n\n var authzHeaderName = options.authorizationHeaderName || 'Authorization';\n\n request.setHeader(authzHeaderName, sprintf(AUTHZ_FMT,\n options.keyId,\n options.algorithm,\n options.headers.join(' '),\n signature));\n\n return true;\n }\n\n};\n"]},"metadata":{},"sourceType":"script"}