jws

package
v0.0.0-...-3bec3de Latest Latest
Warning

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

Go to latest
Published: Jul 29, 2016 License: MIT Imports: 19 Imported by: 0

Documentation

Overview

Package jws implements the digital signature on JSON based data structures as described in https://tools.ietf.org/html/rfc7515

If you do not care about the details, the only things that you would need to use are the following functions:

jws.Sign(payload, algorithm, key)
jws.Verify(encodedjws, algorithm, key)

To sign, simply use `jws.Sign`. `payload` is a []byte buffer that contains whatever data you want to sign. `alg` is one of the jwa.SignatureAlgorithm constants from package jwa. For RSA and ECDSA family of algorithms, you will need to prepare a private key. For HMAC family, you just need a []byte value. The `jws.Sign` function will return the encoded JWS message on success.

To verify, use `jws.Verify`. It will parse the `encodedjws` buffer and verify the result using `algorithm` and `key`. Upon successful verification, the original payload is returned, so you can work on it.

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrInvalidCompactPartsCount  = errors.New("compact JWS format must have three parts")
	ErrInvalidHeaderValue        = errors.New("invalid value for header key")
	ErrInvalidEcdsaSignatureSize = errors.New("invalid signature size of ecdsa algorithm")
	ErrInvalidSignature          = errors.New("invalid signature")
	ErrMissingPrivateKey         = errors.New("missing private key")
	ErrMissingPublicKey          = errors.New("missing public key")
	ErrUnsupportedAlgorithm      = errors.New("unspported algorithm")
)

Errors for JWS

View Source
var DefaultJWKAcceptor = JWKAcceptFunc(func(key jwk.Key) bool {
	if u := key.Use(); u != "" && u != "enc" && u != "sig" {
		return false
	}
	return true
})

DefaultJWKAcceptor is the default acceptor that is used in functions like VerifyWithJWKSet

Functions

func Sign

func Sign(payload []byte, alg jwa.SignatureAlgorithm, key interface{}, hdrs ...*Header) ([]byte, error)

Sign is a short way to generate a JWS in compact serialization for a given payload. If you need more control over the signature generation process, you should manually create signers and tweak the message.

func Verify

func Verify(buf []byte, alg jwa.SignatureAlgorithm, key interface{}) ([]byte, error)

Verify checks if the given JWS message is verifiable using `alg` and `key`. If the verification is successful, `err` is nil, and the content of the payload that was signed is returned. If you need more fine-grained control of the verification process, manually call `Parse`, generate a verifier, and call `Verify` on the parsed JWS message object.

func VerifyWithJKU

func VerifyWithJKU(buf []byte, jwkurl string) ([]byte, error)

VerifyWithJKU verifies the JWS message using a remote JWK file represented in the url.

func VerifyWithJWK

func VerifyWithJWK(buf []byte, key jwk.Key) ([]byte, error)

VerifyWithJWK verifies the JWS message using the specified JWK

func VerifyWithJWKSet

func VerifyWithJWKSet(buf []byte, keyset *jwk.Set, keyaccept JWKAcceptFunc) ([]byte, error)

VerifyWithJWKSet verifies the JWS message using JWK key set. By default it will only pick up keys that have the "use" key set to either "sig" or "enc", but you can override it by providing a keyaccept function.

Types

type CompactSerialize

type CompactSerialize struct{}

CompactSerialize is serializer that produces compact JSON JWS representation

func (CompactSerialize) Serialize

func (s CompactSerialize) Serialize(m *Message) ([]byte, error)

Serialize converts the mssage into a compact JSON format

type EcdsaSign

type EcdsaSign struct {
	Public     *Header
	Protected  *Header
	PrivateKey *ecdsa.PrivateKey
}

EcdsaSign is a signer using ECDSA

func NewEcdsaSign

func NewEcdsaSign(alg jwa.SignatureAlgorithm, key *ecdsa.PrivateKey) (*EcdsaSign, error)

NewEcdsaSign creates a signer that signs payloads using the given private key

func (EcdsaSign) PayloadSign

func (s EcdsaSign) PayloadSign(payload []byte) ([]byte, error)

PayloadSign generates a sign based on the Algorithm instance variable. This fulfills the `PayloadSigner` interface

func (EcdsaSign) ProtectedHeaders

func (s EcdsaSign) ProtectedHeaders() *Header

ProtectedHeaders returns the protected headers for this signer

func (EcdsaSign) PublicHeaders

func (s EcdsaSign) PublicHeaders() *Header

PublicHeaders returns the public headers for this signer

func (*EcdsaSign) SetProtectedHeaders

func (s *EcdsaSign) SetProtectedHeaders(h *Header)

SetProtectedHeaders sets the protected headers for this signer

func (*EcdsaSign) SetPublicHeaders

func (s *EcdsaSign) SetPublicHeaders(h *Header)

SetPublicHeaders sets the public headers for this signer

func (EcdsaSign) SignatureAlgorithm

func (s EcdsaSign) SignatureAlgorithm() jwa.SignatureAlgorithm

SignatureAlgorithm returns the algorithm being used for this signer

type EcdsaVerify

type EcdsaVerify struct {
	// contains filtered or unexported fields
}

EcdsaVerify is a sign verifider using ECDSA

func NewEcdsaVerify

func NewEcdsaVerify(alg jwa.SignatureAlgorithm, key *ecdsa.PublicKey) (*EcdsaVerify, error)

NewEcdsaVerify creates a new JWS verifier using the specified algorithm and the public key

func (EcdsaVerify) Verify

func (v EcdsaVerify) Verify(m *Message) error

Verify checks that signature generated for `payload` matches `signature`. This fulfills the `Verifier` interface

type EncodedHeader

type EncodedHeader struct {
	*Header
	// This is a special field. It's ONLY set when parsed from a serialized form.
	// It's used for verification purposes, because header representations (such as
	// JSON key order) may differ from what the source encoded with and what the
	// go json package uses
	//
	// If this field is populated (Len() > 0), it will be used for signature
	// calculation.
	// If you change the header values, make sure to clear this field, too
	Source buffer.Buffer `json:"-"`
}

EncodedHeader represents a header value that is base64 encoded in JSON format

func (EncodedHeader) MarshalJSON

func (e EncodedHeader) MarshalJSON() ([]byte, error)

MarshalJSON generates the JSON representation of this header

func (*EncodedHeader) UnmarshalJSON

func (e *EncodedHeader) UnmarshalJSON(buf []byte) error

UnmarshalJSON parses the JSON buffer into a Header

type EssentialHeader

type EssentialHeader struct {
	Algorithm              jwa.SignatureAlgorithm `json:"alg,omitempty"`
	ContentType            string                 `json:"cty,omitempty"`
	Critical               []string               `json:"crit,omitempty"`
	Jwk                    jwk.Key                `json:"jwk,omitempty"` // public key
	JwkSetURL              *url.URL               `json:"jku,omitempty"`
	KeyID                  string                 `json:"kid,omitempty"`
	Type                   string                 `json:"typ,omitempty"` // e.g. "JWT"
	X509Url                *url.URL               `json:"x5u,omitempty"`
	X509CertChain          []string               `json:"x5c,omitempty"`
	X509CertThumbprint     string                 `json:"x5t,omitempty"`
	X509CertThumbprintS256 string                 `json:"x5t#S256,omitempty"`
}

EssentialHeader is a set of headers that are already defined in RFC 7515

func (*EssentialHeader) Construct

func (h *EssentialHeader) Construct(m map[string]interface{}) error

Construct walks through the map (most likely parsed from a JSON buffer) and populates the necessary fields on this header

func (*EssentialHeader) Copy

func (h *EssentialHeader) Copy(h2 *EssentialHeader)

Copy copies the other heder over this one

func (*EssentialHeader) Merge

func (h *EssentialHeader) Merge(h2 *EssentialHeader)

Merge merges the current header with another.

type Header struct {
	*EssentialHeader `json:"-"`
	PrivateParams    map[string]interface{} `json:"-"`
}

Header represents a JWS header.

func NewHeader

func NewHeader() *Header

NewHeader creates a new Header

func (Header) Base64Encode

func (h Header) Base64Encode() ([]byte, error)

Base64Encode creates the base64 encoded version of the JSON representation of this header

func (*Header) Copy

func (h *Header) Copy(h2 *Header) error

Copy copies the other heder over this one

func (Header) MarshalJSON

func (h Header) MarshalJSON() ([]byte, error)

MarshalJSON generates the JSON representation of this header

func (*Header) Merge

func (h *Header) Merge(h2 *Header) (*Header, error)

Merge merges the current header with another.

func (*Header) Set

func (h *Header) Set(key string, value interface{}) error

Set sets the value of the given key to the given value. If it's one of the known keys, it will be set in EssentialHeader field. Otherwise, it is set in PrivateParams field.

func (*Header) UnmarshalJSON

func (h *Header) UnmarshalJSON(data []byte) error

UnmarshalJSON parses the JSON buffer into a Header

type HmacSign

type HmacSign struct {
	Public    *Header
	Protected *Header
	Key       []byte
	// contains filtered or unexported fields
}

HmacSign is a symmetric signer using HMAC

func NewHmacSign

func NewHmacSign(alg jwa.SignatureAlgorithm, key []byte) (*HmacSign, error)

NewHmacSign creates a symmetric signer that signs payloads using the given private key

func (HmacSign) PayloadSign

func (s HmacSign) PayloadSign(payload []byte) ([]byte, error)

PayloadSign generates a sign based on the Algorithm instance variable. This fulfills the `Signer` interface

func (HmacSign) ProtectedHeaders

func (s HmacSign) ProtectedHeaders() *Header

ProtectedHeaders returns the protected headers for this signer

func (HmacSign) PublicHeaders

func (s HmacSign) PublicHeaders() *Header

PublicHeaders returns the public headers for this signer

func (*HmacSign) SetProtectedHeaders

func (s *HmacSign) SetProtectedHeaders(h *Header)

SetProtectedHeaders sets the protected headers for this signer

func (*HmacSign) SetPublicHeaders

func (s *HmacSign) SetPublicHeaders(h *Header)

SetPublicHeaders sets the public headers for this signer

func (HmacSign) SignatureAlgorithm

func (s HmacSign) SignatureAlgorithm() jwa.SignatureAlgorithm

SignatureAlgorithm returns the algorithm being used for this signer

type HmacVerify

type HmacVerify struct {
	// contains filtered or unexported fields
}

HmacVerify is a symmetric sign verifier using HMAC

func NewHmacVerify

func NewHmacVerify(alg jwa.SignatureAlgorithm, key []byte) (*HmacVerify, error)

NewHmacVerify creates a new JWS verifier using the specified algorithm and the public key

func (HmacVerify) Verify

func (v HmacVerify) Verify(m *Message) error

Verify checks that signature generated for `payload` matches `signature`. This fulfills the `Verifier` interface

type JSONSerialize

type JSONSerialize struct {
	Pretty bool
}

JSONSerialize is serializer that produces full JSON JWS representation

func (JSONSerialize) Serialize

func (s JSONSerialize) Serialize(m *Message) ([]byte, error)

Serialize converts the mssage into a full JSON format

type JWKAcceptFunc

type JWKAcceptFunc func(jwk.Key) bool

JWKAcceptFunc is an implementation of JWKAcceptor using a plain function

func (JWKAcceptFunc) Accept

func (f JWKAcceptFunc) Accept(key jwk.Key) bool

Accept executes the provided function to determine if the given key can be used

type JWKAcceptor

type JWKAcceptor interface {
	Accept(jwk.Key) bool
}

JWKAcceptor decides which keys can be accepted by functions that iterate over a JWK key set.

type MergedHeader

type MergedHeader struct {
	ProtectedHeader *EncodedHeader
	PublicHeader    *Header
}

MergedHeader is a provides an interface to query both protected and public headers

func (MergedHeader) Algorithm

func (h MergedHeader) Algorithm() jwa.SignatureAlgorithm

Algorithm returns the algorithm used for this signature

func (MergedHeader) KeyID

func (h MergedHeader) KeyID() string

KeyID returns the key ID (kid) for this signature

type Message

type Message struct {
	Payload    buffer.Buffer `json:"payload"`
	Signatures []Signature   `json:"signatures"`
}

Message represents a full JWS encoded message. Flattened serialization is not supported as a struct, but rather it's represented as a Message struct with only one `signature` element

func Parse

func Parse(buf []byte) (*Message, error)

Parse parses the given buffer and creates a jws.Message struct. The input can be in either compact or full JSON serialization.

func ParseString

func ParseString(s string) (*Message, error)

ParseString is the same as Parse, but take in a string

func (Message) LookupSignature

func (m Message) LookupSignature(kid string) []Signature

LookupSignature looks up a particular signature entry using the `kid` value

type MultiSign

type MultiSign struct {
	Signers []PayloadSigner
}

MultiSign is a signer that creates multiple signatures for the message.

func NewMultiSign

func NewMultiSign(signers ...PayloadSigner) *MultiSign

NewMultiSign creates a new MultiSign object

func NewSigner

func NewSigner(signers ...PayloadSigner) *MultiSign

NewSigner creates a new MultiSign object with the given PayloadSigners. It is an alias to `NewMultiSign()`, but it exists so that it's clear to the end users that this is a generic signer that should be used for 99% of the cases

func (*MultiSign) AddSigner

func (m *MultiSign) AddSigner(s PayloadSigner)

AddSigner takes a PayloadSigner and appends it to the list of signers

func (*MultiSign) Sign

func (m *MultiSign) Sign(payload []byte) (*Message, error)

Sign takes a payload, and creates a JWS signed message.

func (*MultiSign) SignString

func (m *MultiSign) SignString(payload string) (*Message, error)

SignString takes a string payload, and creates a JWS signed message.

type PayloadSigner

type PayloadSigner interface {
	PayloadSign([]byte) ([]byte, error)
	PublicHeaders() *Header
	ProtectedHeaders() *Header
	SetPublicHeaders(*Header)
	SetProtectedHeaders(*Header)
	SignatureAlgorithm() jwa.SignatureAlgorithm
}

PayloadSigner generates signature for the given payload

type RsaSign

type RsaSign struct {
	Public     *Header
	Protected  *Header
	PrivateKey *rsa.PrivateKey
}

RsaSign is a signer using RSA

func NewRsaSign

func NewRsaSign(alg jwa.SignatureAlgorithm, key *rsa.PrivateKey) (*RsaSign, error)

NewRsaSign creates a signer that signs payloads using the given private key

func (RsaSign) PayloadSign

func (s RsaSign) PayloadSign(payload []byte) ([]byte, error)

PayloadSign generates a sign based on the Algorithm instance variable. This fulfills the `Signer` interface

func (RsaSign) ProtectedHeaders

func (s RsaSign) ProtectedHeaders() *Header

ProtectedHeaders returns the protected headers for this signer

func (RsaSign) PublicHeaders

func (s RsaSign) PublicHeaders() *Header

PublicHeaders returns the public headers for this signer

func (*RsaSign) SetProtectedHeaders

func (s *RsaSign) SetProtectedHeaders(h *Header)

SetProtectedHeaders sets the protected headers for this signer

func (*RsaSign) SetPublicHeaders

func (s *RsaSign) SetPublicHeaders(h *Header)

SetPublicHeaders sets the public headers for this signer

func (RsaSign) SignatureAlgorithm

func (s RsaSign) SignatureAlgorithm() jwa.SignatureAlgorithm

SignatureAlgorithm returns the algorithm being used for this signer

type RsaVerify

type RsaVerify struct {
	// contains filtered or unexported fields
}

RsaVerify is a sign verifider using RSA

func NewRsaVerify

func NewRsaVerify(alg jwa.SignatureAlgorithm, key *rsa.PublicKey) (*RsaVerify, error)

NewRsaVerify creates a new JWS verifier using the specified algorithm and the public key

func (RsaVerify) Verify

func (v RsaVerify) Verify(m *Message) error

Verify checks that signature generated for `payload` matches `signature`. This fulfills the `Verifier` interface

type Serializer

type Serializer interface {
	Serialize(*Message) ([]byte, error)
}

Serializer defines the interface for things that can serialize JWS messages

type Signature

type Signature struct {
	PublicHeader    *Header        `json:"header"`              // Raw JWS Unprotected Heders
	ProtectedHeader *EncodedHeader `json:"protected,omitempty"` // Base64 encoded JWS Protected Headers
	Signature       buffer.Buffer  `json:"signature"`           // Base64 encoded signature
}

Signature represents a signature generated by one of the signers

func NewSignature

func NewSignature() *Signature

NewSignature creates a new Signature

func (Signature) MergedHeaders

func (s Signature) MergedHeaders() MergedHeader

MergedHeaders returns the merged header for this signature

type Verifier

type Verifier interface {
	Verify(*Message) error
}

Verifier is used to verify the signature against the payload

Jump to

Keyboard shortcuts

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