httpsignatures

package module
v0.0.0-...-1df78eb Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 5, 2017 License: MIT Imports: 13 Imported by: 0

README

httpsignatures-go

GoDoc Build Status

Golang middleware library for the http-signatures spec.

Application

This is server side software, and can be used as middleware in for example the "goji" framework.

Remarks

When the clockskew check is used, the X-Data header prevails over the Data header.

Example

import (
  "https://github.com/quantoztechnology/go-http-signatures"
)

var (
	ErrorIncorrectKeyIdSupplied = "Incorrect keyId supplied"
	ErrorNoAuthorization        = "Request not authorized"
)

// Authenticator checks if the request has the correct signature for authentication
func (app *App) Authenticator(c *web.C, h http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {

		err := verifyRequest(r)

		if err != nil {
			var httpErr int
			var msg string

			switch err.Error() {
			case ErrorIncorrectKeyIdSupplied:
				httpErr = http.StatusBadRequest
				msg = ErrorIncorrectKeyIdSupplied
			case ErrorNoAuthorization:
				httpErr = http.StatusUnauthorized
				msg = ErrorNoAuthorization
			default:
				httpErr, msg = httpsignatures.ErrorToHTTPCode(err.Error())
			}

			if httpErr == http.StatusInternalServerError {
				http.Error(w, "Internal Server Error", http.StatusInternalServerError)
			} else {
				http.Error(w, msg, httpErr)
				return
			}
		}

		h.ServeHTTP(w, r)
	})
}

func verifyRequest(r *http.Request) error {
	keyLookUp := func(keyId string) (string, error) {
		// returns the base64string encoded key to verify the signature
		return keyLookUpFun(keyId)
	}

	allowedClockSkew := -1
	requiredAlgorithm := []string{httpsignatures.AlgorithmHmacSha256}
	_, err := httpsignatures.VerifyRequest(r, keyLookUp, allowedClockSkew, requiredAlgorithm,
		httpsignatures.HeaderRequestTarget, httpsignatures.HeaderHost, httpsignatures.HeaderXDate)
	return err
}

Documentation

Overview

httpsignatures is a golang implementation of the http-signatures spec found at https://tools.ietf.org/html/draft-cavage-http-signatures

Example (CustomSigning)
signer := httpsignatures.NewSigner(
	httpsignatures.AlgorithmHmacSha256,
	httpsignatures.HeaderRequestTarget,
	httpsignatures.HeaderDate,
	"content-length",
)

r, _ := http.NewRequest("GET", "http://example.com/some-api", nil)

signer.SignRequest(r, "keyId", "key")

http.DefaultClient.Do(r)
Output:

Example (Signing)
r, _ := http.NewRequest("GET", "http://example.com/some-api", nil)

signer := httpsignatures.NewSigner(httpsignatures.AlgorithmHmacSha256)
// Sign using the 'Signature' header
signer.SignRequest(r, "keyId", "key")
// OR Sign using the 'Authorization' header
signer.AuthRequest(r, "keyId", "key")

http.DefaultClient.Do(r)
Output:

Example (Verification)
_ = func(w http.ResponseWriter, r *http.Request) {

	keyLookUp := func(keyId string) (string, error) {
		key := keyId
		// check if keyId exists
		if len(keyId) == 0 {
			return "", errors.New("No keyId supplied")
		}
		// add check to see if keyId is allowed to access

		// if all goes well:
		return key, nil
	}

	allowedClockSkew := 300
	_, err := httpsignatures.VerifyRequest(r, keyLookUp, allowedClockSkew, []string{httpsignatures.AlgorithmEd25519},
		httpsignatures.HeaderRequestTarget)

	if err != nil {
		httpErr, msg := httpsignatures.ErrorToHTTPCode(err.Error())
		if httpErr == http.StatusInternalServerError {
			http.Error(w, "Internal Server Error", http.StatusInternalServerError)
		} else {
			http.Error(w, msg, httpErr)
		}
		panic(err)
	}

	// request was signed correctly.

}
Output:

Index

Examples

Constants

View Source
const (
	HeaderRequestTarget string = "(request-target)"
	HeaderDate          string = "date"
	HeaderXDate         string = "x-date"
	HeaderHost          string = "host"
)

Variables

View Source
var (
	AlgorithmHmacSha1   = "hmac-sha1"
	AlgorithmHmacSha256 = "hmac-sha256"
	AlgorithmEd25519    = "ed25519"
)
View Source
var (
	ErrorNoAlgorithmConfigured                     = "No algorithm configured"
	ErrorNoKeyIDConfigured                         = "No keyID configured"
	ErrorMissingRequiredHeader                     = "Missing required header"
	ErrorMissingSignatureParameterSignature        = "Missing signature parameter 'signature'"
	ErrorMissingSignatureParameterAlgorithm        = "Missing signature parameter 'algorithm'"
	ErrorMissingSignatureParameterKeyId            = "Missing signature parameter 'keyId'"
	ErrorNoSignatureHeaderFoundInRequest           = "No Signature header found in request"
	ErrorURLNotInRequest                           = "URL not in Request"
	ErrorMethodNotInRequest                        = "Method not in Request"
	ErrorSignaturesDoNotMatch                      = "Signatures do not match"
	ErrorAllowedClockskewExceeded                  = "Allowed clockskew exceeded"
	ErrorYouProbablyMisconfiguredAllowedClockSkew  = "You probably misconfigured allowedClockSkew, set to -1 to disable"
	ErrorRequiredHeaderNotInHeaderList             = "Required header not in header list"
	ErrorDateHeaderIsMissingForClockSkewComparison = "Date header is missing for clockSkew comparison"
	ErrorNoHeadersConfigLoaded                     = "No headers config loaded"
	ErrorAlgorithmNotAllowed                       = "The used encryption algorithm is not allowed"
)

Functions

func Ed25519Sign

func Ed25519Sign(privateKey *[]byte, message []byte) (*[]byte, error)

Ed25519Sign signs the message with the ed25519 ECDSA using the private Key

func Ed25519Verify

func Ed25519Verify(publicKey *[]byte, message []byte, signature *[]byte) (bool, error)

Ed25519Verify verifies the message with the ed25519 ECDSA using the public Key

func ErrorToHTTPCode

func ErrorToHTTPCode(errString string) (int, string)

func Hmac1Sign

func Hmac1Sign(privateKey *[]byte, message []byte) (*[]byte, error)

func Hmac1Verify

func Hmac1Verify(privateKey *[]byte, message []byte, sig *[]byte) (bool, error)

func Hmac256Sign

func Hmac256Sign(privateKey *[]byte, message []byte) (*[]byte, error)

func Hmac256Verify

func Hmac256Verify(privateKey *[]byte, message []byte, sig *[]byte) (bool, error)

func NewSigner

func NewSigner(algorithm string, headers ...string) *signer

NewSigner adds an algorithm to the signer algorithms

func Sign

func Sign(privateKey *[]byte, message []byte, hashFunc func() hash.Hash, signatureSize int) (*[]byte, error)

func Verify

func Verify(privateKey *[]byte, message []byte, hashFunc func() hash.Hash, sig *[]byte, signatureSize int) (bool, error)

func VerifyRequest

func VerifyRequest(r *http.Request, keyLookUp func(keyID string) (string, error), allowedClockSkew int,
	allowedAlgorithms []string, requiredHeaders ...string) (bool, error)

VerifyRequest verifies the signature added to the request and returns true if it is OK

Types

type Algorithm

type Algorithm struct {
	Name   string
	Sign   func(privateKey *[]byte, message []byte) (*[]byte, error)
	Verify func(key *[]byte, message []byte, signature *[]byte) (bool, error)
}

Algorithm exports the main algorithm properties: name, sign, verify

type HeaderValues

type HeaderValues map[string]string

HeaderList contains headers

type SignatureParameters

type SignatureParameters struct {
	KeyID      string
	Algorithm  *Algorithm
	Headers    HeaderValues
	HeaderList []string
	Signature  string
}

func (*SignatureParameters) FromConfig

func (s *SignatureParameters) FromConfig(keyId string, algorithm string, headers []string) error

FromConfig takes the string configuration and fills the SignatureParameters struct

func (*SignatureParameters) FromRequest

func (s *SignatureParameters) FromRequest(r *http.Request) error

FromRequest takes the signature string from the HTTP-Request both Signature and Authorization http headers are supported.

func (*SignatureParameters) ParseRequest

func (s *SignatureParameters) ParseRequest(r *http.Request) error

ParseRequest extracts the header fields from the request required by the `headers` parameter in the configuration

func (*SignatureParameters) ParseString

func (s *SignatureParameters) ParseString(list string)

ParseString constructs a headerlist from the 'headers' string

func (SignatureParameters) Verify

func (s SignatureParameters) Verify(keyBase64 string) (bool, error)

Verify verifies this signature for the given base64 encodedkey

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL