Socket
Socket
Sign inDemoInstall

http-signature

Package Overview
Dependencies
3
Maintainers
1
Versions
28
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.9.11 to 0.10.0

85

http_signing.md

@@ -49,4 +49,4 @@ # Abstract

credentials := "Signature" params digitalSignature
params := 1#(keyId | [algorithm] | [headers] | [ext])
credentials := "Signature" params
params := 1#(keyId | algorithm | [headers] | [ext] | signature)
digitalSignature := plain-string

@@ -58,2 +58,3 @@

ext := "ext" "=" <"> plain-string <">
signature := "signature" "=" <"> plain-string <">

@@ -97,17 +98,23 @@ headers-value := plain-string

### Digital Signature
#### signature
The `digitalSignature` portion of the credentials is a REQUIRED field, and is
REQUIRED. The `signature` parameter is a `Base64` encoded digital signature
generated by the client. The client uses the `algorithm` and `headers` request
parameters to form a canonicalized `signing string`. This `signing string` is
then signed with the key associated with `keyId` and the algorithm corresponding
to `algorithm`. The result is then `Base64` encoded.
then signed with the key associated with `keyId` and the algorithm
corresponding to `algorithm`. The `signature` parameter is then set to the
`Base64` encoding of the signature.
### Signing String Composition
In order to generate the string that is signed with a key, the client MUST
take the values of each HTTP header specified by `headers`, in the order they
appear, and separate with an ASCII newline `\n`. The last header in the list
MUST NOT include a trailing ASCII newline.
In order to generate the string that is signed with a key, the client MUST take
the values of each HTTP header specified by `headers` in the order they appear.
1. If the header name is not `request-line` then append the lowercased header
name followed with an ASCII colon `:` and an ASCII space ` `.
2. If the header name is `request-line` then appened the HTTP request line,
otherwise append the header value.
3. If value is not the last value then append an ASCII newline `\n`. The string
MUST NOT include a trailing ASCII newline.
# Example Requests

@@ -124,21 +131,40 @@

The "rsa-key-1" keyId refers to a private key known to the client and a public
key known to the server. The "hmac-key-1" keyId refers to key known to the
client and server.
## Default parameterization
Authorization: Signature keyId="123" Base64(RSA-SHA256(Tue, 07 Jun 2011 20:51:35 GMT))
The authorization header and signature would be generated as:
Authorization: Signature keyId="rsa-key-1",algorithm="rsa-sha256",signature="Base64(RSA-SHA256(signing string))"
The client would compose the signing string as:
date: Tue, 07 Jun 2011 20:51:35 GMT
## Header List
Authorization: Signature keyId="123",headers="content-type Date content-md5" Base64(RSA-SHA256(Tue, 07 Jun 2011 20:51:35 GMT))
The authorization header and signature would be generated as:
Authorization: Signature keyId="rsa-key-1",algorithm="rsa-sha256",headers="request-line date content-type content-md5",signature="Base64(RSA-SHA256(signing string))"
The client would compose the signing string as (`+ "\n"` inserted for
readability):
application/json + "\n"
Tue, 07 Jun 2011 20:51:35 GMT + "\n"
h0auK8hnYJKmHTLhKtMTkQ==
POST /foo HTTP/1.1 + "\n"
date: Tue, 07 Jun 2011 20:51:35 GMT + "\n"
content-type: application/json + "\n"
content-md5: h0auK8hnYJKmHTLhKtMTkQ==
## Algorithm
Authorization: Signature keyId="123",algorithm="hmac-sha1" Base64(HMAC-SHA1(Tue, 07 Jun 2011 20:51:35 GMT))
The authorization header and signature would be generated as:
Authorization: Signature keyId="hmac-key-1",algorithm="hmac-sha1",signature="Base64(HMAC-SHA1(signing string))"
The client would compose the signing string as:
date: Tue, 07 Jun 2011 20:51:35 GMT
# Signing Algorithms

@@ -151,2 +177,3 @@

* rsa-sha512
* dsa-sha1
* hmac-sha1

@@ -253,27 +280,23 @@ * hmac-sha256

```
Thu, 05 Jan 2012 21:31:40 GMT
```
date: Thu, 05 Jan 2012 21:31:40 GMT
The Authorization header would be:
Authorization: Signature keyId="Test",algorithm="rsa-sha256" MDyO5tSvin5FBVdq3gMBTwtVgE8U/JpzSwFvY7gu7Q2tiZ5TvfHzf/RzmRoYwO8PoV1UGaw6IMwWzxDQkcoYOwvG/w4ljQBBoNusO/mYSvKrbqxUmZi8rNtrMcb82MS33bai5IeLnOGl31W1UbL4qE/wL8U9wCPGRJlCFLsTgD8=
Authorization: Signature keyId="Test",algorithm="rsa-sha256",signature="JldXnt8W9t643M2Sce10gqCh/+E7QIYLiI+bSjnFBGCti7s+mPPvOjVb72sbd1FjeOUwPTDpKbrQQORrm+xBYfAwCxF3LBSSzORvyJ5nRFCFxfJ3nlQD6Kdxhw8wrVZX5nSem4A/W3C8qH5uhFTRwF4ruRjh+ENHWuovPgO/HGQ="
### All Headers
Parameterized to include all headers, the string to sign would be:
Parameterized to include all headers, the string to sign would be (`+ "\n"`
inserted for readability):
```
/foo?param=value&pet=dog HTTP/1.1
example.com
Thu, 05 Jan 2012 21:31:40 GMT
application/json
Sd/dVLAcvNLSq16eXua5uQ==
18
```
POST /foo?param=value&pet=dog HTTP/1.1 + "\n"
host: example.com + "\n"
date: Thu, 05 Jan 2012 21:31:40 GMT + "\n"
content-type: application/json + "\n"
content-md5: Sd/dVLAcvNLSq16eXua5uQ== + "\n"
content-length: 18
The Authorization header would be:
Authorization: Signature
keyId="Test",algorithm="rsa-sha256",headers="request-line host date content-type content-md5 content-length" gVrKP7wVh1+FmWbNlhj0pNXIe9XmeOA6EcnoOKAvUILnwaMFzaKaam9UmeDPwjC9TdT+jSRqjtyZE49kZcSpYAHxGlPQ4ziXFRfPprlN/3Xwg3sUOGqbBiS3WFuY3QOOWv4tzc5p70g74U/QvHNNiYMcjoz89vRJhefbFSNwCDs=
Authorization: Signature keyId="Test",algorithm="rsa-sha256",headers="request-line host date content-type content-md5 content-length",signature="Gm7W/r+e90REDpWytALMrft4MqZxCmslOTOvwJX17ViEBA5E65QqvWI0vIH3l/vSsGiaMVmuUgzYsJLYMLcm5dGrv1+a+0fCoUdVKPZWHyImQEqpLkopVwqEH67LVECFBqFTAKlQgBn676zrfXQbb+b/VebAsNUtvQMe6cTjnDY="

@@ -22,4 +22,3 @@ // Copyright 2012 Joyent, Inc. All rights reserved.

New: 0,
Params: 1,
Signature: 2
Params: 1
};

@@ -29,3 +28,5 @@

Name: 0,
Value: 1
Quote: 1,
Value: 2,
Comma: 3
};

@@ -93,5 +94,5 @@

* "content-md5"
* ]
* ],
* "signature": "base64"
* },
* "signature": "base64",
* "signingString": "ready to be passed to crypto.verify()"

@@ -144,3 +145,2 @@ * }

params: {},
signature: '',
signingString: '',

@@ -173,10 +173,22 @@

case ParamsState.Name:
var code = c.charCodeAt(0);
// restricted name of A-Z / a-z
if ((code >= 0x41 && code <= 0x5a) || // A-Z
(code >= 0x61 && code <= 0x7a)) { // a-z
tmpName += c;
} else if (c === '=') {
if (tmpName.length === 0)
throw new InvalidHeaderError('bad param format');
substate = ParamsState.Quote;
} else {
throw new InvalidHeaderError('bad param format');
}
break;
case ParamsState.Quote:
if (c === '"') {
parsed.params[tmpName] = '';
tmpValue = '';
substate = ParamsState.Value;
} else if (c === ' ') {
state = State.Signature;
} else if (c !== '=' && c !== ',') {
tmpName += c;
} else {
throw new InvalidHeaderError('bad param format');
}

@@ -188,6 +200,14 @@ break;

parsed.params[tmpName] = tmpValue;
substate = ParamsState.Comma;
} else {
tmpValue += c;
}
break;
case ParamsState.Comma:
if (c === ',') {
tmpName = '';
substate = ParamsState.Name;
} else {
tmpValue += c;
throw new InvalidHeaderError('bad param format');
}

@@ -201,7 +221,2 @@ break;

case State.Signature:
parsed.signature += c;
break;
default:

@@ -233,4 +248,4 @@ throw new Error('Invalid substate');

if (!parsed.signature)
throw new InvalidHeaderError('signature was empty');
if (!parsed.params.signature)
throw new InvalidHeaderError('signature was not specified');

@@ -248,13 +263,12 @@ // Check the algorithm against the official list

var value;
if (h !== 'request-line') {
value = request.headers[h];
var value = request.headers[h];
if (!value)
throw new MissingHeaderError(h + ' was not in the request');
parsed.signingString += h + ': ' + value;
} else {
value =
parsed.signingString +=
request.method + ' ' + request.url + ' HTTP/' + request.httpVersion;
}
parsed.signingString += value;
if ((i + 1) < parsed.params.headers.length)

@@ -261,0 +275,0 @@ parsed.signingString += '\n';

@@ -23,3 +23,4 @@ // Copyright 2012 Joyent, Inc. All rights reserved.

var Authorization = 'Signature keyId="%s",algorithm="%s",headers="%s" %s';
var Authorization =
'Signature keyId="%s",algorithm="%s",headers="%s",signature="%s"';

@@ -105,2 +106,3 @@

* - {String} algorithm optional; defaults to 'rsa-sha256'.
* - {String} httpVersion optional; defaults to '1.1'.
* @return {Boolean} true if Authorization (and optionally Date) were added.

@@ -118,2 +120,3 @@ * @throws {TypeError} on bad parameter types (input).

assert.optionalArrayOfString(options.headers, 'options.headers');
assert.optionalString(options.httpVersion, 'options.httpVersion');

@@ -126,2 +129,4 @@ if (!request.getHeader('Date'))

options.algorithm = 'rsa-sha256';
if (!options.httpVersion)
options.httpVersion = '1.1';

@@ -140,14 +145,15 @@ options.algorithm = options.algorithm.toLowerCase();

var h = options.headers[i].toLowerCase();
request.getHeader(h);
var value = request.getHeader(h);
if (!value) {
if (h === 'request-line') {
value = request.method + ' ' + request.path + ' HTTP/1.1';
} else {
if (h !== 'request-line') {
var value = request.getHeader(h);
if (!value) {
throw new MissingHeaderError(h + ' was not in the request');
}
stringToSign += h + ': ' + value;
} else {
value =
stringToSign +=
request.method + ' ' + request.path + ' HTTP/' + options.httpVersion;
}
stringToSign += value;
if ((i + 1) < options.headers.length)

@@ -154,0 +160,0 @@ stringToSign += '\n';

@@ -32,9 +32,9 @@ // Copyright 2011 Joyent, Inc. All rights reserved.

if (alg[1] === 'HMAC') {
var hmac = crypto.createHmac(alg[2].toLowerCase(), key);
var hmac = crypto.createHmac(alg[2].toUpperCase(), key);
hmac.update(parsedSignature.signingString);
return (hmac.digest('base64') === parsedSignature.signature);
return (hmac.digest('base64') === parsedSignature.params.signature);
} else {
var verify = crypto.createVerify(alg[0]);
verify.update(parsedSignature.signingString);
return verify.verify(key, parsedSignature.signature, 'base64');
return verify.verify(key, parsedSignature.params.signature, 'base64');
}

@@ -41,0 +41,0 @@ }

@@ -5,3 +5,3 @@ {

"description": "Reference implementation of Joyent's HTTP Signature Scheme",
"version": "0.9.11",
"version": "0.10.0",
"repository": {

@@ -25,4 +25,4 @@ "type": "git",

"node-uuid": "1.4.0",
"tap": "0.3.1"
"tap": "0.4.2"
}
}

@@ -0,3 +1,5 @@

# node-http-signature
node-http-signature is a node.js library that has client and server components
for Joyent's `HTTP Signature Scheme`.
for Joyent's [HTTP Signature Scheme](http_signing.md).

@@ -4,0 +6,0 @@ ## Usage

Sorry, the diff of this file is not supported yet

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