Permalink
Browse files

Initial Creation

  • Loading branch information...
0 parents commit d858a7880c7039d5982153eb3a32a6335f95209f Mark Cavage committed Jul 14, 2011
Showing with 1,567 additions and 0 deletions.
  1. +2 −0 .gitignore
  2. +18 −0 LICENSE
  3. +202 −0 http_signing.md
  4. +22 −0 lib/index.js
  5. +289 −0 lib/parser.js
  6. +178 −0 lib/signer.js
  7. +41 −0 lib/verify.js
  8. +27 −0 package.json
  9. +485 −0 tst/parser.test.js
  10. +15 −0 tst/rsa_private.pem
  11. +6 −0 tst/rsa_public.pem
  12. +87 −0 tst/signer.test.js
  13. +195 −0 tst/verify.test.js
@@ -0,0 +1,2 @@
+*.log
+node_modules
18 LICENSE
@@ -0,0 +1,18 @@
+Copyright Joyent, Inc. All rights reserved.
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to
+deal in the Software without restriction, including without limitation the
+rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+sell copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+IN THE SOFTWARE.
@@ -0,0 +1,202 @@
+# Abstract
+
+This document describes a way to add origin authentication, message integrity,
+and replay resistance to HTTP REST requests. It is intended to be used over
+the HTTPS protocol.
+
+# Copyright Notice
+
+Copyright (c) 2011 Joyent, Inc. and the persons identified as document authors.
+All rights reserved.
+
+Code Components extracted from this document must include MIT License text.
+
+# Introduction
+
+This protocol is intended to provide a standard way for clients to sign HTTP
+requests. RFC2617 (HTTP Authentication) defines Basic and Digest authentication
+mechanisms, and RFC5246 (TLS 1.2) defines client-auth, both of which are widely
+employed on the Internet today. However, it is common place that the burdens of
+PKI prevent web service operators from deploying that methodoloy, and so many
+fall back to Basic authentication, which has poor security characteristics.
+
+Additionally, OAuth provides a fully-specified alternative for authorization
+of web service requests, but is not (always) ideal for machine to machine
+communication, as the key acquisition steps (generally) imply a fixed
+infrastructure that may not make sense to a service provider (e.g., symmetric
+keys).
+
+Several web service providers have invented their own schemes for signing
+HTTP requests, but to date, none have been placed in the public domain as a
+standard. This document serves that purpose. There are no techniques in this
+proposal that are novel beyond previous art, however, this aims to be a simple
+mechanism for signing these requests.
+
+# Signature Authentication Scheme
+
+The "signature" authentication scheme is based on the model that the client must
+authenticate itself with a digital signature produced by either a private
+asymmetric key (e.g., RSA) or a shared symmetric key (e.g., HMAC). The scheme
+is parameterized enough such that it is not bound to any particular key type or
+signing algorithm. However, it does explicitly assume that clients can send an
+HTTP `Date` header.
+
+## Authorization Header
+
+The client is expected to send an Authorization header (as defined in RFC 2617)
+with the following parameterization:
+
+ credentials := "Signature" params digitalSignature
+ params := 1#(keyId | [algorithm] | [headers] | [ext])
+ digitalSignature := plain-string
+
+ keyId := "keyId" "=" <"> plain-string <">
+ algorithm := "algorithm" "=" <"> plain-string <">
+ headers := "headers" "=" <"> 1#headers-value <">
+ ext := "ext" "=" <"> plain-string <">
+
+ headers-value := plain-string
+ plain-string = 1*( %x20-21 / %x23-5B / %x5D-7E )
+
+### Signature Parameters
+
+#### keyId
+
+REQUIRED. The `keyId` field is an opaque string that the server can use to look
+up the component they need to validate the signature. It could be an SSH key
+fingerprint, an LDAP DN, etc. Management of keys and assignment of `keyId` is
+out of scope for this document.
+
+#### algorithm
+
+REQUIRED. The `algorithm` parameter is used if the client and server agree on a
+non-standard digital signature algorithm. The full list of supported signature
+mechanisms is listed below.
+
+#### headers
+
+OPTIONAL. The `headers` parameter is used to specify the list of HTTP headers
+used to sign the request. If specified, it should be a quoted list of HTTP
+header names, separated by a single space character. By default, only one
+HTTP header is signed, which is the `Date` header. Note that the list MUST be
+specified in the order the values are concatenated together during signing. To
+include the HTTP request line in the signature calculation, use the special
+`request-line` value. While this is overloading the definition of `headers` in
+HTTP linguism, the request-line is defined in RFC 2616, and as the outlier from
+headers in useful signature calculation, it is deemed simpler to simply use
+`request-line` then to add a separate parameter for it.
+
+#### extensions
+
+OPTIONAL. The `extensions` parameter is used to include additional information
+which is covered by the request. The content and format of the string is out of
+scope for this document, and expected to be specified by implementors.
+
+### Digital Signature
+
+The `digitalSignature` portion of the credentials is a REQUIRED field, and is
+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.
+
+### 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 include a trailing ASCII newline.
+
+# Example Requests
+
+All requests refer to the following request (body ommitted):
+
+ POST /foo HTTP/1.1
+ Host: example.org
+ Date: Tue, 07 Jun 2011 20:51:35 GMT
+ Content-Type: application/json
+ Content-MD5: h0auK8hnYJKmHTLhKtMTkQ==
+ Content-Length: 123
+
+## Default parameterization
+
+ Authorization: Signature keyId="123" Base64(RSA-SHA256(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 client would compose the signing string as:
+
+ application/json
+ Tue, 07 Jun 2011 20:51:35 GMT
+ h0auK8hnYJKmHTLhKtMTkQ==
+
+## Algorithm
+
+ Authorization: Signature keyId="123",algorithm="hmac-sha1" Base64(HMAC-SHA1(Tue, 07 Jun 2011 20:51:35 GMT))
+
+# Signing Algorithms
+
+Currently supported algorithm names are:
+
+* rsa-sha1
+* rsa-sha256
+* rsa-sha512
+* hmac-sha1
+* hmac-sha256
+* hmac-sha512
+
+# Security Considerations
+
+## Default Parameters
+
+Note the default parameterization of the `Signature` scheme is only safe if all
+requests are carried over a secure transport (i.e., TLS). Sending the default
+scheme over a non-secure transport will leave the request vulnerable to
+spoofing, tampering, replay/repudiaton, and integrity violations (if using the
+STRIDE threat-modeling methodology).
+
+## Insecure Transports
+
+If sending the request over plain HTTP, service providers SHOULD require clients
+to sign ALL HTTP headers, and the `request-line`. Additionally, service
+providers SHOULD require `Content-MD5` calculations to be performed to ensure
+against any tampering from clients.
+
+## Nonces
+
+Nonces are out of scope for this document simply because many service providers
+fail to implement them correctly, or do not adopt security specfiications
+because of the infrastructure complexity. Given the `header` parameterization,
+a service provider is fully enabled to add nonce semantics into this scheme by
+using something like an `x-request-nonce` header, and ensuring it is signed
+with the `Date` header.
+
+## Clock Skew
+
+As the default scheme is to sign the `Date` header, service providers SHOULD
+protect against logged replay attacks by enforcing a clock skew. The server
+SHOULD be synchronized with NTP, and the recommendation in this specification
+is to allow 300s of clock skew (in either direction).
+
+## Required Headers to Sign
+
+It is out of scope for this document to dictate what headers a service provider
+will want to enforce, but service providers SHOULD at minimum include the
+`Date` header.
+
+# References
+
+## Normative References
+
+* [RFC2616] Hypertext Transfer Protocol -- HTTP/1.1
+* [RFC2617] HTTP Authentication: Basic and Digest Access Authentication
+* [RFC5246] The Transport Layer Security (TLS) Protocol Version 1.2
+
+## Informative References
+
+ Name: Mark Cavage (editor)
+ Company: Joyent, Inc.
+ Email: mark.cavage@joyent.com
+ URI: http://www.joyent.com
@@ -0,0 +1,22 @@
+// Copyright 2011 Joyent, Inc. All rights reserved.
+
+var parser = require('./parser');
+var signer = require('./signer');
+var verify = require('./verify');
+
+
+
+///--- Exported API
+
+module.exports = {
+
+ parse: parser.parseRequest,
+ parseRequest: parser.parseRequest,
+
+ sign: signer.signRequest,
+ signRequest: signer.signRequest,
+
+ verify: verify.verifySignature,
+ verifySignature: verify.verifySignature
+
+};
Oops, something went wrong.

0 comments on commit d858a78

Please sign in to comment.