cwt

package
v0.4.1 Latest Latest
Warning

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

Go to latest
Published: Dec 17, 2022 License: MIT Imports: 4 Imported by: 2

Documentation

Index

Examples

Constants

View Source
const (
	KeyIss key.IntKey = 1
	KeySub key.IntKey = 2
	KeyAud key.IntKey = 3
	KeyExp key.IntKey = 4
	KeyNbf key.IntKey = 5
	KeyIat key.IntKey = 6
	KeyCti key.IntKey = 7
)

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 is a set of simple claims for CWT.

Example
package main

import (
	"encoding/json"
	"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/go/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

	jsonData, err := json.Marshal(obj2.Payload)
	if err != nil {
		panic(err)
	}
	fmt.Printf("JSON(%d bytes): %s\n", len(jsonData), string(jsonData))
	// JSON(87 bytes): {"iss":"ldc:ca","sub":"ldc:chain","aud":"ldc:txpool","exp":1670123579,"cti":"01020304"}

}
Output:

Validate Claims: cose/go/cwt: Validator.Validate: token has expired
CBOR(44 bytes): a501666c64633a636102696c64633a636861696e036a6c64633a7478706f6f6c041a638c103b074401020304
JSON(87 bytes): {"iss":"ldc:ca","sub":"ldc:chain","aud":"ldc:txpool","exp":1670123579,"cti":"01020304"}

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 is a set of rich claims for CWT.

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

Example
package main

import (
	"encoding/json"
	"fmt"
	"time"

	"github.com/ldclabs/cose/cose"
	"github.com/ldclabs/cose/cwt"
	"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(key.AlgES256)
	if err != nil {
		panic(err)
	}
	ks := key.KeySet{privKey1, privKey2}

	// create a claims set
	claims := cwt.ClaimsMap{
		cwt.KeyIss:    "ldc:ca",
		cwt.KeySub:    "ldc:chain",
		cwt.KeyAud:    "ldc:txpool",
		cwt.KeyExp:    1670123579,
		key.IntKey(9): "read,write", // The scope of an access token, https://www.iana.org/assignments/cwt/cwt.xhtml.
	}

	// 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/go/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

	jsonData, err := json.Marshal(obj2.Payload)
	if err != nil {
		panic(err)
	}
	fmt.Printf("JSON(%d bytes): %s\n", len(jsonData), string(jsonData))
	// JSON(79 bytes): {"1":"ldc:ca","2":"ldc:chain","3":"ldc:txpool","4":1670123579,"9":"read,write"}

}
Output:

Validate Claims: cose/go/cwt: Validator.Validate: token has expired
CBOR(50 bytes): a501666c64633a636102696c64633a636861696e036a6c64633a7478706f6f6c041a638c103b096a726561642c7772697465
JSON(79 bytes): {"1":"ldc:ca","2":"ldc:chain","3":"ldc:txpool","4":1670123579,"9":"read,write"}

func (ClaimsMap) Bytesify

func (c ClaimsMap) Bytesify() []byte

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

func (ClaimsMap) GetBytes

func (cm ClaimsMap) GetBytes(k key.IntKey) ([]byte, error)

GetBytes returns the value for the key as an []byte. If the key is not present, it returns (nil, nil). If the underlying value is not a slice of bytes or an addressable array of bytes, it returns (nil, error).

func (ClaimsMap) GetInt

func (cm ClaimsMap) GetInt(k key.IntKey) (int64, error)

GetInt returns the value for the key as an int64. If the key is not present, it returns (0, nil). If the underlying value's Kind is not Int, Int8, Int16, Int32, Int64, Uint, Uint8, Uint16, Uint32, Int64, or the value is overflows, it returns (0, error).

func (ClaimsMap) GetSmallInt

func (cm ClaimsMap) GetSmallInt(k key.IntKey) (int, error)

GetSmallInt returns the value for the key as an int in [-65536, 65536]. If the key is not present, it returns (0, nil). If the underlying value's Kind is not Int, Int8, Int16, Int32, Int64, Uint, Uint8, Uint16, Uint32, Int64, or the value's range is out of [-65536, 65536], it returns (0, error).

func (ClaimsMap) GetString

func (cm ClaimsMap) GetString(k key.IntKey) (string, error)

GetString returns the value for the key as an string. If the key is not present, it returns ("", nil). If the underlying value is not a string, it returns ("", error).

func (ClaimsMap) GetUint

func (cm ClaimsMap) GetUint(k key.IntKey) (uint64, error)

GetUint returns the value for the key as an uint64. If the key is not present, it returns (0, nil). If the underlying value's Kind is not Int, Int8, Int16, Int32, Int64, Uint, Uint8, Uint16, Uint32, Int64, or the value is overflows, it returns (0, error).

func (ClaimsMap) Has

func (cm ClaimsMap) Has(k key.IntKey) bool

Has returns true if the ClaimsMap contains the key.

func (ClaimsMap) MarshalCBOR

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

MarshalCBOR implements the CBOR Marshaler interface for ClaimsMap. It is the same as IntMap.MarshalCBOR.

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 define validation options for CWT validators.

Jump to

Keyboard shortcuts

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