go-cose – github.com/veraison/go-cose Index | Examples | Files

package cose

import "github.com/veraison/go-cose"

Index

Examples

Constants

const (
	CBORTagSignMessage  = 98
	CBORTagSign1Message = 18
)

CBOR Tags for COSE signatures registered in the IANA "CBOR Tags" registry.

Reference: https://www.iana.org/assignments/cbor-tags/cbor-tags.xhtml#tags

const (
	HeaderLabelAlgorithm         int64 = 1
	HeaderLabelCritical          int64 = 2
	HeaderLabelContentType       int64 = 3
	HeaderLabelKeyID             int64 = 4
	HeaderLabelIV                int64 = 5
	HeaderLabelPartialIV         int64 = 6
	HeaderLabelCounterSignature  int64 = 7
	HeaderLabelCounterSignature0 int64 = 9
	HeaderLabelX5Bag             int64 = 32
	HeaderLabelX5Chain           int64 = 33
	HeaderLabelX5T               int64 = 34
	HeaderLabelX5U               int64 = 35
)

COSE Header labels registered in the IANA "COSE Header Parameters" registry.

Reference: https://www.iana.org/assignments/cose/cose.xhtml#header-parameters

Variables

var (
	ErrAlgorithmMismatch     = errors.New("algorithm mismatch")
	ErrAlgorithmNotFound     = errors.New("algorithm not found")
	ErrAlgorithmNotSupported = errors.New("algorithm not supported")
	ErrEmptySignature        = errors.New("empty signature")
	ErrInvalidAlgorithm      = errors.New("invalid algorithm")
	ErrMissingPayload        = errors.New("missing payload")
	ErrNoSignatures          = errors.New("no signatures attached")
	ErrUnavailableHashFunc   = errors.New("hash function is not available")
	ErrVerification          = errors.New("verification error")
	ErrInvalidPubKey         = errors.New("invalid public key")
	ErrInvalidPrivKey        = errors.New("invalid private key")
	ErrNotPrivKey            = errors.New("not a private key")
	ErrSignOpNotSupported    = errors.New("sign key_op not supported by key")
	ErrVerifyOpNotSupported  = errors.New("verify key_op not supported by key")
)

Common errors

Functions

func I2OSP

func I2OSP(x *big.Int, buf []byte) error

I2OSP - Integer-to-Octet-String primitive converts a nonnegative integer to an octet string of a specified length `len(buf)`, and stores it in `buf`. I2OSP is used for encoding ECDSA signature (r, s) into byte strings.

Reference: https://datatracker.ietf.org/doc/html/rfc8017#section-4.1

func OS2IP

func OS2IP(x []byte) *big.Int

OS2IP - Octet-String-to-Integer primitive converts an octet string to a nonnegative integer. OS2IP is used for decoding ECDSA signature (r, s) from byte strings.

Reference: https://datatracker.ietf.org/doc/html/rfc8017#section-4.2

func Sign1

func Sign1(rand io.Reader, signer Signer, headers Headers, payload []byte, external []byte) ([]byte, error)

Sign1 signs a Sign1Message using the provided Signer.

This method is a wrapper of `Sign1Message.Sign()`.

Reference: https://datatracker.ietf.org/doc/html/rfc8152#section-4.4

Example

This example demonstrates signing COSE_Sign1_Tagged signatures using Sign1().

Code:

{
	// create a signer
	privateKey, err := ecdsa.GenerateKey(elliptic.P521(), rand.Reader)
	if err != nil {
		panic(err)
	}
	signer, err := cose.NewSigner(cose.AlgorithmES512, privateKey)
	if err != nil {
		panic(err)
	}

	// sign message
	headers := cose.Headers{
		Protected: cose.ProtectedHeader{
			cose.HeaderLabelAlgorithm: cose.AlgorithmES512,
		},
		Unprotected: cose.UnprotectedHeader{
			cose.HeaderLabelKeyID: []byte("1"),
		},
	}
	sig, err := cose.Sign1(rand.Reader, signer, headers, []byte("hello world"), nil)
	if err != nil {
		panic(err)
	}

	fmt.Println("message signed")
	_ = sig // further process on sig
	// Output:
	// message signed
}

Output:

message signed

func Sign1Untagged

func Sign1Untagged(rand io.Reader, signer Signer, headers Headers, payload []byte, external []byte) ([]byte, error)

Sign1Untagged signs an UntaggedSign1Message using the provided Signer.

This method is a wrapper of `UntaggedSign1Message.Sign()`.

Reference: https://datatracker.ietf.org/doc/html/rfc8152#section-4.4

Example

This example demonstrates signing COSE_Sign1 signatures using Sign1Untagged().

Code:

{
	// create a signer
	privateKey, err := ecdsa.GenerateKey(elliptic.P521(), rand.Reader)
	if err != nil {
		panic(err)
	}
	signer, err := cose.NewSigner(cose.AlgorithmES512, privateKey)
	if err != nil {
		panic(err)
	}

	// sign message
	headers := cose.Headers{
		Protected: cose.ProtectedHeader{
			cose.HeaderLabelAlgorithm: cose.AlgorithmES512,
		},
		Unprotected: cose.UnprotectedHeader{
			cose.HeaderLabelKeyID: []byte("1"),
		},
	}
	sig, err := cose.Sign1Untagged(rand.Reader, signer, headers, []byte("hello world"), nil)
	if err != nil {
		panic(err)
	}

	fmt.Println("message signed")
	_ = sig // further process on sig
	// Output:
	// message signed
}

Output:

message signed

Types

type Algorithm

type Algorithm int64

Algorithm represents an IANA algorithm entry in the COSE Algorithms registry.

See Also

COSE Algorithms: https://www.iana.org/assignments/cose/cose.xhtml#algorithms

RFC 8152 16.4: https://datatracker.ietf.org/doc/html/rfc8152#section-16.4

const (
	// RSASSA-PSS w/ SHA-256 by RFC 8230.
	// Requires an available crypto.SHA256.
	AlgorithmPS256 Algorithm = -37

	// RSASSA-PSS w/ SHA-384 by RFC 8230.
	// Requires an available crypto.SHA384.
	AlgorithmPS384 Algorithm = -38

	// RSASSA-PSS w/ SHA-512 by RFC 8230.
	// Requires an available crypto.SHA512.
	AlgorithmPS512 Algorithm = -39

	// ECDSA w/ SHA-256 by RFC 8152.
	// Requires an available crypto.SHA256.
	AlgorithmES256 Algorithm = -7

	// ECDSA w/ SHA-384 by RFC 8152.
	// Requires an available crypto.SHA384.
	AlgorithmES384 Algorithm = -35

	// ECDSA w/ SHA-512 by RFC 8152.
	// Requires an available crypto.SHA512.
	AlgorithmES512 Algorithm = -36

	// PureEdDSA by RFC 8152.
	AlgorithmEd25519 Algorithm = -8

	// An invalid/unrecognised algorithm.
	AlgorithmInvalid Algorithm = 0
)

Algorithms supported by this library.

When using an algorithm which requires hashing, make sure the associated hash function is linked to the binary.

func (Algorithm) MarshalCBOR

func (a Algorithm) MarshalCBOR() ([]byte, error)

MarshalCBOR marshals the Algorithm as a CBOR int.

func (Algorithm) String

func (a Algorithm) String() string

String returns the name of the algorithm

func (*Algorithm) UnmarshalCBOR

func (a *Algorithm) UnmarshalCBOR(data []byte) error

UnmarshalCBOR populates the Algorithm from the provided CBOR value (must be int or tstr).

type Curve

type Curve int64

Curve represents the EC2/OKP key's curve. See: https://datatracker.ietf.org/doc/html/rfc8152#section-13.1

const (

	// Invalid/unrecognised curve
	CurveInvalid Curve = 0

	// NIST P-256 also known as secp256r1
	CurveP256 Curve = 1

	// NIST P-384 also known as secp384r1
	CurveP384 Curve = 2

	// NIST P-521 also known as secp521r1
	CurveP521 Curve = 3

	// X25519 for use w/ ECDH only
	CurveX25519 Curve = 4

	// X448 for use w/ ECDH only
	CurveX448 Curve = 5

	// Ed25519 for use /w EdDSA only
	CurveEd25519 Curve = 6

	// Ed448 for use /w EdDSA only
	CurveEd448 Curve = 7
)

func (Curve) MarshalCBOR

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

MarshalCBOR marshals the KeyType as a CBOR int.

func (Curve) String

func (c Curve) String() string

String returns a string representation of the Curve. Note does not represent a valid value of the corresponding serialized entry, and must not be used as such.

func (*Curve) UnmarshalCBOR

func (c *Curve) UnmarshalCBOR(data []byte) error

UnmarshalCBOR populates the KeyType from the provided CBOR value (must be int or tstr).

type Headers

type Headers struct {
	// RawProtected contains the raw CBOR encoded data for the protected header.
	// It is populated when decoding.
	// Applications can use this field for customized encoding / decoding of
	// the protected header in case the default decoder provided by this library
	// is not preferred.
	RawProtected cbor.RawMessage

	// Protected contains parameters that are to be cryptographically protected.
	// When encoding or signing, the protected header is encoded using the
	// default CBOR encoder if RawProtected is set to nil. Otherwise,
	// RawProtected will be used with Protected ignored.
	Protected ProtectedHeader

	// RawUnprotected contains the raw CBOR encoded data for the unprotected
	// header. It is populated when decoding.
	// Applications can use this field for customized encoding / decoding of
	// the unprotected header in case the default decoder provided by this
	// library is not preferred.
	RawUnprotected cbor.RawMessage

	// Unprotected contains parameters that are not cryptographically protected.
	// When encoding, the unprotected header is encoded using the default CBOR
	// encoder if RawUnprotected is set to nil. Otherwise, RawUnprotected will
	// be used with Unprotected ignored.
	Unprotected UnprotectedHeader
}

Headers represents "two buckets of information that are not considered to be part of the payload itself, but are used for holding information about content, algorithms, keys, or evaluation hints for the processing of the layer."

It is represented by CDDL fragments:

Headers = (
    protected : empty_or_serialized_map,
    unprotected : header_map
)

header_map = {
    Generic_Headers,
    * label => values
}

label  = int / tstr
values = any

empty_or_serialized_map = bstr .cbor header_map / bstr .size 0

See Also

https://tools.ietf.org/html/rfc8152#section-3

func (*Headers) MarshalProtected

func (h *Headers) MarshalProtected() ([]byte, error)

MarshalProtected encodes the protected header. RawProtected is returned if it is not set to nil.

func (*Headers) MarshalUnprotected

func (h *Headers) MarshalUnprotected() ([]byte, error)

MarshalUnprotected encodes the unprotected header. RawUnprotected is returned if it is not set to nil.

func (*Headers) UnmarshalFromRaw

func (h *Headers) UnmarshalFromRaw() error

UnmarshalFromRaw decodes Protected from RawProtected and Unprotected from RawUnprotected.

type Key

type Key struct {

	// KeyType identifies the family of keys for this structure, and thus,
	// which of the key-type-specific parameters need to be set.
	KeyType KeyType `cbor:"1,keyasint"`
	// KeyID is the identification value matched to the kid in the message.
	KeyID []byte `cbor:"2,keyasint,omitempty"`
	// KeyOps can be set to restrict the set of operations that the Key is used for.
	KeyOps []KeyOp `cbor:"4,keyasint,omitempty"`
	// BaseIV is the Base IV to be xor-ed with Partial IVs.
	BaseIV []byte `cbor:"5,keyasint,omitempty"`

	// Algorithm is used to restrict the algorithm that is used with the
	// key. If it is set, the application MUST verify that it matches the
	// algorithm for which the Key is being used.
	Algorithm Algorithm `cbor:"-"`
	// Curve is EC identifier -- taken form "COSE Elliptic Curves" IANA registry.
	// Populated from keyStruct.RawKeyParam when key type is EC2 or OKP.
	Curve Curve `cbor:"-"`
	// K is the key value. Populated from keyStruct.RawKeyParam when key
	// type is Symmetric.
	K []byte `cbor:"-"`

	// X is the x-coordinate
	X []byte `cbor:"-2,keyasint,omitempty"`
	// Y is the y-coordinate (sign bits are not supported)
	Y []byte `cbor:"-3,keyasint,omitempty"`
	// D is the private key
	D []byte `cbor:"-4,keyasint,omitempty"`
}

Key represents a COSE_Key structure, as defined by RFC8152. Note: currently, this does NOT support RFC8230 (RSA algorithms).

func NewEC2Key

func NewEC2Key(alg Algorithm, x, y, d []byte) (*Key, error)

NewEC2Key returns a Key created using the provided elliptic curve key data.

func NewKeyFromPrivate

func NewKeyFromPrivate(alg Algorithm, priv crypto.PrivateKey) (*Key, error)

NewKeyFromPrivate returns a Key created using provided crypto.PrivateKey and Algorithm.

func NewKeyFromPublic

func NewKeyFromPublic(alg Algorithm, pub crypto.PublicKey) (*Key, error)

NewKeyFromPublic returns a Key created using the provided crypto.PublicKey and Algorithm.

func NewOKPKey

func NewOKPKey(alg Algorithm, x, d []byte) (*Key, error)

NewOKPKey returns a Key created using the provided Octet Key Pair data.

func NewSymmetricKey

func NewSymmetricKey(k []byte) (*Key, error)

NewSymmetricKey returns a Key created using the provided Symmetric key bytes.

func (*Key) AlgorithmOrDefault

func (k *Key) AlgorithmOrDefault() (Algorithm, error)

AlgorithmOrDefault returns the Algorithm associated with Key. If Key.Algorithm is set, that is what is returned. Otherwise, the algorithm is inferred using Key.Curve. This method does NOT validate that Key.Algorithm, if set, aligns with Key.Curve.

func (*Key) MarshalCBOR

func (k *Key) MarshalCBOR() ([]byte, error)

MarshalCBOR encodes Key into a COSE_Key object.

func (*Key) PrivateKey

func (k *Key) PrivateKey() (crypto.PrivateKey, error)

PrivateKey returns a crypto.PrivateKey generated using Key's parameters.

func (*Key) PublicKey

func (k *Key) PublicKey() (crypto.PublicKey, error)

PublicKey returns a crypto.PublicKey generated using Key's parameters.

func (*Key) Signer

func (k *Key) Signer() (Signer, error)

Signer returns a Signer created using Key.

func (*Key) UnmarshalCBOR

func (k *Key) UnmarshalCBOR(data []byte) error

UnmarshalCBOR decodes a COSE_Key object into Key.

func (Key) Validate

func (k Key) Validate() error

Validate ensures that the parameters set inside the Key are internally consistent (e.g., that the key type is appropriate to the curve.)

func (*Key) Verifier

func (k *Key) Verifier() (Verifier, error)

Verifier returns a Verifier created using Key.

type KeyOp

type KeyOp int64

KeyOp represents a key_ops value used to restrict purposes for which a Key may be used.

const (
	// An inviald key_op value
	KeyOpInvalid KeyOp = 0

	// The key is used to create signatures. Requires private key fields.
	KeyOpSign KeyOp = 1

	// The key is used for verification of signatures.
	KeyOpVerify KeyOp = 2

	// The key is used for key transport encryption.
	KeyOpEncrypt KeyOp = 3

	// The key is used for key transport decryption. Requires private key fields.
	KeyOpDecrypt KeyOp = 4

	// The key is used for key wrap encryption.
	KeyOpWrapKey KeyOp = 5

	// The key is used for key wrap decryption.
	KeyOpUnwrapKey KeyOp = 6

	// The key is used for deriving keys. Requires private key fields.
	KeyOpDeriveKey KeyOp = 7

	// The key is used for deriving bits not to be used as a key. Requires
	// private key fields.
	KeyOpDeriveBits KeyOp = 8

	// The key is used for creating MACs.
	KeyOpMACCreate KeyOp = 9

	// The key is used for validating MACs.
	KeyOpMACVerify KeyOp = 10
)

func KeyOpFromString

func KeyOpFromString(val string) (KeyOp, error)

KeyOpFromString returns the KeyOp corresponding to the specified name. The values are taken from https://www.rfc-editor.org/rfc/rfc7517#section-4.3

func (KeyOp) IsSupported

func (ko KeyOp) IsSupported() bool

IsSupported returnns true if the specified value is represents one of the key_ops defined in https://www.rfc-editor.org/rfc/rfc9052.html#name-cose-key-common-parameters

func (KeyOp) MarshalCBOR

func (ko KeyOp) MarshalCBOR() ([]byte, error)

MarshalCBOR marshals the KeyOp as a CBOR int.

func (KeyOp) String

func (ko KeyOp) String() string

String returns a string representation of the KeyType. Note does not represent a valid value of the corresponding serialized entry, and must not be used as such. (The values returned _mostly_ correspond to those accepted by KeyOpFromString, except for MAC create/verify, which are not defined by RFC7517).

func (*KeyOp) UnmarshalCBOR

func (ko *KeyOp) UnmarshalCBOR(data []byte) error

UnmarshalCBOR populates the KeyOp from the provided CBOR value (must be int or tstr).

type KeyType

type KeyType int64

KeyType identifies the family of keys represented by the associated Key. This determines which files within the Key must be set in order for it to be valid.

const (
	// Invlaid key type
	KeyTypeInvalid KeyType = 0
	// Octet Key Pair
	KeyTypeOKP KeyType = 1
	// Elliptic Curve Keys w/ x- and y-coordinate pair
	KeyTypeEC2 KeyType = 2
	// Symmetric Keys
	KeyTypeSymmetric KeyType = 4
)

func (KeyType) MarshalCBOR

func (kt KeyType) MarshalCBOR() ([]byte, error)

MarshalCBOR marshals the KeyType as a CBOR int.

func (KeyType) String

func (kt KeyType) String() string

String returns a string representation of the KeyType. Note does not represent a valid value of the corresponding serialized entry, and must not be used as such.

func (*KeyType) UnmarshalCBOR

func (kt *KeyType) UnmarshalCBOR(data []byte) error

UnmarshalCBOR populates the KeyType from the provided CBOR value (must be int or tstr).

type ProtectedHeader

type ProtectedHeader map[interface{}]interface{}

ProtectedHeader contains parameters that are to be cryptographically protected.

func (ProtectedHeader) Algorithm

func (h ProtectedHeader) Algorithm() (Algorithm, error)

Algorithm gets the algorithm value from the algorithm header.

func (ProtectedHeader) Critical

func (h ProtectedHeader) Critical() ([]interface{}, error)

Critical indicates which protected header labels an application that is processing a message is required to understand.

Reference: https://datatracker.ietf.org/doc/html/rfc8152#section-3.1

func (ProtectedHeader) MarshalCBOR

func (h ProtectedHeader) MarshalCBOR() ([]byte, error)

MarshalCBOR encodes the protected header into a CBOR bstr object. A zero-length header is encoded as a zero-length string rather than as a zero-length map (encoded as h'a0').

func (ProtectedHeader) SetAlgorithm

func (h ProtectedHeader) SetAlgorithm(alg Algorithm)

SetAlgorithm sets the algorithm value to the algorithm header.

func (*ProtectedHeader) UnmarshalCBOR

func (h *ProtectedHeader) UnmarshalCBOR(data []byte) error

UnmarshalCBOR decodes a CBOR bstr object into ProtectedHeader.

ProtectedHeader is an empty_or_serialized_map where

empty_or_serialized_map = bstr .cbor header_map / bstr .size 0

type Sign1Message

type Sign1Message struct {
	Headers   Headers
	Payload   []byte
	Signature []byte
}

Sign1Message represents a decoded COSE_Sign1 message.

Reference: https://tools.ietf.org/html/rfc8152#section-4.2

Example

This example demonstrates signing and verifying COSE_Sign1 signatures.

Code:

{
	// create message to be signed
	msgToSign := cose.NewSign1Message()
	msgToSign.Payload = []byte("hello world")
	msgToSign.Headers.Protected.SetAlgorithm(cose.AlgorithmES512)
	msgToSign.Headers.Unprotected[cose.HeaderLabelKeyID] = []byte("1")

	// create a signer
	privateKey, err := ecdsa.GenerateKey(elliptic.P521(), rand.Reader)
	if err != nil {
		panic(err)
	}
	signer, err := cose.NewSigner(cose.AlgorithmES512, privateKey)
	if err != nil {
		panic(err)
	}

	// sign message
	err = msgToSign.Sign(rand.Reader, nil, signer)
	if err != nil {
		panic(err)
	}
	sig, err := msgToSign.MarshalCBOR()
	if err != nil {
		panic(err)
	}
	fmt.Println("message signed")

	// create a verifier from a trusted public key
	publicKey := privateKey.Public()
	verifier, err := cose.NewVerifier(cose.AlgorithmES512, publicKey)
	if err != nil {
		panic(err)
	}

	// verify message
	var msgToVerify cose.Sign1Message
	err = msgToVerify.UnmarshalCBOR(sig)
	if err != nil {
		panic(err)
	}
	err = msgToVerify.Verify(nil, verifier)
	if err != nil {
		panic(err)
	}
	fmt.Println("message verified")

	// tamper the message and verification should fail
	msgToVerify.Payload = []byte("foobar")
	err = msgToVerify.Verify(nil, verifier)
	if err != cose.ErrVerification {
		panic(err)
	}
	fmt.Println("verification error as expected")
	// Output:
	// message signed
	// message verified
	// verification error as expected
}

Output:

message signed
message verified
verification error as expected

func NewSign1Message

func NewSign1Message() *Sign1Message

NewSign1Message returns a Sign1Message with header initialized.

func (*Sign1Message) MarshalCBOR

func (m *Sign1Message) MarshalCBOR() ([]byte, error)

MarshalCBOR encodes Sign1Message into a COSE_Sign1_Tagged object.

func (*Sign1Message) Sign

func (m *Sign1Message) Sign(rand io.Reader, external []byte, signer Signer) error

Sign signs a Sign1Message using the provided Signer. The signature is stored in m.Signature.

Note that m.Signature is only valid as long as m.Headers.Protected and m.Payload remain unchanged after calling this method. It is possible to modify m.Headers.Unprotected after signing, i.e., add counter signatures or timestamps.

Reference: https://datatracker.ietf.org/doc/html/rfc8152#section-4.4

func (*Sign1Message) UnmarshalCBOR

func (m *Sign1Message) UnmarshalCBOR(data []byte) error

UnmarshalCBOR decodes a COSE_Sign1_Tagged object into Sign1Message.

func (*Sign1Message) Verify

func (m *Sign1Message) Verify(external []byte, verifier Verifier) error

Verify verifies the signature on the Sign1Message returning nil on success or a suitable error if verification fails.

Reference: https://datatracker.ietf.org/doc/html/rfc8152#section-4.4

type SignMessage

type SignMessage struct {
	Headers    Headers
	Payload    []byte
	Signatures []*Signature
}

SignMessage represents a decoded COSE_Sign message.

Reference: https://tools.ietf.org/html/rfc8152#section-4.1

Experimental

Notice: The COSE Sign API is EXPERIMENTAL and may be changed or removed in a later release.

Example

This example demonstrates signing and verifying COSE_Sign signatures.

The COSE Sign API is EXPERIMENTAL and may be changed or removed in a later release.

Code:

{
	// create a signature holder
	sigHolder := cose.NewSignature()
	sigHolder.Headers.Protected.SetAlgorithm(cose.AlgorithmES512)
	sigHolder.Headers.Unprotected[cose.HeaderLabelKeyID] = []byte("1")

	// create message to be signed
	msgToSign := cose.NewSignMessage()
	msgToSign.Payload = []byte("hello world")
	msgToSign.Signatures = append(msgToSign.Signatures, sigHolder)

	// create a signer
	privateKey, err := ecdsa.GenerateKey(elliptic.P521(), rand.Reader)
	if err != nil {
		panic(err)
	}
	signer, err := cose.NewSigner(cose.AlgorithmES512, privateKey)
	if err != nil {
		panic(err)
	}

	// sign message
	err = msgToSign.Sign(rand.Reader, nil, signer)
	if err != nil {
		panic(err)
	}
	sig, err := msgToSign.MarshalCBOR()
	if err != nil {
		panic(err)
	}
	fmt.Println("message signed")

	// create a verifier from a trusted public key
	publicKey := privateKey.Public()
	verifier, err := cose.NewVerifier(cose.AlgorithmES512, publicKey)
	if err != nil {
		panic(err)
	}

	// verify message
	var msgToVerify cose.SignMessage
	err = msgToVerify.UnmarshalCBOR(sig)
	if err != nil {
		panic(err)
	}
	err = msgToVerify.Verify(nil, verifier)
	if err != nil {
		panic(err)
	}
	fmt.Println("message verified")

	// tamper the message and verification should fail
	msgToVerify.Payload = []byte("foobar")
	err = msgToVerify.Verify(nil, verifier)
	if err != cose.ErrVerification {
		panic(err)
	}
	fmt.Println("verification error as expected")
	// Output:
	// message signed
	// message verified
	// verification error as expected
}

Output:

message signed
message verified
verification error as expected

func NewSignMessage

func NewSignMessage() *SignMessage

NewSignMessage returns a SignMessage with header initialized.

Experimental

Notice: The COSE Sign API is EXPERIMENTAL and may be changed or removed in a later release.

func (*SignMessage) MarshalCBOR

func (m *SignMessage) MarshalCBOR() ([]byte, error)

MarshalCBOR encodes SignMessage into a COSE_Sign_Tagged object.

Experimental

Notice: The COSE Sign API is EXPERIMENTAL and may be changed or removed in a later release.

func (*SignMessage) Sign

func (m *SignMessage) Sign(rand io.Reader, external []byte, signers ...Signer) error

Sign signs a SignMessage using the provided signers corresponding to the signatures.

See `Signature.Sign()` for advanced signing scenarios.

Reference: https://datatracker.ietf.org/doc/html/rfc8152#section-4.4

Experimental

Notice: The COSE Sign API is EXPERIMENTAL and may be changed or removed in a later release.

func (*SignMessage) UnmarshalCBOR

func (m *SignMessage) UnmarshalCBOR(data []byte) error

UnmarshalCBOR decodes a COSE_Sign_Tagged object into SignMessage.

Experimental

Notice: The COSE Sign API is EXPERIMENTAL and may be changed or removed in a later release.

func (*SignMessage) Verify

func (m *SignMessage) Verify(external []byte, verifiers ...Verifier) error

Verify verifies the signatures on the SignMessage against the corresponding verifier, returning nil on success or a suitable error if verification fails.

See `Signature.Verify()` for advanced verification scenarios like threshold policies.

Reference: https://datatracker.ietf.org/doc/html/rfc8152#section-4.4

Experimental

Notice: The COSE Sign API is EXPERIMENTAL and may be changed or removed in a later release.

type Signature

type Signature struct {
	Headers   Headers
	Signature []byte
}

Signature represents a decoded COSE_Signature.

Reference: https://tools.ietf.org/html/rfc8152#section-4.1

Experimental

Notice: The COSE Sign API is EXPERIMENTAL and may be changed or removed in a later release.

func NewSignature

func NewSignature() *Signature

NewSignature returns a Signature with header initialized.

Experimental

Notice: The COSE Sign API is EXPERIMENTAL and may be changed or removed in a later release.

func (*Signature) MarshalCBOR

func (s *Signature) MarshalCBOR() ([]byte, error)

MarshalCBOR encodes Signature into a COSE_Signature object.

Experimental

Notice: The COSE Sign API is EXPERIMENTAL and may be changed or removed in a later release.

func (*Signature) Sign

func (s *Signature) Sign(rand io.Reader, signer Signer, protected cbor.RawMessage, payload, external []byte) error

Sign signs a Signature using the provided Signer. Signing a COSE_Signature requires the encoded protected header and the payload of its parent message.

Reference: https://datatracker.ietf.org/doc/html/rfc8152#section-4.4

Experimental

Notice: The COSE Sign API is EXPERIMENTAL and may be changed or removed in a later release.

func (*Signature) UnmarshalCBOR

func (s *Signature) UnmarshalCBOR(data []byte) error

UnmarshalCBOR decodes a COSE_Signature object into Signature.

Experimental

Notice: The COSE Sign API is EXPERIMENTAL and may be changed or removed in a later release.

func (*Signature) Verify

func (s *Signature) Verify(verifier Verifier, protected cbor.RawMessage, payload, external []byte) error

Verify verifies the signature, returning nil on success or a suitable error if verification fails. Verifying a COSE_Signature requires the encoded protected header and the payload of its parent message.

Reference: https://datatracker.ietf.org/doc/html/rfc8152#section-4.4

Experimental

Notice: The COSE Sign API is EXPERIMENTAL and may be changed or removed in a later release.

type Signer

type Signer interface {
	// Algorithm returns the signing algorithm associated with the private key.
	Algorithm() Algorithm

	// Sign signs message content with the private key, possibly using entropy
	// from rand.
	// The resulting signature should follow RFC 8152 section 8.
	//
	// Reference: https://datatracker.ietf.org/doc/html/rfc8152#section-8
	Sign(rand io.Reader, content []byte) ([]byte, error)
}

Signer is an interface for private keys to sign COSE signatures.

func NewSigner

func NewSigner(alg Algorithm, key crypto.Signer) (Signer, error)

NewSigner returns a signer with a given signing key. The signing key can be a golang built-in crypto private key, a key in HSM, or a remote KMS.

Developers are encouraged to implement the `cose.Signer` interface instead of the `crypto.Signer` interface for better performance.

All signing keys implementing `crypto.Signer` with `Public()` returning a public key of type `*rsa.PublicKey`, `*ecdsa.PublicKey`, or `ed25519.PublicKey` are accepted.

Note: `*rsa.PrivateKey`, `*ecdsa.PrivateKey`, and `ed25519.PrivateKey` implement `crypto.Signer`.

type UnprotectedHeader

type UnprotectedHeader map[interface{}]interface{}

UnprotectedHeader contains parameters that are not cryptographically protected.

func (UnprotectedHeader) MarshalCBOR

func (h UnprotectedHeader) MarshalCBOR() ([]byte, error)

MarshalCBOR encodes the unprotected header into a CBOR map object. A zero-length header is encoded as a zero-length map (encoded as h'a0').

func (*UnprotectedHeader) UnmarshalCBOR

func (h *UnprotectedHeader) UnmarshalCBOR(data []byte) error

UnmarshalCBOR decodes a CBOR map object into UnprotectedHeader.

UnprotectedHeader is a header_map.

type UntaggedSign1Message

type UntaggedSign1Message Sign1Message

func (*UntaggedSign1Message) MarshalCBOR

func (m *UntaggedSign1Message) MarshalCBOR() ([]byte, error)

MarshalCBOR encodes UntaggedSign1Message into a COSE_Sign1 object.

func (*UntaggedSign1Message) Sign

func (m *UntaggedSign1Message) Sign(rand io.Reader, external []byte, signer Signer) error

Sign signs an UnttaggedSign1Message using the provided Signer. The signature is stored in m.Signature.

Note that m.Signature is only valid as long as m.Headers.Protected and m.Payload remain unchanged after calling this method. It is possible to modify m.Headers.Unprotected after signing, i.e., add counter signatures or timestamps.

Reference: https://datatracker.ietf.org/doc/html/rfc8152#section-4.4

func (*UntaggedSign1Message) UnmarshalCBOR

func (m *UntaggedSign1Message) UnmarshalCBOR(data []byte) error

UnmarshalCBOR decodes a COSE_Sign1 object into an UnataggedSign1Message.

func (*UntaggedSign1Message) Verify

func (m *UntaggedSign1Message) Verify(external []byte, verifier Verifier) error

Verify verifies the signature on the UntaggedSign1Message returning nil on success or a suitable error if verification fails.

Reference: https://datatracker.ietf.org/doc/html/rfc8152#section-4.4

type Verifier

type Verifier interface {
	// Algorithm returns the signing algorithm associated with the public key.
	Algorithm() Algorithm

	// Verify verifies message content with the public key, returning nil for
	// success.
	// Otherwise, it returns ErrVerification.
	//
	// Reference: https://datatracker.ietf.org/doc/html/rfc8152#section-8
	Verify(content, signature []byte) error
}

Verifier is an interface for public keys to verify COSE signatures.

func NewVerifier

func NewVerifier(alg Algorithm, key crypto.PublicKey) (Verifier, error)

NewVerifier returns a verifier with a given public key. Only golang built-in crypto public keys of type `*rsa.PublicKey`, `*ecdsa.PublicKey`, and `ed25519.PublicKey` are accepted.

Source Files

algorithm.go cbor.go common.go ecdsa.go ed25519.go errors.go headers.go key.go rsa.go sign.go sign1.go signer.go verifier.go

Version
v1.2.1
Published
Jul 4, 2023
Platform
js/wasm
Imports
13 packages
Last checked
2 months ago

Tools for package owners.