Socket
Socket
Sign inDemoInstall

http-signature

Package Overview
Dependencies
15
Maintainers
16
Versions
28
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 1.3.2 to 1.3.3

5

CHANGES.md

@@ -7,2 +7,7 @@ # node-http-signature changelog

## 1.3.3
- Add support for an opaque param in the Authorization header (#101)
- Add support for adding the keyId and algorithm params into the signing string (#100)
## 1.3.2

@@ -9,0 +14,0 @@

36

lib/parser.js

@@ -113,13 +113,14 @@ // Copyright 2012 Joyent, Inc. All rights reserved.

}
if (options.headers === undefined) {
options.headers = [request.headers['x-date'] ? 'x-date' : 'date'];
}
assert.object(options, 'options');
assert.arrayOfString(options.headers, 'options.headers');
assert.optionalFinite(options.clockSkew, 'options.clockSkew');
var headers = request.headers;
var headers = [request.headers['x-date'] ? 'x-date' : 'date'];
if (options.headers !== undefined) {
assert.arrayOfString(headers, 'options.headers');
headers = options.headers;
}
var authzHeaderName = options.authorizationHeaderName;
var authz = headers[authzHeaderName] || headers[utils.HEADER.AUTH] ||
headers[utils.HEADER.SIG];
var authz = request.headers[authzHeaderName] ||
request.headers[utils.HEADER.AUTH] || request.headers[utils.HEADER.SIG];

@@ -138,3 +139,4 @@ if (!authz) {

var i = 0;
var state = authz === headers[utils.HEADER.SIG] ? State.Params : State.New;
var state = authz === request.headers[utils.HEADER.SIG] ?
State.Params : State.New;
var substate = ParamsState.Name;

@@ -145,3 +147,3 @@ var tmpName = '';

var parsed = {
scheme: authz === headers[utils.HEADER.SIG] ? 'Signature' : '',
scheme: authz === request.headers[utils.HEADER.SIG] ? 'Signature' : '',
params: {},

@@ -241,3 +243,2 @@ signingString: ''

// Check the algorithm against the official list
parsed.params.algorithm = parsed.params.algorithm.toLowerCase();
try {

@@ -275,2 +276,13 @@ validateAlgorithm(parsed.params.algorithm);

request.url;
} else if (h === '(keyid)') {
parsed.signingString += '(keyid): ' + parsed.params.keyId;
} else if (h === '(algorithm)') {
parsed.signingString += '(algorithm): ' + parsed.params.algorithm;
} else if (h === '(opaque)') {
var opaque = parsed.params.opaque;
if (opaque === undefined) {
throw new MissingHeaderError('opaque param was not in the ' +
authzHeaderName + ' header');
}
parsed.signingString += '(opaque): ' + opaque;
} else {

@@ -306,3 +318,3 @@ var value = request.headers[h];

options.headers.forEach(function (hdr) {
headers.forEach(function (hdr) {
// Remember that we already checked any headers in the params

@@ -314,2 +326,3 @@ // were in the request, so if this passes we're good.

parsed.params.algorithm = parsed.params.algorithm.toLowerCase();
if (options.algorithms) {

@@ -323,2 +336,3 @@ if (options.algorithms.indexOf(parsed.params.algorithm) === -1)

parsed.keyId = parsed.params.keyId;
parsed.opaque = parsed.params.opaque;
return parsed;

@@ -325,0 +339,0 @@ }

@@ -20,7 +20,4 @@ // Copyright 2012 Joyent, Inc. All rights reserved.

var AUTHZ_FMT =
'Signature keyId="%s",algorithm="%s",headers="%s",signature="%s"';
var AUTHZ_PARAMS = [ 'keyId', 'algorithm', 'opaque', 'headers', 'signature' ];
var SIGNATURE_FMT = 'keyId="%s",algorithm="%s",headers="%s",signature="%s"';
///--- Specific Errors

@@ -38,2 +35,21 @@

function FormatAuthz(prefix, params) {
assert.string(prefix, 'prefix');
assert.object(params, 'params');
var authz = '';
for (var i = 0; i < AUTHZ_PARAMS.length; i++) {
var param = AUTHZ_PARAMS[i];
var value = params[param];
if (value === undefined)
continue;
assert.string(value, 'params.' + param);
authz += prefix + sprintf('%s="%s"', param, value);
prefix = ',';
}
return (authz);
}
/* See createSigner() */

@@ -195,7 +211,8 @@ function RequestSigner(options) {

authz = sprintf(AUTHZ_FMT,
sig.keyId,
sig.algorithm,
self.rs_headers.join(' '),
sig.signature);
authz = FormatAuthz('Signature ', {
keyId: sig.keyId,
algorithm: sig.keyId,
headers: self.rs_headers.join(' '),
signature: sig.signature
});
} catch (e) {

@@ -217,7 +234,8 @@ cb(e);

var signature = sigObj.toString();
authz = sprintf(AUTHZ_FMT,
this.rs_keyId,
alg,
this.rs_headers.join(' '),
signature);
authz = FormatAuthz('Signature ', {
keyId: this.rs_keyId,
algorithm: alg,
headers: this.rs_headers.join(' '),
signature: signature
});
cb(null, authz);

@@ -296,2 +314,3 @@ }

assert.string(options.keyId, 'options.keyId');
assert.optionalString(options.opaque, 'options.opaque');
assert.optionalArrayOfString(options.headers, 'options.headers');

@@ -302,4 +321,5 @@ assert.optionalString(options.httpVersion, 'options.httpVersion');

request.setHeader('Date', jsprim.rfc1123(new Date()));
if (!options.headers)
options.headers = ['date'];
var headers = ['date'];
if (options.headers)
headers = options.headers;
if (!options.httpVersion)

@@ -314,9 +334,39 @@ options.httpVersion = '1.1';

var key = options.key;
if (alg[0] === 'hmac') {
if (typeof (key) !== 'string' && !Buffer.isBuffer(key))
throw (new TypeError('options.key must be a string or Buffer'));
} else {
if (typeof (key) === 'string' || Buffer.isBuffer(key))
key = sshpk.parsePrivateKey(options.key);
assert.ok(sshpk.PrivateKey.isPrivateKey(key, [1, 2]),
'options.key must be a sshpk.PrivateKey');
if (!PK_ALGOS[key.type]) {
throw (new InvalidAlgorithmError(key.type.toUpperCase() + ' type ' +
'keys are not supported'));
}
if (alg[0] === undefined) {
alg[0] = key.type;
} else if (key.type !== alg[0]) {
throw (new InvalidAlgorithmError('options.key must be a ' +
alg[0].toUpperCase() + ' key, was given a ' +
key.type.toUpperCase() + ' key instead'));
}
if (alg[1] === undefined) {
alg[1] = key.defaultHashAlgorithm();
}
options.algorithm = alg[0] + '-' + alg[1];
}
var i;
var stringToSign = '';
for (i = 0; i < options.headers.length; i++) {
if (typeof (options.headers[i]) !== 'string')
for (i = 0; i < headers.length; i++) {
if (typeof (headers[i]) !== 'string')
throw new TypeError('options.headers must be an array of Strings');
var h = options.headers[i].toLowerCase();
var h = headers[i].toLowerCase();

@@ -341,2 +391,12 @@ if (h === 'request-line') {

request.path;
} else if (h === '(keyid)') {
stringToSign += '(keyid): ' + options.keyId;
} else if (h === '(algorithm)') {
stringToSign += '(algorithm): ' + options.algorithm;
} else if (h === '(opaque)') {
var opaque = options.opaque;
if (opaque == undefined || opaque === '') {
throw new MissingHeaderError('options.opaque was not in the request');
}
stringToSign += '(opaque): ' + opaque;
} else {

@@ -350,3 +410,3 @@ var value = request.getHeader(h);

if ((i + 1) < options.headers.length)
if ((i + 1) < headers.length)
stringToSign += '\n';

@@ -362,28 +422,6 @@ }

if (alg[0] === 'hmac') {
if (typeof (options.key) !== 'string' && !Buffer.isBuffer(options.key))
throw (new TypeError('options.key must be a string or Buffer'));
var hmac = crypto.createHmac(alg[1].toUpperCase(), options.key);
var hmac = crypto.createHmac(alg[1].toUpperCase(), key);
hmac.update(stringToSign);
signature = hmac.digest('base64');
} else {
var key = options.key;
if (typeof (key) === 'string' || Buffer.isBuffer(key))
key = sshpk.parsePrivateKey(options.key);
assert.ok(sshpk.PrivateKey.isPrivateKey(key, [1, 2]),
'options.key must be a sshpk.PrivateKey');
if (!PK_ALGOS[key.type]) {
throw (new InvalidAlgorithmError(key.type.toUpperCase() + ' type ' +
'keys are not supported'));
}
if (alg[0] !== undefined && key.type !== alg[0]) {
throw (new InvalidAlgorithmError('options.key must be a ' +
alg[0].toUpperCase() + ' key, was given a ' +
key.type.toUpperCase() + ' key instead'));
}
var signer = key.createSign(alg[1]);

@@ -396,3 +434,4 @@ signer.update(stringToSign);

}
options.algorithm = key.type + '-' + sigObj.hashAlgorithm;
assert.strictEqual(alg[1], sigObj.hashAlgorithm,
'hash algorithm mismatch');
signature = sigObj.toString();

@@ -403,11 +442,16 @@ assert.notStrictEqual(signature, '', 'empty signature produced');

var authzHeaderName = options.authorizationHeaderName || 'Authorization';
var prefix = authzHeaderName.toLowerCase() === utils.HEADER.SIG ?
'' : 'Signature ';
var FMT = authzHeaderName.toLowerCase() === utils.HEADER.SIG ?
SIGNATURE_FMT : AUTHZ_FMT;
var params = {
'keyId': options.keyId,
'algorithm': options.algorithm,
'signature': signature
};
if (options.opaque)
params.opaque = options.opaque;
if (options.headers)
params.headers = options.headers.join(' ');
request.setHeader(authzHeaderName, sprintf(FMT,
options.keyId,
options.algorithm,
options.headers.join(' '),
signature));
request.setHeader(authzHeaderName, FormatAuthz(prefix, params));

@@ -414,0 +458,0 @@ return true;

{
"name": "http-signature",
"description": "Reference implementation of Joyent's HTTP Signature scheme.",
"version": "1.3.2",
"version": "1.3.3",
"license": "MIT",

@@ -6,0 +6,0 @@ "author": "Joyent, Inc",

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc