cwt

package
v0.6.7 Latest Latest
Warning

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

Go to latest
Published: Jan 6, 2023 License: MIT Imports: 5 Imported by: 2

Documentation

Overview

Package cwt implements CBOR Web Token (CWT) as defined in RFC8392. https://datatracker.ietf.org/doc/html/rfc8392.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Claims

type Claims struct {
	Issuer     string      `cbor:"1,keyasint,omitempty" json:"iss,omitempty"`
	Subject    string      `cbor:"2,keyasint,omitempty" json:"sub,omitempty"`
	Audience   string      `cbor:"3,keyasint,omitempty" json:"aud,omitempty"`
	Expiration uint64      `cbor:"4,keyasint,omitempty" json:"exp,omitempty"` // seconds since epoch
	NotBefore  uint64      `cbor:"5,keyasint,omitempty" json:"nbf,omitempty"` // seconds since epoch
	IssuedAt   uint64      `cbor:"6,keyasint,omitempty" json:"iat,omitempty"` // seconds since epoch
	CWTID      key.ByteStr `cbor:"7,keyasint,omitempty" json:"cti,omitempty"`
}

Claims represents a set of common claims for CWT.

Example
package main

import (
	"fmt"
	"time"

	"github.com/ldclabs/cose/cose"
	"github.com/ldclabs/cose/cwt"
	"github.com/ldclabs/cose/key"
	"github.com/ldclabs/cose/key/ed25519"
)

func main() {
	// Create a ed25519 signer key
	privKey, err := ed25519.GenerateKey()
	if err != nil {
		panic(err)
	}
	signer, err := privKey.Signer()
	if err != nil {
		panic(err)
	}

	// Create a verifier key
	pubKey, err := ed25519.ToPublicKey(privKey)
	if err != nil {
		panic(err)
	}
	verifier, err := pubKey.Verifier()
	if err != nil {
		panic(err)
	}

	// create a claims set
	claims := cwt.Claims{
		Issuer:     "ldc:ca",
		Subject:    "ldc:chain",
		Audience:   "ldc:txpool",
		Expiration: 1670123579,
		CWTID:      []byte{1, 2, 3, 4},
	}

	// sign with Sign1Message
	obj := cose.Sign1Message[cwt.Claims]{Payload: claims}
	cwtData, err := obj.SignAndEncode(signer, nil)
	if err != nil {
		panic(err)
	}

	// decode and verify the cwt
	obj2, err := cose.VerifySign1Message[cwt.Claims](verifier, cwtData, nil)
	if err != nil {
		panic(err)
	}

	// validate the cwt's claims
	validator, err := cwt.NewValidator(&cwt.ValidatorOpts{
		ExpectedIssuer:   "ldc:ca",
		ExpectedAudience: "ldc:txpool",
		ClockSkew:        time.Minute,
	})
	if err != nil {
		panic(err)
	}

	err = validator.Validate(&obj2.Payload)
	fmt.Printf("Validate Claims: %v\n", err)
	// Validate Claims: cose/cwt: Validator.Validate: token has expired

	cborData, err := key.MarshalCBOR(obj2.Payload)
	// cborData, err := cbor.Marshal(myClaims)
	if err != nil {
		panic(err)
	}
	fmt.Printf("CBOR(%d bytes): %x\n", len(cborData), cborData)
	// CBOR(44 bytes): a501666c64633a636102696c64633a636861696e036a6c64633a7478706f6f6c041a638c103b074401020304

}
Output:

Validate Claims: cose/cwt: Validator.Validate: token has expired
CBOR(44 bytes): a501666c64633a636102696c64633a636861696e036a6c64633a7478706f6f6c041a638c103b074401020304

func (*Claims) Bytesify

func (c *Claims) Bytesify() []byte

Bytesify returns a CBOR-encoded byte slice. It returns nil if MarshalCBOR failed.

type ClaimsMap

type ClaimsMap key.IntMap

ClaimsMap supports full claims for CWT.

Reference https://www.iana.org/assignments/cwt/cwt.xhtml

Example
package main

import (
	"fmt"
	"time"

	"github.com/ldclabs/cose/cose"
	"github.com/ldclabs/cose/cwt"
	"github.com/ldclabs/cose/iana"
	"github.com/ldclabs/cose/key"
	"github.com/ldclabs/cose/key/ecdsa"
	"github.com/ldclabs/cose/key/ed25519"
)

func main() {
	// Create a ed25519 signer key
	privKey1, err := ed25519.GenerateKey()
	if err != nil {
		panic(err)
	}
	privKey2, err := ecdsa.GenerateKey(iana.AlgorithmES256)
	if err != nil {
		panic(err)
	}
	ks := key.KeySet{privKey1, privKey2}

	// create a claims set
	claims := cwt.ClaimsMap{
		iana.CWTClaimIss:   "ldc:ca",
		iana.CWTClaimSub:   "ldc:chain",
		iana.CWTClaimAud:   "ldc:txpool",
		iana.CWTClaimExp:   1670123579,
		iana.CWTClaimScope: "read,write",
	}

	// Sign the claims
	signers, err := ks.Signers()
	if err != nil {
		panic(err)
	}
	// sign with SignMessage
	obj := cose.SignMessage[cwt.ClaimsMap]{Payload: claims}
	cwtData, err := obj.SignAndEncode(signers, nil)
	if err != nil {
		panic(err)
	}

	// decode and verify the cwt
	verifiers, err := ks.Verifiers()
	if err != nil {
		panic(err)
	}
	obj2, err := cose.VerifySignMessage[cwt.ClaimsMap](verifiers, cwtData, nil)
	if err != nil {
		panic(err)
	}

	// Validate the claims
	validator, err := cwt.NewValidator(&cwt.ValidatorOpts{
		ExpectedIssuer:   "ldc:ca",
		ExpectedAudience: "ldc:txpool",
		ClockSkew:        time.Minute,
	})
	if err != nil {
		panic(err)
	}

	err = validator.ValidateMap(obj2.Payload)
	fmt.Printf("Validate Claims: %v\n", err)
	// Validate Claims: cose/cwt: Validator.Validate: token has expired

	cborData, err := key.MarshalCBOR(obj2.Payload)
	// cborData, err := cbor.Marshal(myClaims)
	if err != nil {
		panic(err)
	}
	fmt.Printf("CBOR(%d bytes): %x\n", len(cborData), cborData)
	// CBOR(50 bytes): a501666c64633a636102696c64633a636861696e036a6c64633a7478706f6f6c041a638c103b096a726561642c7772697465

}
Output:

Validate Claims: cose/cwt: Validator.Validate: token has expired
CBOR(50 bytes): a501666c64633a636102696c64633a636861696e036a6c64633a7478706f6f6c041a638c103b096a726561642c7772697465

func (ClaimsMap) Bytesify

func (cm ClaimsMap) Bytesify() []byte

Bytesify returns a CBOR-encoded byte slice. It returns nil if MarshalCBOR failed.

func (ClaimsMap) GetBool added in v0.6.0

func (cm ClaimsMap) GetBool(claim int) (bool, error)

GetBool returns the value of the given claim as a bool, or a error.

func (ClaimsMap) GetBytes

func (cm ClaimsMap) GetBytes(claim int) ([]byte, error)

GetBytes returns the value of the given claim as a slice of bytes, or a error.

func (ClaimsMap) GetInt

func (cm ClaimsMap) GetInt(claim int) (int, error)

GetInt returns the value of the given claim as a int, or a error.

func (ClaimsMap) GetInt64 added in v0.6.0

func (cm ClaimsMap) GetInt64(claim int) (int64, error)

GetInt64 returns the value of the given claim as a int64, or a error.

func (ClaimsMap) GetString

func (cm ClaimsMap) GetString(claim int) (string, error)

GetString returns the value of the given claim as a string, or a error.

func (ClaimsMap) GetUint64 added in v0.6.0

func (cm ClaimsMap) GetUint64(claim int) (uint64, error)

GetUint64 returns the value of the given claim as a uint64, or a error.

func (ClaimsMap) Has

func (cm ClaimsMap) Has(claim int) bool

Has returns true if the ClaimsMap has the given claim.

func (ClaimsMap) MarshalCBOR

func (cm ClaimsMap) MarshalCBOR() ([]byte, error)

MarshalCBOR implements the CBOR Marshaler interface for ClaimsMap.

func (*ClaimsMap) UnmarshalCBOR added in v0.6.6

func (cm *ClaimsMap) UnmarshalCBOR(data []byte) error

UnmarshalCBOR implements the CBOR Unmarshaler interface for ClaimsMap.

type Validator

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

Validator defines how CBOR Web Tokens (CWT) should be validated.

func NewValidator

func NewValidator(opts *ValidatorOpts) (*Validator, error)

NewValidator creates a new CWT Validator.

func (*Validator) Validate

func (v *Validator) Validate(claims *Claims) error

Validate validates a *Claims according to the options provided.

func (*Validator) ValidateMap

func (v *Validator) ValidateMap(claims ClaimsMap) error

ValidateMap validates a ClaimsMap according to the options provided.

type ValidatorOpts

type ValidatorOpts struct {
	ExpectedIssuer   string
	ExpectedAudience string

	AllowMissingExpiration bool
	ExpectIssuedInThePast  bool

	ClockSkew time.Duration
	FixedNow  time.Time
}

ValidatorOpts defines validation options for CWT validators.

Jump to

Keyboard shortcuts

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