Documentation
¶
Index ¶
- Constants
- type Claims
- type ClaimsMap
- func (c ClaimsMap) Bytesify() []byte
- func (cm ClaimsMap) GetBytes(k key.IntKey) ([]byte, error)
- func (cm ClaimsMap) GetInt(k key.IntKey) (int64, error)
- func (cm ClaimsMap) GetSmallInt(k key.IntKey) (int, error)
- func (cm ClaimsMap) GetString(k key.IntKey) (string, error)
- func (cm ClaimsMap) GetUint(k key.IntKey) (uint64, error)
- func (cm ClaimsMap) Has(k key.IntKey) bool
- func (c ClaimsMap) MarshalCBOR() ([]byte, error)
- type Validator
- type ValidatorOpts
Examples ¶
Constants ¶
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"}
type ClaimsMap ¶
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 ¶
Bytesify returns a CBOR-encoded byte slice. It returns nil if MarshalCBOR failed.
func (ClaimsMap) GetBytes ¶
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 ¶
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 ¶
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 ¶
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 ¶
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) MarshalCBOR ¶
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) ValidateMap ¶
ValidateMap validates a ClaimsMap according to the options provided.